From 3802a984452ae905e92f61713d8e58c984bc9835 Mon Sep 17 00:00:00 2001 From: Adrian Cruceru Date: Tue, 21 Apr 2020 16:47:08 +0200 Subject: [PATCH 1/3] Libunwind update + toolchain verification --- fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs | 143 ++++++++++++++---- 1 file changed, 114 insertions(+), 29 deletions(-) diff --git a/fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs b/fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs index c3f37115..a61a331f 100644 --- a/fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs +++ b/fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs @@ -24,7 +24,7 @@ use failure::{err_msg, Error, ResultExt}; use xmas_elf::dynamic::{Dynamic as DynEntry, Tag as DynTag}; use xmas_elf::header::Class as HeaderClass; use xmas_elf::program::{SegmentData, Type as PhType}; -use xmas_elf::sections::{SectionData, SHN_UNDEF}; +use xmas_elf::sections::{SectionData, SHN_UNDEF, ShType}; use xmas_elf::symbol_table::{DynEntry64 as DynSymEntry, Entry}; use xmas_elf::ElfFile; @@ -44,10 +44,14 @@ struct Symbols<'a> { ENCLAVE_SIZE: &'a DynSymEntry, CFGDATA_BASE: &'a DynSymEntry, DEBUG: &'a DynSymEntry, - EH_FRM_HDR_BASE: &'a DynSymEntry, - EH_FRM_HDR_SIZE: &'a DynSymEntry, + EH_FRM_HDR_BASE: Option<&'a DynSymEntry>, + EH_FRM_HDR_SIZE: Option<&'a DynSymEntry>, TEXT_BASE: &'a DynSymEntry, TEXT_SIZE: &'a DynSymEntry, + EH_FRM_ADDR: Option<&'a DynSymEntry>, + EH_FRM_LEN: Option<&'a DynSymEntry>, + EH_FRM_HDR_ADDR: Option<&'a DynSymEntry>, + EH_FRM_HDR_LEN: Option<&'a DynSymEntry>, } struct SectionRange { offset: u64, @@ -112,30 +116,38 @@ pub struct LayoutInfo<'a> { library: bool, sized: bool, ehfrm: SectionRange, + ehfrm_hdr: SectionRange, text: SectionRange, } macro_rules! read_syms { - ($($name:ident),* in $syms:ident : $elf:ident) => {{ - $(let mut $name=None;)* + (mandatory: $($mandatory_name:ident),* optional: $($optional_name:ident),* in $syms:ident : $elf:ident) => {{ + $(let mut $mandatory_name=None;)* + $(let mut $optional_name=None;)* for sym in $syms.iter().skip(1) { if sym.shndx()==SHN_UNDEF { bail!("Found undefined dynamic symbol: {}", sym.get_name(&$elf).map_err(err_msg)?); - } $(else if sym.get_name(&$elf).map_err(err_msg)?==stringify!($name) { - if replace(&mut $name,Some(sym)).is_some() { - bail!("Found symbol twice: {}", stringify!($name)); + } $(else if sym.get_name(&$elf).map_err(err_msg)?==stringify!($mandatory_name) { + if replace(&mut $mandatory_name,Some(sym)).is_some() { + bail!("Found symbol twice: {}", stringify!($mandatory_name)); + } + })* + $(else if sym.get_name(&$elf).map_err(err_msg)?==stringify!($optional_name) { + if replace(&mut $optional_name,Some(sym)).is_some() { + bail!("Found symbol twice: {}", stringify!($optional_name)); } })* } - if let ($(Some($name)),*)=($($name),*) { - Symbols{$($name:$name),*} + if let ($(Some($mandatory_name)),*)=($($mandatory_name),*) { + Symbols{$($mandatory_name:$mandatory_name),*, + $($optional_name:$optional_name),*} } else { let mut missing = String::new(); - $(if $name.is_none() { + $(if $mandatory_name.is_none() { if !missing.is_empty() { missing += ", "; } - missing += stringify!($name); + missing += stringify!($mandatory_name); })* bail!("These dynamic symbols are missing: {}", missing) } @@ -154,11 +166,62 @@ macro_rules! check_size { ); } }}; + ($name:ident == $size:expr) => {{ + let size = $name.size(); + if size != $size { + bail!( + "Dynamic symbol {} doesn't have the right size. Expected size {}, got {}.", + stringify!($name), + $size, + size + ); + } + }}; } impl<'a> LayoutInfo<'a> { + + // Check version defined in rust-lang assembly code is supported, see .note.x86_64-fortanix-unknown-sgx section in https://github.com/rust-lang/rust/blob/master/src/libstd/sys/sgx/abi/entry.S + fn check_toolchain_version(elf: &ElfFile<'a>) -> Result<(), Error> { + let note_header = elf.find_section_by_name(".note.x86_64-fortanix-unknown-sgx").ok_or_else(|| format_err!("Could not find .note.x86_64-fortanix-unknown-sgx header!"))?; + + if note_header.get_type() != Ok(ShType::Note) { + bail!("Invalid type {:?} for section: .note.x86_64-fortanix-unknown-sgx", note_header.get_type()); + } + + match note_header.get_data(&elf) { + Ok(SectionData::Note64(header, ptr)) => { + if header.name(ptr) != "toolchain-version" { + bail!("Expecting 'toolchain-version' as name for .note.x86_64-fortanix-unknown-sgx"); + } + + let desc = header.desc(ptr); + + if desc.len() != 4 { + bail!("Expecting 32 bit 'toolchain-version' in .note.x86_64-fortanix-unknown-sgx"); + } + + // According to entry.S in rust-lang 'desc - toolchain version number, 32-bit LE' + let version : u32 = ((desc[0] as u32) << 0) + ((desc[1] as u32) << 8) + ((desc[2] as u32) << 16) + ((desc[3] as u32) << 24); + + let MAX_SUPPORTED_VERSION = 1; + + if version > MAX_SUPPORTED_VERSION { + bail!("Update required for 'fortanix-sgx-tools'. ELF file has toolchain version {}, installed tools supports up to version {}", version, MAX_SUPPORTED_VERSION); + } + }, + Ok(_) => bail!("Section data for .note.x86_64-fortanix-unknown-sgx is not a note."), + Err(_) => bail!("Failed fetching data for section .note.x86_64-fortanix-unknown-sgx.") + } + + Ok(()) + } + #[allow(non_snake_case)] fn check_symbols(elf: &ElfFile<'a>) -> Result, Error> { + + Self::check_toolchain_version(&elf)?; + let dynsym = elf .find_section_by_name(".dynsym") .ok_or_else(|| format_err!("Could not find dynamic symbol table!"))?; @@ -170,18 +233,12 @@ impl<'a> LayoutInfo<'a> { bail!(".dynsym section is not a dynamic symbol table!"); }; - let syms = read_syms!(sgx_entry, - HEAP_BASE, - HEAP_SIZE, - RELA, - RELACOUNT, - ENCLAVE_SIZE, - CFGDATA_BASE, - DEBUG, - EH_FRM_HDR_BASE, - EH_FRM_HDR_SIZE, - TEXT_BASE, - TEXT_SIZE in syms : elf); + // Optional symbols used for compatibility. Old versions use 'EH_FRM_HDR_BASE, EH_FRM_HDR_SIZE', new versions use 'EH_FRM_ADDR, EH_FRM_LEN, EH_FRM_HDR_ADDR, EH_FRM_HDR_LEN. + // Tool must support both variants for backwards compatibility at least until 'https://github.com/fortanix/rust-sgx/issues/174' is merged into rust-lang. + let syms = read_syms!(mandatory: sgx_entry, HEAP_BASE, HEAP_SIZE, RELA, RELACOUNT, ENCLAVE_SIZE, CFGDATA_BASE, DEBUG, TEXT_BASE, TEXT_SIZE + optional: EH_FRM_HDR_BASE, EH_FRM_HDR_SIZE, EH_FRM_ADDR, EH_FRM_LEN, EH_FRM_HDR_ADDR, EH_FRM_HDR_LEN + in syms : elf); + check_size!(syms.HEAP_BASE == 8); check_size!(syms.HEAP_SIZE == 8); @@ -190,8 +247,6 @@ impl<'a> LayoutInfo<'a> { check_size!(syms.ENCLAVE_SIZE == 8); check_size!(syms.CFGDATA_BASE == 8); check_size!(syms.DEBUG == 1); - check_size!(syms.EH_FRM_HDR_BASE == 8); - check_size!(syms.EH_FRM_HDR_SIZE == 8); check_size!(syms.TEXT_BASE == 8); check_size!(syms.TEXT_SIZE == 8); @@ -201,6 +256,20 @@ impl<'a> LayoutInfo<'a> { bail!("ENCLAVE_SIZE symbol is not naturally aligned") } + if let (Some(EH_FRM_HDR_BASE), Some(EH_FRM_HDR_SIZE)) = (syms.EH_FRM_HDR_BASE, syms.EH_FRM_HDR_SIZE) { + check_size!(EH_FRM_HDR_BASE == 8); + check_size!(EH_FRM_HDR_SIZE == 8); + } + else if let (Some(EH_FRM_ADDR), Some(EH_FRM_LEN), Some(EH_FRM_HDR_ADDR), Some(EH_FRM_HDR_LEN)) = (syms.EH_FRM_ADDR, syms.EH_FRM_LEN, syms.EH_FRM_HDR_ADDR, syms.EH_FRM_HDR_LEN) { + check_size!(EH_FRM_ADDR == 8); + check_size!(EH_FRM_LEN == 8); + check_size!(EH_FRM_HDR_ADDR == 8); + check_size!(EH_FRM_HDR_LEN == 8); + } + else { + bail!("Missing EH Frame header symbols, application must either have (EH_FRM_HDR_BASE/EH_FRM_HDR_SIZE) or (EH_FRM_ADDR, EH_FRM_LEN, EH_FRM_HDR_ADDR, EH_FRM_HDR_LEN"); + } + Ok(syms) } @@ -333,7 +402,8 @@ impl<'a> LayoutInfo<'a> { let sym = Self::check_symbols(&elf)?; let dyn = Self::check_dynamic(&elf)?; Self::check_relocs(&elf, dyn.as_ref())?; - let ehfrm = Self::check_section(&elf, ".eh_frame_hdr")?; + let ehfrm = Self::check_section(&elf, ".eh_frame")?; + let ehfrm_hdr = Self::check_section(&elf, ".eh_frame_hdr")?; let text = Self::check_section(&elf, ".text")?; Ok(LayoutInfo { @@ -347,11 +417,13 @@ impl<'a> LayoutInfo<'a> { debug, library, ehfrm, + ehfrm_hdr, text, sized, }) } + #[allow(non_snake_case)] pub fn write_elf_segments( &self, writer: &mut CanonicalSgxsWriter, @@ -379,11 +451,24 @@ impl<'a> LayoutInfo<'a> { ), Splice::for_sym_u64(self.sym.CFGDATA_BASE, memory_size), Splice::for_sym_u8(self.sym.DEBUG, self.debug as _), - Splice::for_sym_u64(self.sym.EH_FRM_HDR_BASE, self.ehfrm.offset), - Splice::for_sym_u64(self.sym.EH_FRM_HDR_SIZE, self.ehfrm.size), Splice::for_sym_u64(self.sym.TEXT_BASE, self.text.offset), Splice::for_sym_u64(self.sym.TEXT_SIZE, self.text.size), ]; + + if let (Some(EH_FRM_HDR_BASE), Some(EH_FRM_HDR_SIZE)) = (self.sym.EH_FRM_HDR_BASE, self.sym.EH_FRM_HDR_SIZE) { + splices.push(Splice::for_sym_u64(EH_FRM_HDR_BASE, self.ehfrm_hdr.offset)); + splices.push(Splice::for_sym_u64(EH_FRM_HDR_SIZE, self.ehfrm_hdr.size)); + } + else if let (Some(EH_FRM_ADDR), Some(EH_FRM_LEN), Some(EH_FRM_HDR_ADDR), Some(EH_FRM_HDR_LEN)) = (self.sym.EH_FRM_ADDR, self.sym.EH_FRM_LEN, self.sym.EH_FRM_HDR_ADDR, self.sym.EH_FRM_HDR_LEN) { + splices.push(Splice::for_sym_u64(EH_FRM_ADDR, self.ehfrm.offset)); + splices.push(Splice::for_sym_u64(EH_FRM_LEN, self.ehfrm.size)); + splices.push(Splice::for_sym_u64(EH_FRM_HDR_ADDR, self.ehfrm_hdr.offset)); + splices.push(Splice::for_sym_u64(EH_FRM_HDR_LEN, self.ehfrm_hdr.size)); + } + else { + bail!("Missing EH Frame header symbols, application must either have (EH_FRM_HDR_BASE/EH_FRM_HDR_SIZE) or (EH_FRM_ADDR, EH_FRM_LEN, EH_FRM_HDR_ADDR, EH_FRM_HDR_LEN"); + } + if let Some(enclave_size) = enclave_size { splices.push(Splice::for_sym_u64(self.sym.ENCLAVE_SIZE, enclave_size)); } From 60b149d56219e6e2a16dc4ac887bed4b4927e01e Mon Sep 17 00:00:00 2001 From: Adrian Cruceru Date: Wed, 22 Apr 2020 10:47:25 +0200 Subject: [PATCH 2/3] rename variables --- fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs b/fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs index a61a331f..7156afe4 100644 --- a/fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs +++ b/fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs @@ -48,9 +48,9 @@ struct Symbols<'a> { EH_FRM_HDR_SIZE: Option<&'a DynSymEntry>, TEXT_BASE: &'a DynSymEntry, TEXT_SIZE: &'a DynSymEntry, - EH_FRM_ADDR: Option<&'a DynSymEntry>, + EH_FRM_OFFSET: Option<&'a DynSymEntry>, EH_FRM_LEN: Option<&'a DynSymEntry>, - EH_FRM_HDR_ADDR: Option<&'a DynSymEntry>, + EH_FRM_HDR_OFFSET: Option<&'a DynSymEntry>, EH_FRM_HDR_LEN: Option<&'a DynSymEntry>, } struct SectionRange { @@ -233,10 +233,12 @@ impl<'a> LayoutInfo<'a> { bail!(".dynsym section is not a dynamic symbol table!"); }; - // Optional symbols used for compatibility. Old versions use 'EH_FRM_HDR_BASE, EH_FRM_HDR_SIZE', new versions use 'EH_FRM_ADDR, EH_FRM_LEN, EH_FRM_HDR_ADDR, EH_FRM_HDR_LEN. + // Optional symbols used for compatibility. Old versions use 'EH_FRM_HDR_BASE, EH_FRM_HDR_SIZE', new versions use 'EH_FRM_OFFSET, EH_FRM_LEN, EH_FRM_HDR_OFFSET, EH_FRM_HDR_LEN. // Tool must support both variants for backwards compatibility at least until 'https://github.com/fortanix/rust-sgx/issues/174' is merged into rust-lang. + // + // Variables have been renamed due to missing 'toolchain' version checks. Rename will cause compile-time failure if using old tool with new toolchain assembly code. let syms = read_syms!(mandatory: sgx_entry, HEAP_BASE, HEAP_SIZE, RELA, RELACOUNT, ENCLAVE_SIZE, CFGDATA_BASE, DEBUG, TEXT_BASE, TEXT_SIZE - optional: EH_FRM_HDR_BASE, EH_FRM_HDR_SIZE, EH_FRM_ADDR, EH_FRM_LEN, EH_FRM_HDR_ADDR, EH_FRM_HDR_LEN + optional: EH_FRM_HDR_BASE, EH_FRM_HDR_SIZE, EH_FRM_OFFSET, EH_FRM_LEN, EH_FRM_HDR_OFFSET, EH_FRM_HDR_LEN in syms : elf); @@ -260,14 +262,14 @@ impl<'a> LayoutInfo<'a> { check_size!(EH_FRM_HDR_BASE == 8); check_size!(EH_FRM_HDR_SIZE == 8); } - else if let (Some(EH_FRM_ADDR), Some(EH_FRM_LEN), Some(EH_FRM_HDR_ADDR), Some(EH_FRM_HDR_LEN)) = (syms.EH_FRM_ADDR, syms.EH_FRM_LEN, syms.EH_FRM_HDR_ADDR, syms.EH_FRM_HDR_LEN) { - check_size!(EH_FRM_ADDR == 8); + else if let (Some(EH_FRM_OFFSET), Some(EH_FRM_LEN), Some(EH_FRM_HDR_OFFSET), Some(EH_FRM_HDR_LEN)) = (syms.EH_FRM_OFFSET, syms.EH_FRM_LEN, syms.EH_FRM_HDR_OFFSET, syms.EH_FRM_HDR_LEN) { + check_size!(EH_FRM_OFFSET == 8); check_size!(EH_FRM_LEN == 8); - check_size!(EH_FRM_HDR_ADDR == 8); + check_size!(EH_FRM_HDR_OFFSET == 8); check_size!(EH_FRM_HDR_LEN == 8); } else { - bail!("Missing EH Frame header symbols, application must either have (EH_FRM_HDR_BASE/EH_FRM_HDR_SIZE) or (EH_FRM_ADDR, EH_FRM_LEN, EH_FRM_HDR_ADDR, EH_FRM_HDR_LEN"); + bail!("Missing EH Frame header symbols, application must either have (EH_FRM_HDR_BASE/EH_FRM_HDR_SIZE) or (EH_FRM_OFFSET, EH_FRM_LEN, EH_FRM_HDR_OFFSET, EH_FRM_HDR_LEN"); } Ok(syms) @@ -459,14 +461,14 @@ impl<'a> LayoutInfo<'a> { splices.push(Splice::for_sym_u64(EH_FRM_HDR_BASE, self.ehfrm_hdr.offset)); splices.push(Splice::for_sym_u64(EH_FRM_HDR_SIZE, self.ehfrm_hdr.size)); } - else if let (Some(EH_FRM_ADDR), Some(EH_FRM_LEN), Some(EH_FRM_HDR_ADDR), Some(EH_FRM_HDR_LEN)) = (self.sym.EH_FRM_ADDR, self.sym.EH_FRM_LEN, self.sym.EH_FRM_HDR_ADDR, self.sym.EH_FRM_HDR_LEN) { - splices.push(Splice::for_sym_u64(EH_FRM_ADDR, self.ehfrm.offset)); + else if let (Some(EH_FRM_OFFSET), Some(EH_FRM_LEN), Some(EH_FRM_HDR_OFFSET), Some(EH_FRM_HDR_LEN)) = (self.sym.EH_FRM_OFFSET, self.sym.EH_FRM_LEN, self.sym.EH_FRM_HDR_OFFSET, self.sym.EH_FRM_HDR_LEN) { + splices.push(Splice::for_sym_u64(EH_FRM_OFFSET, self.ehfrm.offset)); splices.push(Splice::for_sym_u64(EH_FRM_LEN, self.ehfrm.size)); - splices.push(Splice::for_sym_u64(EH_FRM_HDR_ADDR, self.ehfrm_hdr.offset)); + splices.push(Splice::for_sym_u64(EH_FRM_HDR_OFFSET, self.ehfrm_hdr.offset)); splices.push(Splice::for_sym_u64(EH_FRM_HDR_LEN, self.ehfrm_hdr.size)); } else { - bail!("Missing EH Frame header symbols, application must either have (EH_FRM_HDR_BASE/EH_FRM_HDR_SIZE) or (EH_FRM_ADDR, EH_FRM_LEN, EH_FRM_HDR_ADDR, EH_FRM_HDR_LEN"); + bail!("Missing EH Frame header symbols, application must either have (EH_FRM_HDR_BASE/EH_FRM_HDR_SIZE) or (EH_FRM_OFFSET, EH_FRM_LEN, EH_FRM_HDR_OFFSET, EH_FRM_HDR_LEN"); } if let Some(enclave_size) = enclave_size { From f999fd0525a089963abba8551da5bbe59ddf47b3 Mon Sep 17 00:00:00 2001 From: Adrian Cruceru Date: Thu, 30 Apr 2020 17:17:03 +0200 Subject: [PATCH 3/3] Fix code review comments --- fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs b/fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs index 7156afe4..9770ac46 100644 --- a/fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs +++ b/fortanix-sgx-tools/src/bin/ftxsgx-elf2sgxs.rs @@ -33,6 +33,7 @@ use sgxs_crate::sgxs::{self, CanonicalSgxsWriter, SecinfoTruncated, SgxsWrite}; use sgxs_crate::util::{size_fit_natural, size_fit_page}; use clap::ArgMatches; +use std::convert::TryInto; #[allow(non_snake_case)] struct Symbols<'a> { @@ -202,12 +203,12 @@ impl<'a> LayoutInfo<'a> { } // According to entry.S in rust-lang 'desc - toolchain version number, 32-bit LE' - let version : u32 = ((desc[0] as u32) << 0) + ((desc[1] as u32) << 8) + ((desc[2] as u32) << 16) + ((desc[3] as u32) << 24); + let version : u32 = u32::from_le_bytes(desc.try_into().unwrap()); - let MAX_SUPPORTED_VERSION = 1; + let max_supported_version = 1; - if version > MAX_SUPPORTED_VERSION { - bail!("Update required for 'fortanix-sgx-tools'. ELF file has toolchain version {}, installed tools supports up to version {}", version, MAX_SUPPORTED_VERSION); + if version > max_supported_version { + bail!("Update required for 'fortanix-sgx-tools'. ELF file has toolchain version {}, installed tools supports up to version {}", version, max_supported_version); } }, Ok(_) => bail!("Section data for .note.x86_64-fortanix-unknown-sgx is not a note."), @@ -261,14 +262,12 @@ impl<'a> LayoutInfo<'a> { if let (Some(EH_FRM_HDR_BASE), Some(EH_FRM_HDR_SIZE)) = (syms.EH_FRM_HDR_BASE, syms.EH_FRM_HDR_SIZE) { check_size!(EH_FRM_HDR_BASE == 8); check_size!(EH_FRM_HDR_SIZE == 8); - } - else if let (Some(EH_FRM_OFFSET), Some(EH_FRM_LEN), Some(EH_FRM_HDR_OFFSET), Some(EH_FRM_HDR_LEN)) = (syms.EH_FRM_OFFSET, syms.EH_FRM_LEN, syms.EH_FRM_HDR_OFFSET, syms.EH_FRM_HDR_LEN) { + } else if let (Some(EH_FRM_OFFSET), Some(EH_FRM_LEN), Some(EH_FRM_HDR_OFFSET), Some(EH_FRM_HDR_LEN)) = (syms.EH_FRM_OFFSET, syms.EH_FRM_LEN, syms.EH_FRM_HDR_OFFSET, syms.EH_FRM_HDR_LEN) { check_size!(EH_FRM_OFFSET == 8); check_size!(EH_FRM_LEN == 8); check_size!(EH_FRM_HDR_OFFSET == 8); check_size!(EH_FRM_HDR_LEN == 8); - } - else { + } else { bail!("Missing EH Frame header symbols, application must either have (EH_FRM_HDR_BASE/EH_FRM_HDR_SIZE) or (EH_FRM_OFFSET, EH_FRM_LEN, EH_FRM_HDR_OFFSET, EH_FRM_HDR_LEN"); } @@ -468,7 +467,7 @@ impl<'a> LayoutInfo<'a> { splices.push(Splice::for_sym_u64(EH_FRM_HDR_LEN, self.ehfrm_hdr.size)); } else { - bail!("Missing EH Frame header symbols, application must either have (EH_FRM_HDR_BASE/EH_FRM_HDR_SIZE) or (EH_FRM_OFFSET, EH_FRM_LEN, EH_FRM_HDR_OFFSET, EH_FRM_HDR_LEN"); + bail!("Missing .eh_frame header symbols, application must have symbols exported by rust x86_64_fortanix_unknown_sgx toolchain, either (EH_FRM_HDR_BASE/EH_FRM_HDR_SIZE) or (EH_FRM_OFFSET, EH_FRM_LEN, EH_FRM_HDR_OFFSET, EH_FRM_HDR_LEN"); } if let Some(enclave_size) = enclave_size {