From 321f9c181ff0b37a05b621308c8b307032432e35 Mon Sep 17 00:00:00 2001 From: 9names <60134748+9names@users.noreply.github.com> Date: Wed, 21 Feb 2024 22:19:13 +1100 Subject: [PATCH 1/2] Add feature to preserve cmsis-pack metadata in output elf --- .cargo/config | 2 +- Cargo.toml | 5 ++++ build.rs | 28 +++++++++++++++--- build_w_metadata.sh | 33 +++++++++++++++++++++ link_metadata.x | 70 +++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 11 +++++++ 6 files changed, 144 insertions(+), 5 deletions(-) create mode 100755 build_w_metadata.sh create mode 100644 link_metadata.x diff --git a/.cargo/config b/.cargo/config index 8b2fc36..763d367 100644 --- a/.cargo/config +++ b/.cargo/config @@ -2,7 +2,7 @@ rustflags = [ "-C", "link-arg=--nmagic", - "-C", "link-arg=-Tlink.x", + "-C", "link-arg=-Tlink_real.x", # Code-size optimizations. "-C", "inline-threshold=5", diff --git a/Cargo.toml b/Cargo.toml index 6a8e4e8..9322b64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,11 @@ flash-algorithm = { version = "0.4.0", default-features = false, features = [ "panic-handler", ] } +[features] +# Keep extra metadata in the final binary that probe-rs doesn't strictly need. +# Other tools use of these datastructures: probe-rs' target-gen, pyocd, jlink +cmsis-pack-compat = [] + # this lets you use `cargo fix`! [[bin]] name = "flash-algo" diff --git a/build.rs b/build.rs index 3a610c9..6013e91 100644 --- a/build.rs +++ b/build.rs @@ -1,21 +1,41 @@ use std::env; use std::fs::File; use std::io::Write; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; fn main() { // Put `link.x` in our output directory and ensure it's // on the linker search path. let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); - File::create(out.join("link.x")) + + println!("cargo:rustc-link-search={}", out.display()); + + // Call another function to copy the linker script into the output directory. + // This allows us to use a different linker script based on whether the + // cmsis-pack-compat feature is enabled or not + setup_linker_script(out); +} + +#[cfg(not(feature = "cmsis-pack-compat"))] +fn setup_linker_script(out: &Path) { + // rename the linker output to ensure we use the one in the + // build output instead of the one in the project root + File::create(out.join("link_output.x")) .unwrap() .write_all(include_bytes!("link.x")) .unwrap(); - println!("cargo:rustc-link-search={}", out.display()); - // By default, Cargo will re-run a build script whenever // any file in the project changes. By specifying `link.x` // here, we ensure the build script is only re-run when // `link.x` is changed. println!("cargo:rerun-if-changed=link.x"); } + +#[cfg(feature = "cmsis-pack-compat")] +fn setup_linker_script(out: &Path) { + File::create(out.join("link_output.x")) + .unwrap() + .write_all(include_bytes!("link_metadata.x")) + .unwrap(); + println!("cargo:rerun-if-changed=link_metadata.x"); +} diff --git a/build_w_metadata.sh b/build_w_metadata.sh new file mode 100755 index 0000000..f314b92 --- /dev/null +++ b/build_w_metadata.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +set -euo pipefail + +# macOS base64 doesn't take -w argument and defaults to a single line. +if [[ $(uname) = "Darwin" ]]; then + BASE64_FLAGS="" +else + BASE64_FLAGS="-w0" +fi + +cargo build --release --features cmsis-pack-compat +ELF=target/thumbv6m-none-eabi/release/flash-algo + +rust-objdump --disassemble $ELF > target/disassembly.s +rust-objdump -x $ELF > target/dump.txt +rust-nm $ELF -n > target/nm.txt + +function bin { + rust-objcopy $ELF -O binary - | base64 $BASE64_FLAGS +} + +function sym { + echo $((0x$(rust-nm $ELF | grep -w $1 | cut -d ' ' -f 1) + 1)) +} + +cat < Date: Thu, 22 Feb 2024 22:58:42 +1100 Subject: [PATCH 2/2] Fix generated link.x name --- .cargo/config | 2 +- build.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.cargo/config b/.cargo/config index 763d367..64a3068 100644 --- a/.cargo/config +++ b/.cargo/config @@ -2,7 +2,7 @@ rustflags = [ "-C", "link-arg=--nmagic", - "-C", "link-arg=-Tlink_real.x", + "-C", "link-arg=-Tlink_generated.x", # Code-size optimizations. "-C", "inline-threshold=5", diff --git a/build.rs b/build.rs index 6013e91..d63575d 100644 --- a/build.rs +++ b/build.rs @@ -20,7 +20,7 @@ fn main() { fn setup_linker_script(out: &Path) { // rename the linker output to ensure we use the one in the // build output instead of the one in the project root - File::create(out.join("link_output.x")) + File::create(out.join("link_generated.x")) .unwrap() .write_all(include_bytes!("link.x")) .unwrap(); @@ -33,7 +33,7 @@ fn setup_linker_script(out: &Path) { #[cfg(feature = "cmsis-pack-compat")] fn setup_linker_script(out: &Path) { - File::create(out.join("link_output.x")) + File::create(out.join("link_generated.x")) .unwrap() .write_all(include_bytes!("link_metadata.x")) .unwrap();