diff --git a/README.md b/README.md index 838bc48..6d3f7fd 100644 --- a/README.md +++ b/README.md @@ -16,32 +16,33 @@ Arguments: ... application file(s) to package Options: - -v, --verbose Be verbose - --deterministic Produce a deterministic TAB file - --disable Mark the app as disabled in the TBF flags - --app-version Set the version number [default: 0] - --minimum-ram-size in bytes - -o, --output-file output file name [default: TockApp.tab] - -n, --package-name package name - --stack in bytes - --app-heap in bytes [default: 1024] - --kernel-heap in bytes [default: 1024] - --protected-region-size Size of the protected region (including headers) - --permissions ... A list of driver numbers and allowed commands - --write_id A storage ID used for writing data - --read_ids ... Storage IDs that this app is allowed to read - --access_ids ... Storage IDs that this app is allowed to write - --short-id ShortId to request in the app's header - --kernel-major The kernel version that the app requires - --kernel-minor The minimum kernel minor version that the app requires - --supported-boards comma separated list of boards this app is compatible with - --minimum-footer-size Minimum number of bytes to reserve space for in the footer [default: 0] - --sha256 Add a SHA256 hash credential to each TBF - --sha384 Add a SHA384 hash credential to each TBF - --sha512 Add a SHA512 hash credential to each TBF - --rsa4096-private Add an 4096-bit RSA signature credential using this private key - -h, --help Print help - -V, --version Print version + -v, --verbose Be verbose + --deterministic Produce a deterministic TAB file + --disable Mark the app as disabled in the TBF flags + --app-version Set the version number [default: 0] + --minimum-ram-size in bytes - has no effect, kept for backwards compatibility + -o, --output-file output file name [default: TockApp.tab] + -n, --package-name package name + --stack in bytes + --app-heap in bytes [default: 1024] + --kernel-heap in bytes [default: 1024] + --protected-region-size Size of the protected region (including headers) + --permissions ... A list of driver numbers and allowed commands + --write_id A storage ID used for writing data + --read_ids ... Storage IDs that this app is allowed to read + --access_ids ... Storage IDs that this app is allowed to write + --short-id ShortId to request in the app's header + --kernel-major The kernel version that the app requires + --kernel-minor The minimum kernel minor version that the app requires + --supported-boards comma separated list of boards this app is compatible with + --minimum-footer-size Minimum number of bytes to reserve space for in the footer [default: 0] + --sha256 Add a SHA256 hash credential to each TBF + --sha384 Add a SHA384 hash credential to each TBF + --sha512 Add a SHA512 hash credential to each TBF + --rsa4096-private Add an 4096-bit RSA signature credential using this private key + --ecdsa-nist-p256-private Add an ECDSA NIST P256 signature credential using this private key + -h, --help Print help + -V, --version Print version ``` For example, converting a "blink" app from a compiled .elf file (for a Cortex-M4 @@ -167,6 +168,23 @@ increase the size of the protected region to make the start of the TBF header at an address aligned to 256 bytes when the application binary is at its correct fixed address. +#### Trailing Padding (Total Size Alignment) + +elf2tab adds trailing padding to each TBF to satisfy architecture-specific +alignment constraints: + +- **ARM**: total size is padded to a power of 2 (for MPU region alignment). +- **RISC-V**: total size is padded to a multiple of 4 (TBF alignment + requirement). +- **x86**: total size is padded to a multiple of 4096 (page size). + +An application can override the default padding by defining a +`tbf_total_size_padding` symbol in its ELF file. When present, the symbol's +value is interpreted as a byte multiple, and the total TBF size will be padded +to a multiple of that value instead of the architecture default. This is useful, +for example, when a platform requires a different alignment than the +architecture-level default. + #### Syscall Permissions elf2tab allows explicitly specifying the syscalls that an app is allowed to diff --git a/src/cmdline.rs b/src/cmdline.rs index 761ad01..94c1f31 100644 --- a/src/cmdline.rs +++ b/src/cmdline.rs @@ -64,12 +64,12 @@ pub struct Opt { #[arg( long = "minimum-ram-size", id = "min-ram-size", - help = "in bytes", + help = "in bytes - has no effect, kept for backwards compatibility", conflicts_with = "stack-size", conflicts_with = "heap-size", conflicts_with = "kernel-heap-size" )] - pub minimum_stack_size: Option, + pub _minimum_stack_size: Option, #[arg( long = "output-file", diff --git a/src/convert.rs b/src/convert.rs index 80e8830..1fe3d80 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -196,7 +196,10 @@ pub fn elf_to_tbf( // - RISC_V: make sure the entire TBF is a multiple of 4 to meet TBF // alignment requirements. // - x86: use 4k padding to match page size. - let trailing_padding = match elf_file.ehdr.e_machine { + // + // This default may be overridden by a `tbf_total_size_padding` symbol + // in the ELF file. + let arch_trailing_padding = match elf_file.ehdr.e_machine { elf::abi::EM_ARM => Some(TrailingPadding::TotalSizePowerOfTwo), elf::abi::EM_RISCV => Some(TrailingPadding::TotalSizeMultiple(4)), elf::abi::EM_386 => Some(TrailingPadding::TotalSizeMultiple(4096)), @@ -470,26 +473,37 @@ pub fn elf_to_tbf( // Adjust the protected region size to make fixed address work //////////////////////////////////////////////////////////////////////////// - // Applications can hint a desired protected region size to elf2tab by - // defining a special `tbf_protected_region_size` symbol: - let protected_region_size_symbol = + // Applications can hint configuration to elf2tab by defining special + // symbols: + // + // - `tbf_protected_region_size`: desired protected region size. + // - `tbf_total_size_padding`: pad total size to a multiple of this value, + // overriding the architecture default. + let (protected_region_size_symbol, total_size_padding_symbol) = if let Ok(Some((symtab, sym_strtab))) = elf_file.symbol_table() { - // We are looking for the `tbf_protected_region_size` symbol and its - // value. If it exists, we can use it as a hint for the protected - // region size. - symtab - .iter() - .find(|sym| { - let name = sym_strtab - .get(sym.st_name as usize) - .expect("Failed to parse symbol name"); - name == "tbf_protected_region_size" - }) - .map(|tbf_header_sym| tbf_header_sym.st_value as u32) + let mut prs = None; + let mut tsp = None; + for sym in symtab.iter() { + let name = sym_strtab + .get(sym.st_name as usize) + .expect("Failed to parse symbol name"); + if name == "tbf_protected_region_size" { + prs = Some(sym.st_value as u32); + } else if name == "tbf_total_size_padding" { + tsp = Some(sym.st_value as usize); + } + } + (prs, tsp) } else { - None + (None, None) }; + // Override trailing padding if specified in the ELF via the + // `tbf_total_size_padding` symbol. + let trailing_padding = total_size_padding_symbol + .map(TrailingPadding::TotalSizeMultiple) + .or(arch_trailing_padding); + // Determine the protected region size by checking the following sources in // this order: // diff --git a/src/main.rs b/src/main.rs index e88bf3f..6457ee7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -150,7 +150,7 @@ fn main() { ) .unwrap(); if opt.verbose { - println!(""); + println!(); } match outfile.write_all(output_vector.as_ref()) {