aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jonas Schievink <jonasschievink@gmail.com> 2020-08-30 18:35:49 +0200
committerGravatar Jonas Schievink <jonasschievink@gmail.com> 2020-08-30 20:57:45 +0200
commit0f23877e4638183b3c819184e552507c94185383 (patch)
tree1bc1375b3ddddadaf6e92fa9e3b7470332b0c6bb
parent6714e7f4d6ba505feaf0af5bbc9eb7444eb7f614 (diff)
downloadcortex-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.abin18284 -> 16124 bytes
-rw-r--r--bin/thumbv7em-none-eabi.abin23360 -> 20436 bytes
-rw-r--r--bin/thumbv7em-none-eabihf.abin24684 -> 21552 bytes
-rw-r--r--bin/thumbv7m-none-eabi.abin22020 -> 19276 bytes
-rw-r--r--bin/thumbv8m.base-none-eabi.abin20936 -> 18352 bytes
-rw-r--r--bin/thumbv8m.main-none-eabi.abin27220 -> 23652 bytes
-rw-r--r--bin/thumbv8m.main-none-eabihf.abin28488 -> 24704 bytes
-rw-r--r--xtask/Cargo.toml4
-rw-r--r--xtask/src/lib.rs95
9 files changed, 97 insertions, 2 deletions
diff --git a/bin/thumbv6m-none-eabi.a b/bin/thumbv6m-none-eabi.a
index 072dd15..5c8c758 100644
--- a/bin/thumbv6m-none-eabi.a
+++ b/bin/thumbv6m-none-eabi.a
Binary files differ
diff --git a/bin/thumbv7em-none-eabi.a b/bin/thumbv7em-none-eabi.a
index d7a2c88..ec56934 100644
--- a/bin/thumbv7em-none-eabi.a
+++ b/bin/thumbv7em-none-eabi.a
Binary files differ
diff --git a/bin/thumbv7em-none-eabihf.a b/bin/thumbv7em-none-eabihf.a
index 88ac78e..75a7e5d 100644
--- a/bin/thumbv7em-none-eabihf.a
+++ b/bin/thumbv7em-none-eabihf.a
Binary files differ
diff --git a/bin/thumbv7m-none-eabi.a b/bin/thumbv7m-none-eabi.a
index a97ae6a..ae9db60 100644
--- a/bin/thumbv7m-none-eabi.a
+++ b/bin/thumbv7m-none-eabi.a
Binary files differ
diff --git a/bin/thumbv8m.base-none-eabi.a b/bin/thumbv8m.base-none-eabi.a
index 4c68990..e8bb7a6 100644
--- a/bin/thumbv8m.base-none-eabi.a
+++ b/bin/thumbv8m.base-none-eabi.a
Binary files differ
diff --git a/bin/thumbv8m.main-none-eabi.a b/bin/thumbv8m.main-none-eabi.a
index 2e7280d..af9179a 100644
--- a/bin/thumbv8m.main-none-eabi.a
+++ b/bin/thumbv8m.main-none-eabi.a
Binary files differ
diff --git a/bin/thumbv8m.main-none-eabihf.a b/bin/thumbv8m.main-none-eabihf.a
index b16ae98..3189a29 100644
--- a/bin/thumbv8m.main-none-eabihf.a
+++ b/bin/thumbv8m.main-none-eabihf.a
Binary files differ
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());