diff options
author | 2020-08-30 18:35:49 +0200 | |
---|---|---|
committer | 2020-08-30 20:57:45 +0200 | |
commit | 0f23877e4638183b3c819184e552507c94185383 (patch) | |
tree | 1bc1375b3ddddadaf6e92fa9e3b7470332b0c6bb | |
parent | 6714e7f4d6ba505feaf0af5bbc9eb7444eb7f614 (diff) | |
download | cortex-m-0f23877e4638183b3c819184e552507c94185383.tar.gz cortex-m-0f23877e4638183b3c819184e552507c94185383.tar.zst cortex-m-0f23877e4638183b3c819184e552507c94185383.zip |
Patch out the asm shim panic handler
-rw-r--r-- | bin/thumbv6m-none-eabi.a | bin | 18284 -> 16124 bytes | |||
-rw-r--r-- | bin/thumbv7em-none-eabi.a | bin | 23360 -> 20436 bytes | |||
-rw-r--r-- | bin/thumbv7em-none-eabihf.a | bin | 24684 -> 21552 bytes | |||
-rw-r--r-- | bin/thumbv7m-none-eabi.a | bin | 22020 -> 19276 bytes | |||
-rw-r--r-- | bin/thumbv8m.base-none-eabi.a | bin | 20936 -> 18352 bytes | |||
-rw-r--r-- | bin/thumbv8m.main-none-eabi.a | bin | 27220 -> 23652 bytes | |||
-rw-r--r-- | bin/thumbv8m.main-none-eabihf.a | bin | 28488 -> 24704 bytes | |||
-rw-r--r-- | xtask/Cargo.toml | 4 | ||||
-rw-r--r-- | xtask/src/lib.rs | 95 |
9 files changed, 97 insertions, 2 deletions
diff --git a/bin/thumbv6m-none-eabi.a b/bin/thumbv6m-none-eabi.a Binary files differindex 072dd15..5c8c758 100644 --- a/bin/thumbv6m-none-eabi.a +++ b/bin/thumbv6m-none-eabi.a diff --git a/bin/thumbv7em-none-eabi.a b/bin/thumbv7em-none-eabi.a Binary files differindex d7a2c88..ec56934 100644 --- a/bin/thumbv7em-none-eabi.a +++ b/bin/thumbv7em-none-eabi.a diff --git a/bin/thumbv7em-none-eabihf.a b/bin/thumbv7em-none-eabihf.a Binary files differindex 88ac78e..75a7e5d 100644 --- a/bin/thumbv7em-none-eabihf.a +++ b/bin/thumbv7em-none-eabihf.a diff --git a/bin/thumbv7m-none-eabi.a b/bin/thumbv7m-none-eabi.a Binary files differindex a97ae6a..ae9db60 100644 --- a/bin/thumbv7m-none-eabi.a +++ b/bin/thumbv7m-none-eabi.a diff --git a/bin/thumbv8m.base-none-eabi.a b/bin/thumbv8m.base-none-eabi.a Binary files differindex 4c68990..e8bb7a6 100644 --- a/bin/thumbv8m.base-none-eabi.a +++ b/bin/thumbv8m.base-none-eabi.a diff --git a/bin/thumbv8m.main-none-eabi.a b/bin/thumbv8m.main-none-eabi.a Binary files differindex 2e7280d..af9179a 100644 --- a/bin/thumbv8m.main-none-eabi.a +++ b/bin/thumbv8m.main-none-eabi.a diff --git a/bin/thumbv8m.main-none-eabihf.a b/bin/thumbv8m.main-none-eabihf.a Binary files differindex b16ae98..3189a29 100644 --- a/bin/thumbv8m.main-none-eabihf.a +++ b/bin/thumbv8m.main-none-eabihf.a diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 06c5143..e23d1a7 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -11,3 +11,7 @@ harness = false [dependencies] ar = "0.8.0" + +[dependencies.object] +version = "0.21.1" +features = ["write"] diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs index e6248d1..3ff66e8 100644 --- a/xtask/src/lib.rs +++ b/xtask/src/lib.rs @@ -4,12 +4,16 @@ //! //! Also see the docs in `asm.rs`. -use process::Stdio; +use object::{ + read::{Object as _, ObjectSection as _}, + write::{Object, Symbol, SymbolSection}, + SymbolFlags, +}; use std::env::current_dir; use std::{ collections::BTreeMap, fs::{self, File}, - process::{self, Command}, + process::{Command, Stdio}, }; fn toolchain() -> String { @@ -25,6 +29,88 @@ fn rustc() -> Command { cmd } +/// Patches an object file so that it doesn't contain a panic handler. +/// +/// The panic handler defined in `asm/lib.rs` should never get linked to the final program. +/// Unfortunately, Rust uses the same symbol for all panic handlers, and doesn't really like it if +/// that ends up with multiple ones. It also demands that we define a panic handler for the inline +/// assembly shim, even though none of that code should ever be able to panic. The result of this is +/// that the supposedly unreachable panic handler does end up getting linked into the final program, +/// unless it is built with optimizations enabled. +/// +/// To fix that, we put the never-to-be-used panic handler into its own section via +/// `#[link_section]`, and then use this function to delete that section. +fn trim_panic_handler(obj_file: &str) { + let objdata = fs::read(&obj_file).unwrap(); + let obj = object::File::parse(&objdata).unwrap(); + + let mut writer = Object::new(obj.format(), obj.architecture(), obj.endianness()); + for (sec_index, section) in obj.sections().enumerate() { + assert_eq!(section.index().0, sec_index); + + let name = section.name().unwrap(); + if name.starts_with(".ARM") + || name.starts_with(".rel.ARM") + || name.contains("cortex_m_asm_panic") + || name == ".strtab" + || name == ".symtab" + { + // We drop the ARM exception handling tables since they refer back to the panic handler + // symbol. They aren't used either way. We also drop `.strtab` and `.symtab` since they + // otherwise end up having the wrong section type. The object crate should rebuild any + // index tables when writing the file. + continue; + } + + let segment = section + .segment_name() + .unwrap() + .map(|s| s.as_bytes()) + .unwrap_or(&[]); + let sec_id = writer.add_section(segment.to_vec(), name.as_bytes().to_vec(), section.kind()); + + let align = if section.align() == 0 { + // Not sure why but `section.align()` can return 0. + 1 + } else { + section.align() + }; + writer.append_section_data(sec_id, section.data().unwrap(), align); + + // Import all symbols from the section. + for (_sym_idx, symbol) in obj.symbols() { + if symbol.section_index() == Some(section.index()) { + writer.add_symbol(Symbol { + name: symbol.name().unwrap_or("").as_bytes().to_vec(), + value: symbol.address(), + size: symbol.size(), + kind: symbol.kind(), + scope: symbol.scope(), + weak: symbol.is_weak(), + section: match symbol.section() { + object::SymbolSection::Unknown => unimplemented!(), + object::SymbolSection::None => SymbolSection::None, + object::SymbolSection::Undefined => SymbolSection::Undefined, + object::SymbolSection::Absolute => SymbolSection::Absolute, + object::SymbolSection::Common => SymbolSection::Common, + object::SymbolSection::Section(_) => SymbolSection::Section(sec_id), + }, + flags: match symbol.flags() { + SymbolFlags::None => SymbolFlags::None, + SymbolFlags::Elf { st_info, st_other } => { + SymbolFlags::Elf { st_info, st_other } + } + _ => unimplemented!(), + }, + }); + } + } + } + + let obj = writer.write().unwrap(); + fs::write(&obj_file, obj).unwrap(); +} + fn assemble_really(target: &str, cfgs: &[&str], plugin_lto: bool) { let mut cmd = rustc(); @@ -74,6 +160,11 @@ fn assemble_really(target: &str, cfgs: &[&str], plugin_lto: bool) { let status = cmd.status().unwrap(); assert!(status.success()); + if !plugin_lto { + // Post-process the object file. + trim_panic_handler(&obj_file); + } + // Archive `target.o` -> `bin/target.a`. let mut builder = ar::Builder::new(File::create(format!("bin/{}.a", file_stub)).unwrap()); |