diff --git a/Cargo.toml b/Cargo.toml index de8f9c3..c072dad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "commitment-issues" -version = "0.1.1" +version = "0.2.0" edition = "2021" authors = ["Pete Kubiak "] diff --git a/README.md b/README.md index 028eb4e..e302827 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,13 @@ Navigate into your project directory and add the crate to your dependencies with cargo add --git https://github.com/dysonltd/commitment-issues ``` +This crate makes use of code run at compile time through the `build.rs` script. +As such, you will also need to add the crate as a build dependency with: + +```sh +cargo add --build --git https://github.com/dysonltd/commitment-issues +``` + #### Configure the project to include the metadata in the binary Run `cargo generate` with the following command and follow the prompts: @@ -67,7 +74,7 @@ cargo generate -g https://github.com/dysonltd/commitment-issues --init **Please note** the `--init` argument being passed to `cargo generate`. This specifies that the target project already exists. -If certain files already exist in your project, you will need to add commands to them to complete the configuration. +If certain files already exist in your project, you will need to manually add commands to them to complete the configuration. Make sure to follow all the prompts given during the `cargo generate` process. #### Invoke metadata embedding @@ -75,16 +82,14 @@ Make sure to follow all the prompts given during the `cargo generate` process. Add the following to one of your project's source files (e.g. `src/main.rs`): ```rust -use commitment_issues::include_metadata; - -include_metadata!(); +commitment_issues::include_metadata!(); ``` This invokes the `include_metadata!()` macro, which generates a module called `metadata` within your source file at compile time. #### Accessing metadata within project source code -As well as containing the metadata section, the `metadata` module exposes a set of macros to access the various fields of the metadata section from within your code. +As well as containing the metadata, the `metadata` module exposes a set of macros to access the various fields of the metadata section from within your code. The template's [main.rs](https://github.com/dysonltd/commitment-issues/blob/main/template/src/main.rs) file gives an example of how these macros can be used. #### Standard Compile and run @@ -100,13 +105,6 @@ If you see issues relating to being unable to find openssl headers, try activati ## Inspecting binary metadata -The metadata can be found in a section called ".metadata" within the executable binary generated by cargo. - This can easily be read using `objdump` from the [`binutils`](https://www.gnu.org/software/binutils/) package: - -```sh -objdump -s | grep "section \.metadata" -A 20 -``` - The metadata is an 80-byte block beginning with the sequence 0xFFFEFDFC and ending with the sequence 0x01020304 (inclusive). The data contained within is as follows: @@ -124,6 +122,43 @@ Future work will include adding a command line tool for reading metadata from a The current structure of the metadata is fixed. Future work will aim to make it possible to configure the structure of the metadata through a configuration file. +The metadata is embedded into the binary's read-only data section, generally named `.rodata`. +Mac binaries instead store read-only data in `__DATA,__const`. + +The easiest way to inspect the metadata within the binary is using the `objdump` tool from `binutils`. +The `cargo-binutils` package provides cargo integration of these tools. +First install the tools themselves with: + +```sh +rustup component add llvm-tools +``` + +Then the cargo integration can be installed either as precompiled binaries: + +```sh +cargo binstall cargo-binutils +``` + +or from source with: + +```sh +cargo install cargo-binutils +``` + +The binary metadata can now be inspected with: + +```sh +cargo objdump -s -j .rodata +``` + +*NOTE* For Mac binaries, replace `.rodata` with `__DATA,__const`. + +If your read-only data section is very long, it may be easier to find the metadata with grep by looking for the header: + +```sh +cargo objdump -s -j .rodata | grep "fffefdfc" -A 20 +``` + ## Windows targets **TODO!** This crate has not yet been tested for a Windows target. diff --git a/src/lib.rs b/src/lib.rs index 994f840..bbc9568 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,9 +52,10 @@ pub fn include_metadata(_: TokenStream) -> TokenStream { footer: [u8; 4], } - #[cfg_attr(target_os = "macos", link_section = "__DATA,__metadata")] - #[cfg_attr(not(target_os = "macos"), link_section = ".metadata")] + #[cfg_attr(target_os = "macos", link_section = "__TEXT,__const")] + #[cfg_attr(not(target_os = "macos"), link_section = ".rodata.metadata")] #[used] + #[no_mangle] static METADATA: Metadata = Metadata { header: [#(#header),*], diff --git a/template/Cargo.toml.liquid b/template/Cargo.toml.liquid index 85fc24b..72f349c 100644 --- a/template/Cargo.toml.liquid +++ b/template/Cargo.toml.liquid @@ -6,3 +6,6 @@ authors = ["{{authors}}"] [dependencies] commitment-issues = { git = "https://github.com/dysonltd/commitment-issues" } + +[build-dependencies] +commitment-issues = { git = "https://github.com/dysonltd/commitment-issues" } diff --git a/template/build.rs b/template/build.rs index 219dc07..8b5de3c 100644 --- a/template/build.rs +++ b/template/build.rs @@ -1,4 +1,3 @@ fn main() { println!("cargo:rerun-if-changed=./.git/"); - println!("cargo:rustc-link-arg=-Tmetadata.x"); } diff --git a/template/init.rhai b/template/init.rhai index f9f66e0..b7b718f 100644 --- a/template/init.rhai +++ b/template/init.rhai @@ -6,8 +6,6 @@ if variable::get("is_init") { print("*** Add the following statements to your build.rs:"); print(); print("println!(\"cargo:rerun-if-changed={}\", commitment_issues::find_valid_git_root!());"); - print("#[cfg(not(target_os = \"macos\"))]"); - print("println!(\"cargo:rustc-link-arg=-Tmetadata.x\");"); print(); } @@ -25,6 +23,7 @@ if variable::get("is_init") { print("*** To add the commitment issues crate to your project, run:"); print(); print("cargo add --git https://github.com/dysonltd/commitment-issues"); + print("cargo add --build --git https://github.com/dysonltd/commitment-issues"); print(); variable::set("project-name", "existing project"); diff --git a/template/metadata.x b/template/metadata.x deleted file mode 100644 index f743536..0000000 --- a/template/metadata.x +++ /dev/null @@ -1,8 +0,0 @@ -SECTIONS { - . = ALIGN(4); - .metadata : { - KEEP(*(.metadata)) - } - . = ALIGN(4); -} -INSERT AFTER .text; diff --git a/template/src/main.rs b/template/src/main.rs index 70b65a3..a649c49 100644 --- a/template/src/main.rs +++ b/template/src/main.rs @@ -1,6 +1,4 @@ -use commitment_issues::include_metadata; - -include_metadata!(); +commitment_issues::include_metadata!(); fn main() { println!("Hello, world!");