Skip to content
Snippets Groups Projects
Commit e3b0e81f authored by Michael Hauspie's avatar Michael Hauspie
Browse files

Add pip elf export

parent ddcd1374
No related branches found
No related tags found
1 merge request!1Add a new `link` subcommand
...@@ -12,17 +12,20 @@ ...@@ -12,17 +12,20 @@
//! generates a binary that includes Pip MPU and the user code as root //! generates a binary that includes Pip MPU and the user code as root
//! partition //! partition
use anyhow::{anyhow, Result};
use anyhow::Result;
use clap::Parser; use clap::Parser;
use elf::endian::AnyEndian; use elf::endian::AnyEndian;
use std::path::PathBuf; use std::path::PathBuf;
use pip_mpu_relocate::reloc::RelIter; // use pip_mpu_relocate::reloc::RelIter;
use pip_mpu_relocate::relocate::relocate; // use pip_mpu_relocate::relocate::relocate;
use pip_mpu_relocate::symbols::SymbolsQuery; // use pip_mpu_relocate::symbols::SymbolsQuery;
use std::io::Write; use std::io::Write;
const PADDING_SIZE: usize = 32;
const PADDING_BUFFER: [u8; PADDING_SIZE] = [0xff; PADDING_SIZE];
const PIP_EXPORT_SECTIONS: &'static [&str] = &[".vector_table", ".text", ".data"];
/// Options for the link subcommand /// Options for the link subcommand
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
pub struct Opts { pub struct Opts {
...@@ -37,29 +40,56 @@ pub struct Opts { ...@@ -37,29 +40,56 @@ pub struct Opts {
/// Path the Pipcore MPU elf file /// Path the Pipcore MPU elf file
#[arg(long, short)] #[arg(long, short)]
pip_elf: Option<PathBuf> pip_elf: Option<PathBuf>,
}
/// Dump the binary content of the given sections to the output file.
///
/// It returns the number of bytes writen
fn dump_sections<'s, T: Write>(
elf: &elf::ElfBytes<AnyEndian>,
section_names: &[&str],
output: &mut T,
) -> Result<usize> {
let mut output_size = 0;
for section_name in section_names {
let section = match elf.section_header_by_name(section_name)? {
None => return Err(anyhow!("Section {section_name} not found")),
Some(s) => s,
};
let (bytes, compression) = elf.section_data(&section)?;
assert_eq!(compression, None);
output.write_all(bytes)?;
output_size += bytes.len();
}
Ok(output_size)
} }
pub fn link(opts: Opts) -> Result<()> { fn align(value: usize, align: usize) -> usize {
let a = value & (align - 1);
if a == 0 {
0
} else {
align - a
}
}
pub fn link(opts: Opts) -> Result<()> {
// First, open and parse both crt0 and user_code elf files // First, open and parse both crt0 and user_code elf files
let crt0_elf_file = std::fs::read(&opts.crt0_elf)?; let crt0_elf_file = std::fs::read(&opts.crt0_elf)?;
let crt0_elf_data = crt0_elf_file.as_slice(); let crt0_elf_data = crt0_elf_file.as_slice();
let crt0_elf = elf::ElfBytes::<AnyEndian>::minimal_parse(crt0_elf_data)?; let _crt0_elf = elf::ElfBytes::<AnyEndian>::minimal_parse(crt0_elf_data)?;
let user_code_elf_file = std::fs::read(&opts.user_code_elf)?; let user_code_elf_file = std::fs::read(&opts.user_code_elf)?;
let user_code_elf_data = user_code_elf_file.as_slice(); let user_code_elf_data = user_code_elf_file.as_slice();
let user_code_elf = elf::ElfBytes::<AnyEndian>::minimal_parse(user_code_elf_data)?; let _user_code_elf = elf::ElfBytes::<AnyEndian>::minimal_parse(user_code_elf_data)?;
// Then open Pip elf file if necessary // Then open Pip elf file if necessary
let pip_elf_data = match opts.pip_elf { let pip_elf_data = match opts.pip_elf {
None => None, None => None,
Some(pip_path) => { Some(pip_path) => Some(std::fs::read(&pip_path)?),
Some(std::fs::read(&pip_path)?)
}
}; };
let pip_elf = match pip_elf_data { let pip_elf = match pip_elf_data {
...@@ -69,7 +99,41 @@ pub fn link(opts: Opts) -> Result<()> { ...@@ -69,7 +99,41 @@ pub fn link(opts: Opts) -> Result<()> {
// When reaching here, all files were opened and parsed // When reaching here, all files were opened and parsed
// we can safely open the output file // we can safely open the output file
let mut output = std::fs::File::create(opts.output)?; let mut output = std::fs::File::create(opts.output)?;
writeln!(output, "Yeah it works")?;
// First, if needed, output pip binary, padded to 32 bytes
if let Some(pip_elf) = pip_elf {
let output_size = dump_sections(&pip_elf, PIP_EXPORT_SECTIONS, &mut output)?;
// If ouput size is not align on configured padding size bytes, add some padding
let pad_bytes = align(output_size, PADDING_SIZE);
if pad_bytes > 0 {
output.write_all(&PADDING_BUFFER[0..pad_bytes])?;
}
}
Ok(()) Ok(())
} }
#[cfg(test)]
mod tests {
use super::align;
#[test]
fn test_align() {
assert_eq!(align(0, 8), 0);
assert_eq!(align(1, 8), 7);
assert_eq!(align(2, 8), 6);
assert_eq!(align(3, 8), 5);
assert_eq!(align(4, 8), 4);
assert_eq!(align(5, 8), 3);
assert_eq!(align(6, 8), 2);
assert_eq!(align(7, 8), 1);
assert_eq!(align(8, 8), 0);
assert_eq!(align(9, 8), 7);
assert_eq!(align(10, 8), 6);
assert_eq!(align(11, 8), 5);
assert_eq!(align(12, 8), 4);
assert_eq!(align(13, 8), 3);
assert_eq!(align(14, 8), 2);
assert_eq!(align(15, 8), 1);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment