diff --git a/build.rs b/build.rs index d221a57e..7d30046d 100644 --- a/build.rs +++ b/build.rs @@ -128,6 +128,29 @@ fn configure_lib_bagl(command: &mut cc::Build, bolos_sdk: &String) { } } +fn extract_defines_from_cx_makefile(command: &mut cc::Build, makefile: &String) { + let mut makefile = File::open(makefile).unwrap(); + let mut content = String::new(); + makefile.read_to_string(&mut content).unwrap(); + // Extract the defines from the Makefile.conf.cx. + // They all begin with `HAVE` and are ' ' and '\n' separated. + let mut defines = content + .split('\n') + .filter(|line| !line.starts_with('#')) // Remove lines that are commented + .flat_map(|line| line.split(' ').filter(|word| word.starts_with("HAVE"))) + .collect::>(); + + // do not forget NATIVE_LITTLE_ENDIAN + let s = String::from("NATIVE_LITTLE_ENDIAN"); + defines.push(s.as_str()); + + // Add the defines found in the Makefile.conf.cx to our build command. + for define in defines { + // scott could use for_each + command.define(define, None); + } +} + fn main() -> Result<(), Box> { let bolos_sdk = "./ledger-secure-sdk".to_string(); @@ -283,27 +306,7 @@ fn main() -> Result<(), Box> { // all 'finalize_...' functions also declare a new 'cfg' variable corresponding // to the name of the target (as #[cfg(target = "nanox")] does not work, for example) // this allows code to easily import things depending on the target - - let mut makefile = File::open(cx_makefile).unwrap(); - let mut content = String::new(); - makefile.read_to_string(&mut content).unwrap(); - // Extract the defines from the Makefile.conf.cx. - // They all begin with `HAVE` and are ' ' and '\n' separated. - let mut defines = content - .split('\n') - .filter(|line| !line.starts_with('#')) // Remove lines that are commented - .flat_map(|line| line.split(' ').filter(|word| word.starts_with("HAVE"))) - .collect::>(); - - // do not forget NATIVE_LITTLE_ENDIAN - let s = String::from("NATIVE_LITTLE_ENDIAN"); - defines.push(s.as_str()); - - // Add the defines found in the Makefile.conf.cx to our build command. - for define in defines { - // scott could use for_each - command.define(define, None); - } + extract_defines_from_cx_makefile(&mut command, &cx_makefile); command.compile("rust-app"); diff --git a/link.ld b/link.ld index 4c1ada11..7bee28e9 100644 --- a/link.ld +++ b/link.ld @@ -48,8 +48,6 @@ SECTIONS _estack = ABSOLUTE(END_STACK); } > SRAM - .ledger.api_level (INFO): { KEEP(*(.ledger.api_level)) } - .stack_sizes (INFO): { KEEP(*(.stack_sizes)); @@ -63,6 +61,18 @@ SECTIONS *(.ARM.exidx* .gnu.linkonce.armexidx.*) *(.debug_info) } + + ledger.target (INFO): { KEEP(*(ledger.target)) } + ledger.target_id (INFO): { KEEP(*(ledger.target_id)) } + ledger.target_name (INFO): { KEEP(*(ledger.target_name)) } + ledger.app_name (INFO): { KEEP(*(ledger.app_name)) } + ledger.app_version (INFO): { KEEP(*(ledger.app_version)) } + ledger.api_level (INFO): { KEEP(*(ledger.api_level)) } + ledger.sdk_version (INFO): { KEEP(*(ledger.sdk_version)) } + ledger.rust_sdk_version (INFO): { KEEP(*(ledger.rust_sdk_version)) } + ledger.rust_sdk_name (INFO): { KEEP(*(ledger.rust_sdk_name)) } + ledger.sdk_name (INFO): { KEEP(*(ledger.sdk_name)) } + ledger.sdk_hash (INFO): { KEEP(*(ledger.sdk_hash)) } } PROVIDE(_nvram = ABSOLUTE(_nvram_start)); diff --git a/src/infos.rs b/src/infos.rs index 2b5d9529..82047e3c 100644 --- a/src/infos.rs +++ b/src/infos.rs @@ -1,5 +1,25 @@ -/// Expose the API_LEVEL -#[link_section = ".ledger.api_level"] +const MAX_METADATA_STRING_SIZE : usize = 32; + +const fn copy_str_to_u8_array(input: &str) -> [u8; MAX_METADATA_STRING_SIZE] { + let mut result = [0u8; MAX_METADATA_STRING_SIZE]; + let bytes = input.as_bytes(); + let mut count = 0u32; + + // Ensure we don't copy more than MAX_METADATA_STRING_SIZE + let min_length = core::cmp::min(bytes.len(), MAX_METADATA_STRING_SIZE - 1); + // Copy bytes to array + loop { + if count >= min_length as u32 { + result[count as usize] = '\n' as u8; + break; + } + result[count as usize] = bytes[count as usize]; + count += 1; + } + result +} + +/// Expose the API_LEVEL to the app #[used] static API_LEVEL: u8 = if cfg!(target_os = "nanos") { 0 @@ -10,3 +30,71 @@ static API_LEVEL: u8 = if cfg!(target_os = "nanos") { } else { 0xff }; + +#[used] +#[link_section = "ledger.api_level"] +static ELF_API_LEVEL: [u8;4] = if cfg!(target_os = "nanos"){ + *b"0\n\0\0" +} else if cfg!(target_os = "nanox") { + *b"5\n\0\0" +} else if cfg!(target_os = "nanosplus") { + *b"1\n\0\0" +} else { + *b"255\n" +}; + +#[used] +#[link_section = "ledger.target"] +static ELF_TARGET: [u8;8] = if cfg!(target_os = "nanos"){ + *b"nanos\n\0\0" +} else if cfg!(target_os = "nanox") { + *b"nanox\n\0\0" +} else if cfg!(target_os = "nanosplus") { + *b"nanos2\n\0" +} else { + *b"unknown\n" +}; + +#[used] +#[link_section = "ledger.target_id"] +static ELF_TARGET_ID: [u8;11] = if cfg!(target_os = "nanos"){ + *b"0x31100004\n" +} else if cfg!(target_os = "nanox") { + *b"0x33000004\n" +} else if cfg!(target_os = "nanosplus") { + *b"0x33100004\n" +} else { + *b"0xffffffff\n" +}; + +#[used] +#[link_section = "ledger.target_name"] +static ELF_TARGET_NAME: [u8;14] = if cfg!(target_os = "nanos"){ + *b"TARGET_NANOS\n\0" +} else if cfg!(target_os = "nanox") { + *b"TARGET_NANOX\n\0" +} else if cfg!(target_os = "nanosplus") { + *b"TARGET_NANOS2\n" +} else { + *b"WRONG_TARGET\n\0" +}; + +#[used] +#[link_section = "ledger.sdk_hash"] +static ELF_SDK_HASH: [u8;5] = *b"None\n"; + +#[used] +#[link_section = "ledger.sdk_name"] +static ELF_SDK_NAME: [u8;18] = *b"ledger-secure-sdk\n"; + +#[used] +#[link_section = "ledger.sdk_version"] +static ELF_SDK_VERSION: [u8;5] = *b"None\n"; + +#[used] +#[link_section = "ledger.rust_sdk_name"] +static ELF_RUST_SDK_NAME: [u8;MAX_METADATA_STRING_SIZE] = copy_str_to_u8_array(env!("CARGO_PKG_NAME")); + +#[used] +#[link_section = "ledger.rust_sdk_version"] +static ELF_RUST_SDK_VERSION: [u8;MAX_METADATA_STRING_SIZE] = copy_str_to_u8_array(env!("CARGO_PKG_VERSION")); diff --git a/src/lib.rs b/src/lib.rs index f2e7a011..b7253619 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ #![test_runner(testing::sdk_test_runner)] #![allow(incomplete_features)] #![feature(generic_const_exprs)] +#![feature(const_cmp)] pub mod bindings;