mirror of
https://github.com/encounter/decomp-toolkit.git
synced 2025-06-12 09:33:30 +00:00
Major dwarf dump
rework
- Supports games with C++ DWARF info - Syntax highlighting when printing to console (disable with `--no-color`) - Overall improvements to parsing and output
This commit is contained in:
parent
4935708b61
commit
5e13998e93
216
Cargo.lock
generated
216
Cargo.lock
generated
@ -310,7 +310,8 @@ dependencies = [
|
|||||||
"flate2",
|
"flate2",
|
||||||
"glob",
|
"glob",
|
||||||
"hex",
|
"hex",
|
||||||
"indexmap",
|
"indent",
|
||||||
|
"indexmap 2.0.2",
|
||||||
"itertools",
|
"itertools",
|
||||||
"log",
|
"log",
|
||||||
"memchr",
|
"memchr",
|
||||||
@ -334,12 +335,22 @@ dependencies = [
|
|||||||
"sha-1",
|
"sha-1",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"supports-color 2.1.0",
|
"supports-color 2.1.0",
|
||||||
|
"syntect",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-attributes",
|
"tracing-attributes",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"xxhash-rust",
|
"xxhash-rust",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deranged"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3"
|
||||||
|
dependencies = [
|
||||||
|
"powerfmt",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
@ -428,6 +439,12 @@ dependencies = [
|
|||||||
"miniz_oxide 0.7.1",
|
"miniz_oxide 0.7.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fnv"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.14.6"
|
version = "0.14.6"
|
||||||
@ -459,6 +476,12 @@ version = "0.3.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.14.1"
|
version = "0.14.1"
|
||||||
@ -489,6 +512,22 @@ version = "0.4.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indent"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9f1a0777d972970f204fdf8ef319f1f4f8459131636d7e3c96c5d59570d0fa6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown 0.12.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.0.2"
|
version = "2.0.2"
|
||||||
@ -496,7 +535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"
|
checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown 0.14.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -543,6 +582,21 @@ version = "0.2.147"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "line-wrap"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9"
|
||||||
|
dependencies = [
|
||||||
|
"safemem",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linked-hash-map"
|
||||||
|
version = "0.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.4.10"
|
version = "0.4.10"
|
||||||
@ -681,8 +735,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
|
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"hashbrown",
|
"hashbrown 0.14.1",
|
||||||
"indexmap",
|
"indexmap 2.0.2",
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -692,6 +746,28 @@ version = "1.18.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "onig"
|
||||||
|
version = "6.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"onig_sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "onig_sys"
|
||||||
|
version = "69.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "overload"
|
name = "overload"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@ -720,7 +796,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9"
|
checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fixedbitset",
|
"fixedbitset",
|
||||||
"indexmap",
|
"indexmap 2.0.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -729,6 +805,32 @@ version = "0.2.12"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05"
|
checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkg-config"
|
||||||
|
version = "0.3.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "plist"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a4a0cfc5fb21a09dc6af4bf834cf10d4a32fccd9e2ea468c4b1751a097487aa"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"indexmap 1.9.3",
|
||||||
|
"line-wrap",
|
||||||
|
"quick-xml",
|
||||||
|
"serde",
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "powerfmt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppc750cl"
|
name = "ppc750cl"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@ -770,6 +872,15 @@ dependencies = [
|
|||||||
"unicase",
|
"unicase",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-xml"
|
||||||
|
version = "0.30.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.33"
|
version = "1.0.33"
|
||||||
@ -883,6 +994,21 @@ version = "1.0.15"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "safemem"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "same-file"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@ -937,7 +1063,7 @@ version = "0.9.25"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574"
|
checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap 2.0.2",
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
@ -1018,6 +1144,27 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syntect"
|
||||||
|
version = "5.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e02b4b303bf8d08bfeb0445cba5068a3d306b6baece1d5582171a9bf49188f91"
|
||||||
|
dependencies = [
|
||||||
|
"bincode",
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"flate2",
|
||||||
|
"fnv",
|
||||||
|
"once_cell",
|
||||||
|
"onig",
|
||||||
|
"plist",
|
||||||
|
"regex-syntax 0.7.5",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
"walkdir",
|
||||||
|
"yaml-rust",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
@ -1057,6 +1204,35 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5"
|
||||||
|
dependencies = [
|
||||||
|
"deranged",
|
||||||
|
"itoa",
|
||||||
|
"powerfmt",
|
||||||
|
"serde",
|
||||||
|
"time-core",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-core"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20"
|
||||||
|
dependencies = [
|
||||||
|
"time-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.5.11"
|
version = "0.5.11"
|
||||||
@ -1179,6 +1355,16 @@ version = "0.9.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "walkdir"
|
||||||
|
version = "2.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
|
||||||
|
dependencies = [
|
||||||
|
"same-file",
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@ -1195,6 +1381,15 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -1329,3 +1524,12 @@ name = "xxhash-rust"
|
|||||||
version = "0.8.7"
|
version = "0.8.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9828b178da53440fa9c766a3d2f73f7cf5d0ac1fe3980c1e5018d899fd19e07b"
|
checksum = "9828b178da53440fa9c766a3d2f73f7cf5d0ac1fe3980c1e5018d899fd19e07b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yaml-rust"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||||
|
dependencies = [
|
||||||
|
"linked-hash-map",
|
||||||
|
]
|
||||||
|
@ -35,6 +35,7 @@ flagset = { version = "0.4.4", features = ["serde"] }
|
|||||||
flate2 = "1.0.27"
|
flate2 = "1.0.27"
|
||||||
glob = "0.3.1"
|
glob = "0.3.1"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
|
indent = "0.1.1"
|
||||||
indexmap = "2.0.2"
|
indexmap = "2.0.2"
|
||||||
itertools = "0.11.0"
|
itertools = "0.11.0"
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
@ -59,6 +60,7 @@ serde_yaml = "0.9.25"
|
|||||||
sha-1 = "0.10.1"
|
sha-1 = "0.10.1"
|
||||||
smallvec = "1.11.1"
|
smallvec = "1.11.1"
|
||||||
supports-color = "2.1.0"
|
supports-color = "2.1.0"
|
||||||
|
syntect = "5.1.0"
|
||||||
tracing = "0.1.37"
|
tracing = "0.1.37"
|
||||||
tracing-attributes = "0.1.26"
|
tracing-attributes = "0.1.26"
|
||||||
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
|
||||||
|
250
src/cmd/dwarf.rs
250
src/cmd/dwarf.rs
@ -2,16 +2,21 @@ use std::{
|
|||||||
collections::{btree_map, BTreeMap},
|
collections::{btree_map, BTreeMap},
|
||||||
io::{stdout, Cursor, Read, Write},
|
io::{stdout, Cursor, Read, Write},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
|
str::from_utf8,
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Context, Result};
|
||||||
use argp::FromArgs;
|
use argp::FromArgs;
|
||||||
use object::{elf, Object, ObjectSection, ObjectSymbol, RelocationKind, RelocationTarget, Section};
|
use object::{elf, Object, ObjectSection, ObjectSymbol, RelocationKind, RelocationTarget, Section};
|
||||||
|
use syntect::{
|
||||||
|
highlighting::{Color, HighlightIterator, HighlightState, Highlighter, Theme, ThemeSet},
|
||||||
|
parsing::{ParseState, ScopeStack, SyntaxReference, SyntaxSet},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::util::{
|
use crate::util::{
|
||||||
dwarf::{
|
dwarf::{
|
||||||
process_address, process_type, process_variable_location, read_debug_section, type_string,
|
process_root_tag, read_debug_section, should_skip_tag, tag_type_string, AttributeKind,
|
||||||
ud_type, ud_type_def, ud_type_string, AttributeKind, TagKind,
|
TagKind,
|
||||||
},
|
},
|
||||||
file::{buf_writer, map_file},
|
file::{buf_writer, map_file},
|
||||||
};
|
};
|
||||||
@ -40,6 +45,9 @@ pub struct DumpArgs {
|
|||||||
#[argp(option, short = 'o')]
|
#[argp(option, short = 'o')]
|
||||||
/// Output file. (Or directory, for archive)
|
/// Output file. (Or directory, for archive)
|
||||||
out: Option<PathBuf>,
|
out: Option<PathBuf>,
|
||||||
|
#[argp(switch)]
|
||||||
|
/// Disable color output.
|
||||||
|
no_color: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(args: Args) -> Result<()> {
|
pub fn run(args: Args) -> Result<()> {
|
||||||
@ -49,6 +57,12 @@ pub fn run(args: Args) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn dump(args: DumpArgs) -> Result<()> {
|
fn dump(args: DumpArgs) -> Result<()> {
|
||||||
|
let theme_set = ThemeSet::load_defaults();
|
||||||
|
let theme = theme_set.themes.get("Solarized (dark)").context("Failed to load theme")?;
|
||||||
|
let syntax_set = SyntaxSet::load_defaults_newlines();
|
||||||
|
let syntax =
|
||||||
|
syntax_set.find_syntax_by_extension("cpp").context("Failed to find syntax")?.clone();
|
||||||
|
|
||||||
let file = map_file(&args.in_file)?;
|
let file = map_file(&args.in_file)?;
|
||||||
let buf = file.as_slice();
|
let buf = file.as_slice();
|
||||||
if buf.starts_with(b"!<arch>\n") {
|
if buf.starts_with(b"!<arch>\n") {
|
||||||
@ -80,9 +94,13 @@ fn dump(args: DumpArgs) -> Result<()> {
|
|||||||
let mut file = buf_writer(file_path)?;
|
let mut file = buf_writer(file_path)?;
|
||||||
dump_debug_section(&mut file, &obj_file, debug_section)?;
|
dump_debug_section(&mut file, &obj_file, debug_section)?;
|
||||||
file.flush()?;
|
file.flush()?;
|
||||||
} else {
|
} else if args.no_color {
|
||||||
println!("\nFile {}:", name);
|
println!("\n// File {}:", name);
|
||||||
dump_debug_section(&mut stdout(), &obj_file, debug_section)?;
|
dump_debug_section(&mut stdout(), &obj_file, debug_section)?;
|
||||||
|
} else {
|
||||||
|
let mut writer = HighlightWriter::new(syntax_set.clone(), syntax.clone(), theme);
|
||||||
|
writeln!(writer, "\n// File {}:", name)?;
|
||||||
|
dump_debug_section(&mut writer, &obj_file, debug_section)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -94,8 +112,11 @@ fn dump(args: DumpArgs) -> Result<()> {
|
|||||||
let mut file = buf_writer(out_path)?;
|
let mut file = buf_writer(out_path)?;
|
||||||
dump_debug_section(&mut file, &obj_file, debug_section)?;
|
dump_debug_section(&mut file, &obj_file, debug_section)?;
|
||||||
file.flush()?;
|
file.flush()?;
|
||||||
} else {
|
} else if args.no_color {
|
||||||
dump_debug_section(&mut stdout(), &obj_file, debug_section)?;
|
dump_debug_section(&mut stdout(), &obj_file, debug_section)?;
|
||||||
|
} else {
|
||||||
|
let mut writer = HighlightWriter::new(syntax_set, syntax, theme);
|
||||||
|
dump_debug_section(&mut writer, &obj_file, debug_section)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -145,140 +166,37 @@ where
|
|||||||
.string_attribute(AttributeKind::Name)
|
.string_attribute(AttributeKind::Name)
|
||||||
.ok_or_else(|| anyhow!("CompileUnit without name {:?}", tag))?;
|
.ok_or_else(|| anyhow!("CompileUnit without name {:?}", tag))?;
|
||||||
if units.contains(unit) {
|
if units.contains(unit) {
|
||||||
log::warn!("Duplicate unit '{}'", unit);
|
// log::warn!("Duplicate unit '{}'", unit);
|
||||||
} else {
|
} else {
|
||||||
units.push(unit.clone());
|
units.push(unit.clone());
|
||||||
}
|
}
|
||||||
|
writeln!(w, "\n// Compile unit: {}", unit)?;
|
||||||
|
|
||||||
let children = tag.children(&tags);
|
let children = tag.children(&tags);
|
||||||
let mut typedefs = BTreeMap::<u32, Vec<u32>>::new();
|
let mut typedefs = BTreeMap::<u32, Vec<u32>>::new();
|
||||||
for child in children {
|
for child in children {
|
||||||
match child.kind {
|
let tag_type = process_root_tag(&tags, child)?;
|
||||||
TagKind::GlobalSubroutine | TagKind::Subroutine => {
|
if should_skip_tag(&tag_type) {
|
||||||
let _is_prototyped =
|
continue;
|
||||||
child.string_attribute(AttributeKind::Prototyped).is_some();
|
}
|
||||||
if let (Some(_hi), Some(_lo)) = (
|
writeln!(w, "{}", tag_type_string(&tags, &typedefs, &tag_type)?)?;
|
||||||
child.address_attribute(AttributeKind::HighPc),
|
|
||||||
child.address_attribute(AttributeKind::LowPc),
|
|
||||||
) {}
|
|
||||||
let name = child
|
|
||||||
.string_attribute(AttributeKind::Name)
|
|
||||||
.ok_or_else(|| anyhow!("Subroutine without name"))?;
|
|
||||||
let udt = ud_type(&tags, child)?;
|
|
||||||
let ts = ud_type_string(&tags, &typedefs, &udt)?;
|
|
||||||
writeln!(w, "{} {}{} {{", ts.prefix, name, ts.suffix)?;
|
|
||||||
for tag in child.children(&tags) {
|
|
||||||
match tag.kind {
|
|
||||||
TagKind::LocalVariable => {}
|
|
||||||
_ => continue,
|
|
||||||
}
|
|
||||||
let type_attr = tag.type_attribute().ok_or_else(|| {
|
|
||||||
anyhow!("LocalVariable without type attr")
|
|
||||||
})?;
|
|
||||||
let var_type = process_type(type_attr)?;
|
|
||||||
let ts = type_string(&tags, &typedefs, &var_type)?;
|
|
||||||
let name = tag
|
|
||||||
.string_attribute(AttributeKind::Name)
|
|
||||||
.ok_or_else(|| anyhow!("LocalVariable without name"))?;
|
|
||||||
write!(w, "\t{} {}{};", ts.prefix, name, ts.suffix)?;
|
|
||||||
if let Some(location) =
|
|
||||||
tag.block_attribute(AttributeKind::Location)
|
|
||||||
{
|
|
||||||
if !location.is_empty() {
|
|
||||||
write!(
|
|
||||||
w,
|
|
||||||
" // {}",
|
|
||||||
process_variable_location(location)?
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writeln!(w)?;
|
|
||||||
}
|
|
||||||
writeln!(w, "}}")?;
|
|
||||||
}
|
|
||||||
TagKind::Typedef => {
|
|
||||||
let name = child
|
|
||||||
.string_attribute(AttributeKind::Name)
|
|
||||||
.ok_or_else(|| anyhow!("Typedef without name"))?;
|
|
||||||
let attr = child
|
|
||||||
.type_attribute()
|
|
||||||
.ok_or_else(|| anyhow!("Typedef without type attribute"))?;
|
|
||||||
let t = process_type(attr)?;
|
|
||||||
let ts = type_string(&tags, &typedefs, &t)?;
|
|
||||||
writeln!(w, "typedef {} {}{};", ts.prefix, name, ts.suffix)?;
|
|
||||||
|
|
||||||
// TODO fundamental typedefs?
|
if let TagKind::Typedef = child.kind {
|
||||||
if let Some(ud_type_ref) =
|
// TODO fundamental typedefs?
|
||||||
child.reference_attribute(AttributeKind::UserDefType)
|
if let Some(ud_type_ref) =
|
||||||
{
|
child.reference_attribute(AttributeKind::UserDefType)
|
||||||
match typedefs.entry(ud_type_ref) {
|
{
|
||||||
btree_map::Entry::Vacant(e) => {
|
match typedefs.entry(ud_type_ref) {
|
||||||
e.insert(vec![child.key]);
|
btree_map::Entry::Vacant(e) => {
|
||||||
}
|
e.insert(vec![child.key]);
|
||||||
btree_map::Entry::Occupied(e) => {
|
}
|
||||||
e.into_mut().push(child.key);
|
btree_map::Entry::Occupied(e) => {
|
||||||
}
|
e.into_mut().push(child.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TagKind::GlobalVariable | TagKind::LocalVariable => {
|
|
||||||
let name = child
|
|
||||||
.string_attribute(AttributeKind::Name)
|
|
||||||
.ok_or_else(|| anyhow!("Variable without name"))?;
|
|
||||||
let address = if let Some(location) =
|
|
||||||
child.block_attribute(AttributeKind::Location)
|
|
||||||
{
|
|
||||||
Some(process_address(location)?)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
if let Some(type_attr) = child.type_attribute() {
|
|
||||||
let var_type = process_type(type_attr)?;
|
|
||||||
// log::info!("{:?}", var_type);
|
|
||||||
// if let TypeKind::UserDefined(key) = var_type.kind {
|
|
||||||
// let ud_tag = tags
|
|
||||||
// .get(&key)
|
|
||||||
// .ok_or_else(|| anyhow!("Invalid UD type ref"))?;
|
|
||||||
// let ud_type = ud_type(&tags, ud_tag)?;
|
|
||||||
// log::info!("{:?}", ud_type);
|
|
||||||
// }
|
|
||||||
let ts = type_string(&tags, &typedefs, &var_type)?;
|
|
||||||
let st = if child.kind == TagKind::LocalVariable {
|
|
||||||
"static "
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
};
|
|
||||||
let address_str = match address {
|
|
||||||
Some(addr) => format!(" : {:#010X}", addr),
|
|
||||||
None => String::new(),
|
|
||||||
};
|
|
||||||
let size = var_type.size(&tags)?;
|
|
||||||
writeln!(
|
|
||||||
w,
|
|
||||||
"{}{} {}{}{}; // size: {:#X}",
|
|
||||||
st, ts.prefix, name, ts.suffix, address_str, size,
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TagKind::StructureType
|
|
||||||
| TagKind::ArrayType
|
|
||||||
| TagKind::EnumerationType
|
|
||||||
| TagKind::UnionType
|
|
||||||
| TagKind::ClassType
|
|
||||||
| TagKind::SubroutineType => {
|
|
||||||
let udt = ud_type(&tags, child)?;
|
|
||||||
if child.string_attribute(AttributeKind::Name).is_some() {
|
|
||||||
writeln!(w, "{}", ud_type_def(&tags, &typedefs, &udt)?)?;
|
|
||||||
} else {
|
|
||||||
// log::warn!("No name for tag: {:?}", child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
log::warn!("Unhandled CompileUnit child {:?}", child.kind);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// println!("Children: {:?}", children.iter().map(|c| c.kind).collect::<Vec<TagKind>>());
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
log::warn!("Expected CompileUnit, got {:?}", tag.kind);
|
log::warn!("Expected CompileUnit, got {:?}", tag.kind);
|
||||||
@ -298,3 +216,81 @@ where
|
|||||||
// }
|
// }
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct HighlightWriter<'a> {
|
||||||
|
line: String,
|
||||||
|
highlighter: Highlighter<'a>,
|
||||||
|
parse_state: ParseState,
|
||||||
|
highlight_state: HighlightState,
|
||||||
|
syntax_set: SyntaxSet,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> HighlightWriter<'a> {
|
||||||
|
pub fn new(
|
||||||
|
syntax_set: SyntaxSet,
|
||||||
|
syntax: SyntaxReference,
|
||||||
|
theme: &'a Theme,
|
||||||
|
) -> HighlightWriter<'a> {
|
||||||
|
let highlighter = Highlighter::new(theme);
|
||||||
|
let highlight_state = HighlightState::new(&highlighter, ScopeStack::new());
|
||||||
|
HighlightWriter {
|
||||||
|
line: String::new(),
|
||||||
|
highlighter,
|
||||||
|
syntax_set,
|
||||||
|
parse_state: ParseState::new(&syntax),
|
||||||
|
highlight_state,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn blend_fg_color(fg: Color, bg: Color) -> Color {
|
||||||
|
if fg.a == 0xff {
|
||||||
|
return fg;
|
||||||
|
}
|
||||||
|
let ratio = fg.a as u32;
|
||||||
|
let r = (fg.r as u32 * ratio + bg.r as u32 * (255 - ratio)) / 255;
|
||||||
|
let g = (fg.g as u32 * ratio + bg.g as u32 * (255 - ratio)) / 255;
|
||||||
|
let b = (fg.b as u32 * ratio + bg.b as u32 * (255 - ratio)) / 255;
|
||||||
|
Color { r: r as u8, g: g as u8, b: b as u8, a: 255 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Write for HighlightWriter<'_> {
|
||||||
|
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||||
|
let str = from_utf8(buf).map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
|
||||||
|
for s in str.split_inclusive('\n') {
|
||||||
|
self.line.push_str(s);
|
||||||
|
if self.line.ends_with('\n') {
|
||||||
|
self.flush()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(buf.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> std::io::Result<()> {
|
||||||
|
if self.line.is_empty() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let ops = self
|
||||||
|
.parse_state
|
||||||
|
.parse_line(&self.line, &self.syntax_set)
|
||||||
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
|
||||||
|
let iter = HighlightIterator::new(
|
||||||
|
&mut self.highlight_state,
|
||||||
|
&ops[..],
|
||||||
|
&self.line,
|
||||||
|
&self.highlighter,
|
||||||
|
);
|
||||||
|
for (style, text) in iter {
|
||||||
|
print!(
|
||||||
|
"\x1b[48;2;{};{};{}m",
|
||||||
|
style.background.r, style.background.g, style.background.b
|
||||||
|
);
|
||||||
|
let fg = blend_fg_color(style.foreground, style.background);
|
||||||
|
print!("\x1b[38;2;{};{};{}m{}", fg.r, fg.g, fg.b, text);
|
||||||
|
}
|
||||||
|
print!("\x1b[0m");
|
||||||
|
self.line.clear();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1461
src/util/dwarf.rs
1461
src/util/dwarf.rs
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user