From 7a8554d3136fadc75d7dbe8fe8b78dfee6c97ebf Mon Sep 17 00:00:00 2001 From: Joakim Hulthe Date: Thu, 8 Feb 2024 17:34:21 +0100 Subject: [PATCH] initial commit --- .gitignore | 1 + Cargo.lock | 635 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 16 ++ rust-toolchain.toml | 2 + src/ints.rs | 143 ++++++++++ src/main.rs | 208 +++++++++++++++ src/output.rs | 28 ++ src/structs.rs | 96 +++++++ 8 files changed, 1129 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 rust-toolchain.toml create mode 100644 src/ints.rs create mode 100644 src/main.rs create mode 100644 src/output.rs create mode 100644 src/structs.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..fe7c3f5 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,635 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "anstream" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bytecheck" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bytemuck" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "color-eyre" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "elf" +version = "0.1.0" +dependencies = [ + "bytemuck", + "clap", + "color-eyre", + "eyre", + "rand", + "rend", + "serde", + "serde_json", +] + +[[package]] +name = "eyre" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rend" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" +dependencies = [ + "bytecheck", + "bytemuck", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "serde" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_json" +version = "1.0.113" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "sharded-slab", + "thread_local", + "tracing-core", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..61a75e5 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "elf" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +bytemuck = "1.14.0" +clap = { version = "4.4.18", features = ["derive"] } +color-eyre = "0.6.2" +eyre = "0.6.11" +rand = "0.8.5" +rend = { version = "0.4.1", features = ["bytemuck"] } +serde = { version = "1.0.196", features = ["derive"] } +serde_json = "1.0.113" diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..5d56faf --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/src/ints.rs b/src/ints.rs new file mode 100644 index 0000000..a4018a2 --- /dev/null +++ b/src/ints.rs @@ -0,0 +1,143 @@ +use bytemuck::{Pod, Zeroable}; +use core::fmt::Debug; +use core::marker::PhantomData; +use serde::Serialize; + +#[derive(Pod, Zeroable, Clone, Copy, Debug, Serialize)] +#[repr(C, packed)] +pub struct BigEndian; + +#[derive(Pod, Zeroable, Clone, Copy, Debug, Serialize)] +#[repr(C, packed)] +pub struct LittleEndian; + +pub trait Decode: Copy { + type Native: Debug + Copy; + fn to_native(self) -> Self::Native; +} + +#[derive(Pod, Zeroable, Clone, Copy)] +#[repr(C, packed)] +pub struct U64 { + raw: [u8; 8], + _endian: PhantomData, +} + +#[derive(Pod, Zeroable, Clone, Copy)] +#[repr(C, packed)] +pub struct U32 { + raw: [u8; 4], + _endian: PhantomData, +} + +#[derive(Pod, Zeroable, Clone, Copy)] +#[repr(C, packed)] +pub struct U16 { + raw: [u8; 2], + _endian: PhantomData, +} + +impl Decode for U64 { + type Native = u64; + fn to_native(self) -> Self::Native { + u64::from_be_bytes(self.raw) + } +} + +impl Decode for U64 { + type Native = u64; + fn to_native(self) -> Self::Native { + u64::from_le_bytes(self.raw) + } +} + +impl Decode for U32 { + type Native = u32; + fn to_native(self) -> Self::Native { + u32::from_be_bytes(self.raw) + } +} + +impl Decode for U32 { + type Native = u32; + fn to_native(self) -> Self::Native { + u32::from_le_bytes(self.raw) + } +} + +impl Decode for U16 { + type Native = u16; + fn to_native(self) -> Self::Native { + u16::from_be_bytes(self.raw) + } +} + +impl Decode for U16 { + type Native = u16; + fn to_native(self) -> Self::Native { + u16::from_le_bytes(self.raw) + } +} + +impl Debug for U64 +where + Self: Decode, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Debug::fmt(&self.to_native(), f) + } +} + +impl Debug for U32 +where + Self: Decode, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Debug::fmt(&self.to_native(), f) + } +} + +impl Debug for U16 +where + Self: Decode, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Debug::fmt(&self.to_native(), f) + } +} + +impl Serialize for U64 +where + Self: Decode, +{ + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + format!("{:?}", self.to_native()).serialize(serializer) + } +} + +impl Serialize for U32 +where + Self: Decode, +{ + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + format!("{:?}", self.to_native()).serialize(serializer) + } +} + +impl Serialize for U16 +where + Self: Decode, +{ + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + format!("{:?}", self.to_native()).serialize(serializer) + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..0d1d79b --- /dev/null +++ b/src/main.rs @@ -0,0 +1,208 @@ +mod ints; +mod output; +mod structs; + +use crate::{ + ints::BigEndian, + output::Output, + structs::{ElfHeader1, ElfHeader2, SectionHeaderEntry, SymbolTableEntry}, +}; +use bytemuck::from_bytes; +use clap::{Parser, Subcommand}; +use core::str::from_utf8; +use eyre::{bail, eyre, Context}; +use ints::{Decode, LittleEndian, U32, U64}; +use serde_json::Value; +use std::{fs, mem::size_of, path::PathBuf}; + +#[derive(Parser)] +struct Opt { + elf: PathBuf, + + #[clap(subcommand)] + command: Command, +} + +#[derive(Subcommand)] +enum Command { + /// List sections + Sections {}, + + /// List symbols + Symbols { + #[clap(short, long)] + section: String, + }, +} +const HEADER1_LEN: usize = size_of::(); + +macro_rules! parse_elf { + ($endian:ty, $word:ty, $out:expr, $header1:expr, $elf:expr) => {{ + //let header1 = $header1; + let out = $out; + const HEADER2_LEN: usize = size_of::>(); + let elf = $elf; + if elf.len() < HEADER1_LEN + HEADER2_LEN { + bail!("not a valid elf file: file too small"); + } + + let header2: &[u8; HEADER2_LEN] = elf[HEADER1_LEN..][..HEADER2_LEN].try_into()?; + let header2: ElfHeader2<$endian, $word> = *from_bytes(header2); + out.write("header2", &header2)?; + + let e_shentsize = usize::from(header2.e_shentsize.to_native()); + if e_shentsize != size_of::>() { + bail!("wrong e_shentsize (0x{e_shentsize:x})"); + } + + let e_shnum = usize::from(header2.e_shnum.to_native()); + let section_header_table_size = e_shentsize * e_shnum; + let section_header_table_start = + usize::try_from(header2.e_shoff.to_native()).wrap_err("e_shoff bigger than usize")?; + let section_header_table_end = section_header_table_start + section_header_table_size; + + if elf.len() < section_header_table_end { + bail!("not a valid elf file: section table goes past eof"); + } else if elf.len() > section_header_table_end { + bail!("not a valid elf file: section table doesn't end at eof"); + } + + let mut section_header_entries = vec![]; + for entry_start in + (section_header_table_start..section_header_table_end).step_by(e_shentsize) + { + let entry = &elf[entry_start..][..e_shentsize]; + let entry: SectionHeaderEntry<$endian, $word> = *from_bytes(entry); + section_header_entries.push(entry); + } + out.write("section_table", §ion_header_entries)?; + + let names_section_i = usize::from(header2.e_shstrndx.to_native()); + let names_section_entry = §ion_header_entries + .get(names_section_i) + .ok_or(eyre!("invalid e_shstrndx"))?; + + let names_section_start: usize = (names_section_entry.sh_offset.to_native().try_into()) + .wrap_err("sh_offset bigger than usize")?; + let names_section_size: usize = (names_section_entry.sh_size.to_native().try_into()) + .wrap_err("sh_size bigger than usize")?; + let names_section_end = names_section_start + names_section_size; + let names_section = &elf[names_section_start..names_section_end]; + + let mut symtab_i = None; + let mut strtab = None; + + let mut section_header_entries_with_names = vec![]; + for (i, entry) in section_header_entries.iter().enumerate() { + let name_start: usize = (entry.sh_name.to_native()) + .try_into() + .wrap_err("sh_name bigger than usize")?; + + if name_start > names_section.len() { + bail!("sh_name out of bounds for .names section"); + } + + let name_end = (name_start..names_section.len()) + .find(|&i| names_section[i] == b'\0') + .ok_or(eyre!(".names entry missing null byte"))?; + let name = &names_section[name_start..name_end]; + let name = from_utf8(name).wrap_err(eyre!(".names entry not valid utf-8"))?; + let section_start = entry.start().wrap_err_with(|| name.to_string())?; + let section_end = entry.end().wrap_err_with(|| name.to_string())?; + if section_end > elf.len() { + bail!("section {name:?} end is past eof"); + } + + match name { + ".symtab" => symtab_i = Some(i), + ".strtab" => { + strtab = Some(&elf[section_start..section_end]); + } + _ => {} + } + + let mut entry_json = + serde_json::to_value(entry).wrap_err("failed to serialize section header")?; + + let Value::Object(fields) = &mut entry_json else { + unreachable!() + }; + + fields.insert("name".to_string(), Value::String(name.to_string())); + section_header_entries_with_names.push(entry_json); + } + let _ = out.write("section_table", §ion_header_entries_with_names); + + if let Some(symtab_i) = symtab_i { + let symtab = §ion_header_entries[symtab_i]; + const ENTRY_SIZE: usize = size_of::>(); + if symtab.sh_size.to_native() as usize != ENTRY_SIZE { + bail!(".symtab size not a multiple of symtab entry size"); + } + + let section_start: usize = symtab.start().wrap_err(".symtab")?; + let section_end: usize = symtab.end().wrap_err(".symtab")?; + + for entry in elf[section_start..section_end].chunks_exact(ENTRY_SIZE) { + let entry: &[u8; ENTRY_SIZE] = entry.try_into().unwrap(); + let entry: &SymbolTableEntry<$word> = from_bytes(entry); + let name_start: usize = (entry.st_name.to_native().try_into()) + .wrap_err("symtab entry st_name too big to fit in usize")?; + + let name = (name_start != 0) + .then(|| { + strtab.map(|strtab| { + eprintln!("{name_start} {}", strtab.len()); + let name_end = (name_start..strtab.len()) + .find(|&i| strtab[i] == b'\0') + .ok_or(eyre!(".strtab entry missing null byte"))?; + let name = &strtab[name_start..name_end]; + from_utf8(name).wrap_err(eyre!( + ".strtab entry at 0x{name_start:x} is not valid utf-8" + )) + }) + }) + // Option> to Result