Support rust-nightly-2022-02-23
diff --git a/dockerfile/Dockerfile.1804.nightly b/dockerfile/Dockerfile.1804.nightly
index e3ea188..7618c98 100644
--- a/dockerfile/Dockerfile.1804.nightly
+++ b/dockerfile/Dockerfile.1804.nightly
@@ -31,7 +31,7 @@
# Seventh, Rust
-ENV rust_toolchain nightly-2021-11-01
+ENV rust_toolchain nightly-2022-02-23
ADD 05_rust.sh /root
RUN bash /root/05_rust.sh
diff --git a/dockerfile/Dockerfile.2004.nightly b/dockerfile/Dockerfile.2004.nightly
index 2ffc20b..6203670 100644
--- a/dockerfile/Dockerfile.2004.nightly
+++ b/dockerfile/Dockerfile.2004.nightly
@@ -34,7 +34,7 @@
# Seventh, Rust
-ENV rust_toolchain nightly-2021-11-01
+ENV rust_toolchain nightly-2022-02-23
ADD 05_rust.sh /root
RUN bash /root/05_rust.sh
diff --git a/dockerfile/Dockerfile.centos8.nightly b/dockerfile/Dockerfile.centos8.nightly
index bd107c2..939f948 100644
--- a/dockerfile/Dockerfile.centos8.nightly
+++ b/dockerfile/Dockerfile.centos8.nightly
@@ -22,7 +22,7 @@
ADD 04_psw_rpm.sh /root
RUN bash /root/04_psw_rpm.sh
-ENV rust_toolchain nightly-2021-11-01
+ENV rust_toolchain nightly-2022-02-23
ADD 05_rust.sh /root
RUN bash /root/05_rust.sh
diff --git a/edl/sgx_file.edl b/edl/sgx_file.edl
index 07fb1eb..c70ec59 100644
--- a/edl/sgx_file.edl
+++ b/edl/sgx_file.edl
@@ -27,6 +27,7 @@
untrusted {
int u_open_ocall([out] int *error, [in, string] const char *pathname, int flags);
int u_open64_ocall([out] int *error, [in, string] const char *path, int oflag, int mode);
+ int u_openat_ocall([out] int *error, int dirfd, [in, string] const char *pathname, int flags);
int u_fstat_ocall([out] int *error, int fd, [out] struct stat_t *buf);
int u_fstat64_ocall([out] int *error, int fd, [out] struct stat64_t *buf);
@@ -46,6 +47,7 @@
int u_fchmod_ocall([out] int *error, int fd, uint32_t mode);
int u_unlink_ocall([out] int *error, [in, string] const char *pathname);
int u_link_ocall([out] int *error, [in, string] const char *oldpath, [in, string] const char *newpath);
+ int u_unlinkat_ocall([out] int *error, int dirfd, [in, string] const char *pathname, int flags);
int u_linkat_ocall([out] int *error, int olddirfd, [in, string] const char *oldpath, int newdirfd, [in, string] const char *newpath, int flags);
int u_rename_ocall([out] int *error, [in, string] const char *oldpath, [in, string] const char *newpath);
int u_chmod_ocall([out] int *error, [in, string] const char *path, uint32_t mode);
@@ -54,6 +56,7 @@
char *u_realpath_ocall([out] int *error, [in, string] const char *pathname);
int u_mkdir_ocall([out] int *error, [in, string] const char *pathname, uint32_t mode);
int u_rmdir_ocall([out] int *error, [in, string] const char *pathname);
+ void *u_fdopendir_ocall([out] int *error, int fd);
void *u_opendir_ocall([out] int *error, [in, string] const char *pathname);
int u_readdir64_r_ocall([user_check] void *dirp, [in, out] struct dirent64_t *entry, [out] struct dirent64_t **result);
int u_closedir_ocall([out] int *error, [user_check] void *dirp);
diff --git a/rust-toolchain b/rust-toolchain
index 7cc42ef..4e7e21b 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1 +1 @@
-nightly-2021-11-01
+nightly-2022-02-23
\ No newline at end of file
diff --git a/samplecode/backtrace/enclave/Cargo.toml b/samplecode/backtrace/enclave/Cargo.toml
index 00b1f7b..ef0574e 100644
--- a/samplecode/backtrace/enclave/Cargo.toml
+++ b/samplecode/backtrace/enclave/Cargo.toml
@@ -16,6 +16,7 @@
sgx_backtrace = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -24,6 +25,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/backtrace/enclave/Xargo.toml b/samplecode/backtrace/enclave/Xargo.toml
index abb29c4..13d92c3 100644
--- a/samplecode/backtrace/enclave/Xargo.toml
+++ b/samplecode/backtrace/enclave/Xargo.toml
@@ -89,6 +89,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/backtrace/enclave/x86_64-unknown-linux-sgx.json b/samplecode/backtrace/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/backtrace/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/backtrace/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/crypto/enclave/Cargo.toml b/samplecode/crypto/enclave/Cargo.toml
index b6839c3..7bc5264 100644
--- a/samplecode/crypto/enclave/Cargo.toml
+++ b/samplecode/crypto/enclave/Cargo.toml
@@ -17,6 +17,7 @@
sgx_tcrypto = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -25,6 +26,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
@@ -41,6 +43,6 @@
sgx_tstd = { path = "../../../sgx_tstd" }
sgx_tunittest = { path = "../../../sgx_tunittest" }
sgx_types = { path = "../../../sgx_types" }
-sgx_ucrypto = { path = "../../../sgx_ucrypto" }
+#sgx_ucrypto = { path = "../../../sgx_ucrypto" }
sgx_unwind = { path = "../../../sgx_unwind" }
-sgx_urts = { path = "../../../sgx_urts" }
+#sgx_urts = { path = "../../../sgx_urts" }
diff --git a/samplecode/crypto/enclave/x86_64-unknown-linux-sgx.json b/samplecode/crypto/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/crypto/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/crypto/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/db-proxy/db-proxy/enclave/Cargo.toml b/samplecode/db-proxy/db-proxy/enclave/Cargo.toml
index 7c13f5d..9661fe8 100644
--- a/samplecode/db-proxy/db-proxy/enclave/Cargo.toml
+++ b/samplecode/db-proxy/db-proxy/enclave/Cargo.toml
@@ -15,6 +15,7 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../../sgx_alloc" }
sgx_backtrace = { path = "../../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../../sgx_backtrace_sys" }
@@ -23,6 +24,7 @@
sgx_crypto_helper = { path = "../../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../../sgx_demangle" }
sgx_libc = { path = "../../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../../sgx_no_tstd" }
sgx_rand = { path = "../../../../sgx_rand" }
sgx_rand_derive = { path = "../../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../../sgx_serialize" }
@@ -41,4 +43,4 @@
sgx_types = { path = "../../../../sgx_types" }
#sgx_ucrypto = { path = "../../../../sgx_ucrypto" }
sgx_unwind = { path = "../../../../sgx_unwind" }
-#sgx_urts = { path = "../../../../sgx_urts" }
+#sgx_urts = { path = "../../../../sgx_urts" }
\ No newline at end of file
diff --git a/samplecode/db-proxy/db-proxy/enclave/x86_64-unknown-linux-sgx.json b/samplecode/db-proxy/db-proxy/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/db-proxy/db-proxy/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/db-proxy/db-proxy/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/dcap-pckretrieval/enclave/x86_64-unknown-linux-sgx.json b/samplecode/dcap-pckretrieval/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/dcap-pckretrieval/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/dcap-pckretrieval/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/file/enclave/Cargo.toml b/samplecode/file/enclave/Cargo.toml
index 3bac2bf..09ece4c 100644
--- a/samplecode/file/enclave/Cargo.toml
+++ b/samplecode/file/enclave/Cargo.toml
@@ -20,6 +20,7 @@
sgx_serialize_derive = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -28,6 +29,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/file/enclave/x86_64-unknown-linux-sgx.json b/samplecode/file/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/file/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/file/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/hello-regex/enclave/Cargo.toml b/samplecode/hello-regex/enclave/Cargo.toml
index 9e6cfc3..7a7da44 100644
--- a/samplecode/hello-regex/enclave/Cargo.toml
+++ b/samplecode/hello-regex/enclave/Cargo.toml
@@ -18,6 +18,7 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -26,6 +27,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/hello-regex/enclave/x86_64-unknown-linux-sgx.json b/samplecode/hello-regex/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/hello-regex/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/hello-regex/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/hello-rust-vscode-debug/Cargo.toml b/samplecode/hello-rust-vscode-debug/Cargo.toml
index 50897b4..f5ecf2c 100644
--- a/samplecode/hello-rust-vscode-debug/Cargo.toml
+++ b/samplecode/hello-rust-vscode-debug/Cargo.toml
@@ -4,29 +4,3 @@
"app",
"enclave",
]
-
-[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
-sgx_alloc = { path = "../../sgx_alloc" }
-sgx_build_helper = { path = "../../sgx_build_helper" }
-sgx_cov = { path = "../../sgx_cov" }
-sgx_crypto_helper = { path = "../../sgx_crypto_helper" }
-sgx_libc = { path = "../../sgx_libc" }
-sgx_rand = { path = "../../sgx_rand" }
-sgx_rand_derive = { path = "../../sgx_rand_derive" }
-sgx_serialize = { path = "../../sgx_serialize" }
-sgx_serialize_derive = { path = "../../sgx_serialize_derive" }
-sgx_serialize_derive_internals = { path = "../../sgx_serialize_derive_internals" }
-sgx_tcrypto = { path = "../../sgx_tcrypto" }
-sgx_tcrypto_helper = { path = "../../sgx_tcrypto_helper" }
-sgx_tdh = { path = "../../sgx_tdh" }
-sgx_tkey_exchange = { path = "../../sgx_tkey_exchange" }
-sgx_tprotected_fs = { path = "../../sgx_tprotected_fs" }
-sgx_trts = { path = "../../sgx_trts" }
-sgx_tse = { path = "../../sgx_tse" }
-sgx_tseal = { path = "../../sgx_tseal" }
-sgx_tstd = { path = "../../sgx_tstd" }
-sgx_tunittest = { path = "../../sgx_tunittest" }
-sgx_types = { path = "../../sgx_types" }
-sgx_ucrypto = { path = "../../sgx_ucrypto" }
-sgx_unwind = { path = "../../sgx_unwind" }
-sgx_urts = { path = "../../sgx_urts" }
diff --git a/samplecode/hello-rust-vscode-debug/enclave/Cargo.toml b/samplecode/hello-rust-vscode-debug/enclave/Cargo.toml
index f4f3224..c547778 100644
--- a/samplecode/hello-rust-vscode-debug/enclave/Cargo.toml
+++ b/samplecode/hello-rust-vscode-debug/enclave/Cargo.toml
@@ -15,6 +15,7 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -23,6 +24,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/hello-rust-vscode-debug/enclave/x86_64-unknown-linux-sgx.json b/samplecode/hello-rust-vscode-debug/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/hello-rust-vscode-debug/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/hello-rust-vscode-debug/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/hello-rust/enclave/Cargo.toml b/samplecode/hello-rust/enclave/Cargo.toml
index 8e7afa9..fe0ebe3 100644
--- a/samplecode/hello-rust/enclave/Cargo.toml
+++ b/samplecode/hello-rust/enclave/Cargo.toml
@@ -12,14 +12,19 @@
[target.'cfg(not(target_env = "sgx"))'.dependencies]
sgx_types = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
-sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git", features = ["backtrace"] }
-sgx_trts = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
+sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
+
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
+sgx_backtrace = { path = "../../../sgx_backtrace" }
+sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
sgx_build_helper = { path = "../../../sgx_build_helper" }
sgx_cov = { path = "../../../sgx_cov" }
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
+sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
@@ -36,6 +41,6 @@
sgx_tstd = { path = "../../../sgx_tstd" }
sgx_tunittest = { path = "../../../sgx_tunittest" }
sgx_types = { path = "../../../sgx_types" }
-sgx_ucrypto = { path = "../../../sgx_ucrypto" }
+#sgx_ucrypto = { path = "../../../sgx_ucrypto" }
sgx_unwind = { path = "../../../sgx_unwind" }
-sgx_urts = { path = "../../../sgx_urts" }
+#sgx_urts = { path = "../../../sgx_urts" }
\ No newline at end of file
diff --git a/samplecode/hello-rust/enclave/x86_64-unknown-linux-sgx.json b/samplecode/hello-rust/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/hello-rust/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/hello-rust/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/helloworld/enclave/Cargo.toml b/samplecode/helloworld/enclave/Cargo.toml
index f4f3224..c547778 100644
--- a/samplecode/helloworld/enclave/Cargo.toml
+++ b/samplecode/helloworld/enclave/Cargo.toml
@@ -15,6 +15,7 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -23,6 +24,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/helloworld/enclave/x86_64-unknown-linux-sgx.json b/samplecode/helloworld/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/helloworld/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/helloworld/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/http_req/Makefile b/samplecode/http_req/Makefile
index fee080a..4d150cb 100644
--- a/samplecode/http_req/Makefile
+++ b/samplecode/http_req/Makefile
@@ -1,5 +1,4 @@
######## SGX SDK Settings ########
-SGX_SDK_RUST ?= $(HOME)/sgx
SGX_SDK ?= /opt/sgxsdk
SGX_MODE ?= HW
SGX_ARCH ?= x64
@@ -46,8 +45,8 @@
CUSTOM_LIBRARY_PATH := ./lib
CUSTOM_BIN_PATH := ./bin
-CUSTOM_EDL_PATH := $(SGX_SDK_RUST)/edl
-CUSTOM_COMMON_PATH := $(SGX_SDK_RUST)/common
+CUSTOM_EDL_PATH := ../../edl
+CUSTOM_COMMON_PATH := ../../common
######## EDL Settings ########
diff --git a/samplecode/http_req/enclave/Cargo.toml b/samplecode/http_req/enclave/Cargo.toml
index e0cfa8c..9cca0f1 100644
--- a/samplecode/http_req/enclave/Cargo.toml
+++ b/samplecode/http_req/enclave/Cargo.toml
@@ -16,6 +16,7 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git", features = ["net"] }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -24,6 +25,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/http_req/enclave/x86_64-unknown-linux-sgx.json b/samplecode/http_req/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/http_req/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/http_req/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/hugemem/enclave/Cargo.toml b/samplecode/hugemem/enclave/Cargo.toml
index 76f7695..548a28a 100644
--- a/samplecode/hugemem/enclave/Cargo.toml
+++ b/samplecode/hugemem/enclave/Cargo.toml
@@ -15,6 +15,7 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -23,6 +24,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/hugemem/enclave/x86_64-unknown-linux-sgx.json b/samplecode/hugemem/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/hugemem/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/hugemem/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/kvdb-memdb/enclave/Cargo.toml b/samplecode/kvdb-memdb/enclave/Cargo.toml
index 0bc002c..2f9d9a0 100644
--- a/samplecode/kvdb-memdb/enclave/Cargo.toml
+++ b/samplecode/kvdb-memdb/enclave/Cargo.toml
@@ -20,6 +20,7 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -28,6 +29,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/kvdb-memdb/enclave/x86_64-unknown-linux-sgx.json b/samplecode/kvdb-memdb/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/kvdb-memdb/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/kvdb-memdb/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/localattestation/attestation/Cargo.toml b/samplecode/localattestation/attestation/Cargo.toml
index 0fe7a53..a41ecb6 100644
--- a/samplecode/localattestation/attestation/Cargo.toml
+++ b/samplecode/localattestation/attestation/Cargo.toml
@@ -14,6 +14,7 @@
sgx_tdh = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -22,6 +23,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/localattestation/enclave1/Cargo.toml b/samplecode/localattestation/enclave1/Cargo.toml
index 9da182e..8abbd2c 100644
--- a/samplecode/localattestation/enclave1/Cargo.toml
+++ b/samplecode/localattestation/enclave1/Cargo.toml
@@ -17,6 +17,7 @@
attestation = {path = "../attestation/"}
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -25,6 +26,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/localattestation/enclave1/Xargo.toml b/samplecode/localattestation/enclave1/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/localattestation/enclave1/Xargo.toml
+++ b/samplecode/localattestation/enclave1/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/localattestation/enclave1/x86_64-unknown-linux-sgx.json b/samplecode/localattestation/enclave1/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/localattestation/enclave1/x86_64-unknown-linux-sgx.json
+++ b/samplecode/localattestation/enclave1/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/localattestation/enclave2/Cargo.toml b/samplecode/localattestation/enclave2/Cargo.toml
index 214479d..86ca0fb 100644
--- a/samplecode/localattestation/enclave2/Cargo.toml
+++ b/samplecode/localattestation/enclave2/Cargo.toml
@@ -17,6 +17,7 @@
attestation = {path = "../attestation/"}
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -25,6 +26,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/localattestation/enclave2/Xargo.toml b/samplecode/localattestation/enclave2/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/localattestation/enclave2/Xargo.toml
+++ b/samplecode/localattestation/enclave2/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/localattestation/enclave2/x86_64-unknown-linux-sgx.json b/samplecode/localattestation/enclave2/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/localattestation/enclave2/x86_64-unknown-linux-sgx.json
+++ b/samplecode/localattestation/enclave2/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/localattestation/enclave3/Cargo.toml b/samplecode/localattestation/enclave3/Cargo.toml
index bf9a485..e9d06b4 100644
--- a/samplecode/localattestation/enclave3/Cargo.toml
+++ b/samplecode/localattestation/enclave3/Cargo.toml
@@ -17,6 +17,7 @@
attestation = {path = "../attestation/"}
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -25,6 +26,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/localattestation/enclave3/Xargo.toml b/samplecode/localattestation/enclave3/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/localattestation/enclave3/Xargo.toml
+++ b/samplecode/localattestation/enclave3/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/localattestation/enclave3/x86_64-unknown-linux-sgx.json b/samplecode/localattestation/enclave3/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/localattestation/enclave3/x86_64-unknown-linux-sgx.json
+++ b/samplecode/localattestation/enclave3/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/logger/enclave/Cargo.toml b/samplecode/logger/enclave/Cargo.toml
index 4c7e6a7..ab40428 100644
--- a/samplecode/logger/enclave/Cargo.toml
+++ b/samplecode/logger/enclave/Cargo.toml
@@ -19,6 +19,7 @@
env_logger = { git = "https://github.com/mesalock-linux/env_logger-sgx" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -27,6 +28,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/logger/enclave/Xargo.toml b/samplecode/logger/enclave/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/logger/enclave/Xargo.toml
+++ b/samplecode/logger/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/logger/enclave/x86_64-unknown-linux-sgx.json b/samplecode/logger/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/logger/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/logger/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/machine-learning/enclave/Cargo.toml b/samplecode/machine-learning/enclave/Cargo.toml
index 9c9f363..d8721b9 100644
--- a/samplecode/machine-learning/enclave/Cargo.toml
+++ b/samplecode/machine-learning/enclave/Cargo.toml
@@ -10,6 +10,9 @@
[features]
default = []
+[profile.release]
+lto = true
+
[target.'cfg(not(target_env = "sgx"))'.dependencies]
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
sgx_types = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
@@ -25,6 +28,7 @@
serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -33,6 +37,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/machine-learning/enclave/Xargo.toml b/samplecode/machine-learning/enclave/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/machine-learning/enclave/Xargo.toml
+++ b/samplecode/machine-learning/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/machine-learning/enclave/x86_64-unknown-linux-sgx.json b/samplecode/machine-learning/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/machine-learning/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/machine-learning/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/mio/client/enclave/Cargo.toml b/samplecode/mio/client/enclave/Cargo.toml
index 6c83e90..8aa09c6 100644
--- a/samplecode/mio/client/enclave/Cargo.toml
+++ b/samplecode/mio/client/enclave/Cargo.toml
@@ -20,11 +20,16 @@
log = { git = "https://github.com/mesalock-linux/log-sgx" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../../sgx_alloc" }
+sgx_backtrace = { path = "../../../../sgx_backtrace" }
+sgx_backtrace_sys = { path = "../../../../sgx_backtrace_sys" }
sgx_build_helper = { path = "../../../../sgx_build_helper" }
sgx_cov = { path = "../../../../sgx_cov" }
sgx_crypto_helper = { path = "../../../../sgx_crypto_helper" }
+sgx_demangle = { path = "../../../../sgx_demangle" }
sgx_libc = { path = "../../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../../sgx_no_tstd" }
sgx_rand = { path = "../../../../sgx_rand" }
sgx_rand_derive = { path = "../../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../../sgx_serialize" }
diff --git a/samplecode/mio/client/enclave/Xargo.toml b/samplecode/mio/client/enclave/Xargo.toml
index 989d796..795f1f0 100644
--- a/samplecode/mio/client/enclave/Xargo.toml
+++ b/samplecode/mio/client/enclave/Xargo.toml
@@ -89,6 +89,7 @@
[dependencies.sgx_cov]
path = "../../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../../sgx_signal"
stage = 7
diff --git a/samplecode/mio/client/enclave/x86_64-unknown-linux-sgx.json b/samplecode/mio/client/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/mio/client/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/mio/client/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/mio/server/enclave/Cargo.toml b/samplecode/mio/server/enclave/Cargo.toml
index a703daf..9540bee 100644
--- a/samplecode/mio/server/enclave/Cargo.toml
+++ b/samplecode/mio/server/enclave/Cargo.toml
@@ -21,6 +21,7 @@
log = { git = "https://github.com/mesalock-linux/log-sgx" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../../sgx_alloc" }
sgx_backtrace = { path = "../../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../../sgx_backtrace_sys" }
@@ -29,6 +30,7 @@
sgx_crypto_helper = { path = "../../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../../sgx_demangle" }
sgx_libc = { path = "../../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../../sgx_no_tstd" }
sgx_rand = { path = "../../../../sgx_rand" }
sgx_rand_derive = { path = "../../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../../sgx_serialize" }
diff --git a/samplecode/mio/server/enclave/Xargo.toml b/samplecode/mio/server/enclave/Xargo.toml
index 989d796..795f1f0 100644
--- a/samplecode/mio/server/enclave/Xargo.toml
+++ b/samplecode/mio/server/enclave/Xargo.toml
@@ -89,6 +89,7 @@
[dependencies.sgx_cov]
path = "../../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../../sgx_signal"
stage = 7
diff --git a/samplecode/mio/server/enclave/x86_64-unknown-linux-sgx.json b/samplecode/mio/server/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/mio/server/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/mio/server/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/mutual-ra/enclave/Cargo.toml b/samplecode/mutual-ra/enclave/Cargo.toml
index 24aece4..009732b 100644
--- a/samplecode/mutual-ra/enclave/Cargo.toml
+++ b/samplecode/mutual-ra/enclave/Cargo.toml
@@ -37,6 +37,7 @@
features = ["dangerous_configuration"]
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -45,6 +46,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/mutual-ra/enclave/Xargo.toml b/samplecode/mutual-ra/enclave/Xargo.toml
index 333a007..ec653df 100644
--- a/samplecode/mutual-ra/enclave/Xargo.toml
+++ b/samplecode/mutual-ra/enclave/Xargo.toml
@@ -89,6 +89,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/mutual-ra/enclave/x86_64-unknown-linux-sgx.json b/samplecode/mutual-ra/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/mutual-ra/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/mutual-ra/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/net2/enclave/Cargo.toml b/samplecode/net2/enclave/Cargo.toml
index 5b89b2a..07e8b33 100644
--- a/samplecode/net2/enclave/Cargo.toml
+++ b/samplecode/net2/enclave/Cargo.toml
@@ -18,6 +18,7 @@
sgx_types = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -26,6 +27,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/net2/enclave/Xargo.toml b/samplecode/net2/enclave/Xargo.toml
index 80745aa..26fd2ce 100644
--- a/samplecode/net2/enclave/Xargo.toml
+++ b/samplecode/net2/enclave/Xargo.toml
@@ -89,6 +89,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/net2/enclave/x86_64-unknown-linux-sgx.json b/samplecode/net2/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/net2/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/net2/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/pcl/encrypted-hello/enclave/Cargo.toml b/samplecode/pcl/encrypted-hello/enclave/Cargo.toml
index abe33c0..9ab56c7 100644
--- a/samplecode/pcl/encrypted-hello/enclave/Cargo.toml
+++ b/samplecode/pcl/encrypted-hello/enclave/Cargo.toml
@@ -15,11 +15,16 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../../sgx_alloc" }
+sgx_backtrace = { path = "../../../../sgx_backtrace" }
+sgx_backtrace_sys = { path = "../../../../sgx_backtrace_sys" }
sgx_build_helper = { path = "../../../../sgx_build_helper" }
sgx_cov = { path = "../../../../sgx_cov" }
sgx_crypto_helper = { path = "../../../../sgx_crypto_helper" }
+sgx_demangle = { path = "../../../../sgx_demangle" }
sgx_libc = { path = "../../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../../sgx_no_tstd" }
sgx_rand = { path = "../../../../sgx_rand" }
sgx_rand_derive = { path = "../../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../../sgx_serialize" }
@@ -36,6 +41,6 @@
sgx_tstd = { path = "../../../../sgx_tstd" }
sgx_tunittest = { path = "../../../../sgx_tunittest" }
sgx_types = { path = "../../../../sgx_types" }
-sgx_ucrypto = { path = "../../../../sgx_ucrypto" }
+#sgx_ucrypto = { path = "../../../../sgx_ucrypto" }
sgx_unwind = { path = "../../../../sgx_unwind" }
-sgx_urts = { path = "../../../../sgx_urts" }
+#sgx_urts = { path = "../../../../sgx_urts" }
diff --git a/samplecode/pcl/encrypted-hello/enclave/Xargo.toml b/samplecode/pcl/encrypted-hello/enclave/Xargo.toml
index 29ccfac..c578b6c 100644
--- a/samplecode/pcl/encrypted-hello/enclave/Xargo.toml
+++ b/samplecode/pcl/encrypted-hello/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../../sgx_signal"
stage = 7
diff --git a/samplecode/pcl/encrypted-hello/enclave/x86_64-unknown-linux-sgx.json b/samplecode/pcl/encrypted-hello/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/pcl/encrypted-hello/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/pcl/encrypted-hello/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/pcl/pcl-seal/enclave/Cargo.toml b/samplecode/pcl/pcl-seal/enclave/Cargo.toml
index 57127e8..1b85d0a 100644
--- a/samplecode/pcl/pcl-seal/enclave/Cargo.toml
+++ b/samplecode/pcl/pcl-seal/enclave/Cargo.toml
@@ -32,11 +32,16 @@
ue_send_recv = { path = "ue_send_recv" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../../sgx_alloc" }
+sgx_backtrace = { path = "../../../../sgx_backtrace" }
+sgx_backtrace_sys = { path = "../../../../sgx_backtrace_sys" }
sgx_build_helper = { path = "../../../../sgx_build_helper" }
sgx_cov = { path = "../../../../sgx_cov" }
sgx_crypto_helper = { path = "../../../../sgx_crypto_helper" }
+sgx_demangle = { path = "../../../../sgx_demangle" }
sgx_libc = { path = "../../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../../sgx_no_tstd" }
sgx_rand = { path = "../../../../sgx_rand" }
sgx_rand_derive = { path = "../../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../../sgx_serialize" }
@@ -53,6 +58,6 @@
sgx_tstd = { path = "../../../../sgx_tstd" }
sgx_tunittest = { path = "../../../../sgx_tunittest" }
sgx_types = { path = "../../../../sgx_types" }
-sgx_ucrypto = { path = "../../../../sgx_ucrypto" }
+#sgx_ucrypto = { path = "../../../../sgx_ucrypto" }
sgx_unwind = { path = "../../../../sgx_unwind" }
-sgx_urts = { path = "../../../../sgx_urts" }
+#sgx_urts = { path = "../../../../sgx_urts" }
diff --git a/samplecode/pcl/pcl-seal/enclave/Xargo.toml b/samplecode/pcl/pcl-seal/enclave/Xargo.toml
index 989d796..795f1f0 100644
--- a/samplecode/pcl/pcl-seal/enclave/Xargo.toml
+++ b/samplecode/pcl/pcl-seal/enclave/Xargo.toml
@@ -89,6 +89,7 @@
[dependencies.sgx_cov]
path = "../../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../../sgx_signal"
stage = 7
diff --git a/samplecode/pcl/pcl-seal/enclave/ue_send_recv/Cargo.toml b/samplecode/pcl/pcl-seal/enclave/ue_send_recv/Cargo.toml
index 4313441..0bc6a3e 100644
--- a/samplecode/pcl/pcl-seal/enclave/ue_send_recv/Cargo.toml
+++ b/samplecode/pcl/pcl-seal/enclave/ue_send_recv/Cargo.toml
@@ -20,11 +20,16 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../../../sgx_alloc" }
+sgx_backtrace = { path = "../../../../../sgx_backtrace" }
+sgx_backtrace_sys = { path = "../../../../../sgx_backtrace_sys" }
sgx_build_helper = { path = "../../../../../sgx_build_helper" }
sgx_cov = { path = "../../../../../sgx_cov" }
sgx_crypto_helper = { path = "../../../../../sgx_crypto_helper" }
+sgx_demangle = { path = "../../../../../sgx_demangle" }
sgx_libc = { path = "../../../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../../../sgx_no_tstd" }
sgx_rand = { path = "../../../../../sgx_rand" }
sgx_rand_derive = { path = "../../../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../../../sgx_serialize" }
@@ -41,6 +46,6 @@
sgx_tstd = { path = "../../../../../sgx_tstd" }
sgx_tunittest = { path = "../../../../../sgx_tunittest" }
sgx_types = { path = "../../../../../sgx_types" }
-sgx_ucrypto = { path = "../../../../../sgx_ucrypto" }
+#sgx_ucrypto = { path = "../../../../../sgx_ucrypto" }
sgx_unwind = { path = "../../../../../sgx_unwind" }
-sgx_urts = { path = "../../../../../sgx_urts" }
+#sgx_urts = { path = "../../../../../sgx_urts" }
diff --git a/samplecode/pcl/pcl-seal/enclave/x86_64-unknown-linux-sgx.json b/samplecode/pcl/pcl-seal/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/pcl/pcl-seal/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/pcl/pcl-seal/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/project_template/app/rust-toolchain b/samplecode/project_template/app/rust-toolchain
index e966e30..4e7e21b 100644
--- a/samplecode/project_template/app/rust-toolchain
+++ b/samplecode/project_template/app/rust-toolchain
@@ -1 +1 @@
-nightly-2020-10-25
\ No newline at end of file
+nightly-2022-02-23
\ No newline at end of file
diff --git a/samplecode/project_template/enclave/rust-toolchain b/samplecode/project_template/enclave/rust-toolchain
index e966e30..4e7e21b 100644
--- a/samplecode/project_template/enclave/rust-toolchain
+++ b/samplecode/project_template/enclave/rust-toolchain
@@ -1 +1 @@
-nightly-2020-10-25
\ No newline at end of file
+nightly-2022-02-23
\ No newline at end of file
diff --git a/samplecode/prost-protobuf/enclave/Cargo.toml b/samplecode/prost-protobuf/enclave/Cargo.toml
index 120ec2c..ef0d256 100644
--- a/samplecode/prost-protobuf/enclave/Cargo.toml
+++ b/samplecode/prost-protobuf/enclave/Cargo.toml
@@ -23,11 +23,16 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
+sgx_backtrace = { path = "../../../sgx_backtrace" }
+sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
sgx_build_helper = { path = "../../../sgx_build_helper" }
sgx_cov = { path = "../../../sgx_cov" }
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
+sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/prost-protobuf/enclave/x86_64-unknown-linux-sgx.json b/samplecode/prost-protobuf/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/prost-protobuf/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/prost-protobuf/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/protobuf/enclave/Cargo.toml b/samplecode/protobuf/enclave/Cargo.toml
index e78579d..e31301c 100644
--- a/samplecode/protobuf/enclave/Cargo.toml
+++ b/samplecode/protobuf/enclave/Cargo.toml
@@ -18,6 +18,7 @@
protobuf = { git = "https://github.com/mesalock-linux/rust-protobuf-sgx", branch = "v2.8" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -26,6 +27,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/protobuf/enclave/Xargo.toml b/samplecode/protobuf/enclave/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/protobuf/enclave/Xargo.toml
+++ b/samplecode/protobuf/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/protobuf/enclave/x86_64-unknown-linux-sgx.json b/samplecode/protobuf/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/protobuf/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/protobuf/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/psi/SMCServer/enclave/Cargo.toml b/samplecode/psi/SMCServer/enclave/Cargo.toml
index b6e7db2..d00ec7e 100644
--- a/samplecode/psi/SMCServer/enclave/Cargo.toml
+++ b/samplecode/psi/SMCServer/enclave/Cargo.toml
@@ -20,6 +20,7 @@
sgx_rand = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../../sgx_alloc" }
sgx_backtrace = { path = "../../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../../sgx_backtrace_sys" }
@@ -28,6 +29,7 @@
sgx_crypto_helper = { path = "../../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../../sgx_demangle" }
sgx_libc = { path = "../../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../../sgx_no_tstd" }
sgx_rand = { path = "../../../../sgx_rand" }
sgx_rand_derive = { path = "../../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../../sgx_serialize" }
diff --git a/samplecode/psi/SMCServer/enclave/Xargo.toml b/samplecode/psi/SMCServer/enclave/Xargo.toml
index 29ccfac..c578b6c 100644
--- a/samplecode/psi/SMCServer/enclave/Xargo.toml
+++ b/samplecode/psi/SMCServer/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../../sgx_signal"
stage = 7
diff --git a/samplecode/psi/SMCServer/enclave/x86_64-unknown-linux-sgx.json b/samplecode/psi/SMCServer/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/psi/SMCServer/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/psi/SMCServer/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/remoteattestation/Application/Makefile b/samplecode/remoteattestation/Application/Makefile
index 57708fa..14f869a 100644
--- a/samplecode/remoteattestation/Application/Makefile
+++ b/samplecode/remoteattestation/Application/Makefile
@@ -17,7 +17,7 @@
######## SGX SDK Settings ########
SGX_SDK ?= /opt/sgxsdk
-SGX_MODE = HW
+SGX_MODE ?= HW
SGX_ARCH = x64
SGX_PRERELEASE=1
diff --git a/samplecode/remoteattestation/Application/enclave/Cargo.toml b/samplecode/remoteattestation/Application/enclave/Cargo.toml
index 6d15c8a..c71fdcf 100644
--- a/samplecode/remoteattestation/Application/enclave/Cargo.toml
+++ b/samplecode/remoteattestation/Application/enclave/Cargo.toml
@@ -19,6 +19,7 @@
sgx_tkey_exchange = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../../sgx_alloc" }
sgx_backtrace = { path = "../../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../../sgx_backtrace_sys" }
@@ -27,6 +28,7 @@
sgx_crypto_helper = { path = "../../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../../sgx_demangle" }
sgx_libc = { path = "../../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../../sgx_no_tstd" }
sgx_rand = { path = "../../../../sgx_rand" }
sgx_rand_derive = { path = "../../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../../sgx_serialize" }
diff --git a/samplecode/remoteattestation/Application/enclave/Xargo.toml b/samplecode/remoteattestation/Application/enclave/Xargo.toml
index 29ccfac..c578b6c 100644
--- a/samplecode/remoteattestation/Application/enclave/Xargo.toml
+++ b/samplecode/remoteattestation/Application/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../../sgx_signal"
stage = 7
diff --git a/samplecode/remoteattestation/Application/enclave/src/lib.rs b/samplecode/remoteattestation/Application/enclave/src/lib.rs
index 7c9f8b6..f9553bf 100644
--- a/samplecode/remoteattestation/Application/enclave/src/lib.rs
+++ b/samplecode/remoteattestation/Application/enclave/src/lib.rs
@@ -17,78 +17,71 @@
#![crate_name = "raenclave"]
#![crate_type = "staticlib"]
-
#![cfg_attr(not(target_env = "sgx"), no_std)]
#![cfg_attr(target_env = "sgx", feature(rustc_private))]
-
#![allow(unused_variables)]
-extern crate sgx_types;
extern crate sgx_trts;
+extern crate sgx_types;
#[cfg(not(target_env = "sgx"))]
#[macro_use]
extern crate sgx_tstd as std;
-extern crate sgx_tdh;
extern crate sgx_tcrypto;
+extern crate sgx_tdh;
extern crate sgx_tkey_exchange;
-use sgx_types::*;
-use sgx_trts::memeq::ConsttimeMemEq;
use sgx_tcrypto::*;
use sgx_tkey_exchange::*;
+use sgx_trts::memeq::ConsttimeMemEq;
+use sgx_types::*;
use std::slice;
use std::vec::Vec;
-const G_SP_PUB_KEY : sgx_ec256_public_t = sgx_ec256_public_t {
- gx : [0x72, 0x12, 0x8a, 0x7a, 0x17, 0x52, 0x6e, 0xbf,
- 0x85, 0xd0, 0x3a, 0x62, 0x37, 0x30, 0xae, 0xad,
- 0x3e, 0x3d, 0xaa, 0xee, 0x9c, 0x60, 0x73, 0x1d,
- 0xb0, 0x5b, 0xe8, 0x62, 0x1c, 0x4b, 0xeb, 0x38],
- gy : [0xd4, 0x81, 0x40, 0xd9, 0x50, 0xe2, 0x57, 0x7b,
- 0x26, 0xee, 0xb7, 0x41, 0xe7, 0xc6, 0x14, 0xe2,
- 0x24, 0xb7, 0xbd, 0xc9, 0x03, 0xf2, 0x9a, 0x28,
- 0xa8, 0x3c, 0xc8, 0x10, 0x11, 0x14, 0x5e, 0x06]
+const G_SP_PUB_KEY: sgx_ec256_public_t = sgx_ec256_public_t {
+ gx: [
+ 0x72, 0x12, 0x8a, 0x7a, 0x17, 0x52, 0x6e, 0xbf, 0x85, 0xd0, 0x3a, 0x62, 0x37, 0x30, 0xae,
+ 0xad, 0x3e, 0x3d, 0xaa, 0xee, 0x9c, 0x60, 0x73, 0x1d, 0xb0, 0x5b, 0xe8, 0x62, 0x1c, 0x4b,
+ 0xeb, 0x38,
+ ],
+ gy: [
+ 0xd4, 0x81, 0x40, 0xd9, 0x50, 0xe2, 0x57, 0x7b, 0x26, 0xee, 0xb7, 0x41, 0xe7, 0xc6, 0x14,
+ 0xe2, 0x24, 0xb7, 0xbd, 0xc9, 0x03, 0xf2, 0x9a, 0x28, 0xa8, 0x3c, 0xc8, 0x10, 0x11, 0x14,
+ 0x5e, 0x06,
+ ],
};
#[no_mangle]
-pub extern "C"
-fn enclave_init_ra(b_pse: i32, p_context: &mut sgx_ra_context_t) -> sgx_status_t {
- let mut ret: sgx_status_t = sgx_status_t::SGX_SUCCESS;
+pub extern "C" fn enclave_init_ra(b_pse: i32, p_context: &mut sgx_ra_context_t) -> sgx_status_t {
match rsgx_ra_init(&G_SP_PUB_KEY, b_pse) {
Ok(p) => {
*p_context = p;
- ret = sgx_status_t::SGX_SUCCESS;
- },
- Err(x) => {
- ret = x;
- return ret;
+ sgx_status_t::SGX_SUCCESS
}
+ Err(x) => x,
}
- ret
}
#[no_mangle]
-pub extern "C"
-fn enclave_ra_close(context: sgx_ra_context_t) -> sgx_status_t {
+pub extern "C" fn enclave_ra_close(context: sgx_ra_context_t) -> sgx_status_t {
match rsgx_ra_close(context) {
Ok(()) => sgx_status_t::SGX_SUCCESS,
- Err(x) => x
+ Err(x) => x,
}
}
#[no_mangle]
-pub extern "C"
-fn verify_att_result_mac(context : sgx_ra_context_t,
- message : * const u8,
- msg_size: size_t,
- mac : * const u8,
- mac_size: size_t) -> sgx_status_t {
-
- let ret:sgx_status_t;
- let mk_key:sgx_ec_key_128bit_t;
+pub extern "C" fn verify_att_result_mac(
+ context: sgx_ra_context_t,
+ message: *const u8,
+ msg_size: size_t,
+ mac: *const u8,
+ mac_size: size_t,
+) -> sgx_status_t {
+ let ret: sgx_status_t;
+ let mk_key: sgx_ec_key_128bit_t;
let mac_slice;
let message_slice;
- let mac_result:sgx_cmac_128bit_tag_t;
+ let mac_result: sgx_cmac_128bit_tag_t;
if mac_size != SGX_MAC_SIZE || msg_size > u32::max_value as usize {
ret = sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
@@ -100,20 +93,19 @@
message_slice = slice::from_raw_parts(message, msg_size as usize);
}
- if mac_slice.len() != SGX_MAC_SIZE as usize ||
- message_slice.len() != msg_size as usize {
+ if mac_slice.len() != SGX_MAC_SIZE as usize || message_slice.len() != msg_size as usize {
ret = sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
return ret;
}
match rsgx_ra_get_keys(context, sgx_ra_key_type_t::SGX_RA_KEY_MK) {
Ok(k) => mk_key = k,
- Err(x) => return x
+ Err(x) => return x,
}
match rsgx_rijndael128_cmac_slice(&mk_key, message_slice) {
Ok(tag) => mac_result = tag,
- Err(x) => return x
+ Err(x) => return x,
}
if mac_slice.consttime_memeq(&mac_result) == false {
@@ -124,25 +116,23 @@
}
#[no_mangle]
-pub extern "C"
-fn verify_secret_data(context : sgx_ra_context_t,
- p_secret: * const u8,
- sec_size: u32,
- gcm_mac : &[u8;16],
- max_vlen: u32,
- p_ret : & mut [u8;16]) -> sgx_status_t {
-
- let ret:sgx_status_t;
- let sk_key:sgx_ec_key_128bit_t;
+pub extern "C" fn verify_secret_data(
+ context: sgx_ra_context_t,
+ p_secret: *const u8,
+ sec_size: u32,
+ gcm_mac: &[u8; 16],
+ max_vlen: u32,
+ p_ret: &mut [u8; 16],
+) -> sgx_status_t {
+ let ret: sgx_status_t;
+ let sk_key: sgx_ec_key_128bit_t;
match rsgx_ra_get_keys(context, sgx_ra_key_type_t::SGX_RA_KEY_SK) {
Ok(key) => sk_key = key,
- Err(x) => return x
+ Err(x) => return x,
}
- let secret_slice = unsafe {
- slice::from_raw_parts(p_secret, sec_size as usize)
- };
+ let secret_slice = unsafe { slice::from_raw_parts(p_secret, sec_size as usize) };
if secret_slice.len() != sec_size as usize {
ret = sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
@@ -151,27 +141,22 @@
let mut decrypted_vec: Vec<u8> = vec![0; sec_size as usize];
let decrypted_slice = &mut decrypted_vec[..];
- let iv = [0;12];
- let aad:[u8;0] = [0;0];
+ let iv = [0; 12];
+ let aad: [u8; 0] = [0; 0];
- let ret = rsgx_rijndael128GCM_decrypt(&sk_key,
- &secret_slice,
- &iv,
- &aad,
- gcm_mac,
- decrypted_slice);
+ let ret =
+ rsgx_rijndael128GCM_decrypt(&sk_key, &secret_slice, &iv, &aad, gcm_mac, decrypted_slice);
match ret {
Ok(()) => {
if decrypted_slice[0] == 0 && decrypted_slice[1] != 1 {
- return sgx_status_t::SGX_ERROR_INVALID_SIGNATURE;
+ sgx_status_t::SGX_ERROR_INVALID_SIGNATURE
+ } else {
+ sgx_status_t::SGX_SUCCESS
}
- else {
- return sgx_status_t::SGX_SUCCESS;
- }
- },
+ }
Err(_) => {
- return sgx_status_t::SGX_ERROR_UNEXPECTED;
+ sgx_status_t::SGX_ERROR_UNEXPECTED
}
}
}
diff --git a/samplecode/remoteattestation/Application/enclave/x86_64-unknown-linux-sgx.json b/samplecode/remoteattestation/Application/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/remoteattestation/Application/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/remoteattestation/Application/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/remoteattestation/GoogleMessages/Messages.pb.cc b/samplecode/remoteattestation/GoogleMessages/Messages.pb.cc
index c7ecd42..147dc4f 100644
--- a/samplecode/remoteattestation/GoogleMessages/Messages.pb.cc
+++ b/samplecode/remoteattestation/GoogleMessages/Messages.pb.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -38,13 +39,11 @@
const ::google::protobuf::Descriptor* AttestationMessage_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
AttestationMessage_reflection_ = NULL;
-const ::google::protobuf::Descriptor* SecretMessage_descriptor_ = NULL;
-const ::google::protobuf::internal::GeneratedMessageReflection*
- SecretMessage_reflection_ = NULL;
} // namespace
+void protobuf_AssignDesc_Messages_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_Messages_2eproto() {
protobuf_AddDesc_Messages_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -57,16 +56,16 @@
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InitialMessage, size_),
};
InitialMessage_reflection_ =
- new ::google::protobuf::internal::GeneratedMessageReflection(
+ ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
InitialMessage_descriptor_,
InitialMessage::default_instance_,
InitialMessage_offsets_,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InitialMessage, _has_bits_[0]),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InitialMessage, _unknown_fields_),
-1,
- ::google::protobuf::DescriptorPool::generated_pool(),
- ::google::protobuf::MessageFactory::generated_factory(),
- sizeof(InitialMessage));
+ -1,
+ sizeof(InitialMessage),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InitialMessage, _internal_metadata_),
+ -1);
MessageMsg0_descriptor_ = file->message_type(1);
static const int MessageMsg0_offsets_[3] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMsg0, type_),
@@ -74,16 +73,16 @@
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMsg0, status_),
};
MessageMsg0_reflection_ =
- new ::google::protobuf::internal::GeneratedMessageReflection(
+ ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
MessageMsg0_descriptor_,
MessageMsg0::default_instance_,
MessageMsg0_offsets_,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMsg0, _has_bits_[0]),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMsg0, _unknown_fields_),
-1,
- ::google::protobuf::DescriptorPool::generated_pool(),
- ::google::protobuf::MessageFactory::generated_factory(),
- sizeof(MessageMsg0));
+ -1,
+ sizeof(MessageMsg0),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMsg0, _internal_metadata_),
+ -1);
MessageMSG1_descriptor_ = file->message_type(2);
static const int MessageMSG1_offsets_[4] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, type_),
@@ -92,16 +91,16 @@
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, gid_),
};
MessageMSG1_reflection_ =
- new ::google::protobuf::internal::GeneratedMessageReflection(
+ ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
MessageMSG1_descriptor_,
MessageMSG1::default_instance_,
MessageMSG1_offsets_,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, _has_bits_[0]),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, _unknown_fields_),
-1,
- ::google::protobuf::DescriptorPool::generated_pool(),
- ::google::protobuf::MessageFactory::generated_factory(),
- sizeof(MessageMSG1));
+ -1,
+ sizeof(MessageMSG1),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG1, _internal_metadata_),
+ -1);
MessageMSG2_descriptor_ = file->message_type(3);
static const int MessageMSG2_offsets_[12] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, type_),
@@ -118,16 +117,16 @@
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, sigrl_),
};
MessageMSG2_reflection_ =
- new ::google::protobuf::internal::GeneratedMessageReflection(
+ ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
MessageMSG2_descriptor_,
MessageMSG2::default_instance_,
MessageMSG2_offsets_,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, _has_bits_[0]),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, _unknown_fields_),
-1,
- ::google::protobuf::DescriptorPool::generated_pool(),
- ::google::protobuf::MessageFactory::generated_factory(),
- sizeof(MessageMSG2));
+ -1,
+ sizeof(MessageMSG2),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG2, _internal_metadata_),
+ -1);
MessageMSG3_descriptor_ = file->message_type(4);
static const int MessageMSG3_offsets_[7] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, type_),
@@ -139,16 +138,16 @@
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, quote_),
};
MessageMSG3_reflection_ =
- new ::google::protobuf::internal::GeneratedMessageReflection(
+ ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
MessageMSG3_descriptor_,
MessageMSG3::default_instance_,
MessageMSG3_offsets_,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, _has_bits_[0]),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, _unknown_fields_),
-1,
- ::google::protobuf::DescriptorPool::generated_pool(),
- ::google::protobuf::MessageFactory::generated_factory(),
- sizeof(MessageMSG3));
+ -1,
+ sizeof(MessageMSG3),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageMSG3, _internal_metadata_),
+ -1);
AttestationMessage_descriptor_ = file->message_type(5);
static const int AttestationMessage_offsets_[16] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, type_),
@@ -169,40 +168,16 @@
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, payload_),
};
AttestationMessage_reflection_ =
- new ::google::protobuf::internal::GeneratedMessageReflection(
+ ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
AttestationMessage_descriptor_,
AttestationMessage::default_instance_,
AttestationMessage_offsets_,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, _has_bits_[0]),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, _unknown_fields_),
-1,
- ::google::protobuf::DescriptorPool::generated_pool(),
- ::google::protobuf::MessageFactory::generated_factory(),
- sizeof(AttestationMessage));
- SecretMessage_descriptor_ = file->message_type(6);
- static const int SecretMessage_offsets_[10] = {
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SecretMessage, type_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SecretMessage, size_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SecretMessage, encryped_pkey_size_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SecretMessage, encryped_x509_size_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SecretMessage, encrypted_content_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SecretMessage, mac_smk_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SecretMessage, encrypted_pkey_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SecretMessage, encrypted_pkey_mac_smk_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SecretMessage, encrypted_x509_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SecretMessage, encrypted_x509_mac_smk_),
- };
- SecretMessage_reflection_ =
- new ::google::protobuf::internal::GeneratedMessageReflection(
- SecretMessage_descriptor_,
- SecretMessage::default_instance_,
- SecretMessage_offsets_,
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SecretMessage, _has_bits_[0]),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SecretMessage, _unknown_fields_),
-1,
- ::google::protobuf::DescriptorPool::generated_pool(),
- ::google::protobuf::MessageFactory::generated_factory(),
- sizeof(SecretMessage));
+ sizeof(AttestationMessage),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AttestationMessage, _internal_metadata_),
+ -1);
}
namespace {
@@ -213,22 +188,21 @@
&protobuf_AssignDesc_Messages_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
- InitialMessage_descriptor_, &InitialMessage::default_instance());
+ InitialMessage_descriptor_, &InitialMessage::default_instance());
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
- MessageMsg0_descriptor_, &MessageMsg0::default_instance());
+ MessageMsg0_descriptor_, &MessageMsg0::default_instance());
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
- MessageMSG1_descriptor_, &MessageMSG1::default_instance());
+ MessageMSG1_descriptor_, &MessageMSG1::default_instance());
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
- MessageMSG2_descriptor_, &MessageMSG2::default_instance());
+ MessageMSG2_descriptor_, &MessageMSG2::default_instance());
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
- MessageMSG3_descriptor_, &MessageMSG3::default_instance());
+ MessageMSG3_descriptor_, &MessageMSG3::default_instance());
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
- AttestationMessage_descriptor_, &AttestationMessage::default_instance());
- ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
- SecretMessage_descriptor_, &SecretMessage::default_instance());
+ AttestationMessage_descriptor_, &AttestationMessage::default_instance());
}
} // namespace
@@ -246,10 +220,9 @@
delete MessageMSG3_reflection_;
delete AttestationMessage::default_instance_;
delete AttestationMessage_reflection_;
- delete SecretMessage::default_instance_;
- delete SecretMessage_reflection_;
}
+void protobuf_AddDesc_Messages_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_Messages_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -283,14 +256,7 @@
"\030\n \003(\rB\002\020\001\022\030\n\014ec_sign256_y\030\013 \003(\rB\002\020\001\022\023\n\007"
"mac_smk\030\014 \003(\rB\002\020\001\022\023\n\013result_size\030\r \001(\r\022\024"
"\n\010reserved\030\016 \003(\rB\002\020\001\022\027\n\013payload_tag\030\017 \003("
- "\rB\002\020\001\022\023\n\007payload\030\020 \003(\rB\002\020\001\"\227\002\n\rSecretMes"
- "sage\022\014\n\004type\030\001 \002(\r\022\014\n\004size\030\002 \002(\r\022\032\n\022encr"
- "yped_pkey_size\030\003 \001(\r\022\032\n\022encryped_x509_si"
- "ze\030\004 \001(\r\022\035\n\021encrypted_content\030\005 \003(\rB\002\020\001\022"
- "\023\n\007mac_smk\030\006 \003(\rB\002\020\001\022\032\n\016encrypted_pkey\030\007"
- " \003(\rB\002\020\001\022\"\n\026encrypted_pkey_mac_smk\030\010 \003(\r"
- "B\002\020\001\022\032\n\016encrypted_x509\030\t \003(\rB\002\020\001\022\"\n\026encr"
- "ypted_x509_mac_smk\030\n \003(\rB\002\020\001", 1348);
+ "\rB\002\020\001\022\023\n\007payload\030\020 \003(\rB\002\020\001", 1066);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"Messages.proto", &protobuf_RegisterTypes);
InitialMessage::default_instance_ = new InitialMessage();
@@ -299,14 +265,12 @@
MessageMSG2::default_instance_ = new MessageMSG2();
MessageMSG3::default_instance_ = new MessageMSG3();
AttestationMessage::default_instance_ = new AttestationMessage();
- SecretMessage::default_instance_ = new SecretMessage();
InitialMessage::default_instance_->InitAsDefaultInstance();
MessageMsg0::default_instance_->InitAsDefaultInstance();
MessageMSG1::default_instance_->InitAsDefaultInstance();
MessageMSG2::default_instance_->InitAsDefaultInstance();
MessageMSG3::default_instance_->InitAsDefaultInstance();
AttestationMessage::default_instance_->InitAsDefaultInstance();
- SecretMessage::default_instance_->InitAsDefaultInstance();
::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_Messages_2eproto);
}
@@ -319,13 +283,13 @@
// ===================================================================
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int InitialMessage::kTypeFieldNumber;
const int InitialMessage::kSizeFieldNumber;
-#endif // !_MSC_VER
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
InitialMessage::InitialMessage()
- : ::google::protobuf::Message() {
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
SharedCtor();
// @@protoc_insertion_point(constructor:Messages.InitialMessage)
}
@@ -334,7 +298,8 @@
}
InitialMessage::InitialMessage(const InitialMessage& from)
- : ::google::protobuf::Message() {
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL) {
SharedCtor();
MergeFrom(from);
// @@protoc_insertion_point(copy_constructor:Messages.InitialMessage)
@@ -374,33 +339,46 @@
InitialMessage* InitialMessage::default_instance_ = NULL;
-InitialMessage* InitialMessage::New() const {
- return new InitialMessage;
+InitialMessage* InitialMessage::New(::google::protobuf::Arena* arena) const {
+ InitialMessage* n = new InitialMessage;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
}
void InitialMessage::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
- &reinterpret_cast<InitialMessage*>(16)->f) - \
- reinterpret_cast<char*>(16))
+// @@protoc_insertion_point(message_clear_start:Messages.InitialMessage)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(InitialMessage, f) \
+ _Pragma("clang diagnostic pop")
+#else
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+ &reinterpret_cast<InitialMessage*>(16)->f)
+#endif
-#define ZR_(first, last) do { \
- size_t f = OFFSET_OF_FIELD_(first); \
- size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \
- ::memset(&first, 0, n); \
- } while (0)
+#define ZR_(first, last) do {\
+ ::memset(&first, 0,\
+ ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
ZR_(type_, size_);
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
#undef ZR_
::memset(_has_bits_, 0, sizeof(_has_bits_));
- mutable_unknown_fields()->Clear();
+ if (_internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->Clear();
+ }
}
bool InitialMessage::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:Messages.InitialMessage)
for (;;) {
@@ -472,15 +450,15 @@
::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->size(), output);
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
// @@protoc_insertion_point(serialize_end:Messages.InitialMessage)
}
-::google::protobuf::uint8* InitialMessage::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* InitialMessage::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:Messages.InitialMessage)
// required uint32 type = 1;
if (has_type()) {
@@ -492,7 +470,7 @@
target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->size(), target);
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
@@ -501,25 +479,23 @@
}
int InitialMessage::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:Messages.InitialMessage)
int total_size = 0;
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- // required uint32 type = 1;
- if (has_type()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->type());
- }
-
- // optional uint32 size = 2;
- if (has_size()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->size());
- }
-
+ // required uint32 type = 1;
+ if (has_type()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->type());
}
- if (!unknown_fields().empty()) {
+ // optional uint32 size = 2;
+ if (has_size()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->size());
+ }
+
+ if (_internal_metadata_.have_unknown_fields()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
unknown_fields());
@@ -531,19 +507,27 @@
}
void InitialMessage::MergeFrom(const ::google::protobuf::Message& from) {
- GOOGLE_CHECK_NE(&from, this);
- const InitialMessage* source =
- ::google::protobuf::internal::dynamic_cast_if_available<const InitialMessage*>(
- &from);
+// @@protoc_insertion_point(generalized_merge_from_start:Messages.InitialMessage)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
+ const InitialMessage* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const InitialMessage>(
+ &from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:Messages.InitialMessage)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:Messages.InitialMessage)
MergeFrom(*source);
}
}
void InitialMessage::MergeFrom(const InitialMessage& from) {
- GOOGLE_CHECK_NE(&from, this);
+// @@protoc_insertion_point(class_specific_merge_from_start:Messages.InitialMessage)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_type()) {
set_type(from.type());
@@ -552,16 +536,20 @@
set_size(from.size());
}
}
- mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ if (from._internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ }
}
void InitialMessage::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:Messages.InitialMessage)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void InitialMessage::CopyFrom(const InitialMessage& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:Messages.InitialMessage)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -574,13 +562,15 @@
}
void InitialMessage::Swap(InitialMessage* other) {
- if (other != this) {
- std::swap(type_, other->type_);
- std::swap(size_, other->size_);
- std::swap(_has_bits_[0], other->_has_bits_[0]);
- _unknown_fields_.Swap(&other->_unknown_fields_);
- std::swap(_cached_size_, other->_cached_size_);
- }
+ if (other == this) return;
+ InternalSwap(other);
+}
+void InitialMessage::InternalSwap(InitialMessage* other) {
+ std::swap(type_, other->type_);
+ std::swap(size_, other->size_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ std::swap(_cached_size_, other->_cached_size_);
}
::google::protobuf::Metadata InitialMessage::GetMetadata() const {
@@ -591,17 +581,69 @@
return metadata;
}
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// InitialMessage
+
+// required uint32 type = 1;
+bool InitialMessage::has_type() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+void InitialMessage::set_has_type() {
+ _has_bits_[0] |= 0x00000001u;
+}
+void InitialMessage::clear_has_type() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+void InitialMessage::clear_type() {
+ type_ = 0u;
+ clear_has_type();
+}
+ ::google::protobuf::uint32 InitialMessage::type() const {
+ // @@protoc_insertion_point(field_get:Messages.InitialMessage.type)
+ return type_;
+}
+ void InitialMessage::set_type(::google::protobuf::uint32 value) {
+ set_has_type();
+ type_ = value;
+ // @@protoc_insertion_point(field_set:Messages.InitialMessage.type)
+}
+
+// optional uint32 size = 2;
+bool InitialMessage::has_size() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+void InitialMessage::set_has_size() {
+ _has_bits_[0] |= 0x00000002u;
+}
+void InitialMessage::clear_has_size() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+void InitialMessage::clear_size() {
+ size_ = 0u;
+ clear_has_size();
+}
+ ::google::protobuf::uint32 InitialMessage::size() const {
+ // @@protoc_insertion_point(field_get:Messages.InitialMessage.size)
+ return size_;
+}
+ void InitialMessage::set_size(::google::protobuf::uint32 value) {
+ set_has_size();
+ size_ = value;
+ // @@protoc_insertion_point(field_set:Messages.InitialMessage.size)
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
// ===================================================================
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int MessageMsg0::kTypeFieldNumber;
const int MessageMsg0::kEpidFieldNumber;
const int MessageMsg0::kStatusFieldNumber;
-#endif // !_MSC_VER
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
MessageMsg0::MessageMsg0()
- : ::google::protobuf::Message() {
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
SharedCtor();
// @@protoc_insertion_point(constructor:Messages.MessageMsg0)
}
@@ -610,7 +652,8 @@
}
MessageMsg0::MessageMsg0(const MessageMsg0& from)
- : ::google::protobuf::Message() {
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL) {
SharedCtor();
MergeFrom(from);
// @@protoc_insertion_point(copy_constructor:Messages.MessageMsg0)
@@ -651,33 +694,46 @@
MessageMsg0* MessageMsg0::default_instance_ = NULL;
-MessageMsg0* MessageMsg0::New() const {
- return new MessageMsg0;
+MessageMsg0* MessageMsg0::New(::google::protobuf::Arena* arena) const {
+ MessageMsg0* n = new MessageMsg0;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
}
void MessageMsg0::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
- &reinterpret_cast<MessageMsg0*>(16)->f) - \
- reinterpret_cast<char*>(16))
+// @@protoc_insertion_point(message_clear_start:Messages.MessageMsg0)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(MessageMsg0, f) \
+ _Pragma("clang diagnostic pop")
+#else
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+ &reinterpret_cast<MessageMsg0*>(16)->f)
+#endif
-#define ZR_(first, last) do { \
- size_t f = OFFSET_OF_FIELD_(first); \
- size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \
- ::memset(&first, 0, n); \
- } while (0)
+#define ZR_(first, last) do {\
+ ::memset(&first, 0,\
+ ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
ZR_(type_, status_);
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
#undef ZR_
::memset(_has_bits_, 0, sizeof(_has_bits_));
- mutable_unknown_fields()->Clear();
+ if (_internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->Clear();
+ }
}
bool MessageMsg0::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:Messages.MessageMsg0)
for (;;) {
@@ -769,15 +825,15 @@
::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->status(), output);
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
// @@protoc_insertion_point(serialize_end:Messages.MessageMsg0)
}
-::google::protobuf::uint8* MessageMsg0::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* MessageMsg0::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:Messages.MessageMsg0)
// required uint32 type = 1;
if (has_type()) {
@@ -794,7 +850,7 @@
target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->status(), target);
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
@@ -802,33 +858,52 @@
return target;
}
-int MessageMsg0::ByteSize() const {
+int MessageMsg0::RequiredFieldsByteSizeFallback() const {
+// @@protoc_insertion_point(required_fields_byte_size_fallback_start:Messages.MessageMsg0)
int total_size = 0;
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (has_type()) {
// required uint32 type = 1;
- if (has_type()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->type());
- }
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->type());
+ }
+
+ if (has_epid()) {
+ // required uint32 epid = 2;
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->epid());
+ }
+
+ return total_size;
+}
+int MessageMsg0::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:Messages.MessageMsg0)
+ int total_size = 0;
+
+ if (((_has_bits_[0] & 0x00000003) ^ 0x00000003) == 0) { // All required fields are present.
+ // required uint32 type = 1;
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->type());
// required uint32 epid = 2;
- if (has_epid()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->epid());
- }
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->epid());
- // optional uint32 status = 3;
- if (has_status()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->status());
- }
-
+ } else {
+ total_size += RequiredFieldsByteSizeFallback();
}
- if (!unknown_fields().empty()) {
+ // optional uint32 status = 3;
+ if (has_status()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->status());
+ }
+
+ if (_internal_metadata_.have_unknown_fields()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
unknown_fields());
@@ -840,19 +915,27 @@
}
void MessageMsg0::MergeFrom(const ::google::protobuf::Message& from) {
- GOOGLE_CHECK_NE(&from, this);
- const MessageMsg0* source =
- ::google::protobuf::internal::dynamic_cast_if_available<const MessageMsg0*>(
- &from);
+// @@protoc_insertion_point(generalized_merge_from_start:Messages.MessageMsg0)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
+ const MessageMsg0* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const MessageMsg0>(
+ &from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:Messages.MessageMsg0)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:Messages.MessageMsg0)
MergeFrom(*source);
}
}
void MessageMsg0::MergeFrom(const MessageMsg0& from) {
- GOOGLE_CHECK_NE(&from, this);
+// @@protoc_insertion_point(class_specific_merge_from_start:Messages.MessageMsg0)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_type()) {
set_type(from.type());
@@ -864,16 +947,20 @@
set_status(from.status());
}
}
- mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ if (from._internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ }
}
void MessageMsg0::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:Messages.MessageMsg0)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void MessageMsg0::CopyFrom(const MessageMsg0& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:Messages.MessageMsg0)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -886,14 +973,16 @@
}
void MessageMsg0::Swap(MessageMsg0* other) {
- if (other != this) {
- std::swap(type_, other->type_);
- std::swap(epid_, other->epid_);
- std::swap(status_, other->status_);
- std::swap(_has_bits_[0], other->_has_bits_[0]);
- _unknown_fields_.Swap(&other->_unknown_fields_);
- std::swap(_cached_size_, other->_cached_size_);
- }
+ if (other == this) return;
+ InternalSwap(other);
+}
+void MessageMsg0::InternalSwap(MessageMsg0* other) {
+ std::swap(type_, other->type_);
+ std::swap(epid_, other->epid_);
+ std::swap(status_, other->status_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ std::swap(_cached_size_, other->_cached_size_);
}
::google::protobuf::Metadata MessageMsg0::GetMetadata() const {
@@ -904,18 +993,94 @@
return metadata;
}
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// MessageMsg0
+
+// required uint32 type = 1;
+bool MessageMsg0::has_type() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+void MessageMsg0::set_has_type() {
+ _has_bits_[0] |= 0x00000001u;
+}
+void MessageMsg0::clear_has_type() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+void MessageMsg0::clear_type() {
+ type_ = 0u;
+ clear_has_type();
+}
+ ::google::protobuf::uint32 MessageMsg0::type() const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMsg0.type)
+ return type_;
+}
+ void MessageMsg0::set_type(::google::protobuf::uint32 value) {
+ set_has_type();
+ type_ = value;
+ // @@protoc_insertion_point(field_set:Messages.MessageMsg0.type)
+}
+
+// required uint32 epid = 2;
+bool MessageMsg0::has_epid() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+void MessageMsg0::set_has_epid() {
+ _has_bits_[0] |= 0x00000002u;
+}
+void MessageMsg0::clear_has_epid() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+void MessageMsg0::clear_epid() {
+ epid_ = 0u;
+ clear_has_epid();
+}
+ ::google::protobuf::uint32 MessageMsg0::epid() const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMsg0.epid)
+ return epid_;
+}
+ void MessageMsg0::set_epid(::google::protobuf::uint32 value) {
+ set_has_epid();
+ epid_ = value;
+ // @@protoc_insertion_point(field_set:Messages.MessageMsg0.epid)
+}
+
+// optional uint32 status = 3;
+bool MessageMsg0::has_status() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+void MessageMsg0::set_has_status() {
+ _has_bits_[0] |= 0x00000004u;
+}
+void MessageMsg0::clear_has_status() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+void MessageMsg0::clear_status() {
+ status_ = 0u;
+ clear_has_status();
+}
+ ::google::protobuf::uint32 MessageMsg0::status() const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMsg0.status)
+ return status_;
+}
+ void MessageMsg0::set_status(::google::protobuf::uint32 value) {
+ set_has_status();
+ status_ = value;
+ // @@protoc_insertion_point(field_set:Messages.MessageMsg0.status)
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
// ===================================================================
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int MessageMSG1::kTypeFieldNumber;
const int MessageMSG1::kGaXFieldNumber;
const int MessageMSG1::kGaYFieldNumber;
const int MessageMSG1::kGIDFieldNumber;
-#endif // !_MSC_VER
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
MessageMSG1::MessageMSG1()
- : ::google::protobuf::Message() {
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
SharedCtor();
// @@protoc_insertion_point(constructor:Messages.MessageMSG1)
}
@@ -924,7 +1089,8 @@
}
MessageMSG1::MessageMSG1(const MessageMSG1& from)
- : ::google::protobuf::Message() {
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL) {
SharedCtor();
MergeFrom(from);
// @@protoc_insertion_point(copy_constructor:Messages.MessageMSG1)
@@ -963,22 +1129,29 @@
MessageMSG1* MessageMSG1::default_instance_ = NULL;
-MessageMSG1* MessageMSG1::New() const {
- return new MessageMSG1;
+MessageMSG1* MessageMSG1::New(::google::protobuf::Arena* arena) const {
+ MessageMSG1* n = new MessageMSG1;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
}
void MessageMSG1::Clear() {
+// @@protoc_insertion_point(message_clear_start:Messages.MessageMSG1)
type_ = 0u;
gax_.Clear();
gay_.Clear();
gid_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
- mutable_unknown_fields()->Clear();
+ if (_internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->Clear();
+ }
}
bool MessageMSG1::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:Messages.MessageMSG1)
for (;;) {
@@ -1114,15 +1287,15 @@
this->gid(i), output);
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
// @@protoc_insertion_point(serialize_end:Messages.MessageMSG1)
}
-::google::protobuf::uint8* MessageMSG1::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* MessageMSG1::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:Messages.MessageMSG1)
// required uint32 type = 1;
if (has_type()) {
@@ -1171,7 +1344,7 @@
WriteUInt32NoTagToArray(this->gid(i), target);
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
@@ -1180,16 +1353,14 @@
}
int MessageMSG1::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:Messages.MessageMSG1)
int total_size = 0;
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- // required uint32 type = 1;
- if (has_type()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->type());
- }
-
+ // required uint32 type = 1;
+ if (has_type()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->type());
}
// repeated uint32 GaX = 2 [packed = true];
{
@@ -1242,7 +1413,7 @@
total_size += data_size;
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
unknown_fields());
@@ -1254,19 +1425,27 @@
}
void MessageMSG1::MergeFrom(const ::google::protobuf::Message& from) {
- GOOGLE_CHECK_NE(&from, this);
- const MessageMSG1* source =
- ::google::protobuf::internal::dynamic_cast_if_available<const MessageMSG1*>(
- &from);
+// @@protoc_insertion_point(generalized_merge_from_start:Messages.MessageMSG1)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
+ const MessageMSG1* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const MessageMSG1>(
+ &from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:Messages.MessageMSG1)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:Messages.MessageMSG1)
MergeFrom(*source);
}
}
void MessageMSG1::MergeFrom(const MessageMSG1& from) {
- GOOGLE_CHECK_NE(&from, this);
+// @@protoc_insertion_point(class_specific_merge_from_start:Messages.MessageMSG1)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
gax_.MergeFrom(from.gax_);
gay_.MergeFrom(from.gay_);
gid_.MergeFrom(from.gid_);
@@ -1275,16 +1454,20 @@
set_type(from.type());
}
}
- mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ if (from._internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ }
}
void MessageMSG1::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:Messages.MessageMSG1)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void MessageMSG1::CopyFrom(const MessageMSG1& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:Messages.MessageMSG1)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -1297,15 +1480,17 @@
}
void MessageMSG1::Swap(MessageMSG1* other) {
- if (other != this) {
- std::swap(type_, other->type_);
- gax_.Swap(&other->gax_);
- gay_.Swap(&other->gay_);
- gid_.Swap(&other->gid_);
- std::swap(_has_bits_[0], other->_has_bits_[0]);
- _unknown_fields_.Swap(&other->_unknown_fields_);
- std::swap(_cached_size_, other->_cached_size_);
- }
+ if (other == this) return;
+ InternalSwap(other);
+}
+void MessageMSG1::InternalSwap(MessageMSG1* other) {
+ std::swap(type_, other->type_);
+ gax_.UnsafeArenaSwap(&other->gax_);
+ gay_.UnsafeArenaSwap(&other->gay_);
+ gid_.UnsafeArenaSwap(&other->gid_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ std::swap(_cached_size_, other->_cached_size_);
}
::google::protobuf::Metadata MessageMSG1::GetMetadata() const {
@@ -1316,10 +1501,128 @@
return metadata;
}
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// MessageMSG1
+
+// required uint32 type = 1;
+bool MessageMSG1::has_type() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+void MessageMSG1::set_has_type() {
+ _has_bits_[0] |= 0x00000001u;
+}
+void MessageMSG1::clear_has_type() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+void MessageMSG1::clear_type() {
+ type_ = 0u;
+ clear_has_type();
+}
+ ::google::protobuf::uint32 MessageMSG1::type() const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG1.type)
+ return type_;
+}
+ void MessageMSG1::set_type(::google::protobuf::uint32 value) {
+ set_has_type();
+ type_ = value;
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG1.type)
+}
+
+// repeated uint32 GaX = 2 [packed = true];
+int MessageMSG1::gax_size() const {
+ return gax_.size();
+}
+void MessageMSG1::clear_gax() {
+ gax_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG1::gax(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG1.GaX)
+ return gax_.Get(index);
+}
+ void MessageMSG1::set_gax(int index, ::google::protobuf::uint32 value) {
+ gax_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG1.GaX)
+}
+ void MessageMSG1::add_gax(::google::protobuf::uint32 value) {
+ gax_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG1.GaX)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG1::gax() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG1.GaX)
+ return gax_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG1::mutable_gax() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG1.GaX)
+ return &gax_;
+}
+
+// repeated uint32 GaY = 3 [packed = true];
+int MessageMSG1::gay_size() const {
+ return gay_.size();
+}
+void MessageMSG1::clear_gay() {
+ gay_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG1::gay(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG1.GaY)
+ return gay_.Get(index);
+}
+ void MessageMSG1::set_gay(int index, ::google::protobuf::uint32 value) {
+ gay_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG1.GaY)
+}
+ void MessageMSG1::add_gay(::google::protobuf::uint32 value) {
+ gay_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG1.GaY)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG1::gay() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG1.GaY)
+ return gay_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG1::mutable_gay() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG1.GaY)
+ return &gay_;
+}
+
+// repeated uint32 GID = 4 [packed = true];
+int MessageMSG1::gid_size() const {
+ return gid_.size();
+}
+void MessageMSG1::clear_gid() {
+ gid_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG1::gid(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG1.GID)
+ return gid_.Get(index);
+}
+ void MessageMSG1::set_gid(int index, ::google::protobuf::uint32 value) {
+ gid_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG1.GID)
+}
+ void MessageMSG1::add_gid(::google::protobuf::uint32 value) {
+ gid_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG1.GID)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG1::gid() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG1.GID)
+ return gid_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG1::mutable_gid() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG1.GID)
+ return &gid_;
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
// ===================================================================
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int MessageMSG2::kTypeFieldNumber;
const int MessageMSG2::kSizeFieldNumber;
const int MessageMSG2::kPublicKeyGxFieldNumber;
@@ -1332,10 +1635,10 @@
const int MessageMSG2::kSmacFieldNumber;
const int MessageMSG2::kSizeSigrlFieldNumber;
const int MessageMSG2::kSigrlFieldNumber;
-#endif // !_MSC_VER
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
MessageMSG2::MessageMSG2()
- : ::google::protobuf::Message() {
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
SharedCtor();
// @@protoc_insertion_point(constructor:Messages.MessageMSG2)
}
@@ -1344,7 +1647,8 @@
}
MessageMSG2::MessageMSG2(const MessageMSG2& from)
- : ::google::protobuf::Message() {
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL) {
SharedCtor();
MergeFrom(from);
// @@protoc_insertion_point(copy_constructor:Messages.MessageMSG2)
@@ -1387,26 +1691,37 @@
MessageMSG2* MessageMSG2::default_instance_ = NULL;
-MessageMSG2* MessageMSG2::New() const {
- return new MessageMSG2;
+MessageMSG2* MessageMSG2::New(::google::protobuf::Arena* arena) const {
+ MessageMSG2* n = new MessageMSG2;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
}
void MessageMSG2::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
- &reinterpret_cast<MessageMSG2*>(16)->f) - \
- reinterpret_cast<char*>(16))
+// @@protoc_insertion_point(message_clear_start:Messages.MessageMSG2)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(MessageMSG2, f) \
+ _Pragma("clang diagnostic pop")
+#else
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+ &reinterpret_cast<MessageMSG2*>(16)->f)
+#endif
-#define ZR_(first, last) do { \
- size_t f = OFFSET_OF_FIELD_(first); \
- size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \
- ::memset(&first, 0, n); \
- } while (0)
+#define ZR_(first, last) do {\
+ ::memset(&first, 0,\
+ ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
ZR_(type_, size_);
ZR_(quote_type_, cmac_kdf_id_);
size_sigrl_ = 0u;
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
#undef ZR_
public_key_gx_.Clear();
@@ -1417,12 +1732,14 @@
smac_.Clear();
sigrl_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
- mutable_unknown_fields()->Clear();
+ if (_internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->Clear();
+ }
}
bool MessageMSG2::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:Messages.MessageMSG2)
for (;;) {
@@ -1750,15 +2067,15 @@
this->sigrl(i), output);
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
// @@protoc_insertion_point(serialize_end:Messages.MessageMSG2)
}
-::google::protobuf::uint8* MessageMSG2::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* MessageMSG2::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:Messages.MessageMSG2)
// required uint32 type = 1;
if (has_type()) {
@@ -1883,7 +2200,7 @@
WriteUInt32NoTagToArray(this->sigrl(i), target);
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
@@ -1892,16 +2209,16 @@
}
int MessageMSG2::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:Messages.MessageMSG2)
int total_size = 0;
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- // required uint32 type = 1;
- if (has_type()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->type());
- }
-
+ // required uint32 type = 1;
+ if (has_type()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->type());
+ }
+ if (_has_bits_[1 / 32] & 82u) {
// optional uint32 size = 2;
if (has_size()) {
total_size += 1 +
@@ -1924,15 +2241,13 @@
}
}
- if (_has_bits_[10 / 32] & (0xffu << (10 % 32))) {
- // optional uint32 size_sigrl = 11;
- if (has_size_sigrl()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->size_sigrl());
- }
-
+ // optional uint32 size_sigrl = 11;
+ if (has_size_sigrl()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->size_sigrl());
}
+
// repeated uint32 public_key_gx = 3 [packed = true];
{
int data_size = 0;
@@ -2052,7 +2367,7 @@
total_size += data_size;
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
unknown_fields());
@@ -2064,19 +2379,27 @@
}
void MessageMSG2::MergeFrom(const ::google::protobuf::Message& from) {
- GOOGLE_CHECK_NE(&from, this);
- const MessageMSG2* source =
- ::google::protobuf::internal::dynamic_cast_if_available<const MessageMSG2*>(
- &from);
+// @@protoc_insertion_point(generalized_merge_from_start:Messages.MessageMSG2)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
+ const MessageMSG2* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const MessageMSG2>(
+ &from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:Messages.MessageMSG2)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:Messages.MessageMSG2)
MergeFrom(*source);
}
}
void MessageMSG2::MergeFrom(const MessageMSG2& from) {
- GOOGLE_CHECK_NE(&from, this);
+// @@protoc_insertion_point(class_specific_merge_from_start:Messages.MessageMSG2)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
public_key_gx_.MergeFrom(from.public_key_gx_);
public_key_gy_.MergeFrom(from.public_key_gy_);
spid_.MergeFrom(from.spid_);
@@ -2103,16 +2426,20 @@
set_size_sigrl(from.size_sigrl());
}
}
- mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ if (from._internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ }
}
void MessageMSG2::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:Messages.MessageMSG2)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void MessageMSG2::CopyFrom(const MessageMSG2& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:Messages.MessageMSG2)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -2125,23 +2452,25 @@
}
void MessageMSG2::Swap(MessageMSG2* other) {
- if (other != this) {
- std::swap(type_, other->type_);
- std::swap(size_, other->size_);
- public_key_gx_.Swap(&other->public_key_gx_);
- public_key_gy_.Swap(&other->public_key_gy_);
- std::swap(quote_type_, other->quote_type_);
- spid_.Swap(&other->spid_);
- std::swap(cmac_kdf_id_, other->cmac_kdf_id_);
- signature_x_.Swap(&other->signature_x_);
- signature_y_.Swap(&other->signature_y_);
- smac_.Swap(&other->smac_);
- std::swap(size_sigrl_, other->size_sigrl_);
- sigrl_.Swap(&other->sigrl_);
- std::swap(_has_bits_[0], other->_has_bits_[0]);
- _unknown_fields_.Swap(&other->_unknown_fields_);
- std::swap(_cached_size_, other->_cached_size_);
- }
+ if (other == this) return;
+ InternalSwap(other);
+}
+void MessageMSG2::InternalSwap(MessageMSG2* other) {
+ std::swap(type_, other->type_);
+ std::swap(size_, other->size_);
+ public_key_gx_.UnsafeArenaSwap(&other->public_key_gx_);
+ public_key_gy_.UnsafeArenaSwap(&other->public_key_gy_);
+ std::swap(quote_type_, other->quote_type_);
+ spid_.UnsafeArenaSwap(&other->spid_);
+ std::swap(cmac_kdf_id_, other->cmac_kdf_id_);
+ signature_x_.UnsafeArenaSwap(&other->signature_x_);
+ signature_y_.UnsafeArenaSwap(&other->signature_y_);
+ smac_.UnsafeArenaSwap(&other->smac_);
+ std::swap(size_sigrl_, other->size_sigrl_);
+ sigrl_.UnsafeArenaSwap(&other->sigrl_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ std::swap(_cached_size_, other->_cached_size_);
}
::google::protobuf::Metadata MessageMSG2::GetMetadata() const {
@@ -2152,10 +2481,344 @@
return metadata;
}
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// MessageMSG2
+
+// required uint32 type = 1;
+bool MessageMSG2::has_type() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+void MessageMSG2::set_has_type() {
+ _has_bits_[0] |= 0x00000001u;
+}
+void MessageMSG2::clear_has_type() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+void MessageMSG2::clear_type() {
+ type_ = 0u;
+ clear_has_type();
+}
+ ::google::protobuf::uint32 MessageMSG2::type() const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG2.type)
+ return type_;
+}
+ void MessageMSG2::set_type(::google::protobuf::uint32 value) {
+ set_has_type();
+ type_ = value;
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG2.type)
+}
+
+// optional uint32 size = 2;
+bool MessageMSG2::has_size() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+void MessageMSG2::set_has_size() {
+ _has_bits_[0] |= 0x00000002u;
+}
+void MessageMSG2::clear_has_size() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+void MessageMSG2::clear_size() {
+ size_ = 0u;
+ clear_has_size();
+}
+ ::google::protobuf::uint32 MessageMSG2::size() const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG2.size)
+ return size_;
+}
+ void MessageMSG2::set_size(::google::protobuf::uint32 value) {
+ set_has_size();
+ size_ = value;
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG2.size)
+}
+
+// repeated uint32 public_key_gx = 3 [packed = true];
+int MessageMSG2::public_key_gx_size() const {
+ return public_key_gx_.size();
+}
+void MessageMSG2::clear_public_key_gx() {
+ public_key_gx_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG2::public_key_gx(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG2.public_key_gx)
+ return public_key_gx_.Get(index);
+}
+ void MessageMSG2::set_public_key_gx(int index, ::google::protobuf::uint32 value) {
+ public_key_gx_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG2.public_key_gx)
+}
+ void MessageMSG2::add_public_key_gx(::google::protobuf::uint32 value) {
+ public_key_gx_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG2.public_key_gx)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG2::public_key_gx() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG2.public_key_gx)
+ return public_key_gx_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG2::mutable_public_key_gx() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.public_key_gx)
+ return &public_key_gx_;
+}
+
+// repeated uint32 public_key_gy = 4 [packed = true];
+int MessageMSG2::public_key_gy_size() const {
+ return public_key_gy_.size();
+}
+void MessageMSG2::clear_public_key_gy() {
+ public_key_gy_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG2::public_key_gy(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG2.public_key_gy)
+ return public_key_gy_.Get(index);
+}
+ void MessageMSG2::set_public_key_gy(int index, ::google::protobuf::uint32 value) {
+ public_key_gy_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG2.public_key_gy)
+}
+ void MessageMSG2::add_public_key_gy(::google::protobuf::uint32 value) {
+ public_key_gy_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG2.public_key_gy)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG2::public_key_gy() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG2.public_key_gy)
+ return public_key_gy_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG2::mutable_public_key_gy() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.public_key_gy)
+ return &public_key_gy_;
+}
+
+// optional uint32 quote_type = 5;
+bool MessageMSG2::has_quote_type() const {
+ return (_has_bits_[0] & 0x00000010u) != 0;
+}
+void MessageMSG2::set_has_quote_type() {
+ _has_bits_[0] |= 0x00000010u;
+}
+void MessageMSG2::clear_has_quote_type() {
+ _has_bits_[0] &= ~0x00000010u;
+}
+void MessageMSG2::clear_quote_type() {
+ quote_type_ = 0u;
+ clear_has_quote_type();
+}
+ ::google::protobuf::uint32 MessageMSG2::quote_type() const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG2.quote_type)
+ return quote_type_;
+}
+ void MessageMSG2::set_quote_type(::google::protobuf::uint32 value) {
+ set_has_quote_type();
+ quote_type_ = value;
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG2.quote_type)
+}
+
+// repeated uint32 spid = 6 [packed = true];
+int MessageMSG2::spid_size() const {
+ return spid_.size();
+}
+void MessageMSG2::clear_spid() {
+ spid_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG2::spid(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG2.spid)
+ return spid_.Get(index);
+}
+ void MessageMSG2::set_spid(int index, ::google::protobuf::uint32 value) {
+ spid_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG2.spid)
+}
+ void MessageMSG2::add_spid(::google::protobuf::uint32 value) {
+ spid_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG2.spid)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG2::spid() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG2.spid)
+ return spid_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG2::mutable_spid() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.spid)
+ return &spid_;
+}
+
+// optional uint32 cmac_kdf_id = 7;
+bool MessageMSG2::has_cmac_kdf_id() const {
+ return (_has_bits_[0] & 0x00000040u) != 0;
+}
+void MessageMSG2::set_has_cmac_kdf_id() {
+ _has_bits_[0] |= 0x00000040u;
+}
+void MessageMSG2::clear_has_cmac_kdf_id() {
+ _has_bits_[0] &= ~0x00000040u;
+}
+void MessageMSG2::clear_cmac_kdf_id() {
+ cmac_kdf_id_ = 0u;
+ clear_has_cmac_kdf_id();
+}
+ ::google::protobuf::uint32 MessageMSG2::cmac_kdf_id() const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG2.cmac_kdf_id)
+ return cmac_kdf_id_;
+}
+ void MessageMSG2::set_cmac_kdf_id(::google::protobuf::uint32 value) {
+ set_has_cmac_kdf_id();
+ cmac_kdf_id_ = value;
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG2.cmac_kdf_id)
+}
+
+// repeated uint32 signature_x = 8 [packed = true];
+int MessageMSG2::signature_x_size() const {
+ return signature_x_.size();
+}
+void MessageMSG2::clear_signature_x() {
+ signature_x_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG2::signature_x(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG2.signature_x)
+ return signature_x_.Get(index);
+}
+ void MessageMSG2::set_signature_x(int index, ::google::protobuf::uint32 value) {
+ signature_x_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG2.signature_x)
+}
+ void MessageMSG2::add_signature_x(::google::protobuf::uint32 value) {
+ signature_x_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG2.signature_x)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG2::signature_x() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG2.signature_x)
+ return signature_x_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG2::mutable_signature_x() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.signature_x)
+ return &signature_x_;
+}
+
+// repeated uint32 signature_y = 9 [packed = true];
+int MessageMSG2::signature_y_size() const {
+ return signature_y_.size();
+}
+void MessageMSG2::clear_signature_y() {
+ signature_y_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG2::signature_y(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG2.signature_y)
+ return signature_y_.Get(index);
+}
+ void MessageMSG2::set_signature_y(int index, ::google::protobuf::uint32 value) {
+ signature_y_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG2.signature_y)
+}
+ void MessageMSG2::add_signature_y(::google::protobuf::uint32 value) {
+ signature_y_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG2.signature_y)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG2::signature_y() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG2.signature_y)
+ return signature_y_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG2::mutable_signature_y() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.signature_y)
+ return &signature_y_;
+}
+
+// repeated uint32 smac = 10 [packed = true];
+int MessageMSG2::smac_size() const {
+ return smac_.size();
+}
+void MessageMSG2::clear_smac() {
+ smac_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG2::smac(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG2.smac)
+ return smac_.Get(index);
+}
+ void MessageMSG2::set_smac(int index, ::google::protobuf::uint32 value) {
+ smac_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG2.smac)
+}
+ void MessageMSG2::add_smac(::google::protobuf::uint32 value) {
+ smac_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG2.smac)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG2::smac() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG2.smac)
+ return smac_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG2::mutable_smac() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.smac)
+ return &smac_;
+}
+
+// optional uint32 size_sigrl = 11;
+bool MessageMSG2::has_size_sigrl() const {
+ return (_has_bits_[0] & 0x00000400u) != 0;
+}
+void MessageMSG2::set_has_size_sigrl() {
+ _has_bits_[0] |= 0x00000400u;
+}
+void MessageMSG2::clear_has_size_sigrl() {
+ _has_bits_[0] &= ~0x00000400u;
+}
+void MessageMSG2::clear_size_sigrl() {
+ size_sigrl_ = 0u;
+ clear_has_size_sigrl();
+}
+ ::google::protobuf::uint32 MessageMSG2::size_sigrl() const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG2.size_sigrl)
+ return size_sigrl_;
+}
+ void MessageMSG2::set_size_sigrl(::google::protobuf::uint32 value) {
+ set_has_size_sigrl();
+ size_sigrl_ = value;
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG2.size_sigrl)
+}
+
+// repeated uint32 sigrl = 12 [packed = true];
+int MessageMSG2::sigrl_size() const {
+ return sigrl_.size();
+}
+void MessageMSG2::clear_sigrl() {
+ sigrl_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG2::sigrl(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG2.sigrl)
+ return sigrl_.Get(index);
+}
+ void MessageMSG2::set_sigrl(int index, ::google::protobuf::uint32 value) {
+ sigrl_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG2.sigrl)
+}
+ void MessageMSG2::add_sigrl(::google::protobuf::uint32 value) {
+ sigrl_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG2.sigrl)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG2::sigrl() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG2.sigrl)
+ return sigrl_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG2::mutable_sigrl() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG2.sigrl)
+ return &sigrl_;
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
// ===================================================================
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int MessageMSG3::kTypeFieldNumber;
const int MessageMSG3::kSizeFieldNumber;
const int MessageMSG3::kSgxMacFieldNumber;
@@ -2163,10 +2826,10 @@
const int MessageMSG3::kGayMsg3FieldNumber;
const int MessageMSG3::kSecPropertyFieldNumber;
const int MessageMSG3::kQuoteFieldNumber;
-#endif // !_MSC_VER
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
MessageMSG3::MessageMSG3()
- : ::google::protobuf::Message() {
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
SharedCtor();
// @@protoc_insertion_point(constructor:Messages.MessageMSG3)
}
@@ -2175,7 +2838,8 @@
}
MessageMSG3::MessageMSG3(const MessageMSG3& from)
- : ::google::protobuf::Message() {
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL) {
SharedCtor();
MergeFrom(from);
// @@protoc_insertion_point(copy_constructor:Messages.MessageMSG3)
@@ -2215,24 +2879,35 @@
MessageMSG3* MessageMSG3::default_instance_ = NULL;
-MessageMSG3* MessageMSG3::New() const {
- return new MessageMSG3;
+MessageMSG3* MessageMSG3::New(::google::protobuf::Arena* arena) const {
+ MessageMSG3* n = new MessageMSG3;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
}
void MessageMSG3::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
- &reinterpret_cast<MessageMSG3*>(16)->f) - \
- reinterpret_cast<char*>(16))
+// @@protoc_insertion_point(message_clear_start:Messages.MessageMSG3)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(MessageMSG3, f) \
+ _Pragma("clang diagnostic pop")
+#else
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+ &reinterpret_cast<MessageMSG3*>(16)->f)
+#endif
-#define ZR_(first, last) do { \
- size_t f = OFFSET_OF_FIELD_(first); \
- size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \
- ::memset(&first, 0, n); \
- } while (0)
+#define ZR_(first, last) do {\
+ ::memset(&first, 0,\
+ ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
ZR_(type_, size_);
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
#undef ZR_
sgx_mac_.Clear();
@@ -2241,12 +2916,14 @@
sec_property_.Clear();
quote_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
- mutable_unknown_fields()->Clear();
+ if (_internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->Clear();
+ }
}
bool MessageMSG3::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:Messages.MessageMSG3)
for (;;) {
@@ -2458,15 +3135,15 @@
this->quote(i), output);
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
// @@protoc_insertion_point(serialize_end:Messages.MessageMSG3)
}
-::google::protobuf::uint8* MessageMSG3::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* MessageMSG3::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:Messages.MessageMSG3)
// required uint32 type = 1;
if (has_type()) {
@@ -2548,7 +3225,7 @@
WriteUInt32NoTagToArray(this->quote(i), target);
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
@@ -2557,24 +3234,22 @@
}
int MessageMSG3::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:Messages.MessageMSG3)
int total_size = 0;
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- // required uint32 type = 1;
- if (has_type()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->type());
- }
-
- // optional uint32 size = 2;
- if (has_size()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->size());
- }
-
+ // required uint32 type = 1;
+ if (has_type()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->type());
}
+ // optional uint32 size = 2;
+ if (has_size()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->size());
+ }
+
// repeated uint32 sgx_mac = 3 [packed = true];
{
int data_size = 0;
@@ -2660,7 +3335,7 @@
total_size += data_size;
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
unknown_fields());
@@ -2672,19 +3347,27 @@
}
void MessageMSG3::MergeFrom(const ::google::protobuf::Message& from) {
- GOOGLE_CHECK_NE(&from, this);
- const MessageMSG3* source =
- ::google::protobuf::internal::dynamic_cast_if_available<const MessageMSG3*>(
- &from);
+// @@protoc_insertion_point(generalized_merge_from_start:Messages.MessageMSG3)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
+ const MessageMSG3* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const MessageMSG3>(
+ &from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:Messages.MessageMSG3)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:Messages.MessageMSG3)
MergeFrom(*source);
}
}
void MessageMSG3::MergeFrom(const MessageMSG3& from) {
- GOOGLE_CHECK_NE(&from, this);
+// @@protoc_insertion_point(class_specific_merge_from_start:Messages.MessageMSG3)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
sgx_mac_.MergeFrom(from.sgx_mac_);
gax_msg3_.MergeFrom(from.gax_msg3_);
gay_msg3_.MergeFrom(from.gay_msg3_);
@@ -2698,16 +3381,20 @@
set_size(from.size());
}
}
- mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ if (from._internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ }
}
void MessageMSG3::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:Messages.MessageMSG3)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void MessageMSG3::CopyFrom(const MessageMSG3& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:Messages.MessageMSG3)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -2720,18 +3407,20 @@
}
void MessageMSG3::Swap(MessageMSG3* other) {
- if (other != this) {
- std::swap(type_, other->type_);
- std::swap(size_, other->size_);
- sgx_mac_.Swap(&other->sgx_mac_);
- gax_msg3_.Swap(&other->gax_msg3_);
- gay_msg3_.Swap(&other->gay_msg3_);
- sec_property_.Swap(&other->sec_property_);
- quote_.Swap(&other->quote_);
- std::swap(_has_bits_[0], other->_has_bits_[0]);
- _unknown_fields_.Swap(&other->_unknown_fields_);
- std::swap(_cached_size_, other->_cached_size_);
- }
+ if (other == this) return;
+ InternalSwap(other);
+}
+void MessageMSG3::InternalSwap(MessageMSG3* other) {
+ std::swap(type_, other->type_);
+ std::swap(size_, other->size_);
+ sgx_mac_.UnsafeArenaSwap(&other->sgx_mac_);
+ gax_msg3_.UnsafeArenaSwap(&other->gax_msg3_);
+ gay_msg3_.UnsafeArenaSwap(&other->gay_msg3_);
+ sec_property_.UnsafeArenaSwap(&other->sec_property_);
+ quote_.UnsafeArenaSwap(&other->quote_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ std::swap(_cached_size_, other->_cached_size_);
}
::google::protobuf::Metadata MessageMSG3::GetMetadata() const {
@@ -2742,10 +3431,212 @@
return metadata;
}
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// MessageMSG3
+
+// required uint32 type = 1;
+bool MessageMSG3::has_type() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+void MessageMSG3::set_has_type() {
+ _has_bits_[0] |= 0x00000001u;
+}
+void MessageMSG3::clear_has_type() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+void MessageMSG3::clear_type() {
+ type_ = 0u;
+ clear_has_type();
+}
+ ::google::protobuf::uint32 MessageMSG3::type() const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG3.type)
+ return type_;
+}
+ void MessageMSG3::set_type(::google::protobuf::uint32 value) {
+ set_has_type();
+ type_ = value;
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG3.type)
+}
+
+// optional uint32 size = 2;
+bool MessageMSG3::has_size() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+void MessageMSG3::set_has_size() {
+ _has_bits_[0] |= 0x00000002u;
+}
+void MessageMSG3::clear_has_size() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+void MessageMSG3::clear_size() {
+ size_ = 0u;
+ clear_has_size();
+}
+ ::google::protobuf::uint32 MessageMSG3::size() const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG3.size)
+ return size_;
+}
+ void MessageMSG3::set_size(::google::protobuf::uint32 value) {
+ set_has_size();
+ size_ = value;
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG3.size)
+}
+
+// repeated uint32 sgx_mac = 3 [packed = true];
+int MessageMSG3::sgx_mac_size() const {
+ return sgx_mac_.size();
+}
+void MessageMSG3::clear_sgx_mac() {
+ sgx_mac_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG3::sgx_mac(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG3.sgx_mac)
+ return sgx_mac_.Get(index);
+}
+ void MessageMSG3::set_sgx_mac(int index, ::google::protobuf::uint32 value) {
+ sgx_mac_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG3.sgx_mac)
+}
+ void MessageMSG3::add_sgx_mac(::google::protobuf::uint32 value) {
+ sgx_mac_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG3.sgx_mac)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG3::sgx_mac() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG3.sgx_mac)
+ return sgx_mac_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG3::mutable_sgx_mac() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.sgx_mac)
+ return &sgx_mac_;
+}
+
+// repeated uint32 gax_msg3 = 4 [packed = true];
+int MessageMSG3::gax_msg3_size() const {
+ return gax_msg3_.size();
+}
+void MessageMSG3::clear_gax_msg3() {
+ gax_msg3_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG3::gax_msg3(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG3.gax_msg3)
+ return gax_msg3_.Get(index);
+}
+ void MessageMSG3::set_gax_msg3(int index, ::google::protobuf::uint32 value) {
+ gax_msg3_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG3.gax_msg3)
+}
+ void MessageMSG3::add_gax_msg3(::google::protobuf::uint32 value) {
+ gax_msg3_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG3.gax_msg3)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG3::gax_msg3() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG3.gax_msg3)
+ return gax_msg3_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG3::mutable_gax_msg3() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.gax_msg3)
+ return &gax_msg3_;
+}
+
+// repeated uint32 gay_msg3 = 5 [packed = true];
+int MessageMSG3::gay_msg3_size() const {
+ return gay_msg3_.size();
+}
+void MessageMSG3::clear_gay_msg3() {
+ gay_msg3_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG3::gay_msg3(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG3.gay_msg3)
+ return gay_msg3_.Get(index);
+}
+ void MessageMSG3::set_gay_msg3(int index, ::google::protobuf::uint32 value) {
+ gay_msg3_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG3.gay_msg3)
+}
+ void MessageMSG3::add_gay_msg3(::google::protobuf::uint32 value) {
+ gay_msg3_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG3.gay_msg3)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG3::gay_msg3() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG3.gay_msg3)
+ return gay_msg3_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG3::mutable_gay_msg3() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.gay_msg3)
+ return &gay_msg3_;
+}
+
+// repeated uint32 sec_property = 6 [packed = true];
+int MessageMSG3::sec_property_size() const {
+ return sec_property_.size();
+}
+void MessageMSG3::clear_sec_property() {
+ sec_property_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG3::sec_property(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG3.sec_property)
+ return sec_property_.Get(index);
+}
+ void MessageMSG3::set_sec_property(int index, ::google::protobuf::uint32 value) {
+ sec_property_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG3.sec_property)
+}
+ void MessageMSG3::add_sec_property(::google::protobuf::uint32 value) {
+ sec_property_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG3.sec_property)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG3::sec_property() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG3.sec_property)
+ return sec_property_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG3::mutable_sec_property() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.sec_property)
+ return &sec_property_;
+}
+
+// repeated uint32 quote = 7 [packed = true];
+int MessageMSG3::quote_size() const {
+ return quote_.size();
+}
+void MessageMSG3::clear_quote() {
+ quote_.Clear();
+}
+ ::google::protobuf::uint32 MessageMSG3::quote(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.MessageMSG3.quote)
+ return quote_.Get(index);
+}
+ void MessageMSG3::set_quote(int index, ::google::protobuf::uint32 value) {
+ quote_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.MessageMSG3.quote)
+}
+ void MessageMSG3::add_quote(::google::protobuf::uint32 value) {
+ quote_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.MessageMSG3.quote)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+MessageMSG3::quote() const {
+ // @@protoc_insertion_point(field_list:Messages.MessageMSG3.quote)
+ return quote_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+MessageMSG3::mutable_quote() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.MessageMSG3.quote)
+ return "e_;
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
// ===================================================================
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int AttestationMessage::kTypeFieldNumber;
const int AttestationMessage::kSizeFieldNumber;
const int AttestationMessage::kEpidGroupStatusFieldNumber;
@@ -2762,10 +3653,10 @@
const int AttestationMessage::kReservedFieldNumber;
const int AttestationMessage::kPayloadTagFieldNumber;
const int AttestationMessage::kPayloadFieldNumber;
-#endif // !_MSC_VER
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
AttestationMessage::AttestationMessage()
- : ::google::protobuf::Message() {
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
SharedCtor();
// @@protoc_insertion_point(constructor:Messages.AttestationMessage)
}
@@ -2774,7 +3665,8 @@
}
AttestationMessage::AttestationMessage(const AttestationMessage& from)
- : ::google::protobuf::Message() {
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL) {
SharedCtor();
MergeFrom(from);
// @@protoc_insertion_point(copy_constructor:Messages.AttestationMessage)
@@ -2818,28 +3710,39 @@
AttestationMessage* AttestationMessage::default_instance_ = NULL;
-AttestationMessage* AttestationMessage::New() const {
- return new AttestationMessage;
+AttestationMessage* AttestationMessage::New(::google::protobuf::Arena* arena) const {
+ AttestationMessage* n = new AttestationMessage;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
}
void AttestationMessage::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
- &reinterpret_cast<AttestationMessage*>(16)->f) - \
- reinterpret_cast<char*>(16))
+// @@protoc_insertion_point(message_clear_start:Messages.AttestationMessage)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(AttestationMessage, f) \
+ _Pragma("clang diagnostic pop")
+#else
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+ &reinterpret_cast<AttestationMessage*>(16)->f)
+#endif
-#define ZR_(first, last) do { \
- size_t f = OFFSET_OF_FIELD_(first); \
- size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \
- ::memset(&first, 0, n); \
- } while (0)
+#define ZR_(first, last) do {\
+ ::memset(&first, 0,\
+ ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
- if (_has_bits_[0 / 32] & 31) {
+ if (_has_bits_[0 / 32] & 31u) {
ZR_(type_, tcb_evaluation_status_);
pse_evaluation_status_ = 0u;
}
result_size_ = 0u;
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
#undef ZR_
latest_equivalent_tcb_psvn_.Clear();
@@ -2853,12 +3756,14 @@
payload_tag_.Clear();
payload_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
- mutable_unknown_fields()->Clear();
+ if (_internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->Clear();
+ }
}
bool AttestationMessage::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:Messages.AttestationMessage)
for (;;) {
@@ -3290,15 +4195,15 @@
this->payload(i), output);
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
// @@protoc_insertion_point(serialize_end:Messages.AttestationMessage)
}
-::google::protobuf::uint8* AttestationMessage::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* AttestationMessage::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:Messages.AttestationMessage)
// required uint32 type = 1;
if (has_type()) {
@@ -3470,7 +4375,7 @@
WriteUInt32NoTagToArray(this->payload(i), target);
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
@@ -3478,24 +4383,45 @@
return target;
}
-int AttestationMessage::ByteSize() const {
+int AttestationMessage::RequiredFieldsByteSizeFallback() const {
+// @@protoc_insertion_point(required_fields_byte_size_fallback_start:Messages.AttestationMessage)
int total_size = 0;
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (has_type()) {
// required uint32 type = 1;
- if (has_type()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->type());
- }
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->type());
+ }
+
+ if (has_size()) {
+ // required uint32 size = 2;
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->size());
+ }
+
+ return total_size;
+}
+int AttestationMessage::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:Messages.AttestationMessage)
+ int total_size = 0;
+
+ if (((_has_bits_[0] & 0x00000003) ^ 0x00000003) == 0) { // All required fields are present.
+ // required uint32 type = 1;
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->type());
// required uint32 size = 2;
- if (has_size()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->size());
- }
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->size());
+ } else {
+ total_size += RequiredFieldsByteSizeFallback();
+ }
+ if (_has_bits_[2 / 32] & 28u) {
// optional uint32 epid_group_status = 3;
if (has_epid_group_status()) {
total_size += 1 +
@@ -3518,15 +4444,13 @@
}
}
- if (_has_bits_[12 / 32] & (0xffu << (12 % 32))) {
- // optional uint32 result_size = 13;
- if (has_result_size()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->result_size());
- }
-
+ // optional uint32 result_size = 13;
+ if (has_result_size()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt32Size(
+ this->result_size());
}
+
// repeated uint32 latest_equivalent_tcb_psvn = 6 [packed = true];
{
int data_size = 0;
@@ -3697,7 +4621,7 @@
total_size += data_size;
}
- if (!unknown_fields().empty()) {
+ if (_internal_metadata_.have_unknown_fields()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
unknown_fields());
@@ -3709,19 +4633,27 @@
}
void AttestationMessage::MergeFrom(const ::google::protobuf::Message& from) {
- GOOGLE_CHECK_NE(&from, this);
- const AttestationMessage* source =
- ::google::protobuf::internal::dynamic_cast_if_available<const AttestationMessage*>(
- &from);
+// @@protoc_insertion_point(generalized_merge_from_start:Messages.AttestationMessage)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
+ const AttestationMessage* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const AttestationMessage>(
+ &from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:Messages.AttestationMessage)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:Messages.AttestationMessage)
MergeFrom(*source);
}
}
void AttestationMessage::MergeFrom(const AttestationMessage& from) {
- GOOGLE_CHECK_NE(&from, this);
+// @@protoc_insertion_point(class_specific_merge_from_start:Messages.AttestationMessage)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
latest_equivalent_tcb_psvn_.MergeFrom(from.latest_equivalent_tcb_psvn_);
latest_pse_isvsvn_.MergeFrom(from.latest_pse_isvsvn_);
latest_psda_svn_.MergeFrom(from.latest_psda_svn_);
@@ -3754,16 +4686,20 @@
set_result_size(from.result_size());
}
}
- mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ if (from._internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ }
}
void AttestationMessage::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:Messages.AttestationMessage)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void AttestationMessage::CopyFrom(const AttestationMessage& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:Messages.AttestationMessage)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -3776,27 +4712,29 @@
}
void AttestationMessage::Swap(AttestationMessage* other) {
- if (other != this) {
- std::swap(type_, other->type_);
- std::swap(size_, other->size_);
- std::swap(epid_group_status_, other->epid_group_status_);
- std::swap(tcb_evaluation_status_, other->tcb_evaluation_status_);
- std::swap(pse_evaluation_status_, other->pse_evaluation_status_);
- latest_equivalent_tcb_psvn_.Swap(&other->latest_equivalent_tcb_psvn_);
- latest_pse_isvsvn_.Swap(&other->latest_pse_isvsvn_);
- latest_psda_svn_.Swap(&other->latest_psda_svn_);
- performance_rekey_gid_.Swap(&other->performance_rekey_gid_);
- ec_sign256_x_.Swap(&other->ec_sign256_x_);
- ec_sign256_y_.Swap(&other->ec_sign256_y_);
- mac_smk_.Swap(&other->mac_smk_);
- std::swap(result_size_, other->result_size_);
- reserved_.Swap(&other->reserved_);
- payload_tag_.Swap(&other->payload_tag_);
- payload_.Swap(&other->payload_);
- std::swap(_has_bits_[0], other->_has_bits_[0]);
- _unknown_fields_.Swap(&other->_unknown_fields_);
- std::swap(_cached_size_, other->_cached_size_);
- }
+ if (other == this) return;
+ InternalSwap(other);
+}
+void AttestationMessage::InternalSwap(AttestationMessage* other) {
+ std::swap(type_, other->type_);
+ std::swap(size_, other->size_);
+ std::swap(epid_group_status_, other->epid_group_status_);
+ std::swap(tcb_evaluation_status_, other->tcb_evaluation_status_);
+ std::swap(pse_evaluation_status_, other->pse_evaluation_status_);
+ latest_equivalent_tcb_psvn_.UnsafeArenaSwap(&other->latest_equivalent_tcb_psvn_);
+ latest_pse_isvsvn_.UnsafeArenaSwap(&other->latest_pse_isvsvn_);
+ latest_psda_svn_.UnsafeArenaSwap(&other->latest_psda_svn_);
+ performance_rekey_gid_.UnsafeArenaSwap(&other->performance_rekey_gid_);
+ ec_sign256_x_.UnsafeArenaSwap(&other->ec_sign256_x_);
+ ec_sign256_y_.UnsafeArenaSwap(&other->ec_sign256_y_);
+ mac_smk_.UnsafeArenaSwap(&other->mac_smk_);
+ std::swap(result_size_, other->result_size_);
+ reserved_.UnsafeArenaSwap(&other->reserved_);
+ payload_tag_.UnsafeArenaSwap(&other->payload_tag_);
+ payload_.UnsafeArenaSwap(&other->payload_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ std::swap(_cached_size_, other->_cached_size_);
}
::google::protobuf::Metadata AttestationMessage::GetMetadata() const {
@@ -3807,735 +4745,454 @@
return metadata;
}
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// AttestationMessage
-// ===================================================================
-
-#ifndef _MSC_VER
-const int SecretMessage::kTypeFieldNumber;
-const int SecretMessage::kSizeFieldNumber;
-const int SecretMessage::kEncrypedPkeySizeFieldNumber;
-const int SecretMessage::kEncrypedX509SizeFieldNumber;
-const int SecretMessage::kEncryptedContentFieldNumber;
-const int SecretMessage::kMacSmkFieldNumber;
-const int SecretMessage::kEncryptedPkeyFieldNumber;
-const int SecretMessage::kEncryptedPkeyMacSmkFieldNumber;
-const int SecretMessage::kEncryptedX509FieldNumber;
-const int SecretMessage::kEncryptedX509MacSmkFieldNumber;
-#endif // !_MSC_VER
-
-SecretMessage::SecretMessage()
- : ::google::protobuf::Message() {
- SharedCtor();
- // @@protoc_insertion_point(constructor:Messages.SecretMessage)
+// required uint32 type = 1;
+bool AttestationMessage::has_type() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
}
-
-void SecretMessage::InitAsDefaultInstance() {
+void AttestationMessage::set_has_type() {
+ _has_bits_[0] |= 0x00000001u;
}
-
-SecretMessage::SecretMessage(const SecretMessage& from)
- : ::google::protobuf::Message() {
- SharedCtor();
- MergeFrom(from);
- // @@protoc_insertion_point(copy_constructor:Messages.SecretMessage)
+void AttestationMessage::clear_has_type() {
+ _has_bits_[0] &= ~0x00000001u;
}
-
-void SecretMessage::SharedCtor() {
- _cached_size_ = 0;
+void AttestationMessage::clear_type() {
type_ = 0u;
+ clear_has_type();
+}
+ ::google::protobuf::uint32 AttestationMessage::type() const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.type)
+ return type_;
+}
+ void AttestationMessage::set_type(::google::protobuf::uint32 value) {
+ set_has_type();
+ type_ = value;
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.type)
+}
+
+// required uint32 size = 2;
+bool AttestationMessage::has_size() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+void AttestationMessage::set_has_size() {
+ _has_bits_[0] |= 0x00000002u;
+}
+void AttestationMessage::clear_has_size() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+void AttestationMessage::clear_size() {
size_ = 0u;
- encryped_pkey_size_ = 0u;
- encryped_x509_size_ = 0u;
- ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ clear_has_size();
+}
+ ::google::protobuf::uint32 AttestationMessage::size() const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.size)
+ return size_;
+}
+ void AttestationMessage::set_size(::google::protobuf::uint32 value) {
+ set_has_size();
+ size_ = value;
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.size)
}
-SecretMessage::~SecretMessage() {
- // @@protoc_insertion_point(destructor:Messages.SecretMessage)
- SharedDtor();
+// optional uint32 epid_group_status = 3;
+bool AttestationMessage::has_epid_group_status() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+void AttestationMessage::set_has_epid_group_status() {
+ _has_bits_[0] |= 0x00000004u;
+}
+void AttestationMessage::clear_has_epid_group_status() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+void AttestationMessage::clear_epid_group_status() {
+ epid_group_status_ = 0u;
+ clear_has_epid_group_status();
+}
+ ::google::protobuf::uint32 AttestationMessage::epid_group_status() const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.epid_group_status)
+ return epid_group_status_;
+}
+ void AttestationMessage::set_epid_group_status(::google::protobuf::uint32 value) {
+ set_has_epid_group_status();
+ epid_group_status_ = value;
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.epid_group_status)
}
-void SecretMessage::SharedDtor() {
- if (this != default_instance_) {
- }
+// optional uint32 tcb_evaluation_status = 4;
+bool AttestationMessage::has_tcb_evaluation_status() const {
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+void AttestationMessage::set_has_tcb_evaluation_status() {
+ _has_bits_[0] |= 0x00000008u;
+}
+void AttestationMessage::clear_has_tcb_evaluation_status() {
+ _has_bits_[0] &= ~0x00000008u;
+}
+void AttestationMessage::clear_tcb_evaluation_status() {
+ tcb_evaluation_status_ = 0u;
+ clear_has_tcb_evaluation_status();
+}
+ ::google::protobuf::uint32 AttestationMessage::tcb_evaluation_status() const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.tcb_evaluation_status)
+ return tcb_evaluation_status_;
+}
+ void AttestationMessage::set_tcb_evaluation_status(::google::protobuf::uint32 value) {
+ set_has_tcb_evaluation_status();
+ tcb_evaluation_status_ = value;
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.tcb_evaluation_status)
}
-void SecretMessage::SetCachedSize(int size) const {
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _cached_size_ = size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
+// optional uint32 pse_evaluation_status = 5;
+bool AttestationMessage::has_pse_evaluation_status() const {
+ return (_has_bits_[0] & 0x00000010u) != 0;
}
-const ::google::protobuf::Descriptor* SecretMessage::descriptor() {
- protobuf_AssignDescriptorsOnce();
- return SecretMessage_descriptor_;
+void AttestationMessage::set_has_pse_evaluation_status() {
+ _has_bits_[0] |= 0x00000010u;
+}
+void AttestationMessage::clear_has_pse_evaluation_status() {
+ _has_bits_[0] &= ~0x00000010u;
+}
+void AttestationMessage::clear_pse_evaluation_status() {
+ pse_evaluation_status_ = 0u;
+ clear_has_pse_evaluation_status();
+}
+ ::google::protobuf::uint32 AttestationMessage::pse_evaluation_status() const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.pse_evaluation_status)
+ return pse_evaluation_status_;
+}
+ void AttestationMessage::set_pse_evaluation_status(::google::protobuf::uint32 value) {
+ set_has_pse_evaluation_status();
+ pse_evaluation_status_ = value;
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.pse_evaluation_status)
}
-const SecretMessage& SecretMessage::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_Messages_2eproto();
- return *default_instance_;
+// repeated uint32 latest_equivalent_tcb_psvn = 6 [packed = true];
+int AttestationMessage::latest_equivalent_tcb_psvn_size() const {
+ return latest_equivalent_tcb_psvn_.size();
+}
+void AttestationMessage::clear_latest_equivalent_tcb_psvn() {
+ latest_equivalent_tcb_psvn_.Clear();
+}
+ ::google::protobuf::uint32 AttestationMessage::latest_equivalent_tcb_psvn(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
+ return latest_equivalent_tcb_psvn_.Get(index);
+}
+ void AttestationMessage::set_latest_equivalent_tcb_psvn(int index, ::google::protobuf::uint32 value) {
+ latest_equivalent_tcb_psvn_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
+}
+ void AttestationMessage::add_latest_equivalent_tcb_psvn(::google::protobuf::uint32 value) {
+ latest_equivalent_tcb_psvn_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+AttestationMessage::latest_equivalent_tcb_psvn() const {
+ // @@protoc_insertion_point(field_list:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
+ return latest_equivalent_tcb_psvn_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+AttestationMessage::mutable_latest_equivalent_tcb_psvn() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.latest_equivalent_tcb_psvn)
+ return &latest_equivalent_tcb_psvn_;
}
-SecretMessage* SecretMessage::default_instance_ = NULL;
-
-SecretMessage* SecretMessage::New() const {
- return new SecretMessage;
+// repeated uint32 latest_pse_isvsvn = 7 [packed = true];
+int AttestationMessage::latest_pse_isvsvn_size() const {
+ return latest_pse_isvsvn_.size();
+}
+void AttestationMessage::clear_latest_pse_isvsvn() {
+ latest_pse_isvsvn_.Clear();
+}
+ ::google::protobuf::uint32 AttestationMessage::latest_pse_isvsvn(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.latest_pse_isvsvn)
+ return latest_pse_isvsvn_.Get(index);
+}
+ void AttestationMessage::set_latest_pse_isvsvn(int index, ::google::protobuf::uint32 value) {
+ latest_pse_isvsvn_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.latest_pse_isvsvn)
+}
+ void AttestationMessage::add_latest_pse_isvsvn(::google::protobuf::uint32 value) {
+ latest_pse_isvsvn_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.AttestationMessage.latest_pse_isvsvn)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+AttestationMessage::latest_pse_isvsvn() const {
+ // @@protoc_insertion_point(field_list:Messages.AttestationMessage.latest_pse_isvsvn)
+ return latest_pse_isvsvn_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+AttestationMessage::mutable_latest_pse_isvsvn() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.latest_pse_isvsvn)
+ return &latest_pse_isvsvn_;
}
-void SecretMessage::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
- &reinterpret_cast<SecretMessage*>(16)->f) - \
- reinterpret_cast<char*>(16))
+// repeated uint32 latest_psda_svn = 8 [packed = true];
+int AttestationMessage::latest_psda_svn_size() const {
+ return latest_psda_svn_.size();
+}
+void AttestationMessage::clear_latest_psda_svn() {
+ latest_psda_svn_.Clear();
+}
+ ::google::protobuf::uint32 AttestationMessage::latest_psda_svn(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.latest_psda_svn)
+ return latest_psda_svn_.Get(index);
+}
+ void AttestationMessage::set_latest_psda_svn(int index, ::google::protobuf::uint32 value) {
+ latest_psda_svn_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.latest_psda_svn)
+}
+ void AttestationMessage::add_latest_psda_svn(::google::protobuf::uint32 value) {
+ latest_psda_svn_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.AttestationMessage.latest_psda_svn)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+AttestationMessage::latest_psda_svn() const {
+ // @@protoc_insertion_point(field_list:Messages.AttestationMessage.latest_psda_svn)
+ return latest_psda_svn_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+AttestationMessage::mutable_latest_psda_svn() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.latest_psda_svn)
+ return &latest_psda_svn_;
+}
-#define ZR_(first, last) do { \
- size_t f = OFFSET_OF_FIELD_(first); \
- size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \
- ::memset(&first, 0, n); \
- } while (0)
+// repeated uint32 performance_rekey_gid = 9 [packed = true];
+int AttestationMessage::performance_rekey_gid_size() const {
+ return performance_rekey_gid_.size();
+}
+void AttestationMessage::clear_performance_rekey_gid() {
+ performance_rekey_gid_.Clear();
+}
+ ::google::protobuf::uint32 AttestationMessage::performance_rekey_gid(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.performance_rekey_gid)
+ return performance_rekey_gid_.Get(index);
+}
+ void AttestationMessage::set_performance_rekey_gid(int index, ::google::protobuf::uint32 value) {
+ performance_rekey_gid_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.performance_rekey_gid)
+}
+ void AttestationMessage::add_performance_rekey_gid(::google::protobuf::uint32 value) {
+ performance_rekey_gid_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.AttestationMessage.performance_rekey_gid)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+AttestationMessage::performance_rekey_gid() const {
+ // @@protoc_insertion_point(field_list:Messages.AttestationMessage.performance_rekey_gid)
+ return performance_rekey_gid_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+AttestationMessage::mutable_performance_rekey_gid() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.performance_rekey_gid)
+ return &performance_rekey_gid_;
+}
- ZR_(type_, encryped_x509_size_);
+// repeated uint32 ec_sign256_x = 10 [packed = true];
+int AttestationMessage::ec_sign256_x_size() const {
+ return ec_sign256_x_.size();
+}
+void AttestationMessage::clear_ec_sign256_x() {
+ ec_sign256_x_.Clear();
+}
+ ::google::protobuf::uint32 AttestationMessage::ec_sign256_x(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.ec_sign256_x)
+ return ec_sign256_x_.Get(index);
+}
+ void AttestationMessage::set_ec_sign256_x(int index, ::google::protobuf::uint32 value) {
+ ec_sign256_x_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.ec_sign256_x)
+}
+ void AttestationMessage::add_ec_sign256_x(::google::protobuf::uint32 value) {
+ ec_sign256_x_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.AttestationMessage.ec_sign256_x)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+AttestationMessage::ec_sign256_x() const {
+ // @@protoc_insertion_point(field_list:Messages.AttestationMessage.ec_sign256_x)
+ return ec_sign256_x_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+AttestationMessage::mutable_ec_sign256_x() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.ec_sign256_x)
+ return &ec_sign256_x_;
+}
-#undef OFFSET_OF_FIELD_
-#undef ZR_
+// repeated uint32 ec_sign256_y = 11 [packed = true];
+int AttestationMessage::ec_sign256_y_size() const {
+ return ec_sign256_y_.size();
+}
+void AttestationMessage::clear_ec_sign256_y() {
+ ec_sign256_y_.Clear();
+}
+ ::google::protobuf::uint32 AttestationMessage::ec_sign256_y(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.ec_sign256_y)
+ return ec_sign256_y_.Get(index);
+}
+ void AttestationMessage::set_ec_sign256_y(int index, ::google::protobuf::uint32 value) {
+ ec_sign256_y_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.ec_sign256_y)
+}
+ void AttestationMessage::add_ec_sign256_y(::google::protobuf::uint32 value) {
+ ec_sign256_y_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.AttestationMessage.ec_sign256_y)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+AttestationMessage::ec_sign256_y() const {
+ // @@protoc_insertion_point(field_list:Messages.AttestationMessage.ec_sign256_y)
+ return ec_sign256_y_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+AttestationMessage::mutable_ec_sign256_y() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.ec_sign256_y)
+ return &ec_sign256_y_;
+}
- encrypted_content_.Clear();
+// repeated uint32 mac_smk = 12 [packed = true];
+int AttestationMessage::mac_smk_size() const {
+ return mac_smk_.size();
+}
+void AttestationMessage::clear_mac_smk() {
mac_smk_.Clear();
- encrypted_pkey_.Clear();
- encrypted_pkey_mac_smk_.Clear();
- encrypted_x509_.Clear();
- encrypted_x509_mac_smk_.Clear();
- ::memset(_has_bits_, 0, sizeof(_has_bits_));
- mutable_unknown_fields()->Clear();
+}
+ ::google::protobuf::uint32 AttestationMessage::mac_smk(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.mac_smk)
+ return mac_smk_.Get(index);
+}
+ void AttestationMessage::set_mac_smk(int index, ::google::protobuf::uint32 value) {
+ mac_smk_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.mac_smk)
+}
+ void AttestationMessage::add_mac_smk(::google::protobuf::uint32 value) {
+ mac_smk_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.AttestationMessage.mac_smk)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+AttestationMessage::mac_smk() const {
+ // @@protoc_insertion_point(field_list:Messages.AttestationMessage.mac_smk)
+ return mac_smk_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+AttestationMessage::mutable_mac_smk() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.mac_smk)
+ return &mac_smk_;
}
-bool SecretMessage::MergePartialFromCodedStream(
- ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
- ::google::protobuf::uint32 tag;
- // @@protoc_insertion_point(parse_start:Messages.SecretMessage)
- for (;;) {
- ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
- tag = p.first;
- if (!p.second) goto handle_unusual;
- switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
- // required uint32 type = 1;
- case 1: {
- if (tag == 8) {
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- input, &type_)));
- set_has_type();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(16)) goto parse_size;
- break;
- }
-
- // required uint32 size = 2;
- case 2: {
- if (tag == 16) {
- parse_size:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- input, &size_)));
- set_has_size();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(24)) goto parse_encryped_pkey_size;
- break;
- }
-
- // optional uint32 encryped_pkey_size = 3;
- case 3: {
- if (tag == 24) {
- parse_encryped_pkey_size:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- input, &encryped_pkey_size_)));
- set_has_encryped_pkey_size();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(32)) goto parse_encryped_x509_size;
- break;
- }
-
- // optional uint32 encryped_x509_size = 4;
- case 4: {
- if (tag == 32) {
- parse_encryped_x509_size:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- input, &encryped_x509_size_)));
- set_has_encryped_x509_size();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(42)) goto parse_encrypted_content;
- break;
- }
-
- // repeated uint32 encrypted_content = 5 [packed = true];
- case 5: {
- if (tag == 42) {
- parse_encrypted_content:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- input, this->mutable_encrypted_content())));
- } else if (tag == 40) {
- DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- 1, 42, input, this->mutable_encrypted_content())));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(50)) goto parse_mac_smk;
- break;
- }
-
- // repeated uint32 mac_smk = 6 [packed = true];
- case 6: {
- if (tag == 50) {
- parse_mac_smk:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- input, this->mutable_mac_smk())));
- } else if (tag == 48) {
- DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- 1, 50, input, this->mutable_mac_smk())));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(58)) goto parse_encrypted_pkey;
- break;
- }
-
- // repeated uint32 encrypted_pkey = 7 [packed = true];
- case 7: {
- if (tag == 58) {
- parse_encrypted_pkey:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- input, this->mutable_encrypted_pkey())));
- } else if (tag == 56) {
- DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- 1, 58, input, this->mutable_encrypted_pkey())));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(66)) goto parse_encrypted_pkey_mac_smk;
- break;
- }
-
- // repeated uint32 encrypted_pkey_mac_smk = 8 [packed = true];
- case 8: {
- if (tag == 66) {
- parse_encrypted_pkey_mac_smk:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- input, this->mutable_encrypted_pkey_mac_smk())));
- } else if (tag == 64) {
- DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- 1, 66, input, this->mutable_encrypted_pkey_mac_smk())));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(74)) goto parse_encrypted_x509;
- break;
- }
-
- // repeated uint32 encrypted_x509 = 9 [packed = true];
- case 9: {
- if (tag == 74) {
- parse_encrypted_x509:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- input, this->mutable_encrypted_x509())));
- } else if (tag == 72) {
- DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- 1, 74, input, this->mutable_encrypted_x509())));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(82)) goto parse_encrypted_x509_mac_smk;
- break;
- }
-
- // repeated uint32 encrypted_x509_mac_smk = 10 [packed = true];
- case 10: {
- if (tag == 82) {
- parse_encrypted_x509_mac_smk:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- input, this->mutable_encrypted_x509_mac_smk())));
- } else if (tag == 80) {
- DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- 1, 82, input, this->mutable_encrypted_x509_mac_smk())));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectAtEnd()) goto success;
- break;
- }
-
- default: {
- handle_unusual:
- if (tag == 0 ||
- ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- goto success;
- }
- DO_(::google::protobuf::internal::WireFormat::SkipField(
- input, tag, mutable_unknown_fields()));
- break;
- }
- }
- }
-success:
- // @@protoc_insertion_point(parse_success:Messages.SecretMessage)
- return true;
-failure:
- // @@protoc_insertion_point(parse_failure:Messages.SecretMessage)
- return false;
-#undef DO_
+// optional uint32 result_size = 13;
+bool AttestationMessage::has_result_size() const {
+ return (_has_bits_[0] & 0x00001000u) != 0;
+}
+void AttestationMessage::set_has_result_size() {
+ _has_bits_[0] |= 0x00001000u;
+}
+void AttestationMessage::clear_has_result_size() {
+ _has_bits_[0] &= ~0x00001000u;
+}
+void AttestationMessage::clear_result_size() {
+ result_size_ = 0u;
+ clear_has_result_size();
+}
+ ::google::protobuf::uint32 AttestationMessage::result_size() const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.result_size)
+ return result_size_;
+}
+ void AttestationMessage::set_result_size(::google::protobuf::uint32 value) {
+ set_has_result_size();
+ result_size_ = value;
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.result_size)
}
-void SecretMessage::SerializeWithCachedSizes(
- ::google::protobuf::io::CodedOutputStream* output) const {
- // @@protoc_insertion_point(serialize_start:Messages.SecretMessage)
- // required uint32 type = 1;
- if (has_type()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->type(), output);
- }
-
- // required uint32 size = 2;
- if (has_size()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->size(), output);
- }
-
- // optional uint32 encryped_pkey_size = 3;
- if (has_encryped_pkey_size()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->encryped_pkey_size(), output);
- }
-
- // optional uint32 encryped_x509_size = 4;
- if (has_encryped_x509_size()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->encryped_x509_size(), output);
- }
-
- // repeated uint32 encrypted_content = 5 [packed = true];
- if (this->encrypted_content_size() > 0) {
- ::google::protobuf::internal::WireFormatLite::WriteTag(5, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
- output->WriteVarint32(_encrypted_content_cached_byte_size_);
- }
- for (int i = 0; i < this->encrypted_content_size(); i++) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
- this->encrypted_content(i), output);
- }
-
- // repeated uint32 mac_smk = 6 [packed = true];
- if (this->mac_smk_size() > 0) {
- ::google::protobuf::internal::WireFormatLite::WriteTag(6, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
- output->WriteVarint32(_mac_smk_cached_byte_size_);
- }
- for (int i = 0; i < this->mac_smk_size(); i++) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
- this->mac_smk(i), output);
- }
-
- // repeated uint32 encrypted_pkey = 7 [packed = true];
- if (this->encrypted_pkey_size() > 0) {
- ::google::protobuf::internal::WireFormatLite::WriteTag(7, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
- output->WriteVarint32(_encrypted_pkey_cached_byte_size_);
- }
- for (int i = 0; i < this->encrypted_pkey_size(); i++) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
- this->encrypted_pkey(i), output);
- }
-
- // repeated uint32 encrypted_pkey_mac_smk = 8 [packed = true];
- if (this->encrypted_pkey_mac_smk_size() > 0) {
- ::google::protobuf::internal::WireFormatLite::WriteTag(8, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
- output->WriteVarint32(_encrypted_pkey_mac_smk_cached_byte_size_);
- }
- for (int i = 0; i < this->encrypted_pkey_mac_smk_size(); i++) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
- this->encrypted_pkey_mac_smk(i), output);
- }
-
- // repeated uint32 encrypted_x509 = 9 [packed = true];
- if (this->encrypted_x509_size() > 0) {
- ::google::protobuf::internal::WireFormatLite::WriteTag(9, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
- output->WriteVarint32(_encrypted_x509_cached_byte_size_);
- }
- for (int i = 0; i < this->encrypted_x509_size(); i++) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
- this->encrypted_x509(i), output);
- }
-
- // repeated uint32 encrypted_x509_mac_smk = 10 [packed = true];
- if (this->encrypted_x509_mac_smk_size() > 0) {
- ::google::protobuf::internal::WireFormatLite::WriteTag(10, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
- output->WriteVarint32(_encrypted_x509_mac_smk_cached_byte_size_);
- }
- for (int i = 0; i < this->encrypted_x509_mac_smk_size(); i++) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
- this->encrypted_x509_mac_smk(i), output);
- }
-
- if (!unknown_fields().empty()) {
- ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
- unknown_fields(), output);
- }
- // @@protoc_insertion_point(serialize_end:Messages.SecretMessage)
+// repeated uint32 reserved = 14 [packed = true];
+int AttestationMessage::reserved_size() const {
+ return reserved_.size();
+}
+void AttestationMessage::clear_reserved() {
+ reserved_.Clear();
+}
+ ::google::protobuf::uint32 AttestationMessage::reserved(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.reserved)
+ return reserved_.Get(index);
+}
+ void AttestationMessage::set_reserved(int index, ::google::protobuf::uint32 value) {
+ reserved_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.reserved)
+}
+ void AttestationMessage::add_reserved(::google::protobuf::uint32 value) {
+ reserved_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.AttestationMessage.reserved)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+AttestationMessage::reserved() const {
+ // @@protoc_insertion_point(field_list:Messages.AttestationMessage.reserved)
+ return reserved_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+AttestationMessage::mutable_reserved() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.reserved)
+ return &reserved_;
}
-::google::protobuf::uint8* SecretMessage::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
- // @@protoc_insertion_point(serialize_to_array_start:Messages.SecretMessage)
- // required uint32 type = 1;
- if (has_type()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->type(), target);
- }
-
- // required uint32 size = 2;
- if (has_size()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->size(), target);
- }
-
- // optional uint32 encryped_pkey_size = 3;
- if (has_encryped_pkey_size()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->encryped_pkey_size(), target);
- }
-
- // optional uint32 encryped_x509_size = 4;
- if (has_encryped_x509_size()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->encryped_x509_size(), target);
- }
-
- // repeated uint32 encrypted_content = 5 [packed = true];
- if (this->encrypted_content_size() > 0) {
- target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
- 5,
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
- target);
- target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
- _encrypted_content_cached_byte_size_, target);
- }
- for (int i = 0; i < this->encrypted_content_size(); i++) {
- target = ::google::protobuf::internal::WireFormatLite::
- WriteUInt32NoTagToArray(this->encrypted_content(i), target);
- }
-
- // repeated uint32 mac_smk = 6 [packed = true];
- if (this->mac_smk_size() > 0) {
- target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
- 6,
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
- target);
- target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
- _mac_smk_cached_byte_size_, target);
- }
- for (int i = 0; i < this->mac_smk_size(); i++) {
- target = ::google::protobuf::internal::WireFormatLite::
- WriteUInt32NoTagToArray(this->mac_smk(i), target);
- }
-
- // repeated uint32 encrypted_pkey = 7 [packed = true];
- if (this->encrypted_pkey_size() > 0) {
- target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
- 7,
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
- target);
- target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
- _encrypted_pkey_cached_byte_size_, target);
- }
- for (int i = 0; i < this->encrypted_pkey_size(); i++) {
- target = ::google::protobuf::internal::WireFormatLite::
- WriteUInt32NoTagToArray(this->encrypted_pkey(i), target);
- }
-
- // repeated uint32 encrypted_pkey_mac_smk = 8 [packed = true];
- if (this->encrypted_pkey_mac_smk_size() > 0) {
- target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
- 8,
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
- target);
- target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
- _encrypted_pkey_mac_smk_cached_byte_size_, target);
- }
- for (int i = 0; i < this->encrypted_pkey_mac_smk_size(); i++) {
- target = ::google::protobuf::internal::WireFormatLite::
- WriteUInt32NoTagToArray(this->encrypted_pkey_mac_smk(i), target);
- }
-
- // repeated uint32 encrypted_x509 = 9 [packed = true];
- if (this->encrypted_x509_size() > 0) {
- target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
- 9,
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
- target);
- target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
- _encrypted_x509_cached_byte_size_, target);
- }
- for (int i = 0; i < this->encrypted_x509_size(); i++) {
- target = ::google::protobuf::internal::WireFormatLite::
- WriteUInt32NoTagToArray(this->encrypted_x509(i), target);
- }
-
- // repeated uint32 encrypted_x509_mac_smk = 10 [packed = true];
- if (this->encrypted_x509_mac_smk_size() > 0) {
- target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
- 10,
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
- target);
- target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
- _encrypted_x509_mac_smk_cached_byte_size_, target);
- }
- for (int i = 0; i < this->encrypted_x509_mac_smk_size(); i++) {
- target = ::google::protobuf::internal::WireFormatLite::
- WriteUInt32NoTagToArray(this->encrypted_x509_mac_smk(i), target);
- }
-
- if (!unknown_fields().empty()) {
- target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
- unknown_fields(), target);
- }
- // @@protoc_insertion_point(serialize_to_array_end:Messages.SecretMessage)
- return target;
+// repeated uint32 payload_tag = 15 [packed = true];
+int AttestationMessage::payload_tag_size() const {
+ return payload_tag_.size();
+}
+void AttestationMessage::clear_payload_tag() {
+ payload_tag_.Clear();
+}
+ ::google::protobuf::uint32 AttestationMessage::payload_tag(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.payload_tag)
+ return payload_tag_.Get(index);
+}
+ void AttestationMessage::set_payload_tag(int index, ::google::protobuf::uint32 value) {
+ payload_tag_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.payload_tag)
+}
+ void AttestationMessage::add_payload_tag(::google::protobuf::uint32 value) {
+ payload_tag_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.AttestationMessage.payload_tag)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+AttestationMessage::payload_tag() const {
+ // @@protoc_insertion_point(field_list:Messages.AttestationMessage.payload_tag)
+ return payload_tag_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+AttestationMessage::mutable_payload_tag() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.payload_tag)
+ return &payload_tag_;
}
-int SecretMessage::ByteSize() const {
- int total_size = 0;
-
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- // required uint32 type = 1;
- if (has_type()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->type());
- }
-
- // required uint32 size = 2;
- if (has_size()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->size());
- }
-
- // optional uint32 encryped_pkey_size = 3;
- if (has_encryped_pkey_size()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->encryped_pkey_size());
- }
-
- // optional uint32 encryped_x509_size = 4;
- if (has_encryped_x509_size()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->encryped_x509_size());
- }
-
- }
- // repeated uint32 encrypted_content = 5 [packed = true];
- {
- int data_size = 0;
- for (int i = 0; i < this->encrypted_content_size(); i++) {
- data_size += ::google::protobuf::internal::WireFormatLite::
- UInt32Size(this->encrypted_content(i));
- }
- if (data_size > 0) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
- }
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _encrypted_content_cached_byte_size_ = data_size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
- total_size += data_size;
- }
-
- // repeated uint32 mac_smk = 6 [packed = true];
- {
- int data_size = 0;
- for (int i = 0; i < this->mac_smk_size(); i++) {
- data_size += ::google::protobuf::internal::WireFormatLite::
- UInt32Size(this->mac_smk(i));
- }
- if (data_size > 0) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
- }
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _mac_smk_cached_byte_size_ = data_size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
- total_size += data_size;
- }
-
- // repeated uint32 encrypted_pkey = 7 [packed = true];
- {
- int data_size = 0;
- for (int i = 0; i < this->encrypted_pkey_size(); i++) {
- data_size += ::google::protobuf::internal::WireFormatLite::
- UInt32Size(this->encrypted_pkey(i));
- }
- if (data_size > 0) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
- }
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _encrypted_pkey_cached_byte_size_ = data_size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
- total_size += data_size;
- }
-
- // repeated uint32 encrypted_pkey_mac_smk = 8 [packed = true];
- {
- int data_size = 0;
- for (int i = 0; i < this->encrypted_pkey_mac_smk_size(); i++) {
- data_size += ::google::protobuf::internal::WireFormatLite::
- UInt32Size(this->encrypted_pkey_mac_smk(i));
- }
- if (data_size > 0) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
- }
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _encrypted_pkey_mac_smk_cached_byte_size_ = data_size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
- total_size += data_size;
- }
-
- // repeated uint32 encrypted_x509 = 9 [packed = true];
- {
- int data_size = 0;
- for (int i = 0; i < this->encrypted_x509_size(); i++) {
- data_size += ::google::protobuf::internal::WireFormatLite::
- UInt32Size(this->encrypted_x509(i));
- }
- if (data_size > 0) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
- }
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _encrypted_x509_cached_byte_size_ = data_size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
- total_size += data_size;
- }
-
- // repeated uint32 encrypted_x509_mac_smk = 10 [packed = true];
- {
- int data_size = 0;
- for (int i = 0; i < this->encrypted_x509_mac_smk_size(); i++) {
- data_size += ::google::protobuf::internal::WireFormatLite::
- UInt32Size(this->encrypted_x509_mac_smk(i));
- }
- if (data_size > 0) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
- }
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _encrypted_x509_mac_smk_cached_byte_size_ = data_size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
- total_size += data_size;
- }
-
- if (!unknown_fields().empty()) {
- total_size +=
- ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
- unknown_fields());
- }
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _cached_size_ = total_size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
- return total_size;
+// repeated uint32 payload = 16 [packed = true];
+int AttestationMessage::payload_size() const {
+ return payload_.size();
+}
+void AttestationMessage::clear_payload() {
+ payload_.Clear();
+}
+ ::google::protobuf::uint32 AttestationMessage::payload(int index) const {
+ // @@protoc_insertion_point(field_get:Messages.AttestationMessage.payload)
+ return payload_.Get(index);
+}
+ void AttestationMessage::set_payload(int index, ::google::protobuf::uint32 value) {
+ payload_.Set(index, value);
+ // @@protoc_insertion_point(field_set:Messages.AttestationMessage.payload)
+}
+ void AttestationMessage::add_payload(::google::protobuf::uint32 value) {
+ payload_.Add(value);
+ // @@protoc_insertion_point(field_add:Messages.AttestationMessage.payload)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+AttestationMessage::payload() const {
+ // @@protoc_insertion_point(field_list:Messages.AttestationMessage.payload)
+ return payload_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+AttestationMessage::mutable_payload() {
+ // @@protoc_insertion_point(field_mutable_list:Messages.AttestationMessage.payload)
+ return &payload_;
}
-void SecretMessage::MergeFrom(const ::google::protobuf::Message& from) {
- GOOGLE_CHECK_NE(&from, this);
- const SecretMessage* source =
- ::google::protobuf::internal::dynamic_cast_if_available<const SecretMessage*>(
- &from);
- if (source == NULL) {
- ::google::protobuf::internal::ReflectionOps::Merge(from, this);
- } else {
- MergeFrom(*source);
- }
-}
-
-void SecretMessage::MergeFrom(const SecretMessage& from) {
- GOOGLE_CHECK_NE(&from, this);
- encrypted_content_.MergeFrom(from.encrypted_content_);
- mac_smk_.MergeFrom(from.mac_smk_);
- encrypted_pkey_.MergeFrom(from.encrypted_pkey_);
- encrypted_pkey_mac_smk_.MergeFrom(from.encrypted_pkey_mac_smk_);
- encrypted_x509_.MergeFrom(from.encrypted_x509_);
- encrypted_x509_mac_smk_.MergeFrom(from.encrypted_x509_mac_smk_);
- if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from.has_type()) {
- set_type(from.type());
- }
- if (from.has_size()) {
- set_size(from.size());
- }
- if (from.has_encryped_pkey_size()) {
- set_encryped_pkey_size(from.encryped_pkey_size());
- }
- if (from.has_encryped_x509_size()) {
- set_encryped_x509_size(from.encryped_x509_size());
- }
- }
- mutable_unknown_fields()->MergeFrom(from.unknown_fields());
-}
-
-void SecretMessage::CopyFrom(const ::google::protobuf::Message& from) {
- if (&from == this) return;
- Clear();
- MergeFrom(from);
-}
-
-void SecretMessage::CopyFrom(const SecretMessage& from) {
- if (&from == this) return;
- Clear();
- MergeFrom(from);
-}
-
-bool SecretMessage::IsInitialized() const {
- if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;
-
- return true;
-}
-
-void SecretMessage::Swap(SecretMessage* other) {
- if (other != this) {
- std::swap(type_, other->type_);
- std::swap(size_, other->size_);
- std::swap(encryped_pkey_size_, other->encryped_pkey_size_);
- std::swap(encryped_x509_size_, other->encryped_x509_size_);
- encrypted_content_.Swap(&other->encrypted_content_);
- mac_smk_.Swap(&other->mac_smk_);
- encrypted_pkey_.Swap(&other->encrypted_pkey_);
- encrypted_pkey_mac_smk_.Swap(&other->encrypted_pkey_mac_smk_);
- encrypted_x509_.Swap(&other->encrypted_x509_);
- encrypted_x509_mac_smk_.Swap(&other->encrypted_x509_mac_smk_);
- std::swap(_has_bits_[0], other->_has_bits_[0]);
- _unknown_fields_.Swap(&other->_unknown_fields_);
- std::swap(_cached_size_, other->_cached_size_);
- }
-}
-
-::google::protobuf::Metadata SecretMessage::GetMetadata() const {
- protobuf_AssignDescriptorsOnce();
- ::google::protobuf::Metadata metadata;
- metadata.descriptor = SecretMessage_descriptor_;
- metadata.reflection = SecretMessage_reflection_;
- return metadata;
-}
-
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
// @@protoc_insertion_point(namespace_scope)
diff --git a/samplecode/remoteattestation/GoogleMessages/Messages.pb.h b/samplecode/remoteattestation/GoogleMessages/Messages.pb.h
index 8c2e78f..3acdf98 100644
--- a/samplecode/remoteattestation/GoogleMessages/Messages.pb.h
+++ b/samplecode/remoteattestation/GoogleMessages/Messages.pb.h
@@ -8,18 +8,21 @@
#include <google/protobuf/stubs/common.h>
-#if GOOGLE_PROTOBUF_VERSION < 2006000
+#if GOOGLE_PROTOBUF_VERSION < 3000000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
-#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
@@ -29,21 +32,20 @@
namespace Messages {
// Internal implementation detail -- do not call these.
-void protobuf_AddDesc_Messages_2eproto();
+void protobuf_AddDesc_Messages_2eproto();
void protobuf_AssignDesc_Messages_2eproto();
void protobuf_ShutdownFile_Messages_2eproto();
+class AttestationMessage;
class InitialMessage;
-class MessageMsg0;
class MessageMSG1;
class MessageMSG2;
class MessageMSG3;
-class AttestationMessage;
-class SecretMessage;
+class MessageMsg0;
// ===================================================================
-class InitialMessage : public ::google::protobuf::Message {
+class InitialMessage : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Messages.InitialMessage) */ {
public:
InitialMessage();
virtual ~InitialMessage();
@@ -56,11 +58,11 @@
}
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
- return _unknown_fields_;
+ return _internal_metadata_.unknown_fields();
}
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
- return &_unknown_fields_;
+ return _internal_metadata_.mutable_unknown_fields();
}
static const ::google::protobuf::Descriptor* descriptor();
@@ -70,7 +72,9 @@
// implements Message ----------------------------------------------
- InitialMessage* New() const;
+ inline InitialMessage* New() const { return New(NULL); }
+
+ InitialMessage* New(::google::protobuf::Arena* arena) const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
void CopyFrom(const InitialMessage& from);
@@ -83,13 +87,26 @@
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
+ void InternalSwap(InitialMessage* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return _internal_metadata_.arena();
+ }
+ inline void* MaybeArenaPtr() const {
+ return _internal_metadata_.raw_arena_ptr();
+ }
public:
+
::google::protobuf::Metadata GetMetadata() const;
// nested types ----------------------------------------------------
@@ -97,18 +114,18 @@
// accessors -------------------------------------------------------
// required uint32 type = 1;
- inline bool has_type() const;
- inline void clear_type();
+ bool has_type() const;
+ void clear_type();
static const int kTypeFieldNumber = 1;
- inline ::google::protobuf::uint32 type() const;
- inline void set_type(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 type() const;
+ void set_type(::google::protobuf::uint32 value);
// optional uint32 size = 2;
- inline bool has_size() const;
- inline void clear_size();
+ bool has_size() const;
+ void clear_size();
static const int kSizeFieldNumber = 2;
- inline ::google::protobuf::uint32 size() const;
- inline void set_size(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 size() const;
+ void set_size(::google::protobuf::uint32 value);
// @@protoc_insertion_point(class_scope:Messages.InitialMessage)
private:
@@ -117,8 +134,7 @@
inline void set_has_size();
inline void clear_has_size();
- ::google::protobuf::UnknownFieldSet _unknown_fields_;
-
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
::google::protobuf::uint32 type_;
@@ -132,7 +148,7 @@
};
// -------------------------------------------------------------------
-class MessageMsg0 : public ::google::protobuf::Message {
+class MessageMsg0 : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Messages.MessageMsg0) */ {
public:
MessageMsg0();
virtual ~MessageMsg0();
@@ -145,11 +161,11 @@
}
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
- return _unknown_fields_;
+ return _internal_metadata_.unknown_fields();
}
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
- return &_unknown_fields_;
+ return _internal_metadata_.mutable_unknown_fields();
}
static const ::google::protobuf::Descriptor* descriptor();
@@ -159,7 +175,9 @@
// implements Message ----------------------------------------------
- MessageMsg0* New() const;
+ inline MessageMsg0* New() const { return New(NULL); }
+
+ MessageMsg0* New(::google::protobuf::Arena* arena) const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
void CopyFrom(const MessageMsg0& from);
@@ -172,13 +190,26 @@
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
+ void InternalSwap(MessageMsg0* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return _internal_metadata_.arena();
+ }
+ inline void* MaybeArenaPtr() const {
+ return _internal_metadata_.raw_arena_ptr();
+ }
public:
+
::google::protobuf::Metadata GetMetadata() const;
// nested types ----------------------------------------------------
@@ -186,25 +217,25 @@
// accessors -------------------------------------------------------
// required uint32 type = 1;
- inline bool has_type() const;
- inline void clear_type();
+ bool has_type() const;
+ void clear_type();
static const int kTypeFieldNumber = 1;
- inline ::google::protobuf::uint32 type() const;
- inline void set_type(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 type() const;
+ void set_type(::google::protobuf::uint32 value);
// required uint32 epid = 2;
- inline bool has_epid() const;
- inline void clear_epid();
+ bool has_epid() const;
+ void clear_epid();
static const int kEpidFieldNumber = 2;
- inline ::google::protobuf::uint32 epid() const;
- inline void set_epid(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 epid() const;
+ void set_epid(::google::protobuf::uint32 value);
// optional uint32 status = 3;
- inline bool has_status() const;
- inline void clear_status();
+ bool has_status() const;
+ void clear_status();
static const int kStatusFieldNumber = 3;
- inline ::google::protobuf::uint32 status() const;
- inline void set_status(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 status() const;
+ void set_status(::google::protobuf::uint32 value);
// @@protoc_insertion_point(class_scope:Messages.MessageMsg0)
private:
@@ -215,8 +246,10 @@
inline void set_has_status();
inline void clear_has_status();
- ::google::protobuf::UnknownFieldSet _unknown_fields_;
+ // helper for ByteSize()
+ int RequiredFieldsByteSizeFallback() const;
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
::google::protobuf::uint32 type_;
@@ -231,7 +264,7 @@
};
// -------------------------------------------------------------------
-class MessageMSG1 : public ::google::protobuf::Message {
+class MessageMSG1 : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Messages.MessageMSG1) */ {
public:
MessageMSG1();
virtual ~MessageMSG1();
@@ -244,11 +277,11 @@
}
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
- return _unknown_fields_;
+ return _internal_metadata_.unknown_fields();
}
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
- return &_unknown_fields_;
+ return _internal_metadata_.mutable_unknown_fields();
}
static const ::google::protobuf::Descriptor* descriptor();
@@ -258,7 +291,9 @@
// implements Message ----------------------------------------------
- MessageMSG1* New() const;
+ inline MessageMSG1* New() const { return New(NULL); }
+
+ MessageMSG1* New(::google::protobuf::Arena* arena) const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
void CopyFrom(const MessageMSG1& from);
@@ -271,13 +306,26 @@
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
+ void InternalSwap(MessageMSG1* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return _internal_metadata_.arena();
+ }
+ inline void* MaybeArenaPtr() const {
+ return _internal_metadata_.raw_arena_ptr();
+ }
public:
+
::google::protobuf::Metadata GetMetadata() const;
// nested types ----------------------------------------------------
@@ -285,46 +333,46 @@
// accessors -------------------------------------------------------
// required uint32 type = 1;
- inline bool has_type() const;
- inline void clear_type();
+ bool has_type() const;
+ void clear_type();
static const int kTypeFieldNumber = 1;
- inline ::google::protobuf::uint32 type() const;
- inline void set_type(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 type() const;
+ void set_type(::google::protobuf::uint32 value);
// repeated uint32 GaX = 2 [packed = true];
- inline int gax_size() const;
- inline void clear_gax();
+ int gax_size() const;
+ void clear_gax();
static const int kGaXFieldNumber = 2;
- inline ::google::protobuf::uint32 gax(int index) const;
- inline void set_gax(int index, ::google::protobuf::uint32 value);
- inline void add_gax(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 gax(int index) const;
+ void set_gax(int index, ::google::protobuf::uint32 value);
+ void add_gax(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
gax() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_gax();
// repeated uint32 GaY = 3 [packed = true];
- inline int gay_size() const;
- inline void clear_gay();
+ int gay_size() const;
+ void clear_gay();
static const int kGaYFieldNumber = 3;
- inline ::google::protobuf::uint32 gay(int index) const;
- inline void set_gay(int index, ::google::protobuf::uint32 value);
- inline void add_gay(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 gay(int index) const;
+ void set_gay(int index, ::google::protobuf::uint32 value);
+ void add_gay(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
gay() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_gay();
// repeated uint32 GID = 4 [packed = true];
- inline int gid_size() const;
- inline void clear_gid();
+ int gid_size() const;
+ void clear_gid();
static const int kGIDFieldNumber = 4;
- inline ::google::protobuf::uint32 gid(int index) const;
- inline void set_gid(int index, ::google::protobuf::uint32 value);
- inline void add_gid(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 gid(int index) const;
+ void set_gid(int index, ::google::protobuf::uint32 value);
+ void add_gid(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
gid() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_gid();
// @@protoc_insertion_point(class_scope:Messages.MessageMSG1)
@@ -332,8 +380,7 @@
inline void set_has_type();
inline void clear_has_type();
- ::google::protobuf::UnknownFieldSet _unknown_fields_;
-
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
::google::protobuf::RepeatedField< ::google::protobuf::uint32 > gax_;
@@ -352,7 +399,7 @@
};
// -------------------------------------------------------------------
-class MessageMSG2 : public ::google::protobuf::Message {
+class MessageMSG2 : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Messages.MessageMSG2) */ {
public:
MessageMSG2();
virtual ~MessageMSG2();
@@ -365,11 +412,11 @@
}
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
- return _unknown_fields_;
+ return _internal_metadata_.unknown_fields();
}
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
- return &_unknown_fields_;
+ return _internal_metadata_.mutable_unknown_fields();
}
static const ::google::protobuf::Descriptor* descriptor();
@@ -379,7 +426,9 @@
// implements Message ----------------------------------------------
- MessageMSG2* New() const;
+ inline MessageMSG2* New() const { return New(NULL); }
+
+ MessageMSG2* New(::google::protobuf::Arena* arena) const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
void CopyFrom(const MessageMSG2& from);
@@ -392,13 +441,26 @@
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
+ void InternalSwap(MessageMSG2* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return _internal_metadata_.arena();
+ }
+ inline void* MaybeArenaPtr() const {
+ return _internal_metadata_.raw_arena_ptr();
+ }
public:
+
::google::protobuf::Metadata GetMetadata() const;
// nested types ----------------------------------------------------
@@ -406,122 +468,122 @@
// accessors -------------------------------------------------------
// required uint32 type = 1;
- inline bool has_type() const;
- inline void clear_type();
+ bool has_type() const;
+ void clear_type();
static const int kTypeFieldNumber = 1;
- inline ::google::protobuf::uint32 type() const;
- inline void set_type(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 type() const;
+ void set_type(::google::protobuf::uint32 value);
// optional uint32 size = 2;
- inline bool has_size() const;
- inline void clear_size();
+ bool has_size() const;
+ void clear_size();
static const int kSizeFieldNumber = 2;
- inline ::google::protobuf::uint32 size() const;
- inline void set_size(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 size() const;
+ void set_size(::google::protobuf::uint32 value);
// repeated uint32 public_key_gx = 3 [packed = true];
- inline int public_key_gx_size() const;
- inline void clear_public_key_gx();
+ int public_key_gx_size() const;
+ void clear_public_key_gx();
static const int kPublicKeyGxFieldNumber = 3;
- inline ::google::protobuf::uint32 public_key_gx(int index) const;
- inline void set_public_key_gx(int index, ::google::protobuf::uint32 value);
- inline void add_public_key_gx(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 public_key_gx(int index) const;
+ void set_public_key_gx(int index, ::google::protobuf::uint32 value);
+ void add_public_key_gx(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
public_key_gx() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_public_key_gx();
// repeated uint32 public_key_gy = 4 [packed = true];
- inline int public_key_gy_size() const;
- inline void clear_public_key_gy();
+ int public_key_gy_size() const;
+ void clear_public_key_gy();
static const int kPublicKeyGyFieldNumber = 4;
- inline ::google::protobuf::uint32 public_key_gy(int index) const;
- inline void set_public_key_gy(int index, ::google::protobuf::uint32 value);
- inline void add_public_key_gy(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 public_key_gy(int index) const;
+ void set_public_key_gy(int index, ::google::protobuf::uint32 value);
+ void add_public_key_gy(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
public_key_gy() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_public_key_gy();
// optional uint32 quote_type = 5;
- inline bool has_quote_type() const;
- inline void clear_quote_type();
+ bool has_quote_type() const;
+ void clear_quote_type();
static const int kQuoteTypeFieldNumber = 5;
- inline ::google::protobuf::uint32 quote_type() const;
- inline void set_quote_type(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 quote_type() const;
+ void set_quote_type(::google::protobuf::uint32 value);
// repeated uint32 spid = 6 [packed = true];
- inline int spid_size() const;
- inline void clear_spid();
+ int spid_size() const;
+ void clear_spid();
static const int kSpidFieldNumber = 6;
- inline ::google::protobuf::uint32 spid(int index) const;
- inline void set_spid(int index, ::google::protobuf::uint32 value);
- inline void add_spid(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 spid(int index) const;
+ void set_spid(int index, ::google::protobuf::uint32 value);
+ void add_spid(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
spid() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_spid();
// optional uint32 cmac_kdf_id = 7;
- inline bool has_cmac_kdf_id() const;
- inline void clear_cmac_kdf_id();
+ bool has_cmac_kdf_id() const;
+ void clear_cmac_kdf_id();
static const int kCmacKdfIdFieldNumber = 7;
- inline ::google::protobuf::uint32 cmac_kdf_id() const;
- inline void set_cmac_kdf_id(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 cmac_kdf_id() const;
+ void set_cmac_kdf_id(::google::protobuf::uint32 value);
// repeated uint32 signature_x = 8 [packed = true];
- inline int signature_x_size() const;
- inline void clear_signature_x();
+ int signature_x_size() const;
+ void clear_signature_x();
static const int kSignatureXFieldNumber = 8;
- inline ::google::protobuf::uint32 signature_x(int index) const;
- inline void set_signature_x(int index, ::google::protobuf::uint32 value);
- inline void add_signature_x(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 signature_x(int index) const;
+ void set_signature_x(int index, ::google::protobuf::uint32 value);
+ void add_signature_x(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
signature_x() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_signature_x();
// repeated uint32 signature_y = 9 [packed = true];
- inline int signature_y_size() const;
- inline void clear_signature_y();
+ int signature_y_size() const;
+ void clear_signature_y();
static const int kSignatureYFieldNumber = 9;
- inline ::google::protobuf::uint32 signature_y(int index) const;
- inline void set_signature_y(int index, ::google::protobuf::uint32 value);
- inline void add_signature_y(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 signature_y(int index) const;
+ void set_signature_y(int index, ::google::protobuf::uint32 value);
+ void add_signature_y(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
signature_y() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_signature_y();
// repeated uint32 smac = 10 [packed = true];
- inline int smac_size() const;
- inline void clear_smac();
+ int smac_size() const;
+ void clear_smac();
static const int kSmacFieldNumber = 10;
- inline ::google::protobuf::uint32 smac(int index) const;
- inline void set_smac(int index, ::google::protobuf::uint32 value);
- inline void add_smac(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 smac(int index) const;
+ void set_smac(int index, ::google::protobuf::uint32 value);
+ void add_smac(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
smac() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_smac();
// optional uint32 size_sigrl = 11;
- inline bool has_size_sigrl() const;
- inline void clear_size_sigrl();
+ bool has_size_sigrl() const;
+ void clear_size_sigrl();
static const int kSizeSigrlFieldNumber = 11;
- inline ::google::protobuf::uint32 size_sigrl() const;
- inline void set_size_sigrl(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 size_sigrl() const;
+ void set_size_sigrl(::google::protobuf::uint32 value);
// repeated uint32 sigrl = 12 [packed = true];
- inline int sigrl_size() const;
- inline void clear_sigrl();
+ int sigrl_size() const;
+ void clear_sigrl();
static const int kSigrlFieldNumber = 12;
- inline ::google::protobuf::uint32 sigrl(int index) const;
- inline void set_sigrl(int index, ::google::protobuf::uint32 value);
- inline void add_sigrl(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 sigrl(int index) const;
+ void set_sigrl(int index, ::google::protobuf::uint32 value);
+ void add_sigrl(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
sigrl() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_sigrl();
// @@protoc_insertion_point(class_scope:Messages.MessageMSG2)
@@ -537,8 +599,7 @@
inline void set_has_size_sigrl();
inline void clear_has_size_sigrl();
- ::google::protobuf::UnknownFieldSet _unknown_fields_;
-
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
::google::protobuf::uint32 type_;
@@ -569,7 +630,7 @@
};
// -------------------------------------------------------------------
-class MessageMSG3 : public ::google::protobuf::Message {
+class MessageMSG3 : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Messages.MessageMSG3) */ {
public:
MessageMSG3();
virtual ~MessageMSG3();
@@ -582,11 +643,11 @@
}
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
- return _unknown_fields_;
+ return _internal_metadata_.unknown_fields();
}
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
- return &_unknown_fields_;
+ return _internal_metadata_.mutable_unknown_fields();
}
static const ::google::protobuf::Descriptor* descriptor();
@@ -596,7 +657,9 @@
// implements Message ----------------------------------------------
- MessageMSG3* New() const;
+ inline MessageMSG3* New() const { return New(NULL); }
+
+ MessageMSG3* New(::google::protobuf::Arena* arena) const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
void CopyFrom(const MessageMSG3& from);
@@ -609,13 +672,26 @@
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
+ void InternalSwap(MessageMSG3* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return _internal_metadata_.arena();
+ }
+ inline void* MaybeArenaPtr() const {
+ return _internal_metadata_.raw_arena_ptr();
+ }
public:
+
::google::protobuf::Metadata GetMetadata() const;
// nested types ----------------------------------------------------
@@ -623,77 +699,77 @@
// accessors -------------------------------------------------------
// required uint32 type = 1;
- inline bool has_type() const;
- inline void clear_type();
+ bool has_type() const;
+ void clear_type();
static const int kTypeFieldNumber = 1;
- inline ::google::protobuf::uint32 type() const;
- inline void set_type(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 type() const;
+ void set_type(::google::protobuf::uint32 value);
// optional uint32 size = 2;
- inline bool has_size() const;
- inline void clear_size();
+ bool has_size() const;
+ void clear_size();
static const int kSizeFieldNumber = 2;
- inline ::google::protobuf::uint32 size() const;
- inline void set_size(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 size() const;
+ void set_size(::google::protobuf::uint32 value);
// repeated uint32 sgx_mac = 3 [packed = true];
- inline int sgx_mac_size() const;
- inline void clear_sgx_mac();
+ int sgx_mac_size() const;
+ void clear_sgx_mac();
static const int kSgxMacFieldNumber = 3;
- inline ::google::protobuf::uint32 sgx_mac(int index) const;
- inline void set_sgx_mac(int index, ::google::protobuf::uint32 value);
- inline void add_sgx_mac(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 sgx_mac(int index) const;
+ void set_sgx_mac(int index, ::google::protobuf::uint32 value);
+ void add_sgx_mac(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
sgx_mac() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_sgx_mac();
// repeated uint32 gax_msg3 = 4 [packed = true];
- inline int gax_msg3_size() const;
- inline void clear_gax_msg3();
+ int gax_msg3_size() const;
+ void clear_gax_msg3();
static const int kGaxMsg3FieldNumber = 4;
- inline ::google::protobuf::uint32 gax_msg3(int index) const;
- inline void set_gax_msg3(int index, ::google::protobuf::uint32 value);
- inline void add_gax_msg3(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 gax_msg3(int index) const;
+ void set_gax_msg3(int index, ::google::protobuf::uint32 value);
+ void add_gax_msg3(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
gax_msg3() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_gax_msg3();
// repeated uint32 gay_msg3 = 5 [packed = true];
- inline int gay_msg3_size() const;
- inline void clear_gay_msg3();
+ int gay_msg3_size() const;
+ void clear_gay_msg3();
static const int kGayMsg3FieldNumber = 5;
- inline ::google::protobuf::uint32 gay_msg3(int index) const;
- inline void set_gay_msg3(int index, ::google::protobuf::uint32 value);
- inline void add_gay_msg3(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 gay_msg3(int index) const;
+ void set_gay_msg3(int index, ::google::protobuf::uint32 value);
+ void add_gay_msg3(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
gay_msg3() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_gay_msg3();
// repeated uint32 sec_property = 6 [packed = true];
- inline int sec_property_size() const;
- inline void clear_sec_property();
+ int sec_property_size() const;
+ void clear_sec_property();
static const int kSecPropertyFieldNumber = 6;
- inline ::google::protobuf::uint32 sec_property(int index) const;
- inline void set_sec_property(int index, ::google::protobuf::uint32 value);
- inline void add_sec_property(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 sec_property(int index) const;
+ void set_sec_property(int index, ::google::protobuf::uint32 value);
+ void add_sec_property(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
sec_property() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_sec_property();
// repeated uint32 quote = 7 [packed = true];
- inline int quote_size() const;
- inline void clear_quote();
+ int quote_size() const;
+ void clear_quote();
static const int kQuoteFieldNumber = 7;
- inline ::google::protobuf::uint32 quote(int index) const;
- inline void set_quote(int index, ::google::protobuf::uint32 value);
- inline void add_quote(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 quote(int index) const;
+ void set_quote(int index, ::google::protobuf::uint32 value);
+ void add_quote(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
quote() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_quote();
// @@protoc_insertion_point(class_scope:Messages.MessageMSG3)
@@ -703,8 +779,7 @@
inline void set_has_size();
inline void clear_has_size();
- ::google::protobuf::UnknownFieldSet _unknown_fields_;
-
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
::google::protobuf::uint32 type_;
@@ -728,7 +803,7 @@
};
// -------------------------------------------------------------------
-class AttestationMessage : public ::google::protobuf::Message {
+class AttestationMessage : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Messages.AttestationMessage) */ {
public:
AttestationMessage();
virtual ~AttestationMessage();
@@ -741,11 +816,11 @@
}
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
- return _unknown_fields_;
+ return _internal_metadata_.unknown_fields();
}
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
- return &_unknown_fields_;
+ return _internal_metadata_.mutable_unknown_fields();
}
static const ::google::protobuf::Descriptor* descriptor();
@@ -755,7 +830,9 @@
// implements Message ----------------------------------------------
- AttestationMessage* New() const;
+ inline AttestationMessage* New() const { return New(NULL); }
+
+ AttestationMessage* New(::google::protobuf::Arena* arena) const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
void CopyFrom(const AttestationMessage& from);
@@ -768,13 +845,26 @@
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
+ void InternalSwap(AttestationMessage* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return _internal_metadata_.arena();
+ }
+ inline void* MaybeArenaPtr() const {
+ return _internal_metadata_.raw_arena_ptr();
+ }
public:
+
::google::protobuf::Metadata GetMetadata() const;
// nested types ----------------------------------------------------
@@ -782,165 +872,165 @@
// accessors -------------------------------------------------------
// required uint32 type = 1;
- inline bool has_type() const;
- inline void clear_type();
+ bool has_type() const;
+ void clear_type();
static const int kTypeFieldNumber = 1;
- inline ::google::protobuf::uint32 type() const;
- inline void set_type(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 type() const;
+ void set_type(::google::protobuf::uint32 value);
// required uint32 size = 2;
- inline bool has_size() const;
- inline void clear_size();
+ bool has_size() const;
+ void clear_size();
static const int kSizeFieldNumber = 2;
- inline ::google::protobuf::uint32 size() const;
- inline void set_size(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 size() const;
+ void set_size(::google::protobuf::uint32 value);
// optional uint32 epid_group_status = 3;
- inline bool has_epid_group_status() const;
- inline void clear_epid_group_status();
+ bool has_epid_group_status() const;
+ void clear_epid_group_status();
static const int kEpidGroupStatusFieldNumber = 3;
- inline ::google::protobuf::uint32 epid_group_status() const;
- inline void set_epid_group_status(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 epid_group_status() const;
+ void set_epid_group_status(::google::protobuf::uint32 value);
// optional uint32 tcb_evaluation_status = 4;
- inline bool has_tcb_evaluation_status() const;
- inline void clear_tcb_evaluation_status();
+ bool has_tcb_evaluation_status() const;
+ void clear_tcb_evaluation_status();
static const int kTcbEvaluationStatusFieldNumber = 4;
- inline ::google::protobuf::uint32 tcb_evaluation_status() const;
- inline void set_tcb_evaluation_status(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 tcb_evaluation_status() const;
+ void set_tcb_evaluation_status(::google::protobuf::uint32 value);
// optional uint32 pse_evaluation_status = 5;
- inline bool has_pse_evaluation_status() const;
- inline void clear_pse_evaluation_status();
+ bool has_pse_evaluation_status() const;
+ void clear_pse_evaluation_status();
static const int kPseEvaluationStatusFieldNumber = 5;
- inline ::google::protobuf::uint32 pse_evaluation_status() const;
- inline void set_pse_evaluation_status(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 pse_evaluation_status() const;
+ void set_pse_evaluation_status(::google::protobuf::uint32 value);
// repeated uint32 latest_equivalent_tcb_psvn = 6 [packed = true];
- inline int latest_equivalent_tcb_psvn_size() const;
- inline void clear_latest_equivalent_tcb_psvn();
+ int latest_equivalent_tcb_psvn_size() const;
+ void clear_latest_equivalent_tcb_psvn();
static const int kLatestEquivalentTcbPsvnFieldNumber = 6;
- inline ::google::protobuf::uint32 latest_equivalent_tcb_psvn(int index) const;
- inline void set_latest_equivalent_tcb_psvn(int index, ::google::protobuf::uint32 value);
- inline void add_latest_equivalent_tcb_psvn(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 latest_equivalent_tcb_psvn(int index) const;
+ void set_latest_equivalent_tcb_psvn(int index, ::google::protobuf::uint32 value);
+ void add_latest_equivalent_tcb_psvn(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
latest_equivalent_tcb_psvn() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_latest_equivalent_tcb_psvn();
// repeated uint32 latest_pse_isvsvn = 7 [packed = true];
- inline int latest_pse_isvsvn_size() const;
- inline void clear_latest_pse_isvsvn();
+ int latest_pse_isvsvn_size() const;
+ void clear_latest_pse_isvsvn();
static const int kLatestPseIsvsvnFieldNumber = 7;
- inline ::google::protobuf::uint32 latest_pse_isvsvn(int index) const;
- inline void set_latest_pse_isvsvn(int index, ::google::protobuf::uint32 value);
- inline void add_latest_pse_isvsvn(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 latest_pse_isvsvn(int index) const;
+ void set_latest_pse_isvsvn(int index, ::google::protobuf::uint32 value);
+ void add_latest_pse_isvsvn(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
latest_pse_isvsvn() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_latest_pse_isvsvn();
// repeated uint32 latest_psda_svn = 8 [packed = true];
- inline int latest_psda_svn_size() const;
- inline void clear_latest_psda_svn();
+ int latest_psda_svn_size() const;
+ void clear_latest_psda_svn();
static const int kLatestPsdaSvnFieldNumber = 8;
- inline ::google::protobuf::uint32 latest_psda_svn(int index) const;
- inline void set_latest_psda_svn(int index, ::google::protobuf::uint32 value);
- inline void add_latest_psda_svn(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 latest_psda_svn(int index) const;
+ void set_latest_psda_svn(int index, ::google::protobuf::uint32 value);
+ void add_latest_psda_svn(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
latest_psda_svn() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_latest_psda_svn();
// repeated uint32 performance_rekey_gid = 9 [packed = true];
- inline int performance_rekey_gid_size() const;
- inline void clear_performance_rekey_gid();
+ int performance_rekey_gid_size() const;
+ void clear_performance_rekey_gid();
static const int kPerformanceRekeyGidFieldNumber = 9;
- inline ::google::protobuf::uint32 performance_rekey_gid(int index) const;
- inline void set_performance_rekey_gid(int index, ::google::protobuf::uint32 value);
- inline void add_performance_rekey_gid(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 performance_rekey_gid(int index) const;
+ void set_performance_rekey_gid(int index, ::google::protobuf::uint32 value);
+ void add_performance_rekey_gid(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
performance_rekey_gid() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_performance_rekey_gid();
// repeated uint32 ec_sign256_x = 10 [packed = true];
- inline int ec_sign256_x_size() const;
- inline void clear_ec_sign256_x();
+ int ec_sign256_x_size() const;
+ void clear_ec_sign256_x();
static const int kEcSign256XFieldNumber = 10;
- inline ::google::protobuf::uint32 ec_sign256_x(int index) const;
- inline void set_ec_sign256_x(int index, ::google::protobuf::uint32 value);
- inline void add_ec_sign256_x(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 ec_sign256_x(int index) const;
+ void set_ec_sign256_x(int index, ::google::protobuf::uint32 value);
+ void add_ec_sign256_x(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
ec_sign256_x() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_ec_sign256_x();
// repeated uint32 ec_sign256_y = 11 [packed = true];
- inline int ec_sign256_y_size() const;
- inline void clear_ec_sign256_y();
+ int ec_sign256_y_size() const;
+ void clear_ec_sign256_y();
static const int kEcSign256YFieldNumber = 11;
- inline ::google::protobuf::uint32 ec_sign256_y(int index) const;
- inline void set_ec_sign256_y(int index, ::google::protobuf::uint32 value);
- inline void add_ec_sign256_y(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 ec_sign256_y(int index) const;
+ void set_ec_sign256_y(int index, ::google::protobuf::uint32 value);
+ void add_ec_sign256_y(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
ec_sign256_y() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_ec_sign256_y();
// repeated uint32 mac_smk = 12 [packed = true];
- inline int mac_smk_size() const;
- inline void clear_mac_smk();
+ int mac_smk_size() const;
+ void clear_mac_smk();
static const int kMacSmkFieldNumber = 12;
- inline ::google::protobuf::uint32 mac_smk(int index) const;
- inline void set_mac_smk(int index, ::google::protobuf::uint32 value);
- inline void add_mac_smk(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 mac_smk(int index) const;
+ void set_mac_smk(int index, ::google::protobuf::uint32 value);
+ void add_mac_smk(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
mac_smk() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_mac_smk();
// optional uint32 result_size = 13;
- inline bool has_result_size() const;
- inline void clear_result_size();
+ bool has_result_size() const;
+ void clear_result_size();
static const int kResultSizeFieldNumber = 13;
- inline ::google::protobuf::uint32 result_size() const;
- inline void set_result_size(::google::protobuf::uint32 value);
+ ::google::protobuf::uint32 result_size() const;
+ void set_result_size(::google::protobuf::uint32 value);
// repeated uint32 reserved = 14 [packed = true];
- inline int reserved_size() const;
- inline void clear_reserved();
+ int reserved_size() const;
+ void clear_reserved();
static const int kReservedFieldNumber = 14;
- inline ::google::protobuf::uint32 reserved(int index) const;
- inline void set_reserved(int index, ::google::protobuf::uint32 value);
- inline void add_reserved(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 reserved(int index) const;
+ void set_reserved(int index, ::google::protobuf::uint32 value);
+ void add_reserved(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
reserved() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_reserved();
// repeated uint32 payload_tag = 15 [packed = true];
- inline int payload_tag_size() const;
- inline void clear_payload_tag();
+ int payload_tag_size() const;
+ void clear_payload_tag();
static const int kPayloadTagFieldNumber = 15;
- inline ::google::protobuf::uint32 payload_tag(int index) const;
- inline void set_payload_tag(int index, ::google::protobuf::uint32 value);
- inline void add_payload_tag(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 payload_tag(int index) const;
+ void set_payload_tag(int index, ::google::protobuf::uint32 value);
+ void add_payload_tag(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
payload_tag() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_payload_tag();
// repeated uint32 payload = 16 [packed = true];
- inline int payload_size() const;
- inline void clear_payload();
+ int payload_size() const;
+ void clear_payload();
static const int kPayloadFieldNumber = 16;
- inline ::google::protobuf::uint32 payload(int index) const;
- inline void set_payload(int index, ::google::protobuf::uint32 value);
- inline void add_payload(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+ ::google::protobuf::uint32 payload(int index) const;
+ void set_payload(int index, ::google::protobuf::uint32 value);
+ void add_payload(::google::protobuf::uint32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
payload() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+ ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
mutable_payload();
// @@protoc_insertion_point(class_scope:Messages.AttestationMessage)
@@ -958,8 +1048,10 @@
inline void set_has_result_size();
inline void clear_has_result_size();
- ::google::protobuf::UnknownFieldSet _unknown_fields_;
+ // helper for ByteSize()
+ int RequiredFieldsByteSizeFallback() const;
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
::google::protobuf::uint32 type_;
@@ -995,204 +1087,12 @@
void InitAsDefaultInstance();
static AttestationMessage* default_instance_;
};
-// -------------------------------------------------------------------
-
-class SecretMessage : public ::google::protobuf::Message {
- public:
- SecretMessage();
- virtual ~SecretMessage();
-
- SecretMessage(const SecretMessage& from);
-
- inline SecretMessage& operator=(const SecretMessage& from) {
- CopyFrom(from);
- return *this;
- }
-
- inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
- return _unknown_fields_;
- }
-
- inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
- return &_unknown_fields_;
- }
-
- static const ::google::protobuf::Descriptor* descriptor();
- static const SecretMessage& default_instance();
-
- void Swap(SecretMessage* other);
-
- // implements Message ----------------------------------------------
-
- SecretMessage* New() const;
- void CopyFrom(const ::google::protobuf::Message& from);
- void MergeFrom(const ::google::protobuf::Message& from);
- void CopyFrom(const SecretMessage& from);
- void MergeFrom(const SecretMessage& from);
- void Clear();
- bool IsInitialized() const;
-
- int ByteSize() const;
- bool MergePartialFromCodedStream(
- ::google::protobuf::io::CodedInputStream* input);
- void SerializeWithCachedSizes(
- ::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
- int GetCachedSize() const { return _cached_size_; }
- private:
- void SharedCtor();
- void SharedDtor();
- void SetCachedSize(int size) const;
- public:
- ::google::protobuf::Metadata GetMetadata() const;
-
- // nested types ----------------------------------------------------
-
- // accessors -------------------------------------------------------
-
- // required uint32 type = 1;
- inline bool has_type() const;
- inline void clear_type();
- static const int kTypeFieldNumber = 1;
- inline ::google::protobuf::uint32 type() const;
- inline void set_type(::google::protobuf::uint32 value);
-
- // required uint32 size = 2;
- inline bool has_size() const;
- inline void clear_size();
- static const int kSizeFieldNumber = 2;
- inline ::google::protobuf::uint32 size() const;
- inline void set_size(::google::protobuf::uint32 value);
-
- // optional uint32 encryped_pkey_size = 3;
- inline bool has_encryped_pkey_size() const;
- inline void clear_encryped_pkey_size();
- static const int kEncrypedPkeySizeFieldNumber = 3;
- inline ::google::protobuf::uint32 encryped_pkey_size() const;
- inline void set_encryped_pkey_size(::google::protobuf::uint32 value);
-
- // optional uint32 encryped_x509_size = 4;
- inline bool has_encryped_x509_size() const;
- inline void clear_encryped_x509_size();
- static const int kEncrypedX509SizeFieldNumber = 4;
- inline ::google::protobuf::uint32 encryped_x509_size() const;
- inline void set_encryped_x509_size(::google::protobuf::uint32 value);
-
- // repeated uint32 encrypted_content = 5 [packed = true];
- inline int encrypted_content_size() const;
- inline void clear_encrypted_content();
- static const int kEncryptedContentFieldNumber = 5;
- inline ::google::protobuf::uint32 encrypted_content(int index) const;
- inline void set_encrypted_content(int index, ::google::protobuf::uint32 value);
- inline void add_encrypted_content(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
- encrypted_content() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
- mutable_encrypted_content();
-
- // repeated uint32 mac_smk = 6 [packed = true];
- inline int mac_smk_size() const;
- inline void clear_mac_smk();
- static const int kMacSmkFieldNumber = 6;
- inline ::google::protobuf::uint32 mac_smk(int index) const;
- inline void set_mac_smk(int index, ::google::protobuf::uint32 value);
- inline void add_mac_smk(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
- mac_smk() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
- mutable_mac_smk();
-
- // repeated uint32 encrypted_pkey = 7 [packed = true];
- inline int encrypted_pkey_size() const;
- inline void clear_encrypted_pkey();
- static const int kEncryptedPkeyFieldNumber = 7;
- inline ::google::protobuf::uint32 encrypted_pkey(int index) const;
- inline void set_encrypted_pkey(int index, ::google::protobuf::uint32 value);
- inline void add_encrypted_pkey(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
- encrypted_pkey() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
- mutable_encrypted_pkey();
-
- // repeated uint32 encrypted_pkey_mac_smk = 8 [packed = true];
- inline int encrypted_pkey_mac_smk_size() const;
- inline void clear_encrypted_pkey_mac_smk();
- static const int kEncryptedPkeyMacSmkFieldNumber = 8;
- inline ::google::protobuf::uint32 encrypted_pkey_mac_smk(int index) const;
- inline void set_encrypted_pkey_mac_smk(int index, ::google::protobuf::uint32 value);
- inline void add_encrypted_pkey_mac_smk(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
- encrypted_pkey_mac_smk() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
- mutable_encrypted_pkey_mac_smk();
-
- // repeated uint32 encrypted_x509 = 9 [packed = true];
- inline int encrypted_x509_size() const;
- inline void clear_encrypted_x509();
- static const int kEncryptedX509FieldNumber = 9;
- inline ::google::protobuf::uint32 encrypted_x509(int index) const;
- inline void set_encrypted_x509(int index, ::google::protobuf::uint32 value);
- inline void add_encrypted_x509(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
- encrypted_x509() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
- mutable_encrypted_x509();
-
- // repeated uint32 encrypted_x509_mac_smk = 10 [packed = true];
- inline int encrypted_x509_mac_smk_size() const;
- inline void clear_encrypted_x509_mac_smk();
- static const int kEncryptedX509MacSmkFieldNumber = 10;
- inline ::google::protobuf::uint32 encrypted_x509_mac_smk(int index) const;
- inline void set_encrypted_x509_mac_smk(int index, ::google::protobuf::uint32 value);
- inline void add_encrypted_x509_mac_smk(::google::protobuf::uint32 value);
- inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
- encrypted_x509_mac_smk() const;
- inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
- mutable_encrypted_x509_mac_smk();
-
- // @@protoc_insertion_point(class_scope:Messages.SecretMessage)
- private:
- inline void set_has_type();
- inline void clear_has_type();
- inline void set_has_size();
- inline void clear_has_size();
- inline void set_has_encryped_pkey_size();
- inline void clear_has_encryped_pkey_size();
- inline void set_has_encryped_x509_size();
- inline void clear_has_encryped_x509_size();
-
- ::google::protobuf::UnknownFieldSet _unknown_fields_;
-
- ::google::protobuf::uint32 _has_bits_[1];
- mutable int _cached_size_;
- ::google::protobuf::uint32 type_;
- ::google::protobuf::uint32 size_;
- ::google::protobuf::uint32 encryped_pkey_size_;
- ::google::protobuf::uint32 encryped_x509_size_;
- ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > encrypted_content_;
- mutable int _encrypted_content_cached_byte_size_;
- ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > mac_smk_;
- mutable int _mac_smk_cached_byte_size_;
- ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > encrypted_pkey_;
- mutable int _encrypted_pkey_cached_byte_size_;
- ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > encrypted_pkey_mac_smk_;
- mutable int _encrypted_pkey_mac_smk_cached_byte_size_;
- ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > encrypted_x509_;
- mutable int _encrypted_x509_cached_byte_size_;
- ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > encrypted_x509_mac_smk_;
- mutable int _encrypted_x509_mac_smk_cached_byte_size_;
- friend void protobuf_AddDesc_Messages_2eproto();
- friend void protobuf_AssignDesc_Messages_2eproto();
- friend void protobuf_ShutdownFile_Messages_2eproto();
-
- void InitAsDefaultInstance();
- static SecretMessage* default_instance_;
-};
// ===================================================================
// ===================================================================
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
// InitialMessage
// required uint32 type = 1;
@@ -2421,300 +2321,22 @@
return &payload_;
}
+#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
// -------------------------------------------------------------------
-// SecretMessage
+// -------------------------------------------------------------------
-// required uint32 type = 1;
-inline bool SecretMessage::has_type() const {
- return (_has_bits_[0] & 0x00000001u) != 0;
-}
-inline void SecretMessage::set_has_type() {
- _has_bits_[0] |= 0x00000001u;
-}
-inline void SecretMessage::clear_has_type() {
- _has_bits_[0] &= ~0x00000001u;
-}
-inline void SecretMessage::clear_type() {
- type_ = 0u;
- clear_has_type();
-}
-inline ::google::protobuf::uint32 SecretMessage::type() const {
- // @@protoc_insertion_point(field_get:Messages.SecretMessage.type)
- return type_;
-}
-inline void SecretMessage::set_type(::google::protobuf::uint32 value) {
- set_has_type();
- type_ = value;
- // @@protoc_insertion_point(field_set:Messages.SecretMessage.type)
-}
+// -------------------------------------------------------------------
-// required uint32 size = 2;
-inline bool SecretMessage::has_size() const {
- return (_has_bits_[0] & 0x00000002u) != 0;
-}
-inline void SecretMessage::set_has_size() {
- _has_bits_[0] |= 0x00000002u;
-}
-inline void SecretMessage::clear_has_size() {
- _has_bits_[0] &= ~0x00000002u;
-}
-inline void SecretMessage::clear_size() {
- size_ = 0u;
- clear_has_size();
-}
-inline ::google::protobuf::uint32 SecretMessage::size() const {
- // @@protoc_insertion_point(field_get:Messages.SecretMessage.size)
- return size_;
-}
-inline void SecretMessage::set_size(::google::protobuf::uint32 value) {
- set_has_size();
- size_ = value;
- // @@protoc_insertion_point(field_set:Messages.SecretMessage.size)
-}
+// -------------------------------------------------------------------
-// optional uint32 encryped_pkey_size = 3;
-inline bool SecretMessage::has_encryped_pkey_size() const {
- return (_has_bits_[0] & 0x00000004u) != 0;
-}
-inline void SecretMessage::set_has_encryped_pkey_size() {
- _has_bits_[0] |= 0x00000004u;
-}
-inline void SecretMessage::clear_has_encryped_pkey_size() {
- _has_bits_[0] &= ~0x00000004u;
-}
-inline void SecretMessage::clear_encryped_pkey_size() {
- encryped_pkey_size_ = 0u;
- clear_has_encryped_pkey_size();
-}
-inline ::google::protobuf::uint32 SecretMessage::encryped_pkey_size() const {
- // @@protoc_insertion_point(field_get:Messages.SecretMessage.encryped_pkey_size)
- return encryped_pkey_size_;
-}
-inline void SecretMessage::set_encryped_pkey_size(::google::protobuf::uint32 value) {
- set_has_encryped_pkey_size();
- encryped_pkey_size_ = value;
- // @@protoc_insertion_point(field_set:Messages.SecretMessage.encryped_pkey_size)
-}
-
-// optional uint32 encryped_x509_size = 4;
-inline bool SecretMessage::has_encryped_x509_size() const {
- return (_has_bits_[0] & 0x00000008u) != 0;
-}
-inline void SecretMessage::set_has_encryped_x509_size() {
- _has_bits_[0] |= 0x00000008u;
-}
-inline void SecretMessage::clear_has_encryped_x509_size() {
- _has_bits_[0] &= ~0x00000008u;
-}
-inline void SecretMessage::clear_encryped_x509_size() {
- encryped_x509_size_ = 0u;
- clear_has_encryped_x509_size();
-}
-inline ::google::protobuf::uint32 SecretMessage::encryped_x509_size() const {
- // @@protoc_insertion_point(field_get:Messages.SecretMessage.encryped_x509_size)
- return encryped_x509_size_;
-}
-inline void SecretMessage::set_encryped_x509_size(::google::protobuf::uint32 value) {
- set_has_encryped_x509_size();
- encryped_x509_size_ = value;
- // @@protoc_insertion_point(field_set:Messages.SecretMessage.encryped_x509_size)
-}
-
-// repeated uint32 encrypted_content = 5 [packed = true];
-inline int SecretMessage::encrypted_content_size() const {
- return encrypted_content_.size();
-}
-inline void SecretMessage::clear_encrypted_content() {
- encrypted_content_.Clear();
-}
-inline ::google::protobuf::uint32 SecretMessage::encrypted_content(int index) const {
- // @@protoc_insertion_point(field_get:Messages.SecretMessage.encrypted_content)
- return encrypted_content_.Get(index);
-}
-inline void SecretMessage::set_encrypted_content(int index, ::google::protobuf::uint32 value) {
- encrypted_content_.Set(index, value);
- // @@protoc_insertion_point(field_set:Messages.SecretMessage.encrypted_content)
-}
-inline void SecretMessage::add_encrypted_content(::google::protobuf::uint32 value) {
- encrypted_content_.Add(value);
- // @@protoc_insertion_point(field_add:Messages.SecretMessage.encrypted_content)
-}
-inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
-SecretMessage::encrypted_content() const {
- // @@protoc_insertion_point(field_list:Messages.SecretMessage.encrypted_content)
- return encrypted_content_;
-}
-inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
-SecretMessage::mutable_encrypted_content() {
- // @@protoc_insertion_point(field_mutable_list:Messages.SecretMessage.encrypted_content)
- return &encrypted_content_;
-}
-
-// repeated uint32 mac_smk = 6 [packed = true];
-inline int SecretMessage::mac_smk_size() const {
- return mac_smk_.size();
-}
-inline void SecretMessage::clear_mac_smk() {
- mac_smk_.Clear();
-}
-inline ::google::protobuf::uint32 SecretMessage::mac_smk(int index) const {
- // @@protoc_insertion_point(field_get:Messages.SecretMessage.mac_smk)
- return mac_smk_.Get(index);
-}
-inline void SecretMessage::set_mac_smk(int index, ::google::protobuf::uint32 value) {
- mac_smk_.Set(index, value);
- // @@protoc_insertion_point(field_set:Messages.SecretMessage.mac_smk)
-}
-inline void SecretMessage::add_mac_smk(::google::protobuf::uint32 value) {
- mac_smk_.Add(value);
- // @@protoc_insertion_point(field_add:Messages.SecretMessage.mac_smk)
-}
-inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
-SecretMessage::mac_smk() const {
- // @@protoc_insertion_point(field_list:Messages.SecretMessage.mac_smk)
- return mac_smk_;
-}
-inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
-SecretMessage::mutable_mac_smk() {
- // @@protoc_insertion_point(field_mutable_list:Messages.SecretMessage.mac_smk)
- return &mac_smk_;
-}
-
-// repeated uint32 encrypted_pkey = 7 [packed = true];
-inline int SecretMessage::encrypted_pkey_size() const {
- return encrypted_pkey_.size();
-}
-inline void SecretMessage::clear_encrypted_pkey() {
- encrypted_pkey_.Clear();
-}
-inline ::google::protobuf::uint32 SecretMessage::encrypted_pkey(int index) const {
- // @@protoc_insertion_point(field_get:Messages.SecretMessage.encrypted_pkey)
- return encrypted_pkey_.Get(index);
-}
-inline void SecretMessage::set_encrypted_pkey(int index, ::google::protobuf::uint32 value) {
- encrypted_pkey_.Set(index, value);
- // @@protoc_insertion_point(field_set:Messages.SecretMessage.encrypted_pkey)
-}
-inline void SecretMessage::add_encrypted_pkey(::google::protobuf::uint32 value) {
- encrypted_pkey_.Add(value);
- // @@protoc_insertion_point(field_add:Messages.SecretMessage.encrypted_pkey)
-}
-inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
-SecretMessage::encrypted_pkey() const {
- // @@protoc_insertion_point(field_list:Messages.SecretMessage.encrypted_pkey)
- return encrypted_pkey_;
-}
-inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
-SecretMessage::mutable_encrypted_pkey() {
- // @@protoc_insertion_point(field_mutable_list:Messages.SecretMessage.encrypted_pkey)
- return &encrypted_pkey_;
-}
-
-// repeated uint32 encrypted_pkey_mac_smk = 8 [packed = true];
-inline int SecretMessage::encrypted_pkey_mac_smk_size() const {
- return encrypted_pkey_mac_smk_.size();
-}
-inline void SecretMessage::clear_encrypted_pkey_mac_smk() {
- encrypted_pkey_mac_smk_.Clear();
-}
-inline ::google::protobuf::uint32 SecretMessage::encrypted_pkey_mac_smk(int index) const {
- // @@protoc_insertion_point(field_get:Messages.SecretMessage.encrypted_pkey_mac_smk)
- return encrypted_pkey_mac_smk_.Get(index);
-}
-inline void SecretMessage::set_encrypted_pkey_mac_smk(int index, ::google::protobuf::uint32 value) {
- encrypted_pkey_mac_smk_.Set(index, value);
- // @@protoc_insertion_point(field_set:Messages.SecretMessage.encrypted_pkey_mac_smk)
-}
-inline void SecretMessage::add_encrypted_pkey_mac_smk(::google::protobuf::uint32 value) {
- encrypted_pkey_mac_smk_.Add(value);
- // @@protoc_insertion_point(field_add:Messages.SecretMessage.encrypted_pkey_mac_smk)
-}
-inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
-SecretMessage::encrypted_pkey_mac_smk() const {
- // @@protoc_insertion_point(field_list:Messages.SecretMessage.encrypted_pkey_mac_smk)
- return encrypted_pkey_mac_smk_;
-}
-inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
-SecretMessage::mutable_encrypted_pkey_mac_smk() {
- // @@protoc_insertion_point(field_mutable_list:Messages.SecretMessage.encrypted_pkey_mac_smk)
- return &encrypted_pkey_mac_smk_;
-}
-
-// repeated uint32 encrypted_x509 = 9 [packed = true];
-inline int SecretMessage::encrypted_x509_size() const {
- return encrypted_x509_.size();
-}
-inline void SecretMessage::clear_encrypted_x509() {
- encrypted_x509_.Clear();
-}
-inline ::google::protobuf::uint32 SecretMessage::encrypted_x509(int index) const {
- // @@protoc_insertion_point(field_get:Messages.SecretMessage.encrypted_x509)
- return encrypted_x509_.Get(index);
-}
-inline void SecretMessage::set_encrypted_x509(int index, ::google::protobuf::uint32 value) {
- encrypted_x509_.Set(index, value);
- // @@protoc_insertion_point(field_set:Messages.SecretMessage.encrypted_x509)
-}
-inline void SecretMessage::add_encrypted_x509(::google::protobuf::uint32 value) {
- encrypted_x509_.Add(value);
- // @@protoc_insertion_point(field_add:Messages.SecretMessage.encrypted_x509)
-}
-inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
-SecretMessage::encrypted_x509() const {
- // @@protoc_insertion_point(field_list:Messages.SecretMessage.encrypted_x509)
- return encrypted_x509_;
-}
-inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
-SecretMessage::mutable_encrypted_x509() {
- // @@protoc_insertion_point(field_mutable_list:Messages.SecretMessage.encrypted_x509)
- return &encrypted_x509_;
-}
-
-// repeated uint32 encrypted_x509_mac_smk = 10 [packed = true];
-inline int SecretMessage::encrypted_x509_mac_smk_size() const {
- return encrypted_x509_mac_smk_.size();
-}
-inline void SecretMessage::clear_encrypted_x509_mac_smk() {
- encrypted_x509_mac_smk_.Clear();
-}
-inline ::google::protobuf::uint32 SecretMessage::encrypted_x509_mac_smk(int index) const {
- // @@protoc_insertion_point(field_get:Messages.SecretMessage.encrypted_x509_mac_smk)
- return encrypted_x509_mac_smk_.Get(index);
-}
-inline void SecretMessage::set_encrypted_x509_mac_smk(int index, ::google::protobuf::uint32 value) {
- encrypted_x509_mac_smk_.Set(index, value);
- // @@protoc_insertion_point(field_set:Messages.SecretMessage.encrypted_x509_mac_smk)
-}
-inline void SecretMessage::add_encrypted_x509_mac_smk(::google::protobuf::uint32 value) {
- encrypted_x509_mac_smk_.Add(value);
- // @@protoc_insertion_point(field_add:Messages.SecretMessage.encrypted_x509_mac_smk)
-}
-inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
-SecretMessage::encrypted_x509_mac_smk() const {
- // @@protoc_insertion_point(field_list:Messages.SecretMessage.encrypted_x509_mac_smk)
- return encrypted_x509_mac_smk_;
-}
-inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
-SecretMessage::mutable_encrypted_x509_mac_smk() {
- // @@protoc_insertion_point(field_mutable_list:Messages.SecretMessage.encrypted_x509_mac_smk)
- return &encrypted_x509_mac_smk_;
-}
+// -------------------------------------------------------------------
// @@protoc_insertion_point(namespace_scope)
} // namespace Messages
-#ifndef SWIG
-namespace google {
-namespace protobuf {
-
-
-} // namespace google
-} // namespace protobuf
-#endif // SWIG
-
// @@protoc_insertion_point(global_scope)
#endif // PROTOBUF_Messages_2eproto__INCLUDED
diff --git a/samplecode/remoteattestation/GoogleMessages/Messages.proto b/samplecode/remoteattestation/GoogleMessages/Messages.proto
index c828cfd..73675ae 100644
--- a/samplecode/remoteattestation/GoogleMessages/Messages.proto
+++ b/samplecode/remoteattestation/GoogleMessages/Messages.proto
@@ -1,3 +1,4 @@
+syntax = "proto2";
package Messages;
message InitialMessage {
diff --git a/samplecode/remoteattestation/MessageHandler/MessageHandler.cpp b/samplecode/remoteattestation/MessageHandler/MessageHandler.cpp
index 4881348..9c80f2a 100644
--- a/samplecode/remoteattestation/MessageHandler/MessageHandler.cpp
+++ b/samplecode/remoteattestation/MessageHandler/MessageHandler.cpp
@@ -33,6 +33,7 @@
this->nm->connectCallbackHandler([this](string v, int type) {
return this->incomingHandler(v, type);
});
+ return 1;
}
@@ -396,7 +397,7 @@
string MessageHandler::createInitMsg(int type, string msg) {
- Messages::SecretMessage init_msg;
+ Messages::InitialMessage init_msg;
init_msg.set_type(type);
init_msg.set_size(msg.size());
diff --git a/samplecode/remoteattestation/ServiceProvider/isv_app/VerificationManager.cpp b/samplecode/remoteattestation/ServiceProvider/isv_app/VerificationManager.cpp
index 5d75209..029ac44 100644
--- a/samplecode/remoteattestation/ServiceProvider/isv_app/VerificationManager.cpp
+++ b/samplecode/remoteattestation/ServiceProvider/isv_app/VerificationManager.cpp
@@ -55,6 +55,7 @@
this->nm->connectCallbackHandler([this](string v, int type) {
return this->incomingHandler(v, type);
});
+ return 1;
}
@@ -178,10 +179,10 @@
}
break;
case RA_APP_ATT_OK: {
- Messages::SecretMessage sec_msg;
- ret = sec_msg.ParseFromString(v);
+ Messages::InitialMessage msg;
+ ret = msg.ParseFromString(v);
if (ret) {
- if (sec_msg.type() == RA_APP_ATT_OK) {
+ if (msg.type() == RA_APP_ATT_OK) {
this->handleAppAttOk();
}
}
diff --git a/samplecode/remoteattestation/ServiceProvider/service_provider/ServiceProvider.h b/samplecode/remoteattestation/ServiceProvider/service_provider/ServiceProvider.h
index 1228020..dd369be 100644
--- a/samplecode/remoteattestation/ServiceProvider/service_provider/ServiceProvider.h
+++ b/samplecode/remoteattestation/ServiceProvider/service_provider/ServiceProvider.h
@@ -78,7 +78,6 @@
int sp_ra_proc_msg1_req(Messages::MessageMSG1 msg1, Messages::MessageMSG2 *msg2);
int sp_ra_proc_msg3_req(Messages::MessageMSG3 msg, Messages::AttestationMessage *att_msg);
sgx_ra_msg3_t* assembleMSG3(Messages::MessageMSG3 msg);
- int sp_ra_proc_app_att_hmac(Messages::SecretMessage *new_msg, string hmac_key, string hmac_key_filename);
private:
WebService *ws = NULL;
diff --git a/samplecode/sealeddata/enclave/Cargo.toml b/samplecode/sealeddata/enclave/Cargo.toml
index 8bfce6b..64a6e56 100644
--- a/samplecode/sealeddata/enclave/Cargo.toml
+++ b/samplecode/sealeddata/enclave/Cargo.toml
@@ -22,6 +22,7 @@
serde_cbor = { git = "https://github.com/mesalock-linux/cbor-sgx" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -30,6 +31,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/sealeddata/enclave/Xargo.toml b/samplecode/sealeddata/enclave/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/sealeddata/enclave/Xargo.toml
+++ b/samplecode/sealeddata/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/sealeddata/enclave/x86_64-unknown-linux-sgx.json b/samplecode/sealeddata/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/sealeddata/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/sealeddata/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/secretsharing/enclave/Cargo.toml b/samplecode/secretsharing/enclave/Cargo.toml
index ad50140..c5f9504 100644
--- a/samplecode/secretsharing/enclave/Cargo.toml
+++ b/samplecode/secretsharing/enclave/Cargo.toml
@@ -18,6 +18,7 @@
threshold-secret-sharing = { git = "https://github.com/mesalock-linux/rust-threshold-secret-sharing-sgx" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -26,6 +27,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/secretsharing/enclave/Xargo.toml b/samplecode/secretsharing/enclave/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/secretsharing/enclave/Xargo.toml
+++ b/samplecode/secretsharing/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/secretsharing/enclave/x86_64-unknown-linux-sgx.json b/samplecode/secretsharing/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/secretsharing/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/secretsharing/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/serialize/enclave/Cargo.toml b/samplecode/serialize/enclave/Cargo.toml
index 8496a58..00b57a2 100644
--- a/samplecode/serialize/enclave/Cargo.toml
+++ b/samplecode/serialize/enclave/Cargo.toml
@@ -15,6 +15,7 @@
sgx_serialize_derive = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -23,6 +24,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/serialize/enclave/Xargo.toml b/samplecode/serialize/enclave/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/serialize/enclave/Xargo.toml
+++ b/samplecode/serialize/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/serialize/enclave/x86_64-unknown-linux-sgx.json b/samplecode/serialize/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/serialize/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/serialize/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/sgx-cov/enclave/Cargo.toml b/samplecode/sgx-cov/enclave/Cargo.toml
index 9cd5c37..6653d1a 100644
--- a/samplecode/sgx-cov/enclave/Cargo.toml
+++ b/samplecode/sgx-cov/enclave/Cargo.toml
@@ -22,7 +22,9 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
sgx_trts = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
sgx_cov = { git = "https://github.com/apache/teaclave-sgx-sdk.git", optional = true }
+
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -31,6 +33,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/sgx-cov/enclave/x86_64-unknown-linux-sgx.json b/samplecode/sgx-cov/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/sgx-cov/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/sgx-cov/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/static-data-distribution/app/Cargo.toml b/samplecode/static-data-distribution/app/Cargo.toml
index 3ceb7a9..e250741 100644
--- a/samplecode/static-data-distribution/app/Cargo.toml
+++ b/samplecode/static-data-distribution/app/Cargo.toml
@@ -11,30 +11,7 @@
serde_json = "1.0"
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
-sgx_alloc = { path = "../../../sgx_alloc" }
-sgx_backtrace = { path = "../../../sgx_backtrace" }
-sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
-sgx_build_helper = { path = "../../../sgx_build_helper" }
-sgx_cov = { path = "../../../sgx_cov" }
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
-sgx_demangle = { path = "../../../sgx_demangle" }
-sgx_libc = { path = "../../../sgx_libc" }
-sgx_rand = { path = "../../../sgx_rand" }
-sgx_rand_derive = { path = "../../../sgx_rand_derive" }
-sgx_serialize = { path = "../../../sgx_serialize" }
-sgx_serialize_derive = { path = "../../../sgx_serialize_derive" }
-sgx_serialize_derive_internals = { path = "../../../sgx_serialize_derive_internals" }
-sgx_tcrypto = { path = "../../../sgx_tcrypto" }
-sgx_tcrypto_helper = { path = "../../../sgx_tcrypto_helper" }
-sgx_tdh = { path = "../../../sgx_tdh" }
-sgx_tkey_exchange = { path = "../../../sgx_tkey_exchange" }
-sgx_tprotected_fs = { path = "../../../sgx_tprotected_fs" }
-sgx_trts = { path = "../../../sgx_trts" }
-sgx_tse = { path = "../../../sgx_tse" }
-sgx_tseal = { path = "../../../sgx_tseal" }
-sgx_tstd = { path = "../../../sgx_tstd" }
-sgx_tunittest = { path = "../../../sgx_tunittest" }
sgx_types = { path = "../../../sgx_types" }
sgx_ucrypto = { path = "../../../sgx_ucrypto" }
-sgx_unwind = { path = "../../../sgx_unwind" }
sgx_urts = { path = "../../../sgx_urts" }
diff --git a/samplecode/static-data-distribution/enclave/Cargo.toml b/samplecode/static-data-distribution/enclave/Cargo.toml
index 64117b6..fdaf73d 100644
--- a/samplecode/static-data-distribution/enclave/Cargo.toml
+++ b/samplecode/static-data-distribution/enclave/Cargo.toml
@@ -19,13 +19,16 @@
serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
sgx_build_helper = { path = "../../../sgx_build_helper" }
sgx_cov = { path = "../../../sgx_cov" }
+sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/static-data-distribution/enclave/Xargo.toml b/samplecode/static-data-distribution/enclave/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/static-data-distribution/enclave/Xargo.toml
+++ b/samplecode/static-data-distribution/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/static-data-distribution/enclave/x86_64-unknown-linux-sgx.json b/samplecode/static-data-distribution/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/static-data-distribution/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/static-data-distribution/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/switchless/enclave/Cargo.toml b/samplecode/switchless/enclave/Cargo.toml
index 24bf333..19f90bc 100644
--- a/samplecode/switchless/enclave/Cargo.toml
+++ b/samplecode/switchless/enclave/Cargo.toml
@@ -15,6 +15,7 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -23,6 +24,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/switchless/enclave/Xargo.toml b/samplecode/switchless/enclave/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/switchless/enclave/Xargo.toml
+++ b/samplecode/switchless/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/switchless/enclave/x86_64-unknown-linux-sgx.json b/samplecode/switchless/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/switchless/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/switchless/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/tcmalloc/enclave/Cargo.toml b/samplecode/tcmalloc/enclave/Cargo.toml
index f4f3224..c547778 100644
--- a/samplecode/tcmalloc/enclave/Cargo.toml
+++ b/samplecode/tcmalloc/enclave/Cargo.toml
@@ -15,6 +15,7 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -23,6 +24,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/tcmalloc/enclave/Xargo.toml b/samplecode/tcmalloc/enclave/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/tcmalloc/enclave/Xargo.toml
+++ b/samplecode/tcmalloc/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/tcmalloc/enclave/x86_64-unknown-linux-sgx.json b/samplecode/tcmalloc/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/tcmalloc/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/tcmalloc/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/thread/enclave/Cargo.toml b/samplecode/thread/enclave/Cargo.toml
index 4234637..7ee75d1 100644
--- a/samplecode/thread/enclave/Cargo.toml
+++ b/samplecode/thread/enclave/Cargo.toml
@@ -14,6 +14,7 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -22,6 +23,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
diff --git a/samplecode/thread/enclave/Xargo.toml b/samplecode/thread/enclave/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/thread/enclave/Xargo.toml
+++ b/samplecode/thread/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/thread/enclave/x86_64-unknown-linux-sgx.json b/samplecode/thread/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/thread/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/thread/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/tls/tlsclient/enclave/Cargo.toml b/samplecode/tls/tlsclient/enclave/Cargo.toml
index 2947296..842017b 100644
--- a/samplecode/tls/tlsclient/enclave/Cargo.toml
+++ b/samplecode/tls/tlsclient/enclave/Cargo.toml
@@ -22,6 +22,7 @@
# Comment out these following lines to use rust-sgx-sdk from git
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../../sgx_alloc" }
sgx_backtrace = { path = "../../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../../sgx_backtrace_sys" }
@@ -30,6 +31,7 @@
sgx_crypto_helper = { path = "../../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../../sgx_demangle" }
sgx_libc = { path = "../../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../../sgx_no_tstd" }
sgx_rand = { path = "../../../../sgx_rand" }
sgx_rand_derive = { path = "../../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../../sgx_serialize" }
diff --git a/samplecode/tls/tlsclient/enclave/Xargo.toml b/samplecode/tls/tlsclient/enclave/Xargo.toml
index 989d796..795f1f0 100644
--- a/samplecode/tls/tlsclient/enclave/Xargo.toml
+++ b/samplecode/tls/tlsclient/enclave/Xargo.toml
@@ -89,6 +89,7 @@
[dependencies.sgx_cov]
path = "../../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../../sgx_signal"
stage = 7
diff --git a/samplecode/tls/tlsclient/enclave/x86_64-unknown-linux-sgx.json b/samplecode/tls/tlsclient/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/tls/tlsclient/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/tls/tlsclient/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/tls/tlsserver/enclave/Cargo.toml b/samplecode/tls/tlsserver/enclave/Cargo.toml
index 5e9debe..6c34401 100644
--- a/samplecode/tls/tlsserver/enclave/Cargo.toml
+++ b/samplecode/tls/tlsserver/enclave/Cargo.toml
@@ -21,6 +21,7 @@
lazy_static = { version = "1.4.0", default-features = false, features = ["spin_no_std"] }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../../sgx_alloc" }
sgx_backtrace = { path = "../../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../../sgx_backtrace_sys" }
@@ -29,6 +30,7 @@
sgx_crypto_helper = { path = "../../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../../sgx_demangle" }
sgx_libc = { path = "../../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../../sgx_no_tstd" }
sgx_rand = { path = "../../../../sgx_rand" }
sgx_rand_derive = { path = "../../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../../sgx_serialize" }
diff --git a/samplecode/tls/tlsserver/enclave/Xargo.toml b/samplecode/tls/tlsserver/enclave/Xargo.toml
index 989d796..795f1f0 100644
--- a/samplecode/tls/tlsserver/enclave/Xargo.toml
+++ b/samplecode/tls/tlsserver/enclave/Xargo.toml
@@ -89,6 +89,7 @@
[dependencies.sgx_cov]
path = "../../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../../sgx_signal"
stage = 7
diff --git a/samplecode/tls/tlsserver/enclave/x86_64-unknown-linux-sgx.json b/samplecode/tls/tlsserver/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/tls/tlsserver/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/tls/tlsserver/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/tr-mpc/tr-mpc-server/enclave/Cargo.toml b/samplecode/tr-mpc/tr-mpc-server/enclave/Cargo.toml
index 0c9e9e6..9c73729 100644
--- a/samplecode/tr-mpc/tr-mpc-server/enclave/Cargo.toml
+++ b/samplecode/tr-mpc/tr-mpc-server/enclave/Cargo.toml
@@ -32,6 +32,7 @@
# Comment out these following lines to use rust-sgx-sdk from git
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../../sgx_alloc" }
sgx_backtrace = { path = "../../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../../sgx_backtrace_sys" }
@@ -40,6 +41,7 @@
sgx_crypto_helper = { path = "../../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../../sgx_demangle" }
sgx_libc = { path = "../../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../../sgx_no_tstd" }
sgx_rand = { path = "../../../../sgx_rand" }
sgx_rand_derive = { path = "../../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../../sgx_serialize" }
diff --git a/samplecode/tr-mpc/tr-mpc-server/enclave/Xargo.toml b/samplecode/tr-mpc/tr-mpc-server/enclave/Xargo.toml
index 989d796..795f1f0 100644
--- a/samplecode/tr-mpc/tr-mpc-server/enclave/Xargo.toml
+++ b/samplecode/tr-mpc/tr-mpc-server/enclave/Xargo.toml
@@ -89,6 +89,7 @@
[dependencies.sgx_cov]
path = "../../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../../sgx_signal"
stage = 7
diff --git a/samplecode/tr-mpc/tr-mpc-server/enclave/x86_64-unknown-linux-sgx.json b/samplecode/tr-mpc/tr-mpc-server/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/tr-mpc/tr-mpc-server/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/tr-mpc/tr-mpc-server/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/ue-ra/ue-ra-server/enclave/Cargo.toml b/samplecode/ue-ra/ue-ra-server/enclave/Cargo.toml
index 071e8ad..f768c19 100644
--- a/samplecode/ue-ra/ue-ra-server/enclave/Cargo.toml
+++ b/samplecode/ue-ra/ue-ra-server/enclave/Cargo.toml
@@ -31,6 +31,7 @@
# Comment out these following lines to use rust-sgx-sdk from git
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../../sgx_alloc" }
sgx_backtrace = { path = "../../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../../sgx_backtrace_sys" }
@@ -39,6 +40,7 @@
sgx_crypto_helper = { path = "../../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../../sgx_demangle" }
sgx_libc = { path = "../../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../../sgx_no_tstd" }
sgx_rand = { path = "../../../../sgx_rand" }
sgx_rand_derive = { path = "../../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../../sgx_serialize" }
diff --git a/samplecode/ue-ra/ue-ra-server/enclave/Xargo.toml b/samplecode/ue-ra/ue-ra-server/enclave/Xargo.toml
index 989d796..795f1f0 100644
--- a/samplecode/ue-ra/ue-ra-server/enclave/Xargo.toml
+++ b/samplecode/ue-ra/ue-ra-server/enclave/Xargo.toml
@@ -89,6 +89,7 @@
[dependencies.sgx_cov]
path = "../../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../../sgx_signal"
stage = 7
diff --git a/samplecode/ue-ra/ue-ra-server/enclave/x86_64-unknown-linux-sgx.json b/samplecode/ue-ra/ue-ra-server/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/ue-ra/ue-ra-server/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/ue-ra/ue-ra-server/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/unit-test/enclave/Xargo.toml b/samplecode/unit-test/enclave/Xargo.toml
index 61e97a9..e383be2 100644
--- a/samplecode/unit-test/enclave/Xargo.toml
+++ b/samplecode/unit-test/enclave/Xargo.toml
@@ -92,4 +92,4 @@
[dependencies.sgx_signal]
path = "../../../sgx_signal"
-stage = 7
\ No newline at end of file
+stage = 7
diff --git a/samplecode/unit-test/enclave/src/test_time.rs b/samplecode/unit-test/enclave/src/test_time.rs
index a0a3f1d..5d868e5 100644
--- a/samplecode/unit-test/enclave/src/test_time.rs
+++ b/samplecode/unit-test/enclave/src/test_time.rs
@@ -36,7 +36,7 @@
{
let a = Instant::now();
- should_panic!((a - Duration::new(1, 0)).duration_since(a));
+ assert!((a - Duration::new(1, 0)).duration_since(a) == Duration::new(0, 0));
}
{
diff --git a/samplecode/unit-test/enclave/x86_64-unknown-linux-sgx.json b/samplecode/unit-test/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/unit-test/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/unit-test/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/wasmi/enclave/Cargo.toml b/samplecode/wasmi/enclave/Cargo.toml
index 410497e..2b9dba5 100644
--- a/samplecode/wasmi/enclave/Cargo.toml
+++ b/samplecode/wasmi/enclave/Cargo.toml
@@ -20,12 +20,18 @@
[target.'cfg(not(target_env = "sgx"))'.dependencies]
sgx_types = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
+
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
+sgx_backtrace = { path = "../../../sgx_backtrace" }
+sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
sgx_build_helper = { path = "../../../sgx_build_helper" }
sgx_cov = { path = "../../../sgx_cov" }
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
+sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
@@ -42,6 +48,6 @@
sgx_tstd = { path = "../../../sgx_tstd" }
sgx_tunittest = { path = "../../../sgx_tunittest" }
sgx_types = { path = "../../../sgx_types" }
-sgx_ucrypto = { path = "../../../sgx_ucrypto" }
+#sgx_ucrypto = { path = "../../../sgx_ucrypto" }
sgx_unwind = { path = "../../../sgx_unwind" }
-sgx_urts = { path = "../../../sgx_urts" }
+#sgx_urts = { path = "../../../sgx_urts" }
diff --git a/samplecode/wasmi/enclave/Xargo.toml b/samplecode/wasmi/enclave/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/wasmi/enclave/Xargo.toml
+++ b/samplecode/wasmi/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/wasmi/enclave/sgxwasm/Cargo.toml b/samplecode/wasmi/enclave/sgxwasm/Cargo.toml
index 36deb2d..853ed6e 100644
--- a/samplecode/wasmi/enclave/sgxwasm/Cargo.toml
+++ b/samplecode/wasmi/enclave/sgxwasm/Cargo.toml
@@ -14,6 +14,7 @@
sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../../sgx_alloc" }
sgx_backtrace = { path = "../../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../../sgx_backtrace_sys" }
@@ -22,6 +23,7 @@
sgx_crypto_helper = { path = "../../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../../sgx_demangle" }
sgx_libc = { path = "../../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../../sgx_no_tstd" }
sgx_rand = { path = "../../../../sgx_rand" }
sgx_rand_derive = { path = "../../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../../sgx_serialize" }
diff --git a/samplecode/wasmi/enclave/x86_64-unknown-linux-sgx.json b/samplecode/wasmi/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/wasmi/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/wasmi/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/samplecode/zlib-lazy-static-sample/enclave/Cargo.toml b/samplecode/zlib-lazy-static-sample/enclave/Cargo.toml
index a5ebcec..372d9e2 100644
--- a/samplecode/zlib-lazy-static-sample/enclave/Cargo.toml
+++ b/samplecode/zlib-lazy-static-sample/enclave/Cargo.toml
@@ -20,6 +20,7 @@
lazy_static = { version = "1.1.0", features = ["spin_no_std"] }
[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_align_struct_attribute = { path = "../../../sgx_align_struct_attribute" }
sgx_alloc = { path = "../../../sgx_alloc" }
sgx_backtrace = { path = "../../../sgx_backtrace" }
sgx_backtrace_sys = { path = "../../../sgx_backtrace_sys" }
@@ -28,6 +29,7 @@
sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
sgx_demangle = { path = "../../../sgx_demangle" }
sgx_libc = { path = "../../../sgx_libc" }
+sgx_no_tstd = { path = "../../../sgx_no_tstd" }
sgx_rand = { path = "../../../sgx_rand" }
sgx_rand_derive = { path = "../../../sgx_rand_derive" }
sgx_serialize = { path = "../../../sgx_serialize" }
@@ -44,6 +46,6 @@
sgx_tstd = { path = "../../../sgx_tstd" }
sgx_tunittest = { path = "../../../sgx_tunittest" }
sgx_types = { path = "../../../sgx_types" }
-sgx_ucrypto = { path = "../../../sgx_ucrypto" }
+#sgx_ucrypto = { path = "../../../sgx_ucrypto" }
sgx_unwind = { path = "../../../sgx_unwind" }
-sgx_urts = { path = "../../../sgx_urts" }
+#sgx_urts = { path = "../../../sgx_urts" }
diff --git a/samplecode/zlib-lazy-static-sample/enclave/Xargo.toml b/samplecode/zlib-lazy-static-sample/enclave/Xargo.toml
index 31fb7d4..cd02285 100644
--- a/samplecode/zlib-lazy-static-sample/enclave/Xargo.toml
+++ b/samplecode/zlib-lazy-static-sample/enclave/Xargo.toml
@@ -88,6 +88,7 @@
[dependencies.sgx_cov]
path = "../../../sgx_cov"
stage = 7
+
[dependencies.sgx_signal]
path = "../../../sgx_signal"
stage = 7
diff --git a/samplecode/zlib-lazy-static-sample/enclave/x86_64-unknown-linux-sgx.json b/samplecode/zlib-lazy-static-sample/enclave/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/samplecode/zlib-lazy-static-sample/enclave/x86_64-unknown-linux-sgx.json
+++ b/samplecode/zlib-lazy-static-sample/enclave/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",
diff --git a/sgx_align_struct_attribute/Cargo.toml b/sgx_align_struct_attribute/Cargo.toml
index fb81633..46596bd 100644
--- a/sgx_align_struct_attribute/Cargo.toml
+++ b/sgx_align_struct_attribute/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_align_struct_attribute"
diff --git a/sgx_align_struct_attribute/src/align.rs b/sgx_align_struct_attribute/src/align.rs
index 9e3a523..2daf865 100644
--- a/sgx_align_struct_attribute/src/align.rs
+++ b/sgx_align_struct_attribute/src/align.rs
@@ -60,10 +60,7 @@
impl AlignArgs {
pub fn get_layout(&self) -> Result<Layout> {
- let align_iter = self
- .vars
- .iter()
- .find(|v| v.ident.to_string() == "align");
+ let align_iter = self.vars.iter().find(|v| v.ident == "align");
let align: usize = if let Some(align_value) = align_iter {
self.parse_align(&align_value.value)?
} else {
@@ -73,10 +70,7 @@
));
};
- let size_iter = self
- .vars
- .iter()
- .find(|v| v.ident.to_string() == "size");
+ let size_iter = self.vars.iter().find(|v| v.ident == "size");
let size: usize = if let Some(size_value) = size_iter {
self.parse_size(&size_value.value)?
} else {
@@ -180,21 +174,22 @@
quote! {
#attrs
#align_attr
- #vis struct #name#generics {
+ #vis struct #name #generics {
#pad_item,
#fields
}
}
}
+ #[allow(clippy::filter_next, clippy::collapsible_match)]
fn is_contains_specified_attr(&self, atrr: &str) -> bool {
let mut erxcept_attr = false;
for attr in &self.input.attrs {
let ident = attr.path.get_ident();
let meta = attr.parse_meta();
- if ident.map_or(false, |v| v.to_string() == "repr") && meta.is_ok() {
+ if ident.map_or(false, |v| *v == "repr") && meta.is_ok() {
if let Ok(Meta::List(ref m)) = meta {
- if m.nested.len() > 0 {
+ if !m.nested.is_empty() {
erxcept_attr = m
.nested
.iter()
@@ -202,8 +197,7 @@
let mut find = false;
if let syn::NestedMeta::Meta(ref s) = x {
if let syn::Meta::Path(p) = s {
- find =
- p.get_ident().map_or(false, |v| v.to_string() == atrr);
+ find = p.get_ident().map_or(false, |v| *v == atrr);
}
}
find
@@ -226,7 +220,7 @@
fn generate_align_attr(&self) -> proc_macro2::TokenStream {
let align = self.align_layout.align();
- let litint = LitInt::new(&format!("{}", align).to_string(), Span::call_site());
+ let litint = LitInt::new(&format!("{}", align), Span::call_site());
quote! {
#[repr(align(#litint))]
}
diff --git a/sgx_align_struct_attribute/src/layout.rs b/sgx_align_struct_attribute/src/layout.rs
index 68150c4..861f9ee 100644
--- a/sgx_align_struct_attribute/src/layout.rs
+++ b/sgx_align_struct_attribute/src/layout.rs
@@ -72,24 +72,20 @@
Ok(calc_algn(layout.align(), layout.size() + offset))
}
+#[allow(clippy::overflow_check_conditional)]
#[inline]
fn check_overflow(buf: usize, len: usize) -> bool {
(buf + len < len) || (buf + len < buf)
}
fn check_layout(layout: &Layout) -> bool {
- if layout.size() == 0
+ !(layout.size() == 0
|| !layout.align().is_power_of_two()
- || layout.size() > usize::MAX - (layout.align() - 1)
- {
- false
- } else {
- true
- }
+ || layout.size() > usize::MAX - (layout.align() - 1))
}
fn check_align_req(size: usize, align_req: &[AlignReq]) -> bool {
- if align_req.len() == 0 {
+ if align_req.is_empty() {
return false;
}
let len: usize = (size + 7) / 8;
@@ -148,6 +144,7 @@
rol(v, (0 - c as isize) as usize)
}
+#[allow(clippy::comparison_chain)]
fn count_lzb(bmp: i64) -> i32 {
if bmp == 0 {
-1
@@ -195,7 +192,7 @@
if req.len > 63 {
return -1;
} else {
- bmp |= rol(((1 as i64) << req.len) - 1, req.offset);
+ bmp |= rol(((1_i64) << req.len) - 1, req.offset);
}
}
bmp
diff --git a/sgx_alloc/Cargo.toml b/sgx_alloc/Cargo.toml
index 02b464b..387eae2 100644
--- a/sgx_alloc/Cargo.toml
+++ b/sgx_alloc/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://dingelish.github.io/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_alloc"
diff --git a/sgx_alloc/src/alignalloc.rs b/sgx_alloc/src/alignalloc.rs
index f9afa9e..b83c130 100644
--- a/sgx_alloc/src/alignalloc.rs
+++ b/sgx_alloc/src/alignalloc.rs
@@ -373,7 +373,7 @@
if req.len > 63 {
return -1;
} else {
- bmp |= rol(((1 as i64) << req.len) - 1, req.offset);
+ bmp |= rol(((1_i64) << req.len) - 1, req.offset);
}
}
bmp
diff --git a/sgx_alloc/src/lib.rs b/sgx_alloc/src/lib.rs
index 412e458..f1f8451 100644
--- a/sgx_alloc/src/lib.rs
+++ b/sgx_alloc/src/lib.rs
@@ -32,6 +32,7 @@
#![feature(core_intrinsics)]
#![feature(nonnull_slice_from_raw_parts)]
#![feature(slice_ptr_get)]
+#![allow(clippy::missing_safety_doc)]
extern crate alloc;
diff --git a/sgx_alloc/src/system.rs b/sgx_alloc/src/system.rs
index c6d2167..bc7881f 100644
--- a/sgx_alloc/src/system.rs
+++ b/sgx_alloc/src/system.rs
@@ -225,7 +225,6 @@
use core::alloc::{GlobalAlloc, Layout};
use core::ffi::c_void;
use core::ptr;
- use libc;
unsafe impl GlobalAlloc for System {
#[inline]
diff --git a/sgx_backtrace/Cargo.toml b/sgx_backtrace/Cargo.toml
index 0c4799a..2ae3746 100644
--- a/sgx_backtrace/Cargo.toml
+++ b/sgx_backtrace/Cargo.toml
@@ -7,7 +7,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[target.'cfg(not(target_env = "sgx"))'.dependencies]
sgx_demangle = { path = "../sgx_demangle" }
diff --git a/sgx_backtrace_sys/Cargo.toml b/sgx_backtrace_sys/Cargo.toml
index 81645da..cb874f5 100644
--- a/sgx_backtrace_sys/Cargo.toml
+++ b/sgx_backtrace_sys/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
diff --git a/sgx_backtrace_sys/libbacktrace/read.c b/sgx_backtrace_sys/libbacktrace/read.c
index 062b109..2a19349 100644
--- a/sgx_backtrace_sys/libbacktrace/read.c
+++ b/sgx_backtrace_sys/libbacktrace/read.c
@@ -94,6 +94,7 @@
if (got < 0) {
error_callback(data, "read", error);
free(view->base);
+ sgx_ocfree();
return 0;
}
diff --git a/sgx_build_helper/Cargo.toml b/sgx_build_helper/Cargo.toml
index 6705cd8..7b9ebc9 100644
--- a/sgx_build_helper/Cargo.toml
+++ b/sgx_build_helper/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_build_helper"
diff --git a/sgx_cov/Cargo.toml b/sgx_cov/Cargo.toml
index d2b41a9..2e5d173 100644
--- a/sgx_cov/Cargo.toml
+++ b/sgx_cov/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Enabling gcov for SGX crates."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_cov"
diff --git a/sgx_crypto_helper/Cargo.toml b/sgx_crypto_helper/Cargo.toml
index 9d4a145..b2fe636 100644
--- a/sgx_crypto_helper/Cargo.toml
+++ b/sgx_crypto_helper/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_crypto_helper"
diff --git a/sgx_demangle/Cargo.toml b/sgx_demangle/Cargo.toml
index c05799d..5f165b2 100644
--- a/sgx_demangle/Cargo.toml
+++ b/sgx_demangle/Cargo.toml
@@ -7,7 +7,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_demangle"
diff --git a/sgx_edl/Cargo.toml b/sgx_edl/Cargo.toml
index b46a6db..098860b 100644
--- a/sgx_edl/Cargo.toml
+++ b/sgx_edl/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
include = [
"src/lib.rs",
diff --git a/sgx_edl/edl/sgx_file.edl b/sgx_edl/edl/sgx_file.edl
index 07fb1eb..c70ec59 100644
--- a/sgx_edl/edl/sgx_file.edl
+++ b/sgx_edl/edl/sgx_file.edl
@@ -27,6 +27,7 @@
untrusted {
int u_open_ocall([out] int *error, [in, string] const char *pathname, int flags);
int u_open64_ocall([out] int *error, [in, string] const char *path, int oflag, int mode);
+ int u_openat_ocall([out] int *error, int dirfd, [in, string] const char *pathname, int flags);
int u_fstat_ocall([out] int *error, int fd, [out] struct stat_t *buf);
int u_fstat64_ocall([out] int *error, int fd, [out] struct stat64_t *buf);
@@ -46,6 +47,7 @@
int u_fchmod_ocall([out] int *error, int fd, uint32_t mode);
int u_unlink_ocall([out] int *error, [in, string] const char *pathname);
int u_link_ocall([out] int *error, [in, string] const char *oldpath, [in, string] const char *newpath);
+ int u_unlinkat_ocall([out] int *error, int dirfd, [in, string] const char *pathname, int flags);
int u_linkat_ocall([out] int *error, int olddirfd, [in, string] const char *oldpath, int newdirfd, [in, string] const char *newpath, int flags);
int u_rename_ocall([out] int *error, [in, string] const char *oldpath, [in, string] const char *newpath);
int u_chmod_ocall([out] int *error, [in, string] const char *path, uint32_t mode);
@@ -54,6 +56,7 @@
char *u_realpath_ocall([out] int *error, [in, string] const char *pathname);
int u_mkdir_ocall([out] int *error, [in, string] const char *pathname, uint32_t mode);
int u_rmdir_ocall([out] int *error, [in, string] const char *pathname);
+ void *u_fdopendir_ocall([out] int *error, int fd);
void *u_opendir_ocall([out] int *error, [in, string] const char *pathname);
int u_readdir64_r_ocall([user_check] void *dirp, [in, out] struct dirent64_t *entry, [out] struct dirent64_t **result);
int u_closedir_ocall([out] int *error, [user_check] void *dirp);
diff --git a/sgx_libc/BUILD b/sgx_libc/BUILD
index 7c5d226..0d66538 100644
--- a/sgx_libc/BUILD
+++ b/sgx_libc/BUILD
@@ -4,7 +4,7 @@
name = "sgx_libc",
srcs = glob(["src/*.rs"]),
crate_features = ["align"],
- edition = "2018",
+ edition = "2021",
visibility = ["//visibility:public"],
deps = ["//sgx_types"],
)
diff --git a/sgx_libc/Cargo.toml b/sgx_libc/Cargo.toml
index 7441fb5..7f7f364 100644
--- a/sgx_libc/Cargo.toml
+++ b/sgx_libc/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_libc"
diff --git a/sgx_libc/src/lib.rs b/sgx_libc/src/lib.rs
index d60cd39..01d2dd1 100644
--- a/sgx_libc/src/lib.rs
+++ b/sgx_libc/src/lib.rs
@@ -22,7 +22,10 @@
#![allow(overflowing_literals)]
#![allow(non_snake_case)]
#![allow(unused_macros)]
+#![allow(clippy::cmp_null)]
#![allow(unused_assignments)]
+#![allow(clippy::missing_safety_doc)]
+#![allow(clippy::absurd_extreme_comparisons)]
#[macro_use]
extern crate alloc;
diff --git a/sgx_libc/src/linux/x86_64/mod.rs b/sgx_libc/src/linux/x86_64/mod.rs
index 314e805..dc55613 100644
--- a/sgx_libc/src/linux/x86_64/mod.rs
+++ b/sgx_libc/src/linux/x86_64/mod.rs
@@ -1418,9 +1418,9 @@
pub const SA_SIGINFO: c_int = 0x00000004;
pub const SA_NOCLDWAIT: c_int = 0x00000002;
-pub const SIG_DFL: sighandler_t = 0 as sighandler_t;
-pub const SIG_IGN: sighandler_t = 1 as sighandler_t;
-pub const SIG_ERR: sighandler_t = !0 as sighandler_t;
+pub const SIG_DFL: sighandler_t = 0_usize;
+pub const SIG_IGN: sighandler_t = 1_usize;
+pub const SIG_ERR: sighandler_t = !0 as usize;
pub const SIGTRAP: c_int = 5;
pub const SIGCHLD: c_int = 17;
@@ -1536,7 +1536,7 @@
#[inline]
unsafe fn __sigmask(sig: c_int) -> u64 {
- (1 as u64) << (((sig) - 1) % (8 * mem::size_of::<u64>()) as i32)
+ (1_u64) << (((sig) - 1) % (8 * mem::size_of::<u64>()) as i32)
}
#[inline]
@@ -1612,7 +1612,7 @@
#[inline]
pub const fn CMSG_ALIGN(len: usize) -> usize {
- len + mem::size_of::<usize>() - 1 & !(mem::size_of::<usize>() - 1)
+ (len + mem::size_of::<usize>() - 1) & !(mem::size_of::<usize>() - 1)
}
#[inline]
@@ -1620,7 +1620,7 @@
if (*mhdr).msg_controllen as usize >= mem::size_of::<cmsghdr>() {
(*mhdr).msg_control as *mut cmsghdr
} else {
- 0 as *mut cmsghdr
+ ptr::null_mut::<cmsghdr>()
}
}
@@ -1642,14 +1642,14 @@
#[inline]
pub unsafe fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr {
if ((*cmsg).cmsg_len as usize) < mem::size_of::<cmsghdr>() {
- return 0 as *mut cmsghdr;
+ return ptr::null_mut::<cmsghdr>();
};
let next = (cmsg as usize + CMSG_ALIGN((*cmsg).cmsg_len as usize)) as *mut cmsghdr;
let max = (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize;
if (next.offset(1)) as usize > max
|| next as usize + CMSG_ALIGN((*next).cmsg_len as usize) > max
{
- 0 as *mut cmsghdr
+ ptr::null_mut::<cmsghdr>()
} else {
next as *mut cmsghdr
}
@@ -1666,7 +1666,7 @@
#[inline]
pub unsafe fn minor(dev: dev_t) -> c_uint {
let mut minor = 0;
- minor |= (dev & 0x00000000000000ff) >> 0;
+ minor |= dev & 0x00000000000000ff;
minor |= (dev & 0x00000ffffff00000) >> 12;
minor as c_uint
}
@@ -1678,7 +1678,7 @@
let mut dev = 0;
dev |= (major & 0x00000fff) << 8;
dev |= (major & 0xfffff000) << 32;
- dev |= (minor & 0x000000ff) << 0;
+ dev |= minor & 0x000000ff;
dev |= (minor & 0xffffff00) << 12;
dev
}
diff --git a/sgx_libc/src/linux/x86_64/ocall.rs b/sgx_libc/src/linux/x86_64/ocall.rs
index 8a17915..c6a0c82 100644
--- a/sgx_libc/src/linux/x86_64/ocall.rs
+++ b/sgx_libc/src/linux/x86_64/ocall.rs
@@ -111,6 +111,13 @@
oflag: c_int,
mode: c_int,
) -> sgx_status_t;
+ pub fn u_openat_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ dirfd: c_int,
+ pathname: *const c_char,
+ flags: c_int,
+ ) -> sgx_status_t;
pub fn u_fstat_ocall(
result: *mut c_int,
error: *mut c_int,
@@ -204,6 +211,13 @@
oldpath: *const c_char,
newpath: *const c_char,
) -> sgx_status_t;
+ pub fn u_unlinkat_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ dirfd: c_int,
+ pathname: *const c_char,
+ flags: c_int,
+ ) -> sgx_status_t;
pub fn u_linkat_ocall(
result: *mut c_int,
error: *mut c_int,
@@ -254,6 +268,7 @@
error: *mut c_int,
pathname: *const c_char,
) -> sgx_status_t;
+ pub fn u_fdopendir_ocall(result: *mut *mut DIR, error: *mut c_int, fd: c_int) -> sgx_status_t;
pub fn u_opendir_ocall(
result: *mut *mut DIR,
error: *mut c_int,
@@ -684,14 +699,14 @@
if result as isize != -1 {
if sgx_is_outside_enclave(result, length) == 0 {
set_errno(ESGX);
- result = -1 as isize as *mut c_void;
+ result = -1_isize as *mut c_void;
}
} else {
set_errno(error);
}
} else {
set_errno(ESGX);
- result = -1 as isize as *mut c_void;
+ result = -1_isize as *mut c_void;
}
result
}
@@ -1008,6 +1023,29 @@
result
}
+pub unsafe fn openat(dirfd: c_int, pathname: *const c_char, flags: c_int) -> c_int {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+
+ let status = u_openat_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ dirfd,
+ pathname,
+ flags,
+ );
+
+ if status == sgx_status_t::SGX_SUCCESS {
+ if result == -1 {
+ set_errno(error);
+ }
+ } else {
+ set_errno(ESGX);
+ result = -1;
+ }
+ result
+}
+
pub unsafe fn fstat(fd: c_int, buf: *mut stat) -> c_int {
let mut result: c_int = 0;
let mut error: c_int = 0;
@@ -1346,6 +1384,29 @@
result
}
+pub unsafe fn unlinkat(dirfd: c_int, pathname: *const c_char, flags: c_int) -> c_int {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+
+ let status = u_unlinkat_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ dirfd,
+ pathname,
+ flags,
+ );
+
+ if status == sgx_status_t::SGX_SUCCESS {
+ if result == -1 {
+ set_errno(error);
+ }
+ } else {
+ set_errno(ESGX);
+ result = -1;
+ }
+ result
+}
+
pub unsafe fn linkat(
olddirfd: c_int,
oldpath: *const c_char,
@@ -1528,6 +1589,23 @@
result
}
+pub unsafe fn fdopendir(fd: c_int) -> *mut DIR {
+ let mut result: *mut DIR = ptr::null_mut();
+ let mut error: c_int = 0;
+
+ let status = u_fdopendir_ocall(&mut result as *mut *mut DIR, &mut error as *mut c_int, fd);
+
+ if status == sgx_status_t::SGX_SUCCESS {
+ if result.is_null() {
+ set_errno(error);
+ }
+ } else {
+ set_errno(ESGX);
+ result = ptr::null_mut();
+ }
+ result
+}
+
pub unsafe fn opendir(pathname: *const c_char) -> *mut DIR {
let mut result: *mut DIR = ptr::null_mut();
let mut error: c_int = 0;
@@ -2425,7 +2503,7 @@
let mut result: c_int = 0;
let mut error: c_int = 0;
let len_in: socklen_t = if !addrlen.is_null() { *addrlen } else { 0 };
- let mut len_out: socklen_t = 0 as socklen_t;
+ let mut len_out: socklen_t = 0;
let status = u_accept_ocall(
&mut result as *mut c_int,
&mut error as *mut c_int,
@@ -2459,7 +2537,7 @@
let mut result: c_int = 0;
let mut error: c_int = 0;
let len_in: socklen_t = if !addrlen.is_null() { *addrlen } else { 0 };
- let mut len_out: socklen_t = 0 as socklen_t;
+ let mut len_out: socklen_t = 0;
let status = u_accept4_ocall(
&mut result as *mut c_int,
&mut error as *mut c_int,
@@ -2781,7 +2859,7 @@
let mut result: ssize_t = 0;
let mut error: c_int = 0;
let len_in: socklen_t = if !addrlen.is_null() { *addrlen } else { 0 };
- let mut len_out: socklen_t = 0 as socklen_t;
+ let mut len_out: socklen_t = 0;
if buf.is_null() || sgx_is_within_enclave(buf, len) == 0 {
set_errno(EINVAL);
@@ -3012,7 +3090,7 @@
let mut result: c_int = 0;
let mut error: c_int = 0;
let len_in: socklen_t = if !optlen.is_null() { *optlen } else { 0 };
- let mut len_out: socklen_t = 0 as socklen_t;
+ let mut len_out: socklen_t = 0;
let status = u_getsockopt_ocall(
&mut result as *mut c_int,
@@ -3044,7 +3122,7 @@
let mut result: c_int = 0;
let mut error: c_int = 0;
let len_in: socklen_t = if !addrlen.is_null() { *addrlen } else { 0 };
- let mut len_out: socklen_t = 0 as socklen_t;
+ let mut len_out: socklen_t = 0;
let status = u_getpeername_ocall(
&mut result as *mut c_int,
&mut error as *mut c_int,
@@ -3073,7 +3151,7 @@
let mut result: c_int = 0;
let mut error: c_int = 0;
let len_in: socklen_t = if !addrlen.is_null() { *addrlen } else { 0 };
- let mut len_out: socklen_t = 0 as socklen_t;
+ let mut len_out: socklen_t = 0;
let status = u_getsockname_ocall(
&mut result as *mut c_int,
&mut error as *mut c_int,
@@ -3219,7 +3297,7 @@
cur_ptr = cur.ai_next;
}
- if addrinfo_vec.len() > 0 {
+ if !addrinfo_vec.is_empty() {
if result == 0 {
for i in 0..addrinfo_vec.len() - 1 {
addrinfo_vec[i].ai_next = addrinfo_vec[i + 1].as_mut() as *mut addrinfo;
diff --git a/sgx_no_tstd/Cargo.toml b/sgx_no_tstd/Cargo.toml
index 213e6a6..914b1f6 100644
--- a/sgx_no_tstd/Cargo.toml
+++ b/sgx_no_tstd/Cargo.toml
@@ -7,7 +7,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_no_tstd"
diff --git a/sgx_no_tstd/build.rs b/sgx_no_tstd/build.rs
index e1d22fa..c529fee 100644
--- a/sgx_no_tstd/build.rs
+++ b/sgx_no_tstd/build.rs
@@ -15,8 +15,6 @@
// specific language governing permissions and limitations
// under the License.
-#![feature(available_parallelism)]
-
extern crate sgx_build_helper as build_helper;
use build_helper::{native_lib_boilerplate, run};
diff --git a/sgx_panic_abort/Cargo.toml b/sgx_panic_abort/Cargo.toml
index d8084b0..0e01779 100644
--- a/sgx_panic_abort/Cargo.toml
+++ b/sgx_panic_abort/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://dingelish.github.io/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
test = false
diff --git a/sgx_panic_unwind/Cargo.toml b/sgx_panic_unwind/Cargo.toml
index df1a35c..9f654be 100644
--- a/sgx_panic_unwind/Cargo.toml
+++ b/sgx_panic_unwind/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://dingelish.github.io/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
test = false
diff --git a/sgx_panic_unwind/src/dwarf/eh.rs b/sgx_panic_unwind/src/dwarf/eh.rs
index 7394fea..6c59df3 100644
--- a/sgx_panic_unwind/src/dwarf/eh.rs
+++ b/sgx_panic_unwind/src/dwarf/eh.rs
@@ -138,7 +138,11 @@
#[inline]
fn round_up(unrounded: usize, align: usize) -> Result<usize, ()> {
- if align.is_power_of_two() { Ok((unrounded + align - 1) & !(align - 1)) } else { Err(()) }
+ if align.is_power_of_two() {
+ Ok((unrounded + align - 1) & !(align - 1))
+ } else {
+ Err(())
+ }
}
unsafe fn read_encoded_pointer(
diff --git a/sgx_panic_unwind/src/gcc.rs b/sgx_panic_unwind/src/gcc.rs
index 4f507f5..56d95ea 100644
--- a/sgx_panic_unwind/src/gcc.rs
+++ b/sgx_panic_unwind/src/gcc.rs
@@ -87,7 +87,7 @@
// determine whether the exception was thrown by their own runtime.
fn rust_exception_class() -> uw::_Unwind_Exception_Class {
// M O Z \0 R U S T -- vendor, language
- 0x4d4f5a_00_52555354
+ 0x4d4f_5a00_5255_5354
}
// Register ids were lifted from LLVM's TargetLowering::getExceptionPointerRegister()
@@ -122,16 +122,14 @@
};
if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
match eh_action {
- EHAction::None |
- EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND,
+ EHAction::None | EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND,
EHAction::Catch(_) => uw::_URC_HANDLER_FOUND,
EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR,
}
} else {
match eh_action {
EHAction::None => uw::_URC_CONTINUE_UNWIND,
- EHAction::Cleanup(lpad) |
- EHAction::Catch(lpad) => {
+ EHAction::Cleanup(lpad) | EHAction::Catch(lpad) => {
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.0, exception_object as uintptr_t);
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0);
uw::_Unwind_SetIP(context, lpad);
@@ -167,4 +165,3 @@
};
eh::find_eh_action(lsda, &eh_context)
}
-
diff --git a/sgx_panic_unwind/src/lib.rs b/sgx_panic_unwind/src/lib.rs
index fb98924..3e2e111 100644
--- a/sgx_panic_unwind/src/lib.rs
+++ b/sgx_panic_unwind/src/lib.rs
@@ -44,12 +44,14 @@
mod dwarf;
+/// # Safety
#[rustc_std_internal_symbol]
#[allow(improper_ctypes_definitions)]
pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static) {
Box::into_raw(imp::cleanup(payload))
}
+/// # Safety
// Entry point for raising an exception, just delegates to the platform-specific
// implementation.
#[rustc_std_internal_symbol]
diff --git a/sgx_rand/Cargo.toml b/sgx_rand/Cargo.toml
index 09a7545..1a942d5 100644
--- a/sgx_rand/Cargo.toml
+++ b/sgx_rand/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_rand"
diff --git a/sgx_rand_derive/Cargo.toml b/sgx_rand_derive/Cargo.toml
index be5026c..0b77310 100644
--- a/sgx_rand_derive/Cargo.toml
+++ b/sgx_rand_derive/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_rand_derive"
diff --git a/sgx_serialize/Cargo.toml b/sgx_serialize/Cargo.toml
index f415fa5..665244f 100644
--- a/sgx_serialize/Cargo.toml
+++ b/sgx_serialize/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_serialize"
diff --git a/sgx_serialize_derive/Cargo.toml b/sgx_serialize_derive/Cargo.toml
index 9619005..5ce9db3 100644
--- a/sgx_serialize_derive/Cargo.toml
+++ b/sgx_serialize_derive/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_serialize_derive"
diff --git a/sgx_serialize_derive_internals/Cargo.toml b/sgx_serialize_derive_internals/Cargo.toml
index b499f09..239cd3c 100644
--- a/sgx_serialize_derive_internals/Cargo.toml
+++ b/sgx_serialize_derive_internals/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_serialize_derive_internals"
diff --git a/sgx_signal/Cargo.toml b/sgx_signal/Cargo.toml
index 0db8992..7ba3f47 100644
--- a/sgx_signal/Cargo.toml
+++ b/sgx_signal/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_signal"
diff --git a/sgx_signal/src/exception.rs b/sgx_signal/src/exception.rs
index 0f9f7a8..daa541e 100644
--- a/sgx_signal/src/exception.rs
+++ b/sgx_signal/src/exception.rs
@@ -46,7 +46,7 @@
}
#[allow(unknown_lints, bare_trait_objects)]
-type ExceptionHandler = Fn(&mut sgx_exception_info_t) -> ContinueType + Send + Sync;
+type ExceptionHandler = dyn Fn(&mut sgx_exception_info_t) -> ContinueType + Send + Sync;
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct HandlerId(NonZeroU64);
diff --git a/sgx_tcrypto/Cargo.toml b/sgx_tcrypto/Cargo.toml
index 2d010cb..379b830 100644
--- a/sgx_tcrypto/Cargo.toml
+++ b/sgx_tcrypto/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_tcrypto"
diff --git a/sgx_tcrypto_helper/Cargo.toml b/sgx_tcrypto_helper/Cargo.toml
index e85af17..b24f01c 100644
--- a/sgx_tcrypto_helper/Cargo.toml
+++ b/sgx_tcrypto_helper/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_tcrypto_helper"
diff --git a/sgx_tcrypto_helper/x86_64-unknown-linux-sgx.json b/sgx_tcrypto_helper/x86_64-unknown-linux-sgx.json
deleted file mode 100644
index 69b38be..0000000
--- a/sgx_tcrypto_helper/x86_64-unknown-linux-sgx.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "arch": "x86_64",
- "cpu": "x86-64",
- "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
- "dynamic-linking": true,
- "env": "sgx",
- "exe-allocation-crate": "alloc_system",
- "executables": true,
- "has-elf-tls": true,
- "has-rpath": true,
- "linker-flavor": "gcc",
- "linker-is-gnu": true,
- "llvm-target": "x86_64-unknown-linux-gnu",
- "max-atomic-width": 64,
- "os": "linux",
- "position-independent-executables": true,
- "pre-link-args": {
- "gcc": [
- "-Wl,--as-needed",
- "-Wl,-z,noexecstack",
- "-m64"
- ]
- },
- "relro-level": "full",
- "stack-probes": {
- "kind": "inline-or-call",
- "min-llvm-version-for-inline": [
- 11,
- 0,
- 1
- ]
- },
- "target-c-int-width": "32",
- "target-endian": "little",
- "target-family": "unix",
- "target-pointer-width": "64",
- "vendor": "mesalock"
-}
diff --git a/sgx_tdh/Cargo.toml b/sgx_tdh/Cargo.toml
index cf30524..f65a594 100644
--- a/sgx_tdh/Cargo.toml
+++ b/sgx_tdh/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_tdh"
diff --git a/sgx_tkey_exchange/Cargo.toml b/sgx_tkey_exchange/Cargo.toml
index fae39e2..f55cc8e 100644
--- a/sgx_tkey_exchange/Cargo.toml
+++ b/sgx_tkey_exchange/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_tkey_exchange"
diff --git a/sgx_tprotected_fs/Cargo.toml b/sgx_tprotected_fs/Cargo.toml
index 4808968..3978625 100644
--- a/sgx_tprotected_fs/Cargo.toml
+++ b/sgx_tprotected_fs/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_tprotected_fs"
diff --git a/sgx_trts/BUILD b/sgx_trts/BUILD
index 4027e9e..9dec8b6 100644
--- a/sgx_trts/BUILD
+++ b/sgx_trts/BUILD
@@ -3,7 +3,7 @@
rust_library(
name = "sgx_trts",
srcs = glob(["src/*.rs"]),
- edition = "2018",
+ edition = "2021",
visibility = ["//visibility:public"],
deps = [
"//sgx_libc",
diff --git a/sgx_trts/Cargo.toml b/sgx_trts/Cargo.toml
index 79a0919..d43b81a 100644
--- a/sgx_trts/Cargo.toml
+++ b/sgx_trts/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_trts"
diff --git a/sgx_trts/src/c_str.rs b/sgx_trts/src/c_str.rs
index 329b96f..da052e1 100644
--- a/sgx_trts/src/c_str.rs
+++ b/sgx_trts/src/c_str.rs
@@ -366,7 +366,6 @@
/// Basic usage:
///
/// ```
- /// #![feature(cstring_from_vec_with_nul)]
/// use std::ffi::CString;
///
/// // Some invalid bytes in a vector
@@ -443,38 +442,61 @@
/// internal 0 byte. The [`NulError`] returned will contain the bytes as well as
/// the position of the nul byte.
pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
- trait SpecIntoVec {
- fn into_vec(self) -> Vec<u8>;
+ trait SpecNewImpl {
+ fn spec_new_impl(self) -> Result<CString, NulError>;
}
- impl<T: Into<Vec<u8>>> SpecIntoVec for T {
- default fn into_vec(self) -> Vec<u8> {
- self.into()
- }
- }
- // Specialization for avoiding reallocation.
- impl SpecIntoVec for &'_ [u8] {
- fn into_vec(self) -> Vec<u8> {
- let mut v = Vec::with_capacity(self.len() + 1);
- v.extend(self);
- v
- }
- }
- impl SpecIntoVec for &'_ str {
- fn into_vec(self) -> Vec<u8> {
- let mut v = Vec::with_capacity(self.len() + 1);
- v.extend(self.as_bytes());
- v
+
+ impl<T: Into<Vec<u8>>> SpecNewImpl for T {
+ default fn spec_new_impl(self) -> Result<CString, NulError> {
+ let bytes: Vec<u8> = self.into();
+ match memchr::memchr(0, &bytes) {
+ Some(i) => Err(NulError(i, bytes)),
+ None => Ok(unsafe { CString::_from_vec_unchecked(bytes) }),
+ }
}
}
- Self::_new(SpecIntoVec::into_vec(t))
- }
+ // Specialization for avoiding reallocation
+ #[inline(always)] // Without that it is not inlined into specializations
+ fn spec_new_impl_bytes(bytes: &[u8]) -> Result<CString, NulError> {
+ // We cannot have such large slice that we would overflow here
+ // but using `checked_add` allows LLVM to assume that capacity never overflows
+ // and generate twice shorter code.
+ // `saturating_add` doesn't help for some reason.
+ let capacity = bytes.len().checked_add(1).unwrap();
- fn _new(bytes: Vec<u8>) -> Result<CString, NulError> {
- match memchr::memchr(0, &bytes) {
- Some(i) => Err(NulError(i, bytes)),
- None => Ok(unsafe { CString::from_vec_unchecked(bytes) }),
+ // Allocate before validation to avoid duplication of allocation code.
+ // We still need to allocate and copy memory even if we get an error.
+ let mut buffer = Vec::with_capacity(capacity);
+ buffer.extend(bytes);
+
+ // Check memory of self instead of new buffer.
+ // This allows better optimizations if lto enabled.
+ match memchr::memchr(0, bytes) {
+ Some(i) => Err(NulError(i, buffer)),
+ None => Ok(unsafe { CString::_from_vec_unchecked(buffer) }),
+ }
}
+
+ impl SpecNewImpl for &'_ [u8] {
+ fn spec_new_impl(self) -> Result<CString, NulError> {
+ spec_new_impl_bytes(self)
+ }
+ }
+
+ impl SpecNewImpl for &'_ str {
+ fn spec_new_impl(self) -> Result<CString, NulError> {
+ spec_new_impl_bytes(self.as_bytes())
+ }
+ }
+
+ impl SpecNewImpl for &'_ mut [u8] {
+ fn spec_new_impl(self) -> Result<CString, NulError> {
+ spec_new_impl_bytes(self)
+ }
+ }
+
+ t.spec_new_impl()
}
/// Creates a C-compatible string by consuming a byte vector,
@@ -497,10 +519,15 @@
/// }
/// ```
#[must_use]
- pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
+ pub unsafe fn from_vec_unchecked(v: Vec<u8>) -> Self {
+ debug_assert!(memchr::memchr(0, &v).is_none());
+ Self::_from_vec_unchecked(v)
+ }
+
+ unsafe fn _from_vec_unchecked(mut v: Vec<u8>) -> Self {
v.reserve_exact(1);
v.push(0);
- CString {
+ Self {
inner: v.into_boxed_slice(),
}
}
@@ -620,11 +647,10 @@
/// let err = cstring.into_string().err().expect("into_string().err() failed");
/// assert_eq!(err.utf8_error().valid_up_to(), 1);
/// ```
-
pub fn into_string(self) -> Result<String, IntoStringError> {
String::from_utf8(self.into_bytes()).map_err(|e| IntoStringError {
error: e.utf8_error(),
- inner: unsafe { CString::from_vec_unchecked(e.into_bytes()) },
+ inner: unsafe { Self::_from_vec_unchecked(e.into_bytes()) },
})
}
@@ -766,7 +792,6 @@
/// # Example
///
/// ```
- /// #![feature(cstring_from_vec_with_nul)]
/// use std::ffi::CString;
/// assert_eq!(
/// unsafe { CString::from_vec_with_nul_unchecked(b"abc\0".to_vec()) },
@@ -775,6 +800,11 @@
/// ```
#[must_use]
pub unsafe fn from_vec_with_nul_unchecked(v: Vec<u8>) -> Self {
+ debug_assert!(memchr::memchr(0, &v).unwrap() + 1 == v.len());
+ Self::_from_vec_with_nul_unchecked(v)
+ }
+
+ unsafe fn _from_vec_with_nul_unchecked(v: Vec<u8>) -> Self {
Self {
inner: v.into_boxed_slice(),
}
@@ -796,7 +826,6 @@
/// when called without the ending nul byte.
///
/// ```
- /// #![feature(cstring_from_vec_with_nul)]
/// use std::ffi::CString;
/// assert_eq!(
/// CString::from_vec_with_nul(b"abc\0".to_vec())
@@ -808,7 +837,6 @@
/// An incorrectly formatted [`Vec`] will produce an error.
///
/// ```
- /// #![feature(cstring_from_vec_with_nul)]
/// use std::ffi::{CString, FromVecWithNulError};
/// // Interior nul byte
/// let _: FromVecWithNulError = CString::from_vec_with_nul(b"a\0bc".to_vec()).unwrap_err();
@@ -821,7 +849,7 @@
Some(nul_pos) if nul_pos + 1 == v.len() => {
// SAFETY: We know there is only one nul byte, at the end
// of the vec.
- Ok(unsafe { Self::from_vec_with_nul_unchecked(v) })
+ Ok(unsafe { Self::_from_vec_with_nul_unchecked(v) })
}
Some(nul_pos) => Err(FromVecWithNulError {
error_kind: FromBytesWithNulErrorKind::InteriorNul(nul_pos),
@@ -852,7 +880,7 @@
#[inline]
fn deref(&self) -> &CStr {
- unsafe { CStr::from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) }
+ unsafe { CStr::_from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) }
}
}
@@ -909,6 +937,8 @@
}
impl<'a> From<Cow<'a, CStr>> for CString {
+ /// Converts a `Cow<'a, CStr>` into a `CString`, by copying the contents if they are
+ /// borrowed.
#[inline]
fn from(s: Cow<'a, CStr>) -> Self {
s.into_owned()
@@ -916,6 +946,8 @@
}
impl From<&CStr> for Box<CStr> {
+ /// Converts a `&CStr` into a `Box<CStr>`,
+ /// by copying the contents into a newly allocated [`Box`].
fn from(s: &CStr) -> Box<CStr> {
let boxed: Box<[u8]> = Box::from(s.to_bytes_with_nul());
unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) }
@@ -923,6 +955,8 @@
}
impl From<Cow<'_, CStr>> for Box<CStr> {
+ /// Converts a `Cow<'a, CStr>` into a `Box<CStr>`,
+ /// by copying the contents if they are borrowed.
#[inline]
fn from(cow: Cow<'_, CStr>) -> Box<CStr> {
match cow {
@@ -956,7 +990,7 @@
};
// SAFETY: `v` cannot contain null bytes, given the type-level
// invariant of `NonZeroU8`.
- CString::from_vec_unchecked(v)
+ Self::_from_vec_unchecked(v)
}
}
}
@@ -1001,7 +1035,8 @@
}
impl From<CString> for Arc<CStr> {
- /// Converts a [`CString`] into an <code>[Arc]<[CStr]></code> without copying or allocating.
+ /// Converts a [`CString`] into an <code>[Arc]<[CStr]></code> by moving the [`CString`]
+ /// data into a new [`Arc`] buffer.
#[inline]
fn from(s: CString) -> Arc<CStr> {
let arc: Arc<[u8]> = Arc::from(s.into_inner());
@@ -1010,6 +1045,8 @@
}
impl From<&CStr> for Arc<CStr> {
+ /// Converts a `&CStr` into a `Arc<CStr>`,
+ /// by copying the contents into a newly allocated [`Arc`].
#[inline]
fn from(s: &CStr) -> Arc<CStr> {
let arc: Arc<[u8]> = Arc::from(s.to_bytes_with_nul());
@@ -1018,7 +1055,8 @@
}
impl From<CString> for Rc<CStr> {
- /// Converts a [`CString`] into an <code>[Rc]<[CStr]></code> without copying or allocating.
+ /// Converts a [`CString`] into an <code>[Rc]<[CStr]></code> by moving the [`CString`]
+ /// data into a new [`Arc`] buffer.
#[inline]
fn from(s: CString) -> Rc<CStr> {
let rc: Rc<[u8]> = Rc::from(s.into_inner());
@@ -1027,6 +1065,8 @@
}
impl From<&CStr> for Rc<CStr> {
+ /// Converts a `&CStr` into a `Rc<CStr>`,
+ /// by copying the contents into a newly allocated [`Rc`].
#[inline]
fn from(s: &CStr) -> Rc<CStr> {
let rc: Rc<[u8]> = Rc::from(s.to_bytes_with_nul());
@@ -1146,7 +1186,7 @@
// The cast from c_char to u8 is ok because a c_char is always one byte.
let len = libc::strlen(ptr);
let ptr = ptr as *const u8;
- CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
+ Self::_from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
}
/// Creates a C string wrapper from a byte slice.
@@ -1181,15 +1221,16 @@
/// let cstr = CStr::from_bytes_with_nul(b"he\0llo\0");
/// assert!(cstr.is_err());
/// ```
- pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&CStr, FromBytesWithNulError> {
+ pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
let nul_pos = memchr::memchr(0, bytes);
- if let Some(nul_pos) = nul_pos {
- if nul_pos + 1 != bytes.len() {
- return Err(FromBytesWithNulError::interior_nul(nul_pos));
+ match nul_pos {
+ Some(nul_pos) if nul_pos + 1 == bytes.len() => {
+ // SAFETY: We know there is only one nul byte, at the end
+ // of the byte slice.
+ Ok(unsafe { Self::_from_bytes_with_nul_unchecked(bytes) })
}
- Ok(unsafe { CStr::from_bytes_with_nul_unchecked(bytes) })
- } else {
- Err(FromBytesWithNulError::not_nul_terminated())
+ Some(nul_pos) => Err(FromBytesWithNulError::interior_nul(nul_pos)),
+ None => Err(FromBytesWithNulError::not_nul_terminated()),
}
}
@@ -1213,12 +1254,19 @@
#[inline]
#[must_use]
pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
+ // We're in a const fn, so this is the best we can do
+ debug_assert!(!bytes.is_empty() && bytes[bytes.len() - 1] == 0);
+ Self::_from_bytes_with_nul_unchecked(bytes)
+ }
+
+ #[inline]
+ const unsafe fn _from_bytes_with_nul_unchecked(bytes: &[u8]) -> &Self {
// SAFETY: Casting to CStr is safe because its internal representation
// is a [u8] too (safe only inside std).
// Dereferencing the obtained pointer is safe because it comes from a
// reference. Making a reference is then safe because its lifetime
// is bound by the lifetime of the given `bytes`.
- &*(bytes as *const [u8] as *const CStr)
+ &*(bytes as *const [u8] as *const Self)
}
/// Returns the inner pointer to this C string.
@@ -1450,6 +1498,7 @@
}
impl From<&CStr> for CString {
+ /// Copies the contents of the `&CStr` into a newly allocated `CString`.
fn from(s: &CStr) -> CString {
s.to_owned()
}
@@ -1473,7 +1522,7 @@
// byte, since otherwise we could get an empty string that doesn't end
// in a null.
if index.start < bytes.len() {
- unsafe { CStr::from_bytes_with_nul_unchecked(&bytes[index.start..]) }
+ unsafe { CStr::_from_bytes_with_nul_unchecked(&bytes[index.start..]) }
} else {
panic!(
"index out of bounds: the len is {} but the index is {}",
diff --git a/sgx_trts/src/enclave.rs b/sgx_trts/src/enclave.rs
index 6759491..76f510f 100644
--- a/sgx_trts/src/enclave.rs
+++ b/sgx_trts/src/enclave.rs
@@ -562,6 +562,7 @@
unsafe { g_global_data.tcs_max_num as u32 }
}
+#[allow(clippy::collapsible_if, clippy::nonminimal_bool)]
pub fn rsgx_get_tcs_num() -> (u32, u32, u32) {
let gd = unsafe {
let p = rsgx_get_global_data();
diff --git a/sgx_trts/src/lib.rs b/sgx_trts/src/lib.rs
index 15be2d4..7659bdc 100644
--- a/sgx_trts/src/lib.rs
+++ b/sgx_trts/src/lib.rs
@@ -64,17 +64,17 @@
#![no_std]
#![cfg_attr(target_env = "sgx", feature(rustc_private))]
-#![allow(incomplete_features)]
#![feature(allocator_api)]
-#![feature(asm)]
-#![feature(const_raw_ptr_deref)]
-#![allow(non_camel_case_types)]
-#![allow(non_upper_case_globals)]
-#![allow(non_snake_case)]
#![feature(specialization)]
#![feature(vec_into_raw_parts)]
#![feature(toowned_clone_into)]
#![feature(rustc_attrs)]
+#![allow(incomplete_features)]
+#![allow(non_camel_case_types)]
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(clippy::missing_safety_doc)]
+#![allow(clippy::derive_hash_xor_eq)]
#[cfg(target_env = "sgx")]
extern crate sgx_types;
diff --git a/sgx_trts/src/veh.rs b/sgx_trts/src/veh.rs
index 88ae687..19b7342 100644
--- a/sgx_trts/src/veh.rs
+++ b/sgx_trts/src/veh.rs
@@ -107,6 +107,7 @@
///
/// The exception handler was not unregistered (not a valid pointer, handler not found).
///
+#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn rsgx_unregister_exception_handler(handle: exception_handle) -> bool {
let ret = unsafe { sgx_unregister_exception_handler(handle) };
ret != 0
diff --git a/sgx_tse/Cargo.toml b/sgx_tse/Cargo.toml
index 2ece588..2ba59fd 100644
--- a/sgx_tse/Cargo.toml
+++ b/sgx_tse/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_tse"
diff --git a/sgx_tseal/Cargo.toml b/sgx_tseal/Cargo.toml
index 180edd0..45cb55a 100644
--- a/sgx_tseal/Cargo.toml
+++ b/sgx_tseal/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_tseal"
diff --git a/sgx_tstd/Cargo.toml b/sgx_tstd/Cargo.toml
index 2d27a6e..cac5bd6 100644
--- a/sgx_tstd/Cargo.toml
+++ b/sgx_tstd/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_tstd"
diff --git a/sgx_tstd/hashbrown/CHANGELOG.md b/sgx_tstd/hashbrown/CHANGELOG.md
index c88d3e0..4637bd0 100644
--- a/sgx_tstd/hashbrown/CHANGELOG.md
+++ b/sgx_tstd/hashbrown/CHANGELOG.md
@@ -2,11 +2,41 @@
All notable changes to this project will be documented in this file.
-The format is based on [Keep a Changelog](http://keepachangelog.com/)
-and this project adheres to [Semantic Versioning](http://semver.org/).
+The format is based on [Keep a Changelog](https://keepachangelog.com/)
+and this project adheres to [Semantic Versioning](https://semver.org/).
## [Unreleased]
+## [v0.12.0] - 2022-01-17
+
+## Added
+
+- Added `From<[T; N]>` and `From<[(K, V); N]>` for `HashSet` and `HashMap` respectively. (#297)
+- Added an `allocator()` getter to HashMap and HashSet. (#257)
+- Added `insert_unique_unchecked` to `HashMap` and `HashSet`. (#293)
+- Added `into_keys` and `into_values` to HashMap. (#295)
+- Implement `From<array>` on `HashSet` and `HashMap`. (#298)
+- Added `entry_ref` API to `HashMap`. (#201)
+
+## Changed
+
+- Bumped minimum Rust version to 1.56.1 and edition to 2021.
+- Use u64 for the GroupWord on WebAssembly. (#271)
+- Optimized `find`. (#279)
+- Made rehashing and resizing less generic to reduce compilation time. (#282)
+- Inlined small functions. (#283)
+- Use `BuildHasher::hash_one` when `feature = "nightly"` is enabled. (#292)
+- Relaxed the bounds on `Debug` for `HashSet`. (#296)
+- Rename `get_each_mut` to `get_many_mut` and align API with the stdlib. (#291)
+- Don't hash the key when searching in an empty table. (#305)
+
+## Fixed
+
+- Guard against allocations exceeding isize::MAX. (#268)
+- Made `RawTable::insert_no_grow` unsafe. (#254)
+- Inline `static_empty`. (#280)
+- Fixed trait bounds on Send/Sync impls. (#303)
+
## [v0.11.2] - 2021-03-25
## Fixed
@@ -307,7 +337,8 @@
- Initial release
-[Unreleased]: https://github.com/rust-lang/hashbrown/compare/v0.11.2...HEAD
+[Unreleased]: https://github.com/rust-lang/hashbrown/compare/v0.12.0...HEAD
+[v0.12.0]: https://github.com/rust-lang/hashbrown/compare/v0.11.2...v0.12.0
[v0.11.2]: https://github.com/rust-lang/hashbrown/compare/v0.11.1...v0.11.2
[v0.11.1]: https://github.com/rust-lang/hashbrown/compare/v0.11.0...v0.11.1
[v0.11.0]: https://github.com/rust-lang/hashbrown/compare/v0.10.0...v0.11.0
diff --git a/sgx_tstd/hashbrown/Cargo.toml b/sgx_tstd/hashbrown/Cargo.toml
index 7bcb6ba..6927577 100644
--- a/sgx_tstd/hashbrown/Cargo.toml
+++ b/sgx_tstd/hashbrown/Cargo.toml
@@ -1,85 +1,63 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
[package]
-edition = "2018"
name = "hashbrown_tstd"
-version = "0.11.2"
+version = "0.12.0"
authors = ["Amanieu d'Antras <amanieu@gmail.com>"]
-exclude = [".travis.yml", "bors.toml", "/ci/*"]
description = "A Rust port of Google's SwissTable hash map"
+license = "Apache-2.0/MIT"
+repository = "https://github.com/rust-lang/hashbrown"
readme = "README.md"
keywords = ["hash", "no_std", "hashmap", "swisstable"]
categories = ["data-structures", "no-std"]
-license = "Apache-2.0/MIT"
-repository = "https://github.com/rust-lang/hashbrown"
-[package.metadata.docs.rs]
-features = ["nightly", "rayon", "serde", "raw"]
-[dependencies.ahash]
-version = "0.7.0"
-optional = true
-default-features = false
+exclude = [".github", "bors.toml", "/ci/*"]
+edition = "2021"
-# [dependencies.alloc]
-# version = "1.0.0"
-# optional = true
-# package = "rustc-std-workspace-alloc"
+[dependencies]
+# For the default hasher
+ahash = { version = "0.7.0", default-features = false, optional = true }
-[dependencies.bumpalo]
-version = "3.5.0"
-optional = true
+# For external trait impls
+rayon = { version = "1.0", optional = true }
+serde = { version = "1.0.25", default-features = false, optional = true }
-# [dependencies.compiler_builtins]
-# version = "0.1.2"
-# optional = true
+# When built as part of libstd
+# core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
+# compiler_builtins = { version = "0.1.2", optional = true }
+# alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
-# [dependencies.core]
-# version = "1.0.0"
-# optional = true
-# package = "rustc-std-workspace-core"
+# Optional support for bumpalo
+bumpalo = { version = "3.5.0", optional = true }
-[dependencies.rayon]
-version = "1.0"
-optional = true
-
-[dependencies.serde]
-version = "1.0.25"
-optional = true
-default-features = false
-[dev-dependencies.doc-comment]
-version = "0.3.1"
-
-[dev-dependencies.fnv]
-version = "1.0.7"
-
-[dev-dependencies.lazy_static]
-version = "1.4"
-
-[dev-dependencies.rand]
-version = "0.7.3"
-features = ["small_rng"]
-
-[dev-dependencies.rayon]
-version = "1.0"
-
-[dev-dependencies.serde_test]
-version = "1.0"
+[dev-dependencies]
+lazy_static = "1.4"
+rand = { version = "0.8.3", features = ["small_rng"] }
+rayon = "1.0"
+fnv = "1.0.7"
+serde_test = "1.0"
+doc-comment = "0.3.1"
[features]
-ahash-compile-time-rng = ["ahash/compile-time-rng"]
default = ["ahash", "inline-more"]
-inline-more = []
+
+ahash-compile-time-rng = ["ahash/compile-time-rng"]
nightly = []
-raw = []
-# rustc-dep-of-std = ["nightly", "core", "compiler_builtins", "alloc", "rustc-internal-api"]
-rustc-dep-of-std = ["nightly", "rustc-internal-api"]
rustc-internal-api = []
+# rustc-dep-of-std = [
+# "nightly",
+# "core",
+# "compiler_builtins",
+# "alloc",
+# "rustc-internal-api",
+# ]
+rustc-dep-of-std = [
+ "nightly",
+ "rustc-internal-api",
+]
+raw = []
+
+# Enables usage of `#[inline]` on far more functions than by default in this
+# crate. This may lead to a performance increase but often comes at a compile
+# time cost.
+inline-more = []
+
+[package.metadata.docs.rs]
+features = ["nightly", "rayon", "serde", "raw"]
diff --git a/sgx_tstd/hashbrown/Cargo.toml.orig b/sgx_tstd/hashbrown/Cargo.toml.orig
deleted file mode 100644
index a056c3c..0000000
--- a/sgx_tstd/hashbrown/Cargo.toml.orig
+++ /dev/null
@@ -1,59 +0,0 @@
-[package]
-name = "hashbrown"
-version = "0.11.2"
-authors = ["Amanieu d'Antras <amanieu@gmail.com>"]
-description = "A Rust port of Google's SwissTable hash map"
-license = "Apache-2.0/MIT"
-repository = "https://github.com/rust-lang/hashbrown"
-readme = "README.md"
-keywords = ["hash", "no_std", "hashmap", "swisstable"]
-categories = ["data-structures", "no-std"]
-exclude = [".travis.yml", "bors.toml", "/ci/*"]
-edition = "2018"
-
-[dependencies]
-# For the default hasher
-ahash = { version = "0.7.0", default-features = false, optional = true }
-
-# For external trait impls
-rayon = { version = "1.0", optional = true }
-serde = { version = "1.0.25", default-features = false, optional = true }
-
-# When built as part of libstd
-core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
-compiler_builtins = { version = "0.1.2", optional = true }
-alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
-
-# Optional support for bumpalo
-bumpalo = { version = "3.5.0", optional = true }
-
-[dev-dependencies]
-lazy_static = "1.4"
-rand = { version = "0.7.3", features = ["small_rng"] }
-rayon = "1.0"
-fnv = "1.0.7"
-serde_test = "1.0"
-doc-comment = "0.3.1"
-
-[features]
-default = ["ahash", "inline-more"]
-
-ahash-compile-time-rng = ["ahash/compile-time-rng"]
-nightly = []
-rustc-internal-api = []
-rustc-dep-of-std = [
- "nightly",
- "core",
- "compiler_builtins",
- "alloc",
- "rustc-internal-api",
-]
-raw = []
-
-# Enables usage of `#[inline]` on far more functions than by default in this
-# crate. This may lead to a performance increase but often comes at a compile
-# time cost.
-inline-more = []
-
-[package.metadata.docs.rs]
-features = ["nightly", "rayon", "serde", "raw"]
diff --git a/sgx_tstd/hashbrown/README.md b/sgx_tstd/hashbrown/README.md
index 86664c4..0b29cb5 100644
--- a/sgx_tstd/hashbrown/README.md
+++ b/sgx_tstd/hashbrown/README.md
@@ -1,10 +1,10 @@
hashbrown
=========
-[![Build Status](https://travis-ci.com/rust-lang/hashbrown.svg?branch=master)](https://travis-ci.com/rust-lang/hashbrown)
+[![Build Status](https://github.com/rust-lang/hashbrown/actions/workflows/rust.yml/badge.svg)](https://github.com/rust-lang/hashbrown/actions)
[![Crates.io](https://img.shields.io/crates/v/hashbrown.svg)](https://crates.io/crates/hashbrown)
[![Documentation](https://docs.rs/hashbrown/badge.svg)](https://docs.rs/hashbrown)
-[![Rust](https://img.shields.io/badge/rust-1.49.0%2B-blue.svg?maxAge=3600)](https://github.com/rust-lang/hashbrown)
+[![Rust](https://img.shields.io/badge/rust-1.56.1%2B-blue.svg?maxAge=3600)](https://github.com/rust-lang/hashbrown)
This crate is a Rust port of Google's high-performance [SwissTable] hash
map, adapted to make it a drop-in replacement for Rust's standard `HashMap`
@@ -114,8 +114,8 @@
Licensed under either of:
- * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
+ * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
+ * MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)
at your option.
diff --git a/sgx_tstd/hashbrown/benches/bench.rs b/sgx_tstd/hashbrown/benches/bench.rs
index 568c513..c393b9a 100644
--- a/sgx_tstd/hashbrown/benches/bench.rs
+++ b/sgx_tstd/hashbrown/benches/bench.rs
@@ -38,7 +38,7 @@
type Item = usize;
fn next(&mut self) -> Option<usize> {
// Add 1 then multiply by some 32 bit prime.
- self.state = self.state.wrapping_add(1).wrapping_mul(3787392781);
+ self.state = self.state.wrapping_add(1).wrapping_mul(3_787_392_781);
Some(self.state)
}
}
diff --git a/sgx_tstd/hashbrown/benches/insert_unique_unchecked.rs b/sgx_tstd/hashbrown/benches/insert_unique_unchecked.rs
new file mode 100644
index 0000000..857ad18
--- /dev/null
+++ b/sgx_tstd/hashbrown/benches/insert_unique_unchecked.rs
@@ -0,0 +1,32 @@
+//! Compare `insert` and `insert_unique_unchecked` operations performance.
+
+#![feature(test)]
+
+extern crate test;
+
+use hashbrown::HashMap;
+use test::Bencher;
+
+#[bench]
+fn insert(b: &mut Bencher) {
+ let keys: Vec<String> = (0..1000).map(|i| format!("xxxx{}yyyy", i)).collect();
+ b.iter(|| {
+ let mut m = HashMap::with_capacity(1000);
+ for k in &keys {
+ m.insert(k, k);
+ }
+ m
+ });
+}
+
+#[bench]
+fn insert_unique_unchecked(b: &mut Bencher) {
+ let keys: Vec<String> = (0..1000).map(|i| format!("xxxx{}yyyy", i)).collect();
+ b.iter(|| {
+ let mut m = HashMap::with_capacity(1000);
+ for k in &keys {
+ m.insert_unique_unchecked(k, k);
+ }
+ m
+ });
+}
diff --git a/sgx_tstd/hashbrown/ci/miri.sh b/sgx_tstd/hashbrown/ci/miri.sh
new file mode 100644
index 0000000..6b95c2d
--- /dev/null
+++ b/sgx_tstd/hashbrown/ci/miri.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env sh
+
+set -ex
+
+export CARGO_NET_RETRY=5
+export CARGO_NET_TIMEOUT=10
+
+MIRI_NIGHTLY=nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri)
+echo "Installing latest nightly with Miri: $MIRI_NIGHTLY"
+rustup default "$MIRI_NIGHTLY"
+
+rustup component add miri
+cargo miri setup
+
+cargo miri test
diff --git a/sgx_tstd/hashbrown/ci/run.sh b/sgx_tstd/hashbrown/ci/run.sh
new file mode 100644
index 0000000..a8257e5
--- /dev/null
+++ b/sgx_tstd/hashbrown/ci/run.sh
@@ -0,0 +1,47 @@
+#!/usr/bin/env sh
+
+set -ex
+
+: "${TARGET?The TARGET environment variable must be set.}"
+
+if [ "${NO_STD}" = "1" ]; then
+ # Unfortunately serde currently doesn't work without std due to a cargo bug.
+ FEATURES="rustc-internal-api"
+ OP="build"
+else
+ FEATURES="rustc-internal-api,serde,rayon,raw,bumpalo"
+ OP="test"
+fi
+if [ "${CHANNEL}" = "nightly" ]; then
+ FEATURES="${FEATURES},nightly"
+ export RUSTFLAGS="$RUSTFLAGS -D warnings"
+fi
+
+CARGO=cargo
+if [ "${CROSS}" = "1" ]; then
+ export CARGO_NET_RETRY=5
+ export CARGO_NET_TIMEOUT=10
+
+ cargo install --git https://github.com/rust-embedded/cross.git
+ CARGO=cross
+fi
+
+# Make sure we can compile without the default hasher
+"${CARGO}" -vv build --target="${TARGET}" --no-default-features
+"${CARGO}" -vv build --target="${TARGET}" --release --no-default-features
+
+"${CARGO}" -vv ${OP} --target="${TARGET}"
+"${CARGO}" -vv ${OP} --target="${TARGET}" --features "${FEATURES}"
+
+"${CARGO}" -vv ${OP} --target="${TARGET}" --release
+"${CARGO}" -vv ${OP} --target="${TARGET}" --release --features "${FEATURES}"
+
+if [ "${CHANNEL}" = "nightly" ] && [ "${NO_STD}" != 1 ]; then
+ # Run benchmark on native targets, build them on non-native ones:
+ NO_RUN=""
+ if [ "${CROSS}" = "1" ]; then
+ NO_RUN="--no-run"
+ fi
+
+ "${CARGO}" -vv bench "${NO_RUN}" --features "${FEATURES}"
+fi
diff --git a/sgx_tstd/hashbrown/ci/tools.sh b/sgx_tstd/hashbrown/ci/tools.sh
new file mode 100644
index 0000000..5ae8b2e
--- /dev/null
+++ b/sgx_tstd/hashbrown/ci/tools.sh
@@ -0,0 +1,41 @@
+#!/usr/bin/env sh
+
+set -ex
+
+retry() {
+ result=0
+ count=1
+ max=5
+ while [ "$count" -le 3 ]; do
+ [ "$result" -ne 0 ] && {
+ printf "\nRetrying, %d of %d\n" $count $max >&2
+ }
+ "$@"
+ result=$?
+ [ $result -eq 0 ] && break
+ count=$((count + 1))
+ sleep 1
+ done
+
+ [ "$count" -gt 3 ] && {
+ printf "\nFailed %d times.\n" $max >&2
+ }
+
+ return $result
+}
+
+
+if retry rustup component add rustfmt ; then
+ cargo fmt --all -- --check
+fi
+
+if retry rustup component add clippy ; then
+ cargo clippy --all --tests --features serde,rayon,bumpalo -- -D clippy::all -D clippy::pedantic
+ cargo clippy --all --tests --features raw -- -D clippy::all -D clippy::pedantic \
+ -A clippy::missing_safety_doc -A clippy::missing_errors_doc
+fi
+
+if command -v shellcheck ; then
+ shellcheck --version
+ shellcheck ci/*.sh
+fi
diff --git a/sgx_tstd/hashbrown/src/external_trait_impls/rayon/helpers.rs b/sgx_tstd/hashbrown/src/external_trait_impls/rayon/helpers.rs
index 9382007..070b08c 100644
--- a/sgx_tstd/hashbrown/src/external_trait_impls/rayon/helpers.rs
+++ b/sgx_tstd/hashbrown/src/external_trait_impls/rayon/helpers.rs
@@ -4,6 +4,7 @@
use rayon::iter::{IntoParallelIterator, ParallelIterator};
/// Helper for collecting parallel iterators to an intermediary
+#[allow(clippy::linkedlist)] // yes, we need linked list here for efficient appending!
pub(super) fn collect<I: IntoParallelIterator>(iter: I) -> (LinkedList<Vec<I::Item>>, usize) {
let list = iter
.into_par_iter()
diff --git a/sgx_tstd/hashbrown/src/external_trait_impls/rayon/map.rs b/sgx_tstd/hashbrown/src/external_trait_impls/rayon/map.rs
index 61b7380..14d91c2 100644
--- a/sgx_tstd/hashbrown/src/external_trait_impls/rayon/map.rs
+++ b/sgx_tstd/hashbrown/src/external_trait_impls/rayon/map.rs
@@ -512,7 +512,7 @@
where
H: Hasher,
{
- self.k.hash(state)
+ self.k.hash(state);
}
}
@@ -679,7 +679,7 @@
fn test_values_mut() {
let vec = vec![(1, 1), (2, 2), (3, 3)];
let mut map: HashMap<_, _> = vec.into_par_iter().collect();
- map.par_values_mut().for_each(|value| *value = (*value) * 2);
+ map.par_values_mut().for_each(|value| *value *= 2);
let values: Vec<_> = map.par_values().cloned().collect();
assert_eq!(values.len(), 3);
assert!(values.contains(&2));
diff --git a/sgx_tstd/hashbrown/src/external_trait_impls/rayon/raw.rs b/sgx_tstd/hashbrown/src/external_trait_impls/rayon/raw.rs
index 18da1ea..883303e 100644
--- a/sgx_tstd/hashbrown/src/external_trait_impls/rayon/raw.rs
+++ b/sgx_tstd/hashbrown/src/external_trait_impls/rayon/raw.rs
@@ -87,7 +87,7 @@
}
}
-impl<T: Send, A: Allocator + Clone> ParallelIterator for RawIntoParIter<T, A> {
+impl<T: Send, A: Allocator + Clone + Send> ParallelIterator for RawIntoParIter<T, A> {
type Item = T;
#[cfg_attr(feature = "inline-more", inline)]
@@ -116,7 +116,7 @@
marker: PhantomData<&'a RawTable<T, A>>,
}
-unsafe impl<T, A: Allocator + Clone> Send for RawParDrain<'_, T, A> {}
+unsafe impl<T: Send, A: Allocator + Clone> Send for RawParDrain<'_, T, A> {}
impl<T, A: Allocator + Clone> RawParDrain<'_, T, A> {
#[cfg_attr(feature = "inline-more", inline)]
@@ -134,7 +134,7 @@
C: UnindexedConsumer<Self::Item>,
{
let _guard = guard(self.table, |table| unsafe {
- table.as_mut().clear_no_drop()
+ table.as_mut().clear_no_drop();
});
let iter = unsafe { self.table.as_ref().iter().iter };
mem::forget(self);
@@ -146,7 +146,9 @@
impl<T, A: Allocator + Clone> Drop for RawParDrain<'_, T, A> {
fn drop(&mut self) {
// If drive_unindexed is not called then simply clear the table.
- unsafe { self.table.as_mut().clear() }
+ unsafe {
+ self.table.as_mut().clear();
+ }
}
}
@@ -175,7 +177,7 @@
{
// Make sure to modify the iterator in-place so that any remaining
// elements are processed in our Drop impl.
- while let Some(item) = self.iter.next() {
+ for item in &mut self.iter {
folder = folder.consume(unsafe { item.read() });
if folder.full() {
return folder;
@@ -193,7 +195,7 @@
fn drop(&mut self) {
// Drop all remaining elements
if mem::needs_drop::<T>() {
- while let Some(item) = self.iter.next() {
+ for item in &mut self.iter {
unsafe {
item.drop();
}
diff --git a/sgx_tstd/hashbrown/src/external_trait_impls/serde.rs b/sgx_tstd/hashbrown/src/external_trait_impls/serde.rs
index 7816e78..4d62dee 100644
--- a/sgx_tstd/hashbrown/src/external_trait_impls/serde.rs
+++ b/sgx_tstd/hashbrown/src/external_trait_impls/serde.rs
@@ -161,6 +161,7 @@
deserializer.deserialize_seq(visitor)
}
+ #[allow(clippy::missing_errors_doc)]
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
where
D: Deserializer<'de>,
diff --git a/sgx_tstd/hashbrown/src/lib.rs b/sgx_tstd/hashbrown/src/lib.rs
index b2d6584..701b6ea 100644
--- a/sgx_tstd/hashbrown/src/lib.rs
+++ b/sgx_tstd/hashbrown/src/lib.rs
@@ -21,7 +21,8 @@
allocator_api,
slice_ptr_get,
nonnull_slice_from_raw_parts,
- maybe_uninit_array_assume_init
+ maybe_uninit_array_assume_init,
+ build_hasher_simple_hash_one
)
)]
#![allow(
@@ -128,20 +129,6 @@
},
}
-/// The error type for [`RawTable::get_each_mut`](crate::raw::RawTable::get_each_mut),
-/// [`HashMap::get_each_mut`], and [`HashMap::get_each_key_value_mut`].
-#[cfg(feature = "nightly")]
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub enum UnavailableMutError {
- /// The requested entry is not present in the table.
- Absent,
- /// The requested entry is present, but a mutable reference to it was already created and
- /// returned from this call to `get_each_mut` or `get_each_key_value_mut`.
- ///
- /// Includes the index of the existing mutable reference in the returned array.
- Duplicate(usize),
-}
-
/// Wrapper around `Bump` which allows it to be used as an allocator for
/// `HashMap`, `HashSet` and `RawTable`.
///
diff --git a/sgx_tstd/hashbrown/src/macros.rs b/sgx_tstd/hashbrown/src/macros.rs
index 0279597..4de6b5a 100644
--- a/sgx_tstd/hashbrown/src/macros.rs
+++ b/sgx_tstd/hashbrown/src/macros.rs
@@ -57,8 +57,8 @@
// default fn syntax for specialization changes in the future.
#[cfg(feature = "nightly")]
macro_rules! default_fn {
- ($($tt:tt)*) => {
- default $($tt)*
+ (#[$($a:tt)*] $($tt:tt)*) => {
+ #[$($a)*] default $($tt)*
}
}
#[cfg(not(feature = "nightly"))]
diff --git a/sgx_tstd/hashbrown/src/map.rs b/sgx_tstd/hashbrown/src/map.rs
index ab11288..d0592cb 100644
--- a/sgx_tstd/hashbrown/src/map.rs
+++ b/sgx_tstd/hashbrown/src/map.rs
@@ -1,15 +1,11 @@
use crate::raw::{Allocator, Bucket, Global, RawDrain, RawIntoIter, RawIter, RawTable};
use crate::TryReserveError;
-#[cfg(feature = "nightly")]
-use crate::UnavailableMutError;
use core::borrow::Borrow;
use core::fmt::{self, Debug};
use core::hash::{BuildHasher, Hash};
use core::iter::{FromIterator, FusedIterator};
use core::marker::PhantomData;
use core::mem;
-#[cfg(feature = "nightly")]
-use core::mem::MaybeUninit;
use core::ops::Index;
/// Default hasher for `HashMap`.
@@ -244,6 +240,7 @@
move |x| k.eq(x.borrow())
}
+#[cfg(not(feature = "nightly"))]
#[cfg_attr(feature = "inline-more", inline)]
pub(crate) fn make_hash<K, Q, S>(hash_builder: &S, val: &Q) -> u64
where
@@ -257,6 +254,18 @@
state.finish()
}
+#[cfg(feature = "nightly")]
+#[cfg_attr(feature = "inline-more", inline)]
+pub(crate) fn make_hash<K, Q, S>(hash_builder: &S, val: &Q) -> u64
+where
+ K: Borrow<Q>,
+ Q: Hash + ?Sized,
+ S: BuildHasher,
+{
+ hash_builder.hash_one(val)
+}
+
+#[cfg(not(feature = "nightly"))]
#[cfg_attr(feature = "inline-more", inline)]
pub(crate) fn make_insert_hash<K, S>(hash_builder: &S, val: &K) -> u64
where
@@ -269,6 +278,16 @@
state.finish()
}
+#[cfg(feature = "nightly")]
+#[cfg_attr(feature = "inline-more", inline)]
+pub(crate) fn make_insert_hash<K, S>(hash_builder: &S, val: &K) -> u64
+where
+ K: Hash,
+ S: BuildHasher,
+{
+ hash_builder.hash_one(val)
+}
+
#[cfg(feature = "ahash")]
impl<K, V> HashMap<K, V, DefaultHashBuilder> {
/// Creates an empty `HashMap`.
@@ -395,6 +414,12 @@
}
impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
+ /// Returns a reference to the underlying allocator.
+ #[inline]
+ pub fn allocator(&self) -> &A {
+ self.table.allocator()
+ }
+
/// Creates an empty `HashMap` which will use the given hash builder to hash
/// keys. It will be allocated with the given allocator.
///
@@ -773,6 +798,52 @@
pub fn clear(&mut self) {
self.table.clear();
}
+
+ /// Creates a consuming iterator visiting all the keys in arbitrary order.
+ /// The map cannot be used after calling this.
+ /// The iterator element type is `K`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("a", 1);
+ /// map.insert("b", 2);
+ /// map.insert("c", 3);
+ ///
+ /// let vec: Vec<&str> = map.into_keys().collect();
+ /// ```
+ #[inline]
+ pub fn into_keys(self) -> IntoKeys<K, V, A> {
+ IntoKeys {
+ inner: self.into_iter(),
+ }
+ }
+
+ /// Creates a consuming iterator visiting all the values in arbitrary order.
+ /// The map cannot be used after calling this.
+ /// The iterator element type is `V`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("a", 1);
+ /// map.insert("b", 2);
+ /// map.insert("c", 3);
+ ///
+ /// let vec: Vec<i32> = map.into_values().collect();
+ /// ```
+ #[inline]
+ pub fn into_values(self) -> IntoValues<K, V, A> {
+ IntoValues {
+ inner: self.into_iter(),
+ }
+ }
}
impl<K, V, S, A> HashMap<K, V, S, A>
@@ -915,6 +986,46 @@
}
}
+ /// Gets the given key's corresponding entry by reference in the map for in-place manipulation.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let mut words: HashMap<String, usize> = HashMap::new();
+ /// let source = ["poneyland", "horseyland", "poneyland", "poneyland"];
+ /// for (i, &s) in source.iter().enumerate() {
+ /// let counter = words.entry_ref(s).or_insert(0);
+ /// *counter += 1;
+ /// }
+ ///
+ /// assert_eq!(words["poneyland"], 3);
+ /// assert_eq!(words["horseyland"], 1);
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn entry_ref<'a, 'b, Q: ?Sized>(&'a mut self, key: &'b Q) -> EntryRef<'a, 'b, K, Q, V, S, A>
+ where
+ K: Borrow<Q>,
+ Q: Hash + Eq,
+ {
+ let hash = make_hash::<K, Q, S>(&self.hash_builder, key);
+ if let Some(elem) = self.table.find(hash, equivalent_key(key)) {
+ EntryRef::Occupied(OccupiedEntryRef {
+ hash,
+ key: Some(KeyOrRef::Borrowed(key)),
+ elem,
+ table: self,
+ })
+ } else {
+ EntryRef::Vacant(VacantEntryRef {
+ hash,
+ key: KeyOrRef::Borrowed(key),
+ table: self,
+ })
+ }
+ }
+
/// Returns a reference to the value corresponding to the key.
///
/// The key may be any borrowed form of the map's key type, but
@@ -985,8 +1096,12 @@
K: Borrow<Q>,
Q: Hash + Eq,
{
- let hash = make_hash::<K, Q, S>(&self.hash_builder, k);
- self.table.get(hash, equivalent_key(k))
+ if self.table.is_empty() {
+ None
+ } else {
+ let hash = make_hash::<K, Q, S>(&self.hash_builder, k);
+ self.table.get(hash, equivalent_key(k))
+ }
}
/// Returns the key-value pair corresponding to the supplied key, with a mutable reference to value.
@@ -1093,24 +1208,24 @@
K: Borrow<Q>,
Q: Hash + Eq,
{
- let hash = make_hash::<K, Q, S>(&self.hash_builder, k);
- self.table.get_mut(hash, equivalent_key(k))
+ if self.table.is_empty() {
+ None
+ } else {
+ let hash = make_hash::<K, Q, S>(&self.hash_builder, k);
+ self.table.get_mut(hash, equivalent_key(k))
+ }
}
/// Attempts to get mutable references to `N` values in the map at once.
///
- /// Returns an array of length `N` with the results of each query. For soundness,
- /// at most one mutable reference will be returned to any value. An
- /// `Err(UnavailableMutError::Duplicate(i))` in the returned array indicates that a suitable
- /// key-value pair exists, but a mutable reference to the value already occurs at index `i` in
- /// the returned array.
- ///
- /// This method is available only if the `nightly` feature is enabled.
+ /// Returns an array of length `N` with the results of each query. For soundness, at most one
+ /// mutable reference will be returned to any value. `None` will be returned if any of the
+ /// keys are duplicates or missing.
///
/// # Examples
///
/// ```
- /// use hashbrown::{HashMap, UnavailableMutError};
+ /// use hashbrown::HashMap;
///
/// let mut libraries = HashMap::new();
/// libraries.insert("Bodleian Library".to_string(), 1602);
@@ -1118,58 +1233,59 @@
/// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
/// libraries.insert("Library of Congress".to_string(), 1800);
///
- /// let got = libraries.get_each_mut([
- /// "Athenæum",
- /// "New York Public Library",
+ /// let got = libraries.get_many_mut([
/// "Athenæum",
/// "Library of Congress",
/// ]);
/// assert_eq!(
/// got,
- /// [
- /// Ok(&mut 1807),
- /// Err(UnavailableMutError::Absent),
- /// Err(UnavailableMutError::Duplicate(0)),
- /// Ok(&mut 1800),
- /// ]
+ /// Some([
+ /// &mut 1807,
+ /// &mut 1800,
+ /// ]),
/// );
+ ///
+ /// // Missing keys result in None
+ /// let got = libraries.get_many_mut([
+ /// "Athenæum",
+ /// "New York Public Library",
+ /// ]);
+ /// assert_eq!(got, None);
+ ///
+ /// // Duplicate keys result in None
+ /// let got = libraries.get_many_mut([
+ /// "Athenæum",
+ /// "Athenæum",
+ /// ]);
+ /// assert_eq!(got, None);
/// ```
- #[cfg(feature = "nightly")]
- pub fn get_each_mut<Q: ?Sized, const N: usize>(
- &mut self,
- ks: [&Q; N],
- ) -> [Result<&'_ mut V, UnavailableMutError>; N]
+ pub fn get_many_mut<Q: ?Sized, const N: usize>(&mut self, ks: [&Q; N]) -> Option<[&'_ mut V; N]>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
- let mut pairs = self.get_each_inner_mut(ks);
- // TODO use `MaybeUninit::uninit_array` here instead once that's stable.
- let mut out: [MaybeUninit<Result<&'_ mut V, UnavailableMutError>>; N] =
- unsafe { MaybeUninit::uninit().assume_init() };
- for i in 0..N {
- out[i] = MaybeUninit::new(
- mem::replace(&mut pairs[i], Err(UnavailableMutError::Absent)).map(|(_, v)| v),
- );
- }
- unsafe { MaybeUninit::array_assume_init(out) }
+ self.get_many_mut_inner(ks).map(|res| res.map(|(_, v)| v))
}
- /// Attempts to get mutable references to `N` values in the map at once, with immutable
- /// references to the corresponding keys.
+ /// Attempts to get mutable references to `N` values in the map at once, without validating that
+ /// the values are unique.
///
- /// Returns an array of length `N` with the results of each query. For soundness,
- /// at most one mutable reference will be returned to any value. An
- /// `Err(UnavailableMutError::Duplicate(i))` in the returned array indicates that a suitable
- /// key-value pair exists, but a mutable reference to the value already occurs at index `i` in
- /// the returned array.
+ /// Returns an array of length `N` with the results of each query. `None` will be returned if
+ /// any of the keys are missing.
///
- /// This method is available only if the `nightly` feature is enabled.
+ /// For a safe alternative see [`get_many_mut`].
+ ///
+ /// # Safety
+ ///
+ /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
+ /// references are not used.
+ ///
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
///
/// # Examples
///
/// ```
- /// use hashbrown::{HashMap, UnavailableMutError};
+ /// use hashbrown::HashMap;
///
/// let mut libraries = HashMap::new();
/// libraries.insert("Bodleian Library".to_string(), 1602);
@@ -1177,49 +1293,176 @@
/// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
/// libraries.insert("Library of Congress".to_string(), 1800);
///
- /// let got = libraries.get_each_key_value_mut([
- /// "Bodleian Library",
- /// "Herzogin-Anna-Amalia-Bibliothek",
- /// "Herzogin-Anna-Amalia-Bibliothek",
- /// "Gewandhaus",
+ /// let got = libraries.get_many_mut([
+ /// "Athenæum",
+ /// "Library of Congress",
/// ]);
/// assert_eq!(
/// got,
- /// [
- /// Ok((&"Bodleian Library".to_string(), &mut 1602)),
- /// Ok((&"Herzogin-Anna-Amalia-Bibliothek".to_string(), &mut 1691)),
- /// Err(UnavailableMutError::Duplicate(1)),
- /// Err(UnavailableMutError::Absent),
- /// ]
+ /// Some([
+ /// &mut 1807,
+ /// &mut 1800,
+ /// ]),
/// );
+ ///
+ /// // Missing keys result in None
+ /// let got = libraries.get_many_mut([
+ /// "Athenæum",
+ /// "New York Public Library",
+ /// ]);
+ /// assert_eq!(got, None);
/// ```
- #[cfg(feature = "nightly")]
- pub fn get_each_key_value_mut<Q: ?Sized, const N: usize>(
+ pub unsafe fn get_many_unchecked_mut<Q: ?Sized, const N: usize>(
&mut self,
ks: [&Q; N],
- ) -> [Result<(&'_ K, &'_ mut V), UnavailableMutError>; N]
+ ) -> Option<[&'_ mut V; N]>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
- let mut pairs = self.get_each_inner_mut(ks);
- // TODO use `MaybeUninit::uninit_array` here instead once that's stable.
- let mut out: [MaybeUninit<Result<(&'_ K, &'_ mut V), UnavailableMutError>>; N] =
- unsafe { MaybeUninit::uninit().assume_init() };
- for i in 0..N {
- out[i] = MaybeUninit::new(
- mem::replace(&mut pairs[i], Err(UnavailableMutError::Absent))
- .map(|(k, v)| (&*k, v)),
- );
- }
- unsafe { MaybeUninit::array_assume_init(out) }
+ self.get_many_unchecked_mut_inner(ks)
+ .map(|res| res.map(|(_, v)| v))
}
- #[cfg(feature = "nightly")]
- fn get_each_inner_mut<Q: ?Sized, const N: usize>(
+ /// Attempts to get mutable references to `N` values in the map at once, with immutable
+ /// references to the corresponding keys.
+ ///
+ /// Returns an array of length `N` with the results of each query. For soundness, at most one
+ /// mutable reference will be returned to any value. `None` will be returned if any of the keys
+ /// are duplicates or missing.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let mut libraries = HashMap::new();
+ /// libraries.insert("Bodleian Library".to_string(), 1602);
+ /// libraries.insert("Athenæum".to_string(), 1807);
+ /// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
+ /// libraries.insert("Library of Congress".to_string(), 1800);
+ ///
+ /// let got = libraries.get_many_key_value_mut([
+ /// "Bodleian Library",
+ /// "Herzogin-Anna-Amalia-Bibliothek",
+ /// ]);
+ /// assert_eq!(
+ /// got,
+ /// Some([
+ /// (&"Bodleian Library".to_string(), &mut 1602),
+ /// (&"Herzogin-Anna-Amalia-Bibliothek".to_string(), &mut 1691),
+ /// ]),
+ /// );
+ /// // Missing keys result in None
+ /// let got = libraries.get_many_key_value_mut([
+ /// "Bodleian Library",
+ /// "Gewandhaus",
+ /// ]);
+ /// assert_eq!(got, None);
+ ///
+ /// // Duplicate keys result in None
+ /// let got = libraries.get_many_key_value_mut([
+ /// "Bodleian Library",
+ /// "Herzogin-Anna-Amalia-Bibliothek",
+ /// "Herzogin-Anna-Amalia-Bibliothek",
+ /// ]);
+ /// assert_eq!(got, None);
+ /// ```
+ pub fn get_many_key_value_mut<Q: ?Sized, const N: usize>(
&mut self,
ks: [&Q; N],
- ) -> [Result<&'_ mut (K, V), UnavailableMutError>; N]
+ ) -> Option<[(&'_ K, &'_ mut V); N]>
+ where
+ K: Borrow<Q>,
+ Q: Hash + Eq,
+ {
+ self.get_many_mut_inner(ks)
+ .map(|res| res.map(|(k, v)| (&*k, v)))
+ }
+
+ /// Attempts to get mutable references to `N` values in the map at once, with immutable
+ /// references to the corresponding keys, without validating that the values are unique.
+ ///
+ /// Returns an array of length `N` with the results of each query. `None` will be returned if
+ /// any of the keys are missing.
+ ///
+ /// For a safe alternative see [`get_many_key_value_mut`].
+ ///
+ /// # Safety
+ ///
+ /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
+ /// references are not used.
+ ///
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let mut libraries = HashMap::new();
+ /// libraries.insert("Bodleian Library".to_string(), 1602);
+ /// libraries.insert("Athenæum".to_string(), 1807);
+ /// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
+ /// libraries.insert("Library of Congress".to_string(), 1800);
+ ///
+ /// let got = libraries.get_many_key_value_mut([
+ /// "Bodleian Library",
+ /// "Herzogin-Anna-Amalia-Bibliothek",
+ /// ]);
+ /// assert_eq!(
+ /// got,
+ /// Some([
+ /// (&"Bodleian Library".to_string(), &mut 1602),
+ /// (&"Herzogin-Anna-Amalia-Bibliothek".to_string(), &mut 1691),
+ /// ]),
+ /// );
+ /// // Missing keys result in None
+ /// let got = libraries.get_many_key_value_mut([
+ /// "Bodleian Library",
+ /// "Gewandhaus",
+ /// ]);
+ /// assert_eq!(got, None);
+ /// ```
+ pub unsafe fn get_many_key_value_unchecked_mut<Q: ?Sized, const N: usize>(
+ &mut self,
+ ks: [&Q; N],
+ ) -> Option<[(&'_ K, &'_ mut V); N]>
+ where
+ K: Borrow<Q>,
+ Q: Hash + Eq,
+ {
+ self.get_many_unchecked_mut_inner(ks)
+ .map(|res| res.map(|(k, v)| (&*k, v)))
+ }
+
+ fn get_many_mut_inner<Q: ?Sized, const N: usize>(
+ &mut self,
+ ks: [&Q; N],
+ ) -> Option<[&'_ mut (K, V); N]>
+ where
+ K: Borrow<Q>,
+ Q: Hash + Eq,
+ {
+ let hashes = self.build_hashes_inner(ks);
+ self.table
+ .get_many_mut(hashes, |i, (k, _)| ks[i].eq(k.borrow()))
+ }
+
+ unsafe fn get_many_unchecked_mut_inner<Q: ?Sized, const N: usize>(
+ &mut self,
+ ks: [&Q; N],
+ ) -> Option<[&'_ mut (K, V); N]>
+ where
+ K: Borrow<Q>,
+ Q: Hash + Eq,
+ {
+ let hashes = self.build_hashes_inner(ks);
+ self.table
+ .get_many_unchecked_mut(hashes, |i, (k, _)| ks[i].eq(k.borrow()))
+ }
+
+ fn build_hashes_inner<Q: ?Sized, const N: usize>(&self, ks: [&Q; N]) -> [u64; N]
where
K: Borrow<Q>,
Q: Hash + Eq,
@@ -1228,8 +1471,7 @@
for i in 0..N {
hashes[i] = make_hash::<K, Q, S>(&self.hash_builder, ks[i]);
}
- self.table
- .get_each_mut(hashes, |i, (k, _)| ks[i].eq(k.borrow()))
+ hashes
}
/// Inserts a key-value pair into the map.
@@ -1269,6 +1511,36 @@
}
}
+ /// Insert a key-value pair into the map without checking
+ /// if the key already exists in the map.
+ ///
+ /// Returns a reference to the key and value just inserted.
+ ///
+ /// This operation is safe if a key does not exist in the map.
+ ///
+ /// However, if a key exists in the map already, the behavior is unspecified:
+ /// this operation may panic, loop forever, or any following operation with the map
+ /// may panic, loop forever or return arbitrary result.
+ ///
+ /// That said, this operation (and following operations) are guaranteed to
+ /// not violate memory safety.
+ ///
+ /// This operation is faster than regular insert, because it does not perform
+ /// lookup before insertion.
+ ///
+ /// This operation is useful during initial population of the map.
+ /// For example, when constructing a map from another map, we know
+ /// that keys are unique.
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn insert_unique_unchecked(&mut self, k: K, v: V) -> (&K, &mut V) {
+ let hash = make_insert_hash::<K, S>(&self.hash_builder, &k);
+ let bucket = self
+ .table
+ .insert(hash, (k, v), make_hasher::<K, _, V, S>(&self.hash_builder));
+ let (k_ref, v_ref) = unsafe { bucket.as_mut() };
+ (k_ref, v_ref)
+ }
+
/// Tries to insert a key-value pair into the map, and returns
/// a mutable reference to the value in the entry.
///
@@ -1495,6 +1767,27 @@
}
}
+// The default hasher is used to match the std implementation signature
+#[cfg(feature = "ahash")]
+impl<K, V, A, const N: usize> From<[(K, V); N]> for HashMap<K, V, DefaultHashBuilder, A>
+where
+ K: Eq + Hash,
+ A: Default + Allocator + Clone,
+{
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let map1 = HashMap::from([(1, 2), (3, 4)]);
+ /// let map2: HashMap<_, _> = [(1, 2), (3, 4)].into();
+ /// assert_eq!(map1, map2);
+ /// ```
+ fn from(arr: [(K, V); N]) -> Self {
+ arr.into_iter().collect()
+ }
+}
+
/// An iterator over the entries of a `HashMap`.
///
/// This `struct` is created by the [`iter`] method on [`HashMap`]. See its
@@ -1575,6 +1868,88 @@
}
}
+/// An owning iterator over the keys of a `HashMap`.
+///
+/// This `struct` is created by the [`into_keys`] method on [`HashMap`].
+/// See its documentation for more.
+///
+/// [`into_keys`]: struct.HashMap.html#method.into_keys
+/// [`HashMap`]: struct.HashMap.html
+pub struct IntoKeys<K, V, A: Allocator + Clone = Global> {
+ inner: IntoIter<K, V, A>,
+}
+
+impl<K, V, A: Allocator + Clone> Iterator for IntoKeys<K, V, A> {
+ type Item = K;
+
+ #[inline]
+ fn next(&mut self) -> Option<K> {
+ self.inner.next().map(|(k, _)| k)
+ }
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+}
+
+impl<K, V, A: Allocator + Clone> ExactSizeIterator for IntoKeys<K, V, A> {
+ #[inline]
+ fn len(&self) -> usize {
+ self.inner.len()
+ }
+}
+
+impl<K, V, A: Allocator + Clone> FusedIterator for IntoKeys<K, V, A> {}
+
+impl<K: Debug, V: Debug, A: Allocator + Clone> fmt::Debug for IntoKeys<K, V, A> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_list()
+ .entries(self.inner.iter().map(|(k, _)| k))
+ .finish()
+ }
+}
+
+/// An owning iterator over the values of a `HashMap`.
+///
+/// This `struct` is created by the [`into_values`] method on [`HashMap`].
+/// See its documentation for more.
+///
+/// [`into_values`]: struct.HashMap.html#method.into_values
+/// [`HashMap`]: struct.HashMap.html
+pub struct IntoValues<K, V, A: Allocator + Clone = Global> {
+ inner: IntoIter<K, V, A>,
+}
+
+impl<K, V, A: Allocator + Clone> Iterator for IntoValues<K, V, A> {
+ type Item = V;
+
+ #[inline]
+ fn next(&mut self) -> Option<V> {
+ self.inner.next().map(|(_, v)| v)
+ }
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+}
+
+impl<K, V, A: Allocator + Clone> ExactSizeIterator for IntoValues<K, V, A> {
+ #[inline]
+ fn len(&self) -> usize {
+ self.inner.len()
+ }
+}
+
+impl<K, V, A: Allocator + Clone> FusedIterator for IntoValues<K, V, A> {}
+
+impl<K: Debug, V: Debug, A: Allocator + Clone> fmt::Debug for IntoValues<K, V, A> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_list()
+ .entries(self.inner.iter().map(|(k, _)| k))
+ .finish()
+ }
+}
+
/// An iterator over the keys of a `HashMap`.
///
/// This `struct` is created by the [`keys`] method on [`HashMap`]. See its
@@ -1686,7 +2061,7 @@
impl<T: Iterator> Drop for ConsumeAllOnDrop<'_, T> {
#[cfg_attr(feature = "inline-more", inline)]
fn drop(&mut self) {
- self.0.for_each(drop)
+ self.0.for_each(drop);
}
}
@@ -1723,7 +2098,7 @@
F: FnMut(&K, &mut V) -> bool,
{
unsafe {
- while let Some(item) = self.iter.next() {
+ for item in &mut self.iter {
let &mut (ref key, ref mut value) = item.as_mut();
if f(key, value) {
return Some(self.table.remove(item));
@@ -1786,6 +2161,7 @@
where
K: Send,
V: Send,
+ S: Send,
A: Send + Allocator + Clone,
{
}
@@ -1793,7 +2169,8 @@
where
K: Sync,
V: Sync,
- A: Send + Allocator + Clone,
+ S: Sync,
+ A: Sync + Allocator + Clone,
{
}
@@ -2413,6 +2790,119 @@
}
}
+/// A view into a single entry in a map, which may either be vacant or occupied.
+///
+/// This `enum` is constructed from the [`entry_ref`] method on [`HashMap`].
+///
+/// [`HashMap`]: struct.HashMap.html
+/// [`entry_ref`]: struct.HashMap.html#method.entry_ref
+pub enum EntryRef<'a, 'b, K, Q: ?Sized, V, S, A = Global>
+where
+ A: Allocator + Clone,
+{
+ /// An occupied entry.
+ Occupied(OccupiedEntryRef<'a, 'b, K, Q, V, S, A>),
+
+ /// A vacant entry.
+ Vacant(VacantEntryRef<'a, 'b, K, Q, V, S, A>),
+}
+
+impl<K: Borrow<Q>, Q: ?Sized + Debug, V: Debug, S, A: Allocator + Clone> Debug
+ for EntryRef<'_, '_, K, Q, V, S, A>
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match *self {
+ EntryRef::Vacant(ref v) => f.debug_tuple("EntryRef").field(v).finish(),
+ EntryRef::Occupied(ref o) => f.debug_tuple("EntryRef").field(o).finish(),
+ }
+ }
+}
+
+enum KeyOrRef<'a, K, Q: ?Sized> {
+ Borrowed(&'a Q),
+ Owned(K),
+}
+
+impl<'a, K, Q: ?Sized> KeyOrRef<'a, K, Q> {
+ fn into_owned(self) -> K
+ where
+ K: From<&'a Q>,
+ {
+ match self {
+ Self::Borrowed(borrowed) => borrowed.into(),
+ Self::Owned(owned) => owned,
+ }
+ }
+}
+
+impl<'a, K: Borrow<Q>, Q: ?Sized> AsRef<Q> for KeyOrRef<'a, K, Q> {
+ fn as_ref(&self) -> &Q {
+ match self {
+ Self::Borrowed(borrowed) => borrowed,
+ Self::Owned(owned) => owned.borrow(),
+ }
+ }
+}
+
+/// A view into an occupied entry in a `HashMap`.
+/// It is part of the [`EntryRef`] enum.
+///
+/// [`EntryRef`]: enum.EntryRef.html
+pub struct OccupiedEntryRef<'a, 'b, K, Q: ?Sized, V, S, A: Allocator + Clone = Global> {
+ hash: u64,
+ key: Option<KeyOrRef<'b, K, Q>>,
+ elem: Bucket<(K, V)>,
+ table: &'a mut HashMap<K, V, S, A>,
+}
+
+unsafe impl<'a, 'b, K, Q, V, S, A> Send for OccupiedEntryRef<'a, 'b, K, Q, V, S, A>
+where
+ K: Send,
+ Q: Sync + ?Sized,
+ V: Send,
+ S: Send,
+ A: Send + Allocator + Clone,
+{
+}
+unsafe impl<'a, 'b, K, Q, V, S, A> Sync for OccupiedEntryRef<'a, 'b, K, Q, V, S, A>
+where
+ K: Sync,
+ Q: Sync + ?Sized,
+ V: Sync,
+ S: Sync,
+ A: Sync + Allocator + Clone,
+{
+}
+
+impl<K: Borrow<Q>, Q: ?Sized + Debug, V: Debug, S, A: Allocator + Clone> Debug
+ for OccupiedEntryRef<'_, '_, K, Q, V, S, A>
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("OccupiedEntryRef")
+ .field("key", &self.key())
+ .field("value", &self.get())
+ .finish()
+ }
+}
+
+/// A view into a vacant entry in a `HashMap`.
+/// It is part of the [`EntryRef`] enum.
+///
+/// [`EntryRef`]: enum.EntryRef.html
+pub struct VacantEntryRef<'a, 'b, K, Q: ?Sized, V, S, A: Allocator + Clone = Global> {
+ hash: u64,
+ key: KeyOrRef<'b, K, Q>,
+ table: &'a mut HashMap<K, V, S, A>,
+}
+
+impl<K: Borrow<Q>, Q: ?Sized + Debug, V, S, A: Allocator + Clone> Debug
+ for VacantEntryRef<'_, '_, K, Q, V, S, A>
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_tuple("VacantEntryRef").field(&self.key()).finish()
+ }
+}
+
/// The error returned by [`try_insert`](HashMap::try_insert) when the key already exists.
///
/// Contains the occupied entry, and the value that was not inserted.
@@ -3362,6 +3852,689 @@
}
}
+impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator + Clone> EntryRef<'a, 'b, K, Q, V, S, A> {
+ /// Sets the value of the entry, and returns an OccupiedEntryRef.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ /// let entry = map.entry_ref("horseyland").insert(37);
+ ///
+ /// assert_eq!(entry.key(), "horseyland");
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn insert(self, value: V) -> OccupiedEntryRef<'a, 'b, K, Q, V, S, A>
+ where
+ K: Hash + From<&'b Q>,
+ S: BuildHasher,
+ {
+ match self {
+ EntryRef::Occupied(mut entry) => {
+ entry.insert(value);
+ entry
+ }
+ EntryRef::Vacant(entry) => entry.insert_entry(value),
+ }
+ }
+
+ /// Ensures a value is in the entry by inserting the default if empty, and returns
+ /// a mutable reference to the value in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ ///
+ /// map.entry_ref("poneyland").or_insert(3);
+ /// assert_eq!(map["poneyland"], 3);
+ ///
+ /// *map.entry_ref("poneyland").or_insert(10) *= 2;
+ /// assert_eq!(map["poneyland"], 6);
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn or_insert(self, default: V) -> &'a mut V
+ where
+ K: Hash + From<&'b Q>,
+ S: BuildHasher,
+ {
+ match self {
+ EntryRef::Occupied(entry) => entry.into_mut(),
+ EntryRef::Vacant(entry) => entry.insert(default),
+ }
+ }
+
+ /// Ensures a value is in the entry by inserting the result of the default function if empty,
+ /// and returns a mutable reference to the value in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let mut map: HashMap<String, String> = HashMap::new();
+ /// let s = "hoho".to_string();
+ ///
+ /// map.entry_ref("poneyland").or_insert_with(|| s);
+ ///
+ /// assert_eq!(map["poneyland"], "hoho".to_string());
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V
+ where
+ K: Hash + From<&'b Q>,
+ S: BuildHasher,
+ {
+ match self {
+ EntryRef::Occupied(entry) => entry.into_mut(),
+ EntryRef::Vacant(entry) => entry.insert(default()),
+ }
+ }
+
+ /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
+ /// This method allows for generating key-derived values for insertion by providing the default
+ /// function a reference to the key that was moved during the `.entry_ref(key)` method call.
+ ///
+ /// The reference to the moved key is provided so that cloning or copying the key is
+ /// unnecessary, unlike with `.or_insert_with(|| ... )`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let mut map: HashMap<String, usize> = HashMap::new();
+ ///
+ /// map.entry_ref("poneyland").or_insert_with_key(|key| key.chars().count());
+ ///
+ /// assert_eq!(map["poneyland"], 9);
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn or_insert_with_key<F: FnOnce(&Q) -> V>(self, default: F) -> &'a mut V
+ where
+ K: Hash + Borrow<Q> + From<&'b Q>,
+ S: BuildHasher,
+ {
+ match self {
+ EntryRef::Occupied(entry) => entry.into_mut(),
+ EntryRef::Vacant(entry) => {
+ let value = default(entry.key.as_ref());
+ entry.insert(value)
+ }
+ }
+ }
+
+ /// Returns a reference to this entry's key.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ /// assert_eq!(map.entry_ref("poneyland").key(), "poneyland");
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn key(&self) -> &Q
+ where
+ K: Borrow<Q>,
+ {
+ match *self {
+ EntryRef::Occupied(ref entry) => entry.key(),
+ EntryRef::Vacant(ref entry) => entry.key(),
+ }
+ }
+
+ /// Provides in-place mutable access to an occupied entry before any
+ /// potential inserts into the map.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ ///
+ /// map.entry_ref("poneyland")
+ /// .and_modify(|e| { *e += 1 })
+ /// .or_insert(42);
+ /// assert_eq!(map["poneyland"], 42);
+ ///
+ /// map.entry_ref("poneyland")
+ /// .and_modify(|e| { *e += 1 })
+ /// .or_insert(42);
+ /// assert_eq!(map["poneyland"], 43);
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn and_modify<F>(self, f: F) -> Self
+ where
+ F: FnOnce(&mut V),
+ {
+ match self {
+ EntryRef::Occupied(mut entry) => {
+ f(entry.get_mut());
+ EntryRef::Occupied(entry)
+ }
+ EntryRef::Vacant(entry) => EntryRef::Vacant(entry),
+ }
+ }
+
+ /// Provides shared access to the key and owned access to the value of
+ /// an occupied entry and allows to replace or remove it based on the
+ /// value of the returned option.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ /// use hashbrown::hash_map::EntryRef;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ ///
+ /// let entry = map
+ /// .entry_ref("poneyland")
+ /// .and_replace_entry_with(|_k, _v| panic!());
+ ///
+ /// match entry {
+ /// EntryRef::Vacant(e) => {
+ /// assert_eq!(e.key(), "poneyland");
+ /// }
+ /// EntryRef::Occupied(_) => panic!(),
+ /// }
+ ///
+ /// map.insert("poneyland".to_string(), 42);
+ ///
+ /// let entry = map
+ /// .entry_ref("poneyland")
+ /// .and_replace_entry_with(|k, v| {
+ /// assert_eq!(k, "poneyland");
+ /// assert_eq!(v, 42);
+ /// Some(v + 1)
+ /// });
+ ///
+ /// match entry {
+ /// EntryRef::Occupied(e) => {
+ /// assert_eq!(e.key(), "poneyland");
+ /// assert_eq!(e.get(), &43);
+ /// }
+ /// EntryRef::Vacant(_) => panic!(),
+ /// }
+ ///
+ /// assert_eq!(map["poneyland"], 43);
+ ///
+ /// let entry = map
+ /// .entry_ref("poneyland")
+ /// .and_replace_entry_with(|_k, _v| None);
+ ///
+ /// match entry {
+ /// EntryRef::Vacant(e) => assert_eq!(e.key(), "poneyland"),
+ /// EntryRef::Occupied(_) => panic!(),
+ /// }
+ ///
+ /// assert!(!map.contains_key("poneyland"));
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn and_replace_entry_with<F>(self, f: F) -> Self
+ where
+ F: FnOnce(&Q, V) -> Option<V>,
+ K: Borrow<Q>,
+ {
+ match self {
+ EntryRef::Occupied(entry) => entry.replace_entry_with(f),
+ EntryRef::Vacant(_) => self,
+ }
+ }
+}
+
+impl<'a, 'b, K, Q: ?Sized, V: Default, S, A: Allocator + Clone> EntryRef<'a, 'b, K, Q, V, S, A> {
+ /// Ensures a value is in the entry by inserting the default value if empty,
+ /// and returns a mutable reference to the value in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let mut map: HashMap<&str, Option<u32>> = HashMap::new();
+ /// map.entry("poneyland").or_default();
+ ///
+ /// assert_eq!(map["poneyland"], None);
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn or_default(self) -> &'a mut V
+ where
+ K: Hash + From<&'b Q>,
+ S: BuildHasher,
+ {
+ match self {
+ EntryRef::Occupied(entry) => entry.into_mut(),
+ EntryRef::Vacant(entry) => entry.insert(Default::default()),
+ }
+ }
+}
+
+impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator + Clone> OccupiedEntryRef<'a, 'b, K, Q, V, S, A> {
+ /// Gets a reference to the key in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ /// map.entry_ref("poneyland").or_insert(12);
+ /// assert_eq!(map.entry_ref("poneyland").key(), "poneyland");
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn key(&self) -> &Q
+ where
+ K: Borrow<Q>,
+ {
+ unsafe { &self.elem.as_ref().0 }.borrow()
+ }
+
+ /// Take the ownership of the key and value from the map.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ /// use hashbrown::hash_map::EntryRef;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ /// map.entry_ref("poneyland").or_insert(12);
+ ///
+ /// if let EntryRef::Occupied(o) = map.entry_ref("poneyland") {
+ /// // We delete the entry from the map.
+ /// o.remove_entry();
+ /// }
+ ///
+ /// assert_eq!(map.contains_key("poneyland"), false);
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn remove_entry(self) -> (K, V) {
+ unsafe { self.table.table.remove(self.elem) }
+ }
+
+ /// Gets a reference to the value in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ /// use hashbrown::hash_map::EntryRef;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ /// map.entry_ref("poneyland").or_insert(12);
+ ///
+ /// if let EntryRef::Occupied(o) = map.entry_ref("poneyland") {
+ /// assert_eq!(o.get(), &12);
+ /// }
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn get(&self) -> &V {
+ unsafe { &self.elem.as_ref().1 }
+ }
+
+ /// Gets a mutable reference to the value in the entry.
+ ///
+ /// If you need a reference to the `OccupiedEntryRef` which may outlive the
+ /// destruction of the `EntryRef` value, see [`into_mut`].
+ ///
+ /// [`into_mut`]: #method.into_mut
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ /// use hashbrown::hash_map::EntryRef;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ /// map.entry_ref("poneyland").or_insert(12);
+ ///
+ /// assert_eq!(map["poneyland"], 12);
+ /// if let EntryRef::Occupied(mut o) = map.entry_ref("poneyland") {
+ /// *o.get_mut() += 10;
+ /// assert_eq!(*o.get(), 22);
+ ///
+ /// // We can use the same Entry multiple times.
+ /// *o.get_mut() += 2;
+ /// }
+ ///
+ /// assert_eq!(map["poneyland"], 24);
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn get_mut(&mut self) -> &mut V {
+ unsafe { &mut self.elem.as_mut().1 }
+ }
+
+ /// Converts the OccupiedEntryRef into a mutable reference to the value in the entry
+ /// with a lifetime bound to the map itself.
+ ///
+ /// If you need multiple references to the `OccupiedEntryRef`, see [`get_mut`].
+ ///
+ /// [`get_mut`]: #method.get_mut
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ /// use hashbrown::hash_map::EntryRef;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ /// map.entry_ref("poneyland").or_insert(12);
+ ///
+ /// assert_eq!(map["poneyland"], 12);
+ /// if let EntryRef::Occupied(o) = map.entry_ref("poneyland") {
+ /// *o.into_mut() += 10;
+ /// }
+ ///
+ /// assert_eq!(map["poneyland"], 22);
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn into_mut(self) -> &'a mut V {
+ unsafe { &mut self.elem.as_mut().1 }
+ }
+
+ /// Sets the value of the entry, and returns the entry's old value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ /// use hashbrown::hash_map::EntryRef;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ /// map.entry_ref("poneyland").or_insert(12);
+ ///
+ /// if let EntryRef::Occupied(mut o) = map.entry_ref("poneyland") {
+ /// assert_eq!(o.insert(15), 12);
+ /// }
+ ///
+ /// assert_eq!(map["poneyland"], 15);
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn insert(&mut self, mut value: V) -> V {
+ let old_value = self.get_mut();
+ mem::swap(&mut value, old_value);
+ value
+ }
+
+ /// Takes the value out of the entry, and returns it.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ /// use hashbrown::hash_map::EntryRef;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ /// map.entry_ref("poneyland").or_insert(12);
+ ///
+ /// if let EntryRef::Occupied(o) = map.entry_ref("poneyland") {
+ /// assert_eq!(o.remove(), 12);
+ /// }
+ ///
+ /// assert_eq!(map.contains_key("poneyland"), false);
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn remove(self) -> V {
+ self.remove_entry().1
+ }
+
+ /// Replaces the entry, returning the old key and value. The new key in the hash map will be
+ /// the key used to create this entry.
+ ///
+ /// # Panics
+ ///
+ /// Will panic if this OccupiedEntry was created through [`EntryRef::insert`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::hash_map::{EntryRef, HashMap};
+ /// use std::rc::Rc;
+ ///
+ /// let mut map: HashMap<Rc<str>, u32> = HashMap::new();
+ /// map.insert(Rc::from("Stringthing"), 15);
+ ///
+ /// if let EntryRef::Occupied(entry) = map.entry_ref("Stringthing") {
+ /// // Also replace the key with a handle to our other key.
+ /// let (old_key, old_value): (Rc<str>, u32) = entry.replace_entry(16);
+ /// }
+ ///
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn replace_entry(self, value: V) -> (K, V)
+ where
+ K: From<&'b Q>,
+ {
+ let entry = unsafe { self.elem.as_mut() };
+
+ let old_key = mem::replace(&mut entry.0, self.key.unwrap().into_owned());
+ let old_value = mem::replace(&mut entry.1, value);
+
+ (old_key, old_value)
+ }
+
+ /// Replaces the key in the hash map with the key used to create this entry.
+ ///
+ /// # Panics
+ ///
+ /// Will panic if this OccupiedEntry was created through [`Entry::insert`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::hash_map::{EntryRef, HashMap};
+ /// use std::rc::Rc;
+ ///
+ /// let mut map: HashMap<Rc<str>, u32> = HashMap::new();
+ /// let mut known_strings: Vec<Rc<str>> = Vec::new();
+ ///
+ /// // Initialise known strings, run program, etc.
+ ///
+ /// reclaim_memory(&mut map, &known_strings);
+ ///
+ /// fn reclaim_memory(map: &mut HashMap<Rc<str>, u32>, known_strings: &[Rc<str>] ) {
+ /// for s in known_strings {
+ /// if let EntryRef::Occupied(entry) = map.entry_ref(s.as_ref()) {
+ /// // Replaces the entry's key with our version of it in `known_strings`.
+ /// entry.replace_key();
+ /// }
+ /// }
+ /// }
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn replace_key(self) -> K
+ where
+ K: From<&'b Q>,
+ {
+ let entry = unsafe { self.elem.as_mut() };
+ mem::replace(&mut entry.0, self.key.unwrap().into_owned())
+ }
+
+ /// Provides shared access to the key and owned access to the value of
+ /// the entry and allows to replace or remove it based on the
+ /// value of the returned option.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ /// use hashbrown::hash_map::EntryRef;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ /// map.insert("poneyland".to_string(), 42);
+ ///
+ /// let entry = match map.entry_ref("poneyland") {
+ /// EntryRef::Occupied(e) => {
+ /// e.replace_entry_with(|k, v| {
+ /// assert_eq!(k, "poneyland");
+ /// assert_eq!(v, 42);
+ /// Some(v + 1)
+ /// })
+ /// }
+ /// EntryRef::Vacant(_) => panic!(),
+ /// };
+ ///
+ /// match entry {
+ /// EntryRef::Occupied(e) => {
+ /// assert_eq!(e.key(), "poneyland");
+ /// assert_eq!(e.get(), &43);
+ /// }
+ /// EntryRef::Vacant(_) => panic!(),
+ /// }
+ ///
+ /// assert_eq!(map["poneyland"], 43);
+ ///
+ /// let entry = match map.entry_ref("poneyland") {
+ /// EntryRef::Occupied(e) => e.replace_entry_with(|_k, _v| None),
+ /// EntryRef::Vacant(_) => panic!(),
+ /// };
+ ///
+ /// match entry {
+ /// EntryRef::Vacant(e) => {
+ /// assert_eq!(e.key(), "poneyland");
+ /// }
+ /// EntryRef::Occupied(_) => panic!(),
+ /// }
+ ///
+ /// assert!(!map.contains_key("poneyland"));
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn replace_entry_with<F>(self, f: F) -> EntryRef<'a, 'b, K, Q, V, S, A>
+ where
+ F: FnOnce(&Q, V) -> Option<V>,
+ K: Borrow<Q>,
+ {
+ unsafe {
+ let mut spare_key = None;
+
+ self.table
+ .table
+ .replace_bucket_with(self.elem.clone(), |(key, value)| {
+ if let Some(new_value) = f(key.borrow(), value) {
+ Some((key, new_value))
+ } else {
+ spare_key = Some(KeyOrRef::Owned(key));
+ None
+ }
+ });
+
+ if let Some(key) = spare_key {
+ EntryRef::Vacant(VacantEntryRef {
+ hash: self.hash,
+ key,
+ table: self.table,
+ })
+ } else {
+ EntryRef::Occupied(self)
+ }
+ }
+ }
+}
+
+impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator + Clone> VacantEntryRef<'a, 'b, K, Q, V, S, A> {
+ /// Gets a reference to the key that would be used when inserting a value
+ /// through the `VacantEntryRef`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ /// let key: &str = "poneyland";
+ /// assert_eq!(map.entry_ref(key).key(), "poneyland");
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn key(&self) -> &Q
+ where
+ K: Borrow<Q>,
+ {
+ self.key.as_ref()
+ }
+
+ /// Take ownership of the key.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ /// use hashbrown::hash_map::EntryRef;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ /// let key: &str = "poneyland";
+ ///
+ /// if let EntryRef::Vacant(v) = map.entry_ref(key) {
+ /// v.into_key();
+ /// }
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn into_key(self) -> K
+ where
+ K: From<&'b Q>,
+ {
+ self.key.into_owned()
+ }
+
+ /// Sets the value of the entry with the VacantEntryRef's key,
+ /// and returns a mutable reference to it.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashMap;
+ /// use hashbrown::hash_map::EntryRef;
+ ///
+ /// let mut map: HashMap<String, u32> = HashMap::new();
+ /// let key: &str = "poneyland";
+ ///
+ /// if let EntryRef::Vacant(o) = map.entry_ref(key) {
+ /// o.insert(37);
+ /// }
+ /// assert_eq!(map["poneyland"], 37);
+ /// ```
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn insert(self, value: V) -> &'a mut V
+ where
+ K: Hash + From<&'b Q>,
+ S: BuildHasher,
+ {
+ let table = &mut self.table.table;
+ let entry = table.insert_entry(
+ self.hash,
+ (self.key.into_owned(), value),
+ make_hasher::<K, _, V, S>(&self.table.hash_builder),
+ );
+ &mut entry.1
+ }
+
+ #[cfg_attr(feature = "inline-more", inline)]
+ fn insert_entry(self, value: V) -> OccupiedEntryRef<'a, 'b, K, Q, V, S, A>
+ where
+ K: Hash + From<&'b Q>,
+ S: BuildHasher,
+ {
+ let elem = self.table.table.insert(
+ self.hash,
+ (self.key.into_owned(), value),
+ make_hasher::<K, _, V, S>(&self.table.hash_builder),
+ );
+ OccupiedEntryRef {
+ hash: self.hash,
+ key: None,
+ elem,
+ table: self.table,
+ }
+ }
+}
+
impl<K, V, S, A> FromIterator<(K, V)> for HashMap<K, V, S, A>
where
K: Eq + Hash,
@@ -3500,8 +4673,8 @@
mod test_map {
use super::DefaultHashBuilder;
use super::Entry::{Occupied, Vacant};
+ use super::EntryRef;
use super::{HashMap, RawEntryMut};
- use crate::TryReserveError::*;
use rand::{rngs::SmallRng, Rng, SeedableRng};
use std::borrow::ToOwned;
use std::cell::RefCell;
@@ -3570,6 +4743,7 @@
assert_eq!(m.len(), 1);
assert!(m.insert(2, 4).is_none());
assert_eq!(m.len(), 2);
+ #[allow(clippy::redundant_clone)]
let m2 = m.clone();
assert_eq!(*m2.get(&1).unwrap(), 2);
assert_eq!(*m2.get(&2).unwrap(), 4);
@@ -3723,6 +4897,7 @@
}
});
+ #[allow(clippy::let_underscore_drop)] // kind-of a false positive
for _ in half.by_ref() {}
DROP_VECTOR.with(|v| {
@@ -3760,6 +4935,17 @@
}
#[test]
+ fn test_empty_entry_ref() {
+ let mut m: HashMap<std::string::String, bool> = HashMap::new();
+ match m.entry_ref("poneyland") {
+ EntryRef::Occupied(_) => panic!(),
+ EntryRef::Vacant(_) => {}
+ }
+ assert!(*m.entry_ref("poneyland").or_insert(true));
+ assert_eq!(m.len(), 1);
+ }
+
+ #[test]
fn test_empty_iter() {
let mut m: HashMap<i32, bool> = HashMap::new();
assert_eq!(m.drain().next(), None);
@@ -3889,6 +5075,18 @@
}
#[test]
+ fn test_insert_unique_unchecked() {
+ let mut map = HashMap::new();
+ let (k1, v1) = map.insert_unique_unchecked(10, 11);
+ assert_eq!((&10, &mut 11), (k1, v1));
+ let (k2, v2) = map.insert_unique_unchecked(20, 21);
+ assert_eq!((&20, &mut 21), (k2, v2));
+ assert_eq!(Some(&11), map.get(&10));
+ assert_eq!(Some(&21), map.get(&20));
+ assert_eq!(None, map.get(&30));
+ }
+
+ #[test]
fn test_is_empty() {
let mut m = HashMap::with_capacity(4);
assert!(m.insert(1, 2).is_none());
@@ -3934,7 +5132,7 @@
fn test_keys() {
let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
let map: HashMap<_, _> = vec.into_iter().collect();
- let keys: Vec<_> = map.keys().cloned().collect();
+ let keys: Vec<_> = map.keys().copied().collect();
assert_eq!(keys.len(), 3);
assert!(keys.contains(&1));
assert!(keys.contains(&2));
@@ -3945,7 +5143,7 @@
fn test_values() {
let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
let map: HashMap<_, _> = vec.into_iter().collect();
- let values: Vec<_> = map.values().cloned().collect();
+ let values: Vec<_> = map.values().copied().collect();
assert_eq!(values.len(), 3);
assert!(values.contains(&'a'));
assert!(values.contains(&'b'));
@@ -3957,9 +5155,9 @@
let vec = vec![(1, 1), (2, 2), (3, 3)];
let mut map: HashMap<_, _> = vec.into_iter().collect();
for value in map.values_mut() {
- *value = (*value) * 2
+ *value *= 2;
}
- let values: Vec<_> = map.values().cloned().collect();
+ let values: Vec<_> = map.values().copied().collect();
assert_eq!(values.len(), 3);
assert!(values.contains(&2));
assert!(values.contains(&4));
@@ -3967,6 +5165,30 @@
}
#[test]
+ fn test_into_keys() {
+ let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
+ let map: HashMap<_, _> = vec.into_iter().collect();
+ let keys: Vec<_> = map.into_keys().collect();
+
+ assert_eq!(keys.len(), 3);
+ assert!(keys.contains(&1));
+ assert!(keys.contains(&2));
+ assert!(keys.contains(&3));
+ }
+
+ #[test]
+ fn test_into_values() {
+ let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
+ let map: HashMap<_, _> = vec.into_iter().collect();
+ let values: Vec<_> = map.into_values().collect();
+
+ assert_eq!(values.len(), 3);
+ assert!(values.contains(&'a'));
+ assert!(values.contains(&'b'));
+ assert!(values.contains(&'c'));
+ }
+
+ #[test]
fn test_find() {
let mut m = HashMap::new();
assert!(m.get(&1).is_none());
@@ -4124,7 +5346,7 @@
fn test_from_iter() {
let xs = [(1, 1), (2, 2), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
- let map: HashMap<_, _> = xs.iter().cloned().collect();
+ let map: HashMap<_, _> = xs.iter().copied().collect();
for &(k, v) in &xs {
assert_eq!(map.get(&k), Some(&v));
@@ -4137,7 +5359,7 @@
fn test_size_hint() {
let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
- let map: HashMap<_, _> = xs.iter().cloned().collect();
+ let map: HashMap<_, _> = xs.iter().copied().collect();
let mut iter = map.iter();
@@ -4150,7 +5372,7 @@
fn test_iter_len() {
let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
- let map: HashMap<_, _> = xs.iter().cloned().collect();
+ let map: HashMap<_, _> = xs.iter().copied().collect();
let mut iter = map.iter();
@@ -4163,7 +5385,7 @@
fn test_mut_size_hint() {
let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
- let mut map: HashMap<_, _> = xs.iter().cloned().collect();
+ let mut map: HashMap<_, _> = xs.iter().copied().collect();
let mut iter = map.iter_mut();
@@ -4176,7 +5398,7 @@
fn test_iter_mut_len() {
let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
- let mut map: HashMap<_, _> = xs.iter().cloned().collect();
+ let mut map: HashMap<_, _> = xs.iter().copied().collect();
let mut iter = map.iter_mut();
@@ -4205,6 +5427,7 @@
map.insert(2, 1);
map.insert(3, 4);
+ #[allow(clippy::no_effect)] // false positive lint
map[&4];
}
@@ -4212,7 +5435,7 @@
fn test_entry() {
let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
- let mut map: HashMap<_, _> = xs.iter().cloned().collect();
+ let mut map: HashMap<_, _> = xs.iter().copied().collect();
// Existing key (insert)
match map.entry(1) {
@@ -4259,6 +5482,63 @@
}
#[test]
+ fn test_entry_ref() {
+ let xs = [
+ ("One".to_owned(), 10),
+ ("Two".to_owned(), 20),
+ ("Three".to_owned(), 30),
+ ("Four".to_owned(), 40),
+ ("Five".to_owned(), 50),
+ ("Six".to_owned(), 60),
+ ];
+
+ let mut map: HashMap<_, _> = xs.iter().cloned().collect();
+
+ // Existing key (insert)
+ match map.entry_ref("One") {
+ EntryRef::Vacant(_) => unreachable!(),
+ EntryRef::Occupied(mut view) => {
+ assert_eq!(view.get(), &10);
+ assert_eq!(view.insert(100), 10);
+ }
+ }
+ assert_eq!(map.get("One").unwrap(), &100);
+ assert_eq!(map.len(), 6);
+
+ // Existing key (update)
+ match map.entry_ref("Two") {
+ EntryRef::Vacant(_) => unreachable!(),
+ EntryRef::Occupied(mut view) => {
+ let v = view.get_mut();
+ let new_v = (*v) * 10;
+ *v = new_v;
+ }
+ }
+ assert_eq!(map.get("Two").unwrap(), &200);
+ assert_eq!(map.len(), 6);
+
+ // Existing key (take)
+ match map.entry_ref("Three") {
+ EntryRef::Vacant(_) => unreachable!(),
+ EntryRef::Occupied(view) => {
+ assert_eq!(view.remove(), 30);
+ }
+ }
+ assert_eq!(map.get("Three"), None);
+ assert_eq!(map.len(), 5);
+
+ // Inexistent key (insert)
+ match map.entry_ref("Ten") {
+ EntryRef::Occupied(_) => unreachable!(),
+ EntryRef::Vacant(view) => {
+ assert_eq!(*view.insert(1000), 1000);
+ }
+ }
+ assert_eq!(map.get("Ten").unwrap(), &1000);
+ assert_eq!(map.len(), 6);
+ }
+
+ #[test]
fn test_entry_take_doesnt_corrupt() {
#![allow(deprecated)] //rand
// Test for #19292
@@ -4271,18 +5551,18 @@
let mut m = HashMap::new();
let mut rng = {
- let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
- SmallRng::from_seed(seed)
+ let seed = u64::from_le_bytes(*b"testseed");
+ SmallRng::seed_from_u64(seed)
};
// Populate the map with some items.
for _ in 0..50 {
- let x = rng.gen_range(-10, 10);
+ let x = rng.gen_range(-10..10);
m.insert(x, ());
}
for _ in 0..1000 {
- let x = rng.gen_range(-10, 10);
+ let x = rng.gen_range(-10..10);
match m.entry(x) {
Vacant(_) => {}
Occupied(e) => {
@@ -4295,6 +5575,44 @@
}
#[test]
+ fn test_entry_ref_take_doesnt_corrupt() {
+ #![allow(deprecated)] //rand
+ // Test for #19292
+ fn check(m: &HashMap<std::string::String, ()>) {
+ for k in m.keys() {
+ assert!(m.contains_key(k), "{} is in keys() but not in the map?", k);
+ }
+ }
+
+ let mut m = HashMap::new();
+
+ let mut rng = {
+ let seed = u64::from_le_bytes(*b"testseed");
+ SmallRng::seed_from_u64(seed)
+ };
+
+ // Populate the map with some items.
+ for _ in 0..50 {
+ let mut x = std::string::String::with_capacity(1);
+ x.push(rng.gen_range('a'..='z'));
+ m.insert(x, ());
+ }
+
+ for _ in 0..1000 {
+ let mut x = std::string::String::with_capacity(1);
+ x.push(rng.gen_range('a'..='z'));
+ match m.entry_ref(x.as_str()) {
+ EntryRef::Vacant(_) => {}
+ EntryRef::Occupied(e) => {
+ e.remove();
+ }
+ }
+
+ check(&m);
+ }
+ }
+
+ #[test]
fn test_extend_ref() {
let mut a = HashMap::new();
a.insert(1, "one");
@@ -4341,11 +5659,11 @@
let key = "hello there";
let value = "value goes here";
assert!(a.is_empty());
- a.insert(key.clone(), value.clone());
+ a.insert(key, value);
assert_eq!(a.len(), 1);
assert_eq!(a[key], value);
- match a.entry(key.clone()) {
+ match a.entry(key) {
Vacant(_) => panic!(),
Occupied(e) => assert_eq!(key, *e.key()),
}
@@ -4354,17 +5672,53 @@
}
#[test]
+ fn test_occupied_entry_ref_key() {
+ let mut a = HashMap::new();
+ let key = "hello there";
+ let value = "value goes here";
+ assert!(a.is_empty());
+ a.insert(key.to_owned(), value);
+ assert_eq!(a.len(), 1);
+ assert_eq!(a[key], value);
+
+ match a.entry_ref(key) {
+ EntryRef::Vacant(_) => panic!(),
+ EntryRef::Occupied(e) => assert_eq!(key, e.key()),
+ }
+ assert_eq!(a.len(), 1);
+ assert_eq!(a[key], value);
+ }
+
+ #[test]
fn test_vacant_entry_key() {
let mut a = HashMap::new();
let key = "hello there";
let value = "value goes here";
assert!(a.is_empty());
- match a.entry(key.clone()) {
+ match a.entry(key) {
Occupied(_) => panic!(),
Vacant(e) => {
assert_eq!(key, *e.key());
- e.insert(value.clone());
+ e.insert(value);
+ }
+ }
+ assert_eq!(a.len(), 1);
+ assert_eq!(a[key], value);
+ }
+
+ #[test]
+ fn test_vacant_entry_ref_key() {
+ let mut a: HashMap<std::string::String, &str> = HashMap::new();
+ let key = "hello there";
+ let value = "value goes here";
+
+ assert!(a.is_empty());
+ match a.entry_ref(key) {
+ EntryRef::Occupied(_) => panic!(),
+ EntryRef::Vacant(e) => {
+ assert_eq!(key, e.key());
+ e.insert(value);
}
}
assert_eq!(a.len(), 1);
@@ -4415,6 +5769,49 @@
}
#[test]
+ fn test_occupied_entry_ref_replace_entry_with() {
+ let mut a: HashMap<std::string::String, &str> = HashMap::new();
+
+ let key = "a key";
+ let value = "an initial value";
+ let new_value = "a new value";
+
+ let entry = a.entry_ref(key).insert(value).replace_entry_with(|k, v| {
+ assert_eq!(k, key);
+ assert_eq!(v, value);
+ Some(new_value)
+ });
+
+ match entry {
+ EntryRef::Occupied(e) => {
+ assert_eq!(e.key(), key);
+ assert_eq!(e.get(), &new_value);
+ }
+ EntryRef::Vacant(_) => panic!(),
+ }
+
+ assert_eq!(a[key], new_value);
+ assert_eq!(a.len(), 1);
+
+ let entry = match a.entry_ref(key) {
+ EntryRef::Occupied(e) => e.replace_entry_with(|k, v| {
+ assert_eq!(k, key);
+ assert_eq!(v, new_value);
+ None
+ }),
+ EntryRef::Vacant(_) => panic!(),
+ };
+
+ match entry {
+ EntryRef::Vacant(e) => assert_eq!(e.key(), key),
+ EntryRef::Occupied(_) => panic!(),
+ }
+
+ assert!(!a.contains_key(key));
+ assert_eq!(a.len(), 0);
+ }
+
+ #[test]
fn test_entry_and_replace_entry_with() {
let mut a = HashMap::new();
@@ -4464,6 +5861,55 @@
}
#[test]
+ fn test_entry_ref_and_replace_entry_with() {
+ let mut a = HashMap::new();
+
+ let key = "a key";
+ let value = "an initial value";
+ let new_value = "a new value";
+
+ let entry = a.entry_ref(key).and_replace_entry_with(|_, _| panic!());
+
+ match entry {
+ EntryRef::Vacant(e) => assert_eq!(e.key(), key),
+ EntryRef::Occupied(_) => panic!(),
+ }
+
+ a.insert(key.to_owned(), value);
+
+ let entry = a.entry_ref(key).and_replace_entry_with(|k, v| {
+ assert_eq!(k, key);
+ assert_eq!(v, value);
+ Some(new_value)
+ });
+
+ match entry {
+ EntryRef::Occupied(e) => {
+ assert_eq!(e.key(), key);
+ assert_eq!(e.get(), &new_value);
+ }
+ EntryRef::Vacant(_) => panic!(),
+ }
+
+ assert_eq!(a[key], new_value);
+ assert_eq!(a.len(), 1);
+
+ let entry = a.entry_ref(key).and_replace_entry_with(|k, v| {
+ assert_eq!(k, key);
+ assert_eq!(v, new_value);
+ None
+ });
+
+ match entry {
+ EntryRef::Vacant(e) => assert_eq!(e.key(), key),
+ EntryRef::Occupied(_) => panic!(),
+ }
+
+ assert!(!a.contains_key(key));
+ assert_eq!(a.len(), 0);
+ }
+
+ #[test]
fn test_raw_occupied_entry_replace_entry_with() {
let mut a = HashMap::new();
@@ -4581,24 +6027,56 @@
let mut m = HashMap::new();
let mut rng = {
- let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
- SmallRng::from_seed(seed)
+ let seed = u64::from_le_bytes(*b"testseed");
+ SmallRng::seed_from_u64(seed)
};
// Populate the map with some items.
for _ in 0..50 {
- let x = rng.gen_range(-10, 10);
+ let x = rng.gen_range(-10..10);
m.insert(x, ());
}
for _ in 0..1000 {
- let x = rng.gen_range(-10, 10);
+ let x = rng.gen_range(-10..10);
m.entry(x).and_replace_entry_with(|_, _| None);
check(&m);
}
}
#[test]
+ fn test_replace_entry_ref_with_doesnt_corrupt() {
+ #![allow(deprecated)] //rand
+ // Test for #19292
+ fn check(m: &HashMap<std::string::String, ()>) {
+ for k in m.keys() {
+ assert!(m.contains_key(k), "{} is in keys() but not in the map?", k);
+ }
+ }
+
+ let mut m = HashMap::new();
+
+ let mut rng = {
+ let seed = u64::from_le_bytes(*b"testseed");
+ SmallRng::seed_from_u64(seed)
+ };
+
+ // Populate the map with some items.
+ for _ in 0..50 {
+ let mut x = std::string::String::with_capacity(1);
+ x.push(rng.gen_range('a'..='z'));
+ m.insert(x, ());
+ }
+
+ for _ in 0..1000 {
+ let mut x = std::string::String::with_capacity(1);
+ x.push(rng.gen_range('a'..='z'));
+ m.entry_ref(x.as_str()).and_replace_entry_with(|_, _| None);
+ check(&m);
+ }
+ }
+
+ #[test]
fn test_retain() {
let mut map: HashMap<i32, i32> = (0..100).map(|x| (x, x * 10)).collect();
@@ -4629,21 +6107,27 @@
#[test]
#[cfg_attr(miri, ignore)] // FIXME: no OOM signalling (https://github.com/rust-lang/miri/issues/613)
fn test_try_reserve() {
- let mut empty_bytes: HashMap<u8, u8> = HashMap::new();
+ use crate::TryReserveError::{AllocError, CapacityOverflow};
const MAX_USIZE: usize = usize::MAX;
+ let mut empty_bytes: HashMap<u8, u8> = HashMap::new();
+
if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) {
} else {
panic!("usize::MAX should trigger an overflow!");
}
- if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE / 8) {
+ if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE / 16) {
} else {
// This may succeed if there is enough free memory. Attempt to
- // allocate a second hashmap to ensure the allocation will fail.
+ // allocate a few more hashmaps to ensure the allocation will fail.
let mut empty_bytes2: HashMap<u8, u8> = HashMap::new();
- if let Err(AllocError { .. }) = empty_bytes2.try_reserve(MAX_USIZE / 8) {
+ let _ = empty_bytes2.try_reserve(MAX_USIZE / 16);
+ let mut empty_bytes3: HashMap<u8, u8> = HashMap::new();
+ let _ = empty_bytes3.try_reserve(MAX_USIZE / 16);
+ let mut empty_bytes4: HashMap<u8, u8> = HashMap::new();
+ if let Err(AllocError { .. }) = empty_bytes4.try_reserve(MAX_USIZE / 16) {
} else {
panic!("usize::MAX / 8 should trigger an OOM!");
}
@@ -4654,9 +6138,9 @@
fn test_raw_entry() {
use super::RawEntryMut::{Occupied, Vacant};
- let xs = [(1i32, 10i32), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
+ let xs = [(1_i32, 10_i32), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
- let mut map: HashMap<_, _> = xs.iter().cloned().collect();
+ let mut map: HashMap<_, _> = xs.iter().copied().collect();
let compute_hash = |map: &HashMap<i32, i32>, k: i32| -> u64 {
super::make_insert_hash::<i32, _>(map.hasher(), &k)
@@ -4729,7 +6213,7 @@
// Ensure all lookup methods produce equivalent results.
for k in 0..12 {
let hash = compute_hash(&map, k);
- let v = map.get(&k).cloned();
+ let v = map.get(&k).copied();
let kv = v.as_ref().map(|v| (&k, v));
assert_eq!(map.raw_entry().from_key(&k), kv);
@@ -4799,8 +6283,6 @@
#[test]
#[cfg(feature = "raw")]
fn test_into_iter_refresh() {
- use core::hash::{BuildHasher, Hash, Hasher};
-
#[cfg(miri)]
const N: usize = 32;
#[cfg(not(miri))]
@@ -4808,13 +6290,13 @@
let mut rng = rand::thread_rng();
for n in 0..N {
- let mut m = HashMap::new();
+ let mut map = HashMap::new();
for i in 0..n {
- assert!(m.insert(i, 2 * i).is_none());
+ assert!(map.insert(i, 2 * i).is_none());
}
- let hasher = m.hasher().clone();
+ let hash_builder = map.hasher().clone();
- let mut it = unsafe { m.table.iter() };
+ let mut it = unsafe { map.table.iter() };
assert_eq!(it.len(), n);
let mut i = 0;
@@ -4823,23 +6305,21 @@
loop {
// occasionally remove some elements
if i < n && rng.gen_bool(0.1) {
- let mut hsh = hasher.build_hasher();
- i.hash(&mut hsh);
- let hash = hsh.finish();
+ let hash_value = super::make_insert_hash(&hash_builder, &i);
unsafe {
- let e = m.table.find(hash, |q| q.0.eq(&i));
+ let e = map.table.find(hash_value, |q| q.0.eq(&i));
if let Some(e) = e {
it.reflect_remove(&e);
- let t = m.table.remove(e);
+ let t = map.table.remove(e);
removed.push(t);
left -= 1;
} else {
assert!(removed.contains(&(i, 2 * i)), "{} not in {:?}", i, removed);
- let e = m.table.insert(
- hash,
+ let e = map.table.insert(
+ hash_value,
(i, 2 * i),
- super::make_hasher::<usize, _, usize, _>(&hasher),
+ super::make_hasher::<usize, _, usize, _>(&hash_builder),
);
it.reflect_insert(&e);
if let Some(p) = removed.iter().position(|e| e == &(i, 2 * i)) {
@@ -4857,14 +6337,14 @@
assert!(i < n);
let t = unsafe { e.unwrap().as_ref() };
assert!(!removed.contains(t));
- let (k, v) = t;
- assert_eq!(*v, 2 * k);
+ let (key, value) = t;
+ assert_eq!(*value, 2 * key);
i += 1;
}
assert!(i <= n);
// just for safety:
- assert_eq!(m.table.len(), left);
+ assert_eq!(map.table.len(), left);
}
}
@@ -4886,37 +6366,38 @@
const EMPTY_MAP: HashMap<u32, std::string::String, MyHasher> =
HashMap::with_hasher(MyHasher);
- let mut map = EMPTY_MAP.clone();
+ let mut map = EMPTY_MAP;
map.insert(17, "seventeen".to_owned());
assert_eq!("seventeen", map[&17]);
}
#[test]
- #[cfg(feature = "nightly")]
fn test_get_each_mut() {
- use crate::UnavailableMutError::*;
-
let mut map = HashMap::new();
map.insert("foo".to_owned(), 0);
map.insert("bar".to_owned(), 10);
map.insert("baz".to_owned(), 20);
map.insert("qux".to_owned(), 30);
- let xs = map.get_each_mut(["foo", "dud", "foo", "qux"]);
- assert_eq!(
- xs,
- [Ok(&mut 0), Err(Absent), Err(Duplicate(0)), Ok(&mut 30)]
- );
+ let xs = map.get_many_mut(["foo", "qux"]);
+ assert_eq!(xs, Some([&mut 0, &mut 30]));
- let ys = map.get_each_key_value_mut(["bar", "baz", "baz", "dip"]);
+ let xs = map.get_many_mut(["foo", "dud"]);
+ assert_eq!(xs, None);
+
+ let xs = map.get_many_mut(["foo", "foo"]);
+ assert_eq!(xs, None);
+
+ let ys = map.get_many_key_value_mut(["bar", "baz"]);
assert_eq!(
ys,
- [
- Ok((&"bar".to_owned(), &mut 10)),
- Ok((&"baz".to_owned(), &mut 20)),
- Err(Duplicate(1)),
- Err(Absent),
- ]
+ Some([(&"bar".to_owned(), &mut 10), (&"baz".to_owned(), &mut 20),]),
);
+
+ let ys = map.get_many_key_value_mut(["bar", "dip"]);
+ assert_eq!(ys, None);
+
+ let ys = map.get_many_key_value_mut(["baz", "baz"]);
+ assert_eq!(ys, None);
}
}
diff --git a/sgx_tstd/hashbrown/src/raw/alloc.rs b/sgx_tstd/hashbrown/src/raw/alloc.rs
index de6c455..76fe1e9 100644
--- a/sgx_tstd/hashbrown/src/raw/alloc.rs
+++ b/sgx_tstd/hashbrown/src/raw/alloc.rs
@@ -33,6 +33,7 @@
use crate::alloc::alloc::{alloc, dealloc, Layout};
use core::ptr::NonNull;
+ #[allow(clippy::missing_safety_doc)] // not exposed outside of this crate
pub unsafe trait Allocator {
fn allocate(&self, layout: Layout) -> Result<NonNull<u8>, ()>;
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout);
@@ -47,7 +48,7 @@
}
#[inline]
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
- dealloc(ptr.as_ptr(), layout)
+ dealloc(ptr.as_ptr(), layout);
}
}
impl Default for Global {
diff --git a/sgx_tstd/hashbrown/src/raw/bitmask.rs b/sgx_tstd/hashbrown/src/raw/bitmask.rs
index 99b2d53..7d4f9fc 100644
--- a/sgx_tstd/hashbrown/src/raw/bitmask.rs
+++ b/sgx_tstd/hashbrown/src/raw/bitmask.rs
@@ -106,7 +106,7 @@
}
}
-/// Iterator over the contents of a `BitMask`, returning the indicies of set
+/// Iterator over the contents of a `BitMask`, returning the indices of set
/// bits.
pub struct BitMaskIter(BitMask);
diff --git a/sgx_tstd/hashbrown/src/raw/generic.rs b/sgx_tstd/hashbrown/src/raw/generic.rs
index ef066e8..b4d31e6 100644
--- a/sgx_tstd/hashbrown/src/raw/generic.rs
+++ b/sgx_tstd/hashbrown/src/raw/generic.rs
@@ -9,12 +9,14 @@
target_pointer_width = "64",
target_arch = "aarch64",
target_arch = "x86_64",
+ target_arch = "wasm32",
))]
type GroupWord = u64;
#[cfg(all(
target_pointer_width = "32",
not(target_arch = "aarch64"),
not(target_arch = "x86_64"),
+ not(target_arch = "wasm32"),
))]
type GroupWord = u32;
@@ -37,7 +39,7 @@
#[derive(Copy, Clone)]
pub struct Group(GroupWord);
-// We perform all operations in the native endianess, and convert to
+// We perform all operations in the native endianness, and convert to
// little-endian just before creating a BitMask. The can potentially
// enable the compiler to eliminate unnecessary byte swaps if we are
// only checking whether a BitMask is empty.
@@ -50,6 +52,7 @@
/// value for an empty hash table.
///
/// This is guaranteed to be aligned to the group size.
+ #[inline]
pub const fn static_empty() -> &'static [u8; Group::WIDTH] {
#[repr(C)]
struct AlignedBytes {
@@ -103,7 +106,7 @@
#[inline]
pub fn match_byte(self, byte: u8) -> BitMask {
// This algorithm is derived from
- // http://graphics.stanford.edu/~seander/bithacks.html##ValueInWord
+ // https://graphics.stanford.edu/~seander/bithacks.html##ValueInWord
let cmp = self.0 ^ repeat(byte);
BitMask((cmp.wrapping_sub(repeat(0x01)) & !cmp & repeat(0x80)).to_le())
}
diff --git a/sgx_tstd/hashbrown/src/raw/mod.rs b/sgx_tstd/hashbrown/src/raw/mod.rs
index 3ae6980..fce54d9 100644
--- a/sgx_tstd/hashbrown/src/raw/mod.rs
+++ b/sgx_tstd/hashbrown/src/raw/mod.rs
@@ -1,16 +1,13 @@
use crate::alloc::alloc::{handle_alloc_error, Layout};
use crate::scopeguard::guard;
use crate::TryReserveError;
-#[cfg(feature = "nightly")]
-use crate::UnavailableMutError;
-use core::hint;
use core::iter::FusedIterator;
use core::marker::PhantomData;
use core::mem;
use core::mem::ManuallyDrop;
-#[cfg(feature = "nightly")]
use core::mem::MaybeUninit;
use core::ptr::NonNull;
+use core::{hint, ptr};
cfg_if! {
// Use the SSE2 implementation if possible: it allows us to scan 16 buckets
@@ -59,7 +56,7 @@
#[inline]
fn likely(b: bool) -> bool {
if !b {
- cold()
+ cold();
}
b
}
@@ -67,18 +64,18 @@
#[inline]
fn unlikely(b: bool) -> bool {
if b {
- cold()
+ cold();
}
b
}
#[cfg(feature = "nightly")]
-#[cfg_attr(feature = "inline-more", inline)]
+#[inline]
unsafe fn offset_from<T>(to: *const T, from: *const T) -> usize {
to.offset_from(from) as usize
}
#[cfg(not(feature = "nightly"))]
-#[cfg_attr(feature = "inline-more", inline)]
+#[inline]
unsafe fn offset_from<T>(to: *const T, from: *const T) -> usize {
(to as usize - from as usize) / mem::size_of::<T>()
}
@@ -211,7 +208,7 @@
// Any overflows will have been caught by the checked_mul. Also, any
// rounding errors from the division above will be cleaned up by
- // next_power_of_two (which can't overflow because of the previous divison).
+ // next_power_of_two (which can't overflow because of the previous division).
Some(adjusted_cap.next_power_of_two())
}
@@ -292,14 +289,14 @@
unsafe impl<T> Send for Bucket<T> {}
impl<T> Clone for Bucket<T> {
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
fn clone(&self) -> Self {
Self { ptr: self.ptr }
}
}
impl<T> Bucket<T> {
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
unsafe fn from_base_index(base: NonNull<T>, index: usize) -> Self {
let ptr = if mem::size_of::<T>() == 0 {
// won't overflow because index must be less than length
@@ -311,7 +308,7 @@
ptr: NonNull::new_unchecked(ptr),
}
}
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
unsafe fn to_base_index(&self, base: NonNull<T>) -> usize {
if mem::size_of::<T>() == 0 {
self.ptr.as_ptr() as usize - 1
@@ -319,7 +316,7 @@
offset_from(base.as_ptr(), self.ptr.as_ptr())
}
}
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
pub fn as_ptr(&self) -> *mut T {
if mem::size_of::<T>() == 0 {
// Just return an arbitrary ZST pointer which is properly aligned
@@ -328,7 +325,7 @@
unsafe { self.ptr.as_ptr().sub(1) }
}
}
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
unsafe fn next_n(&self, offset: usize) -> Self {
let ptr = if mem::size_of::<T>() == 0 {
(self.ptr.as_ptr() as usize + offset) as *mut T
@@ -343,23 +340,24 @@
pub unsafe fn drop(&self) {
self.as_ptr().drop_in_place();
}
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
pub unsafe fn read(&self) -> T {
self.as_ptr().read()
}
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
pub unsafe fn write(&self, val: T) {
self.as_ptr().write(val);
}
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
pub unsafe fn as_ref<'a>(&self) -> &'a T {
&*self.as_ptr()
}
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
pub unsafe fn as_mut<'a>(&self) -> &'a mut T {
&mut *self.as_ptr()
}
- #[cfg_attr(feature = "inline-more", inline)]
+ #[cfg(feature = "raw")]
+ #[inline]
pub unsafe fn copy_from_nonoverlapping(&self, other: &Self) {
self.as_ptr().copy_from_nonoverlapping(other.as_ptr(), 1);
}
@@ -398,7 +396,7 @@
/// In effect this returns a table with exactly 1 bucket. However we can
/// leave the data pointer dangling since that bucket is never written to
/// due to our load factor forcing us to always have at least 1 free bucket.
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
pub const fn new() -> Self {
Self {
table: RawTableInner::new_in(Global),
@@ -427,7 +425,7 @@
/// In effect this returns a table with exactly 1 bucket. However we can
/// leave the data pointer dangling since that bucket is never written to
/// due to our load factor forcing us to always have at least 1 free bucket.
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
pub fn new_in(alloc: A) -> Self {
Self {
table: RawTableInner::new_in(alloc),
@@ -492,33 +490,39 @@
}
}
+ /// Returns a reference to the underlying allocator.
+ #[inline]
+ pub fn allocator(&self) -> &A {
+ &self.table.alloc
+ }
+
/// Deallocates the table without dropping any entries.
#[cfg_attr(feature = "inline-more", inline)]
unsafe fn free_buckets(&mut self) {
- self.table.free_buckets(TableLayout::new::<T>())
+ self.table.free_buckets(TableLayout::new::<T>());
}
/// Returns pointer to one past last element of data table.
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
pub unsafe fn data_end(&self) -> NonNull<T> {
NonNull::new_unchecked(self.table.ctrl.as_ptr().cast())
}
/// Returns pointer to start of data table.
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
#[cfg(feature = "nightly")]
pub unsafe fn data_start(&self) -> *mut T {
self.data_end().as_ptr().wrapping_sub(self.buckets())
}
/// Returns the index of a bucket from a `Bucket`.
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
pub unsafe fn bucket_index(&self, bucket: &Bucket<T>) -> usize {
bucket.to_base_index(self.data_end())
}
/// Returns a pointer to an element in the table.
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
pub unsafe fn bucket(&self, index: usize) -> Bucket<T> {
debug_assert_ne!(self.table.bucket_mask, 0);
debug_assert!(index < self.buckets());
@@ -530,7 +534,7 @@
#[deprecated(since = "0.8.1", note = "use erase or remove instead")]
pub unsafe fn erase_no_drop(&mut self, item: &Bucket<T>) {
let index = self.bucket_index(item);
- self.table.erase(index)
+ self.table.erase(index);
}
/// Erases an element from the table, dropping it in place.
@@ -550,7 +554,9 @@
pub fn erase_entry(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> bool {
// Avoid `Option::map` because it bloats LLVM IR.
if let Some(bucket) = self.find(hash, eq) {
- unsafe { self.erase(bucket) };
+ unsafe {
+ self.erase(bucket);
+ }
true
} else {
false
@@ -579,7 +585,7 @@
/// Marks all table buckets as empty without dropping their contents.
#[cfg_attr(feature = "inline-more", inline)]
pub fn clear_no_drop(&mut self) {
- self.table.clear_no_drop()
+ self.table.clear_no_drop();
}
/// Removes all elements from the table without freeing the backing memory.
@@ -593,7 +599,7 @@
}
unsafe fn drop_elements(&mut self) {
- if mem::needs_drop::<T>() && self.len() != 0 {
+ if mem::needs_drop::<T>() && !self.is_empty() {
for item in self.iter() {
item.drop();
}
@@ -624,7 +630,7 @@
if min_buckets < self.buckets() {
// Fast path if the table is empty
if self.table.items == 0 {
- *self = Self::with_capacity_in(min_size, self.table.alloc.clone())
+ *self = Self::with_capacity_in(min_size, self.table.alloc.clone());
} else {
// Avoid `Result::unwrap_or_else` because it bloats LLVM IR.
if self
@@ -676,102 +682,18 @@
hasher: impl Fn(&T) -> u64,
fallibility: Fallibility,
) -> Result<(), TryReserveError> {
- // Avoid `Option::ok_or_else` because it bloats LLVM IR.
- let new_items = match self.table.items.checked_add(additional) {
- Some(new_items) => new_items,
- None => return Err(fallibility.capacity_overflow()),
- };
- let full_capacity = bucket_mask_to_capacity(self.table.bucket_mask);
- if new_items <= full_capacity / 2 {
- // Rehash in-place without re-allocating if we have plenty of spare
- // capacity that is locked up due to DELETED entries.
- self.rehash_in_place(hasher);
- Ok(())
- } else {
- // Otherwise, conservatively resize to at least the next size up
- // to avoid churning deletes into frequent rehashes.
- self.resize(
- usize::max(new_items, full_capacity + 1),
- hasher,
- fallibility,
- )
- }
- }
-
- /// Rehashes the contents of the table in place (i.e. without changing the
- /// allocation).
- ///
- /// If `hasher` panics then some the table's contents may be lost.
- fn rehash_in_place(&mut self, hasher: impl Fn(&T) -> u64) {
unsafe {
- // If the hash function panics then properly clean up any elements
- // that we haven't rehashed yet. We unfortunately can't preserve the
- // element since we lost their hash and have no way of recovering it
- // without risking another panic.
- self.table.prepare_rehash_in_place();
-
- let mut guard = guard(&mut self.table, move |self_| {
+ self.table.reserve_rehash_inner(
+ additional,
+ &|table, index| hasher(table.bucket::<T>(index).as_ref()),
+ fallibility,
+ TableLayout::new::<T>(),
if mem::needs_drop::<T>() {
- for i in 0..self_.buckets() {
- if *self_.ctrl(i) == DELETED {
- self_.set_ctrl(i, EMPTY);
- self_.bucket::<T>(i).drop();
- self_.items -= 1;
- }
- }
- }
- self_.growth_left = bucket_mask_to_capacity(self_.bucket_mask) - self_.items;
- });
-
- // At this point, DELETED elements are elements that we haven't
- // rehashed yet. Find them and re-insert them at their ideal
- // position.
- 'outer: for i in 0..guard.buckets() {
- if *guard.ctrl(i) != DELETED {
- continue;
- }
-
- 'inner: loop {
- // Hash the current item
- let item = guard.bucket(i);
- let hash = hasher(item.as_ref());
-
- // Search for a suitable place to put it
- let new_i = guard.find_insert_slot(hash);
-
- // Probing works by scanning through all of the control
- // bytes in groups, which may not be aligned to the group
- // size. If both the new and old position fall within the
- // same unaligned group, then there is no benefit in moving
- // it and we can just continue to the next item.
- if likely(guard.is_in_same_group(i, new_i, hash)) {
- guard.set_ctrl_h2(i, hash);
- continue 'outer;
- }
-
- // We are moving the current item to a new position. Write
- // our H2 to the control byte of the new position.
- let prev_ctrl = guard.replace_ctrl_h2(new_i, hash);
- if prev_ctrl == EMPTY {
- guard.set_ctrl(i, EMPTY);
- // If the target slot is empty, simply move the current
- // element into the new slot and clear the old control
- // byte.
- guard.bucket(new_i).copy_from_nonoverlapping(&item);
- continue 'outer;
- } else {
- // If the target slot is occupied, swap the two elements
- // and then continue processing the element that we just
- // swapped into the old slot.
- debug_assert_eq!(prev_ctrl, DELETED);
- mem::swap(guard.bucket(new_i).as_mut(), item.as_mut());
- continue 'inner;
- }
- }
- }
-
- guard.growth_left = bucket_mask_to_capacity(guard.bucket_mask) - guard.items;
- mem::forget(guard);
+ Some(mem::transmute(ptr::drop_in_place::<T> as unsafe fn(*mut T)))
+ } else {
+ None
+ },
+ )
}
}
@@ -784,30 +706,12 @@
fallibility: Fallibility,
) -> Result<(), TryReserveError> {
unsafe {
- let mut new_table =
- self.table
- .prepare_resize(TableLayout::new::<T>(), capacity, fallibility)?;
-
- // Copy all elements to the new table.
- for item in self.iter() {
- // This may panic.
- let hash = hasher(item.as_ref());
-
- // We can use a simpler version of insert() here since:
- // - there are no DELETED entries.
- // - we know there is enough space in the table.
- // - all elements are unique.
- let (index, _) = new_table.prepare_insert_slot(hash);
- new_table.bucket(index).copy_from_nonoverlapping(&item);
- }
-
- // We successfully copied all elements without panicking. Now replace
- // self with the new table. The old table will have its memory freed but
- // the items will not be dropped (since they have been moved into the
- // new table).
- mem::swap(&mut self.table, &mut new_table);
-
- Ok(())
+ self.table.resize_inner(
+ capacity,
+ &|table, index| hasher(table.bucket::<T>(index).as_ref()),
+ fallibility,
+ TableLayout::new::<T>(),
+ )
}
}
@@ -872,19 +776,17 @@
/// This does not check if the given element already exists in the table.
#[cfg_attr(feature = "inline-more", inline)]
#[cfg(any(feature = "raw", feature = "rustc-internal-api"))]
- pub fn insert_no_grow(&mut self, hash: u64, value: T) -> Bucket<T> {
- unsafe {
- let (index, old_ctrl) = self.table.prepare_insert_slot(hash);
- let bucket = self.table.bucket(index);
+ pub unsafe fn insert_no_grow(&mut self, hash: u64, value: T) -> Bucket<T> {
+ let (index, old_ctrl) = self.table.prepare_insert_slot(hash);
+ let bucket = self.table.bucket(index);
- // If we are replacing a DELETED entry then we don't need to update
- // the load counter.
- self.table.growth_left -= special_is_empty(old_ctrl) as usize;
+ // If we are replacing a DELETED entry then we don't need to update
+ // the load counter.
+ self.table.growth_left -= special_is_empty(old_ctrl) as usize;
- bucket.write(value);
- self.table.items += 1;
- bucket
- }
+ bucket.write(value);
+ self.table.items += 1;
+ bucket
}
/// Temporary removes a bucket, applying the given function to the removed
@@ -917,14 +819,14 @@
/// Searches for an element in the table.
#[inline]
pub fn find(&self, hash: u64, mut eq: impl FnMut(&T) -> bool) -> Option<Bucket<T>> {
- unsafe {
- for bucket in self.iter_hash(hash) {
- let elm = bucket.as_ref();
- if likely(eq(elm)) {
- return Some(bucket);
- }
- }
- None
+ let result = self.table.find_inner(hash, &mut |index| unsafe {
+ eq(self.bucket(index).as_ref())
+ });
+
+ // Avoid `Option::map` because it bloats LLVM IR.
+ match result {
+ Some(index) => Some(unsafe { self.bucket(index) }),
+ None => None,
}
}
@@ -950,79 +852,84 @@
/// Attempts to get mutable references to `N` entries in the table at once.
///
- /// Returns an array of length `N` with the results of each query. For soundness,
- /// at most one mutable reference will be returned to any entry. An
- /// `Err(UnavailableMutError::Duplicate(i))` in the returned array indicates that a suitable
- /// entry exists, but a mutable reference to it already occurs at index `i` in the returned
- /// array.
+ /// Returns an array of length `N` with the results of each query.
+ ///
+ /// At most one mutable reference will be returned to any entry. `None` will be returned if any
+ /// of the hashes are duplicates. `None` will be returned if the hash is not found.
///
/// The `eq` argument should be a closure such that `eq(i, k)` returns true if `k` is equal to
/// the `i`th key to be looked up.
- ///
- /// This method is available only if the `nightly` feature is enabled.
- #[cfg(feature = "nightly")]
- pub fn get_each_mut<const N: usize>(
+ pub fn get_many_mut<const N: usize>(
+ &mut self,
+ hashes: [u64; N],
+ eq: impl FnMut(usize, &T) -> bool,
+ ) -> Option<[&'_ mut T; N]> {
+ unsafe {
+ let ptrs = self.get_many_mut_pointers(hashes, eq)?;
+
+ for (i, &cur) in ptrs.iter().enumerate() {
+ if ptrs[..i].iter().any(|&prev| ptr::eq::<T>(prev, cur)) {
+ return None;
+ }
+ }
+ // All bucket are distinct from all previous buckets so we're clear to return the result
+ // of the lookup.
+
+ // TODO use `MaybeUninit::array_assume_init` here instead once that's stable.
+ Some(mem::transmute_copy(&ptrs))
+ }
+ }
+
+ pub unsafe fn get_many_unchecked_mut<const N: usize>(
+ &mut self,
+ hashes: [u64; N],
+ eq: impl FnMut(usize, &T) -> bool,
+ ) -> Option<[&'_ mut T; N]> {
+ let ptrs = self.get_many_mut_pointers(hashes, eq)?;
+ Some(mem::transmute_copy(&ptrs))
+ }
+
+ unsafe fn get_many_mut_pointers<const N: usize>(
&mut self,
hashes: [u64; N],
mut eq: impl FnMut(usize, &T) -> bool,
- ) -> [Result<&'_ mut T, UnavailableMutError>; N] {
- // Collect the requested buckets.
+ ) -> Option<[*mut T; N]> {
// TODO use `MaybeUninit::uninit_array` here instead once that's stable.
- let mut buckets: [MaybeUninit<Option<Bucket<T>>>; N] =
- unsafe { MaybeUninit::uninit().assume_init() };
- for i in 0..N {
- buckets[i] = MaybeUninit::new(self.find(hashes[i], |k| eq(i, k)));
- }
- let buckets: [Option<Bucket<T>>; N] = unsafe { MaybeUninit::array_assume_init(buckets) };
+ let mut outs: MaybeUninit<[*mut T; N]> = MaybeUninit::uninit();
+ let outs_ptr = outs.as_mut_ptr();
- // Walk through the buckets, checking for duplicates and building up the output array.
- // TODO use `MaybeUninit::uninit_array` here instead once that's stable.
- let mut out: [MaybeUninit<Result<&'_ mut T, UnavailableMutError>>; N] =
- unsafe { MaybeUninit::uninit().assume_init() };
- for i in 0..N {
- out[i] = MaybeUninit::new(
- #[allow(clippy::never_loop)]
- 'outer: loop {
- for j in 0..i {
- match (&buckets[j], &buckets[i]) {
- // These two buckets are the same, and we can't safely return a second
- // mutable reference to the same entry.
- (Some(prev), Some(cur)) if prev.as_ptr() == cur.as_ptr() => {
- break 'outer Err(UnavailableMutError::Duplicate(j));
- }
- _ => {}
- }
- }
- // This bucket is distinct from all previous buckets (or it doesn't exist), so
- // we're clear to return the result of the lookup.
- break match &buckets[i] {
- None => Err(UnavailableMutError::Absent),
- Some(bkt) => unsafe { Ok(bkt.as_mut()) },
- };
- },
- )
+ for (i, &hash) in hashes.iter().enumerate() {
+ let cur = self.find(hash, |k| eq(i, k))?;
+ *(*outs_ptr).get_unchecked_mut(i) = cur.as_mut();
}
- unsafe { MaybeUninit::array_assume_init(out) }
+ // TODO use `MaybeUninit::array_assume_init` here instead once that's stable.
+ Some(outs.assume_init())
}
/// Returns the number of elements the map can hold without reallocating.
///
/// This number is a lower bound; the table might be able to hold
/// more, but is guaranteed to be able to hold at least this many.
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
pub fn capacity(&self) -> usize {
self.table.items + self.table.growth_left
}
/// Returns the number of elements in the table.
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
pub fn len(&self) -> usize {
self.table.items
}
+ /// Returns `true` if the table contains no elements.
+ #[inline]
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+
/// Returns the number of buckets in the table.
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
pub fn buckets(&self) -> usize {
self.table.bucket_mask + 1
}
@@ -1031,7 +938,7 @@
/// the caller to ensure that the `RawTable` outlives the `RawIter`.
/// Because we cannot make the `next` method unsafe on the `RawIter`
/// struct, we have to make the `iter` method unsafe.
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
pub unsafe fn iter(&self) -> RawIter<T> {
let data = Bucket::from_base_index(self.data_end(), 0);
RawIter {
@@ -1042,12 +949,15 @@
/// Returns an iterator over occupied buckets that could match a given hash.
///
- /// In rare cases, the iterator may return a bucket with a different hash.
+ /// `RawTable` only stores 7 bits of the hash value, so this iterator may
+ /// return items that have a hash value different than the one provided. You
+ /// should always validate the returned values before using them.
///
/// It is up to the caller to ensure that the `RawTable` outlives the
/// `RawIterHash`. Because we cannot make the `next` method unsafe on the
/// `RawIterHash` struct, we have to make the `iter_hash` method unsafe.
#[cfg_attr(feature = "inline-more", inline)]
+ #[cfg(feature = "raw")]
pub unsafe fn iter_hash(&self, hash: u64) -> RawIterHash<'_, T, A> {
RawIterHash::new(self, hash)
}
@@ -1121,11 +1031,21 @@
}
}
-unsafe impl<T, A: Allocator + Clone> Send for RawTable<T, A> where T: Send {}
-unsafe impl<T, A: Allocator + Clone> Sync for RawTable<T, A> where T: Sync {}
+unsafe impl<T, A: Allocator + Clone> Send for RawTable<T, A>
+where
+ T: Send,
+ A: Send,
+{
+}
+unsafe impl<T, A: Allocator + Clone> Sync for RawTable<T, A>
+where
+ T: Sync,
+ A: Sync,
+{
+}
impl<A> RawTableInner<A> {
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
const fn new_in(alloc: A) -> Self {
Self {
// Be careful to cast the entire slice to a raw pointer.
@@ -1154,6 +1074,15 @@
None => return Err(fallibility.capacity_overflow()),
};
+ // We need an additional check to ensure that the allocation doesn't
+ // exceed `isize::MAX`. We can skip this check on 64-bit systems since
+ // such allocations will never succeed anyways.
+ //
+ // This mirrors what Vec does in the standard library.
+ if mem::size_of::<usize>() < 8 && layout.size() > isize::MAX as usize {
+ return Err(fallibility.capacity_overflow());
+ }
+
let ptr: NonNull<u8> = match do_alloc(&alloc, layout) {
Ok(block) => block.cast(),
Err(_) => return Err(fallibility.alloc_err(layout)),
@@ -1221,7 +1150,7 @@
// EMPTY entries. These will unfortunately trigger a
// match, but once masked may point to a full bucket that
// is already occupied. We detect this situation here and
- // perform a second scan starting at the begining of the
+ // perform a second scan starting at the beginning of the
// table. This second scan is guaranteed to find an empty
// slot (due to the load factor) before hitting the trailing
// control bytes (containing EMPTY).
@@ -1240,6 +1169,32 @@
}
}
+ /// Searches for an element in the table. This uses dynamic dispatch to reduce the amount of
+ /// code generated, but it is eliminated by LLVM optimizations.
+ #[inline]
+ fn find_inner(&self, hash: u64, eq: &mut dyn FnMut(usize) -> bool) -> Option<usize> {
+ let h2_hash = h2(hash);
+ let mut probe_seq = self.probe_seq(hash);
+
+ loop {
+ let group = unsafe { Group::load(self.ctrl(probe_seq.pos)) };
+
+ for bit in group.match_byte(h2_hash) {
+ let index = (probe_seq.pos + bit) & self.bucket_mask;
+
+ if likely(eq(index)) {
+ return Some(index);
+ }
+ }
+
+ if likely(group.match_empty().any_bit_set()) {
+ return None;
+ }
+
+ probe_seq.move_next(self.bucket_mask);
+ }
+ }
+
#[allow(clippy::mut_mut)]
#[inline]
unsafe fn prepare_rehash_in_place(&mut self) {
@@ -1263,14 +1218,22 @@
}
}
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
unsafe fn bucket<T>(&self, index: usize) -> Bucket<T> {
debug_assert_ne!(self.bucket_mask, 0);
debug_assert!(index < self.buckets());
Bucket::from_base_index(self.data_end(), index)
}
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
+ unsafe fn bucket_ptr(&self, index: usize, size_of: usize) -> *mut u8 {
+ debug_assert_ne!(self.bucket_mask, 0);
+ debug_assert!(index < self.buckets());
+ let base: *mut u8 = self.data_end().as_ptr();
+ base.sub((index + 1) * size_of)
+ }
+
+ #[inline]
unsafe fn data_end<T>(&self) -> NonNull<T> {
NonNull::new_unchecked(self.ctrl.as_ptr().cast())
}
@@ -1322,7 +1285,7 @@
/// the end of the array.
#[inline]
unsafe fn set_ctrl_h2(&self, index: usize, hash: u64) {
- self.set_ctrl(index, h2(hash))
+ self.set_ctrl(index, h2(hash));
}
#[inline]
@@ -1415,6 +1378,179 @@
}))
}
+ /// Reserves or rehashes to make room for `additional` more elements.
+ ///
+ /// This uses dynamic dispatch to reduce the amount of
+ /// code generated, but it is eliminated by LLVM optimizations when inlined.
+ #[allow(clippy::inline_always)]
+ #[inline(always)]
+ unsafe fn reserve_rehash_inner(
+ &mut self,
+ additional: usize,
+ hasher: &dyn Fn(&mut Self, usize) -> u64,
+ fallibility: Fallibility,
+ layout: TableLayout,
+ drop: Option<fn(*mut u8)>,
+ ) -> Result<(), TryReserveError> {
+ // Avoid `Option::ok_or_else` because it bloats LLVM IR.
+ let new_items = match self.items.checked_add(additional) {
+ Some(new_items) => new_items,
+ None => return Err(fallibility.capacity_overflow()),
+ };
+ let full_capacity = bucket_mask_to_capacity(self.bucket_mask);
+ if new_items <= full_capacity / 2 {
+ // Rehash in-place without re-allocating if we have plenty of spare
+ // capacity that is locked up due to DELETED entries.
+ self.rehash_in_place(hasher, layout.size, drop);
+ Ok(())
+ } else {
+ // Otherwise, conservatively resize to at least the next size up
+ // to avoid churning deletes into frequent rehashes.
+ self.resize_inner(
+ usize::max(new_items, full_capacity + 1),
+ hasher,
+ fallibility,
+ layout,
+ )
+ }
+ }
+
+ /// Allocates a new table of a different size and moves the contents of the
+ /// current table into it.
+ ///
+ /// This uses dynamic dispatch to reduce the amount of
+ /// code generated, but it is eliminated by LLVM optimizations when inlined.
+ #[allow(clippy::inline_always)]
+ #[inline(always)]
+ unsafe fn resize_inner(
+ &mut self,
+ capacity: usize,
+ hasher: &dyn Fn(&mut Self, usize) -> u64,
+ fallibility: Fallibility,
+ layout: TableLayout,
+ ) -> Result<(), TryReserveError> {
+ let mut new_table = self.prepare_resize(layout, capacity, fallibility)?;
+
+ // Copy all elements to the new table.
+ for i in 0..self.buckets() {
+ if !is_full(*self.ctrl(i)) {
+ continue;
+ }
+
+ // This may panic.
+ let hash = hasher(self, i);
+
+ // We can use a simpler version of insert() here since:
+ // - there are no DELETED entries.
+ // - we know there is enough space in the table.
+ // - all elements are unique.
+ let (index, _) = new_table.prepare_insert_slot(hash);
+
+ ptr::copy_nonoverlapping(
+ self.bucket_ptr(i, layout.size),
+ new_table.bucket_ptr(index, layout.size),
+ layout.size,
+ );
+ }
+
+ // We successfully copied all elements without panicking. Now replace
+ // self with the new table. The old table will have its memory freed but
+ // the items will not be dropped (since they have been moved into the
+ // new table).
+ mem::swap(self, &mut new_table);
+
+ Ok(())
+ }
+
+ /// Rehashes the contents of the table in place (i.e. without changing the
+ /// allocation).
+ ///
+ /// If `hasher` panics then some the table's contents may be lost.
+ ///
+ /// This uses dynamic dispatch to reduce the amount of
+ /// code generated, but it is eliminated by LLVM optimizations when inlined.
+ #[allow(clippy::inline_always)]
+ #[cfg_attr(feature = "inline-more", inline(always))]
+ #[cfg_attr(not(feature = "inline-more"), inline)]
+ unsafe fn rehash_in_place(
+ &mut self,
+ hasher: &dyn Fn(&mut Self, usize) -> u64,
+ size_of: usize,
+ drop: Option<fn(*mut u8)>,
+ ) {
+ // If the hash function panics then properly clean up any elements
+ // that we haven't rehashed yet. We unfortunately can't preserve the
+ // element since we lost their hash and have no way of recovering it
+ // without risking another panic.
+ self.prepare_rehash_in_place();
+
+ let mut guard = guard(self, move |self_| {
+ if let Some(drop) = drop {
+ for i in 0..self_.buckets() {
+ if *self_.ctrl(i) == DELETED {
+ self_.set_ctrl(i, EMPTY);
+ drop(self_.bucket_ptr(i, size_of));
+ self_.items -= 1;
+ }
+ }
+ }
+ self_.growth_left = bucket_mask_to_capacity(self_.bucket_mask) - self_.items;
+ });
+
+ // At this point, DELETED elements are elements that we haven't
+ // rehashed yet. Find them and re-insert them at their ideal
+ // position.
+ 'outer: for i in 0..guard.buckets() {
+ if *guard.ctrl(i) != DELETED {
+ continue;
+ }
+
+ let i_p = guard.bucket_ptr(i, size_of);
+
+ 'inner: loop {
+ // Hash the current item
+ let hash = hasher(*guard, i);
+
+ // Search for a suitable place to put it
+ let new_i = guard.find_insert_slot(hash);
+ let new_i_p = guard.bucket_ptr(new_i, size_of);
+
+ // Probing works by scanning through all of the control
+ // bytes in groups, which may not be aligned to the group
+ // size. If both the new and old position fall within the
+ // same unaligned group, then there is no benefit in moving
+ // it and we can just continue to the next item.
+ if likely(guard.is_in_same_group(i, new_i, hash)) {
+ guard.set_ctrl_h2(i, hash);
+ continue 'outer;
+ }
+
+ // We are moving the current item to a new position. Write
+ // our H2 to the control byte of the new position.
+ let prev_ctrl = guard.replace_ctrl_h2(new_i, hash);
+ if prev_ctrl == EMPTY {
+ guard.set_ctrl(i, EMPTY);
+ // If the target slot is empty, simply move the current
+ // element into the new slot and clear the old control
+ // byte.
+ ptr::copy_nonoverlapping(i_p, new_i_p, size_of);
+ continue 'outer;
+ } else {
+ // If the target slot is occupied, swap the two elements
+ // and then continue processing the element that we just
+ // swapped into the old slot.
+ debug_assert_eq!(prev_ctrl, DELETED);
+ ptr::swap_nonoverlapping(i_p, new_i_p, size_of);
+ continue 'inner;
+ }
+ }
+ }
+
+ guard.growth_left = bucket_mask_to_capacity(guard.bucket_mask) - guard.items;
+
+ mem::forget(guard);
+ }
+
#[inline]
unsafe fn free_buckets(&mut self, table_layout: TableLayout) {
// Avoid `Option::unwrap_or_else` because it bloats LLVM IR.
@@ -1454,7 +1590,7 @@
//
// Note that in this context `leading_zeros` refers to the bytes at the
// end of a group, while `trailing_zeros` refers to the bytes at the
- // begining of a group.
+ // beginning of a group.
let ctrl = if empty_before.leading_zeros() + empty_after.trailing_zeros() >= Group::WIDTH {
DELETED
} else {
@@ -1524,7 +1660,7 @@
self.clone_from_spec(source, |self_| {
// We need to leave the table in an empty state.
- self_.clear_no_drop()
+ self_.clear_no_drop();
});
}
}
@@ -1536,8 +1672,8 @@
unsafe fn clone_from_spec(&mut self, source: &Self, on_panic: impl FnMut(&mut Self));
}
impl<T: Clone, A: Allocator + Clone> RawTableClone for RawTable<T, A> {
- #[cfg_attr(feature = "inline-more", inline)]
default_fn! {
+ #[cfg_attr(feature = "inline-more", inline)]
unsafe fn clone_from_spec(&mut self, source: &Self, on_panic: impl FnMut(&mut Self)) {
self.clone_from_impl(source, on_panic);
}
@@ -1574,7 +1710,7 @@
// to make sure we drop only the elements that have been
// cloned so far.
let mut guard = guard((0, &mut *self), |(index, self_)| {
- if mem::needs_drop::<T>() && self_.len() != 0 {
+ if mem::needs_drop::<T>() && !self_.is_empty() {
for i in 0..=*index {
if is_full(*self_.table.ctrl(i)) {
self_.bucket(i).drop();
@@ -1650,7 +1786,7 @@
}
impl<T, A: Allocator + Clone + Default> Default for RawTable<T, A> {
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
fn default() -> Self {
Self::new_in(Default::default())
}
@@ -1824,7 +1960,7 @@
}
}
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
// We don't have an item count, so just guess based on the range size.
(
@@ -1871,7 +2007,7 @@
/// For the iterator to remain valid, this method must be called once
/// for each insert before `next` is called again.
///
- /// This method does not guarantee that an insertion of a bucket witha greater
+ /// This method does not guarantee that an insertion of a bucket with a greater
/// index than the last one yielded will be reflected in the iterator.
///
/// This method should be called _after_ the given insert is made.
@@ -1923,7 +2059,7 @@
// If it did, we're done.
// - Otherwise, update the iterator cached group so that it won't
// yield a to-be-removed bucket, or _will_ yield a to-be-added bucket.
- // We'll also need ot update the item count accordingly.
+ // We'll also need to update the item count accordingly.
if let Some(index) = self.iter.current_group.lowest_set_bit() {
let next_bucket = self.iter.data.next_n(index);
if b.as_ptr() > next_bucket.as_ptr() {
@@ -2006,7 +2142,7 @@
}
}
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.items, Some(self.items))
}
@@ -2030,8 +2166,18 @@
}
}
-unsafe impl<T, A: Allocator + Clone> Send for RawIntoIter<T, A> where T: Send {}
-unsafe impl<T, A: Allocator + Clone> Sync for RawIntoIter<T, A> where T: Sync {}
+unsafe impl<T, A: Allocator + Clone> Send for RawIntoIter<T, A>
+where
+ T: Send,
+ A: Send,
+{
+}
+unsafe impl<T, A: Allocator + Clone> Sync for RawIntoIter<T, A>
+where
+ T: Sync,
+ A: Sync,
+{
+}
#[cfg(feature = "nightly")]
unsafe impl<#[may_dangle] T, A: Allocator + Clone> Drop for RawIntoIter<T, A> {
@@ -2072,7 +2218,7 @@
unsafe { Some(self.iter.next()?.read()) }
}
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
@@ -2103,8 +2249,18 @@
}
}
-unsafe impl<T, A: Allocator + Copy> Send for RawDrain<'_, T, A> where T: Send {}
-unsafe impl<T, A: Allocator + Copy> Sync for RawDrain<'_, T, A> where T: Sync {}
+unsafe impl<T, A: Allocator + Copy> Send for RawDrain<'_, T, A>
+where
+ T: Send,
+ A: Send,
+{
+}
+unsafe impl<T, A: Allocator + Copy> Sync for RawDrain<'_, T, A>
+where
+ T: Sync,
+ A: Sync,
+{
+}
impl<T, A: Allocator + Clone> Drop for RawDrain<'_, T, A> {
#[cfg_attr(feature = "inline-more", inline)]
@@ -2136,7 +2292,7 @@
}
}
- #[cfg_attr(feature = "inline-more", inline)]
+ #[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
@@ -2147,7 +2303,9 @@
/// Iterator over occupied buckets that could match a given hash.
///
-/// In rare cases, the iterator may return a bucket with a different hash.
+/// `RawTable` only stores 7 bits of the hash value, so this iterator may return
+/// items that have a hash value different than the one provided. You should
+/// always validate the returned values before using them.
pub struct RawIterHash<'a, T, A: Allocator + Clone = Global> {
inner: RawIterHashInner<'a, A>,
_marker: PhantomData<T>,
@@ -2170,6 +2328,7 @@
impl<'a, T, A: Allocator + Clone> RawIterHash<'a, T, A> {
#[cfg_attr(feature = "inline-more", inline)]
+ #[cfg(feature = "raw")]
fn new(table: &'a RawTable<T, A>, hash: u64) -> Self {
RawIterHash {
inner: RawIterHashInner::new(&table.table, hash),
@@ -2179,6 +2338,7 @@
}
impl<'a, A: Allocator + Clone> RawIterHashInner<'a, A> {
#[cfg_attr(feature = "inline-more", inline)]
+ #[cfg(feature = "raw")]
fn new(table: &'a RawTableInner<A>, hash: u64) -> Self {
unsafe {
let h2_hash = h2(hash);
@@ -2235,6 +2395,20 @@
mod test_map {
use super::*;
+ fn rehash_in_place<T>(table: &mut RawTable<T>, hasher: impl Fn(&T) -> u64) {
+ unsafe {
+ table.table.rehash_in_place(
+ &|table, index| hasher(table.bucket::<T>(index).as_ref()),
+ mem::size_of::<T>(),
+ if mem::needs_drop::<T>() {
+ Some(mem::transmute(ptr::drop_in_place::<T> as unsafe fn(*mut T)))
+ } else {
+ None
+ },
+ );
+ }
+ }
+
#[test]
fn rehash() {
let mut table = RawTable::new();
@@ -2250,7 +2424,7 @@
assert!(table.find(i + 100, |x| *x == i + 100).is_none());
}
- table.rehash_in_place(hasher);
+ rehash_in_place(&mut table, hasher);
for i in 0..100 {
unsafe {
diff --git a/sgx_tstd/hashbrown/src/raw/sse2.rs b/sgx_tstd/hashbrown/src/raw/sse2.rs
index eed9684..a0bf6da 100644
--- a/sgx_tstd/hashbrown/src/raw/sse2.rs
+++ b/sgx_tstd/hashbrown/src/raw/sse2.rs
@@ -28,6 +28,7 @@
/// value for an empty hash table.
///
/// This is guaranteed to be aligned to the group size.
+ #[inline]
#[allow(clippy::items_after_statements)]
pub const fn static_empty() -> &'static [u8; Group::WIDTH] {
#[repr(C)]
diff --git a/sgx_tstd/hashbrown/src/rustc_entry.rs b/sgx_tstd/hashbrown/src/rustc_entry.rs
index 1793c4a..465db47 100644
--- a/sgx_tstd/hashbrown/src/rustc_entry.rs
+++ b/sgx_tstd/hashbrown/src/rustc_entry.rs
@@ -574,8 +574,10 @@
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn insert(self, value: V) -> &'a mut V {
- let bucket = self.table.insert_no_grow(self.hash, (self.key, value));
- unsafe { &mut bucket.as_mut().1 }
+ unsafe {
+ let bucket = self.table.insert_no_grow(self.hash, (self.key, value));
+ &mut bucket.as_mut().1
+ }
}
/// Sets the value of the entry with the RustcVacantEntry's key,
@@ -596,7 +598,7 @@
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn insert_entry(self, value: V) -> RustcOccupiedEntry<'a, K, V, A> {
- let bucket = self.table.insert_no_grow(self.hash, (self.key, value));
+ let bucket = unsafe { self.table.insert_no_grow(self.hash, (self.key, value)) };
RustcOccupiedEntry {
key: None,
elem: bucket,
diff --git a/sgx_tstd/hashbrown/src/scopeguard.rs b/sgx_tstd/hashbrown/src/scopeguard.rs
index 4e9bf04..ccdc0c5 100644
--- a/sgx_tstd/hashbrown/src/scopeguard.rs
+++ b/sgx_tstd/hashbrown/src/scopeguard.rs
@@ -44,6 +44,6 @@
{
#[inline]
fn drop(&mut self) {
- (self.dropfn)(&mut self.value)
+ (self.dropfn)(&mut self.value);
}
}
diff --git a/sgx_tstd/hashbrown/src/set.rs b/sgx_tstd/hashbrown/src/set.rs
index d59183b..bb83054 100644
--- a/sgx_tstd/hashbrown/src/set.rs
+++ b/sgx_tstd/hashbrown/src/set.rs
@@ -378,7 +378,7 @@
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn clear(&mut self) {
- self.map.clear()
+ self.map.clear();
}
}
@@ -454,6 +454,12 @@
where
A: Allocator + Clone,
{
+ /// Returns a reference to the underlying allocator.
+ #[inline]
+ pub fn allocator(&self) -> &A {
+ self.map.allocator()
+ }
+
/// Creates a new empty hash set which will use the given hasher to hash
/// keys.
///
@@ -553,7 +559,7 @@
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn reserve(&mut self, additional: usize) {
- self.map.reserve(additional)
+ self.map.reserve(additional);
}
/// Tries to reserve capacity for at least `additional` more elements to be inserted
@@ -595,7 +601,7 @@
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn shrink_to_fit(&mut self) {
- self.map.shrink_to_fit()
+ self.map.shrink_to_fit();
}
/// Shrinks the capacity of the set with a lower limit. It will drop
@@ -621,7 +627,7 @@
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn shrink_to(&mut self, min_capacity: usize) {
- self.map.shrink_to(min_capacity)
+ self.map.shrink_to(min_capacity);
}
/// Visits the values representing the difference,
@@ -985,6 +991,30 @@
self.map.insert(value, ()).is_none()
}
+ /// Insert a value the set without checking if the value already exists in the set.
+ ///
+ /// Returns a reference to the value just inserted.
+ ///
+ /// This operation is safe if a value does not exist in the set.
+ ///
+ /// However, if a value exists in the set already, the behavior is unspecified:
+ /// this operation may panic, loop forever, or any following operation with the set
+ /// may panic, loop forever or return arbitrary result.
+ ///
+ /// That said, this operation (and following operations) are guaranteed to
+ /// not violate memory safety.
+ ///
+ /// This operation is faster than regular insert, because it does not perform
+ /// lookup before insertion.
+ ///
+ /// This operation is useful during initial population of the set.
+ /// For example, when constructing a set from another set, we know
+ /// that values are unique.
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub fn insert_unique_unchecked(&mut self, value: T) -> &T {
+ self.map.insert_unique_unchecked(value, ()).0
+ }
+
/// Adds a value to the set, replacing the existing value, if any, that is equal to the given
/// one. Returns the replaced value.
///
@@ -1098,8 +1128,7 @@
impl<T, S, A> fmt::Debug for HashSet<T, S, A>
where
- T: Eq + Hash + fmt::Debug,
- S: BuildHasher,
+ T: fmt::Debug,
A: Allocator + Clone,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1130,6 +1159,27 @@
}
}
+// The default hasher is used to match the std implementation signature
+#[cfg(feature = "ahash")]
+impl<T, A, const N: usize> From<[T; N]> for HashSet<T, DefaultHashBuilder, A>
+where
+ T: Eq + Hash,
+ A: Default + Allocator + Clone,
+{
+ /// # Examples
+ ///
+ /// ```
+ /// use hashbrown::HashSet;
+ ///
+ /// let set1 = HashSet::from([1, 2, 3, 4]);
+ /// let set2: HashSet<_> = [1, 2, 3, 4].into();
+ /// assert_eq!(set1, set2);
+ /// ```
+ fn from(arr: [T; N]) -> Self {
+ arr.into_iter().collect()
+ }
+}
+
impl<T, S, A> Extend<T> for HashSet<T, S, A>
where
T: Eq + Hash,
@@ -1162,7 +1212,7 @@
{
#[cfg_attr(feature = "inline-more", inline)]
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
- self.extend(iter.into_iter().cloned());
+ self.extend(iter.into_iter().copied());
}
#[inline]
@@ -1963,7 +2013,7 @@
let expected = [3, 5, 11, 77];
for x in a.intersection(&b) {
assert!(expected.contains(x));
- i += 1
+ i += 1;
}
assert_eq!(i, expected.len());
}
@@ -1986,7 +2036,7 @@
let expected = [1, 5, 11];
for x in a.difference(&b) {
assert!(expected.contains(x));
- i += 1
+ i += 1;
}
assert_eq!(i, expected.len());
}
@@ -2012,7 +2062,7 @@
let expected = [-2, 1, 5, 11, 14, 22];
for x in a.symmetric_difference(&b) {
assert!(expected.contains(x));
- i += 1
+ i += 1;
}
assert_eq!(i, expected.len());
}
@@ -2042,7 +2092,7 @@
let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
for x in a.union(&b) {
assert!(expected.contains(x));
- i += 1
+ i += 1;
}
assert_eq!(i, expected.len());
}
@@ -2068,7 +2118,7 @@
fn test_from_iter() {
let xs = [1, 2, 2, 3, 4, 5, 6, 7, 8, 9];
- let set: HashSet<_> = xs.iter().cloned().collect();
+ let set: HashSet<_> = xs.iter().copied().collect();
for x in &xs {
assert!(set.contains(x));
@@ -2230,7 +2280,7 @@
#[test]
fn test_retain() {
let xs = [1, 2, 3, 4, 5, 6];
- let mut set: HashSet<i32> = xs.iter().cloned().collect();
+ let mut set: HashSet<i32> = xs.iter().copied().collect();
set.retain(|&k| k % 2 == 0);
assert_eq!(set.len(), 3);
assert!(set.contains(&2));
@@ -2272,7 +2322,7 @@
const EMPTY_SET: HashSet<u32, MyHasher> = HashSet::with_hasher(MyHasher);
- let mut set = EMPTY_SET.clone();
+ let mut set = EMPTY_SET;
set.insert(19);
assert!(set.contains(&19));
}
diff --git a/sgx_tstd/hashbrown/tests/rayon.rs b/sgx_tstd/hashbrown/tests/rayon.rs
index 39b4770..8c603c5 100644
--- a/sgx_tstd/hashbrown/tests/rayon.rs
+++ b/sgx_tstd/hashbrown/tests/rayon.rs
@@ -269,20 +269,20 @@
let mut map_seq = MAP_EXISTING_EMPTY.clone();
let mut map_par = MAP_EXISTING_EMPTY.clone();
- map_seq.extend(MAP_EXTENSION_EMPTY.iter().cloned());
- map_par.par_extend(MAP_EXTENSION_EMPTY.par_iter().cloned());
+ map_seq.extend(MAP_EXTENSION_EMPTY.iter().copied());
+ map_par.par_extend(MAP_EXTENSION_EMPTY.par_iter().copied());
assert_eq3!(map_seq, map_par, expected);
}
#[test]
fn map_seq_par_equivalence_existing_empty_extend() {
- let expected = MAP_EXTENSION.iter().cloned().collect::<HashMap<_, _>>();
+ let expected = MAP_EXTENSION.iter().copied().collect::<HashMap<_, _>>();
let mut map_seq = MAP_EXISTING_EMPTY.clone();
let mut map_par = MAP_EXISTING_EMPTY.clone();
- map_seq.extend(MAP_EXTENSION.iter().cloned());
- map_par.par_extend(MAP_EXTENSION.par_iter().cloned());
+ map_seq.extend(MAP_EXTENSION.iter().copied());
+ map_par.par_extend(MAP_EXTENSION.par_iter().copied());
assert_eq3!(map_seq, map_par, expected);
}
@@ -293,8 +293,8 @@
let mut map_seq = MAP_EXISTING.clone();
let mut map_par = MAP_EXISTING.clone();
- map_seq.extend(MAP_EXTENSION_EMPTY.iter().cloned());
- map_par.par_extend(MAP_EXTENSION_EMPTY.par_iter().cloned());
+ map_seq.extend(MAP_EXTENSION_EMPTY.iter().copied());
+ map_par.par_extend(MAP_EXTENSION_EMPTY.par_iter().copied());
assert_eq3!(map_seq, map_par, expected);
}
@@ -305,8 +305,8 @@
let mut map_seq = MAP_EXISTING.clone();
let mut map_par = MAP_EXISTING.clone();
- map_seq.extend(MAP_EXTENSION.iter().cloned());
- map_par.par_extend(MAP_EXTENSION.par_iter().cloned());
+ map_seq.extend(MAP_EXTENSION.iter().copied());
+ map_par.par_extend(MAP_EXTENSION.par_iter().copied());
assert_eq3!(map_seq, map_par, expected);
}
@@ -423,20 +423,20 @@
let mut set_seq = SET_EXISTING_EMPTY.clone();
let mut set_par = SET_EXISTING_EMPTY.clone();
- set_seq.extend(SET_EXTENSION_EMPTY.iter().cloned());
- set_par.par_extend(SET_EXTENSION_EMPTY.par_iter().cloned());
+ set_seq.extend(SET_EXTENSION_EMPTY.iter().copied());
+ set_par.par_extend(SET_EXTENSION_EMPTY.par_iter().copied());
assert_eq3!(set_seq, set_par, expected);
}
#[test]
fn set_seq_par_equivalence_existing_empty_extend() {
- let expected = SET_EXTENSION.iter().cloned().collect::<HashSet<_>>();
+ let expected = SET_EXTENSION.iter().copied().collect::<HashSet<_>>();
let mut set_seq = SET_EXISTING_EMPTY.clone();
let mut set_par = SET_EXISTING_EMPTY.clone();
- set_seq.extend(SET_EXTENSION.iter().cloned());
- set_par.par_extend(SET_EXTENSION.par_iter().cloned());
+ set_seq.extend(SET_EXTENSION.iter().copied());
+ set_par.par_extend(SET_EXTENSION.par_iter().copied());
assert_eq3!(set_seq, set_par, expected);
}
@@ -447,8 +447,8 @@
let mut set_seq = SET_EXISTING.clone();
let mut set_par = SET_EXISTING.clone();
- set_seq.extend(SET_EXTENSION_EMPTY.iter().cloned());
- set_par.par_extend(SET_EXTENSION_EMPTY.par_iter().cloned());
+ set_seq.extend(SET_EXTENSION_EMPTY.iter().copied());
+ set_par.par_extend(SET_EXTENSION_EMPTY.par_iter().copied());
assert_eq3!(set_seq, set_par, expected);
}
@@ -459,37 +459,37 @@
let mut set_seq = SET_EXISTING.clone();
let mut set_par = SET_EXISTING.clone();
- set_seq.extend(SET_EXTENSION.iter().cloned());
- set_par.par_extend(SET_EXTENSION.par_iter().cloned());
+ set_seq.extend(SET_EXTENSION.iter().copied());
+ set_par.par_extend(SET_EXTENSION.par_iter().copied());
assert_eq3!(set_seq, set_par, expected);
}
lazy_static! {
- static ref SET_A: HashSet<char> = ['a', 'b', 'c', 'd'].iter().cloned().collect();
- static ref SET_B: HashSet<char> = ['a', 'b', 'e', 'f'].iter().cloned().collect();
- static ref SET_DIFF_AB: HashSet<char> = ['c', 'd'].iter().cloned().collect();
- static ref SET_DIFF_BA: HashSet<char> = ['e', 'f'].iter().cloned().collect();
- static ref SET_SYMM_DIFF_AB: HashSet<char> = ['c', 'd', 'e', 'f'].iter().cloned().collect();
- static ref SET_INTERSECTION_AB: HashSet<char> = ['a', 'b'].iter().cloned().collect();
+ static ref SET_A: HashSet<char> = ['a', 'b', 'c', 'd'].iter().copied().collect();
+ static ref SET_B: HashSet<char> = ['a', 'b', 'e', 'f'].iter().copied().collect();
+ static ref SET_DIFF_AB: HashSet<char> = ['c', 'd'].iter().copied().collect();
+ static ref SET_DIFF_BA: HashSet<char> = ['e', 'f'].iter().copied().collect();
+ static ref SET_SYMM_DIFF_AB: HashSet<char> = ['c', 'd', 'e', 'f'].iter().copied().collect();
+ static ref SET_INTERSECTION_AB: HashSet<char> = ['a', 'b'].iter().copied().collect();
static ref SET_UNION_AB: HashSet<char> =
- ['a', 'b', 'c', 'd', 'e', 'f'].iter().cloned().collect();
+ ['a', 'b', 'c', 'd', 'e', 'f'].iter().copied().collect();
}
#[test]
fn set_seq_par_equivalence_difference() {
- let diff_ab_seq = SET_A.difference(&*SET_B).cloned().collect::<HashSet<_>>();
+ let diff_ab_seq = SET_A.difference(&*SET_B).copied().collect::<HashSet<_>>();
let diff_ab_par = SET_A
.par_difference(&*SET_B)
- .cloned()
+ .copied()
.collect::<HashSet<_>>();
assert_eq3!(diff_ab_seq, diff_ab_par, *SET_DIFF_AB);
- let diff_ba_seq = SET_B.difference(&*SET_A).cloned().collect::<HashSet<_>>();
+ let diff_ba_seq = SET_B.difference(&*SET_A).copied().collect::<HashSet<_>>();
let diff_ba_par = SET_B
.par_difference(&*SET_A)
- .cloned()
+ .copied()
.collect::<HashSet<_>>();
assert_eq3!(diff_ba_seq, diff_ba_par, *SET_DIFF_BA);
@@ -499,11 +499,11 @@
fn set_seq_par_equivalence_symmetric_difference() {
let symm_diff_ab_seq = SET_A
.symmetric_difference(&*SET_B)
- .cloned()
+ .copied()
.collect::<HashSet<_>>();
let symm_diff_ab_par = SET_A
.par_symmetric_difference(&*SET_B)
- .cloned()
+ .copied()
.collect::<HashSet<_>>();
assert_eq3!(symm_diff_ab_seq, symm_diff_ab_par, *SET_SYMM_DIFF_AB);
@@ -511,10 +511,10 @@
#[test]
fn set_seq_par_equivalence_intersection() {
- let intersection_ab_seq = SET_A.intersection(&*SET_B).cloned().collect::<HashSet<_>>();
+ let intersection_ab_seq = SET_A.intersection(&*SET_B).copied().collect::<HashSet<_>>();
let intersection_ab_par = SET_A
.par_intersection(&*SET_B)
- .cloned()
+ .copied()
.collect::<HashSet<_>>();
assert_eq3!(
@@ -526,8 +526,8 @@
#[test]
fn set_seq_par_equivalence_union() {
- let union_ab_seq = SET_A.union(&*SET_B).cloned().collect::<HashSet<_>>();
- let union_ab_par = SET_A.par_union(&*SET_B).cloned().collect::<HashSet<_>>();
+ let union_ab_seq = SET_A.union(&*SET_B).copied().collect::<HashSet<_>>();
+ let union_ab_par = SET_A.par_union(&*SET_B).copied().collect::<HashSet<_>>();
assert_eq3!(union_ab_seq, union_ab_par, *SET_UNION_AB);
}
diff --git a/sgx_tstd/hashbrown/tests/set.rs b/sgx_tstd/hashbrown/tests/set.rs
index 3fc0717..5ae1ec9 100644
--- a/sgx_tstd/hashbrown/tests/set.rs
+++ b/sgx_tstd/hashbrown/tests/set.rs
@@ -2,29 +2,33 @@
use hashbrown::HashSet;
use rand::{distributions::Alphanumeric, rngs::SmallRng, Rng, SeedableRng};
+use std::iter;
#[test]
fn test_hashset_insert_remove() {
let mut m: HashSet<Vec<char>> = HashSet::new();
- //let num: u32 = 4096;
- //let tx: Vec<Vec<u8>> = (0..num).map(|i| (i..(16 + i)).collect()).collect();
- let seed: [u8; 16] = [
- 130, 220, 246, 217, 111, 124, 221, 189, 190, 234, 121, 93, 67, 95, 100, 43,
- ];
+ let seed = u64::from_le_bytes(*b"testseed");
- let rng = &mut SmallRng::from_seed(seed);
- let tx: Vec<Vec<char>> = (0..4096)
- .map(|_| (rng.sample_iter(&Alphanumeric).take(32).collect()))
- .collect();
+ let rng = &mut SmallRng::seed_from_u64(seed);
+ let tx: Vec<Vec<char>> = iter::repeat_with(|| {
+ rng.sample_iter(&Alphanumeric)
+ .take(32)
+ .map(char::from)
+ .collect()
+ })
+ .take(4096)
+ .collect();
+ // more readable with explicit `true` / `false`
+ #[allow(clippy::bool_assert_comparison)]
for _ in 0..32 {
- for i in 0..4096 {
- assert_eq!(m.contains(&tx[i].clone()), false);
- assert_eq!(m.insert(tx[i].clone()), true);
+ for x in &tx {
+ assert_eq!(m.contains(x), false);
+ assert_eq!(m.insert(x.clone()), true);
}
- for i in 0..4096 {
- println!("removing {} {:?}", i, tx[i]);
- assert_eq!(m.remove(&tx[i]), true);
+ for (i, x) in tx.iter().enumerate() {
+ println!("removing {} {:?}", i, x);
+ assert_eq!(m.remove(x), true);
}
}
}
diff --git a/sgx_tstd/src/backtrace.rs b/sgx_tstd/src/backtrace.rs
index e7c96b8..a491f5d 100644
--- a/sgx_tstd/src/backtrace.rs
+++ b/sgx_tstd/src/backtrace.rs
@@ -83,13 +83,14 @@
// a backtrace or actually symbolizing it.
pub use crate::sys_common::backtrace::__rust_begin_short_backtrace;
-pub use crate::sys_common::backtrace::PrintFormat;
use crate::cell::UnsafeCell;
use crate::ffi::c_void;
use crate::fmt;
+use crate::fs;
use crate::enclave;
use crate::io;
+use crate::panic::{BacktraceStyle, get_backtrace_style, set_backtrace_style};
use crate::path::Path;
use crate::sync::Once;
use crate::sys::backtrace::{self, BytesOrWideString};
@@ -97,12 +98,8 @@
lock,
output_filename,
resolve_frame_unsynchronized,
- rust_backtrace_env,
- RustBacktrace,
- set_enabled,
SymbolName,
};
-use crate::untrusted::fs;
use crate::vec::Vec;
/// A captured OS thread stack backtrace.
@@ -249,7 +246,16 @@
impl Backtrace {
/// Returns whether backtrace captures are enabled
fn enabled() -> bool {
- matches!(rust_backtrace_env(), RustBacktrace::Print(_))
+ match get_backtrace_style() {
+ Some(style) => {
+ match style {
+ BacktraceStyle::Full => true,
+ BacktraceStyle::Short => true,
+ BacktraceStyle::Off => false,
+ }
+ }
+ None => false,
+ }
}
/// Capture a stack backtrace of the current thread.
@@ -424,6 +430,7 @@
unsafe impl Sync for LazilyResolvedCapture where Capture: Sync {}
impl Capture {
+ #[allow(clippy::infallible_destructuring_match)]
fn resolve(&mut self) {
// If we're already resolved, nothing to do!
if self.resolved {
@@ -460,12 +467,19 @@
fn ip(&self) -> *mut c_void {
match self {
RawFrame::Actual(frame) => frame.ip(),
- #[cfg(test)]
- RawFrame::Fake => 1 as *mut c_void,
}
}
}
+/// Controls how the backtrace should be formatted.
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum PrintFormat {
+ /// Show only relevant data from the backtrace.
+ Short,
+ /// Show all the frames with absolute path for files.
+ Full,
+}
+
/// Enable backtrace for dumping call stack on crash.
///
/// Enabling backtrace here makes the panic information along with call stack
@@ -477,6 +491,10 @@
pub fn enable_backtrace<P: AsRef<Path>>(path: P, format: PrintFormat) -> io::Result<()> {
let _ = fs::metadata(&path)?;
enclave::set_enclave_path(path)?;
- set_enabled(format);
+ let style = match format {
+ PrintFormat::Short => BacktraceStyle::Short,
+ PrintFormat::Full => BacktraceStyle::Full,
+ };
+ set_backtrace_style(style);
Ok(())
}
diff --git a/sgx_tstd/src/collections/hash/map.rs b/sgx_tstd/src/collections/hash/map.rs
index 8b7fd72..2c5012a 100644
--- a/sgx_tstd/src/collections/hash/map.rs
+++ b/sgx_tstd/src/collections/hash/map.rs
@@ -342,10 +342,11 @@
/// ```
/// use std::collections::HashMap;
///
- /// let mut map = HashMap::new();
- /// map.insert("a", 1);
- /// map.insert("b", 2);
- /// map.insert("c", 3);
+ /// let map = HashMap::from([
+ /// ("a", 1),
+ /// ("b", 2),
+ /// ("c", 3),
+ /// ]);
///
/// for key in map.keys() {
/// println!("{}", key);
@@ -355,6 +356,33 @@
Keys { inner: self.iter() }
}
+ /// Creates a consuming iterator visiting all the keys in arbitrary order.
+ /// The map cannot be used after calling this.
+ /// The iterator element type is `K`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let map = HashMap::from([
+ /// ("a", 1),
+ /// ("b", 2),
+ /// ("c", 3),
+ /// ]);
+ ///
+ /// let mut vec: Vec<&str> = map.into_keys().collect();
+ /// // The `IntoKeys` iterator produces keys in arbitrary order, so the
+ /// // keys must be sorted to test them against a sorted array.
+ /// vec.sort_unstable();
+ /// assert_eq!(vec, ["a", "b", "c"]);
+ /// ```
+ #[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
+ pub fn into_keys(self) -> IntoKeys<K, V> {
+ IntoKeys { inner: self.into_iter() }
+ }
+
/// An iterator visiting all values in arbitrary order.
/// The iterator element type is `&'a V`.
///
@@ -363,10 +391,11 @@
/// ```
/// use std::collections::HashMap;
///
- /// let mut map = HashMap::new();
- /// map.insert("a", 1);
- /// map.insert("b", 2);
- /// map.insert("c", 3);
+ /// let map = HashMap::from([
+ /// ("a", 1),
+ /// ("b", 2),
+ /// ("c", 3),
+ /// ]);
///
/// for val in map.values() {
/// println!("{}", val);
@@ -384,11 +413,11 @@
/// ```
/// use std::collections::HashMap;
///
- /// let mut map = HashMap::new();
- ///
- /// map.insert("a", 1);
- /// map.insert("b", 2);
- /// map.insert("c", 3);
+ /// let mut map = HashMap::from([
+ /// ("a", 1),
+ /// ("b", 2),
+ /// ("c", 3),
+ /// ]);
///
/// for val in map.values_mut() {
/// *val = *val + 10;
@@ -402,6 +431,33 @@
ValuesMut { inner: self.iter_mut() }
}
+ /// Creates a consuming iterator visiting all the values in arbitrary order.
+ /// The map cannot be used after calling this.
+ /// The iterator element type is `V`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let map = HashMap::from([
+ /// ("a", 1),
+ /// ("b", 2),
+ /// ("c", 3),
+ /// ]);
+ ///
+ /// let mut vec: Vec<i32> = map.into_values().collect();
+ /// // The `IntoValues` iterator produces values in arbitrary order, so
+ /// // the values must be sorted to test them against a sorted array.
+ /// vec.sort_unstable();
+ /// assert_eq!(vec, [1, 2, 3]);
+ /// ```
+ #[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
+ pub fn into_values(self) -> IntoValues<K, V> {
+ IntoValues { inner: self.into_iter() }
+ }
+
/// An iterator visiting all key-value pairs in arbitrary order.
/// The iterator element type is `(&'a K, &'a V)`.
///
@@ -410,15 +466,17 @@
/// ```
/// use std::collections::HashMap;
///
- /// let mut map = HashMap::new();
- /// map.insert("a", 1);
- /// map.insert("b", 2);
- /// map.insert("c", 3);
+ /// let map = HashMap::from([
+ /// ("a", 1),
+ /// ("b", 2),
+ /// ("c", 3),
+ /// ]);
///
/// for (key, val) in map.iter() {
/// println!("key: {} val: {}", key, val);
/// }
/// ```
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
pub fn iter(&self) -> Iter<'_, K, V> {
Iter { base: self.base.iter() }
}
@@ -432,10 +490,11 @@
/// ```
/// use std::collections::HashMap;
///
- /// let mut map = HashMap::new();
- /// map.insert("a", 1);
- /// map.insert("b", 2);
- /// map.insert("c", 3);
+ /// let mut map = HashMap::from([
+ /// ("a", 1),
+ /// ("b", 2),
+ /// ("c", 3),
+ /// ]);
///
/// // Update all values
/// for (_, val) in map.iter_mut() {
@@ -446,6 +505,7 @@
/// println!("key: {} val: {}", key, val);
/// }
/// ```
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
IterMut { base: self.base.iter_mut() }
}
@@ -486,6 +546,10 @@
/// Clears the map, returning all key-value pairs as an iterator. Keeps the
/// allocated memory for reuse.
///
+ /// If the returned iterator is dropped before being fully consumed, it
+ /// drops the remaining key-value pairs. The returned iterator keeps a
+ /// mutable borrow on the vector to optimize its implementation.
+ ///
/// # Examples
///
/// ```
@@ -503,6 +567,7 @@
/// assert!(a.is_empty());
/// ```
#[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
pub fn drain(&mut self) -> Drain<'_, K, V> {
Drain { base: self.base.drain() }
}
@@ -543,6 +608,7 @@
/// assert_eq!(odds, vec![1, 3, 5, 7]);
/// ```
#[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
pub fn drain_filter<F>(&mut self, pred: F) -> DrainFilter<'_, K, V, F>
where
F: FnMut(&K, &mut V) -> bool,
@@ -550,6 +616,29 @@
DrainFilter { base: self.base.drain_filter(pred) }
}
+ /// Retains only the elements specified by the predicate.
+ ///
+ /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
+ /// The elements are visited in unsorted (and unspecified) order.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x*10)).collect();
+ /// map.retain(|&k, _| k % 2 == 0);
+ /// assert_eq!(map.len(), 4);
+ /// ```
+ #[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
+ pub fn retain<F>(&mut self, f: F)
+ where
+ F: FnMut(&K, &mut V) -> bool,
+ {
+ self.base.retain(f)
+ }
+
/// Clears the map, removing all key-value pairs. Keeps the allocated memory
/// for reuse.
///
@@ -917,78 +1006,6 @@
{
self.base.remove_entry(k)
}
-
- /// Retains only the elements specified by the predicate.
- ///
- /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
- /// The elements are visited in unsorted (and unspecified) order.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x*10)).collect();
- /// map.retain(|&k, _| k % 2 == 0);
- /// assert_eq!(map.len(), 4);
- /// ```
- #[inline]
- pub fn retain<F>(&mut self, f: F)
- where
- F: FnMut(&K, &mut V) -> bool,
- {
- self.base.retain(f)
- }
-
- /// Creates a consuming iterator visiting all the keys in arbitrary order.
- /// The map cannot be used after calling this.
- /// The iterator element type is `K`.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// map.insert("a", 1);
- /// map.insert("b", 2);
- /// map.insert("c", 3);
- ///
- /// let mut vec: Vec<&str> = map.into_keys().collect();
- /// // The `IntoKeys` iterator produces keys in arbitrary order, so the
- /// // keys must be sorted to test them against a sorted array.
- /// vec.sort_unstable();
- /// assert_eq!(vec, ["a", "b", "c"]);
- /// ```
- #[inline]
- pub fn into_keys(self) -> IntoKeys<K, V> {
- IntoKeys { inner: self.into_iter() }
- }
-
- /// Creates a consuming iterator visiting all the values in arbitrary order.
- /// The map cannot be used after calling this.
- /// The iterator element type is `V`.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// map.insert("a", 1);
- /// map.insert("b", 2);
- /// map.insert("c", 3);
- ///
- /// let mut vec: Vec<i32> = map.into_values().collect();
- /// // The `IntoValues` iterator produces values in arbitrary order, so
- /// // the values must be sorted to test them against a sorted array.
- /// vec.sort_unstable();
- /// assert_eq!(vec, [1, 2, 3]);
- /// ```
- #[inline]
- pub fn into_values(self) -> IntoValues<K, V> {
- IntoValues { inner: self.into_iter() }
- }
}
impl<K, V, S> HashMap<K, V, S>
@@ -1158,7 +1175,7 @@
/// assert_eq!(map1, map2);
/// ```
fn from(arr: [(K, V); N]) -> Self {
- crate::array::IntoIter::new(arr).collect()
+ Self::from_iter(arr)
}
}
@@ -1174,8 +1191,9 @@
/// ```
/// use std::collections::HashMap;
///
-/// let mut map = HashMap::new();
-/// map.insert("a", 1);
+/// let map = HashMap::from([
+/// ("a", 1),
+/// ]);
/// let iter = map.iter();
/// ```
pub struct Iter<'a, K: 'a, V: 'a> {
@@ -1208,8 +1226,9 @@
/// ```
/// use std::collections::HashMap;
///
-/// let mut map = HashMap::new();
-/// map.insert("a", 1);
+/// let mut map = HashMap::from([
+/// ("a", 1),
+/// ]);
/// let iter = map.iter_mut();
/// ```
pub struct IterMut<'a, K: 'a, V: 'a> {
@@ -1237,8 +1256,9 @@
/// ```
/// use std::collections::HashMap;
///
-/// let mut map = HashMap::new();
-/// map.insert("a", 1);
+/// let map = HashMap::from([
+/// ("a", 1),
+/// ]);
/// let iter = map.into_iter();
/// ```
pub struct IntoIter<K, V> {
@@ -1265,8 +1285,9 @@
/// ```
/// use std::collections::HashMap;
///
-/// let mut map = HashMap::new();
-/// map.insert("a", 1);
+/// let map = HashMap::from([
+/// ("a", 1),
+/// ]);
/// let iter_keys = map.keys();
/// ```
pub struct Keys<'a, K: 'a, V: 'a> {
@@ -1299,8 +1320,9 @@
/// ```
/// use std::collections::HashMap;
///
-/// let mut map = HashMap::new();
-/// map.insert("a", 1);
+/// let map = HashMap::from([
+/// ("a", 1),
+/// ]);
/// let iter_values = map.values();
/// ```
pub struct Values<'a, K: 'a, V: 'a> {
@@ -1333,8 +1355,9 @@
/// ```
/// use std::collections::HashMap;
///
-/// let mut map = HashMap::new();
-/// map.insert("a", 1);
+/// let mut map = HashMap::from([
+/// ("a", 1),
+/// ]);
/// let iter = map.drain();
/// ```
pub struct Drain<'a, K: 'a, V: 'a> {
@@ -1362,8 +1385,9 @@
///
/// use std::collections::HashMap;
///
-/// let mut map = HashMap::new();
-/// map.insert("a", 1);
+/// let mut map = HashMap::from([
+/// ("a", 1),
+/// ]);
/// let iter = map.drain_filter(|_k, v| *v % 2 == 0);
/// ```
pub struct DrainFilter<'a, K, V, F>
@@ -1385,8 +1409,9 @@
/// ```
/// use std::collections::HashMap;
///
-/// let mut map = HashMap::new();
-/// map.insert("a", 1);
+/// let mut map = HashMap::from([
+/// ("a", 1),
+/// ]);
/// let iter_values = map.values_mut();
/// ```
pub struct ValuesMut<'a, K: 'a, V: 'a> {
@@ -1405,8 +1430,9 @@
/// ```
/// use std::collections::HashMap;
///
-/// let mut map = HashMap::new();
-/// map.insert("a", 1);
+/// let map = HashMap::from([
+/// ("a", 1),
+/// ]);
/// let iter_keys = map.into_keys();
/// ```
pub struct IntoKeys<K, V> {
@@ -1425,8 +1451,9 @@
/// ```
/// use std::collections::HashMap;
///
-/// let mut map = HashMap::new();
-/// map.insert("a", 1);
+/// let map = HashMap::from([
+/// ("a", 1),
+/// ]);
/// let iter_keys = map.into_values();
/// ```
pub struct IntoValues<K, V> {
@@ -1628,6 +1655,7 @@
/// .or_insert("poneyland", 0);
/// assert_eq!(map["poneyland"], 43);
/// ```
+ #[must_use]
#[inline]
pub fn and_modify<F>(self, f: F) -> Self
where
@@ -1912,15 +1940,17 @@
/// ```
/// use std::collections::HashMap;
///
- /// let mut map = HashMap::new();
- /// map.insert("a", 1);
- /// map.insert("b", 2);
- /// map.insert("c", 3);
+ /// let map = HashMap::from([
+ /// ("a", 1),
+ /// ("b", 2),
+ /// ("c", 3),
+ /// ]);
///
/// // Not possible with .iter()
/// let vec: Vec<(&str, i32)> = map.into_iter().collect();
/// ```
#[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
fn into_iter(self) -> IntoIter<K, V> {
IntoIter { base: self.base.into_iter() }
}
@@ -2310,6 +2340,7 @@
/// .or_insert(42);
/// assert_eq!(map["poneyland"], 43);
/// ```
+ #[must_use]
#[inline]
pub fn and_modify<F>(self, f: F) -> Self
where
@@ -2333,12 +2364,12 @@
/// use std::collections::HashMap;
///
/// let mut map: HashMap<&str, String> = HashMap::new();
- /// let entry = map.entry("poneyland").insert("hoho".to_string());
+ /// let entry = map.entry("poneyland").insert_entry("hoho".to_string());
///
/// assert_eq!(entry.key(), &"poneyland");
/// ```
#[inline]
- pub fn insert(self, value: V) -> OccupiedEntry<'a, K, V> {
+ pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> {
match self {
Occupied(mut entry) => {
entry.insert(value);
@@ -2664,12 +2695,12 @@
/// let mut map: HashMap<&str, u32> = HashMap::new();
///
/// if let Entry::Vacant(o) = map.entry("poneyland") {
- /// o.insert(37);
+ /// o.insert_entry(37);
/// }
/// assert_eq!(map["poneyland"], 37);
/// ```
#[inline]
- fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> {
+ pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> {
let base = self.base.insert_entry(value);
OccupiedEntry { base }
}
diff --git a/sgx_tstd/src/collections/hash/set.rs b/sgx_tstd/src/collections/hash/set.rs
index 2eb6577..b6b62b6 100644
--- a/sgx_tstd/src/collections/hash/set.rs
+++ b/sgx_tstd/src/collections/hash/set.rs
@@ -195,6 +195,7 @@
/// }
/// ```
#[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
pub fn iter(&self) -> Iter<'_, T> {
Iter { base: self.base.iter() }
}
@@ -233,14 +234,19 @@
self.base.is_empty()
}
- /// Clears the set, returning all elements in an iterator.
+ /// Clears the set, returning all elements as an iterator. Keeps the
+ /// allocated memory for reuse.
+ ///
+ /// If the returned iterator is dropped before being fully consumed, it
+ /// drops the remaining elements. The returned iterator keeps a mutable
+ /// borrow on the vector to optimize its implementation.
///
/// # Examples
///
/// ```
/// use std::collections::HashSet;
///
- /// let mut set: HashSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// let mut set = HashSet::from([1, 2, 3]);
/// assert!(!set.is_empty());
///
/// // print 1, 2, 3 in an arbitrary order
@@ -251,6 +257,7 @@
/// assert!(set.is_empty());
/// ```
#[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
pub fn drain(&mut self) -> Drain<'_, T> {
Drain { base: self.base.drain() }
}
@@ -288,6 +295,7 @@
/// assert_eq!(odds, vec![1, 3, 5, 7]);
/// ```
#[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
pub fn drain_filter<F>(&mut self, pred: F) -> DrainFilter<'_, T, F>
where
F: FnMut(&T) -> bool,
@@ -295,6 +303,28 @@
DrainFilter { base: self.base.drain_filter(pred) }
}
+ /// Retains only the elements specified by the predicate.
+ ///
+ /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
+ /// The elements are visited in unsorted (and unspecified) order.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ ///
+ /// let mut set = HashSet::from([1, 2, 3, 4, 5, 6]);
+ /// set.retain(|&k| k % 2 == 0);
+ /// assert_eq!(set.len(), 3);
+ /// ```
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
+ pub fn retain<F>(&mut self, f: F)
+ where
+ F: FnMut(&T) -> bool,
+ {
+ self.base.retain(f)
+ }
+
/// Clears the set, removing all values.
///
/// # Examples
@@ -486,8 +516,8 @@
///
/// ```
/// use std::collections::HashSet;
- /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
- /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
+ /// let a = HashSet::from([1, 2, 3]);
+ /// let b = HashSet::from([4, 2, 3, 4]);
///
/// // Can be seen as `a - b`.
/// for x in a.difference(&b) {
@@ -503,6 +533,7 @@
/// assert_eq!(diff, [4].iter().collect());
/// ```
#[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
pub fn difference<'a>(&'a self, other: &'a HashSet<T, S>) -> Difference<'a, T, S> {
Difference { iter: self.iter(), other }
}
@@ -514,8 +545,8 @@
///
/// ```
/// use std::collections::HashSet;
- /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
- /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
+ /// let a = HashSet::from([1, 2, 3]);
+ /// let b = HashSet::from([4, 2, 3, 4]);
///
/// // Print 1, 4 in arbitrary order.
/// for x in a.symmetric_difference(&b) {
@@ -529,6 +560,7 @@
/// assert_eq!(diff1, [1, 4].iter().collect());
/// ```
#[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
pub fn symmetric_difference<'a>(
&'a self,
other: &'a HashSet<T, S>,
@@ -543,8 +575,8 @@
///
/// ```
/// use std::collections::HashSet;
- /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
- /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
+ /// let a = HashSet::from([1, 2, 3]);
+ /// let b = HashSet::from([4, 2, 3, 4]);
///
/// // Print 2, 3 in arbitrary order.
/// for x in a.intersection(&b) {
@@ -555,6 +587,7 @@
/// assert_eq!(intersection, [2, 3].iter().collect());
/// ```
#[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
pub fn intersection<'a>(&'a self, other: &'a HashSet<T, S>) -> Intersection<'a, T, S> {
if self.len() <= other.len() {
Intersection { iter: self.iter(), other }
@@ -570,8 +603,8 @@
///
/// ```
/// use std::collections::HashSet;
- /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
- /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
+ /// let a = HashSet::from([1, 2, 3]);
+ /// let b = HashSet::from([4, 2, 3, 4]);
///
/// // Print 1, 2, 3, 4 in arbitrary order.
/// for x in a.union(&b) {
@@ -582,6 +615,7 @@
/// assert_eq!(union, [1, 2, 3, 4].iter().collect());
/// ```
#[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> Union<'a, T, S> {
if self.len() >= other.len() {
Union { iter: self.iter().chain(other.difference(self)) }
@@ -601,7 +635,7 @@
/// ```
/// use std::collections::HashSet;
///
- /// let set: HashSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// let set = HashSet::from([1, 2, 3]);
/// assert_eq!(set.contains(&1), true);
/// assert_eq!(set.contains(&4), false);
/// ```
@@ -625,7 +659,7 @@
/// ```
/// use std::collections::HashSet;
///
- /// let set: HashSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// let set = HashSet::from([1, 2, 3]);
/// assert_eq!(set.get(&2), Some(&2));
/// assert_eq!(set.get(&4), None);
/// ```
@@ -648,7 +682,7 @@
///
/// use std::collections::HashSet;
///
- /// let mut set: HashSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// let mut set = HashSet::from([1, 2, 3]);
/// assert_eq!(set.len(), 3);
/// assert_eq!(set.get_or_insert(2), &2);
/// assert_eq!(set.get_or_insert(100), &100);
@@ -732,7 +766,7 @@
/// ```
/// use std::collections::HashSet;
///
- /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// let a = HashSet::from([1, 2, 3]);
/// let mut b = HashSet::new();
///
/// assert_eq!(a.is_disjoint(&b), true);
@@ -757,7 +791,7 @@
/// ```
/// use std::collections::HashSet;
///
- /// let sup: HashSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// let sup = HashSet::from([1, 2, 3]);
/// let mut set = HashSet::new();
///
/// assert_eq!(set.is_subset(&sup), true);
@@ -778,7 +812,7 @@
/// ```
/// use std::collections::HashSet;
///
- /// let sub: HashSet<_> = [1, 2].iter().cloned().collect();
+ /// let sub = HashSet::from([1, 2]);
/// let mut set = HashSet::new();
///
/// assert_eq!(set.is_superset(&sub), false);
@@ -875,7 +909,7 @@
/// ```
/// use std::collections::HashSet;
///
- /// let mut set: HashSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// let mut set = HashSet::from([1, 2, 3]);
/// assert_eq!(set.take(&2), Some(2));
/// assert_eq!(set.take(&2), None);
/// ```
@@ -887,28 +921,6 @@
{
self.base.take(value)
}
-
- /// Retains only the elements specified by the predicate.
- ///
- /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
- /// The elements are visited in unsorted (and unspecified) order.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::collections::HashSet;
- ///
- /// let xs = [1, 2, 3, 4, 5, 6];
- /// let mut set: HashSet<i32> = xs.iter().cloned().collect();
- /// set.retain(|&k| k % 2 == 0);
- /// assert_eq!(set.len(), 3);
- /// ```
- pub fn retain<F>(&mut self, f: F)
- where
- F: FnMut(&T) -> bool,
- {
- self.base.retain(f)
- }
}
impl<T, S> Clone for HashSet<T, S>
@@ -996,7 +1008,7 @@
/// assert_eq!(set1, set2);
/// ```
fn from(arr: [T; N]) -> Self {
- crate::array::IntoIter::new(arr).collect()
+ Self::from_iter(arr)
}
}
@@ -1067,8 +1079,8 @@
/// ```
/// use std::collections::HashSet;
///
- /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
- /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
+ /// let a = HashSet::from([1, 2, 3]);
+ /// let b = HashSet::from([3, 4, 5]);
///
/// let set = &a | &b;
///
@@ -1099,8 +1111,8 @@
/// ```
/// use std::collections::HashSet;
///
- /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
- /// let b: HashSet<_> = vec![2, 3, 4].into_iter().collect();
+ /// let a = HashSet::from([1, 2, 3]);
+ /// let b = HashSet::from([2, 3, 4]);
///
/// let set = &a & &b;
///
@@ -1131,8 +1143,8 @@
/// ```
/// use std::collections::HashSet;
///
- /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
- /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
+ /// let a = HashSet::from([1, 2, 3]);
+ /// let b = HashSet::from([3, 4, 5]);
///
/// let set = &a ^ &b;
///
@@ -1163,8 +1175,8 @@
/// ```
/// use std::collections::HashSet;
///
- /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
- /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
+ /// let a = HashSet::from([1, 2, 3]);
+ /// let b = HashSet::from([3, 4, 5]);
///
/// let set = &a - &b;
///
@@ -1193,7 +1205,7 @@
/// ```
/// use std::collections::HashSet;
///
-/// let a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
+/// let a = HashSet::from([1, 2, 3]);
///
/// let mut iter = a.iter();
/// ```
@@ -1214,7 +1226,7 @@
/// ```
/// use std::collections::HashSet;
///
-/// let a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
+/// let a = HashSet::from([1, 2, 3]);
///
/// let mut iter = a.into_iter();
/// ```
@@ -1234,7 +1246,7 @@
/// ```
/// use std::collections::HashSet;
///
-/// let mut a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
+/// let mut a = HashSet::from([1, 2, 3]);
///
/// let mut drain = a.drain();
/// ```
@@ -1255,7 +1267,7 @@
///
/// use std::collections::HashSet;
///
-/// let mut a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
+/// let mut a = HashSet::from([1, 2, 3]);
///
/// let mut drain_filtered = a.drain_filter(|v| v % 2 == 0);
/// ```
@@ -1278,8 +1290,8 @@
/// ```
/// use std::collections::HashSet;
///
-/// let a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
-/// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
+/// let a = HashSet::from([1, 2, 3]);
+/// let b = HashSet::from([4, 2, 3, 4]);
///
/// let mut intersection = a.intersection(&b);
/// ```
@@ -1304,8 +1316,8 @@
/// ```
/// use std::collections::HashSet;
///
-/// let a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
-/// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
+/// let a = HashSet::from([1, 2, 3]);
+/// let b = HashSet::from([4, 2, 3, 4]);
///
/// let mut difference = a.difference(&b);
/// ```
@@ -1330,8 +1342,8 @@
/// ```
/// use std::collections::HashSet;
///
-/// let a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
-/// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
+/// let a = HashSet::from([1, 2, 3]);
+/// let b = HashSet::from([4, 2, 3, 4]);
///
/// let mut intersection = a.symmetric_difference(&b);
/// ```
@@ -1353,8 +1365,8 @@
/// ```
/// use std::collections::HashSet;
///
-/// let a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
-/// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
+/// let a = HashSet::from([1, 2, 3]);
+/// let b = HashSet::from([4, 2, 3, 4]);
///
/// let mut union_iter = a.union(&b);
/// ```
@@ -1369,6 +1381,7 @@
type IntoIter = Iter<'a, T>;
#[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
@@ -1399,6 +1412,7 @@
/// }
/// ```
#[inline]
+ #[cfg_attr(not(bootstrap), rustc_lint_query_instability)]
fn into_iter(self) -> IntoIter<T> {
IntoIter { base: self.base.into_iter() }
}
diff --git a/sgx_tstd/src/collections/mod.rs b/sgx_tstd/src/collections/mod.rs
index aca02b2..5b2dcbd 100644
--- a/sgx_tstd/src/collections/mod.rs
+++ b/sgx_tstd/src/collections/mod.rs
@@ -249,7 +249,7 @@
//! ```
//! use std::collections::VecDeque;
//!
-//! let vec = vec![1, 2, 3, 4];
+//! let vec = [1, 2, 3, 4];
//! let buf: VecDeque<_> = vec.into_iter().collect();
//! ```
//!
@@ -285,7 +285,7 @@
//! not. Normally, this would require a `find` followed by an `insert`,
//! effectively duplicating the search effort on each insertion.
//!
-//! When a user calls `map.entry(&key)`, the map will search for the key and
+//! When a user calls `map.entry(key)`, the map will search for the key and
//! then yield a variant of the `Entry` enum.
//!
//! If a `Vacant(entry)` is yielded, then the key *was not* found. In this case
diff --git a/sgx_tstd/src/env.rs b/sgx_tstd/src/env.rs
index 1cd21da..cae3405 100644
--- a/sgx_tstd/src/env.rs
+++ b/sgx_tstd/src/env.rs
@@ -35,6 +35,11 @@
/// Returns the current working directory as a [`PathBuf`].
///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `getcwd` function on Unix
+/// and the `GetCurrentDirectoryW` function on Windows.
+///
/// # Errors
///
/// Returns an [`Err`] if the current working directory value is invalid.
@@ -60,6 +65,11 @@
/// Changes the current working directory to the specified path.
///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `chdir` function on Unix
+/// and the `SetCurrentDirectoryW` function on Windows.
+///
/// Returns an [`Err`] if the operation fails.
///
/// # Examples
@@ -562,28 +572,25 @@
/// may result in "insecure temporary file" security vulnerabilities. Consider
/// using a crate that securely creates temporary files or directories.
///
-/// # Unix
+/// # Platform-specific behavior
///
-/// Returns the value of the `TMPDIR` environment variable if it is
+/// On Unix, returns the value of the `TMPDIR` environment variable if it is
/// set, otherwise for non-Android it returns `/tmp`. If Android, since there
/// is no global temporary folder (it is usually allocated per-app), it returns
/// `/data/local/tmp`.
+/// On Windows, the behavior is equivalent to that of [`GetTempPath2`][GetTempPath2] /
+/// [`GetTempPath`][GetTempPath], which this function uses internally.
+/// Note that, this [may change in the future][changes].
///
-/// # Windows
-///
-/// Returns the value of, in order, the `TMP`, `TEMP`,
-/// `USERPROFILE` environment variable if any are set and not the empty
-/// string. Otherwise, `temp_dir` returns the path of the Windows directory.
-/// This behavior is identical to that of [`GetTempPath`][msdn], which this
-/// function uses internally.
-///
-/// [msdn]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
+/// [changes]: io#platform-specific-behavior
+/// [GetTempPath2]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a
+/// [GetTempPath]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
///
/// ```no_run
/// use std::env;
///
/// fn main() {
-/// let mut dir = env::temp_dir();
+/// let dir = env::temp_dir();
/// println!("Temporary directory: {}", dir.display());
/// }
/// ```
diff --git a/sgx_tstd/src/error.rs b/sgx_tstd/src/error.rs
index 91cc72c..d795fc9 100644
--- a/sgx_tstd/src/error.rs
+++ b/sgx_tstd/src/error.rs
@@ -39,11 +39,14 @@
use crate::cell;
use crate::char;
use crate::fmt::{self, Debug, Display};
+#[cfg(feature = "backtrace")]
+use crate::fmt::Write;
use crate::mem::transmute;
use crate::num;
use crate::str;
use crate::string;
use crate::sync::Arc;
+use crate::time;
use sgx_types::sgx_status_t;
@@ -76,7 +79,7 @@
///
/// #[derive(Debug)]
/// struct SuperError {
- /// side: SuperErrorSideKick,
+ /// source: SuperErrorSideKick,
/// }
///
/// impl fmt::Display for SuperError {
@@ -87,7 +90,7 @@
///
/// impl Error for SuperError {
/// fn source(&self) -> Option<&(dyn Error + 'static)> {
- /// Some(&self.side)
+ /// Some(&self.source)
/// }
/// }
///
@@ -103,7 +106,7 @@
/// impl Error for SuperErrorSideKick {}
///
/// fn get_super_error() -> Result<(), SuperError> {
- /// Err(SuperError { side: SuperErrorSideKick })
+ /// Err(SuperError { source: SuperErrorSideKick })
/// }
///
/// fn main() {
@@ -452,6 +455,8 @@
}
}
+impl Error for char::TryFromCharError {}
+
impl<'a, K: Debug + Ord, V: Debug> Error
for crate::collections::btree_map::OccupiedError<'a, K, V>
{
@@ -570,24 +575,24 @@
impl Error for alloc_crate::collections::TryReserveError {}
-impl Error for core::time::FromSecsError {}
+impl Error for time::FromFloatSecsError {}
// Copied from `any.rs`.
impl dyn Error + 'static {
- /// Returns `true` if the boxed type is the same as `T`
+ /// Returns `true` if the inner type is the same as `T`.
#[inline]
pub fn is<T: Error + 'static>(&self) -> bool {
// Get `TypeId` of the type this function is instantiated with.
let t = TypeId::of::<T>();
- // Get `TypeId` of the type in the trait object.
- let boxed = self.type_id(private::Internal);
+ // Get `TypeId` of the type in the trait object (`self`).
+ let concrete = self.type_id(private::Internal);
// Compare both `TypeId`s on equality.
- t == boxed
+ t == concrete
}
- /// Returns some reference to the boxed value if it is of type `T`, or
+ /// Returns some reference to the inner value if it is of type `T`, or
/// `None` if it isn't.
#[inline]
pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
@@ -598,7 +603,7 @@
}
}
- /// Returns some mutable reference to the boxed value if it is of type `T`, or
+ /// Returns some mutable reference to the inner value if it is of type `T`, or
/// `None` if it isn't.
#[inline]
pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
@@ -763,3 +768,637 @@
})
}
}
+
+/// An error reporter that print's an error and its sources.
+///
+/// Report also exposes configuration options for formatting the error chain, either entirely on a
+/// single line, or in multi-line format with each cause in the error chain on a new line.
+///
+/// `Report` only requires that the wrapped error implements `Error`. It doesn't require that the
+/// wrapped error be `Send`, `Sync`, or `'static`.
+///
+/// # Examples
+///
+/// ```rust
+/// #![feature(error_reporter)]
+/// use std::error::{Error, Report};
+/// use std::fmt;
+///
+/// #[derive(Debug)]
+/// struct SuperError {
+/// source: SuperErrorSideKick,
+/// }
+///
+/// impl fmt::Display for SuperError {
+/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+/// write!(f, "SuperError is here!")
+/// }
+/// }
+///
+/// impl Error for SuperError {
+/// fn source(&self) -> Option<&(dyn Error + 'static)> {
+/// Some(&self.source)
+/// }
+/// }
+///
+/// #[derive(Debug)]
+/// struct SuperErrorSideKick;
+///
+/// impl fmt::Display for SuperErrorSideKick {
+/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+/// write!(f, "SuperErrorSideKick is here!")
+/// }
+/// }
+///
+/// impl Error for SuperErrorSideKick {}
+///
+/// fn get_super_error() -> Result<(), SuperError> {
+/// Err(SuperError { source: SuperErrorSideKick })
+/// }
+///
+/// fn main() {
+/// match get_super_error() {
+/// Err(e) => println!("Error: {}", Report::new(e)),
+/// _ => println!("No error"),
+/// }
+/// }
+/// ```
+///
+/// This example produces the following output:
+///
+/// ```console
+/// Error: SuperError is here!: SuperErrorSideKick is here!
+/// ```
+///
+/// ## Output consistency
+///
+/// Report prints the same output via `Display` and `Debug`, so it works well with
+/// [`Result::unwrap`]/[`Result::expect`] which print their `Err` variant via `Debug`:
+///
+/// ```should_panic
+/// #![feature(error_reporter)]
+/// use std::error::Report;
+/// # use std::error::Error;
+/// # use std::fmt;
+/// # #[derive(Debug)]
+/// # struct SuperError {
+/// # source: SuperErrorSideKick,
+/// # }
+/// # impl fmt::Display for SuperError {
+/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+/// # write!(f, "SuperError is here!")
+/// # }
+/// # }
+/// # impl Error for SuperError {
+/// # fn source(&self) -> Option<&(dyn Error + 'static)> {
+/// # Some(&self.source)
+/// # }
+/// # }
+/// # #[derive(Debug)]
+/// # struct SuperErrorSideKick;
+/// # impl fmt::Display for SuperErrorSideKick {
+/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+/// # write!(f, "SuperErrorSideKick is here!")
+/// # }
+/// # }
+/// # impl Error for SuperErrorSideKick {}
+/// # fn get_super_error() -> Result<(), SuperError> {
+/// # Err(SuperError { source: SuperErrorSideKick })
+/// # }
+///
+/// get_super_error().map_err(Report::new).unwrap();
+/// ```
+///
+/// This example produces the following output:
+///
+/// ```console
+/// thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: SuperError is here!: SuperErrorSideKick is here!', src/error.rs:34:40
+/// note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+/// ```
+///
+/// ## Return from `main`
+///
+/// `Report` also implements `From` for all types that implement [`Error`], this when combined with
+/// the `Debug` output means `Report` is an ideal starting place for formatting errors returned
+/// from `main`.
+///
+/// ```should_panic
+/// #![feature(error_reporter)]
+/// use std::error::Report;
+/// # use std::error::Error;
+/// # use std::fmt;
+/// # #[derive(Debug)]
+/// # struct SuperError {
+/// # source: SuperErrorSideKick,
+/// # }
+/// # impl fmt::Display for SuperError {
+/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+/// # write!(f, "SuperError is here!")
+/// # }
+/// # }
+/// # impl Error for SuperError {
+/// # fn source(&self) -> Option<&(dyn Error + 'static)> {
+/// # Some(&self.source)
+/// # }
+/// # }
+/// # #[derive(Debug)]
+/// # struct SuperErrorSideKick;
+/// # impl fmt::Display for SuperErrorSideKick {
+/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+/// # write!(f, "SuperErrorSideKick is here!")
+/// # }
+/// # }
+/// # impl Error for SuperErrorSideKick {}
+/// # fn get_super_error() -> Result<(), SuperError> {
+/// # Err(SuperError { source: SuperErrorSideKick })
+/// # }
+///
+/// fn main() -> Result<(), Report> {
+/// get_super_error()?;
+/// Ok(())
+/// }
+/// ```
+///
+/// This example produces the following output:
+///
+/// ```console
+/// Error: SuperError is here!: SuperErrorSideKick is here!
+/// ```
+///
+/// **Note**: `Report`s constructed via `?` and `From` will be configured to use the single line
+/// output format, if you want to make sure your `Report`s are pretty printed and include backtrace
+/// you will need to manually convert and enable those flags.
+///
+/// ```should_panic
+/// #![feature(error_reporter)]
+/// use std::error::Report;
+/// # use std::error::Error;
+/// # use std::fmt;
+/// # #[derive(Debug)]
+/// # struct SuperError {
+/// # source: SuperErrorSideKick,
+/// # }
+/// # impl fmt::Display for SuperError {
+/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+/// # write!(f, "SuperError is here!")
+/// # }
+/// # }
+/// # impl Error for SuperError {
+/// # fn source(&self) -> Option<&(dyn Error + 'static)> {
+/// # Some(&self.source)
+/// # }
+/// # }
+/// # #[derive(Debug)]
+/// # struct SuperErrorSideKick;
+/// # impl fmt::Display for SuperErrorSideKick {
+/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+/// # write!(f, "SuperErrorSideKick is here!")
+/// # }
+/// # }
+/// # impl Error for SuperErrorSideKick {}
+/// # fn get_super_error() -> Result<(), SuperError> {
+/// # Err(SuperError { source: SuperErrorSideKick })
+/// # }
+///
+/// fn main() -> Result<(), Report> {
+/// get_super_error()
+/// .map_err(Report::from)
+/// .map_err(|r| r.pretty(true).show_backtrace(true))?;
+/// Ok(())
+/// }
+/// ```
+///
+/// This example produces the following output:
+///
+/// ```console
+/// Error: SuperError is here!
+///
+/// Caused by:
+/// SuperErrorSideKick is here!
+/// ```
+#[cfg(feature = "backtrace")]
+pub struct Report<E = Box<dyn Error>> {
+ /// The error being reported.
+ error: E,
+ /// Whether a backtrace should be included as part of the report.
+ show_backtrace: bool,
+ /// Whether the report should be pretty-printed.
+ pretty: bool,
+}
+
+#[cfg(feature = "backtrace")]
+impl<E> Report<E>
+where
+ Report<E>: From<E>,
+{
+ /// Create a new `Report` from an input error.
+ pub fn new(error: E) -> Report<E> {
+ Self::from(error)
+ }
+}
+
+#[cfg(feature = "backtrace")]
+impl<E> Report<E> {
+ /// Enable pretty-printing the report across multiple lines.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// #![feature(error_reporter)]
+ /// use std::error::Report;
+ /// # use std::error::Error;
+ /// # use std::fmt;
+ /// # #[derive(Debug)]
+ /// # struct SuperError {
+ /// # source: SuperErrorSideKick,
+ /// # }
+ /// # impl fmt::Display for SuperError {
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// # write!(f, "SuperError is here!")
+ /// # }
+ /// # }
+ /// # impl Error for SuperError {
+ /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
+ /// # Some(&self.source)
+ /// # }
+ /// # }
+ /// # #[derive(Debug)]
+ /// # struct SuperErrorSideKick;
+ /// # impl fmt::Display for SuperErrorSideKick {
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// # write!(f, "SuperErrorSideKick is here!")
+ /// # }
+ /// # }
+ /// # impl Error for SuperErrorSideKick {}
+ ///
+ /// let error = SuperError { source: SuperErrorSideKick };
+ /// let report = Report::new(error).pretty(true);
+ /// eprintln!("Error: {:?}", report);
+ /// ```
+ ///
+ /// This example produces the following output:
+ ///
+ /// ```console
+ /// Error: SuperError is here!
+ ///
+ /// Caused by:
+ /// SuperErrorSideKick is here!
+ /// ```
+ ///
+ /// When there are multiple source errors the causes will be numbered in order of iteration
+ /// starting from the outermost error.
+ ///
+ /// ```rust
+ /// #![feature(error_reporter)]
+ /// use std::error::Report;
+ /// # use std::error::Error;
+ /// # use std::fmt;
+ /// # #[derive(Debug)]
+ /// # struct SuperError {
+ /// # source: SuperErrorSideKick,
+ /// # }
+ /// # impl fmt::Display for SuperError {
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// # write!(f, "SuperError is here!")
+ /// # }
+ /// # }
+ /// # impl Error for SuperError {
+ /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
+ /// # Some(&self.source)
+ /// # }
+ /// # }
+ /// # #[derive(Debug)]
+ /// # struct SuperErrorSideKick {
+ /// # source: SuperErrorSideKickSideKick,
+ /// # }
+ /// # impl fmt::Display for SuperErrorSideKick {
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// # write!(f, "SuperErrorSideKick is here!")
+ /// # }
+ /// # }
+ /// # impl Error for SuperErrorSideKick {
+ /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
+ /// # Some(&self.source)
+ /// # }
+ /// # }
+ /// # #[derive(Debug)]
+ /// # struct SuperErrorSideKickSideKick;
+ /// # impl fmt::Display for SuperErrorSideKickSideKick {
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// # write!(f, "SuperErrorSideKickSideKick is here!")
+ /// # }
+ /// # }
+ /// # impl Error for SuperErrorSideKickSideKick { }
+ ///
+ /// let source = SuperErrorSideKickSideKick;
+ /// let source = SuperErrorSideKick { source };
+ /// let error = SuperError { source };
+ /// let report = Report::new(error).pretty(true);
+ /// eprintln!("Error: {:?}", report);
+ /// ```
+ ///
+ /// This example produces the following output:
+ ///
+ /// ```console
+ /// Error: SuperError is here!
+ ///
+ /// Caused by:
+ /// 0: SuperErrorSideKick is here!
+ /// 1: SuperErrorSideKickSideKick is here!
+ /// ```
+ pub fn pretty(mut self, pretty: bool) -> Self {
+ self.pretty = pretty;
+ self
+ }
+
+ /// Display backtrace if available when using pretty output format.
+ ///
+ /// # Examples
+ ///
+ /// **Note**: Report will search for the first `Backtrace` it can find starting from the
+ /// outermost error. In this example it will display the backtrace from the second error in the
+ /// chain, `SuperErrorSideKick`.
+ ///
+ /// ```rust
+ /// #![feature(error_reporter)]
+ /// #![feature(backtrace)]
+ /// # use std::error::Error;
+ /// # use std::fmt;
+ /// use std::error::Report;
+ /// use std::backtrace::Backtrace;
+ ///
+ /// # #[derive(Debug)]
+ /// # struct SuperError {
+ /// # source: SuperErrorSideKick,
+ /// # }
+ /// # impl fmt::Display for SuperError {
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// # write!(f, "SuperError is here!")
+ /// # }
+ /// # }
+ /// # impl Error for SuperError {
+ /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
+ /// # Some(&self.source)
+ /// # }
+ /// # }
+ /// #[derive(Debug)]
+ /// struct SuperErrorSideKick {
+ /// backtrace: Backtrace,
+ /// }
+ ///
+ /// impl SuperErrorSideKick {
+ /// fn new() -> SuperErrorSideKick {
+ /// SuperErrorSideKick { backtrace: Backtrace::force_capture() }
+ /// }
+ /// }
+ ///
+ /// impl Error for SuperErrorSideKick {
+ /// fn backtrace(&self) -> Option<&Backtrace> {
+ /// Some(&self.backtrace)
+ /// }
+ /// }
+ ///
+ /// // The rest of the example is unchanged ...
+ /// # impl fmt::Display for SuperErrorSideKick {
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// # write!(f, "SuperErrorSideKick is here!")
+ /// # }
+ /// # }
+ ///
+ /// let source = SuperErrorSideKick::new();
+ /// let error = SuperError { source };
+ /// let report = Report::new(error).pretty(true).show_backtrace(true);
+ /// eprintln!("Error: {:?}", report);
+ /// ```
+ ///
+ /// This example produces something similar to the following output:
+ ///
+ /// ```console
+ /// Error: SuperError is here!
+ ///
+ /// Caused by:
+ /// SuperErrorSideKick is here!
+ ///
+ /// Stack backtrace:
+ /// 0: rust_out::main::_doctest_main_src_error_rs_1158_0::SuperErrorSideKick::new
+ /// 1: rust_out::main::_doctest_main_src_error_rs_1158_0
+ /// 2: rust_out::main
+ /// 3: core::ops::function::FnOnce::call_once
+ /// 4: std::sys_common::backtrace::__rust_begin_short_backtrace
+ /// 5: std::rt::lang_start::{{closure}}
+ /// 6: std::panicking::try
+ /// 7: std::rt::lang_start_internal
+ /// 8: std::rt::lang_start
+ /// 9: main
+ /// 10: __libc_start_main
+ /// 11: _start
+ /// ```
+ pub fn show_backtrace(mut self, show_backtrace: bool) -> Self {
+ self.show_backtrace = show_backtrace;
+ self
+ }
+}
+
+#[cfg(feature = "backtrace")]
+impl<E> Report<E>
+where
+ E: Error,
+{
+ fn backtrace(&self) -> Option<&Backtrace> {
+ // have to grab the backtrace on the first error directly since that error may not be
+ // 'static
+ let backtrace = self.error.backtrace();
+ backtrace.or_else(|| {
+ self.error
+ .source()
+ .and_then(|source| source.chain().find_map(|source| source.backtrace()))
+ })
+ }
+
+ /// Format the report as a single line.
+ fn fmt_singleline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", self.error)?;
+
+ let sources = self.error.source().into_iter().flat_map(<dyn Error>::chain);
+
+ for cause in sources {
+ write!(f, ": {}", cause)?;
+ }
+
+ Ok(())
+ }
+
+ /// Format the report as multiple lines, with each error cause on its own line.
+ fn fmt_multiline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let error = &self.error;
+
+ write!(f, "{}", error)?;
+
+ if let Some(cause) = error.source() {
+ write!(f, "\n\nCaused by:")?;
+
+ let multiple = cause.source().is_some();
+
+ for (ind, error) in cause.chain().enumerate() {
+ writeln!(f)?;
+ let mut indented = Indented { inner: f };
+ if multiple {
+ write!(indented, "{: >4}: {}", ind, error)?;
+ } else {
+ write!(indented, " {}", error)?;
+ }
+ }
+ }
+
+ if self.show_backtrace {
+ let backtrace = self.backtrace();
+
+ if let Some(backtrace) = backtrace {
+ let backtrace = backtrace.to_string();
+
+ f.write_str("\n\nStack backtrace:\n")?;
+ f.write_str(backtrace.trim_end())?;
+ }
+ }
+
+ Ok(())
+ }
+}
+
+#[cfg(feature = "backtrace")]
+impl Report<Box<dyn Error>> {
+ fn backtrace(&self) -> Option<&Backtrace> {
+ // have to grab the backtrace on the first error directly since that error may not be
+ // 'static
+ let backtrace = self.error.backtrace();
+ backtrace.or_else(|| {
+ self.error
+ .source()
+ .and_then(|source| source.chain().find_map(|source| source.backtrace()))
+ })
+ }
+
+ /// Format the report as a single line.
+ fn fmt_singleline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", self.error)?;
+
+ let sources = self.error.source().into_iter().flat_map(<dyn Error>::chain);
+
+ for cause in sources {
+ write!(f, ": {}", cause)?;
+ }
+
+ Ok(())
+ }
+
+ /// Format the report as multiple lines, with each error cause on its own line.
+ fn fmt_multiline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let error = &self.error;
+
+ write!(f, "{}", error)?;
+
+ if let Some(cause) = error.source() {
+ write!(f, "\n\nCaused by:")?;
+
+ let multiple = cause.source().is_some();
+
+ for (ind, error) in cause.chain().enumerate() {
+ writeln!(f)?;
+ let mut indented = Indented { inner: f };
+ if multiple {
+ write!(indented, "{: >4}: {}", ind, error)?;
+ } else {
+ write!(indented, " {}", error)?;
+ }
+ }
+ }
+
+ if self.show_backtrace {
+ let backtrace = self.backtrace();
+
+ if let Some(backtrace) = backtrace {
+ let backtrace = backtrace.to_string();
+
+ f.write_str("\n\nStack backtrace:\n")?;
+ f.write_str(backtrace.trim_end())?;
+ }
+ }
+
+ Ok(())
+ }
+}
+
+#[cfg(feature = "backtrace")]
+impl<E> From<E> for Report<E>
+where
+ E: Error,
+{
+ fn from(error: E) -> Self {
+ Report { error, show_backtrace: false, pretty: false }
+ }
+}
+
+#[cfg(feature = "backtrace")]
+impl<'a, E> From<E> for Report<Box<dyn Error + 'a>>
+where
+ E: Error + 'a,
+{
+ fn from(error: E) -> Self {
+ let error = box error;
+ Report { error, show_backtrace: false, pretty: false }
+ }
+}
+
+#[cfg(feature = "backtrace")]
+impl<E> fmt::Display for Report<E>
+where
+ E: Error,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ if self.pretty { self.fmt_multiline(f) } else { self.fmt_singleline(f) }
+ }
+}
+
+#[cfg(feature = "backtrace")]
+impl fmt::Display for Report<Box<dyn Error>> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ if self.pretty { self.fmt_multiline(f) } else { self.fmt_singleline(f) }
+ }
+}
+
+// This type intentionally outputs the same format for `Display` and `Debug`for
+// situations where you unwrap a `Report` or return it from main.
+#[cfg(feature = "backtrace")]
+impl<E> fmt::Debug for Report<E>
+where
+ Report<E>: fmt::Display,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Display::fmt(self, f)
+ }
+}
+
+/// Wrapper type for indenting the inner source.
+#[cfg(feature = "backtrace")]
+struct Indented<'a, D> {
+ inner: &'a mut D,
+}
+
+#[cfg(feature = "backtrace")]
+impl<T> Write for Indented<'_, T>
+where
+ T: Write,
+{
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ for (i, line) in s.split('\n').enumerate() {
+ if i > 0 {
+ self.inner.write_char('\n')?;
+ self.inner.write_str(" ")?;
+ }
+
+ self.inner.write_str(line)?;
+ }
+
+ Ok(())
+ }
+}
diff --git a/sgx_tstd/src/ffi/c_str.rs b/sgx_tstd/src/ffi/c_str.rs
index 1e542ce..6ecdabd 100644
--- a/sgx_tstd/src/ffi/c_str.rs
+++ b/sgx_tstd/src/ffi/c_str.rs
@@ -30,7 +30,7 @@
impl From<NulError> for io::Error {
/// Converts a [`NulError`] into a [`io::Error`].
fn from(_: NulError) -> io::Error {
- io::Error::new_const(io::ErrorKind::InvalidInput, &"data provided contains a nul byte")
+ io::const_io_error!(io::ErrorKind::InvalidInput, "data provided contains a nul byte")
}
}
diff --git a/sgx_tstd/src/ffi/mod.rs b/sgx_tstd/src/ffi/mod.rs
index b93c5f4..1c6152a 100644
--- a/sgx_tstd/src/ffi/mod.rs
+++ b/sgx_tstd/src/ffi/mod.rs
@@ -98,9 +98,9 @@
//! [`OsStr`] and Rust strings work similarly to those for [`CString`]
//! and [`CStr`].
//!
-//! * [`OsString`] represents an owned string in whatever
-//! representation the operating system prefers. In the Rust standard
-//! library, various APIs that transfer strings to/from the operating
+//! * [`OsString`] losslessly represents an owned platform string. However, this
+//! representation is not necessarily in a form native to the platform.
+//! In the Rust standard library, various APIs that transfer strings to/from the operating
//! system use [`OsString`] instead of plain strings. For example,
//! [`env::var_os()`] is used to query environment variables; it
//! returns an <code>[Option]<[OsString]></code>. If the environment variable
@@ -109,9 +109,9 @@
//! your code can detect errors in case the environment variable did
//! not in fact contain valid Unicode data.
//!
-//! * [`OsStr`] represents a borrowed reference to a string in a
-//! format that can be passed to the operating system. It can be
-//! converted into a UTF-8 Rust string slice in a similar way to
+//! * [`OsStr`] losslessly represents a borrowed reference to a platform string.
+//! However, this representation is not necessarily in a form native to the platform.
+//! It can be converted into a UTF-8 Rust string slice in a similar way to
//! [`OsString`].
//!
//! # Conversions
@@ -130,16 +130,19 @@
//!
//! ## On Windows
//!
+//! An [`OsStr`] can be losslessly converted to a native Windows string. And
+//! a native Windows string can be losslessly converted to an [`OsString`].
+//!
//! On Windows, [`OsStr`] implements the
//! <code>std::os::windows::ffi::[OsStrExt][windows.OsStrExt]</code> trait,
//! which provides an [`encode_wide`] method. This provides an
-//! iterator that can be [`collect`]ed into a vector of [`u16`].
+//! iterator that can be [`collect`]ed into a vector of [`u16`]. After a nul
+//! characters is appended, this is the same as a native Windows string.
//!
//! Additionally, on Windows [`OsString`] implements the
//! <code>std::os::windows:ffi::[OsStringExt][windows.OsStringExt]</code>
-//! trait, which provides a [`from_wide`] method. The result of this
-//! method is an [`OsString`] which can be round-tripped to a Windows
-//! string losslessly.
+//! trait, which provides a [`from_wide`] method to convert a native Windows
+//! string (without the terminating nul character) to an [`OsString`].
//!
//! [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value
//! [Unicode code point]: https://www.unicode.org/glossary/#code_point
diff --git a/sgx_tstd/src/ffi/os_str.rs b/sgx_tstd/src/ffi/os_str.rs
index e11c6aa..8dc3d03 100644
--- a/sgx_tstd/src/ffi/os_str.rs
+++ b/sgx_tstd/src/ffi/os_str.rs
@@ -19,6 +19,7 @@
use crate::borrow::{Borrow, Cow};
use crate::cmp;
+use crate::collections::TryReserveError;
use crate::fmt;
use crate::hash::{Hash, Hasher};
use crate::iter::{Extend, FromIterator};
@@ -269,6 +270,42 @@
self.inner.reserve(additional)
}
+ /// Tries to reserve capacity for at least `additional` more length units
+ /// in the given `OsString`. The string may reserve more space to avoid
+ /// frequent reallocations. After calling `try_reserve`, capacity will be
+ /// greater than or equal to `self.len() + additional`. Does nothing if
+ /// capacity is already sufficient.
+ ///
+ /// # Errors
+ ///
+ /// If the capacity overflows, or the allocator reports a failure, then an error
+ /// is returned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(try_reserve_2)]
+ /// use std::ffi::{OsStr, OsString};
+ /// use std::collections::TryReserveError;
+ ///
+ /// fn process_data(data: &str) -> Result<OsString, TryReserveError> {
+ /// let mut s = OsString::new();
+ ///
+ /// // Pre-reserve the memory, exiting if we can't
+ /// s.try_reserve(OsStr::new(data).len())?;
+ ///
+ /// // Now we know this can't OOM in the middle of our complex work
+ /// s.push(data);
+ ///
+ /// Ok(s)
+ /// }
+ /// # process_data("123").expect("why is the test harness OOMing on 3 bytes?");
+ /// ```
+ #[inline]
+ pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
+ self.inner.try_reserve(additional)
+ }
+
/// Reserves the minimum capacity for exactly `additional` more capacity to
/// be inserted in the given `OsString`. Does nothing if the capacity is
/// already sufficient.
@@ -293,6 +330,48 @@
self.inner.reserve_exact(additional)
}
+ /// Tries to reserve the minimum capacity for exactly `additional`
+ /// more length units in the given `OsString`. After calling
+ /// `try_reserve_exact`, capacity will be greater than or equal to
+ /// `self.len() + additional` if it returns `Ok(())`.
+ /// Does nothing if the capacity is already sufficient.
+ ///
+ /// Note that the allocator may give the `OsString` more space than it
+ /// requests. Therefore, capacity can not be relied upon to be precisely
+ /// minimal. Prefer [`try_reserve`] if future insertions are expected.
+ ///
+ /// [`try_reserve`]: OsString::try_reserve
+ ///
+ /// # Errors
+ ///
+ /// If the capacity overflows, or the allocator reports a failure, then an error
+ /// is returned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(try_reserve_2)]
+ /// use std::ffi::{OsStr, OsString};
+ /// use std::collections::TryReserveError;
+ ///
+ /// fn process_data(data: &str) -> Result<OsString, TryReserveError> {
+ /// let mut s = OsString::new();
+ ///
+ /// // Pre-reserve the memory, exiting if we can't
+ /// s.try_reserve_exact(OsStr::new(data).len())?;
+ ///
+ /// // Now we know this can't OOM in the middle of our complex work
+ /// s.push(data);
+ ///
+ /// Ok(s)
+ /// }
+ /// # process_data("123").expect("why is the test harness OOMing on 3 bytes?");
+ /// ```
+ #[inline]
+ pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
+ self.inner.try_reserve_exact(additional)
+ }
+
/// Shrinks the capacity of the `OsString` to match its length.
///
/// # Examples
@@ -369,6 +448,8 @@
}
impl<T: ?Sized + AsRef<OsStr>> From<&T> for OsString {
+ /// Copies any value implementing <code>[AsRef]<[OsStr]></code>
+ /// into a newly allocated [`OsString`].
fn from(s: &T) -> OsString {
s.as_ref().to_os_string()
}
@@ -828,6 +909,7 @@
}
impl From<&OsStr> for Box<OsStr> {
+ /// Copies the string into a newly allocated <code>[Box]<[OsStr]></code>.
#[inline]
fn from(s: &OsStr) -> Box<OsStr> {
let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr;
@@ -836,6 +918,8 @@
}
impl From<Cow<'_, OsStr>> for Box<OsStr> {
+ /// Converts a `Cow<'a, OsStr>` into a <code>[Box]<[OsStr]></code>,
+ /// by copying the contents if they are borrowed.
#[inline]
fn from(cow: Cow<'_, OsStr>) -> Box<OsStr> {
match cow {
@@ -870,7 +954,8 @@
}
impl From<OsString> for Arc<OsStr> {
- /// Converts an [`OsString`] into an <code>[Arc]<[OsStr]></code> without copying or allocating.
+ /// Converts an [`OsString`] into an <code>[Arc]<[OsStr]></code> by moving the [`OsString`]
+ /// data into a new [`Arc`] buffer.
#[inline]
fn from(s: OsString) -> Arc<OsStr> {
let arc = s.inner.into_arc();
@@ -879,6 +964,7 @@
}
impl From<&OsStr> for Arc<OsStr> {
+ /// Copies the string into a newly allocated <code>[Arc]<[OsStr]></code>.
#[inline]
fn from(s: &OsStr) -> Arc<OsStr> {
let arc = s.inner.into_arc();
@@ -887,7 +973,8 @@
}
impl From<OsString> for Rc<OsStr> {
- /// Converts an [`OsString`] into an <code>[Rc]<[OsStr]></code> without copying or allocating.
+ /// Converts an [`OsString`] into an <code>[Rc]<[OsStr]></code> by moving the [`OsString`]
+ /// data into a new [`Rc`] buffer.
#[inline]
fn from(s: OsString) -> Rc<OsStr> {
let rc = s.inner.into_rc();
@@ -896,6 +983,7 @@
}
impl From<&OsStr> for Rc<OsStr> {
+ /// Copies the string into a newly allocated <code>[Rc]<[OsStr]></code>.
#[inline]
fn from(s: &OsStr) -> Rc<OsStr> {
let rc = s.inner.into_rc();
@@ -904,6 +992,7 @@
}
impl<'a> From<OsString> for Cow<'a, OsStr> {
+ /// Moves the string into a [`Cow::Owned`].
#[inline]
fn from(s: OsString) -> Cow<'a, OsStr> {
Cow::Owned(s)
@@ -911,6 +1000,7 @@
}
impl<'a> From<&'a OsStr> for Cow<'a, OsStr> {
+ /// Converts the string reference into a [`Cow::Borrowed`].
#[inline]
fn from(s: &'a OsStr) -> Cow<'a, OsStr> {
Cow::Borrowed(s)
@@ -918,6 +1008,7 @@
}
impl<'a> From<&'a OsString> for Cow<'a, OsStr> {
+ /// Converts the string reference into a [`Cow::Borrowed`].
#[inline]
fn from(s: &'a OsString) -> Cow<'a, OsStr> {
Cow::Borrowed(s.as_os_str())
@@ -925,6 +1016,8 @@
}
impl<'a> From<Cow<'a, OsStr>> for OsString {
+ /// Converts a `Cow<'a, OsStr>` into an [`OsString`],
+ /// by copying the contents if they are borrowed.
#[inline]
fn from(s: Cow<'a, OsStr>) -> Self {
s.into_owned()
diff --git a/sgx_tstd/src/fs.rs b/sgx_tstd/src/fs.rs
index 1f467fc..cbac797 100644
--- a/sgx_tstd/src/fs.rs
+++ b/sgx_tstd/src/fs.rs
@@ -20,7 +20,7 @@
#![deny(unsafe_op_in_unsafe_fn)]
use crate::ffi::OsString;
use crate::fmt;
-use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
+use crate::io::{self, IoSlice, IoSliceMut, Read, ReadBuf, Seek, SeekFrom, Write};
use crate::path::{Path, PathBuf};
use crate::sys::fs as fs_imp;
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
@@ -96,6 +96,7 @@
///
/// [`BufReader<R>`]: io::BufReader
/// [`sync_all`]: File::sync_all
+#[cfg_attr(not(test), rustc_diagnostic_item = "File")]
pub struct File {
inner: fs_imp::File,
}
@@ -351,9 +352,10 @@
/// open or create a file with specific options if `open()` or `create()`
/// are not appropriate.
///
- /// It is equivalent to `OpenOptions::new()` but allows you to write more
- /// readable code. Instead of `OpenOptions::new().read(true).open("foo.txt")`
- /// you can write `File::with_options().read(true).open("foo.txt")`. This
+ /// It is equivalent to `OpenOptions::new()`, but allows you to write more
+ /// readable code. Instead of
+ /// `OpenOptions::new().append(true).open("example.log")`,
+ /// you can write `File::options().append(true).open("example.log")`. This
/// also avoids the need to import `OpenOptions`.
///
/// See the [`OpenOptions::new`] function for more details.
@@ -361,16 +363,15 @@
/// # Examples
///
/// ```no_run
- /// #![feature(with_options)]
/// use std::fs::File;
///
/// fn main() -> std::io::Result<()> {
- /// let mut f = File::with_options().read(true).open("foo.txt")?;
+ /// let mut f = File::options().append(true).open("example.log")?;
/// Ok(())
/// }
/// ```
#[must_use]
- pub fn with_options() -> OpenOptions {
+ pub fn options() -> OpenOptions {
OpenOptions::new()
}
@@ -610,15 +611,13 @@
self.inner.read_vectored(bufs)
}
- #[inline]
- fn is_read_vectored(&self) -> bool {
- self.inner.is_read_vectored()
+ fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ self.inner.read_buf(buf)
}
#[inline]
- unsafe fn initializer(&self) -> Initializer {
- // SAFETY: Read is guaranteed to work on uninitialized memory
- unsafe { Initializer::nop() }
+ fn is_read_vectored(&self) -> bool {
+ self.inner.is_read_vectored()
}
// Reserves space in the buffer based on the file size when available.
@@ -663,6 +662,10 @@
self.inner.read(buf)
}
+ fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ self.inner.read_buf(buf)
+ }
+
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
self.inner.read_vectored(bufs)
}
@@ -672,12 +675,6 @@
self.inner.is_read_vectored()
}
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- // SAFETY: Read is guaranteed to work on uninitialized memory
- unsafe { Initializer::nop() }
- }
-
// Reserves space in the buffer based on the file size when available.
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
buf.reserve(buffer_capacity_required(self));
@@ -1021,14 +1018,13 @@
///
#[cfg_attr(unix, doc = "```no_run")]
#[cfg_attr(not(unix), doc = "```ignore")]
- /// #![feature(is_symlink)]
/// use std::fs;
/// use std::path::Path;
/// use std::os::unix::fs::symlink;
///
/// fn main() -> std::io::Result<()> {
/// let link_path = Path::new("link");
- /// symlink("/origin_does_not_exists/", link_path)?;
+ /// symlink("/origin_does_not_exist/", link_path)?;
///
/// let metadata = fs::symlink_metadata(link_path)?;
///
@@ -1985,13 +1981,17 @@
///
/// # Platform-specific behavior
///
-/// This function currently corresponds to `opendir`, `lstat`, `rm` and `rmdir` functions on Unix
-/// and the `FindFirstFile`, `GetFileAttributesEx`, `DeleteFile`, and `RemoveDirectory` functions
-/// on Windows.
-/// Note that, this [may change in the future][changes].
+/// This function currently corresponds to `openat`, `fdopendir`, `unlinkat` and `lstat` functions
+/// on Unix (except for macOS before version 10.10 and REDOX) and the `CreateFileW`,
+/// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtCreateFile` functions on
+/// Windows. Note that, this [may change in the future][changes].
///
/// [changes]: io#platform-specific-behavior
///
+/// On macOS before version 10.10 and REDOX this function is not protected against time-of-check to
+/// time-of-use (TOCTOU) race conditions, and should not be used in security-sensitive code on
+/// those platforms. All other platforms are protected.
+///
/// # Errors
///
/// See [`fs::remove_file`] and [`fs::remove_dir`].
@@ -2009,7 +2009,6 @@
/// Ok(())
/// }
/// ```
-#[doc(alias = "delete")]
pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
fs_imp::remove_dir_all(path.as_ref())
}
@@ -2197,9 +2196,9 @@
match path.parent() {
Some(p) => self.create_dir_all(p)?,
None => {
- return Err(io::Error::new_const(
+ return Err(io::const_io_error!(
io::ErrorKind::Uncategorized,
- &"failed to create whole tree",
+ "failed to create whole tree",
));
}
}
@@ -2222,7 +2221,7 @@
/// This function will traverse symbolic links to query information about the
/// destination file. In case of broken symbolic links this will return `Ok(false)`.
///
-/// As opposed to the `exists()` method, this one doesn't silently ignore errors
+/// As opposed to the [`Path::exists`] method, this one doesn't silently ignore errors
/// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission
/// denied on some of the parent directories.)
///
@@ -2235,6 +2234,8 @@
/// assert!(!fs::try_exists("does_not_exist.txt").expect("Can't check existence of file does_not_exist.txt"));
/// assert!(fs::try_exists("/root/secret_file.txt").is_err());
/// ```
+///
+/// [`Path::exists`]: crate::path::Path::exists
// FIXME: stabilization should modify documentation of `exists()` to recommend this method
// instead.
#[inline]
diff --git a/sgx_tstd/src/io/buffered/bufreader.rs b/sgx_tstd/src/io/buffered/bufreader.rs
index 1f0e5fb..cd0795f 100644
--- a/sgx_tstd/src/io/buffered/bufreader.rs
+++ b/sgx_tstd/src/io/buffered/bufreader.rs
@@ -18,8 +18,9 @@
use crate::cmp;
use crate::fmt;
use crate::io::{
- self, BufRead, Initializer, IoSliceMut, Read, Seek, SeekFrom, SizeHint, DEFAULT_BUF_SIZE,
+ self, BufRead, IoSliceMut, Read, ReadBuf, Seek, SeekFrom, SizeHint, DEFAULT_BUF_SIZE,
};
+use crate::mem::MaybeUninit;
/// The `BufReader<R>` struct adds buffering to any reader.
///
@@ -63,9 +64,10 @@
/// ```
pub struct BufReader<R> {
inner: R,
- buf: Box<[u8]>,
+ buf: Box<[MaybeUninit<u8>]>,
pos: usize,
cap: usize,
+ init: usize,
}
impl<R: Read> BufReader<R> {
@@ -105,11 +107,8 @@
/// }
/// ```
pub fn with_capacity(capacity: usize, inner: R) -> BufReader<R> {
- unsafe {
- let mut buf = Box::new_uninit_slice(capacity).assume_init();
- inner.initializer().initialize(&mut buf);
- BufReader { inner, buf, pos: 0, cap: 0 }
- }
+ let buf = Box::new_uninit_slice(capacity);
+ BufReader { inner, buf, pos: 0, cap: 0, init: 0 }
}
}
@@ -182,7 +181,8 @@
/// }
/// ```
pub fn buffer(&self) -> &[u8] {
- &self.buf[self.pos..self.cap]
+ // SAFETY: self.cap is always <= self.init, so self.buf[self.pos..self.cap] is always init
+ unsafe { MaybeUninit::slice_assume_init_ref(&self.buf[self.pos..self.cap]) }
}
/// Returns the number of bytes the internal buffer can hold at once.
@@ -243,6 +243,7 @@
/// the buffer will not be flushed, allowing for more efficient seeks.
/// This method does not return the location of the underlying reader, so the caller
/// must track this information themselves if it is required.
+ #[allow(clippy::collapsible_else_if)]
pub fn seek_relative(&mut self, offset: i64) -> io::Result<()> {
let pos = self.pos as u64;
if offset < 0 {
@@ -278,6 +279,25 @@
Ok(nread)
}
+ fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ // If we don't have any buffered data and we're doing a massive read
+ // (larger than our internal buffer), bypass our internal buffer
+ // entirely.
+ if self.pos == self.cap && buf.remaining() >= self.buf.len() {
+ self.discard_buffer();
+ return self.inner.read_buf(buf);
+ }
+
+ let prev = buf.filled_len();
+
+ let mut rem = self.fill_buf()?;
+ rem.read_buf(buf)?;
+
+ self.consume(buf.filled_len() - prev); //slice impl of read_buf known to never unfill buf
+
+ Ok(())
+ }
+
// Small read_exacts from a BufReader are extremely common when used with a deserializer.
// The default implementation calls read in a loop, which results in surprisingly poor code
// generation for the common path where the buffer has enough bytes to fill the passed-in
@@ -310,16 +330,11 @@
self.inner.is_read_vectored()
}
- // we can't skip unconditionally because of the large buffer case in read.
- unsafe fn initializer(&self) -> Initializer {
- self.inner.initializer()
- }
-
// The inner reader might have an optimized `read_to_end`. Drain our buffer and then
// delegate to the inner implementation.
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
let nread = self.cap - self.pos;
- buf.extend_from_slice(&self.buf[self.pos..self.cap]);
+ buf.extend_from_slice(self.buffer());
self.discard_buffer();
Ok(nread + self.inner.read_to_end(buf)?)
}
@@ -350,9 +365,9 @@
let mut bytes = Vec::new();
self.read_to_end(&mut bytes)?;
let string = crate::str::from_utf8(&bytes).map_err(|_| {
- io::Error::new_const(
+ io::const_io_error!(
io::ErrorKind::InvalidData,
- &"stream did not contain valid UTF-8",
+ "stream did not contain valid UTF-8",
)
})?;
*buf += string;
@@ -369,10 +384,23 @@
// to tell the compiler that the pos..cap slice is always valid.
if self.pos >= self.cap {
debug_assert!(self.pos == self.cap);
- self.cap = self.inner.read(&mut self.buf)?;
+
+ let mut readbuf = ReadBuf::uninit(&mut self.buf);
+
+ // SAFETY: `self.init` is either 0 or set to `readbuf.initialized_len()`
+ // from the last time this function was called
+ unsafe {
+ readbuf.assume_init(self.init);
+ }
+
+ self.inner.read_buf(&mut readbuf)?;
+
+ self.cap = readbuf.filled_len();
+ self.init = readbuf.initialized_len();
+
self.pos = 0;
}
- Ok(&self.buf[self.pos..self.cap])
+ Ok(self.buffer())
}
fn consume(&mut self, amt: usize) {
diff --git a/sgx_tstd/src/io/buffered/bufwriter.rs b/sgx_tstd/src/io/buffered/bufwriter.rs
index c9805f8..3897735 100644
--- a/sgx_tstd/src/io/buffered/bufwriter.rs
+++ b/sgx_tstd/src/io/buffered/bufwriter.rs
@@ -18,7 +18,7 @@
use crate::error;
use crate::fmt;
use crate::io::{
- self, Error, ErrorKind, IntoInnerError, IoSlice, Seek, SeekFrom, Write, DEFAULT_BUF_SIZE,
+ self, ErrorKind, IntoInnerError, IoSlice, Seek, SeekFrom, Write, DEFAULT_BUF_SIZE,
};
use crate::mem;
use crate::ptr;
@@ -182,9 +182,9 @@
match r {
Ok(0) => {
- return Err(Error::new_const(
+ return Err(io::const_io_error!(
ErrorKind::WriteZero,
- &"failed to write the buffered data",
+ "failed to write the buffered data",
));
}
Ok(n) => guard.consume(n),
diff --git a/sgx_tstd/src/io/buffered/mod.rs b/sgx_tstd/src/io/buffered/mod.rs
index c01cb1c..f854b53 100644
--- a/sgx_tstd/src/io/buffered/mod.rs
+++ b/sgx_tstd/src/io/buffered/mod.rs
@@ -26,12 +26,11 @@
use crate::fmt;
use crate::io::Error;
-pub use bufreader::BufReader;
-pub use bufwriter::BufWriter;
-pub use bufwriter::WriterPanicked;
-pub use linewriter::LineWriter;
+pub use self::{bufreader::BufReader, bufwriter::BufWriter, linewriter::LineWriter};
use linewritershim::LineWriterShim;
+pub use bufwriter::WriterPanicked;
+
/// An error returned by [`BufWriter::into_inner`] which combines an error that
/// happened while writing out the buffer, and the buffered writer object
/// which may be used to recover from the condition.
diff --git a/sgx_tstd/src/io/copy.rs b/sgx_tstd/src/io/copy.rs
index f3f0a93..b5aa5f4 100644
--- a/sgx_tstd/src/io/copy.rs
+++ b/sgx_tstd/src/io/copy.rs
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License..
-use super::{BufWriter, ErrorKind, Read, Result, Write, DEFAULT_BUF_SIZE};
+use super::{BufWriter, ErrorKind, Read, ReadBuf, Result, Write, DEFAULT_BUF_SIZE};
use crate::mem::MaybeUninit;
/// Copies the entire contents of a reader into a writer.
@@ -61,6 +61,16 @@
R: Read,
W: Write,
{
+ generic_copy(reader, writer)
+}
+
+/// The userspace read-write-loop implementation of `io::copy` that is used when
+/// OS-specific specializations for copy offloading are not available or not applicable.
+pub(crate) fn generic_copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> Result<u64>
+where
+ R: Read,
+ W: Write,
+{
BufferedCopySpec::copy_to(reader, writer)
}
@@ -82,33 +92,30 @@
return stack_buffer_copy(reader, writer);
}
- // FIXME: #42788
- //
- // - This creates a (mut) reference to a slice of
- // _uninitialized_ integers, which is **undefined behavior**
- //
- // - Only the standard library gets to soundly "ignore" this,
- // based on its privileged knowledge of unstable rustc
- // internals;
- unsafe {
- let spare_cap = writer.buffer_mut().spare_capacity_mut();
- reader.initializer().initialize(MaybeUninit::slice_assume_init_mut(spare_cap));
- }
-
let mut len = 0;
+ let mut init = 0;
loop {
let buf = writer.buffer_mut();
- let spare_cap = buf.spare_capacity_mut();
+ let mut read_buf = ReadBuf::uninit(buf.spare_capacity_mut());
- if spare_cap.len() >= DEFAULT_BUF_SIZE {
- match reader.read(unsafe { MaybeUninit::slice_assume_init_mut(spare_cap) }) {
- Ok(0) => return Ok(len), // EOF reached
- Ok(bytes_read) => {
- assert!(bytes_read <= spare_cap.len());
- // SAFETY: The initializer contract guarantees that either it or `read`
- // will have initialized these bytes. And we just checked that the number
- // of bytes is within the buffer capacity.
+ // SAFETY: init is either 0 or the initialized_len of the previous iteration
+ unsafe {
+ read_buf.assume_init(init);
+ }
+
+ if read_buf.capacity() >= DEFAULT_BUF_SIZE {
+ match reader.read_buf(&mut read_buf) {
+ Ok(()) => {
+ let bytes_read = read_buf.filled_len();
+
+ if bytes_read == 0 {
+ return Ok(len);
+ }
+
+ init = read_buf.initialized_len() - bytes_read;
+
+ // SAFETY: ReadBuf guarantees all of its filled bytes are init
unsafe { buf.set_len(buf.len() + bytes_read) };
len += bytes_read as u64;
// Read again if the buffer still has enough capacity, as BufWriter itself would do
@@ -129,28 +136,26 @@
reader: &mut R,
writer: &mut W,
) -> Result<u64> {
- let mut buf = MaybeUninit::<[u8; DEFAULT_BUF_SIZE]>::uninit();
- // FIXME: #42788
- //
- // - This creates a (mut) reference to a slice of
- // _uninitialized_ integers, which is **undefined behavior**
- //
- // - Only the standard library gets to soundly "ignore" this,
- // based on its privileged knowledge of unstable rustc
- // internals;
- unsafe {
- reader.initializer().initialize(buf.assume_init_mut());
- }
+ let mut buf = [MaybeUninit::uninit(); DEFAULT_BUF_SIZE];
+ let mut buf = ReadBuf::uninit(&mut buf);
- let mut written = 0;
+ let mut len = 0;
+
loop {
- let len = match reader.read(unsafe { buf.assume_init_mut() }) {
- Ok(0) => return Ok(written),
- Ok(len) => len,
- Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
+ match reader.read_buf(&mut buf) {
+ Ok(()) => {}
+ Err(e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
};
- writer.write_all(unsafe { &buf.assume_init_ref()[..len] })?;
- written += len as u64;
+
+ if buf.filled().is_empty() {
+ break;
+ }
+
+ len += buf.filled().len() as u64;
+ writer.write_all(buf.filled())?;
+ buf.clear();
}
+
+ Ok(len)
}
diff --git a/sgx_tstd/src/io/cursor.rs b/sgx_tstd/src/io/cursor.rs
index 01ef7bb..be40a32 100644
--- a/sgx_tstd/src/io/cursor.rs
+++ b/sgx_tstd/src/io/cursor.rs
@@ -18,7 +18,7 @@
use crate::io::prelude::*;
use crate::cmp;
-use crate::io::{self, Error, ErrorKind, Initializer, IoSlice, IoSliceMut, SeekFrom};
+use crate::io::{self, ErrorKind, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
use core::convert::TryInto;
@@ -297,9 +297,9 @@
self.pos = n;
Ok(self.pos)
}
- None => Err(Error::new_const(
+ None => Err(io::const_io_error!(
ErrorKind::InvalidInput,
- &"invalid seek to a negative or overflowing position",
+ "invalid seek to a negative or overflowing position",
)),
}
}
@@ -323,6 +323,16 @@
Ok(n)
}
+ fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ let prev_filled = buf.filled_len();
+
+ Read::read_buf(&mut self.fill_buf()?, buf)?;
+
+ self.pos += (buf.filled_len() - prev_filled) as u64;
+
+ Ok(())
+ }
+
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
let mut nread = 0;
for buf in bufs {
@@ -345,11 +355,6 @@
self.pos += n as u64;
Ok(())
}
-
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
}
impl<T> BufRead for Cursor<T>
@@ -393,9 +398,9 @@
// Resizing write implementation
fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usize> {
let pos: usize = (*pos_mut).try_into().map_err(|_| {
- Error::new_const(
+ io::const_io_error!(
ErrorKind::InvalidInput,
- &"cursor position exceeds maximum possible vector length",
+ "cursor position exceeds maximum possible vector length",
)
})?;
// Make sure the internal buffer is as least as big as where we
diff --git a/sgx_tstd/src/io/error.rs b/sgx_tstd/src/io/error.rs
index 11b7c0b..6de63fb 100644
--- a/sgx_tstd/src/io/error.rs
+++ b/sgx_tstd/src/io/error.rs
@@ -15,6 +15,9 @@
// specific language governing permissions and limitations
// under the License..
+mod repr_unpacked;
+use repr_unpacked::Repr;
+
use crate::convert::From;
use crate::error;
use crate::fmt;
@@ -79,16 +82,59 @@
}
}
-enum Repr {
+// Only derive debug in tests, to make sure it
+// doesn't accidentally get printed.
+#[cfg_attr(feature = "unit_test", derive(Debug))]
+enum ErrorData<C> {
Os(i32),
Simple(ErrorKind),
- // &str is a fat pointer, but &&str is a thin pointer.
- SimpleMessage(ErrorKind, &'static &'static str),
- Custom(Box<Custom>),
+ SimpleMessage(&'static SimpleMessage),
+ Custom(C),
SgxStatus(sgx_status_t),
}
+// `#[repr(align(4))]` is probably redundant, it should have that value or
+// higher already. We include it just because repr_bitpacked.rs's encoding
+// requires an alignment >= 4 (note that `#[repr(align)]` will not reduce the
+// alignment required by the struct, only increase it).
+//
+// If we add more variants to ErrorData, this can be increased to 8, but it
+// should probably be behind `#[cfg_attr(target_pointer_width = "64", ...)]` or
+// whatever cfg we're using to enable the `repr_bitpacked` code, since only the
+// that version needs the alignment, and 8 is higher than the alignment we'll
+// have on 32 bit platforms.
+//
+// (For the sake of being explicit: the alignment requirement here only matters
+// if `error/repr_bitpacked.rs` is in use — for the unpacked repr it doesn't
+// matter at all)
+#[repr(align(4))]
#[derive(Debug)]
+pub(crate) struct SimpleMessage {
+ kind: ErrorKind,
+ message: &'static str,
+}
+
+impl SimpleMessage {
+ pub(crate) const fn new(kind: ErrorKind, message: &'static str) -> Self {
+ Self { kind, message }
+ }
+}
+
+/// Create and return an `io::Error` for a given `ErrorKind` and constant
+/// message. This doesn't allocate.
+pub(crate) macro const_io_error($kind:expr, $message:expr $(,)?) {
+ $crate::io::error::Error::from_static_message({
+ const MESSAGE_DATA: $crate::io::error::SimpleMessage =
+ $crate::io::error::SimpleMessage::new($kind, $message);
+ &MESSAGE_DATA
+ })
+}
+
+// As with `SimpleMessage`: `#[repr(align(4))]` here is just because
+// repr_bitpacked's encoding requires it. In practice it almost certainly be
+// already be this high or higher.
+#[derive(Debug)]
+#[repr(align(4))]
struct Custom {
kind: ErrorKind,
error: Box<dyn error::Error + Send + Sync>,
@@ -223,11 +269,10 @@
///
/// The filesystem does not support making so many hardlinks to the same file.
TooManyLinks,
- /// Filename too long.
+ /// A filename was invalid.
///
- /// The limit might be from the underlying filesystem or API, or an administratively imposed
- /// resource limit.
- FilenameTooLong,
+ /// This error can also cause if it exceeded the filename length limit.
+ InvalidFilename,
/// Program argument list too long.
///
/// When trying to run an external program, a system or process limit on the size of the
@@ -304,12 +349,12 @@
DirectoryNotEmpty => "directory not empty",
ExecutableFileBusy => "executable file busy",
FileTooLarge => "file too large",
- FilenameTooLong => "filename too long",
FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)",
FilesystemQuotaExceeded => "filesystem quota exceeded",
HostUnreachable => "host unreachable",
Interrupted => "operation interrupted",
InvalidData => "invalid data",
+ InvalidFilename => "invalid filename",
InvalidInput => "invalid input parameter",
IsADirectory => "is a directory",
NetworkDown => "network down",
@@ -332,17 +377,32 @@
Unsupported => "unsupported",
WouldBlock => "operation would block",
WriteZero => "write zero",
- ErrorKind::SgxError => "Sgx error status",
+ SgxError => "Sgx error status",
}
}
}
+impl fmt::Display for ErrorKind {
+ /// Shows a human-readable description of the `ErrorKind`.
+ ///
+ /// This is similar to `impl Display for Error`, but doesn't require first converting to Error.
+ ///
+ /// # Examples
+ /// ```
+ /// use std::io::ErrorKind;
+ /// assert_eq!("entity not found", ErrorKind::NotFound.to_string());
+ /// ```
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.write_str(self.as_str())
+ }
+}
+
/// Intended for use for errors not exposed to the user, where allocating onto
/// the heap (for normal construction via Error::new) is too costly.
impl From<ErrorKind> for Error {
/// Converts an [`ErrorKind`] into an [`Error`].
///
- /// This conversion allocates a new error with a simple representation of error kind.
+ /// This conversion creates a new error with a simple representation of error kind.
///
/// # Examples
///
@@ -355,14 +415,14 @@
/// ```
#[inline]
fn from(kind: ErrorKind) -> Error {
- Error { repr: Repr::Simple(kind) }
+ Error { repr: Repr::new_simple(kind) }
}
}
impl From<sgx_status_t> for Error {
#[inline]
fn from(status: sgx_status_t) -> Error {
- Error { repr: Repr::SgxStatus(status) }
+ Error { repr: Repr::new_sgx(status) }
}
}
@@ -374,6 +434,9 @@
/// originate from the OS itself. The `error` argument is an arbitrary
/// payload which will be contained in this [`Error`].
///
+ /// If no extra payload is required, use the `From` conversion from
+ /// `ErrorKind`.
+ ///
/// # Examples
///
/// ```
@@ -384,6 +447,9 @@
///
/// // errors can also be created from other errors
/// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
+ ///
+ /// // creating an error without payload
+ /// let eof_error = Error::from(ErrorKind::UnexpectedEof);
/// ```
pub fn new<E>(kind: ErrorKind, error: E) -> Error
where
@@ -392,21 +458,49 @@
Self::_new(kind, error.into())
}
- fn _new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error {
- Error { repr: Repr::Custom(Box::new(Custom { kind, error })) }
+ /// Creates a new I/O error from an arbitrary error payload.
+ ///
+ /// This function is used to generically create I/O errors which do not
+ /// originate from the OS itself. It is a shortcut for [`Error::new`]
+ /// with [`ErrorKind::Other`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(io_error_other)]
+ ///
+ /// use std::io::Error;
+ ///
+ /// // errors can be created from strings
+ /// let custom_error = Error::other("oh no!");
+ ///
+ /// // errors can also be created from other errors
+ /// let custom_error2 = Error::other(custom_error);
+ /// ```
+ pub fn other<E>(error: E) -> Error
+ where
+ E: Into<Box<dyn error::Error + Send + Sync>>,
+ {
+ Self::_new(ErrorKind::Other, error.into())
}
- /// Creates a new I/O error from a known kind of error as well as a
- /// constant message.
+ fn _new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error {
+ Error { repr: Repr::new_custom(Box::new(Custom { kind, error })) }
+ }
+
+ /// Creates a new I/O error from a known kind of error as well as a constant
+ /// message.
///
/// This function does not allocate.
///
- /// This function should maybe change to
- /// `new_const<const MSG: &'static str>(kind: ErrorKind)`
- /// in the future, when const generics allow that.
+ /// You should not use this directly, and instead use the `const_io_error!`
+ /// macro: `io::const_io_error!(ErrorKind::Something, "some_message")`.
+ ///
+ /// This function should maybe change to `from_static_message<const MSG: &'static
+ /// str>(kind: ErrorKind)` in the future, when const generics allow that.
#[inline]
- pub(crate) const fn new_const(kind: ErrorKind, message: &'static &'static str) -> Error {
- Self { repr: Repr::SimpleMessage(kind, message) }
+ pub(crate) const fn from_static_message(msg: &'static SimpleMessage) -> Error {
+ Self { repr: Repr::new_simple_message(msg) }
}
/// Returns an error representing the last OS error which occurred.
@@ -415,12 +509,18 @@
/// `GetLastError` on Windows) and will return a corresponding instance of
/// [`Error`] for the error code.
///
+ /// This should be called immediately after a call to a platform function,
+ /// otherwise the state of the error value is indeterminate. In particular,
+ /// other standard library functions may call platform functions that may
+ /// (or may not) reset the error value even if they succeed.
+ ///
/// # Examples
///
/// ```
/// use std::io::Error;
///
- /// println!("last OS error: {:?}", Error::last_os_error());
+ /// let os_error = Error::last_os_error();
+ /// println!("last OS error: {:?}", os_error);
/// ```
#[must_use]
#[inline]
@@ -456,7 +556,7 @@
#[must_use]
#[inline]
pub fn from_raw_os_error(code: i32) -> Error {
- Error { repr: Repr::Os(code) }
+ Error { repr: Repr::new_os(code) }
}
/// Returns the OS error that this error represents (if any).
@@ -491,18 +591,18 @@
#[must_use]
#[inline]
pub fn raw_os_error(&self) -> Option<i32> {
- match self.repr {
- Repr::Os(i) => Some(i),
- Repr::Custom(..) => None,
- Repr::Simple(..) => None,
- Repr::SimpleMessage(..) => None,
- Repr::SgxStatus(..) => None,
+ match self.repr.data() {
+ ErrorData::Os(i) => Some(i),
+ ErrorData::Custom(..) => None,
+ ErrorData::Simple(..) => None,
+ ErrorData::SimpleMessage(..) => None,
+ ErrorData::SgxStatus(..) => None,
}
}
/// Creates a new instance of an `Error` from a particular SGX error status.
pub fn from_sgx_error(status: sgx_status_t) -> Error {
- Error { repr: Repr::SgxStatus(status) }
+ Error { repr: Repr::new_sgx(status) }
}
/// Returns the SGX error that this error represents (if any).
@@ -511,12 +611,12 @@
/// then this function will return `Some`, otherwise
/// it will return `None`.
pub fn raw_sgx_error(&self) -> Option<sgx_status_t> {
- match self.repr {
- Repr::Os(..) => None,
- Repr::Custom(..) => None,
- Repr::Simple(..) => None,
- Repr::SimpleMessage(..) => None,
- Repr::SgxStatus(status) => Some(status),
+ match self.repr.data() {
+ ErrorData::Os(..) => None,
+ ErrorData::Custom(..) => None,
+ ErrorData::Simple(..) => None,
+ ErrorData::SimpleMessage(..) => None,
+ ErrorData::SgxStatus(status) => Some(status),
}
}
@@ -550,12 +650,12 @@
#[must_use]
#[inline]
pub fn get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)> {
- match self.repr {
- Repr::Os(..) => None,
- Repr::Simple(..) => None,
- Repr::SimpleMessage(..) => None,
- Repr::Custom(ref c) => Some(&*c.error),
- Repr::SgxStatus(ref s) => Some(s),
+ match self.repr.data() {
+ ErrorData::Os(..) => None,
+ ErrorData::Simple(..) => None,
+ ErrorData::SimpleMessage(..) => None,
+ ErrorData::Custom(c) => Some(&*c.error),
+ ErrorData::SgxStatus(..) => None,
}
}
@@ -624,12 +724,12 @@
#[must_use]
#[inline]
pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)> {
- match self.repr {
- Repr::Os(..) => None,
- Repr::Simple(..) => None,
- Repr::SimpleMessage(..) => None,
- Repr::Custom(ref mut c) => Some(&mut *c.error),
- Repr::SgxStatus(ref mut s) => Some(s),
+ match self.repr.data_mut() {
+ ErrorData::Os(..) => None,
+ ErrorData::Simple(..) => None,
+ ErrorData::SimpleMessage(..) => None,
+ ErrorData::Custom(c) => Some(&mut *c.error),
+ ErrorData::SgxStatus(..) => None,
}
}
@@ -663,12 +763,12 @@
#[must_use = "`self` will be dropped if the result is not used"]
#[inline]
pub fn into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>> {
- match self.repr {
- Repr::Os(..) => None,
- Repr::Simple(..) => None,
- Repr::SimpleMessage(..) => None,
- Repr::Custom(c) => Some(c.error),
- Repr::SgxStatus(s) => Some(Box::new(s)),
+ match self.repr.into_data() {
+ ErrorData::Os(..) => None,
+ ErrorData::Simple(..) => None,
+ ErrorData::SimpleMessage(..) => None,
+ ErrorData::Custom(c) => Some(c.error),
+ ErrorData::SgxStatus(s) => Some(Box::new(s)),
}
}
@@ -693,31 +793,33 @@
#[must_use]
#[inline]
pub fn kind(&self) -> ErrorKind {
- match self.repr {
- Repr::Os(code) => sys::decode_error_kind(code),
- Repr::Custom(ref c) => c.kind,
- Repr::Simple(kind) => kind,
- Repr::SimpleMessage(kind, _) => kind,
- Repr::SgxStatus(..) => ErrorKind::SgxError,
+ match self.repr.data() {
+ ErrorData::Os(code) => sys::decode_error_kind(code),
+ ErrorData::Custom(c) => c.kind,
+ ErrorData::Simple(kind) => kind,
+ ErrorData::SimpleMessage(m) => m.kind,
+ ErrorData::SgxStatus(..) => ErrorKind::SgxError,
}
}
}
impl fmt::Debug for Repr {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- match *self {
- Repr::Os(code) => fmt
+ match self.data() {
+ ErrorData::Os(code) => fmt
.debug_struct("Os")
.field("code", &code)
.field("kind", &sys::decode_error_kind(code))
.field("message", &sys::os::error_string(code))
.finish(),
- Repr::Custom(ref c) => fmt::Debug::fmt(&c, fmt),
- Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
- Repr::SimpleMessage(kind, &message) => {
- fmt.debug_struct("Error").field("kind", &kind).field("message", &message).finish()
- }
- Repr::SgxStatus(status) => fmt
+ ErrorData::Custom(c) => fmt::Debug::fmt(&c, fmt),
+ ErrorData::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
+ ErrorData::SimpleMessage(msg) => fmt
+ .debug_struct("Error")
+ .field("kind", &msg.kind)
+ .field("message", &msg.message)
+ .finish(),
+ ErrorData::SgxStatus(status) => fmt
.debug_struct("Sgx")
.field("code", &status)
.field("message", &status.__description())
@@ -728,15 +830,15 @@
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self.repr {
- Repr::Os(code) => {
+ match self.repr.data() {
+ ErrorData::Os(code) => {
let detail = sys::os::error_string(code);
write!(fmt, "{} (os error {})", detail, code)
}
- Repr::Custom(ref c) => c.error.fmt(fmt),
- Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
- Repr::SimpleMessage(_, &msg) => msg.fmt(fmt),
- Repr::SgxStatus(status) => {
+ ErrorData::Custom(c) => c.error.fmt(fmt),
+ ErrorData::Simple(kind) => write!(fmt, "{}", kind.as_str()),
+ ErrorData::SimpleMessage(msg) => msg.message.fmt(fmt),
+ ErrorData::SgxStatus(status) => {
let detail = status.__description();
write!(fmt, "{} (sgx error: {})", detail, status)
}
@@ -747,32 +849,32 @@
impl error::Error for Error {
#[allow(deprecated, deprecated_in_future)]
fn description(&self) -> &str {
- match self.repr {
- Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(),
- Repr::SimpleMessage(_, &msg) => msg,
- Repr::Custom(ref c) => c.error.description(),
- Repr::SgxStatus(ref s) => s.description(),
+ match self.repr.data() {
+ ErrorData::Os(..) | ErrorData::Simple(..) => self.kind().as_str(),
+ ErrorData::SimpleMessage(msg) => msg.message,
+ ErrorData::Custom(c) => c.error.description(),
+ ErrorData::SgxStatus(ref s) => s.__description(),
}
}
#[allow(deprecated)]
fn cause(&self) -> Option<&dyn error::Error> {
- match self.repr {
- Repr::Os(..) => None,
- Repr::Simple(..) => None,
- Repr::SimpleMessage(..) => None,
- Repr::Custom(ref c) => c.error.cause(),
- Repr::SgxStatus(ref s) => Some(s),
+ match self.repr.data() {
+ ErrorData::Os(..) => None,
+ ErrorData::Simple(..) => None,
+ ErrorData::SimpleMessage(..) => None,
+ ErrorData::Custom(c) => c.error.cause(),
+ ErrorData::SgxStatus(..) => None,
}
}
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
- match self.repr {
- Repr::Os(..) => None,
- Repr::Simple(..) => None,
- Repr::SimpleMessage(..) => None,
- Repr::Custom(ref c) => c.error.source(),
- Repr::SgxStatus(ref s) => Some(s),
+ match self.repr.data() {
+ ErrorData::Os(..) => None,
+ ErrorData::Simple(..) => None,
+ ErrorData::SimpleMessage(..) => None,
+ ErrorData::Custom(c) => c.error.source(),
+ ErrorData::SgxStatus(..) => None,
}
}
}
diff --git a/sgx_tstd/src/io/error/repr_unpacked.rs b/sgx_tstd/src/io/error/repr_unpacked.rs
new file mode 100644
index 0000000..f171307
--- /dev/null
+++ b/sgx_tstd/src/io/error/repr_unpacked.rs
@@ -0,0 +1,58 @@
+//! This is a fairly simple unpacked error representation that's used on
+//! non-64bit targets, where the packed 64 bit representation wouldn't work, and
+//! would have no benefit.
+
+use super::{Custom, ErrorData, ErrorKind, SimpleMessage};
+use alloc_crate::boxed::Box;
+
+use sgx_types::sgx_status_t;
+
+type Inner = ErrorData<Box<Custom>>;
+
+pub(super) struct Repr(Inner);
+
+impl Repr {
+ pub(super) fn new_custom(b: Box<Custom>) -> Self {
+ Self(Inner::Custom(b))
+ }
+ #[inline]
+ pub(super) fn new_os(code: i32) -> Self {
+ Self(Inner::Os(code))
+ }
+ #[inline]
+ pub(super) fn new_simple(kind: ErrorKind) -> Self {
+ Self(Inner::Simple(kind))
+ }
+ #[inline]
+ pub(super) const fn new_simple_message(m: &'static SimpleMessage) -> Self {
+ Self(Inner::SimpleMessage(m))
+ }
+ #[inline]
+ pub(super) const fn new_sgx(status: sgx_status_t) -> Self {
+ Self(Inner::SgxStatus(status))
+ }
+ #[inline]
+ pub(super) fn into_data(self) -> ErrorData<Box<Custom>> {
+ self.0
+ }
+ #[inline]
+ pub(super) fn data(&self) -> ErrorData<&Custom> {
+ match &self.0 {
+ Inner::Os(c) => ErrorData::Os(*c),
+ Inner::Simple(k) => ErrorData::Simple(*k),
+ Inner::SimpleMessage(m) => ErrorData::SimpleMessage(*m),
+ Inner::Custom(m) => ErrorData::Custom(&*m),
+ Inner::SgxStatus(s) => ErrorData::SgxStatus(*s),
+ }
+ }
+ #[inline]
+ pub(super) fn data_mut(&mut self) -> ErrorData<&mut Custom> {
+ match &mut self.0 {
+ Inner::Os(c) => ErrorData::Os(*c),
+ Inner::Simple(k) => ErrorData::Simple(*k),
+ Inner::SimpleMessage(m) => ErrorData::SimpleMessage(*m),
+ Inner::Custom(m) => ErrorData::Custom(&mut *m),
+ Inner::SgxStatus(s) => ErrorData::SgxStatus(*s),
+ }
+ }
+}
diff --git a/sgx_tstd/src/io/impls.rs b/sgx_tstd/src/io/impls.rs
index f30b868..2a8ebc6 100644
--- a/sgx_tstd/src/io/impls.rs
+++ b/sgx_tstd/src/io/impls.rs
@@ -19,7 +19,7 @@
use crate::cmp;
use crate::fmt;
use crate::io::{
- self, BufRead, Error, ErrorKind, Initializer, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write,
+ self, BufRead, ErrorKind, IoSlice, IoSliceMut, Read, ReadBuf, Seek, SeekFrom, Write,
};
use crate::mem;
@@ -33,6 +33,11 @@
}
#[inline]
+ fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ (**self).read_buf(buf)
+ }
+
+ #[inline]
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
(**self).read_vectored(bufs)
}
@@ -43,11 +48,6 @@
}
#[inline]
- unsafe fn initializer(&self) -> Initializer {
- (**self).initializer()
- }
-
- #[inline]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
(**self).read_to_end(buf)
}
@@ -136,6 +136,11 @@
}
#[inline]
+ fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ (**self).read_buf(buf)
+ }
+
+ #[inline]
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
(**self).read_vectored(bufs)
}
@@ -146,11 +151,6 @@
}
#[inline]
- unsafe fn initializer(&self) -> Initializer {
- (**self).initializer()
- }
-
- #[inline]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
(**self).read_to_end(buf)
}
@@ -259,6 +259,17 @@
}
#[inline]
+ fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ let amt = cmp::min(buf.remaining(), self.len());
+ let (a, b) = self.split_at(amt);
+
+ buf.append(a);
+
+ *self = b;
+ Ok(())
+ }
+
+ #[inline]
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
let mut nread = 0;
for buf in bufs {
@@ -277,14 +288,12 @@
}
#[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
-
- #[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
if buf.len() > self.len() {
- return Err(Error::new_const(ErrorKind::UnexpectedEof, &"failed to fill whole buffer"));
+ return Err(io::const_io_error!(
+ ErrorKind::UnexpectedEof,
+ "failed to fill whole buffer"
+ ));
}
let (a, b) = self.split_at(buf.len());
@@ -332,6 +341,7 @@
/// return short writes: ultimately, `Ok(0)`; in this situation, `write_all` returns an error of
/// kind `ErrorKind::WriteZero`.
impl Write for &mut [u8] {
+ #[allow(clippy::mem_replace_with_default)]
#[inline]
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
let amt = cmp::min(data.len(), self.len());
@@ -364,7 +374,7 @@
if self.write(data)? == data.len() {
Ok(())
} else {
- Err(Error::new_const(ErrorKind::WriteZero, &"failed to write whole buffer"))
+ Err(io::const_io_error!(ErrorKind::WriteZero, "failed to write whole buffer"))
}
}
diff --git a/sgx_tstd/src/io/mod.rs b/sgx_tstd/src/io/mod.rs
index 8ca7acf..2497f3d 100644
--- a/sgx_tstd/src/io/mod.rs
+++ b/sgx_tstd/src/io/mod.rs
@@ -268,25 +268,30 @@
use crate::fmt;
use crate::mem::replace;
use crate::ops::{Deref, DerefMut};
-use crate::ptr;
use crate::slice;
use crate::str;
use crate::sys;
use crate::sys_common::memchr;
-pub use self::buffered::IntoInnerError;
+
pub use self::buffered::WriterPanicked;
-pub use self::buffered::{BufReader, BufWriter, LineWriter};
-pub use self::copy::copy;
-pub use self::cursor::Cursor;
-pub use self::error::{Error, ErrorKind, Result};
-#[cfg(feature = "stdio")]
-pub use self::stdio::{stderr, stdin, stdout, Stderr, Stdin, Stdout};
-#[cfg(feature = "stdio")]
-pub use self::stdio::{StderrLock, StdinLock, StdoutLock};
+
#[cfg(feature = "stdio")]
pub use self::stdio::{_eprint, _print};
-pub use self::util::{empty, repeat, sink, Empty, Repeat, Sink};
+#[cfg(feature = "stdio")]
+pub use self::stdio::{stderr_locked, stdin_locked, stdout_locked};
+#[cfg(feature = "stdio")]
+pub use self::stdio::{stderr, stdin, stdout, Stderr, StderrLock, Stdin, StdinLock, Stdout, StdoutLock};
+pub use self::{
+ buffered::{BufReader, BufWriter, IntoInnerError, LineWriter},
+ copy::copy,
+ cursor::Cursor,
+ error::{Error, ErrorKind, Result},
+ util::{empty, repeat, sink, Empty, Repeat, Sink},
+};
+
+pub use self::readbuf::ReadBuf;
+pub(crate) use error::const_io_error;
mod buffered;
pub(crate) mod copy;
@@ -294,12 +299,14 @@
mod error;
mod impls;
pub mod prelude;
+mod readbuf;
#[cfg(feature = "stdio")]
mod stdio;
mod util;
const DEFAULT_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
+#[cfg(feature = "stdio")]
pub(crate) use stdio::cleanup;
struct Guard<'a> {
@@ -342,7 +349,10 @@
let ret = f(g.buf);
if str::from_utf8(&g.buf[g.len..]).is_err() {
ret.and_then(|_| {
- Err(Error::new_const(ErrorKind::InvalidData, &"stream did not contain valid UTF-8"))
+ Err(error::const_io_error!(
+ ErrorKind::InvalidData,
+ "stream did not contain valid UTF-8"
+ ))
})
} else {
g.len = g.buf.len();
@@ -356,52 +366,43 @@
// of data to return. Simply tacking on an extra DEFAULT_BUF_SIZE space every
// time is 4,500 times (!) slower than a default reservation size of 32 if the
// reader has a very small amount of data to return.
-//
-// Because we're extending the buffer with uninitialized data for trusted
-// readers, we need to make sure to truncate that if any of this panics.
pub(crate) fn default_read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> {
let start_len = buf.len();
let start_cap = buf.capacity();
- let mut g = Guard { len: buf.len(), buf };
+
+ let mut initialized = 0; // Extra initialized bytes from previous loop iteration
loop {
- // If we've read all the way up to the capacity, reserve more space.
- if g.len == g.buf.capacity() {
- g.buf.reserve(32);
+ if buf.len() == buf.capacity() {
+ buf.reserve(32); // buf is full, need more space
}
- // Initialize any excess capacity and adjust the length so we can write
- // to it.
- if g.buf.len() < g.buf.capacity() {
- unsafe {
- // FIXME(danielhenrymantilla): #42788
- //
- // - This creates a (mut) reference to a slice of
- // _uninitialized_ integers, which is **undefined behavior**
- //
- // - Only the standard library gets to soundly "ignore" this,
- // based on its privileged knowledge of unstable rustc
- // internals;
- let capacity = g.buf.capacity();
- g.buf.set_len(capacity);
- r.initializer().initialize(&mut g.buf[g.len..]);
- }
+ let mut read_buf = ReadBuf::uninit(buf.spare_capacity_mut());
+
+ // SAFETY: These bytes were initialized but not filled in the previous loop
+ unsafe {
+ read_buf.assume_init(initialized);
}
- let buf = &mut g.buf[g.len..];
- match r.read(buf) {
- Ok(0) => return Ok(g.len - start_len),
- Ok(n) => {
- // We can't allow bogus values from read. If it is too large, the returned vec could have its length
- // set past its capacity, or if it overflows the vec could be shortened which could create an invalid
- // string if this is called via read_to_string.
- assert!(n <= buf.len());
- g.len += n;
- }
- Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
+ match r.read_buf(&mut read_buf) {
+ Ok(()) => {}
+ Err(e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
}
- if g.len == g.buf.capacity() && g.buf.capacity() == start_cap {
+ if read_buf.filled_len() == 0 {
+ return Ok(buf.len() - start_len);
+ }
+
+ // store how much was initialized but not filled
+ initialized = read_buf.initialized_len() - read_buf.filled_len();
+ let new_len = read_buf.filled_len() + buf.len();
+
+ // SAFETY: ReadBuf's invariants mean this much memory is init
+ unsafe {
+ buf.set_len(new_len);
+ }
+
+ if buf.len() == buf.capacity() && buf.capacity() == start_cap {
// The buffer might be an exact fit. Let's read into a probe buffer
// and see if it returns `Ok(0)`. If so, we've avoided an
// unnecessary doubling of the capacity. But if not, append the
@@ -410,10 +411,9 @@
loop {
match r.read(&mut probe) {
- Ok(0) => return Ok(g.len - start_len),
+ Ok(0) => return Ok(buf.len() - start_len),
Ok(n) => {
- g.buf.extend_from_slice(&probe[..n]);
- g.len += n;
+ buf.extend_from_slice(&probe[..n]);
break;
}
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
@@ -469,12 +469,21 @@
}
}
if !buf.is_empty() {
- Err(Error::new_const(ErrorKind::UnexpectedEof, &"failed to fill whole buffer"))
+ Err(error::const_io_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer"))
} else {
Ok(())
}
}
+pub(crate) fn default_read_buf<F>(read: F, buf: &mut ReadBuf<'_>) -> Result<()>
+where
+ F: FnOnce(&mut [u8]) -> Result<usize>,
+{
+ let n = read(buf.initialize_unfilled())?;
+ buf.add_filled(n);
+ Ok(())
+}
+
/// The `Read` trait allows for reading bytes from a source.
///
/// Implementors of the `Read` trait are called 'readers'.
@@ -652,30 +661,6 @@
false
}
- /// Determines if this `Read`er can work with buffers of uninitialized
- /// memory.
- ///
- /// The default implementation returns an initializer which will zero
- /// buffers.
- ///
- /// If a `Read`er guarantees that it can work properly with uninitialized
- /// memory, it should call [`Initializer::nop()`]. See the documentation for
- /// [`Initializer`] for details.
- ///
- /// The behavior of this method must be independent of the state of the
- /// `Read`er - the method only takes `&self` so that it can be used through
- /// trait objects.
- ///
- /// # Safety
- ///
- /// This method is unsafe because a `Read`er could otherwise return a
- /// non-zeroing `Initializer` from another `Read` type without an `unsafe`
- /// block.
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::zeroing()
- }
-
/// Read all bytes until EOF in this source, placing them into `buf`.
///
/// All bytes read from this source will be appended to the specified buffer
@@ -822,7 +807,38 @@
default_read_exact(self, buf)
}
- /// Creates a "by reference" adapter for this instance of `Read`.
+ /// Pull some bytes from this source into the specified buffer.
+ ///
+ /// This is equivalent to the [`read`](Read::read) method, except that it is passed a [`ReadBuf`] rather than `[u8]` to allow use
+ /// with uninitialized buffers. The new data will be appended to any existing contents of `buf`.
+ ///
+ /// The default implementation delegates to `read`.
+ fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> Result<()> {
+ default_read_buf(|b| self.read(b), buf)
+ }
+
+ /// Read the exact number of bytes required to fill `buf`.
+ ///
+ /// This is equivalent to the [`read_exact`](Read::read_exact) method, except that it is passed a [`ReadBuf`] rather than `[u8]` to
+ /// allow use with uninitialized buffers.
+ fn read_buf_exact(&mut self, buf: &mut ReadBuf<'_>) -> Result<()> {
+ while buf.remaining() > 0 {
+ let prev_filled = buf.filled().len();
+ match self.read_buf(buf) {
+ Ok(()) => {}
+ Err(e) if e.kind() == ErrorKind::Interrupted => continue,
+ Err(e) => return Err(e),
+ }
+
+ if buf.filled().len() == prev_filled {
+ return Err(Error::new(ErrorKind::UnexpectedEof, "failed to fill buffer"));
+ }
+ }
+
+ Ok(())
+ }
+
+ /// Creates a "by reference" adaptor for this instance of `Read`.
///
/// The returned adapter also implements `Read` and will simply borrow this
/// current reader.
@@ -1016,13 +1032,13 @@
///
/// # use std::io;
/// fn main() -> io::Result<()> {
-/// let stdin = io::read_to_string(&mut io::stdin())?;
+/// let stdin = io::read_to_string(io::stdin())?;
/// println!("Stdin was:");
/// println!("{}", stdin);
/// Ok(())
/// }
/// ```
-pub fn read_to_string<R: Read>(reader: &mut R) -> Result<String> {
+pub fn read_to_string<R: Read>(mut reader: R) -> Result<String> {
let mut buf = String::new();
reader.read_to_string(&mut buf)?;
Ok(buf)
@@ -1114,6 +1130,7 @@
/// assert_eq!(bufs[0].deref(), [2; 14].as_ref());
/// assert_eq!(bufs[1].deref(), [3; 8].as_ref());
/// ```
+ #[allow(clippy::mem_replace_with_default)]
#[inline]
pub fn advance_slices(bufs: &mut &mut [IoSliceMut<'a>], n: usize) {
// Number of buffers to remove.
@@ -1239,6 +1256,7 @@
/// IoSlice::advance_slices(&mut bufs, 10);
/// assert_eq!(bufs[0].deref(), [2; 14].as_ref());
/// assert_eq!(bufs[1].deref(), [3; 8].as_ref());
+ #[allow(clippy::mem_replace_with_default)]
#[inline]
pub fn advance_slices(bufs: &mut &mut [IoSlice<'a>], n: usize) {
// Number of buffers to remove.
@@ -1270,48 +1288,6 @@
}
}
-/// A type used to conditionally initialize buffers passed to `Read` methods.
-#[derive(Debug)]
-pub struct Initializer(bool);
-
-impl Initializer {
- /// Returns a new `Initializer` which will zero out buffers.
- #[must_use]
- #[inline]
- pub fn zeroing() -> Initializer {
- Initializer(true)
- }
-
- /// Returns a new `Initializer` which will not zero out buffers.
- ///
- /// # Safety
- ///
- /// This may only be called by `Read`ers which guarantee that they will not
- /// read from buffers passed to `Read` methods, and that the return value of
- /// the method accurately reflects the number of bytes that have been
- /// written to the head of the buffer.
- #[must_use]
- #[inline]
- pub unsafe fn nop() -> Initializer {
- Initializer(false)
- }
-
- /// Indicates if a buffer should be initialized.
- #[must_use]
- #[inline]
- pub fn should_initialize(&self) -> bool {
- self.0
- }
-
- /// Initializes a buffer if necessary.
- #[inline]
- pub fn initialize(&self, buf: &mut [u8]) {
- if self.should_initialize() {
- unsafe { ptr::write_bytes(buf.as_mut_ptr(), 0, buf.len()) }
- }
- }
-}
-
/// A trait for objects which are byte-oriented sinks.
///
/// Implementors of the `Write` trait are sometimes called 'writers'.
@@ -1514,9 +1490,9 @@
while !buf.is_empty() {
match self.write(buf) {
Ok(0) => {
- return Err(Error::new_const(
+ return Err(error::const_io_error!(
ErrorKind::WriteZero,
- &"failed to write whole buffer",
+ "failed to write whole buffer",
));
}
Ok(n) => buf = &buf[n..],
@@ -1581,9 +1557,9 @@
while !bufs.is_empty() {
match self.write_vectored(bufs) {
Ok(0) => {
- return Err(Error::new_const(
+ return Err(error::const_io_error!(
ErrorKind::WriteZero,
- &"failed to write whole buffer",
+ "failed to write whole buffer",
));
}
Ok(n) => IoSlice::advance_slices(&mut bufs, n),
@@ -1657,7 +1633,7 @@
if output.error.is_err() {
output.error
} else {
- Err(Error::new_const(ErrorKind::Uncategorized, &"formatter error"))
+ Err(error::const_io_error!(ErrorKind::Uncategorized, "formatter error"))
}
}
}
@@ -2336,11 +2312,6 @@
}
self.second.read_vectored(bufs)
}
-
- unsafe fn initializer(&self) -> Initializer {
- let initializer = self.first.initializer();
- if initializer.should_initialize() { initializer } else { self.second.initializer() }
- }
}
impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
@@ -2535,8 +2506,53 @@
Ok(n)
}
- unsafe fn initializer(&self) -> Initializer {
- self.inner.initializer()
+ fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> Result<()> {
+ // Don't call into inner reader at all at EOF because it may still block
+ if self.limit == 0 {
+ return Ok(());
+ }
+
+ let prev_filled = buf.filled_len();
+
+ if self.limit <= buf.remaining() as u64 {
+ // if we just use an as cast to convert, limit may wrap around on a 32 bit target
+ let limit = cmp::min(self.limit, usize::MAX as u64) as usize;
+
+ let extra_init = cmp::min(limit as usize, buf.initialized_len() - buf.filled_len());
+
+ // SAFETY: no uninit data is written to ibuf
+ let ibuf = unsafe { &mut buf.unfilled_mut()[..limit] };
+
+ let mut sliced_buf = ReadBuf::uninit(ibuf);
+
+ // SAFETY: extra_init bytes of ibuf are known to be initialized
+ unsafe {
+ sliced_buf.assume_init(extra_init);
+ }
+
+ self.inner.read_buf(&mut sliced_buf)?;
+
+ let new_init = sliced_buf.initialized_len();
+ let filled = sliced_buf.filled_len();
+
+ // sliced_buf / ibuf must drop here
+
+ // SAFETY: new_init bytes of buf's unfilled buffer have been initialized
+ unsafe {
+ buf.assume_init(new_init);
+ }
+
+ buf.add_filled(filled);
+
+ self.limit -= filled as u64;
+ } else {
+ self.inner.read_buf(buf)?;
+
+ //inner may unfill
+ self.limit -= buf.filled_len().saturating_sub(prev_filled) as u64;
+ }
+
+ Ok(())
}
}
diff --git a/sgx_tstd/src/io/readbuf.rs b/sgx_tstd/src/io/readbuf.rs
new file mode 100644
index 0000000..db776d7
--- /dev/null
+++ b/sgx_tstd/src/io/readbuf.rs
@@ -0,0 +1,257 @@
+// 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 crate::cmp;
+use crate::fmt::{self, Debug, Formatter};
+use crate::mem::MaybeUninit;
+
+/// A wrapper around a byte buffer that is incrementally filled and initialized.
+///
+/// This type is a sort of "double cursor". It tracks three regions in the buffer: a region at the beginning of the
+/// buffer that has been logically filled with data, a region that has been initialized at some point but not yet
+/// logically filled, and a region at the end that is fully uninitialized. The filled region is guaranteed to be a
+/// subset of the initialized region.
+///
+/// In summary, the contents of the buffer can be visualized as:
+/// ```not_rust
+/// [ capacity ]
+/// [ filled | unfilled ]
+/// [ initialized | uninitialized ]
+/// ```
+pub struct ReadBuf<'a> {
+ buf: &'a mut [MaybeUninit<u8>],
+ filled: usize,
+ initialized: usize,
+}
+
+impl Debug for ReadBuf<'_> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.debug_struct("ReadBuf")
+ .field("init", &self.initialized())
+ .field("filled", &self.filled)
+ .field("capacity", &self.capacity())
+ .finish()
+ }
+}
+
+impl<'a> ReadBuf<'a> {
+ /// Creates a new `ReadBuf` from a fully initialized buffer.
+ #[inline]
+ pub fn new(buf: &'a mut [u8]) -> ReadBuf<'a> {
+ let len = buf.len();
+
+ ReadBuf {
+ //SAFETY: initialized data never becoming uninitialized is an invariant of ReadBuf
+ buf: unsafe { (buf as *mut [u8]).as_uninit_slice_mut().unwrap() },
+ filled: 0,
+ initialized: len,
+ }
+ }
+
+ /// Creates a new `ReadBuf` from a fully uninitialized buffer.
+ ///
+ /// Use `assume_init` if part of the buffer is known to be already initialized.
+ #[inline]
+ pub fn uninit(buf: &'a mut [MaybeUninit<u8>]) -> ReadBuf<'a> {
+ ReadBuf { buf, filled: 0, initialized: 0 }
+ }
+
+ /// Returns the total capacity of the buffer.
+ #[inline]
+ pub fn capacity(&self) -> usize {
+ self.buf.len()
+ }
+
+ /// Returns a shared reference to the filled portion of the buffer.
+ #[inline]
+ pub fn filled(&self) -> &[u8] {
+ //SAFETY: We only slice the filled part of the buffer, which is always valid
+ unsafe { MaybeUninit::slice_assume_init_ref(&self.buf[0..self.filled]) }
+ }
+
+ /// Returns a mutable reference to the filled portion of the buffer.
+ #[inline]
+ pub fn filled_mut(&mut self) -> &mut [u8] {
+ //SAFETY: We only slice the filled part of the buffer, which is always valid
+ unsafe { MaybeUninit::slice_assume_init_mut(&mut self.buf[0..self.filled]) }
+ }
+
+ /// Returns a shared reference to the initialized portion of the buffer.
+ ///
+ /// This includes the filled portion.
+ #[inline]
+ pub fn initialized(&self) -> &[u8] {
+ //SAFETY: We only slice the initialized part of the buffer, which is always valid
+ unsafe { MaybeUninit::slice_assume_init_ref(&self.buf[0..self.initialized]) }
+ }
+
+ /// Returns a mutable reference to the initialized portion of the buffer.
+ ///
+ /// This includes the filled portion.
+ #[inline]
+ pub fn initialized_mut(&mut self) -> &mut [u8] {
+ //SAFETY: We only slice the initialized part of the buffer, which is always valid
+ unsafe { MaybeUninit::slice_assume_init_mut(&mut self.buf[0..self.initialized]) }
+ }
+
+ /// Returns a mutable reference to the unfilled part of the buffer without ensuring that it has been fully
+ /// initialized.
+ ///
+ /// # Safety
+ ///
+ /// The caller must not de-initialize portions of the buffer that have already been initialized.
+ #[inline]
+ pub unsafe fn unfilled_mut(&mut self) -> &mut [MaybeUninit<u8>] {
+ &mut self.buf[self.filled..]
+ }
+
+ /// Returns a mutable reference to the uninitialized part of the buffer.
+ ///
+ /// It is safe to uninitialize any of these bytes.
+ #[inline]
+ pub fn uninitialized_mut(&mut self) -> &mut [MaybeUninit<u8>] {
+ &mut self.buf[self.initialized..]
+ }
+
+ /// Returns a mutable reference to the unfilled part of the buffer, ensuring it is fully initialized.
+ ///
+ /// Since `ReadBuf` tracks the region of the buffer that has been initialized, this is effectively "free" after
+ /// the first use.
+ #[inline]
+ pub fn initialize_unfilled(&mut self) -> &mut [u8] {
+ // should optimize out the assertion
+ self.initialize_unfilled_to(self.remaining())
+ }
+
+ /// Returns a mutable reference to the first `n` bytes of the unfilled part of the buffer, ensuring it is
+ /// fully initialized.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `self.remaining()` is less than `n`.
+ #[inline]
+ pub fn initialize_unfilled_to(&mut self, n: usize) -> &mut [u8] {
+ assert!(self.remaining() >= n);
+
+ let extra_init = self.initialized - self.filled;
+ // If we don't have enough initialized, do zeroing
+ if n > extra_init {
+ let uninit = n - extra_init;
+ let unfilled = &mut self.uninitialized_mut()[0..uninit];
+
+ for byte in unfilled.iter_mut() {
+ byte.write(0);
+ }
+
+ // SAFETY: we just initialized uninit bytes, and the previous bytes were already init
+ unsafe {
+ self.assume_init(n);
+ }
+ }
+
+ let filled = self.filled;
+
+ &mut self.initialized_mut()[filled..filled + n]
+ }
+
+ /// Returns the number of bytes at the end of the slice that have not yet been filled.
+ #[inline]
+ pub fn remaining(&self) -> usize {
+ self.capacity() - self.filled
+ }
+
+ /// Clears the buffer, resetting the filled region to empty.
+ ///
+ /// The number of initialized bytes is not changed, and the contents of the buffer are not modified.
+ #[inline]
+ pub fn clear(&mut self) {
+ self.set_filled(0); // The assertion in `set_filled` is optimized out
+ }
+
+ /// Increases the size of the filled region of the buffer.
+ ///
+ /// The number of initialized bytes is not changed.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the filled region of the buffer would become larger than the initialized region.
+ #[inline]
+ pub fn add_filled(&mut self, n: usize) {
+ self.set_filled(self.filled + n);
+ }
+
+ /// Sets the size of the filled region of the buffer.
+ ///
+ /// The number of initialized bytes is not changed.
+ ///
+ /// Note that this can be used to *shrink* the filled region of the buffer in addition to growing it (for
+ /// example, by a `Read` implementation that compresses data in-place).
+ ///
+ /// # Panics
+ ///
+ /// Panics if the filled region of the buffer would become larger than the initialized region.
+ #[inline]
+ pub fn set_filled(&mut self, n: usize) {
+ assert!(n <= self.initialized);
+
+ self.filled = n;
+ }
+
+ /// Asserts that the first `n` unfilled bytes of the buffer are initialized.
+ ///
+ /// `ReadBuf` assumes that bytes are never de-initialized, so this method does nothing when called with fewer
+ /// bytes than are already known to be initialized.
+ ///
+ /// # Safety
+ ///
+ /// The caller must ensure that the first `n` unfilled bytes of the buffer have already been initialized.
+ #[inline]
+ pub unsafe fn assume_init(&mut self, n: usize) {
+ self.initialized = cmp::max(self.initialized, self.filled + n);
+ }
+
+ /// Appends data to the buffer, advancing the written position and possibly also the initialized position.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `self.remaining()` is less than `buf.len()`.
+ #[inline]
+ pub fn append(&mut self, buf: &[u8]) {
+ assert!(self.remaining() >= buf.len());
+
+ // SAFETY: we do not de-initialize any of the elements of the slice
+ unsafe {
+ MaybeUninit::write_slice(&mut self.unfilled_mut()[..buf.len()], buf);
+ }
+
+ // SAFETY: We just added the entire contents of buf to the filled section.
+ unsafe { self.assume_init(buf.len()) }
+ self.add_filled(buf.len());
+ }
+
+ /// Returns the amount of bytes that have been filled.
+ #[inline]
+ pub fn filled_len(&self) -> usize {
+ self.filled
+ }
+
+ /// Returns the amount of bytes that have been initialized.
+ #[inline]
+ pub fn initialized_len(&self) -> usize {
+ self.initialized
+ }
+}
diff --git a/sgx_tstd/src/io/stdio.rs b/sgx_tstd/src/io/stdio.rs
index bb72030..8a18478 100644
--- a/sgx_tstd/src/io/stdio.rs
+++ b/sgx_tstd/src/io/stdio.rs
@@ -19,7 +19,7 @@
use crate::cell::RefCell;
use crate::fmt;
-use crate::io::{self, BufReader, Initializer, IoSlice, IoSliceMut, LineWriter, Lines, Split};
+use crate::io::{self, BufReader, IoSlice, IoSliceMut, LineWriter, Lines};
use crate::lazy::SyncOnceCell;
use crate::pin::Pin;
use crate::sync::{SgxMutex as Mutex, SgxMutexGuard as MutexGuard};
@@ -93,11 +93,6 @@
self.0.is_read_vectored()
}
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
-
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
handle_ebadf(self.0.read_to_end(buf), 0)
}
@@ -447,28 +442,6 @@
pub fn lines(self) -> Lines<StdinLock<'static>> {
self.into_locked().lines()
}
-
- /// Consumes this handle and returns an iterator over input bytes,
- /// split at the specified byte value.
- ///
- /// For detailed semantics of this method, see the documentation on
- /// [`BufRead::split`].
- ///
- /// # Examples
- ///
- /// ```no_run
- /// #![feature(stdin_forwarders)]
- /// use std::io;
- ///
- /// let splits = io::stdin().split(b'-');
- /// for split in splits {
- /// println!("got a chunk: {}", String::from_utf8_lossy(&split.unwrap()));
- /// }
- /// ```
- #[must_use = "`self` will be dropped if the result is not used"]
- pub fn split(self, byte: u8) -> Split<StdinLock<'static>> {
- self.into_locked().split(byte)
- }
}
impl fmt::Debug for Stdin {
@@ -488,10 +461,6 @@
fn is_read_vectored(&self) -> bool {
self.lock().is_read_vectored()
}
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.lock().read_to_end(buf)
}
@@ -524,11 +493,6 @@
self.inner.is_read_vectored()
}
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
-
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.inner.read_to_end(buf)
}
diff --git a/sgx_tstd/src/io/util.rs b/sgx_tstd/src/io/util.rs
index 16f8055..efc956d 100644
--- a/sgx_tstd/src/io/util.rs
+++ b/sgx_tstd/src/io/util.rs
@@ -19,7 +19,7 @@
use crate::fmt;
use crate::io::{
- self, BufRead, Initializer, IoSlice, IoSliceMut, Read, Seek, SeekFrom, SizeHint, Write,
+ self, BufRead, IoSlice, IoSliceMut, Read, ReadBuf, Seek, SeekFrom, SizeHint, Write,
};
/// A reader which is always at EOF.
@@ -57,8 +57,8 @@
}
#[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
+ fn read_buf(&mut self, _buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ Ok(())
}
}
@@ -134,6 +134,24 @@
Ok(buf.len())
}
+ fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ // SAFETY: No uninit bytes are being written
+ for slot in unsafe { buf.unfilled_mut() } {
+ slot.write(self.byte);
+ }
+
+ let remaining = buf.remaining();
+
+ // SAFETY: the entire unfilled portion of buf has been initialized
+ unsafe {
+ buf.assume_init(remaining);
+ }
+
+ buf.add_filled(remaining);
+
+ Ok(())
+ }
+
#[inline]
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
let mut nwritten = 0;
@@ -147,11 +165,6 @@
fn is_read_vectored(&self) -> bool {
true
}
-
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
}
impl SizeHint for Repeat {
diff --git a/sgx_tstd/src/lib.rs b/sgx_tstd/src/lib.rs
index 7f3b018..e7fe9ff 100644
--- a/sgx_tstd/src/lib.rs
+++ b/sgx_tstd/src/lib.rs
@@ -46,39 +46,36 @@
#![allow(clippy::declare_interior_mutable_const)]
#![allow(clippy::len_without_is_empty)]
-#![allow(clippy::mem_replace_with_default)]
#![allow(clippy::missing_safety_doc)]
#![allow(clippy::new_without_default)]
#![allow(clippy::transmute_ptr_to_ptr)]
#![allow(clippy::wrong_self_convention)]
#![feature(rustc_allow_const_fn_unstable)]
-
#![feature(alloc_error_handler)]
#![feature(allocator_api)]
#![feature(allocator_internals)]
#![feature(allow_internal_unsafe)]
#![feature(allow_internal_unstable)]
#![feature(array_error_internals)]
-#![feature(asm)]
#![feature(assert_matches)]
-#![feature(async_stream)]
+#![feature(async_iterator)]
#![feature(bench_black_box)]
#![feature(bool_to_option)]
#![feature(box_syntax)]
-#![feature(c_variadic)]
#![feature(c_unwind)]
+#![feature(c_variadic)]
#![feature(cfg_accessible)]
#![feature(cfg_eval)]
#![feature(cfg_target_has_atomic)]
#![feature(char_error_internals)]
#![feature(char_internals)]
+#![feature(concat_bytes)]
#![feature(concat_idents)]
-#![feature(const_caller_location)]
#![feature(const_fn_fn_ptr_basics)]
#![feature(const_fn_trait_bound)]
#![feature(const_format_args)]
-#![feature(const_raw_ptr_deref)]
+#![feature(const_mut_refs)]
#![feature(const_trait_impl)]
#![feature(core_intrinsics)]
#![feature(core_panic)]
@@ -88,23 +85,22 @@
#![feature(duration_checked_float)]
#![feature(duration_constants)]
#![feature(edition_panic)]
+#![feature(exact_size_is_empty)]
#![feature(extend_one)]
#![feature(fn_traits)]
+#![feature(float_minimum_maximum)]
#![feature(format_args_nl)]
#![feature(gen_future)]
#![feature(get_mut_unchecked)]
-#![feature(global_asm)]
#![feature(hashmap_internals)]
-#![feature(into_future)]
#![feature(int_error_internals)]
-#![feature(iter_zip)]
+#![feature(into_future)]
#![feature(lang_items)]
#![feature(linked_list_remove)]
-#![feature(llvm_asm)]
#![feature(log_syntax)]
#![feature(map_try_insert)]
-#![feature(maybe_uninit_extra)]
#![feature(maybe_uninit_slice)]
+#![feature(maybe_uninit_write_slice)]
#![feature(mixed_integer_ops)]
#![feature(must_not_suspend)]
#![feature(needs_panic_runtime)]
@@ -114,11 +110,13 @@
#![feature(once_cell)]
#![feature(panic_info_message)]
#![feature(panic_internals)]
+#![feature(panic_can_unwind)]
#![feature(panic_unwind)]
-#![feature(pin_static_ref)]
#![feature(prelude_import)]
+#![feature(ptr_as_uninit)]
#![feature(ptr_internals)]
#![feature(rustc_attrs)]
+#![feature(slice_internals)]
#![feature(specialization)]
#![feature(std_internals)]
#![feature(str_internals)]
@@ -130,7 +128,6 @@
#![feature(try_blocks)]
#![feature(try_reserve_kind)]
#![feature(unboxed_closures)]
-#![feature(vec_spare_capacity)]
#![default_lib_allocator]
// Explicitly import the prelude. The compiler uses this same unstable attribute
@@ -189,6 +186,7 @@
pub use alloc_crate::vec;
pub use core::any;
pub use core::array;
+pub use core::async_iter;
pub use core::cell;
pub use core::char;
pub use core::clone;
@@ -213,7 +211,6 @@
pub use core::pin;
pub use core::ptr;
pub use core::result;
-pub use core::stream;
pub use core::u128;
pub use core::u16;
pub use core::u32;
@@ -221,6 +218,11 @@
pub use core::u8;
pub use core::usize;
+// The runtime entry point and a few unstable public functions used by the
+// compiler
+#[macro_use]
+pub mod rt;
+
pub mod f32;
pub mod f64;
@@ -257,10 +259,14 @@
pub use alloc_crate::task::*;
}
-// The runtime entry point and a few unstable public functions used by the
-// compiler
-#[macro_use]
-pub mod rt;
+pub mod arch {
+ // The `no_inline`-attribute is required to make the documentation of all
+ // targets available.
+ // See https://github.com/rust-lang/rust/pull/57808#issuecomment-457390549 for
+ // more information.
+ #[doc(no_inline)] // Note (#82861): required for correct documentation
+ pub use core::arch::*;
+}
// Platform-abstraction modules
mod sys;
@@ -295,10 +301,12 @@
#[allow(deprecated)]
pub use core::{
assert, assert_matches, cfg, column, compile_error, concat, concat_idents, const_format_args,
- env, file, format_args, format_args_nl, include, include_bytes, include_str, line, llvm_asm,
- log_syntax, module_path, option_env, stringify, trace_macros,
+ env, file, format_args, format_args_nl, include, include_bytes, include_str, line, log_syntax,
+ module_path, option_env, stringify, trace_macros,
};
+pub use core::concat_bytes;
+
pub use core::primitive;
mod sealed {
diff --git a/sgx_tstd/src/macros.rs b/sgx_tstd/src/macros.rs
index e992568..5b4e7d0 100644
--- a/sgx_tstd/src/macros.rs
+++ b/sgx_tstd/src/macros.rs
@@ -70,7 +70,9 @@
///
/// io::stdout().flush().unwrap();
/// ```
+#[cfg(feature = "stdio")]
#[macro_export]
+#[cfg_attr(not(test), rustc_diagnostic_item = "print_macro")]
#[allow_internal_unstable(print_internals)]
macro_rules! print {
($($arg:tt)*) => ($crate::io::_print($crate::format_args!($($arg)*)));
@@ -102,7 +104,9 @@
/// println!("hello there!");
/// println!("format {} arguments", "some");
/// ```
+#[cfg(feature = "stdio")]
#[macro_export]
+#[cfg_attr(not(test), rustc_diagnostic_item = "println_macro")]
#[allow_internal_unstable(print_internals, format_args_nl)]
macro_rules! println {
() => ($crate::print!("\n"));
@@ -113,10 +117,12 @@
#[cfg(not(feature = "stdio"))]
#[macro_export]
+#[cfg_attr(not(test), rustc_diagnostic_item = "print_macro")]
macro_rules! print { ($($arg:tt)*) => ({}) }
#[cfg(not(feature = "stdio"))]
#[macro_export]
+#[cfg_attr(not(test), rustc_diagnostic_item = "println_macro")]
macro_rules! println { ($($arg:tt)*) => ({}) }
/// Prints to the standard error.
@@ -140,7 +146,9 @@
/// ```
/// eprint!("Error: Could not complete task");
/// ```
+#[cfg(feature = "stdio")]
#[macro_export]
+#[cfg_attr(not(test), rustc_diagnostic_item = "eprint_macro")]
#[allow_internal_unstable(print_internals)]
macro_rules! eprint {
($($arg:tt)*) => ($crate::io::_eprint($crate::format_args!($($arg)*)));
@@ -167,7 +175,9 @@
/// ```
/// eprintln!("Error: Could not complete task");
/// ```
+#[cfg(feature = "stdio")]
#[macro_export]
+#[cfg_attr(not(test), rustc_diagnostic_item = "eprintln_macro")]
#[allow_internal_unstable(print_internals, format_args_nl)]
macro_rules! eprintln {
() => ($crate::eprint!("\n"));
@@ -178,10 +188,12 @@
#[cfg(not(feature = "stdio"))]
#[macro_export]
+#[cfg_attr(not(test), rustc_diagnostic_item = "eprint_macro")]
macro_rules! eprint { ($($arg:tt)*) => ({}) }
#[cfg(not(feature = "stdio"))]
#[macro_export]
+#[cfg_attr(not(test), rustc_diagnostic_item = "eprintln_macro")]
macro_rules! eprintln { ($($arg:tt)*) => ({}) }
/// Prints and returns the value of a given expression for quick and dirty
@@ -309,6 +321,7 @@
/// [`debug!`]: https://docs.rs/log/*/log/macro.debug.html
/// [`log`]: https://crates.io/crates/log
#[macro_export]
+#[cfg_attr(not(test), rustc_diagnostic_item = "dbg_macro")]
macro_rules! dbg {
// NOTE: We cannot use `concat!` to make a static string as a format argument
// of `eprintln!` because `file!` could contain a `{` or
diff --git a/sgx_tstd/src/net/addr.rs b/sgx_tstd/src/net/addr.rs
index 83a4dbc..affcf4d 100644
--- a/sgx_tstd/src/net/addr.rs
+++ b/sgx_tstd/src/net/addr.rs
@@ -919,8 +919,7 @@
}
#[cfg(feature = "net")]
-#[allow(clippy::unnecessary_wraps)]
-#[allow(clippy::needless_collect)]
+#[allow(clippy::unnecessary_wraps, clippy::needless_collect)]
fn resolve_socket_addr(lh: LookupHost) -> io::Result<vec::IntoIter<SocketAddr>> {
let p = lh.port();
let v: Vec<_> = lh
@@ -948,7 +947,7 @@
}
#[cfg(not(feature = "net"))]
- let r = Err(io::Error::new_const(io::ErrorKind::InvalidInput, &"invalid socket address"));
+ let r = Err(io::const_io_error!(io::ErrorKind::InvalidInput, "invalid socket address"));
#[cfg(feature = "net")]
let r = resolve_socket_addr((host, port).try_into()?);
r
@@ -972,7 +971,7 @@
}
#[cfg(not(feature = "net"))]
- let r = Err(io::Error::new_const(io::ErrorKind::InvalidInput, &"invalid socket address"));
+ let r = Err(io::const_io_error!(io::ErrorKind::InvalidInput, "invalid socket address"));
#[cfg(feature = "net")]
let r = resolve_socket_addr(self.try_into()?);
r
diff --git a/sgx_tstd/src/net/ip.rs b/sgx_tstd/src/net/ip.rs
index 79503e7..2bcf01e 100644
--- a/sgx_tstd/src/net/ip.rs
+++ b/sgx_tstd/src/net/ip.rs
@@ -841,12 +841,7 @@
#[inline]
#[allow(clippy::match_like_matches_macro)]
pub const fn is_documentation(&self) -> bool {
- match self.octets() {
- [192, 0, 2, _] => true,
- [198, 51, 100, _] => true,
- [203, 0, 113, _] => true,
- _ => false,
- }
+ matches!(self.octets(), [192, 0, 2, _] | [198, 51, 100, _] | [203, 0, 113, _])
}
/// Converts this address to an [IPv4-compatible] [`IPv6` address].
@@ -1087,8 +1082,8 @@
/// ```
/// use std::net::Ipv4Addr;
///
- /// let addr = Ipv4Addr::new(0xca, 0xfe, 0xba, 0xbe);
- /// assert_eq!(0xcafebabe, u32::from(addr));
+ /// let addr = Ipv4Addr::new(0x12, 0x34, 0x56, 0x78);
+ /// assert_eq!(0x12345678, u32::from(addr));
/// ```
#[inline]
fn from(ip: Ipv4Addr) -> u32 {
@@ -1105,8 +1100,8 @@
/// ```
/// use std::net::Ipv4Addr;
///
- /// let addr = Ipv4Addr::from(0xcafebabe);
- /// assert_eq!(Ipv4Addr::new(0xca, 0xfe, 0xba, 0xbe), addr);
+ /// let addr = Ipv4Addr::from(0x12345678);
+ /// assert_eq!(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78), addr);
/// ```
#[inline]
fn from(ip: u32) -> Ipv4Addr {
@@ -1161,7 +1156,6 @@
/// let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff);
/// ```
#[allow(clippy::too_many_arguments)]
- #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
#[must_use]
#[inline]
pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr {
@@ -1736,7 +1730,7 @@
}
}
} else {
- // Slow path: write the address to a local buffer, the use f.pad.
+ // Slow path: write the address to a local buffer, then use f.pad.
// Defined recursively by using the fast path to write to the
// buffer.
diff --git a/sgx_tstd/src/net/mod.rs b/sgx_tstd/src/net/mod.rs
index 1796702..f6c9de4 100644
--- a/sgx_tstd/src/net/mod.rs
+++ b/sgx_tstd/src/net/mod.rs
@@ -32,12 +32,14 @@
//! with networking objects like [`TcpListener`], [`TcpStream`] or [`UdpSocket`]
//! * Other types are return or parameter types for various methods in this module
-use crate::io::{self, Error, ErrorKind};
+use crate::io::{self, ErrorKind};
pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
pub use self::ip::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
pub use self::parser::AddrParseError;
#[cfg(feature = "net")]
+pub use self::tcp::IntoIncoming;
+#[cfg(feature = "net")]
pub use self::tcp::{Incoming, TcpListener, TcpStream};
#[cfg(feature = "net")]
pub use self::udp::UdpSocket;
@@ -96,6 +98,6 @@
}
}
Err(last_err.unwrap_or_else(|| {
- Error::new_const(ErrorKind::InvalidInput, &"could not resolve to any addresses")
+ io::const_io_error!(ErrorKind::InvalidInput, "could not resolve to any addresses")
}))
}
\ No newline at end of file
diff --git a/sgx_tstd/src/net/tcp.rs b/sgx_tstd/src/net/tcp.rs
index b939990..bdcadd5 100644
--- a/sgx_tstd/src/net/tcp.rs
+++ b/sgx_tstd/src/net/tcp.rs
@@ -18,7 +18,7 @@
use crate::io::prelude::*;
use crate::fmt;
-use crate::io::{self, Initializer, IoSlice, IoSliceMut};
+use crate::io::{self, IoSlice, IoSliceMut};
use crate::net::{Shutdown, SocketAddr, ToSocketAddrs};
use crate::sys_common::net as net_imp;
use crate::sys_common::{AsInner, FromInner, IntoInner};
@@ -448,7 +448,7 @@
/// use std::net::TcpStream;
///
/// let stream = TcpStream::connect("127.0.0.1:8000")
- /// .expect("couldn't bind to address");
+ /// .expect("Couldn't connect to the server...");
/// let mut buf = [0; 10];
/// let len = stream.peek(&mut buf).expect("peek failed");
/// ```
@@ -659,12 +659,6 @@
fn is_read_vectored(&self) -> bool {
self.0.is_read_vectored()
}
-
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- // SAFETY: Read is guaranteed to work on uninitialized memory
- Initializer::nop()
- }
}
impl Write for TcpStream {
@@ -699,12 +693,6 @@
fn is_read_vectored(&self) -> bool {
self.0.is_read_vectored()
}
-
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- // SAFETY: Read is guaranteed to work on uninitialized memory
- Initializer::nop()
- }
}
impl Write for &TcpStream {
diff --git a/sgx_tstd/src/net/udp.rs b/sgx_tstd/src/net/udp.rs
index 2ba2f0b..52ddab8 100644
--- a/sgx_tstd/src/net/udp.rs
+++ b/sgx_tstd/src/net/udp.rs
@@ -16,7 +16,7 @@
// under the License..
use crate::fmt;
-use crate::io::{self, Error, ErrorKind};
+use crate::io::{self, ErrorKind};
use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs};
use crate::sys_common::net as net_imp;
use crate::sys_common::{AsInner, FromInner, IntoInner};
@@ -203,7 +203,9 @@
pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A) -> io::Result<usize> {
match addr.to_socket_addrs()?.next() {
Some(addr) => self.0.send_to(buf, &addr),
- None => Err(Error::new_const(ErrorKind::InvalidInput, &"no addresses to send data to")),
+ None => {
+ Err(io::const_io_error!(ErrorKind::InvalidInput, "no addresses to send data to"))
+ }
}
}
diff --git a/sgx_tstd/src/os/fd/owned.rs b/sgx_tstd/src/os/fd/owned.rs
index 4f00737..ca7d353 100644
--- a/sgx_tstd/src/os/fd/owned.rs
+++ b/sgx_tstd/src/os/fd/owned.rs
@@ -21,10 +21,11 @@
use super::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::fmt;
+use crate::fs;
use crate::marker::PhantomData;
use crate::mem::forget;
+use crate::sys::cvt;
use crate::sys_common::{AsInner, FromInner, IntoInner};
-use crate::untrusted::fs;
/// A borrowed file descriptor.
///
@@ -80,6 +81,21 @@
}
}
+impl OwnedFd {
+ /// Creates a new `OwnedFd` instance that shares the same underlying file handle
+ /// as the existing `OwnedFd` instance.
+ pub fn try_clone(&self) -> crate::io::Result<Self> {
+ // We want to atomically duplicate this file descriptor and set the
+ // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This
+ // is a POSIX flag that was added to Linux in 2.6.24.
+ let cmd = libc::F_DUPFD_CLOEXEC;
+
+ let fd = cvt(unsafe { libc::fcntl_arg1(self.as_raw_fd(), cmd, 0) })?;
+ Ok(unsafe { Self::from_raw_fd(fd) })
+ }
+
+}
+
impl AsRawFd for BorrowedFd<'_> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
@@ -171,6 +187,20 @@
fn as_fd(&self) -> BorrowedFd<'_>;
}
+impl<T: AsFd> AsFd for &T {
+ #[inline]
+ fn as_fd(&self) -> BorrowedFd<'_> {
+ T::as_fd(self)
+ }
+}
+
+impl<T: AsFd> AsFd for &mut T {
+ #[inline]
+ fn as_fd(&self) -> BorrowedFd<'_> {
+ T::as_fd(self)
+ }
+}
+
impl AsFd for BorrowedFd<'_> {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
@@ -291,5 +321,6 @@
}
mod libc {
- pub use sgx_libc::ocall::close;
+ pub use sgx_libc::F_DUPFD_CLOEXEC;
+ pub use sgx_libc::ocall::{close, fcntl_arg1};
}
diff --git a/sgx_tstd/src/os/fd/raw.rs b/sgx_tstd/src/os/fd/raw.rs
index d73008d..44a63fb 100644
--- a/sgx_tstd/src/os/fd/raw.rs
+++ b/sgx_tstd/src/os/fd/raw.rs
@@ -17,12 +17,14 @@
//! Raw Unix-like file descriptors.
+use crate::fs;
+#[cfg(feature = "stdio")]
use crate::io;
use crate::os::raw;
use crate::os::unix::io::OwnedFd;
use crate::sys_common::{AsInner, IntoInner};
-use crate::untrusted::fs;
+#[cfg(feature = "stdio")]
use sgx_libc as libc;
/// Raw file descriptors.
diff --git a/sgx_tstd/src/os/fs.rs b/sgx_tstd/src/os/linux/fs.rs
similarity index 97%
rename from sgx_tstd/src/os/fs.rs
rename to sgx_tstd/src/os/linux/fs.rs
index 2305e1a..478350c 100644
--- a/sgx_tstd/src/os/fs.rs
+++ b/sgx_tstd/src/os/linux/fs.rs
@@ -15,16 +15,15 @@
// specific language governing permissions and limitations
// under the License..
-//! Linux-specific extensions to primitives in the `std::fs` module.
+//! Linux-specific extensions to primitives in the [`std::fs`] module.
+//!
+//! [`std::fs`]: crate::fs
-#[cfg(feature = "untrusted_fs")]
use crate::fs::Metadata;
use crate::sys_common::AsInner;
-#[cfg(not(feature = "untrusted_fs"))]
-use crate::untrusted::fs::Metadata;
#[allow(deprecated)]
-use crate::os::raw;
+use crate::os::linux::raw;
use sgx_libc as libc;
diff --git a/sgx_tstd/src/os/linux/mod.rs b/sgx_tstd/src/os/linux/mod.rs
new file mode 100644
index 0000000..473f2ef
--- /dev/null
+++ b/sgx_tstd/src/os/linux/mod.rs
@@ -0,0 +1,21 @@
+// 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..
+
+//! Linux-specific definitions.
+
+pub mod fs;
+pub mod raw;
diff --git a/sgx_tstd/src/os/raw.rs b/sgx_tstd/src/os/linux/raw.rs
similarity index 73%
rename from sgx_tstd/src/os/raw.rs
rename to sgx_tstd/src/os/linux/raw.rs
index 1defce6..8639757 100644
--- a/sgx_tstd/src/os/raw.rs
+++ b/sgx_tstd/src/os/linux/raw.rs
@@ -17,34 +17,17 @@
//! Linux-specific raw type definitions.
-pub type c_char = i8;
-pub type c_schar = i8;
-pub type c_uchar = u8;
-pub type c_short = i16;
-pub type c_ushort = u16;
-pub type c_int = i32;
-pub type c_uint = u32;
-#[cfg(target_pointer_width = "32")]
-pub type c_long = i32;
-#[cfg(target_pointer_width = "32")]
-pub type c_ulong = u32;
-#[cfg(target_pointer_width = "64")]
-pub type c_long = i64;
-#[cfg(target_pointer_width = "64")]
-pub type c_ulong = u64;
-pub type c_longlong = i64;
-pub type c_ulonglong = u64;
-pub type c_float = f32;
-pub type c_double = f64;
+#![allow(deprecated)]
-#[doc(no_inline)]
-pub use core::ffi::c_void;
+use crate::os::raw::c_void;
pub type dev_t = u64;
pub type mode_t = u32;
pub type pthread_t = *mut c_void;
-pub use self::arch::{off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t};
+#[doc(inline)]
+pub use self::arch::{blkcnt_t, blksize_t, ino_t, nlink_t, off_t, stat, time_t};
+
mod arch {
use crate::os::raw::{c_long, c_int};
@@ -78,4 +61,4 @@
pub st_ctime_nsec: c_long,
pub __unused: [c_long; 3],
}
-}
\ No newline at end of file
+}
diff --git a/sgx_tstd/src/os/mod.rs b/sgx_tstd/src/os/mod.rs
index 657af0e..e8c86c1 100644
--- a/sgx_tstd/src/os/mod.rs
+++ b/sgx_tstd/src/os/mod.rs
@@ -17,7 +17,7 @@
//! OS-specific functionality.
-pub mod fs;
+pub mod linux;
pub mod raw;
pub mod unix;
diff --git a/sgx_tstd/src/os/raw/mod.rs b/sgx_tstd/src/os/raw/mod.rs
new file mode 100644
index 0000000..57515b6
--- /dev/null
+++ b/sgx_tstd/src/os/raw/mod.rs
@@ -0,0 +1,89 @@
+// 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..
+
+//! Platform-specific types, as defined by C.
+//!
+//! Code that interacts via FFI will almost certainly be using the
+//! base types provided by C, which aren't nearly as nicely defined
+//! as Rust's primitive types. This module provides types which will
+//! match those defined by C, so that code that interacts with C will
+//! refer to the correct types.
+
+use core::num::*;
+
+macro_rules! type_alias_no_nz {
+ {
+ $Alias:ident = $Real:ty;
+ $( $Cfg:tt )*
+ } => {
+ $( $Cfg )*
+ pub type $Alias = $Real;
+ }
+}
+
+macro_rules! type_alias {
+ {
+ $Alias:ident = $Real:ty, $NZAlias:ident = $NZReal:ty;
+ $( $Cfg:tt )*
+ } => {
+ type_alias_no_nz! { $Alias = $Real; $( $Cfg )* }
+
+ $( $Cfg )*
+ pub type $NZAlias = $NZReal;
+ }
+}
+
+type_alias! { c_char = i8, NonZero_c_char = NonZeroI8; }
+type_alias! { c_schar = i8, NonZero_c_schar = NonZeroI8; }
+type_alias! { c_uchar = u8, NonZero_c_uchar = NonZeroU8; }
+type_alias! { c_short = i16, NonZero_c_short = NonZeroI16; }
+type_alias! { c_ushort = u16, NonZero_c_ushort = NonZeroU16; }
+type_alias! { c_int = i32, NonZero_c_int = NonZeroI32; }
+type_alias! { c_uint = u32, NonZero_c_uint = NonZeroU32; }
+type_alias! { c_long = i32, NonZero_c_long = NonZeroI32;
+#[cfg(target_pointer_width = "32")] }
+type_alias! { c_ulong = u32, NonZero_c_ulong = NonZeroU32;
+#[cfg(target_pointer_width = "32")] }
+type_alias! { c_long = i64, NonZero_c_long = NonZeroI64;
+#[cfg(target_pointer_width = "64")] }
+type_alias! { c_ulong = u64, NonZero_c_ulong = NonZeroU64;
+#[cfg(target_pointer_width = "64")] }
+type_alias! { c_longlong = i64, NonZero_c_longlong = NonZeroI64; }
+type_alias! { c_ulonglong = u64, NonZero_c_ulonglong = NonZeroU64; }
+type_alias_no_nz! { c_float = f32; }
+type_alias_no_nz! { c_double = f64; }
+
+#[doc(no_inline)]
+pub use core::ffi::c_void;
+
+/// Equivalent to C's `size_t` type, from `stddef.h` (or `cstddef` for C++).
+///
+/// This type is currently always [`usize`], however in the future there may be
+/// platforms where this is not the case.
+pub type c_size_t = usize;
+
+/// Equivalent to C's `ptrdiff_t` type, from `stddef.h` (or `cstddef` for C++).
+///
+/// This type is currently always [`isize`], however in the future there may be
+/// platforms where this is not the case.
+pub type c_ptrdiff_t = isize;
+
+/// Equivalent to C's `ssize_t` (on POSIX) or `SSIZE_T` (on Windows) type.
+///
+/// This type is currently always [`isize`], however in the future there may be
+/// platforms where this is not the case.
+pub type c_ssize_t = isize;
diff --git a/sgx_tstd/src/os/unix/ffi/os_str.rs b/sgx_tstd/src/os/unix/ffi/os_str.rs
index c06e5ea..5ba5083 100644
--- a/sgx_tstd/src/os/unix/ffi/os_str.rs
+++ b/sgx_tstd/src/os/unix/ffi/os_str.rs
@@ -41,9 +41,11 @@
}
impl OsStringExt for OsString {
+ #[inline]
fn from_vec(vec: Vec<u8>) -> OsString {
FromInner::from_inner(Buf { inner: vec })
}
+ #[inline]
fn into_vec(self) -> Vec<u8> {
self.into_inner().inner
}
diff --git a/sgx_tstd/src/os/unix/fs.rs b/sgx_tstd/src/os/unix/fs.rs
index c5487a2..3e0de5d 100644
--- a/sgx_tstd/src/os/unix/fs.rs
+++ b/sgx_tstd/src/os/unix/fs.rs
@@ -15,14 +15,17 @@
// specific language governing permissions and limitations
// under the License..
-//! Unix-specific extensions to primitives in the `std::fs` module.
+//! Unix-specific extensions to primitives in the [`std::fs`] module.
+//!
+//! [`std::fs`]: crate::fs
+use super::platform::fs::MetadataExt as _;
+use crate::fs::{self, OpenOptions, Permissions};
use crate::io;
-use crate::os::fs::MetadataExt as _;
+use crate::os::unix::io::{AsFd, AsRawFd};
use crate::path::Path;
use crate::sys;
use crate::sys_common::{AsInner, AsInnerMut, FromInner};
-use crate::untrusted::fs::{self, OpenOptions, Permissions};
// Used for `File::read` on intra-doc links
use crate::ffi::OsStr;
use crate::sealed::Sealed;
@@ -125,7 +128,7 @@
}
}
if !buf.is_empty() {
- Err(io::Error::new_const(io::ErrorKind::UnexpectedEof, &"failed to fill whole buffer"))
+ Err(io::const_io_error!(io::ErrorKind::UnexpectedEof, "failed to fill whole buffer",))
} else {
Ok(())
}
@@ -205,9 +208,9 @@
while !buf.is_empty() {
match self.write_at(buf, offset) {
Ok(0) => {
- return Err(io::Error::new_const(
+ return Err(io::const_io_error!(
io::ErrorKind::WriteZero,
- &"failed to write whole buffer",
+ "failed to write whole buffer",
));
}
Ok(n) => {
@@ -885,6 +888,72 @@
}
}
+/// Change the owner and group of the specified path.
+///
+/// Specifying either the uid or gid as `None` will leave it unchanged.
+///
+/// Changing the owner typically requires privileges, such as root or a specific capability.
+/// Changing the group typically requires either being the owner and a member of the group, or
+/// having privileges.
+///
+/// If called on a symbolic link, this will change the owner and group of the link target. To
+/// change the owner and group of the link itself, see [`lchown`].
+///
+/// # Examples
+///
+/// ```no_run
+/// #![feature(unix_chown)]
+/// use std::os::unix::fs;
+///
+/// fn main() -> std::io::Result<()> {
+/// fs::chown("/sandbox", Some(0), Some(0))?;
+/// Ok(())
+/// }
+/// ```
+pub fn chown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
+ sys::fs::chown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
+}
+
+/// Change the owner and group of the file referenced by the specified open file descriptor.
+///
+/// For semantics and required privileges, see [`chown`].
+///
+/// # Examples
+///
+/// ```no_run
+/// #![feature(unix_chown)]
+/// use std::os::unix::fs;
+///
+/// fn main() -> std::io::Result<()> {
+/// let f = std::fs::File::open("/file")?;
+/// fs::fchown(&f, Some(0), Some(0))?;
+/// Ok(())
+/// }
+/// ```
+pub fn fchown<F: AsFd>(fd: F, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
+ sys::fs::fchown(fd.as_fd().as_raw_fd(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
+}
+
+/// Change the owner and group of the specified path, without dereferencing symbolic links.
+///
+/// Identical to [`chown`], except that if called on a symbolic link, this will change the owner
+/// and group of the link itself rather than the owner and group of the link target.
+///
+/// # Examples
+///
+/// ```no_run
+/// #![feature(unix_chown)]
+/// use std::os::unix::fs;
+///
+/// fn main() -> std::io::Result<()> {
+/// fs::lchown("/symlink", Some(0), Some(0))?;
+/// Ok(())
+/// }
+/// ```
+pub fn lchown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
+ sys::fs::lchown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
+}
+
/// Change the root directory of the current process to the specified path.
///
/// This typically requires privileges, such as root or a specific capability.
diff --git a/sgx_tstd/src/os/unix/io/fd.rs b/sgx_tstd/src/os/unix/io/fd.rs
index f855305..88143de 100644
--- a/sgx_tstd/src/os/unix/io/fd.rs
+++ b/sgx_tstd/src/os/unix/io/fd.rs
@@ -15,7 +15,6 @@
// specific language governing permissions and limitations
// under the License..
-
//! Owned and borrowed file descriptors.
pub use crate::os::fd::owned::*;
diff --git a/sgx_tstd/src/os/unix/mod.rs b/sgx_tstd/src/os/unix/mod.rs
index 11c2de6..11fc726 100644
--- a/sgx_tstd/src/os/unix/mod.rs
+++ b/sgx_tstd/src/os/unix/mod.rs
@@ -21,8 +21,8 @@
//! exposes Unix-specific functions that would otherwise be inappropriate as
//! part of the core `std` library.
//!
-//! It exposes more ways to deal with platform-specific strings (`OsStr`,
-//! `OsString`), allows to set permissions more granularly, extract low-level
+//! It exposes more ways to deal with platform-specific strings ([`OsStr`],
+//! [`OsString`]), allows to set permissions more granularly, extract low-level
//! file descriptors from files and sockets, and has platform-specific helpers
//! for spawning processes.
//!
@@ -45,6 +45,8 @@
//! [`OsStr`]: crate::ffi::OsStr
//! [`OsString`]: crate::ffi::OsString
+use crate::os::linux as platform;
+
pub mod ffi;
pub mod fs;
pub mod io;
@@ -71,6 +73,7 @@
#[doc(no_inline)]
pub use super::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
#[doc(no_inline)]
+ #[doc(no_inline)]
#[cfg(feature = "thread")]
pub use super::thread::JoinHandleExt;
}
diff --git a/sgx_tstd/src/os/unix/net/addr.rs b/sgx_tstd/src/os/unix/net/addr.rs
index 279caa9..8efe3af 100644
--- a/sgx_tstd/src/os/unix/net/addr.rs
+++ b/sgx_tstd/src/os/unix/net/addr.rs
@@ -19,7 +19,7 @@
use crate::os::unix::ffi::OsStrExt;
use crate::path::Path;
use crate::sys::cvt;
-use crate::{ascii, fmt, io, iter, mem};
+use crate::{ascii, fmt, io, mem, ptr};
use sgx_libc as libc;
fn sun_path_offset(addr: &libc::sockaddr_un) -> usize {
@@ -29,30 +29,33 @@
path - base
}
-pub(super) unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::socklen_t)> {
- let mut addr: libc::sockaddr_un = mem::zeroed();
+pub(super) fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::socklen_t)> {
+ // SAFETY: All zeros is a valid representation for `sockaddr_un`.
+ let mut addr: libc::sockaddr_un = unsafe { mem::zeroed() };
addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
let bytes = path.as_os_str().as_bytes();
if bytes.contains(&0) {
- return Err(io::Error::new_const(
+ return Err(io::const_io_error!(
io::ErrorKind::InvalidInput,
- &"paths must not contain interior null bytes",
+ "paths must not contain interior null bytes",
));
}
if bytes.len() >= addr.sun_path.len() {
- return Err(io::Error::new_const(
+ return Err(io::const_io_error!(
io::ErrorKind::InvalidInput,
- &"path must be shorter than SUN_LEN",
+ "path must be shorter than SUN_LEN",
));
}
- for (dst, src) in iter::zip(&mut addr.sun_path, bytes) {
- *dst = *src as libc::c_char;
- }
- // null byte for pathname addresses is already there because we zeroed the
- // struct
+ // SAFETY: `bytes` and `addr.sun_path` are not overlapping and
+ // both point to valid memory.
+ // NOTE: We zeroed the memory above, so the path is already null
+ // terminated.
+ unsafe {
+ ptr::copy_nonoverlapping(bytes.as_ptr(), addr.sun_path.as_mut_ptr().cast(), bytes.len())
+ };
let mut len = sun_path_offset(&addr) + bytes.len();
match bytes.get(0) {
@@ -124,15 +127,51 @@
// linux returns zero bytes of address
len = sun_path_offset(&addr) as libc::socklen_t; // i.e., zero-length address
} else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
- return Err(io::Error::new_const(
+ return Err(io::const_io_error!(
io::ErrorKind::InvalidInput,
- &"file descriptor did not correspond to a Unix socket",
+ "file descriptor did not correspond to a Unix socket",
));
}
Ok(SocketAddr { addr, len })
}
+ /// Constructs a `SockAddr` with the family `AF_UNIX` and the provided path.
+ ///
+ /// # Errors
+ ///
+ /// Returns an error if the path is longer than `SUN_LEN` or if it contains
+ /// NULL bytes.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(unix_socket_creation)]
+ /// use std::os::unix::net::SocketAddr;
+ /// use std::path::Path;
+ ///
+ /// # fn main() -> std::io::Result<()> {
+ /// let address = SocketAddr::from_path("/path/to/socket")?;
+ /// assert_eq!(address.as_pathname(), Some(Path::new("/path/to/socket")));
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// Creating a `SocketAddr` with a NULL byte results in an error.
+ ///
+ /// ```
+ /// #![feature(unix_socket_creation)]
+ /// use std::os::unix::net::SocketAddr;
+ ///
+ /// assert!(SocketAddr::from_path("/path/with/\0/bytes").is_err());
+ /// ```
+ pub fn from_path<P>(path: P) -> io::Result<SocketAddr>
+ where
+ P: AsRef<Path>,
+ {
+ sockaddr_un(path.as_ref()).map(|(addr, len)| SocketAddr { addr, len })
+ }
+
/// Returns `true` if the address is unnamed.
///
/// # Examples
@@ -277,9 +316,9 @@
addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
if namespace.len() + 1 > addr.sun_path.len() {
- return Err(io::Error::new_const(
+ return Err(io::const_io_error!(
io::ErrorKind::InvalidInput,
- &"namespace must be shorter than SUN_LEN",
+ "namespace must be shorter than SUN_LEN",
));
}
diff --git a/sgx_tstd/src/os/unix/net/listener.rs b/sgx_tstd/src/os/unix/net/listener.rs
index 498d368..ca91a3a 100644
--- a/sgx_tstd/src/os/unix/net/listener.rs
+++ b/sgx_tstd/src/os/unix/net/listener.rs
@@ -365,6 +365,7 @@
/// }
/// ```
#[derive(Debug)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct Incoming<'a> {
listener: &'a UnixListener,
}
diff --git a/sgx_tstd/src/os/unix/net/stream.rs b/sgx_tstd/src/os/unix/net/stream.rs
index c642623..5e797d4 100644
--- a/sgx_tstd/src/os/unix/net/stream.rs
+++ b/sgx_tstd/src/os/unix/net/stream.rs
@@ -18,7 +18,7 @@
use super::{recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to, SocketAncillary};
use super::{sockaddr_un, SocketAddr};
use crate::fmt;
-use crate::io::{self, Initializer, IoSlice, IoSliceMut};
+use crate::io::{self, IoSlice, IoSliceMut};
use crate::net::Shutdown;
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
use crate::os::unix::ucred;
@@ -556,11 +556,6 @@
fn is_read_vectored(&self) -> bool {
io::Read::is_read_vectored(&&*self)
}
-
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
}
impl<'a> io::Read for &'a UnixStream {
@@ -576,11 +571,6 @@
fn is_read_vectored(&self) -> bool {
self.0.is_read_vectored()
}
-
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
}
impl io::Write for UnixStream {
diff --git a/sgx_tstd/src/os/unix/raw.rs b/sgx_tstd/src/os/unix/raw.rs
index 8b094ba..93de8f8 100644
--- a/sgx_tstd/src/os/unix/raw.rs
+++ b/sgx_tstd/src/os/unix/raw.rs
@@ -17,6 +17,8 @@
//! Unix-specific primitives available on all unix platforms.
+#![allow(deprecated)]
+
#[allow(non_camel_case_types)]
pub type uid_t = u32;
#[allow(non_camel_case_types)]
@@ -25,8 +27,8 @@
pub type pid_t = i32;
#[doc(inline)]
-pub use crate::os::raw::pthread_t;
+pub use super::platform::raw::pthread_t;
#[doc(inline)]
-pub use crate::os::raw::{blkcnt_t, time_t};
+pub use super::platform::raw::{blkcnt_t, time_t};
#[doc(inline)]
-pub use crate::os::raw::{blksize_t, dev_t, ino_t, mode_t, nlink_t, off_t};
+pub use super::platform::raw::{blksize_t, dev_t, ino_t, mode_t, nlink_t, off_t};
diff --git a/sgx_tstd/src/os/unix/thread.rs b/sgx_tstd/src/os/unix/thread.rs
index 08127d4..5ac3ed1 100644
--- a/sgx_tstd/src/os/unix/thread.rs
+++ b/sgx_tstd/src/os/unix/thread.rs
@@ -15,7 +15,9 @@
// specific language governing permissions and limitations
// under the License..
-//! Unix-specific extensions to primitives in the `std::thread` module.
+//! Unix-specific extensions to primitives in the [`std::thread`] module.
+//!
+//! [`std::thread`]: crate::thread
#[allow(deprecated)]
use crate::os::unix::raw::pthread_t;
diff --git a/sgx_tstd/src/panic.rs b/sgx_tstd/src/panic.rs
index 5e05262..cca723a 100644
--- a/sgx_tstd/src/panic.rs
+++ b/sgx_tstd/src/panic.rs
@@ -20,6 +20,8 @@
use crate::any::Any;
use crate::collections;
use crate::panicking;
+#[cfg(feature = "backtrace")]
+use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::sync::{SgxMutex, SgxRwLock};
use crate::thread::Result;
@@ -48,6 +50,8 @@
pub use crate::panicking::{set_hook, take_hook};
+pub use crate::panicking::update_hook;
+
pub use core::panic::{Location, PanicInfo};
pub use core::panic::{AssertUnwindSafe, RefUnwindSafe, UnwindSafe};
@@ -199,3 +203,86 @@
pub fn always_abort() {
crate::panicking::panic_count::set_always_abort();
}
+
+/// The configuration for whether and how the default panic hook will capture
+/// and display the backtrace.
+#[cfg(feature = "backtrace")]
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[non_exhaustive]
+pub enum BacktraceStyle {
+ /// Prints a terser backtrace which ideally only contains relevant
+ /// information.
+ Short,
+ /// Prints a backtrace with all possible information.
+ Full,
+ /// Disable collecting and displaying backtraces.
+ Off,
+}
+
+#[cfg(feature = "backtrace")]
+impl BacktraceStyle {
+ pub(crate) fn full() -> Option<Self> {
+ Some(BacktraceStyle::Full)
+ }
+
+ fn as_usize(self) -> usize {
+ match self {
+ BacktraceStyle::Short => 1,
+ BacktraceStyle::Full => 2,
+ BacktraceStyle::Off => 3,
+ }
+ }
+
+ fn from_usize(s: usize) -> Option<Self> {
+ Some(match s {
+ 0 => return None,
+ 1 => BacktraceStyle::Short,
+ 2 => BacktraceStyle::Full,
+ 3 => BacktraceStyle::Off,
+ _ => unreachable!(),
+ })
+ }
+}
+
+// Tracks whether we should/can capture a backtrace, and how we should display
+// that backtrace.
+//
+// Internally stores equivalent of an Option<BacktraceStyle>.
+#[cfg(feature = "backtrace")]
+static SHOULD_CAPTURE: AtomicUsize = AtomicUsize::new(0);
+
+/// Configure whether the default panic hook will capture and display a
+/// backtrace.
+///
+/// The default value for this setting may be set by the `RUST_BACKTRACE`
+/// environment variable; see the details in [`get_backtrace_style`].
+#[cfg(feature = "backtrace")]
+pub fn set_backtrace_style(style: BacktraceStyle) {
+ SHOULD_CAPTURE.store(style.as_usize(), Ordering::Release);
+}
+
+/// Checks whether the standard library's panic hook will capture and print a
+/// backtrace.
+///
+/// This function will, if a backtrace style has not been set via
+/// [`set_backtrace_style`], read the environment variable `RUST_BACKTRACE` to
+/// determine a default value for the backtrace formatting:
+///
+/// The first call to `get_backtrace_style` may read the `RUST_BACKTRACE`
+/// environment variable if `set_backtrace_style` has not been called to
+/// override the default value. After a call to `set_backtrace_style` or
+/// `get_backtrace_style`, any changes to `RUST_BACKTRACE` will have no effect.
+///
+/// `RUST_BACKTRACE` is read according to these rules:
+///
+/// * `0` for `BacktraceStyle::Off`
+/// * `full` for `BacktraceStyle::Full`
+/// * `1` for `BacktraceStyle::Short`
+/// * Other values are currently `BacktraceStyle::Short`, but this may change in
+/// the future
+///
+/// Returns `None` if backtraces aren't currently supported.
+#[cfg(feature = "backtrace")]
+pub fn get_backtrace_style() -> Option<BacktraceStyle> {
+ BacktraceStyle::from_usize(SHOULD_CAPTURE.load(Ordering::Acquire))
+}
diff --git a/sgx_tstd/src/panicking.rs b/sgx_tstd/src/panicking.rs
index 561a814..9df0b38 100644
--- a/sgx_tstd/src/panicking.rs
+++ b/sgx_tstd/src/panicking.rs
@@ -24,15 +24,24 @@
//! * Executing a panic up to doing the actual implementation
//! * Shims around "try"
+#![deny(unsafe_op_in_unsafe_fn)]
+
+#[cfg(feature = "backtrace")]
+use crate::panic::BacktraceStyle;
use core::panic::{BoxMeUp, Location, PanicInfo};
use crate::any::Any;
use crate::fmt;
use crate::intrinsics;
use crate::mem::{self, ManuallyDrop};
-use crate::ptr;
-use crate::sync::atomic::{AtomicPtr, Ordering};
+#[cfg(feature = "backtrace")]
+use crate::sync::atomic::{AtomicBool, Ordering};
+#[cfg(feature = "stdio")]
use crate::sys::stdio::panic_output;
+#[cfg(feature = "backtrace")]
+use crate::sys_common::backtrace;
+use crate::sys_common::rwlock::SgxThreadRwLock;
+#[cfg(feature = "stdio")]
use crate::sys_common::thread_info;
use crate::thread;
@@ -76,7 +85,20 @@
rtabort!("Rust cannot catch foreign exceptions");
}
-static PANIC_HANDLER: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
+#[derive(Copy, Clone)]
+enum Hook {
+ Default,
+ Custom(*mut (dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send)),
+}
+
+impl Hook {
+ fn custom(f: impl Fn(&PanicInfo<'_>) + 'static + Sync + Send) -> Self {
+ Self::Custom(Box::into_raw(Box::new(f)))
+ }
+}
+
+static HOOK_LOCK: SgxThreadRwLock = SgxThreadRwLock::new();
+static mut HOOK: Hook = Hook::Default;
/// Registers a custom panic hook, replacing any that was previously registered.
///
@@ -98,11 +120,43 @@
///
/// Panics if called from a panicking thread.
///
-pub fn set_hook(hook: fn(&PanicInfo<'_>)) {
- assert!(!thread::panicking(), "cannot modify the panic hook from a panicking thread");
- PANIC_HANDLER.store(hook as *mut (), Ordering::SeqCst);
-}
+/// # Examples
+///
+/// The following will print "Custom panic hook":
+///
+/// ```should_panic
+/// use std::panic;
+///
+/// panic::set_hook(Box::new(|_| {
+/// println!("Custom panic hook");
+/// }));
+///
+/// panic!("Normal panic");
+/// ```
+pub fn set_hook(hook: Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send>) {
+ if thread::panicking() {
+ panic!("cannot modify the panic hook from a panicking thread");
+ }
+ // SAFETY:
+ //
+ // - `HOOK` can only be modified while holding write access to `HOOK_LOCK`.
+ // - The argument of `Box::from_raw` is always a valid pointer that was created using
+ // `Box::into_raw`.
+ unsafe {
+ let _guard = HOOK_LOCK.write();
+ let old_hook = HOOK;
+ HOOK = Hook::Custom(Box::into_raw(hook));
+ let _ = HOOK_LOCK.write_unlock();
+
+ if let Hook::Custom(ptr) = old_hook {
+ #[allow(unused_must_use)]
+ {
+ Box::from_raw(ptr);
+ }
+ }
+ }
+}
/// Unregisters the current panic hook, returning it.
///
@@ -115,29 +169,120 @@
/// # Panics
///
/// Panics if called from a panicking thread.
-///
-pub fn take_hook() -> fn(&PanicInfo<'_>) {
- let hook = PANIC_HANDLER.swap(ptr::null_mut(), Ordering::SeqCst);
- if hook.is_null() { default_hook } else { unsafe { mem::transmute(hook) } }
+///
+/// # Examples
+///
+/// The following will print "Normal panic":
+///
+/// ```should_panic
+/// use std::panic;
+///
+/// panic::set_hook(Box::new(|_| {
+/// println!("Custom panic hook");
+/// }));
+///
+/// let _ = panic::take_hook();
+///
+/// panic!("Normal panic");
+/// ```
+#[must_use]
+pub fn take_hook() -> Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send> {
+ if thread::panicking() {
+ panic!("cannot modify the panic hook from a panicking thread");
+ }
+
+ // SAFETY:
+ //
+ // - `HOOK` can only be modified while holding write access to `HOOK_LOCK`.
+ // - The argument of `Box::from_raw` is always a valid pointer that was created using
+ // `Box::into_raw`.
+ unsafe {
+ let _guard = HOOK_LOCK.write();
+ let hook = HOOK;
+ HOOK = Hook::Default;
+ let _ = HOOK_LOCK.write_unlock();
+
+ match hook {
+ Hook::Default => Box::new(default_hook),
+ Hook::Custom(ptr) => Box::from_raw(ptr),
+ }
+ }
+}
+
+/// Atomic combination of [`take_hook`] and [`set_hook`]. Use this to replace the panic handler with
+/// a new panic handler that does something and then executes the old handler.
+///
+/// [`take_hook`]: ./fn.take_hook.html
+/// [`set_hook`]: ./fn.set_hook.html
+///
+/// # Panics
+///
+/// Panics if called from a panicking thread.
+///
+/// # Examples
+///
+/// The following will print the custom message, and then the normal output of panic.
+///
+/// ```should_panic
+/// #![feature(panic_update_hook)]
+/// use std::panic;
+///
+/// // Equivalent to
+/// // let prev = panic::take_hook();
+/// // panic::set_hook(move |info| {
+/// // println!("...");
+/// // prev(info);
+/// // );
+/// panic::update_hook(move |prev, info| {
+/// println!("Print custom message and execute panic handler as usual");
+/// prev(info);
+/// });
+///
+/// panic!("Custom and then normal");
+/// ```
+pub fn update_hook<F>(hook_fn: F)
+where
+ F: Fn(&(dyn Fn(&PanicInfo<'_>) + Send + Sync + 'static), &PanicInfo<'_>)
+ + Sync
+ + Send
+ + 'static,
+{
+ if thread::panicking() {
+ panic!("cannot modify the panic hook from a panicking thread");
+ }
+
+ // SAFETY:
+ //
+ // - `HOOK` can only be modified while holding write access to `HOOK_LOCK`.
+ // - The argument of `Box::from_raw` is always a valid pointer that was created using
+ // `Box::into_raw`.
+ unsafe {
+ let _guard = HOOK_LOCK.write();
+ let old_hook = HOOK;
+ HOOK = Hook::Default;
+
+ let prev = match old_hook {
+ Hook::Default => Box::new(default_hook),
+ Hook::Custom(ptr) => Box::from_raw(ptr),
+ };
+
+ HOOK = Hook::custom(move |info| hook_fn(&prev, info));
+ let _ = HOOK_LOCK.write_unlock();
+ }
}
#[cfg(not(feature = "stdio"))]
-#[allow(unused_variables)]
-fn default_hook(info: &PanicInfo<'_>) {}
+fn default_hook(_info: &PanicInfo<'_>) {}
#[cfg(feature = "stdio")]
fn default_hook(info: &PanicInfo<'_>) {
- #[cfg(feature = "backtrace")]
- use crate::sys_common::backtrace::{self, RustBacktrace};
-
// If this is a double panic, make sure that we print a backtrace
// for this panic. Otherwise only print it if logging is enabled.
#[cfg(feature = "backtrace")]
- let backtrace_env = if panic_count::get_count() >= 2 {
- use crate::sys::backtrace::PrintFmt;
- RustBacktrace::Print(PrintFmt::Full)
+ let backtrace = if panic_count::get_count() >= 2 {
+ BacktraceStyle::full()
} else {
- backtrace::rust_backtrace_env()
+ crate::panic::get_backtrace_style()
};
// The current implementation always returns `Some`.
@@ -156,14 +301,18 @@
let write = |err: &mut dyn crate::io::Write| {
let _ = writeln!(err, "thread '{}' panicked at '{}', {}", name, msg, location);
- #[cfg(feature = "backtrace")] {
- use crate::sync::atomic::AtomicBool;
+ #[cfg(feature = "backtrace")]
+ {
static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
- match backtrace_env {
- RustBacktrace::Print(format) => drop(backtrace::print(err, format)),
- RustBacktrace::Disabled => {}
- RustBacktrace::RuntimeDisabled => {
+ match backtrace {
+ Some(BacktraceStyle::Short) => {
+ drop(backtrace::print(err, crate::sys::backtrace::PrintFmt::Short))
+ }
+ Some(BacktraceStyle::Full) => {
+ drop(backtrace::print(err, crate::sys::backtrace::PrintFmt::Full))
+ }
+ Some(BacktraceStyle::Off) => {
if FIRST_PANIC.swap(false, Ordering::SeqCst) {
let _ = writeln!(
err,
@@ -171,6 +320,8 @@
);
}
}
+ // If backtraces aren't supported, do nothing.
+ None => {}
}
}
};
@@ -180,13 +331,6 @@
}
}
-fn panic_handler(info: &PanicInfo<'_>) {
- let hook = PANIC_HANDLER.load(Ordering::SeqCst);
- let handler: fn(&PanicInfo<'_>) =
- if hook.is_null() { default_hook } else { unsafe { mem::transmute(hook) } };
- handler(info);
-}
-
#[doc(hidden)]
pub mod panic_count {
use crate::cell::Cell;
@@ -318,12 +462,14 @@
// The call to `intrinsics::r#try` is made safe by:
// - `do_call`, the first argument, can be called with the initial `data_ptr`.
// - `do_catch`, the second argument, can be called with the `data_ptr` as well.
- // See their safety preconditions for more informations
- return if intrinsics::r#try(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
- Ok(ManuallyDrop::into_inner(data.r))
- } else {
- Err(ManuallyDrop::into_inner(data.p))
- };
+ // See their safety preconditions for more information
+ unsafe {
+ return if intrinsics::r#try(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
+ Ok(ManuallyDrop::into_inner(data.r))
+ } else {
+ Err(ManuallyDrop::into_inner(data.p))
+ };
+ }
// We consider unwinding to be rare, so mark this function as cold. However,
// do not mark it no-inline -- that decision is best to leave to the
@@ -335,7 +481,7 @@
// the panic handler `__rust_panic_cleanup`. As such we can only
// assume it returns the correct thing for `Box::from_raw` to work
// without undefined behavior.
- let obj = Box::from_raw(__rust_panic_cleanup(payload));
+ let obj = unsafe { Box::from_raw(__rust_panic_cleanup(payload)) };
panic_count::decrease();
obj
}
@@ -349,7 +495,7 @@
// expects normal function pointers.
#[inline]
fn do_call<F: FnOnce() -> R, R>(data: *mut u8) {
- // SAFETY: this is the responsibilty of the caller, see above.
+ // SAFETY: this is the responsibility of the caller, see above.
unsafe {
let data = data as *mut Data<F, R>;
let data = &mut (*data);
@@ -371,7 +517,7 @@
// expects normal function pointers.
#[inline]
fn do_catch<F: FnOnce() -> R, R>(data: *mut u8, payload: *mut u8) {
- // SAFETY: this is the responsibilty of the caller, see above.
+ // SAFETY: this is the responsibility of the caller, see above.
//
// When `__rustc_panic_cleaner` is correctly implemented we can rely
// on `obj` being the correct thing to pass to `data.p` (after wrapping
@@ -446,20 +592,32 @@
let loc = info.location().unwrap(); // The current implementation always returns Some
let msg = info.message().unwrap(); // The current implementation always returns Some
- #[cfg(feature = "backtrace")] {
+ #[cfg(feature = "backtrace")]
+ {
crate::sys_common::backtrace::__rust_end_short_backtrace(move || {
if let Some(msg) = msg.as_str() {
- rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc);
+ rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc, info.can_unwind());
} else {
- rust_panic_with_hook(&mut PanicPayload::new(msg), info.message(), loc);
+ rust_panic_with_hook(
+ &mut PanicPayload::new(msg),
+ info.message(),
+ loc,
+ info.can_unwind(),
+ );
}
})
}
- #[cfg(not(feature = "backtrace"))] {
+ #[cfg(not(feature = "backtrace"))]
+ {
if let Some(msg) = msg.as_str() {
- rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc);
+ rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc, info.can_unwind());
} else {
- rust_panic_with_hook(&mut PanicPayload::new(msg), info.message(), loc);
+ rust_panic_with_hook(
+ &mut PanicPayload::new(msg),
+ info.message(),
+ loc,
+ info.can_unwind(),
+ );
}
}
}
@@ -474,7 +632,8 @@
#[inline(never)]
#[cold]
#[track_caller]
-pub fn begin_panic<M: Any + Send>(msg: M) -> ! {
+#[rustc_do_not_const_check] // hooked by const-eval
+pub const fn begin_panic<M: Any + Send>(msg: M) -> ! {
struct PanicPayload<A> {
inner: Option<A>,
}
@@ -510,11 +669,11 @@
let loc = Location::caller();
#[cfg(feature = "backtrace")] {
crate::sys_common::backtrace::__rust_end_short_backtrace(move || {
- rust_panic_with_hook(&mut PanicPayload::new(msg), None, loc)
+ rust_panic_with_hook(&mut PanicPayload::new(msg), None, loc, true)
})
}
#[cfg(not(feature = "backtrace"))] {
- rust_panic_with_hook(&mut PanicPayload::new(msg), None, loc)
+ rust_panic_with_hook(&mut PanicPayload::new(msg), None, loc, true)
}
}
@@ -527,6 +686,7 @@
payload: &mut dyn BoxMeUp,
message: Option<&fmt::Arguments<'_>>,
location: &Location<'_>,
+ can_unwind: bool,
) -> ! {
let (must_abort, panics) = panic_count::increase();
@@ -543,17 +703,37 @@
} else {
// Unfortunately, this does not print a backtrace, because creating
// a `Backtrace` will allocate, which we must to avoid here.
- let panicinfo = PanicInfo::internal_constructor(message, location);
+ let panicinfo = PanicInfo::internal_constructor(message, location, can_unwind);
rtprintpanic!("{}\npanicked after panic::always_abort(), aborting.\n", panicinfo);
}
rsgx_abort()
}
- let mut info = PanicInfo::internal_constructor(message, location);
- info.set_payload(payload.get());
- panic_handler(&info);
+ unsafe {
+ let mut info = PanicInfo::internal_constructor(message, location, can_unwind);
+ let _guard = HOOK_LOCK.read();
+ match HOOK {
+ // Some platforms (like wasm) know that printing to stderr won't ever actually
+ // print anything, and if that's the case we can skip the default
+ // hook. Since string formatting happens lazily when calling `payload`
+ // methods, this means we avoid formatting the string at all!
+ // (The panic runtime might still call `payload.take_box()` though and trigger
+ // formatting.)
+ #[cfg(feature = "stdio")]
+ Hook::Default if panic_output().is_none() => {}
+ Hook::Default => {
+ info.set_payload(payload.get());
+ default_hook(&info);
+ }
+ Hook::Custom(ptr) => {
+ info.set_payload(payload.get());
+ (*ptr)(&info);
+ }
+ };
+ let _ = HOOK_LOCK.read_unlock();
+ }
- if panics > 1 {
+ if panics > 1 || !can_unwind {
// If a thread panics while it's already unwinding then we
// have limited options. Currently our preference is to
// just abort. In the future we may consider resuming
diff --git a/sgx_tstd/src/path.rs b/sgx_tstd/src/path.rs
index 3b2d6f3..ac7726c 100644
--- a/sgx_tstd/src/path.rs
+++ b/sgx_tstd/src/path.rs
@@ -29,6 +29,13 @@
//! [`PathBuf`]; note that the paths may differ syntactically by the
//! normalization described in the documentation for the [`components`] method.
//!
+//! ## Case sensitivity
+//!
+//! Unless otherwise indicated path methods that do not access the filesystem,
+//! such as [`Path::starts_with`] and [`Path::ends_with`], are case sensitive no
+//! matter the platform or filesystem. An exception to this is made for Windows
+//! drive letters.
+//!
//! ## Simple usage
//!
//! Path manipulation includes both parsing components from slices and building
@@ -78,12 +85,12 @@
use crate::borrow::{Borrow, Cow};
use crate::cmp;
+use crate::collections::TryReserveError;
use crate::error::Error;
use crate::fmt;
#[cfg(feature = "untrusted_fs")]
use crate::fs;
use crate::hash::{Hash, Hasher};
-#[cfg(feature = "untrusted_fs")]
use crate::io;
use crate::iter::{self, FusedIterator};
use crate::ops::{self, Deref};
@@ -92,7 +99,7 @@
use crate::sync::Arc;
use crate::ffi::{OsStr, OsString};
-
+use crate::sys;
use crate::sys::path::{is_sep_byte, is_verbatim_sep, parse_prefix, MAIN_SEP_STR};
////////////////////////////////////////////////////////////////////////////////
@@ -132,6 +139,18 @@
/// }
/// }
///
+/// # if cfg!(windows) {
+/// assert_eq!(Verbatim(OsStr::new("pictures")),
+/// get_path_prefix(r"\\?\pictures\kittens"));
+/// assert_eq!(VerbatimUNC(OsStr::new("server"), OsStr::new("share")),
+/// get_path_prefix(r"\\?\UNC\server\share"));
+/// assert_eq!(VerbatimDisk(b'C'), get_path_prefix(r"\\?\c:\"));
+/// assert_eq!(DeviceNS(OsStr::new("BrainInterface")),
+/// get_path_prefix(r"\\.\BrainInterface"));
+/// assert_eq!(UNC(OsStr::new("server"), OsStr::new("share")),
+/// get_path_prefix(r"\\server\share"));
+/// assert_eq!(Disk(b'C'), get_path_prefix(r"C:\Users\Rust\Pictures\Ferris"));
+/// # }
/// ```
#[derive(Copy, Clone, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub enum Prefix<'a> {
@@ -247,6 +266,11 @@
/// For example, `/` on Unix and `\` on Windows.
pub const MAIN_SEPARATOR: char = crate::sys::path::MAIN_SEP;
+/// The primary separator of path components for the current platform.
+///
+/// For example, `/` on Unix and `\` on Windows.
+pub const MAIN_SEPARATOR_STR: &str = crate::sys::path::MAIN_SEP_STR;
+
////////////////////////////////////////////////////////////////////////////////
// Misc helpers
////////////////////////////////////////////////////////////////////////////////
@@ -929,6 +953,25 @@
impl<'a> cmp::PartialEq for Components<'a> {
#[inline]
fn eq(&self, other: &Components<'a>) -> bool {
+ let Components { path: _, front: _, back: _, has_physical_root: _, prefix: _ } = self;
+
+ // Fast path for exact matches, e.g. for hashmap lookups.
+ // Don't explicitly compare the prefix or has_physical_root fields since they'll
+ // either be covered by the `path` buffer or are only relevant for `prefix_verbatim()`.
+ if self.path.len() == other.path.len()
+ && self.front == other.front
+ && self.back == State::Body
+ && other.back == State::Body
+ && self.prefix_verbatim() == other.prefix_verbatim()
+ {
+ // possible future improvement: this could bail out earlier if there were a
+ // reverse memcmp/bcmp comparing back to front
+ if self.path == other.path {
+ return true;
+ }
+ }
+
+ // compare back to front since absolute paths often share long prefixes
Iterator::eq(self.clone().rev(), other.clone().rev())
}
}
@@ -960,13 +1003,12 @@
// The fast path isn't taken for paths with a PrefixComponent to avoid backtracking into
// the middle of one
if left.prefix.is_none() && right.prefix.is_none() && left.front == right.front {
- // this might benefit from a [u8]::first_mismatch simd implementation, if it existed
- let first_difference =
- match left.path.iter().zip(right.path.iter()).position(|(&a, &b)| a != b) {
- None if left.path.len() == right.path.len() => return cmp::Ordering::Equal,
- None => left.path.len().min(right.path.len()),
- Some(diff) => diff,
- };
+ // possible future improvement: a [u8]::first_mismatch simd implementation
+ let first_difference = match left.path.iter().zip(right.path).position(|(&a, &b)| a != b) {
+ None if left.path.len() == right.path.len() => return cmp::Ordering::Equal,
+ None => left.path.len().min(right.path.len()),
+ Some(diff) => diff,
+ };
if let Some(previous_sep) =
left.path[..first_difference].iter().rposition(|&b| left.is_sep_byte(b))
@@ -1420,6 +1462,14 @@
self.inner.reserve(additional)
}
+ /// Invokes [`try_reserve`] on the underlying instance of [`OsString`].
+ ///
+ /// [`try_reserve`]: OsString::try_reserve
+ #[inline]
+ pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
+ self.inner.try_reserve(additional)
+ }
+
/// Invokes [`reserve_exact`] on the underlying instance of [`OsString`].
///
/// [`reserve_exact`]: OsString::reserve_exact
@@ -1428,6 +1478,14 @@
self.inner.reserve_exact(additional)
}
+ /// Invokes [`try_reserve_exact`] on the underlying instance of [`OsString`].
+ ///
+ /// [`try_reserve_exact`]: OsString::try_reserve_exact
+ #[inline]
+ pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
+ self.inner.try_reserve_exact(additional)
+ }
+
/// Invokes [`shrink_to_fit`] on the underlying instance of [`OsString`].
///
/// [`shrink_to_fit`]: OsString::shrink_to_fit
@@ -1482,7 +1540,7 @@
}
impl From<Box<Path>> for PathBuf {
- /// Converts a `Box<Path>` into a `PathBuf`
+ /// Converts a <code>[Box]<[Path]></code> into a [`PathBuf`].
///
/// This conversion does not allocate or copy memory.
#[inline]
@@ -1492,7 +1550,7 @@
}
impl From<PathBuf> for Box<Path> {
- /// Converts a `PathBuf` into a `Box<Path>`
+ /// Converts a [`PathBuf`] into a <code>[Box]<[Path]></code>.
///
/// This conversion currently should not allocate memory,
/// but this behavior is not guaranteed on all platforms or in all future versions.
@@ -1510,7 +1568,7 @@
}
impl<T: ?Sized + AsRef<OsStr>> From<&T> for PathBuf {
- /// Converts a borrowed `OsStr` to a `PathBuf`.
+ /// Converts a borrowed [`OsStr`] to a [`PathBuf`].
///
/// Allocates a [`PathBuf`] and copies the data into it.
#[inline]
@@ -1649,7 +1707,8 @@
}
impl From<PathBuf> for Arc<Path> {
- /// Converts a [`PathBuf`] into an [`Arc`] by moving the [`PathBuf`] data into a new [`Arc`] buffer.
+ /// Converts a [`PathBuf`] into an <code>[Arc]<[Path]></code> by moving the [`PathBuf`] data
+ /// into a new [`Arc`] buffer.
#[inline]
fn from(s: PathBuf) -> Arc<Path> {
let arc: Arc<OsStr> = Arc::from(s.into_os_string());
@@ -1667,7 +1726,8 @@
}
impl From<PathBuf> for Rc<Path> {
- /// Converts a [`PathBuf`] into an [`Rc`] by moving the [`PathBuf`] data into a new `Rc` buffer.
+ /// Converts a [`PathBuf`] into an <code>[Rc]<[Path]></code> by moving the [`PathBuf`] data into
+ /// a new [`Rc`] buffer.
#[inline]
fn from(s: PathBuf) -> Rc<Path> {
let rc: Rc<OsStr> = Rc::from(s.into_os_string());
@@ -1676,7 +1736,7 @@
}
impl From<&Path> for Rc<Path> {
- /// Converts a [`Path`] into an [`Rc`] by copying the [`Path`] data into a new `Rc` buffer.
+ /// Converts a [`Path`] into an [`Rc`] by copying the [`Path`] data into a new [`Rc`] buffer.
#[inline]
fn from(s: &Path) -> Rc<Path> {
let rc: Rc<OsStr> = Rc::from(s.as_os_str());
@@ -2551,7 +2611,7 @@
/// This function will traverse symbolic links to query information about the
/// destination file. In case of broken symbolic links this will return `Ok(false)`.
///
- /// As opposed to the `exists()` method, this one doesn't silently ignore errors
+ /// As opposed to the [`exists()`] method, this one doesn't silently ignore errors
/// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission
/// denied on some of the parent directories.)
///
@@ -2564,6 +2624,8 @@
/// assert!(!Path::new("does_not_exist.txt").try_exists().expect("Can't check existence of file does_not_exist.txt"));
/// assert!(Path::new("/root/secret_file.txt").try_exists().is_err());
/// ```
+ ///
+ /// [`exists()`]: Self::exists
// FIXME: stabilization should modify documentation of `exists()` to recommend this method
// instead.
#[cfg(feature = "untrusted_fs")]
@@ -2644,12 +2706,11 @@
///
#[cfg_attr(unix, doc = "```no_run")]
#[cfg_attr(not(unix), doc = "```ignore")]
- /// #![feature(is_symlink)]
/// use std::path::Path;
/// use std::os::unix::fs::symlink;
///
/// let link_path = Path::new("link");
- /// symlink("/origin_does_not_exists/", link_path).unwrap();
+ /// symlink("/origin_does_not_exist/", link_path).unwrap();
/// assert_eq!(link_path.is_symlink(), true);
/// assert_eq!(link_path.exists(), false);
/// ```
@@ -2733,9 +2794,51 @@
impl Hash for Path {
fn hash<H: Hasher>(&self, h: &mut H) {
- for component in self.components() {
- component.hash(h);
+ let bytes = self.as_u8_slice();
+ let (prefix_len, verbatim) = match parse_prefix(&self.inner) {
+ Some(prefix) => {
+ prefix.hash(h);
+ (prefix.len(), prefix.is_verbatim())
+ }
+ None => (0, false),
+ };
+ let bytes = &bytes[prefix_len..];
+
+ let mut component_start = 0;
+ let mut bytes_hashed = 0;
+
+ for i in 0..bytes.len() {
+ let is_sep = if verbatim { is_verbatim_sep(bytes[i]) } else { is_sep_byte(bytes[i]) };
+ if is_sep {
+ if i > component_start {
+ let to_hash = &bytes[component_start..i];
+ h.write(to_hash);
+ bytes_hashed += to_hash.len();
+ }
+
+ // skip over separator and optionally a following CurDir item
+ // since components() would normalize these away.
+ component_start = i + 1;
+
+ let tail = &bytes[component_start..];
+
+ if !verbatim {
+ component_start += match tail {
+ [b'.'] => 1,
+ [b'.', sep, ..] if is_sep_byte(*sep) => 1,
+ _ => 0,
+ };
+ }
+ }
}
+
+ if component_start < bytes.len() {
+ let to_hash = &bytes[component_start..];
+ h.write(to_hash);
+ bytes_hashed += to_hash.len();
+ }
+
+ h.write_usize(bytes_hashed);
}
}
@@ -2920,3 +3023,83 @@
"prefix not found"
}
}
+
+/// Makes the path absolute without accessing the filesystem.
+///
+/// If the path is relative, the current directory is used as the base directory.
+/// All intermediate components will be resolved according to platforms-specific
+/// rules but unlike [`canonicalize`][crate::fs::canonicalize] this does not
+/// resolve symlinks and may succeed even if the path does not exist.
+///
+/// If the `path` is empty or getting the
+/// [current directory][crate::env::current_dir] fails then an error will be
+/// returned.
+///
+/// # Examples
+///
+/// ## Posix paths
+///
+/// ```
+/// #![feature(absolute_path)]
+/// # #[cfg(unix)]
+/// fn main() -> std::io::Result<()> {
+/// use std::path::{self, Path};
+///
+/// // Relative to absolute
+/// let absolute = path::absolute("foo/./bar")?;
+/// assert!(absolute.ends_with("foo/bar"));
+///
+/// // Absolute to absolute
+/// let absolute = path::absolute("/foo//test/.././bar.rs")?;
+/// assert_eq!(absolute, Path::new("/foo/test/../bar.rs"));
+/// Ok(())
+/// }
+/// # #[cfg(not(unix))]
+/// # fn main() {}
+/// ```
+///
+/// The path is resolved using [POSIX semantics][posix-semantics] except that
+/// it stops short of resolving symlinks. This means it will keep `..`
+/// components and trailing slashes.
+///
+/// ## Windows paths
+///
+/// ```
+/// #![feature(absolute_path)]
+/// # #[cfg(windows)]
+/// fn main() -> std::io::Result<()> {
+/// use std::path::{self, Path};
+///
+/// // Relative to absolute
+/// let absolute = path::absolute("foo/./bar")?;
+/// assert!(absolute.ends_with(r"foo\bar"));
+///
+/// // Absolute to absolute
+/// let absolute = path::absolute(r"C:\foo//test\..\./bar.rs")?;
+///
+/// assert_eq!(absolute, Path::new(r"C:\foo\bar.rs"));
+/// Ok(())
+/// }
+/// # #[cfg(not(windows))]
+/// # fn main() {}
+/// ```
+///
+/// For verbatim paths this will simply return the path as given. For other
+/// paths this is currently equivalent to calling [`GetFullPathNameW`][windows-path]
+/// This may change in the future.
+///
+/// [posix-semantics]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
+/// [windows-path]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamew
+#[cfg(feature = "untrusted_fs")]
+pub fn absolute<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
+ _absolute(path)
+}
+
+pub(crate) fn _absolute<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
+ let path = path.as_ref();
+ if path.as_os_str().is_empty() {
+ Err(io::const_io_error!(io::ErrorKind::InvalidInput, "cannot make an empty path absolute",))
+ } else {
+ sys::path::absolute(path)
+ }
+}
diff --git a/sgx_tstd/src/prelude/v1.rs b/sgx_tstd/src/prelude/v1.rs
index 3ac7da0..756a2c2 100644
--- a/sgx_tstd/src/prelude/v1.rs
+++ b/sgx_tstd/src/prelude/v1.rs
@@ -46,25 +46,23 @@
#[doc(no_inline)]
pub use core::prelude::v1::{
assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,
- format_args_nl, include, include_bytes, include_str, line, llvm_asm, log_syntax, module_path,
- option_env, stringify, trace_macros, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq,
- PartialOrd,
+ format_args_nl, include, include_bytes, include_str, line, log_syntax, module_path, option_env,
+ stringify, trace_macros, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd,
};
-// FIXME: Attribute and internal derive macros are not documented because for them rustdoc generates
-// dead links which fail link checker testing.
-#[allow(deprecated, deprecated_in_future)]
-#[doc(hidden)]
-pub use core::prelude::v1::{
- global_allocator, test, test_case, RustcDecodable, RustcEncodable,
-};
+#[doc(no_inline)]
+pub use core::prelude::v1::concat_bytes;
-#[doc(hidden)]
-pub use core::prelude::v1::derive;
-#[doc(hidden)]
+#[allow(deprecated)]
+pub use core::prelude::v1::{RustcDecodable, RustcEncodable};
+
+// Do not `doc(no_inline)` so that they become doc items on their own
+// (no public module for them to be re-exported from).
+pub use core::prelude::v1::{derive, global_allocator, test, test_case};
+
+// Do not `doc(no_inline)` either.
pub use core::prelude::v1::cfg_accessible;
-#[doc(hidden)]
pub use core::prelude::v1::cfg_eval;
// The file so far is equivalent to src/libcore/prelude/v1.rs,
diff --git a/sgx_tstd/src/rt.rs b/sgx_tstd/src/rt.rs
index cebae78..3104350 100644
--- a/sgx_tstd/src/rt.rs
+++ b/sgx_tstd/src/rt.rs
@@ -37,6 +37,7 @@
// - the standard error output
// - some dedicated platform specific output
// - nothing (so this macro is a no-op)
+#[cfg(feature = "stdio")]
macro_rules! rtprintpanic {
($($t:tt)*) => {
if let Some(mut out) = crate::sys::stdio::panic_output() {
@@ -45,6 +46,13 @@
}
}
+#[cfg(not(feature = "stdio"))]
+macro_rules! rtprintpanic {
+ ($($t:tt)*) => {
+ format_args!($($t)*);
+ }
+}
+
macro_rules! rtabort {
($($t:tt)*) => {
{
@@ -118,7 +126,7 @@
// One-time runtime cleanup.
// NOTE: this is not guaranteed to run, for example when the program aborts.
-fn cleanup() {
+pub (crate) fn cleanup() {
static CLEANUP: Once = Once::new();
CLEANUP.call_once(|| {
// Flush stdout and disable buffering.
diff --git a/sgx_tstd/src/sgxfs.rs b/sgx_tstd/src/sgxfs.rs
index ffacfad..2a702c0 100644
--- a/sgx_tstd/src/sgxfs.rs
+++ b/sgx_tstd/src/sgxfs.rs
@@ -17,7 +17,7 @@
//! Filesystem manipulation operations.
-use crate::io::{self, SeekFrom, Seek, Read, Initializer, Write};
+use crate::io::{self, SeekFrom, Seek, Read, Write};
use crate::path::Path;
use crate::sys::sgxfs as fs_imp;
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
@@ -157,11 +157,6 @@
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
-
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
}
impl Write for SgxFile {
@@ -181,11 +176,6 @@
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
-
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
}
impl<'a> Write for &'a SgxFile {
diff --git a/sgx_tstd/src/sync/mpsc/mod.rs b/sgx_tstd/src/sync/mpsc/mod.rs
index 805deb1..55fd9a0 100644
--- a/sgx_tstd/src/sync/mpsc/mod.rs
+++ b/sgx_tstd/src/sync/mpsc/mod.rs
@@ -435,12 +435,13 @@
}
/// An owning iterator over messages on a [`Receiver`],
-/// created by **Receiver::into_iter**.
+/// created by [`into_iter`].
///
/// This iterator will block whenever [`next`]
/// is called, waiting for a new message, and [`None`] will be
/// returned if the corresponding channel has hung up.
///
+/// [`into_iter`]: Receiver::into_iter
/// [`next`]: Iterator::next
///
/// # Examples
diff --git a/sgx_tstd/src/sync/mutex.rs b/sgx_tstd/src/sync/mutex.rs
index 0bba39c..6cbf87a 100644
--- a/sgx_tstd/src/sync/mutex.rs
+++ b/sgx_tstd/src/sync/mutex.rs
@@ -213,6 +213,9 @@
/// [`lock`]: Mutex::lock
/// [`try_lock`]: Mutex::try_lock
#[must_use = "if unused the Mutex will immediately unlock"]
+#[must_not_suspend = "holding a MutexGuard across suspend \
+ points can cause deadlocks, delays, \
+ and cause Futures to not implement `Send`"]
pub struct SgxMutexGuard<'a, T: ?Sized + 'a> {
lock: &'a SgxMutex<T>,
poison: poison::Guard,
diff --git a/sgx_tstd/src/sync/once.rs b/sgx_tstd/src/sync/once.rs
index 262dc81..999b47d 100644
--- a/sgx_tstd/src/sync/once.rs
+++ b/sgx_tstd/src/sync/once.rs
@@ -104,6 +104,7 @@
use crate::cell::Cell;
use crate::fmt;
use crate::marker;
+use crate::panic::{RefUnwindSafe, UnwindSafe};
use crate::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use crate::thread::{self, SgxThread as Thread};
@@ -134,6 +135,10 @@
unsafe impl Sync for Once {}
unsafe impl Send for Once {}
+impl UnwindSafe for Once {}
+
+impl RefUnwindSafe for Once {}
+
/// State yielded to [`Once::call_once_force()`]’s closure parameter. The state
/// can be used to query the poison status of the [`Once`].
#[derive(Debug)]
diff --git a/sgx_tstd/src/sync/remutex.bak.rs b/sgx_tstd/src/sync/remutex.bak.rs
deleted file mode 100644
index 6e2aafb..0000000
--- a/sgx_tstd/src/sync/remutex.bak.rs
+++ /dev/null
@@ -1,186 +0,0 @@
-// 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 alloc_crate::boxed::Box;
-use core::fmt;
-use core::ops::Deref;
-use crate::sys_common::poison::{self, LockResult, TryLockError, TryLockResult};
-use crate::sys_common::remutex as sys;
-
-pub use crate::sys_common::remutex::SgxReentrantThreadMutex;
-
-
-/// A re-entrant mutual exclusion
-///
-/// This mutex will block *other* threads waiting for the lock to become
-/// available. The thread which has already locked the mutex can lock it
-/// multiple times without blocking, preventing a common source of deadlocks.
-pub struct SgxReentrantMutex<T> {
- inner: Box<sys::SgxReentrantThreadMutex>,
- poison: poison::Flag,
- data: T,
-}
-
-unsafe impl<T: Send> Send for SgxReentrantMutex<T> {}
-unsafe impl<T: Send> Sync for SgxReentrantMutex<T> {}
-
-impl<T> SgxReentrantMutex<T> {
- /// Creates a new reentrant mutex in an unlocked state.
- pub fn new(t: T) -> SgxReentrantMutex<T> {
- SgxReentrantMutex{
- inner: Box::new(sys::SgxReentrantThreadMutex::new()),
- poison: poison::Flag::new(),
- data: t,
- }
- }
-
- /// Acquires a mutex, blocking the current thread until it is able to do so.
- ///
- /// This function will block the caller until it is available to acquire the mutex.
- /// Upon returning, the thread is the only thread with the mutex held. When the thread
- /// calling this method already holds the lock, the call shall succeed without
- /// blocking.
- ///
- /// # Errors
- ///
- /// If another user of this mutex panicked while holding the mutex, then
- /// this call will return failure if the mutex would otherwise be
- /// acquired.
- pub fn lock(&self) -> LockResult<SgxReentrantMutexGuard<'_, T>> {
- unsafe {
- self.inner.lock();
- SgxReentrantMutexGuard::new(self)
- }
- }
-
- /// Attempts to acquire this lock.
- ///
- /// If the lock could not be acquired at this time, then `Err` is returned.
- /// Otherwise, an RAII guard is returned.
- ///
- /// This function does not block.
- ///
- /// # Errors
- ///
- /// If another user of this mutex panicked while holding the mutex, then
- /// this call will return failure if the mutex would otherwise be
- /// acquired.
- pub fn try_lock(&self) -> TryLockResult<SgxReentrantMutexGuard<'_, T>> {
- unsafe {
- match self.inner.try_lock() {
- Ok(_) => Ok(SgxReentrantMutexGuard::new(self)?),
- Err(_) => Err(TryLockError::WouldBlock),
- }
- }
- }
-}
-
-impl<T> Drop for SgxReentrantMutex<T> {
- fn drop(&mut self) {
- // This is actually safe b/c we know that there is no further usage of
- // this mutex (it's up to the user to arrange for a mutex to get
- // dropped, that's not our job)
- let result = unsafe { self.inner.destroy() };
- debug_assert_eq!(result, Ok(()), "Error when destroy an SgxReentrantMutex: {}", result.unwrap_err());
- }
-}
-
-impl<T: fmt::Debug + 'static> fmt::Debug for SgxReentrantMutex<T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self.try_lock() {
- Ok(guard) => f.debug_struct("SgxReentrantMutex").field("data", &*guard).finish(),
- Err(TryLockError::Poisoned(err)) => {
- f.debug_struct("SgxReentrantMutex").field("data", &**err.get_ref()).finish()
- },
- Err(TryLockError::WouldBlock) => {
- struct LockedPlaceholder;
- impl fmt::Debug for LockedPlaceholder {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str("<locked>")
- }
- }
-
- f.debug_struct("SgxReentrantMutex").field("data", &LockedPlaceholder).finish()
- }
- }
- }
-}
-
-/// An RAII implementation of a "scoped lock" of a mutex. When this structure is
-/// dropped (falls out of scope), the lock will be unlocked.
-///
-/// The data protected by the mutex can be accessed through this guard via its
-/// Deref implementation.
-///
-/// # Mutability
-///
-/// Unlike `MutexGuard`, `ReentrantMutexGuard` does not implement `DerefMut`,
-/// because implementation of the trait would violate Rust’s reference aliasing
-/// rules. Use interior mutability (usually `RefCell`) in order to mutate the
-/// guarded data.
-#[must_use]
-pub struct SgxReentrantMutexGuard<'a, T: 'a> {
- // funny underscores due to how Deref currently works (it disregards field
- // privacy).
- lock: &'a SgxReentrantMutex<T>,
- poison: poison::Guard,
-}
-
-impl<T> !Send for SgxReentrantMutexGuard<'_, T> {}
-
-impl<'mutex, T> SgxReentrantMutexGuard<'mutex, T> {
- fn new(lock: &'mutex SgxReentrantMutex<T>) -> LockResult<SgxReentrantMutexGuard<'mutex, T>> {
- poison::map_result(lock.poison.borrow(), |guard| {
- SgxReentrantMutexGuard {
- lock: lock,
- poison: guard,
- }
- })
- }
-}
-
-impl<T> Deref for SgxReentrantMutexGuard<'_, T> {
- type Target = T;
-
- fn deref(&self) -> &T {
- &self.lock.data
- }
-}
-
-impl<T> Drop for SgxReentrantMutexGuard<'_, T> {
- #[inline]
- fn drop(&mut self) {
- let result = unsafe {
- self.lock.poison.done(&self.poison);
- self.lock.inner.unlock()
- };
- debug_assert_eq!(result, Ok(()), "Error when unlocking an SgxReentrantMutex: {}", result.unwrap_err());
- }
-}
-
-impl<T: fmt::Debug> fmt::Debug for SgxReentrantMutexGuard<'_, T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Debug::fmt(&**self, f)
- }
-}
-
-impl<T: fmt::Display> fmt::Display for SgxReentrantMutexGuard<'_, T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- (**self).fmt(f)
- }
-}
diff --git a/sgx_tstd/src/sys/backtrace/mod.rs b/sgx_tstd/src/sys/backtrace/mod.rs
index 9e6dc80..f26ea11 100644
--- a/sgx_tstd/src/sys/backtrace/mod.rs
+++ b/sgx_tstd/src/sys/backtrace/mod.rs
@@ -138,7 +138,7 @@
pub fn get_enclave_filename() -> io::Result<Vec<u8>> {
let p = enclave::get_enclave_path();
let result = match p {
- None => Err(Error::new(ErrorKind::Other, "Not implemented")),
+ None => Err(Error::new(ErrorKind::Other, "no enclave path found")),
Some(path) => {
let cstr = CString::new(path.as_os_str().as_bytes())?;
let v = unsafe { mem::transmute(cstr.into_bytes_with_nul()) };
diff --git a/sgx_tstd/src/sys/fd.rs b/sgx_tstd/src/sys/fd.rs
index cac6135..f38a9e4 100644
--- a/sgx_tstd/src/sys/fd.rs
+++ b/sgx_tstd/src/sys/fd.rs
@@ -16,7 +16,7 @@
// under the License..
use crate::cmp;
-use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read};
+use crate::io::{self, IoSlice, IoSliceMut, Read, ReadBuf};
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
use crate::sys::cvt;
use crate::sys_common::{AsInner, FromInner, IntoInner};
@@ -66,27 +66,36 @@
}
pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
- unsafe fn cvt_pread64(
- fd: c_int,
- buf: *mut c_void,
- count: usize,
- offset: i64,
- ) -> io::Result<isize> {
- use libc::pread64;
- cvt(pread64(fd, buf, count, offset))
- }
+ use libc::pread64;
unsafe {
- cvt_pread64(
+ cvt(pread64(
self.as_raw_fd(),
buf.as_mut_ptr() as *mut c_void,
cmp::min(buf.len(), READ_LIMIT),
offset as i64,
- )
+ ))
.map(|n| n as usize)
}
}
+ pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ let ret = cvt(unsafe {
+ libc::read(
+ self.as_raw_fd(),
+ buf.unfilled_mut().as_mut_ptr() as *mut c_void,
+ cmp::min(buf.remaining(), READ_LIMIT),
+ )
+ })?;
+
+ // Safety: `ret` bytes were written to the initialized portion of the buffer
+ unsafe {
+ buf.assume_init(ret as usize);
+ }
+ buf.add_filled(ret as usize);
+ Ok(())
+ }
+
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
let ret = cvt(unsafe {
libc::write(
@@ -115,23 +124,15 @@
}
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
- unsafe fn cvt_pwrite64(
- fd: c_int,
- buf: *const c_void,
- count: usize,
- offset: i64,
- ) -> io::Result<isize> {
- use libc::pwrite64;
- cvt(pwrite64(fd, buf, count, offset))
- }
+ use libc::pwrite64;
unsafe {
- cvt_pwrite64(
+ cvt(pwrite64(
self.as_raw_fd(),
buf.as_ptr() as *const c_void,
cmp::min(buf.len(), READ_LIMIT),
offset as i64,
- )
+ ))
.map(|n| n as usize)
}
}
@@ -159,12 +160,9 @@
}
}
+ #[inline]
pub fn duplicate(&self) -> io::Result<FileDesc> {
- // We want to atomically duplicate this file descriptor and set the
- // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This
- // is a POSIX flag that was added to Linux in 2.6.24.
- let fd = cvt(unsafe { libc::fcntl_arg1(self.as_raw_fd(), libc::F_DUPFD_CLOEXEC, 0) })?;
- Ok(unsafe { FileDesc::from_raw_fd(fd) })
+ Ok(Self(self.0.try_clone()?))
}
}
@@ -172,11 +170,6 @@
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
(**self).read(buf)
}
-
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
}
impl AsInner<OwnedFd> for FileDesc {
diff --git a/sgx_tstd/src/sys/fs.rs b/sgx_tstd/src/sys/fs.rs
index 3e8daf3..bcebf72 100644
--- a/sgx_tstd/src/sys/fs.rs
+++ b/sgx_tstd/src/sys/fs.rs
@@ -19,7 +19,7 @@
use crate::ffi::{CStr, CString, OsStr, OsString};
use crate::fmt;
-use crate::io::{self, Error, IoSlice, IoSliceMut, SeekFrom};
+use crate::io::{self, Error, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
use crate::mem;
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd};
use crate::path::{Path, PathBuf};
@@ -29,11 +29,10 @@
use crate::sys::time::SystemTime;
use crate::sys::{cvt, cvt_r};
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
-use crate::untrusted::fs;
-use sgx_libc::{c_int, dirent64, mode_t, off64_t, stat64};
+use sgx_libc::{c_int, dirent64, mode_t, off64_t, stat64, time_t};
-pub use crate::sys_common::fs::{remove_dir_all, try_exists};
+pub use crate::sys_common::fs::try_exists;
pub struct File(FileDesc);
@@ -115,22 +114,22 @@
impl FileAttr {
pub fn modified(&self) -> io::Result<SystemTime> {
Ok(SystemTime::from(libc::timespec {
- tv_sec: self.stat.st_mtime as libc::time_t,
+ tv_sec: self.stat.st_mtime as time_t,
tv_nsec: self.stat.st_mtime_nsec as _,
}))
}
pub fn accessed(&self) -> io::Result<SystemTime> {
Ok(SystemTime::from(libc::timespec {
- tv_sec: self.stat.st_atime as libc::time_t,
+ tv_sec: self.stat.st_atime as time_t,
tv_nsec: self.stat.st_atime_nsec as _,
}))
}
pub fn created(&self) -> io::Result<SystemTime> {
- Err(io::Error::new_const(
+ Err(io::const_io_error!(
io::ErrorKind::Unsupported,
- &"creation time is not available on this platform \
+ "creation time is not available on this platform \
currently",
))
}
@@ -235,16 +234,16 @@
impl DirEntry {
pub fn path(&self) -> PathBuf {
- self.dir.root.join(OsStr::from_bytes(self.name_bytes()))
+ self.dir.root.join(self.file_name_os_str())
}
pub fn file_name(&self) -> OsString {
- OsStr::from_bytes(self.name_bytes()).to_os_string()
+ self.file_name_os_str().to_os_string()
}
pub fn metadata(&self) -> io::Result<FileAttr> {
let fd = cvt(unsafe { libc::dirfd(self.dir.dirp.0) })?;
- let name = self.entry.d_name.as_ptr();
+ let name = self.name_cstr().as_ptr();
let mut stat: stat64 = unsafe { mem::zeroed() };
cvt(unsafe { libc::fstatat64(fd, name, &mut stat, libc::AT_SYMLINK_NOFOLLOW) })?;
Ok(FileAttr::from_stat64(stat))
@@ -259,7 +258,7 @@
libc::DT_SOCK => Ok(FileType { mode: libc::S_IFSOCK }),
libc::DT_DIR => Ok(FileType { mode: libc::S_IFDIR }),
libc::DT_BLK => Ok(FileType { mode: libc::S_IFBLK }),
- _ => lstat(&self.path()).map(|m| m.file_type()),
+ _ => self.metadata().map(|m| m.file_type()),
}
}
@@ -271,6 +270,10 @@
unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes() }
}
+ fn name_cstr(&self) -> &CStr {
+ unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()) }
+ }
+
pub fn file_name_os_str(&self) -> &OsStr {
OsStr::from_bytes(self.name_bytes())
}
@@ -401,7 +404,7 @@
pub fn truncate(&self, size: u64) -> io::Result<()> {
use crate::convert::TryInto;
let size: off64_t =
- size.try_into().map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
+ size.try_into().map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
cvt_r(|| unsafe { libc::ftruncate64(self.as_raw_fd(), size) }).map(drop)
}
@@ -422,6 +425,10 @@
self.0.read_at(buf, offset)
}
+ pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+ self.0.read_buf(buf)
+ }
+
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
}
@@ -577,7 +584,10 @@
Err(Error::last_os_error())
} else {
let inner = InnerReadDir { dirp: Dir(ptr), root };
- Ok(ReadDir { inner: Arc::new(inner), end_of_stream: false })
+ Ok(ReadDir {
+ inner: Arc::new(inner),
+ end_of_stream: false,
+ })
}
}
}
@@ -676,7 +686,7 @@
Ok(PathBuf::from(OsString::from_vec(buf)))
}
-fn open_from(from: &Path) -> io::Result<(fs::File, fs::Metadata)> {
+fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)> {
use crate::untrusted::fs::File;
use crate::sys_common::fs::NOT_FILE_ERROR;
@@ -690,10 +700,12 @@
fn open_to_and_set_permissions(
to: &Path,
- reader_metadata: fs::Metadata,
-) -> io::Result<(fs::File, fs::Metadata)> {
+ reader_metadata: crate::fs::Metadata,
+) -> io::Result<(crate::fs::File, crate::fs::Metadata)> {
+ use crate::fs::OpenOptions;
+
let perm = reader_metadata.permissions();
- let writer = fs::OpenOptions::new()
+ let writer = OpenOptions::new()
// create the file with the correct mode right away
.mode(perm.mode())
.write(true)
@@ -717,6 +729,18 @@
io::copy::copy(&mut reader, &mut writer)
}
+pub fn chown(_path: &Path, _uid: u32, _gid: u32) -> io::Result<()> {
+ super::unsupported::unsupported()
+}
+
+pub fn fchown(_fd: c_int, _uid: u32, _gid: u32) -> io::Result<()> {
+ super::unsupported::unsupported()
+}
+
+pub fn lchown(_path: &Path, _uid: u32, _gid: u32) -> io::Result<()> {
+ super::unsupported::unsupported()
+}
+
pub fn chroot(_dir: &Path) -> io::Result<()> {
super::unsupported::unsupported()
}
@@ -729,3 +753,113 @@
};
pub use sgx_libc::*;
}
+
+pub use remove_dir_impl::remove_dir_all;
+
+mod remove_dir_impl {
+ use super::{cstr, lstat, Dir, DirEntry, InnerReadDir, ReadDir};
+ use crate::ffi::CStr;
+ use crate::io;
+ use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd};
+ use crate::os::unix::prelude::{OwnedFd, RawFd};
+ use crate::path::{Path, PathBuf};
+ use crate::sync::Arc;
+ use crate::sys::{cvt, cvt_r};
+ use libc::{fdopendir, openat, unlinkat};
+
+ pub fn openat_nofollow_dironly(parent_fd: Option<RawFd>, p: &CStr) -> io::Result<OwnedFd> {
+ let fd = cvt_r(|| unsafe {
+ openat(
+ parent_fd.unwrap_or(libc::AT_FDCWD),
+ p.as_ptr(),
+ libc::O_CLOEXEC | libc::O_RDONLY | libc::O_NOFOLLOW | libc::O_DIRECTORY,
+ )
+ })?;
+ Ok(unsafe { OwnedFd::from_raw_fd(fd) })
+ }
+
+ fn fdreaddir(dir_fd: OwnedFd) -> io::Result<(ReadDir, RawFd)> {
+ let ptr = unsafe { fdopendir(dir_fd.as_raw_fd()) };
+ if ptr.is_null() {
+ return Err(io::Error::last_os_error());
+ }
+ let dirp = Dir(ptr);
+ // file descriptor is automatically closed by libc::closedir() now, so give up ownership
+ let new_parent_fd = dir_fd.into_raw_fd();
+ // a valid root is not needed because we do not call any functions involving the full path
+ // of the DirEntrys.
+ let dummy_root = PathBuf::new();
+ Ok((
+ ReadDir {
+ inner: Arc::new(InnerReadDir { dirp, root: dummy_root }),
+ end_of_stream: false,
+ },
+ new_parent_fd,
+ ))
+ }
+
+ fn is_dir(ent: &DirEntry) -> Option<bool> {
+ match ent.entry.d_type {
+ libc::DT_UNKNOWN => None,
+ libc::DT_DIR => Some(true),
+ _ => Some(false),
+ }
+ }
+
+ fn remove_dir_all_recursive(parent_fd: Option<RawFd>, p: &Path) -> io::Result<()> {
+ let pcstr = cstr(p)?;
+
+ // entry is expected to be a directory, open as such
+ let fd = openat_nofollow_dironly(parent_fd, &pcstr)?;
+
+ // open the directory passing ownership of the fd
+ let (dir, fd) = fdreaddir(fd)?;
+ for child in dir {
+ let child = child?;
+ match is_dir(&child) {
+ Some(true) => {
+ remove_dir_all_recursive(Some(fd), Path::new(&child.file_name()))?;
+ }
+ Some(false) => {
+ cvt(unsafe { unlinkat(fd, child.name_cstr().as_ptr(), 0) })?;
+ }
+ None => match cvt(unsafe { unlinkat(fd, child.name_cstr().as_ptr(), 0) }) {
+ // type unknown - try to unlink
+ Err(err)
+ if err.raw_os_error() == Some(libc::EISDIR)
+ || err.raw_os_error() == Some(libc::EPERM) =>
+ {
+ // if the file is a directory unlink fails with EISDIR on Linux and EPERM everyhwere else
+ remove_dir_all_recursive(Some(fd), Path::new(&child.file_name()))?;
+ }
+ result => {
+ result?;
+ }
+ },
+ }
+ }
+
+ // unlink the directory after removing its contents
+ cvt(unsafe {
+ unlinkat(parent_fd.unwrap_or(libc::AT_FDCWD), pcstr.as_ptr(), libc::AT_REMOVEDIR)
+ })?;
+ Ok(())
+ }
+
+ pub fn remove_dir_all(p: &Path) -> io::Result<()> {
+ // We cannot just call remove_dir_all_recursive() here because that would not delete a passed
+ // symlink. No need to worry about races, because remove_dir_all_recursive() does not recurse
+ // into symlinks.
+ let attr = lstat(p)?;
+ if attr.file_type().is_symlink() {
+ crate::fs::remove_file(p)
+ } else {
+ remove_dir_all_recursive(None, p)
+ }
+ }
+
+ mod libc {
+ pub use sgx_libc::ocall::{fdopendir, openat, unlinkat};
+ pub use sgx_libc::*;
+ }
+}
diff --git a/sgx_tstd/src/sys/mod.rs b/sgx_tstd/src/sys/mod.rs
index 589e18c..7811256 100644
--- a/sgx_tstd/src/sys/mod.rs
+++ b/sgx_tstd/src/sys/mod.rs
@@ -75,7 +75,7 @@
libc::ENOSPC => StorageFull,
libc::ENOSYS => Unsupported,
libc::EMLINK => TooManyLinks,
- libc::ENAMETOOLONG => FilenameTooLong,
+ libc::ENAMETOOLONG => InvalidFilename,
libc::ENETDOWN => NetworkDown,
libc::ENETUNREACH => NetworkUnreachable,
libc::ENOTCONN => NotConnected,
@@ -148,9 +148,6 @@
}
pub fn unsupported_err() -> io::Error {
- io::Error::new_const(
- io::ErrorKind::Unsupported,
- &"operation not supported on this platform",
- )
+ io::const_io_error!(io::ErrorKind::Unsupported, "operation not supported on this platform",)
}
}
diff --git a/sgx_tstd/src/sys/net.rs b/sgx_tstd/src/sys/net.rs
index 0683999..7375f07 100644
--- a/sgx_tstd/src/sys/net.rs
+++ b/sgx_tstd/src/sys/net.rs
@@ -44,9 +44,6 @@
return Ok(());
}
- // We may need to trigger a glibc workaround. See on_resolver_failure() for details.
- // on_resolver_failure();
-
if err == libc::EAI_SYSTEM {
return Err(io::Error::last_os_error());
}
@@ -117,9 +114,9 @@
let mut pollfd = libc::pollfd { fd: self.as_raw_fd(), events: libc::POLLOUT, revents: 0 };
if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
- return Err(io::Error::new_const(
+ return Err(io::const_io_error!(
io::ErrorKind::InvalidInput,
- &"cannot set a 0 duration timeout",
+ "cannot set a 0 duration timeout",
));
}
@@ -128,7 +125,7 @@
loop {
let elapsed = start.elapsed();
if elapsed >= timeout {
- return Err(io::Error::new_const(io::ErrorKind::TimedOut, &"connection timed out"));
+ return Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out"));
}
let timeout = timeout - elapsed;
@@ -155,9 +152,9 @@
// for POLLHUP rather than read readiness
if pollfd.revents & libc::POLLHUP != 0 {
let e = self.take_error()?.unwrap_or_else(|| {
- io::Error::new_const(
+ io::const_io_error!(
io::ErrorKind::Uncategorized,
- &"no error set after POLLHUP",
+ "no error set after POLLHUP",
)
});
return Err(e);
@@ -169,16 +166,6 @@
}
}
- // Attention:
- // this function is a blocking function, which make an OCALL
- // and block itself **in the untrusted OS**. This is very much
- // dangerous and is misleading.
- // In SGX programming, execution is by default in enclave and
- // cannot leak information by design. Howeverm, this function
- // is not. It leaks events.
- // This function is guarded by feature `net` and should only
- // be used on demand.
- // We don't support linux kernel < 2.6.28. So we only use accept4.
pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t) -> io::Result<Socket> {
// Unfortunately the only known way right now to accept a socket and
// atomically set the CLOEXEC flag is to use the `accept4` syscall on
@@ -274,9 +261,9 @@
let timeout = match dur {
Some(dur) => {
if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
- return Err(io::Error::new_const(
+ return Err(io::const_io_error!(
io::ErrorKind::InvalidInput,
- &"cannot set a 0 duration timeout",
+ "cannot set a 0 duration timeout",
));
}
diff --git a/sgx_tstd/src/sys/os.rs b/sgx_tstd/src/sys/os.rs
index de3821c..afcedf7 100644
--- a/sgx_tstd/src/sys/os.rs
+++ b/sgx_tstd/src/sys/os.rs
@@ -52,7 +52,7 @@
pub fn error_string(error: i32) -> String {
let mut buf = [0_i8; TMPBUF_SZ];
unsafe {
- assert!(!(trts_error::error_string(error, &mut buf) < 0), "strerror_r failure");
+ assert!(trts_error::error_string(error, &mut buf) >= 0, "strerror_r failure");
let p = buf.as_ptr() as *const _;
str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
@@ -162,9 +162,9 @@
pub fn current_exe() -> io::Result<PathBuf> {
match crate::fs::read_link("/proc/self/exe") {
- Err(ref e) if e.kind() == io::ErrorKind::NotFound => Err(io::Error::new_const(
+ Err(ref e) if e.kind() == io::ErrorKind::NotFound => Err(io::const_io_error!(
io::ErrorKind::Uncategorized,
- &"no /proc/self/exe available. Is /proc mounted?",
+ "no /proc/self/exe available. Is /proc mounted?",
)),
other => other,
}
diff --git a/sgx_tstd/src/sys/os_str.rs b/sgx_tstd/src/sys/os_str.rs
index dec62b4..33d0387 100644
--- a/sgx_tstd/src/sys/os_str.rs
+++ b/sgx_tstd/src/sys/os_str.rs
@@ -19,6 +19,7 @@
//! systems: just a `Vec<u8>`/`[u8]`.
use crate::borrow::Cow;
+use crate::collections::TryReserveError;
use crate::fmt;
use crate::fmt::Write;
use crate::mem;
@@ -126,11 +127,21 @@
}
#[inline]
+ pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
+ self.inner.try_reserve(additional)
+ }
+
+ #[inline]
pub fn reserve_exact(&mut self, additional: usize) {
self.inner.reserve_exact(additional)
}
#[inline]
+ pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
+ self.inner.try_reserve_exact(additional)
+ }
+
+ #[inline]
pub fn shrink_to_fit(&mut self) {
self.inner.shrink_to_fit()
}
diff --git a/sgx_tstd/src/sys/path.rs b/sgx_tstd/src/sys/path.rs
index d7d98cb..61ee743 100644
--- a/sgx_tstd/src/sys/path.rs
+++ b/sgx_tstd/src/sys/path.rs
@@ -15,8 +15,10 @@
// specific language governing permissions and limitations
// under the License..
+use crate::env;
use crate::ffi::OsStr;
-use crate::path::Prefix;
+use crate::io;
+use crate::path::{Path, PathBuf, Prefix};
#[inline]
pub fn is_sep_byte(b: u8) -> bool {
@@ -28,9 +30,50 @@
b == b'/'
}
+#[inline]
pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
None
}
pub const MAIN_SEP_STR: &str = "/";
pub const MAIN_SEP: char = '/';
+
+/// Make a POSIX path absolute without changing its semantics.
+pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
+ // This is mostly a wrapper around collecting `Path::components`, with
+ // exceptions made where this conflicts with the POSIX specification.
+ // See 4.13 Pathname Resolution, IEEE Std 1003.1-2017
+ // https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
+
+ let mut components = path.components();
+ let path_os = path.as_os_str().bytes();
+
+ let mut normalized = if path.is_absolute() {
+ // "If a pathname begins with two successive <slash> characters, the
+ // first component following the leading <slash> characters may be
+ // interpreted in an implementation-defined manner, although more than
+ // two leading <slash> characters shall be treated as a single <slash>
+ // character."
+ if path_os.starts_with(b"//") && !path_os.starts_with(b"///") {
+ components.next();
+ PathBuf::from("//")
+ } else {
+ PathBuf::new()
+ }
+ } else {
+ env::current_dir()?
+ };
+ normalized.extend(components);
+
+ // "Interfaces using pathname resolution may specify additional constraints
+ // when a pathname that does not name an existing directory contains at
+ // least one non- <slash> character and contains one or more trailing
+ // <slash> characters".
+ // A trailing <slash> is also meaningful if "a symbolic link is
+ // encountered during pathname resolution".
+ if path_os.ends_with(b"/") {
+ normalized.push("");
+ }
+
+ Ok(normalized)
+}
diff --git a/sgx_tstd/src/sys/rwlock.bak.rs b/sgx_tstd/src/sys/rwlock.bak.rs
deleted file mode 100644
index b9339a5..0000000
--- a/sgx_tstd/src/sys/rwlock.bak.rs
+++ /dev/null
@@ -1,308 +0,0 @@
-// 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 core::cell::UnsafeCell;
-use crate::sync::{SgxThreadCondvar, SgxThreadMutex, SgxThreadSpinlock};
-use crate::thread;
-use sgx_trts::libc;
-use sgx_types::{sgx_thread_t, SysError, SGX_THREAD_T_NULL};
-
-struct SgxThreadRwLockInner {
- readers_num: u32,
- writers_num: u32,
- busy: u32,
- writer_thread: sgx_thread_t,
- condvar: SgxThreadCondvar,
- mutex: SgxThreadMutex,
- spinlock: SgxThreadSpinlock,
-}
-
-impl SgxThreadRwLockInner {
- const fn new() -> Self {
- SgxThreadRwLockInner {
- readers_num: 0,
- writers_num: 0,
- busy: 0,
- writer_thread: SGX_THREAD_T_NULL,
- condvar: SgxThreadCondvar::new(),
- mutex: SgxThreadMutex::new(),
- spinlock: SgxThreadSpinlock::new(),
- }
- }
-
- unsafe fn ref_busy(&mut self) -> SysError {
- let ret: SysError;
- self.spinlock.lock();
- {
- if self.busy == u32::MAX {
- ret = Err(libc::EAGAIN);
- } else {
- self.busy += 1;
- ret = Ok(());
- }
- }
- self.spinlock.unlock();
- ret
- }
-
- unsafe fn deref_busy(&mut self) -> SysError {
- let ret: SysError;
- self.spinlock.lock();
- {
- if self.busy == 0 {
- ret = Err(libc::EAGAIN);
- } else {
- self.busy -= 1;
- ret = Ok(());
- }
- }
- self.spinlock.unlock();
- ret
- }
-
- unsafe fn read(&mut self) -> SysError {
- self.ref_busy()?;
- self.mutex.lock();
- {
- if self.writer_thread == thread::rsgx_thread_self() {
- self.mutex.unlock();
- self.deref_busy();
- return Err(libc::EDEADLK);
- }
- if self.readers_num == u32::MAX {
- self.mutex.unlock();
- self.deref_busy();
- return Err(libc::EAGAIN);
- }
- while self.writers_num > 0 {
- self.condvar.wait(&self.mutex);
- }
- self.readers_num += 1;
- }
- self.mutex.unlock();
- self.deref_busy();
- Ok(())
- }
-
- unsafe fn try_read(&mut self) -> SysError {
- self.ref_busy()?;
- self.mutex.lock();
- {
- let mut ret = Ok(());
- if self.writer_thread == thread::rsgx_thread_self() {
- ret = Err(libc::EDEADLK);
- } else if self.readers_num == u32::MAX {
- ret = Err(libc::EAGAIN);
- } else if self.writers_num > 0 {
- ret = Err(libc::EBUSY);
- }
- match ret {
- Ok(_) => {}
- Err(e) => {
- self.mutex.unlock();
- self.deref_busy();
- return Err(e);
- }
- }
- self.readers_num += 1;
- }
- self.mutex.unlock();
- self.deref_busy();
- Ok(())
- }
-
- unsafe fn write(&mut self) -> SysError {
- self.ref_busy()?;
- self.mutex.lock();
- {
- if self.writer_thread == thread::rsgx_thread_self() {
- self.mutex.unlock();
- self.deref_busy();
- return Err(libc::EDEADLK);
- }
-
- if self.writers_num == u32::MAX {
- self.mutex.unlock();
- self.deref_busy();
- return Err(libc::EAGAIN);
- }
-
- self.writers_num += 1;
- while self.readers_num > 0 {
- self.condvar.wait(&self.mutex);
- }
- while self.writer_thread != SGX_THREAD_T_NULL {
- self.condvar.wait(&self.mutex);
- }
- self.writer_thread = thread::rsgx_thread_self();
- }
- self.mutex.unlock();
- self.deref_busy();
- Ok(())
- }
-
- pub unsafe fn try_write(&mut self) -> SysError {
- self.ref_busy()?;
- self.mutex.lock();
- {
- let mut ret = Ok(());
- if self.writer_thread == thread::rsgx_thread_self() {
- ret = Err(libc::EDEADLK);
- } else if self.writers_num == u32::MAX {
- ret = Err(libc::EAGAIN);
- } else if self.readers_num > 0 || self.writer_thread != SGX_THREAD_T_NULL {
- ret = Err(libc::EBUSY);
- }
-
- match ret {
- Ok(_) => {}
- Err(e) => {
- self.mutex.unlock();
- self.deref_busy();
- return Err(e);
- }
- }
- self.writers_num += 1;
- self.writer_thread = thread::rsgx_thread_self();
- }
- self.mutex.unlock();
- self.deref_busy();
- Ok(())
- }
-
- unsafe fn read_unlock(&mut self) -> SysError {
- self.raw_unlock()
- }
-
- unsafe fn write_unlock(&mut self) -> SysError {
- self.raw_unlock()
- }
-
- unsafe fn raw_unlock(&mut self) -> SysError {
- self.mutex.lock();
- {
- if self.readers_num > 0 {
- self.readers_num -= 1;
- if self.readers_num == 0 && self.writers_num > 0 {
- self.condvar.broadcast();
- }
- } else {
- if self.writer_thread != thread::rsgx_thread_self() {
- self.mutex.unlock();
- return Err(libc::EPERM);
- }
- self.writers_num -= 1;
- self.writer_thread = SGX_THREAD_T_NULL;
- if self.busy > 0 {
- self.condvar.broadcast();
- }
- }
- }
- self.mutex.unlock();
- Ok(())
- }
-
- unsafe fn destroy(&mut self) -> SysError {
- self.mutex.lock();
- {
- if self.readers_num > 0 || self.writers_num > 0 || self.busy > 0 {
- self.spinlock.unlock();
- return Err(libc::EBUSY);
- }
-
- self.condvar.destroy();
- self.mutex.destroy();
- }
- self.spinlock.unlock();
- Ok(())
- }
-}
-
-/// An OS-based reader-writer lock.
-///
-/// This structure is entirely unsafe and serves as the lowest layer of a
-/// cross-platform binding of system rwlocks. It is recommended to use the
-/// safer types at the top level of this crate instead of this type.
-pub struct SgxThreadRwLock {
- lock: UnsafeCell<SgxThreadRwLockInner>,
-}
-
-impl SgxThreadRwLock {
- /// Creates a new reader-writer lock for use.
- pub const fn new() -> Self {
- SgxThreadRwLock {
- lock: UnsafeCell::new(SgxThreadRwLockInner::new()),
- }
- }
-
- /// Acquires shared access to the underlying lock, blocking the current
- /// thread to do so.
- #[inline]
- pub unsafe fn read(&self) -> SysError {
- let rwlock: &mut SgxThreadRwLockInner = &mut *self.lock.get();
- rwlock.read()
- }
-
- /// Attempts to acquire shared access to this lock, returning whether it
- /// succeeded or not.
- ///
- /// This function does not block the current thread.
- #[inline]
- pub unsafe fn try_read(&self) -> SysError {
- let rwlock: &mut SgxThreadRwLockInner = &mut *self.lock.get();
- rwlock.try_read()
- }
-
- /// Acquires write access to the underlying lock, blocking the current thread
- /// to do so.
- #[inline]
- pub unsafe fn write(&self) -> SysError {
- let rwlock: &mut SgxThreadRwLockInner = &mut *self.lock.get();
- rwlock.write()
- }
-
- /// Attempts to acquire exclusive access to this lock, returning whether it
- /// succeeded or not.
- ///
- /// This function does not block the current thread.
- #[inline]
- pub unsafe fn try_write(&self) -> SysError {
- let rwlock: &mut SgxThreadRwLockInner = &mut *self.lock.get();
- rwlock.try_write()
- }
-
- /// Unlocks previously acquired shared access to this lock.
- #[inline]
- pub unsafe fn read_unlock(&self) -> SysError {
- let rwlock: &mut SgxThreadRwLockInner = &mut *self.lock.get();
- rwlock.read_unlock()
- }
-
- /// Unlocks previously acquired exclusive access to this lock.
- #[inline]
- pub unsafe fn write_unlock(&self) -> SysError {
- let rwlock: &mut SgxThreadRwLockInner = &mut *self.lock.get();
- rwlock.write_unlock()
- }
-
- /// Destroys OS-related resources with this RWLock.
- #[inline]
- pub unsafe fn destroy(&self) -> SysError {
- let rwlock: &mut SgxThreadRwLockInner = &mut *self.lock.get();
- rwlock.destroy()
- }
-}
diff --git a/sgx_tstd/src/sys/thread.rs b/sgx_tstd/src/sys/thread.rs
index 8d0cfef..538995b 100644
--- a/sgx_tstd/src/sys/thread.rs
+++ b/sgx_tstd/src/sys/thread.rs
@@ -138,9 +138,9 @@
pub fn available_parallelism() -> io::Result<NonZeroUsize> {
let cpus = enclave::rsgx_get_cpu_core_num();
- NonZeroUsize::new(cpus as usize).ok_or_else(|| io::Error::new_const(
+ NonZeroUsize::new(cpus as usize).ok_or_else(|| io::const_io_error!(
io::ErrorKind::NotFound,
- &"The number of hardware threads is not known for the target platform",
+ "The number of hardware threads is not known for the target platform",
))
}
diff --git a/sgx_tstd/src/sys/time.rs b/sgx_tstd/src/sys/time.rs
index 9f28de2..d9b351a 100644
--- a/sgx_tstd/src/sys/time.rs
+++ b/sgx_tstd/src/sys/time.rs
@@ -157,15 +157,6 @@
Instant { t: now(libc::CLOCK_MONOTONIC) }
}
- pub const fn zero() -> Instant {
- Instant { t: Timespec::zero() }
- }
-
- pub fn actually_monotonic() -> bool {
- (cfg!(target_os = "linux") && cfg!(target_arch = "x86_64"))
- || (cfg!(target_os = "linux") && cfg!(target_arch = "x86"))
- }
-
pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
self.t.sub_timespec(&other.t).ok()
}
diff --git a/sgx_tstd/src/sys_common/backtrace.rs b/sgx_tstd/src/sys_common/backtrace.rs
index 5f3a88c..dd2d30c 100644
--- a/sgx_tstd/src/sys_common/backtrace.rs
+++ b/sgx_tstd/src/sys_common/backtrace.rs
@@ -24,7 +24,6 @@
use crate::io;
use crate::io::prelude::*;
use crate::path::{Path, PathBuf};
-use crate::sync::atomic::{self, Ordering};
use crate::sync::SgxThreadMutex as ThreadMutex;
use crate::sys::backtrace::{self, BacktraceFmt, BytesOrWideString, PrintFmt};
@@ -163,58 +162,14 @@
result
}
-pub enum RustBacktrace {
- Print(PrintFmt),
- Disabled,
- RuntimeDisabled,
-}
-
-/// Controls how the backtrace should be formatted.
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
-pub enum PrintFormat {
- /// Show only relevant data from the backtrace.
- Short = 2,
- /// Show all the frames with absolute path for files.
- Full = 3,
-}
-
-static ENABLED: atomic::AtomicIsize = atomic::AtomicIsize::new(1);
-
-// For now logging is turned off by default, and this function checks to see
-// whether the magical environment variable is present to see if it's turned on.
-pub fn rust_backtrace_env() -> RustBacktrace {
- // If the `backtrace` feature of this crate isn't enabled quickly return
- // `None` so this can be constant propagated all over the place to turn
- // optimize away callers.
- if !cfg!(feature = "backtrace") {
- return RustBacktrace::Disabled;
- }
-
- match ENABLED.load(Ordering::SeqCst) {
- 0 => RustBacktrace::Disabled,
- 1 => RustBacktrace::RuntimeDisabled,
- 2 => RustBacktrace::Print(PrintFmt::Short),
- 3 => RustBacktrace::Print(PrintFmt::Full),
- _ => unreachable!(),
- }
-}
-
-pub fn set_enabled(print_fmt: PrintFormat) {
- ENABLED.store(match print_fmt {
- PrintFormat::Short => 2,
- PrintFormat::Full => 3,
- }, Ordering::SeqCst);
-}
-
/// Prints the filename of the backtrace frame.
///
/// See also `output`.
-#[allow(unused_variables)]
pub fn output_filename(
fmt: &mut fmt::Formatter<'_>,
bows: BytesOrWideString<'_>,
- print_fmt: PrintFmt,
- cwd: Option<&PathBuf>,
+ _print_fmt: PrintFmt,
+ _cwd: Option<&PathBuf>,
) -> fmt::Result {
let file: Cow<'_, Path> = match bows {
BytesOrWideString::Bytes(bytes) => {
@@ -233,4 +188,4 @@
// }
// }
fmt::Display::fmt(&file.display(), fmt)
-}
\ No newline at end of file
+}
diff --git a/sgx_tstd/src/sys_common/fs.rs b/sgx_tstd/src/sys_common/fs.rs
index 0b6ea93..e006f9a 100644
--- a/sgx_tstd/src/sys_common/fs.rs
+++ b/sgx_tstd/src/sys_common/fs.rs
@@ -14,13 +14,14 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License..
+
+use crate::fs;
use crate::io::{self, Error, ErrorKind};
use crate::path::Path;
-use crate::untrusted::fs;
-pub(crate) const NOT_FILE_ERROR: Error = Error::new_const(
+pub(crate) const NOT_FILE_ERROR: Error = io::const_io_error!(
ErrorKind::InvalidInput,
- &"the source path is neither a regular file nor a symlink to a regular file",
+ "the source path is neither a regular file nor a symlink to a regular file",
);
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
diff --git a/sgx_tstd/src/sys_common/net.rs b/sgx_tstd/src/sys_common/net.rs
index f7964ef..dea810c 100644
--- a/sgx_tstd/src/sys_common/net.rs
+++ b/sgx_tstd/src/sys_common/net.rs
@@ -21,7 +21,7 @@
use crate::convert::{TryFrom, TryInto};
use crate::ffi::CString;
use crate::fmt;
-use crate::io::{self, Error, ErrorKind, IoSlice, IoSliceMut};
+use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
use crate::mem;
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
use crate::ptr;
@@ -82,7 +82,7 @@
*(storage as *const _ as *const c::sockaddr_in6)
})))
}
- _ => Err(Error::new_const(ErrorKind::InvalidInput, &"invalid argument")),
+ _ => Err(io::const_io_error!(ErrorKind::InvalidInput, "invalid argument")),
}
}
@@ -106,6 +106,7 @@
}
}
+#[allow(clippy::transmute_ptr_to_ref)]
impl Iterator for LookupHost {
type Item = SocketAddr;
fn next(&mut self) -> Option<SocketAddr> {
@@ -113,7 +114,7 @@
unsafe {
let cur = self.cur.as_ref()?;
self.cur = cur.ai_next;
- match sockaddr_to_addr(&*(cur.ai_addr as *const c::sockaddr_storage), cur.ai_addrlen as usize) {
+ match sockaddr_to_addr(mem::transmute(cur.ai_addr), cur.ai_addrlen as usize) {
Ok(addr) => return Some(addr),
Err(_) => continue,
}
@@ -139,7 +140,7 @@
($e:expr, $msg:expr) => {
match $e {
Some(r) => r,
- None => return Err(io::Error::new_const(io::ErrorKind::InvalidInput, &$msg)),
+ None => return Err(io::const_io_error!(io::ErrorKind::InvalidInput, $msg)),
}
};
}
diff --git a/sgx_tstd/src/sys_common/thread_local_key.rs b/sgx_tstd/src/sys_common/thread_local_key.rs
index e124508..a6d04ea 100644
--- a/sgx_tstd/src/sys_common/thread_local_key.rs
+++ b/sgx_tstd/src/sys_common/thread_local_key.rs
@@ -64,7 +64,7 @@
#![allow(non_camel_case_types)]
#![allow(dead_code)] // sys isn't exported yet
-use core::sync::atomic::{self, AtomicUsize, Ordering};
+use crate::sync::atomic::{self, AtomicUsize, Ordering};
use crate::sys::thread_local_key as imp;
use crate::sync::SgxThreadMutex;
diff --git a/sgx_tstd/src/sys_common/thread_parker/generic.rs b/sgx_tstd/src/sys_common/thread_parker/generic.rs
index 68da129..f30e346 100644
--- a/sgx_tstd/src/sys_common/thread_parker/generic.rs
+++ b/sgx_tstd/src/sys_common/thread_parker/generic.rs
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License..
-//! Parker implementaiton based on a Mutex and Condvar.
+//! Parker implementation based on a Mutex and Condvar.
use crate::sync::atomic::AtomicUsize;
use crate::sync::atomic::Ordering::SeqCst;
@@ -37,7 +37,7 @@
Parker { state: AtomicUsize::new(EMPTY), lock: Mutex::new(()), cvar: Condvar::new() }
}
- // This implementaiton doesn't require `unsafe`, but other implementations
+ // This implementation doesn't require `unsafe`, but other implementations
// may assume this is only called by the thread that owns the Parker.
#[allow(clippy::single_match)]
pub unsafe fn park(&self) {
@@ -73,7 +73,7 @@
}
}
- // This implementaiton doesn't require `unsafe`, but other implementations
+ // This implementation doesn't require `unsafe`, but other implementations
// may assume this is only called by the thread that owns the Parker.
pub unsafe fn park_timeout(&self, dur: Duration) {
// Like `park` above we have a fast path for an already-notified thread, and
diff --git a/sgx_tstd/src/sys_common/wtf8.rs b/sgx_tstd/src/sys_common/wtf8.rs
index d37342a..771be71 100644
--- a/sgx_tstd/src/sys_common/wtf8.rs
+++ b/sgx_tstd/src/sys_common/wtf8.rs
@@ -37,6 +37,7 @@
use crate::borrow::Cow;
use crate::char;
+use crate::collections::TryReserveError;
use crate::fmt;
use crate::hash::{Hash, Hasher};
use crate::iter::FromIterator;
@@ -246,11 +247,47 @@
self.bytes.reserve(additional)
}
+ /// Tries to reserve capacity for at least `additional` more length units
+ /// in the given `Wtf8Buf`. The `Wtf8Buf` may reserve more space to avoid
+ /// frequent reallocations. After calling `try_reserve`, capacity will be
+ /// greater than or equal to `self.len() + additional`. Does nothing if
+ /// capacity is already sufficient.
+ ///
+ /// # Errors
+ ///
+ /// If the capacity overflows, or the allocator reports a failure, then an error
+ /// is returned.
+ #[inline]
+ pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
+ self.bytes.try_reserve(additional)
+ }
+
#[inline]
pub fn reserve_exact(&mut self, additional: usize) {
self.bytes.reserve_exact(additional)
}
+ /// Tries to reserve the minimum capacity for exactly `additional`
+ /// length units in the given `Wtf8Buf`. After calling
+ /// `try_reserve_exact`, capacity will be greater than or equal to
+ /// `self.len() + additional` if it returns `Ok(())`.
+ /// Does nothing if the capacity is already sufficient.
+ ///
+ /// Note that the allocator may give the `Wtf8Buf` more space than it
+ /// requests. Therefore, capacity can not be relied upon to be precisely
+ /// minimal. Prefer [`try_reserve`] if future insertions are expected.
+ ///
+ /// [`try_reserve`]: Wtf8Buf::try_reserve
+ ///
+ /// # Errors
+ ///
+ /// If the capacity overflows, or the allocator reports a failure, then an error
+ /// is returned.
+ #[inline]
+ pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
+ self.bytes.try_reserve_exact(additional)
+ }
+
#[inline]
pub fn shrink_to_fit(&mut self) {
self.bytes.shrink_to_fit()
@@ -825,7 +862,8 @@
#[inline]
fn next(&mut self) -> Option<CodePoint> {
- next_code_point(&mut self.bytes).map(|c| CodePoint { value: c })
+ // SAFETY: `self.bytes` has been created from a WTF-8 string
+ unsafe { next_code_point(&mut self.bytes).map(|c| CodePoint { value: c }) }
}
#[inline]
diff --git a/sgx_tstd/src/thread/local.rs b/sgx_tstd/src/thread/local.rs
index e98c26d..6319514 100644
--- a/sgx_tstd/src/thread/local.rs
+++ b/sgx_tstd/src/thread/local.rs
@@ -116,6 +116,7 @@
///
/// [`std::thread::LocalKey`]: crate::thread::LocalKey
#[macro_export]
+#[cfg_attr(not(test), rustc_diagnostic_item = "thread_local_macro")]
#[allow_internal_unstable(thread_local_internals)]
macro_rules! thread_local {
// empty (base case for the recursion)
@@ -151,11 +152,11 @@
#[cfg(not(feature = "thread"))]
#[inline] // see comments below
unsafe fn __getit() -> $crate::result::Result<&'static $t, $crate::thread::AccessError> {
- const _REQUIRE_UNSTABLE: () = $crate::thread::require_unstable_const_init_thread_local();
+ const INIT_EXPR: $t = $init;
if !$crate::mem::needs_drop::<$t>() || $crate::thread::thread_policy() == $crate::thread::SgxThreadPolicy::Bound {
#[thread_local]
- static mut VAL: $t = $init;
+ static mut VAL: $t = INIT_EXPR;
Ok(&VAL)
} else {
Err($crate::thread::AccessError::new(
@@ -166,7 +167,10 @@
#[cfg(feature = "thread")]
unsafe fn __getit() -> $crate::result::Result<&'static $t, $crate::thread::AccessError> {
- const _REQUIRE_UNSTABLE: () = $crate::thread::require_unstable_const_init_thread_local();
+ const INIT_EXPR: $t = $init;
+
+ #[thread_local]
+ static mut VAL: $t = INIT_EXPR;
// If a dtor isn't needed we can do something "very raw" and
// just get going.
@@ -182,8 +186,6 @@
));
}
- #[thread_local]
- static mut VAL: $t = $init;
// 0 == dtor not registered
// 1 == dtor registered, dtor not run
// 2 == dtor registered and is running or has run
@@ -242,7 +244,11 @@
static __KEY: $crate::thread::__FastLocalKeyInner<$t> =
$crate::thread::__FastLocalKeyInner::new();
- __KEY.get(__init)
+ // FIXME: remove the #[allow(...)] marker when macros don't
+ // raise warning for missing/extraneous unsafe blocks anymore.
+ // See https://github.com/rust-lang/rust/issues/74838.
+ #[allow(unused_unsafe)]
+ unsafe { __KEY.get(__init) }
}
unsafe {
@@ -421,7 +427,7 @@
pub unsafe fn get(&self, init: fn() -> T) -> Result<&'static T, AccessError> {
if !mem::needs_drop::<T>() || thread::thread_policy() == SgxThreadPolicy::Bound {
- // SAFETY: The caller must ensure no reference is ever handed out to
+ // SAFETY: The caller must ensure no reference is ever handed out to
// the inner cell nor mutable reference to the Option<T> inside said
// cell. This make it safe to hand a reference, though the lifetime
// of 'static is itself unsafe, making the get method unsafe.
@@ -509,7 +515,7 @@
Key { inner: LazyKeyInner::new(), dtor_state: Cell::new(DtorState::Unregistered) }
}
- // note that this is just a publically-callable function only for the
+ // note that this is just a publicly-callable function only for the
// const-initialized form of thread locals, basically a way to call the
// free `register_dtor` function defined elsewhere in libstd.
pub unsafe fn register_dtor(a: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
@@ -518,7 +524,7 @@
pub unsafe fn get<F: FnOnce() -> T>(&self, init: F) -> Result<&'static T, AccessError> {
// SAFETY: See the definitions of `LazyKeyInner::get` and
- // `try_initialize` for more informations.
+ // `try_initialize` for more information.
//
// The caller must ensure no mutable references are ever active to
// the inner cell or the inner T when this is called.
@@ -547,13 +553,13 @@
if !super::pthread_info_tls.m_pthread.is_null() {
// Note:
- // If the current thread was created by pthread_create, we should call
+ // If the current thread was created by `pthread_create`, we should call
// the try_register_dtor function. You can know whether the current thread has
// been created by pthread_create() through the m_thread member of pthread_info
// (thread local storage) of pthread library in intel sgx sdk.
//
- // Destructor will only be called when a thread created by pthread_create exits,
- // because sys_common::thread_local::StaticKey does not call pthread_key_delete
+ // Destructor will only be called when a thread created by `pthread_create` exits,
+ // because `sys_common::thread_local::StaticKey` does not call `pthread_key_delete`
// to trigger the destructor.
if !mem::needs_drop::<T>() || self.try_register_dtor() {
// SAFETY: See comment above (his function doc).
diff --git a/sgx_tstd/src/thread/mod.rs b/sgx_tstd/src/thread/mod.rs
index 33fe854..9fcaf3f 100644
--- a/sgx_tstd/src/thread/mod.rs
+++ b/sgx_tstd/src/thread/mod.rs
@@ -55,6 +55,12 @@
#[macro_use]
mod local;
+#[cfg(feature = "thread")]
+mod scoped;
+
+#[cfg(feature = "thread")]
+pub use scoped::{scope, Scope, ScopedJoinHandle};
+
pub use self::local::{AccessError, LocalKey};
pub use self::local::statik::Key as __StaticLocalKeyInner;
@@ -63,11 +69,6 @@
#[cfg(feature = "thread")]
pub use self::local::os::Key as __OsLocalKeyInner;
-// This is only used to make thread locals with `const { .. }` initialization
-// expressions unstable. If and/or when that syntax is stabilized with thread
-// locals this will simply be removed.
-pub const fn require_unstable_const_init_thread_local() {}
-
////////////////////////////////////////////////////////////////////////////////
// Builder
////////////////////////////////////////////////////////////////////////////////
@@ -113,6 +114,7 @@
/// [`unwrap`]: crate::result::Result::unwrap
/// [naming-threads]: ./index.html#naming-threads
#[cfg(feature = "thread")]
+#[must_use = "must eventually spawn the thread"]
#[derive(Debug)]
pub struct Builder {
// A name for the thread-to-be, for identification in panic messages
@@ -281,6 +283,20 @@
F: Send + 'a,
T: Send + 'a,
{
+ Ok(JoinHandle(self.spawn_unchecked_(f, None)?))
+ }
+
+ unsafe fn spawn_unchecked_<'a, 'scope, F, T>(
+ self,
+ f: F,
+ scope_data: Option<&'scope scoped::ScopeData>,
+ ) -> io::Result<JoinInner<'scope, T>>
+ where
+ F: FnOnce() -> T,
+ F: Send + 'a,
+ T: Send + 'a,
+ 'scope: 'a,
+ {
let Builder { name } = self;
let my_thread = SgxThread::new(name.map(|name| {
@@ -288,7 +304,8 @@
}));
let their_thread = my_thread.clone();
- let my_packet: Arc<UnsafeCell<Option<Result<T>>>> = Arc::new(UnsafeCell::new(None));
+ let my_packet: Arc<Packet<'scope, T>> =
+ Arc::new(Packet { scope: scope_data, result: UnsafeCell::new(None) });
let their_packet = my_packet.clone();
let main = move || {
@@ -306,10 +323,14 @@
// closure (it is an Arc<...>) and `my_packet` will be stored in the
// same `JoinInner` as this closure meaning the mutation will be
// safe (not modify it and affect a value far away).
- *their_packet.get() = Some(try_result);
+ *their_packet.result.get() = Some(try_result);
};
- Ok(JoinHandle(JoinInner {
+ if let Some(scope_data) = scope_data {
+ scope_data.increment_num_running_threads();
+ }
+
+ Ok(JoinInner {
// SAFETY:
//
// `imp::Thread::new` takes a closure with a `'static` lifetime, since it's passed
@@ -323,14 +344,14 @@
// Similarly, the `sys` implementation must guarantee that no references to the closure
// exist after the thread has terminated, which is signaled by `Thread::join`
// returning.
- native: Some(imp::Thread::new(
+ native: imp::Thread::new(
mem::transmute::<Box<dyn FnOnce() + 'a>, Box<dyn FnOnce() + 'static>>(
Box::new(main),
- ),
- )?),
+ ),
+ )?,
thread: my_thread,
- packet: Packet(my_packet),
- }))
+ packet: my_packet,
+ })
}
}
@@ -787,10 +808,13 @@
/// A unique identifier for a running thread.
///
-/// A `ThreadId` is an opaque object that has a unique value for each thread
-/// that creates one. `ThreadId`s are not guaranteed to correspond to a thread's
-/// system-designated identifier. A `ThreadId` can be retrieved from the [`id`]
-/// method on a [`Thread`].
+/// A `ThreadId` is an opaque object that uniquely identifies each thread
+/// created during the lifetime of a process. `ThreadId`s are guaranteed not to
+/// be reused, even when a thread terminates. `ThreadId`s are under the control
+/// of Rust's standard library and there may not be any relationship between
+/// `ThreadId` and the underlying platform's notion of a thread identifier --
+/// the two concepts cannot, therefore, be used interchangeably. A `ThreadId`
+/// can be retrieved from the [`id`] method on a [`Thread`].
///
/// # Examples
///
@@ -821,7 +845,10 @@
// If we somehow use up all our bits, panic so that we're not
// covering up subtle bugs of IDs being reused.
- assert!(!(COUNTER == u64::MAX), "failed to generate unique thread ID: bitspace exhausted");
+ if COUNTER == u64::MAX {
+ let _ = GUARD.unlock(); // in case the panic handler ends up calling `ThreadId::new()`, avoid reentrant lock acquire.
+ panic!("failed to generate unique thread ID: bitspace exhausted");
+ }
let id = COUNTER;
COUNTER += 1;
@@ -1044,46 +1071,60 @@
/// [`std::panic::resume_unwind`]: crate::panic::resume_unwind
pub type Result<T> = crate::result::Result<T, Box<dyn Any + Send + 'static>>;
-// This packet is used to communicate the return value between the spawned thread
-// and the rest of the program. Memory is shared through the `Arc` within and there's
-// no need for a mutex here because synchronization happens with `join()` (the
-// caller will never read this packet until the thread has exited).
+// This packet is used to communicate the return value between the spawned
+// thread and the rest of the program. It is shared through an `Arc` and
+// there's no need for a mutex here because synchronization happens with `join()`
+// (the caller will never read this packet until the thread has exited).
//
-// This packet itself is then stored into a `JoinInner` which in turns is placed
-// in `JoinHandle` and `JoinGuard`. Due to the usage of `UnsafeCell` we need to
-// manually worry about impls like Send and Sync. The type `T` should
-// already always be Send (otherwise the thread could not have been created) and
-// this type is inherently Sync because no methods take &self. Regardless,
-// however, we add inheriting impls for Send/Sync to this type to ensure it's
-// Send/Sync and that future modifications will still appropriately classify it.
+// An Arc to the packet is stored into a `JoinInner` which in turns is placed
+// in `JoinHandle`.
#[cfg(feature = "thread")]
-struct Packet<T>(Arc<UnsafeCell<Option<Result<T>>>>);
+struct Packet<'scope, T> {
+ scope: Option<&'scope scoped::ScopeData>,
+ result: UnsafeCell<Option<Result<T>>>,
+}
+
+// Due to the usage of `UnsafeCell` we need to manually implement Sync.
+// The type `T` should already always be Send (otherwise the thread could not
+// have been created) and the Packet is Sync because all access to the
+// `UnsafeCell` synchronized (by the `join()` boundary), and `ScopeData` is Sync.
+#[cfg(feature = "thread")]
+unsafe impl<'scope, T: Sync> Sync for Packet<'scope, T> {}
#[cfg(feature = "thread")]
-unsafe impl<T: Send> Send for Packet<T> {}
-#[cfg(feature = "thread")]
-unsafe impl<T: Sync> Sync for Packet<T> {}
+impl<'scope, T> Drop for Packet<'scope, T> {
+ fn drop(&mut self) {
+ // Book-keeping so the scope knows when it's done.
+ if let Some(scope) = self.scope {
+ // If this packet was for a thread that ran in a scope, the thread
+ // panicked, and nobody consumed the panic payload, we make sure
+ // the scope function will panic.
+ let unhandled_panic = matches!(self.result.get_mut(), Some(Err(_)));
+ scope.decrement_num_running_threads(unhandled_panic);
+ }
+ }
+}
/// Inner representation for JoinHandle
#[cfg(feature = "thread")]
-struct JoinInner<T> {
- native: Option<imp::Thread>,
+struct JoinInner<'scope, T> {
+ native: imp::Thread,
thread: SgxThread,
- packet: Packet<T>,
+ packet: Arc<Packet<'scope, T>>,
}
#[cfg(feature = "thread")]
-impl<T> JoinInner<T> {
- fn join(&mut self) -> Result<T> {
- self.native.take().unwrap().join();
- unsafe { (*self.packet.0.get()).take().unwrap() }
+impl<'scope, T> JoinInner<'scope, T> {
+ fn join(mut self) -> Result<T> {
+ self.native.join();
+ Arc::get_mut(&mut self.packet).unwrap().result.get_mut().take().unwrap()
}
}
/// An owned permission to join on a thread (block on its termination).
///
/// A `JoinHandle` *detaches* the associated thread when it is dropped, which
-/// means that there is no longer any handle to thread and no way to `join`
+/// means that there is no longer any handle to the thread and no way to `join`
/// on it.
///
/// Due to platform restrictions, it is not possible to [`Clone`] this
@@ -1143,7 +1184,7 @@
/// [`thread::Builder::spawn`]: Builder::spawn
/// [`thread::spawn`]: spawn
#[cfg(feature = "thread")]
-pub struct JoinHandle<T>(JoinInner<T>);
+pub struct JoinHandle<T>(JoinInner<'static, T>);
#[cfg(feature = "thread")]
unsafe impl<T> Send for JoinHandle<T> {}
@@ -1206,22 +1247,30 @@
/// }).unwrap();
/// join_handle.join().expect("Couldn't join on the associated thread");
/// ```
- pub fn join(mut self) -> Result<T> {
+ pub fn join(self) -> Result<T> {
self.0.join()
}
+
+ /// Checks if the associated thread is still running its main function.
+ ///
+ /// This might return `false` for a brief moment after the thread's main
+ /// function has returned, but before the thread itself has stopped running.
+ pub fn is_running(&self) -> bool {
+ Arc::strong_count(&self.0.packet) > 1
+ }
}
#[cfg(feature = "thread")]
impl<T> AsInner<imp::Thread> for JoinHandle<T> {
fn as_inner(&self) -> &imp::Thread {
- self.0.native.as_ref().unwrap()
+ &self.0.native
}
}
#[cfg(feature = "thread")]
impl<T> IntoInner<imp::Thread> for JoinHandle<T> {
fn into_inner(self) -> imp::Thread {
- self.0.native.unwrap()
+ self.0.native
}
}
@@ -1256,9 +1305,12 @@
/// The purpose of this API is to provide an easy and portable way to query
/// the default amount of parallelism the program should use. Among other things it
/// does not expose information on NUMA regions, does not account for
-/// differences in (co)processor capabilities, and will not modify the program's
-/// global state in order to more accurately query the amount of available
-/// parallelism.
+/// differences in (co)processor capabilities or current system load,
+/// and will not modify the program's global state in order to more accurately
+/// query the amount of available parallelism.
+///
+/// Where both fixed steady-state and burst limits are available the steady-state
+/// capacity will be used to ensure more predictable latencies.
///
/// Resource limits can be changed during the runtime of a program, therefore the value is
/// not cached and instead recomputed every time this function is called. It should not be
@@ -1271,6 +1323,15 @@
/// platform-specific APIs as well. The following platform limitations currently
/// apply to `available_parallelism`:
///
+/// On Windows:
+/// - It may undercount the amount of parallelism available on systems with more
+/// than 64 logical CPUs. However, programs typically need specific support to
+/// take advantage of more than 64 logical CPUs, and in the absence of such
+/// support, the number returned by this function accurately reflects the
+/// number of logical CPUs the program can use by default.
+/// - It may overcount the amount of parallelism available on systems limited by
+/// process-wide affinity masks, or job object limitations.
+///
/// On Linux:
/// - It may overcount the amount of parallelism available when limited by a
/// process-wide affinity mask, or when affected by cgroup limits.
@@ -1292,10 +1353,10 @@
///
/// ```
/// # #![allow(dead_code)]
-/// #![feature(available_parallelism)]
-/// use std::thread;
+/// use std::{io, thread};
///
-/// let count = thread::available_parallelism().map(|n| n.get()).unwrap_or(1);
+/// let count = thread::available_parallelism()?.get();
+/// assert!(count >= 1_usize);
/// ```
#[cfg(feature = "thread")]
pub fn available_parallelism() -> io::Result<NonZeroUsize> {
diff --git a/sgx_tstd/src/thread/scoped.rs b/sgx_tstd/src/thread/scoped.rs
new file mode 100644
index 0000000..5a4b9c9
--- /dev/null
+++ b/sgx_tstd/src/thread/scoped.rs
@@ -0,0 +1,332 @@
+// 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 super::{current, park, Builder, JoinInner, Result, SgxThread};
+use crate::fmt;
+use crate::io;
+use crate::marker::PhantomData;
+use crate::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};
+use crate::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
+use crate::sync::Arc;
+
+/// A scope to spawn scoped threads in.
+///
+/// See [`scope`] for details.
+pub struct Scope<'env> {
+ data: ScopeData,
+ /// Invariance over 'env, to make sure 'env cannot shrink,
+ /// which is necessary for soundness.
+ ///
+ /// Without invariance, this would compile fine but be unsound:
+ ///
+ /// ```compile_fail
+ /// #![feature(scoped_threads)]
+ ///
+ /// std::thread::scope(|s| {
+ /// s.spawn(|s| {
+ /// let a = String::from("abcd");
+ /// s.spawn(|_| println!("{:?}", a)); // might run after `a` is dropped
+ /// });
+ /// });
+ /// ```
+ env: PhantomData<&'env mut &'env ()>,
+}
+
+/// An owned permission to join on a scoped thread (block on its termination).
+///
+/// See [`Scope::spawn`] for details.
+pub struct ScopedJoinHandle<'scope, T>(JoinInner<'scope, T>);
+
+pub(super) struct ScopeData {
+ num_running_threads: AtomicUsize,
+ a_thread_panicked: AtomicBool,
+ main_thread: SgxThread,
+}
+
+impl ScopeData {
+ pub(super) fn increment_num_running_threads(&self) {
+ // We check for 'overflow' with usize::MAX / 2, to make sure there's no
+ // chance it overflows to 0, which would result in unsoundness.
+ if self.num_running_threads.fetch_add(1, Ordering::Relaxed) > usize::MAX / 2 {
+ // This can only reasonably happen by mem::forget()'ing many many ScopedJoinHandles.
+ self.decrement_num_running_threads(false);
+ panic!("too many running threads in thread scope");
+ }
+ }
+ pub(super) fn decrement_num_running_threads(&self, panic: bool) {
+ if panic {
+ self.a_thread_panicked.store(true, Ordering::Relaxed);
+ }
+ if self.num_running_threads.fetch_sub(1, Ordering::Release) == 1 {
+ self.main_thread.unpark();
+ }
+ }
+}
+
+/// Create a scope for spawning scoped threads.
+///
+/// The function passed to `scope` will be provided a [`Scope`] object,
+/// through which scoped threads can be [spawned][`Scope::spawn`].
+///
+/// Unlike non-scoped threads, scoped threads can borrow non-`'static` data,
+/// as the scope guarantees all threads will be joined at the end of the scope.
+///
+/// All threads spawned within the scope that haven't been manually joined
+/// will be automatically joined before this function returns.
+///
+/// # Panics
+///
+/// If any of the automatically joined threads panicked, this function will panic.
+///
+/// If you want to handle panics from spawned threads,
+/// [`join`][ScopedJoinHandle::join] them before the end of the scope.
+///
+/// # Example
+///
+/// ```
+/// #![feature(scoped_threads)]
+/// use std::thread;
+///
+/// let mut a = vec![1, 2, 3];
+/// let mut x = 0;
+///
+/// thread::scope(|s| {
+/// s.spawn(|_| {
+/// println!("hello from the first scoped thread");
+/// // We can borrow `a` here.
+/// dbg!(&a);
+/// });
+/// s.spawn(|_| {
+/// println!("hello from the second scoped thread");
+/// // We can even mutably borrow `x` here,
+/// // because no other threads are using it.
+/// x += a[0] + a[2];
+/// });
+/// println!("hello from the main thread");
+/// });
+///
+/// // After the scope, we can modify and access our variables again:
+/// a.push(4);
+/// assert_eq!(x, a.len());
+/// ```
+#[track_caller]
+pub fn scope<'env, F, T>(f: F) -> T
+where
+ F: FnOnce(&Scope<'env>) -> T,
+{
+ let scope = Scope {
+ data: ScopeData {
+ num_running_threads: AtomicUsize::new(0),
+ main_thread: current(),
+ a_thread_panicked: AtomicBool::new(false),
+ },
+ env: PhantomData,
+ };
+
+ // Run `f`, but catch panics so we can make sure to wait for all the threads to join.
+ let result = catch_unwind(AssertUnwindSafe(|| f(&scope)));
+
+ // Wait until all the threads are finished.
+ while scope.data.num_running_threads.load(Ordering::Acquire) != 0 {
+ park();
+ }
+
+ // Throw any panic from `f`, or the return value of `f` if no thread panicked.
+ match result {
+ Err(e) => resume_unwind(e),
+ Ok(_) if scope.data.a_thread_panicked.load(Ordering::Relaxed) => {
+ panic!("a scoped thread panicked")
+ }
+ Ok(result) => result,
+ }
+}
+
+impl<'env> Scope<'env> {
+ /// Spawns a new thread within a scope, returning a [`ScopedJoinHandle`] for it.
+ ///
+ /// Unlike non-scoped threads, threads spawned with this function may
+ /// borrow non-`'static` data from the outside the scope. See [`scope`] for
+ /// details.
+ ///
+ /// The join handle provides a [`join`] method that can be used to join the spawned
+ /// thread. If the spawned thread panics, [`join`] will return an [`Err`] containing
+ /// the panic payload.
+ ///
+ /// If the join handle is dropped, the spawned thread will implicitly joined at the
+ /// end of the scope. In that case, if the spawned thread panics, [`scope`] will
+ /// panic after all threads are joined.
+ ///
+ /// This call will create a thread using default parameters of [`Builder`].
+ /// If you want to specify the stack size or the name of the thread, use
+ /// [`Builder::spawn_scoped`] instead.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the OS fails to create a thread; use [`Builder::spawn_scoped`]
+ /// to recover from such errors.
+ ///
+ /// [`join`]: ScopedJoinHandle::join
+ pub fn spawn<'scope, F, T>(&'scope self, f: F) -> ScopedJoinHandle<'scope, T>
+ where
+ F: FnOnce(&Scope<'env>) -> T + Send + 'env,
+ T: Send + 'env,
+ {
+ Builder::new().spawn_scoped(self, f).expect("failed to spawn thread")
+ }
+}
+
+impl Builder {
+ /// Spawns a new scoped thread using the settings set through this `Builder`.
+ ///
+ /// Unlike [`Scope::spawn`], this method yields an [`io::Result`] to
+ /// capture any failure to create the thread at the OS level.
+ ///
+ /// [`io::Result`]: crate::io::Result
+ ///
+ /// # Panics
+ ///
+ /// Panics if a thread name was set and it contained null bytes.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// #![feature(scoped_threads)]
+ /// use std::thread;
+ ///
+ /// let mut a = vec![1, 2, 3];
+ /// let mut x = 0;
+ ///
+ /// thread::scope(|s| {
+ /// thread::Builder::new()
+ /// .name("first".to_string())
+ /// .spawn_scoped(s, |_|
+ /// {
+ /// println!("hello from the {:?} scoped thread", thread::current().name());
+ /// // We can borrow `a` here.
+ /// dbg!(&a);
+ /// })
+ /// .unwrap();
+ /// thread::Builder::new()
+ /// .name("second".to_string())
+ /// .spawn_scoped(s, |_|
+ /// {
+ /// println!("hello from the {:?} scoped thread", thread::current().name());
+ /// // We can even mutably borrow `x` here,
+ /// // because no other threads are using it.
+ /// x += a[0] + a[2];
+ /// })
+ /// .unwrap();
+ /// println!("hello from the main thread");
+ /// });
+ ///
+ /// // After the scope, we can modify and access our variables again:
+ /// a.push(4);
+ /// assert_eq!(x, a.len());
+ /// ```
+ pub fn spawn_scoped<'scope, 'env, F, T>(
+ self,
+ scope: &'scope Scope<'env>,
+ f: F,
+ ) -> io::Result<ScopedJoinHandle<'scope, T>>
+ where
+ F: FnOnce(&Scope<'env>) -> T + Send + 'env,
+ T: Send + 'env,
+ {
+ Ok(ScopedJoinHandle(unsafe { self.spawn_unchecked_(|| f(scope), Some(&scope.data)) }?))
+ }
+}
+
+impl<'scope, T> ScopedJoinHandle<'scope, T> {
+ /// Extracts a handle to the underlying thread.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(scoped_threads)]
+ /// #![feature(thread_is_running)]
+ ///
+ /// use std::thread;
+ ///
+ /// thread::scope(|s| {
+ /// let t = s.spawn(|_| {
+ /// println!("hello");
+ /// });
+ /// println!("thread id: {:?}", t.thread().id());
+ /// });
+ /// ```
+ #[must_use]
+ pub fn thread(&self) -> &SgxThread {
+ &self.0.thread
+ }
+
+ /// Waits for the associated thread to finish.
+ ///
+ /// This function will return immediately if the associated thread has already finished.
+ ///
+ /// In terms of [atomic memory orderings], the completion of the associated
+ /// thread synchronizes with this function returning.
+ /// In other words, all operations performed by that thread
+ /// [happen before](https://doc.rust-lang.org/nomicon/atomics.html#data-accesses)
+ /// all operations that happen after `join` returns.
+ ///
+ /// If the associated thread panics, [`Err`] is returned with the panic payload.
+ ///
+ /// [atomic memory orderings]: crate::sync::atomic
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(scoped_threads)]
+ /// #![feature(thread_is_running)]
+ ///
+ /// use std::thread;
+ ///
+ /// thread::scope(|s| {
+ /// let t = s.spawn(|_| {
+ /// panic!("oh no");
+ /// });
+ /// assert!(t.join().is_err());
+ /// });
+ /// ```
+ pub fn join(self) -> Result<T> {
+ self.0.join()
+ }
+
+ /// Checks if the associated thread is still running its main function.
+ ///
+ /// This might return `false` for a brief moment after the thread's main
+ /// function has returned, but before the thread itself has stopped running.
+ pub fn is_running(&self) -> bool {
+ Arc::strong_count(&self.0.packet) > 1
+ }
+}
+
+impl<'env> fmt::Debug for Scope<'env> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("Scope")
+ .field("num_running_threads", &self.data.num_running_threads.load(Ordering::Relaxed))
+ .field("a_thread_panicked", &self.data.a_thread_panicked.load(Ordering::Relaxed))
+ .field("main_thread", &self.data.main_thread)
+ .finish_non_exhaustive()
+ }
+}
+
+impl<'scope, T> fmt::Debug for ScopedJoinHandle<'scope, T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("ScopedJoinHandle").finish_non_exhaustive()
+ }
+}
diff --git a/sgx_tstd/src/time.rs b/sgx_tstd/src/time.rs
index fe761bc..6de4707 100644
--- a/sgx_tstd/src/time.rs
+++ b/sgx_tstd/src/time.rs
@@ -48,8 +48,6 @@
#![allow(clippy::needless_doctest_main)]
-mod monotonic;
-
use crate::error::Error;
use crate::fmt;
use crate::ops::{Add, AddAssign, Sub, SubAssign};
@@ -58,16 +56,16 @@
pub use core::time::Duration;
-pub use core::time::FromSecsError;
+pub use core::time::FromFloatSecsError;
/// A measurement of a monotonically nondecreasing clock.
/// Opaque and useful only with [`Duration`].
///
-/// Instants are always guaranteed to be no less than any previously measured
-/// instant when created, and are often useful for tasks such as measuring
+/// Instants are always guaranteed, barring [platform bugs], to be no less than any previously
+/// measured instant when created, and are often useful for tasks such as measuring
/// benchmarks or timing how long an operation takes.
///
-/// Note, however, that instants are not guaranteed to be **steady**. In other
+/// Note, however, that instants are **not** guaranteed to be **steady**. In other
/// words, each tick of the underlying clock might not be the same length (e.g.
/// some seconds may be longer than others). An instant may jump forwards or
/// experience time dilation (slow down or speed up), but it will never go
@@ -97,6 +95,8 @@
/// }
/// ```
///
+/// [platform bugs]: Instant#monotonicity
+///
/// # OS-specific behaviors
///
/// An `Instant` is a wrapper around system-specific types and it may behave
@@ -138,6 +138,26 @@
/// > structure cannot represent the new point in time.
///
/// [`add`]: Instant::add
+///
+/// ## Monotonicity
+///
+/// On all platforms `Instant` will try to use an OS API that guarantees monotonic behavior
+/// if available, which is the case for all [tier 1] platforms.
+/// In practice such guarantees are – under rare circumstances – broken by hardware, virtualization
+/// or operating system bugs. To work around these bugs and platforms not offering monotonic clocks
+/// [`duration_since`], [`elapsed`] and [`sub`] saturate to zero. In older Rust versions this
+/// lead to a panic instead. [`checked_duration_since`] can be used to detect and handle situations
+/// where monotonicity is violated, or `Instant`s are subtracted in the wrong order.
+///
+/// This workaround obscures programming errors where earlier and later instants are accidentally
+/// swapped. For this reason future rust versions may reintroduce panics.
+///
+/// [tier 1]: https://doc.rust-lang.org/rustc/platform-support.html
+/// [`duration_since`]: Instant::duration_since
+/// [`elapsed`]: Instant::elapsed
+/// [`sub`]: Instant::sub
+/// [`checked_duration_since`]: Instant::checked_duration_since
+///
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Instant(time::Instant);
@@ -189,7 +209,12 @@
/// }
/// ```
///
-/// # Underlying System calls
+/// # Platform-specific behavior
+///
+/// The precision of `SystemTime` can depend on the underlying OS-specific time format.
+/// For example, on Windows the time is represented in 100 nanosecond intervals whereas Linux
+/// can represent nanosecond intervals.
+///
/// Currently, the following system calls are being used to get the current time using `now()`:
///
/// | Platform | System call |
@@ -258,81 +283,47 @@
Instant::_now()
}
+ #[inline]
pub(crate) fn _now() -> Instant {
- let os_now = time::Instant::now();
-
- // And here we come upon a sad state of affairs. The whole point of
- // `Instant` is that it's monotonically increasing. We've found in the
- // wild, however, that it's not actually monotonically increasing for
- // one reason or another. These appear to be OS and hardware level bugs,
- // and there's not really a whole lot we can do about them. Here's a
- // taste of what we've found:
- //
- // * #48514 - OpenBSD, x86_64
- // * #49281 - linux arm64 and s390x
- // * #51648 - windows, x86
- // * #56560 - windows, x86_64, AWS
- // * #56612 - windows, x86, vm (?)
- // * #56940 - linux, arm64
- // * https://bugzilla.mozilla.org/show_bug.cgi?id=1487778 - a similar
- // Firefox bug
- //
- // It seems that this just happens a lot in the wild.
- // We're seeing panics across various platforms where consecutive calls
- // to `Instant::now`, such as via the `elapsed` function, are panicking
- // as they're going backwards. Placed here is a last-ditch effort to try
- // to fix things up. We keep a global "latest now" instance which is
- // returned instead of what the OS says if the OS goes backwards.
- //
- // To hopefully mitigate the impact of this, a few platforms are
- // excluded as "these at least haven't gone backwards yet".
- //
- // While issues have been seen on arm64 platforms the Arm architecture
- // requires that the counter monotonically increases and that it must
- // provide a uniform view of system time (e.g. it must not be possible
- // for a core to recieve a message from another core with a time stamp
- // and observe time going backwards (ARM DDI 0487G.b D11.1.2). While
- // there have been a few 64bit SoCs that have bugs which cause time to
- // not monoticially increase, these have been fixed in the Linux kernel
- // and we shouldn't penalize all Arm SoCs for those who refuse to
- // update their kernels:
- // SUN50I_ERRATUM_UNKNOWN1 - Allwinner A64 / Pine A64 - fixed in 5.1
- // FSL_ERRATUM_A008585 - Freescale LS2080A/LS1043A - fixed in 4.10
- // HISILICON_ERRATUM_161010101 - Hisilicon 1610 - fixed in 4.11
- // ARM64_ERRATUM_858921 - Cortex A73 - fixed in 4.12
- if time::Instant::actually_monotonic() {
- return Instant(os_now);
- }
-
- Instant(monotonic::monotonize(os_now))
+ Instant(time::Instant::now())
}
- /// Returns the amount of time elapsed from another instant to this one.
+ /// Returns the amount of time elapsed from another instant to this one,
+ /// or zero duration if that instant is later than this one.
///
/// # Panics
///
- /// This function will panic if `earlier` is later than `self`.
+ /// Previous rust versions panicked when `earlier` was later than `self`. Currently this
+ /// method saturates. Future versions may reintroduce the panic in some circumstances.
+ /// See [Monotonicity].
+ ///
+ /// [Monotonicity]: Instant#monotonicity
///
/// # Examples
///
/// ```no_run
/// use std::time::{Duration, Instant};
/// use std::thread::sleep;
- /// use std::untrusted::time::InstantEx;
///
/// let now = Instant::now();
/// sleep(Duration::new(1, 0));
/// let new_now = Instant::now();
/// println!("{:?}", new_now.duration_since(now));
+ /// println!("{:?}", now.duration_since(new_now)); // 0ns
/// ```
#[must_use]
pub fn duration_since(&self, earlier: Instant) -> Duration {
- self.0.checked_sub_instant(&earlier.0).expect("supplied instant is later than self")
+ self.checked_duration_since(earlier).unwrap_or_default()
}
/// Returns the amount of time elapsed from another instant to this one,
/// or None if that instant is later than this one.
///
+ /// Due to [monotonicity bugs], even under correct logical ordering of the passed `Instant`s,
+ /// this method can return `None`.
+ ///
+ /// [monotonicity bugs]: Instant#monotonicity
+ ///
/// # Examples
///
/// ```no_run
@@ -376,9 +367,11 @@
///
/// # Panics
///
- /// This function may panic if the current time is earlier than this
- /// instant, which is something that can happen if an `Instant` is
- /// produced synthetically.
+ /// Previous rust versions panicked when self was earlier than the current time. Currently this
+ /// method returns a Duration of zero in that case. Future versions may reintroduce the panic.
+ /// See [Monotonicity].
+ ///
+ /// [Monotonicity]: Instant#monotonicity
///
/// # Examples
///
@@ -454,6 +447,16 @@
impl Sub<Instant> for Instant {
type Output = Duration;
+ /// Returns the amount of time elapsed from another instant to this one,
+ /// or zero duration if that instant is later than this one.
+ ///
+ /// # Panics
+ ///
+ /// Previous rust versions panicked when `other` was later than `self`. Currently this
+ /// method saturates. Future versions may reintroduce the panic in some circumstances.
+ /// See [Monotonicity].
+ ///
+ /// [Monotonicity]: Instant#monotonicity
fn sub(self, other: Instant) -> Duration {
self.duration_since(other)
}
@@ -503,6 +506,7 @@
SystemTime::_now()
}
+ #[inline]
pub(crate) fn _now() -> SystemTime {
SystemTime(time::SystemTime::now())
}
diff --git a/sgx_tstd/src/time/monotonic.rs b/sgx_tstd/src/time/monotonic.rs
deleted file mode 100644
index f577a6c..0000000
--- a/sgx_tstd/src/time/monotonic.rs
+++ /dev/null
@@ -1,134 +0,0 @@
-// 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 crate::sys::time;
-
-#[inline]
-pub(super) fn monotonize(raw: time::Instant) -> time::Instant {
- inner::monotonize(raw)
-}
-
-#[cfg(all(target_has_atomic = "64", not(target_has_atomic = "128")))]
-pub mod inner {
- use crate::sync::atomic::AtomicU64;
- use crate::sync::atomic::Ordering::*;
- use crate::sys::time;
- use crate::time::Duration;
-
- pub(in crate::time) const ZERO: time::Instant = time::Instant::zero();
-
- // bits 30 and 31 are never used since the nanoseconds part never exceeds 10^9
- const UNINITIALIZED: u64 = 0b11 << 30;
- static MONO: AtomicU64 = AtomicU64::new(UNINITIALIZED);
-
- #[inline]
- pub(super) fn monotonize(raw: time::Instant) -> time::Instant {
- monotonize_impl(&MONO, raw)
- }
-
- #[inline]
- pub(in crate::time) fn monotonize_impl(mono: &AtomicU64, raw: time::Instant) -> time::Instant {
- let delta = raw.checked_sub_instant(&ZERO).unwrap();
- let secs = delta.as_secs();
- // occupies no more than 30 bits (10^9 seconds)
- let nanos = delta.subsec_nanos() as u64;
-
- // This wraps around every 136 years (2^32 seconds).
- // To detect backsliding we use wrapping arithmetic and declare forward steps smaller
- // than 2^31 seconds as expected and everything else as a backslide which will be
- // monotonized.
- // This could be a problem for programs that call instants at intervals greater
- // than 68 years. Interstellar probes may want to ensure that actually_monotonic() is true.
- let packed = (secs << 32) | nanos;
- let updated = mono.fetch_update(Relaxed, Relaxed, |old| {
- (old == UNINITIALIZED || packed.wrapping_sub(old) < u64::MAX / 2).then_some(packed)
- });
- match updated {
- Ok(_) => raw,
- Err(newer) => {
- // Backslide occurred. We reconstruct monotonized time from the upper 32 bit of the
- // passed in value and the 64bits loaded from the atomic
- let seconds_lower = newer >> 32;
- let mut seconds_upper = secs & 0xffff_ffff_0000_0000;
- if secs & 0xffff_ffff > seconds_lower {
- // Backslide caused the lower 32bit of the seconds part to wrap.
- // This must be the case because the seconds part is larger even though
- // we are in the backslide branch, i.e. the seconds count should be smaller or equal.
- //
- // We assume that backslides are smaller than 2^32 seconds
- // which means we need to add 1 to the upper half to restore it.
- //
- // Example:
- // most recent observed time: 0xA1_0000_0000_0000_0000u128
- // bits stored in AtomicU64: 0x0000_0000_0000_0000u64
- // backslide by 1s
- // caller time is 0xA0_ffff_ffff_0000_0000u128
- // -> we can fix up the upper half time by adding 1 << 32
- seconds_upper = seconds_upper.wrapping_add(0x1_0000_0000);
- }
- let secs = seconds_upper | seconds_lower;
- let nanos = newer as u32;
- ZERO.checked_add_duration(&Duration::new(secs, nanos)).unwrap()
- }
- }
- }
-}
-
-#[cfg(target_has_atomic = "128")]
-pub mod inner {
- use crate::sync::atomic::AtomicU128;
- use crate::sync::atomic::Ordering::*;
- use crate::sys::time;
- use crate::time::Duration;
-
- const ZERO: time::Instant = time::Instant::zero();
- static MONO: AtomicU128 = AtomicU128::new(0);
-
- #[inline]
- pub(super) fn monotonize(raw: time::Instant) -> time::Instant {
- let delta = raw.checked_sub_instant(&ZERO).unwrap();
- // Split into seconds and nanos since Duration doesn't have a
- // constructor that takes a u128
- let secs = delta.as_secs() as u128;
- let nanos = delta.subsec_nanos() as u128;
- let timestamp: u128 = secs << 64 | nanos;
- let timestamp = MONO.fetch_max(timestamp, Relaxed).max(timestamp);
- let secs = (timestamp >> 64) as u64;
- let nanos = timestamp as u32;
- ZERO.checked_add_duration(&Duration::new(secs, nanos)).unwrap()
- }
-}
-
-#[cfg(not(any(target_has_atomic = "64", target_has_atomic = "128")))]
-pub mod inner {
- use crate::cmp;
- use crate::sys::time;
- use crate::sys_common::mutex::StaticMutex;
-
- #[inline]
- pub(super) fn monotonize(os_now: time::Instant) -> time::Instant {
- static LOCK: SgxThreadMutex = SgxThreadMutex::new();
- static mut LAST_NOW: time::Instant = time::Instant::zero();
- unsafe {
- let _lock = LOCK.lock();
- let now = cmp::max(LAST_NOW, os_now);
- LAST_NOW = now;
- let _ = LOCK.unlock();
- now
- }
- }
-}
diff --git a/sgx_tstd/src/untrusted/path.rs b/sgx_tstd/src/untrusted/path.rs
index eae9843..fb6144f 100644
--- a/sgx_tstd/src/untrusted/path.rs
+++ b/sgx_tstd/src/untrusted/path.rs
@@ -15,10 +15,9 @@
// specific language governing permissions and limitations
// under the License..
-use crate::untrusted::fs;
+use crate::fs;
use crate::io;
-use crate::path::Path;
-use crate::path::PathBuf;
+use crate::path::{self, Path, PathBuf};
pub trait PathEx {
fn metadata(&self) -> io::Result<fs::Metadata>;
@@ -275,3 +274,73 @@
fs::symlink_metadata(self).map(|m| m.is_symlink()).unwrap_or(false)
}
}
+
+/// Makes the path absolute without accessing the filesystem.
+///
+/// If the path is relative, the current directory is used as the base directory.
+/// All intermediate components will be resolved according to platforms-specific
+/// rules but unlike [`canonicalize`][crate::fs::canonicalize] this does not
+/// resolve symlinks and may succeed even if the path does not exist.
+///
+/// If the `path` is empty or getting the
+/// [current directory][crate::env::current_dir] fails then an error will be
+/// returned.
+///
+/// # Examples
+///
+/// ## Posix paths
+///
+/// ```
+/// #![feature(absolute_path)]
+/// # #[cfg(unix)]
+/// fn main() -> std::io::Result<()> {
+/// use std::path::{self, Path};
+///
+/// // Relative to absolute
+/// let absolute = path::absolute("foo/./bar")?;
+/// assert!(absolute.ends_with("foo/bar"));
+///
+/// // Absolute to absolute
+/// let absolute = path::absolute("/foo//test/.././bar.rs")?;
+/// assert_eq!(absolute, Path::new("/foo/test/../bar.rs"));
+/// Ok(())
+/// }
+/// # #[cfg(not(unix))]
+/// # fn main() {}
+/// ```
+///
+/// The path is resolved using [POSIX semantics][posix-semantics] except that
+/// it stops short of resolving symlinks. This means it will keep `..`
+/// components and trailing slashes.
+///
+/// ## Windows paths
+///
+/// ```
+/// #![feature(absolute_path)]
+/// # #[cfg(windows)]
+/// fn main() -> std::io::Result<()> {
+/// use std::path::{self, Path};
+///
+/// // Relative to absolute
+/// let absolute = path::absolute("foo/./bar")?;
+/// assert!(absolute.ends_with(r"foo\bar"));
+///
+/// // Absolute to absolute
+/// let absolute = path::absolute(r"C:\foo//test\..\./bar.rs")?;
+///
+/// assert_eq!(absolute, Path::new(r"C:\foo\bar.rs"));
+/// Ok(())
+/// }
+/// # #[cfg(not(windows))]
+/// # fn main() {}
+/// ```
+///
+/// For verbatim paths this will simply return the path as given. For other
+/// paths this is currently equivalent to calling [`GetFullPathNameW`][windows-path]
+/// This may change in the future.
+///
+/// [posix-semantics]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
+/// [windows-path]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamew
+pub fn absolute<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
+ path::_absolute(path)
+}
diff --git a/sgx_tunittest/Cargo.toml b/sgx_tunittest/Cargo.toml
index b218bd0..75bc127 100644
--- a/sgx_tunittest/Cargo.toml
+++ b/sgx_tunittest/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
include = [
"LICENSE",
diff --git a/sgx_types/BUILD b/sgx_types/BUILD
index 99de063..c83124b 100644
--- a/sgx_types/BUILD
+++ b/sgx_types/BUILD
@@ -3,7 +3,7 @@
rust_library(
name = "sgx_types",
visibility = ["//visibility:public"],
- edition = "2018",
+ edition = "2021",
srcs = glob(["src/*.rs"]),
deps = [],
)
\ No newline at end of file
diff --git a/sgx_types/Cargo.toml b/sgx_types/Cargo.toml
index 04dd878..f46b176 100644
--- a/sgx_types/Cargo.toml
+++ b/sgx_types/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_types"
diff --git a/sgx_ucrypto/Cargo.toml b/sgx_ucrypto/Cargo.toml
index 99d1547..5fe574a 100644
--- a/sgx_ucrypto/Cargo.toml
+++ b/sgx_ucrypto/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_ucrypto"
diff --git a/sgx_unwind/Cargo.toml b/sgx_unwind/Cargo.toml
index feae347..c90d477 100644
--- a/sgx_unwind/Cargo.toml
+++ b/sgx_unwind/Cargo.toml
@@ -7,7 +7,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
exclude = [
"libunwind/autom4te.cache/*",
"libunwind/aclocal.m4",
diff --git a/sgx_unwind/build.rs b/sgx_unwind/build.rs
index dada8f6..89c5603 100644
--- a/sgx_unwind/build.rs
+++ b/sgx_unwind/build.rs
@@ -15,8 +15,6 @@
// specific language governing permissions and limitations
// under the License..
-#![feature(available_parallelism)]
-
extern crate sgx_build_helper as build_helper;
use build_helper::{native_lib_boilerplate, run};
diff --git a/sgx_unwind/libunwind/src/se-iterate-phdr.c b/sgx_unwind/libunwind/src/se-iterate-phdr.c
index 85f08f2..74390a6 100644
--- a/sgx_unwind/libunwind/src/se-iterate-phdr.c
+++ b/sgx_unwind/libunwind/src/se-iterate-phdr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2020 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011-2021 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/sgx_unwind/libunwind/src/se-libc-stubs.c b/sgx_unwind/libunwind/src/se-libc-stubs.c
index bb94ece..cb1592c 100644
--- a/sgx_unwind/libunwind/src/se-libc-stubs.c
+++ b/sgx_unwind/libunwind/src/se-libc-stubs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2020 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011-2021 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/sgx_unwind/src/macros.rs b/sgx_unwind/src/macros.rs
index a1d26d6..ae6fa6e 100644
--- a/sgx_unwind/src/macros.rs
+++ b/sgx_unwind/src/macros.rs
@@ -1,12 +1,19 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
+// 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
//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
+// 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..
/// A macro for defining `#[cfg]` if-else statements.
///
diff --git a/sgx_urts/Cargo.toml b/sgx_urts/Cargo.toml
index 00c5b2b..b5a2320 100644
--- a/sgx_urts/Cargo.toml
+++ b/sgx_urts/Cargo.toml
@@ -6,7 +6,7 @@
license-file = "LICENSE"
documentation = "https://teaclave.apache.org/sgx-sdk-docs/"
description = "Rust SGX SDK provides the ability to write Intel SGX applications in Rust Programming Language."
-edition = "2018"
+edition = "2021"
[lib]
name = "sgx_urts"
diff --git a/sgx_urts/src/file.rs b/sgx_urts/src/file.rs
index 1666232..0b6d8b7 100644
--- a/sgx_urts/src/file.rs
+++ b/sgx_urts/src/file.rs
@@ -57,6 +57,26 @@
}
#[no_mangle]
+pub extern "C" fn u_openat_ocall(
+ error: *mut c_int,
+ dirfd: c_int,
+ pathname: *const c_char,
+ flags: c_int,
+) -> c_int {
+ let mut errno = 0;
+ let ret = unsafe { libc::openat(dirfd, pathname, flags) };
+ if ret < 0 {
+ errno = Error::last_os_error().raw_os_error().unwrap_or(0);
+ }
+ if !error.is_null() {
+ unsafe {
+ *error = errno;
+ }
+ }
+ ret
+}
+
+#[no_mangle]
pub extern "C" fn u_fstat_ocall(error: *mut c_int, fd: c_int, buf: *mut stat) -> c_int {
let mut errno = 0;
let ret = unsafe { libc::fstat(fd, buf) };
@@ -338,6 +358,26 @@
}
#[no_mangle]
+pub extern "C" fn u_unlinkat_ocall(
+ error: *mut c_int,
+ dirfd: c_int,
+ pathname: *const c_char,
+ flags: c_int,
+) -> c_int {
+ let mut errno = 0;
+ let ret = unsafe { libc::unlinkat(dirfd, pathname, flags) };
+ if ret < 0 {
+ errno = Error::last_os_error().raw_os_error().unwrap_or(0);
+ }
+ if !error.is_null() {
+ unsafe {
+ *error = errno;
+ }
+ }
+ ret
+}
+
+#[no_mangle]
pub extern "C" fn u_linkat_ocall(
error: *mut c_int,
olddirfd: c_int,
@@ -478,6 +518,21 @@
}
#[no_mangle]
+pub extern "C" fn u_fdopendir_ocall(error: *mut c_int, fd: c_int) -> *mut DIR {
+ let mut errno = 0;
+ let ret = unsafe { libc::fdopendir(fd) };
+ if ret.is_null() {
+ errno = Error::last_os_error().raw_os_error().unwrap_or(0);
+ }
+ if !error.is_null() {
+ unsafe {
+ *error = errno;
+ }
+ }
+ ret
+}
+
+#[no_mangle]
pub extern "C" fn u_opendir_ocall(error: *mut c_int, pathname: *const c_char) -> *mut DIR {
let mut errno = 0;
let ret = unsafe { libc::opendir(pathname) };
diff --git a/sgx_ustdc/file.c b/sgx_ustdc/file.c
index 3303015..2a3fa7c 100644
--- a/sgx_ustdc/file.c
+++ b/sgx_ustdc/file.c
@@ -47,6 +47,15 @@
return ret;
}
+int u_openat_ocall(int *error, int dirfd, const char *pathname, int flags)
+{
+ int ret = openat(dirfd, pathname, flags);
+ if (error) {
+ *error = ret == -1 ? errno : 0;
+ }
+ return ret;
+}
+
int u_fstat_ocall(int *error, int fd, struct stat *buf)
{
int ret = fstat(fd, buf);
@@ -200,6 +209,15 @@
return ret;
}
+int u_unlinkat_ocall(int *error, int dirfd, const char *pathname, int flags)
+{
+ int ret = unlinkat(dirfd, pathname, flags);
+ if (error) {
+ *error = ret == -1 ? errno : 0;
+ }
+ return ret;
+}
+
int u_linkat_ocall(int *error, int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags)
{
int ret = linkat(olddirfd, oldpath, newdirfd, newpath, flags);
@@ -272,7 +290,16 @@
return ret;
}
-void *u_opendir_ocall(int *error, const char *pathname)
+DIR *u_fdopendir_ocall(int *error, int fd)
+{
+ DIR *ret = fdopendir(fd);
+ if (error) {
+ *error = ret == NULL ? errno : 0;
+ }
+ return ret;
+}
+
+DIR *u_opendir_ocall(int *error, const char *pathname)
{
DIR *ret = opendir(pathname);
if (error) {
diff --git a/xargo/sgx_tstd/Cargo.toml b/xargo/sgx_tstd/Cargo.toml
index 391c5b1..7a1c23c 100644
--- a/xargo/sgx_tstd/Cargo.toml
+++ b/xargo/sgx_tstd/Cargo.toml
@@ -3,7 +3,7 @@
version = "0.0.0"
authors = ["The Teaclave Authors"]
build = "build.rs"
-edition = "2018"
+edition = "2021"
[lib]
name = "std"
diff --git a/xargo/x86_64-unknown-linux-sgx.json b/xargo/x86_64-unknown-linux-sgx.json
index 69b38be..53f104e 100644
--- a/xargo/x86_64-unknown-linux-sgx.json
+++ b/xargo/x86_64-unknown-linux-sgx.json
@@ -1,13 +1,13 @@
{
"arch": "x86_64",
"cpu": "x86-64",
+ "crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "sgx",
- "exe-allocation-crate": "alloc_system",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
+ "has-thread-local": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -30,6 +30,13 @@
1
]
},
+ "supported-sanitizers": [
+ "address",
+ "cfi",
+ "leak",
+ "memory",
+ "thread"
+ ],
"target-c-int-width": "32",
"target-endian": "little",
"target-family": "unix",