summaryrefslogtreecommitdiffstats
path: root/vendor/gimli
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gimli')
-rw-r--r--vendor/gimli/.cargo-checksum.json2
-rw-r--r--vendor/gimli/CHANGELOG.md65
-rw-r--r--vendor/gimli/CONTRIBUTING.md137
-rw-r--r--vendor/gimli/Cargo.lock345
-rw-r--r--vendor/gimli/Cargo.toml91
-rw-r--r--vendor/gimli/README.md17
-rw-r--r--vendor/gimli/benches/bench.rs807
-rw-r--r--vendor/gimli/clippy.toml1
-rw-r--r--vendor/gimli/examples/dwarf-validate.rs267
-rw-r--r--vendor/gimli/examples/dwarfdump.rs2369
-rw-r--r--vendor/gimli/examples/simple.rs67
-rw-r--r--vendor/gimli/examples/simple_line.rs106
-rw-r--r--vendor/gimli/fixtures/self/README.md147
-rw-r--r--vendor/gimli/fixtures/self/debug_abbrevbin1865 -> 0 bytes
-rw-r--r--vendor/gimli/fixtures/self/debug_arangesbin16304 -> 0 bytes
-rw-r--r--vendor/gimli/fixtures/self/debug_infobin392832 -> 0 bytes
-rw-r--r--vendor/gimli/fixtures/self/debug_inlinedbin25062 -> 0 bytes
-rw-r--r--vendor/gimli/fixtures/self/debug_linebin109251 -> 0 bytes
-rw-r--r--vendor/gimli/fixtures/self/debug_locbin283588 -> 0 bytes
-rw-r--r--vendor/gimli/fixtures/self/debug_pubnamesbin138556 -> 0 bytes
-rw-r--r--vendor/gimli/fixtures/self/debug_pubtypesbin52984 -> 0 bytes
-rw-r--r--vendor/gimli/fixtures/self/debug_rangesbin186016 -> 0 bytes
-rw-r--r--vendor/gimli/fixtures/self/debug_strbin145794 -> 0 bytes
-rw-r--r--vendor/gimli/fixtures/self/eh_framebin147656 -> 0 bytes
-rw-r--r--vendor/gimli/fixtures/self/eh_frame_hdrbin108732 -> 0 bytes
-rw-r--r--vendor/gimli/rustfmt.toml0
-rw-r--r--vendor/gimli/src/arch.rs21
-rw-r--r--vendor/gimli/src/common.rs10
-rw-r--r--vendor/gimli/src/constants.rs14
-rw-r--r--vendor/gimli/src/lib.rs4
-rw-r--r--vendor/gimli/src/read/cfi.rs226
-rw-r--r--vendor/gimli/src/read/endian_slice.rs33
-rw-r--r--vendor/gimli/src/read/line.rs2
-rw-r--r--vendor/gimli/src/read/mod.rs6
-rw-r--r--vendor/gimli/src/read/op.rs10
-rw-r--r--vendor/gimli/src/read/reader.rs2
-rw-r--r--vendor/gimli/src/read/unit.rs2
-rw-r--r--vendor/gimli/src/read/value.rs6
-rw-r--r--vendor/gimli/src/write/cfi.rs91
-rw-r--r--vendor/gimli/src/write/unit.rs8
-rw-r--r--vendor/gimli/tests/convert_self.rs158
-rwxr-xr-xvendor/gimli/tests/parse_self.rs431
42 files changed, 411 insertions, 5034 deletions
diff --git a/vendor/gimli/.cargo-checksum.json b/vendor/gimli/.cargo-checksum.json
index 5ffb76b27..92605591d 100644
--- a/vendor/gimli/.cargo-checksum.json
+++ b/vendor/gimli/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"71187c6f7d8c6d8b265cad8dab182e9a79b77f47c696f67cb01dacf697cebb1d","CONTRIBUTING.md":"5f513ec06013e4f6f097e9c9492da5a47b9f25c94c6ecadfb655a77405fe912c","Cargo.lock":"c62e5cea9b318657dd2cbe0281765bae6ad3e6aed4dd845c74be6b5fbf7e6dcd","Cargo.toml":"00ec44ce045b53f6d5de383d6813f911a3f29cfa496b7a9bf1dfdd1ff4573ce7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"2ef8998059f83f88a4702932a8ce0cf374006b7946b0e6557ba0c714d2413823","benches/bench.rs":"e0045b989683794951563aa91b37069b2f6ae55f95e288d23f5c984b46e3a7eb","clippy.toml":"50fd0cdaae995561b1d688c9410fe99335fc7ac3916a400dafd25ff63f8215f7","examples/dwarf-validate.rs":"4aac1045e3c08bf00878eeff75c0cfc30c06171c5eab2e71d757505786729687","examples/dwarfdump.rs":"d67c9a94ef894fed33899b317ec8551e0ed3d06bd8aaf52ec43dea12e0d4598e","examples/simple.rs":"4c3425e8bd1880d9522f5ed2581fb5ccd452d4be678eebc0e147c48722a7be1d","examples/simple_line.rs":"ac795f859a17650dde466b5b23b8c161b2e3b8eb57e32f5b6718a3072f6bfad0","fixtures/self/README.md":"7cfd76031ec5a4b38cc4eb56ccbfe1bb590fb54c333d037550bdeaaeacfc20cb","fixtures/self/debug_abbrev":"7c0faa940d9c68d196d03ad55a20e5c746040fa428ff323277fa381deff82bba","fixtures/self/debug_aranges":"8c2aeb2335f61d04ecb7b747070d24f83a6517cbee79dc5c96d97fb6c53d6b6d","fixtures/self/debug_info":"42028a5983006e0703f9ca9515cd27d891ae4af70279fae5011d547f581e2661","fixtures/self/debug_inlined":"89d9516f06ff835621936037f5884fc56712bf304c1dcde52251ddd510fe8710","fixtures/self/debug_line":"b29aebcca3b38bb2bb8aa708cbe74a0dce5a3b0c18916b63d6d17282c017bec7","fixtures/self/debug_loc":"8906ccb9c204f233eb74c1d069dee97a19d18c2051f9147795d7b5364a9266aa","fixtures/self/debug_pubnames":"cf58e237f89c68afba724597fa7e260448636b45f2e69dc6f1bfe34006e27c48","fixtures/self/debug_pubtypes":"d43c1bed71c9d14d1683294cdc1833f069cf131d6e95ee808547919b4f352d81","fixtures/self/debug_ranges":"6d765ac18d33accd89186d077eeb505cbdf97d990c9201d63d9463cd7787ce7a","fixtures/self/debug_str":"9ed904b68eee77b8558b80b3b7ca03e8527f6c64483e9d6d845f40270eb21183","fixtures/self/eh_frame":"6dc3d84351cac42cf73d03452fbb532470dd94d08715154c48417e3f62095f17","fixtures/self/eh_frame_hdr":"afba7a0aa233c9a8c81c986495bd2505164844adb93272d6bc0c9e592e684716","rustfmt.toml":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","src/arch.rs":"3a9b44d51a770b83e19c5420c7a6c090cf895fe668cbecea4e3c20acdfef871c","src/common.rs":"227d13db91b65d49b1b2d22033eb8374521731a50a7210ceb0ef49194a5d545c","src/constants.rs":"358cf7924c79bc72de59d23d1fa02b2047d6c763c8fbd8be263ab8cd3e3ba7ec","src/endianity.rs":"1f7e62ae34f540c06bedf1e7948739211556eea7dd83731a5ca52c7d687ed0fc","src/leb128.rs":"996d5c79d027f97c010ca487bc4ff5f8265f4b9e63d62b4e4fa291383c259ee9","src/lib.rs":"9a307a6d1fbebeae581df014b4f2b8bd16399fa883209fbdcc4d85eb9ec1dfd5","src/read/abbrev.rs":"31f7e9544a30e35f49dca355981730c2eb145e55ddbf281161d842a566d0a88d","src/read/addr.rs":"f63f289edf889e87107bb2090fb1c50b48af7015f31b7c39c3d6ea09630a38e9","src/read/aranges.rs":"ba3302f87cffb7ee15f48b0530ebd707f45ad056934223078d25ae2a1b034f1c","src/read/cfi.rs":"85cb294cf6a932d31769a747c58d1767b83e64831d8c633ab0b517014fe1cdec","src/read/dwarf.rs":"bac3f10a4f813833cf337361dd13d7e9bcb177355488ec785e901c5369e12daf","src/read/endian_reader.rs":"320983a859c2bb0dd44a3e6fae55ff0a84dba3fa80c2edbc64aa8135c44eddf0","src/read/endian_slice.rs":"476055ef571d53fbb890545fe5893b9083b10b90ec9e538bd82216bbe8bc45fd","src/read/index.rs":"e79b8d591b8e2007a37f5ea85a6d71b69d56ca3739a85cf7bf361724c5b829fa","src/read/lazy.rs":"85642e886ab3a94cea53534d1e133d1c4c17d2deaf291facdc316507e499ce22","src/read/line.rs":"f15196fa61955c40dfdd50f9034667143ab8d58efd8a51469ff7100c8c61f0be","src/read/lists.rs":"67ca9e1a36a91feb4996d035211de845205212bfda02163685d217818567ff93","src/read/loclists.rs":"857701a9e86aee809bfca3fd661e283b4f05038764dfc9c3cb1a349acc00bc47","src/read/lookup.rs":"0cf89ba12b9d48b1fe035dd3a497730323acb9427a9457abbc2f7c58c4c71165","src/read/mod.rs":"2d537e3c8dedc9b2096d27641d86edd598b51b4c26f476f8bc65e6eba5303acb","src/read/op.rs":"57aba989cc3d49772a51de7d487cbd10458f688487d3ae4e5efae4c84adb4e39","src/read/pubnames.rs":"ed752ee1a7017e6d3be42d81e4ddaaac960ef08081463a19106c9f041526d4a3","src/read/pubtypes.rs":"5e75b32c0923e827aff0bb2db456797a0e8d38ba46be992558a7990b3196bcf5","src/read/reader.rs":"b10ff3e77b54347e96b1f3cff30da104dfdd0c4d7a55b672950788f1f1ae3478","src/read/rnglists.rs":"4ec166e73fdfc85efa97b3b005b514bb64d454edb1ba0f201c45df4f2127e745","src/read/str.rs":"4c2f50014451621fea45969cd313f6840fcd3a99d7a2d081bfa1f8e0e434133a","src/read/unit.rs":"4e8af3c654faf8dc42b8bc62edf2f2402c6b42b31889662b0b48753c08b9893a","src/read/util.rs":"40f07a7b6623f29d03e15e41cda625a613ab1973969a4ddbb42365a8550b7e79","src/read/value.rs":"5a91e03ad3d41f679b264753498434b91948c6b89955e4beb4522498386d9b1d","src/test_util.rs":"291eefa6b51c6d934ba2f4a4c9bc7c403046fc1cccf4d43487820f0154bb89e2","src/write/abbrev.rs":"fa02163389e92e804d139cf84f833ab6af932083f0eb2d74464b4a70bd3237ff","src/write/cfi.rs":"3b04b0ebd82363738199cc673f64e0ceb60506a67c4f18b435a109caa62840f3","src/write/dwarf.rs":"8a1a0893e31134ad68993994594f3024ad0c8af7c1188b29e0ffc26b42edef21","src/write/endian_vec.rs":"1d5811986648816a677580b22630f5059757a381487d73e9adbb3008c9ae0c58","src/write/line.rs":"73bf3bab57433fe1dc891c48303cbc4e482306a1b9425f3483ad2985a9676ee9","src/write/loc.rs":"5c1f8d97d8e871a6663ad704f5e15694bddd54b85f2d801b52a520522f1258fd","src/write/mod.rs":"d8aa1da854cdee629d470d00d87e00dc6998e4bec1ca951f8d2f277730ab9d69","src/write/op.rs":"08fec7613aaa9061aae6e31d8b49933c812a6b7609f69e611a2a953af09aa18a","src/write/range.rs":"259e21e32bebbf7cdd8027d401862dee95cb5111e45bc4ff30bf54e3306d0262","src/write/section.rs":"effefef0d5e4557cb099431a20a7304392e6bf4ce04941d72b8bd2df9100e297","src/write/str.rs":"4850cc2fee55980f9cbb6b4169f9861ab9d05c2b28a85c2b790480b83a66f514","src/write/unit.rs":"8876c88dc3529d32e9894acc3194ed99fe437bb7520821c18f9f9f638db08d81","src/write/writer.rs":"7d5dd07b82ec3becebb060c106d4ea697cbd8b9b64a5de78403511a5244e08b1","tests/convert_self.rs":"180909b562969e1691b64628ded8654e6e0b10b3357f39917bd8ac288c5826dd","tests/parse_self.rs":"f2da1c7daef7139545c9367c2f26199e8b4623b31d4ec6480ddd851e6980f2dc"},"package":"ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"c4ed38f2fcbc511dfe7631a79d7fb154c782eac0dd8f1d390846ba257bcf66c7","Cargo.toml":"b5b1c07a6bd1b719ab1d79742fb6e5c83e23e41ea44c269a86cf47b368b7743c","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"ca364ea6f4977f61d45064f656a3ed08a2dda69056a0f573c8e7b9d5bf45a510","src/arch.rs":"8c97cee9a199e0b3b9453e69517a6302ca582481406bdbc36dfc8a7d8506071f","src/common.rs":"301ec88e624ea0ab28a0b4c6819712feacc2886a3640b159f1a8b7eb007ac634","src/constants.rs":"cf37acb6703a3f7cbb5b26467721560a074a03f2a8dfd1a6104d916cb5255117","src/endianity.rs":"1f7e62ae34f540c06bedf1e7948739211556eea7dd83731a5ca52c7d687ed0fc","src/leb128.rs":"996d5c79d027f97c010ca487bc4ff5f8265f4b9e63d62b4e4fa291383c259ee9","src/lib.rs":"0dd6cff2e1fa56a79188b3b83c738b747af3288ef37f5e867e2a53971190818c","src/read/abbrev.rs":"31f7e9544a30e35f49dca355981730c2eb145e55ddbf281161d842a566d0a88d","src/read/addr.rs":"f63f289edf889e87107bb2090fb1c50b48af7015f31b7c39c3d6ea09630a38e9","src/read/aranges.rs":"ba3302f87cffb7ee15f48b0530ebd707f45ad056934223078d25ae2a1b034f1c","src/read/cfi.rs":"6eccbb361753bf2a68a647c100c1f5e29d8b3e5171a2cf1e4c6cdc3ba1ca4586","src/read/dwarf.rs":"bac3f10a4f813833cf337361dd13d7e9bcb177355488ec785e901c5369e12daf","src/read/endian_reader.rs":"320983a859c2bb0dd44a3e6fae55ff0a84dba3fa80c2edbc64aa8135c44eddf0","src/read/endian_slice.rs":"9163375a1d6403cd91b7b665ed42306252500c15d104c75a824c0b7a635ac7be","src/read/index.rs":"e79b8d591b8e2007a37f5ea85a6d71b69d56ca3739a85cf7bf361724c5b829fa","src/read/lazy.rs":"85642e886ab3a94cea53534d1e133d1c4c17d2deaf291facdc316507e499ce22","src/read/line.rs":"19d38cbd27645885c59c41f7b8e7a509e0be1d701e4b30be13780744384c674b","src/read/lists.rs":"67ca9e1a36a91feb4996d035211de845205212bfda02163685d217818567ff93","src/read/loclists.rs":"857701a9e86aee809bfca3fd661e283b4f05038764dfc9c3cb1a349acc00bc47","src/read/lookup.rs":"0cf89ba12b9d48b1fe035dd3a497730323acb9427a9457abbc2f7c58c4c71165","src/read/mod.rs":"45b203294b007cd5184a5b0d65facf8549461dacc0cf928f05b3fe3c479046e0","src/read/op.rs":"a7502462986453d773c28cd4a34d344738e58348290445792c60a8a29cb0857c","src/read/pubnames.rs":"ed752ee1a7017e6d3be42d81e4ddaaac960ef08081463a19106c9f041526d4a3","src/read/pubtypes.rs":"5e75b32c0923e827aff0bb2db456797a0e8d38ba46be992558a7990b3196bcf5","src/read/reader.rs":"3e8ce504b651e14b839ef63c080c705ba7aef956ac2c7a74e298c015b791e2d2","src/read/rnglists.rs":"4ec166e73fdfc85efa97b3b005b514bb64d454edb1ba0f201c45df4f2127e745","src/read/str.rs":"4c2f50014451621fea45969cd313f6840fcd3a99d7a2d081bfa1f8e0e434133a","src/read/unit.rs":"60ecb8099d9386d85119b45ab92d628f3d3409b04669489b76e732d338b27f65","src/read/util.rs":"40f07a7b6623f29d03e15e41cda625a613ab1973969a4ddbb42365a8550b7e79","src/read/value.rs":"5ce8ef633f5af47bd367a5e4cde2c71bcef297c91a8d567192e460c890aef6de","src/test_util.rs":"291eefa6b51c6d934ba2f4a4c9bc7c403046fc1cccf4d43487820f0154bb89e2","src/write/abbrev.rs":"fa02163389e92e804d139cf84f833ab6af932083f0eb2d74464b4a70bd3237ff","src/write/cfi.rs":"e274b8b28f4e58c49ce530a5c630a26c6074be12f0faffed09709b700748afd7","src/write/dwarf.rs":"8a1a0893e31134ad68993994594f3024ad0c8af7c1188b29e0ffc26b42edef21","src/write/endian_vec.rs":"1d5811986648816a677580b22630f5059757a381487d73e9adbb3008c9ae0c58","src/write/line.rs":"73bf3bab57433fe1dc891c48303cbc4e482306a1b9425f3483ad2985a9676ee9","src/write/loc.rs":"5c1f8d97d8e871a6663ad704f5e15694bddd54b85f2d801b52a520522f1258fd","src/write/mod.rs":"d8aa1da854cdee629d470d00d87e00dc6998e4bec1ca951f8d2f277730ab9d69","src/write/op.rs":"08fec7613aaa9061aae6e31d8b49933c812a6b7609f69e611a2a953af09aa18a","src/write/range.rs":"259e21e32bebbf7cdd8027d401862dee95cb5111e45bc4ff30bf54e3306d0262","src/write/section.rs":"effefef0d5e4557cb099431a20a7304392e6bf4ce04941d72b8bd2df9100e297","src/write/str.rs":"4850cc2fee55980f9cbb6b4169f9861ab9d05c2b28a85c2b790480b83a66f514","src/write/unit.rs":"4a96a5f302b3bdf03faf3ff404bbcbed60d295080853ab8dabff5efa53f9ba37","src/write/writer.rs":"7d5dd07b82ec3becebb060c106d4ea697cbd8b9b64a5de78403511a5244e08b1"},"package":"6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"} \ No newline at end of file
diff --git a/vendor/gimli/CHANGELOG.md b/vendor/gimli/CHANGELOG.md
index e90718c5a..8c5456b25 100644
--- a/vendor/gimli/CHANGELOG.md
+++ b/vendor/gimli/CHANGELOG.md
@@ -2,6 +2,69 @@
--------------------------------------------------------------------------------
+## 0.28.0
+
+Released 2023/08/12.
+
+### Breaking changes
+
+* Deleted `impl From<EndianSlice> for &[u8]`. Use `EndianSlice::slice` instead.
+ [#669](https://github.com/gimli-rs/gimli/pull/669)
+
+* Deleted `impl Index<usize> for EndianSlice` and
+ `impl Index<RangeFrom<usize>> for EndianSlice`.
+ [#669](https://github.com/gimli-rs/gimli/pull/669)
+
+* Replaced `impl From<Pointer> for u64` with `Pointer::pointer`.
+ [#670](https://github.com/gimli-rs/gimli/pull/670)
+
+* Updated `fallible-iterator` to 0.3.0.
+ [#672](https://github.com/gimli-rs/gimli/pull/672)
+
+* Changed some optional dependencies to use the `dep:` feature syntax.
+ [#672](https://github.com/gimli-rs/gimli/pull/672)
+
+* Added `non_exhaustive` attribute to `read::RegisterRule`,
+ `read::CallFrameInstruction`, and `write::CallFrameInstruction`.
+ [#673](https://github.com/gimli-rs/gimli/pull/673)
+
+### Changed
+
+* The minimum supported rust version for the `read` feature and its dependencies
+ increased to 1.60.0.
+
+* The minimum supported rust version for other features increased to 1.65.0.
+
+### Added
+
+* Added `Vendor`, `read::DebugFrame::set_vendor`, and `read::EhFrame::set_vendor`.
+ [#673](https://github.com/gimli-rs/gimli/pull/673)
+
+* Added more ARM and AArch64 register definitions, and
+ `DW_CFA_AARCH64_negate_ra_state` support.
+ [#673](https://github.com/gimli-rs/gimli/pull/673)
+
+--------------------------------------------------------------------------------
+
+## 0.27.3
+
+Released 2023/06/14.
+
+### Changed
+
+* Excluded test fixtures from published package.
+ [#661](https://github.com/gimli-rs/gimli/pull/661)
+
+### Added
+
+* Added `FallibleIterator` implementation for `read::OperationIter`.
+ [#649](https://github.com/gimli-rs/gimli/pull/649)
+
+* Added `DW_AT_GNU_deleted` constant.
+ [#658](https://github.com/gimli-rs/gimli/pull/658)
+
+--------------------------------------------------------------------------------
+
## 0.27.2
Released 2023/02/15.
@@ -546,7 +609,7 @@ and adding support for writing CFI.
### Fixed
-* The `code_alignment_factor` is now used when evaluting CFI instructions
+* The `code_alignment_factor` is now used when evaluating CFI instructions
that advance the location.
[#401](https://github.com/gimli-rs/gimli/pull/401)
diff --git a/vendor/gimli/CONTRIBUTING.md b/vendor/gimli/CONTRIBUTING.md
deleted file mode 100644
index 4f9e574ce..000000000
--- a/vendor/gimli/CONTRIBUTING.md
+++ /dev/null
@@ -1,137 +0,0 @@
-# Contributing to `gimli`
-
-Hi! We'd love to have your contributions! If you want help or mentorship, reach
-out to us in a GitHub issue, or ping `fitzgen` in `#rust` on `irc.mozilla.org`.
-
-* [Code of Conduct](#coc)
-* [Filing an Issue](#issues)
-* [Building `gimli`](#building)
-* [Testing `gimli`](#testing)
- * [Test Coverage](#coverage)
- * [Using `test-assembler`](#test-assembler)
- * [Fuzzing](#fuzzing)
-* [Benchmarking](#benchmarking)
-* [Style](#style)
-
-## <a id="coc"></a> Code of Conduct
-
-We abide by the
-[Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html) and ask
-that you do as well.
-
-## <a id="issues"></a> Filing an Issue
-
-Think you've found a bug? File an issue! To help us understand and reproduce the
-issue, provide us with:
-
-* The (preferably minimal) test case
-* Steps to reproduce the issue using the test case
-* The expected result of following those steps
-* The actual result of following those steps
-
-Definitely file an issue if you see an unexpected panic originating from within
-`gimli`! `gimli` should never panic unless it is explicitly documented to panic
-in the specific circumstances provided.
-
-## <a id="building"></a> Building `gimli`
-
-`gimli` should always build on stable `rustc`, but we recommend using
-[`rustup`](https://www.rustup.rs/) so you can switch to nightly `rustc` and run
-benchmarks.
-
-To build `gimli`:
-
-```
-$ cargo build
-```
-
-## <a id="testing"></a> Testing `gimli`
-
-Run the tests with `cargo`:
-
-```
-$ cargo test
-```
-
-### <a id="coverage"></a> Test Coverage
-
-If you have `kcov` installed under linux, then you can generate code coverage
-results using the `coverage` script in the root of the repository, and view them
-at `target/kcov/index.html`. Otherwise you can create a pull request and view
-the coverage results on coveralls.io.
-
-```
-$ ./coverage
-```
-
-The ideal we aim to reach is having our unit tests exercise every branch in
-`gimli`. We allow an exception for branches which propagate errors inside a
-`try!(..)` invocation, but we *do* want to exercise the original error paths.
-
-Pull requests adding new code should ensure that this ideal is met.
-
-At the time of writing we have 94% test coverage according to our coveralls.io
-continuous integration. That number should generally stay the same or go up ;)
-This is a bit subjective, because -.001% is just noise and doesn't matter.
-
-### <a id="test-assembler"></a> Using `test-assembler`
-
-We use the awesome
-[`test-assembler`](https://github.com/luser/rust-test-assembler) crate to
-construct binary test data. It makes building complex test cases readable.
-
-[Here is an example usage in `gimli`](https://github.com/gimli-rs/gimli/blob/156451f3fe6eeb2fa62b84b362c33fcb176e1171/src/loc.rs#L263)
-
-### <a id="fuzzing"></a> Fuzzing
-
-First, install `cargo fuzz`:
-
-```
-$ cargo install cargo-fuzz
-```
-
-Optionally, [set up the corpora for our fuzz targets by following these
-instructions](https://github.com/gimli-rs/gimli-libfuzzer-corpora/blob/master/README.md#using-these-corpora).
-
-Finally, run a fuzz target! In this case, we are running the `eh_frame` fuzz
-target:
-
-```
-$ cargo fuzz run eh_frame
-```
-
-The fuzz target definitions live in `fuzz/fuzz_targets/*`. You can add new ones
-via `cargo fuzz add <my_new_target>`.
-
-## <a id="benchmarking"></a> Benchmarking
-
-The benchmarks require nightly `rustc`, so use `rustup`:
-
-```
-$ rustup run nightly cargo bench
-```
-
-We aim to be the fastest DWARF library. Period.
-
-Please provide before and after benchmark results with your pull requests. You
-may also find [`cargo benchcmp`](https://github.com/BurntSushi/cargo-benchcmp)
-handy for comparing results.
-
-Pull requests adding `#[bench]` micro-benchmarks that exercise a new edge case
-are very welcome!
-
-## <a id="style"></a> Style
-
-We use `rustfmt` to automatically format and style all of our code.
-
-To install `rustfmt`:
-
-```
-$ rustup component add rustfmt-preview
-```
-
-To run `rustfmt` on `gimli`:
-
-```
-$ cargo fmt
-```
diff --git a/vendor/gimli/Cargo.lock b/vendor/gimli/Cargo.lock
deleted file mode 100644
index 566f1dd6c..000000000
--- a/vendor/gimli/Cargo.lock
+++ /dev/null
@@ -1,345 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "adler"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
-
-[[package]]
-name = "aho-corasick"
-version = "0.7.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "autocfg"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
-
-[[package]]
-name = "byteorder"
-version = "1.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-
-[[package]]
-name = "compiler_builtins"
-version = "0.1.86"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5dae98c88e576098d7ab13ebcb40cc43e5114b2beafe61a87cda9200649ff205"
-
-[[package]]
-name = "crc32fast"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "crossbeam"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c"
-dependencies = [
- "cfg-if",
- "crossbeam-channel",
- "crossbeam-deque",
- "crossbeam-epoch",
- "crossbeam-queue",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-channel"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-deque"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
-dependencies = [
- "cfg-if",
- "crossbeam-epoch",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-epoch"
-version = "0.9.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
-dependencies = [
- "autocfg",
- "cfg-if",
- "crossbeam-utils",
- "memoffset",
- "scopeguard",
-]
-
-[[package]]
-name = "crossbeam-queue"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "either"
-version = "1.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
-
-[[package]]
-name = "fallible-iterator"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
-
-[[package]]
-name = "flate2"
-version = "1.0.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
-dependencies = [
- "crc32fast",
- "miniz_oxide",
-]
-
-[[package]]
-name = "getopts"
-version = "0.2.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
-dependencies = [
- "unicode-width",
-]
-
-[[package]]
-name = "gimli"
-version = "0.27.2"
-dependencies = [
- "compiler_builtins",
- "crossbeam",
- "fallible-iterator",
- "getopts",
- "indexmap",
- "memmap2",
- "num_cpus",
- "object",
- "rayon",
- "regex",
- "rustc-std-workspace-alloc",
- "rustc-std-workspace-core",
- "stable_deref_trait",
- "test-assembler",
- "typed-arena",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-
-[[package]]
-name = "hermit-abi"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "indexmap"
-version = "1.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
-dependencies = [
- "autocfg",
- "hashbrown",
-]
-
-[[package]]
-name = "libc"
-version = "0.2.139"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
-
-[[package]]
-name = "memchr"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
-
-[[package]]
-name = "memmap2"
-version = "0.5.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "memoffset"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "miniz_oxide"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
-dependencies = [
- "adler",
-]
-
-[[package]]
-name = "num_cpus"
-version = "1.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
-dependencies = [
- "hermit-abi",
- "libc",
-]
-
-[[package]]
-name = "object"
-version = "0.30.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439"
-dependencies = [
- "flate2",
- "memchr",
- "wasmparser",
-]
-
-[[package]]
-name = "rayon"
-version = "1.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
-dependencies = [
- "either",
- "rayon-core",
-]
-
-[[package]]
-name = "rayon-core"
-version = "1.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b"
-dependencies = [
- "crossbeam-channel",
- "crossbeam-deque",
- "crossbeam-utils",
- "num_cpus",
-]
-
-[[package]]
-name = "regex"
-version = "1.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-syntax"
-version = "0.6.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
-
-[[package]]
-name = "rustc-std-workspace-alloc"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff66d57013a5686e1917ed6a025d54dd591fcda71a41fe07edf4d16726aefa86"
-
-[[package]]
-name = "rustc-std-workspace-core"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1956f5517128a2b6f23ab2dadf1a976f4f5b27962e7724c2bf3d45e539ec098c"
-
-[[package]]
-name = "scopeguard"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
-
-[[package]]
-name = "stable_deref_trait"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
-
-[[package]]
-name = "test-assembler"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a6da51de149453f5c43fa67d5e73cccd75b3c5727a38a2f18c5f3c47f2db582"
-dependencies = [
- "byteorder",
-]
-
-[[package]]
-name = "typed-arena"
-version = "2.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
-
-[[package]]
-name = "unicode-width"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
-
-[[package]]
-name = "wasmparser"
-version = "0.57.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32fddd575d477c6e9702484139cf9f23dcd554b06d185ed0f56c857dd3a47aa6"
diff --git a/vendor/gimli/Cargo.toml b/vendor/gimli/Cargo.toml
index f49444711..f7d9c9dc1 100644
--- a/vendor/gimli/Cargo.toml
+++ b/vendor/gimli/Cargo.toml
@@ -11,11 +11,16 @@
[package]
edition = "2018"
+rust-version = "1.60"
name = "gimli"
-version = "0.27.2"
-exclude = [
- "/releases/*",
- "/.github",
+version = "0.28.0"
+include = [
+ "/CHANGELOG.md",
+ "/Cargo.toml",
+ "/LICENSE-APACHE",
+ "/LICENSE-MIT",
+ "/README.md",
+ "/src",
]
description = "A library for reading and writing the DWARF debugging format."
documentation = "https://docs.rs/gimli"
@@ -33,6 +38,7 @@ categories = [
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/gimli-rs/gimli"
+resolver = "2"
[profile.bench]
codegen-units = 1
@@ -42,28 +48,6 @@ split-debuginfo = "packed"
[profile.test]
split-debuginfo = "packed"
-[[example]]
-name = "simple"
-required-features = ["read"]
-
-[[example]]
-name = "simple_line"
-required-features = ["read"]
-
-[[example]]
-name = "dwarfdump"
-required-features = [
- "read",
- "std",
-]
-
-[[example]]
-name = "dwarf-validate"
-required-features = [
- "read",
- "std",
-]
-
[dependencies.alloc]
version = "1.0.0"
optional = true
@@ -79,12 +63,12 @@ optional = true
package = "rustc-std-workspace-core"
[dependencies.fallible-iterator]
-version = "0.2.0"
+version = "0.3.0"
optional = true
default-features = false
[dependencies.indexmap]
-version = "1.0.2"
+version = "2.0.0"
optional = true
[dependencies.stable_deref_trait]
@@ -92,55 +76,34 @@ version = "1.1.0"
optional = true
default-features = false
-[dev-dependencies.crossbeam]
-version = "0.8"
-
-[dev-dependencies.getopts]
-version = "0.2"
-
-[dev-dependencies.memmap2]
-version = "0.5.5"
-
-[dev-dependencies.num_cpus]
-version = "1"
-
-[dev-dependencies.object]
-version = "0.30.0"
-features = ["wasm"]
-
-[dev-dependencies.rayon]
-version = "1.0"
-
-[dev-dependencies.regex]
-version = "1"
-
[dev-dependencies.test-assembler]
version = "0.1.3"
-[dev-dependencies.typed-arena]
-version = "2"
-
[features]
default = [
- "read",
+ "read-all",
"write",
- "std",
- "fallible-iterator",
- "endian-reader",
]
endian-reader = [
"read",
- "stable_deref_trait",
+ "dep:stable_deref_trait",
]
+fallible-iterator = ["dep:fallible-iterator"]
read = ["read-core"]
+read-all = [
+ "read",
+ "std",
+ "fallible-iterator",
+ "endian-reader",
+]
read-core = []
rustc-dep-of-std = [
- "core",
- "alloc",
- "compiler_builtins",
+ "dep:core",
+ "dep:alloc",
+ "dep:compiler_builtins",
]
std = [
- "fallible-iterator/std",
- "stable_deref_trait/std",
+ "fallible-iterator?/std",
+ "stable_deref_trait?/std",
]
-write = ["indexmap"]
+write = ["dep:indexmap"]
diff --git a/vendor/gimli/README.md b/vendor/gimli/README.md
index cc73daf4d..fa6467cbc 100644
--- a/vendor/gimli/README.md
+++ b/vendor/gimli/README.md
@@ -22,7 +22,7 @@
* Unsure which object file parser to use? Try the cross-platform
[`object`](https://github.com/gimli-rs/object) crate. See the
- [`examples/`](./examples) directory for usage with `gimli`.
+ [`gimli-examples`](./crates/examples/src/bin) crate for usage with `gimli`.
## Install
@@ -30,10 +30,13 @@ Add this to your `Cargo.toml`:
```toml
[dependencies]
-gimli = "0.27.2"
+gimli = "0.28.0"
```
-The minimum supported Rust version is 1.42.0.
+The minimum supported Rust version is:
+
+* 1.60.0 for the `read` feature and its dependencies.
+* 1.65.0 for other features.
## Documentation
@@ -41,11 +44,11 @@ The minimum supported Rust version is 1.42.0.
* Example programs:
- * [A simple `.debug_info` parser](./examples/simple.rs)
+ * [A simple `.debug_info` parser](./crates/examples/src/bin/simple.rs)
- * [A simple `.debug_line` parser](./examples/simple_line.rs)
+ * [A simple `.debug_line` parser](./crates/examples/src/bin/simple_line.rs)
- * [A `dwarfdump` clone](./examples/dwarfdump.rs)
+ * [A `dwarfdump` clone](./crates/examples/src/bin/dwarfdump.rs)
* [An `addr2line` clone](https://github.com/gimli-rs/addr2line)
@@ -56,7 +59,7 @@ The minimum supported Rust version is 1.42.0.
compilers used to create each compilation unit within a shared library or
executable (via `DW_AT_producer`).
- * [`dwarf-validate`](./examples/dwarf-validate.rs), a program to validate the
+ * [`dwarf-validate`](./crates/examples/src/bin/dwarf-validate.rs), a program to validate the
integrity of some DWARF and its references between sections and compilation
units.
diff --git a/vendor/gimli/benches/bench.rs b/vendor/gimli/benches/bench.rs
deleted file mode 100644
index fb29df77c..000000000
--- a/vendor/gimli/benches/bench.rs
+++ /dev/null
@@ -1,807 +0,0 @@
-#![feature(test)]
-
-extern crate test;
-
-use gimli::{
- AttributeValue, DebugAbbrev, DebugAddr, DebugAddrBase, DebugAranges, DebugInfo, DebugLine,
- DebugLineOffset, DebugLoc, DebugLocLists, DebugPubNames, DebugPubTypes, DebugRanges,
- DebugRngLists, Encoding, EndianSlice, EntriesTreeNode, Expression, LittleEndian, LocationLists,
- Operation, RangeLists, RangeListsOffset, Reader, ReaderOffset,
-};
-use std::env;
-use std::fs::File;
-use std::io::Read;
-use std::path::PathBuf;
-use std::rc::Rc;
-
-pub fn read_section(section: &str) -> Vec<u8> {
- let mut path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".into()));
- path.push("./fixtures/self/");
- path.push(section);
-
- assert!(path.is_file());
- let mut file = File::open(path).unwrap();
-
- let mut buf = Vec::new();
- file.read_to_end(&mut buf).unwrap();
- buf
-}
-
-#[bench]
-fn bench_parsing_debug_abbrev(b: &mut test::Bencher) {
- let debug_info = read_section("debug_info");
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
- let unit = debug_info
- .units()
- .next()
- .expect("Should have at least one compilation unit")
- .expect("And it should parse OK");
-
- let debug_abbrev = read_section("debug_abbrev");
-
- b.iter(|| {
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
- test::black_box(
- unit.abbreviations(&debug_abbrev)
- .expect("Should parse abbreviations"),
- );
- });
-}
-
-#[inline]
-fn impl_bench_parsing_debug_info<R: Reader>(
- debug_info: DebugInfo<R>,
- debug_abbrev: DebugAbbrev<R>,
-) {
- let mut iter = debug_info.units();
- while let Some(unit) = iter.next().expect("Should parse compilation unit") {
- let abbrevs = unit
- .abbreviations(&debug_abbrev)
- .expect("Should parse abbreviations");
-
- let mut cursor = unit.entries(&abbrevs);
- while let Some((_, entry)) = cursor.next_dfs().expect("Should parse next dfs") {
- let mut attrs = entry.attrs();
- loop {
- match attrs.next() {
- Ok(Some(ref attr)) => {
- test::black_box(attr);
- }
- Ok(None) => break,
- e @ Err(_) => {
- e.expect("Should parse entry's attribute");
- }
- }
- }
- }
- }
-}
-
-#[bench]
-fn bench_parsing_debug_info(b: &mut test::Bencher) {
- let debug_info = read_section("debug_info");
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- b.iter(|| impl_bench_parsing_debug_info(debug_info, debug_abbrev));
-}
-
-#[bench]
-fn bench_parsing_debug_info_with_endian_rc_slice(b: &mut test::Bencher) {
- let debug_info = read_section("debug_info");
- let debug_info = Rc::from(&debug_info[..]);
- let debug_info = gimli::EndianRcSlice::new(debug_info, LittleEndian);
- let debug_info = DebugInfo::from(debug_info);
-
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = Rc::from(&debug_abbrev[..]);
- let debug_abbrev = gimli::EndianRcSlice::new(debug_abbrev, LittleEndian);
- let debug_abbrev = DebugAbbrev::from(debug_abbrev);
-
- b.iter(|| impl_bench_parsing_debug_info(debug_info.clone(), debug_abbrev.clone()));
-}
-
-#[bench]
-fn bench_parsing_debug_info_tree(b: &mut test::Bencher) {
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- let debug_info = read_section("debug_info");
-
- b.iter(|| {
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let mut iter = debug_info.units();
- while let Some(unit) = iter.next().expect("Should parse compilation unit") {
- let abbrevs = unit
- .abbreviations(&debug_abbrev)
- .expect("Should parse abbreviations");
-
- let mut tree = unit
- .entries_tree(&abbrevs, None)
- .expect("Should have entries tree");
- let root = tree.root().expect("Should parse root entry");
- parse_debug_info_tree(root);
- }
- });
-}
-
-fn parse_debug_info_tree<R: Reader>(node: EntriesTreeNode<R>) {
- {
- let mut attrs = node.entry().attrs();
- loop {
- match attrs.next() {
- Ok(Some(ref attr)) => {
- test::black_box(attr);
- }
- Ok(None) => break,
- e @ Err(_) => {
- e.expect("Should parse entry's attribute");
- }
- }
- }
- }
- let mut children = node.children();
- while let Some(child) = children.next().expect("Should parse child entry") {
- parse_debug_info_tree(child);
- }
-}
-
-#[bench]
-fn bench_parsing_debug_info_raw(b: &mut test::Bencher) {
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- let debug_info = read_section("debug_info");
-
- b.iter(|| {
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let mut iter = debug_info.units();
- while let Some(unit) = iter.next().expect("Should parse compilation unit") {
- let abbrevs = unit
- .abbreviations(&debug_abbrev)
- .expect("Should parse abbreviations");
-
- let mut raw = unit
- .entries_raw(&abbrevs, None)
- .expect("Should have entries");
- while !raw.is_empty() {
- if let Some(abbrev) = raw
- .read_abbreviation()
- .expect("Should parse abbreviation code")
- {
- for spec in abbrev.attributes().iter().cloned() {
- match raw.read_attribute(spec) {
- Ok(ref attr) => {
- test::black_box(attr);
- }
- e @ Err(_) => {
- e.expect("Should parse attribute");
- }
- }
- }
- }
- }
- }
- });
-}
-
-#[bench]
-fn bench_parsing_debug_aranges(b: &mut test::Bencher) {
- let debug_aranges = read_section("debug_aranges");
- let debug_aranges = DebugAranges::new(&debug_aranges, LittleEndian);
-
- b.iter(|| {
- let mut headers = debug_aranges.headers();
- while let Some(header) = headers.next().expect("Should parse arange header OK") {
- let mut entries = header.entries();
- while let Some(arange) = entries.next().expect("Should parse arange entry OK") {
- test::black_box(arange);
- }
- }
- });
-}
-
-#[bench]
-fn bench_parsing_debug_pubnames(b: &mut test::Bencher) {
- let debug_pubnames = read_section("debug_pubnames");
- let debug_pubnames = DebugPubNames::new(&debug_pubnames, LittleEndian);
-
- b.iter(|| {
- let mut pubnames = debug_pubnames.items();
- while let Some(pubname) = pubnames.next().expect("Should parse pubname OK") {
- test::black_box(pubname);
- }
- });
-}
-
-#[bench]
-fn bench_parsing_debug_pubtypes(b: &mut test::Bencher) {
- let debug_pubtypes = read_section("debug_pubtypes");
- let debug_pubtypes = DebugPubTypes::new(&debug_pubtypes, LittleEndian);
-
- b.iter(|| {
- let mut pubtypes = debug_pubtypes.items();
- while let Some(pubtype) = pubtypes.next().expect("Should parse pubtype OK") {
- test::black_box(pubtype);
- }
- });
-}
-
-// We happen to know that there is a line number program and header at
-// offset 0 and that address size is 8 bytes. No need to parse DIEs to grab
-// this info off of the compilation units.
-const OFFSET: DebugLineOffset = DebugLineOffset(0);
-const ADDRESS_SIZE: u8 = 8;
-
-#[bench]
-fn bench_parsing_line_number_program_opcodes(b: &mut test::Bencher) {
- let debug_line = read_section("debug_line");
- let debug_line = DebugLine::new(&debug_line, LittleEndian);
-
- b.iter(|| {
- let program = debug_line
- .program(OFFSET, ADDRESS_SIZE, None, None)
- .expect("Should parse line number program header");
- let header = program.header();
-
- let mut instructions = header.instructions();
- while let Some(instruction) = instructions
- .next_instruction(header)
- .expect("Should parse instruction")
- {
- test::black_box(instruction);
- }
- });
-}
-
-#[bench]
-fn bench_executing_line_number_programs(b: &mut test::Bencher) {
- let debug_line = read_section("debug_line");
- let debug_line = DebugLine::new(&debug_line, LittleEndian);
-
- b.iter(|| {
- let program = debug_line
- .program(OFFSET, ADDRESS_SIZE, None, None)
- .expect("Should parse line number program header");
-
- let mut rows = program.rows();
- while let Some(row) = rows
- .next_row()
- .expect("Should parse and execute all rows in the line number program")
- {
- test::black_box(row);
- }
- });
-}
-
-#[bench]
-fn bench_parsing_debug_loc(b: &mut test::Bencher) {
- let debug_info = read_section("debug_info");
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- let debug_addr = DebugAddr::from(EndianSlice::new(&[], LittleEndian));
- let debug_addr_base = DebugAddrBase(0);
-
- let debug_loc = read_section("debug_loc");
- let debug_loc = DebugLoc::new(&debug_loc, LittleEndian);
- let debug_loclists = DebugLocLists::new(&[], LittleEndian);
- let loclists = LocationLists::new(debug_loc, debug_loclists);
-
- let mut offsets = Vec::new();
-
- let mut iter = debug_info.units();
- while let Some(unit) = iter.next().expect("Should parse compilation unit") {
- let abbrevs = unit
- .abbreviations(&debug_abbrev)
- .expect("Should parse abbreviations");
-
- let mut cursor = unit.entries(&abbrevs);
- cursor.next_dfs().expect("Should parse next dfs");
-
- let mut low_pc = 0;
-
- {
- let unit_entry = cursor.current().expect("Should have a root entry");
- let low_pc_attr = unit_entry
- .attr_value(gimli::DW_AT_low_pc)
- .expect("Should parse low_pc");
- if let Some(gimli::AttributeValue::Addr(address)) = low_pc_attr {
- low_pc = address;
- }
- }
-
- while cursor.next_dfs().expect("Should parse next dfs").is_some() {
- let entry = cursor.current().expect("Should have a current entry");
- let mut attrs = entry.attrs();
- while let Some(attr) = attrs.next().expect("Should parse entry's attribute") {
- if let gimli::AttributeValue::LocationListsRef(offset) = attr.value() {
- offsets.push((offset, unit.encoding(), low_pc));
- }
- }
- }
- }
-
- b.iter(|| {
- for &(offset, encoding, base_address) in &*offsets {
- let mut locs = loclists
- .locations(offset, encoding, base_address, &debug_addr, debug_addr_base)
- .expect("Should parse locations OK");
- while let Some(loc) = locs.next().expect("Should parse next location") {
- test::black_box(loc);
- }
- }
- });
-}
-
-#[bench]
-fn bench_parsing_debug_ranges(b: &mut test::Bencher) {
- let debug_info = read_section("debug_info");
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- let debug_addr = DebugAddr::from(EndianSlice::new(&[], LittleEndian));
- let debug_addr_base = DebugAddrBase(0);
-
- let debug_ranges = read_section("debug_ranges");
- let debug_ranges = DebugRanges::new(&debug_ranges, LittleEndian);
- let debug_rnglists = DebugRngLists::new(&[], LittleEndian);
- let rnglists = RangeLists::new(debug_ranges, debug_rnglists);
-
- let mut offsets = Vec::new();
-
- let mut iter = debug_info.units();
- while let Some(unit) = iter.next().expect("Should parse compilation unit") {
- let abbrevs = unit
- .abbreviations(&debug_abbrev)
- .expect("Should parse abbreviations");
-
- let mut cursor = unit.entries(&abbrevs);
- cursor.next_dfs().expect("Should parse next dfs");
-
- let mut low_pc = 0;
-
- {
- let unit_entry = cursor.current().expect("Should have a root entry");
- let low_pc_attr = unit_entry
- .attr_value(gimli::DW_AT_low_pc)
- .expect("Should parse low_pc");
- if let Some(gimli::AttributeValue::Addr(address)) = low_pc_attr {
- low_pc = address;
- }
- }
-
- while cursor.next_dfs().expect("Should parse next dfs").is_some() {
- let entry = cursor.current().expect("Should have a current entry");
- let mut attrs = entry.attrs();
- while let Some(attr) = attrs.next().expect("Should parse entry's attribute") {
- if let gimli::AttributeValue::RangeListsRef(offset) = attr.value() {
- offsets.push((RangeListsOffset(offset.0), unit.encoding(), low_pc));
- }
- }
- }
- }
-
- b.iter(|| {
- for &(offset, encoding, base_address) in &*offsets {
- let mut ranges = rnglists
- .ranges(offset, encoding, base_address, &debug_addr, debug_addr_base)
- .expect("Should parse ranges OK");
- while let Some(range) = ranges.next().expect("Should parse next range") {
- test::black_box(range);
- }
- }
- });
-}
-
-fn debug_info_expressions<R: Reader>(
- debug_info: &DebugInfo<R>,
- debug_abbrev: &DebugAbbrev<R>,
-) -> Vec<(Expression<R>, Encoding)> {
- let mut expressions = Vec::new();
-
- let mut iter = debug_info.units();
- while let Some(unit) = iter.next().expect("Should parse compilation unit") {
- let abbrevs = unit
- .abbreviations(debug_abbrev)
- .expect("Should parse abbreviations");
-
- let mut cursor = unit.entries(&abbrevs);
- while let Some((_, entry)) = cursor.next_dfs().expect("Should parse next dfs") {
- let mut attrs = entry.attrs();
- while let Some(attr) = attrs.next().expect("Should parse entry's attribute") {
- if let AttributeValue::Exprloc(expression) = attr.value() {
- expressions.push((expression, unit.encoding()));
- }
- }
- }
- }
-
- expressions
-}
-
-#[bench]
-fn bench_parsing_debug_info_expressions(b: &mut test::Bencher) {
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- let debug_info = read_section("debug_info");
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let expressions = debug_info_expressions(&debug_info, &debug_abbrev);
-
- b.iter(|| {
- for &(expression, encoding) in &*expressions {
- let mut pc = expression.0;
- while !pc.is_empty() {
- Operation::parse(&mut pc, encoding).expect("Should parse operation");
- }
- }
- });
-}
-
-#[bench]
-fn bench_evaluating_debug_info_expressions(b: &mut test::Bencher) {
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- let debug_info = read_section("debug_info");
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let expressions = debug_info_expressions(&debug_info, &debug_abbrev);
-
- b.iter(|| {
- for &(expression, encoding) in &*expressions {
- let mut eval = expression.evaluation(encoding);
- eval.set_initial_value(0);
- let result = eval.evaluate().expect("Should evaluate expression");
- test::black_box(result);
- }
- });
-}
-
-fn debug_loc_expressions<R: Reader>(
- debug_info: &DebugInfo<R>,
- debug_abbrev: &DebugAbbrev<R>,
- debug_addr: &DebugAddr<R>,
- loclists: &LocationLists<R>,
-) -> Vec<(Expression<R>, Encoding)> {
- let debug_addr_base = DebugAddrBase(R::Offset::from_u8(0));
-
- let mut expressions = Vec::new();
-
- let mut iter = debug_info.units();
- while let Some(unit) = iter.next().expect("Should parse compilation unit") {
- let abbrevs = unit
- .abbreviations(debug_abbrev)
- .expect("Should parse abbreviations");
-
- let mut cursor = unit.entries(&abbrevs);
- cursor.next_dfs().expect("Should parse next dfs");
-
- let mut low_pc = 0;
-
- {
- let unit_entry = cursor.current().expect("Should have a root entry");
- let low_pc_attr = unit_entry
- .attr_value(gimli::DW_AT_low_pc)
- .expect("Should parse low_pc");
- if let Some(gimli::AttributeValue::Addr(address)) = low_pc_attr {
- low_pc = address;
- }
- }
-
- while cursor.next_dfs().expect("Should parse next dfs").is_some() {
- let entry = cursor.current().expect("Should have a current entry");
- let mut attrs = entry.attrs();
- while let Some(attr) = attrs.next().expect("Should parse entry's attribute") {
- if let gimli::AttributeValue::LocationListsRef(offset) = attr.value() {
- let mut locs = loclists
- .locations(offset, unit.encoding(), low_pc, debug_addr, debug_addr_base)
- .expect("Should parse locations OK");
- while let Some(loc) = locs.next().expect("Should parse next location") {
- expressions.push((loc.data, unit.encoding()));
- }
- }
- }
- }
- }
-
- expressions
-}
-
-#[bench]
-fn bench_parsing_debug_loc_expressions(b: &mut test::Bencher) {
- let debug_info = read_section("debug_info");
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- let debug_addr = DebugAddr::from(EndianSlice::new(&[], LittleEndian));
-
- let debug_loc = read_section("debug_loc");
- let debug_loc = DebugLoc::new(&debug_loc, LittleEndian);
- let debug_loclists = DebugLocLists::new(&[], LittleEndian);
- let loclists = LocationLists::new(debug_loc, debug_loclists);
-
- let expressions = debug_loc_expressions(&debug_info, &debug_abbrev, &debug_addr, &loclists);
-
- b.iter(|| {
- for &(expression, encoding) in &*expressions {
- let mut pc = expression.0;
- while !pc.is_empty() {
- Operation::parse(&mut pc, encoding).expect("Should parse operation");
- }
- }
- });
-}
-
-#[bench]
-fn bench_evaluating_debug_loc_expressions(b: &mut test::Bencher) {
- let debug_info = read_section("debug_info");
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- let debug_addr = DebugAddr::from(EndianSlice::new(&[], LittleEndian));
-
- let debug_loc = read_section("debug_loc");
- let debug_loc = DebugLoc::new(&debug_loc, LittleEndian);
- let debug_loclists = DebugLocLists::new(&[], LittleEndian);
- let loclists = LocationLists::new(debug_loc, debug_loclists);
-
- let expressions = debug_loc_expressions(&debug_info, &debug_abbrev, &debug_addr, &loclists);
-
- b.iter(|| {
- for &(expression, encoding) in &*expressions {
- let mut eval = expression.evaluation(encoding);
- eval.set_initial_value(0);
- let result = eval.evaluate().expect("Should evaluate expression");
- test::black_box(result);
- }
- });
-}
-
-// See comment above `test_parse_self_eh_frame`.
-#[cfg(target_pointer_width = "64")]
-mod cfi {
- use super::*;
- use fallible_iterator::FallibleIterator;
-
- use gimli::{
- BaseAddresses, CieOrFde, EhFrame, FrameDescriptionEntry, LittleEndian, UnwindContext,
- UnwindSection,
- };
-
- #[bench]
- fn iterate_entries_and_do_not_parse_any_fde(b: &mut test::Bencher) {
- let eh_frame = read_section("eh_frame");
- let eh_frame = EhFrame::new(&eh_frame, LittleEndian);
-
- let bases = BaseAddresses::default()
- .set_eh_frame(0)
- .set_got(0)
- .set_text(0);
-
- b.iter(|| {
- let mut entries = eh_frame.entries(&bases);
- while let Some(entry) = entries.next().expect("Should parse CFI entry OK") {
- test::black_box(entry);
- }
- });
- }
-
- #[bench]
- fn iterate_entries_and_parse_every_fde(b: &mut test::Bencher) {
- let eh_frame = read_section("eh_frame");
- let eh_frame = EhFrame::new(&eh_frame, LittleEndian);
-
- let bases = BaseAddresses::default()
- .set_eh_frame(0)
- .set_got(0)
- .set_text(0);
-
- b.iter(|| {
- let mut entries = eh_frame.entries(&bases);
- while let Some(entry) = entries.next().expect("Should parse CFI entry OK") {
- match entry {
- CieOrFde::Cie(cie) => {
- test::black_box(cie);
- }
- CieOrFde::Fde(partial) => {
- let fde = partial
- .parse(EhFrame::cie_from_offset)
- .expect("Should be able to get CIE for FED");
- test::black_box(fde);
- }
- };
- }
- });
- }
-
- #[bench]
- fn iterate_entries_and_parse_every_fde_and_instructions(b: &mut test::Bencher) {
- let eh_frame = read_section("eh_frame");
- let eh_frame = EhFrame::new(&eh_frame, LittleEndian);
-
- let bases = BaseAddresses::default()
- .set_eh_frame(0)
- .set_got(0)
- .set_text(0);
-
- b.iter(|| {
- let mut entries = eh_frame.entries(&bases);
- while let Some(entry) = entries.next().expect("Should parse CFI entry OK") {
- match entry {
- CieOrFde::Cie(cie) => {
- let mut instrs = cie.instructions(&eh_frame, &bases);
- while let Some(i) =
- instrs.next().expect("Can parse next CFI instruction OK")
- {
- test::black_box(i);
- }
- }
- CieOrFde::Fde(partial) => {
- let fde = partial
- .parse(EhFrame::cie_from_offset)
- .expect("Should be able to get CIE for FED");
- let mut instrs = fde.instructions(&eh_frame, &bases);
- while let Some(i) =
- instrs.next().expect("Can parse next CFI instruction OK")
- {
- test::black_box(i);
- }
- }
- };
- }
- });
- }
-
- #[bench]
- fn iterate_entries_evaluate_every_fde(b: &mut test::Bencher) {
- let eh_frame = read_section("eh_frame");
- let eh_frame = EhFrame::new(&eh_frame, LittleEndian);
-
- let bases = BaseAddresses::default()
- .set_eh_frame(0)
- .set_got(0)
- .set_text(0);
-
- let mut ctx = Box::new(UnwindContext::new());
-
- b.iter(|| {
- let mut entries = eh_frame.entries(&bases);
- while let Some(entry) = entries.next().expect("Should parse CFI entry OK") {
- match entry {
- CieOrFde::Cie(_) => {}
- CieOrFde::Fde(partial) => {
- let fde = partial
- .parse(EhFrame::cie_from_offset)
- .expect("Should be able to get CIE for FED");
- let mut table = fde
- .rows(&eh_frame, &bases, &mut ctx)
- .expect("Should be able to initialize ctx");
- while let Some(row) =
- table.next_row().expect("Should get next unwind table row")
- {
- test::black_box(row);
- }
- }
- };
- }
- });
- }
-
- fn instrs_len<R: Reader>(
- eh_frame: &EhFrame<R>,
- bases: &BaseAddresses,
- fde: &FrameDescriptionEntry<R>,
- ) -> usize {
- fde.instructions(eh_frame, bases)
- .fold(0, |count, _| Ok(count + 1))
- .expect("fold over instructions OK")
- }
-
- fn get_fde_with_longest_cfi_instructions<R: Reader>(
- eh_frame: &EhFrame<R>,
- bases: &BaseAddresses,
- ) -> FrameDescriptionEntry<R> {
- let mut longest: Option<(usize, FrameDescriptionEntry<_>)> = None;
-
- let mut entries = eh_frame.entries(bases);
- while let Some(entry) = entries.next().expect("Should parse CFI entry OK") {
- match entry {
- CieOrFde::Cie(_) => {}
- CieOrFde::Fde(partial) => {
- let fde = partial
- .parse(EhFrame::cie_from_offset)
- .expect("Should be able to get CIE for FED");
-
- let this_len = instrs_len(eh_frame, bases, &fde);
-
- let found_new_longest = match longest {
- None => true,
- Some((longest_len, ref _fde)) => this_len > longest_len,
- };
-
- if found_new_longest {
- longest = Some((this_len, fde));
- }
- }
- };
- }
-
- longest.expect("At least one FDE in .eh_frame").1
- }
-
- #[bench]
- fn parse_longest_fde_instructions(b: &mut test::Bencher) {
- let eh_frame = read_section("eh_frame");
- let eh_frame = EhFrame::new(&eh_frame, LittleEndian);
- let bases = BaseAddresses::default()
- .set_eh_frame(0)
- .set_got(0)
- .set_text(0);
- let fde = get_fde_with_longest_cfi_instructions(&eh_frame, &bases);
-
- b.iter(|| {
- let mut instrs = fde.instructions(&eh_frame, &bases);
- while let Some(i) = instrs.next().expect("Should parse instruction OK") {
- test::black_box(i);
- }
- });
- }
-
- #[bench]
- fn eval_longest_fde_instructions_new_ctx_everytime(b: &mut test::Bencher) {
- let eh_frame = read_section("eh_frame");
- let eh_frame = EhFrame::new(&eh_frame, LittleEndian);
- let bases = BaseAddresses::default()
- .set_eh_frame(0)
- .set_got(0)
- .set_text(0);
- let fde = get_fde_with_longest_cfi_instructions(&eh_frame, &bases);
-
- b.iter(|| {
- let mut ctx = Box::new(UnwindContext::new());
- let mut table = fde
- .rows(&eh_frame, &bases, &mut ctx)
- .expect("Should initialize the ctx OK");
- while let Some(row) = table.next_row().expect("Should get next unwind table row") {
- test::black_box(row);
- }
- });
- }
-
- #[bench]
- fn eval_longest_fde_instructions_same_ctx(b: &mut test::Bencher) {
- let eh_frame = read_section("eh_frame");
- let eh_frame = EhFrame::new(&eh_frame, LittleEndian);
- let bases = BaseAddresses::default()
- .set_eh_frame(0)
- .set_got(0)
- .set_text(0);
- let fde = get_fde_with_longest_cfi_instructions(&eh_frame, &bases);
-
- let mut ctx = Box::new(UnwindContext::new());
-
- b.iter(|| {
- let mut table = fde
- .rows(&eh_frame, &bases, &mut ctx)
- .expect("Should initialize the ctx OK");
- while let Some(row) = table.next_row().expect("Should get next unwind table row") {
- test::black_box(row);
- }
- });
- }
-}
diff --git a/vendor/gimli/clippy.toml b/vendor/gimli/clippy.toml
deleted file mode 100644
index f97e544b6..000000000
--- a/vendor/gimli/clippy.toml
+++ /dev/null
@@ -1 +0,0 @@
-msrv = "1.42.0"
diff --git a/vendor/gimli/examples/dwarf-validate.rs b/vendor/gimli/examples/dwarf-validate.rs
deleted file mode 100644
index 54d8f3a1d..000000000
--- a/vendor/gimli/examples/dwarf-validate.rs
+++ /dev/null
@@ -1,267 +0,0 @@
-// Allow clippy lints when building without clippy.
-#![allow(unknown_lints)]
-
-use gimli::{AttributeValue, UnitHeader};
-use object::{Object, ObjectSection};
-use rayon::prelude::*;
-use std::borrow::{Borrow, Cow};
-use std::env;
-use std::fs;
-use std::io::{self, BufWriter, Write};
-use std::iter::Iterator;
-use std::path::{Path, PathBuf};
-use std::process;
-use std::sync::Mutex;
-use typed_arena::Arena;
-
-trait Reader: gimli::Reader<Offset = usize> + Send + Sync {
- type SyncSendEndian: gimli::Endianity + Send + Sync;
-}
-
-impl<'input, Endian> Reader for gimli::EndianSlice<'input, Endian>
-where
- Endian: gimli::Endianity + Send + Sync,
-{
- type SyncSendEndian = Endian;
-}
-
-struct ErrorWriter<W: Write + Send> {
- inner: Mutex<(W, usize)>,
- path: PathBuf,
-}
-
-impl<W: Write + Send> ErrorWriter<W> {
- #[allow(clippy::needless_pass_by_value)]
- fn error(&self, s: String) {
- let mut lock = self.inner.lock().unwrap();
- writeln!(&mut lock.0, "DWARF error in {}: {}", self.path.display(), s).unwrap();
- lock.1 += 1;
- }
-}
-
-fn main() {
- let mut w = BufWriter::new(io::stdout());
- let mut errors = 0;
- for arg in env::args_os().skip(1) {
- let path = Path::new(&arg);
- let file = match fs::File::open(&path) {
- Ok(file) => file,
- Err(err) => {
- eprintln!("Failed to open file '{}': {}", path.display(), err);
- errors += 1;
- continue;
- }
- };
- let file = match unsafe { memmap2::Mmap::map(&file) } {
- Ok(mmap) => mmap,
- Err(err) => {
- eprintln!("Failed to map file '{}': {}", path.display(), &err);
- errors += 1;
- continue;
- }
- };
- let file = match object::File::parse(&*file) {
- Ok(file) => file,
- Err(err) => {
- eprintln!("Failed to parse file '{}': {}", path.display(), err);
- errors += 1;
- continue;
- }
- };
-
- let endian = if file.is_little_endian() {
- gimli::RunTimeEndian::Little
- } else {
- gimli::RunTimeEndian::Big
- };
- let mut error_writer = ErrorWriter {
- inner: Mutex::new((&mut w, 0)),
- path: path.to_owned(),
- };
- validate_file(&mut error_writer, &file, endian);
- errors += error_writer.inner.into_inner().unwrap().1;
- }
- // Flush any errors.
- drop(w);
- if errors > 0 {
- process::exit(1);
- }
-}
-
-fn validate_file<W, Endian>(w: &mut ErrorWriter<W>, file: &object::File, endian: Endian)
-where
- W: Write + Send,
- Endian: gimli::Endianity + Send + Sync,
-{
- let arena = Arena::new();
-
- fn load_section<'a, 'file, 'input, S, Endian>(
- arena: &'a Arena<Cow<'file, [u8]>>,
- file: &'file object::File<'input>,
- endian: Endian,
- ) -> S
- where
- S: gimli::Section<gimli::EndianSlice<'a, Endian>>,
- Endian: gimli::Endianity + Send + Sync,
- 'file: 'input,
- 'a: 'file,
- {
- let data = match file.section_by_name(S::section_name()) {
- Some(ref section) => section
- .uncompressed_data()
- .unwrap_or(Cow::Borrowed(&[][..])),
- None => Cow::Borrowed(&[][..]),
- };
- let data_ref = (*arena.alloc(data)).borrow();
- S::from(gimli::EndianSlice::new(data_ref, endian))
- }
-
- // Variables representing sections of the file. The type of each is inferred from its use in the
- // validate_info function below.
- let debug_abbrev = &load_section(&arena, file, endian);
- let debug_info = &load_section(&arena, file, endian);
-
- validate_info(w, debug_info, debug_abbrev);
-}
-
-struct UnitSummary {
- // True if we successfully parsed all the DIEs and attributes in the compilation unit
- internally_valid: bool,
- offset: gimli::DebugInfoOffset,
- die_offsets: Vec<gimli::UnitOffset>,
- global_die_references: Vec<(gimli::UnitOffset, gimli::DebugInfoOffset)>,
-}
-
-fn validate_info<W, R>(
- w: &mut ErrorWriter<W>,
- debug_info: &gimli::DebugInfo<R>,
- debug_abbrev: &gimli::DebugAbbrev<R>,
-) where
- W: Write + Send,
- R: Reader,
-{
- let mut units = Vec::new();
- let mut units_iter = debug_info.units();
- let mut last_offset = 0;
- loop {
- let u = match units_iter.next() {
- Err(err) => {
- w.error(format!(
- "Can't read unit header at offset {:#x}, stopping reading units: {}",
- last_offset, err
- ));
- break;
- }
- Ok(None) => break,
- Ok(Some(u)) => u,
- };
- last_offset = u.offset().as_debug_info_offset().unwrap().0 + u.length_including_self();
- units.push(u);
- }
- let process_unit = |unit: UnitHeader<R>| -> UnitSummary {
- let unit_offset = unit.offset().as_debug_info_offset().unwrap();
- let mut ret = UnitSummary {
- internally_valid: false,
- offset: unit_offset,
- die_offsets: Vec::new(),
- global_die_references: Vec::new(),
- };
- let abbrevs = match unit.abbreviations(debug_abbrev) {
- Ok(abbrevs) => abbrevs,
- Err(err) => {
- w.error(format!(
- "Invalid abbrevs for unit {:#x}: {}",
- unit_offset.0, &err
- ));
- return ret;
- }
- };
- let mut entries = unit.entries(&abbrevs);
- let mut unit_refs = Vec::new();
- loop {
- let (_, entry) = match entries.next_dfs() {
- Err(err) => {
- w.error(format!(
- "Invalid DIE for unit {:#x}: {}",
- unit_offset.0, &err
- ));
- return ret;
- }
- Ok(None) => break,
- Ok(Some(entry)) => entry,
- };
- ret.die_offsets.push(entry.offset());
-
- let mut attrs = entry.attrs();
- loop {
- let attr = match attrs.next() {
- Err(err) => {
- w.error(format!(
- "Invalid attribute for unit {:#x} at DIE {:#x}: {}",
- unit_offset.0,
- entry.offset().0,
- &err
- ));
- return ret;
- }
- Ok(None) => break,
- Ok(Some(attr)) => attr,
- };
- match attr.value() {
- AttributeValue::UnitRef(offset) => {
- unit_refs.push((entry.offset(), offset));
- }
- AttributeValue::DebugInfoRef(offset) => {
- ret.global_die_references.push((entry.offset(), offset));
- }
- _ => (),
- }
- }
- }
- ret.internally_valid = true;
- ret.die_offsets.shrink_to_fit();
- ret.global_die_references.shrink_to_fit();
-
- // Check intra-unit references
- for (from, to) in unit_refs {
- if ret.die_offsets.binary_search(&to).is_err() {
- w.error(format!(
- "Invalid intra-unit reference in unit {:#x} from DIE {:#x} to {:#x}",
- unit_offset.0, from.0, to.0
- ));
- }
- }
-
- ret
- };
- let processed_units = units.into_par_iter().map(process_unit).collect::<Vec<_>>();
-
- let check_unit = |summary: &UnitSummary| {
- if !summary.internally_valid {
- return;
- }
- for &(from, to) in summary.global_die_references.iter() {
- let u = match processed_units.binary_search_by_key(&to, |v| v.offset) {
- Ok(i) => &processed_units[i],
- Err(i) => {
- if i > 0 {
- &processed_units[i - 1]
- } else {
- w.error(format!("Invalid cross-unit reference in unit {:#x} from DIE {:#x} to global DIE {:#x}: no unit found",
- summary.offset.0, from.0, to.0));
- continue;
- }
- }
- };
- if !u.internally_valid {
- continue;
- }
- let to_offset = gimli::UnitOffset(to.0 - u.offset.0);
- if u.die_offsets.binary_search(&to_offset).is_err() {
- w.error(format!("Invalid cross-unit reference in unit {:#x} from DIE {:#x} to global DIE {:#x}: unit at {:#x} contains no DIE {:#x}",
- summary.offset.0, from.0, to.0, u.offset.0, to_offset.0));
- }
- }
- };
- processed_units.par_iter().for_each(check_unit);
-}
diff --git a/vendor/gimli/examples/dwarfdump.rs b/vendor/gimli/examples/dwarfdump.rs
deleted file mode 100644
index a11f298f8..000000000
--- a/vendor/gimli/examples/dwarfdump.rs
+++ /dev/null
@@ -1,2369 +0,0 @@
-// Allow clippy lints when building without clippy.
-#![allow(unknown_lints)]
-
-use fallible_iterator::FallibleIterator;
-use gimli::{Section, UnitHeader, UnitOffset, UnitSectionOffset, UnitType, UnwindSection};
-use object::{Object, ObjectSection, ObjectSymbol};
-use regex::bytes::Regex;
-use std::borrow::{Borrow, Cow};
-use std::cmp::min;
-use std::collections::HashMap;
-use std::env;
-use std::fmt::{self, Debug};
-use std::fs;
-use std::io;
-use std::io::{BufWriter, Write};
-use std::iter::Iterator;
-use std::mem;
-use std::process;
-use std::result;
-use std::sync::{Condvar, Mutex};
-use typed_arena::Arena;
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum Error {
- GimliError(gimli::Error),
- ObjectError(object::read::Error),
- IoError,
-}
-
-impl fmt::Display for Error {
- #[inline]
- fn fmt(&self, f: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> {
- Debug::fmt(self, f)
- }
-}
-
-fn writeln_error<W: Write, R: Reader>(
- w: &mut W,
- dwarf: &gimli::Dwarf<R>,
- err: Error,
- msg: &str,
-) -> io::Result<()> {
- writeln!(
- w,
- "{}: {}",
- msg,
- match err {
- Error::GimliError(err) => dwarf.format_error(err),
- Error::ObjectError(err) =>
- format!("{}:{:?}", "An object error occurred while reading", err),
- Error::IoError => "An I/O error occurred while writing.".to_string(),
- }
- )
-}
-
-impl From<gimli::Error> for Error {
- fn from(err: gimli::Error) -> Self {
- Error::GimliError(err)
- }
-}
-
-impl From<io::Error> for Error {
- fn from(_: io::Error) -> Self {
- Error::IoError
- }
-}
-
-impl From<object::read::Error> for Error {
- fn from(err: object::read::Error) -> Self {
- Error::ObjectError(err)
- }
-}
-
-pub type Result<T> = result::Result<T, Error>;
-
-fn parallel_output<W, II, F>(w: &mut W, max_workers: usize, iter: II, f: F) -> Result<()>
-where
- W: Write + Send,
- F: Sync + Fn(II::Item, &mut Vec<u8>) -> Result<()>,
- II: IntoIterator,
- II::IntoIter: Send,
-{
- struct ParallelOutputState<I, W> {
- iterator: I,
- current_worker: usize,
- result: Result<()>,
- w: W,
- }
-
- let state = Mutex::new(ParallelOutputState {
- iterator: iter.into_iter().fuse(),
- current_worker: 0,
- result: Ok(()),
- w,
- });
- let workers = min(max_workers, num_cpus::get());
- let mut condvars = Vec::new();
- for _ in 0..workers {
- condvars.push(Condvar::new());
- }
- {
- let state_ref = &state;
- let f_ref = &f;
- let condvars_ref = &condvars;
- crossbeam::scope(|scope| {
- for i in 0..workers {
- scope.spawn(move |_| {
- let mut v = Vec::new();
- let mut lock = state_ref.lock().unwrap();
- while lock.current_worker != i {
- lock = condvars_ref[i].wait(lock).unwrap();
- }
- loop {
- let item = if lock.result.is_ok() {
- lock.iterator.next()
- } else {
- None
- };
- lock.current_worker = (i + 1) % workers;
- condvars_ref[lock.current_worker].notify_one();
- mem::drop(lock);
-
- let ret = if let Some(item) = item {
- v.clear();
- f_ref(item, &mut v)
- } else {
- return;
- };
-
- lock = state_ref.lock().unwrap();
- while lock.current_worker != i {
- lock = condvars_ref[i].wait(lock).unwrap();
- }
- if lock.result.is_ok() {
- let ret2 = lock.w.write_all(&v);
- if ret.is_err() {
- lock.result = ret;
- } else {
- lock.result = ret2.map_err(Error::from);
- }
- }
- }
- });
- }
- })
- .unwrap();
- }
- state.into_inner().unwrap().result
-}
-
-trait Reader: gimli::Reader<Offset = usize> + Send + Sync {}
-
-impl<'input, Endian> Reader for gimli::EndianSlice<'input, Endian> where
- Endian: gimli::Endianity + Send + Sync
-{
-}
-
-type RelocationMap = HashMap<usize, object::Relocation>;
-
-fn add_relocations(
- relocations: &mut RelocationMap,
- file: &object::File,
- section: &object::Section,
-) {
- for (offset64, mut relocation) in section.relocations() {
- let offset = offset64 as usize;
- if offset as u64 != offset64 {
- continue;
- }
- let offset = offset as usize;
- match relocation.kind() {
- object::RelocationKind::Absolute => {
- match relocation.target() {
- object::RelocationTarget::Symbol(symbol_idx) => {
- match file.symbol_by_index(symbol_idx) {
- Ok(symbol) => {
- let addend =
- symbol.address().wrapping_add(relocation.addend() as u64);
- relocation.set_addend(addend as i64);
- }
- Err(_) => {
- eprintln!(
- "Relocation with invalid symbol for section {} at offset 0x{:08x}",
- section.name().unwrap(),
- offset
- );
- }
- }
- }
- _ => {}
- }
- if relocations.insert(offset, relocation).is_some() {
- eprintln!(
- "Multiple relocations for section {} at offset 0x{:08x}",
- section.name().unwrap(),
- offset
- );
- }
- }
- _ => {
- eprintln!(
- "Unsupported relocation for section {} at offset 0x{:08x}",
- section.name().unwrap(),
- offset
- );
- }
- }
- }
-}
-
-/// Apply relocations to addresses and offsets during parsing,
-/// instead of requiring the data to be fully relocated prior
-/// to parsing.
-///
-/// Pros
-/// - allows readonly buffers, we don't need to implement writing of values back to buffers
-/// - potentially allows us to handle addresses and offsets differently
-/// - potentially allows us to add metadata from the relocation (eg symbol names)
-/// Cons
-/// - maybe incomplete
-#[derive(Debug, Clone)]
-struct Relocate<'a, R: gimli::Reader<Offset = usize>> {
- relocations: &'a RelocationMap,
- section: R,
- reader: R,
-}
-
-impl<'a, R: gimli::Reader<Offset = usize>> Relocate<'a, R> {
- fn relocate(&self, offset: usize, value: u64) -> u64 {
- if let Some(relocation) = self.relocations.get(&offset) {
- match relocation.kind() {
- object::RelocationKind::Absolute => {
- if relocation.has_implicit_addend() {
- // Use the explicit addend too, because it may have the symbol value.
- return value.wrapping_add(relocation.addend() as u64);
- } else {
- return relocation.addend() as u64;
- }
- }
- _ => {}
- }
- };
- value
- }
-}
-
-impl<'a, R: gimli::Reader<Offset = usize>> gimli::Reader for Relocate<'a, R> {
- type Endian = R::Endian;
- type Offset = R::Offset;
-
- fn read_address(&mut self, address_size: u8) -> gimli::Result<u64> {
- let offset = self.reader.offset_from(&self.section);
- let value = self.reader.read_address(address_size)?;
- Ok(self.relocate(offset, value))
- }
-
- fn read_length(&mut self, format: gimli::Format) -> gimli::Result<usize> {
- let offset = self.reader.offset_from(&self.section);
- let value = self.reader.read_length(format)?;
- <usize as gimli::ReaderOffset>::from_u64(self.relocate(offset, value as u64))
- }
-
- fn read_offset(&mut self, format: gimli::Format) -> gimli::Result<usize> {
- let offset = self.reader.offset_from(&self.section);
- let value = self.reader.read_offset(format)?;
- <usize as gimli::ReaderOffset>::from_u64(self.relocate(offset, value as u64))
- }
-
- fn read_sized_offset(&mut self, size: u8) -> gimli::Result<usize> {
- let offset = self.reader.offset_from(&self.section);
- let value = self.reader.read_sized_offset(size)?;
- <usize as gimli::ReaderOffset>::from_u64(self.relocate(offset, value as u64))
- }
-
- #[inline]
- fn split(&mut self, len: Self::Offset) -> gimli::Result<Self> {
- let mut other = self.clone();
- other.reader.truncate(len)?;
- self.reader.skip(len)?;
- Ok(other)
- }
-
- // All remaining methods simply delegate to `self.reader`.
-
- #[inline]
- fn endian(&self) -> Self::Endian {
- self.reader.endian()
- }
-
- #[inline]
- fn len(&self) -> Self::Offset {
- self.reader.len()
- }
-
- #[inline]
- fn empty(&mut self) {
- self.reader.empty()
- }
-
- #[inline]
- fn truncate(&mut self, len: Self::Offset) -> gimli::Result<()> {
- self.reader.truncate(len)
- }
-
- #[inline]
- fn offset_from(&self, base: &Self) -> Self::Offset {
- self.reader.offset_from(&base.reader)
- }
-
- #[inline]
- fn offset_id(&self) -> gimli::ReaderOffsetId {
- self.reader.offset_id()
- }
-
- #[inline]
- fn lookup_offset_id(&self, id: gimli::ReaderOffsetId) -> Option<Self::Offset> {
- self.reader.lookup_offset_id(id)
- }
-
- #[inline]
- fn find(&self, byte: u8) -> gimli::Result<Self::Offset> {
- self.reader.find(byte)
- }
-
- #[inline]
- fn skip(&mut self, len: Self::Offset) -> gimli::Result<()> {
- self.reader.skip(len)
- }
-
- #[inline]
- fn to_slice(&self) -> gimli::Result<Cow<[u8]>> {
- self.reader.to_slice()
- }
-
- #[inline]
- fn to_string(&self) -> gimli::Result<Cow<str>> {
- self.reader.to_string()
- }
-
- #[inline]
- fn to_string_lossy(&self) -> gimli::Result<Cow<str>> {
- self.reader.to_string_lossy()
- }
-
- #[inline]
- fn read_slice(&mut self, buf: &mut [u8]) -> gimli::Result<()> {
- self.reader.read_slice(buf)
- }
-}
-
-impl<'a, R: Reader> Reader for Relocate<'a, R> {}
-
-#[derive(Default)]
-struct Flags<'a> {
- eh_frame: bool,
- goff: bool,
- info: bool,
- line: bool,
- pubnames: bool,
- pubtypes: bool,
- aranges: bool,
- dwo: bool,
- dwp: bool,
- dwo_parent: Option<object::File<'a>>,
- sup: Option<object::File<'a>>,
- raw: bool,
- match_units: Option<Regex>,
-}
-
-fn print_usage(opts: &getopts::Options) -> ! {
- let brief = format!("Usage: {} <options> <file>", env::args().next().unwrap());
- write!(&mut io::stderr(), "{}", opts.usage(&brief)).ok();
- process::exit(1);
-}
-
-fn main() {
- let mut opts = getopts::Options::new();
- opts.optflag(
- "",
- "eh-frame",
- "print .eh-frame exception handling frame information",
- );
- opts.optflag("G", "", "show global die offsets");
- opts.optflag("i", "", "print .debug_info and .debug_types sections");
- opts.optflag("l", "", "print .debug_line section");
- opts.optflag("p", "", "print .debug_pubnames section");
- opts.optflag("r", "", "print .debug_aranges section");
- opts.optflag("y", "", "print .debug_pubtypes section");
- opts.optflag(
- "",
- "dwo",
- "print the .dwo versions of the selected sections",
- );
- opts.optflag(
- "",
- "dwp",
- "print the .dwp versions of the selected sections",
- );
- opts.optopt(
- "",
- "dwo-parent",
- "use the specified file as the parent of the dwo or dwp (e.g. for .debug_addr)",
- "library path",
- );
- opts.optflag("", "raw", "print raw data values");
- opts.optopt(
- "u",
- "match-units",
- "print compilation units whose output matches a regex",
- "REGEX",
- );
- opts.optopt("", "sup", "path to supplementary object file", "PATH");
-
- let matches = match opts.parse(env::args().skip(1)) {
- Ok(m) => m,
- Err(e) => {
- writeln!(&mut io::stderr(), "{:?}\n", e).ok();
- print_usage(&opts);
- }
- };
- if matches.free.is_empty() {
- print_usage(&opts);
- }
-
- let mut all = true;
- let mut flags = Flags::default();
- if matches.opt_present("eh-frame") {
- flags.eh_frame = true;
- all = false;
- }
- if matches.opt_present("G") {
- flags.goff = true;
- }
- if matches.opt_present("i") {
- flags.info = true;
- all = false;
- }
- if matches.opt_present("l") {
- flags.line = true;
- all = false;
- }
- if matches.opt_present("p") {
- flags.pubnames = true;
- all = false;
- }
- if matches.opt_present("y") {
- flags.pubtypes = true;
- all = false;
- }
- if matches.opt_present("r") {
- flags.aranges = true;
- all = false;
- }
- if matches.opt_present("dwo") {
- flags.dwo = true;
- }
- if matches.opt_present("dwp") {
- flags.dwp = true;
- }
- if matches.opt_present("raw") {
- flags.raw = true;
- }
- if all {
- // .eh_frame is excluded even when printing all information.
- // cosmetic flags like -G must be set explicitly too.
- flags.info = true;
- flags.line = true;
- flags.pubnames = true;
- flags.pubtypes = true;
- flags.aranges = true;
- }
- flags.match_units = if let Some(r) = matches.opt_str("u") {
- match Regex::new(&r) {
- Ok(r) => Some(r),
- Err(e) => {
- eprintln!("Invalid regular expression {}: {}", r, e);
- process::exit(1);
- }
- }
- } else {
- None
- };
-
- let arena_mmap = Arena::new();
- let load_file = |path| {
- let file = match fs::File::open(&path) {
- Ok(file) => file,
- Err(err) => {
- eprintln!("Failed to open file '{}': {}", path, err);
- process::exit(1);
- }
- };
- let mmap = match unsafe { memmap2::Mmap::map(&file) } {
- Ok(mmap) => mmap,
- Err(err) => {
- eprintln!("Failed to map file '{}': {}", path, err);
- process::exit(1);
- }
- };
- let mmap_ref = (*arena_mmap.alloc(mmap)).borrow();
- match object::File::parse(&**mmap_ref) {
- Ok(file) => Some(file),
- Err(err) => {
- eprintln!("Failed to parse file '{}': {}", path, err);
- process::exit(1);
- }
- }
- };
-
- flags.sup = matches.opt_str("sup").and_then(load_file);
- flags.dwo_parent = matches.opt_str("dwo-parent").and_then(load_file);
- if flags.dwo_parent.is_some() && !flags.dwo && !flags.dwp {
- eprintln!("--dwo-parent also requires --dwo or --dwp");
- process::exit(1);
- }
- if flags.dwo_parent.is_none() && flags.dwp {
- eprintln!("--dwp also requires --dwo-parent");
- process::exit(1);
- }
-
- for file_path in &matches.free {
- if matches.free.len() != 1 {
- println!("{}", file_path);
- println!();
- }
-
- let file = match fs::File::open(&file_path) {
- Ok(file) => file,
- Err(err) => {
- eprintln!("Failed to open file '{}': {}", file_path, err);
- continue;
- }
- };
- let file = match unsafe { memmap2::Mmap::map(&file) } {
- Ok(mmap) => mmap,
- Err(err) => {
- eprintln!("Failed to map file '{}': {}", file_path, err);
- continue;
- }
- };
- let file = match object::File::parse(&*file) {
- Ok(file) => file,
- Err(err) => {
- eprintln!("Failed to parse file '{}': {}", file_path, err);
- continue;
- }
- };
-
- let endian = if file.is_little_endian() {
- gimli::RunTimeEndian::Little
- } else {
- gimli::RunTimeEndian::Big
- };
- let ret = dump_file(&file, endian, &flags);
- match ret {
- Ok(_) => (),
- Err(err) => eprintln!("Failed to dump '{}': {}", file_path, err,),
- }
- }
-}
-
-fn empty_file_section<'input, 'arena, Endian: gimli::Endianity>(
- endian: Endian,
- arena_relocations: &'arena Arena<RelocationMap>,
-) -> Relocate<'arena, gimli::EndianSlice<'arena, Endian>> {
- let reader = gimli::EndianSlice::new(&[], endian);
- let section = reader;
- let relocations = RelocationMap::default();
- let relocations = (*arena_relocations.alloc(relocations)).borrow();
- Relocate {
- relocations,
- section,
- reader,
- }
-}
-
-fn load_file_section<'input, 'arena, Endian: gimli::Endianity>(
- id: gimli::SectionId,
- file: &object::File<'input>,
- endian: Endian,
- is_dwo: bool,
- arena_data: &'arena Arena<Cow<'input, [u8]>>,
- arena_relocations: &'arena Arena<RelocationMap>,
-) -> Result<Relocate<'arena, gimli::EndianSlice<'arena, Endian>>> {
- let mut relocations = RelocationMap::default();
- let name = if is_dwo {
- id.dwo_name()
- } else if file.format() == object::BinaryFormat::Xcoff {
- id.xcoff_name()
- } else {
- Some(id.name())
- };
-
- let data = match name.and_then(|name| file.section_by_name(&name)) {
- Some(ref section) => {
- // DWO sections never have relocations, so don't bother.
- if !is_dwo {
- add_relocations(&mut relocations, file, section);
- }
- section.uncompressed_data()?
- }
- // Use a non-zero capacity so that `ReaderOffsetId`s are unique.
- None => Cow::Owned(Vec::with_capacity(1)),
- };
- let data_ref = (*arena_data.alloc(data)).borrow();
- let reader = gimli::EndianSlice::new(data_ref, endian);
- let section = reader;
- let relocations = (*arena_relocations.alloc(relocations)).borrow();
- Ok(Relocate {
- relocations,
- section,
- reader,
- })
-}
-
-fn dump_file<Endian>(file: &object::File, endian: Endian, flags: &Flags) -> Result<()>
-where
- Endian: gimli::Endianity + Send + Sync,
-{
- let arena_data = Arena::new();
- let arena_relocations = Arena::new();
-
- let dwo_parent = if let Some(dwo_parent_file) = flags.dwo_parent.as_ref() {
- let mut load_dwo_parent_section = |id: gimli::SectionId| -> Result<_> {
- load_file_section(
- id,
- dwo_parent_file,
- endian,
- false,
- &arena_data,
- &arena_relocations,
- )
- };
- Some(gimli::Dwarf::load(&mut load_dwo_parent_section)?)
- } else {
- None
- };
- let dwo_parent = dwo_parent.as_ref();
-
- let dwo_parent_units = if let Some(dwo_parent) = dwo_parent {
- Some(
- match dwo_parent
- .units()
- .map(|unit_header| dwo_parent.unit(unit_header))
- .filter_map(|unit| Ok(unit.dwo_id.map(|dwo_id| (dwo_id, unit))))
- .collect()
- {
- Ok(units) => units,
- Err(err) => {
- eprintln!("Failed to process --dwo-parent units: {}", err);
- return Ok(());
- }
- },
- )
- } else {
- None
- };
- let dwo_parent_units = dwo_parent_units.as_ref();
-
- let mut load_section = |id: gimli::SectionId| -> Result<_> {
- load_file_section(
- id,
- file,
- endian,
- flags.dwo || flags.dwp,
- &arena_data,
- &arena_relocations,
- )
- };
-
- let w = &mut BufWriter::new(io::stdout());
- if flags.dwp {
- let empty = empty_file_section(endian, &arena_relocations);
- let dwp = gimli::DwarfPackage::load(&mut load_section, empty)?;
- dump_dwp(w, &dwp, dwo_parent.unwrap(), dwo_parent_units, flags)?;
- w.flush()?;
- return Ok(());
- }
-
- let mut dwarf = gimli::Dwarf::load(&mut load_section)?;
- if flags.dwo {
- if let Some(dwo_parent) = dwo_parent {
- dwarf.make_dwo(&dwo_parent);
- } else {
- dwarf.file_type = gimli::DwarfFileType::Dwo;
- }
- }
-
- if let Some(sup_file) = flags.sup.as_ref() {
- let mut load_sup_section = |id: gimli::SectionId| -> Result<_> {
- // Note: we really only need the `.debug_str` section,
- // but for now we load them all.
- load_file_section(id, sup_file, endian, false, &arena_data, &arena_relocations)
- };
- dwarf.load_sup(&mut load_sup_section)?;
- }
-
- if flags.eh_frame {
- let eh_frame = gimli::EhFrame::load(&mut load_section).unwrap();
- dump_eh_frame(w, file, eh_frame)?;
- }
- if flags.info {
- dump_info(w, &dwarf, dwo_parent_units, flags)?;
- dump_types(w, &dwarf, dwo_parent_units, flags)?;
- }
- if flags.line {
- dump_line(w, &dwarf)?;
- }
- if flags.pubnames {
- let debug_pubnames = &gimli::Section::load(&mut load_section).unwrap();
- dump_pubnames(w, debug_pubnames, &dwarf.debug_info)?;
- }
- if flags.aranges {
- let debug_aranges = &gimli::Section::load(&mut load_section).unwrap();
- dump_aranges(w, debug_aranges)?;
- }
- if flags.pubtypes {
- let debug_pubtypes = &gimli::Section::load(&mut load_section).unwrap();
- dump_pubtypes(w, debug_pubtypes, &dwarf.debug_info)?;
- }
- w.flush()?;
- Ok(())
-}
-
-fn dump_eh_frame<R: Reader, W: Write>(
- w: &mut W,
- file: &object::File,
- mut eh_frame: gimli::EhFrame<R>,
-) -> Result<()> {
- // TODO: this might be better based on the file format.
- let address_size = file
- .architecture()
- .address_size()
- .map(|w| w.bytes())
- .unwrap_or(mem::size_of::<usize>() as u8);
- eh_frame.set_address_size(address_size);
-
- fn register_name_none(_: gimli::Register) -> Option<&'static str> {
- None
- }
- let arch_register_name = match file.architecture() {
- object::Architecture::Arm | object::Architecture::Aarch64 => gimli::Arm::register_name,
- object::Architecture::I386 => gimli::X86::register_name,
- object::Architecture::X86_64 => gimli::X86_64::register_name,
- _ => register_name_none,
- };
- let register_name = &|register| match arch_register_name(register) {
- Some(name) => Cow::Borrowed(name),
- None => Cow::Owned(format!("{}", register.0)),
- };
-
- let mut bases = gimli::BaseAddresses::default();
- if let Some(section) = file.section_by_name(".eh_frame_hdr") {
- bases = bases.set_eh_frame_hdr(section.address());
- }
- if let Some(section) = file.section_by_name(".eh_frame") {
- bases = bases.set_eh_frame(section.address());
- }
- if let Some(section) = file.section_by_name(".text") {
- bases = bases.set_text(section.address());
- }
- if let Some(section) = file.section_by_name(".got") {
- bases = bases.set_got(section.address());
- }
-
- // TODO: Print "__eh_frame" here on macOS, and more generally use the
- // section that we're actually looking at, which is what the canonical
- // dwarfdump does.
- writeln!(
- w,
- "Exception handling frame information for section .eh_frame"
- )?;
-
- let mut cies = HashMap::new();
-
- let mut entries = eh_frame.entries(&bases);
- loop {
- match entries.next()? {
- None => return Ok(()),
- Some(gimli::CieOrFde::Cie(cie)) => {
- writeln!(w)?;
- writeln!(w, "{:#010x}: CIE", cie.offset())?;
- writeln!(w, " length: {:#010x}", cie.entry_len())?;
- // TODO: CIE_id
- writeln!(w, " version: {:#04x}", cie.version())?;
- // TODO: augmentation
- writeln!(w, " code_align: {}", cie.code_alignment_factor())?;
- writeln!(w, " data_align: {}", cie.data_alignment_factor())?;
- writeln!(
- w,
- " ra_register: {}",
- register_name(cie.return_address_register())
- )?;
- if let Some(encoding) = cie.lsda_encoding() {
- writeln!(
- w,
- " lsda_encoding: {}/{}",
- encoding.application(),
- encoding.format()
- )?;
- }
- if let Some((encoding, personality)) = cie.personality_with_encoding() {
- write!(
- w,
- " personality: {}/{} ",
- encoding.application(),
- encoding.format()
- )?;
- dump_pointer(w, personality)?;
- writeln!(w)?;
- }
- if let Some(encoding) = cie.fde_address_encoding() {
- writeln!(
- w,
- " fde_encoding: {}/{}",
- encoding.application(),
- encoding.format()
- )?;
- }
- let instructions = cie.instructions(&eh_frame, &bases);
- dump_cfi_instructions(w, instructions, true, register_name)?;
- writeln!(w)?;
- }
- Some(gimli::CieOrFde::Fde(partial)) => {
- let mut offset = None;
- let fde = partial.parse(|_, bases, o| {
- offset = Some(o);
- cies.entry(o)
- .or_insert_with(|| eh_frame.cie_from_offset(bases, o))
- .clone()
- })?;
-
- writeln!(w)?;
- writeln!(w, "{:#010x}: FDE", fde.offset())?;
- writeln!(w, " length: {:#010x}", fde.entry_len())?;
- writeln!(w, " CIE_pointer: {:#010x}", offset.unwrap().0)?;
- // TODO: symbolicate the start address like the canonical dwarfdump does.
- writeln!(w, " start_addr: {:#018x}", fde.initial_address())?;
- writeln!(
- w,
- " range_size: {:#018x} (end_addr = {:#018x})",
- fde.len(),
- fde.initial_address() + fde.len()
- )?;
- if let Some(lsda) = fde.lsda() {
- write!(w, " lsda: ")?;
- dump_pointer(w, lsda)?;
- writeln!(w)?;
- }
- let instructions = fde.instructions(&eh_frame, &bases);
- dump_cfi_instructions(w, instructions, false, register_name)?;
- writeln!(w)?;
- }
- }
- }
-}
-
-fn dump_pointer<W: Write>(w: &mut W, p: gimli::Pointer) -> Result<()> {
- match p {
- gimli::Pointer::Direct(p) => {
- write!(w, "{:#018x}", p)?;
- }
- gimli::Pointer::Indirect(p) => {
- write!(w, "({:#018x})", p)?;
- }
- }
- Ok(())
-}
-
-#[allow(clippy::unneeded_field_pattern)]
-fn dump_cfi_instructions<R: Reader, W: Write>(
- w: &mut W,
- mut insns: gimli::CallFrameInstructionIter<R>,
- is_initial: bool,
- register_name: &dyn Fn(gimli::Register) -> Cow<'static, str>,
-) -> Result<()> {
- use gimli::CallFrameInstruction::*;
-
- // TODO: we need to actually evaluate these instructions as we iterate them
- // so we can print the initialized state for CIEs, and each unwind row's
- // registers for FDEs.
- //
- // TODO: We should print DWARF expressions for the CFI instructions that
- // embed DWARF expressions within themselves.
-
- if !is_initial {
- writeln!(w, " Instructions:")?;
- }
-
- loop {
- match insns.next() {
- Err(e) => {
- writeln!(w, "Failed to decode CFI instruction: {}", e)?;
- return Ok(());
- }
- Ok(None) => {
- if is_initial {
- writeln!(w, " Instructions: Init State:")?;
- }
- return Ok(());
- }
- Ok(Some(op)) => match op {
- SetLoc { address } => {
- writeln!(w, " DW_CFA_set_loc ({:#x})", address)?;
- }
- AdvanceLoc { delta } => {
- writeln!(w, " DW_CFA_advance_loc ({})", delta)?;
- }
- DefCfa { register, offset } => {
- writeln!(
- w,
- " DW_CFA_def_cfa ({}, {})",
- register_name(register),
- offset
- )?;
- }
- DefCfaSf {
- register,
- factored_offset,
- } => {
- writeln!(
- w,
- " DW_CFA_def_cfa_sf ({}, {})",
- register_name(register),
- factored_offset
- )?;
- }
- DefCfaRegister { register } => {
- writeln!(
- w,
- " DW_CFA_def_cfa_register ({})",
- register_name(register)
- )?;
- }
- DefCfaOffset { offset } => {
- writeln!(w, " DW_CFA_def_cfa_offset ({})", offset)?;
- }
- DefCfaOffsetSf { factored_offset } => {
- writeln!(
- w,
- " DW_CFA_def_cfa_offset_sf ({})",
- factored_offset
- )?;
- }
- DefCfaExpression { expression: _ } => {
- writeln!(w, " DW_CFA_def_cfa_expression (...)")?;
- }
- Undefined { register } => {
- writeln!(
- w,
- " DW_CFA_undefined ({})",
- register_name(register)
- )?;
- }
- SameValue { register } => {
- writeln!(
- w,
- " DW_CFA_same_value ({})",
- register_name(register)
- )?;
- }
- Offset {
- register,
- factored_offset,
- } => {
- writeln!(
- w,
- " DW_CFA_offset ({}, {})",
- register_name(register),
- factored_offset
- )?;
- }
- OffsetExtendedSf {
- register,
- factored_offset,
- } => {
- writeln!(
- w,
- " DW_CFA_offset_extended_sf ({}, {})",
- register_name(register),
- factored_offset
- )?;
- }
- ValOffset {
- register,
- factored_offset,
- } => {
- writeln!(
- w,
- " DW_CFA_val_offset ({}, {})",
- register_name(register),
- factored_offset
- )?;
- }
- ValOffsetSf {
- register,
- factored_offset,
- } => {
- writeln!(
- w,
- " DW_CFA_val_offset_sf ({}, {})",
- register_name(register),
- factored_offset
- )?;
- }
- Register {
- dest_register,
- src_register,
- } => {
- writeln!(
- w,
- " DW_CFA_register ({}, {})",
- register_name(dest_register),
- register_name(src_register)
- )?;
- }
- Expression {
- register,
- expression: _,
- } => {
- writeln!(
- w,
- " DW_CFA_expression ({}, ...)",
- register_name(register)
- )?;
- }
- ValExpression {
- register,
- expression: _,
- } => {
- writeln!(
- w,
- " DW_CFA_val_expression ({}, ...)",
- register_name(register)
- )?;
- }
- Restore { register } => {
- writeln!(
- w,
- " DW_CFA_restore ({})",
- register_name(register)
- )?;
- }
- RememberState => {
- writeln!(w, " DW_CFA_remember_state")?;
- }
- RestoreState => {
- writeln!(w, " DW_CFA_restore_state")?;
- }
- ArgsSize { size } => {
- writeln!(w, " DW_CFA_GNU_args_size ({})", size)?;
- }
- Nop => {
- writeln!(w, " DW_CFA_nop")?;
- }
- },
- }
- }
-}
-
-fn dump_dwp<R: Reader, W: Write + Send>(
- w: &mut W,
- dwp: &gimli::DwarfPackage<R>,
- dwo_parent: &gimli::Dwarf<R>,
- dwo_parent_units: Option<&HashMap<gimli::DwoId, gimli::Unit<R>>>,
- flags: &Flags,
-) -> Result<()>
-where
- R::Endian: Send + Sync,
-{
- if dwp.cu_index.unit_count() != 0 {
- writeln!(
- w,
- "\n.debug_cu_index: version = {}, sections = {}, units = {}, slots = {}",
- dwp.cu_index.version(),
- dwp.cu_index.section_count(),
- dwp.cu_index.unit_count(),
- dwp.cu_index.slot_count(),
- )?;
- for i in 1..=dwp.cu_index.unit_count() {
- writeln!(w, "\nCU index {}", i)?;
- dump_dwp_sections(
- w,
- &dwp,
- dwo_parent,
- dwo_parent_units,
- flags,
- dwp.cu_index.sections(i)?,
- )?;
- }
- }
-
- if dwp.tu_index.unit_count() != 0 {
- writeln!(
- w,
- "\n.debug_tu_index: version = {}, sections = {}, units = {}, slots = {}",
- dwp.tu_index.version(),
- dwp.tu_index.section_count(),
- dwp.tu_index.unit_count(),
- dwp.tu_index.slot_count(),
- )?;
- for i in 1..=dwp.tu_index.unit_count() {
- writeln!(w, "\nTU index {}", i)?;
- dump_dwp_sections(
- w,
- &dwp,
- dwo_parent,
- dwo_parent_units,
- flags,
- dwp.tu_index.sections(i)?,
- )?;
- }
- }
-
- Ok(())
-}
-
-fn dump_dwp_sections<R: Reader, W: Write + Send>(
- w: &mut W,
- dwp: &gimli::DwarfPackage<R>,
- dwo_parent: &gimli::Dwarf<R>,
- dwo_parent_units: Option<&HashMap<gimli::DwoId, gimli::Unit<R>>>,
- flags: &Flags,
- sections: gimli::UnitIndexSectionIterator<R>,
-) -> Result<()>
-where
- R::Endian: Send + Sync,
-{
- for section in sections.clone() {
- writeln!(
- w,
- " {}: offset = 0x{:x}, size = 0x{:x}",
- section.section.dwo_name().unwrap(),
- section.offset,
- section.size
- )?;
- }
- let dwarf = dwp.sections(sections, dwo_parent)?;
- if flags.info {
- dump_info(w, &dwarf, dwo_parent_units, flags)?;
- dump_types(w, &dwarf, dwo_parent_units, flags)?;
- }
- if flags.line {
- dump_line(w, &dwarf)?;
- }
- Ok(())
-}
-
-fn dump_info<R: Reader, W: Write + Send>(
- w: &mut W,
- dwarf: &gimli::Dwarf<R>,
- dwo_parent_units: Option<&HashMap<gimli::DwoId, gimli::Unit<R>>>,
- flags: &Flags,
-) -> Result<()>
-where
- R::Endian: Send + Sync,
-{
- writeln!(w, "\n.debug_info")?;
-
- let units = match dwarf.units().collect::<Vec<_>>() {
- Ok(units) => units,
- Err(err) => {
- writeln_error(
- w,
- dwarf,
- Error::GimliError(err),
- "Failed to read unit headers",
- )?;
- return Ok(());
- }
- };
- let process_unit = |header: UnitHeader<R>, buf: &mut Vec<u8>| -> Result<()> {
- dump_unit(buf, header, dwarf, dwo_parent_units, flags)?;
- if !flags
- .match_units
- .as_ref()
- .map(|r| r.is_match(&buf))
- .unwrap_or(true)
- {
- buf.clear();
- }
- Ok(())
- };
- // Don't use more than 16 cores even if available. No point in soaking hundreds
- // of cores if you happen to have them.
- parallel_output(w, 16, units, process_unit)
-}
-
-fn dump_types<R: Reader, W: Write>(
- w: &mut W,
- dwarf: &gimli::Dwarf<R>,
- dwo_parent_units: Option<&HashMap<gimli::DwoId, gimli::Unit<R>>>,
- flags: &Flags,
-) -> Result<()> {
- writeln!(w, "\n.debug_types")?;
-
- let mut iter = dwarf.type_units();
- while let Some(header) = iter.next()? {
- dump_unit(w, header, dwarf, dwo_parent_units, flags)?;
- }
- Ok(())
-}
-
-fn dump_unit<R: Reader, W: Write>(
- w: &mut W,
- header: UnitHeader<R>,
- dwarf: &gimli::Dwarf<R>,
- dwo_parent_units: Option<&HashMap<gimli::DwoId, gimli::Unit<R>>>,
- flags: &Flags,
-) -> Result<()> {
- write!(w, "\nUNIT<")?;
- match header.offset() {
- UnitSectionOffset::DebugInfoOffset(o) => {
- write!(w, ".debug_info+0x{:08x}", o.0)?;
- }
- UnitSectionOffset::DebugTypesOffset(o) => {
- write!(w, ".debug_types+0x{:08x}", o.0)?;
- }
- }
- writeln!(w, ">: length = 0x{:x}, format = {:?}, version = {}, address_size = {}, abbrev_offset = 0x{:x}",
- header.unit_length(),
- header.format(),
- header.version(),
- header.address_size(),
- header.debug_abbrev_offset().0,
- )?;
-
- match header.type_() {
- UnitType::Compilation | UnitType::Partial => (),
- UnitType::Type {
- type_signature,
- type_offset,
- }
- | UnitType::SplitType {
- type_signature,
- type_offset,
- } => {
- write!(w, " signature = ")?;
- dump_type_signature(w, type_signature)?;
- writeln!(w)?;
- writeln!(w, " type_offset = 0x{:x}", type_offset.0,)?;
- }
- UnitType::Skeleton(dwo_id) | UnitType::SplitCompilation(dwo_id) => {
- write!(w, " dwo_id = ")?;
- writeln!(w, "0x{:016x}", dwo_id.0)?;
- }
- }
-
- let mut unit = match dwarf.unit(header) {
- Ok(unit) => unit,
- Err(err) => {
- writeln_error(w, dwarf, err.into(), "Failed to parse unit root entry")?;
- return Ok(());
- }
- };
-
- if let Some(dwo_parent_units) = dwo_parent_units {
- if let Some(dwo_id) = unit.dwo_id {
- if let Some(parent_unit) = dwo_parent_units.get(&dwo_id) {
- unit.copy_relocated_attributes(parent_unit);
- }
- }
- }
-
- let entries_result = dump_entries(w, unit, dwarf, flags);
- if let Err(err) = entries_result {
- writeln_error(w, dwarf, err, "Failed to dump entries")?;
- }
- Ok(())
-}
-
-fn spaces(buf: &mut String, len: usize) -> &str {
- while buf.len() < len {
- buf.push(' ');
- }
- &buf[..len]
-}
-
-// " GOFF=0x{:08x}" adds exactly 16 spaces.
-const GOFF_SPACES: usize = 16;
-
-fn write_offset<R: Reader, W: Write>(
- w: &mut W,
- unit: &gimli::Unit<R>,
- offset: gimli::UnitOffset<R::Offset>,
- flags: &Flags,
-) -> Result<()> {
- write!(w, "<0x{:08x}", offset.0)?;
- if flags.goff {
- let goff = match offset.to_unit_section_offset(unit) {
- UnitSectionOffset::DebugInfoOffset(o) => o.0,
- UnitSectionOffset::DebugTypesOffset(o) => o.0,
- };
- write!(w, " GOFF=0x{:08x}", goff)?;
- }
- write!(w, ">")?;
- Ok(())
-}
-
-fn dump_entries<R: Reader, W: Write>(
- w: &mut W,
- unit: gimli::Unit<R>,
- dwarf: &gimli::Dwarf<R>,
- flags: &Flags,
-) -> Result<()> {
- let mut spaces_buf = String::new();
-
- let mut entries = unit.entries_raw(None)?;
- while !entries.is_empty() {
- let offset = entries.next_offset();
- let depth = entries.next_depth();
- let abbrev = entries.read_abbreviation()?;
-
- let mut indent = if depth >= 0 {
- depth as usize * 2 + 2
- } else {
- 2
- };
- write!(w, "<{}{}>", if depth < 10 { " " } else { "" }, depth)?;
- write_offset(w, &unit, offset, flags)?;
- writeln!(
- w,
- "{}{}",
- spaces(&mut spaces_buf, indent),
- abbrev.map(|x| x.tag()).unwrap_or(gimli::DW_TAG_null)
- )?;
-
- indent += 18;
- if flags.goff {
- indent += GOFF_SPACES;
- }
-
- for spec in abbrev.map(|x| x.attributes()).unwrap_or(&[]) {
- let attr = entries.read_attribute(*spec)?;
- w.write_all(spaces(&mut spaces_buf, indent).as_bytes())?;
- if let Some(n) = attr.name().static_string() {
- let right_padding = 27 - std::cmp::min(27, n.len());
- write!(w, "{}{} ", n, spaces(&mut spaces_buf, right_padding))?;
- } else {
- write!(w, "{:27} ", attr.name())?;
- }
- if flags.raw {
- writeln!(w, "{:?}", attr.raw_value())?;
- } else {
- match dump_attr_value(w, &attr, &unit, dwarf) {
- Ok(_) => (),
- Err(err) => writeln_error(w, dwarf, err, "Failed to dump attribute value")?,
- };
- }
- }
- }
- Ok(())
-}
-
-fn dump_attr_value<R: Reader, W: Write>(
- w: &mut W,
- attr: &gimli::Attribute<R>,
- unit: &gimli::Unit<R>,
- dwarf: &gimli::Dwarf<R>,
-) -> Result<()> {
- let value = attr.value();
- match value {
- gimli::AttributeValue::Addr(address) => {
- writeln!(w, "0x{:08x}", address)?;
- }
- gimli::AttributeValue::Block(data) => {
- for byte in data.to_slice()?.iter() {
- write!(w, "{:02x}", byte)?;
- }
- writeln!(w)?;
- }
- gimli::AttributeValue::Data1(_)
- | gimli::AttributeValue::Data2(_)
- | gimli::AttributeValue::Data4(_)
- | gimli::AttributeValue::Data8(_) => {
- if let (Some(udata), Some(sdata)) = (attr.udata_value(), attr.sdata_value()) {
- if sdata >= 0 {
- writeln!(w, "{}", udata)?;
- } else {
- writeln!(w, "{} ({})", udata, sdata)?;
- }
- } else {
- writeln!(w, "{:?}", value)?;
- }
- }
- gimli::AttributeValue::Sdata(data) => {
- match attr.name() {
- gimli::DW_AT_data_member_location => {
- writeln!(w, "{}", data)?;
- }
- _ => {
- if data >= 0 {
- writeln!(w, "0x{:08x}", data)?;
- } else {
- writeln!(w, "0x{:08x} ({})", data, data)?;
- }
- }
- };
- }
- gimli::AttributeValue::Udata(data) => {
- match attr.name() {
- gimli::DW_AT_high_pc => {
- writeln!(w, "<offset-from-lowpc>{}", data)?;
- }
- gimli::DW_AT_data_member_location => {
- if let Some(sdata) = attr.sdata_value() {
- // This is a DW_FORM_data* value.
- // libdwarf-dwarfdump displays this as signed too.
- if sdata >= 0 {
- writeln!(w, "{}", data)?;
- } else {
- writeln!(w, "{} ({})", data, sdata)?;
- }
- } else {
- writeln!(w, "{}", data)?;
- }
- }
- gimli::DW_AT_lower_bound | gimli::DW_AT_upper_bound => {
- writeln!(w, "{}", data)?;
- }
- _ => {
- writeln!(w, "0x{:08x}", data)?;
- }
- };
- }
- gimli::AttributeValue::Exprloc(ref data) => {
- if let gimli::AttributeValue::Exprloc(_) = attr.raw_value() {
- write!(w, "len 0x{:04x}: ", data.0.len())?;
- for byte in data.0.to_slice()?.iter() {
- write!(w, "{:02x}", byte)?;
- }
- write!(w, ": ")?;
- }
- dump_exprloc(w, unit.encoding(), data)?;
- writeln!(w)?;
- }
- gimli::AttributeValue::Flag(true) => {
- writeln!(w, "yes")?;
- }
- gimli::AttributeValue::Flag(false) => {
- writeln!(w, "no")?;
- }
- gimli::AttributeValue::SecOffset(offset) => {
- writeln!(w, "0x{:08x}", offset)?;
- }
- gimli::AttributeValue::DebugAddrBase(base) => {
- writeln!(w, "<.debug_addr+0x{:08x}>", base.0)?;
- }
- gimli::AttributeValue::DebugAddrIndex(index) => {
- write!(w, "(indirect address, index {:#x}): ", index.0)?;
- let address = dwarf.address(unit, index)?;
- writeln!(w, "0x{:08x}", address)?;
- }
- gimli::AttributeValue::UnitRef(offset) => {
- write!(w, "0x{:08x}", offset.0)?;
- match offset.to_unit_section_offset(unit) {
- UnitSectionOffset::DebugInfoOffset(goff) => {
- write!(w, "<.debug_info+0x{:08x}>", goff.0)?;
- }
- UnitSectionOffset::DebugTypesOffset(goff) => {
- write!(w, "<.debug_types+0x{:08x}>", goff.0)?;
- }
- }
- writeln!(w)?;
- }
- gimli::AttributeValue::DebugInfoRef(offset) => {
- writeln!(w, "<.debug_info+0x{:08x}>", offset.0)?;
- }
- gimli::AttributeValue::DebugInfoRefSup(offset) => {
- writeln!(w, "<.debug_info(sup)+0x{:08x}>", offset.0)?;
- }
- gimli::AttributeValue::DebugLineRef(offset) => {
- writeln!(w, "<.debug_line+0x{:08x}>", offset.0)?;
- }
- gimli::AttributeValue::LocationListsRef(offset) => {
- dump_loc_list(w, offset, unit, dwarf)?;
- }
- gimli::AttributeValue::DebugLocListsBase(base) => {
- writeln!(w, "<.debug_loclists+0x{:08x}>", base.0)?;
- }
- gimli::AttributeValue::DebugLocListsIndex(index) => {
- write!(w, "(indirect location list, index {:#x}): ", index.0)?;
- let offset = dwarf.locations_offset(unit, index)?;
- dump_loc_list(w, offset, unit, dwarf)?;
- }
- gimli::AttributeValue::DebugMacinfoRef(offset) => {
- writeln!(w, "<.debug_macinfo+0x{:08x}>", offset.0)?;
- }
- gimli::AttributeValue::DebugMacroRef(offset) => {
- writeln!(w, "<.debug_macro+0x{:08x}>", offset.0)?;
- }
- gimli::AttributeValue::RangeListsRef(offset) => {
- let offset = dwarf.ranges_offset_from_raw(unit, offset);
- dump_range_list(w, offset, unit, dwarf)?;
- }
- gimli::AttributeValue::DebugRngListsBase(base) => {
- writeln!(w, "<.debug_rnglists+0x{:08x}>", base.0)?;
- }
- gimli::AttributeValue::DebugRngListsIndex(index) => {
- write!(w, "(indirect range list, index {:#x}): ", index.0)?;
- let offset = dwarf.ranges_offset(unit, index)?;
- dump_range_list(w, offset, unit, dwarf)?;
- }
- gimli::AttributeValue::DebugTypesRef(signature) => {
- dump_type_signature(w, signature)?;
- writeln!(w, " <type signature>")?;
- }
- gimli::AttributeValue::DebugStrRef(offset) => {
- if let Ok(s) = dwarf.debug_str.get_str(offset) {
- writeln!(w, "{}", s.to_string_lossy()?)?;
- } else {
- writeln!(w, "<.debug_str+0x{:08x}>", offset.0)?;
- }
- }
- gimli::AttributeValue::DebugStrRefSup(offset) => {
- if let Some(s) = dwarf
- .sup()
- .and_then(|sup| sup.debug_str.get_str(offset).ok())
- {
- writeln!(w, "{}", s.to_string_lossy()?)?;
- } else {
- writeln!(w, "<.debug_str(sup)+0x{:08x}>", offset.0)?;
- }
- }
- gimli::AttributeValue::DebugStrOffsetsBase(base) => {
- writeln!(w, "<.debug_str_offsets+0x{:08x}>", base.0)?;
- }
- gimli::AttributeValue::DebugStrOffsetsIndex(index) => {
- write!(w, "(indirect string, index {:#x}): ", index.0)?;
- let offset = dwarf.debug_str_offsets.get_str_offset(
- unit.encoding().format,
- unit.str_offsets_base,
- index,
- )?;
- if let Ok(s) = dwarf.debug_str.get_str(offset) {
- writeln!(w, "{}", s.to_string_lossy()?)?;
- } else {
- writeln!(w, "<.debug_str+0x{:08x}>", offset.0)?;
- }
- }
- gimli::AttributeValue::DebugLineStrRef(offset) => {
- if let Ok(s) = dwarf.debug_line_str.get_str(offset) {
- writeln!(w, "{}", s.to_string_lossy()?)?;
- } else {
- writeln!(w, "<.debug_line_str=0x{:08x}>", offset.0)?;
- }
- }
- gimli::AttributeValue::String(s) => {
- writeln!(w, "{}", s.to_string_lossy()?)?;
- }
- gimli::AttributeValue::Encoding(value) => {
- writeln!(w, "{}", value)?;
- }
- gimli::AttributeValue::DecimalSign(value) => {
- writeln!(w, "{}", value)?;
- }
- gimli::AttributeValue::Endianity(value) => {
- writeln!(w, "{}", value)?;
- }
- gimli::AttributeValue::Accessibility(value) => {
- writeln!(w, "{}", value)?;
- }
- gimli::AttributeValue::Visibility(value) => {
- writeln!(w, "{}", value)?;
- }
- gimli::AttributeValue::Virtuality(value) => {
- writeln!(w, "{}", value)?;
- }
- gimli::AttributeValue::Language(value) => {
- writeln!(w, "{}", value)?;
- }
- gimli::AttributeValue::AddressClass(value) => {
- writeln!(w, "{}", value)?;
- }
- gimli::AttributeValue::IdentifierCase(value) => {
- writeln!(w, "{}", value)?;
- }
- gimli::AttributeValue::CallingConvention(value) => {
- writeln!(w, "{}", value)?;
- }
- gimli::AttributeValue::Inline(value) => {
- writeln!(w, "{}", value)?;
- }
- gimli::AttributeValue::Ordering(value) => {
- writeln!(w, "{}", value)?;
- }
- gimli::AttributeValue::FileIndex(value) => {
- write!(w, "0x{:08x}", value)?;
- dump_file_index(w, value, unit, dwarf)?;
- writeln!(w)?;
- }
- gimli::AttributeValue::DwoId(value) => {
- writeln!(w, "0x{:016x}", value.0)?;
- }
- }
-
- Ok(())
-}
-
-fn dump_type_signature<W: Write>(w: &mut W, signature: gimli::DebugTypeSignature) -> Result<()> {
- write!(w, "0x{:016x}", signature.0)?;
- Ok(())
-}
-
-fn dump_file_index<R: Reader, W: Write>(
- w: &mut W,
- file_index: u64,
- unit: &gimli::Unit<R>,
- dwarf: &gimli::Dwarf<R>,
-) -> Result<()> {
- if file_index == 0 && unit.header.version() <= 4 {
- return Ok(());
- }
- let header = match unit.line_program {
- Some(ref program) => program.header(),
- None => return Ok(()),
- };
- let file = match header.file(file_index) {
- Some(file) => file,
- None => {
- writeln!(w, "Unable to get header for file {}", file_index)?;
- return Ok(());
- }
- };
- write!(w, " ")?;
- if let Some(directory) = file.directory(header) {
- let directory = dwarf.attr_string(unit, directory)?;
- let directory = directory.to_string_lossy()?;
- if file.directory_index() != 0 && !directory.starts_with('/') {
- if let Some(ref comp_dir) = unit.comp_dir {
- write!(w, "{}/", comp_dir.to_string_lossy()?,)?;
- }
- }
- write!(w, "{}/", directory)?;
- }
- write!(
- w,
- "{}",
- dwarf
- .attr_string(unit, file.path_name())?
- .to_string_lossy()?
- )?;
- Ok(())
-}
-
-fn dump_exprloc<R: Reader, W: Write>(
- w: &mut W,
- encoding: gimli::Encoding,
- data: &gimli::Expression<R>,
-) -> Result<()> {
- let mut pc = data.0.clone();
- let mut space = false;
- while pc.len() != 0 {
- let pc_clone = pc.clone();
- match gimli::Operation::parse(&mut pc, encoding) {
- Ok(op) => {
- if space {
- write!(w, " ")?;
- } else {
- space = true;
- }
- dump_op(w, encoding, pc_clone, op)?;
- }
- Err(gimli::Error::InvalidExpression(op)) => {
- writeln!(w, "WARNING: unsupported operation 0x{:02x}", op.0)?;
- return Ok(());
- }
- Err(gimli::Error::UnsupportedRegister(register)) => {
- writeln!(w, "WARNING: unsupported register {}", register)?;
- return Ok(());
- }
- Err(gimli::Error::UnexpectedEof(_)) => {
- writeln!(w, "WARNING: truncated or malformed expression")?;
- return Ok(());
- }
- Err(e) => {
- writeln!(w, "WARNING: unexpected operation parse error: {}", e)?;
- return Ok(());
- }
- }
- }
- Ok(())
-}
-
-fn dump_op<R: Reader, W: Write>(
- w: &mut W,
- encoding: gimli::Encoding,
- mut pc: R,
- op: gimli::Operation<R>,
-) -> Result<()> {
- let dwop = gimli::DwOp(pc.read_u8()?);
- write!(w, "{}", dwop)?;
- match op {
- gimli::Operation::Deref {
- base_type, size, ..
- } => {
- if dwop == gimli::DW_OP_deref_size || dwop == gimli::DW_OP_xderef_size {
- write!(w, " {}", size)?;
- }
- if base_type != UnitOffset(0) {
- write!(w, " type 0x{:08x}", base_type.0)?;
- }
- }
- gimli::Operation::Pick { index } => {
- if dwop == gimli::DW_OP_pick {
- write!(w, " {}", index)?;
- }
- }
- gimli::Operation::PlusConstant { value } => {
- write!(w, " {}", value as i64)?;
- }
- gimli::Operation::Bra { target } => {
- write!(w, " {}", target)?;
- }
- gimli::Operation::Skip { target } => {
- write!(w, " {}", target)?;
- }
- gimli::Operation::SignedConstant { value } => match dwop {
- gimli::DW_OP_const1s
- | gimli::DW_OP_const2s
- | gimli::DW_OP_const4s
- | gimli::DW_OP_const8s
- | gimli::DW_OP_consts => {
- write!(w, " {}", value)?;
- }
- _ => {}
- },
- gimli::Operation::UnsignedConstant { value } => match dwop {
- gimli::DW_OP_const1u
- | gimli::DW_OP_const2u
- | gimli::DW_OP_const4u
- | gimli::DW_OP_const8u
- | gimli::DW_OP_constu => {
- write!(w, " {}", value)?;
- }
- _ => {
- // These have the value encoded in the operation, eg DW_OP_lit0.
- }
- },
- gimli::Operation::Register { register } => {
- if dwop == gimli::DW_OP_regx {
- write!(w, " {}", register.0)?;
- }
- }
- gimli::Operation::RegisterOffset {
- register,
- offset,
- base_type,
- } => {
- if dwop >= gimli::DW_OP_breg0 && dwop <= gimli::DW_OP_breg31 {
- write!(w, "{:+}", offset)?;
- } else {
- write!(w, " {}", register.0)?;
- if offset != 0 {
- write!(w, "{:+}", offset)?;
- }
- if base_type != UnitOffset(0) {
- write!(w, " type 0x{:08x}", base_type.0)?;
- }
- }
- }
- gimli::Operation::FrameOffset { offset } => {
- write!(w, " {}", offset)?;
- }
- gimli::Operation::Call { offset } => match offset {
- gimli::DieReference::UnitRef(gimli::UnitOffset(offset)) => {
- write!(w, " 0x{:08x}", offset)?;
- }
- gimli::DieReference::DebugInfoRef(gimli::DebugInfoOffset(offset)) => {
- write!(w, " 0x{:08x}", offset)?;
- }
- },
- gimli::Operation::Piece {
- size_in_bits,
- bit_offset: None,
- } => {
- write!(w, " {}", size_in_bits / 8)?;
- }
- gimli::Operation::Piece {
- size_in_bits,
- bit_offset: Some(bit_offset),
- } => {
- write!(w, " 0x{:08x} offset 0x{:08x}", size_in_bits, bit_offset)?;
- }
- gimli::Operation::ImplicitValue { data } => {
- let data = data.to_slice()?;
- write!(w, " 0x{:08x} contents 0x", data.len())?;
- for byte in data.iter() {
- write!(w, "{:02x}", byte)?;
- }
- }
- gimli::Operation::ImplicitPointer { value, byte_offset } => {
- write!(w, " 0x{:08x} {}", value.0, byte_offset)?;
- }
- gimli::Operation::EntryValue { expression } => {
- write!(w, "(")?;
- dump_exprloc(w, encoding, &gimli::Expression(expression))?;
- write!(w, ")")?;
- }
- gimli::Operation::ParameterRef { offset } => {
- write!(w, " 0x{:08x}", offset.0)?;
- }
- gimli::Operation::Address { address } => {
- write!(w, " 0x{:08x}", address)?;
- }
- gimli::Operation::AddressIndex { index } => {
- write!(w, " 0x{:08x}", index.0)?;
- }
- gimli::Operation::ConstantIndex { index } => {
- write!(w, " 0x{:08x}", index.0)?;
- }
- gimli::Operation::TypedLiteral { base_type, value } => {
- write!(w, " type 0x{:08x} contents 0x", base_type.0)?;
- for byte in value.to_slice()?.iter() {
- write!(w, "{:02x}", byte)?;
- }
- }
- gimli::Operation::Convert { base_type } => {
- write!(w, " type 0x{:08x}", base_type.0)?;
- }
- gimli::Operation::Reinterpret { base_type } => {
- write!(w, " type 0x{:08x}", base_type.0)?;
- }
- gimli::Operation::WasmLocal { index }
- | gimli::Operation::WasmGlobal { index }
- | gimli::Operation::WasmStack { index } => {
- let wasmop = pc.read_u8()?;
- write!(w, " 0x{:x} 0x{:x}", wasmop, index)?;
- }
- gimli::Operation::Drop
- | gimli::Operation::Swap
- | gimli::Operation::Rot
- | gimli::Operation::Abs
- | gimli::Operation::And
- | gimli::Operation::Div
- | gimli::Operation::Minus
- | gimli::Operation::Mod
- | gimli::Operation::Mul
- | gimli::Operation::Neg
- | gimli::Operation::Not
- | gimli::Operation::Or
- | gimli::Operation::Plus
- | gimli::Operation::Shl
- | gimli::Operation::Shr
- | gimli::Operation::Shra
- | gimli::Operation::Xor
- | gimli::Operation::Eq
- | gimli::Operation::Ge
- | gimli::Operation::Gt
- | gimli::Operation::Le
- | gimli::Operation::Lt
- | gimli::Operation::Ne
- | gimli::Operation::Nop
- | gimli::Operation::PushObjectAddress
- | gimli::Operation::TLS
- | gimli::Operation::CallFrameCFA
- | gimli::Operation::StackValue => {}
- };
- Ok(())
-}
-
-fn dump_range<W: Write>(w: &mut W, range: Option<gimli::Range>) -> Result<()> {
- if let Some(range) = range {
- write!(w, " [0x{:08x}, 0x{:08x}]", range.begin, range.end)?;
- } else {
- write!(w, " [ignored]")?;
- }
- Ok(())
-}
-
-fn dump_loc_list<R: Reader, W: Write>(
- w: &mut W,
- offset: gimli::LocationListsOffset<R::Offset>,
- unit: &gimli::Unit<R>,
- dwarf: &gimli::Dwarf<R>,
-) -> Result<()> {
- let mut locations = dwarf.locations(unit, offset)?;
- writeln!(
- w,
- "<loclist at {}+0x{:08x}>",
- if unit.encoding().version < 5 {
- ".debug_loc"
- } else {
- ".debug_loclists"
- },
- offset.0,
- )?;
- let mut i = 0;
- while let Some(raw) = locations.next_raw()? {
- write!(w, "\t\t\t[{:2}]", i)?;
- i += 1;
- let range = locations
- .convert_raw(raw.clone())?
- .map(|location| location.range);
- match raw {
- gimli::RawLocListEntry::BaseAddress { addr } => {
- writeln!(w, "<base-address 0x{:08x}>", addr)?;
- }
- gimli::RawLocListEntry::BaseAddressx { addr } => {
- let addr_val = dwarf.address(unit, addr)?;
- writeln!(w, "<base-addressx [{}]0x{:08x}>", addr.0, addr_val)?;
- }
- gimli::RawLocListEntry::StartxEndx {
- begin,
- end,
- ref data,
- } => {
- let begin_val = dwarf.address(unit, begin)?;
- let end_val = dwarf.address(unit, end)?;
- write!(
- w,
- "<startx-endx [{}]0x{:08x}, [{}]0x{:08x}>",
- begin.0, begin_val, end.0, end_val,
- )?;
- dump_range(w, range)?;
- dump_exprloc(w, unit.encoding(), data)?;
- writeln!(w)?;
- }
- gimli::RawLocListEntry::StartxLength {
- begin,
- length,
- ref data,
- } => {
- let begin_val = dwarf.address(unit, begin)?;
- write!(
- w,
- "<startx-length [{}]0x{:08x}, 0x{:08x}>",
- begin.0, begin_val, length,
- )?;
- dump_range(w, range)?;
- dump_exprloc(w, unit.encoding(), data)?;
- writeln!(w)?;
- }
- gimli::RawLocListEntry::AddressOrOffsetPair {
- begin,
- end,
- ref data,
- }
- | gimli::RawLocListEntry::OffsetPair {
- begin,
- end,
- ref data,
- } => {
- write!(w, "<offset-pair 0x{:08x}, 0x{:08x}>", begin, end)?;
- dump_range(w, range)?;
- dump_exprloc(w, unit.encoding(), data)?;
- writeln!(w)?;
- }
- gimli::RawLocListEntry::DefaultLocation { ref data } => {
- write!(w, "<default location>")?;
- dump_exprloc(w, unit.encoding(), data)?;
- writeln!(w)?;
- }
- gimli::RawLocListEntry::StartEnd {
- begin,
- end,
- ref data,
- } => {
- write!(w, "<start-end 0x{:08x}, 0x{:08x}>", begin, end)?;
- dump_range(w, range)?;
- dump_exprloc(w, unit.encoding(), data)?;
- writeln!(w)?;
- }
- gimli::RawLocListEntry::StartLength {
- begin,
- length,
- ref data,
- } => {
- write!(w, "<start-length 0x{:08x}, 0x{:08x}>", begin, length)?;
- dump_range(w, range)?;
- dump_exprloc(w, unit.encoding(), data)?;
- writeln!(w)?;
- }
- };
- }
- Ok(())
-}
-
-fn dump_range_list<R: Reader, W: Write>(
- w: &mut W,
- offset: gimli::RangeListsOffset<R::Offset>,
- unit: &gimli::Unit<R>,
- dwarf: &gimli::Dwarf<R>,
-) -> Result<()> {
- let mut ranges = dwarf.ranges(unit, offset)?;
- writeln!(
- w,
- "<rnglist at {}+0x{:08x}>",
- if unit.encoding().version < 5 {
- ".debug_ranges"
- } else {
- ".debug_rnglists"
- },
- offset.0,
- )?;
- let mut i = 0;
- while let Some(raw) = ranges.next_raw()? {
- write!(w, "\t\t\t[{:2}] ", i)?;
- i += 1;
- let range = ranges.convert_raw(raw.clone())?;
- match raw {
- gimli::RawRngListEntry::BaseAddress { addr } => {
- writeln!(w, "<new base address 0x{:08x}>", addr)?;
- }
- gimli::RawRngListEntry::BaseAddressx { addr } => {
- let addr_val = dwarf.address(unit, addr)?;
- writeln!(w, "<new base addressx [{}]0x{:08x}>", addr.0, addr_val)?;
- }
- gimli::RawRngListEntry::StartxEndx { begin, end } => {
- let begin_val = dwarf.address(unit, begin)?;
- let end_val = dwarf.address(unit, end)?;
- write!(
- w,
- "<startx-endx [{}]0x{:08x}, [{}]0x{:08x}>",
- begin.0, begin_val, end.0, end_val,
- )?;
- dump_range(w, range)?;
- writeln!(w)?;
- }
- gimli::RawRngListEntry::StartxLength { begin, length } => {
- let begin_val = dwarf.address(unit, begin)?;
- write!(
- w,
- "<startx-length [{}]0x{:08x}, 0x{:08x}>",
- begin.0, begin_val, length,
- )?;
- dump_range(w, range)?;
- writeln!(w)?;
- }
- gimli::RawRngListEntry::AddressOrOffsetPair { begin, end }
- | gimli::RawRngListEntry::OffsetPair { begin, end } => {
- write!(w, "<offset-pair 0x{:08x}, 0x{:08x}>", begin, end)?;
- dump_range(w, range)?;
- writeln!(w)?;
- }
- gimli::RawRngListEntry::StartEnd { begin, end } => {
- write!(w, "<start-end 0x{:08x}, 0x{:08x}>", begin, end)?;
- dump_range(w, range)?;
- writeln!(w)?;
- }
- gimli::RawRngListEntry::StartLength { begin, length } => {
- write!(w, "<start-length 0x{:08x}, 0x{:08x}>", begin, length)?;
- dump_range(w, range)?;
- writeln!(w)?;
- }
- };
- }
- Ok(())
-}
-
-fn dump_line<R: Reader, W: Write>(w: &mut W, dwarf: &gimli::Dwarf<R>) -> Result<()> {
- let mut iter = dwarf.units();
- while let Some(header) = iter.next()? {
- writeln!(
- w,
- "\n.debug_line: line number info for unit at .debug_info offset 0x{:08x}",
- header.offset().as_debug_info_offset().unwrap().0
- )?;
- let unit = match dwarf.unit(header) {
- Ok(unit) => unit,
- Err(err) => {
- writeln_error(
- w,
- dwarf,
- err.into(),
- "Failed to parse unit root entry for dump_line",
- )?;
- continue;
- }
- };
- match dump_line_program(w, &unit, dwarf) {
- Ok(_) => (),
- Err(Error::IoError) => return Err(Error::IoError),
- Err(err) => writeln_error(w, dwarf, err, "Failed to dump line program")?,
- }
- }
- Ok(())
-}
-
-fn dump_line_program<R: Reader, W: Write>(
- w: &mut W,
- unit: &gimli::Unit<R>,
- dwarf: &gimli::Dwarf<R>,
-) -> Result<()> {
- if let Some(program) = unit.line_program.clone() {
- {
- let header = program.header();
- writeln!(w)?;
- writeln!(
- w,
- "Offset: 0x{:x}",
- header.offset().0
- )?;
- writeln!(
- w,
- "Length: {}",
- header.unit_length()
- )?;
- writeln!(
- w,
- "DWARF version: {}",
- header.version()
- )?;
- writeln!(
- w,
- "Address size: {}",
- header.address_size()
- )?;
- writeln!(
- w,
- "Prologue length: {}",
- header.header_length()
- )?;
- writeln!(
- w,
- "Minimum instruction length: {}",
- header.minimum_instruction_length()
- )?;
- writeln!(
- w,
- "Maximum operations per instruction: {}",
- header.maximum_operations_per_instruction()
- )?;
- writeln!(
- w,
- "Default is_stmt: {}",
- header.default_is_stmt()
- )?;
- writeln!(
- w,
- "Line base: {}",
- header.line_base()
- )?;
- writeln!(
- w,
- "Line range: {}",
- header.line_range()
- )?;
- writeln!(
- w,
- "Opcode base: {}",
- header.opcode_base()
- )?;
-
- writeln!(w)?;
- writeln!(w, "Opcodes:")?;
- for (i, length) in header
- .standard_opcode_lengths()
- .to_slice()?
- .iter()
- .enumerate()
- {
- writeln!(w, " Opcode {} has {} args", i + 1, length)?;
- }
-
- let base = if header.version() >= 5 { 0 } else { 1 };
- writeln!(w)?;
- writeln!(w, "The Directory Table:")?;
- for (i, dir) in header.include_directories().iter().enumerate() {
- writeln!(
- w,
- " {} {}",
- base + i,
- dwarf.attr_string(unit, dir.clone())?.to_string_lossy()?
- )?;
- }
-
- writeln!(w)?;
- writeln!(w, "The File Name Table")?;
- write!(w, " Entry\tDir\tTime\tSize")?;
- if header.file_has_md5() {
- write!(w, "\tMD5\t\t\t\t")?;
- }
- writeln!(w, "\tName")?;
- for (i, file) in header.file_names().iter().enumerate() {
- write!(
- w,
- " {}\t{}\t{}\t{}",
- base + i,
- file.directory_index(),
- file.timestamp(),
- file.size(),
- )?;
- if header.file_has_md5() {
- let md5 = file.md5();
- write!(w, "\t")?;
- for i in 0..16 {
- write!(w, "{:02X}", md5[i])?;
- }
- }
- writeln!(
- w,
- "\t{}",
- dwarf
- .attr_string(unit, file.path_name())?
- .to_string_lossy()?
- )?;
- }
-
- writeln!(w)?;
- writeln!(w, "Line Number Instructions:")?;
- let mut instructions = header.instructions();
- while let Some(instruction) = instructions.next_instruction(header)? {
- writeln!(w, " {}", instruction)?;
- }
-
- writeln!(w)?;
- writeln!(w, "Line Number Rows:")?;
- writeln!(w, "<pc> [lno,col]")?;
- }
- let mut rows = program.rows();
- let mut file_index = std::u64::MAX;
- while let Some((header, row)) = rows.next_row()? {
- let line = match row.line() {
- Some(line) => line.get(),
- None => 0,
- };
- let column = match row.column() {
- gimli::ColumnType::Column(column) => column.get(),
- gimli::ColumnType::LeftEdge => 0,
- };
- write!(w, "0x{:08x} [{:4},{:2}]", row.address(), line, column)?;
- if row.is_stmt() {
- write!(w, " NS")?;
- }
- if row.basic_block() {
- write!(w, " BB")?;
- }
- if row.end_sequence() {
- write!(w, " ET")?;
- }
- if row.prologue_end() {
- write!(w, " PE")?;
- }
- if row.epilogue_begin() {
- write!(w, " EB")?;
- }
- if row.isa() != 0 {
- write!(w, " IS={}", row.isa())?;
- }
- if row.discriminator() != 0 {
- write!(w, " DI={}", row.discriminator())?;
- }
- if file_index != row.file_index() {
- file_index = row.file_index();
- if let Some(file) = row.file(header) {
- if let Some(directory) = file.directory(header) {
- write!(
- w,
- " uri: \"{}/{}\"",
- dwarf.attr_string(unit, directory)?.to_string_lossy()?,
- dwarf
- .attr_string(unit, file.path_name())?
- .to_string_lossy()?
- )?;
- } else {
- write!(
- w,
- " uri: \"{}\"",
- dwarf
- .attr_string(unit, file.path_name())?
- .to_string_lossy()?
- )?;
- }
- }
- }
- writeln!(w)?;
- }
- }
- Ok(())
-}
-
-fn dump_pubnames<R: Reader, W: Write>(
- w: &mut W,
- debug_pubnames: &gimli::DebugPubNames<R>,
- debug_info: &gimli::DebugInfo<R>,
-) -> Result<()> {
- writeln!(w, "\n.debug_pubnames")?;
-
- let mut cu_offset;
- let mut cu_die_offset = gimli::DebugInfoOffset(0);
- let mut prev_cu_offset = None;
- let mut pubnames = debug_pubnames.items();
- while let Some(pubname) = pubnames.next()? {
- cu_offset = pubname.unit_header_offset();
- if Some(cu_offset) != prev_cu_offset {
- let cu = debug_info.header_from_offset(cu_offset)?;
- cu_die_offset = gimli::DebugInfoOffset(cu_offset.0 + cu.header_size());
- prev_cu_offset = Some(cu_offset);
- }
- let die_in_cu = pubname.die_offset();
- let die_in_sect = cu_offset.0 + die_in_cu.0;
- writeln!(w,
- "global die-in-sect 0x{:08x}, cu-in-sect 0x{:08x}, die-in-cu 0x{:08x}, cu-header-in-sect 0x{:08x} '{}'",
- die_in_sect,
- cu_die_offset.0,
- die_in_cu.0,
- cu_offset.0,
- pubname.name().to_string_lossy()?
- )?;
- }
- Ok(())
-}
-
-fn dump_pubtypes<R: Reader, W: Write>(
- w: &mut W,
- debug_pubtypes: &gimli::DebugPubTypes<R>,
- debug_info: &gimli::DebugInfo<R>,
-) -> Result<()> {
- writeln!(w, "\n.debug_pubtypes")?;
-
- let mut cu_offset;
- let mut cu_die_offset = gimli::DebugInfoOffset(0);
- let mut prev_cu_offset = None;
- let mut pubtypes = debug_pubtypes.items();
- while let Some(pubtype) = pubtypes.next()? {
- cu_offset = pubtype.unit_header_offset();
- if Some(cu_offset) != prev_cu_offset {
- let cu = debug_info.header_from_offset(cu_offset)?;
- cu_die_offset = gimli::DebugInfoOffset(cu_offset.0 + cu.header_size());
- prev_cu_offset = Some(cu_offset);
- }
- let die_in_cu = pubtype.die_offset();
- let die_in_sect = cu_offset.0 + die_in_cu.0;
- writeln!(w,
- "pubtype die-in-sect 0x{:08x}, cu-in-sect 0x{:08x}, die-in-cu 0x{:08x}, cu-header-in-sect 0x{:08x} '{}'",
- die_in_sect,
- cu_die_offset.0,
- die_in_cu.0,
- cu_offset.0,
- pubtype.name().to_string_lossy()?
- )?;
- }
- Ok(())
-}
-
-fn dump_aranges<R: Reader, W: Write>(
- w: &mut W,
- debug_aranges: &gimli::DebugAranges<R>,
-) -> Result<()> {
- writeln!(w, "\n.debug_aranges")?;
-
- let mut headers = debug_aranges.headers();
- while let Some(header) = headers.next()? {
- writeln!(
- w,
- "Address Range Header: length = 0x{:08x}, version = 0x{:04x}, cu_offset = 0x{:08x}, addr_size = 0x{:02x}, seg_size = 0x{:02x}",
- header.length(),
- header.encoding().version,
- header.debug_info_offset().0,
- header.encoding().address_size,
- header.segment_size(),
- )?;
- let mut aranges = header.entries();
- while let Some(arange) = aranges.next()? {
- let range = arange.range();
- if let Some(segment) = arange.segment() {
- writeln!(
- w,
- "[0x{:016x}, 0x{:016x}) segment 0x{:x}",
- range.begin, range.end, segment
- )?;
- } else {
- writeln!(w, "[0x{:016x}, 0x{:016x})", range.begin, range.end)?;
- }
- }
- }
- Ok(())
-}
diff --git a/vendor/gimli/examples/simple.rs b/vendor/gimli/examples/simple.rs
deleted file mode 100644
index 7c958d45c..000000000
--- a/vendor/gimli/examples/simple.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-//! A simple example of parsing `.debug_info`.
-
-use object::{Object, ObjectSection};
-use std::{borrow, env, fs};
-
-fn main() {
- for path in env::args().skip(1) {
- let file = fs::File::open(&path).unwrap();
- let mmap = unsafe { memmap2::Mmap::map(&file).unwrap() };
- let object = object::File::parse(&*mmap).unwrap();
- let endian = if object.is_little_endian() {
- gimli::RunTimeEndian::Little
- } else {
- gimli::RunTimeEndian::Big
- };
- dump_file(&object, endian).unwrap();
- }
-}
-
-fn dump_file(object: &object::File, endian: gimli::RunTimeEndian) -> Result<(), gimli::Error> {
- // Load a section and return as `Cow<[u8]>`.
- let load_section = |id: gimli::SectionId| -> Result<borrow::Cow<[u8]>, gimli::Error> {
- match object.section_by_name(id.name()) {
- Some(ref section) => Ok(section
- .uncompressed_data()
- .unwrap_or(borrow::Cow::Borrowed(&[][..]))),
- None => Ok(borrow::Cow::Borrowed(&[][..])),
- }
- };
-
- // Load all of the sections.
- let dwarf_cow = gimli::Dwarf::load(&load_section)?;
-
- // Borrow a `Cow<[u8]>` to create an `EndianSlice`.
- let borrow_section: &dyn for<'a> Fn(
- &'a borrow::Cow<[u8]>,
- ) -> gimli::EndianSlice<'a, gimli::RunTimeEndian> =
- &|section| gimli::EndianSlice::new(&*section, endian);
-
- // Create `EndianSlice`s for all of the sections.
- let dwarf = dwarf_cow.borrow(&borrow_section);
-
- // Iterate over the compilation units.
- let mut iter = dwarf.units();
- while let Some(header) = iter.next()? {
- println!(
- "Unit at <.debug_info+0x{:x}>",
- header.offset().as_debug_info_offset().unwrap().0
- );
- let unit = dwarf.unit(header)?;
-
- // Iterate over the Debugging Information Entries (DIEs) in the unit.
- let mut depth = 0;
- let mut entries = unit.entries();
- while let Some((delta_depth, entry)) = entries.next_dfs()? {
- depth += delta_depth;
- println!("<{}><{:x}> {}", depth, entry.offset().0, entry.tag());
-
- // Iterate over the attributes in the DIE.
- let mut attrs = entry.attrs();
- while let Some(attr) = attrs.next()? {
- println!(" {}: {:?}", attr.name(), attr.value());
- }
- }
- }
- Ok(())
-}
diff --git a/vendor/gimli/examples/simple_line.rs b/vendor/gimli/examples/simple_line.rs
deleted file mode 100644
index 87b224cda..000000000
--- a/vendor/gimli/examples/simple_line.rs
+++ /dev/null
@@ -1,106 +0,0 @@
-//! A simple example of parsing `.debug_line`.
-
-use object::{Object, ObjectSection};
-use std::{borrow, env, fs, path};
-
-fn main() {
- for path in env::args().skip(1) {
- let file = fs::File::open(&path).unwrap();
- let mmap = unsafe { memmap2::Mmap::map(&file).unwrap() };
- let object = object::File::parse(&*mmap).unwrap();
- let endian = if object.is_little_endian() {
- gimli::RunTimeEndian::Little
- } else {
- gimli::RunTimeEndian::Big
- };
- dump_file(&object, endian).unwrap();
- }
-}
-
-fn dump_file(object: &object::File, endian: gimli::RunTimeEndian) -> Result<(), gimli::Error> {
- // Load a section and return as `Cow<[u8]>`.
- let load_section = |id: gimli::SectionId| -> Result<borrow::Cow<[u8]>, gimli::Error> {
- match object.section_by_name(id.name()) {
- Some(ref section) => Ok(section
- .uncompressed_data()
- .unwrap_or(borrow::Cow::Borrowed(&[][..]))),
- None => Ok(borrow::Cow::Borrowed(&[][..])),
- }
- };
-
- // Load all of the sections.
- let dwarf_cow = gimli::Dwarf::load(&load_section)?;
-
- // Borrow a `Cow<[u8]>` to create an `EndianSlice`.
- let borrow_section: &dyn for<'a> Fn(
- &'a borrow::Cow<[u8]>,
- ) -> gimli::EndianSlice<'a, gimli::RunTimeEndian> =
- &|section| gimli::EndianSlice::new(&*section, endian);
-
- // Create `EndianSlice`s for all of the sections.
- let dwarf = dwarf_cow.borrow(&borrow_section);
-
- // Iterate over the compilation units.
- let mut iter = dwarf.units();
- while let Some(header) = iter.next()? {
- println!(
- "Line number info for unit at <.debug_info+0x{:x}>",
- header.offset().as_debug_info_offset().unwrap().0
- );
- let unit = dwarf.unit(header)?;
-
- // Get the line program for the compilation unit.
- if let Some(program) = unit.line_program.clone() {
- let comp_dir = if let Some(ref dir) = unit.comp_dir {
- path::PathBuf::from(dir.to_string_lossy().into_owned())
- } else {
- path::PathBuf::new()
- };
-
- // Iterate over the line program rows.
- let mut rows = program.rows();
- while let Some((header, row)) = rows.next_row()? {
- if row.end_sequence() {
- // End of sequence indicates a possible gap in addresses.
- println!("{:x} end-sequence", row.address());
- } else {
- // Determine the path. Real applications should cache this for performance.
- let mut path = path::PathBuf::new();
- if let Some(file) = row.file(header) {
- path = comp_dir.clone();
-
- // The directory index 0 is defined to correspond to the compilation unit directory.
- if file.directory_index() != 0 {
- if let Some(dir) = file.directory(header) {
- path.push(
- dwarf.attr_string(&unit, dir)?.to_string_lossy().as_ref(),
- );
- }
- }
-
- path.push(
- dwarf
- .attr_string(&unit, file.path_name())?
- .to_string_lossy()
- .as_ref(),
- );
- }
-
- // Determine line/column. DWARF line/column is never 0, so we use that
- // but other applications may want to display this differently.
- let line = match row.line() {
- Some(line) => line.get(),
- None => 0,
- };
- let column = match row.column() {
- gimli::ColumnType::LeftEdge => 0,
- gimli::ColumnType::Column(column) => column.get(),
- };
-
- println!("{:x} {}:{}:{}", row.address(), path.display(), line, column);
- }
- }
- }
- }
- Ok(())
-}
diff --git a/vendor/gimli/fixtures/self/README.md b/vendor/gimli/fixtures/self/README.md
deleted file mode 100644
index 91053d9b4..000000000
--- a/vendor/gimli/fixtures/self/README.md
+++ /dev/null
@@ -1,147 +0,0 @@
-# What are these files?
-
-These files are the DWARF data generated for (an early version of) this
-library. Each file corresponds is a section from the built library's object
-file. By splitting the sections out to their own files, we don't need to worry
-about cross platform and cross object file format issues when running examples.
-
-# Updating and adding new sections
-
-## macOS
-
-Use `otool` to list the sections of a binary:
-
-```
-$ otool -l path/to/binary
-```
-
-You should see output similar to this:
-
-```
-Load command 0
- cmd LC_SEGMENT_64
- cmdsize 72
- segname __PAGEZERO
- vmaddr 0x0000000000000000
- vmsize 0x0000000100000000
- fileoff 0
- filesize 0
- maxprot 0x00000000
- initprot 0x00000000
- nsects 0
- flags 0x0
-Load command 1
- cmd LC_SEGMENT_64
- cmdsize 712
- segname __TEXT
- vmaddr 0x0000000100000000
- vmsize 0x00000000001b7000
- fileoff 0
- filesize 1798144
- maxprot 0x00000007
- initprot 0x00000005
- nsects 8
- flags 0x0
-Section
- sectname __text
- segname __TEXT
- addr 0x0000000100000a50
- size 0x0000000000170716
- offset 2640
- align 2^4 (16)
- reloff 0
- nreloc 0
- flags 0x80000400
- reserved1 0
- reserved2 0
-```
-
-Etc.
-
-Find the `Section` entry of the section you'd like to isolate. For example, if
-you're looking for `eh_frame`, find an entry like this:
-
-```
-Section
- sectname __eh_frame
- segname __TEXT
- addr 0x0000000100192f38
- size 0x00000000000240c8
- offset 1650488
- align 2^3 (8)
- reloff 0
- nreloc 0
- flags 0x00000000
- reserved1 0
- reserved2 0
-```
-
-Then use `dd` to copy `size` bytes starting from `offset`:
-
-```
-$ dd bs=1 skip=1650488 count=$(printf "%d" 0x00000000000240c8) if=path/to/binary of=fixtures/self/eh_frame
-```
-
-Finally, use `otool` and `hexdump` to verify that the isolated section has the
-same data as the section within the binary:
-
-```
-$ otool -s __TEXT __eh_frame path/to/binary | head
-path/to/binary:
-Contents of (__TEXT,__eh_frame) section
-0000000100192f38 14 00 00 00 00 00 00 00 01 7a 52 00 01 78 10 01
-0000000100192f48 10 0c 07 08 90 01 00 00 24 00 00 00 1c 00 00 00
-0000000100192f58 f8 da e6 ff ff ff ff ff 66 00 00 00 00 00 00 00
-0000000100192f68 00 41 0e 10 86 02 43 0d 06 00 00 00 00 00 00 00
-0000000100192f78 1c 00 00 00 00 00 00 00 01 7a 50 4c 52 00 01 78
-0000000100192f88 10 07 9b 9d 40 02 00 10 10 0c 07 08 90 01 00 00
-0000000100192f98 2c 00 00 00 24 00 00 00 20 db e6 ff ff ff ff ff
-0000000100192fa8 8d 00 00 00 00 00 00 00 08 37 e7 fd ff ff ff ff
-
-$ otool -s __TEXT __eh_frame path/to/binary | tail
-00000001001b6f68 9a 0a 00 00 00 00 00 00 00 41 0e 10 86 02 43 0d
-00000001001b6f78 06 50 83 07 8c 06 8d 05 8e 04 8f 03 00 00 00 00
-00000001001b6f88 24 00 00 00 7c 0e 00 00 30 a0 fb ff ff ff ff ff
-00000001001b6f98 15 00 00 00 00 00 00 00 00 41 0e 10 86 02 43 0d
-00000001001b6fa8 06 00 00 00 00 00 00 00 24 00 00 00 a4 0e 00 00
-00000001001b6fb8 28 a0 fb ff ff ff ff ff 1c 00 00 00 00 00 00 00
-00000001001b6fc8 00 41 0e 10 86 02 43 0d 06 00 00 00 00 00 00 00
-00000001001b6fd8 24 00 00 00 cc 0e 00 00 20 a0 fb ff ff ff ff ff
-00000001001b6fe8 66 01 00 00 00 00 00 00 00 41 0e 10 86 02 43 0d
-00000001001b6ff8 06 00 00 00 00 00 00 00
-```
-
-This should be the same, ignoring the leading offsets:
-
-```
-$ hexdump fixtures/self/eh_frame | head
-0000000 14 00 00 00 00 00 00 00 01 7a 52 00 01 78 10 01
-0000010 10 0c 07 08 90 01 00 00 24 00 00 00 1c 00 00 00
-0000020 f8 da e6 ff ff ff ff ff 66 00 00 00 00 00 00 00
-0000030 00 41 0e 10 86 02 43 0d 06 00 00 00 00 00 00 00
-0000040 1c 00 00 00 00 00 00 00 01 7a 50 4c 52 00 01 78
-0000050 10 07 9b 9d 40 02 00 10 10 0c 07 08 90 01 00 00
-0000060 2c 00 00 00 24 00 00 00 20 db e6 ff ff ff ff ff
-0000070 8d 00 00 00 00 00 00 00 08 37 e7 fd ff ff ff ff
-0000080 ff 41 0e 10 86 02 43 0d 06 00 00 00 00 00 00 00
-0000090 24 00 00 00 94 00 00 00 80 db e6 ff ff ff ff ff
-
-$ hexdump fixtures/self/eh_frame | tail
-0024040 06 50 83 07 8c 06 8d 05 8e 04 8f 03 00 00 00 00
-0024050 24 00 00 00 7c 0e 00 00 30 a0 fb ff ff ff ff ff
-0024060 15 00 00 00 00 00 00 00 00 41 0e 10 86 02 43 0d
-0024070 06 00 00 00 00 00 00 00 24 00 00 00 a4 0e 00 00
-0024080 28 a0 fb ff ff ff ff ff 1c 00 00 00 00 00 00 00
-0024090 00 41 0e 10 86 02 43 0d 06 00 00 00 00 00 00 00
-00240a0 24 00 00 00 cc 0e 00 00 20 a0 fb ff ff ff ff ff
-00240b0 66 01 00 00 00 00 00 00 00 41 0e 10 86 02 43 0d
-00240c0 06 00 00 00 00 00 00 00
-```
-
-## Linux
-
-Something like this:
-
-```
-objcopy --dump-section .eh_frame=fixtures/self/eh_frame path/to/binary
-```
diff --git a/vendor/gimli/fixtures/self/debug_abbrev b/vendor/gimli/fixtures/self/debug_abbrev
deleted file mode 100644
index 809e61152..000000000
--- a/vendor/gimli/fixtures/self/debug_abbrev
+++ /dev/null
Binary files differ
diff --git a/vendor/gimli/fixtures/self/debug_aranges b/vendor/gimli/fixtures/self/debug_aranges
deleted file mode 100644
index b2d983d78..000000000
--- a/vendor/gimli/fixtures/self/debug_aranges
+++ /dev/null
Binary files differ
diff --git a/vendor/gimli/fixtures/self/debug_info b/vendor/gimli/fixtures/self/debug_info
deleted file mode 100644
index aa430a5ce..000000000
--- a/vendor/gimli/fixtures/self/debug_info
+++ /dev/null
Binary files differ
diff --git a/vendor/gimli/fixtures/self/debug_inlined b/vendor/gimli/fixtures/self/debug_inlined
deleted file mode 100644
index 949d18c93..000000000
--- a/vendor/gimli/fixtures/self/debug_inlined
+++ /dev/null
Binary files differ
diff --git a/vendor/gimli/fixtures/self/debug_line b/vendor/gimli/fixtures/self/debug_line
deleted file mode 100644
index 896a07364..000000000
--- a/vendor/gimli/fixtures/self/debug_line
+++ /dev/null
Binary files differ
diff --git a/vendor/gimli/fixtures/self/debug_loc b/vendor/gimli/fixtures/self/debug_loc
deleted file mode 100644
index 3fcdb32ba..000000000
--- a/vendor/gimli/fixtures/self/debug_loc
+++ /dev/null
Binary files differ
diff --git a/vendor/gimli/fixtures/self/debug_pubnames b/vendor/gimli/fixtures/self/debug_pubnames
deleted file mode 100644
index bbcd62e24..000000000
--- a/vendor/gimli/fixtures/self/debug_pubnames
+++ /dev/null
Binary files differ
diff --git a/vendor/gimli/fixtures/self/debug_pubtypes b/vendor/gimli/fixtures/self/debug_pubtypes
deleted file mode 100644
index 68b4e0405..000000000
--- a/vendor/gimli/fixtures/self/debug_pubtypes
+++ /dev/null
Binary files differ
diff --git a/vendor/gimli/fixtures/self/debug_ranges b/vendor/gimli/fixtures/self/debug_ranges
deleted file mode 100644
index a5f52ed4a..000000000
--- a/vendor/gimli/fixtures/self/debug_ranges
+++ /dev/null
Binary files differ
diff --git a/vendor/gimli/fixtures/self/debug_str b/vendor/gimli/fixtures/self/debug_str
deleted file mode 100644
index da35ee574..000000000
--- a/vendor/gimli/fixtures/self/debug_str
+++ /dev/null
Binary files differ
diff --git a/vendor/gimli/fixtures/self/eh_frame b/vendor/gimli/fixtures/self/eh_frame
deleted file mode 100644
index 1d4df1a61..000000000
--- a/vendor/gimli/fixtures/self/eh_frame
+++ /dev/null
Binary files differ
diff --git a/vendor/gimli/fixtures/self/eh_frame_hdr b/vendor/gimli/fixtures/self/eh_frame_hdr
deleted file mode 100644
index a590ba213..000000000
--- a/vendor/gimli/fixtures/self/eh_frame_hdr
+++ /dev/null
Binary files differ
diff --git a/vendor/gimli/rustfmt.toml b/vendor/gimli/rustfmt.toml
deleted file mode 100644
index e69de29bb..000000000
--- a/vendor/gimli/rustfmt.toml
+++ /dev/null
diff --git a/vendor/gimli/src/arch.rs b/vendor/gimli/src/arch.rs
index abc872d83..adb405280 100644
--- a/vendor/gimli/src/arch.rs
+++ b/vendor/gimli/src/arch.rs
@@ -44,7 +44,8 @@ macro_rules! registers {
/// ARM architecture specific definitions.
///
-/// See [DWARF for the ARM Architecture](https://developer.arm.com/documentation/ihi0040/c/).
+/// See [DWARF for the ARM Architecture](
+/// https://github.com/ARM-software/abi-aa/blob/main/aadwarf32/aadwarf32.rst).
#[derive(Debug, Clone, Copy)]
pub struct Arm;
@@ -99,6 +100,8 @@ registers!(Arm, {
SPSR_UND = (132, "SPSR_UND"),
SPSR_SVC = (133, "SPSR_SVC"),
+ RA_AUTH_CODE = (143, "RA_AUTH_CODE"),
+
R8_USR = (144, "R8_USR"),
R9_USR = (145, "R9_USR"),
R10_USR = (146, "R10_USR"),
@@ -168,6 +171,11 @@ registers!(Arm, {
D29 = (285, "D29"),
D30 = (286, "D30"),
D31 = (287, "D31"),
+
+ TPIDRURO = (320, "TPIDRURO"),
+ TPIDRURW = (321, "TPIDRURW"),
+ TPIDPR = (322, "TPIDPR"),
+ HTPIDPR = (323, "HTPIDPR"),
},
aliases {
SP = (13, "SP"),
@@ -219,7 +227,8 @@ aliases {
/// ARM 64-bit (AArch64) architecture specific definitions.
///
-/// See [DWARF for the ARM 64-bit Architecture](https://developer.arm.com/documentation/ihi0057/b/).
+/// See [DWARF for the ARM 64-bit Architecture](
+/// https://github.com/ARM-software/abi-aa/blob/main/aadwarf64/aadwarf64.rst).
#[derive(Debug, Clone, Copy)]
pub struct AArch64;
@@ -256,6 +265,14 @@ registers!(AArch64, {
X29 = (29, "X29"),
X30 = (30, "X30"),
SP = (31, "SP"),
+ PC = (32, "PC"),
+ ELR_MODE = (33, "ELR_mode"),
+ RA_SIGN_STATE = (34, "RA_SIGN_STATE"),
+ TPIDRRO_EL0 = (35, "TPIDRRO_EL0"),
+ TPIDR_EL0 = (36, "TPIDR_EL0"),
+ TPIDR_EL1 = (37, "TPIDR_EL1"),
+ TPIDR_EL2 = (38, "TPIDR_EL2"),
+ TPIDR_EL3 = (39, "TPIDR_EL3"),
V0 = (64, "V0"),
V1 = (65, "V1"),
diff --git a/vendor/gimli/src/common.rs b/vendor/gimli/src/common.rs
index 3c8073622..fc6693d1c 100644
--- a/vendor/gimli/src/common.rs
+++ b/vendor/gimli/src/common.rs
@@ -27,6 +27,16 @@ impl Format {
}
}
+/// Which vendor extensions to support.
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+#[non_exhaustive]
+pub enum Vendor {
+ /// A default set of extensions, including some common GNU extensions.
+ Default,
+ /// AAarch64 extensions.
+ AArch64,
+}
+
/// Encoding parameters that are commonly used for multiple DWARF sections.
///
/// This is intended to be small enough to pass by value.
diff --git a/vendor/gimli/src/constants.rs b/vendor/gimli/src/constants.rs
index c617f4e2e..e58050ba0 100644
--- a/vendor/gimli/src/constants.rs
+++ b/vendor/gimli/src/constants.rs
@@ -56,7 +56,10 @@ use core::fmt;
// }
// }
macro_rules! dw {
- ($(#[$meta:meta])* $struct_name:ident($struct_type:ty) { $($name:ident = $val:expr),+ $(,)? }) => {
+ ($(#[$meta:meta])* $struct_name:ident($struct_type:ty)
+ { $($name:ident = $val:expr),+ $(,)? }
+ $(, aliases { $($alias_name:ident = $alias_val:expr),+ $(,)? })?
+ ) => {
$(#[$meta])*
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct $struct_name(pub $struct_type);
@@ -64,6 +67,9 @@ macro_rules! dw {
$(
pub const $name: $struct_name = $struct_name($val);
)+
+ $($(
+ pub const $alias_name: $struct_name = $struct_name($alias_val);
+ )+)*
impl $struct_name {
pub fn static_string(&self) -> Option<&'static str> {
@@ -182,6 +188,9 @@ DwCfa(u8) {
DW_CFA_GNU_window_save = 0x2d,
DW_CFA_GNU_args_size = 0x2e,
DW_CFA_GNU_negative_offset_extended = 0x2f,
+},
+aliases {
+ DW_CFA_AARCH64_negate_ra_state = 0x2d,
});
dw!(
@@ -529,6 +538,7 @@ DwAt(u16) {
DW_AT_GNU_all_call_sites = 0x2117,
DW_AT_GNU_all_source_call_sites = 0x2118,
DW_AT_GNU_macros = 0x2119,
+ DW_AT_GNU_deleted = 0x211a,
// Extensions for Fission proposal.
DW_AT_GNU_dwo_name = 0x2130,
@@ -1276,7 +1286,7 @@ dw!(
/// format of the pointer, the upper four bits describe how the encoding should
/// be applied.
///
-/// Defined in https://refspecs.linuxfoundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html
+/// Defined in `<https://refspecs.linuxfoundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html>`
DwEhPe(u8) {
// Format of pointer encoding.
diff --git a/vendor/gimli/src/lib.rs b/vendor/gimli/src/lib.rs
index db30375aa..5dea34439 100644
--- a/vendor/gimli/src/lib.rs
+++ b/vendor/gimli/src/lib.rs
@@ -48,7 +48,7 @@ extern crate alloc;
#[macro_use]
extern crate std;
-#[cfg(feature = "stable_deref_trait")]
+#[cfg(feature = "endian-reader")]
pub use stable_deref_trait::{CloneStableDeref, StableDeref};
mod common;
@@ -62,7 +62,7 @@ pub mod constants;
pub use crate::constants::*;
mod endianity;
-pub use crate::endianity::{BigEndian, Endianity, LittleEndian, NativeEndian, RunTimeEndian};
+pub use crate::endianity::*;
pub mod leb128;
diff --git a/vendor/gimli/src/read/cfi.rs b/vendor/gimli/src/read/cfi.rs
index 5e9befac1..6ac019f10 100644
--- a/vendor/gimli/src/read/cfi.rs
+++ b/vendor/gimli/src/read/cfi.rs
@@ -8,7 +8,9 @@ use core::mem;
use core::num::Wrapping;
use super::util::{ArrayLike, ArrayVec};
-use crate::common::{DebugFrameOffset, EhFrameOffset, Encoding, Format, Register, SectionId};
+use crate::common::{
+ DebugFrameOffset, EhFrameOffset, Encoding, Format, Register, SectionId, Vendor,
+};
use crate::constants::{self, DwEhPe};
use crate::endianity::Endianity;
use crate::read::{
@@ -34,6 +36,7 @@ pub struct DebugFrame<R: Reader> {
section: R,
address_size: u8,
segment_size: u8,
+ vendor: Vendor,
}
impl<R: Reader> DebugFrame<R> {
@@ -52,6 +55,13 @@ impl<R: Reader> DebugFrame<R> {
pub fn set_segment_size(&mut self, segment_size: u8) {
self.segment_size = segment_size
}
+
+ /// Set the vendor extensions to use.
+ ///
+ /// This defaults to `Vendor::Default`.
+ pub fn set_vendor(&mut self, vendor: Vendor) {
+ self.vendor = vendor;
+ }
}
impl<'input, Endian> DebugFrame<EndianSlice<'input, Endian>>
@@ -95,6 +105,7 @@ impl<R: Reader> From<R> for DebugFrame<R> {
section,
address_size: mem::size_of::<usize>() as u8,
segment_size: 0,
+ vendor: Vendor::Default,
}
}
}
@@ -158,11 +169,7 @@ impl<R: Reader> EhFrameHdr<R> {
if fde_count_enc == constants::DW_EH_PE_omit || table_enc == constants::DW_EH_PE_omit {
fde_count = 0
} else {
- let ptr = parse_encoded_pointer(fde_count_enc, &parameters, &mut reader)?;
- fde_count = match ptr {
- Pointer::Direct(c) => c,
- Pointer::Indirect(_) => return Err(Error::UnsupportedPointerEncoding),
- }
+ fde_count = parse_encoded_pointer(fde_count_enc, &parameters, &mut reader)?.direct()?;
}
Ok(ParsedEhFrameHdr {
@@ -348,11 +355,8 @@ impl<'a, R: Reader + 'a> EhHdrTable<'a, R> {
let head = reader.split(R::Offset::from_u64((len / 2) * row_size)?)?;
let tail = reader.clone();
- let pivot = parse_encoded_pointer(self.hdr.table_enc, &parameters, &mut reader)?;
- let pivot = match pivot {
- Pointer::Direct(x) => x,
- Pointer::Indirect(_) => return Err(Error::UnsupportedPointerEncoding),
- };
+ let pivot =
+ parse_encoded_pointer(self.hdr.table_enc, &parameters, &mut reader)?.direct()?;
match pivot.cmp(&address) {
Ordering::Equal => {
@@ -379,15 +383,8 @@ impl<'a, R: Reader + 'a> EhHdrTable<'a, R> {
///
/// This does not support indirect pointers.
pub fn pointer_to_offset(&self, ptr: Pointer) -> Result<EhFrameOffset<R::Offset>> {
- let ptr = match ptr {
- Pointer::Direct(x) => x,
- _ => return Err(Error::UnsupportedPointerEncoding),
- };
-
- let eh_frame_ptr = match self.hdr.eh_frame_ptr() {
- Pointer::Direct(x) => x,
- _ => return Err(Error::UnsupportedPointerEncoding),
- };
+ let ptr = ptr.direct()?;
+ let eh_frame_ptr = self.hdr.eh_frame_ptr().direct()?;
// Calculate the offset in the EhFrame section
R::Offset::from_u64(ptr - eh_frame_ptr).map(EhFrameOffset)
@@ -496,6 +493,7 @@ impl<'a, R: Reader + 'a> EhHdrTable<'a, R> {
pub struct EhFrame<R: Reader> {
section: R,
address_size: u8,
+ vendor: Vendor,
}
impl<R: Reader> EhFrame<R> {
@@ -505,6 +503,13 @@ impl<R: Reader> EhFrame<R> {
pub fn set_address_size(&mut self, address_size: u8) {
self.address_size = address_size
}
+
+ /// Set the vendor extensions to use.
+ ///
+ /// This defaults to `Vendor::Default`.
+ pub fn set_vendor(&mut self, vendor: Vendor) {
+ self.vendor = vendor;
+ }
}
impl<'input, Endian> EhFrame<EndianSlice<'input, Endian>>
@@ -547,6 +552,7 @@ impl<R: Reader> From<R> for EhFrame<R> {
EhFrame {
section,
address_size: mem::size_of::<usize>() as u8,
+ vendor: Vendor::Default,
}
}
}
@@ -627,6 +633,9 @@ pub trait _UnwindSectionPrivate<R: Reader> {
/// The segment size to use if `has_address_and_segment_sizes` returns false.
fn segment_size(&self) -> u8;
+
+ /// The vendor extensions to use.
+ fn vendor(&self) -> Vendor;
}
/// A section holding unwind information: either `.debug_frame` or
@@ -822,6 +831,10 @@ impl<R: Reader> _UnwindSectionPrivate<R> for DebugFrame<R> {
fn segment_size(&self) -> u8 {
self.segment_size
}
+
+ fn vendor(&self) -> Vendor {
+ self.vendor
+ }
}
impl<R: Reader> UnwindSection<R> for DebugFrame<R> {
@@ -862,6 +875,10 @@ impl<R: Reader> _UnwindSectionPrivate<R> for EhFrame<R> {
fn segment_size(&self) -> u8 {
0
}
+
+ fn vendor(&self) -> Vendor {
+ self.vendor
+ }
}
impl<R: Reader> UnwindSection<R> for EhFrame<R> {
@@ -1435,6 +1452,7 @@ impl<R: Reader> CommonInformationEntry<R> {
address_size: self.address_size,
section: section.section(),
},
+ vendor: section.vendor(),
}
}
@@ -1683,12 +1701,12 @@ impl<R: Reader> FrameDescriptionEntry<R> {
let initial_address = parse_encoded_pointer(encoding, parameters, input)?;
// Ignore indirection.
- let initial_address = initial_address.into();
+ let initial_address = initial_address.pointer();
// Address ranges cannot be relative to anything, so just grab the
// data format bits from the encoding.
let address_range = parse_encoded_pointer(encoding.format(), parameters, input)?;
- Ok((initial_address, address_range.into()))
+ Ok((initial_address, address_range.pointer()))
} else {
let initial_address = input.read_address(cie.address_size)?;
let address_range = input.read_address(cie.address_size)?;
@@ -1778,6 +1796,7 @@ impl<R: Reader> FrameDescriptionEntry<R> {
address_size: self.cie.address_size,
section: section.section(),
},
+ vendor: section.vendor(),
}
}
@@ -2414,6 +2433,18 @@ impl<'a, 'ctx, R: Reader, A: UnwindContextStorage<R>> UnwindTable<'a, 'ctx, R, A
self.ctx.row_mut().saved_args_size = size;
}
+ // AArch64 extension.
+ NegateRaState => {
+ let register = crate::AArch64::RA_SIGN_STATE;
+ let value = match self.ctx.row().register(register) {
+ RegisterRule::Undefined => 0,
+ RegisterRule::Constant(value) => value,
+ _ => return Err(Error::CfiInstructionInInvalidContext),
+ };
+ self.ctx
+ .set_register_rule(register, RegisterRule::Constant(value ^ 1))?;
+ }
+
// No operation.
Nop => {}
};
@@ -2783,6 +2814,7 @@ impl<R: Reader> CfaRule<R> {
/// has been saved and the rule to find the value for the register in the
/// previous frame."
#[derive(Clone, Debug, PartialEq, Eq)]
+#[non_exhaustive]
pub enum RegisterRule<R: Reader> {
/// > A register that has this rule has no recoverable value in the previous
/// > frame. (By convention, it is not preserved by a callee.)
@@ -2815,6 +2847,9 @@ pub enum RegisterRule<R: Reader> {
/// "The rule is defined externally to this specification by the augmenter."
Architectural,
+
+ /// This is a pseudo-register with a constant value.
+ Constant(u64),
}
impl<R: Reader> RegisterRule<R> {
@@ -2825,6 +2860,7 @@ impl<R: Reader> RegisterRule<R> {
/// A parsed call frame instruction.
#[derive(Clone, Debug, PartialEq, Eq)]
+#[non_exhaustive]
pub enum CallFrameInstruction<R: Reader> {
// 6.4.2.1 Row Creation Methods
/// > 1. DW_CFA_set_loc
@@ -3102,6 +3138,17 @@ pub enum CallFrameInstruction<R: Reader> {
size: u64,
},
+ /// > DW_CFA_AARCH64_negate_ra_state
+ /// >
+ /// > AArch64 Extension
+ /// >
+ /// > The DW_CFA_AARCH64_negate_ra_state operation negates bit[0] of the
+ /// > RA_SIGN_STATE pseudo-register. It does not take any operands. The
+ /// > DW_CFA_AARCH64_negate_ra_state must not be mixed with other DWARF Register
+ /// > Rule Instructions on the RA_SIGN_STATE pseudo-register in one Common
+ /// > Information Entry (CIE) and Frame Descriptor Entry (FDE) program sequence.
+ NegateRaState,
+
// 6.4.2.5 Padding Instruction
/// > 1. DW_CFA_nop
/// >
@@ -3118,6 +3165,7 @@ impl<R: Reader> CallFrameInstruction<R> {
input: &mut R,
address_encoding: Option<DwEhPe>,
parameters: &PointerEncodingParameters<R>,
+ vendor: Vendor,
) -> Result<CallFrameInstruction<R>> {
let instruction = input.read_u8()?;
let high_bits = instruction & CFI_INSTRUCTION_HIGH_BITS_MASK;
@@ -3151,10 +3199,7 @@ impl<R: Reader> CallFrameInstruction<R> {
constants::DW_CFA_set_loc => {
let address = if let Some(encoding) = address_encoding {
- match parse_encoded_pointer(encoding, parameters, input)? {
- Pointer::Direct(x) => x,
- _ => return Err(Error::UnsupportedPointerEncoding),
- }
+ parse_encoded_pointer(encoding, parameters, input)?.direct()?
} else {
input.read_address(parameters.address_size)?
};
@@ -3309,6 +3354,10 @@ impl<R: Reader> CallFrameInstruction<R> {
Ok(CallFrameInstruction::ArgsSize { size })
}
+ constants::DW_CFA_AARCH64_negate_ra_state if vendor == Vendor::AArch64 => {
+ Ok(CallFrameInstruction::NegateRaState)
+ }
+
otherwise => Err(Error::UnknownCallFrameInstruction(otherwise)),
}
}
@@ -3323,6 +3372,7 @@ pub struct CallFrameInstructionIter<'a, R: Reader> {
input: R,
address_encoding: Option<constants::DwEhPe>,
parameters: PointerEncodingParameters<'a, R>,
+ vendor: Vendor,
}
impl<'a, R: Reader> CallFrameInstructionIter<'a, R> {
@@ -3332,8 +3382,12 @@ impl<'a, R: Reader> CallFrameInstructionIter<'a, R> {
return Ok(None);
}
- match CallFrameInstruction::parse(&mut self.input, self.address_encoding, &self.parameters)
- {
+ match CallFrameInstruction::parse(
+ &mut self.input,
+ self.address_encoding,
+ &self.parameters,
+ self.vendor,
+ ) {
Ok(instruction) => Ok(Some(instruction)),
Err(e) => {
self.input.empty();
@@ -3389,15 +3443,6 @@ impl Default for Pointer {
}
}
-impl From<Pointer> for u64 {
- #[inline]
- fn from(p: Pointer) -> u64 {
- match p {
- Pointer::Direct(p) | Pointer::Indirect(p) => p,
- }
- }
-}
-
impl Pointer {
#[inline]
fn new(encoding: constants::DwEhPe, address: u64) -> Pointer {
@@ -3407,6 +3452,23 @@ impl Pointer {
Pointer::Direct(address)
}
}
+
+ /// Return the direct pointer value.
+ #[inline]
+ pub fn direct(self) -> Result<u64> {
+ match self {
+ Pointer::Direct(p) => Ok(p),
+ Pointer::Indirect(_) => Err(Error::UnsupportedPointerEncoding),
+ }
+ }
+
+ /// Return the pointer value, discarding indirectness information.
+ #[inline]
+ pub fn pointer(self) -> u64 {
+ match self {
+ Pointer::Direct(p) | Pointer::Indirect(p) => p,
+ }
+ }
}
#[derive(Clone, Debug)]
@@ -3637,7 +3699,7 @@ mod tests {
.uleb(cie.code_alignment_factor)
.sleb(cie.data_alignment_factor)
.uleb(cie.return_address_register.0.into())
- .append_bytes(cie.initial_instructions.into())
+ .append_bytes(cie.initial_instructions.slice())
.mark(&end);
cie.length = (&end - &start) as usize;
@@ -3714,11 +3776,11 @@ mod tests {
let section = section.uleb(u64::from(fde.cie.address_size));
match fde.cie.address_size {
4 => section.D32({
- let x: u64 = lsda.into();
+ let x: u64 = lsda.pointer();
x as u32
}),
8 => section.D64({
- let x: u64 = lsda.into();
+ let x: u64 = lsda.pointer();
x
}),
x => panic!("Unsupported address size: {}", x),
@@ -3732,7 +3794,7 @@ mod tests {
section
};
- let section = section.append_bytes(fde.instructions.into()).mark(&end);
+ let section = section.append_bytes(fde.instructions.slice()).mark(&end);
fde.length = (&end - &start) as usize;
length.set_const(fde.length as u64);
@@ -4445,7 +4507,7 @@ mod tests {
address_size,
section: &R::default(),
};
- CallFrameInstruction::parse(input, None, parameters)
+ CallFrameInstruction::parse(input, None, parameters, Vendor::Default)
}
#[test]
@@ -4558,7 +4620,12 @@ mod tests {
section: &EndianSlice::new(&[], LittleEndian),
};
assert_eq!(
- CallFrameInstruction::parse(input, Some(constants::DW_EH_PE_textrel), parameters),
+ CallFrameInstruction::parse(
+ input,
+ Some(constants::DW_EH_PE_textrel),
+ parameters,
+ Vendor::Default
+ ),
Ok(CallFrameInstruction::SetLoc {
address: expected_addr,
})
@@ -5018,6 +5085,27 @@ mod tests {
}
#[test]
+ fn test_parse_cfi_instruction_negate_ra_state() {
+ let expected_rest = [1, 2, 3, 4];
+ let section = Section::with_endian(Endian::Little)
+ .D8(constants::DW_CFA_AARCH64_negate_ra_state.0)
+ .append_bytes(&expected_rest);
+ let contents = section.get_contents().unwrap();
+ let input = &mut EndianSlice::new(&contents, LittleEndian);
+ let parameters = &PointerEncodingParameters {
+ bases: &SectionBaseAddresses::default(),
+ func_base: None,
+ address_size: 8,
+ section: &EndianSlice::default(),
+ };
+ assert_eq!(
+ CallFrameInstruction::parse(input, None, parameters, Vendor::AArch64),
+ Ok(CallFrameInstruction::NegateRaState)
+ );
+ assert_eq!(*input, EndianSlice::new(&expected_rest, LittleEndian));
+ }
+
+ #[test]
fn test_parse_cfi_instruction_unknown_instruction() {
let expected_rest = [1, 2, 3, 4];
let unknown_instr = constants::DwCfa(0b0011_1111);
@@ -5065,6 +5153,7 @@ mod tests {
input,
address_encoding: None,
parameters,
+ vendor: Vendor::Default,
};
assert_eq!(
@@ -5102,6 +5191,7 @@ mod tests {
input,
address_encoding: None,
parameters,
+ vendor: Vendor::Default,
};
assert_eq!(
@@ -5580,6 +5670,55 @@ mod tests {
}
#[test]
+ fn test_eval_negate_ra_state() {
+ let cie = make_test_cie();
+ let ctx = UnwindContext::new();
+ let mut expected = ctx.clone();
+ expected
+ .set_register_rule(crate::AArch64::RA_SIGN_STATE, RegisterRule::Constant(1))
+ .unwrap();
+ let instructions = [(Ok(false), CallFrameInstruction::NegateRaState)];
+ assert_eval(ctx, expected, cie, None, instructions);
+
+ let cie = make_test_cie();
+ let ctx = UnwindContext::new();
+ let mut expected = ctx.clone();
+ expected
+ .set_register_rule(crate::AArch64::RA_SIGN_STATE, RegisterRule::Constant(0))
+ .unwrap();
+ let instructions = [
+ (Ok(false), CallFrameInstruction::NegateRaState),
+ (Ok(false), CallFrameInstruction::NegateRaState),
+ ];
+ assert_eval(ctx, expected, cie, None, instructions);
+
+ // NegateRaState can't be used with other instructions.
+ let cie = make_test_cie();
+ let ctx = UnwindContext::new();
+ let mut expected = ctx.clone();
+ expected
+ .set_register_rule(
+ crate::AArch64::RA_SIGN_STATE,
+ RegisterRule::Offset(cie.data_alignment_factor as i64),
+ )
+ .unwrap();
+ let instructions = [
+ (
+ Ok(false),
+ CallFrameInstruction::Offset {
+ register: crate::AArch64::RA_SIGN_STATE,
+ factored_offset: 1,
+ },
+ ),
+ (
+ Err(Error::CfiInstructionInInvalidContext),
+ CallFrameInstruction::NegateRaState,
+ ),
+ ];
+ assert_eval(ctx, expected, cie, None, instructions);
+ }
+
+ #[test]
fn test_eval_nop() {
let cie = make_test_cie();
let ctx = UnwindContext::new();
@@ -6262,7 +6401,6 @@ mod tests {
section.start().set_const(0);
let section = section.get_contents().unwrap();
- let section = EndianSlice::new(&section, LittleEndian);
let eh_frame = kind.section(&section);
// Setup eh_frame_hdr
diff --git a/vendor/gimli/src/read/endian_slice.rs b/vendor/gimli/src/read/endian_slice.rs
index d0fd67c0b..fbf5cbb79 100644
--- a/vendor/gimli/src/read/endian_slice.rs
+++ b/vendor/gimli/src/read/endian_slice.rs
@@ -4,7 +4,7 @@
use alloc::borrow::Cow;
#[cfg(feature = "read")]
use alloc::string::String;
-use core::ops::{Deref, Index, Range, RangeFrom, RangeTo};
+use core::ops::{Deref, Range, RangeFrom, RangeTo};
use core::str;
use crate::endianity::Endianity;
@@ -57,7 +57,7 @@ where
(self.range_to(..idx), self.range_from(idx..))
}
- /// Find the first occurence of a byte in the slice, and return its index.
+ /// Find the first occurrence of a byte in the slice, and return its index.
#[inline]
pub fn find(&self, byte: u8) -> Option<usize> {
self.slice.iter().position(|ch| *ch == byte)
@@ -167,26 +167,6 @@ where
}
}
-impl<'input, Endian> Index<usize> for EndianSlice<'input, Endian>
-where
- Endian: Endianity,
-{
- type Output = u8;
- fn index(&self, idx: usize) -> &Self::Output {
- &self.slice[idx]
- }
-}
-
-impl<'input, Endian> Index<RangeFrom<usize>> for EndianSlice<'input, Endian>
-where
- Endian: Endianity,
-{
- type Output = [u8];
- fn index(&self, idx: RangeFrom<usize>) -> &Self::Output {
- &self.slice[idx]
- }
-}
-
impl<'input, Endian> Deref for EndianSlice<'input, Endian>
where
Endian: Endianity,
@@ -197,15 +177,6 @@ where
}
}
-impl<'input, Endian> From<EndianSlice<'input, Endian>> for &'input [u8]
-where
- Endian: Endianity,
-{
- fn from(endian_slice: EndianSlice<'input, Endian>) -> &'input [u8] {
- endian_slice.slice
- }
-}
-
impl<'input, Endian> Reader for EndianSlice<'input, Endian>
where
Endian: Endianity,
diff --git a/vendor/gimli/src/read/line.rs b/vendor/gimli/src/read/line.rs
index 65400a99e..47eae92e6 100644
--- a/vendor/gimli/src/read/line.rs
+++ b/vendor/gimli/src/read/line.rs
@@ -2327,7 +2327,7 @@ mod tests {
fn test_parse_unknown_standard_opcode_many_args() {
let input = [OPCODE_BASE, 1, 2, 3];
let input = EndianSlice::new(&input, LittleEndian);
- let args = EndianSlice::new(&input[1..], LittleEndian);
+ let args = input.range_from(1..);
let mut standard_opcode_lengths = Vec::new();
let mut header = make_test_header(input);
standard_opcode_lengths.extend(header.standard_opcode_lengths.slice());
diff --git a/vendor/gimli/src/read/mod.rs b/vendor/gimli/src/read/mod.rs
index 82b79502d..22a8e9fbe 100644
--- a/vendor/gimli/src/read/mod.rs
+++ b/vendor/gimli/src/read/mod.rs
@@ -41,10 +41,10 @@
//!
//! Full example programs:
//!
-//! * [A simple parser](https://github.com/gimli-rs/gimli/blob/master/examples/simple.rs)
+//! * [A simple parser](https://github.com/gimli-rs/gimli/blob/master/crates/examples/src/bin/simple.rs)
//!
//! * [A `dwarfdump`
-//! clone](https://github.com/gimli-rs/gimli/blob/master/examples/dwarfdump.rs)
+//! clone](https://github.com/gimli-rs/gimli/blob/master/crates/examples/src/bin/dwarfdump.rs)
//!
//! * [An `addr2line` clone](https://github.com/gimli-rs/addr2line)
//!
@@ -55,7 +55,7 @@
//! compilers used to create each compilation unit within a shared library or
//! executable (via `DW_AT_producer`)
//!
-//! * [`dwarf-validate`](https://github.com/gimli-rs/gimli/blob/master/examples/dwarf-validate.rs),
+//! * [`dwarf-validate`](https://github.com/gimli-rs/gimli/blob/master/crates/examples/src/bin/dwarf-validate.rs),
//! a program to validate the integrity of some DWARF and its references
//! between sections and compilation units.
//!
diff --git a/vendor/gimli/src/read/op.rs b/vendor/gimli/src/read/op.rs
index 670d1ad21..0b6a71b48 100644
--- a/vendor/gimli/src/read/op.rs
+++ b/vendor/gimli/src/read/op.rs
@@ -985,6 +985,16 @@ impl<R: Reader> OperationIter<R> {
}
}
+#[cfg(feature = "fallible-iterator")]
+impl<R: Reader> fallible_iterator::FallibleIterator for OperationIter<R> {
+ type Item = Operation<R>;
+ type Error = Error;
+
+ fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
+ OperationIter::next(self)
+ }
+}
+
/// Specification of what storage should be used for [`Evaluation`].
///
#[cfg_attr(
diff --git a/vendor/gimli/src/read/reader.rs b/vendor/gimli/src/read/reader.rs
index 1bb748bb8..e7dd4772c 100644
--- a/vendor/gimli/src/read/reader.rs
+++ b/vendor/gimli/src/read/reader.rs
@@ -245,7 +245,7 @@ pub trait Reader: Debug + Clone {
/// it is associated with this reader.
fn lookup_offset_id(&self, id: ReaderOffsetId) -> Option<Self::Offset>;
- /// Find the index of the first occurence of the given byte.
+ /// Find the index of the first occurrence of the given byte.
/// The offset of the reader is not changed.
fn find(&self, byte: u8) -> Result<Self::Offset>;
diff --git a/vendor/gimli/src/read/unit.rs b/vendor/gimli/src/read/unit.rs
index 672435330..d799f0f07 100644
--- a/vendor/gimli/src/read/unit.rs
+++ b/vendor/gimli/src/read/unit.rs
@@ -3295,7 +3295,7 @@ mod tests {
}
};
- let section = section.append_bytes(unit.entries_buf.into()).mark(&end);
+ let section = section.append_bytes(unit.entries_buf.slice()).mark(&end);
unit.unit_length = (&end - &start) as usize;
length.set_const(unit.unit_length as u64);
diff --git a/vendor/gimli/src/read/value.rs b/vendor/gimli/src/read/value.rs
index 6f43ebb26..77b08eda5 100644
--- a/vendor/gimli/src/read/value.rs
+++ b/vendor/gimli/src/read/value.rs
@@ -367,7 +367,7 @@ impl Value {
Value::I64(value) => Value::I64(value.wrapping_neg()),
Value::F32(value) => Value::F32(-value),
Value::F64(value) => Value::F64(-value),
- // It's unclear if these should implicity convert to a signed value.
+ // It's unclear if these should implicitly convert to a signed value.
// For now, we don't support them.
Value::U8(_) | Value::U16(_) | Value::U32(_) | Value::U64(_) => {
return Err(Error::UnsupportedTypeOperation);
@@ -664,7 +664,7 @@ impl Value {
Value::U16(v1) => Value::U16(if v2 >= 16 { 0 } else { v1 >> v2 }),
Value::U32(v1) => Value::U32(if v2 >= 32 { 0 } else { v1 >> v2 }),
Value::U64(v1) => Value::U64(if v2 >= 64 { 0 } else { v1 >> v2 }),
- // It's unclear if signed values should implicity convert to an unsigned value.
+ // It's unclear if signed values should implicitly convert to an unsigned value.
// For now, we don't support them.
Value::I8(_) | Value::I16(_) | Value::I32(_) | Value::I64(_) => {
return Err(Error::UnsupportedTypeOperation);
@@ -737,7 +737,7 @@ impl Value {
} else {
v1 >> v2
}),
- // It's unclear if unsigned values should implicity convert to a signed value.
+ // It's unclear if unsigned values should implicitly convert to a signed value.
// For now, we don't support them.
Value::U8(_) | Value::U16(_) | Value::U32(_) | Value::U64(_) => {
return Err(Error::UnsupportedTypeOperation);
diff --git a/vendor/gimli/src/write/cfi.rs b/vendor/gimli/src/write/cfi.rs
index 718cb69ad..5e108f15a 100644
--- a/vendor/gimli/src/write/cfi.rs
+++ b/vendor/gimli/src/write/cfi.rs
@@ -377,6 +377,7 @@ impl FrameDescriptionEntry {
///
/// This may be a CFA definition, a register rule, or some other directive.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+#[non_exhaustive]
pub enum CallFrameInstruction {
/// Define the CFA rule to use the provided register and offset.
Cfa(Register, i32),
@@ -410,6 +411,9 @@ pub enum CallFrameInstruction {
RestoreState,
/// The size of the arguments that have been pushed onto the stack.
ArgsSize(u32),
+
+ /// AAarch64 extension: negate the `RA_SIGN_STATE` pseudo-register.
+ NegateRaState,
}
impl CallFrameInstruction {
@@ -523,6 +527,9 @@ impl CallFrameInstruction {
w.write_u8(constants::DW_CFA_GNU_args_size.0)?;
w.write_uleb128(size.into())?;
}
+ CallFrameInstruction::NegateRaState => {
+ w.write_u8(constants::DW_CFA_AARCH64_negate_ra_state.0)?;
+ }
}
Ok(())
}
@@ -834,6 +841,7 @@ pub(crate) mod convert {
read::CallFrameInstruction::ArgsSize { size } => {
CallFrameInstruction::ArgsSize(size as u32)
}
+ read::CallFrameInstruction::NegateRaState => CallFrameInstruction::NegateRaState,
read::CallFrameInstruction::Nop => return Ok(None),
}))
}
@@ -847,7 +855,7 @@ mod tests {
use crate::arch::X86_64;
use crate::read;
use crate::write::EndianVec;
- use crate::LittleEndian;
+ use crate::{LittleEndian, Vendor};
#[test]
fn test_frame_table() {
@@ -980,44 +988,61 @@ mod tests {
(28 + 0x20280, CallFrameInstruction::ArgsSize(23)),
];
+ let fde_instructions_aarch64 = [(0, CallFrameInstruction::NegateRaState)];
+
for &version in &[1, 3, 4] {
for &address_size in &[4, 8] {
- for &format in &[Format::Dwarf32, Format::Dwarf64] {
- let encoding = Encoding {
- format,
- version,
- address_size,
- };
- let mut frames = FrameTable::default();
-
- let mut cie = CommonInformationEntry::new(encoding, 2, 8, X86_64::RA);
- for i in &cie_instructions {
- cie.add_instruction(i.clone());
- }
- let cie_id = frames.add_cie(cie);
+ for &vendor in &[Vendor::Default, Vendor::AArch64] {
+ for &format in &[Format::Dwarf32, Format::Dwarf64] {
+ let encoding = Encoding {
+ format,
+ version,
+ address_size,
+ };
+ let mut frames = FrameTable::default();
+
+ let mut cie = CommonInformationEntry::new(encoding, 2, 8, X86_64::RA);
+ for i in &cie_instructions {
+ cie.add_instruction(i.clone());
+ }
+ let cie_id = frames.add_cie(cie);
- let mut fde = FrameDescriptionEntry::new(Address::Constant(0x1000), 0x10);
- for (o, i) in &fde_instructions {
- fde.add_instruction(*o, i.clone());
- }
- frames.add_fde(cie_id, fde);
+ let mut fde = FrameDescriptionEntry::new(Address::Constant(0x1000), 0x10);
+ for (o, i) in &fde_instructions {
+ fde.add_instruction(*o, i.clone());
+ }
+ frames.add_fde(cie_id, fde);
+
+ if vendor == Vendor::AArch64 {
+ let mut fde =
+ FrameDescriptionEntry::new(Address::Constant(0x2000), 0x10);
+ for (o, i) in &fde_instructions_aarch64 {
+ fde.add_instruction(*o, i.clone());
+ }
+ frames.add_fde(cie_id, fde);
+ }
- let mut debug_frame = DebugFrame::from(EndianVec::new(LittleEndian));
- frames.write_debug_frame(&mut debug_frame).unwrap();
+ let mut debug_frame = DebugFrame::from(EndianVec::new(LittleEndian));
+ frames.write_debug_frame(&mut debug_frame).unwrap();
- let mut read_debug_frame =
- read::DebugFrame::new(debug_frame.slice(), LittleEndian);
- read_debug_frame.set_address_size(address_size);
- let frames = FrameTable::from(&read_debug_frame, &|address| {
- Some(Address::Constant(address))
- })
- .unwrap();
+ let mut read_debug_frame =
+ read::DebugFrame::new(debug_frame.slice(), LittleEndian);
+ read_debug_frame.set_address_size(address_size);
+ read_debug_frame.set_vendor(vendor);
+ let frames = FrameTable::from(&read_debug_frame, &|address| {
+ Some(Address::Constant(address))
+ })
+ .unwrap();
- assert_eq!(
- &frames.cies.get_index(0).unwrap().instructions,
- &cie_instructions
- );
- assert_eq!(&frames.fdes[0].1.instructions, &fde_instructions);
+ assert_eq!(
+ &frames.cies.get_index(0).unwrap().instructions,
+ &cie_instructions
+ );
+ assert_eq!(&frames.fdes[0].1.instructions, &fde_instructions);
+ if vendor == Vendor::AArch64 {
+ assert_eq!(&frames.fdes[1].1.instructions, &fde_instructions_aarch64);
+ }
+ }
}
}
}
diff --git a/vendor/gimli/src/write/unit.rs b/vendor/gimli/src/write/unit.rs
index 23027bc2c..dd8ba6748 100644
--- a/vendor/gimli/src/write/unit.rs
+++ b/vendor/gimli/src/write/unit.rs
@@ -4,7 +4,7 @@ use std::{slice, usize};
use crate::common::{
DebugAbbrevOffset, DebugInfoOffset, DebugLineOffset, DebugMacinfoOffset, DebugMacroOffset,
- DebugStrOffset, DebugTypeSignature, DwoId, Encoding, Format, SectionId,
+ DebugStrOffset, DebugTypeSignature, Encoding, Format, SectionId,
};
use crate::constants;
use crate::leb128::write::{sleb128_size, uleb128_size};
@@ -159,7 +159,7 @@ pub struct Unit {
// - entries can be added in any order
// - entries have a fixed id
// - able to quickly lookup an entry from its id
- // Limitations of current implemention:
+ // Limitations of current implementation:
// - mutable iteration of children is messy due to borrow checker
entries: Vec<DebuggingInformationEntry>,
/// The index of the root entry in entries.
@@ -1378,6 +1378,7 @@ pub struct DebugInfoOffsets {
impl DebugInfoOffsets {
#[cfg(test)]
+ #[cfg(feature = "read")]
pub(crate) fn unit_offsets(&self, unit: UnitId) -> &UnitOffsets {
debug_assert_eq!(self.base_id, unit.base_id);
&self.units[unit.index]
@@ -1408,6 +1409,7 @@ pub(crate) struct UnitOffsets {
impl UnitOffsets {
#[cfg(test)]
+ #[cfg(feature = "read")]
fn none() -> Self {
UnitOffsets {
base_id: BaseId::default(),
@@ -1471,7 +1473,7 @@ pub(crate) struct DebugInfoReference {
#[cfg(feature = "read")]
pub(crate) mod convert {
use super::*;
- use crate::common::UnitSectionOffset;
+ use crate::common::{DwoId, UnitSectionOffset};
use crate::read::{self, Reader};
use crate::write::{self, ConvertError, ConvertResult, LocationList, RangeList};
use std::collections::HashMap;
diff --git a/vendor/gimli/tests/convert_self.rs b/vendor/gimli/tests/convert_self.rs
deleted file mode 100644
index 7c069ebd6..000000000
--- a/vendor/gimli/tests/convert_self.rs
+++ /dev/null
@@ -1,158 +0,0 @@
-#![cfg(all(feature = "read", feature = "write"))]
-
-use std::env;
-use std::fs::File;
-use std::io::Read;
-use std::path::PathBuf;
-
-use gimli::read;
-use gimli::write::{self, Address, EndianVec};
-use gimli::LittleEndian;
-
-fn read_section(section: &str) -> Vec<u8> {
- let mut path = PathBuf::new();
- if let Ok(dir) = env::var("CARGO_MANIFEST_DIR") {
- path.push(dir);
- }
- path.push("fixtures/self");
- path.push(section);
-
- println!("Reading section \"{}\" at path {:?}", section, path);
- assert!(path.is_file());
- let mut file = File::open(path).unwrap();
-
- let mut buf = Vec::new();
- file.read_to_end(&mut buf).unwrap();
- buf
-}
-
-#[test]
-fn test_convert_debug_info() {
- // Convert existing sections
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = read::DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- let debug_info = read_section("debug_info");
- let debug_info = read::DebugInfo::new(&debug_info, LittleEndian);
-
- let debug_line = read_section("debug_line");
- let debug_line = read::DebugLine::new(&debug_line, LittleEndian);
-
- let debug_str = read_section("debug_str");
- let debug_str = read::DebugStr::new(&debug_str, LittleEndian);
-
- let debug_ranges = read_section("debug_ranges");
- let debug_ranges = read::DebugRanges::new(&debug_ranges, LittleEndian);
-
- let debug_rnglists = read::DebugRngLists::new(&[], LittleEndian);
-
- let ranges = gimli::RangeLists::new(debug_ranges, debug_rnglists);
-
- let debug_loc = read_section("debug_loc");
- let debug_loc = read::DebugLoc::new(&debug_loc, LittleEndian);
-
- let debug_loclists = read::DebugLocLists::new(&[], LittleEndian);
-
- let locations = gimli::LocationLists::new(debug_loc, debug_loclists);
-
- let dwarf = read::Dwarf {
- debug_abbrev,
- debug_info,
- debug_line,
- debug_str,
- ranges,
- locations,
- ..Default::default()
- };
-
- let mut dwarf = write::Dwarf::from(&dwarf, &|address| Some(Address::Constant(address)))
- .expect("Should convert DWARF information");
-
- assert_eq!(dwarf.units.count(), 23);
- let entries: usize = (0..dwarf.units.count())
- .map(|i| dwarf.units.get(dwarf.units.id(i)).count())
- .sum();
- assert_eq!(entries, 29_560);
- assert_eq!(dwarf.line_strings.count(), 0);
- assert_eq!(dwarf.strings.count(), 3921);
-
- // Write to new sections
- let mut write_sections = write::Sections::new(EndianVec::new(LittleEndian));
- dwarf
- .write(&mut write_sections)
- .expect("Should write DWARF information");
- let debug_info_data = write_sections.debug_info.slice();
- let debug_abbrev_data = write_sections.debug_abbrev.slice();
- let debug_line_data = write_sections.debug_line.slice();
- let debug_ranges_data = write_sections.debug_ranges.slice();
- let debug_loc_data = write_sections.debug_loc.slice();
- let debug_str_data = write_sections.debug_str.slice();
- assert_eq!(debug_info_data.len(), 394_930);
- assert_eq!(debug_abbrev_data.len(), 9701);
- assert_eq!(debug_line_data.len(), 105_797);
- assert_eq!(debug_ranges_data.len(), 155_712);
- assert_eq!(debug_loc_data.len(), 245_168);
- assert_eq!(debug_str_data.len(), 144_731);
-
- // Convert new sections
- let debug_abbrev = read::DebugAbbrev::new(debug_abbrev_data, LittleEndian);
- let debug_info = read::DebugInfo::new(debug_info_data, LittleEndian);
- let debug_line = read::DebugLine::new(debug_line_data, LittleEndian);
- let debug_str = read::DebugStr::new(debug_str_data, LittleEndian);
- let debug_ranges = read::DebugRanges::new(debug_ranges_data, LittleEndian);
- let debug_rnglists = read::DebugRngLists::new(&[], LittleEndian);
- let debug_loc = read::DebugLoc::new(debug_loc_data, LittleEndian);
- let debug_loclists = read::DebugLocLists::new(&[], LittleEndian);
-
- let ranges = gimli::RangeLists::new(debug_ranges, debug_rnglists);
- let locations = gimli::LocationLists::new(debug_loc, debug_loclists);
-
- let dwarf = read::Dwarf {
- debug_abbrev,
- debug_info,
- debug_line,
- debug_str,
- ranges,
- locations,
- ..Default::default()
- };
-
- let dwarf = write::Dwarf::from(&dwarf, &|address| Some(Address::Constant(address)))
- .expect("Should convert DWARF information");
-
- assert_eq!(dwarf.units.count(), 23);
- let entries: usize = (0..dwarf.units.count())
- .map(|i| dwarf.units.get(dwarf.units.id(i)).count())
- .sum();
- assert_eq!(entries, 29_560);
- assert_eq!(dwarf.strings.count(), 3921);
-}
-
-#[test]
-fn test_convert_eh_frame() {
- // Convert existing section
- let eh_frame = read_section("eh_frame");
- let mut eh_frame = read::EhFrame::new(&eh_frame, LittleEndian);
- // The `.eh_frame` fixture data was created on a 64-bit machine.
- eh_frame.set_address_size(8);
- let frames = write::FrameTable::from(&eh_frame, &|address| Some(Address::Constant(address)))
- .expect("Should convert eh_frame information");
- assert_eq!(frames.cie_count(), 2);
- assert_eq!(frames.fde_count(), 3482);
-
- // Write to new section
- let mut write_eh_frame = write::EhFrame(EndianVec::new(LittleEndian));
- frames
- .write_eh_frame(&mut write_eh_frame)
- .expect("Should write eh_frame information");
- let eh_frame = write_eh_frame.slice();
- assert_eq!(eh_frame.len(), 147144);
-
- // Convert new section
- let mut eh_frame = read::EhFrame::new(&eh_frame, LittleEndian);
- eh_frame.set_address_size(8);
- let frames = write::FrameTable::from(&eh_frame, &|address| Some(Address::Constant(address)))
- .expect("Should convert eh_frame information");
- assert_eq!(frames.cie_count(), 2);
- assert_eq!(frames.fde_count(), 3482);
-}
diff --git a/vendor/gimli/tests/parse_self.rs b/vendor/gimli/tests/parse_self.rs
deleted file mode 100755
index fb316314e..000000000
--- a/vendor/gimli/tests/parse_self.rs
+++ /dev/null
@@ -1,431 +0,0 @@
-#![cfg(all(feature = "read", feature = "std", feature = "endian-reader"))]
-
-use gimli::{
- AttributeValue, DebugAbbrev, DebugAddr, DebugAddrBase, DebugAranges, DebugInfo, DebugLine,
- DebugLoc, DebugLocLists, DebugPubNames, DebugPubTypes, DebugRanges, DebugRngLists, DebugStr,
- Encoding, EndianSlice, Expression, LittleEndian, LocationLists, Operation, RangeLists,
- RangeListsOffset, Reader,
-};
-use std::collections::hash_map::HashMap;
-use std::env;
-use std::fs::File;
-use std::io::Read;
-use std::path::PathBuf;
-use std::rc::Rc;
-
-fn read_section(section: &str) -> Vec<u8> {
- let mut path = PathBuf::new();
- if let Ok(dir) = env::var("CARGO_MANIFEST_DIR") {
- path.push(dir);
- }
- path.push("fixtures/self");
- path.push(section);
-
- println!("Reading section \"{}\" at path {:?}", section, path);
- assert!(path.is_file());
- let mut file = File::open(path).unwrap();
-
- let mut buf = Vec::new();
- file.read_to_end(&mut buf).unwrap();
- buf
-}
-
-fn parse_expression<R: Reader>(expr: Expression<R>, encoding: Encoding) {
- let mut pc = expr.0.clone();
- while !pc.is_empty() {
- Operation::parse(&mut pc, encoding).expect("Should parse operation");
- }
-
- // Also attempt to evaluate some of it.
- let mut eval = expr.evaluation(encoding);
- eval.set_initial_value(0);
- eval.evaluate().expect("Should evaluate expression");
-}
-
-fn impl_parse_self_debug_info<R: gimli::Reader>(
- debug_info: &DebugInfo<R>,
- debug_abbrev: &DebugAbbrev<R>,
-) {
- let mut iter = debug_info.units();
- while let Some(unit) = iter.next().expect("Should parse compilation unit") {
- let abbrevs = unit
- .abbreviations(&debug_abbrev)
- .expect("Should parse abbreviations");
-
- let mut cursor = unit.entries(&abbrevs);
-
- while cursor.next_dfs().expect("Should parse next dfs").is_some() {
- let entry = cursor.current().expect("Should have a current entry");
-
- let mut attrs = entry.attrs();
- while let Some(attr) = attrs.next().expect("Should parse entry's attribute") {
- if let AttributeValue::Exprloc(expression) = attr.value() {
- parse_expression(expression, unit.encoding());
- }
- }
- }
- }
-}
-
-#[test]
-fn test_parse_self_debug_info() {
- let debug_info = read_section("debug_info");
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- impl_parse_self_debug_info(&debug_info, &debug_abbrev);
-}
-
-#[test]
-fn test_parse_self_debug_info_with_endian_rc_slice() {
- let debug_info = read_section("debug_info");
- let debug_info = Rc::from(&debug_info[..]);
- let debug_info = gimli::EndianRcSlice::new(debug_info, LittleEndian);
- let debug_info = DebugInfo::from(debug_info);
-
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = Rc::from(&debug_abbrev[..]);
- let debug_abbrev = gimli::EndianRcSlice::new(debug_abbrev, LittleEndian);
- let debug_abbrev = DebugAbbrev::from(debug_abbrev);
-
- impl_parse_self_debug_info(&debug_info, &debug_abbrev);
-}
-
-#[test]
-fn test_parse_self_debug_line() {
- let debug_info = read_section("debug_info");
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- let debug_line = read_section("debug_line");
- let debug_line = DebugLine::new(&debug_line, LittleEndian);
-
- let debug_str = read_section("debug_str");
- let debug_str = DebugStr::new(&debug_str, LittleEndian);
-
- let mut iter = debug_info.units();
- while let Some(unit) = iter.next().expect("Should parse compilation unit") {
- let abbrevs = unit
- .abbreviations(&debug_abbrev)
- .expect("Should parse abbreviations");
-
- let mut cursor = unit.entries(&abbrevs);
- cursor.next_dfs().expect("Should parse next dfs");
-
- let unit_entry = cursor.current().expect("Should have a root entry");
-
- let comp_dir = unit_entry
- .attr_value(gimli::DW_AT_comp_dir)
- .expect("Should parse comp_dir attribute")
- .and_then(|val| val.string_value(&debug_str));
- let comp_name = unit_entry
- .attr_value(gimli::DW_AT_name)
- .expect("Should parse name attribute")
- .and_then(|val| val.string_value(&debug_str));
-
- if let Some(AttributeValue::DebugLineRef(offset)) = unit_entry
- .attr_value(gimli::DW_AT_stmt_list)
- .expect("Should parse stmt_list")
- {
- let program = debug_line
- .program(offset, unit.address_size(), comp_dir, comp_name)
- .expect("should parse line number program header");
-
- let mut results = Vec::new();
- let mut rows = program.rows();
- while let Some((_, row)) = rows
- .next_row()
- .expect("Should parse and execute all rows in the line number program")
- {
- results.push(*row);
- }
- results.reverse();
-
- let program = debug_line
- .program(offset, unit.address_size(), comp_dir, comp_name)
- .expect("should parse line number program header");
- let (program, sequences) = program
- .sequences()
- .expect("should parse and execute the entire line number program");
- assert!(!sequences.is_empty()); // Should be at least one sequence.
- for sequence in sequences {
- let mut rows = program.resume_from(&sequence);
- while let Some((_, row)) = rows
- .next_row()
- .expect("Should parse and execute all rows after resuming")
- {
- let other_row = results.pop().unwrap();
- assert!(row.address() >= sequence.start);
- assert!(row.address() <= sequence.end);
- assert_eq!(row.address(), other_row.address());
- assert_eq!(row.line(), other_row.line());
- }
- }
- assert!(results.is_empty());
- }
- }
-}
-
-#[test]
-fn test_parse_self_debug_loc() {
- let debug_info = read_section("debug_info");
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- let debug_addr = DebugAddr::from(EndianSlice::new(&[], LittleEndian));
- let debug_addr_base = DebugAddrBase(0);
-
- let debug_loc = read_section("debug_loc");
- let debug_loc = DebugLoc::new(&debug_loc, LittleEndian);
- let debug_loclists = DebugLocLists::new(&[], LittleEndian);
- let loclists = LocationLists::new(debug_loc, debug_loclists);
-
- let mut iter = debug_info.units();
- while let Some(unit) = iter.next().expect("Should parse compilation unit") {
- let abbrevs = unit
- .abbreviations(&debug_abbrev)
- .expect("Should parse abbreviations");
-
- let mut cursor = unit.entries(&abbrevs);
- cursor.next_dfs().expect("Should parse next dfs");
-
- let mut low_pc = 0;
-
- {
- let unit_entry = cursor.current().expect("Should have a root entry");
- let low_pc_attr = unit_entry
- .attr_value(gimli::DW_AT_low_pc)
- .expect("Should parse low_pc");
- if let Some(gimli::AttributeValue::Addr(address)) = low_pc_attr {
- low_pc = address;
- }
- }
-
- while cursor.next_dfs().expect("Should parse next dfs").is_some() {
- let entry = cursor.current().expect("Should have a current entry");
- let mut attrs = entry.attrs();
- while let Some(attr) = attrs.next().expect("Should parse entry's attribute") {
- if let AttributeValue::LocationListsRef(offset) = attr.value() {
- let mut locs = loclists
- .locations(
- offset,
- unit.encoding(),
- low_pc,
- &debug_addr,
- debug_addr_base,
- )
- .expect("Should parse locations OK");
- while let Some(loc) = locs.next().expect("Should parse next location") {
- assert!(loc.range.begin <= loc.range.end);
- parse_expression(loc.data, unit.encoding());
- }
- }
- }
- }
- }
-}
-
-#[test]
-fn test_parse_self_debug_ranges() {
- let debug_info = read_section("debug_info");
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- let debug_addr = DebugAddr::from(EndianSlice::new(&[], LittleEndian));
- let debug_addr_base = DebugAddrBase(0);
-
- let debug_ranges = read_section("debug_ranges");
- let debug_ranges = DebugRanges::new(&debug_ranges, LittleEndian);
- let debug_rnglists = DebugRngLists::new(&[], LittleEndian);
- let rnglists = RangeLists::new(debug_ranges, debug_rnglists);
-
- let mut iter = debug_info.units();
- while let Some(unit) = iter.next().expect("Should parse compilation unit") {
- let abbrevs = unit
- .abbreviations(&debug_abbrev)
- .expect("Should parse abbreviations");
-
- let mut cursor = unit.entries(&abbrevs);
- cursor.next_dfs().expect("Should parse next dfs");
-
- let mut low_pc = 0;
-
- {
- let unit_entry = cursor.current().expect("Should have a root entry");
- let low_pc_attr = unit_entry
- .attr_value(gimli::DW_AT_low_pc)
- .expect("Should parse low_pc");
- if let Some(gimli::AttributeValue::Addr(address)) = low_pc_attr {
- low_pc = address;
- }
- }
-
- while cursor.next_dfs().expect("Should parse next dfs").is_some() {
- let entry = cursor.current().expect("Should have a current entry");
- let mut attrs = entry.attrs();
- while let Some(attr) = attrs.next().expect("Should parse entry's attribute") {
- if let AttributeValue::RangeListsRef(offset) = attr.value() {
- let mut ranges = rnglists
- .ranges(
- RangeListsOffset(offset.0),
- unit.encoding(),
- low_pc,
- &debug_addr,
- debug_addr_base,
- )
- .expect("Should parse ranges OK");
- while let Some(range) = ranges.next().expect("Should parse next range") {
- assert!(range.begin <= range.end);
- }
- }
- }
- }
- }
-}
-
-#[test]
-fn test_parse_self_debug_aranges() {
- let debug_aranges = read_section("debug_aranges");
- let debug_aranges = DebugAranges::new(&debug_aranges, LittleEndian);
-
- let mut headers = debug_aranges.headers();
- while let Some(header) = headers.next().expect("Should parse arange header OK") {
- let mut entries = header.entries();
- while let Some(_) = entries.next().expect("Should parse arange entry OK") {
- // Not really anything else we can check right now.
- }
- }
-}
-
-#[test]
-fn test_parse_self_debug_pubnames() {
- let debug_info = read_section("debug_info");
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- let debug_pubnames = read_section("debug_pubnames");
- let debug_pubnames = DebugPubNames::new(&debug_pubnames, LittleEndian);
-
- let mut units = HashMap::new();
- let mut abbrevs = HashMap::new();
- let mut pubnames = debug_pubnames.items();
- while let Some(entry) = pubnames.next().expect("Should parse pubname OK") {
- let unit_offset = entry.unit_header_offset();
- let unit = units.entry(unit_offset).or_insert_with(|| {
- debug_info
- .header_from_offset(unit_offset)
- .expect("Should parse unit header OK")
- });
- let abbrev_offset = unit.debug_abbrev_offset();
- let abbrevs = abbrevs.entry(abbrev_offset).or_insert_with(|| {
- debug_abbrev
- .abbreviations(abbrev_offset)
- .expect("Should parse abbreviations OK")
- });
- let mut cursor = unit
- .entries_at_offset(abbrevs, entry.die_offset())
- .expect("DIE offset should be valid");
- assert!(cursor.next_dfs().expect("Should parse DIE").is_some());
- }
-}
-
-#[test]
-fn test_parse_self_debug_pubtypes() {
- let debug_info = read_section("debug_info");
- let debug_info = DebugInfo::new(&debug_info, LittleEndian);
-
- let debug_abbrev = read_section("debug_abbrev");
- let debug_abbrev = DebugAbbrev::new(&debug_abbrev, LittleEndian);
-
- let debug_pubtypes = read_section("debug_pubtypes");
- let debug_pubtypes = DebugPubTypes::new(&debug_pubtypes, LittleEndian);
-
- let mut units = HashMap::new();
- let mut abbrevs = HashMap::new();
- let mut pubtypes = debug_pubtypes.items();
- while let Some(entry) = pubtypes.next().expect("Should parse pubtype OK") {
- let unit_offset = entry.unit_header_offset();
- let unit = units.entry(unit_offset).or_insert_with(|| {
- debug_info
- .header_from_offset(unit_offset)
- .expect("Should parse unit header OK")
- });
- let abbrev_offset = unit.debug_abbrev_offset();
- let abbrevs = abbrevs.entry(abbrev_offset).or_insert_with(|| {
- debug_abbrev
- .abbreviations(abbrev_offset)
- .expect("Should parse abbreviations OK")
- });
- let mut cursor = unit
- .entries_at_offset(abbrevs, entry.die_offset())
- .expect("DIE offset should be valid");
- assert!(cursor.next_dfs().expect("Should parse DIE").is_some());
- }
-}
-
-#[test]
-fn test_parse_self_eh_frame() {
- use gimli::{BaseAddresses, CieOrFde, EhFrame, UnwindSection};
-
- let eh_frame = read_section("eh_frame");
- let mut eh_frame = EhFrame::new(&eh_frame, LittleEndian);
- // The `.eh_frame` fixture data was created on a 64-bit machine.
- eh_frame.set_address_size(8);
-
- let bases = BaseAddresses::default()
- .set_eh_frame(0)
- .set_text(0)
- .set_got(0);
- let mut entries = eh_frame.entries(&bases);
- while let Some(entry) = entries.next().expect("Should parse CFI entry OK") {
- match entry {
- CieOrFde::Cie(cie) => {
- let mut instrs = cie.instructions(&eh_frame, &bases);
- while let Some(_) = instrs.next().expect("Can parse next CFI instruction OK") {
- // TODO FITZGEN
- }
- }
- CieOrFde::Fde(partial) => {
- let fde = partial
- .parse(UnwindSection::cie_from_offset)
- .expect("Should be able to get CIE for FDE");
-
- let mut instrs = fde.instructions(&eh_frame, &bases);
- while let Some(_) = instrs.next().expect("Can parse next CFI instruction OK") {
- // TODO FITZGEN
- }
- }
- }
- }
-}
-
-#[test]
-fn test_parse_self_eh_frame_hdr() {
- use gimli::{BaseAddresses, EhFrameHdr};
-
- let eh_frame_hdr = read_section("eh_frame_hdr");
- let eh_frame_hdr = EhFrameHdr::new(&eh_frame_hdr, LittleEndian);
-
- let bases = BaseAddresses::default()
- .set_eh_frame(0)
- .set_eh_frame_hdr(0)
- .set_text(0)
- .set_got(0);
-
- // `.eh_frame_hdr` was generated on a 64 bit machine.
- let address_size = 8;
-
- let _parsed_header = eh_frame_hdr
- .parse(&bases, address_size)
- .expect("we can parse the `.eh_frame_hdr` section OK");
-}