aboutsummaryrefslogtreecommitdiff
path: root/vendor/object
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/object')
-rw-r--r--vendor/object/.cargo-checksum.json1
-rw-r--r--vendor/object/CHANGELOG.md754
-rw-r--r--vendor/object/Cargo.toml163
-rw-r--r--vendor/object/LICENSE-APACHE201
-rw-r--r--vendor/object/LICENSE-MIT25
-rw-r--r--vendor/object/README.md56
-rw-r--r--vendor/object/clippy.toml1
-rw-r--r--vendor/object/src/archive.rs91
-rw-r--r--vendor/object/src/common.rs536
-rw-r--r--vendor/object/src/elf.rs6287
-rw-r--r--vendor/object/src/endian.rs831
-rw-r--r--vendor/object/src/lib.rs99
-rw-r--r--vendor/object/src/macho.rs3307
-rw-r--r--vendor/object/src/pe.rs3056
-rw-r--r--vendor/object/src/pod.rs239
-rw-r--r--vendor/object/src/read/any.rs1328
-rw-r--r--vendor/object/src/read/archive.rs759
-rw-r--r--vendor/object/src/read/coff/comdat.rs211
-rw-r--r--vendor/object/src/read/coff/file.rs381
-rw-r--r--vendor/object/src/read/coff/import.rs220
-rw-r--r--vendor/object/src/read/coff/mod.rs66
-rw-r--r--vendor/object/src/read/coff/relocation.rs106
-rw-r--r--vendor/object/src/read/coff/section.rs585
-rw-r--r--vendor/object/src/read/coff/symbol.rs635
-rw-r--r--vendor/object/src/read/elf/attributes.rs307
-rw-r--r--vendor/object/src/read/elf/comdat.rs162
-rw-r--r--vendor/object/src/read/elf/compression.rs56
-rw-r--r--vendor/object/src/read/elf/dynamic.rs117
-rw-r--r--vendor/object/src/read/elf/file.rs916
-rw-r--r--vendor/object/src/read/elf/hash.rs224
-rw-r--r--vendor/object/src/read/elf/mod.rs78
-rw-r--r--vendor/object/src/read/elf/note.rs271
-rw-r--r--vendor/object/src/read/elf/relocation.rs628
-rw-r--r--vendor/object/src/read/elf/section.rs1150
-rw-r--r--vendor/object/src/read/elf/segment.rs334
-rw-r--r--vendor/object/src/read/elf/symbol.rs595
-rw-r--r--vendor/object/src/read/elf/version.rs424
-rw-r--r--vendor/object/src/read/macho/dyld_cache.rs344
-rw-r--r--vendor/object/src/read/macho/fat.rs122
-rw-r--r--vendor/object/src/read/macho/file.rs781
-rw-r--r--vendor/object/src/read/macho/load_command.rs382
-rw-r--r--vendor/object/src/read/macho/mod.rs72
-rw-r--r--vendor/object/src/read/macho/relocation.rs158
-rw-r--r--vendor/object/src/read/macho/section.rs389
-rw-r--r--vendor/object/src/read/macho/segment.rs303
-rw-r--r--vendor/object/src/read/macho/symbol.rs492
-rw-r--r--vendor/object/src/read/mod.rs860
-rw-r--r--vendor/object/src/read/pe/data_directory.rs213
-rw-r--r--vendor/object/src/read/pe/export.rs333
-rw-r--r--vendor/object/src/read/pe/file.rs1050
-rw-r--r--vendor/object/src/read/pe/import.rs337
-rw-r--r--vendor/object/src/read/pe/mod.rs68
-rw-r--r--vendor/object/src/read/pe/relocation.rs92
-rw-r--r--vendor/object/src/read/pe/resource.rs209
-rw-r--r--vendor/object/src/read/pe/rich.rs91
-rw-r--r--vendor/object/src/read/pe/section.rs440
-rw-r--r--vendor/object/src/read/read_cache.rs178
-rw-r--r--vendor/object/src/read/read_ref.rs137
-rw-r--r--vendor/object/src/read/traits.rs551
-rw-r--r--vendor/object/src/read/util.rs425
-rw-r--r--vendor/object/src/read/wasm.rs966
-rw-r--r--vendor/object/src/read/xcoff/comdat.rs135
-rw-r--r--vendor/object/src/read/xcoff/file.rs696
-rw-r--r--vendor/object/src/read/xcoff/mod.rs63
-rw-r--r--vendor/object/src/read/xcoff/relocation.rs127
-rw-r--r--vendor/object/src/read/xcoff/section.rs431
-rw-r--r--vendor/object/src/read/xcoff/segment.rs117
-rw-r--r--vendor/object/src/read/xcoff/symbol.rs786
-rw-r--r--vendor/object/src/write/coff/mod.rs10
-rw-r--r--vendor/object/src/write/coff/object.rs583
-rw-r--r--vendor/object/src/write/coff/writer.rs518
-rw-r--r--vendor/object/src/write/elf/mod.rs9
-rw-r--r--vendor/object/src/write/elf/object.rs907
-rw-r--r--vendor/object/src/write/elf/writer.rs2143
-rw-r--r--vendor/object/src/write/macho.rs1095
-rw-r--r--vendor/object/src/write/mod.rs961
-rw-r--r--vendor/object/src/write/pe.rs847
-rw-r--r--vendor/object/src/write/string.rs159
-rw-r--r--vendor/object/src/write/util.rs260
-rw-r--r--vendor/object/src/write/xcoff.rs556
-rw-r--r--vendor/object/src/xcoff.rs905
-rw-r--r--vendor/object/tests/integration.rs2
-rw-r--r--vendor/object/tests/parse_self.rs25
-rw-r--r--vendor/object/tests/read/coff.rs23
-rw-r--r--vendor/object/tests/read/mod.rs3
-rw-r--r--vendor/object/tests/round_trip/bss.rs255
-rw-r--r--vendor/object/tests/round_trip/coff.rs56
-rw-r--r--vendor/object/tests/round_trip/comdat.rs225
-rw-r--r--vendor/object/tests/round_trip/common.rs245
-rw-r--r--vendor/object/tests/round_trip/elf.rs289
-rw-r--r--vendor/object/tests/round_trip/macho.rs64
-rw-r--r--vendor/object/tests/round_trip/mod.rs686
-rw-r--r--vendor/object/tests/round_trip/section_flags.rs90
-rw-r--r--vendor/object/tests/round_trip/tls.rs316
94 files changed, 0 insertions, 47780 deletions
diff --git a/vendor/object/.cargo-checksum.json b/vendor/object/.cargo-checksum.json
deleted file mode 100644
index ae4a4fb..0000000
--- a/vendor/object/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"CHANGELOG.md":"8b7856a7b2ed9d534abaf22e924f28b7dc470ee62b8b83a81836111e8e6b8a17","Cargo.toml":"7a6f454c405b4debc0ba393deac7d32bb844745f80d1e42bc6aa6ca30f2078cd","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b74dfa0bcee5c420c6b7f67b4b2658f9ab8388c97b8e733975f2cecbdd668a6","README.md":"f2e83094c790fee1543503a19763c80afbfc35ab3bcf9e273e0efef0646ca181","clippy.toml":"e1e95839ba8e8bbf07f99ff49e2f151b9048c7981301a5480571842bbaf78ca2","src/archive.rs":"d6cead723242c26db2967b63385b79ed2008980a8c64b123a5eecffd7ed388fc","src/common.rs":"4b08104045d9f4fc6b0cd87d273a694e3a442d38e8cea88dadaf56202069310b","src/elf.rs":"76013b28af828ea4828c2fdce1ccc0753330bbb59f92b0feeb2902ca5277a931","src/endian.rs":"b4f63a85ccd3d5c11615baf5ba946c82046c221a1b8c74ee8c6fa4360782980c","src/lib.rs":"e9344c09eaaa38b3b68c5721da7593c35b21bcd19e2f8fa8b9e086359883fef1","src/macho.rs":"e62808b0c84494b68e7e69b2f7fd9c0620b2ef61b6a2af3403de30284cf6b898","src/pe.rs":"cd61391b064bea4c99cff515d9c635227218cf62b7aa719b66e3b1935379c497","src/pod.rs":"d2967732f0052e6cfa18a2dd62c57bc3b640a20eb9a6db9f39836000ceabb399","src/read/any.rs":"8b9c1c4d3e42a4a31d8aa3a8e00873eeb59c39e39a95f18375414046386c55a3","src/read/archive.rs":"e72051dc3315ca5c8e43eae0ab68dadef774f2e88f7755cd663ee0996b567d9a","src/read/coff/comdat.rs":"bc48209a993c67d9151d45e6cb0c4d05781cba50fc3ee19261adca6ef49772de","src/read/coff/file.rs":"bac38db07bee4d05342da7df2d352fd6d9bb41d684531f643916f4c4612b14dc","src/read/coff/import.rs":"2688a34ae2169e93405a4aad2380e15a28edd2db94286becd6644e9996ceb7b2","src/read/coff/mod.rs":"c3b0c4f09993b07a85fda3dd2de9c80258aaadce6c0598eb25e55fab4c6bbf1c","src/read/coff/relocation.rs":"001c5dab38a3f49d3a07ea9be78e1c6fe085a34accc041916b82779dd003177e","src/read/coff/section.rs":"cf4d098074ef45e25e98466cc2edb17f4209c955508c550fd8281a93fd5d10db","src/read/coff/symbol.rs":"b4323e6d905c520e43c1886f71423048397fdcda685e66be673f5dcaa62ee48f","src/read/elf/attributes.rs":"a9ac569d6ce02c98af70f83dcc74b0e27d008da5471851d6d307ecb270f60468","src/read/elf/comdat.rs":"44f281b8b2f7f763ac79bc8136e7f06bb9c145ff445054789fb0e045987b8904","src/read/elf/compression.rs":"726bb1ca96a480ac2a0c8ccaa4c2291d62ca6c4af2b1a2e43b74ae7be17f6d75","src/read/elf/dynamic.rs":"c934f8b72d71ed39ff129ce37a8177b5bf12fba93695914eae48112bf89702b4","src/read/elf/file.rs":"cc088179cae5c961991a553df10a52f61a5ee4122f9683faf988f94f5f209c3f","src/read/elf/hash.rs":"caf8cd5eb547bd212c3ecff5d33b39bc22f68e1d78de72a9333c0062e06e0507","src/read/elf/mod.rs":"7c0d4d10c1055f57184f470aa014e6358394ec95019a74da8d5079d275437d0b","src/read/elf/note.rs":"ca7fe4d04fe130e7c29bea5f5f559f4561272e4658a502444164003f36e620ec","src/read/elf/relocation.rs":"e43491ecfcd84b3a4b01d595cb28aea85fde5f8968a21053c0f28ae2fc4c5bc6","src/read/elf/section.rs":"c0ea5bc99c22791e2992dc348769bc72cfffac637ac6881cd34b3e1a767a692b","src/read/elf/segment.rs":"a9b235d4193e879957c0c929830870cbe57cb0305f5d9ed10911c4fe10b19430","src/read/elf/symbol.rs":"ed4f3cdffe33435a600561d8cc0c20842c58c8c922cfdac9067eaab6d1e37cf7","src/read/elf/version.rs":"70d2d9a0eae9d4602a79bbf8cc03e689921801b7d463a4381b331df534e59fda","src/read/macho/dyld_cache.rs":"855845db4eeaae89513e525786adc9f42225e3a4ec0e3a063629e87dd29f1059","src/read/macho/fat.rs":"a57272f0cd4bfdbacad1aac953e874631fcc445ce406b990892630542cdf2bda","src/read/macho/file.rs":"2d33692bae78ac7f07f946044c5c54c1294e774f7dc530181b9683e440828ba7","src/read/macho/load_command.rs":"bcb912923b5da843670275451ccb94527d50fa97d643b28924377f1c83d2339b","src/read/macho/mod.rs":"0e97e28f379766511f33d8ccb97eaa690a352f9180080a376a86516249b1bdd8","src/read/macho/relocation.rs":"be5d2588d7e6ccb0b9dda6f495eb0bc730eb01eb129e0a418ce5dce2ebb7de69","src/read/macho/section.rs":"dfc40939fc511bb6ad784eef7465d8c224d8efc246fceacaa7c8e4c6153e1f48","src/read/macho/segment.rs":"4888f4020ff98e7495405865631a3de4f1d1f21cc9df157900d689b0f64791f0","src/read/macho/symbol.rs":"f51e723355d84270d05bf289cefa4bcc35815f00ad075c2d63289e2d6ee6e9fd","src/read/mod.rs":"c53ea9bbf3129c4a837db5aebe3f4ae6ed05eb71f3305499a1434c8548a35f31","src/read/pe/data_directory.rs":"730c5b90174ddcce49f78fc9ff6fbdde0a011dc7d50154c8fe3a5a8b1a09a015","src/read/pe/export.rs":"88cd068d1ed84c1153f94ee5d71d9d9dc07de4a65499938379006e2d0801f592","src/read/pe/file.rs":"d88319d9e1358f5c0f1789c85770d144b45b94c6273e901682645acc717e2113","src/read/pe/import.rs":"5d5cedc95294cbfbab705b48e87bce29b57b083c17e47ce09806cf53588d2859","src/read/pe/mod.rs":"f0c70bf86680e7afdfdffbf4f3118efc9801516c6898663f574b115b62b1fbcd","src/read/pe/relocation.rs":"27795df870bc38b3aab57a9ef78c141633442727dbcd5b1c4b61513ec64069a6","src/read/pe/resource.rs":"1cbac8460d717c6fb5782aaad25a9c4148a1fbf050bd33b0eef476116b072711","src/read/pe/rich.rs":"ae9b2fc927bab2661e8d200a10128aebde37d26b50cb9069e9af9eb7bacee591","src/read/pe/section.rs":"5658ab6c7fc3b03c646d8dc28e795b5ec7a047ba7065db037d82b6f71ecbd81f","src/read/read_cache.rs":"775c3b357898981b5944302f2d773d637ac0dc6e26074023863153d30101b657","src/read/read_ref.rs":"712d276e6891f4cf512ed35be73ce2872ecd25c523c8554bdfd175445e120e56","src/read/traits.rs":"53a234182e58450b80972350b5645916877e6c30b4bd9ee8ed569deff7bef28a","src/read/util.rs":"03f3dc16d43e0b351feaff4e47f5cb996f9cc05e540e7996bff6961ff9901034","src/read/wasm.rs":"34c5a7344efcc57105f105282deb22b4dd3641394f518fb25aa9d7ea7ab2319f","src/read/xcoff/comdat.rs":"d054619dabe880f90b9a7935d13e8aaf35b10c7a52bd6d517cb93f1fc9a847d1","src/read/xcoff/file.rs":"dfa599bab234220089cf8b891dae299d1a760366535956ad55fe70b5e179b167","src/read/xcoff/mod.rs":"40921a3e9d65360f57c7301f11dd12ec82f71311b689272f209758ecbc755eb3","src/read/xcoff/relocation.rs":"b383d883f8966a4d9da8de5c2146b324e8758500ea73fd1c51c0216407db6ce9","src/read/xcoff/section.rs":"b39d79d680ce48de13526ca3dfbbb39baece92174e6732fa040418e1d4cfe89c","src/read/xcoff/segment.rs":"ce6f0c1c6dd5aa3dce620c7645fa9c790ee56765b6586782ac0e747c0e949f79","src/read/xcoff/symbol.rs":"c15031c2a0fd8cc7202087adac14baf8abbdd5ffb30d0f4b6bbbea9024e1ada0","src/write/coff/mod.rs":"511bd3a19575b1d888d0d1abb17bb697c36eda0e7032375afb13daedc972c27e","src/write/coff/object.rs":"13c8e7ca89a470280cae8478fe2637a518d81a087af2958868611c4e6a39f4cf","src/write/coff/writer.rs":"65754d28af57fc5a415af5665759a728e4526d13052f50dc7f2c00f3e307b225","src/write/elf/mod.rs":"1bb945edad539b4f19dda5d46c9b86fa4ea3721eedda77ca2595b5519c3e30f2","src/write/elf/object.rs":"ebb433b0e5afa4945b6ac2152137f56331507a2b5d8e8e698052f77ccb351486","src/write/elf/writer.rs":"84336230a24413a41e342735c153c3421c70707ec92c2df02e7d3536e5d41b55","src/write/macho.rs":"28d41a8423f4652d558c43fd9abf86488e60dc0be311aa4ddc4a863879179707","src/write/mod.rs":"7561a31d1e5da73a8c56b742ed550deffa1dd64ddf33e46d12ffde464906df61","src/write/pe.rs":"6c72185705a3e067c481f2b9f81c64a84e062e67781928e58fd1150314dad8f9","src/write/string.rs":"0033a6f5137b42988ac41dbaa2efb94a4d74d8b043c9a34c40125e8ee6912420","src/write/util.rs":"d93a7d00260cf6df0cca481d5fb5845ee5a87787dc4fc35a64f2abeb91096965","src/write/xcoff.rs":"290e98f8c71baafc1f2111e1513f35a95a7f7914cc0f446bbc24547a17eb3af1","src/xcoff.rs":"bfcfbcea61436aa41a6fc8ee2395654552d1dadd3d0e17d7e11679c65b7978aa","tests/integration.rs":"0fa704827e4da1be38dac2e3820d92f6b20c4d415803b04f67c3516020b1de97","tests/parse_self.rs":"81b44b2dd1de9a5d8c18d9bd8926156e39fb83931837afa8ca344da0d309aeee","tests/read/coff.rs":"d3ec2079f00237640d01cb66eb24c55c85d7a775bb94f9f5c9f77e21cb7a785d","tests/read/mod.rs":"7833826f169ac3be2b4f274e5fc8cf4a51742bd0010803ff0dc20ea5643a7e61","tests/round_trip/bss.rs":"849d69b063fd757fed02219dd81e9d13b82068a2025d2cc5cfd40cf557e31bda","tests/round_trip/coff.rs":"8a25aab7164a5c8aa7a21279f8bae1f4d5f68a8d09c29a4ecd0d0c14564851cc","tests/round_trip/comdat.rs":"a8f729e218fee21e90b9f39b5cfcb4f80bc3ce26d3a297323667e6eb14f882cc","tests/round_trip/common.rs":"ced08ff559ca4d343ceef54bb4c581a3405cd96d6a1628ba43b7aab82070800b","tests/round_trip/elf.rs":"d7351d888ccad246a646ab3bea1afc3d445adeb28c5d3c8f157f7cde3717281c","tests/round_trip/macho.rs":"f6566e658f8c627668646763010a3872fd7b7b0a5aebeed00b0690acad90d147","tests/round_trip/mod.rs":"a7ac4075f61ddec0b6bf87e7d447ba27bab01c8ae0b14d78af87bcc9df34fe9c","tests/round_trip/section_flags.rs":"0e17639e5f86d576f039a294c274ce8db2e2a8add31a2fffc33a6e93a6d2791e","tests/round_trip/tls.rs":"302f46d7481e1738b7561057869cec33d03b8760aba1d78ef0fe5adf603001f6"},"package":"a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"} \ No newline at end of file
diff --git a/vendor/object/CHANGELOG.md b/vendor/object/CHANGELOG.md
deleted file mode 100644
index 12c8653..0000000
--- a/vendor/object/CHANGELOG.md
+++ /dev/null
@@ -1,754 +0,0 @@
-# `object` Change Log
-
---------------------------------------------------------------------------------
-
-## 0.32.2
-
-Released 2023/12/24.
-
-### Added
-
-* Added ELF relocations for LoongArch ABI v2.20.
- [#578](https://github.com/gimli-rs/object/pull/578)
- [#589](https://github.com/gimli-rs/object/pull/589)
-
-* Added ELF support for SHARC.
- [#593](https://github.com/gimli-rs/object/pull/593)
-
-* Added `write::coff::Writer`.
- [#595](https://github.com/gimli-rs/object/pull/595)
-
-* Added `SubArchitecture::Arm64EC` support for PE/COFF.
- [#607](https://github.com/gimli-rs/object/pull/607)
-
-* Added `SubArchitecture::Arm64E` support for Mach-O.
- [#614](https://github.com/gimli-rs/object/pull/614)
-
-* Added `read::Object::symbol_by_name` and `read::Object::symbol_by_name_bytes`.
- [#602](https://github.com/gimli-rs/object/pull/602)
-
-* Added more functions to the low level API in `read::xcoff`.
- [#608](https://github.com/gimli-rs/object/pull/608)
-
-* Added more functions to the low level API in `read::macho`.
- [#584](https://github.com/gimli-rs/object/pull/584)
-
-### Changed
-
-* Fixes for AArch64 relocation addends for Mach-O.
- [#581](https://github.com/gimli-rs/object/pull/581)
-
-* Changes to `write::Object` output for Mach-O, including the addition of a `LC_DYSYMTAB` load command.
- [#584](https://github.com/gimli-rs/object/pull/584)
-
-* Changed `write::Object` to always use `R_X86_64_PLT32` for x86-64 branches for ELF.
- [#590](https://github.com/gimli-rs/object/pull/590)
-
-* Fixed `read::ObjectSymbol::kind` for undefined section symbols for COFF.
- [#592](https://github.com/gimli-rs/object/pull/592)
-
-* Fixed `write::Object` to accept undefined section symbols for COFF.
- [#594](https://github.com/gimli-rs/object/pull/594)
-
-* Improved parsing of auxiliary section symbols for COFF.
- [#603](https://github.com/gimli-rs/object/pull/603)
-
-* Improved the selection of symbols for `read::Object::symbol_map`.
- This includes changes to `read::Symbol::is_definition`.
- [#601](https://github.com/gimli-rs/object/pull/601)
- [#606](https://github.com/gimli-rs/object/pull/606)
-
-* Changed `read::ObjectSymbol::kind` for ELF `STT_NOTYPE` symbols to `SymbolKind::Unknown`.
- [#604](https://github.com/gimli-rs/object/pull/604)
-
-* Changed `read::ObjectSymbol::scope` for XCOFF `C_HIDEXT` symbols to `SymbolScope::Compilation`.
- [#605](https://github.com/gimli-rs/object/pull/605)
-
---------------------------------------------------------------------------------
-
-## 0.32.1
-
-Released 2023/09/03.
-
-### Added
-
-* Added `write::Object::set_macho_cpu_subtype`.
- [#574](https://github.com/gimli-rs/object/pull/574)
-
---------------------------------------------------------------------------------
-
-## 0.32.0
-
-Released 2023/08/12.
-
-### Breaking changes
-
-* Changed `read::elf::Note::name` to exclude all trailing null bytes.
- [#549](https://github.com/gimli-rs/object/pull/549)
-
-* Updated dependencies, and changed some optional dependencies to use the `dep:`
- feature syntax.
- [#558](https://github.com/gimli-rs/object/pull/558)
- [#569](https://github.com/gimli-rs/object/pull/569)
-
-### Changed
-
-* The minimum supported rust version for the `read` feature and its dependencies
- has changed to 1.60.0.
-
-* The minimum supported rust version for other features has changed to 1.65.0.
-
-* Changed many definitions from `static` to `const`.
- [#549](https://github.com/gimli-rs/object/pull/549)
-
-* Fixed Mach-O section alignment padding in `write::Object`.
- [#553](https://github.com/gimli-rs/object/pull/553)
-
-* Changed `read::File` to an enum.
- [#564](https://github.com/gimli-rs/object/pull/564)
-
-### Added
-
-* Added `elf::ELF_NOTE_GO`, `elf::NT_GO_BUILD_ID`, and `read::elf::Note::name_bytes`.
- [#549](https://github.com/gimli-rs/object/pull/549)
-
-* Added `read::FileKind::CoffImport` and `read::coff::ImportFile`.
- [#555](https://github.com/gimli-rs/object/pull/555)
- [#556](https://github.com/gimli-rs/object/pull/556)
-
-* Added `Architecture::Csky` and basic ELF support for C-SKY.
- [#561](https://github.com/gimli-rs/object/pull/561)
-
-* Added `read::elf::ElfSymbol::raw_symbol`.
- [#562](https://github.com/gimli-rs/object/pull/562)
-
---------------------------------------------------------------------------------
-
-## 0.30.4
-
-Released 2023/06/05.
-
-### Changed
-
-* Fixed Mach-O section alignment padding in `write::Object`.
- [#553](https://github.com/gimli-rs/object/pull/553)
-
---------------------------------------------------------------------------------
-
-## 0.31.1
-
-Released 2023/05/09.
-
-### Changed
-
-* Fixed address for global symbols in `read::wasm`.
- [#539](https://github.com/gimli-rs/object/pull/539)
-
-* Fixed writing of alignment for empty ELF sections.
- [#540](https://github.com/gimli-rs/object/pull/540)
-
-### Added
-
-* Added more `elf::GNU_PROPERTY_*` definitions.
- Added `read::elf::note::gnu_properties`, `write::StandardSection::GnuProperty`,
- and `write::Object::add_elf_gnu_property_u32`.
- [#537](https://github.com/gimli-rs/object/pull/537)
- [#541](https://github.com/gimli-rs/object/pull/541)
-
-* Added Mach-O support for `Architecture::Aarch64_Ilp32`.
- [#542](https://github.com/gimli-rs/object/pull/542)
- [#545](https://github.com/gimli-rs/object/pull/545)
-
-* Added `Architecture::Wasm64`.
- [#543](https://github.com/gimli-rs/object/pull/543)
-
---------------------------------------------------------------------------------
-
-## 0.31.0
-
-Released 2023/04/14.
-
-### Breaking changes
-
-* Added a type parameter on existing COFF types to support reading COFF `/bigobj` files.
- [#502](https://github.com/gimli-rs/object/pull/502)
-
-* Changed PE symbols to support COFF `/bigobj`.
- Changed `pe::IMAGE_SYM_*` to `i32`.
- Changed `pe::ImageSymbolEx::section_number` to `I32Bytes`.
- Deleted a number of methods from `pe::ImageSymbol`.
- Use the `read::pe::ImageSymbol` trait instead.
- [#502](https://github.com/gimli-rs/object/pull/502)
-
-* Changed `pe::Guid` to a single array, and added methods to read the individual fields.
- [#502](https://github.com/gimli-rs/object/pull/502)
-
-* Added `Symbol` type parameter to `SymbolFlags` to support `SymbolFlags::Xcoff`.
- [#527](https://github.com/gimli-rs/object/pull/527)
-
-### Changed
-
-* Fix alignment when reserving zero length sections in `write::elf::Write::reserve`.
- [#514](https://github.com/gimli-rs/object/pull/514)
-
-* Validate command size in `read::macho::LoadCommandIterator`.
- [#516](https://github.com/gimli-rs/object/pull/516)
-
-* Handle invalid alignment in `read::macho::MachoSection::align`.
- [#516](https://github.com/gimli-rs/object/pull/516)
-
-* Accept `SymbolKind::Unknown` in `write::Object::macho_write`.
- [#519](https://github.com/gimli-rs/object/pull/519)
-
-* Updated `wasmparser` dependency.
- [#528](https://github.com/gimli-rs/object/pull/528)
-
-### Added
-
-* Added more `elf::EF_RISCV_*` definitions.
- [#507](https://github.com/gimli-rs/object/pull/507)
-
-* Added `read::elf::SectionHeader::gnu_attributes` and associated types.
- Added `.gnu.attributes` support to `write::elf::Writer`.
- [#509](https://github.com/gimli-rs/object/pull/509)
- [#525](https://github.com/gimli-rs/object/pull/525)
-
-* Added `write::Object::set_macho_build_version`.
- [#524](https://github.com/gimli-rs/object/pull/524)
-
-* Added `read::FileKind::Xcoff32`, `read::FileKind::Xcoff64`, `read::XcoffFile`,
- and associated types.
- Added XCOFF support to `write::Object`.
- [#469](https://github.com/gimli-rs/object/pull/469)
- [#476](https://github.com/gimli-rs/object/pull/476)
- [#477](https://github.com/gimli-rs/object/pull/477)
- [#482](https://github.com/gimli-rs/object/pull/482)
- [#484](https://github.com/gimli-rs/object/pull/484)
- [#486](https://github.com/gimli-rs/object/pull/486)
- [#527](https://github.com/gimli-rs/object/pull/527)
-
-* Added `read::FileKind::CoffBig`, `read::pe::CoffHeader` and `read::pe::ImageSymbol`.
- [#502](https://github.com/gimli-rs/object/pull/502)
-
-* Added `elf::PT_GNU_PROPERTY`.
- [#530](https://github.com/gimli-rs/object/pull/530)
-
-* Added `elf::ELFCOMPRESS_ZSTD`, `read::CompressionFormat::Zstandard`,
- and Zstandard decompression in `read::CompressedData::decompress` using
- the `ruzstd` crate.
- [#532](https://github.com/gimli-rs/object/pull/532)
-
-* Added `read::elf::NoteIterator::new`.
- [#533](https://github.com/gimli-rs/object/pull/533)
-
---------------------------------------------------------------------------------
-
-## 0.30.3
-
-Released 2023/01/23.
-
-### Added
-
-* Added `SectionKind::ReadOnlyDataWithRel` for writing.
- [#504](https://github.com/gimli-rs/object/pull/504)
-
---------------------------------------------------------------------------------
-
-## 0.30.2
-
-Released 2023/01/11.
-
-### Added
-
-* Added more ELF constants for AVR flags and relocations.
- [#500](https://github.com/gimli-rs/object/pull/500)
-
---------------------------------------------------------------------------------
-
-## 0.30.1
-
-Released 2023/01/04.
-
-### Changed
-
-* Changed `read::ElfSymbol::kind` to handle `STT_NOTYPE` and `STT_GNU_IFUNC`.
- [#498](https://github.com/gimli-rs/object/pull/498)
-
-### Added
-
-* Added `read::CoffSymbol::raw_symbol`.
- [#494](https://github.com/gimli-rs/object/pull/494)
-
-* Added ELF support for Solana Binary Format.
- [#491](https://github.com/gimli-rs/object/pull/491)
-
-* Added ELF support for AArch64 ILP32.
- [#497](https://github.com/gimli-rs/object/pull/497)
-
---------------------------------------------------------------------------------
-
-## 0.30.0
-
-Released 2022/11/22.
-
-### Breaking changes
-
-* The minimum supported rust version for the `read` feature has changed to 1.52.0.
- [#458](https://github.com/gimli-rs/object/pull/458)
-
-* The minimum supported rust version for the `write` feature has changed to 1.61.0.
-
-* Fixed endian handling in `read::elf::SymbolTable::shndx`.
- [#458](https://github.com/gimli-rs/object/pull/458)
-
-* Fixed endian handling in `read::pe::ResourceName`.
- [#458](https://github.com/gimli-rs/object/pull/458)
-
-* Changed definitions for LoongArch ELF header flags.
- [#483](https://github.com/gimli-rs/object/pull/483)
-
-### Changed
-
-* Fixed parsing of multiple debug directory entries in `read::pe::PeFile::pdb_info`.
- [#451](https://github.com/gimli-rs/object/pull/451)
-
-* Changed the section name used when writing COFF stub symbols.
- [#475](https://github.com/gimli-rs/object/pull/475)
-
-### Added
-
-* Added `read::pe::DataDirectories::delay_load_import_table`.
- [#448](https://github.com/gimli-rs/object/pull/448)
-
-* Added `read::macho::LoadCommandData::raw_data`.
- [#449](https://github.com/gimli-rs/object/pull/449)
-
-* Added ELF relocations for LoongArch ps ABI v2.
- [#450](https://github.com/gimli-rs/object/pull/450)
-
-* Added PowerPC support for Mach-O.
- [#460](https://github.com/gimli-rs/object/pull/460)
-
-* Added support for reading the AIX big archive format.
- [#462](https://github.com/gimli-rs/object/pull/462)
- [#467](https://github.com/gimli-rs/object/pull/467)
- [#473](https://github.com/gimli-rs/object/pull/473)
-
-* Added support for `RelocationEncoding::AArch64Call` when writing Mach-O files.
- [#465](https://github.com/gimli-rs/object/pull/465)
-
-* Added support for `RelocationKind::Relative` when writing RISC-V ELF files.
- [#470](https://github.com/gimli-rs/object/pull/470)
-
-* Added Xtensa architecture support for ELF.
- [#481](https://github.com/gimli-rs/object/pull/481)
-
-* Added `read::pe::ResourceName::raw_data`.
- [#487](https://github.com/gimli-rs/object/pull/487)
-
---------------------------------------------------------------------------------
-
-## 0.29.0
-
-Released 2022/06/22.
-
-### Breaking changes
-
-* The `write` feature now has a minimum supported rust version of 1.56.1.
- [#444](https://github.com/gimli-rs/object/pull/444)
-
-* Added `os_abi` and `abi_version` fields to `FileFlags::Elf`.
- [#438](https://github.com/gimli-rs/object/pull/438)
- [#441](https://github.com/gimli-rs/object/pull/441)
-
-### Changed
-
-* Fixed handling of empty symbol tables in `read::elf::ElfFile::symbol_table` and
- `read::elf::ElfFile::dynamic_symbol_table`.
- [#443](https://github.com/gimli-rs/object/pull/443)
-
-### Added
-
-* Added more `ELF_OSABI_*` constants.
- [#439](https://github.com/gimli-rs/object/pull/439)
-
---------------------------------------------------------------------------------
-
-## 0.28.4
-
-Released 2022/05/09.
-
-### Added
-
-* Added `read::pe::DataDirectories::resource_directory`.
- [#425](https://github.com/gimli-rs/object/pull/425)
- [#427](https://github.com/gimli-rs/object/pull/427)
-
-* Added PE support for more ARM relocations.
- [#428](https://github.com/gimli-rs/object/pull/428)
-
-* Added support for `Architecture::LoongArch64`.
- [#430](https://github.com/gimli-rs/object/pull/430)
- [#432](https://github.com/gimli-rs/object/pull/432)
-
-* Added `elf::EF_MIPS_ABI` and associated constants.
- [#433](https://github.com/gimli-rs/object/pull/433)
-
---------------------------------------------------------------------------------
-
-## 0.28.3
-
-Released 2022/01/19.
-
-### Changed
-
-* For the Mach-O support in `write::Object`, accept `RelocationKind::MachO` for all
- architectures, and accept `RelocationKind::Absolute` for ARM64.
- [#422](https://github.com/gimli-rs/object/pull/422)
-
-### Added
-
-* Added `pe::ImageDataDirectory::file_range`, `read::pe::SectionTable::pe_file_range_at`
- and `pe::ImageSectionHeader::pe_file_range_at`.
- [#421](https://github.com/gimli-rs/object/pull/421)
-
-* Added `write::Object::add_coff_exports`.
- [#423](https://github.com/gimli-rs/object/pull/423)
-
---------------------------------------------------------------------------------
-
-## 0.28.2
-
-Released 2022/01/09.
-
-### Changed
-
-* Ignored errors for the Wasm extended name section in `read::WasmFile::parse`.
- [#408](https://github.com/gimli-rs/object/pull/408)
-
-* Ignored errors for the COFF symbol table in `read::PeFile::parse`.
- [#410](https://github.com/gimli-rs/object/pull/410)
-
-* Fixed handling of `SectionFlags::Coff` in `write::Object::coff_write`.
- [#412](https://github.com/gimli-rs/object/pull/412)
-
-### Added
-
-* Added `read::ObjectSegment::flags`.
- [#416](https://github.com/gimli-rs/object/pull/416)
- [#418](https://github.com/gimli-rs/object/pull/418)
-
---------------------------------------------------------------------------------
-
-## 0.28.1
-
-Released 2021/12/12.
-
-### Changed
-
-* Fixed `read::elf::SymbolTable::shndx_section`.
- [#405](https://github.com/gimli-rs/object/pull/405)
-
-* Fixed build warnings.
- [#405](https://github.com/gimli-rs/object/pull/405)
- [#406](https://github.com/gimli-rs/object/pull/406)
-
---------------------------------------------------------------------------------
-
-## 0.28.0
-
-Released 2021/12/12.
-
-### Breaking changes
-
-* `write_core` feature no longer enables `std` support. Use `write_std` instead.
- [#400](https://github.com/gimli-rs/object/pull/400)
-
-* Multiple changes related to Mach-O split dyld cache support.
- [#398](https://github.com/gimli-rs/object/pull/398)
-
-### Added
-
-* Added `write::pe::Writer::write_file_align`.
- [#397](https://github.com/gimli-rs/object/pull/397)
-
-* Added support for Mach-O split dyld cache.
- [#398](https://github.com/gimli-rs/object/pull/398)
-
-* Added support for `IMAGE_SCN_LNK_NRELOC_OVFL` when reading and writing COFF.
- [#399](https://github.com/gimli-rs/object/pull/399)
-
-* Added `write::elf::Writer::reserve_null_symbol_index`.
- [#402](https://github.com/gimli-rs/object/pull/402)
-
---------------------------------------------------------------------------------
-
-## 0.27.1
-
-Released 2021/10/22.
-
-### Changed
-
-* Fixed build error with older Rust versions due to cargo resolver version.
-
---------------------------------------------------------------------------------
-
-## 0.27.0
-
-Released 2021/10/17.
-
-### Breaking changes
-
-* Changed `read::elf` to use `SectionIndex` instead of `usize` in more places.
- [#341](https://github.com/gimli-rs/object/pull/341)
-
-* Changed some `read::elf` section methods to additionally return the linked section index.
- [#341](https://github.com/gimli-rs/object/pull/341)
-
-* Changed `read::pe::ImageNtHeaders::parse` to return `DataDirectories` instead of a slice.
- [#357](https://github.com/gimli-rs/object/pull/357)
-
-* Deleted `value` parameter for `write:WritableBuffer::resize`.
- [#369](https://github.com/gimli-rs/object/pull/369)
-
-* Changed `write::Object` and `write::Section` to use `Cow` for section data.
- This added a lifetime parameter, which existing users can set to `'static`.
- [#370](https://github.com/gimli-rs/object/pull/370)
-
-### Changed
-
-* Fixed parsing when PE import directory has zero size.
- [#341](https://github.com/gimli-rs/object/pull/341)
-
-* Fixed parsing when PE import directory has zero for original first thunk.
- [#385](https://github.com/gimli-rs/object/pull/385)
- [#387](https://github.com/gimli-rs/object/pull/387)
-
-* Fixed parsing when PE export directory has zero number of names.
- [#353](https://github.com/gimli-rs/object/pull/353)
-
-* Fixed parsing when PE export directory has zero number of names and addresses.
- [#362](https://github.com/gimli-rs/object/pull/362)
-
-* Fixed parsing when PE sections are contiguous.
- [#354](https://github.com/gimli-rs/object/pull/354)
-
-* Fixed `std` feature for `indexmap` dependency.
- [#374](https://github.com/gimli-rs/object/pull/374)
-
-* Fixed overflow in COFF section name offset parsing.
- [#390](https://github.com/gimli-rs/object/pull/390)
-
-### Added
-
-* Added `name_bytes` methods to unified `read` traits.
- [#351](https://github.com/gimli-rs/object/pull/351)
-
-* Added `read::Object::kind`.
- [#352](https://github.com/gimli-rs/object/pull/352)
-
-* Added `read::elf::VersionTable` and related helpers.
- [#341](https://github.com/gimli-rs/object/pull/341)
-
-* Added `read::elf::SectionTable::dynamic` and related helpers.
- [#345](https://github.com/gimli-rs/object/pull/345)
-
-* Added `read::coff::SectionTable::max_section_file_offset`.
- [#344](https://github.com/gimli-rs/object/pull/344)
-
-* Added `read::pe::ExportTable` and related helpers.
- [#349](https://github.com/gimli-rs/object/pull/349)
- [#353](https://github.com/gimli-rs/object/pull/353)
-
-* Added `read::pe::ImportTable` and related helpers.
- [#357](https://github.com/gimli-rs/object/pull/357)
-
-* Added `read::pe::DataDirectories` and related helpers.
- [#357](https://github.com/gimli-rs/object/pull/357)
- [#384](https://github.com/gimli-rs/object/pull/384)
-
-* Added `read::pe::RichHeaderInfo` and related helpers.
- [#375](https://github.com/gimli-rs/object/pull/375)
- [#379](https://github.com/gimli-rs/object/pull/379)
-
-* Added `read::pe::RelocationBlocks` and related helpers.
- [#378](https://github.com/gimli-rs/object/pull/378)
-
-* Added `write::elf::Writer`.
- [#350](https://github.com/gimli-rs/object/pull/350)
-
-* Added `write::pe::Writer`.
- [#382](https://github.com/gimli-rs/object/pull/382)
- [#388](https://github.com/gimli-rs/object/pull/388)
-
-* Added `write::Section::data/data_mut`.
- [#367](https://github.com/gimli-rs/object/pull/367)
-
-* Added `write::Object::write_stream`.
- [#369](https://github.com/gimli-rs/object/pull/369)
-
-* Added MIPSr6 ELF header flag definitions.
- [#372](https://github.com/gimli-rs/object/pull/372)
-
---------------------------------------------------------------------------------
-
-## 0.26.2
-
-Released 2021/08/28.
-
-### Added
-
-* Added support for 64-bit symbol table names to `read::archive`.
- [#366](https://github.com/gimli-rs/object/pull/366)
-
---------------------------------------------------------------------------------
-
-## 0.26.1
-
-Released 2021/08/19.
-
-### Changed
-
-* Activate `memchr`'s `rustc-dep-of-std` feature
- [#356](https://github.com/gimli-rs/object/pull/356)
-
---------------------------------------------------------------------------------
-
-## 0.26.0
-
-Released 2021/07/26.
-
-### Breaking changes
-
-* Changed `ReadRef::read_bytes_at_until` to accept a range parameter.
- [#326](https://github.com/gimli-rs/object/pull/326)
-
-* Added `ReadRef` type parameter to `read::StringTable` and types that
- contain it. String table entries are now only read as required.
- [#326](https://github.com/gimli-rs/object/pull/326)
-
-* Changed result type of `read::elf::SectionHeader::data` and `data_as_array`.
- [#332](https://github.com/gimli-rs/object/pull/332)
-
-* Moved `pod::WritableBuffer` to `write::WritableBuffer`.
- Renamed `WritableBuffer::extend` to `write_bytes`.
- Added more provided methods to `WritableBuffer`.
- [#335](https://github.com/gimli-rs/object/pull/335)
-
-* Moved `pod::Bytes` to `read::Bytes`.
- [#336](https://github.com/gimli-rs/object/pull/336)
-
-* Added `is_mips64el` parameter to `elf::Rela64::r_info/set_r_info`.
- [#337](https://github.com/gimli-rs/object/pull/337)
-
-### Changed
-
-* Removed `alloc` dependency when no features are enabled.
- [#336](https://github.com/gimli-rs/object/pull/336)
-
-### Added
-
-* Added `read::pe::PeFile` methods: `section_table`, `data_directory`, and `data`.
- [#324](https://github.com/gimli-rs/object/pull/324)
-
-* Added more ELF definitions.
- [#332](https://github.com/gimli-rs/object/pull/332)
-
-* Added `read::elf::SectionTable` methods for hash tables and symbol version
- information.
- [#332](https://github.com/gimli-rs/object/pull/332)
-
-* Added PE RISC-V definitions.
- [#333](https://github.com/gimli-rs/object/pull/333)
-
-* Added `WritableBuffer` implementation for `Vec`.
- [#335](https://github.com/gimli-rs/object/pull/335)
-
---------------------------------------------------------------------------------
-
-## 0.25.3
-
-Released 2021/06/12.
-
-### Added
-
-* Added `RelocationEncoding::AArch64Call`.
- [#322](https://github.com/gimli-rs/object/pull/322)
-
---------------------------------------------------------------------------------
-
-## 0.25.2
-
-Released 2021/06/04.
-
-### Added
-
-* Added `Architecture::X86_64_X32`.
- [#320](https://github.com/gimli-rs/object/pull/320)
-
---------------------------------------------------------------------------------
-
-## 0.25.1
-
-Released 2021/06/03.
-
-### Changed
-
-* write: Fix choice of `SHT_REL` or `SHT_RELA` for most architectures.
- [#318](https://github.com/gimli-rs/object/pull/318)
-
-* write: Fix relocation encoding for MIPS64EL.
- [#318](https://github.com/gimli-rs/object/pull/318)
-
---------------------------------------------------------------------------------
-
-## 0.25.0
-
-Released 2021/06/02.
-
-### Breaking changes
-
-* Added `non_exhaustive` to most public enums.
- [#306](https://github.com/gimli-rs/object/pull/306)
-
-* `MachHeader::parse` and `MachHeader::load_commands` now require a header offset.
- [#304](https://github.com/gimli-rs/object/pull/304)
-
-* Added `ReadRef::read_bytes_at_until`.
- [#308](https://github.com/gimli-rs/object/pull/308)
-
-* `PeFile::entry`, `PeSection::address` and `PeSegment::address` now return a
- virtual address instead of a RVA.
- [#315](https://github.com/gimli-rs/object/pull/315)
-
-### Added
-
-* Added `pod::from_bytes_mut`, `pod::slice_from_bytes_mut`, `pod::bytes_of_mut`,
- and `pod::bytes_of_slice_mut`.
- [#296](https://github.com/gimli-rs/object/pull/296)
- [#297](https://github.com/gimli-rs/object/pull/297)
-
-* Added `Object::pdb_info`.
- [#298](https://github.com/gimli-rs/object/pull/298)
-
-* Added `read::macho::DyldCache`, other associated definitions,
- and support for these in the examples.
- [#308](https://github.com/gimli-rs/object/pull/308)
-
-* Added more architecture support.
- [#303](https://github.com/gimli-rs/object/pull/303)
- [#309](https://github.com/gimli-rs/object/pull/309)
-
-* Derive more traits for enums.
- [#311](https://github.com/gimli-rs/object/pull/311)
-
-* Added `Object::relative_address_base`.
- [#315](https://github.com/gimli-rs/object/pull/315)
-
-### Changed
-
-* Improved performance for string parsing.
- [#302](https://github.com/gimli-rs/object/pull/302)
-
-* `objdump` example allows selecting container members.
- [#308](https://github.com/gimli-rs/object/pull/308)
diff --git a/vendor/object/Cargo.toml b/vendor/object/Cargo.toml
deleted file mode 100644
index c408ae5..0000000
--- a/vendor/object/Cargo.toml
+++ /dev/null
@@ -1,163 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies.
-#
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
-
-[package]
-edition = "2018"
-rust-version = "1.60"
-name = "object"
-version = "0.32.2"
-exclude = [
- "/.github",
- "/testfiles",
-]
-description = "A unified interface for reading and writing object file formats."
-readme = "README.md"
-keywords = [
- "object",
- "elf",
- "mach-o",
- "pe",
- "coff",
-]
-license = "Apache-2.0 OR MIT"
-repository = "https://github.com/gimli-rs/object"
-resolver = "2"
-
-[package.metadata.docs.rs]
-features = ["doc"]
-
-[dependencies.alloc]
-version = "1.0.0"
-optional = true
-package = "rustc-std-workspace-alloc"
-
-[dependencies.compiler_builtins]
-version = "0.1.2"
-optional = true
-
-[dependencies.core]
-version = "1.0.0"
-optional = true
-package = "rustc-std-workspace-core"
-
-[dependencies.crc32fast]
-version = "1.2"
-optional = true
-default-features = false
-
-[dependencies.flate2]
-version = "1"
-optional = true
-
-[dependencies.hashbrown]
-version = "0.14.0"
-features = ["ahash"]
-optional = true
-default-features = false
-
-[dependencies.indexmap]
-version = "2.0"
-optional = true
-default-features = false
-
-[dependencies.memchr]
-version = "2.4.1"
-default-features = false
-
-[dependencies.ruzstd]
-version = "0.5.0"
-optional = true
-
-[dependencies.wasmparser]
-version = "0.118.0"
-optional = true
-
-[features]
-all = [
- "read",
- "write",
- "std",
- "compression",
- "wasm",
-]
-archive = []
-cargo-all = []
-coff = []
-compression = [
- "dep:flate2",
- "dep:ruzstd",
- "std",
-]
-default = [
- "read",
- "compression",
-]
-doc = [
- "read_core",
- "write_std",
- "std",
- "compression",
- "archive",
- "coff",
- "elf",
- "macho",
- "pe",
- "wasm",
- "xcoff",
-]
-elf = []
-macho = []
-pe = ["coff"]
-read = [
- "read_core",
- "archive",
- "coff",
- "elf",
- "macho",
- "pe",
- "xcoff",
- "unaligned",
-]
-read_core = []
-rustc-dep-of-std = [
- "core",
- "compiler_builtins",
- "alloc",
- "memchr/rustc-dep-of-std",
-]
-std = ["memchr/std"]
-unaligned = []
-unstable = []
-unstable-all = [
- "all",
- "unstable",
-]
-wasm = ["dep:wasmparser"]
-write = [
- "write_std",
- "coff",
- "elf",
- "macho",
- "pe",
- "xcoff",
-]
-write_core = [
- "dep:crc32fast",
- "dep:indexmap",
- "dep:hashbrown",
-]
-write_std = [
- "write_core",
- "std",
- "indexmap?/std",
- "crc32fast?/std",
-]
-xcoff = []
diff --git a/vendor/object/LICENSE-APACHE b/vendor/object/LICENSE-APACHE
deleted file mode 100644
index 16fe87b..0000000
--- a/vendor/object/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/vendor/object/LICENSE-MIT b/vendor/object/LICENSE-MIT
deleted file mode 100644
index 8440c7e..0000000
--- a/vendor/object/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2015 The Gimli Developers
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/vendor/object/README.md b/vendor/object/README.md
deleted file mode 100644
index 08d9c80..0000000
--- a/vendor/object/README.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# `object`
-
-The `object` crate provides a unified interface to working with object files
-across platforms. It supports reading relocatable object files and executable files,
-and writing COFF/ELF/Mach-O/XCOFF relocatable object files and ELF/PE executable files.
-
-For reading files, it provides multiple levels of support:
-
-* raw struct definitions suitable for zero copy access
-* low level APIs for accessing the raw structs ([example](crates/examples/src/readobj/))
-* a higher level unified API for accessing common features of object files, such
- as sections and symbols ([example](crates/examples/src/objdump.rs))
-
-Supported file formats: ELF, Mach-O, Windows PE/COFF, Wasm, XCOFF, and Unix archive.
-
-## Example for unified read API
-```rust
-use object::{Object, ObjectSection};
-use std::error::Error;
-use std::fs;
-
-/// Reads a file and displays the name of each section.
-fn main() -> Result<(), Box<dyn Error>> {
- let binary_data = fs::read("path/to/binary")?;
- let file = object::File::parse(&*binary_data)?;
- for section in file.sections() {
- println!("{}", section.name()?);
- }
- Ok(())
-}
-```
-
-See [`crates/examples`](crates/examples) for more examples.
-
-## Minimum Supported Rust Version (MSRV)
-
-Changes to MSRV are considered breaking changes. We are conservative about changing the MSRV,
-but sometimes are required to due to dependencies. The MSRV is:
-
- * 1.60.0 for the `read` feature and its dependencies.
- * 1.65.0 for other features.
-
-## License
-
-Licensed under either of
-
- * Apache License, Version 2.0 ([`LICENSE-APACHE`](./LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
- * MIT license ([`LICENSE-MIT`](./LICENSE-MIT) or https://opensource.org/licenses/MIT)
-
-at your option.
-
-## Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
-dual licensed as above, without any additional terms or conditions.
diff --git a/vendor/object/clippy.toml b/vendor/object/clippy.toml
deleted file mode 100644
index 16caf02..0000000
--- a/vendor/object/clippy.toml
+++ /dev/null
@@ -1 +0,0 @@
-msrv = "1.60.0"
diff --git a/vendor/object/src/archive.rs b/vendor/object/src/archive.rs
deleted file mode 100644
index 6271d07..0000000
--- a/vendor/object/src/archive.rs
+++ /dev/null
@@ -1,91 +0,0 @@
-//! Archive definitions.
-//!
-//! These definitions are independent of read/write support, although we do implement
-//! some traits useful for those.
-
-use crate::pod::Pod;
-
-/// File identification bytes stored at the beginning of the file.
-pub const MAGIC: [u8; 8] = *b"!<arch>\n";
-
-/// File identification bytes at the beginning of AIX big archive.
-pub const AIX_BIG_MAGIC: [u8; 8] = *b"<bigaf>\n";
-
-/// File identification bytes stored at the beginning of a thin archive.
-///
-/// A thin archive only contains a symbol table and file names.
-pub const THIN_MAGIC: [u8; 8] = *b"!<thin>\n";
-
-/// The terminator for each archive member header.
-pub const TERMINATOR: [u8; 2] = *b"`\n";
-
-/// The header at the start of an archive member.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Header {
- /// The file name.
- pub name: [u8; 16],
- /// File modification timestamp in decimal.
- pub date: [u8; 12],
- /// User ID in decimal.
- pub uid: [u8; 6],
- /// Group ID in decimal.
- pub gid: [u8; 6],
- /// File mode in octal.
- pub mode: [u8; 8],
- /// File size in decimal.
- pub size: [u8; 10],
- /// Must be equal to `TERMINATOR`.
- pub terminator: [u8; 2],
-}
-
-/// The header at the start of an AIX big archive member, without name.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct AixHeader {
- /// File member size in decimal.
- pub size: [u8; 20],
- /// Next member offset in decimal.
- pub nxtmem: [u8; 20],
- /// Previous member offset in decimal.
- pub prvmem: [u8; 20],
- /// File member date in decimal.
- pub date: [u8; 12],
- /// File member user id in decimal.
- pub uid: [u8; 12],
- /// File member group id in decimal.
- pub gid: [u8; 12],
- /// File member mode in octal.
- pub mode: [u8; 12],
- /// File member name length in decimal.
- pub namlen: [u8; 4],
-}
-
-/// The AIX big archive's fixed length header at file beginning.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct AixFileHeader {
- /// Archive magic string.
- pub magic: [u8; 8],
- /// Offset of member table.
- pub memoff: [u8; 20],
- /// Offset of global symbol table.
- pub gstoff: [u8; 20],
- /// Offset of global symbol table for 64-bit objects.
- pub gst64off: [u8; 20],
- /// Offset of first member.
- pub fstmoff: [u8; 20],
- /// Offset of last member.
- pub lstmoff: [u8; 20],
- /// Offset of first member on free list.
- pub freeoff: [u8; 20],
-}
-
-/// Offset of a member in an AIX big archive.
-///
-/// This is used in the member index.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct AixMemberOffset(pub [u8; 20]);
-
-unsafe_impl_pod!(Header, AixHeader, AixFileHeader, AixMemberOffset,);
diff --git a/vendor/object/src/common.rs b/vendor/object/src/common.rs
deleted file mode 100644
index 36f6656..0000000
--- a/vendor/object/src/common.rs
+++ /dev/null
@@ -1,536 +0,0 @@
-/// A CPU architecture.
-#[allow(missing_docs)]
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum Architecture {
- Unknown,
- Aarch64,
- #[allow(non_camel_case_types)]
- Aarch64_Ilp32,
- Arm,
- Avr,
- Bpf,
- Csky,
- I386,
- X86_64,
- #[allow(non_camel_case_types)]
- X86_64_X32,
- Hexagon,
- LoongArch64,
- Mips,
- Mips64,
- Msp430,
- PowerPc,
- PowerPc64,
- Riscv32,
- Riscv64,
- S390x,
- Sbf,
- Sharc,
- Sparc64,
- Wasm32,
- Wasm64,
- Xtensa,
-}
-
-/// A CPU sub-architecture.
-#[allow(missing_docs)]
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum SubArchitecture {
- Arm64E,
- Arm64EC,
-}
-
-impl Architecture {
- /// The size of an address value for this architecture.
- ///
- /// Returns `None` for unknown architectures.
- pub fn address_size(self) -> Option<AddressSize> {
- match self {
- Architecture::Unknown => None,
- Architecture::Aarch64 => Some(AddressSize::U64),
- Architecture::Aarch64_Ilp32 => Some(AddressSize::U32),
- Architecture::Arm => Some(AddressSize::U32),
- Architecture::Avr => Some(AddressSize::U8),
- Architecture::Bpf => Some(AddressSize::U64),
- Architecture::Csky => Some(AddressSize::U32),
- Architecture::I386 => Some(AddressSize::U32),
- Architecture::X86_64 => Some(AddressSize::U64),
- Architecture::X86_64_X32 => Some(AddressSize::U32),
- Architecture::Hexagon => Some(AddressSize::U32),
- Architecture::LoongArch64 => Some(AddressSize::U64),
- Architecture::Mips => Some(AddressSize::U32),
- Architecture::Mips64 => Some(AddressSize::U64),
- Architecture::Msp430 => Some(AddressSize::U16),
- Architecture::PowerPc => Some(AddressSize::U32),
- Architecture::PowerPc64 => Some(AddressSize::U64),
- Architecture::Riscv32 => Some(AddressSize::U32),
- Architecture::Riscv64 => Some(AddressSize::U64),
- Architecture::S390x => Some(AddressSize::U64),
- Architecture::Sbf => Some(AddressSize::U64),
- Architecture::Sharc => Some(AddressSize::U32),
- Architecture::Sparc64 => Some(AddressSize::U64),
- Architecture::Wasm32 => Some(AddressSize::U32),
- Architecture::Wasm64 => Some(AddressSize::U64),
- Architecture::Xtensa => Some(AddressSize::U32),
- }
- }
-}
-
-/// The size of an address value for an architecture.
-///
-/// This may differ from the address size supported by the file format (such as for COFF).
-#[allow(missing_docs)]
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-#[repr(u8)]
-pub enum AddressSize {
- U8 = 1,
- U16 = 2,
- U32 = 4,
- U64 = 8,
-}
-
-impl AddressSize {
- /// The size in bytes of an address value.
- #[inline]
- pub fn bytes(self) -> u8 {
- self as u8
- }
-}
-
-/// A binary file format.
-#[allow(missing_docs)]
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum BinaryFormat {
- Coff,
- Elf,
- MachO,
- Pe,
- Wasm,
- Xcoff,
-}
-
-/// The kind of a section.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum SectionKind {
- /// The section kind is unknown.
- Unknown,
- /// An executable code section.
- ///
- /// Example ELF sections: `.text`
- ///
- /// Example Mach-O sections: `__TEXT/__text`
- Text,
- /// A data section.
- ///
- /// Example ELF sections: `.data`
- ///
- /// Example Mach-O sections: `__DATA/__data`
- Data,
- /// A read only data section.
- ///
- /// Example ELF sections: `.rodata`
- ///
- /// Example Mach-O sections: `__TEXT/__const`, `__DATA/__const`, `__TEXT/__literal4`
- ReadOnlyData,
- /// A read only data section with relocations.
- ///
- /// This is the same as either `Data` or `ReadOnlyData`, depending on the file format.
- /// This value is only used in the API for writing files. It is never returned when reading files.
- ReadOnlyDataWithRel,
- /// A loadable string section.
- ///
- /// Example ELF sections: `.rodata.str`
- ///
- /// Example Mach-O sections: `__TEXT/__cstring`
- ReadOnlyString,
- /// An uninitialized data section.
- ///
- /// Example ELF sections: `.bss`
- ///
- /// Example Mach-O sections: `__DATA/__bss`
- UninitializedData,
- /// An uninitialized common data section.
- ///
- /// Example Mach-O sections: `__DATA/__common`
- Common,
- /// A TLS data section.
- ///
- /// Example ELF sections: `.tdata`
- ///
- /// Example Mach-O sections: `__DATA/__thread_data`
- Tls,
- /// An uninitialized TLS data section.
- ///
- /// Example ELF sections: `.tbss`
- ///
- /// Example Mach-O sections: `__DATA/__thread_bss`
- UninitializedTls,
- /// A TLS variables section.
- ///
- /// This contains TLS variable structures, rather than the variable initializers.
- ///
- /// Example Mach-O sections: `__DATA/__thread_vars`
- TlsVariables,
- /// A non-loadable string section.
- ///
- /// Example ELF sections: `.comment`, `.debug_str`
- OtherString,
- /// Some other non-loadable section.
- ///
- /// Example ELF sections: `.debug_info`
- Other,
- /// Debug information.
- ///
- /// Example Mach-O sections: `__DWARF/__debug_info`
- Debug,
- /// Information for the linker.
- ///
- /// Example COFF sections: `.drectve`
- Linker,
- /// ELF note section.
- Note,
- /// Metadata such as symbols or relocations.
- ///
- /// Example ELF sections: `.symtab`, `.strtab`, `.group`
- Metadata,
- /// Some other ELF section type.
- ///
- /// This is the `sh_type` field in the section header.
- /// The meaning may be dependent on the architecture.
- Elf(u32),
-}
-
-impl SectionKind {
- /// Return true if this section contains zerofill data.
- pub fn is_bss(self) -> bool {
- self == SectionKind::UninitializedData
- || self == SectionKind::UninitializedTls
- || self == SectionKind::Common
- }
-}
-
-/// The selection kind for a COMDAT section group.
-///
-/// This determines the way in which the linker resolves multiple definitions of the COMDAT
-/// sections.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum ComdatKind {
- /// The selection kind is unknown.
- Unknown,
- /// Multiple definitions are allowed.
- ///
- /// An arbitrary definition is selected, and the rest are removed.
- ///
- /// This is the only supported selection kind for ELF.
- Any,
- /// Multiple definitions are not allowed.
- ///
- /// This is used to group sections without allowing duplicates.
- NoDuplicates,
- /// Multiple definitions must have the same size.
- ///
- /// An arbitrary definition is selected, and the rest are removed.
- SameSize,
- /// Multiple definitions must match exactly.
- ///
- /// An arbitrary definition is selected, and the rest are removed.
- ExactMatch,
- /// Multiple definitions are allowed, and the largest is selected.
- ///
- /// An arbitrary definition with the largest size is selected, and the rest are removed.
- Largest,
- /// Multiple definitions are allowed, and the newest is selected.
- Newest,
-}
-
-/// The kind of a symbol.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum SymbolKind {
- /// The symbol kind is unknown.
- Unknown,
- /// The symbol is a null placeholder.
- Null,
- /// The symbol is for executable code.
- Text,
- /// The symbol is for a data object.
- Data,
- /// The symbol is for a section.
- Section,
- /// The symbol is the name of a file. It precedes symbols within that file.
- File,
- /// The symbol is for a code label.
- Label,
- /// The symbol is for a thread local storage entity.
- Tls,
-}
-
-/// A symbol scope.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub enum SymbolScope {
- /// Unknown scope.
- Unknown,
- /// Symbol is visible to the compilation unit.
- Compilation,
- /// Symbol is visible to the static linkage unit.
- Linkage,
- /// Symbol is visible to dynamically linked objects.
- Dynamic,
-}
-
-/// The operation used to calculate the result of the relocation.
-///
-/// The relocation descriptions use the following definitions. Note that
-/// these definitions probably don't match any ELF ABI.
-///
-/// * A - The value of the addend.
-/// * G - The address of the symbol's entry within the global offset table.
-/// * L - The address of the symbol's entry within the procedure linkage table.
-/// * P - The address of the place of the relocation.
-/// * S - The address of the symbol.
-/// * GotBase - The address of the global offset table.
-/// * Image - The base address of the image.
-/// * Section - The address of the section containing the symbol.
-///
-/// 'XxxRelative' means 'Xxx + A - P'. 'XxxOffset' means 'S + A - Xxx'.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum RelocationKind {
- /// S + A
- Absolute,
- /// S + A - P
- Relative,
- /// G + A - GotBase
- Got,
- /// G + A - P
- GotRelative,
- /// GotBase + A - P
- GotBaseRelative,
- /// S + A - GotBase
- GotBaseOffset,
- /// L + A - P
- PltRelative,
- /// S + A - Image
- ImageOffset,
- /// S + A - Section
- SectionOffset,
- /// The index of the section containing the symbol.
- SectionIndex,
- /// Some other ELF relocation. The value is dependent on the architecture.
- Elf(u32),
- /// Some other Mach-O relocation. The value is dependent on the architecture.
- MachO {
- /// The relocation type.
- value: u8,
- /// Whether the relocation is relative to the place.
- relative: bool,
- },
- /// Some other COFF relocation. The value is dependent on the architecture.
- Coff(u16),
- /// Some other XCOFF relocation.
- Xcoff(u8),
-}
-
-/// Information about how the result of the relocation operation is encoded in the place.
-///
-/// This is usually architecture specific, such as specifying an addressing mode or
-/// a specific instruction.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum RelocationEncoding {
- /// Generic encoding.
- Generic,
-
- /// x86 sign extension at runtime.
- ///
- /// Used with `RelocationKind::Absolute`.
- X86Signed,
- /// x86 rip-relative addressing.
- ///
- /// The `RelocationKind` must be PC relative.
- X86RipRelative,
- /// x86 rip-relative addressing in movq instruction.
- ///
- /// The `RelocationKind` must be PC relative.
- X86RipRelativeMovq,
- /// x86 branch instruction.
- ///
- /// The `RelocationKind` must be PC relative.
- X86Branch,
-
- /// s390x PC-relative offset shifted right by one bit.
- ///
- /// The `RelocationKind` must be PC relative.
- S390xDbl,
-
- /// AArch64 call target.
- ///
- /// The `RelocationKind` must be PC relative.
- AArch64Call,
-
- /// LoongArch branch offset with two trailing zeros.
- ///
- /// The `RelocationKind` must be PC relative.
- LoongArchBranch,
-
- /// SHARC+ 48-bit Type A instruction
- ///
- /// Represents these possible variants, each with a corresponding
- /// `R_SHARC_*` constant:
- ///
- /// * 24-bit absolute address
- /// * 32-bit absolute address
- /// * 6-bit relative address
- /// * 24-bit relative address
- /// * 6-bit absolute address in the immediate value field
- /// * 16-bit absolute address in the immediate value field
- SharcTypeA,
-
- /// SHARC+ 32-bit Type B instruction
- ///
- /// Represents these possible variants, each with a corresponding
- /// `R_SHARC_*` constant:
- ///
- /// * 6-bit absolute address in the immediate value field
- /// * 7-bit absolute address in the immediate value field
- /// * 16-bit absolute address
- /// * 6-bit relative address
- SharcTypeB,
-}
-
-/// File flags that are specific to each file format.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum FileFlags {
- /// No file flags.
- None,
- /// ELF file flags.
- Elf {
- /// `os_abi` field in the ELF file header.
- os_abi: u8,
- /// `abi_version` field in the ELF file header.
- abi_version: u8,
- /// `e_flags` field in the ELF file header.
- e_flags: u32,
- },
- /// Mach-O file flags.
- MachO {
- /// `flags` field in the Mach-O file header.
- flags: u32,
- },
- /// COFF file flags.
- Coff {
- /// `Characteristics` field in the COFF file header.
- characteristics: u16,
- },
- /// XCOFF file flags.
- Xcoff {
- /// `f_flags` field in the XCOFF file header.
- f_flags: u16,
- },
-}
-
-/// Segment flags that are specific to each file format.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum SegmentFlags {
- /// No segment flags.
- None,
- /// ELF segment flags.
- Elf {
- /// `p_flags` field in the segment header.
- p_flags: u32,
- },
- /// Mach-O segment flags.
- MachO {
- /// `flags` field in the segment header.
- flags: u32,
- /// `maxprot` field in the segment header.
- maxprot: u32,
- /// `initprot` field in the segment header.
- initprot: u32,
- },
- /// COFF segment flags.
- Coff {
- /// `Characteristics` field in the segment header.
- characteristics: u32,
- },
-}
-
-/// Section flags that are specific to each file format.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum SectionFlags {
- /// No section flags.
- None,
- /// ELF section flags.
- Elf {
- /// `sh_flags` field in the section header.
- sh_flags: u64,
- },
- /// Mach-O section flags.
- MachO {
- /// `flags` field in the section header.
- flags: u32,
- },
- /// COFF section flags.
- Coff {
- /// `Characteristics` field in the section header.
- characteristics: u32,
- },
- /// XCOFF section flags.
- Xcoff {
- /// `s_flags` field in the section header.
- s_flags: u32,
- },
-}
-
-/// Symbol flags that are specific to each file format.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum SymbolFlags<Section, Symbol> {
- /// No symbol flags.
- None,
- /// ELF symbol flags.
- Elf {
- /// `st_info` field in the ELF symbol.
- st_info: u8,
- /// `st_other` field in the ELF symbol.
- st_other: u8,
- },
- /// Mach-O symbol flags.
- MachO {
- /// `n_desc` field in the Mach-O symbol.
- n_desc: u16,
- },
- /// COFF flags for a section symbol.
- CoffSection {
- /// `Selection` field in the auxiliary symbol for the section.
- selection: u8,
- /// `Number` field in the auxiliary symbol for the section.
- associative_section: Option<Section>,
- },
- /// XCOFF symbol flags.
- Xcoff {
- /// `n_sclass` field in the XCOFF symbol.
- n_sclass: u8,
- /// `x_smtyp` field in the CSECT auxiliary symbol.
- ///
- /// Only valid if `n_sclass` is `C_EXT`, `C_WEAKEXT`, or `C_HIDEXT`.
- x_smtyp: u8,
- /// `x_smclas` field in the CSECT auxiliary symbol.
- ///
- /// Only valid if `n_sclass` is `C_EXT`, `C_WEAKEXT`, or `C_HIDEXT`.
- x_smclas: u8,
- /// The containing csect for the symbol.
- ///
- /// Only valid if `x_smtyp` is `XTY_LD`.
- containing_csect: Option<Symbol>,
- },
-}
diff --git a/vendor/object/src/elf.rs b/vendor/object/src/elf.rs
deleted file mode 100644
index f620171..0000000
--- a/vendor/object/src/elf.rs
+++ /dev/null
@@ -1,6287 +0,0 @@
-//! ELF definitions.
-//!
-//! These definitions are independent of read/write support, although we do implement
-//! some traits useful for those.
-//!
-//! This module is the equivalent of /usr/include/elf.h, and is based heavily on it.
-
-#![allow(missing_docs)]
-#![allow(clippy::identity_op)]
-
-use crate::endian::{Endian, U32Bytes, U64Bytes, I32, I64, U16, U32, U64};
-use crate::pod::Pod;
-
-/// The header at the start of every 32-bit ELF file.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FileHeader32<E: Endian> {
- /// Magic number and other information.
- pub e_ident: Ident,
- /// Object file type. One of the `ET_*` constants.
- pub e_type: U16<E>,
- /// Architecture. One of the `EM_*` constants.
- pub e_machine: U16<E>,
- /// Object file version. Must be `EV_CURRENT`.
- pub e_version: U32<E>,
- /// Entry point virtual address.
- pub e_entry: U32<E>,
- /// Program header table file offset.
- pub e_phoff: U32<E>,
- /// Section header table file offset.
- pub e_shoff: U32<E>,
- /// Processor-specific flags.
- ///
- /// A combination of the `EF_*` constants.
- pub e_flags: U32<E>,
- /// Size in bytes of this header.
- pub e_ehsize: U16<E>,
- /// Program header table entry size.
- pub e_phentsize: U16<E>,
- /// Program header table entry count.
- ///
- /// If the count is greater than or equal to `PN_XNUM` then this field is set to
- /// `PN_XNUM` and the count is stored in the `sh_info` field of section 0.
- pub e_phnum: U16<E>,
- /// Section header table entry size.
- pub e_shentsize: U16<E>,
- /// Section header table entry count.
- ///
- /// If the count is greater than or equal to `SHN_LORESERVE` then this field is set to
- /// `0` and the count is stored in the `sh_size` field of section 0.
- /// first section header.
- pub e_shnum: U16<E>,
- /// Section header string table index.
- ///
- /// If the index is greater than or equal to `SHN_LORESERVE` then this field is set to
- /// `SHN_XINDEX` and the index is stored in the `sh_link` field of section 0.
- pub e_shstrndx: U16<E>,
-}
-
-/// The header at the start of every 64-bit ELF file.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FileHeader64<E: Endian> {
- /// Magic number and other information.
- pub e_ident: Ident,
- /// Object file type. One of the `ET_*` constants.
- pub e_type: U16<E>,
- /// Architecture. One of the `EM_*` constants.
- pub e_machine: U16<E>,
- /// Object file version. Must be `EV_CURRENT`.
- pub e_version: U32<E>,
- /// Entry point virtual address.
- pub e_entry: U64<E>,
- /// Program header table file offset.
- pub e_phoff: U64<E>,
- /// Section header table file offset.
- pub e_shoff: U64<E>,
- /// Processor-specific flags.
- ///
- /// A combination of the `EF_*` constants.
- pub e_flags: U32<E>,
- /// Size in bytes of this header.
- pub e_ehsize: U16<E>,
- /// Program header table entry size.
- pub e_phentsize: U16<E>,
- /// Program header table entry count.
- ///
- /// If the count is greater than or equal to `PN_XNUM` then this field is set to
- /// `PN_XNUM` and the count is stored in the `sh_info` field of section 0.
- pub e_phnum: U16<E>,
- /// Section header table entry size.
- pub e_shentsize: U16<E>,
- /// Section header table entry count.
- ///
- /// If the count is greater than or equal to `SHN_LORESERVE` then this field is set to
- /// `0` and the count is stored in the `sh_size` field of section 0.
- /// first section header.
- pub e_shnum: U16<E>,
- /// Section header string table index.
- ///
- /// If the index is greater than or equal to `SHN_LORESERVE` then this field is set to
- /// `SHN_XINDEX` and the index is stored in the `sh_link` field of section 0.
- pub e_shstrndx: U16<E>,
-}
-
-/// Magic number and other information.
-///
-/// Contained in the file header.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Ident {
- /// Magic number. Must be `ELFMAG`.
- pub magic: [u8; 4],
- /// File class. One of the `ELFCLASS*` constants.
- pub class: u8,
- /// Data encoding. One of the `ELFDATA*` constants.
- pub data: u8,
- /// ELF version. Must be `EV_CURRENT`.
- pub version: u8,
- /// OS ABI identification. One of the `ELFOSABI*` constants.
- pub os_abi: u8,
- /// ABI version.
- ///
- /// The meaning of this field depends on the `os_abi` value.
- pub abi_version: u8,
- /// Padding bytes.
- pub padding: [u8; 7],
-}
-
-/// File identification bytes stored in `Ident::magic`.
-pub const ELFMAG: [u8; 4] = [0x7f, b'E', b'L', b'F'];
-
-// Values for `Ident::class`.
-/// Invalid class.
-pub const ELFCLASSNONE: u8 = 0;
-/// 32-bit object.
-pub const ELFCLASS32: u8 = 1;
-/// 64-bit object.
-pub const ELFCLASS64: u8 = 2;
-
-// Values for `Ident::data`.
-/// Invalid data encoding.
-pub const ELFDATANONE: u8 = 0;
-/// 2's complement, little endian.
-pub const ELFDATA2LSB: u8 = 1;
-/// 2's complement, big endian.
-pub const ELFDATA2MSB: u8 = 2;
-
-// Values for `Ident::os_abi`.
-/// UNIX System V ABI.
-pub const ELFOSABI_NONE: u8 = 0;
-/// UNIX System V ABI.
-///
-/// Alias.
-pub const ELFOSABI_SYSV: u8 = 0;
-/// HP-UX.
-pub const ELFOSABI_HPUX: u8 = 1;
-/// NetBSD.
-pub const ELFOSABI_NETBSD: u8 = 2;
-/// Object uses GNU ELF extensions.
-pub const ELFOSABI_GNU: u8 = 3;
-/// Object uses GNU ELF extensions.
-///
-/// Compatibility alias.
-pub const ELFOSABI_LINUX: u8 = ELFOSABI_GNU;
-/// GNU/Hurd.
-pub const ELFOSABI_HURD: u8 = 4;
-/// Sun Solaris.
-pub const ELFOSABI_SOLARIS: u8 = 6;
-/// IBM AIX.
-pub const ELFOSABI_AIX: u8 = 7;
-/// SGI Irix.
-pub const ELFOSABI_IRIX: u8 = 8;
-/// FreeBSD.
-pub const ELFOSABI_FREEBSD: u8 = 9;
-/// Compaq TRU64 UNIX.
-pub const ELFOSABI_TRU64: u8 = 10;
-/// Novell Modesto.
-pub const ELFOSABI_MODESTO: u8 = 11;
-/// OpenBSD.
-pub const ELFOSABI_OPENBSD: u8 = 12;
-/// OpenVMS.
-pub const ELFOSABI_OPENVMS: u8 = 13;
-/// Hewlett-Packard Non-Stop Kernel.
-pub const ELFOSABI_NSK: u8 = 14;
-/// AROS
-pub const ELFOSABI_AROS: u8 = 15;
-/// FenixOS
-pub const ELFOSABI_FENIXOS: u8 = 16;
-/// Nuxi CloudABI
-pub const ELFOSABI_CLOUDABI: u8 = 17;
-/// ARM EABI.
-pub const ELFOSABI_ARM_AEABI: u8 = 64;
-/// ARM.
-pub const ELFOSABI_ARM: u8 = 97;
-/// Standalone (embedded) application.
-pub const ELFOSABI_STANDALONE: u8 = 255;
-
-// Values for `FileHeader*::e_type`.
-/// No file type.
-pub const ET_NONE: u16 = 0;
-/// Relocatable file.
-pub const ET_REL: u16 = 1;
-/// Executable file.
-pub const ET_EXEC: u16 = 2;
-/// Shared object file.
-pub const ET_DYN: u16 = 3;
-/// Core file.
-pub const ET_CORE: u16 = 4;
-/// OS-specific range start.
-pub const ET_LOOS: u16 = 0xfe00;
-/// OS-specific range end.
-pub const ET_HIOS: u16 = 0xfeff;
-/// Processor-specific range start.
-pub const ET_LOPROC: u16 = 0xff00;
-/// Processor-specific range end.
-pub const ET_HIPROC: u16 = 0xffff;
-
-// Values for `FileHeader*::e_machine`.
-/// No machine
-pub const EM_NONE: u16 = 0;
-/// AT&T WE 32100
-pub const EM_M32: u16 = 1;
-/// SUN SPARC
-pub const EM_SPARC: u16 = 2;
-/// Intel 80386
-pub const EM_386: u16 = 3;
-/// Motorola m68k family
-pub const EM_68K: u16 = 4;
-/// Motorola m88k family
-pub const EM_88K: u16 = 5;
-/// Intel MCU
-pub const EM_IAMCU: u16 = 6;
-/// Intel 80860
-pub const EM_860: u16 = 7;
-/// MIPS R3000 big-endian
-pub const EM_MIPS: u16 = 8;
-/// IBM System/370
-pub const EM_S370: u16 = 9;
-/// MIPS R3000 little-endian
-pub const EM_MIPS_RS3_LE: u16 = 10;
-/// HPPA
-pub const EM_PARISC: u16 = 15;
-/// Fujitsu VPP500
-pub const EM_VPP500: u16 = 17;
-/// Sun's "v8plus"
-pub const EM_SPARC32PLUS: u16 = 18;
-/// Intel 80960
-pub const EM_960: u16 = 19;
-/// PowerPC
-pub const EM_PPC: u16 = 20;
-/// PowerPC 64-bit
-pub const EM_PPC64: u16 = 21;
-/// IBM S390
-pub const EM_S390: u16 = 22;
-/// IBM SPU/SPC
-pub const EM_SPU: u16 = 23;
-/// NEC V800 series
-pub const EM_V800: u16 = 36;
-/// Fujitsu FR20
-pub const EM_FR20: u16 = 37;
-/// TRW RH-32
-pub const EM_RH32: u16 = 38;
-/// Motorola RCE
-pub const EM_RCE: u16 = 39;
-/// ARM
-pub const EM_ARM: u16 = 40;
-/// Digital Alpha
-pub const EM_FAKE_ALPHA: u16 = 41;
-/// Hitachi SH
-pub const EM_SH: u16 = 42;
-/// SPARC v9 64-bit
-pub const EM_SPARCV9: u16 = 43;
-/// Siemens Tricore
-pub const EM_TRICORE: u16 = 44;
-/// Argonaut RISC Core
-pub const EM_ARC: u16 = 45;
-/// Hitachi H8/300
-pub const EM_H8_300: u16 = 46;
-/// Hitachi H8/300H
-pub const EM_H8_300H: u16 = 47;
-/// Hitachi H8S
-pub const EM_H8S: u16 = 48;
-/// Hitachi H8/500
-pub const EM_H8_500: u16 = 49;
-/// Intel Merced
-pub const EM_IA_64: u16 = 50;
-/// Stanford MIPS-X
-pub const EM_MIPS_X: u16 = 51;
-/// Motorola Coldfire
-pub const EM_COLDFIRE: u16 = 52;
-/// Motorola M68HC12
-pub const EM_68HC12: u16 = 53;
-/// Fujitsu MMA Multimedia Accelerator
-pub const EM_MMA: u16 = 54;
-/// Siemens PCP
-pub const EM_PCP: u16 = 55;
-/// Sony nCPU embeeded RISC
-pub const EM_NCPU: u16 = 56;
-/// Denso NDR1 microprocessor
-pub const EM_NDR1: u16 = 57;
-/// Motorola Start*Core processor
-pub const EM_STARCORE: u16 = 58;
-/// Toyota ME16 processor
-pub const EM_ME16: u16 = 59;
-/// STMicroelectronic ST100 processor
-pub const EM_ST100: u16 = 60;
-/// Advanced Logic Corp. Tinyj emb.fam
-pub const EM_TINYJ: u16 = 61;
-/// AMD x86-64 architecture
-pub const EM_X86_64: u16 = 62;
-/// Sony DSP Processor
-pub const EM_PDSP: u16 = 63;
-/// Digital PDP-10
-pub const EM_PDP10: u16 = 64;
-/// Digital PDP-11
-pub const EM_PDP11: u16 = 65;
-/// Siemens FX66 microcontroller
-pub const EM_FX66: u16 = 66;
-/// STMicroelectronics ST9+ 8/16 mc
-pub const EM_ST9PLUS: u16 = 67;
-/// STmicroelectronics ST7 8 bit mc
-pub const EM_ST7: u16 = 68;
-/// Motorola MC68HC16 microcontroller
-pub const EM_68HC16: u16 = 69;
-/// Motorola MC68HC11 microcontroller
-pub const EM_68HC11: u16 = 70;
-/// Motorola MC68HC08 microcontroller
-pub const EM_68HC08: u16 = 71;
-/// Motorola MC68HC05 microcontroller
-pub const EM_68HC05: u16 = 72;
-/// Silicon Graphics SVx
-pub const EM_SVX: u16 = 73;
-/// STMicroelectronics ST19 8 bit mc
-pub const EM_ST19: u16 = 74;
-/// Digital VAX
-pub const EM_VAX: u16 = 75;
-/// Axis Communications 32-bit emb.proc
-pub const EM_CRIS: u16 = 76;
-/// Infineon Technologies 32-bit emb.proc
-pub const EM_JAVELIN: u16 = 77;
-/// Element 14 64-bit DSP Processor
-pub const EM_FIREPATH: u16 = 78;
-/// LSI Logic 16-bit DSP Processor
-pub const EM_ZSP: u16 = 79;
-/// Donald Knuth's educational 64-bit proc
-pub const EM_MMIX: u16 = 80;
-/// Harvard University machine-independent object files
-pub const EM_HUANY: u16 = 81;
-/// SiTera Prism
-pub const EM_PRISM: u16 = 82;
-/// Atmel AVR 8-bit microcontroller
-pub const EM_AVR: u16 = 83;
-/// Fujitsu FR30
-pub const EM_FR30: u16 = 84;
-/// Mitsubishi D10V
-pub const EM_D10V: u16 = 85;
-/// Mitsubishi D30V
-pub const EM_D30V: u16 = 86;
-/// NEC v850
-pub const EM_V850: u16 = 87;
-/// Mitsubishi M32R
-pub const EM_M32R: u16 = 88;
-/// Matsushita MN10300
-pub const EM_MN10300: u16 = 89;
-/// Matsushita MN10200
-pub const EM_MN10200: u16 = 90;
-/// picoJava
-pub const EM_PJ: u16 = 91;
-/// OpenRISC 32-bit embedded processor
-pub const EM_OPENRISC: u16 = 92;
-/// ARC International ARCompact
-pub const EM_ARC_COMPACT: u16 = 93;
-/// Tensilica Xtensa Architecture
-pub const EM_XTENSA: u16 = 94;
-/// Alphamosaic VideoCore
-pub const EM_VIDEOCORE: u16 = 95;
-/// Thompson Multimedia General Purpose Proc
-pub const EM_TMM_GPP: u16 = 96;
-/// National Semi. 32000
-pub const EM_NS32K: u16 = 97;
-/// Tenor Network TPC
-pub const EM_TPC: u16 = 98;
-/// Trebia SNP 1000
-pub const EM_SNP1K: u16 = 99;
-/// STMicroelectronics ST200
-pub const EM_ST200: u16 = 100;
-/// Ubicom IP2xxx
-pub const EM_IP2K: u16 = 101;
-/// MAX processor
-pub const EM_MAX: u16 = 102;
-/// National Semi. CompactRISC
-pub const EM_CR: u16 = 103;
-/// Fujitsu F2MC16
-pub const EM_F2MC16: u16 = 104;
-/// Texas Instruments msp430
-pub const EM_MSP430: u16 = 105;
-/// Analog Devices Blackfin DSP
-pub const EM_BLACKFIN: u16 = 106;
-/// Seiko Epson S1C33 family
-pub const EM_SE_C33: u16 = 107;
-/// Sharp embedded microprocessor
-pub const EM_SEP: u16 = 108;
-/// Arca RISC
-pub const EM_ARCA: u16 = 109;
-/// PKU-Unity & MPRC Peking Uni. mc series
-pub const EM_UNICORE: u16 = 110;
-/// eXcess configurable cpu
-pub const EM_EXCESS: u16 = 111;
-/// Icera Semi. Deep Execution Processor
-pub const EM_DXP: u16 = 112;
-/// Altera Nios II
-pub const EM_ALTERA_NIOS2: u16 = 113;
-/// National Semi. CompactRISC CRX
-pub const EM_CRX: u16 = 114;
-/// Motorola XGATE
-pub const EM_XGATE: u16 = 115;
-/// Infineon C16x/XC16x
-pub const EM_C166: u16 = 116;
-/// Renesas M16C
-pub const EM_M16C: u16 = 117;
-/// Microchip Technology dsPIC30F
-pub const EM_DSPIC30F: u16 = 118;
-/// Freescale Communication Engine RISC
-pub const EM_CE: u16 = 119;
-/// Renesas M32C
-pub const EM_M32C: u16 = 120;
-/// Altium TSK3000
-pub const EM_TSK3000: u16 = 131;
-/// Freescale RS08
-pub const EM_RS08: u16 = 132;
-/// Analog Devices SHARC family
-pub const EM_SHARC: u16 = 133;
-/// Cyan Technology eCOG2
-pub const EM_ECOG2: u16 = 134;
-/// Sunplus S+core7 RISC
-pub const EM_SCORE7: u16 = 135;
-/// New Japan Radio (NJR) 24-bit DSP
-pub const EM_DSP24: u16 = 136;
-/// Broadcom VideoCore III
-pub const EM_VIDEOCORE3: u16 = 137;
-/// RISC for Lattice FPGA
-pub const EM_LATTICEMICO32: u16 = 138;
-/// Seiko Epson C17
-pub const EM_SE_C17: u16 = 139;
-/// Texas Instruments TMS320C6000 DSP
-pub const EM_TI_C6000: u16 = 140;
-/// Texas Instruments TMS320C2000 DSP
-pub const EM_TI_C2000: u16 = 141;
-/// Texas Instruments TMS320C55x DSP
-pub const EM_TI_C5500: u16 = 142;
-/// Texas Instruments App. Specific RISC
-pub const EM_TI_ARP32: u16 = 143;
-/// Texas Instruments Prog. Realtime Unit
-pub const EM_TI_PRU: u16 = 144;
-/// STMicroelectronics 64bit VLIW DSP
-pub const EM_MMDSP_PLUS: u16 = 160;
-/// Cypress M8C
-pub const EM_CYPRESS_M8C: u16 = 161;
-/// Renesas R32C
-pub const EM_R32C: u16 = 162;
-/// NXP Semi. TriMedia
-pub const EM_TRIMEDIA: u16 = 163;
-/// QUALCOMM Hexagon
-pub const EM_HEXAGON: u16 = 164;
-/// Intel 8051 and variants
-pub const EM_8051: u16 = 165;
-/// STMicroelectronics STxP7x
-pub const EM_STXP7X: u16 = 166;
-/// Andes Tech. compact code emb. RISC
-pub const EM_NDS32: u16 = 167;
-/// Cyan Technology eCOG1X
-pub const EM_ECOG1X: u16 = 168;
-/// Dallas Semi. MAXQ30 mc
-pub const EM_MAXQ30: u16 = 169;
-/// New Japan Radio (NJR) 16-bit DSP
-pub const EM_XIMO16: u16 = 170;
-/// M2000 Reconfigurable RISC
-pub const EM_MANIK: u16 = 171;
-/// Cray NV2 vector architecture
-pub const EM_CRAYNV2: u16 = 172;
-/// Renesas RX
-pub const EM_RX: u16 = 173;
-/// Imagination Tech. META
-pub const EM_METAG: u16 = 174;
-/// MCST Elbrus
-pub const EM_MCST_ELBRUS: u16 = 175;
-/// Cyan Technology eCOG16
-pub const EM_ECOG16: u16 = 176;
-/// National Semi. CompactRISC CR16
-pub const EM_CR16: u16 = 177;
-/// Freescale Extended Time Processing Unit
-pub const EM_ETPU: u16 = 178;
-/// Infineon Tech. SLE9X
-pub const EM_SLE9X: u16 = 179;
-/// Intel L10M
-pub const EM_L10M: u16 = 180;
-/// Intel K10M
-pub const EM_K10M: u16 = 181;
-/// ARM AARCH64
-pub const EM_AARCH64: u16 = 183;
-/// Amtel 32-bit microprocessor
-pub const EM_AVR32: u16 = 185;
-/// STMicroelectronics STM8
-pub const EM_STM8: u16 = 186;
-/// Tileta TILE64
-pub const EM_TILE64: u16 = 187;
-/// Tilera TILEPro
-pub const EM_TILEPRO: u16 = 188;
-/// Xilinx MicroBlaze
-pub const EM_MICROBLAZE: u16 = 189;
-/// NVIDIA CUDA
-pub const EM_CUDA: u16 = 190;
-/// Tilera TILE-Gx
-pub const EM_TILEGX: u16 = 191;
-/// CloudShield
-pub const EM_CLOUDSHIELD: u16 = 192;
-/// KIPO-KAIST Core-A 1st gen.
-pub const EM_COREA_1ST: u16 = 193;
-/// KIPO-KAIST Core-A 2nd gen.
-pub const EM_COREA_2ND: u16 = 194;
-/// Synopsys ARCompact V2
-pub const EM_ARC_COMPACT2: u16 = 195;
-/// Open8 RISC
-pub const EM_OPEN8: u16 = 196;
-/// Renesas RL78
-pub const EM_RL78: u16 = 197;
-/// Broadcom VideoCore V
-pub const EM_VIDEOCORE5: u16 = 198;
-/// Renesas 78KOR
-pub const EM_78KOR: u16 = 199;
-/// Freescale 56800EX DSC
-pub const EM_56800EX: u16 = 200;
-/// Beyond BA1
-pub const EM_BA1: u16 = 201;
-/// Beyond BA2
-pub const EM_BA2: u16 = 202;
-/// XMOS xCORE
-pub const EM_XCORE: u16 = 203;
-/// Microchip 8-bit PIC(r)
-pub const EM_MCHP_PIC: u16 = 204;
-/// KM211 KM32
-pub const EM_KM32: u16 = 210;
-/// KM211 KMX32
-pub const EM_KMX32: u16 = 211;
-/// KM211 KMX16
-pub const EM_EMX16: u16 = 212;
-/// KM211 KMX8
-pub const EM_EMX8: u16 = 213;
-/// KM211 KVARC
-pub const EM_KVARC: u16 = 214;
-/// Paneve CDP
-pub const EM_CDP: u16 = 215;
-/// Cognitive Smart Memory Processor
-pub const EM_COGE: u16 = 216;
-/// Bluechip CoolEngine
-pub const EM_COOL: u16 = 217;
-/// Nanoradio Optimized RISC
-pub const EM_NORC: u16 = 218;
-/// CSR Kalimba
-pub const EM_CSR_KALIMBA: u16 = 219;
-/// Zilog Z80
-pub const EM_Z80: u16 = 220;
-/// Controls and Data Services VISIUMcore
-pub const EM_VISIUM: u16 = 221;
-/// FTDI Chip FT32
-pub const EM_FT32: u16 = 222;
-/// Moxie processor
-pub const EM_MOXIE: u16 = 223;
-/// AMD GPU
-pub const EM_AMDGPU: u16 = 224;
-/// RISC-V
-pub const EM_RISCV: u16 = 243;
-/// Linux BPF -- in-kernel virtual machine
-pub const EM_BPF: u16 = 247;
-/// C-SKY
-pub const EM_CSKY: u16 = 252;
-/// Loongson LoongArch
-pub const EM_LOONGARCH: u16 = 258;
-/// Solana Binary Format
-pub const EM_SBF: u16 = 263;
-/// Digital Alpha
-pub const EM_ALPHA: u16 = 0x9026;
-
-// Values for `FileHeader*::e_version` and `Ident::version`.
-/// Invalid ELF version.
-pub const EV_NONE: u8 = 0;
-/// Current ELF version.
-pub const EV_CURRENT: u8 = 1;
-
-/// Section header.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct SectionHeader32<E: Endian> {
- /// Section name.
- ///
- /// This is an offset into the section header string table.
- pub sh_name: U32<E>,
- /// Section type. One of the `SHT_*` constants.
- pub sh_type: U32<E>,
- /// Section flags. A combination of the `SHF_*` constants.
- pub sh_flags: U32<E>,
- /// Section virtual address at execution.
- pub sh_addr: U32<E>,
- /// Section file offset.
- pub sh_offset: U32<E>,
- /// Section size in bytes.
- pub sh_size: U32<E>,
- /// Link to another section.
- ///
- /// The section relationship depends on the `sh_type` value.
- pub sh_link: U32<E>,
- /// Additional section information.
- ///
- /// The meaning of this field depends on the `sh_type` value.
- pub sh_info: U32<E>,
- /// Section alignment.
- pub sh_addralign: U32<E>,
- /// Entry size if the section holds a table.
- pub sh_entsize: U32<E>,
-}
-
-/// Section header.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct SectionHeader64<E: Endian> {
- /// Section name.
- ///
- /// This is an offset into the section header string table.
- pub sh_name: U32<E>,
- /// Section type. One of the `SHT_*` constants.
- pub sh_type: U32<E>,
- /// Section flags. A combination of the `SHF_*` constants.
- pub sh_flags: U64<E>,
- /// Section virtual address at execution.
- pub sh_addr: U64<E>,
- /// Section file offset.
- pub sh_offset: U64<E>,
- /// Section size in bytes.
- pub sh_size: U64<E>,
- /// Link to another section.
- ///
- /// The section relationship depends on the `sh_type` value.
- pub sh_link: U32<E>,
- /// Additional section information.
- ///
- /// The meaning of this field depends on the `sh_type` value.
- pub sh_info: U32<E>,
- /// Section alignment.
- pub sh_addralign: U64<E>,
- /// Entry size if the section holds a table.
- pub sh_entsize: U64<E>,
-}
-
-// Special values for section indices.
-/// Undefined section.
-pub const SHN_UNDEF: u16 = 0;
-/// OS-specific range start.
-/// Start of reserved section indices.
-pub const SHN_LORESERVE: u16 = 0xff00;
-/// Start of processor-specific section indices.
-pub const SHN_LOPROC: u16 = 0xff00;
-/// End of processor-specific section indices.
-pub const SHN_HIPROC: u16 = 0xff1f;
-/// Start of OS-specific section indices.
-pub const SHN_LOOS: u16 = 0xff20;
-/// End of OS-specific section indices.
-pub const SHN_HIOS: u16 = 0xff3f;
-/// Associated symbol is absolute.
-pub const SHN_ABS: u16 = 0xfff1;
-/// Associated symbol is common.
-pub const SHN_COMMON: u16 = 0xfff2;
-/// Section index is in the `SHT_SYMTAB_SHNDX` section.
-pub const SHN_XINDEX: u16 = 0xffff;
-/// End of reserved section indices.
-pub const SHN_HIRESERVE: u16 = 0xffff;
-
-// Values for `SectionHeader*::sh_type`.
-/// Section header table entry is unused.
-pub const SHT_NULL: u32 = 0;
-/// Program data.
-pub const SHT_PROGBITS: u32 = 1;
-/// Symbol table.
-pub const SHT_SYMTAB: u32 = 2;
-/// String table.
-pub const SHT_STRTAB: u32 = 3;
-/// Relocation entries with explicit addends.
-pub const SHT_RELA: u32 = 4;
-/// Symbol hash table.
-pub const SHT_HASH: u32 = 5;
-/// Dynamic linking information.
-pub const SHT_DYNAMIC: u32 = 6;
-/// Notes.
-pub const SHT_NOTE: u32 = 7;
-/// Program space with no data (bss).
-pub const SHT_NOBITS: u32 = 8;
-/// Relocation entries without explicit addends.
-pub const SHT_REL: u32 = 9;
-/// Reserved section type.
-pub const SHT_SHLIB: u32 = 10;
-/// Dynamic linker symbol table.
-pub const SHT_DYNSYM: u32 = 11;
-/// Array of constructors.
-pub const SHT_INIT_ARRAY: u32 = 14;
-/// Array of destructors.
-pub const SHT_FINI_ARRAY: u32 = 15;
-/// Array of pre-constructors.
-pub const SHT_PREINIT_ARRAY: u32 = 16;
-/// Section group.
-pub const SHT_GROUP: u32 = 17;
-/// Extended section indices for a symbol table.
-pub const SHT_SYMTAB_SHNDX: u32 = 18;
-/// Start of OS-specific section types.
-pub const SHT_LOOS: u32 = 0x6000_0000;
-/// Object attributes.
-pub const SHT_GNU_ATTRIBUTES: u32 = 0x6fff_fff5;
-/// GNU-style hash table.
-pub const SHT_GNU_HASH: u32 = 0x6fff_fff6;
-/// Prelink library list
-pub const SHT_GNU_LIBLIST: u32 = 0x6fff_fff7;
-/// Checksum for DSO content.
-pub const SHT_CHECKSUM: u32 = 0x6fff_fff8;
-/// Sun-specific low bound.
-pub const SHT_LOSUNW: u32 = 0x6fff_fffa;
-#[allow(non_upper_case_globals)]
-pub const SHT_SUNW_move: u32 = 0x6fff_fffa;
-pub const SHT_SUNW_COMDAT: u32 = 0x6fff_fffb;
-#[allow(non_upper_case_globals)]
-pub const SHT_SUNW_syminfo: u32 = 0x6fff_fffc;
-/// Version definition section.
-#[allow(non_upper_case_globals)]
-pub const SHT_GNU_VERDEF: u32 = 0x6fff_fffd;
-/// Version needs section.
-#[allow(non_upper_case_globals)]
-pub const SHT_GNU_VERNEED: u32 = 0x6fff_fffe;
-/// Version symbol table.
-#[allow(non_upper_case_globals)]
-pub const SHT_GNU_VERSYM: u32 = 0x6fff_ffff;
-/// Sun-specific high bound.
-pub const SHT_HISUNW: u32 = 0x6fff_ffff;
-/// End of OS-specific section types.
-pub const SHT_HIOS: u32 = 0x6fff_ffff;
-/// Start of processor-specific section types.
-pub const SHT_LOPROC: u32 = 0x7000_0000;
-/// End of processor-specific section types.
-pub const SHT_HIPROC: u32 = 0x7fff_ffff;
-/// Start of application-specific section types.
-pub const SHT_LOUSER: u32 = 0x8000_0000;
-/// End of application-specific section types.
-pub const SHT_HIUSER: u32 = 0x8fff_ffff;
-
-// Values for `SectionHeader*::sh_flags`.
-/// Section is writable.
-pub const SHF_WRITE: u32 = 1 << 0;
-/// Section occupies memory during execution.
-pub const SHF_ALLOC: u32 = 1 << 1;
-/// Section is executable.
-pub const SHF_EXECINSTR: u32 = 1 << 2;
-/// Section may be be merged to eliminate duplication.
-pub const SHF_MERGE: u32 = 1 << 4;
-/// Section contains nul-terminated strings.
-pub const SHF_STRINGS: u32 = 1 << 5;
-/// The `sh_info` field contains a section header table index.
-pub const SHF_INFO_LINK: u32 = 1 << 6;
-/// Section has special ordering requirements when combining sections.
-pub const SHF_LINK_ORDER: u32 = 1 << 7;
-/// Section requires special OS-specific handling.
-pub const SHF_OS_NONCONFORMING: u32 = 1 << 8;
-/// Section is a member of a group.
-pub const SHF_GROUP: u32 = 1 << 9;
-/// Section holds thread-local storage.
-pub const SHF_TLS: u32 = 1 << 10;
-/// Section is compressed.
-///
-/// Compressed sections begin with one of the `CompressionHeader*` headers.
-pub const SHF_COMPRESSED: u32 = 1 << 11;
-/// OS-specific section flags.
-pub const SHF_MASKOS: u32 = 0x0ff0_0000;
-/// Processor-specific section flags.
-pub const SHF_MASKPROC: u32 = 0xf000_0000;
-/// This section is excluded from the final executable or shared library.
-pub const SHF_EXCLUDE: u32 = 0x8000_0000;
-
-/// Section compression header.
-///
-/// Used when `SHF_COMPRESSED` is set.
-///
-/// Note: this type currently allows for misaligned headers, but that may be
-/// changed in a future version.
-#[derive(Debug, Default, Clone, Copy)]
-#[repr(C)]
-pub struct CompressionHeader32<E: Endian> {
- /// Compression format. One of the `ELFCOMPRESS_*` values.
- pub ch_type: U32Bytes<E>,
- /// Uncompressed data size.
- pub ch_size: U32Bytes<E>,
- /// Uncompressed data alignment.
- pub ch_addralign: U32Bytes<E>,
-}
-
-/// Section compression header.
-///
-/// Used when `SHF_COMPRESSED` is set.
-///
-/// Note: this type currently allows for misaligned headers, but that may be
-/// changed in a future version.
-#[derive(Debug, Default, Clone, Copy)]
-#[repr(C)]
-pub struct CompressionHeader64<E: Endian> {
- /// Compression format. One of the `ELFCOMPRESS_*` values.
- pub ch_type: U32Bytes<E>,
- /// Reserved.
- pub ch_reserved: U32Bytes<E>,
- /// Uncompressed data size.
- pub ch_size: U64Bytes<E>,
- /// Uncompressed data alignment.
- pub ch_addralign: U64Bytes<E>,
-}
-
-/// ZLIB/DEFLATE algorithm.
-pub const ELFCOMPRESS_ZLIB: u32 = 1;
-/// Zstandard algorithm.
-pub const ELFCOMPRESS_ZSTD: u32 = 2;
-/// Start of OS-specific compression types.
-pub const ELFCOMPRESS_LOOS: u32 = 0x6000_0000;
-/// End of OS-specific compression types.
-pub const ELFCOMPRESS_HIOS: u32 = 0x6fff_ffff;
-/// Start of processor-specific compression types.
-pub const ELFCOMPRESS_LOPROC: u32 = 0x7000_0000;
-/// End of processor-specific compression types.
-pub const ELFCOMPRESS_HIPROC: u32 = 0x7fff_ffff;
-
-// Values for the flag entry for section groups.
-/// Mark group as COMDAT.
-pub const GRP_COMDAT: u32 = 1;
-
-/// Symbol table entry.
-#[derive(Debug, Default, Clone, Copy)]
-#[repr(C)]
-pub struct Sym32<E: Endian> {
- /// Symbol name.
- ///
- /// This is an offset into the symbol string table.
- pub st_name: U32<E>,
- /// Symbol value.
- pub st_value: U32<E>,
- /// Symbol size.
- pub st_size: U32<E>,
- /// Symbol type and binding.
- ///
- /// Use the `st_type` and `st_bind` methods to access this value.
- pub st_info: u8,
- /// Symbol visibility.
- ///
- /// Use the `st_visibility` method to access this value.
- pub st_other: u8,
- /// Section index or one of the `SHN_*` values.
- pub st_shndx: U16<E>,
-}
-
-impl<E: Endian> Sym32<E> {
- /// Get the `st_bind` component of the `st_info` field.
- #[inline]
- pub fn st_bind(&self) -> u8 {
- self.st_info >> 4
- }
-
- /// Get the `st_type` component of the `st_info` field.
- #[inline]
- pub fn st_type(&self) -> u8 {
- self.st_info & 0xf
- }
-
- /// Set the `st_info` field given the `st_bind` and `st_type` components.
- #[inline]
- pub fn set_st_info(&mut self, st_bind: u8, st_type: u8) {
- self.st_info = (st_bind << 4) + (st_type & 0xf);
- }
-
- /// Get the `st_visibility` component of the `st_info` field.
- #[inline]
- pub fn st_visibility(&self) -> u8 {
- self.st_other & 0x3
- }
-}
-
-/// Symbol table entry.
-#[derive(Debug, Default, Clone, Copy)]
-#[repr(C)]
-pub struct Sym64<E: Endian> {
- /// Symbol name.
- ///
- /// This is an offset into the symbol string table.
- pub st_name: U32<E>,
- /// Symbol type and binding.
- ///
- /// Use the `st_bind` and `st_type` methods to access this value.
- pub st_info: u8,
- /// Symbol visibility.
- ///
- /// Use the `st_visibility` method to access this value.
- pub st_other: u8,
- /// Section index or one of the `SHN_*` values.
- pub st_shndx: U16<E>,
- /// Symbol value.
- pub st_value: U64<E>,
- /// Symbol size.
- pub st_size: U64<E>,
-}
-
-impl<E: Endian> Sym64<E> {
- /// Get the `st_bind` component of the `st_info` field.
- #[inline]
- pub fn st_bind(&self) -> u8 {
- self.st_info >> 4
- }
-
- /// Get the `st_type` component of the `st_info` field.
- #[inline]
- pub fn st_type(&self) -> u8 {
- self.st_info & 0xf
- }
-
- /// Set the `st_info` field given the `st_bind` and `st_type` components.
- #[inline]
- pub fn set_st_info(&mut self, st_bind: u8, st_type: u8) {
- self.st_info = (st_bind << 4) + (st_type & 0xf);
- }
-
- /// Get the `st_visibility` component of the `st_info` field.
- #[inline]
- pub fn st_visibility(&self) -> u8 {
- self.st_other & 0x3
- }
-}
-
-/// Additional information about a `Sym32`.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Syminfo32<E: Endian> {
- /// Direct bindings, symbol bound to.
- pub si_boundto: U16<E>,
- /// Per symbol flags.
- pub si_flags: U16<E>,
-}
-
-/// Additional information about a `Sym64`.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Syminfo64<E: Endian> {
- /// Direct bindings, symbol bound to.
- pub si_boundto: U16<E>,
- /// Per symbol flags.
- pub si_flags: U16<E>,
-}
-
-// Values for `Syminfo*::si_boundto`.
-/// Symbol bound to self
-pub const SYMINFO_BT_SELF: u16 = 0xffff;
-/// Symbol bound to parent
-pub const SYMINFO_BT_PARENT: u16 = 0xfffe;
-/// Beginning of reserved entries
-pub const SYMINFO_BT_LOWRESERVE: u16 = 0xff00;
-
-// Values for `Syminfo*::si_flags`.
-/// Direct bound symbol
-pub const SYMINFO_FLG_DIRECT: u16 = 0x0001;
-/// Pass-thru symbol for translator
-pub const SYMINFO_FLG_PASSTHRU: u16 = 0x0002;
-/// Symbol is a copy-reloc
-pub const SYMINFO_FLG_COPY: u16 = 0x0004;
-/// Symbol bound to object to be lazy loaded
-pub const SYMINFO_FLG_LAZYLOAD: u16 = 0x0008;
-
-// Syminfo version values.
-pub const SYMINFO_NONE: u16 = 0;
-pub const SYMINFO_CURRENT: u16 = 1;
-pub const SYMINFO_NUM: u16 = 2;
-
-// Values for bind component of `Sym*::st_info`.
-/// Local symbol.
-pub const STB_LOCAL: u8 = 0;
-/// Global symbol.
-pub const STB_GLOBAL: u8 = 1;
-/// Weak symbol.
-pub const STB_WEAK: u8 = 2;
-/// Start of OS-specific symbol binding.
-pub const STB_LOOS: u8 = 10;
-/// Unique symbol.
-pub const STB_GNU_UNIQUE: u8 = 10;
-/// End of OS-specific symbol binding.
-pub const STB_HIOS: u8 = 12;
-/// Start of processor-specific symbol binding.
-pub const STB_LOPROC: u8 = 13;
-/// End of processor-specific symbol binding.
-pub const STB_HIPROC: u8 = 15;
-
-// Values for type component of `Sym*::st_info`.
-/// Symbol type is unspecified.
-pub const STT_NOTYPE: u8 = 0;
-/// Symbol is a data object.
-pub const STT_OBJECT: u8 = 1;
-/// Symbol is a code object.
-pub const STT_FUNC: u8 = 2;
-/// Symbol is associated with a section.
-pub const STT_SECTION: u8 = 3;
-/// Symbol's name is a file name.
-pub const STT_FILE: u8 = 4;
-/// Symbol is a common data object.
-pub const STT_COMMON: u8 = 5;
-/// Symbol is a thread-local storage object.
-pub const STT_TLS: u8 = 6;
-/// Start of OS-specific symbol types.
-pub const STT_LOOS: u8 = 10;
-/// Symbol is an indirect code object.
-pub const STT_GNU_IFUNC: u8 = 10;
-/// End of OS-specific symbol types.
-pub const STT_HIOS: u8 = 12;
-/// Start of processor-specific symbol types.
-pub const STT_LOPROC: u8 = 13;
-/// End of processor-specific symbol types.
-pub const STT_HIPROC: u8 = 15;
-
-// Values for visibility component of `Symbol*::st_other`.
-/// Default symbol visibility rules.
-pub const STV_DEFAULT: u8 = 0;
-/// Processor specific hidden class.
-pub const STV_INTERNAL: u8 = 1;
-/// Symbol is not visible to other components.
-pub const STV_HIDDEN: u8 = 2;
-/// Symbol is visible to other components, but is not preemptible.
-pub const STV_PROTECTED: u8 = 3;
-
-/// Relocation table entry without explicit addend.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Rel32<E: Endian> {
- /// Relocation address.
- pub r_offset: U32<E>,
- /// Relocation type and symbol index.
- pub r_info: U32<E>,
-}
-
-impl<E: Endian> Rel32<E> {
- /// Get the `r_sym` component of the `r_info` field.
- #[inline]
- pub fn r_sym(&self, endian: E) -> u32 {
- self.r_info.get(endian) >> 8
- }
-
- /// Get the `r_type` component of the `r_info` field.
- #[inline]
- pub fn r_type(&self, endian: E) -> u32 {
- self.r_info.get(endian) & 0xff
- }
-
- /// Calculate the `r_info` field given the `r_sym` and `r_type` components.
- pub fn r_info(endian: E, r_sym: u32, r_type: u8) -> U32<E> {
- U32::new(endian, (r_sym << 8) | u32::from(r_type))
- }
-
- /// Set the `r_info` field given the `r_sym` and `r_type` components.
- pub fn set_r_info(&mut self, endian: E, r_sym: u32, r_type: u8) {
- self.r_info = Self::r_info(endian, r_sym, r_type)
- }
-}
-
-/// Relocation table entry with explicit addend.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Rela32<E: Endian> {
- /// Relocation address.
- pub r_offset: U32<E>,
- /// Relocation type and symbol index.
- pub r_info: U32<E>,
- /// Explicit addend.
- pub r_addend: I32<E>,
-}
-
-impl<E: Endian> Rela32<E> {
- /// Get the `r_sym` component of the `r_info` field.
- #[inline]
- pub fn r_sym(&self, endian: E) -> u32 {
- self.r_info.get(endian) >> 8
- }
-
- /// Get the `r_type` component of the `r_info` field.
- #[inline]
- pub fn r_type(&self, endian: E) -> u32 {
- self.r_info.get(endian) & 0xff
- }
-
- /// Calculate the `r_info` field given the `r_sym` and `r_type` components.
- pub fn r_info(endian: E, r_sym: u32, r_type: u8) -> U32<E> {
- U32::new(endian, (r_sym << 8) | u32::from(r_type))
- }
-
- /// Set the `r_info` field given the `r_sym` and `r_type` components.
- pub fn set_r_info(&mut self, endian: E, r_sym: u32, r_type: u8) {
- self.r_info = Self::r_info(endian, r_sym, r_type)
- }
-}
-
-impl<E: Endian> From<Rel32<E>> for Rela32<E> {
- fn from(rel: Rel32<E>) -> Self {
- Rela32 {
- r_offset: rel.r_offset,
- r_info: rel.r_info,
- r_addend: I32::default(),
- }
- }
-}
-
-/// Relocation table entry without explicit addend.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Rel64<E: Endian> {
- /// Relocation address.
- pub r_offset: U64<E>,
- /// Relocation type and symbol index.
- pub r_info: U64<E>,
-}
-
-impl<E: Endian> Rel64<E> {
- /// Get the `r_sym` component of the `r_info` field.
- #[inline]
- pub fn r_sym(&self, endian: E) -> u32 {
- (self.r_info.get(endian) >> 32) as u32
- }
-
- /// Get the `r_type` component of the `r_info` field.
- #[inline]
- pub fn r_type(&self, endian: E) -> u32 {
- (self.r_info.get(endian) & 0xffff_ffff) as u32
- }
-
- /// Calculate the `r_info` field given the `r_sym` and `r_type` components.
- pub fn r_info(endian: E, r_sym: u32, r_type: u32) -> U64<E> {
- U64::new(endian, (u64::from(r_sym) << 32) | u64::from(r_type))
- }
-
- /// Set the `r_info` field given the `r_sym` and `r_type` components.
- pub fn set_r_info(&mut self, endian: E, r_sym: u32, r_type: u32) {
- self.r_info = Self::r_info(endian, r_sym, r_type)
- }
-}
-
-impl<E: Endian> From<Rel64<E>> for Rela64<E> {
- fn from(rel: Rel64<E>) -> Self {
- Rela64 {
- r_offset: rel.r_offset,
- r_info: rel.r_info,
- r_addend: I64::default(),
- }
- }
-}
-
-/// Relocation table entry with explicit addend.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Rela64<E: Endian> {
- /// Relocation address.
- pub r_offset: U64<E>,
- /// Relocation type and symbol index.
- pub r_info: U64<E>,
- /// Explicit addend.
- pub r_addend: I64<E>,
-}
-
-impl<E: Endian> Rela64<E> {
- pub(crate) fn get_r_info(&self, endian: E, is_mips64el: bool) -> u64 {
- let mut t = self.r_info.get(endian);
- if is_mips64el {
- t = (t << 32)
- | ((t >> 8) & 0xff000000)
- | ((t >> 24) & 0x00ff0000)
- | ((t >> 40) & 0x0000ff00)
- | ((t >> 56) & 0x000000ff);
- }
- t
- }
-
- /// Get the `r_sym` component of the `r_info` field.
- #[inline]
- pub fn r_sym(&self, endian: E, is_mips64el: bool) -> u32 {
- (self.get_r_info(endian, is_mips64el) >> 32) as u32
- }
-
- /// Get the `r_type` component of the `r_info` field.
- #[inline]
- pub fn r_type(&self, endian: E, is_mips64el: bool) -> u32 {
- (self.get_r_info(endian, is_mips64el) & 0xffff_ffff) as u32
- }
-
- /// Calculate the `r_info` field given the `r_sym` and `r_type` components.
- pub fn r_info(endian: E, is_mips64el: bool, r_sym: u32, r_type: u32) -> U64<E> {
- let mut t = (u64::from(r_sym) << 32) | u64::from(r_type);
- if is_mips64el {
- t = (t >> 32)
- | ((t & 0xff000000) << 8)
- | ((t & 0x00ff0000) << 24)
- | ((t & 0x0000ff00) << 40)
- | ((t & 0x000000ff) << 56);
- }
- U64::new(endian, t)
- }
-
- /// Set the `r_info` field given the `r_sym` and `r_type` components.
- pub fn set_r_info(&mut self, endian: E, is_mips64el: bool, r_sym: u32, r_type: u32) {
- self.r_info = Self::r_info(endian, is_mips64el, r_sym, r_type);
- }
-}
-
-/// Program segment header.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ProgramHeader32<E: Endian> {
- /// Segment type. One of the `PT_*` constants.
- pub p_type: U32<E>,
- /// Segment file offset.
- pub p_offset: U32<E>,
- /// Segment virtual address.
- pub p_vaddr: U32<E>,
- /// Segment physical address.
- pub p_paddr: U32<E>,
- /// Segment size in the file.
- pub p_filesz: U32<E>,
- /// Segment size in memory.
- pub p_memsz: U32<E>,
- /// Segment flags. A combination of the `PF_*` constants.
- pub p_flags: U32<E>,
- /// Segment alignment.
- pub p_align: U32<E>,
-}
-
-/// Program segment header.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ProgramHeader64<E: Endian> {
- /// Segment type. One of the `PT_*` constants.
- pub p_type: U32<E>,
- /// Segment flags. A combination of the `PF_*` constants.
- pub p_flags: U32<E>,
- /// Segment file offset.
- pub p_offset: U64<E>,
- /// Segment virtual address.
- pub p_vaddr: U64<E>,
- /// Segment physical address.
- pub p_paddr: U64<E>,
- /// Segment size in the file.
- pub p_filesz: U64<E>,
- /// Segment size in memory.
- pub p_memsz: U64<E>,
- /// Segment alignment.
- pub p_align: U64<E>,
-}
-
-/// Special value for `FileHeader*::e_phnum`.
-///
-/// This indicates that the real number of program headers is too large to fit into e_phnum.
-/// Instead the real value is in the field `sh_info` of section 0.
-pub const PN_XNUM: u16 = 0xffff;
-
-// Values for `ProgramHeader*::p_type`.
-/// Program header table entry is unused.
-pub const PT_NULL: u32 = 0;
-/// Loadable program segment.
-pub const PT_LOAD: u32 = 1;
-/// Dynamic linking information.
-pub const PT_DYNAMIC: u32 = 2;
-/// Program interpreter.
-pub const PT_INTERP: u32 = 3;
-/// Auxiliary information.
-pub const PT_NOTE: u32 = 4;
-/// Reserved.
-pub const PT_SHLIB: u32 = 5;
-/// Segment contains the program header table.
-pub const PT_PHDR: u32 = 6;
-/// Thread-local storage segment.
-pub const PT_TLS: u32 = 7;
-/// Start of OS-specific segment types.
-pub const PT_LOOS: u32 = 0x6000_0000;
-/// GCC `.eh_frame_hdr` segment.
-pub const PT_GNU_EH_FRAME: u32 = 0x6474_e550;
-/// Indicates stack executability.
-pub const PT_GNU_STACK: u32 = 0x6474_e551;
-/// Read-only after relocation.
-pub const PT_GNU_RELRO: u32 = 0x6474_e552;
-/// Segment containing `.note.gnu.property` section.
-pub const PT_GNU_PROPERTY: u32 = 0x6474_e553;
-/// End of OS-specific segment types.
-pub const PT_HIOS: u32 = 0x6fff_ffff;
-/// Start of processor-specific segment types.
-pub const PT_LOPROC: u32 = 0x7000_0000;
-/// End of processor-specific segment types.
-pub const PT_HIPROC: u32 = 0x7fff_ffff;
-
-// Values for `ProgramHeader*::p_flags`.
-/// Segment is executable.
-pub const PF_X: u32 = 1 << 0;
-/// Segment is writable.
-pub const PF_W: u32 = 1 << 1;
-/// Segment is readable.
-pub const PF_R: u32 = 1 << 2;
-/// OS-specific segment flags.
-pub const PF_MASKOS: u32 = 0x0ff0_0000;
-/// Processor-specific segment flags.
-pub const PF_MASKPROC: u32 = 0xf000_0000;
-
-/// Note name for core files.
-pub const ELF_NOTE_CORE: &[u8] = b"CORE";
-/// Note name for linux core files.
-///
-/// Notes in linux core files may also use `ELF_NOTE_CORE`.
-pub const ELF_NOTE_LINUX: &[u8] = b"LINUX";
-
-// Values for `NoteHeader*::n_type` in core files.
-//
-/// Contains copy of prstatus struct.
-pub const NT_PRSTATUS: u32 = 1;
-/// Contains copy of fpregset struct.
-pub const NT_PRFPREG: u32 = 2;
-/// Contains copy of fpregset struct.
-pub const NT_FPREGSET: u32 = 2;
-/// Contains copy of prpsinfo struct.
-pub const NT_PRPSINFO: u32 = 3;
-/// Contains copy of prxregset struct.
-pub const NT_PRXREG: u32 = 4;
-/// Contains copy of task structure.
-pub const NT_TASKSTRUCT: u32 = 4;
-/// String from sysinfo(SI_PLATFORM).
-pub const NT_PLATFORM: u32 = 5;
-/// Contains copy of auxv array.
-pub const NT_AUXV: u32 = 6;
-/// Contains copy of gwindows struct.
-pub const NT_GWINDOWS: u32 = 7;
-/// Contains copy of asrset struct.
-pub const NT_ASRS: u32 = 8;
-/// Contains copy of pstatus struct.
-pub const NT_PSTATUS: u32 = 10;
-/// Contains copy of psinfo struct.
-pub const NT_PSINFO: u32 = 13;
-/// Contains copy of prcred struct.
-pub const NT_PRCRED: u32 = 14;
-/// Contains copy of utsname struct.
-pub const NT_UTSNAME: u32 = 15;
-/// Contains copy of lwpstatus struct.
-pub const NT_LWPSTATUS: u32 = 16;
-/// Contains copy of lwpinfo struct.
-pub const NT_LWPSINFO: u32 = 17;
-/// Contains copy of fprxregset struct.
-pub const NT_PRFPXREG: u32 = 20;
-/// Contains copy of siginfo_t, size might increase.
-pub const NT_SIGINFO: u32 = 0x5349_4749;
-/// Contains information about mapped files.
-pub const NT_FILE: u32 = 0x4649_4c45;
-/// Contains copy of user_fxsr_struct.
-pub const NT_PRXFPREG: u32 = 0x46e6_2b7f;
-/// PowerPC Altivec/VMX registers.
-pub const NT_PPC_VMX: u32 = 0x100;
-/// PowerPC SPE/EVR registers.
-pub const NT_PPC_SPE: u32 = 0x101;
-/// PowerPC VSX registers.
-pub const NT_PPC_VSX: u32 = 0x102;
-/// Target Address Register.
-pub const NT_PPC_TAR: u32 = 0x103;
-/// Program Priority Register.
-pub const NT_PPC_PPR: u32 = 0x104;
-/// Data Stream Control Register.
-pub const NT_PPC_DSCR: u32 = 0x105;
-/// Event Based Branch Registers.
-pub const NT_PPC_EBB: u32 = 0x106;
-/// Performance Monitor Registers.
-pub const NT_PPC_PMU: u32 = 0x107;
-/// TM checkpointed GPR Registers.
-pub const NT_PPC_TM_CGPR: u32 = 0x108;
-/// TM checkpointed FPR Registers.
-pub const NT_PPC_TM_CFPR: u32 = 0x109;
-/// TM checkpointed VMX Registers.
-pub const NT_PPC_TM_CVMX: u32 = 0x10a;
-/// TM checkpointed VSX Registers.
-pub const NT_PPC_TM_CVSX: u32 = 0x10b;
-/// TM Special Purpose Registers.
-pub const NT_PPC_TM_SPR: u32 = 0x10c;
-/// TM checkpointed Target Address Register.
-pub const NT_PPC_TM_CTAR: u32 = 0x10d;
-/// TM checkpointed Program Priority Register.
-pub const NT_PPC_TM_CPPR: u32 = 0x10e;
-/// TM checkpointed Data Stream Control Register.
-pub const NT_PPC_TM_CDSCR: u32 = 0x10f;
-/// Memory Protection Keys registers.
-pub const NT_PPC_PKEY: u32 = 0x110;
-/// i386 TLS slots (struct user_desc).
-pub const NT_386_TLS: u32 = 0x200;
-/// x86 io permission bitmap (1=deny).
-pub const NT_386_IOPERM: u32 = 0x201;
-/// x86 extended state using xsave.
-pub const NT_X86_XSTATE: u32 = 0x202;
-/// s390 upper register halves.
-pub const NT_S390_HIGH_GPRS: u32 = 0x300;
-/// s390 timer register.
-pub const NT_S390_TIMER: u32 = 0x301;
-/// s390 TOD clock comparator register.
-pub const NT_S390_TODCMP: u32 = 0x302;
-/// s390 TOD programmable register.
-pub const NT_S390_TODPREG: u32 = 0x303;
-/// s390 control registers.
-pub const NT_S390_CTRS: u32 = 0x304;
-/// s390 prefix register.
-pub const NT_S390_PREFIX: u32 = 0x305;
-/// s390 breaking event address.
-pub const NT_S390_LAST_BREAK: u32 = 0x306;
-/// s390 system call restart data.
-pub const NT_S390_SYSTEM_CALL: u32 = 0x307;
-/// s390 transaction diagnostic block.
-pub const NT_S390_TDB: u32 = 0x308;
-/// s390 vector registers 0-15 upper half.
-pub const NT_S390_VXRS_LOW: u32 = 0x309;
-/// s390 vector registers 16-31.
-pub const NT_S390_VXRS_HIGH: u32 = 0x30a;
-/// s390 guarded storage registers.
-pub const NT_S390_GS_CB: u32 = 0x30b;
-/// s390 guarded storage broadcast control block.
-pub const NT_S390_GS_BC: u32 = 0x30c;
-/// s390 runtime instrumentation.
-pub const NT_S390_RI_CB: u32 = 0x30d;
-/// ARM VFP/NEON registers.
-pub const NT_ARM_VFP: u32 = 0x400;
-/// ARM TLS register.
-pub const NT_ARM_TLS: u32 = 0x401;
-/// ARM hardware breakpoint registers.
-pub const NT_ARM_HW_BREAK: u32 = 0x402;
-/// ARM hardware watchpoint registers.
-pub const NT_ARM_HW_WATCH: u32 = 0x403;
-/// ARM system call number.
-pub const NT_ARM_SYSTEM_CALL: u32 = 0x404;
-/// ARM Scalable Vector Extension registers.
-pub const NT_ARM_SVE: u32 = 0x405;
-/// Vmcore Device Dump Note.
-pub const NT_VMCOREDD: u32 = 0x700;
-/// MIPS DSP ASE registers.
-pub const NT_MIPS_DSP: u32 = 0x800;
-/// MIPS floating-point mode.
-pub const NT_MIPS_FP_MODE: u32 = 0x801;
-
-/// Note type for version string.
-///
-/// This note may appear in object files.
-///
-/// It must be handled as a special case because it has no descriptor, and instead
-/// uses the note name as the version string.
-pub const NT_VERSION: u32 = 1;
-
-/// Dynamic section entry.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Dyn32<E: Endian> {
- /// Dynamic entry type.
- pub d_tag: U32<E>,
- /// Value (integer or address).
- pub d_val: U32<E>,
-}
-
-/// Dynamic section entry.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Dyn64<E: Endian> {
- /// Dynamic entry type.
- pub d_tag: U64<E>,
- /// Value (integer or address).
- pub d_val: U64<E>,
-}
-
-// Values for `Dyn*::d_tag`.
-
-/// Marks end of dynamic section
-pub const DT_NULL: u32 = 0;
-/// Name of needed library
-pub const DT_NEEDED: u32 = 1;
-/// Size in bytes of PLT relocs
-pub const DT_PLTRELSZ: u32 = 2;
-/// Processor defined value
-pub const DT_PLTGOT: u32 = 3;
-/// Address of symbol hash table
-pub const DT_HASH: u32 = 4;
-/// Address of string table
-pub const DT_STRTAB: u32 = 5;
-/// Address of symbol table
-pub const DT_SYMTAB: u32 = 6;
-/// Address of Rela relocs
-pub const DT_RELA: u32 = 7;
-/// Total size of Rela relocs
-pub const DT_RELASZ: u32 = 8;
-/// Size of one Rela reloc
-pub const DT_RELAENT: u32 = 9;
-/// Size of string table
-pub const DT_STRSZ: u32 = 10;
-/// Size of one symbol table entry
-pub const DT_SYMENT: u32 = 11;
-/// Address of init function
-pub const DT_INIT: u32 = 12;
-/// Address of termination function
-pub const DT_FINI: u32 = 13;
-/// Name of shared object
-pub const DT_SONAME: u32 = 14;
-/// Library search path (deprecated)
-pub const DT_RPATH: u32 = 15;
-/// Start symbol search here
-pub const DT_SYMBOLIC: u32 = 16;
-/// Address of Rel relocs
-pub const DT_REL: u32 = 17;
-/// Total size of Rel relocs
-pub const DT_RELSZ: u32 = 18;
-/// Size of one Rel reloc
-pub const DT_RELENT: u32 = 19;
-/// Type of reloc in PLT
-pub const DT_PLTREL: u32 = 20;
-/// For debugging; unspecified
-pub const DT_DEBUG: u32 = 21;
-/// Reloc might modify .text
-pub const DT_TEXTREL: u32 = 22;
-/// Address of PLT relocs
-pub const DT_JMPREL: u32 = 23;
-/// Process relocations of object
-pub const DT_BIND_NOW: u32 = 24;
-/// Array with addresses of init fct
-pub const DT_INIT_ARRAY: u32 = 25;
-/// Array with addresses of fini fct
-pub const DT_FINI_ARRAY: u32 = 26;
-/// Size in bytes of DT_INIT_ARRAY
-pub const DT_INIT_ARRAYSZ: u32 = 27;
-/// Size in bytes of DT_FINI_ARRAY
-pub const DT_FINI_ARRAYSZ: u32 = 28;
-/// Library search path
-pub const DT_RUNPATH: u32 = 29;
-/// Flags for the object being loaded
-pub const DT_FLAGS: u32 = 30;
-/// Start of encoded range
-pub const DT_ENCODING: u32 = 32;
-/// Array with addresses of preinit fct
-pub const DT_PREINIT_ARRAY: u32 = 32;
-/// size in bytes of DT_PREINIT_ARRAY
-pub const DT_PREINIT_ARRAYSZ: u32 = 33;
-/// Address of SYMTAB_SHNDX section
-pub const DT_SYMTAB_SHNDX: u32 = 34;
-/// Start of OS-specific
-pub const DT_LOOS: u32 = 0x6000_000d;
-/// End of OS-specific
-pub const DT_HIOS: u32 = 0x6fff_f000;
-/// Start of processor-specific
-pub const DT_LOPROC: u32 = 0x7000_0000;
-/// End of processor-specific
-pub const DT_HIPROC: u32 = 0x7fff_ffff;
-
-// `DT_*` entries between `DT_VALRNGHI` & `DT_VALRNGLO` use `d_val` as a value.
-pub const DT_VALRNGLO: u32 = 0x6fff_fd00;
-/// Prelinking timestamp
-pub const DT_GNU_PRELINKED: u32 = 0x6fff_fdf5;
-/// Size of conflict section
-pub const DT_GNU_CONFLICTSZ: u32 = 0x6fff_fdf6;
-/// Size of library list
-pub const DT_GNU_LIBLISTSZ: u32 = 0x6fff_fdf7;
-pub const DT_CHECKSUM: u32 = 0x6fff_fdf8;
-pub const DT_PLTPADSZ: u32 = 0x6fff_fdf9;
-pub const DT_MOVEENT: u32 = 0x6fff_fdfa;
-pub const DT_MOVESZ: u32 = 0x6fff_fdfb;
-/// Feature selection (DTF_*).
-pub const DT_FEATURE_1: u32 = 0x6fff_fdfc;
-/// Flags for DT_* entries, affecting the following DT_* entry.
-pub const DT_POSFLAG_1: u32 = 0x6fff_fdfd;
-/// Size of syminfo table (in bytes)
-pub const DT_SYMINSZ: u32 = 0x6fff_fdfe;
-/// Entry size of syminfo
-pub const DT_SYMINENT: u32 = 0x6fff_fdff;
-pub const DT_VALRNGHI: u32 = 0x6fff_fdff;
-
-// `DT_*` entries between `DT_ADDRRNGHI` & `DT_ADDRRNGLO` use `d_val` as an address.
-//
-// If any adjustment is made to the ELF object after it has been
-// built these entries will need to be adjusted.
-pub const DT_ADDRRNGLO: u32 = 0x6fff_fe00;
-/// GNU-style hash table.
-pub const DT_GNU_HASH: u32 = 0x6fff_fef5;
-pub const DT_TLSDESC_PLT: u32 = 0x6fff_fef6;
-pub const DT_TLSDESC_GOT: u32 = 0x6fff_fef7;
-/// Start of conflict section
-pub const DT_GNU_CONFLICT: u32 = 0x6fff_fef8;
-/// Library list
-pub const DT_GNU_LIBLIST: u32 = 0x6fff_fef9;
-/// Configuration information.
-pub const DT_CONFIG: u32 = 0x6fff_fefa;
-/// Dependency auditing.
-pub const DT_DEPAUDIT: u32 = 0x6fff_fefb;
-/// Object auditing.
-pub const DT_AUDIT: u32 = 0x6fff_fefc;
-/// PLT padding.
-pub const DT_PLTPAD: u32 = 0x6fff_fefd;
-/// Move table.
-pub const DT_MOVETAB: u32 = 0x6fff_fefe;
-/// Syminfo table.
-pub const DT_SYMINFO: u32 = 0x6fff_feff;
-pub const DT_ADDRRNGHI: u32 = 0x6fff_feff;
-
-// The versioning entry types. The next are defined as part of the
-// GNU extension.
-pub const DT_VERSYM: u32 = 0x6fff_fff0;
-pub const DT_RELACOUNT: u32 = 0x6fff_fff9;
-pub const DT_RELCOUNT: u32 = 0x6fff_fffa;
-/// State flags, see DF_1_* below.
-pub const DT_FLAGS_1: u32 = 0x6fff_fffb;
-/// Address of version definition table
-pub const DT_VERDEF: u32 = 0x6fff_fffc;
-/// Number of version definitions
-pub const DT_VERDEFNUM: u32 = 0x6fff_fffd;
-/// Address of table with needed versions
-pub const DT_VERNEED: u32 = 0x6fff_fffe;
-/// Number of needed versions
-pub const DT_VERNEEDNUM: u32 = 0x6fff_ffff;
-
-// Machine-independent extensions in the "processor-specific" range.
-/// Shared object to load before self
-pub const DT_AUXILIARY: u32 = 0x7fff_fffd;
-/// Shared object to get values from
-pub const DT_FILTER: u32 = 0x7fff_ffff;
-
-// Values of `Dyn*::d_val` in the `DT_FLAGS` entry.
-/// Object may use DF_ORIGIN
-pub const DF_ORIGIN: u32 = 0x0000_0001;
-/// Symbol resolutions starts here
-pub const DF_SYMBOLIC: u32 = 0x0000_0002;
-/// Object contains text relocations
-pub const DF_TEXTREL: u32 = 0x0000_0004;
-/// No lazy binding for this object
-pub const DF_BIND_NOW: u32 = 0x0000_0008;
-/// Module uses the static TLS model
-pub const DF_STATIC_TLS: u32 = 0x0000_0010;
-
-// Values of `Dyn*::d_val` in the `DT_FLAGS_1` entry.
-/// Set RTLD_NOW for this object.
-pub const DF_1_NOW: u32 = 0x0000_0001;
-/// Set RTLD_GLOBAL for this object.
-pub const DF_1_GLOBAL: u32 = 0x0000_0002;
-/// Set RTLD_GROUP for this object.
-pub const DF_1_GROUP: u32 = 0x0000_0004;
-/// Set RTLD_NODELETE for this object.
-pub const DF_1_NODELETE: u32 = 0x0000_0008;
-/// Trigger filtee loading at runtime.
-pub const DF_1_LOADFLTR: u32 = 0x0000_0010;
-/// Set RTLD_INITFIRST for this object.
-pub const DF_1_INITFIRST: u32 = 0x0000_0020;
-/// Set RTLD_NOOPEN for this object.
-pub const DF_1_NOOPEN: u32 = 0x0000_0040;
-/// $ORIGIN must be handled.
-pub const DF_1_ORIGIN: u32 = 0x0000_0080;
-/// Direct binding enabled.
-pub const DF_1_DIRECT: u32 = 0x0000_0100;
-pub const DF_1_TRANS: u32 = 0x0000_0200;
-/// Object is used to interpose.
-pub const DF_1_INTERPOSE: u32 = 0x0000_0400;
-/// Ignore default lib search path.
-pub const DF_1_NODEFLIB: u32 = 0x0000_0800;
-/// Object can't be dldump'ed.
-pub const DF_1_NODUMP: u32 = 0x0000_1000;
-/// Configuration alternative created.
-pub const DF_1_CONFALT: u32 = 0x0000_2000;
-/// Filtee terminates filters search.
-pub const DF_1_ENDFILTEE: u32 = 0x0000_4000;
-/// Disp reloc applied at build time.
-pub const DF_1_DISPRELDNE: u32 = 0x0000_8000;
-/// Disp reloc applied at run-time.
-pub const DF_1_DISPRELPND: u32 = 0x0001_0000;
-/// Object has no-direct binding.
-pub const DF_1_NODIRECT: u32 = 0x0002_0000;
-pub const DF_1_IGNMULDEF: u32 = 0x0004_0000;
-pub const DF_1_NOKSYMS: u32 = 0x0008_0000;
-pub const DF_1_NOHDR: u32 = 0x0010_0000;
-/// Object is modified after built.
-pub const DF_1_EDITED: u32 = 0x0020_0000;
-pub const DF_1_NORELOC: u32 = 0x0040_0000;
-/// Object has individual interposers.
-pub const DF_1_SYMINTPOSE: u32 = 0x0080_0000;
-/// Global auditing required.
-pub const DF_1_GLOBAUDIT: u32 = 0x0100_0000;
-/// Singleton symbols are used.
-pub const DF_1_SINGLETON: u32 = 0x0200_0000;
-pub const DF_1_STUB: u32 = 0x0400_0000;
-pub const DF_1_PIE: u32 = 0x0800_0000;
-
-/// Version symbol information
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Versym<E: Endian>(pub U16<E>);
-
-/// Symbol is hidden.
-pub const VERSYM_HIDDEN: u16 = 0x8000;
-/// Symbol version index.
-pub const VERSYM_VERSION: u16 = 0x7fff;
-
-/// Version definition sections
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Verdef<E: Endian> {
- /// Version revision
- pub vd_version: U16<E>,
- /// Version information
- pub vd_flags: U16<E>,
- /// Version Index
- pub vd_ndx: U16<E>,
- /// Number of associated aux entries
- pub vd_cnt: U16<E>,
- /// Version name hash value
- pub vd_hash: U32<E>,
- /// Offset in bytes to verdaux array
- pub vd_aux: U32<E>,
- /// Offset in bytes to next verdef entry
- pub vd_next: U32<E>,
-}
-
-// Legal values for vd_version (version revision).
-/// No version
-pub const VER_DEF_NONE: u16 = 0;
-/// Current version
-pub const VER_DEF_CURRENT: u16 = 1;
-
-// Legal values for vd_flags (version information flags).
-/// Version definition of file itself
-pub const VER_FLG_BASE: u16 = 0x1;
-// Legal values for vd_flags and vna_flags (version information flags).
-/// Weak version identifier
-pub const VER_FLG_WEAK: u16 = 0x2;
-
-// Versym symbol index values.
-/// Symbol is local.
-pub const VER_NDX_LOCAL: u16 = 0;
-/// Symbol is global.
-pub const VER_NDX_GLOBAL: u16 = 1;
-
-/// Auxiliary version information.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Verdaux<E: Endian> {
- /// Version or dependency names
- pub vda_name: U32<E>,
- /// Offset in bytes to next verdaux
- pub vda_next: U32<E>,
-}
-
-/// Version dependency.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Verneed<E: Endian> {
- /// Version of structure
- pub vn_version: U16<E>,
- /// Number of associated aux entries
- pub vn_cnt: U16<E>,
- /// Offset of filename for this dependency
- pub vn_file: U32<E>,
- /// Offset in bytes to vernaux array
- pub vn_aux: U32<E>,
- /// Offset in bytes to next verneed entry
- pub vn_next: U32<E>,
-}
-
-// Legal values for vn_version (version revision).
-/// No version
-pub const VER_NEED_NONE: u16 = 0;
-/// Current version
-pub const VER_NEED_CURRENT: u16 = 1;
-
-/// Auxiliary needed version information.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Vernaux<E: Endian> {
- /// Hash value of dependency name
- pub vna_hash: U32<E>,
- /// Dependency specific information
- pub vna_flags: U16<E>,
- /// Version Index
- pub vna_other: U16<E>,
- /// Dependency name string offset
- pub vna_name: U32<E>,
- /// Offset in bytes to next vernaux entry
- pub vna_next: U32<E>,
-}
-
-// TODO: Elf*_auxv_t, AT_*
-
-/// Note section entry header.
-///
-/// A note consists of a header followed by a variable length name and descriptor.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct NoteHeader32<E: Endian> {
- /// Length of the note's name.
- ///
- /// Some known names are defined by the `ELF_NOTE_*` constants.
- pub n_namesz: U32<E>,
- /// Length of the note's descriptor.
- ///
- /// The content of the descriptor depends on the note name and type.
- pub n_descsz: U32<E>,
- /// Type of the note.
- ///
- /// One of the `NT_*` constants. The note name determines which
- /// `NT_*` constants are valid.
- pub n_type: U32<E>,
-}
-
-/// Note section entry header.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct NoteHeader64<E: Endian> {
- /// Length of the note's name.
- ///
- /// Some known names are defined by the `ELF_NOTE_*` constants.
- pub n_namesz: U32<E>,
- /// Length of the note's descriptor.
- ///
- /// The content of the descriptor depends on the note name and type.
- pub n_descsz: U32<E>,
- /// Type of the note.
- ///
- /// One of the `NT_*` constants. The note name determines which
- /// `NT_*` constants are valid.
- pub n_type: U32<E>,
-}
-
-/// Solaris entries in the note section have this name.
-pub const ELF_NOTE_SOLARIS: &[u8] = b"SUNW Solaris";
-
-// Values for `n_type` when the name is `ELF_NOTE_SOLARIS`.
-/// Desired pagesize for the binary.
-pub const NT_SOLARIS_PAGESIZE_HINT: u32 = 1;
-
-/// GNU entries in the note section have this name.
-pub const ELF_NOTE_GNU: &[u8] = b"GNU";
-
-/// Go entries in the note section have this name.
-// See https://go-review.googlesource.com/9520 and https://go-review.googlesource.com/10704.
-pub const ELF_NOTE_GO: &[u8] = b"Go";
-
-// Note types for `ELF_NOTE_GNU`.
-
-/// ABI information.
-///
-/// The descriptor consists of words:
-/// - word 0: OS descriptor
-/// - word 1: major version of the ABI
-/// - word 2: minor version of the ABI
-/// - word 3: subminor version of the ABI
-pub const NT_GNU_ABI_TAG: u32 = 1;
-
-/// OS descriptor for `NT_GNU_ABI_TAG`.
-pub const ELF_NOTE_OS_LINUX: u32 = 0;
-/// OS descriptor for `NT_GNU_ABI_TAG`.
-pub const ELF_NOTE_OS_GNU: u32 = 1;
-/// OS descriptor for `NT_GNU_ABI_TAG`.
-pub const ELF_NOTE_OS_SOLARIS2: u32 = 2;
-/// OS descriptor for `NT_GNU_ABI_TAG`.
-pub const ELF_NOTE_OS_FREEBSD: u32 = 3;
-
-/// Synthetic hwcap information.
-///
-/// The descriptor begins with two words:
-/// - word 0: number of entries
-/// - word 1: bitmask of enabled entries
-/// Then follow variable-length entries, one byte followed by a
-/// '\0'-terminated hwcap name string. The byte gives the bit
-/// number to test if enabled, (1U << bit) & bitmask. */
-pub const NT_GNU_HWCAP: u32 = 2;
-
-/// Build ID bits as generated by `ld --build-id`.
-///
-/// The descriptor consists of any nonzero number of bytes.
-pub const NT_GNU_BUILD_ID: u32 = 3;
-
-/// Build ID bits as generated by Go's gc compiler.
-///
-/// The descriptor consists of any nonzero number of bytes.
-// See https://go-review.googlesource.com/10707.
-pub const NT_GO_BUILD_ID: u32 = 4;
-
-/// Version note generated by GNU gold containing a version string.
-pub const NT_GNU_GOLD_VERSION: u32 = 4;
-
-/// Program property.
-pub const NT_GNU_PROPERTY_TYPE_0: u32 = 5;
-
-// Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0).
-
-/// Stack size.
-pub const GNU_PROPERTY_STACK_SIZE: u32 = 1;
-/// No copy relocation on protected data symbol.
-pub const GNU_PROPERTY_NO_COPY_ON_PROTECTED: u32 = 2;
-
-// A 4-byte unsigned integer property: A bit is set if it is set in all
-// relocatable inputs.
-pub const GNU_PROPERTY_UINT32_AND_LO: u32 = 0xb0000000;
-pub const GNU_PROPERTY_UINT32_AND_HI: u32 = 0xb0007fff;
-
-// A 4-byte unsigned integer property: A bit is set if it is set in any
-// relocatable inputs.
-pub const GNU_PROPERTY_UINT32_OR_LO: u32 = 0xb0008000;
-pub const GNU_PROPERTY_UINT32_OR_HI: u32 = 0xb000ffff;
-
-/// The needed properties by the object file. */
-pub const GNU_PROPERTY_1_NEEDED: u32 = GNU_PROPERTY_UINT32_OR_LO;
-
-/// Set if the object file requires canonical function pointers and
-/// cannot be used with copy relocation.
-pub const GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS: u32 = 1 << 0;
-
-/// Processor-specific semantics, lo
-pub const GNU_PROPERTY_LOPROC: u32 = 0xc0000000;
-/// Processor-specific semantics, hi
-pub const GNU_PROPERTY_HIPROC: u32 = 0xdfffffff;
-/// Application-specific semantics, lo
-pub const GNU_PROPERTY_LOUSER: u32 = 0xe0000000;
-/// Application-specific semantics, hi
-pub const GNU_PROPERTY_HIUSER: u32 = 0xffffffff;
-
-/// AArch64 specific GNU properties.
-pub const GNU_PROPERTY_AARCH64_FEATURE_1_AND: u32 = 0xc0000000;
-pub const GNU_PROPERTY_AARCH64_FEATURE_PAUTH: u32 = 0xc0000001;
-
-pub const GNU_PROPERTY_AARCH64_FEATURE_1_BTI: u32 = 1 << 0;
-pub const GNU_PROPERTY_AARCH64_FEATURE_1_PAC: u32 = 1 << 1;
-
-// A 4-byte unsigned integer property: A bit is set if it is set in all
-// relocatable inputs.
-pub const GNU_PROPERTY_X86_UINT32_AND_LO: u32 = 0xc0000002;
-pub const GNU_PROPERTY_X86_UINT32_AND_HI: u32 = 0xc0007fff;
-
-// A 4-byte unsigned integer property: A bit is set if it is set in any
-// relocatable inputs.
-pub const GNU_PROPERTY_X86_UINT32_OR_LO: u32 = 0xc0008000;
-pub const GNU_PROPERTY_X86_UINT32_OR_HI: u32 = 0xc000ffff;
-
-// A 4-byte unsigned integer property: A bit is set if it is set in any
-// relocatable inputs and the property is present in all relocatable
-// inputs.
-pub const GNU_PROPERTY_X86_UINT32_OR_AND_LO: u32 = 0xc0010000;
-pub const GNU_PROPERTY_X86_UINT32_OR_AND_HI: u32 = 0xc0017fff;
-
-/// The x86 instruction sets indicated by the corresponding bits are
-/// used in program. Their support in the hardware is optional.
-pub const GNU_PROPERTY_X86_ISA_1_USED: u32 = 0xc0010002;
-/// The x86 instruction sets indicated by the corresponding bits are
-/// used in program and they must be supported by the hardware.
-pub const GNU_PROPERTY_X86_ISA_1_NEEDED: u32 = 0xc0008002;
-/// X86 processor-specific features used in program.
-pub const GNU_PROPERTY_X86_FEATURE_1_AND: u32 = 0xc0000002;
-
-/// GNU_PROPERTY_X86_ISA_1_BASELINE: CMOV, CX8 (cmpxchg8b), FPU (fld),
-/// MMX, OSFXSR (fxsave), SCE (syscall), SSE and SSE2.
-pub const GNU_PROPERTY_X86_ISA_1_BASELINE: u32 = 1 << 0;
-/// GNU_PROPERTY_X86_ISA_1_V2: GNU_PROPERTY_X86_ISA_1_BASELINE,
-/// CMPXCHG16B (cmpxchg16b), LAHF-SAHF (lahf), POPCNT (popcnt), SSE3,
-/// SSSE3, SSE4.1 and SSE4.2.
-pub const GNU_PROPERTY_X86_ISA_1_V2: u32 = 1 << 1;
-/// GNU_PROPERTY_X86_ISA_1_V3: GNU_PROPERTY_X86_ISA_1_V2, AVX, AVX2, BMI1,
-/// BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE.
-pub const GNU_PROPERTY_X86_ISA_1_V3: u32 = 1 << 2;
-/// GNU_PROPERTY_X86_ISA_1_V4: GNU_PROPERTY_X86_ISA_1_V3, AVX512F,
-/// AVX512BW, AVX512CD, AVX512DQ and AVX512VL.
-pub const GNU_PROPERTY_X86_ISA_1_V4: u32 = 1 << 3;
-
-/// This indicates that all executable sections are compatible with IBT.
-pub const GNU_PROPERTY_X86_FEATURE_1_IBT: u32 = 1 << 0;
-/// This indicates that all executable sections are compatible with SHSTK.
-pub const GNU_PROPERTY_X86_FEATURE_1_SHSTK: u32 = 1 << 1;
-
-// TODO: Elf*_Move
-
-/// Header of `SHT_HASH` section.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct HashHeader<E: Endian> {
- /// The number of hash buckets.
- pub bucket_count: U32<E>,
- /// The number of chain values.
- pub chain_count: U32<E>,
- // Array of hash bucket start indices.
- // buckets: U32<E>[bucket_count]
- // Array of hash chain links. An index of 0 terminates the chain.
- // chains: U32<E>[chain_count]
-}
-
-/// Calculate the SysV hash for a symbol name.
-///
-/// Used for `SHT_HASH`.
-pub fn hash(name: &[u8]) -> u32 {
- let mut hash = 0u32;
- for byte in name {
- hash = hash.wrapping_mul(16).wrapping_add(u32::from(*byte));
- hash ^= (hash >> 24) & 0xf0;
- }
- hash & 0xfff_ffff
-}
-
-/// Header of `SHT_GNU_HASH` section.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct GnuHashHeader<E: Endian> {
- /// The number of hash buckets.
- pub bucket_count: U32<E>,
- /// The symbol table index of the first symbol in the hash.
- pub symbol_base: U32<E>,
- /// The number of words in the bloom filter.
- ///
- /// Must be a non-zero power of 2.
- pub bloom_count: U32<E>,
- /// The bit shift count for the bloom filter.
- pub bloom_shift: U32<E>,
- // Array of bloom filter words.
- // bloom_filters: U32<E>[bloom_count] or U64<E>[bloom_count]
- // Array of hash bucket start indices.
- // buckets: U32<E>[bucket_count]
- // Array of hash values, one for each symbol starting at symbol_base.
- // values: U32<E>[symbol_count]
-}
-
-/// Calculate the GNU hash for a symbol name.
-///
-/// Used for `SHT_GNU_HASH`.
-pub fn gnu_hash(name: &[u8]) -> u32 {
- let mut hash = 5381u32;
- for byte in name {
- hash = hash.wrapping_mul(33).wrapping_add(u32::from(*byte));
- }
- hash
-}
-
-// Motorola 68k specific definitions.
-
-// m68k values for `Rel*::r_type`.
-
-/// No reloc
-pub const R_68K_NONE: u32 = 0;
-/// Direct 32 bit
-pub const R_68K_32: u32 = 1;
-/// Direct 16 bit
-pub const R_68K_16: u32 = 2;
-/// Direct 8 bit
-pub const R_68K_8: u32 = 3;
-/// PC relative 32 bit
-pub const R_68K_PC32: u32 = 4;
-/// PC relative 16 bit
-pub const R_68K_PC16: u32 = 5;
-/// PC relative 8 bit
-pub const R_68K_PC8: u32 = 6;
-/// 32 bit PC relative GOT entry
-pub const R_68K_GOT32: u32 = 7;
-/// 16 bit PC relative GOT entry
-pub const R_68K_GOT16: u32 = 8;
-/// 8 bit PC relative GOT entry
-pub const R_68K_GOT8: u32 = 9;
-/// 32 bit GOT offset
-pub const R_68K_GOT32O: u32 = 10;
-/// 16 bit GOT offset
-pub const R_68K_GOT16O: u32 = 11;
-/// 8 bit GOT offset
-pub const R_68K_GOT8O: u32 = 12;
-/// 32 bit PC relative PLT address
-pub const R_68K_PLT32: u32 = 13;
-/// 16 bit PC relative PLT address
-pub const R_68K_PLT16: u32 = 14;
-/// 8 bit PC relative PLT address
-pub const R_68K_PLT8: u32 = 15;
-/// 32 bit PLT offset
-pub const R_68K_PLT32O: u32 = 16;
-/// 16 bit PLT offset
-pub const R_68K_PLT16O: u32 = 17;
-/// 8 bit PLT offset
-pub const R_68K_PLT8O: u32 = 18;
-/// Copy symbol at runtime
-pub const R_68K_COPY: u32 = 19;
-/// Create GOT entry
-pub const R_68K_GLOB_DAT: u32 = 20;
-/// Create PLT entry
-pub const R_68K_JMP_SLOT: u32 = 21;
-/// Adjust by program base
-pub const R_68K_RELATIVE: u32 = 22;
-/// 32 bit GOT offset for GD
-pub const R_68K_TLS_GD32: u32 = 25;
-/// 16 bit GOT offset for GD
-pub const R_68K_TLS_GD16: u32 = 26;
-/// 8 bit GOT offset for GD
-pub const R_68K_TLS_GD8: u32 = 27;
-/// 32 bit GOT offset for LDM
-pub const R_68K_TLS_LDM32: u32 = 28;
-/// 16 bit GOT offset for LDM
-pub const R_68K_TLS_LDM16: u32 = 29;
-/// 8 bit GOT offset for LDM
-pub const R_68K_TLS_LDM8: u32 = 30;
-/// 32 bit module-relative offset
-pub const R_68K_TLS_LDO32: u32 = 31;
-/// 16 bit module-relative offset
-pub const R_68K_TLS_LDO16: u32 = 32;
-/// 8 bit module-relative offset
-pub const R_68K_TLS_LDO8: u32 = 33;
-/// 32 bit GOT offset for IE
-pub const R_68K_TLS_IE32: u32 = 34;
-/// 16 bit GOT offset for IE
-pub const R_68K_TLS_IE16: u32 = 35;
-/// 8 bit GOT offset for IE
-pub const R_68K_TLS_IE8: u32 = 36;
-/// 32 bit offset relative to static TLS block
-pub const R_68K_TLS_LE32: u32 = 37;
-/// 16 bit offset relative to static TLS block
-pub const R_68K_TLS_LE16: u32 = 38;
-/// 8 bit offset relative to static TLS block
-pub const R_68K_TLS_LE8: u32 = 39;
-/// 32 bit module number
-pub const R_68K_TLS_DTPMOD32: u32 = 40;
-/// 32 bit module-relative offset
-pub const R_68K_TLS_DTPREL32: u32 = 41;
-/// 32 bit TP-relative offset
-pub const R_68K_TLS_TPREL32: u32 = 42;
-
-// Intel 80386 specific definitions.
-
-// i386 values for `Rel*::r_type`.
-
-/// No reloc
-pub const R_386_NONE: u32 = 0;
-/// Direct 32 bit
-pub const R_386_32: u32 = 1;
-/// PC relative 32 bit
-pub const R_386_PC32: u32 = 2;
-/// 32 bit GOT entry
-pub const R_386_GOT32: u32 = 3;
-/// 32 bit PLT address
-pub const R_386_PLT32: u32 = 4;
-/// Copy symbol at runtime
-pub const R_386_COPY: u32 = 5;
-/// Create GOT entry
-pub const R_386_GLOB_DAT: u32 = 6;
-/// Create PLT entry
-pub const R_386_JMP_SLOT: u32 = 7;
-/// Adjust by program base
-pub const R_386_RELATIVE: u32 = 8;
-/// 32 bit offset to GOT
-pub const R_386_GOTOFF: u32 = 9;
-/// 32 bit PC relative offset to GOT
-pub const R_386_GOTPC: u32 = 10;
-/// Direct 32 bit PLT address
-pub const R_386_32PLT: u32 = 11;
-/// Offset in static TLS block
-pub const R_386_TLS_TPOFF: u32 = 14;
-/// Address of GOT entry for static TLS block offset
-pub const R_386_TLS_IE: u32 = 15;
-/// GOT entry for static TLS block offset
-pub const R_386_TLS_GOTIE: u32 = 16;
-/// Offset relative to static TLS block
-pub const R_386_TLS_LE: u32 = 17;
-/// Direct 32 bit for GNU version of general dynamic thread local data
-pub const R_386_TLS_GD: u32 = 18;
-/// Direct 32 bit for GNU version of local dynamic thread local data in LE code
-pub const R_386_TLS_LDM: u32 = 19;
-/// Direct 16 bit
-pub const R_386_16: u32 = 20;
-/// PC relative 16 bit
-pub const R_386_PC16: u32 = 21;
-/// Direct 8 bit
-pub const R_386_8: u32 = 22;
-/// PC relative 8 bit
-pub const R_386_PC8: u32 = 23;
-/// Direct 32 bit for general dynamic thread local data
-pub const R_386_TLS_GD_32: u32 = 24;
-/// Tag for pushl in GD TLS code
-pub const R_386_TLS_GD_PUSH: u32 = 25;
-/// Relocation for call to __tls_get_addr()
-pub const R_386_TLS_GD_CALL: u32 = 26;
-/// Tag for popl in GD TLS code
-pub const R_386_TLS_GD_POP: u32 = 27;
-/// Direct 32 bit for local dynamic thread local data in LE code
-pub const R_386_TLS_LDM_32: u32 = 28;
-/// Tag for pushl in LDM TLS code
-pub const R_386_TLS_LDM_PUSH: u32 = 29;
-/// Relocation for call to __tls_get_addr() in LDM code
-pub const R_386_TLS_LDM_CALL: u32 = 30;
-/// Tag for popl in LDM TLS code
-pub const R_386_TLS_LDM_POP: u32 = 31;
-/// Offset relative to TLS block
-pub const R_386_TLS_LDO_32: u32 = 32;
-/// GOT entry for negated static TLS block offset
-pub const R_386_TLS_IE_32: u32 = 33;
-/// Negated offset relative to static TLS block
-pub const R_386_TLS_LE_32: u32 = 34;
-/// ID of module containing symbol
-pub const R_386_TLS_DTPMOD32: u32 = 35;
-/// Offset in TLS block
-pub const R_386_TLS_DTPOFF32: u32 = 36;
-/// Negated offset in static TLS block
-pub const R_386_TLS_TPOFF32: u32 = 37;
-/// 32-bit symbol size
-pub const R_386_SIZE32: u32 = 38;
-/// GOT offset for TLS descriptor.
-pub const R_386_TLS_GOTDESC: u32 = 39;
-/// Marker of call through TLS descriptor for relaxation.
-pub const R_386_TLS_DESC_CALL: u32 = 40;
-/// TLS descriptor containing pointer to code and to argument, returning the TLS offset for the symbol.
-pub const R_386_TLS_DESC: u32 = 41;
-/// Adjust indirectly by program base
-pub const R_386_IRELATIVE: u32 = 42;
-/// Load from 32 bit GOT entry, relaxable.
-pub const R_386_GOT32X: u32 = 43;
-
-// ADI SHARC specific definitions
-
-// SHARC values for `Rel*::r_type`
-
-/// 24-bit absolute address in bits 23:0 of a 48-bit instr
-///
-/// Targets:
-///
-/// * Type 25a (PC_DIRECT)
-pub const R_SHARC_ADDR24_V3: u32 = 0x0b;
-
-/// 32-bit absolute address in bits 31:0 of a 48-bit instr
-///
-/// Targets:
-///
-/// * Type 14a
-/// * Type 14d
-/// * Type 15a
-/// * Type 16a
-/// * Type 17a
-/// * Type 18a
-/// * Type 19a
-pub const R_SHARC_ADDR32_V3: u32 = 0x0c;
-
-/// 32-bit absolute address in bits 31:0 of a 32-bit data location
-///
-/// Represented with `RelocationEncoding::Generic`
-pub const R_SHARC_ADDR_VAR_V3: u32 = 0x0d;
-
-/// 6-bit PC-relative address in bits 32:27 of a 48-bit instr
-///
-/// Targets:
-///
-/// * Type 9a
-/// * Type 10a
-pub const R_SHARC_PCRSHORT_V3: u32 = 0x0e;
-
-/// 24-bit PC-relative address in bits 23:0 of a 48-bit instr
-///
-/// Targets:
-///
-/// * Type 8a
-/// * Type 12a (truncated to 23 bits after relocation)
-/// * Type 13a (truncated to 23 bits after relocation)
-/// * Type 25a (PC Relative)
-pub const R_SHARC_PCRLONG_V3: u32 = 0x0f;
-
-/// 6-bit absolute address in bits 32:27 of a 48-bit instr
-///
-/// Targets:
-///
-/// * Type 4a
-/// * Type 4b
-/// * Type 4d
-pub const R_SHARC_DATA6_V3: u32 = 0x10;
-
-/// 16-bit absolute address in bits 39:24 of a 48-bit instr
-///
-/// Targets:
-///
-/// * Type 12a
-pub const R_SHARC_DATA16_V3: u32 = 0x11;
-
-/// 6-bit absolute address into bits 16:11 of a 32-bit instr
-///
-/// Targets:
-///
-/// * Type 4b
-pub const R_SHARC_DATA6_VISA_V3: u32 = 0x12;
-
-/// 7-bit absolute address into bits 6:0 of a 32-bit instr
-pub const R_SHARC_DATA7_VISA_V3: u32 = 0x13;
-
-/// 16-bit absolute address into bits 15:0 of a 32-bit instr
-pub const R_SHARC_DATA16_VISA_V3: u32 = 0x14;
-
-/// 6-bit PC-relative address into bits 16:11 of a Type B
-///
-/// Targets:
-///
-/// * Type 9b
-pub const R_SHARC_PCR6_VISA_V3: u32 = 0x17;
-
-/// 16-bit absolute address into bits 15:0 of a 16-bit location.
-///
-/// Represented with `RelocationEncoding::Generic`
-pub const R_SHARC_ADDR_VAR16_V3: u32 = 0x19;
-
-pub const R_SHARC_CALC_PUSH_ADDR: u32 = 0xe0;
-pub const R_SHARC_CALC_PUSH_ADDEND: u32 = 0xe1;
-pub const R_SHARC_CALC_ADD: u32 = 0xe2;
-pub const R_SHARC_CALC_SUB: u32 = 0xe3;
-pub const R_SHARC_CALC_MUL: u32 = 0xe4;
-pub const R_SHARC_CALC_DIV: u32 = 0xe5;
-pub const R_SHARC_CALC_MOD: u32 = 0xe6;
-pub const R_SHARC_CALC_LSHIFT: u32 = 0xe7;
-pub const R_SHARC_CALC_RSHIFT: u32 = 0xe8;
-pub const R_SHARC_CALC_AND: u32 = 0xe9;
-pub const R_SHARC_CALC_OR: u32 = 0xea;
-pub const R_SHARC_CALC_XOR: u32 = 0xeb;
-pub const R_SHARC_CALC_PUSH_LEN: u32 = 0xec;
-pub const R_SHARC_CALC_NOT: u32 = 0xf6;
-
-// SHARC values for `SectionHeader*::sh_type`.
-
-/// .adi.attributes
-pub const SHT_SHARC_ADI_ATTRIBUTES: u32 = SHT_LOPROC + 0x2;
-
-// SUN SPARC specific definitions.
-
-// SPARC values for `st_type` component of `Sym*::st_info`.
-
-/// Global register reserved to app.
-pub const STT_SPARC_REGISTER: u8 = 13;
-
-// SPARC values for `FileHeader64::e_flags`.
-
-pub const EF_SPARCV9_MM: u32 = 3;
-pub const EF_SPARCV9_TSO: u32 = 0;
-pub const EF_SPARCV9_PSO: u32 = 1;
-pub const EF_SPARCV9_RMO: u32 = 2;
-/// little endian data
-pub const EF_SPARC_LEDATA: u32 = 0x80_0000;
-pub const EF_SPARC_EXT_MASK: u32 = 0xFF_FF00;
-/// generic V8+ features
-pub const EF_SPARC_32PLUS: u32 = 0x00_0100;
-/// Sun UltraSPARC1 extensions
-pub const EF_SPARC_SUN_US1: u32 = 0x00_0200;
-/// HAL R1 extensions
-pub const EF_SPARC_HAL_R1: u32 = 0x00_0400;
-/// Sun UltraSPARCIII extensions
-pub const EF_SPARC_SUN_US3: u32 = 0x00_0800;
-
-// SPARC values for `Rel*::r_type`.
-
-/// No reloc
-pub const R_SPARC_NONE: u32 = 0;
-/// Direct 8 bit
-pub const R_SPARC_8: u32 = 1;
-/// Direct 16 bit
-pub const R_SPARC_16: u32 = 2;
-/// Direct 32 bit
-pub const R_SPARC_32: u32 = 3;
-/// PC relative 8 bit
-pub const R_SPARC_DISP8: u32 = 4;
-/// PC relative 16 bit
-pub const R_SPARC_DISP16: u32 = 5;
-/// PC relative 32 bit
-pub const R_SPARC_DISP32: u32 = 6;
-/// PC relative 30 bit shifted
-pub const R_SPARC_WDISP30: u32 = 7;
-/// PC relative 22 bit shifted
-pub const R_SPARC_WDISP22: u32 = 8;
-/// High 22 bit
-pub const R_SPARC_HI22: u32 = 9;
-/// Direct 22 bit
-pub const R_SPARC_22: u32 = 10;
-/// Direct 13 bit
-pub const R_SPARC_13: u32 = 11;
-/// Truncated 10 bit
-pub const R_SPARC_LO10: u32 = 12;
-/// Truncated 10 bit GOT entry
-pub const R_SPARC_GOT10: u32 = 13;
-/// 13 bit GOT entry
-pub const R_SPARC_GOT13: u32 = 14;
-/// 22 bit GOT entry shifted
-pub const R_SPARC_GOT22: u32 = 15;
-/// PC relative 10 bit truncated
-pub const R_SPARC_PC10: u32 = 16;
-/// PC relative 22 bit shifted
-pub const R_SPARC_PC22: u32 = 17;
-/// 30 bit PC relative PLT address
-pub const R_SPARC_WPLT30: u32 = 18;
-/// Copy symbol at runtime
-pub const R_SPARC_COPY: u32 = 19;
-/// Create GOT entry
-pub const R_SPARC_GLOB_DAT: u32 = 20;
-/// Create PLT entry
-pub const R_SPARC_JMP_SLOT: u32 = 21;
-/// Adjust by program base
-pub const R_SPARC_RELATIVE: u32 = 22;
-/// Direct 32 bit unaligned
-pub const R_SPARC_UA32: u32 = 23;
-
-// Sparc64 values for `Rel*::r_type`.
-
-/// Direct 32 bit ref to PLT entry
-pub const R_SPARC_PLT32: u32 = 24;
-/// High 22 bit PLT entry
-pub const R_SPARC_HIPLT22: u32 = 25;
-/// Truncated 10 bit PLT entry
-pub const R_SPARC_LOPLT10: u32 = 26;
-/// PC rel 32 bit ref to PLT entry
-pub const R_SPARC_PCPLT32: u32 = 27;
-/// PC rel high 22 bit PLT entry
-pub const R_SPARC_PCPLT22: u32 = 28;
-/// PC rel trunc 10 bit PLT entry
-pub const R_SPARC_PCPLT10: u32 = 29;
-/// Direct 10 bit
-pub const R_SPARC_10: u32 = 30;
-/// Direct 11 bit
-pub const R_SPARC_11: u32 = 31;
-/// Direct 64 bit
-pub const R_SPARC_64: u32 = 32;
-/// 10bit with secondary 13bit addend
-pub const R_SPARC_OLO10: u32 = 33;
-/// Top 22 bits of direct 64 bit
-pub const R_SPARC_HH22: u32 = 34;
-/// High middle 10 bits of ...
-pub const R_SPARC_HM10: u32 = 35;
-/// Low middle 22 bits of ...
-pub const R_SPARC_LM22: u32 = 36;
-/// Top 22 bits of pc rel 64 bit
-pub const R_SPARC_PC_HH22: u32 = 37;
-/// High middle 10 bit of ...
-pub const R_SPARC_PC_HM10: u32 = 38;
-/// Low miggle 22 bits of ...
-pub const R_SPARC_PC_LM22: u32 = 39;
-/// PC relative 16 bit shifted
-pub const R_SPARC_WDISP16: u32 = 40;
-/// PC relative 19 bit shifted
-pub const R_SPARC_WDISP19: u32 = 41;
-/// was part of v9 ABI but was removed
-pub const R_SPARC_GLOB_JMP: u32 = 42;
-/// Direct 7 bit
-pub const R_SPARC_7: u32 = 43;
-/// Direct 5 bit
-pub const R_SPARC_5: u32 = 44;
-/// Direct 6 bit
-pub const R_SPARC_6: u32 = 45;
-/// PC relative 64 bit
-pub const R_SPARC_DISP64: u32 = 46;
-/// Direct 64 bit ref to PLT entry
-pub const R_SPARC_PLT64: u32 = 47;
-/// High 22 bit complemented
-pub const R_SPARC_HIX22: u32 = 48;
-/// Truncated 11 bit complemented
-pub const R_SPARC_LOX10: u32 = 49;
-/// Direct high 12 of 44 bit
-pub const R_SPARC_H44: u32 = 50;
-/// Direct mid 22 of 44 bit
-pub const R_SPARC_M44: u32 = 51;
-/// Direct low 10 of 44 bit
-pub const R_SPARC_L44: u32 = 52;
-/// Global register usage
-pub const R_SPARC_REGISTER: u32 = 53;
-/// Direct 64 bit unaligned
-pub const R_SPARC_UA64: u32 = 54;
-/// Direct 16 bit unaligned
-pub const R_SPARC_UA16: u32 = 55;
-pub const R_SPARC_TLS_GD_HI22: u32 = 56;
-pub const R_SPARC_TLS_GD_LO10: u32 = 57;
-pub const R_SPARC_TLS_GD_ADD: u32 = 58;
-pub const R_SPARC_TLS_GD_CALL: u32 = 59;
-pub const R_SPARC_TLS_LDM_HI22: u32 = 60;
-pub const R_SPARC_TLS_LDM_LO10: u32 = 61;
-pub const R_SPARC_TLS_LDM_ADD: u32 = 62;
-pub const R_SPARC_TLS_LDM_CALL: u32 = 63;
-pub const R_SPARC_TLS_LDO_HIX22: u32 = 64;
-pub const R_SPARC_TLS_LDO_LOX10: u32 = 65;
-pub const R_SPARC_TLS_LDO_ADD: u32 = 66;
-pub const R_SPARC_TLS_IE_HI22: u32 = 67;
-pub const R_SPARC_TLS_IE_LO10: u32 = 68;
-pub const R_SPARC_TLS_IE_LD: u32 = 69;
-pub const R_SPARC_TLS_IE_LDX: u32 = 70;
-pub const R_SPARC_TLS_IE_ADD: u32 = 71;
-pub const R_SPARC_TLS_LE_HIX22: u32 = 72;
-pub const R_SPARC_TLS_LE_LOX10: u32 = 73;
-pub const R_SPARC_TLS_DTPMOD32: u32 = 74;
-pub const R_SPARC_TLS_DTPMOD64: u32 = 75;
-pub const R_SPARC_TLS_DTPOFF32: u32 = 76;
-pub const R_SPARC_TLS_DTPOFF64: u32 = 77;
-pub const R_SPARC_TLS_TPOFF32: u32 = 78;
-pub const R_SPARC_TLS_TPOFF64: u32 = 79;
-pub const R_SPARC_GOTDATA_HIX22: u32 = 80;
-pub const R_SPARC_GOTDATA_LOX10: u32 = 81;
-pub const R_SPARC_GOTDATA_OP_HIX22: u32 = 82;
-pub const R_SPARC_GOTDATA_OP_LOX10: u32 = 83;
-pub const R_SPARC_GOTDATA_OP: u32 = 84;
-pub const R_SPARC_H34: u32 = 85;
-pub const R_SPARC_SIZE32: u32 = 86;
-pub const R_SPARC_SIZE64: u32 = 87;
-pub const R_SPARC_WDISP10: u32 = 88;
-pub const R_SPARC_JMP_IREL: u32 = 248;
-pub const R_SPARC_IRELATIVE: u32 = 249;
-pub const R_SPARC_GNU_VTINHERIT: u32 = 250;
-pub const R_SPARC_GNU_VTENTRY: u32 = 251;
-pub const R_SPARC_REV32: u32 = 252;
-
-// Sparc64 values for `Dyn32::d_tag`.
-
-pub const DT_SPARC_REGISTER: u32 = 0x7000_0001;
-
-// MIPS R3000 specific definitions.
-
-// MIPS values for `FileHeader32::e_flags`.
-
-/// A .noreorder directive was used.
-pub const EF_MIPS_NOREORDER: u32 = 1;
-/// Contains PIC code.
-pub const EF_MIPS_PIC: u32 = 2;
-/// Uses PIC calling sequence.
-pub const EF_MIPS_CPIC: u32 = 4;
-pub const EF_MIPS_XGOT: u32 = 8;
-pub const EF_MIPS_64BIT_WHIRL: u32 = 16;
-pub const EF_MIPS_ABI2: u32 = 32;
-pub const EF_MIPS_ABI_ON32: u32 = 64;
-/// Uses FP64 (12 callee-saved).
-pub const EF_MIPS_FP64: u32 = 512;
-/// Uses IEEE 754-2008 NaN encoding.
-pub const EF_MIPS_NAN2008: u32 = 1024;
-/// MIPS architecture level.
-pub const EF_MIPS_ARCH: u32 = 0xf000_0000;
-
-/// The first MIPS 32 bit ABI
-pub const EF_MIPS_ABI_O32: u32 = 0x0000_1000;
-/// O32 ABI extended for 64-bit architectures
-pub const EF_MIPS_ABI_O64: u32 = 0x0000_2000;
-/// EABI in 32-bit mode
-pub const EF_MIPS_ABI_EABI32: u32 = 0x0000_3000;
-/// EABI in 64-bit mode
-pub const EF_MIPS_ABI_EABI64: u32 = 0x0000_4000;
-/// Mask for selecting EF_MIPS_ABI_ variant
-pub const EF_MIPS_ABI: u32 = 0x0000_f000;
-
-// Legal values for MIPS architecture level.
-
-/// -mips1 code.
-pub const EF_MIPS_ARCH_1: u32 = 0x0000_0000;
-/// -mips2 code.
-pub const EF_MIPS_ARCH_2: u32 = 0x1000_0000;
-/// -mips3 code.
-pub const EF_MIPS_ARCH_3: u32 = 0x2000_0000;
-/// -mips4 code.
-pub const EF_MIPS_ARCH_4: u32 = 0x3000_0000;
-/// -mips5 code.
-pub const EF_MIPS_ARCH_5: u32 = 0x4000_0000;
-/// MIPS32 code.
-pub const EF_MIPS_ARCH_32: u32 = 0x5000_0000;
-/// MIPS64 code.
-pub const EF_MIPS_ARCH_64: u32 = 0x6000_0000;
-/// MIPS32r2 code.
-pub const EF_MIPS_ARCH_32R2: u32 = 0x7000_0000;
-/// MIPS64r2 code.
-pub const EF_MIPS_ARCH_64R2: u32 = 0x8000_0000;
-/// MIPS32r6 code
-pub const EF_MIPS_ARCH_32R6: u32 = 0x9000_0000;
-/// MIPS64r6 code
-pub const EF_MIPS_ARCH_64R6: u32 = 0xa000_0000;
-
-// MIPS values for `Sym32::st_shndx`.
-
-/// Allocated common symbols.
-pub const SHN_MIPS_ACOMMON: u16 = 0xff00;
-/// Allocated test symbols.
-pub const SHN_MIPS_TEXT: u16 = 0xff01;
-/// Allocated data symbols.
-pub const SHN_MIPS_DATA: u16 = 0xff02;
-/// Small common symbols.
-pub const SHN_MIPS_SCOMMON: u16 = 0xff03;
-/// Small undefined symbols.
-pub const SHN_MIPS_SUNDEFINED: u16 = 0xff04;
-
-// MIPS values for `SectionHeader32::sh_type`.
-
-/// Shared objects used in link.
-pub const SHT_MIPS_LIBLIST: u32 = 0x7000_0000;
-pub const SHT_MIPS_MSYM: u32 = 0x7000_0001;
-/// Conflicting symbols.
-pub const SHT_MIPS_CONFLICT: u32 = 0x7000_0002;
-/// Global data area sizes.
-pub const SHT_MIPS_GPTAB: u32 = 0x7000_0003;
-/// Reserved for SGI/MIPS compilers
-pub const SHT_MIPS_UCODE: u32 = 0x7000_0004;
-/// MIPS ECOFF debugging info.
-pub const SHT_MIPS_DEBUG: u32 = 0x7000_0005;
-/// Register usage information.
-pub const SHT_MIPS_REGINFO: u32 = 0x7000_0006;
-pub const SHT_MIPS_PACKAGE: u32 = 0x7000_0007;
-pub const SHT_MIPS_PACKSYM: u32 = 0x7000_0008;
-pub const SHT_MIPS_RELD: u32 = 0x7000_0009;
-pub const SHT_MIPS_IFACE: u32 = 0x7000_000b;
-pub const SHT_MIPS_CONTENT: u32 = 0x7000_000c;
-/// Miscellaneous options.
-pub const SHT_MIPS_OPTIONS: u32 = 0x7000_000d;
-pub const SHT_MIPS_SHDR: u32 = 0x7000_0010;
-pub const SHT_MIPS_FDESC: u32 = 0x7000_0011;
-pub const SHT_MIPS_EXTSYM: u32 = 0x7000_0012;
-pub const SHT_MIPS_DENSE: u32 = 0x7000_0013;
-pub const SHT_MIPS_PDESC: u32 = 0x7000_0014;
-pub const SHT_MIPS_LOCSYM: u32 = 0x7000_0015;
-pub const SHT_MIPS_AUXSYM: u32 = 0x7000_0016;
-pub const SHT_MIPS_OPTSYM: u32 = 0x7000_0017;
-pub const SHT_MIPS_LOCSTR: u32 = 0x7000_0018;
-pub const SHT_MIPS_LINE: u32 = 0x7000_0019;
-pub const SHT_MIPS_RFDESC: u32 = 0x7000_001a;
-pub const SHT_MIPS_DELTASYM: u32 = 0x7000_001b;
-pub const SHT_MIPS_DELTAINST: u32 = 0x7000_001c;
-pub const SHT_MIPS_DELTACLASS: u32 = 0x7000_001d;
-/// DWARF debugging information.
-pub const SHT_MIPS_DWARF: u32 = 0x7000_001e;
-pub const SHT_MIPS_DELTADECL: u32 = 0x7000_001f;
-pub const SHT_MIPS_SYMBOL_LIB: u32 = 0x7000_0020;
-/// Event section.
-pub const SHT_MIPS_EVENTS: u32 = 0x7000_0021;
-pub const SHT_MIPS_TRANSLATE: u32 = 0x7000_0022;
-pub const SHT_MIPS_PIXIE: u32 = 0x7000_0023;
-pub const SHT_MIPS_XLATE: u32 = 0x7000_0024;
-pub const SHT_MIPS_XLATE_DEBUG: u32 = 0x7000_0025;
-pub const SHT_MIPS_WHIRL: u32 = 0x7000_0026;
-pub const SHT_MIPS_EH_REGION: u32 = 0x7000_0027;
-pub const SHT_MIPS_XLATE_OLD: u32 = 0x7000_0028;
-pub const SHT_MIPS_PDR_EXCEPTION: u32 = 0x7000_0029;
-
-// MIPS values for `SectionHeader32::sh_flags`.
-
-/// Must be in global data area.
-pub const SHF_MIPS_GPREL: u32 = 0x1000_0000;
-pub const SHF_MIPS_MERGE: u32 = 0x2000_0000;
-pub const SHF_MIPS_ADDR: u32 = 0x4000_0000;
-pub const SHF_MIPS_STRINGS: u32 = 0x8000_0000;
-pub const SHF_MIPS_NOSTRIP: u32 = 0x0800_0000;
-pub const SHF_MIPS_LOCAL: u32 = 0x0400_0000;
-pub const SHF_MIPS_NAMES: u32 = 0x0200_0000;
-pub const SHF_MIPS_NODUPE: u32 = 0x0100_0000;
-
-// MIPS values for `Sym32::st_other`.
-
-pub const STO_MIPS_PLT: u8 = 0x8;
-/// Only valid for `STB_MIPS_SPLIT_COMMON`.
-pub const STO_MIPS_SC_ALIGN_UNUSED: u8 = 0xff;
-
-// MIPS values for `Sym32::st_info'.
-pub const STB_MIPS_SPLIT_COMMON: u8 = 13;
-
-// Entries found in sections of type `SHT_MIPS_GPTAB`.
-
-// TODO: Elf32_gptab, Elf32_RegInfo, Elf_Options
-
-// Values for `Elf_Options::kind`.
-
-/// Undefined.
-pub const ODK_NULL: u32 = 0;
-/// Register usage information.
-pub const ODK_REGINFO: u32 = 1;
-/// Exception processing options.
-pub const ODK_EXCEPTIONS: u32 = 2;
-/// Section padding options.
-pub const ODK_PAD: u32 = 3;
-/// Hardware workarounds performed
-pub const ODK_HWPATCH: u32 = 4;
-/// record the fill value used by the linker.
-pub const ODK_FILL: u32 = 5;
-/// reserve space for desktop tools to write.
-pub const ODK_TAGS: u32 = 6;
-/// HW workarounds. 'AND' bits when merging.
-pub const ODK_HWAND: u32 = 7;
-/// HW workarounds. 'OR' bits when merging.
-pub const ODK_HWOR: u32 = 8;
-
-// Values for `Elf_Options::info` for `ODK_EXCEPTIONS` entries.
-
-/// FPE's which MUST be enabled.
-pub const OEX_FPU_MIN: u32 = 0x1f;
-/// FPE's which MAY be enabled.
-pub const OEX_FPU_MAX: u32 = 0x1f00;
-/// page zero must be mapped.
-pub const OEX_PAGE0: u32 = 0x10000;
-/// Force sequential memory mode?
-pub const OEX_SMM: u32 = 0x20000;
-/// Force floating point debug mode?
-pub const OEX_FPDBUG: u32 = 0x40000;
-pub const OEX_PRECISEFP: u32 = OEX_FPDBUG;
-/// Dismiss invalid address faults?
-pub const OEX_DISMISS: u32 = 0x80000;
-
-pub const OEX_FPU_INVAL: u32 = 0x10;
-pub const OEX_FPU_DIV0: u32 = 0x08;
-pub const OEX_FPU_OFLO: u32 = 0x04;
-pub const OEX_FPU_UFLO: u32 = 0x02;
-pub const OEX_FPU_INEX: u32 = 0x01;
-
-// Masks for `Elf_Options::info` for an `ODK_HWPATCH` entry. */
-/// R4000 end-of-page patch.
-pub const OHW_R4KEOP: u32 = 0x1;
-/// may need R8000 prefetch patch.
-pub const OHW_R8KPFETCH: u32 = 0x2;
-/// R5000 end-of-page patch.
-pub const OHW_R5KEOP: u32 = 0x4;
-/// R5000 cvt.\[ds\].l bug. clean=1.
-pub const OHW_R5KCVTL: u32 = 0x8;
-
-pub const OPAD_PREFIX: u32 = 0x1;
-pub const OPAD_POSTFIX: u32 = 0x2;
-pub const OPAD_SYMBOL: u32 = 0x4;
-
-// Entries found in sections of type `SHT_MIPS_OPTIONS`.
-
-// TODO: Elf_Options_Hw
-
-// Masks for `ElfOptions::info` for `ODK_HWAND` and `ODK_HWOR` entries.
-
-pub const OHWA0_R4KEOP_CHECKED: u32 = 0x0000_0001;
-pub const OHWA1_R4KEOP_CLEAN: u32 = 0x0000_0002;
-
-// MIPS values for `Rel*::r_type`.
-
-/// No reloc
-pub const R_MIPS_NONE: u32 = 0;
-/// Direct 16 bit
-pub const R_MIPS_16: u32 = 1;
-/// Direct 32 bit
-pub const R_MIPS_32: u32 = 2;
-/// PC relative 32 bit
-pub const R_MIPS_REL32: u32 = 3;
-/// Direct 26 bit shifted
-pub const R_MIPS_26: u32 = 4;
-/// High 16 bit
-pub const R_MIPS_HI16: u32 = 5;
-/// Low 16 bit
-pub const R_MIPS_LO16: u32 = 6;
-/// GP relative 16 bit
-pub const R_MIPS_GPREL16: u32 = 7;
-/// 16 bit literal entry
-pub const R_MIPS_LITERAL: u32 = 8;
-/// 16 bit GOT entry
-pub const R_MIPS_GOT16: u32 = 9;
-/// PC relative 16 bit
-pub const R_MIPS_PC16: u32 = 10;
-/// 16 bit GOT entry for function
-pub const R_MIPS_CALL16: u32 = 11;
-/// GP relative 32 bit
-pub const R_MIPS_GPREL32: u32 = 12;
-
-pub const R_MIPS_SHIFT5: u32 = 16;
-pub const R_MIPS_SHIFT6: u32 = 17;
-pub const R_MIPS_64: u32 = 18;
-pub const R_MIPS_GOT_DISP: u32 = 19;
-pub const R_MIPS_GOT_PAGE: u32 = 20;
-pub const R_MIPS_GOT_OFST: u32 = 21;
-pub const R_MIPS_GOT_HI16: u32 = 22;
-pub const R_MIPS_GOT_LO16: u32 = 23;
-pub const R_MIPS_SUB: u32 = 24;
-pub const R_MIPS_INSERT_A: u32 = 25;
-pub const R_MIPS_INSERT_B: u32 = 26;
-pub const R_MIPS_DELETE: u32 = 27;
-pub const R_MIPS_HIGHER: u32 = 28;
-pub const R_MIPS_HIGHEST: u32 = 29;
-pub const R_MIPS_CALL_HI16: u32 = 30;
-pub const R_MIPS_CALL_LO16: u32 = 31;
-pub const R_MIPS_SCN_DISP: u32 = 32;
-pub const R_MIPS_REL16: u32 = 33;
-pub const R_MIPS_ADD_IMMEDIATE: u32 = 34;
-pub const R_MIPS_PJUMP: u32 = 35;
-pub const R_MIPS_RELGOT: u32 = 36;
-pub const R_MIPS_JALR: u32 = 37;
-/// Module number 32 bit
-pub const R_MIPS_TLS_DTPMOD32: u32 = 38;
-/// Module-relative offset 32 bit
-pub const R_MIPS_TLS_DTPREL32: u32 = 39;
-/// Module number 64 bit
-pub const R_MIPS_TLS_DTPMOD64: u32 = 40;
-/// Module-relative offset 64 bit
-pub const R_MIPS_TLS_DTPREL64: u32 = 41;
-/// 16 bit GOT offset for GD
-pub const R_MIPS_TLS_GD: u32 = 42;
-/// 16 bit GOT offset for LDM
-pub const R_MIPS_TLS_LDM: u32 = 43;
-/// Module-relative offset, high 16 bits
-pub const R_MIPS_TLS_DTPREL_HI16: u32 = 44;
-/// Module-relative offset, low 16 bits
-pub const R_MIPS_TLS_DTPREL_LO16: u32 = 45;
-/// 16 bit GOT offset for IE
-pub const R_MIPS_TLS_GOTTPREL: u32 = 46;
-/// TP-relative offset, 32 bit
-pub const R_MIPS_TLS_TPREL32: u32 = 47;
-/// TP-relative offset, 64 bit
-pub const R_MIPS_TLS_TPREL64: u32 = 48;
-/// TP-relative offset, high 16 bits
-pub const R_MIPS_TLS_TPREL_HI16: u32 = 49;
-/// TP-relative offset, low 16 bits
-pub const R_MIPS_TLS_TPREL_LO16: u32 = 50;
-pub const R_MIPS_GLOB_DAT: u32 = 51;
-pub const R_MIPS_COPY: u32 = 126;
-pub const R_MIPS_JUMP_SLOT: u32 = 127;
-
-// MIPS values for `ProgramHeader32::p_type`.
-
-/// Register usage information.
-pub const PT_MIPS_REGINFO: u32 = 0x7000_0000;
-/// Runtime procedure table.
-pub const PT_MIPS_RTPROC: u32 = 0x7000_0001;
-pub const PT_MIPS_OPTIONS: u32 = 0x7000_0002;
-/// FP mode requirement.
-pub const PT_MIPS_ABIFLAGS: u32 = 0x7000_0003;
-
-// MIPS values for `ProgramHeader32::p_flags`.
-
-pub const PF_MIPS_LOCAL: u32 = 0x1000_0000;
-
-// MIPS values for `Dyn32::d_tag`.
-
-/// Runtime linker interface version
-pub const DT_MIPS_RLD_VERSION: u32 = 0x7000_0001;
-/// Timestamp
-pub const DT_MIPS_TIME_STAMP: u32 = 0x7000_0002;
-/// Checksum
-pub const DT_MIPS_ICHECKSUM: u32 = 0x7000_0003;
-/// Version string (string tbl index)
-pub const DT_MIPS_IVERSION: u32 = 0x7000_0004;
-/// Flags
-pub const DT_MIPS_FLAGS: u32 = 0x7000_0005;
-/// Base address
-pub const DT_MIPS_BASE_ADDRESS: u32 = 0x7000_0006;
-pub const DT_MIPS_MSYM: u32 = 0x7000_0007;
-/// Address of CONFLICT section
-pub const DT_MIPS_CONFLICT: u32 = 0x7000_0008;
-/// Address of LIBLIST section
-pub const DT_MIPS_LIBLIST: u32 = 0x7000_0009;
-/// Number of local GOT entries
-pub const DT_MIPS_LOCAL_GOTNO: u32 = 0x7000_000a;
-/// Number of CONFLICT entries
-pub const DT_MIPS_CONFLICTNO: u32 = 0x7000_000b;
-/// Number of LIBLIST entries
-pub const DT_MIPS_LIBLISTNO: u32 = 0x7000_0010;
-/// Number of DYNSYM entries
-pub const DT_MIPS_SYMTABNO: u32 = 0x7000_0011;
-/// First external DYNSYM
-pub const DT_MIPS_UNREFEXTNO: u32 = 0x7000_0012;
-/// First GOT entry in DYNSYM
-pub const DT_MIPS_GOTSYM: u32 = 0x7000_0013;
-/// Number of GOT page table entries
-pub const DT_MIPS_HIPAGENO: u32 = 0x7000_0014;
-/// Address of run time loader map.
-pub const DT_MIPS_RLD_MAP: u32 = 0x7000_0016;
-/// Delta C++ class definition.
-pub const DT_MIPS_DELTA_CLASS: u32 = 0x7000_0017;
-/// Number of entries in DT_MIPS_DELTA_CLASS.
-pub const DT_MIPS_DELTA_CLASS_NO: u32 = 0x7000_0018;
-/// Delta C++ class instances.
-pub const DT_MIPS_DELTA_INSTANCE: u32 = 0x7000_0019;
-/// Number of entries in DT_MIPS_DELTA_INSTANCE.
-pub const DT_MIPS_DELTA_INSTANCE_NO: u32 = 0x7000_001a;
-/// Delta relocations.
-pub const DT_MIPS_DELTA_RELOC: u32 = 0x7000_001b;
-/// Number of entries in DT_MIPS_DELTA_RELOC.
-pub const DT_MIPS_DELTA_RELOC_NO: u32 = 0x7000_001c;
-/// Delta symbols that Delta relocations refer to.
-pub const DT_MIPS_DELTA_SYM: u32 = 0x7000_001d;
-/// Number of entries in DT_MIPS_DELTA_SYM.
-pub const DT_MIPS_DELTA_SYM_NO: u32 = 0x7000_001e;
-/// Delta symbols that hold the class declaration.
-pub const DT_MIPS_DELTA_CLASSSYM: u32 = 0x7000_0020;
-/// Number of entries in DT_MIPS_DELTA_CLASSSYM.
-pub const DT_MIPS_DELTA_CLASSSYM_NO: u32 = 0x7000_0021;
-/// Flags indicating for C++ flavor.
-pub const DT_MIPS_CXX_FLAGS: u32 = 0x7000_0022;
-pub const DT_MIPS_PIXIE_INIT: u32 = 0x7000_0023;
-pub const DT_MIPS_SYMBOL_LIB: u32 = 0x7000_0024;
-pub const DT_MIPS_LOCALPAGE_GOTIDX: u32 = 0x7000_0025;
-pub const DT_MIPS_LOCAL_GOTIDX: u32 = 0x7000_0026;
-pub const DT_MIPS_HIDDEN_GOTIDX: u32 = 0x7000_0027;
-pub const DT_MIPS_PROTECTED_GOTIDX: u32 = 0x7000_0028;
-/// Address of .options.
-pub const DT_MIPS_OPTIONS: u32 = 0x7000_0029;
-/// Address of .interface.
-pub const DT_MIPS_INTERFACE: u32 = 0x7000_002a;
-pub const DT_MIPS_DYNSTR_ALIGN: u32 = 0x7000_002b;
-/// Size of the .interface section.
-pub const DT_MIPS_INTERFACE_SIZE: u32 = 0x7000_002c;
-/// Address of rld_text_rsolve function stored in GOT.
-pub const DT_MIPS_RLD_TEXT_RESOLVE_ADDR: u32 = 0x7000_002d;
-/// Default suffix of dso to be added by rld on dlopen() calls.
-pub const DT_MIPS_PERF_SUFFIX: u32 = 0x7000_002e;
-/// (O32)Size of compact rel section.
-pub const DT_MIPS_COMPACT_SIZE: u32 = 0x7000_002f;
-/// GP value for aux GOTs.
-pub const DT_MIPS_GP_VALUE: u32 = 0x7000_0030;
-/// Address of aux .dynamic.
-pub const DT_MIPS_AUX_DYNAMIC: u32 = 0x7000_0031;
-/// The address of .got.plt in an executable using the new non-PIC ABI.
-pub const DT_MIPS_PLTGOT: u32 = 0x7000_0032;
-/// The base of the PLT in an executable using the new non-PIC ABI if that PLT is writable. For a non-writable PLT, this is omitted or has a zero value.
-pub const DT_MIPS_RWPLT: u32 = 0x7000_0034;
-/// An alternative description of the classic MIPS RLD_MAP that is usable in a PIE as it stores a relative offset from the address of the tag rather than an absolute address.
-pub const DT_MIPS_RLD_MAP_REL: u32 = 0x7000_0035;
-
-// Values for `DT_MIPS_FLAGS` `Dyn32` entry.
-
-/// No flags
-pub const RHF_NONE: u32 = 0;
-/// Use quickstart
-pub const RHF_QUICKSTART: u32 = 1 << 0;
-/// Hash size not power of 2
-pub const RHF_NOTPOT: u32 = 1 << 1;
-/// Ignore LD_LIBRARY_PATH
-pub const RHF_NO_LIBRARY_REPLACEMENT: u32 = 1 << 2;
-pub const RHF_NO_MOVE: u32 = 1 << 3;
-pub const RHF_SGI_ONLY: u32 = 1 << 4;
-pub const RHF_GUARANTEE_INIT: u32 = 1 << 5;
-pub const RHF_DELTA_C_PLUS_PLUS: u32 = 1 << 6;
-pub const RHF_GUARANTEE_START_INIT: u32 = 1 << 7;
-pub const RHF_PIXIE: u32 = 1 << 8;
-pub const RHF_DEFAULT_DELAY_LOAD: u32 = 1 << 9;
-pub const RHF_REQUICKSTART: u32 = 1 << 10;
-pub const RHF_REQUICKSTARTED: u32 = 1 << 11;
-pub const RHF_CORD: u32 = 1 << 12;
-pub const RHF_NO_UNRES_UNDEF: u32 = 1 << 13;
-pub const RHF_RLD_ORDER_SAFE: u32 = 1 << 14;
-
-// Entries found in sections of type `SHT_MIPS_LIBLIST`.
-
-// TODO: Elf32_Lib, Elf64_Lib
-
-// Values for `Lib*::l_flags`.
-
-pub const LL_NONE: u32 = 0;
-/// Require exact match
-pub const LL_EXACT_MATCH: u32 = 1 << 0;
-/// Ignore interface version
-pub const LL_IGNORE_INT_VER: u32 = 1 << 1;
-pub const LL_REQUIRE_MINOR: u32 = 1 << 2;
-pub const LL_EXPORTS: u32 = 1 << 3;
-pub const LL_DELAY_LOAD: u32 = 1 << 4;
-pub const LL_DELTA: u32 = 1 << 5;
-
-// TODO: MIPS ABI flags
-
-// PA-RISC specific definitions.
-
-// PA-RISC values for `FileHeader32::e_flags`.
-
-/// Trap nil pointer dereference.
-pub const EF_PARISC_TRAPNIL: u32 = 0x0001_0000;
-/// Program uses arch. extensions.
-pub const EF_PARISC_EXT: u32 = 0x0002_0000;
-/// Program expects little endian.
-pub const EF_PARISC_LSB: u32 = 0x0004_0000;
-/// Program expects wide mode.
-pub const EF_PARISC_WIDE: u32 = 0x0008_0000;
-/// No kernel assisted branch prediction.
-pub const EF_PARISC_NO_KABP: u32 = 0x0010_0000;
-/// Allow lazy swapping.
-pub const EF_PARISC_LAZYSWAP: u32 = 0x0040_0000;
-/// Architecture version.
-pub const EF_PARISC_ARCH: u32 = 0x0000_ffff;
-
-// Values for `EF_PARISC_ARCH'.
-
-/// PA-RISC 1.0 big-endian.
-pub const EFA_PARISC_1_0: u32 = 0x020b;
-/// PA-RISC 1.1 big-endian.
-pub const EFA_PARISC_1_1: u32 = 0x0210;
-/// PA-RISC 2.0 big-endian.
-pub const EFA_PARISC_2_0: u32 = 0x0214;
-
-// PA-RISC values for `Sym*::st_shndx`.
-
-/// Section for tentatively declared symbols in ANSI C.
-pub const SHN_PARISC_ANSI_COMMON: u16 = 0xff00;
-/// Common blocks in huge model.
-pub const SHN_PARISC_HUGE_COMMON: u16 = 0xff01;
-
-// PA-RISC values for `SectionHeader32::sh_type`.
-
-/// Contains product specific ext.
-pub const SHT_PARISC_EXT: u32 = 0x7000_0000;
-/// Unwind information.
-pub const SHT_PARISC_UNWIND: u32 = 0x7000_0001;
-/// Debug info for optimized code.
-pub const SHT_PARISC_DOC: u32 = 0x7000_0002;
-
-// PA-RISC values for `SectionHeader32::sh_flags`.
-
-/// Section with short addressing.
-pub const SHF_PARISC_SHORT: u32 = 0x2000_0000;
-/// Section far from gp.
-pub const SHF_PARISC_HUGE: u32 = 0x4000_0000;
-/// Static branch prediction code.
-pub const SHF_PARISC_SBP: u32 = 0x8000_0000;
-
-// PA-RISC values for `st_type` component of `Sym32::st_info`.
-
-/// Millicode function entry point.
-pub const STT_PARISC_MILLICODE: u8 = 13;
-
-pub const STT_HP_OPAQUE: u8 = STT_LOOS + 0x1;
-pub const STT_HP_STUB: u8 = STT_LOOS + 0x2;
-
-// PA-RISC values for `Rel*::r_type`.
-
-/// No reloc.
-pub const R_PARISC_NONE: u32 = 0;
-/// Direct 32-bit reference.
-pub const R_PARISC_DIR32: u32 = 1;
-/// Left 21 bits of eff. address.
-pub const R_PARISC_DIR21L: u32 = 2;
-/// Right 17 bits of eff. address.
-pub const R_PARISC_DIR17R: u32 = 3;
-/// 17 bits of eff. address.
-pub const R_PARISC_DIR17F: u32 = 4;
-/// Right 14 bits of eff. address.
-pub const R_PARISC_DIR14R: u32 = 6;
-/// 32-bit rel. address.
-pub const R_PARISC_PCREL32: u32 = 9;
-/// Left 21 bits of rel. address.
-pub const R_PARISC_PCREL21L: u32 = 10;
-/// Right 17 bits of rel. address.
-pub const R_PARISC_PCREL17R: u32 = 11;
-/// 17 bits of rel. address.
-pub const R_PARISC_PCREL17F: u32 = 12;
-/// Right 14 bits of rel. address.
-pub const R_PARISC_PCREL14R: u32 = 14;
-/// Left 21 bits of rel. address.
-pub const R_PARISC_DPREL21L: u32 = 18;
-/// Right 14 bits of rel. address.
-pub const R_PARISC_DPREL14R: u32 = 22;
-/// GP-relative, left 21 bits.
-pub const R_PARISC_GPREL21L: u32 = 26;
-/// GP-relative, right 14 bits.
-pub const R_PARISC_GPREL14R: u32 = 30;
-/// LT-relative, left 21 bits.
-pub const R_PARISC_LTOFF21L: u32 = 34;
-/// LT-relative, right 14 bits.
-pub const R_PARISC_LTOFF14R: u32 = 38;
-/// 32 bits section rel. address.
-pub const R_PARISC_SECREL32: u32 = 41;
-/// No relocation, set segment base.
-pub const R_PARISC_SEGBASE: u32 = 48;
-/// 32 bits segment rel. address.
-pub const R_PARISC_SEGREL32: u32 = 49;
-/// PLT rel. address, left 21 bits.
-pub const R_PARISC_PLTOFF21L: u32 = 50;
-/// PLT rel. address, right 14 bits.
-pub const R_PARISC_PLTOFF14R: u32 = 54;
-/// 32 bits LT-rel. function pointer.
-pub const R_PARISC_LTOFF_FPTR32: u32 = 57;
-/// LT-rel. fct ptr, left 21 bits.
-pub const R_PARISC_LTOFF_FPTR21L: u32 = 58;
-/// LT-rel. fct ptr, right 14 bits.
-pub const R_PARISC_LTOFF_FPTR14R: u32 = 62;
-/// 64 bits function address.
-pub const R_PARISC_FPTR64: u32 = 64;
-/// 32 bits function address.
-pub const R_PARISC_PLABEL32: u32 = 65;
-/// Left 21 bits of fdesc address.
-pub const R_PARISC_PLABEL21L: u32 = 66;
-/// Right 14 bits of fdesc address.
-pub const R_PARISC_PLABEL14R: u32 = 70;
-/// 64 bits PC-rel. address.
-pub const R_PARISC_PCREL64: u32 = 72;
-/// 22 bits PC-rel. address.
-pub const R_PARISC_PCREL22F: u32 = 74;
-/// PC-rel. address, right 14 bits.
-pub const R_PARISC_PCREL14WR: u32 = 75;
-/// PC rel. address, right 14 bits.
-pub const R_PARISC_PCREL14DR: u32 = 76;
-/// 16 bits PC-rel. address.
-pub const R_PARISC_PCREL16F: u32 = 77;
-/// 16 bits PC-rel. address.
-pub const R_PARISC_PCREL16WF: u32 = 78;
-/// 16 bits PC-rel. address.
-pub const R_PARISC_PCREL16DF: u32 = 79;
-/// 64 bits of eff. address.
-pub const R_PARISC_DIR64: u32 = 80;
-/// 14 bits of eff. address.
-pub const R_PARISC_DIR14WR: u32 = 83;
-/// 14 bits of eff. address.
-pub const R_PARISC_DIR14DR: u32 = 84;
-/// 16 bits of eff. address.
-pub const R_PARISC_DIR16F: u32 = 85;
-/// 16 bits of eff. address.
-pub const R_PARISC_DIR16WF: u32 = 86;
-/// 16 bits of eff. address.
-pub const R_PARISC_DIR16DF: u32 = 87;
-/// 64 bits of GP-rel. address.
-pub const R_PARISC_GPREL64: u32 = 88;
-/// GP-rel. address, right 14 bits.
-pub const R_PARISC_GPREL14WR: u32 = 91;
-/// GP-rel. address, right 14 bits.
-pub const R_PARISC_GPREL14DR: u32 = 92;
-/// 16 bits GP-rel. address.
-pub const R_PARISC_GPREL16F: u32 = 93;
-/// 16 bits GP-rel. address.
-pub const R_PARISC_GPREL16WF: u32 = 94;
-/// 16 bits GP-rel. address.
-pub const R_PARISC_GPREL16DF: u32 = 95;
-/// 64 bits LT-rel. address.
-pub const R_PARISC_LTOFF64: u32 = 96;
-/// LT-rel. address, right 14 bits.
-pub const R_PARISC_LTOFF14WR: u32 = 99;
-/// LT-rel. address, right 14 bits.
-pub const R_PARISC_LTOFF14DR: u32 = 100;
-/// 16 bits LT-rel. address.
-pub const R_PARISC_LTOFF16F: u32 = 101;
-/// 16 bits LT-rel. address.
-pub const R_PARISC_LTOFF16WF: u32 = 102;
-/// 16 bits LT-rel. address.
-pub const R_PARISC_LTOFF16DF: u32 = 103;
-/// 64 bits section rel. address.
-pub const R_PARISC_SECREL64: u32 = 104;
-/// 64 bits segment rel. address.
-pub const R_PARISC_SEGREL64: u32 = 112;
-/// PLT-rel. address, right 14 bits.
-pub const R_PARISC_PLTOFF14WR: u32 = 115;
-/// PLT-rel. address, right 14 bits.
-pub const R_PARISC_PLTOFF14DR: u32 = 116;
-/// 16 bits LT-rel. address.
-pub const R_PARISC_PLTOFF16F: u32 = 117;
-/// 16 bits PLT-rel. address.
-pub const R_PARISC_PLTOFF16WF: u32 = 118;
-/// 16 bits PLT-rel. address.
-pub const R_PARISC_PLTOFF16DF: u32 = 119;
-/// 64 bits LT-rel. function ptr.
-pub const R_PARISC_LTOFF_FPTR64: u32 = 120;
-/// LT-rel. fct. ptr., right 14 bits.
-pub const R_PARISC_LTOFF_FPTR14WR: u32 = 123;
-/// LT-rel. fct. ptr., right 14 bits.
-pub const R_PARISC_LTOFF_FPTR14DR: u32 = 124;
-/// 16 bits LT-rel. function ptr.
-pub const R_PARISC_LTOFF_FPTR16F: u32 = 125;
-/// 16 bits LT-rel. function ptr.
-pub const R_PARISC_LTOFF_FPTR16WF: u32 = 126;
-/// 16 bits LT-rel. function ptr.
-pub const R_PARISC_LTOFF_FPTR16DF: u32 = 127;
-pub const R_PARISC_LORESERVE: u32 = 128;
-/// Copy relocation.
-pub const R_PARISC_COPY: u32 = 128;
-/// Dynamic reloc, imported PLT
-pub const R_PARISC_IPLT: u32 = 129;
-/// Dynamic reloc, exported PLT
-pub const R_PARISC_EPLT: u32 = 130;
-/// 32 bits TP-rel. address.
-pub const R_PARISC_TPREL32: u32 = 153;
-/// TP-rel. address, left 21 bits.
-pub const R_PARISC_TPREL21L: u32 = 154;
-/// TP-rel. address, right 14 bits.
-pub const R_PARISC_TPREL14R: u32 = 158;
-/// LT-TP-rel. address, left 21 bits.
-pub const R_PARISC_LTOFF_TP21L: u32 = 162;
-/// LT-TP-rel. address, right 14 bits.
-pub const R_PARISC_LTOFF_TP14R: u32 = 166;
-/// 14 bits LT-TP-rel. address.
-pub const R_PARISC_LTOFF_TP14F: u32 = 167;
-/// 64 bits TP-rel. address.
-pub const R_PARISC_TPREL64: u32 = 216;
-/// TP-rel. address, right 14 bits.
-pub const R_PARISC_TPREL14WR: u32 = 219;
-/// TP-rel. address, right 14 bits.
-pub const R_PARISC_TPREL14DR: u32 = 220;
-/// 16 bits TP-rel. address.
-pub const R_PARISC_TPREL16F: u32 = 221;
-/// 16 bits TP-rel. address.
-pub const R_PARISC_TPREL16WF: u32 = 222;
-/// 16 bits TP-rel. address.
-pub const R_PARISC_TPREL16DF: u32 = 223;
-/// 64 bits LT-TP-rel. address.
-pub const R_PARISC_LTOFF_TP64: u32 = 224;
-/// LT-TP-rel. address, right 14 bits.
-pub const R_PARISC_LTOFF_TP14WR: u32 = 227;
-/// LT-TP-rel. address, right 14 bits.
-pub const R_PARISC_LTOFF_TP14DR: u32 = 228;
-/// 16 bits LT-TP-rel. address.
-pub const R_PARISC_LTOFF_TP16F: u32 = 229;
-/// 16 bits LT-TP-rel. address.
-pub const R_PARISC_LTOFF_TP16WF: u32 = 230;
-/// 16 bits LT-TP-rel. address.
-pub const R_PARISC_LTOFF_TP16DF: u32 = 231;
-pub const R_PARISC_GNU_VTENTRY: u32 = 232;
-pub const R_PARISC_GNU_VTINHERIT: u32 = 233;
-/// GD 21-bit left.
-pub const R_PARISC_TLS_GD21L: u32 = 234;
-/// GD 14-bit right.
-pub const R_PARISC_TLS_GD14R: u32 = 235;
-/// GD call to __t_g_a.
-pub const R_PARISC_TLS_GDCALL: u32 = 236;
-/// LD module 21-bit left.
-pub const R_PARISC_TLS_LDM21L: u32 = 237;
-/// LD module 14-bit right.
-pub const R_PARISC_TLS_LDM14R: u32 = 238;
-/// LD module call to __t_g_a.
-pub const R_PARISC_TLS_LDMCALL: u32 = 239;
-/// LD offset 21-bit left.
-pub const R_PARISC_TLS_LDO21L: u32 = 240;
-/// LD offset 14-bit right.
-pub const R_PARISC_TLS_LDO14R: u32 = 241;
-/// DTP module 32-bit.
-pub const R_PARISC_TLS_DTPMOD32: u32 = 242;
-/// DTP module 64-bit.
-pub const R_PARISC_TLS_DTPMOD64: u32 = 243;
-/// DTP offset 32-bit.
-pub const R_PARISC_TLS_DTPOFF32: u32 = 244;
-/// DTP offset 32-bit.
-pub const R_PARISC_TLS_DTPOFF64: u32 = 245;
-pub const R_PARISC_TLS_LE21L: u32 = R_PARISC_TPREL21L;
-pub const R_PARISC_TLS_LE14R: u32 = R_PARISC_TPREL14R;
-pub const R_PARISC_TLS_IE21L: u32 = R_PARISC_LTOFF_TP21L;
-pub const R_PARISC_TLS_IE14R: u32 = R_PARISC_LTOFF_TP14R;
-pub const R_PARISC_TLS_TPREL32: u32 = R_PARISC_TPREL32;
-pub const R_PARISC_TLS_TPREL64: u32 = R_PARISC_TPREL64;
-pub const R_PARISC_HIRESERVE: u32 = 255;
-
-// PA-RISC values for `ProgramHeader*::p_type`.
-
-pub const PT_HP_TLS: u32 = PT_LOOS + 0x0;
-pub const PT_HP_CORE_NONE: u32 = PT_LOOS + 0x1;
-pub const PT_HP_CORE_VERSION: u32 = PT_LOOS + 0x2;
-pub const PT_HP_CORE_KERNEL: u32 = PT_LOOS + 0x3;
-pub const PT_HP_CORE_COMM: u32 = PT_LOOS + 0x4;
-pub const PT_HP_CORE_PROC: u32 = PT_LOOS + 0x5;
-pub const PT_HP_CORE_LOADABLE: u32 = PT_LOOS + 0x6;
-pub const PT_HP_CORE_STACK: u32 = PT_LOOS + 0x7;
-pub const PT_HP_CORE_SHM: u32 = PT_LOOS + 0x8;
-pub const PT_HP_CORE_MMF: u32 = PT_LOOS + 0x9;
-pub const PT_HP_PARALLEL: u32 = PT_LOOS + 0x10;
-pub const PT_HP_FASTBIND: u32 = PT_LOOS + 0x11;
-pub const PT_HP_OPT_ANNOT: u32 = PT_LOOS + 0x12;
-pub const PT_HP_HSL_ANNOT: u32 = PT_LOOS + 0x13;
-pub const PT_HP_STACK: u32 = PT_LOOS + 0x14;
-
-pub const PT_PARISC_ARCHEXT: u32 = 0x7000_0000;
-pub const PT_PARISC_UNWIND: u32 = 0x7000_0001;
-
-// PA-RISC values for `ProgramHeader*::p_flags`.
-
-pub const PF_PARISC_SBP: u32 = 0x0800_0000;
-
-pub const PF_HP_PAGE_SIZE: u32 = 0x0010_0000;
-pub const PF_HP_FAR_SHARED: u32 = 0x0020_0000;
-pub const PF_HP_NEAR_SHARED: u32 = 0x0040_0000;
-pub const PF_HP_CODE: u32 = 0x0100_0000;
-pub const PF_HP_MODIFY: u32 = 0x0200_0000;
-pub const PF_HP_LAZYSWAP: u32 = 0x0400_0000;
-pub const PF_HP_SBP: u32 = 0x0800_0000;
-
-// Alpha specific definitions.
-
-// Alpha values for `FileHeader64::e_flags`.
-
-/// All addresses must be < 2GB.
-pub const EF_ALPHA_32BIT: u32 = 1;
-/// Relocations for relaxing exist.
-pub const EF_ALPHA_CANRELAX: u32 = 2;
-
-// Alpha values for `SectionHeader64::sh_type`.
-
-// These two are primerily concerned with ECOFF debugging info.
-pub const SHT_ALPHA_DEBUG: u32 = 0x7000_0001;
-pub const SHT_ALPHA_REGINFO: u32 = 0x7000_0002;
-
-// Alpha values for `SectionHeader64::sh_flags`.
-
-pub const SHF_ALPHA_GPREL: u32 = 0x1000_0000;
-
-// Alpha values for `Sym64::st_other`.
-/// No PV required.
-pub const STO_ALPHA_NOPV: u8 = 0x80;
-/// PV only used for initial ldgp.
-pub const STO_ALPHA_STD_GPLOAD: u8 = 0x88;
-
-// Alpha values for `Rel64::r_type`.
-
-/// No reloc
-pub const R_ALPHA_NONE: u32 = 0;
-/// Direct 32 bit
-pub const R_ALPHA_REFLONG: u32 = 1;
-/// Direct 64 bit
-pub const R_ALPHA_REFQUAD: u32 = 2;
-/// GP relative 32 bit
-pub const R_ALPHA_GPREL32: u32 = 3;
-/// GP relative 16 bit w/optimization
-pub const R_ALPHA_LITERAL: u32 = 4;
-/// Optimization hint for LITERAL
-pub const R_ALPHA_LITUSE: u32 = 5;
-/// Add displacement to GP
-pub const R_ALPHA_GPDISP: u32 = 6;
-/// PC+4 relative 23 bit shifted
-pub const R_ALPHA_BRADDR: u32 = 7;
-/// PC+4 relative 16 bit shifted
-pub const R_ALPHA_HINT: u32 = 8;
-/// PC relative 16 bit
-pub const R_ALPHA_SREL16: u32 = 9;
-/// PC relative 32 bit
-pub const R_ALPHA_SREL32: u32 = 10;
-/// PC relative 64 bit
-pub const R_ALPHA_SREL64: u32 = 11;
-/// GP relative 32 bit, high 16 bits
-pub const R_ALPHA_GPRELHIGH: u32 = 17;
-/// GP relative 32 bit, low 16 bits
-pub const R_ALPHA_GPRELLOW: u32 = 18;
-/// GP relative 16 bit
-pub const R_ALPHA_GPREL16: u32 = 19;
-/// Copy symbol at runtime
-pub const R_ALPHA_COPY: u32 = 24;
-/// Create GOT entry
-pub const R_ALPHA_GLOB_DAT: u32 = 25;
-/// Create PLT entry
-pub const R_ALPHA_JMP_SLOT: u32 = 26;
-/// Adjust by program base
-pub const R_ALPHA_RELATIVE: u32 = 27;
-pub const R_ALPHA_TLS_GD_HI: u32 = 28;
-pub const R_ALPHA_TLSGD: u32 = 29;
-pub const R_ALPHA_TLS_LDM: u32 = 30;
-pub const R_ALPHA_DTPMOD64: u32 = 31;
-pub const R_ALPHA_GOTDTPREL: u32 = 32;
-pub const R_ALPHA_DTPREL64: u32 = 33;
-pub const R_ALPHA_DTPRELHI: u32 = 34;
-pub const R_ALPHA_DTPRELLO: u32 = 35;
-pub const R_ALPHA_DTPREL16: u32 = 36;
-pub const R_ALPHA_GOTTPREL: u32 = 37;
-pub const R_ALPHA_TPREL64: u32 = 38;
-pub const R_ALPHA_TPRELHI: u32 = 39;
-pub const R_ALPHA_TPRELLO: u32 = 40;
-pub const R_ALPHA_TPREL16: u32 = 41;
-
-// Magic values of the `R_ALPHA_LITUSE` relocation addend.
-pub const LITUSE_ALPHA_ADDR: u32 = 0;
-pub const LITUSE_ALPHA_BASE: u32 = 1;
-pub const LITUSE_ALPHA_BYTOFF: u32 = 2;
-pub const LITUSE_ALPHA_JSR: u32 = 3;
-pub const LITUSE_ALPHA_TLS_GD: u32 = 4;
-pub const LITUSE_ALPHA_TLS_LDM: u32 = 5;
-
-// Alpha values for `Dyn64::d_tag`.
-pub const DT_ALPHA_PLTRO: u32 = DT_LOPROC + 0;
-
-// PowerPC specific declarations.
-
-// PowerPC values for `FileHeader*::e_flags`.
-/// PowerPC embedded flag
-pub const EF_PPC_EMB: u32 = 0x8000_0000;
-
-// Cygnus local bits below .
-/// PowerPC -mrelocatable flag
-pub const EF_PPC_RELOCATABLE: u32 = 0x0001_0000;
-/// PowerPC -mrelocatable-lib flag
-pub const EF_PPC_RELOCATABLE_LIB: u32 = 0x0000_8000;
-
-// PowerPC values for `Rel*::r_type` defined by the ABIs.
-pub const R_PPC_NONE: u32 = 0;
-/// 32bit absolute address
-pub const R_PPC_ADDR32: u32 = 1;
-/// 26bit address, 2 bits ignored.
-pub const R_PPC_ADDR24: u32 = 2;
-/// 16bit absolute address
-pub const R_PPC_ADDR16: u32 = 3;
-/// lower 16bit of absolute address
-pub const R_PPC_ADDR16_LO: u32 = 4;
-/// high 16bit of absolute address
-pub const R_PPC_ADDR16_HI: u32 = 5;
-/// adjusted high 16bit
-pub const R_PPC_ADDR16_HA: u32 = 6;
-/// 16bit address, 2 bits ignored
-pub const R_PPC_ADDR14: u32 = 7;
-pub const R_PPC_ADDR14_BRTAKEN: u32 = 8;
-pub const R_PPC_ADDR14_BRNTAKEN: u32 = 9;
-/// PC relative 26 bit
-pub const R_PPC_REL24: u32 = 10;
-/// PC relative 16 bit
-pub const R_PPC_REL14: u32 = 11;
-pub const R_PPC_REL14_BRTAKEN: u32 = 12;
-pub const R_PPC_REL14_BRNTAKEN: u32 = 13;
-pub const R_PPC_GOT16: u32 = 14;
-pub const R_PPC_GOT16_LO: u32 = 15;
-pub const R_PPC_GOT16_HI: u32 = 16;
-pub const R_PPC_GOT16_HA: u32 = 17;
-pub const R_PPC_PLTREL24: u32 = 18;
-pub const R_PPC_COPY: u32 = 19;
-pub const R_PPC_GLOB_DAT: u32 = 20;
-pub const R_PPC_JMP_SLOT: u32 = 21;
-pub const R_PPC_RELATIVE: u32 = 22;
-pub const R_PPC_LOCAL24PC: u32 = 23;
-pub const R_PPC_UADDR32: u32 = 24;
-pub const R_PPC_UADDR16: u32 = 25;
-pub const R_PPC_REL32: u32 = 26;
-pub const R_PPC_PLT32: u32 = 27;
-pub const R_PPC_PLTREL32: u32 = 28;
-pub const R_PPC_PLT16_LO: u32 = 29;
-pub const R_PPC_PLT16_HI: u32 = 30;
-pub const R_PPC_PLT16_HA: u32 = 31;
-pub const R_PPC_SDAREL16: u32 = 32;
-pub const R_PPC_SECTOFF: u32 = 33;
-pub const R_PPC_SECTOFF_LO: u32 = 34;
-pub const R_PPC_SECTOFF_HI: u32 = 35;
-pub const R_PPC_SECTOFF_HA: u32 = 36;
-
-// PowerPC values for `Rel*::r_type` defined for the TLS access ABI.
-/// none (sym+add)@tls
-pub const R_PPC_TLS: u32 = 67;
-/// word32 (sym+add)@dtpmod
-pub const R_PPC_DTPMOD32: u32 = 68;
-/// half16* (sym+add)@tprel
-pub const R_PPC_TPREL16: u32 = 69;
-/// half16 (sym+add)@tprel@l
-pub const R_PPC_TPREL16_LO: u32 = 70;
-/// half16 (sym+add)@tprel@h
-pub const R_PPC_TPREL16_HI: u32 = 71;
-/// half16 (sym+add)@tprel@ha
-pub const R_PPC_TPREL16_HA: u32 = 72;
-/// word32 (sym+add)@tprel
-pub const R_PPC_TPREL32: u32 = 73;
-/// half16*(sym+add)@dtprel
-pub const R_PPC_DTPREL16: u32 = 74;
-/// half16 (sym+add)@dtprel@l
-pub const R_PPC_DTPREL16_LO: u32 = 75;
-/// half16 (sym+add)@dtprel@h
-pub const R_PPC_DTPREL16_HI: u32 = 76;
-/// half16 (sym+add)@dtprel@ha
-pub const R_PPC_DTPREL16_HA: u32 = 77;
-/// word32 (sym+add)@dtprel
-pub const R_PPC_DTPREL32: u32 = 78;
-/// half16* (sym+add)@got@tlsgd
-pub const R_PPC_GOT_TLSGD16: u32 = 79;
-/// half16 (sym+add)@got@tlsgd@l
-pub const R_PPC_GOT_TLSGD16_LO: u32 = 80;
-/// half16 (sym+add)@got@tlsgd@h
-pub const R_PPC_GOT_TLSGD16_HI: u32 = 81;
-/// half16 (sym+add)@got@tlsgd@ha
-pub const R_PPC_GOT_TLSGD16_HA: u32 = 82;
-/// half16* (sym+add)@got@tlsld
-pub const R_PPC_GOT_TLSLD16: u32 = 83;
-/// half16 (sym+add)@got@tlsld@l
-pub const R_PPC_GOT_TLSLD16_LO: u32 = 84;
-/// half16 (sym+add)@got@tlsld@h
-pub const R_PPC_GOT_TLSLD16_HI: u32 = 85;
-/// half16 (sym+add)@got@tlsld@ha
-pub const R_PPC_GOT_TLSLD16_HA: u32 = 86;
-/// half16* (sym+add)@got@tprel
-pub const R_PPC_GOT_TPREL16: u32 = 87;
-/// half16 (sym+add)@got@tprel@l
-pub const R_PPC_GOT_TPREL16_LO: u32 = 88;
-/// half16 (sym+add)@got@tprel@h
-pub const R_PPC_GOT_TPREL16_HI: u32 = 89;
-/// half16 (sym+add)@got@tprel@ha
-pub const R_PPC_GOT_TPREL16_HA: u32 = 90;
-/// half16* (sym+add)@got@dtprel
-pub const R_PPC_GOT_DTPREL16: u32 = 91;
-/// half16* (sym+add)@got@dtprel@l
-pub const R_PPC_GOT_DTPREL16_LO: u32 = 92;
-/// half16* (sym+add)@got@dtprel@h
-pub const R_PPC_GOT_DTPREL16_HI: u32 = 93;
-/// half16* (sym+add)@got@dtprel@ha
-pub const R_PPC_GOT_DTPREL16_HA: u32 = 94;
-/// none (sym+add)@tlsgd
-pub const R_PPC_TLSGD: u32 = 95;
-/// none (sym+add)@tlsld
-pub const R_PPC_TLSLD: u32 = 96;
-
-// PowerPC values for `Rel*::r_type` from the Embedded ELF ABI.
-pub const R_PPC_EMB_NADDR32: u32 = 101;
-pub const R_PPC_EMB_NADDR16: u32 = 102;
-pub const R_PPC_EMB_NADDR16_LO: u32 = 103;
-pub const R_PPC_EMB_NADDR16_HI: u32 = 104;
-pub const R_PPC_EMB_NADDR16_HA: u32 = 105;
-pub const R_PPC_EMB_SDAI16: u32 = 106;
-pub const R_PPC_EMB_SDA2I16: u32 = 107;
-pub const R_PPC_EMB_SDA2REL: u32 = 108;
-/// 16 bit offset in SDA
-pub const R_PPC_EMB_SDA21: u32 = 109;
-pub const R_PPC_EMB_MRKREF: u32 = 110;
-pub const R_PPC_EMB_RELSEC16: u32 = 111;
-pub const R_PPC_EMB_RELST_LO: u32 = 112;
-pub const R_PPC_EMB_RELST_HI: u32 = 113;
-pub const R_PPC_EMB_RELST_HA: u32 = 114;
-pub const R_PPC_EMB_BIT_FLD: u32 = 115;
-/// 16 bit relative offset in SDA
-pub const R_PPC_EMB_RELSDA: u32 = 116;
-
-// Diab tool values for `Rel*::r_type`.
-/// like EMB_SDA21, but lower 16 bit
-pub const R_PPC_DIAB_SDA21_LO: u32 = 180;
-/// like EMB_SDA21, but high 16 bit
-pub const R_PPC_DIAB_SDA21_HI: u32 = 181;
-/// like EMB_SDA21, adjusted high 16
-pub const R_PPC_DIAB_SDA21_HA: u32 = 182;
-/// like EMB_RELSDA, but lower 16 bit
-pub const R_PPC_DIAB_RELSDA_LO: u32 = 183;
-/// like EMB_RELSDA, but high 16 bit
-pub const R_PPC_DIAB_RELSDA_HI: u32 = 184;
-/// like EMB_RELSDA, adjusted high 16
-pub const R_PPC_DIAB_RELSDA_HA: u32 = 185;
-
-/// GNU extension to support local ifunc.
-pub const R_PPC_IRELATIVE: u32 = 248;
-
-// GNU relocs used in PIC code sequences.
-/// half16 (sym+add-.)
-pub const R_PPC_REL16: u32 = 249;
-/// half16 (sym+add-.)@l
-pub const R_PPC_REL16_LO: u32 = 250;
-/// half16 (sym+add-.)@h
-pub const R_PPC_REL16_HI: u32 = 251;
-/// half16 (sym+add-.)@ha
-pub const R_PPC_REL16_HA: u32 = 252;
-
-/// This is a phony reloc to handle any old fashioned TOC16 references that may
-/// still be in object files.
-pub const R_PPC_TOC16: u32 = 255;
-
-// PowerPC specific values for `Dyn*::d_tag`.
-pub const DT_PPC_GOT: u32 = DT_LOPROC + 0;
-pub const DT_PPC_OPT: u32 = DT_LOPROC + 1;
-
-// PowerPC specific values for the `DT_PPC_OPT` entry.
-pub const PPC_OPT_TLS: u32 = 1;
-
-// PowerPC64 values for `Rel*::r_type` defined by the ABIs.
-pub const R_PPC64_NONE: u32 = R_PPC_NONE;
-/// 32bit absolute address
-pub const R_PPC64_ADDR32: u32 = R_PPC_ADDR32;
-/// 26bit address, word aligned
-pub const R_PPC64_ADDR24: u32 = R_PPC_ADDR24;
-/// 16bit absolute address
-pub const R_PPC64_ADDR16: u32 = R_PPC_ADDR16;
-/// lower 16bits of address
-pub const R_PPC64_ADDR16_LO: u32 = R_PPC_ADDR16_LO;
-/// high 16bits of address.
-pub const R_PPC64_ADDR16_HI: u32 = R_PPC_ADDR16_HI;
-/// adjusted high 16bits.
-pub const R_PPC64_ADDR16_HA: u32 = R_PPC_ADDR16_HA;
-/// 16bit address, word aligned
-pub const R_PPC64_ADDR14: u32 = R_PPC_ADDR14;
-pub const R_PPC64_ADDR14_BRTAKEN: u32 = R_PPC_ADDR14_BRTAKEN;
-pub const R_PPC64_ADDR14_BRNTAKEN: u32 = R_PPC_ADDR14_BRNTAKEN;
-/// PC-rel. 26 bit, word aligned
-pub const R_PPC64_REL24: u32 = R_PPC_REL24;
-/// PC relative 16 bit
-pub const R_PPC64_REL14: u32 = R_PPC_REL14;
-pub const R_PPC64_REL14_BRTAKEN: u32 = R_PPC_REL14_BRTAKEN;
-pub const R_PPC64_REL14_BRNTAKEN: u32 = R_PPC_REL14_BRNTAKEN;
-pub const R_PPC64_GOT16: u32 = R_PPC_GOT16;
-pub const R_PPC64_GOT16_LO: u32 = R_PPC_GOT16_LO;
-pub const R_PPC64_GOT16_HI: u32 = R_PPC_GOT16_HI;
-pub const R_PPC64_GOT16_HA: u32 = R_PPC_GOT16_HA;
-
-pub const R_PPC64_COPY: u32 = R_PPC_COPY;
-pub const R_PPC64_GLOB_DAT: u32 = R_PPC_GLOB_DAT;
-pub const R_PPC64_JMP_SLOT: u32 = R_PPC_JMP_SLOT;
-pub const R_PPC64_RELATIVE: u32 = R_PPC_RELATIVE;
-
-pub const R_PPC64_UADDR32: u32 = R_PPC_UADDR32;
-pub const R_PPC64_UADDR16: u32 = R_PPC_UADDR16;
-pub const R_PPC64_REL32: u32 = R_PPC_REL32;
-pub const R_PPC64_PLT32: u32 = R_PPC_PLT32;
-pub const R_PPC64_PLTREL32: u32 = R_PPC_PLTREL32;
-pub const R_PPC64_PLT16_LO: u32 = R_PPC_PLT16_LO;
-pub const R_PPC64_PLT16_HI: u32 = R_PPC_PLT16_HI;
-pub const R_PPC64_PLT16_HA: u32 = R_PPC_PLT16_HA;
-
-pub const R_PPC64_SECTOFF: u32 = R_PPC_SECTOFF;
-pub const R_PPC64_SECTOFF_LO: u32 = R_PPC_SECTOFF_LO;
-pub const R_PPC64_SECTOFF_HI: u32 = R_PPC_SECTOFF_HI;
-pub const R_PPC64_SECTOFF_HA: u32 = R_PPC_SECTOFF_HA;
-/// word30 (S + A - P) >> 2
-pub const R_PPC64_ADDR30: u32 = 37;
-/// doubleword64 S + A
-pub const R_PPC64_ADDR64: u32 = 38;
-/// half16 #higher(S + A)
-pub const R_PPC64_ADDR16_HIGHER: u32 = 39;
-/// half16 #highera(S + A)
-pub const R_PPC64_ADDR16_HIGHERA: u32 = 40;
-/// half16 #highest(S + A)
-pub const R_PPC64_ADDR16_HIGHEST: u32 = 41;
-/// half16 #highesta(S + A)
-pub const R_PPC64_ADDR16_HIGHESTA: u32 = 42;
-/// doubleword64 S + A
-pub const R_PPC64_UADDR64: u32 = 43;
-/// doubleword64 S + A - P
-pub const R_PPC64_REL64: u32 = 44;
-/// doubleword64 L + A
-pub const R_PPC64_PLT64: u32 = 45;
-/// doubleword64 L + A - P
-pub const R_PPC64_PLTREL64: u32 = 46;
-/// half16* S + A - .TOC
-pub const R_PPC64_TOC16: u32 = 47;
-/// half16 #lo(S + A - .TOC.)
-pub const R_PPC64_TOC16_LO: u32 = 48;
-/// half16 #hi(S + A - .TOC.)
-pub const R_PPC64_TOC16_HI: u32 = 49;
-/// half16 #ha(S + A - .TOC.)
-pub const R_PPC64_TOC16_HA: u32 = 50;
-/// doubleword64 .TOC
-pub const R_PPC64_TOC: u32 = 51;
-/// half16* M + A
-pub const R_PPC64_PLTGOT16: u32 = 52;
-/// half16 #lo(M + A)
-pub const R_PPC64_PLTGOT16_LO: u32 = 53;
-/// half16 #hi(M + A)
-pub const R_PPC64_PLTGOT16_HI: u32 = 54;
-/// half16 #ha(M + A)
-pub const R_PPC64_PLTGOT16_HA: u32 = 55;
-
-/// half16ds* (S + A) >> 2
-pub const R_PPC64_ADDR16_DS: u32 = 56;
-/// half16ds #lo(S + A) >> 2
-pub const R_PPC64_ADDR16_LO_DS: u32 = 57;
-/// half16ds* (G + A) >> 2
-pub const R_PPC64_GOT16_DS: u32 = 58;
-/// half16ds #lo(G + A) >> 2
-pub const R_PPC64_GOT16_LO_DS: u32 = 59;
-/// half16ds #lo(L + A) >> 2
-pub const R_PPC64_PLT16_LO_DS: u32 = 60;
-/// half16ds* (R + A) >> 2
-pub const R_PPC64_SECTOFF_DS: u32 = 61;
-/// half16ds #lo(R + A) >> 2
-pub const R_PPC64_SECTOFF_LO_DS: u32 = 62;
-/// half16ds* (S + A - .TOC.) >> 2
-pub const R_PPC64_TOC16_DS: u32 = 63;
-/// half16ds #lo(S + A - .TOC.) >> 2
-pub const R_PPC64_TOC16_LO_DS: u32 = 64;
-/// half16ds* (M + A) >> 2
-pub const R_PPC64_PLTGOT16_DS: u32 = 65;
-/// half16ds #lo(M + A) >> 2
-pub const R_PPC64_PLTGOT16_LO_DS: u32 = 66;
-
-// PowerPC64 values for `Rel*::r_type` defined for the TLS access ABI.
-/// none (sym+add)@tls
-pub const R_PPC64_TLS: u32 = 67;
-/// doubleword64 (sym+add)@dtpmod
-pub const R_PPC64_DTPMOD64: u32 = 68;
-/// half16* (sym+add)@tprel
-pub const R_PPC64_TPREL16: u32 = 69;
-/// half16 (sym+add)@tprel@l
-pub const R_PPC64_TPREL16_LO: u32 = 70;
-/// half16 (sym+add)@tprel@h
-pub const R_PPC64_TPREL16_HI: u32 = 71;
-/// half16 (sym+add)@tprel@ha
-pub const R_PPC64_TPREL16_HA: u32 = 72;
-/// doubleword64 (sym+add)@tprel
-pub const R_PPC64_TPREL64: u32 = 73;
-/// half16* (sym+add)@dtprel
-pub const R_PPC64_DTPREL16: u32 = 74;
-/// half16 (sym+add)@dtprel@l
-pub const R_PPC64_DTPREL16_LO: u32 = 75;
-/// half16 (sym+add)@dtprel@h
-pub const R_PPC64_DTPREL16_HI: u32 = 76;
-/// half16 (sym+add)@dtprel@ha
-pub const R_PPC64_DTPREL16_HA: u32 = 77;
-/// doubleword64 (sym+add)@dtprel
-pub const R_PPC64_DTPREL64: u32 = 78;
-/// half16* (sym+add)@got@tlsgd
-pub const R_PPC64_GOT_TLSGD16: u32 = 79;
-/// half16 (sym+add)@got@tlsgd@l
-pub const R_PPC64_GOT_TLSGD16_LO: u32 = 80;
-/// half16 (sym+add)@got@tlsgd@h
-pub const R_PPC64_GOT_TLSGD16_HI: u32 = 81;
-/// half16 (sym+add)@got@tlsgd@ha
-pub const R_PPC64_GOT_TLSGD16_HA: u32 = 82;
-/// half16* (sym+add)@got@tlsld
-pub const R_PPC64_GOT_TLSLD16: u32 = 83;
-/// half16 (sym+add)@got@tlsld@l
-pub const R_PPC64_GOT_TLSLD16_LO: u32 = 84;
-/// half16 (sym+add)@got@tlsld@h
-pub const R_PPC64_GOT_TLSLD16_HI: u32 = 85;
-/// half16 (sym+add)@got@tlsld@ha
-pub const R_PPC64_GOT_TLSLD16_HA: u32 = 86;
-/// half16ds* (sym+add)@got@tprel
-pub const R_PPC64_GOT_TPREL16_DS: u32 = 87;
-/// half16ds (sym+add)@got@tprel@l
-pub const R_PPC64_GOT_TPREL16_LO_DS: u32 = 88;
-/// half16 (sym+add)@got@tprel@h
-pub const R_PPC64_GOT_TPREL16_HI: u32 = 89;
-/// half16 (sym+add)@got@tprel@ha
-pub const R_PPC64_GOT_TPREL16_HA: u32 = 90;
-/// half16ds* (sym+add)@got@dtprel
-pub const R_PPC64_GOT_DTPREL16_DS: u32 = 91;
-/// half16ds (sym+add)@got@dtprel@l
-pub const R_PPC64_GOT_DTPREL16_LO_DS: u32 = 92;
-/// half16 (sym+add)@got@dtprel@h
-pub const R_PPC64_GOT_DTPREL16_HI: u32 = 93;
-/// half16 (sym+add)@got@dtprel@ha
-pub const R_PPC64_GOT_DTPREL16_HA: u32 = 94;
-/// half16ds* (sym+add)@tprel
-pub const R_PPC64_TPREL16_DS: u32 = 95;
-/// half16ds (sym+add)@tprel@l
-pub const R_PPC64_TPREL16_LO_DS: u32 = 96;
-/// half16 (sym+add)@tprel@higher
-pub const R_PPC64_TPREL16_HIGHER: u32 = 97;
-/// half16 (sym+add)@tprel@highera
-pub const R_PPC64_TPREL16_HIGHERA: u32 = 98;
-/// half16 (sym+add)@tprel@highest
-pub const R_PPC64_TPREL16_HIGHEST: u32 = 99;
-/// half16 (sym+add)@tprel@highesta
-pub const R_PPC64_TPREL16_HIGHESTA: u32 = 100;
-/// half16ds* (sym+add)@dtprel
-pub const R_PPC64_DTPREL16_DS: u32 = 101;
-/// half16ds (sym+add)@dtprel@l
-pub const R_PPC64_DTPREL16_LO_DS: u32 = 102;
-/// half16 (sym+add)@dtprel@higher
-pub const R_PPC64_DTPREL16_HIGHER: u32 = 103;
-/// half16 (sym+add)@dtprel@highera
-pub const R_PPC64_DTPREL16_HIGHERA: u32 = 104;
-/// half16 (sym+add)@dtprel@highest
-pub const R_PPC64_DTPREL16_HIGHEST: u32 = 105;
-/// half16 (sym+add)@dtprel@highesta
-pub const R_PPC64_DTPREL16_HIGHESTA: u32 = 106;
-/// none (sym+add)@tlsgd
-pub const R_PPC64_TLSGD: u32 = 107;
-/// none (sym+add)@tlsld
-pub const R_PPC64_TLSLD: u32 = 108;
-/// none
-pub const R_PPC64_TOCSAVE: u32 = 109;
-
-// Added when HA and HI relocs were changed to report overflows.
-pub const R_PPC64_ADDR16_HIGH: u32 = 110;
-pub const R_PPC64_ADDR16_HIGHA: u32 = 111;
-pub const R_PPC64_TPREL16_HIGH: u32 = 112;
-pub const R_PPC64_TPREL16_HIGHA: u32 = 113;
-pub const R_PPC64_DTPREL16_HIGH: u32 = 114;
-pub const R_PPC64_DTPREL16_HIGHA: u32 = 115;
-
-/// GNU extension to support local ifunc.
-pub const R_PPC64_JMP_IREL: u32 = 247;
-/// GNU extension to support local ifunc.
-pub const R_PPC64_IRELATIVE: u32 = 248;
-/// half16 (sym+add-.)
-pub const R_PPC64_REL16: u32 = 249;
-/// half16 (sym+add-.)@l
-pub const R_PPC64_REL16_LO: u32 = 250;
-/// half16 (sym+add-.)@h
-pub const R_PPC64_REL16_HI: u32 = 251;
-/// half16 (sym+add-.)@ha
-pub const R_PPC64_REL16_HA: u32 = 252;
-
-// PowerPC64 values for `FileHeader64::e_flags.
-/// PowerPC64 bits specifying ABI.
-///
-/// 1 for original function descriptor using ABI,
-/// 2 for revised ABI without function descriptors,
-/// 0 for unspecified or not using any features affected by the differences.
-pub const EF_PPC64_ABI: u32 = 3;
-
-// PowerPC64 values for `Dyn64::d_tag.
-pub const DT_PPC64_GLINK: u32 = DT_LOPROC + 0;
-pub const DT_PPC64_OPD: u32 = DT_LOPROC + 1;
-pub const DT_PPC64_OPDSZ: u32 = DT_LOPROC + 2;
-pub const DT_PPC64_OPT: u32 = DT_LOPROC + 3;
-
-// PowerPC64 bits for `DT_PPC64_OPT` entry.
-pub const PPC64_OPT_TLS: u32 = 1;
-pub const PPC64_OPT_MULTI_TOC: u32 = 2;
-pub const PPC64_OPT_LOCALENTRY: u32 = 4;
-
-// PowerPC64 values for `Sym64::st_other.
-pub const STO_PPC64_LOCAL_BIT: u8 = 5;
-pub const STO_PPC64_LOCAL_MASK: u8 = 7 << STO_PPC64_LOCAL_BIT;
-
-// ARM specific declarations.
-
-// ARM values for `FileHeader*::e_flags`.
-pub const EF_ARM_RELEXEC: u32 = 0x01;
-pub const EF_ARM_HASENTRY: u32 = 0x02;
-pub const EF_ARM_INTERWORK: u32 = 0x04;
-pub const EF_ARM_APCS_26: u32 = 0x08;
-pub const EF_ARM_APCS_FLOAT: u32 = 0x10;
-pub const EF_ARM_PIC: u32 = 0x20;
-/// 8-bit structure alignment is in use
-pub const EF_ARM_ALIGN8: u32 = 0x40;
-pub const EF_ARM_NEW_ABI: u32 = 0x80;
-pub const EF_ARM_OLD_ABI: u32 = 0x100;
-pub const EF_ARM_SOFT_FLOAT: u32 = 0x200;
-pub const EF_ARM_VFP_FLOAT: u32 = 0x400;
-pub const EF_ARM_MAVERICK_FLOAT: u32 = 0x800;
-
-/// NB conflicts with EF_ARM_SOFT_FLOAT
-pub const EF_ARM_ABI_FLOAT_SOFT: u32 = 0x200;
-/// NB conflicts with EF_ARM_VFP_FLOAT
-pub const EF_ARM_ABI_FLOAT_HARD: u32 = 0x400;
-
-// Other constants defined in the ARM ELF spec. version B-01.
-// NB. These conflict with values defined above.
-pub const EF_ARM_SYMSARESORTED: u32 = 0x04;
-pub const EF_ARM_DYNSYMSUSESEGIDX: u32 = 0x08;
-pub const EF_ARM_MAPSYMSFIRST: u32 = 0x10;
-
-// Constants defined in AAELF.
-pub const EF_ARM_BE8: u32 = 0x0080_0000;
-pub const EF_ARM_LE8: u32 = 0x0040_0000;
-
-pub const EF_ARM_EABIMASK: u32 = 0xff00_0000;
-pub const EF_ARM_EABI_UNKNOWN: u32 = 0x0000_0000;
-pub const EF_ARM_EABI_VER1: u32 = 0x0100_0000;
-pub const EF_ARM_EABI_VER2: u32 = 0x0200_0000;
-pub const EF_ARM_EABI_VER3: u32 = 0x0300_0000;
-pub const EF_ARM_EABI_VER4: u32 = 0x0400_0000;
-pub const EF_ARM_EABI_VER5: u32 = 0x0500_0000;
-
-// ARM Thumb values for `st_type` component of `Sym*::st_info`.
-/// A Thumb function.
-pub const STT_ARM_TFUNC: u8 = STT_LOPROC;
-/// A Thumb label.
-pub const STT_ARM_16BIT: u8 = STT_HIPROC;
-
-// ARM values for `SectionHeader*::sh_flags`.
-/// Section contains an entry point
-pub const SHF_ARM_ENTRYSECT: u32 = 0x1000_0000;
-/// Section may be multiply defined in the input to a link step.
-pub const SHF_ARM_COMDEF: u32 = 0x8000_0000;
-
-// ARM values for `ProgramHeader*::p_flags`.
-/// Segment contains the location addressed by the static base.
-pub const PF_ARM_SB: u32 = 0x1000_0000;
-/// Position-independent segment.
-pub const PF_ARM_PI: u32 = 0x2000_0000;
-/// Absolute segment.
-pub const PF_ARM_ABS: u32 = 0x4000_0000;
-
-// ARM values for `ProgramHeader*::p_type`.
-/// ARM unwind segment.
-pub const PT_ARM_EXIDX: u32 = PT_LOPROC + 1;
-
-// ARM values for `SectionHeader*::sh_type`.
-/// ARM unwind section.
-pub const SHT_ARM_EXIDX: u32 = SHT_LOPROC + 1;
-/// Preemption details.
-pub const SHT_ARM_PREEMPTMAP: u32 = SHT_LOPROC + 2;
-/// ARM attributes section.
-pub const SHT_ARM_ATTRIBUTES: u32 = SHT_LOPROC + 3;
-
-// AArch64 values for `Rel*::r_type`.
-
-/// No relocation.
-pub const R_AARCH64_NONE: u32 = 0;
-
-// ILP32 AArch64 relocs.
-/// Direct 32 bit.
-pub const R_AARCH64_P32_ABS32: u32 = 1;
-/// Copy symbol at runtime.
-pub const R_AARCH64_P32_COPY: u32 = 180;
-/// Create GOT entry.
-pub const R_AARCH64_P32_GLOB_DAT: u32 = 181;
-/// Create PLT entry.
-pub const R_AARCH64_P32_JUMP_SLOT: u32 = 182;
-/// Adjust by program base.
-pub const R_AARCH64_P32_RELATIVE: u32 = 183;
-/// Module number, 32 bit.
-pub const R_AARCH64_P32_TLS_DTPMOD: u32 = 184;
-/// Module-relative offset, 32 bit.
-pub const R_AARCH64_P32_TLS_DTPREL: u32 = 185;
-/// TP-relative offset, 32 bit.
-pub const R_AARCH64_P32_TLS_TPREL: u32 = 186;
-/// TLS Descriptor.
-pub const R_AARCH64_P32_TLSDESC: u32 = 187;
-/// STT_GNU_IFUNC relocation.
-pub const R_AARCH64_P32_IRELATIVE: u32 = 188;
-
-// LP64 AArch64 relocs.
-/// Direct 64 bit.
-pub const R_AARCH64_ABS64: u32 = 257;
-/// Direct 32 bit.
-pub const R_AARCH64_ABS32: u32 = 258;
-/// Direct 16-bit.
-pub const R_AARCH64_ABS16: u32 = 259;
-/// PC-relative 64-bit.
-pub const R_AARCH64_PREL64: u32 = 260;
-/// PC-relative 32-bit.
-pub const R_AARCH64_PREL32: u32 = 261;
-/// PC-relative 16-bit.
-pub const R_AARCH64_PREL16: u32 = 262;
-/// Dir. MOVZ imm. from bits 15:0.
-pub const R_AARCH64_MOVW_UABS_G0: u32 = 263;
-/// Likewise for MOVK; no check.
-pub const R_AARCH64_MOVW_UABS_G0_NC: u32 = 264;
-/// Dir. MOVZ imm. from bits 31:16.
-pub const R_AARCH64_MOVW_UABS_G1: u32 = 265;
-/// Likewise for MOVK; no check.
-pub const R_AARCH64_MOVW_UABS_G1_NC: u32 = 266;
-/// Dir. MOVZ imm. from bits 47:32.
-pub const R_AARCH64_MOVW_UABS_G2: u32 = 267;
-/// Likewise for MOVK; no check.
-pub const R_AARCH64_MOVW_UABS_G2_NC: u32 = 268;
-/// Dir. MOV{K,Z} imm. from 63:48.
-pub const R_AARCH64_MOVW_UABS_G3: u32 = 269;
-/// Dir. MOV{N,Z} imm. from 15:0.
-pub const R_AARCH64_MOVW_SABS_G0: u32 = 270;
-/// Dir. MOV{N,Z} imm. from 31:16.
-pub const R_AARCH64_MOVW_SABS_G1: u32 = 271;
-/// Dir. MOV{N,Z} imm. from 47:32.
-pub const R_AARCH64_MOVW_SABS_G2: u32 = 272;
-/// PC-rel. LD imm. from bits 20:2.
-pub const R_AARCH64_LD_PREL_LO19: u32 = 273;
-/// PC-rel. ADR imm. from bits 20:0.
-pub const R_AARCH64_ADR_PREL_LO21: u32 = 274;
-/// Page-rel. ADRP imm. from 32:12.
-pub const R_AARCH64_ADR_PREL_PG_HI21: u32 = 275;
-/// Likewise; no overflow check.
-pub const R_AARCH64_ADR_PREL_PG_HI21_NC: u32 = 276;
-/// Dir. ADD imm. from bits 11:0.
-pub const R_AARCH64_ADD_ABS_LO12_NC: u32 = 277;
-/// Likewise for LD/ST; no check.
-pub const R_AARCH64_LDST8_ABS_LO12_NC: u32 = 278;
-/// PC-rel. TBZ/TBNZ imm. from 15:2.
-pub const R_AARCH64_TSTBR14: u32 = 279;
-/// PC-rel. cond. br. imm. from 20:2.
-pub const R_AARCH64_CONDBR19: u32 = 280;
-/// PC-rel. B imm. from bits 27:2.
-pub const R_AARCH64_JUMP26: u32 = 282;
-/// Likewise for CALL.
-pub const R_AARCH64_CALL26: u32 = 283;
-/// Dir. ADD imm. from bits 11:1.
-pub const R_AARCH64_LDST16_ABS_LO12_NC: u32 = 284;
-/// Likewise for bits 11:2.
-pub const R_AARCH64_LDST32_ABS_LO12_NC: u32 = 285;
-/// Likewise for bits 11:3.
-pub const R_AARCH64_LDST64_ABS_LO12_NC: u32 = 286;
-/// PC-rel. MOV{N,Z} imm. from 15:0.
-pub const R_AARCH64_MOVW_PREL_G0: u32 = 287;
-/// Likewise for MOVK; no check.
-pub const R_AARCH64_MOVW_PREL_G0_NC: u32 = 288;
-/// PC-rel. MOV{N,Z} imm. from 31:16.
-pub const R_AARCH64_MOVW_PREL_G1: u32 = 289;
-/// Likewise for MOVK; no check.
-pub const R_AARCH64_MOVW_PREL_G1_NC: u32 = 290;
-/// PC-rel. MOV{N,Z} imm. from 47:32.
-pub const R_AARCH64_MOVW_PREL_G2: u32 = 291;
-/// Likewise for MOVK; no check.
-pub const R_AARCH64_MOVW_PREL_G2_NC: u32 = 292;
-/// PC-rel. MOV{N,Z} imm. from 63:48.
-pub const R_AARCH64_MOVW_PREL_G3: u32 = 293;
-/// Dir. ADD imm. from bits 11:4.
-pub const R_AARCH64_LDST128_ABS_LO12_NC: u32 = 299;
-/// GOT-rel. off. MOV{N,Z} imm. 15:0.
-pub const R_AARCH64_MOVW_GOTOFF_G0: u32 = 300;
-/// Likewise for MOVK; no check.
-pub const R_AARCH64_MOVW_GOTOFF_G0_NC: u32 = 301;
-/// GOT-rel. o. MOV{N,Z} imm. 31:16.
-pub const R_AARCH64_MOVW_GOTOFF_G1: u32 = 302;
-/// Likewise for MOVK; no check.
-pub const R_AARCH64_MOVW_GOTOFF_G1_NC: u32 = 303;
-/// GOT-rel. o. MOV{N,Z} imm. 47:32.
-pub const R_AARCH64_MOVW_GOTOFF_G2: u32 = 304;
-/// Likewise for MOVK; no check.
-pub const R_AARCH64_MOVW_GOTOFF_G2_NC: u32 = 305;
-/// GOT-rel. o. MOV{N,Z} imm. 63:48.
-pub const R_AARCH64_MOVW_GOTOFF_G3: u32 = 306;
-/// GOT-relative 64-bit.
-pub const R_AARCH64_GOTREL64: u32 = 307;
-/// GOT-relative 32-bit.
-pub const R_AARCH64_GOTREL32: u32 = 308;
-/// PC-rel. GOT off. load imm. 20:2.
-pub const R_AARCH64_GOT_LD_PREL19: u32 = 309;
-/// GOT-rel. off. LD/ST imm. 14:3.
-pub const R_AARCH64_LD64_GOTOFF_LO15: u32 = 310;
-/// P-page-rel. GOT off. ADRP 32:12.
-pub const R_AARCH64_ADR_GOT_PAGE: u32 = 311;
-/// Dir. GOT off. LD/ST imm. 11:3.
-pub const R_AARCH64_LD64_GOT_LO12_NC: u32 = 312;
-/// GOT-page-rel. GOT off. LD/ST 14:3
-pub const R_AARCH64_LD64_GOTPAGE_LO15: u32 = 313;
-/// PC-relative ADR imm. 20:0.
-pub const R_AARCH64_TLSGD_ADR_PREL21: u32 = 512;
-/// page-rel. ADRP imm. 32:12.
-pub const R_AARCH64_TLSGD_ADR_PAGE21: u32 = 513;
-/// direct ADD imm. from 11:0.
-pub const R_AARCH64_TLSGD_ADD_LO12_NC: u32 = 514;
-/// GOT-rel. MOV{N,Z} 31:16.
-pub const R_AARCH64_TLSGD_MOVW_G1: u32 = 515;
-/// GOT-rel. MOVK imm. 15:0.
-pub const R_AARCH64_TLSGD_MOVW_G0_NC: u32 = 516;
-/// Like 512; local dynamic model.
-pub const R_AARCH64_TLSLD_ADR_PREL21: u32 = 517;
-/// Like 513; local dynamic model.
-pub const R_AARCH64_TLSLD_ADR_PAGE21: u32 = 518;
-/// Like 514; local dynamic model.
-pub const R_AARCH64_TLSLD_ADD_LO12_NC: u32 = 519;
-/// Like 515; local dynamic model.
-pub const R_AARCH64_TLSLD_MOVW_G1: u32 = 520;
-/// Like 516; local dynamic model.
-pub const R_AARCH64_TLSLD_MOVW_G0_NC: u32 = 521;
-/// TLS PC-rel. load imm. 20:2.
-pub const R_AARCH64_TLSLD_LD_PREL19: u32 = 522;
-/// TLS DTP-rel. MOV{N,Z} 47:32.
-pub const R_AARCH64_TLSLD_MOVW_DTPREL_G2: u32 = 523;
-/// TLS DTP-rel. MOV{N,Z} 31:16.
-pub const R_AARCH64_TLSLD_MOVW_DTPREL_G1: u32 = 524;
-/// Likewise; MOVK; no check.
-pub const R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC: u32 = 525;
-/// TLS DTP-rel. MOV{N,Z} 15:0.
-pub const R_AARCH64_TLSLD_MOVW_DTPREL_G0: u32 = 526;
-/// Likewise; MOVK; no check.
-pub const R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC: u32 = 527;
-/// DTP-rel. ADD imm. from 23:12.
-pub const R_AARCH64_TLSLD_ADD_DTPREL_HI12: u32 = 528;
-/// DTP-rel. ADD imm. from 11:0.
-pub const R_AARCH64_TLSLD_ADD_DTPREL_LO12: u32 = 529;
-/// Likewise; no ovfl. check.
-pub const R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC: u32 = 530;
-/// DTP-rel. LD/ST imm. 11:0.
-pub const R_AARCH64_TLSLD_LDST8_DTPREL_LO12: u32 = 531;
-/// Likewise; no check.
-pub const R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC: u32 = 532;
-/// DTP-rel. LD/ST imm. 11:1.
-pub const R_AARCH64_TLSLD_LDST16_DTPREL_LO12: u32 = 533;
-/// Likewise; no check.
-pub const R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC: u32 = 534;
-/// DTP-rel. LD/ST imm. 11:2.
-pub const R_AARCH64_TLSLD_LDST32_DTPREL_LO12: u32 = 535;
-/// Likewise; no check.
-pub const R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC: u32 = 536;
-/// DTP-rel. LD/ST imm. 11:3.
-pub const R_AARCH64_TLSLD_LDST64_DTPREL_LO12: u32 = 537;
-/// Likewise; no check.
-pub const R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC: u32 = 538;
-/// GOT-rel. MOV{N,Z} 31:16.
-pub const R_AARCH64_TLSIE_MOVW_GOTTPREL_G1: u32 = 539;
-/// GOT-rel. MOVK 15:0.
-pub const R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: u32 = 540;
-/// Page-rel. ADRP 32:12.
-pub const R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: u32 = 541;
-/// Direct LD off. 11:3.
-pub const R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: u32 = 542;
-/// PC-rel. load imm. 20:2.
-pub const R_AARCH64_TLSIE_LD_GOTTPREL_PREL19: u32 = 543;
-/// TLS TP-rel. MOV{N,Z} 47:32.
-pub const R_AARCH64_TLSLE_MOVW_TPREL_G2: u32 = 544;
-/// TLS TP-rel. MOV{N,Z} 31:16.
-pub const R_AARCH64_TLSLE_MOVW_TPREL_G1: u32 = 545;
-/// Likewise; MOVK; no check.
-pub const R_AARCH64_TLSLE_MOVW_TPREL_G1_NC: u32 = 546;
-/// TLS TP-rel. MOV{N,Z} 15:0.
-pub const R_AARCH64_TLSLE_MOVW_TPREL_G0: u32 = 547;
-/// Likewise; MOVK; no check.
-pub const R_AARCH64_TLSLE_MOVW_TPREL_G0_NC: u32 = 548;
-/// TP-rel. ADD imm. 23:12.
-pub const R_AARCH64_TLSLE_ADD_TPREL_HI12: u32 = 549;
-/// TP-rel. ADD imm. 11:0.
-pub const R_AARCH64_TLSLE_ADD_TPREL_LO12: u32 = 550;
-/// Likewise; no ovfl. check.
-pub const R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: u32 = 551;
-/// TP-rel. LD/ST off. 11:0.
-pub const R_AARCH64_TLSLE_LDST8_TPREL_LO12: u32 = 552;
-/// Likewise; no ovfl. check.
-pub const R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: u32 = 553;
-/// TP-rel. LD/ST off. 11:1.
-pub const R_AARCH64_TLSLE_LDST16_TPREL_LO12: u32 = 554;
-/// Likewise; no check.
-pub const R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: u32 = 555;
-/// TP-rel. LD/ST off. 11:2.
-pub const R_AARCH64_TLSLE_LDST32_TPREL_LO12: u32 = 556;
-/// Likewise; no check.
-pub const R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: u32 = 557;
-/// TP-rel. LD/ST off. 11:3.
-pub const R_AARCH64_TLSLE_LDST64_TPREL_LO12: u32 = 558;
-/// Likewise; no check.
-pub const R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: u32 = 559;
-/// PC-rel. load immediate 20:2.
-pub const R_AARCH64_TLSDESC_LD_PREL19: u32 = 560;
-/// PC-rel. ADR immediate 20:0.
-pub const R_AARCH64_TLSDESC_ADR_PREL21: u32 = 561;
-/// Page-rel. ADRP imm. 32:12.
-pub const R_AARCH64_TLSDESC_ADR_PAGE21: u32 = 562;
-/// Direct LD off. from 11:3.
-pub const R_AARCH64_TLSDESC_LD64_LO12: u32 = 563;
-/// Direct ADD imm. from 11:0.
-pub const R_AARCH64_TLSDESC_ADD_LO12: u32 = 564;
-/// GOT-rel. MOV{N,Z} imm. 31:16.
-pub const R_AARCH64_TLSDESC_OFF_G1: u32 = 565;
-/// GOT-rel. MOVK imm. 15:0; no ck.
-pub const R_AARCH64_TLSDESC_OFF_G0_NC: u32 = 566;
-/// Relax LDR.
-pub const R_AARCH64_TLSDESC_LDR: u32 = 567;
-/// Relax ADD.
-pub const R_AARCH64_TLSDESC_ADD: u32 = 568;
-/// Relax BLR.
-pub const R_AARCH64_TLSDESC_CALL: u32 = 569;
-/// TP-rel. LD/ST off. 11:4.
-pub const R_AARCH64_TLSLE_LDST128_TPREL_LO12: u32 = 570;
-/// Likewise; no check.
-pub const R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC: u32 = 571;
-/// DTP-rel. LD/ST imm. 11:4.
-pub const R_AARCH64_TLSLD_LDST128_DTPREL_LO12: u32 = 572;
-/// Likewise; no check.
-pub const R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC: u32 = 573;
-/// Copy symbol at runtime.
-pub const R_AARCH64_COPY: u32 = 1024;
-/// Create GOT entry.
-pub const R_AARCH64_GLOB_DAT: u32 = 1025;
-/// Create PLT entry.
-pub const R_AARCH64_JUMP_SLOT: u32 = 1026;
-/// Adjust by program base.
-pub const R_AARCH64_RELATIVE: u32 = 1027;
-/// Module number, 64 bit.
-pub const R_AARCH64_TLS_DTPMOD: u32 = 1028;
-/// Module-relative offset, 64 bit.
-pub const R_AARCH64_TLS_DTPREL: u32 = 1029;
-/// TP-relative offset, 64 bit.
-pub const R_AARCH64_TLS_TPREL: u32 = 1030;
-/// TLS Descriptor.
-pub const R_AARCH64_TLSDESC: u32 = 1031;
-/// STT_GNU_IFUNC relocation.
-pub const R_AARCH64_IRELATIVE: u32 = 1032;
-
-// AVR values for `FileHeader*::e_flags`.
-
-/// Bitmask for `EF_AVR_ARCH_*`.
-pub const EF_AVR_ARCH: u32 = 0x7F;
-
-/// If set, it is assumed that the elf file uses local symbols as reference
-/// for the relocations so that linker relaxation is possible.
-pub const EF_AVR_LINKRELAX_PREPARED: u32 = 0x80;
-
-pub const EF_AVR_ARCH_AVR1: u32 = 1;
-pub const EF_AVR_ARCH_AVR2: u32 = 2;
-pub const EF_AVR_ARCH_AVR25: u32 = 25;
-pub const EF_AVR_ARCH_AVR3: u32 = 3;
-pub const EF_AVR_ARCH_AVR31: u32 = 31;
-pub const EF_AVR_ARCH_AVR35: u32 = 35;
-pub const EF_AVR_ARCH_AVR4: u32 = 4;
-pub const EF_AVR_ARCH_AVR5: u32 = 5;
-pub const EF_AVR_ARCH_AVR51: u32 = 51;
-pub const EF_AVR_ARCH_AVR6: u32 = 6;
-pub const EF_AVR_ARCH_AVRTINY: u32 = 100;
-pub const EF_AVR_ARCH_XMEGA1: u32 = 101;
-pub const EF_AVR_ARCH_XMEGA2: u32 = 102;
-pub const EF_AVR_ARCH_XMEGA3: u32 = 103;
-pub const EF_AVR_ARCH_XMEGA4: u32 = 104;
-pub const EF_AVR_ARCH_XMEGA5: u32 = 105;
-pub const EF_AVR_ARCH_XMEGA6: u32 = 106;
-pub const EF_AVR_ARCH_XMEGA7: u32 = 107;
-
-// AVR values for `Rel*::r_type`.
-
-pub const R_AVR_NONE: u32 = 0;
-/// Direct 32 bit
-pub const R_AVR_32: u32 = 1;
-pub const R_AVR_7_PCREL: u32 = 2;
-pub const R_AVR_13_PCREL: u32 = 3;
-/// Direct 16 bit
-pub const R_AVR_16: u32 = 4;
-pub const R_AVR_16_PM: u32 = 5;
-pub const R_AVR_LO8_LDI: u32 = 6;
-pub const R_AVR_HI8_LDI: u32 = 7;
-pub const R_AVR_HH8_LDI: u32 = 8;
-pub const R_AVR_LO8_LDI_NEG: u32 = 9;
-pub const R_AVR_HI8_LDI_NEG: u32 = 10;
-pub const R_AVR_HH8_LDI_NEG: u32 = 11;
-pub const R_AVR_LO8_LDI_PM: u32 = 12;
-pub const R_AVR_HI8_LDI_PM: u32 = 13;
-pub const R_AVR_HH8_LDI_PM: u32 = 14;
-pub const R_AVR_LO8_LDI_PM_NEG: u32 = 15;
-pub const R_AVR_HI8_LDI_PM_NEG: u32 = 16;
-pub const R_AVR_HH8_LDI_PM_NEG: u32 = 17;
-pub const R_AVR_CALL: u32 = 18;
-pub const R_AVR_LDI: u32 = 19;
-pub const R_AVR_6: u32 = 20;
-pub const R_AVR_6_ADIW: u32 = 21;
-pub const R_AVR_MS8_LDI: u32 = 22;
-pub const R_AVR_MS8_LDI_NEG: u32 = 23;
-pub const R_AVR_LO8_LDI_GS: u32 = 24;
-pub const R_AVR_HI8_LDI_GS: u32 = 25;
-pub const R_AVR_8: u32 = 26;
-pub const R_AVR_8_LO8: u32 = 27;
-pub const R_AVR_8_HI8: u32 = 28;
-pub const R_AVR_8_HLO8: u32 = 29;
-pub const R_AVR_DIFF8: u32 = 30;
-pub const R_AVR_DIFF16: u32 = 31;
-pub const R_AVR_DIFF32: u32 = 32;
-pub const R_AVR_LDS_STS_16: u32 = 33;
-pub const R_AVR_PORT6: u32 = 34;
-pub const R_AVR_PORT5: u32 = 35;
-pub const R_AVR_32_PCREL: u32 = 36;
-
-// MSP430 values for `Rel*::r_type`.
-
-/// Direct 32 bit
-pub const R_MSP430_32: u32 = 1;
-/// Direct 16 bit
-pub const R_MSP430_16_BYTE: u32 = 5;
-
-// Hexagon values for `Rel*::r_type`.
-
-/// Direct 32 bit
-pub const R_HEX_32: u32 = 6;
-
-// ARM values for `Rel*::r_type`.
-
-/// No reloc
-pub const R_ARM_NONE: u32 = 0;
-/// Deprecated PC relative 26 bit branch.
-pub const R_ARM_PC24: u32 = 1;
-/// Direct 32 bit
-pub const R_ARM_ABS32: u32 = 2;
-/// PC relative 32 bit
-pub const R_ARM_REL32: u32 = 3;
-pub const R_ARM_PC13: u32 = 4;
-/// Direct 16 bit
-pub const R_ARM_ABS16: u32 = 5;
-/// Direct 12 bit
-pub const R_ARM_ABS12: u32 = 6;
-/// Direct & 0x7C (`LDR`, `STR`).
-pub const R_ARM_THM_ABS5: u32 = 7;
-/// Direct 8 bit
-pub const R_ARM_ABS8: u32 = 8;
-pub const R_ARM_SBREL32: u32 = 9;
-/// PC relative 24 bit (Thumb32 `BL`).
-pub const R_ARM_THM_PC22: u32 = 10;
-/// PC relative & 0x3FC (Thumb16 `LDR`, `ADD`, `ADR`).
-pub const R_ARM_THM_PC8: u32 = 11;
-pub const R_ARM_AMP_VCALL9: u32 = 12;
-/// Obsolete static relocation.
-pub const R_ARM_SWI24: u32 = 13;
-/// Dynamic relocation.
-pub const R_ARM_TLS_DESC: u32 = 13;
-/// Reserved.
-pub const R_ARM_THM_SWI8: u32 = 14;
-/// Reserved.
-pub const R_ARM_XPC25: u32 = 15;
-/// Reserved.
-pub const R_ARM_THM_XPC22: u32 = 16;
-/// ID of module containing symbol
-pub const R_ARM_TLS_DTPMOD32: u32 = 17;
-/// Offset in TLS block
-pub const R_ARM_TLS_DTPOFF32: u32 = 18;
-/// Offset in static TLS block
-pub const R_ARM_TLS_TPOFF32: u32 = 19;
-/// Copy symbol at runtime
-pub const R_ARM_COPY: u32 = 20;
-/// Create GOT entry
-pub const R_ARM_GLOB_DAT: u32 = 21;
-/// Create PLT entry
-pub const R_ARM_JUMP_SLOT: u32 = 22;
-/// Adjust by program base
-pub const R_ARM_RELATIVE: u32 = 23;
-/// 32 bit offset to GOT
-pub const R_ARM_GOTOFF: u32 = 24;
-/// 32 bit PC relative offset to GOT
-pub const R_ARM_GOTPC: u32 = 25;
-/// 32 bit GOT entry
-pub const R_ARM_GOT32: u32 = 26;
-/// Deprecated, 32 bit PLT address.
-pub const R_ARM_PLT32: u32 = 27;
-/// PC relative 24 bit (`BL`, `BLX`).
-pub const R_ARM_CALL: u32 = 28;
-/// PC relative 24 bit (`B`, `BL<cond>`).
-pub const R_ARM_JUMP24: u32 = 29;
-/// PC relative 24 bit (Thumb32 `B.W`).
-pub const R_ARM_THM_JUMP24: u32 = 30;
-/// Adjust by program base.
-pub const R_ARM_BASE_ABS: u32 = 31;
-/// Obsolete.
-pub const R_ARM_ALU_PCREL_7_0: u32 = 32;
-/// Obsolete.
-pub const R_ARM_ALU_PCREL_15_8: u32 = 33;
-/// Obsolete.
-pub const R_ARM_ALU_PCREL_23_15: u32 = 34;
-/// Deprecated, prog. base relative.
-pub const R_ARM_LDR_SBREL_11_0: u32 = 35;
-/// Deprecated, prog. base relative.
-pub const R_ARM_ALU_SBREL_19_12: u32 = 36;
-/// Deprecated, prog. base relative.
-pub const R_ARM_ALU_SBREL_27_20: u32 = 37;
-pub const R_ARM_TARGET1: u32 = 38;
-/// Program base relative.
-pub const R_ARM_SBREL31: u32 = 39;
-pub const R_ARM_V4BX: u32 = 40;
-pub const R_ARM_TARGET2: u32 = 41;
-/// 32 bit PC relative.
-pub const R_ARM_PREL31: u32 = 42;
-/// Direct 16-bit (`MOVW`).
-pub const R_ARM_MOVW_ABS_NC: u32 = 43;
-/// Direct high 16-bit (`MOVT`).
-pub const R_ARM_MOVT_ABS: u32 = 44;
-/// PC relative 16-bit (`MOVW`).
-pub const R_ARM_MOVW_PREL_NC: u32 = 45;
-/// PC relative (MOVT).
-pub const R_ARM_MOVT_PREL: u32 = 46;
-/// Direct 16 bit (Thumb32 `MOVW`).
-pub const R_ARM_THM_MOVW_ABS_NC: u32 = 47;
-/// Direct high 16 bit (Thumb32 `MOVT`).
-pub const R_ARM_THM_MOVT_ABS: u32 = 48;
-/// PC relative 16 bit (Thumb32 `MOVW`).
-pub const R_ARM_THM_MOVW_PREL_NC: u32 = 49;
-/// PC relative high 16 bit (Thumb32 `MOVT`).
-pub const R_ARM_THM_MOVT_PREL: u32 = 50;
-/// PC relative 20 bit (Thumb32 `B<cond>.W`).
-pub const R_ARM_THM_JUMP19: u32 = 51;
-/// PC relative X & 0x7E (Thumb16 `CBZ`, `CBNZ`).
-pub const R_ARM_THM_JUMP6: u32 = 52;
-/// PC relative 12 bit (Thumb32 `ADR.W`).
-pub const R_ARM_THM_ALU_PREL_11_0: u32 = 53;
-/// PC relative 12 bit (Thumb32 `LDR{D,SB,H,SH}`).
-pub const R_ARM_THM_PC12: u32 = 54;
-/// Direct 32-bit.
-pub const R_ARM_ABS32_NOI: u32 = 55;
-/// PC relative 32-bit.
-pub const R_ARM_REL32_NOI: u32 = 56;
-/// PC relative (`ADD`, `SUB`).
-pub const R_ARM_ALU_PC_G0_NC: u32 = 57;
-/// PC relative (`ADD`, `SUB`).
-pub const R_ARM_ALU_PC_G0: u32 = 58;
-/// PC relative (`ADD`, `SUB`).
-pub const R_ARM_ALU_PC_G1_NC: u32 = 59;
-/// PC relative (`ADD`, `SUB`).
-pub const R_ARM_ALU_PC_G1: u32 = 60;
-/// PC relative (`ADD`, `SUB`).
-pub const R_ARM_ALU_PC_G2: u32 = 61;
-/// PC relative (`LDR`,`STR`,`LDRB`,`STRB`).
-pub const R_ARM_LDR_PC_G1: u32 = 62;
-/// PC relative (`LDR`,`STR`,`LDRB`,`STRB`).
-pub const R_ARM_LDR_PC_G2: u32 = 63;
-/// PC relative (`STR{D,H}`, `LDR{D,SB,H,SH}`).
-pub const R_ARM_LDRS_PC_G0: u32 = 64;
-/// PC relative (`STR{D,H}`, `LDR{D,SB,H,SH}`).
-pub const R_ARM_LDRS_PC_G1: u32 = 65;
-/// PC relative (`STR{D,H}`, `LDR{D,SB,H,SH}`).
-pub const R_ARM_LDRS_PC_G2: u32 = 66;
-/// PC relative (`LDC`, `STC`).
-pub const R_ARM_LDC_PC_G0: u32 = 67;
-/// PC relative (`LDC`, `STC`).
-pub const R_ARM_LDC_PC_G1: u32 = 68;
-/// PC relative (`LDC`, `STC`).
-pub const R_ARM_LDC_PC_G2: u32 = 69;
-/// Program base relative (`ADD`,`SUB`).
-pub const R_ARM_ALU_SB_G0_NC: u32 = 70;
-/// Program base relative (`ADD`,`SUB`).
-pub const R_ARM_ALU_SB_G0: u32 = 71;
-/// Program base relative (`ADD`,`SUB`).
-pub const R_ARM_ALU_SB_G1_NC: u32 = 72;
-/// Program base relative (`ADD`,`SUB`).
-pub const R_ARM_ALU_SB_G1: u32 = 73;
-/// Program base relative (`ADD`,`SUB`).
-pub const R_ARM_ALU_SB_G2: u32 = 74;
-/// Program base relative (`LDR`, `STR`, `LDRB`, `STRB`).
-pub const R_ARM_LDR_SB_G0: u32 = 75;
-/// Program base relative (`LDR`, `STR`, `LDRB`, `STRB`).
-pub const R_ARM_LDR_SB_G1: u32 = 76;
-/// Program base relative (`LDR`, `STR`, `LDRB`, `STRB`).
-pub const R_ARM_LDR_SB_G2: u32 = 77;
-/// Program base relative (`LDR`, `STR`, `LDRB`, `STRB`).
-pub const R_ARM_LDRS_SB_G0: u32 = 78;
-/// Program base relative (`LDR`, `STR`, `LDRB`, `STRB`).
-pub const R_ARM_LDRS_SB_G1: u32 = 79;
-/// Program base relative (`LDR`, `STR`, `LDRB`, `STRB`).
-pub const R_ARM_LDRS_SB_G2: u32 = 80;
-/// Program base relative (`LDC`,`STC`).
-pub const R_ARM_LDC_SB_G0: u32 = 81;
-/// Program base relative (`LDC`,`STC`).
-pub const R_ARM_LDC_SB_G1: u32 = 82;
-/// Program base relative (`LDC`,`STC`).
-pub const R_ARM_LDC_SB_G2: u32 = 83;
-/// Program base relative 16 bit (`MOVW`).
-pub const R_ARM_MOVW_BREL_NC: u32 = 84;
-/// Program base relative high 16 bit (`MOVT`).
-pub const R_ARM_MOVT_BREL: u32 = 85;
-/// Program base relative 16 bit (`MOVW`).
-pub const R_ARM_MOVW_BREL: u32 = 86;
-/// Program base relative 16 bit (Thumb32 `MOVW`).
-pub const R_ARM_THM_MOVW_BREL_NC: u32 = 87;
-/// Program base relative high 16 bit (Thumb32 `MOVT`).
-pub const R_ARM_THM_MOVT_BREL: u32 = 88;
-/// Program base relative 16 bit (Thumb32 `MOVW`).
-pub const R_ARM_THM_MOVW_BREL: u32 = 89;
-pub const R_ARM_TLS_GOTDESC: u32 = 90;
-pub const R_ARM_TLS_CALL: u32 = 91;
-/// TLS relaxation.
-pub const R_ARM_TLS_DESCSEQ: u32 = 92;
-pub const R_ARM_THM_TLS_CALL: u32 = 93;
-pub const R_ARM_PLT32_ABS: u32 = 94;
-/// GOT entry.
-pub const R_ARM_GOT_ABS: u32 = 95;
-/// PC relative GOT entry.
-pub const R_ARM_GOT_PREL: u32 = 96;
-/// GOT entry relative to GOT origin (`LDR`).
-pub const R_ARM_GOT_BREL12: u32 = 97;
-/// 12 bit, GOT entry relative to GOT origin (`LDR`, `STR`).
-pub const R_ARM_GOTOFF12: u32 = 98;
-pub const R_ARM_GOTRELAX: u32 = 99;
-pub const R_ARM_GNU_VTENTRY: u32 = 100;
-pub const R_ARM_GNU_VTINHERIT: u32 = 101;
-/// PC relative & 0xFFE (Thumb16 `B`).
-pub const R_ARM_THM_PC11: u32 = 102;
-/// PC relative & 0x1FE (Thumb16 `B`/`B<cond>`).
-pub const R_ARM_THM_PC9: u32 = 103;
-/// PC-rel 32 bit for global dynamic thread local data
-pub const R_ARM_TLS_GD32: u32 = 104;
-/// PC-rel 32 bit for local dynamic thread local data
-pub const R_ARM_TLS_LDM32: u32 = 105;
-/// 32 bit offset relative to TLS block
-pub const R_ARM_TLS_LDO32: u32 = 106;
-/// PC-rel 32 bit for GOT entry of static TLS block offset
-pub const R_ARM_TLS_IE32: u32 = 107;
-/// 32 bit offset relative to static TLS block
-pub const R_ARM_TLS_LE32: u32 = 108;
-/// 12 bit relative to TLS block (`LDR`, `STR`).
-pub const R_ARM_TLS_LDO12: u32 = 109;
-/// 12 bit relative to static TLS block (`LDR`, `STR`).
-pub const R_ARM_TLS_LE12: u32 = 110;
-/// 12 bit GOT entry relative to GOT origin (`LDR`).
-pub const R_ARM_TLS_IE12GP: u32 = 111;
-/// Obsolete.
-pub const R_ARM_ME_TOO: u32 = 128;
-pub const R_ARM_THM_TLS_DESCSEQ: u32 = 129;
-pub const R_ARM_THM_TLS_DESCSEQ16: u32 = 129;
-pub const R_ARM_THM_TLS_DESCSEQ32: u32 = 130;
-/// GOT entry relative to GOT origin, 12 bit (Thumb32 `LDR`).
-pub const R_ARM_THM_GOT_BREL12: u32 = 131;
-pub const R_ARM_IRELATIVE: u32 = 160;
-pub const R_ARM_RXPC25: u32 = 249;
-pub const R_ARM_RSBREL32: u32 = 250;
-pub const R_ARM_THM_RPC22: u32 = 251;
-pub const R_ARM_RREL32: u32 = 252;
-pub const R_ARM_RABS22: u32 = 253;
-pub const R_ARM_RPC24: u32 = 254;
-pub const R_ARM_RBASE: u32 = 255;
-
-// C-SKY values for `Rel*::r_type`.
-/// no reloc
-pub const R_CKCORE_NONE: u32 = 0;
-/// direct 32 bit (S + A)
-pub const R_CKCORE_ADDR32: u32 = 1;
-/// disp ((S + A - P) >> 2) & 0xff
-pub const R_CKCORE_PCRELIMM8BY4: u32 = 2;
-/// disp ((S + A - P) >> 1) & 0x7ff
-pub const R_CKCORE_PCRELIMM11BY2: u32 = 3;
-/// 32-bit rel (S + A - P)
-pub const R_CKCORE_PCREL32: u32 = 5;
-/// disp ((S + A - P) >>1) & 0x7ff
-pub const R_CKCORE_PCRELJSR_IMM11BY2: u32 = 6;
-/// 32 bit adjust program base(B + A)
-pub const R_CKCORE_RELATIVE: u32 = 9;
-/// 32 bit adjust by program base
-pub const R_CKCORE_COPY: u32 = 10;
-/// off between got and sym (S)
-pub const R_CKCORE_GLOB_DAT: u32 = 11;
-/// PLT entry (S)
-pub const R_CKCORE_JUMP_SLOT: u32 = 12;
-/// offset to GOT (S + A - GOT)
-pub const R_CKCORE_GOTOFF: u32 = 13;
-/// PC offset to GOT (GOT + A - P)
-pub const R_CKCORE_GOTPC: u32 = 14;
-/// 32 bit GOT entry (G)
-pub const R_CKCORE_GOT32: u32 = 15;
-/// 32 bit PLT entry (G)
-pub const R_CKCORE_PLT32: u32 = 16;
-/// GOT entry in GLOB_DAT (GOT + G)
-pub const R_CKCORE_ADDRGOT: u32 = 17;
-/// PLT entry in GLOB_DAT (GOT + G)
-pub const R_CKCORE_ADDRPLT: u32 = 18;
-/// ((S + A - P) >> 1) & 0x3ff_ffff
-pub const R_CKCORE_PCREL_IMM26BY2: u32 = 19;
-/// disp ((S + A - P) >> 1) & 0xffff
-pub const R_CKCORE_PCREL_IMM16BY2: u32 = 20;
-/// disp ((S + A - P) >> 2) & 0xffff
-pub const R_CKCORE_PCREL_IMM16BY4: u32 = 21;
-/// disp ((S + A - P) >> 1) & 0x3ff
-pub const R_CKCORE_PCREL_IMM10BY2: u32 = 22;
-/// disp ((S + A - P) >> 2) & 0x3ff
-pub const R_CKCORE_PCREL_IMM10BY4: u32 = 23;
-/// high & low 16 bit ADDR, ((S + A) >> 16) & 0xffff
-pub const R_CKCORE_ADDR_HI16: u32 = 24;
-/// (S + A) & 0xffff
-pub const R_CKCORE_ADDR_LO16: u32 = 25;
-/// high & low 16 bit GOTPC, ((GOT + A - P) >> 16) & 0xffff
-pub const R_CKCORE_GOTPC_HI16: u32 = 26;
-/// (GOT + A - P) & 0xffff
-pub const R_CKCORE_GOTPC_LO16: u32 = 27;
-/// high & low 16 bit GOTOFF, ((S + A - GOT) >> 16) & 0xffff
-pub const R_CKCORE_GOTOFF_HI16: u32 = 28;
-/// (S + A - GOT) & 0xffff
-pub const R_CKCORE_GOTOFF_LO16: u32 = 29;
-/// 12 bit disp GOT entry (G)
-pub const R_CKCORE_GOT12: u32 = 30;
-/// high & low 16 bit GOT, (G >> 16) & 0xffff
-pub const R_CKCORE_GOT_HI16: u32 = 31;
-/// (G & 0xffff)
-pub const R_CKCORE_GOT_LO16: u32 = 32;
-/// 12 bit disp PLT entry (G)
-pub const R_CKCORE_PLT12: u32 = 33;
-/// high & low 16 bit PLT, (G >> 16) & 0xffff
-pub const R_CKCORE_PLT_HI16: u32 = 34;
-/// G & 0xffff
-pub const R_CKCORE_PLT_LO16: u32 = 35;
-/// high & low 16 bit ADDRGOT, (GOT + G * 4) & 0xffff
-pub const R_CKCORE_ADDRGOT_HI16: u32 = 36;
-/// (GOT + G * 4) & 0xffff
-pub const R_CKCORE_ADDRGOT_LO16: u32 = 37;
-/// high & low 16 bit ADDRPLT, ((GOT + G * 4) >> 16) & 0xFFFF
-pub const R_CKCORE_ADDRPLT_HI16: u32 = 38;
-/// (GOT+G*4) & 0xffff
-pub const R_CKCORE_ADDRPLT_LO16: u32 = 39;
-/// disp ((S+A-P) >>1) & x3ff_ffff
-pub const R_CKCORE_PCREL_JSR_IMM26BY2: u32 = 40;
-/// (S+A-BTEXT) & 0xffff
-pub const R_CKCORE_TOFFSET_LO16: u32 = 41;
-/// (S+A-BTEXT) & 0xffff
-pub const R_CKCORE_DOFFSET_LO16: u32 = 42;
-/// disp ((S+A-P) >>1) & 0x3ffff
-pub const R_CKCORE_PCREL_IMM18BY2: u32 = 43;
-/// disp (S+A-BDATA) & 0x3ffff
-pub const R_CKCORE_DOFFSET_IMM18: u32 = 44;
-/// disp ((S+A-BDATA)>>1) & 0x3ffff
-pub const R_CKCORE_DOFFSET_IMM18BY2: u32 = 45;
-/// disp ((S+A-BDATA)>>2) & 0x3ffff
-pub const R_CKCORE_DOFFSET_IMM18BY4: u32 = 46;
-/// disp (G >> 2)
-pub const R_CKCORE_GOT_IMM18BY4: u32 = 48;
-/// disp (G >> 2)
-pub const R_CKCORE_PLT_IMM18BY4: u32 = 49;
-/// disp ((S+A-P) >>2) & 0x7f
-pub const R_CKCORE_PCREL_IMM7BY4: u32 = 50;
-/// 32 bit offset to TLS block
-pub const R_CKCORE_TLS_LE32: u32 = 51;
-pub const R_CKCORE_TLS_IE32: u32 = 52;
-pub const R_CKCORE_TLS_GD32: u32 = 53;
-pub const R_CKCORE_TLS_LDM32: u32 = 54;
-pub const R_CKCORE_TLS_LDO32: u32 = 55;
-pub const R_CKCORE_TLS_DTPMOD32: u32 = 56;
-pub const R_CKCORE_TLS_DTPOFF32: u32 = 57;
-pub const R_CKCORE_TLS_TPOFF32: u32 = 58;
-
-// C-SKY values for `FileHeader*::e_flags`.
-pub const EF_CSKY_ABIMASK: u32 = 0xF000_0000;
-pub const EF_CSKY_OTHER: u32 = 0x0FFF_0000;
-pub const EF_CSKY_PROCESSOR: u32 = 0x0000_FFFF;
-
-pub const EF_CSKY_ABIV1: u32 = 0x1000_0000;
-pub const EF_CSKY_ABIV2: u32 = 0x2000_0000;
-
-// C-SKY values for `SectionHeader*::sh_type`.
-/// C-SKY attributes section.
-pub const SHT_CSKY_ATTRIBUTES: u32 = SHT_LOPROC + 1;
-
-// IA-64 specific declarations.
-
-// IA-64 values for `FileHeader64::e_flags`.
-/// os-specific flags
-pub const EF_IA_64_MASKOS: u32 = 0x0000_000f;
-/// 64-bit ABI
-pub const EF_IA_64_ABI64: u32 = 0x0000_0010;
-/// arch. version mask
-pub const EF_IA_64_ARCH: u32 = 0xff00_0000;
-
-// IA-64 values for `ProgramHeader64::p_type`.
-/// arch extension bits
-pub const PT_IA_64_ARCHEXT: u32 = PT_LOPROC + 0;
-/// ia64 unwind bits
-pub const PT_IA_64_UNWIND: u32 = PT_LOPROC + 1;
-pub const PT_IA_64_HP_OPT_ANOT: u32 = PT_LOOS + 0x12;
-pub const PT_IA_64_HP_HSL_ANOT: u32 = PT_LOOS + 0x13;
-pub const PT_IA_64_HP_STACK: u32 = PT_LOOS + 0x14;
-
-// IA-64 values for `ProgramHeader64::p_flags`.
-/// spec insns w/o recovery
-pub const PF_IA_64_NORECOV: u32 = 0x8000_0000;
-
-// IA-64 values for `SectionHeader64::sh_type`.
-/// extension bits
-pub const SHT_IA_64_EXT: u32 = SHT_LOPROC + 0;
-/// unwind bits
-pub const SHT_IA_64_UNWIND: u32 = SHT_LOPROC + 1;
-
-// IA-64 values for `SectionHeader64::sh_flags`.
-/// section near gp
-pub const SHF_IA_64_SHORT: u32 = 0x1000_0000;
-/// spec insns w/o recovery
-pub const SHF_IA_64_NORECOV: u32 = 0x2000_0000;
-
-// IA-64 values for `Dyn64::d_tag`.
-pub const DT_IA_64_PLT_RESERVE: u32 = DT_LOPROC + 0;
-
-// IA-64 values for `Rel*::r_type`.
-/// none
-pub const R_IA64_NONE: u32 = 0x00;
-/// symbol + addend, add imm14
-pub const R_IA64_IMM14: u32 = 0x21;
-/// symbol + addend, add imm22
-pub const R_IA64_IMM22: u32 = 0x22;
-/// symbol + addend, mov imm64
-pub const R_IA64_IMM64: u32 = 0x23;
-/// symbol + addend, data4 MSB
-pub const R_IA64_DIR32MSB: u32 = 0x24;
-/// symbol + addend, data4 LSB
-pub const R_IA64_DIR32LSB: u32 = 0x25;
-/// symbol + addend, data8 MSB
-pub const R_IA64_DIR64MSB: u32 = 0x26;
-/// symbol + addend, data8 LSB
-pub const R_IA64_DIR64LSB: u32 = 0x27;
-/// @gprel(sym + add), add imm22
-pub const R_IA64_GPREL22: u32 = 0x2a;
-/// @gprel(sym + add), mov imm64
-pub const R_IA64_GPREL64I: u32 = 0x2b;
-/// @gprel(sym + add), data4 MSB
-pub const R_IA64_GPREL32MSB: u32 = 0x2c;
-/// @gprel(sym + add), data4 LSB
-pub const R_IA64_GPREL32LSB: u32 = 0x2d;
-/// @gprel(sym + add), data8 MSB
-pub const R_IA64_GPREL64MSB: u32 = 0x2e;
-/// @gprel(sym + add), data8 LSB
-pub const R_IA64_GPREL64LSB: u32 = 0x2f;
-/// @ltoff(sym + add), add imm22
-pub const R_IA64_LTOFF22: u32 = 0x32;
-/// @ltoff(sym + add), mov imm64
-pub const R_IA64_LTOFF64I: u32 = 0x33;
-/// @pltoff(sym + add), add imm22
-pub const R_IA64_PLTOFF22: u32 = 0x3a;
-/// @pltoff(sym + add), mov imm64
-pub const R_IA64_PLTOFF64I: u32 = 0x3b;
-/// @pltoff(sym + add), data8 MSB
-pub const R_IA64_PLTOFF64MSB: u32 = 0x3e;
-/// @pltoff(sym + add), data8 LSB
-pub const R_IA64_PLTOFF64LSB: u32 = 0x3f;
-/// @fptr(sym + add), mov imm64
-pub const R_IA64_FPTR64I: u32 = 0x43;
-/// @fptr(sym + add), data4 MSB
-pub const R_IA64_FPTR32MSB: u32 = 0x44;
-/// @fptr(sym + add), data4 LSB
-pub const R_IA64_FPTR32LSB: u32 = 0x45;
-/// @fptr(sym + add), data8 MSB
-pub const R_IA64_FPTR64MSB: u32 = 0x46;
-/// @fptr(sym + add), data8 LSB
-pub const R_IA64_FPTR64LSB: u32 = 0x47;
-/// @pcrel(sym + add), brl
-pub const R_IA64_PCREL60B: u32 = 0x48;
-/// @pcrel(sym + add), ptb, call
-pub const R_IA64_PCREL21B: u32 = 0x49;
-/// @pcrel(sym + add), chk.s
-pub const R_IA64_PCREL21M: u32 = 0x4a;
-/// @pcrel(sym + add), fchkf
-pub const R_IA64_PCREL21F: u32 = 0x4b;
-/// @pcrel(sym + add), data4 MSB
-pub const R_IA64_PCREL32MSB: u32 = 0x4c;
-/// @pcrel(sym + add), data4 LSB
-pub const R_IA64_PCREL32LSB: u32 = 0x4d;
-/// @pcrel(sym + add), data8 MSB
-pub const R_IA64_PCREL64MSB: u32 = 0x4e;
-/// @pcrel(sym + add), data8 LSB
-pub const R_IA64_PCREL64LSB: u32 = 0x4f;
-/// @ltoff(@fptr(s+a)), imm22
-pub const R_IA64_LTOFF_FPTR22: u32 = 0x52;
-/// @ltoff(@fptr(s+a)), imm64
-pub const R_IA64_LTOFF_FPTR64I: u32 = 0x53;
-/// @ltoff(@fptr(s+a)), data4 MSB
-pub const R_IA64_LTOFF_FPTR32MSB: u32 = 0x54;
-/// @ltoff(@fptr(s+a)), data4 LSB
-pub const R_IA64_LTOFF_FPTR32LSB: u32 = 0x55;
-/// @ltoff(@fptr(s+a)), data8 MSB
-pub const R_IA64_LTOFF_FPTR64MSB: u32 = 0x56;
-/// @ltoff(@fptr(s+a)), data8 LSB
-pub const R_IA64_LTOFF_FPTR64LSB: u32 = 0x57;
-/// @segrel(sym + add), data4 MSB
-pub const R_IA64_SEGREL32MSB: u32 = 0x5c;
-/// @segrel(sym + add), data4 LSB
-pub const R_IA64_SEGREL32LSB: u32 = 0x5d;
-/// @segrel(sym + add), data8 MSB
-pub const R_IA64_SEGREL64MSB: u32 = 0x5e;
-/// @segrel(sym + add), data8 LSB
-pub const R_IA64_SEGREL64LSB: u32 = 0x5f;
-/// @secrel(sym + add), data4 MSB
-pub const R_IA64_SECREL32MSB: u32 = 0x64;
-/// @secrel(sym + add), data4 LSB
-pub const R_IA64_SECREL32LSB: u32 = 0x65;
-/// @secrel(sym + add), data8 MSB
-pub const R_IA64_SECREL64MSB: u32 = 0x66;
-/// @secrel(sym + add), data8 LSB
-pub const R_IA64_SECREL64LSB: u32 = 0x67;
-/// data 4 + REL
-pub const R_IA64_REL32MSB: u32 = 0x6c;
-/// data 4 + REL
-pub const R_IA64_REL32LSB: u32 = 0x6d;
-/// data 8 + REL
-pub const R_IA64_REL64MSB: u32 = 0x6e;
-/// data 8 + REL
-pub const R_IA64_REL64LSB: u32 = 0x6f;
-/// symbol + addend, data4 MSB
-pub const R_IA64_LTV32MSB: u32 = 0x74;
-/// symbol + addend, data4 LSB
-pub const R_IA64_LTV32LSB: u32 = 0x75;
-/// symbol + addend, data8 MSB
-pub const R_IA64_LTV64MSB: u32 = 0x76;
-/// symbol + addend, data8 LSB
-pub const R_IA64_LTV64LSB: u32 = 0x77;
-/// @pcrel(sym + add), 21bit inst
-pub const R_IA64_PCREL21BI: u32 = 0x79;
-/// @pcrel(sym + add), 22bit inst
-pub const R_IA64_PCREL22: u32 = 0x7a;
-/// @pcrel(sym + add), 64bit inst
-pub const R_IA64_PCREL64I: u32 = 0x7b;
-/// dynamic reloc, imported PLT, MSB
-pub const R_IA64_IPLTMSB: u32 = 0x80;
-/// dynamic reloc, imported PLT, LSB
-pub const R_IA64_IPLTLSB: u32 = 0x81;
-/// copy relocation
-pub const R_IA64_COPY: u32 = 0x84;
-/// Addend and symbol difference
-pub const R_IA64_SUB: u32 = 0x85;
-/// LTOFF22, relaxable.
-pub const R_IA64_LTOFF22X: u32 = 0x86;
-/// Use of LTOFF22X.
-pub const R_IA64_LDXMOV: u32 = 0x87;
-/// @tprel(sym + add), imm14
-pub const R_IA64_TPREL14: u32 = 0x91;
-/// @tprel(sym + add), imm22
-pub const R_IA64_TPREL22: u32 = 0x92;
-/// @tprel(sym + add), imm64
-pub const R_IA64_TPREL64I: u32 = 0x93;
-/// @tprel(sym + add), data8 MSB
-pub const R_IA64_TPREL64MSB: u32 = 0x96;
-/// @tprel(sym + add), data8 LSB
-pub const R_IA64_TPREL64LSB: u32 = 0x97;
-/// @ltoff(@tprel(s+a)), imm2
-pub const R_IA64_LTOFF_TPREL22: u32 = 0x9a;
-/// @dtpmod(sym + add), data8 MSB
-pub const R_IA64_DTPMOD64MSB: u32 = 0xa6;
-/// @dtpmod(sym + add), data8 LSB
-pub const R_IA64_DTPMOD64LSB: u32 = 0xa7;
-/// @ltoff(@dtpmod(sym + add)), imm22
-pub const R_IA64_LTOFF_DTPMOD22: u32 = 0xaa;
-/// @dtprel(sym + add), imm14
-pub const R_IA64_DTPREL14: u32 = 0xb1;
-/// @dtprel(sym + add), imm22
-pub const R_IA64_DTPREL22: u32 = 0xb2;
-/// @dtprel(sym + add), imm64
-pub const R_IA64_DTPREL64I: u32 = 0xb3;
-/// @dtprel(sym + add), data4 MSB
-pub const R_IA64_DTPREL32MSB: u32 = 0xb4;
-/// @dtprel(sym + add), data4 LSB
-pub const R_IA64_DTPREL32LSB: u32 = 0xb5;
-/// @dtprel(sym + add), data8 MSB
-pub const R_IA64_DTPREL64MSB: u32 = 0xb6;
-/// @dtprel(sym + add), data8 LSB
-pub const R_IA64_DTPREL64LSB: u32 = 0xb7;
-/// @ltoff(@dtprel(s+a)), imm22
-pub const R_IA64_LTOFF_DTPREL22: u32 = 0xba;
-
-// SH specific declarations.
-
-// SH values `FileHeader*::e_flags`.
-pub const EF_SH_MACH_MASK: u32 = 0x1f;
-pub const EF_SH_UNKNOWN: u32 = 0x0;
-pub const EF_SH1: u32 = 0x1;
-pub const EF_SH2: u32 = 0x2;
-pub const EF_SH3: u32 = 0x3;
-pub const EF_SH_DSP: u32 = 0x4;
-pub const EF_SH3_DSP: u32 = 0x5;
-pub const EF_SH4AL_DSP: u32 = 0x6;
-pub const EF_SH3E: u32 = 0x8;
-pub const EF_SH4: u32 = 0x9;
-pub const EF_SH2E: u32 = 0xb;
-pub const EF_SH4A: u32 = 0xc;
-pub const EF_SH2A: u32 = 0xd;
-pub const EF_SH4_NOFPU: u32 = 0x10;
-pub const EF_SH4A_NOFPU: u32 = 0x11;
-pub const EF_SH4_NOMMU_NOFPU: u32 = 0x12;
-pub const EF_SH2A_NOFPU: u32 = 0x13;
-pub const EF_SH3_NOMMU: u32 = 0x14;
-pub const EF_SH2A_SH4_NOFPU: u32 = 0x15;
-pub const EF_SH2A_SH3_NOFPU: u32 = 0x16;
-pub const EF_SH2A_SH4: u32 = 0x17;
-pub const EF_SH2A_SH3E: u32 = 0x18;
-
-// SH values `Rel*::r_type`.
-pub const R_SH_NONE: u32 = 0;
-pub const R_SH_DIR32: u32 = 1;
-pub const R_SH_REL32: u32 = 2;
-pub const R_SH_DIR8WPN: u32 = 3;
-pub const R_SH_IND12W: u32 = 4;
-pub const R_SH_DIR8WPL: u32 = 5;
-pub const R_SH_DIR8WPZ: u32 = 6;
-pub const R_SH_DIR8BP: u32 = 7;
-pub const R_SH_DIR8W: u32 = 8;
-pub const R_SH_DIR8L: u32 = 9;
-pub const R_SH_SWITCH16: u32 = 25;
-pub const R_SH_SWITCH32: u32 = 26;
-pub const R_SH_USES: u32 = 27;
-pub const R_SH_COUNT: u32 = 28;
-pub const R_SH_ALIGN: u32 = 29;
-pub const R_SH_CODE: u32 = 30;
-pub const R_SH_DATA: u32 = 31;
-pub const R_SH_LABEL: u32 = 32;
-pub const R_SH_SWITCH8: u32 = 33;
-pub const R_SH_GNU_VTINHERIT: u32 = 34;
-pub const R_SH_GNU_VTENTRY: u32 = 35;
-pub const R_SH_TLS_GD_32: u32 = 144;
-pub const R_SH_TLS_LD_32: u32 = 145;
-pub const R_SH_TLS_LDO_32: u32 = 146;
-pub const R_SH_TLS_IE_32: u32 = 147;
-pub const R_SH_TLS_LE_32: u32 = 148;
-pub const R_SH_TLS_DTPMOD32: u32 = 149;
-pub const R_SH_TLS_DTPOFF32: u32 = 150;
-pub const R_SH_TLS_TPOFF32: u32 = 151;
-pub const R_SH_GOT32: u32 = 160;
-pub const R_SH_PLT32: u32 = 161;
-pub const R_SH_COPY: u32 = 162;
-pub const R_SH_GLOB_DAT: u32 = 163;
-pub const R_SH_JMP_SLOT: u32 = 164;
-pub const R_SH_RELATIVE: u32 = 165;
-pub const R_SH_GOTOFF: u32 = 166;
-pub const R_SH_GOTPC: u32 = 167;
-
-// S/390 specific definitions.
-
-// S/390 values `FileHeader*::e_flags`.
-
-/// High GPRs kernel facility needed.
-pub const EF_S390_HIGH_GPRS: u32 = 0x0000_0001;
-
-// S/390 values `Rel*::r_type`.
-
-/// No reloc.
-pub const R_390_NONE: u32 = 0;
-/// Direct 8 bit.
-pub const R_390_8: u32 = 1;
-/// Direct 12 bit.
-pub const R_390_12: u32 = 2;
-/// Direct 16 bit.
-pub const R_390_16: u32 = 3;
-/// Direct 32 bit.
-pub const R_390_32: u32 = 4;
-/// PC relative 32 bit.
-pub const R_390_PC32: u32 = 5;
-/// 12 bit GOT offset.
-pub const R_390_GOT12: u32 = 6;
-/// 32 bit GOT offset.
-pub const R_390_GOT32: u32 = 7;
-/// 32 bit PC relative PLT address.
-pub const R_390_PLT32: u32 = 8;
-/// Copy symbol at runtime.
-pub const R_390_COPY: u32 = 9;
-/// Create GOT entry.
-pub const R_390_GLOB_DAT: u32 = 10;
-/// Create PLT entry.
-pub const R_390_JMP_SLOT: u32 = 11;
-/// Adjust by program base.
-pub const R_390_RELATIVE: u32 = 12;
-/// 32 bit offset to GOT.
-pub const R_390_GOTOFF32: u32 = 13;
-/// 32 bit PC relative offset to GOT.
-pub const R_390_GOTPC: u32 = 14;
-/// 16 bit GOT offset.
-pub const R_390_GOT16: u32 = 15;
-/// PC relative 16 bit.
-pub const R_390_PC16: u32 = 16;
-/// PC relative 16 bit shifted by 1.
-pub const R_390_PC16DBL: u32 = 17;
-/// 16 bit PC rel. PLT shifted by 1.
-pub const R_390_PLT16DBL: u32 = 18;
-/// PC relative 32 bit shifted by 1.
-pub const R_390_PC32DBL: u32 = 19;
-/// 32 bit PC rel. PLT shifted by 1.
-pub const R_390_PLT32DBL: u32 = 20;
-/// 32 bit PC rel. GOT shifted by 1.
-pub const R_390_GOTPCDBL: u32 = 21;
-/// Direct 64 bit.
-pub const R_390_64: u32 = 22;
-/// PC relative 64 bit.
-pub const R_390_PC64: u32 = 23;
-/// 64 bit GOT offset.
-pub const R_390_GOT64: u32 = 24;
-/// 64 bit PC relative PLT address.
-pub const R_390_PLT64: u32 = 25;
-/// 32 bit PC rel. to GOT entry >> 1.
-pub const R_390_GOTENT: u32 = 26;
-/// 16 bit offset to GOT.
-pub const R_390_GOTOFF16: u32 = 27;
-/// 64 bit offset to GOT.
-pub const R_390_GOTOFF64: u32 = 28;
-/// 12 bit offset to jump slot.
-pub const R_390_GOTPLT12: u32 = 29;
-/// 16 bit offset to jump slot.
-pub const R_390_GOTPLT16: u32 = 30;
-/// 32 bit offset to jump slot.
-pub const R_390_GOTPLT32: u32 = 31;
-/// 64 bit offset to jump slot.
-pub const R_390_GOTPLT64: u32 = 32;
-/// 32 bit rel. offset to jump slot.
-pub const R_390_GOTPLTENT: u32 = 33;
-/// 16 bit offset from GOT to PLT.
-pub const R_390_PLTOFF16: u32 = 34;
-/// 32 bit offset from GOT to PLT.
-pub const R_390_PLTOFF32: u32 = 35;
-/// 16 bit offset from GOT to PLT.
-pub const R_390_PLTOFF64: u32 = 36;
-/// Tag for load insn in TLS code.
-pub const R_390_TLS_LOAD: u32 = 37;
-/// Tag for function call in general dynamic TLS code.
-pub const R_390_TLS_GDCALL: u32 = 38;
-/// Tag for function call in local dynamic TLS code.
-pub const R_390_TLS_LDCALL: u32 = 39;
-/// Direct 32 bit for general dynamic thread local data.
-pub const R_390_TLS_GD32: u32 = 40;
-/// Direct 64 bit for general dynamic thread local data.
-pub const R_390_TLS_GD64: u32 = 41;
-/// 12 bit GOT offset for static TLS block offset.
-pub const R_390_TLS_GOTIE12: u32 = 42;
-/// 32 bit GOT offset for static TLS block offset.
-pub const R_390_TLS_GOTIE32: u32 = 43;
-/// 64 bit GOT offset for static TLS block offset.
-pub const R_390_TLS_GOTIE64: u32 = 44;
-/// Direct 32 bit for local dynamic thread local data in LE code.
-pub const R_390_TLS_LDM32: u32 = 45;
-/// Direct 64 bit for local dynamic thread local data in LE code.
-pub const R_390_TLS_LDM64: u32 = 46;
-/// 32 bit address of GOT entry for negated static TLS block offset.
-pub const R_390_TLS_IE32: u32 = 47;
-/// 64 bit address of GOT entry for negated static TLS block offset.
-pub const R_390_TLS_IE64: u32 = 48;
-/// 32 bit rel. offset to GOT entry for negated static TLS block offset.
-pub const R_390_TLS_IEENT: u32 = 49;
-/// 32 bit negated offset relative to static TLS block.
-pub const R_390_TLS_LE32: u32 = 50;
-/// 64 bit negated offset relative to static TLS block.
-pub const R_390_TLS_LE64: u32 = 51;
-/// 32 bit offset relative to TLS block.
-pub const R_390_TLS_LDO32: u32 = 52;
-/// 64 bit offset relative to TLS block.
-pub const R_390_TLS_LDO64: u32 = 53;
-/// ID of module containing symbol.
-pub const R_390_TLS_DTPMOD: u32 = 54;
-/// Offset in TLS block.
-pub const R_390_TLS_DTPOFF: u32 = 55;
-/// Negated offset in static TLS block.
-pub const R_390_TLS_TPOFF: u32 = 56;
-/// Direct 20 bit.
-pub const R_390_20: u32 = 57;
-/// 20 bit GOT offset.
-pub const R_390_GOT20: u32 = 58;
-/// 20 bit offset to jump slot.
-pub const R_390_GOTPLT20: u32 = 59;
-/// 20 bit GOT offset for static TLS block offset.
-pub const R_390_TLS_GOTIE20: u32 = 60;
-/// STT_GNU_IFUNC relocation.
-pub const R_390_IRELATIVE: u32 = 61;
-
-// CRIS values `Rel*::r_type`.
-pub const R_CRIS_NONE: u32 = 0;
-pub const R_CRIS_8: u32 = 1;
-pub const R_CRIS_16: u32 = 2;
-pub const R_CRIS_32: u32 = 3;
-pub const R_CRIS_8_PCREL: u32 = 4;
-pub const R_CRIS_16_PCREL: u32 = 5;
-pub const R_CRIS_32_PCREL: u32 = 6;
-pub const R_CRIS_GNU_VTINHERIT: u32 = 7;
-pub const R_CRIS_GNU_VTENTRY: u32 = 8;
-pub const R_CRIS_COPY: u32 = 9;
-pub const R_CRIS_GLOB_DAT: u32 = 10;
-pub const R_CRIS_JUMP_SLOT: u32 = 11;
-pub const R_CRIS_RELATIVE: u32 = 12;
-pub const R_CRIS_16_GOT: u32 = 13;
-pub const R_CRIS_32_GOT: u32 = 14;
-pub const R_CRIS_16_GOTPLT: u32 = 15;
-pub const R_CRIS_32_GOTPLT: u32 = 16;
-pub const R_CRIS_32_GOTREL: u32 = 17;
-pub const R_CRIS_32_PLT_GOTREL: u32 = 18;
-pub const R_CRIS_32_PLT_PCREL: u32 = 19;
-
-// AMD x86-64 values `Rel*::r_type`.
-/// No reloc
-pub const R_X86_64_NONE: u32 = 0;
-/// Direct 64 bit
-pub const R_X86_64_64: u32 = 1;
-/// PC relative 32 bit signed
-pub const R_X86_64_PC32: u32 = 2;
-/// 32 bit GOT entry
-pub const R_X86_64_GOT32: u32 = 3;
-/// 32 bit PLT address
-pub const R_X86_64_PLT32: u32 = 4;
-/// Copy symbol at runtime
-pub const R_X86_64_COPY: u32 = 5;
-/// Create GOT entry
-pub const R_X86_64_GLOB_DAT: u32 = 6;
-/// Create PLT entry
-pub const R_X86_64_JUMP_SLOT: u32 = 7;
-/// Adjust by program base
-pub const R_X86_64_RELATIVE: u32 = 8;
-/// 32 bit signed PC relative offset to GOT
-pub const R_X86_64_GOTPCREL: u32 = 9;
-/// Direct 32 bit zero extended
-pub const R_X86_64_32: u32 = 10;
-/// Direct 32 bit sign extended
-pub const R_X86_64_32S: u32 = 11;
-/// Direct 16 bit zero extended
-pub const R_X86_64_16: u32 = 12;
-/// 16 bit sign extended pc relative
-pub const R_X86_64_PC16: u32 = 13;
-/// Direct 8 bit sign extended
-pub const R_X86_64_8: u32 = 14;
-/// 8 bit sign extended pc relative
-pub const R_X86_64_PC8: u32 = 15;
-/// ID of module containing symbol
-pub const R_X86_64_DTPMOD64: u32 = 16;
-/// Offset in module's TLS block
-pub const R_X86_64_DTPOFF64: u32 = 17;
-/// Offset in initial TLS block
-pub const R_X86_64_TPOFF64: u32 = 18;
-/// 32 bit signed PC relative offset to two GOT entries for GD symbol
-pub const R_X86_64_TLSGD: u32 = 19;
-/// 32 bit signed PC relative offset to two GOT entries for LD symbol
-pub const R_X86_64_TLSLD: u32 = 20;
-/// Offset in TLS block
-pub const R_X86_64_DTPOFF32: u32 = 21;
-/// 32 bit signed PC relative offset to GOT entry for IE symbol
-pub const R_X86_64_GOTTPOFF: u32 = 22;
-/// Offset in initial TLS block
-pub const R_X86_64_TPOFF32: u32 = 23;
-/// PC relative 64 bit
-pub const R_X86_64_PC64: u32 = 24;
-/// 64 bit offset to GOT
-pub const R_X86_64_GOTOFF64: u32 = 25;
-/// 32 bit signed pc relative offset to GOT
-pub const R_X86_64_GOTPC32: u32 = 26;
-/// 64-bit GOT entry offset
-pub const R_X86_64_GOT64: u32 = 27;
-/// 64-bit PC relative offset to GOT entry
-pub const R_X86_64_GOTPCREL64: u32 = 28;
-/// 64-bit PC relative offset to GOT
-pub const R_X86_64_GOTPC64: u32 = 29;
-/// like GOT64, says PLT entry needed
-pub const R_X86_64_GOTPLT64: u32 = 30;
-/// 64-bit GOT relative offset to PLT entry
-pub const R_X86_64_PLTOFF64: u32 = 31;
-/// Size of symbol plus 32-bit addend
-pub const R_X86_64_SIZE32: u32 = 32;
-/// Size of symbol plus 64-bit addend
-pub const R_X86_64_SIZE64: u32 = 33;
-/// GOT offset for TLS descriptor.
-pub const R_X86_64_GOTPC32_TLSDESC: u32 = 34;
-/// Marker for call through TLS descriptor.
-pub const R_X86_64_TLSDESC_CALL: u32 = 35;
-/// TLS descriptor.
-pub const R_X86_64_TLSDESC: u32 = 36;
-/// Adjust indirectly by program base
-pub const R_X86_64_IRELATIVE: u32 = 37;
-/// 64-bit adjust by program base
-pub const R_X86_64_RELATIVE64: u32 = 38;
-// 39 Reserved was R_X86_64_PC32_BND
-// 40 Reserved was R_X86_64_PLT32_BND
-/// Load from 32 bit signed pc relative offset to GOT entry without REX prefix, relaxable.
-pub const R_X86_64_GOTPCRELX: u32 = 41;
-/// Load from 32 bit signed pc relative offset to GOT entry with REX prefix, relaxable.
-pub const R_X86_64_REX_GOTPCRELX: u32 = 42;
-
-// AMD x86-64 values `SectionHeader*::sh_type`.
-/// Unwind information.
-pub const SHT_X86_64_UNWIND: u32 = 0x7000_0001;
-
-// AM33 values `Rel*::r_type`.
-/// No reloc.
-pub const R_MN10300_NONE: u32 = 0;
-/// Direct 32 bit.
-pub const R_MN10300_32: u32 = 1;
-/// Direct 16 bit.
-pub const R_MN10300_16: u32 = 2;
-/// Direct 8 bit.
-pub const R_MN10300_8: u32 = 3;
-/// PC-relative 32-bit.
-pub const R_MN10300_PCREL32: u32 = 4;
-/// PC-relative 16-bit signed.
-pub const R_MN10300_PCREL16: u32 = 5;
-/// PC-relative 8-bit signed.
-pub const R_MN10300_PCREL8: u32 = 6;
-/// Ancient C++ vtable garbage...
-pub const R_MN10300_GNU_VTINHERIT: u32 = 7;
-/// ... collection annotation.
-pub const R_MN10300_GNU_VTENTRY: u32 = 8;
-/// Direct 24 bit.
-pub const R_MN10300_24: u32 = 9;
-/// 32-bit PCrel offset to GOT.
-pub const R_MN10300_GOTPC32: u32 = 10;
-/// 16-bit PCrel offset to GOT.
-pub const R_MN10300_GOTPC16: u32 = 11;
-/// 32-bit offset from GOT.
-pub const R_MN10300_GOTOFF32: u32 = 12;
-/// 24-bit offset from GOT.
-pub const R_MN10300_GOTOFF24: u32 = 13;
-/// 16-bit offset from GOT.
-pub const R_MN10300_GOTOFF16: u32 = 14;
-/// 32-bit PCrel to PLT entry.
-pub const R_MN10300_PLT32: u32 = 15;
-/// 16-bit PCrel to PLT entry.
-pub const R_MN10300_PLT16: u32 = 16;
-/// 32-bit offset to GOT entry.
-pub const R_MN10300_GOT32: u32 = 17;
-/// 24-bit offset to GOT entry.
-pub const R_MN10300_GOT24: u32 = 18;
-/// 16-bit offset to GOT entry.
-pub const R_MN10300_GOT16: u32 = 19;
-/// Copy symbol at runtime.
-pub const R_MN10300_COPY: u32 = 20;
-/// Create GOT entry.
-pub const R_MN10300_GLOB_DAT: u32 = 21;
-/// Create PLT entry.
-pub const R_MN10300_JMP_SLOT: u32 = 22;
-/// Adjust by program base.
-pub const R_MN10300_RELATIVE: u32 = 23;
-/// 32-bit offset for global dynamic.
-pub const R_MN10300_TLS_GD: u32 = 24;
-/// 32-bit offset for local dynamic.
-pub const R_MN10300_TLS_LD: u32 = 25;
-/// Module-relative offset.
-pub const R_MN10300_TLS_LDO: u32 = 26;
-/// GOT offset for static TLS block offset.
-pub const R_MN10300_TLS_GOTIE: u32 = 27;
-/// GOT address for static TLS block offset.
-pub const R_MN10300_TLS_IE: u32 = 28;
-/// Offset relative to static TLS block.
-pub const R_MN10300_TLS_LE: u32 = 29;
-/// ID of module containing symbol.
-pub const R_MN10300_TLS_DTPMOD: u32 = 30;
-/// Offset in module TLS block.
-pub const R_MN10300_TLS_DTPOFF: u32 = 31;
-/// Offset in static TLS block.
-pub const R_MN10300_TLS_TPOFF: u32 = 32;
-/// Adjustment for next reloc as needed by linker relaxation.
-pub const R_MN10300_SYM_DIFF: u32 = 33;
-/// Alignment requirement for linker relaxation.
-pub const R_MN10300_ALIGN: u32 = 34;
-
-// M32R values `Rel32::r_type`.
-/// No reloc.
-pub const R_M32R_NONE: u32 = 0;
-/// Direct 16 bit.
-pub const R_M32R_16: u32 = 1;
-/// Direct 32 bit.
-pub const R_M32R_32: u32 = 2;
-/// Direct 24 bit.
-pub const R_M32R_24: u32 = 3;
-/// PC relative 10 bit shifted.
-pub const R_M32R_10_PCREL: u32 = 4;
-/// PC relative 18 bit shifted.
-pub const R_M32R_18_PCREL: u32 = 5;
-/// PC relative 26 bit shifted.
-pub const R_M32R_26_PCREL: u32 = 6;
-/// High 16 bit with unsigned low.
-pub const R_M32R_HI16_ULO: u32 = 7;
-/// High 16 bit with signed low.
-pub const R_M32R_HI16_SLO: u32 = 8;
-/// Low 16 bit.
-pub const R_M32R_LO16: u32 = 9;
-/// 16 bit offset in SDA.
-pub const R_M32R_SDA16: u32 = 10;
-pub const R_M32R_GNU_VTINHERIT: u32 = 11;
-pub const R_M32R_GNU_VTENTRY: u32 = 12;
-// M32R values `Rela32::r_type`.
-/// Direct 16 bit.
-pub const R_M32R_16_RELA: u32 = 33;
-/// Direct 32 bit.
-pub const R_M32R_32_RELA: u32 = 34;
-/// Direct 24 bit.
-pub const R_M32R_24_RELA: u32 = 35;
-/// PC relative 10 bit shifted.
-pub const R_M32R_10_PCREL_RELA: u32 = 36;
-/// PC relative 18 bit shifted.
-pub const R_M32R_18_PCREL_RELA: u32 = 37;
-/// PC relative 26 bit shifted.
-pub const R_M32R_26_PCREL_RELA: u32 = 38;
-/// High 16 bit with unsigned low
-pub const R_M32R_HI16_ULO_RELA: u32 = 39;
-/// High 16 bit with signed low
-pub const R_M32R_HI16_SLO_RELA: u32 = 40;
-/// Low 16 bit
-pub const R_M32R_LO16_RELA: u32 = 41;
-/// 16 bit offset in SDA
-pub const R_M32R_SDA16_RELA: u32 = 42;
-pub const R_M32R_RELA_GNU_VTINHERIT: u32 = 43;
-pub const R_M32R_RELA_GNU_VTENTRY: u32 = 44;
-/// PC relative 32 bit.
-pub const R_M32R_REL32: u32 = 45;
-
-/// 24 bit GOT entry
-pub const R_M32R_GOT24: u32 = 48;
-/// 26 bit PC relative to PLT shifted
-pub const R_M32R_26_PLTREL: u32 = 49;
-/// Copy symbol at runtime
-pub const R_M32R_COPY: u32 = 50;
-/// Create GOT entry
-pub const R_M32R_GLOB_DAT: u32 = 51;
-/// Create PLT entry
-pub const R_M32R_JMP_SLOT: u32 = 52;
-/// Adjust by program base
-pub const R_M32R_RELATIVE: u32 = 53;
-/// 24 bit offset to GOT
-pub const R_M32R_GOTOFF: u32 = 54;
-/// 24 bit PC relative offset to GOT
-pub const R_M32R_GOTPC24: u32 = 55;
-/// High 16 bit GOT entry with unsigned low
-pub const R_M32R_GOT16_HI_ULO: u32 = 56;
-/// High 16 bit GOT entry with signed low
-pub const R_M32R_GOT16_HI_SLO: u32 = 57;
-/// Low 16 bit GOT entry
-pub const R_M32R_GOT16_LO: u32 = 58;
-/// High 16 bit PC relative offset to GOT with unsigned low
-pub const R_M32R_GOTPC_HI_ULO: u32 = 59;
-/// High 16 bit PC relative offset to GOT with signed low
-pub const R_M32R_GOTPC_HI_SLO: u32 = 60;
-/// Low 16 bit PC relative offset to GOT
-pub const R_M32R_GOTPC_LO: u32 = 61;
-/// High 16 bit offset to GOT with unsigned low
-pub const R_M32R_GOTOFF_HI_ULO: u32 = 62;
-/// High 16 bit offset to GOT with signed low
-pub const R_M32R_GOTOFF_HI_SLO: u32 = 63;
-/// Low 16 bit offset to GOT
-pub const R_M32R_GOTOFF_LO: u32 = 64;
-/// Keep this the last entry.
-pub const R_M32R_NUM: u32 = 256;
-
-// MicroBlaze values `Rel*::r_type`.
-/// No reloc.
-pub const R_MICROBLAZE_NONE: u32 = 0;
-/// Direct 32 bit.
-pub const R_MICROBLAZE_32: u32 = 1;
-/// PC relative 32 bit.
-pub const R_MICROBLAZE_32_PCREL: u32 = 2;
-/// PC relative 64 bit.
-pub const R_MICROBLAZE_64_PCREL: u32 = 3;
-/// Low 16 bits of PCREL32.
-pub const R_MICROBLAZE_32_PCREL_LO: u32 = 4;
-/// Direct 64 bit.
-pub const R_MICROBLAZE_64: u32 = 5;
-/// Low 16 bit.
-pub const R_MICROBLAZE_32_LO: u32 = 6;
-/// Read-only small data area.
-pub const R_MICROBLAZE_SRO32: u32 = 7;
-/// Read-write small data area.
-pub const R_MICROBLAZE_SRW32: u32 = 8;
-/// No reloc.
-pub const R_MICROBLAZE_64_NONE: u32 = 9;
-/// Symbol Op Symbol relocation.
-pub const R_MICROBLAZE_32_SYM_OP_SYM: u32 = 10;
-/// GNU C++ vtable hierarchy.
-pub const R_MICROBLAZE_GNU_VTINHERIT: u32 = 11;
-/// GNU C++ vtable member usage.
-pub const R_MICROBLAZE_GNU_VTENTRY: u32 = 12;
-/// PC-relative GOT offset.
-pub const R_MICROBLAZE_GOTPC_64: u32 = 13;
-/// GOT entry offset.
-pub const R_MICROBLAZE_GOT_64: u32 = 14;
-/// PLT offset (PC-relative).
-pub const R_MICROBLAZE_PLT_64: u32 = 15;
-/// Adjust by program base.
-pub const R_MICROBLAZE_REL: u32 = 16;
-/// Create PLT entry.
-pub const R_MICROBLAZE_JUMP_SLOT: u32 = 17;
-/// Create GOT entry.
-pub const R_MICROBLAZE_GLOB_DAT: u32 = 18;
-/// 64 bit offset to GOT.
-pub const R_MICROBLAZE_GOTOFF_64: u32 = 19;
-/// 32 bit offset to GOT.
-pub const R_MICROBLAZE_GOTOFF_32: u32 = 20;
-/// Runtime copy.
-pub const R_MICROBLAZE_COPY: u32 = 21;
-/// TLS Reloc.
-pub const R_MICROBLAZE_TLS: u32 = 22;
-/// TLS General Dynamic.
-pub const R_MICROBLAZE_TLSGD: u32 = 23;
-/// TLS Local Dynamic.
-pub const R_MICROBLAZE_TLSLD: u32 = 24;
-/// TLS Module ID.
-pub const R_MICROBLAZE_TLSDTPMOD32: u32 = 25;
-/// TLS Offset Within TLS Block.
-pub const R_MICROBLAZE_TLSDTPREL32: u32 = 26;
-/// TLS Offset Within TLS Block.
-pub const R_MICROBLAZE_TLSDTPREL64: u32 = 27;
-/// TLS Offset From Thread Pointer.
-pub const R_MICROBLAZE_TLSGOTTPREL32: u32 = 28;
-/// TLS Offset From Thread Pointer.
-pub const R_MICROBLAZE_TLSTPREL32: u32 = 29;
-
-// Nios II values `Dyn::d_tag`.
-/// Address of _gp.
-pub const DT_NIOS2_GP: u32 = 0x7000_0002;
-
-// Nios II values `Rel*::r_type`.
-/// No reloc.
-pub const R_NIOS2_NONE: u32 = 0;
-/// Direct signed 16 bit.
-pub const R_NIOS2_S16: u32 = 1;
-/// Direct unsigned 16 bit.
-pub const R_NIOS2_U16: u32 = 2;
-/// PC relative 16 bit.
-pub const R_NIOS2_PCREL16: u32 = 3;
-/// Direct call.
-pub const R_NIOS2_CALL26: u32 = 4;
-/// 5 bit constant expression.
-pub const R_NIOS2_IMM5: u32 = 5;
-/// 5 bit expression, shift 22.
-pub const R_NIOS2_CACHE_OPX: u32 = 6;
-/// 6 bit constant expression.
-pub const R_NIOS2_IMM6: u32 = 7;
-/// 8 bit constant expression.
-pub const R_NIOS2_IMM8: u32 = 8;
-/// High 16 bit.
-pub const R_NIOS2_HI16: u32 = 9;
-/// Low 16 bit.
-pub const R_NIOS2_LO16: u32 = 10;
-/// High 16 bit, adjusted.
-pub const R_NIOS2_HIADJ16: u32 = 11;
-/// 32 bit symbol value + addend.
-pub const R_NIOS2_BFD_RELOC_32: u32 = 12;
-/// 16 bit symbol value + addend.
-pub const R_NIOS2_BFD_RELOC_16: u32 = 13;
-/// 8 bit symbol value + addend.
-pub const R_NIOS2_BFD_RELOC_8: u32 = 14;
-/// 16 bit GP pointer offset.
-pub const R_NIOS2_GPREL: u32 = 15;
-/// GNU C++ vtable hierarchy.
-pub const R_NIOS2_GNU_VTINHERIT: u32 = 16;
-/// GNU C++ vtable member usage.
-pub const R_NIOS2_GNU_VTENTRY: u32 = 17;
-/// Unconditional branch.
-pub const R_NIOS2_UJMP: u32 = 18;
-/// Conditional branch.
-pub const R_NIOS2_CJMP: u32 = 19;
-/// Indirect call through register.
-pub const R_NIOS2_CALLR: u32 = 20;
-/// Alignment requirement for linker relaxation.
-pub const R_NIOS2_ALIGN: u32 = 21;
-/// 16 bit GOT entry.
-pub const R_NIOS2_GOT16: u32 = 22;
-/// 16 bit GOT entry for function.
-pub const R_NIOS2_CALL16: u32 = 23;
-/// %lo of offset to GOT pointer.
-pub const R_NIOS2_GOTOFF_LO: u32 = 24;
-/// %hiadj of offset to GOT pointer.
-pub const R_NIOS2_GOTOFF_HA: u32 = 25;
-/// %lo of PC relative offset.
-pub const R_NIOS2_PCREL_LO: u32 = 26;
-/// %hiadj of PC relative offset.
-pub const R_NIOS2_PCREL_HA: u32 = 27;
-/// 16 bit GOT offset for TLS GD.
-pub const R_NIOS2_TLS_GD16: u32 = 28;
-/// 16 bit GOT offset for TLS LDM.
-pub const R_NIOS2_TLS_LDM16: u32 = 29;
-/// 16 bit module relative offset.
-pub const R_NIOS2_TLS_LDO16: u32 = 30;
-/// 16 bit GOT offset for TLS IE.
-pub const R_NIOS2_TLS_IE16: u32 = 31;
-/// 16 bit LE TP-relative offset.
-pub const R_NIOS2_TLS_LE16: u32 = 32;
-/// Module number.
-pub const R_NIOS2_TLS_DTPMOD: u32 = 33;
-/// Module-relative offset.
-pub const R_NIOS2_TLS_DTPREL: u32 = 34;
-/// TP-relative offset.
-pub const R_NIOS2_TLS_TPREL: u32 = 35;
-/// Copy symbol at runtime.
-pub const R_NIOS2_COPY: u32 = 36;
-/// Create GOT entry.
-pub const R_NIOS2_GLOB_DAT: u32 = 37;
-/// Create PLT entry.
-pub const R_NIOS2_JUMP_SLOT: u32 = 38;
-/// Adjust by program base.
-pub const R_NIOS2_RELATIVE: u32 = 39;
-/// 16 bit offset to GOT pointer.
-pub const R_NIOS2_GOTOFF: u32 = 40;
-/// Direct call in .noat section.
-pub const R_NIOS2_CALL26_NOAT: u32 = 41;
-/// %lo() of GOT entry.
-pub const R_NIOS2_GOT_LO: u32 = 42;
-/// %hiadj() of GOT entry.
-pub const R_NIOS2_GOT_HA: u32 = 43;
-/// %lo() of function GOT entry.
-pub const R_NIOS2_CALL_LO: u32 = 44;
-/// %hiadj() of function GOT entry.
-pub const R_NIOS2_CALL_HA: u32 = 45;
-
-// TILEPro values `Rel*::r_type`.
-/// No reloc
-pub const R_TILEPRO_NONE: u32 = 0;
-/// Direct 32 bit
-pub const R_TILEPRO_32: u32 = 1;
-/// Direct 16 bit
-pub const R_TILEPRO_16: u32 = 2;
-/// Direct 8 bit
-pub const R_TILEPRO_8: u32 = 3;
-/// PC relative 32 bit
-pub const R_TILEPRO_32_PCREL: u32 = 4;
-/// PC relative 16 bit
-pub const R_TILEPRO_16_PCREL: u32 = 5;
-/// PC relative 8 bit
-pub const R_TILEPRO_8_PCREL: u32 = 6;
-/// Low 16 bit
-pub const R_TILEPRO_LO16: u32 = 7;
-/// High 16 bit
-pub const R_TILEPRO_HI16: u32 = 8;
-/// High 16 bit, adjusted
-pub const R_TILEPRO_HA16: u32 = 9;
-/// Copy relocation
-pub const R_TILEPRO_COPY: u32 = 10;
-/// Create GOT entry
-pub const R_TILEPRO_GLOB_DAT: u32 = 11;
-/// Create PLT entry
-pub const R_TILEPRO_JMP_SLOT: u32 = 12;
-/// Adjust by program base
-pub const R_TILEPRO_RELATIVE: u32 = 13;
-/// X1 pipe branch offset
-pub const R_TILEPRO_BROFF_X1: u32 = 14;
-/// X1 pipe jump offset
-pub const R_TILEPRO_JOFFLONG_X1: u32 = 15;
-/// X1 pipe jump offset to PLT
-pub const R_TILEPRO_JOFFLONG_X1_PLT: u32 = 16;
-/// X0 pipe 8-bit
-pub const R_TILEPRO_IMM8_X0: u32 = 17;
-/// Y0 pipe 8-bit
-pub const R_TILEPRO_IMM8_Y0: u32 = 18;
-/// X1 pipe 8-bit
-pub const R_TILEPRO_IMM8_X1: u32 = 19;
-/// Y1 pipe 8-bit
-pub const R_TILEPRO_IMM8_Y1: u32 = 20;
-/// X1 pipe mtspr
-pub const R_TILEPRO_MT_IMM15_X1: u32 = 21;
-/// X1 pipe mfspr
-pub const R_TILEPRO_MF_IMM15_X1: u32 = 22;
-/// X0 pipe 16-bit
-pub const R_TILEPRO_IMM16_X0: u32 = 23;
-/// X1 pipe 16-bit
-pub const R_TILEPRO_IMM16_X1: u32 = 24;
-/// X0 pipe low 16-bit
-pub const R_TILEPRO_IMM16_X0_LO: u32 = 25;
-/// X1 pipe low 16-bit
-pub const R_TILEPRO_IMM16_X1_LO: u32 = 26;
-/// X0 pipe high 16-bit
-pub const R_TILEPRO_IMM16_X0_HI: u32 = 27;
-/// X1 pipe high 16-bit
-pub const R_TILEPRO_IMM16_X1_HI: u32 = 28;
-/// X0 pipe high 16-bit, adjusted
-pub const R_TILEPRO_IMM16_X0_HA: u32 = 29;
-/// X1 pipe high 16-bit, adjusted
-pub const R_TILEPRO_IMM16_X1_HA: u32 = 30;
-/// X0 pipe PC relative 16 bit
-pub const R_TILEPRO_IMM16_X0_PCREL: u32 = 31;
-/// X1 pipe PC relative 16 bit
-pub const R_TILEPRO_IMM16_X1_PCREL: u32 = 32;
-/// X0 pipe PC relative low 16 bit
-pub const R_TILEPRO_IMM16_X0_LO_PCREL: u32 = 33;
-/// X1 pipe PC relative low 16 bit
-pub const R_TILEPRO_IMM16_X1_LO_PCREL: u32 = 34;
-/// X0 pipe PC relative high 16 bit
-pub const R_TILEPRO_IMM16_X0_HI_PCREL: u32 = 35;
-/// X1 pipe PC relative high 16 bit
-pub const R_TILEPRO_IMM16_X1_HI_PCREL: u32 = 36;
-/// X0 pipe PC relative ha() 16 bit
-pub const R_TILEPRO_IMM16_X0_HA_PCREL: u32 = 37;
-/// X1 pipe PC relative ha() 16 bit
-pub const R_TILEPRO_IMM16_X1_HA_PCREL: u32 = 38;
-/// X0 pipe 16-bit GOT offset
-pub const R_TILEPRO_IMM16_X0_GOT: u32 = 39;
-/// X1 pipe 16-bit GOT offset
-pub const R_TILEPRO_IMM16_X1_GOT: u32 = 40;
-/// X0 pipe low 16-bit GOT offset
-pub const R_TILEPRO_IMM16_X0_GOT_LO: u32 = 41;
-/// X1 pipe low 16-bit GOT offset
-pub const R_TILEPRO_IMM16_X1_GOT_LO: u32 = 42;
-/// X0 pipe high 16-bit GOT offset
-pub const R_TILEPRO_IMM16_X0_GOT_HI: u32 = 43;
-/// X1 pipe high 16-bit GOT offset
-pub const R_TILEPRO_IMM16_X1_GOT_HI: u32 = 44;
-/// X0 pipe ha() 16-bit GOT offset
-pub const R_TILEPRO_IMM16_X0_GOT_HA: u32 = 45;
-/// X1 pipe ha() 16-bit GOT offset
-pub const R_TILEPRO_IMM16_X1_GOT_HA: u32 = 46;
-/// X0 pipe mm "start"
-pub const R_TILEPRO_MMSTART_X0: u32 = 47;
-/// X0 pipe mm "end"
-pub const R_TILEPRO_MMEND_X0: u32 = 48;
-/// X1 pipe mm "start"
-pub const R_TILEPRO_MMSTART_X1: u32 = 49;
-/// X1 pipe mm "end"
-pub const R_TILEPRO_MMEND_X1: u32 = 50;
-/// X0 pipe shift amount
-pub const R_TILEPRO_SHAMT_X0: u32 = 51;
-/// X1 pipe shift amount
-pub const R_TILEPRO_SHAMT_X1: u32 = 52;
-/// Y0 pipe shift amount
-pub const R_TILEPRO_SHAMT_Y0: u32 = 53;
-/// Y1 pipe shift amount
-pub const R_TILEPRO_SHAMT_Y1: u32 = 54;
-/// X1 pipe destination 8-bit
-pub const R_TILEPRO_DEST_IMM8_X1: u32 = 55;
-// Relocs 56-59 are currently not defined.
-/// "jal" for TLS GD
-pub const R_TILEPRO_TLS_GD_CALL: u32 = 60;
-/// X0 pipe "addi" for TLS GD
-pub const R_TILEPRO_IMM8_X0_TLS_GD_ADD: u32 = 61;
-/// X1 pipe "addi" for TLS GD
-pub const R_TILEPRO_IMM8_X1_TLS_GD_ADD: u32 = 62;
-/// Y0 pipe "addi" for TLS GD
-pub const R_TILEPRO_IMM8_Y0_TLS_GD_ADD: u32 = 63;
-/// Y1 pipe "addi" for TLS GD
-pub const R_TILEPRO_IMM8_Y1_TLS_GD_ADD: u32 = 64;
-/// "lw_tls" for TLS IE
-pub const R_TILEPRO_TLS_IE_LOAD: u32 = 65;
-/// X0 pipe 16-bit TLS GD offset
-pub const R_TILEPRO_IMM16_X0_TLS_GD: u32 = 66;
-/// X1 pipe 16-bit TLS GD offset
-pub const R_TILEPRO_IMM16_X1_TLS_GD: u32 = 67;
-/// X0 pipe low 16-bit TLS GD offset
-pub const R_TILEPRO_IMM16_X0_TLS_GD_LO: u32 = 68;
-/// X1 pipe low 16-bit TLS GD offset
-pub const R_TILEPRO_IMM16_X1_TLS_GD_LO: u32 = 69;
-/// X0 pipe high 16-bit TLS GD offset
-pub const R_TILEPRO_IMM16_X0_TLS_GD_HI: u32 = 70;
-/// X1 pipe high 16-bit TLS GD offset
-pub const R_TILEPRO_IMM16_X1_TLS_GD_HI: u32 = 71;
-/// X0 pipe ha() 16-bit TLS GD offset
-pub const R_TILEPRO_IMM16_X0_TLS_GD_HA: u32 = 72;
-/// X1 pipe ha() 16-bit TLS GD offset
-pub const R_TILEPRO_IMM16_X1_TLS_GD_HA: u32 = 73;
-/// X0 pipe 16-bit TLS IE offset
-pub const R_TILEPRO_IMM16_X0_TLS_IE: u32 = 74;
-/// X1 pipe 16-bit TLS IE offset
-pub const R_TILEPRO_IMM16_X1_TLS_IE: u32 = 75;
-/// X0 pipe low 16-bit TLS IE offset
-pub const R_TILEPRO_IMM16_X0_TLS_IE_LO: u32 = 76;
-/// X1 pipe low 16-bit TLS IE offset
-pub const R_TILEPRO_IMM16_X1_TLS_IE_LO: u32 = 77;
-/// X0 pipe high 16-bit TLS IE offset
-pub const R_TILEPRO_IMM16_X0_TLS_IE_HI: u32 = 78;
-/// X1 pipe high 16-bit TLS IE offset
-pub const R_TILEPRO_IMM16_X1_TLS_IE_HI: u32 = 79;
-/// X0 pipe ha() 16-bit TLS IE offset
-pub const R_TILEPRO_IMM16_X0_TLS_IE_HA: u32 = 80;
-/// X1 pipe ha() 16-bit TLS IE offset
-pub const R_TILEPRO_IMM16_X1_TLS_IE_HA: u32 = 81;
-/// ID of module containing symbol
-pub const R_TILEPRO_TLS_DTPMOD32: u32 = 82;
-/// Offset in TLS block
-pub const R_TILEPRO_TLS_DTPOFF32: u32 = 83;
-/// Offset in static TLS block
-pub const R_TILEPRO_TLS_TPOFF32: u32 = 84;
-/// X0 pipe 16-bit TLS LE offset
-pub const R_TILEPRO_IMM16_X0_TLS_LE: u32 = 85;
-/// X1 pipe 16-bit TLS LE offset
-pub const R_TILEPRO_IMM16_X1_TLS_LE: u32 = 86;
-/// X0 pipe low 16-bit TLS LE offset
-pub const R_TILEPRO_IMM16_X0_TLS_LE_LO: u32 = 87;
-/// X1 pipe low 16-bit TLS LE offset
-pub const R_TILEPRO_IMM16_X1_TLS_LE_LO: u32 = 88;
-/// X0 pipe high 16-bit TLS LE offset
-pub const R_TILEPRO_IMM16_X0_TLS_LE_HI: u32 = 89;
-/// X1 pipe high 16-bit TLS LE offset
-pub const R_TILEPRO_IMM16_X1_TLS_LE_HI: u32 = 90;
-/// X0 pipe ha() 16-bit TLS LE offset
-pub const R_TILEPRO_IMM16_X0_TLS_LE_HA: u32 = 91;
-/// X1 pipe ha() 16-bit TLS LE offset
-pub const R_TILEPRO_IMM16_X1_TLS_LE_HA: u32 = 92;
-
-/// GNU C++ vtable hierarchy
-pub const R_TILEPRO_GNU_VTINHERIT: u32 = 128;
-/// GNU C++ vtable member usage
-pub const R_TILEPRO_GNU_VTENTRY: u32 = 129;
-
-// TILE-Gx values `Rel*::r_type`.
-/// No reloc
-pub const R_TILEGX_NONE: u32 = 0;
-/// Direct 64 bit
-pub const R_TILEGX_64: u32 = 1;
-/// Direct 32 bit
-pub const R_TILEGX_32: u32 = 2;
-/// Direct 16 bit
-pub const R_TILEGX_16: u32 = 3;
-/// Direct 8 bit
-pub const R_TILEGX_8: u32 = 4;
-/// PC relative 64 bit
-pub const R_TILEGX_64_PCREL: u32 = 5;
-/// PC relative 32 bit
-pub const R_TILEGX_32_PCREL: u32 = 6;
-/// PC relative 16 bit
-pub const R_TILEGX_16_PCREL: u32 = 7;
-/// PC relative 8 bit
-pub const R_TILEGX_8_PCREL: u32 = 8;
-/// hword 0 16-bit
-pub const R_TILEGX_HW0: u32 = 9;
-/// hword 1 16-bit
-pub const R_TILEGX_HW1: u32 = 10;
-/// hword 2 16-bit
-pub const R_TILEGX_HW2: u32 = 11;
-/// hword 3 16-bit
-pub const R_TILEGX_HW3: u32 = 12;
-/// last hword 0 16-bit
-pub const R_TILEGX_HW0_LAST: u32 = 13;
-/// last hword 1 16-bit
-pub const R_TILEGX_HW1_LAST: u32 = 14;
-/// last hword 2 16-bit
-pub const R_TILEGX_HW2_LAST: u32 = 15;
-/// Copy relocation
-pub const R_TILEGX_COPY: u32 = 16;
-/// Create GOT entry
-pub const R_TILEGX_GLOB_DAT: u32 = 17;
-/// Create PLT entry
-pub const R_TILEGX_JMP_SLOT: u32 = 18;
-/// Adjust by program base
-pub const R_TILEGX_RELATIVE: u32 = 19;
-/// X1 pipe branch offset
-pub const R_TILEGX_BROFF_X1: u32 = 20;
-/// X1 pipe jump offset
-pub const R_TILEGX_JUMPOFF_X1: u32 = 21;
-/// X1 pipe jump offset to PLT
-pub const R_TILEGX_JUMPOFF_X1_PLT: u32 = 22;
-/// X0 pipe 8-bit
-pub const R_TILEGX_IMM8_X0: u32 = 23;
-/// Y0 pipe 8-bit
-pub const R_TILEGX_IMM8_Y0: u32 = 24;
-/// X1 pipe 8-bit
-pub const R_TILEGX_IMM8_X1: u32 = 25;
-/// Y1 pipe 8-bit
-pub const R_TILEGX_IMM8_Y1: u32 = 26;
-/// X1 pipe destination 8-bit
-pub const R_TILEGX_DEST_IMM8_X1: u32 = 27;
-/// X1 pipe mtspr
-pub const R_TILEGX_MT_IMM14_X1: u32 = 28;
-/// X1 pipe mfspr
-pub const R_TILEGX_MF_IMM14_X1: u32 = 29;
-/// X0 pipe mm "start"
-pub const R_TILEGX_MMSTART_X0: u32 = 30;
-/// X0 pipe mm "end"
-pub const R_TILEGX_MMEND_X0: u32 = 31;
-/// X0 pipe shift amount
-pub const R_TILEGX_SHAMT_X0: u32 = 32;
-/// X1 pipe shift amount
-pub const R_TILEGX_SHAMT_X1: u32 = 33;
-/// Y0 pipe shift amount
-pub const R_TILEGX_SHAMT_Y0: u32 = 34;
-/// Y1 pipe shift amount
-pub const R_TILEGX_SHAMT_Y1: u32 = 35;
-/// X0 pipe hword 0
-pub const R_TILEGX_IMM16_X0_HW0: u32 = 36;
-/// X1 pipe hword 0
-pub const R_TILEGX_IMM16_X1_HW0: u32 = 37;
-/// X0 pipe hword 1
-pub const R_TILEGX_IMM16_X0_HW1: u32 = 38;
-/// X1 pipe hword 1
-pub const R_TILEGX_IMM16_X1_HW1: u32 = 39;
-/// X0 pipe hword 2
-pub const R_TILEGX_IMM16_X0_HW2: u32 = 40;
-/// X1 pipe hword 2
-pub const R_TILEGX_IMM16_X1_HW2: u32 = 41;
-/// X0 pipe hword 3
-pub const R_TILEGX_IMM16_X0_HW3: u32 = 42;
-/// X1 pipe hword 3
-pub const R_TILEGX_IMM16_X1_HW3: u32 = 43;
-/// X0 pipe last hword 0
-pub const R_TILEGX_IMM16_X0_HW0_LAST: u32 = 44;
-/// X1 pipe last hword 0
-pub const R_TILEGX_IMM16_X1_HW0_LAST: u32 = 45;
-/// X0 pipe last hword 1
-pub const R_TILEGX_IMM16_X0_HW1_LAST: u32 = 46;
-/// X1 pipe last hword 1
-pub const R_TILEGX_IMM16_X1_HW1_LAST: u32 = 47;
-/// X0 pipe last hword 2
-pub const R_TILEGX_IMM16_X0_HW2_LAST: u32 = 48;
-/// X1 pipe last hword 2
-pub const R_TILEGX_IMM16_X1_HW2_LAST: u32 = 49;
-/// X0 pipe PC relative hword 0
-pub const R_TILEGX_IMM16_X0_HW0_PCREL: u32 = 50;
-/// X1 pipe PC relative hword 0
-pub const R_TILEGX_IMM16_X1_HW0_PCREL: u32 = 51;
-/// X0 pipe PC relative hword 1
-pub const R_TILEGX_IMM16_X0_HW1_PCREL: u32 = 52;
-/// X1 pipe PC relative hword 1
-pub const R_TILEGX_IMM16_X1_HW1_PCREL: u32 = 53;
-/// X0 pipe PC relative hword 2
-pub const R_TILEGX_IMM16_X0_HW2_PCREL: u32 = 54;
-/// X1 pipe PC relative hword 2
-pub const R_TILEGX_IMM16_X1_HW2_PCREL: u32 = 55;
-/// X0 pipe PC relative hword 3
-pub const R_TILEGX_IMM16_X0_HW3_PCREL: u32 = 56;
-/// X1 pipe PC relative hword 3
-pub const R_TILEGX_IMM16_X1_HW3_PCREL: u32 = 57;
-/// X0 pipe PC-rel last hword 0
-pub const R_TILEGX_IMM16_X0_HW0_LAST_PCREL: u32 = 58;
-/// X1 pipe PC-rel last hword 0
-pub const R_TILEGX_IMM16_X1_HW0_LAST_PCREL: u32 = 59;
-/// X0 pipe PC-rel last hword 1
-pub const R_TILEGX_IMM16_X0_HW1_LAST_PCREL: u32 = 60;
-/// X1 pipe PC-rel last hword 1
-pub const R_TILEGX_IMM16_X1_HW1_LAST_PCREL: u32 = 61;
-/// X0 pipe PC-rel last hword 2
-pub const R_TILEGX_IMM16_X0_HW2_LAST_PCREL: u32 = 62;
-/// X1 pipe PC-rel last hword 2
-pub const R_TILEGX_IMM16_X1_HW2_LAST_PCREL: u32 = 63;
-/// X0 pipe hword 0 GOT offset
-pub const R_TILEGX_IMM16_X0_HW0_GOT: u32 = 64;
-/// X1 pipe hword 0 GOT offset
-pub const R_TILEGX_IMM16_X1_HW0_GOT: u32 = 65;
-/// X0 pipe PC-rel PLT hword 0
-pub const R_TILEGX_IMM16_X0_HW0_PLT_PCREL: u32 = 66;
-/// X1 pipe PC-rel PLT hword 0
-pub const R_TILEGX_IMM16_X1_HW0_PLT_PCREL: u32 = 67;
-/// X0 pipe PC-rel PLT hword 1
-pub const R_TILEGX_IMM16_X0_HW1_PLT_PCREL: u32 = 68;
-/// X1 pipe PC-rel PLT hword 1
-pub const R_TILEGX_IMM16_X1_HW1_PLT_PCREL: u32 = 69;
-/// X0 pipe PC-rel PLT hword 2
-pub const R_TILEGX_IMM16_X0_HW2_PLT_PCREL: u32 = 70;
-/// X1 pipe PC-rel PLT hword 2
-pub const R_TILEGX_IMM16_X1_HW2_PLT_PCREL: u32 = 71;
-/// X0 pipe last hword 0 GOT offset
-pub const R_TILEGX_IMM16_X0_HW0_LAST_GOT: u32 = 72;
-/// X1 pipe last hword 0 GOT offset
-pub const R_TILEGX_IMM16_X1_HW0_LAST_GOT: u32 = 73;
-/// X0 pipe last hword 1 GOT offset
-pub const R_TILEGX_IMM16_X0_HW1_LAST_GOT: u32 = 74;
-/// X1 pipe last hword 1 GOT offset
-pub const R_TILEGX_IMM16_X1_HW1_LAST_GOT: u32 = 75;
-/// X0 pipe PC-rel PLT hword 3
-pub const R_TILEGX_IMM16_X0_HW3_PLT_PCREL: u32 = 76;
-/// X1 pipe PC-rel PLT hword 3
-pub const R_TILEGX_IMM16_X1_HW3_PLT_PCREL: u32 = 77;
-/// X0 pipe hword 0 TLS GD offset
-pub const R_TILEGX_IMM16_X0_HW0_TLS_GD: u32 = 78;
-/// X1 pipe hword 0 TLS GD offset
-pub const R_TILEGX_IMM16_X1_HW0_TLS_GD: u32 = 79;
-/// X0 pipe hword 0 TLS LE offset
-pub const R_TILEGX_IMM16_X0_HW0_TLS_LE: u32 = 80;
-/// X1 pipe hword 0 TLS LE offset
-pub const R_TILEGX_IMM16_X1_HW0_TLS_LE: u32 = 81;
-/// X0 pipe last hword 0 LE off
-pub const R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE: u32 = 82;
-/// X1 pipe last hword 0 LE off
-pub const R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: u32 = 83;
-/// X0 pipe last hword 1 LE off
-pub const R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: u32 = 84;
-/// X1 pipe last hword 1 LE off
-pub const R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: u32 = 85;
-/// X0 pipe last hword 0 GD off
-pub const R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: u32 = 86;
-/// X1 pipe last hword 0 GD off
-pub const R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: u32 = 87;
-/// X0 pipe last hword 1 GD off
-pub const R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: u32 = 88;
-/// X1 pipe last hword 1 GD off
-pub const R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: u32 = 89;
-// Relocs 90-91 are currently not defined.
-/// X0 pipe hword 0 TLS IE offset
-pub const R_TILEGX_IMM16_X0_HW0_TLS_IE: u32 = 92;
-/// X1 pipe hword 0 TLS IE offset
-pub const R_TILEGX_IMM16_X1_HW0_TLS_IE: u32 = 93;
-/// X0 pipe PC-rel PLT last hword 0
-pub const R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL: u32 = 94;
-/// X1 pipe PC-rel PLT last hword 0
-pub const R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL: u32 = 95;
-/// X0 pipe PC-rel PLT last hword 1
-pub const R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL: u32 = 96;
-/// X1 pipe PC-rel PLT last hword 1
-pub const R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL: u32 = 97;
-/// X0 pipe PC-rel PLT last hword 2
-pub const R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL: u32 = 98;
-/// X1 pipe PC-rel PLT last hword 2
-pub const R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL: u32 = 99;
-/// X0 pipe last hword 0 IE off
-pub const R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: u32 = 100;
-/// X1 pipe last hword 0 IE off
-pub const R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: u32 = 101;
-/// X0 pipe last hword 1 IE off
-pub const R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: u32 = 102;
-/// X1 pipe last hword 1 IE off
-pub const R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: u32 = 103;
-// Relocs 104-105 are currently not defined.
-/// 64-bit ID of symbol's module
-pub const R_TILEGX_TLS_DTPMOD64: u32 = 106;
-/// 64-bit offset in TLS block
-pub const R_TILEGX_TLS_DTPOFF64: u32 = 107;
-/// 64-bit offset in static TLS block
-pub const R_TILEGX_TLS_TPOFF64: u32 = 108;
-/// 32-bit ID of symbol's module
-pub const R_TILEGX_TLS_DTPMOD32: u32 = 109;
-/// 32-bit offset in TLS block
-pub const R_TILEGX_TLS_DTPOFF32: u32 = 110;
-/// 32-bit offset in static TLS block
-pub const R_TILEGX_TLS_TPOFF32: u32 = 111;
-/// "jal" for TLS GD
-pub const R_TILEGX_TLS_GD_CALL: u32 = 112;
-/// X0 pipe "addi" for TLS GD
-pub const R_TILEGX_IMM8_X0_TLS_GD_ADD: u32 = 113;
-/// X1 pipe "addi" for TLS GD
-pub const R_TILEGX_IMM8_X1_TLS_GD_ADD: u32 = 114;
-/// Y0 pipe "addi" for TLS GD
-pub const R_TILEGX_IMM8_Y0_TLS_GD_ADD: u32 = 115;
-/// Y1 pipe "addi" for TLS GD
-pub const R_TILEGX_IMM8_Y1_TLS_GD_ADD: u32 = 116;
-/// "ld_tls" for TLS IE
-pub const R_TILEGX_TLS_IE_LOAD: u32 = 117;
-/// X0 pipe "addi" for TLS GD/IE
-pub const R_TILEGX_IMM8_X0_TLS_ADD: u32 = 118;
-/// X1 pipe "addi" for TLS GD/IE
-pub const R_TILEGX_IMM8_X1_TLS_ADD: u32 = 119;
-/// Y0 pipe "addi" for TLS GD/IE
-pub const R_TILEGX_IMM8_Y0_TLS_ADD: u32 = 120;
-/// Y1 pipe "addi" for TLS GD/IE
-pub const R_TILEGX_IMM8_Y1_TLS_ADD: u32 = 121;
-
-/// GNU C++ vtable hierarchy
-pub const R_TILEGX_GNU_VTINHERIT: u32 = 128;
-/// GNU C++ vtable member usage
-pub const R_TILEGX_GNU_VTENTRY: u32 = 129;
-
-// RISC-V values `FileHeader*::e_flags`.
-pub const EF_RISCV_RVC: u32 = 0x0001;
-pub const EF_RISCV_FLOAT_ABI: u32 = 0x0006;
-pub const EF_RISCV_FLOAT_ABI_SOFT: u32 = 0x0000;
-pub const EF_RISCV_FLOAT_ABI_SINGLE: u32 = 0x0002;
-pub const EF_RISCV_FLOAT_ABI_DOUBLE: u32 = 0x0004;
-pub const EF_RISCV_FLOAT_ABI_QUAD: u32 = 0x0006;
-pub const EF_RISCV_RVE: u32 = 0x0008;
-pub const EF_RISCV_TSO: u32 = 0x0010;
-
-// RISC-V values `Rel*::r_type`.
-pub const R_RISCV_NONE: u32 = 0;
-pub const R_RISCV_32: u32 = 1;
-pub const R_RISCV_64: u32 = 2;
-pub const R_RISCV_RELATIVE: u32 = 3;
-pub const R_RISCV_COPY: u32 = 4;
-pub const R_RISCV_JUMP_SLOT: u32 = 5;
-pub const R_RISCV_TLS_DTPMOD32: u32 = 6;
-pub const R_RISCV_TLS_DTPMOD64: u32 = 7;
-pub const R_RISCV_TLS_DTPREL32: u32 = 8;
-pub const R_RISCV_TLS_DTPREL64: u32 = 9;
-pub const R_RISCV_TLS_TPREL32: u32 = 10;
-pub const R_RISCV_TLS_TPREL64: u32 = 11;
-pub const R_RISCV_BRANCH: u32 = 16;
-pub const R_RISCV_JAL: u32 = 17;
-pub const R_RISCV_CALL: u32 = 18;
-pub const R_RISCV_CALL_PLT: u32 = 19;
-pub const R_RISCV_GOT_HI20: u32 = 20;
-pub const R_RISCV_TLS_GOT_HI20: u32 = 21;
-pub const R_RISCV_TLS_GD_HI20: u32 = 22;
-pub const R_RISCV_PCREL_HI20: u32 = 23;
-pub const R_RISCV_PCREL_LO12_I: u32 = 24;
-pub const R_RISCV_PCREL_LO12_S: u32 = 25;
-pub const R_RISCV_HI20: u32 = 26;
-pub const R_RISCV_LO12_I: u32 = 27;
-pub const R_RISCV_LO12_S: u32 = 28;
-pub const R_RISCV_TPREL_HI20: u32 = 29;
-pub const R_RISCV_TPREL_LO12_I: u32 = 30;
-pub const R_RISCV_TPREL_LO12_S: u32 = 31;
-pub const R_RISCV_TPREL_ADD: u32 = 32;
-pub const R_RISCV_ADD8: u32 = 33;
-pub const R_RISCV_ADD16: u32 = 34;
-pub const R_RISCV_ADD32: u32 = 35;
-pub const R_RISCV_ADD64: u32 = 36;
-pub const R_RISCV_SUB8: u32 = 37;
-pub const R_RISCV_SUB16: u32 = 38;
-pub const R_RISCV_SUB32: u32 = 39;
-pub const R_RISCV_SUB64: u32 = 40;
-pub const R_RISCV_GNU_VTINHERIT: u32 = 41;
-pub const R_RISCV_GNU_VTENTRY: u32 = 42;
-pub const R_RISCV_ALIGN: u32 = 43;
-pub const R_RISCV_RVC_BRANCH: u32 = 44;
-pub const R_RISCV_RVC_JUMP: u32 = 45;
-pub const R_RISCV_RVC_LUI: u32 = 46;
-pub const R_RISCV_GPREL_I: u32 = 47;
-pub const R_RISCV_GPREL_S: u32 = 48;
-pub const R_RISCV_TPREL_I: u32 = 49;
-pub const R_RISCV_TPREL_S: u32 = 50;
-pub const R_RISCV_RELAX: u32 = 51;
-pub const R_RISCV_SUB6: u32 = 52;
-pub const R_RISCV_SET6: u32 = 53;
-pub const R_RISCV_SET8: u32 = 54;
-pub const R_RISCV_SET16: u32 = 55;
-pub const R_RISCV_SET32: u32 = 56;
-pub const R_RISCV_32_PCREL: u32 = 57;
-
-// BPF values `Rel*::r_type`.
-/// No reloc
-pub const R_BPF_NONE: u32 = 0;
-pub const R_BPF_64_64: u32 = 1;
-pub const R_BPF_64_32: u32 = 10;
-
-// SBF values `Rel*::r_type`.
-/// No reloc
-pub const R_SBF_NONE: u32 = 0;
-pub const R_SBF_64_64: u32 = 1;
-pub const R_SBF_64_32: u32 = 10;
-
-// Imagination Meta values `Rel*::r_type`.
-
-pub const R_METAG_HIADDR16: u32 = 0;
-pub const R_METAG_LOADDR16: u32 = 1;
-/// 32bit absolute address
-pub const R_METAG_ADDR32: u32 = 2;
-/// No reloc
-pub const R_METAG_NONE: u32 = 3;
-pub const R_METAG_RELBRANCH: u32 = 4;
-pub const R_METAG_GETSETOFF: u32 = 5;
-
-// Backward compatibility
-pub const R_METAG_REG32OP1: u32 = 6;
-pub const R_METAG_REG32OP2: u32 = 7;
-pub const R_METAG_REG32OP3: u32 = 8;
-pub const R_METAG_REG16OP1: u32 = 9;
-pub const R_METAG_REG16OP2: u32 = 10;
-pub const R_METAG_REG16OP3: u32 = 11;
-pub const R_METAG_REG32OP4: u32 = 12;
-
-pub const R_METAG_HIOG: u32 = 13;
-pub const R_METAG_LOOG: u32 = 14;
-
-pub const R_METAG_REL8: u32 = 15;
-pub const R_METAG_REL16: u32 = 16;
-
-pub const R_METAG_GNU_VTINHERIT: u32 = 30;
-pub const R_METAG_GNU_VTENTRY: u32 = 31;
-
-// PIC relocations
-pub const R_METAG_HI16_GOTOFF: u32 = 32;
-pub const R_METAG_LO16_GOTOFF: u32 = 33;
-pub const R_METAG_GETSET_GOTOFF: u32 = 34;
-pub const R_METAG_GETSET_GOT: u32 = 35;
-pub const R_METAG_HI16_GOTPC: u32 = 36;
-pub const R_METAG_LO16_GOTPC: u32 = 37;
-pub const R_METAG_HI16_PLT: u32 = 38;
-pub const R_METAG_LO16_PLT: u32 = 39;
-pub const R_METAG_RELBRANCH_PLT: u32 = 40;
-pub const R_METAG_GOTOFF: u32 = 41;
-pub const R_METAG_PLT: u32 = 42;
-pub const R_METAG_COPY: u32 = 43;
-pub const R_METAG_JMP_SLOT: u32 = 44;
-pub const R_METAG_RELATIVE: u32 = 45;
-pub const R_METAG_GLOB_DAT: u32 = 46;
-
-// TLS relocations
-pub const R_METAG_TLS_GD: u32 = 47;
-pub const R_METAG_TLS_LDM: u32 = 48;
-pub const R_METAG_TLS_LDO_HI16: u32 = 49;
-pub const R_METAG_TLS_LDO_LO16: u32 = 50;
-pub const R_METAG_TLS_LDO: u32 = 51;
-pub const R_METAG_TLS_IE: u32 = 52;
-pub const R_METAG_TLS_IENONPIC: u32 = 53;
-pub const R_METAG_TLS_IENONPIC_HI16: u32 = 54;
-pub const R_METAG_TLS_IENONPIC_LO16: u32 = 55;
-pub const R_METAG_TLS_TPOFF: u32 = 56;
-pub const R_METAG_TLS_DTPMOD: u32 = 57;
-pub const R_METAG_TLS_DTPOFF: u32 = 58;
-pub const R_METAG_TLS_LE: u32 = 59;
-pub const R_METAG_TLS_LE_HI16: u32 = 60;
-pub const R_METAG_TLS_LE_LO16: u32 = 61;
-
-// NDS32 values `Rel*::r_type`.
-pub const R_NDS32_NONE: u32 = 0;
-pub const R_NDS32_32_RELA: u32 = 20;
-pub const R_NDS32_COPY: u32 = 39;
-pub const R_NDS32_GLOB_DAT: u32 = 40;
-pub const R_NDS32_JMP_SLOT: u32 = 41;
-pub const R_NDS32_RELATIVE: u32 = 42;
-pub const R_NDS32_TLS_TPOFF: u32 = 102;
-pub const R_NDS32_TLS_DESC: u32 = 119;
-
-// LoongArch values `FileHeader*::e_flags`.
-/// Additional properties of the base ABI type, including the FP calling
-/// convention.
-pub const EF_LARCH_ABI_MODIFIER_MASK: u32 = 0x7;
-/// Uses GPRs and the stack for parameter passing
-pub const EF_LARCH_ABI_SOFT_FLOAT: u32 = 0x1;
-/// Uses GPRs, 32-bit FPRs and the stack for parameter passing
-pub const EF_LARCH_ABI_SINGLE_FLOAT: u32 = 0x2;
-/// Uses GPRs, 64-bit FPRs and the stack for parameter passing
-pub const EF_LARCH_ABI_DOUBLE_FLOAT: u32 = 0x3;
-/// Uses relocation types directly writing to immediate slots
-pub const EF_LARCH_OBJABI_V1: u32 = 0x40;
-
-// LoongArch values `Rel*::r_type`.
-/// No reloc
-pub const R_LARCH_NONE: u32 = 0;
-/// Runtime address resolving
-pub const R_LARCH_32: u32 = 1;
-/// Runtime address resolving
-pub const R_LARCH_64: u32 = 2;
-/// Runtime fixup for load-address
-pub const R_LARCH_RELATIVE: u32 = 3;
-/// Runtime memory copy in executable
-pub const R_LARCH_COPY: u32 = 4;
-/// Runtime PLT supporting
-pub const R_LARCH_JUMP_SLOT: u32 = 5;
-/// Runtime relocation for TLS-GD
-pub const R_LARCH_TLS_DTPMOD32: u32 = 6;
-/// Runtime relocation for TLS-GD
-pub const R_LARCH_TLS_DTPMOD64: u32 = 7;
-/// Runtime relocation for TLS-GD
-pub const R_LARCH_TLS_DTPREL32: u32 = 8;
-/// Runtime relocation for TLS-GD
-pub const R_LARCH_TLS_DTPREL64: u32 = 9;
-/// Runtime relocation for TLE-IE
-pub const R_LARCH_TLS_TPREL32: u32 = 10;
-/// Runtime relocation for TLE-IE
-pub const R_LARCH_TLS_TPREL64: u32 = 11;
-/// Runtime local indirect function resolving
-pub const R_LARCH_IRELATIVE: u32 = 12;
-/// Mark la.abs: load absolute address for static link.
-pub const R_LARCH_MARK_LA: u32 = 20;
-/// Mark external label branch: access PC relative address for static link.
-pub const R_LARCH_MARK_PCREL: u32 = 21;
-/// Push PC-relative offset
-pub const R_LARCH_SOP_PUSH_PCREL: u32 = 22;
-/// Push constant or absolute address
-pub const R_LARCH_SOP_PUSH_ABSOLUTE: u32 = 23;
-/// Duplicate stack top
-pub const R_LARCH_SOP_PUSH_DUP: u32 = 24;
-/// Push for access GOT entry
-pub const R_LARCH_SOP_PUSH_GPREL: u32 = 25;
-/// Push for TLS-LE
-pub const R_LARCH_SOP_PUSH_TLS_TPREL: u32 = 26;
-/// Push for TLS-IE
-pub const R_LARCH_SOP_PUSH_TLS_GOT: u32 = 27;
-/// Push for TLS-GD
-pub const R_LARCH_SOP_PUSH_TLS_GD: u32 = 28;
-/// Push for external function calling
-pub const R_LARCH_SOP_PUSH_PLT_PCREL: u32 = 29;
-/// Assert stack top
-pub const R_LARCH_SOP_ASSERT: u32 = 30;
-/// Stack top logical not (unary)
-pub const R_LARCH_SOP_NOT: u32 = 31;
-/// Stack top subtraction (binary)
-pub const R_LARCH_SOP_SUB: u32 = 32;
-/// Stack top left shift (binary)
-pub const R_LARCH_SOP_SL: u32 = 33;
-/// Stack top right shift (binary)
-pub const R_LARCH_SOP_SR: u32 = 34;
-/// Stack top addition (binary)
-pub const R_LARCH_SOP_ADD: u32 = 35;
-/// Stack top bitwise and (binary)
-pub const R_LARCH_SOP_AND: u32 = 36;
-/// Stack top selection (tertiary)
-pub const R_LARCH_SOP_IF_ELSE: u32 = 37;
-/// Pop stack top to fill 5-bit signed immediate operand
-pub const R_LARCH_SOP_POP_32_S_10_5: u32 = 38;
-/// Pop stack top to fill 12-bit unsigned immediate operand
-pub const R_LARCH_SOP_POP_32_U_10_12: u32 = 39;
-/// Pop stack top to fill 12-bit signed immediate operand
-pub const R_LARCH_SOP_POP_32_S_10_12: u32 = 40;
-/// Pop stack top to fill 16-bit signed immediate operand
-pub const R_LARCH_SOP_POP_32_S_10_16: u32 = 41;
-/// Pop stack top to fill 18-bit signed immediate operand with two trailing
-/// zeros implied
-pub const R_LARCH_SOP_POP_32_S_10_16_S2: u32 = 42;
-/// Pop stack top to fill 20-bit signed immediate operand
-pub const R_LARCH_SOP_POP_32_S_5_20: u32 = 43;
-/// Pop stack top to fill 23-bit signed immediate operand with two trailing
-/// zeros implied
-pub const R_LARCH_SOP_POP_32_S_0_5_10_16_S2: u32 = 44;
-/// Pop stack top to fill 28-bit signed immediate operand with two trailing
-/// zeros implied
-pub const R_LARCH_SOP_POP_32_S_0_10_10_16_S2: u32 = 45;
-/// Pop stack top to fill an instruction
-pub const R_LARCH_SOP_POP_32_U: u32 = 46;
-/// 8-bit in-place addition
-pub const R_LARCH_ADD8: u32 = 47;
-/// 16-bit in-place addition
-pub const R_LARCH_ADD16: u32 = 48;
-/// 24-bit in-place addition
-pub const R_LARCH_ADD24: u32 = 49;
-/// 32-bit in-place addition
-pub const R_LARCH_ADD32: u32 = 50;
-/// 64-bit in-place addition
-pub const R_LARCH_ADD64: u32 = 51;
-/// 8-bit in-place subtraction
-pub const R_LARCH_SUB8: u32 = 52;
-/// 16-bit in-place subtraction
-pub const R_LARCH_SUB16: u32 = 53;
-/// 24-bit in-place subtraction
-pub const R_LARCH_SUB24: u32 = 54;
-/// 32-bit in-place subtraction
-pub const R_LARCH_SUB32: u32 = 55;
-/// 64-bit in-place subtraction
-pub const R_LARCH_SUB64: u32 = 56;
-/// GNU C++ vtable hierarchy
-pub const R_LARCH_GNU_VTINHERIT: u32 = 57;
-/// GNU C++ vtable member usage
-pub const R_LARCH_GNU_VTENTRY: u32 = 58;
-/// 18-bit PC-relative jump offset with two trailing zeros
-pub const R_LARCH_B16: u32 = 64;
-/// 23-bit PC-relative jump offset with two trailing zeros
-pub const R_LARCH_B21: u32 = 65;
-/// 28-bit PC-relative jump offset with two trailing zeros
-pub const R_LARCH_B26: u32 = 66;
-/// 12..=31 bits of 32/64-bit absolute address
-pub const R_LARCH_ABS_HI20: u32 = 67;
-/// 0..=11 bits of 32/64-bit absolute address
-pub const R_LARCH_ABS_LO12: u32 = 68;
-/// 32..=51 bits of 64-bit absolute address
-pub const R_LARCH_ABS64_LO20: u32 = 69;
-/// 52..=63 bits of 64-bit absolute address
-pub const R_LARCH_ABS64_HI12: u32 = 70;
-/// The signed 32-bit offset `offs` from `PC & 0xfffff000` to
-/// `(S + A + 0x800) & 0xfffff000`, with 12 trailing zeros removed.
-///
-/// We define the *PC relative anchor* for `S + A` as `PC + offs` (`offs`
-/// is sign-extended to VA bits).
-pub const R_LARCH_PCALA_HI20: u32 = 71;
-/// Same as R_LARCH_ABS_LO12. 0..=11 bits of the 32/64-bit offset from the
-/// [PC relative anchor][R_LARCH_PCALA_HI20].
-pub const R_LARCH_PCALA_LO12: u32 = 72;
-/// 32..=51 bits of the 64-bit offset from the
-/// [PC relative anchor][R_LARCH_PCALA_HI20].
-pub const R_LARCH_PCALA64_LO20: u32 = 73;
-/// 52..=63 bits of the 64-bit offset from the
-/// [PC relative anchor][R_LARCH_PCALA_HI20].
-pub const R_LARCH_PCALA64_HI12: u32 = 74;
-/// The signed 32-bit offset `offs` from `PC & 0xfffff000` to
-/// `(GP + G + 0x800) & 0xfffff000`, with 12 trailing zeros removed.
-///
-/// We define the *PC relative anchor* for the GOT entry at `GP + G` as
-/// `PC + offs` (`offs` is sign-extended to VA bits).
-pub const R_LARCH_GOT_PC_HI20: u32 = 75;
-/// 0..=11 bits of the 32/64-bit offset from the
-/// [PC relative anchor][R_LARCH_GOT_PC_HI20] to the GOT entry.
-pub const R_LARCH_GOT_PC_LO12: u32 = 76;
-/// 32..=51 bits of the 64-bit offset from the
-/// [PC relative anchor][R_LARCH_GOT_PC_HI20] to the GOT entry.
-pub const R_LARCH_GOT64_PC_LO20: u32 = 77;
-/// 52..=63 bits of the 64-bit offset from the
-/// [PC relative anchor][R_LARCH_GOT_PC_HI20] to the GOT entry.
-pub const R_LARCH_GOT64_PC_HI12: u32 = 78;
-/// 12..=31 bits of 32/64-bit GOT entry absolute address
-pub const R_LARCH_GOT_HI20: u32 = 79;
-/// 0..=11 bits of 32/64-bit GOT entry absolute address
-pub const R_LARCH_GOT_LO12: u32 = 80;
-/// 32..=51 bits of 64-bit GOT entry absolute address
-pub const R_LARCH_GOT64_LO20: u32 = 81;
-/// 52..=63 bits of 64-bit GOT entry absolute address
-pub const R_LARCH_GOT64_HI12: u32 = 82;
-/// 12..=31 bits of TLS LE 32/64-bit offset from thread pointer
-pub const R_LARCH_TLS_LE_HI20: u32 = 83;
-/// 0..=11 bits of TLS LE 32/64-bit offset from thread pointer
-pub const R_LARCH_TLS_LE_LO12: u32 = 84;
-/// 32..=51 bits of TLS LE 64-bit offset from thread pointer
-pub const R_LARCH_TLS_LE64_LO20: u32 = 85;
-/// 52..=63 bits of TLS LE 64-bit offset from thread pointer
-pub const R_LARCH_TLS_LE64_HI12: u32 = 86;
-/// The signed 32-bit offset `offs` from `PC & 0xfffff000` to
-/// `(GP + IE + 0x800) & 0xfffff000`, with 12 trailing zeros removed.
-///
-/// We define the *PC relative anchor* for the TLS IE GOT entry at
-/// `GP + IE` as `PC + offs` (`offs` is sign-extended to VA bits).
-pub const R_LARCH_TLS_IE_PC_HI20: u32 = 87;
-/// 0..=12 bits of the 32/64-bit offset from the
-/// [PC-relative anchor][R_LARCH_TLS_IE_PC_HI20] to the TLS IE GOT entry.
-pub const R_LARCH_TLS_IE_PC_LO12: u32 = 88;
-/// 32..=51 bits of the 64-bit offset from the
-/// [PC-relative anchor][R_LARCH_TLS_IE_PC_HI20] to the TLS IE GOT entry.
-pub const R_LARCH_TLS_IE64_PC_LO20: u32 = 89;
-/// 52..=63 bits of the 64-bit offset from the
-/// [PC-relative anchor][R_LARCH_TLS_IE_PC_HI20] to the TLS IE GOT entry.
-pub const R_LARCH_TLS_IE64_PC_HI12: u32 = 90;
-/// 12..=31 bits of TLS IE GOT entry 32/64-bit absolute address
-pub const R_LARCH_TLS_IE_HI20: u32 = 91;
-/// 0..=11 bits of TLS IE GOT entry 32/64-bit absolute address
-pub const R_LARCH_TLS_IE_LO12: u32 = 92;
-/// 32..=51 bits of TLS IE GOT entry 64-bit absolute address
-pub const R_LARCH_TLS_IE64_LO20: u32 = 93;
-/// 51..=63 bits of TLS IE GOT entry 64-bit absolute address
-pub const R_LARCH_TLS_IE64_HI12: u32 = 94;
-/// 12..=31 bits of the offset from `PC` to `GP + GD + 0x800`, where
-/// `GP + GD` is a TLS LD GOT entry
-pub const R_LARCH_TLS_LD_PC_HI20: u32 = 95;
-/// 12..=31 bits of TLS LD GOT entry 32/64-bit absolute address
-pub const R_LARCH_TLS_LD_HI20: u32 = 96;
-/// 12..=31 bits of the 32/64-bit PC-relative offset to the PC-relative
-/// anchor for the TLE GD GOT entry.
-pub const R_LARCH_TLS_GD_PC_HI20: u32 = 97;
-/// 12..=31 bits of TLS GD GOT entry 32/64-bit absolute address
-pub const R_LARCH_TLS_GD_HI20: u32 = 98;
-/// 32-bit PC relative
-pub const R_LARCH_32_PCREL: u32 = 99;
-/// Paired with a normal relocation at the same address to indicate the
-/// instruction can be relaxed
-pub const R_LARCH_RELAX: u32 = 100;
-/// Reserved
-pub const R_LARCH_DELETE: u32 = 101;
-/// Delete some bytes to ensure the instruction at PC + A aligned to
-/// `A.next_power_of_two()`-byte boundary
-pub const R_LARCH_ALIGN: u32 = 102;
-/// 22-bit PC-relative offset with two trailing zeros
-pub const R_LARCH_PCREL20_S2: u32 = 103;
-/// Reserved
-pub const R_LARCH_CFA: u32 = 104;
-/// 6-bit in-place addition
-pub const R_LARCH_ADD6: u32 = 105;
-/// 6-bit in-place subtraction
-pub const R_LARCH_SUB6: u32 = 106;
-/// LEB128 in-place addition
-pub const R_LARCH_ADD_ULEB128: u32 = 107;
-/// LEB128 in-place subtraction
-pub const R_LARCH_SUB_ULEB128: u32 = 108;
-/// 64-bit PC relative
-pub const R_LARCH_64_PCREL: u32 = 109;
-/// 18..=37 bits of `S + A - PC` into the `pcaddu18i` instruction at `PC`,
-/// and 2..=17 bits of `S + A - PC` into the `jirl` instruction at `PC + 4`
-pub const R_LARCH_CALL36: u32 = 110;
-
-// Xtensa values Rel*::r_type`.
-pub const R_XTENSA_NONE: u32 = 0;
-pub const R_XTENSA_32: u32 = 1;
-pub const R_XTENSA_RTLD: u32 = 2;
-pub const R_XTENSA_GLOB_DAT: u32 = 3;
-pub const R_XTENSA_JMP_SLOT: u32 = 4;
-pub const R_XTENSA_RELATIVE: u32 = 5;
-pub const R_XTENSA_PLT: u32 = 6;
-pub const R_XTENSA_OP0: u32 = 8;
-pub const R_XTENSA_OP1: u32 = 9;
-pub const R_XTENSA_OP2: u32 = 10;
-pub const R_XTENSA_ASM_EXPAND: u32 = 11;
-pub const R_XTENSA_ASM_SIMPLIFY: u32 = 12;
-pub const R_XTENSA_32_PCREL: u32 = 14;
-pub const R_XTENSA_GNU_VTINHERIT: u32 = 15;
-pub const R_XTENSA_GNU_VTENTRY: u32 = 16;
-pub const R_XTENSA_DIFF8: u32 = 17;
-pub const R_XTENSA_DIFF16: u32 = 18;
-pub const R_XTENSA_DIFF32: u32 = 19;
-pub const R_XTENSA_SLOT0_OP: u32 = 20;
-pub const R_XTENSA_SLOT1_OP: u32 = 21;
-pub const R_XTENSA_SLOT2_OP: u32 = 22;
-pub const R_XTENSA_SLOT3_OP: u32 = 23;
-pub const R_XTENSA_SLOT4_OP: u32 = 24;
-pub const R_XTENSA_SLOT5_OP: u32 = 25;
-pub const R_XTENSA_SLOT6_OP: u32 = 26;
-pub const R_XTENSA_SLOT7_OP: u32 = 27;
-pub const R_XTENSA_SLOT8_OP: u32 = 28;
-pub const R_XTENSA_SLOT9_OP: u32 = 29;
-pub const R_XTENSA_SLOT10_OP: u32 = 30;
-pub const R_XTENSA_SLOT11_OP: u32 = 31;
-pub const R_XTENSA_SLOT12_OP: u32 = 32;
-pub const R_XTENSA_SLOT13_OP: u32 = 33;
-pub const R_XTENSA_SLOT14_OP: u32 = 34;
-pub const R_XTENSA_SLOT0_ALT: u32 = 35;
-pub const R_XTENSA_SLOT1_ALT: u32 = 36;
-pub const R_XTENSA_SLOT2_ALT: u32 = 37;
-pub const R_XTENSA_SLOT3_ALT: u32 = 38;
-pub const R_XTENSA_SLOT4_ALT: u32 = 39;
-pub const R_XTENSA_SLOT5_ALT: u32 = 40;
-pub const R_XTENSA_SLOT6_ALT: u32 = 41;
-pub const R_XTENSA_SLOT7_ALT: u32 = 42;
-pub const R_XTENSA_SLOT8_ALT: u32 = 43;
-pub const R_XTENSA_SLOT9_ALT: u32 = 44;
-pub const R_XTENSA_SLOT10_ALT: u32 = 45;
-pub const R_XTENSA_SLOT11_ALT: u32 = 46;
-pub const R_XTENSA_SLOT12_ALT: u32 = 47;
-pub const R_XTENSA_SLOT13_ALT: u32 = 48;
-pub const R_XTENSA_SLOT14_ALT: u32 = 49;
-pub const R_XTENSA_TLSDESC_FN: u32 = 50;
-pub const R_XTENSA_TLSDESC_ARG: u32 = 51;
-pub const R_XTENSA_TLS_DTPOFF: u32 = 52;
-pub const R_XTENSA_TLS_TPOFF: u32 = 53;
-pub const R_XTENSA_TLS_FUNC: u32 = 54;
-pub const R_XTENSA_TLS_ARG: u32 = 55;
-pub const R_XTENSA_TLS_CALL: u32 = 56;
-pub const R_XTENSA_PDIFF8: u32 = 57;
-pub const R_XTENSA_PDIFF16: u32 = 58;
-pub const R_XTENSA_PDIFF32: u32 = 59;
-pub const R_XTENSA_NDIFF8: u32 = 60;
-pub const R_XTENSA_NDIFF16: u32 = 61;
-pub const R_XTENSA_NDIFF32: u32 = 62;
-
-#[allow(non_upper_case_globals)]
-pub const Tag_File: u8 = 1;
-#[allow(non_upper_case_globals)]
-pub const Tag_Section: u8 = 2;
-#[allow(non_upper_case_globals)]
-pub const Tag_Symbol: u8 = 3;
-
-unsafe_impl_endian_pod!(
- FileHeader32,
- FileHeader64,
- SectionHeader32,
- SectionHeader64,
- CompressionHeader32,
- CompressionHeader64,
- Sym32,
- Sym64,
- Syminfo32,
- Syminfo64,
- Rel32,
- Rel64,
- Rela32,
- Rela64,
- ProgramHeader32,
- ProgramHeader64,
- Dyn32,
- Dyn64,
- Versym,
- Verdef,
- Verdaux,
- Verneed,
- Vernaux,
- NoteHeader32,
- NoteHeader64,
- HashHeader,
- GnuHashHeader,
-);
diff --git a/vendor/object/src/endian.rs b/vendor/object/src/endian.rs
deleted file mode 100644
index e4a36ba..0000000
--- a/vendor/object/src/endian.rs
+++ /dev/null
@@ -1,831 +0,0 @@
-//! Types for compile-time and run-time endianness.
-
-use crate::pod::Pod;
-use core::fmt::{self, Debug};
-use core::marker::PhantomData;
-
-/// A trait for using an endianness specification.
-///
-/// Provides methods for converting between the specified endianness and
-/// the native endianness of the target machine.
-///
-/// This trait does not require that the endianness is known at compile time.
-pub trait Endian: Debug + Default + Clone + Copy + PartialEq + Eq + 'static {
- /// Construct a specification for the endianness of some values.
- ///
- /// Returns `None` if the type does not support specifying the given endianness.
- fn from_big_endian(big_endian: bool) -> Option<Self>;
-
- /// Construct a specification for the endianness of some values.
- ///
- /// Returns `None` if the type does not support specifying the given endianness.
- fn from_little_endian(little_endian: bool) -> Option<Self> {
- Self::from_big_endian(!little_endian)
- }
-
- /// Return true for big endian byte order.
- fn is_big_endian(self) -> bool;
-
- /// Return true for little endian byte order.
- #[inline]
- fn is_little_endian(self) -> bool {
- !self.is_big_endian()
- }
-
- /// Converts an unsigned 16 bit integer to native endian.
- #[inline]
- fn read_u16(self, n: u16) -> u16 {
- if self.is_big_endian() {
- u16::from_be(n)
- } else {
- u16::from_le(n)
- }
- }
-
- /// Converts an unsigned 32 bit integer to native endian.
- #[inline]
- fn read_u32(self, n: u32) -> u32 {
- if self.is_big_endian() {
- u32::from_be(n)
- } else {
- u32::from_le(n)
- }
- }
-
- /// Converts an unsigned 64 bit integer to native endian.
- #[inline]
- fn read_u64(self, n: u64) -> u64 {
- if self.is_big_endian() {
- u64::from_be(n)
- } else {
- u64::from_le(n)
- }
- }
-
- /// Converts a signed 16 bit integer to native endian.
- #[inline]
- fn read_i16(self, n: i16) -> i16 {
- if self.is_big_endian() {
- i16::from_be(n)
- } else {
- i16::from_le(n)
- }
- }
-
- /// Converts a signed 32 bit integer to native endian.
- #[inline]
- fn read_i32(self, n: i32) -> i32 {
- if self.is_big_endian() {
- i32::from_be(n)
- } else {
- i32::from_le(n)
- }
- }
-
- /// Converts a signed 64 bit integer to native endian.
- #[inline]
- fn read_i64(self, n: i64) -> i64 {
- if self.is_big_endian() {
- i64::from_be(n)
- } else {
- i64::from_le(n)
- }
- }
-
- /// Converts an unaligned unsigned 16 bit integer to native endian.
- #[inline]
- fn read_u16_bytes(self, n: [u8; 2]) -> u16 {
- if self.is_big_endian() {
- u16::from_be_bytes(n)
- } else {
- u16::from_le_bytes(n)
- }
- }
-
- /// Converts an unaligned unsigned 32 bit integer to native endian.
- #[inline]
- fn read_u32_bytes(self, n: [u8; 4]) -> u32 {
- if self.is_big_endian() {
- u32::from_be_bytes(n)
- } else {
- u32::from_le_bytes(n)
- }
- }
-
- /// Converts an unaligned unsigned 64 bit integer to native endian.
- #[inline]
- fn read_u64_bytes(self, n: [u8; 8]) -> u64 {
- if self.is_big_endian() {
- u64::from_be_bytes(n)
- } else {
- u64::from_le_bytes(n)
- }
- }
-
- /// Converts an unaligned signed 16 bit integer to native endian.
- #[inline]
- fn read_i16_bytes(self, n: [u8; 2]) -> i16 {
- if self.is_big_endian() {
- i16::from_be_bytes(n)
- } else {
- i16::from_le_bytes(n)
- }
- }
-
- /// Converts an unaligned signed 32 bit integer to native endian.
- #[inline]
- fn read_i32_bytes(self, n: [u8; 4]) -> i32 {
- if self.is_big_endian() {
- i32::from_be_bytes(n)
- } else {
- i32::from_le_bytes(n)
- }
- }
-
- /// Converts an unaligned signed 64 bit integer to native endian.
- #[inline]
- fn read_i64_bytes(self, n: [u8; 8]) -> i64 {
- if self.is_big_endian() {
- i64::from_be_bytes(n)
- } else {
- i64::from_le_bytes(n)
- }
- }
-
- /// Converts an unsigned 16 bit integer from native endian.
- #[inline]
- fn write_u16(self, n: u16) -> u16 {
- if self.is_big_endian() {
- u16::to_be(n)
- } else {
- u16::to_le(n)
- }
- }
-
- /// Converts an unsigned 32 bit integer from native endian.
- #[inline]
- fn write_u32(self, n: u32) -> u32 {
- if self.is_big_endian() {
- u32::to_be(n)
- } else {
- u32::to_le(n)
- }
- }
-
- /// Converts an unsigned 64 bit integer from native endian.
- #[inline]
- fn write_u64(self, n: u64) -> u64 {
- if self.is_big_endian() {
- u64::to_be(n)
- } else {
- u64::to_le(n)
- }
- }
-
- /// Converts a signed 16 bit integer from native endian.
- #[inline]
- fn write_i16(self, n: i16) -> i16 {
- if self.is_big_endian() {
- i16::to_be(n)
- } else {
- i16::to_le(n)
- }
- }
-
- /// Converts a signed 32 bit integer from native endian.
- #[inline]
- fn write_i32(self, n: i32) -> i32 {
- if self.is_big_endian() {
- i32::to_be(n)
- } else {
- i32::to_le(n)
- }
- }
-
- /// Converts a signed 64 bit integer from native endian.
- #[inline]
- fn write_i64(self, n: i64) -> i64 {
- if self.is_big_endian() {
- i64::to_be(n)
- } else {
- i64::to_le(n)
- }
- }
-
- /// Converts an unaligned unsigned 16 bit integer from native endian.
- #[inline]
- fn write_u16_bytes(self, n: u16) -> [u8; 2] {
- if self.is_big_endian() {
- u16::to_be_bytes(n)
- } else {
- u16::to_le_bytes(n)
- }
- }
-
- /// Converts an unaligned unsigned 32 bit integer from native endian.
- #[inline]
- fn write_u32_bytes(self, n: u32) -> [u8; 4] {
- if self.is_big_endian() {
- u32::to_be_bytes(n)
- } else {
- u32::to_le_bytes(n)
- }
- }
-
- /// Converts an unaligned unsigned 64 bit integer from native endian.
- #[inline]
- fn write_u64_bytes(self, n: u64) -> [u8; 8] {
- if self.is_big_endian() {
- u64::to_be_bytes(n)
- } else {
- u64::to_le_bytes(n)
- }
- }
-
- /// Converts an unaligned signed 16 bit integer from native endian.
- #[inline]
- fn write_i16_bytes(self, n: i16) -> [u8; 2] {
- if self.is_big_endian() {
- i16::to_be_bytes(n)
- } else {
- i16::to_le_bytes(n)
- }
- }
-
- /// Converts an unaligned signed 32 bit integer from native endian.
- #[inline]
- fn write_i32_bytes(self, n: i32) -> [u8; 4] {
- if self.is_big_endian() {
- i32::to_be_bytes(n)
- } else {
- i32::to_le_bytes(n)
- }
- }
-
- /// Converts an unaligned signed 64 bit integer from native endian.
- #[inline]
- fn write_i64_bytes(self, n: i64) -> [u8; 8] {
- if self.is_big_endian() {
- i64::to_be_bytes(n)
- } else {
- i64::to_le_bytes(n)
- }
- }
-}
-
-/// An endianness that is selectable at run-time.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub enum Endianness {
- /// Little endian byte order.
- Little,
- /// Big endian byte order.
- Big,
-}
-
-impl Default for Endianness {
- #[cfg(target_endian = "little")]
- #[inline]
- fn default() -> Endianness {
- Endianness::Little
- }
-
- #[cfg(target_endian = "big")]
- #[inline]
- fn default() -> Endianness {
- Endianness::Big
- }
-}
-
-impl Endian for Endianness {
- #[inline]
- fn from_big_endian(big_endian: bool) -> Option<Self> {
- Some(if big_endian {
- Endianness::Big
- } else {
- Endianness::Little
- })
- }
-
- #[inline]
- fn is_big_endian(self) -> bool {
- self != Endianness::Little
- }
-}
-
-/// Compile-time little endian byte order.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct LittleEndian;
-
-impl Default for LittleEndian {
- #[inline]
- fn default() -> LittleEndian {
- LittleEndian
- }
-}
-
-impl Endian for LittleEndian {
- #[inline]
- fn from_big_endian(big_endian: bool) -> Option<Self> {
- if big_endian {
- None
- } else {
- Some(LittleEndian)
- }
- }
-
- #[inline]
- fn is_big_endian(self) -> bool {
- false
- }
-}
-
-/// Compile-time big endian byte order.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct BigEndian;
-
-impl Default for BigEndian {
- #[inline]
- fn default() -> BigEndian {
- BigEndian
- }
-}
-
-impl Endian for BigEndian {
- #[inline]
- fn from_big_endian(big_endian: bool) -> Option<Self> {
- if big_endian {
- Some(BigEndian)
- } else {
- None
- }
- }
-
- #[inline]
- fn is_big_endian(self) -> bool {
- true
- }
-}
-
-/// The native endianness for the target platform.
-#[cfg(target_endian = "little")]
-pub type NativeEndian = LittleEndian;
-
-#[cfg(target_endian = "little")]
-#[allow(non_upper_case_globals)]
-#[doc(hidden)]
-pub const NativeEndian: LittleEndian = LittleEndian;
-
-/// The native endianness for the target platform.
-#[cfg(target_endian = "big")]
-pub type NativeEndian = BigEndian;
-
-#[cfg(target_endian = "big")]
-#[allow(non_upper_case_globals)]
-#[doc(hidden)]
-pub const NativeEndian: BigEndian = BigEndian;
-
-macro_rules! unsafe_impl_endian_pod {
- ($($struct_name:ident),+ $(,)?) => {
- $(
- unsafe impl<E: Endian> Pod for $struct_name<E> { }
- )+
- }
-}
-
-#[cfg(not(feature = "unaligned"))]
-mod aligned {
- use super::{fmt, Endian, PhantomData, Pod};
-
- /// A `u16` value with an externally specified endianness of type `E`.
- #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
- #[repr(transparent)]
- pub struct U16<E: Endian>(u16, PhantomData<E>);
-
- impl<E: Endian> U16<E> {
- /// Construct a new value given bytes that already have the required endianness.
- pub fn from_bytes(n: [u8; 2]) -> Self {
- Self(u16::from_ne_bytes(n), PhantomData)
- }
-
- /// Construct a new value given a native endian value.
- pub fn new(e: E, n: u16) -> Self {
- Self(e.write_u16(n), PhantomData)
- }
-
- /// Return the value as a native endian value.
- pub fn get(self, e: E) -> u16 {
- e.read_u16(self.0)
- }
-
- /// Set the value given a native endian value.
- pub fn set(&mut self, e: E, n: u16) {
- self.0 = e.write_u16(n);
- }
- }
-
- /// A `u32` value with an externally specified endianness of type `E`.
- #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
- #[repr(transparent)]
- pub struct U32<E: Endian>(u32, PhantomData<E>);
-
- impl<E: Endian> U32<E> {
- /// Construct a new value given bytes that already have the required endianness.
- pub fn from_bytes(n: [u8; 4]) -> Self {
- Self(u32::from_ne_bytes(n), PhantomData)
- }
-
- /// Construct a new value given a native endian value.
- pub fn new(e: E, n: u32) -> Self {
- Self(e.write_u32(n), PhantomData)
- }
- /// Return the value as a native endian value.
- pub fn get(self, e: E) -> u32 {
- e.read_u32(self.0)
- }
- /// Set the value given a native endian value.
- pub fn set(&mut self, e: E, n: u32) {
- self.0 = e.write_u32(n);
- }
- }
-
- /// A `u64` value with an externally specified endianness of type `E`.
- #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
- #[repr(transparent)]
- pub struct U64<E: Endian>(u64, PhantomData<E>);
-
- impl<E: Endian> U64<E> {
- /// Construct a new value given bytes that already have the required endianness.
- pub fn from_bytes(n: [u8; 8]) -> Self {
- Self(u64::from_ne_bytes(n), PhantomData)
- }
-
- /// Construct a new value given a native endian value.
- pub fn new(e: E, n: u64) -> Self {
- Self(e.write_u64(n), PhantomData)
- }
- /// Return the value as a native endian value.
- pub fn get(self, e: E) -> u64 {
- e.read_u64(self.0)
- }
- /// Set the value given a native endian value.
- pub fn set(&mut self, e: E, n: u64) {
- self.0 = e.write_u64(n);
- }
- }
-
- /// An `i16` value with an externally specified endianness of type `E`.
- #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
- #[repr(transparent)]
- pub struct I16<E: Endian>(i16, PhantomData<E>);
-
- impl<E: Endian> I16<E> {
- /// Construct a new value given bytes that already have the required endianness.
- pub fn from_bytes(n: [u8; 2]) -> Self {
- Self(i16::from_ne_bytes(n), PhantomData)
- }
-
- /// Construct a new value given a native endian value.
- pub fn new(e: E, n: i16) -> Self {
- Self(e.write_i16(n), PhantomData)
- }
- /// Return the value as a native endian value.
- pub fn get(self, e: E) -> i16 {
- e.read_i16(self.0)
- }
- /// Set the value given a native endian value.
- pub fn set(&mut self, e: E, n: i16) {
- self.0 = e.write_i16(n);
- }
- }
-
- /// An `i32` value with an externally specified endianness of type `E`.
- #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
- #[repr(transparent)]
- pub struct I32<E: Endian>(i32, PhantomData<E>);
-
- impl<E: Endian> I32<E> {
- /// Construct a new value given bytes that already have the required endianness.
- pub fn from_bytes(n: [u8; 4]) -> Self {
- Self(i32::from_ne_bytes(n), PhantomData)
- }
-
- /// Construct a new value given a native endian value.
- pub fn new(e: E, n: i32) -> Self {
- Self(e.write_i32(n), PhantomData)
- }
- /// Return the value as a native endian value.
- pub fn get(self, e: E) -> i32 {
- e.read_i32(self.0)
- }
- /// Set the value given a native endian value.
- pub fn set(&mut self, e: E, n: i32) {
- self.0 = e.write_i32(n);
- }
- }
-
- /// An `i64` value with an externally specified endianness of type `E`.
- #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
- #[repr(transparent)]
- pub struct I64<E: Endian>(i64, PhantomData<E>);
-
- impl<E: Endian> I64<E> {
- /// Construct a new value given bytes that already have the required endianness.
- pub fn from_bytes(n: [u8; 8]) -> Self {
- Self(i64::from_ne_bytes(n), PhantomData)
- }
-
- /// Construct a new value given a native endian value.
- pub fn new(e: E, n: i64) -> Self {
- Self(e.write_i64(n), PhantomData)
- }
- /// Return the value as a native endian value.
- pub fn get(self, e: E) -> i64 {
- e.read_i64(self.0)
- }
- /// Set the value given a native endian value.
- pub fn set(&mut self, e: E, n: i64) {
- self.0 = e.write_i64(n);
- }
- }
-
- impl<E: Endian> fmt::Debug for U16<E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "U16({:x})", self.0)
- }
- }
-
- impl<E: Endian> fmt::Debug for U32<E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "U32({:x})", self.0)
- }
- }
-
- impl<E: Endian> fmt::Debug for U64<E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "U64({:x})", self.0)
- }
- }
-
- impl<E: Endian> fmt::Debug for I16<E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "I16({:x})", self.0)
- }
- }
-
- impl<E: Endian> fmt::Debug for I32<E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "I32({:x})", self.0)
- }
- }
-
- impl<E: Endian> fmt::Debug for I64<E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "I64({:x})", self.0)
- }
- }
-
- unsafe_impl_endian_pod!(U16, U32, U64, I16, I32, I64);
-}
-
-#[cfg(not(feature = "unaligned"))]
-pub use aligned::*;
-
-/// A `u16` value with an externally specified endianness of type `E`.
-#[cfg(feature = "unaligned")]
-pub type U16<E> = U16Bytes<E>;
-
-/// A `u32` value with an externally specified endianness of type `E`.
-#[cfg(feature = "unaligned")]
-pub type U32<E> = U32Bytes<E>;
-
-/// A `u64` value with an externally specified endianness of type `E`.
-#[cfg(feature = "unaligned")]
-pub type U64<E> = U64Bytes<E>;
-
-/// An `i16` value with an externally specified endianness of type `E`.
-#[cfg(feature = "unaligned")]
-pub type I16<E> = I16Bytes<E>;
-
-/// An `i32` value with an externally specified endianness of type `E`.
-#[cfg(feature = "unaligned")]
-pub type I32<E> = I32Bytes<E>;
-
-/// An `i64` value with an externally specified endianness of type `E`.
-#[cfg(feature = "unaligned")]
-pub type I64<E> = I64Bytes<E>;
-
-/// An unaligned `u16` value with an externally specified endianness of type `E`.
-#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[repr(transparent)]
-pub struct U16Bytes<E: Endian>([u8; 2], PhantomData<E>);
-
-impl<E: Endian> U16Bytes<E> {
- /// Construct a new value given bytes that already have the required endianness.
- pub fn from_bytes(n: [u8; 2]) -> Self {
- Self(n, PhantomData)
- }
-
- /// Construct a new value given a native endian value.
- pub fn new(e: E, n: u16) -> Self {
- Self(e.write_u16_bytes(n), PhantomData)
- }
-
- /// Return the value as a native endian value.
- pub fn get(self, e: E) -> u16 {
- e.read_u16_bytes(self.0)
- }
-
- /// Set the value given a native endian value.
- pub fn set(&mut self, e: E, n: u16) {
- self.0 = e.write_u16_bytes(n);
- }
-}
-
-/// An unaligned `u32` value with an externally specified endianness of type `E`.
-#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[repr(transparent)]
-pub struct U32Bytes<E: Endian>([u8; 4], PhantomData<E>);
-
-impl<E: Endian> U32Bytes<E> {
- /// Construct a new value given bytes that already have the required endianness.
- pub fn from_bytes(n: [u8; 4]) -> Self {
- Self(n, PhantomData)
- }
-
- /// Construct a new value given a native endian value.
- pub fn new(e: E, n: u32) -> Self {
- Self(e.write_u32_bytes(n), PhantomData)
- }
-
- /// Return the value as a native endian value.
- pub fn get(self, e: E) -> u32 {
- e.read_u32_bytes(self.0)
- }
-
- /// Set the value given a native endian value.
- pub fn set(&mut self, e: E, n: u32) {
- self.0 = e.write_u32_bytes(n);
- }
-}
-
-/// An unaligned `u64` value with an externally specified endianness of type `E`.
-#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[repr(transparent)]
-pub struct U64Bytes<E: Endian>([u8; 8], PhantomData<E>);
-
-impl<E: Endian> U64Bytes<E> {
- /// Construct a new value given bytes that already have the required endianness.
- pub fn from_bytes(n: [u8; 8]) -> Self {
- Self(n, PhantomData)
- }
-
- /// Construct a new value given a native endian value.
- pub fn new(e: E, n: u64) -> Self {
- Self(e.write_u64_bytes(n), PhantomData)
- }
-
- /// Return the value as a native endian value.
- pub fn get(self, e: E) -> u64 {
- e.read_u64_bytes(self.0)
- }
-
- /// Set the value given a native endian value.
- pub fn set(&mut self, e: E, n: u64) {
- self.0 = e.write_u64_bytes(n);
- }
-}
-
-/// An unaligned `i16` value with an externally specified endianness of type `E`.
-#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[repr(transparent)]
-pub struct I16Bytes<E: Endian>([u8; 2], PhantomData<E>);
-
-impl<E: Endian> I16Bytes<E> {
- /// Construct a new value given bytes that already have the required endianness.
- pub fn from_bytes(n: [u8; 2]) -> Self {
- Self(n, PhantomData)
- }
-
- /// Construct a new value given a native endian value.
- pub fn new(e: E, n: i16) -> Self {
- Self(e.write_i16_bytes(n), PhantomData)
- }
-
- /// Return the value as a native endian value.
- pub fn get(self, e: E) -> i16 {
- e.read_i16_bytes(self.0)
- }
-
- /// Set the value given a native endian value.
- pub fn set(&mut self, e: E, n: i16) {
- self.0 = e.write_i16_bytes(n);
- }
-}
-
-/// An unaligned `i32` value with an externally specified endianness of type `E`.
-#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[repr(transparent)]
-pub struct I32Bytes<E: Endian>([u8; 4], PhantomData<E>);
-
-impl<E: Endian> I32Bytes<E> {
- /// Construct a new value given bytes that already have the required endianness.
- pub fn from_bytes(n: [u8; 4]) -> Self {
- Self(n, PhantomData)
- }
-
- /// Construct a new value given a native endian value.
- pub fn new(e: E, n: i32) -> Self {
- Self(e.write_i32_bytes(n), PhantomData)
- }
-
- /// Return the value as a native endian value.
- pub fn get(self, e: E) -> i32 {
- e.read_i32_bytes(self.0)
- }
-
- /// Set the value given a native endian value.
- pub fn set(&mut self, e: E, n: i32) {
- self.0 = e.write_i32_bytes(n);
- }
-}
-
-/// An unaligned `i64` value with an externally specified endianness of type `E`.
-#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[repr(transparent)]
-pub struct I64Bytes<E: Endian>([u8; 8], PhantomData<E>);
-
-impl<E: Endian> I64Bytes<E> {
- /// Construct a new value given bytes that already have the required endianness.
- pub fn from_bytes(n: [u8; 8]) -> Self {
- Self(n, PhantomData)
- }
-
- /// Construct a new value given a native endian value.
- pub fn new(e: E, n: i64) -> Self {
- Self(e.write_i64_bytes(n), PhantomData)
- }
-
- /// Return the value as a native endian value.
- pub fn get(self, e: E) -> i64 {
- e.read_i64_bytes(self.0)
- }
-
- /// Set the value given a native endian value.
- pub fn set(&mut self, e: E, n: i64) {
- self.0 = e.write_i64_bytes(n);
- }
-}
-
-impl<E: Endian> fmt::Debug for U16Bytes<E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "U16({:x}, {:x})", self.0[0], self.0[1],)
- }
-}
-
-impl<E: Endian> fmt::Debug for U32Bytes<E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "U32({:x}, {:x}, {:x}, {:x})",
- self.0[0], self.0[1], self.0[2], self.0[3],
- )
- }
-}
-
-impl<E: Endian> fmt::Debug for U64Bytes<E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "U64({:x}, {:x}, {:x}, {:x}, {:x}, {:x}, {:x}, {:x})",
- self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7],
- )
- }
-}
-
-impl<E: Endian> fmt::Debug for I16Bytes<E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "I16({:x}, {:x})", self.0[0], self.0[1],)
- }
-}
-
-impl<E: Endian> fmt::Debug for I32Bytes<E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "I32({:x}, {:x}, {:x}, {:x})",
- self.0[0], self.0[1], self.0[2], self.0[3],
- )
- }
-}
-
-impl<E: Endian> fmt::Debug for I64Bytes<E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "I64({:x}, {:x}, {:x}, {:x}, {:x}, {:x}, {:x}, {:x})",
- self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7],
- )
- }
-}
-
-unsafe_impl_endian_pod!(U16Bytes, U32Bytes, U64Bytes, I16Bytes, I32Bytes, I64Bytes);
diff --git a/vendor/object/src/lib.rs b/vendor/object/src/lib.rs
deleted file mode 100644
index 5956e06..0000000
--- a/vendor/object/src/lib.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-//! # `object`
-//!
-//! The `object` crate provides a unified interface to working with object files
-//! across platforms. It supports reading relocatable object files and executable files,
-//! and writing relocatable object files and some executable files.
-//!
-//! ## Raw struct definitions
-//!
-//! Raw structs are defined for: [ELF](elf), [Mach-O](macho), [PE/COFF](pe),
-//! [XCOFF](xcoff), [archive].
-//! Types and traits for zerocopy support are defined in the [`pod`] and [`endian`] modules.
-//!
-//! ## Unified read API
-//!
-//! The [`read`] module provides a unified read API using the [`read::Object`] trait.
-//! There is an implementation of this trait for [`read::File`], which allows reading any
-//! file format, as well as implementations for each file format.
-//!
-//! ## Low level read API
-//!
-//! The [`read#modules`] submodules define helpers that operate on the raw structs.
-//! These can be used instead of the unified API, or in conjunction with it to access
-//! details that are not available via the unified API.
-//!
-//! ## Unified write API
-//!
-//! The [`mod@write`] module provides a unified write API for relocatable object files
-//! using [`write::Object`]. This does not support writing executable files.
-//!
-//! ## Low level write API
-//!
-//! The [`mod@write#modules`] submodules define helpers for writing the raw structs.
-//!
-//! ## Shared definitions
-//!
-//! The crate provides a number of definitions that are used by both the read and write
-//! APIs. These are defined at the top level module, but none of these are the main entry
-//! points of the crate.
-
-#![deny(missing_docs)]
-#![deny(missing_debug_implementations)]
-#![no_std]
-#![warn(rust_2018_idioms)]
-// Style.
-#![allow(clippy::collapsible_if)]
-#![allow(clippy::comparison_chain)]
-#![allow(clippy::manual_flatten)]
-#![allow(clippy::match_like_matches_macro)]
-#![allow(clippy::single_match)]
-#![allow(clippy::type_complexity)]
-// Occurs due to fallible iteration.
-#![allow(clippy::should_implement_trait)]
-// Unit errors are converted to other types by callers.
-#![allow(clippy::result_unit_err)]
-// Worse readability sometimes.
-#![allow(clippy::collapsible_else_if)]
-
-#[cfg(feature = "cargo-all")]
-compile_error!("'--all-features' is not supported; use '--features all' instead");
-
-#[cfg(any(feature = "read_core", feature = "write_core"))]
-#[allow(unused_imports)]
-#[macro_use]
-extern crate alloc;
-
-#[cfg(feature = "std")]
-#[allow(unused_imports)]
-#[macro_use]
-extern crate std;
-
-mod common;
-pub use common::*;
-
-#[macro_use]
-pub mod endian;
-pub use endian::*;
-
-#[macro_use]
-pub mod pod;
-pub use pod::*;
-
-#[cfg(feature = "read_core")]
-pub mod read;
-#[cfg(feature = "read_core")]
-pub use read::*;
-
-#[cfg(feature = "write_core")]
-pub mod write;
-
-#[cfg(feature = "archive")]
-pub mod archive;
-#[cfg(feature = "elf")]
-pub mod elf;
-#[cfg(feature = "macho")]
-pub mod macho;
-#[cfg(any(feature = "coff", feature = "pe"))]
-pub mod pe;
-#[cfg(feature = "xcoff")]
-pub mod xcoff;
diff --git a/vendor/object/src/macho.rs b/vendor/object/src/macho.rs
deleted file mode 100644
index 3cd38e0..0000000
--- a/vendor/object/src/macho.rs
+++ /dev/null
@@ -1,3307 +0,0 @@
-//! Mach-O definitions.
-//!
-//! These definitions are independent of read/write support, although we do implement
-//! some traits useful for those.
-//!
-//! This module is based heavily on header files from MacOSX11.1.sdk.
-
-#![allow(missing_docs)]
-
-use crate::endian::{BigEndian, Endian, U64Bytes, U16, U32, U64};
-use crate::pod::Pod;
-
-// Definitions from "/usr/include/mach/machine.h".
-
-/*
- * Capability bits used in the definition of cpu_type.
- */
-
-/// mask for architecture bits
-pub const CPU_ARCH_MASK: u32 = 0xff00_0000;
-/// 64 bit ABI
-pub const CPU_ARCH_ABI64: u32 = 0x0100_0000;
-/// ABI for 64-bit hardware with 32-bit types; LP32
-pub const CPU_ARCH_ABI64_32: u32 = 0x0200_0000;
-
-/*
- * Machine types known by all.
- */
-
-pub const CPU_TYPE_ANY: u32 = !0;
-
-pub const CPU_TYPE_VAX: u32 = 1;
-pub const CPU_TYPE_MC680X0: u32 = 6;
-pub const CPU_TYPE_X86: u32 = 7;
-pub const CPU_TYPE_X86_64: u32 = CPU_TYPE_X86 | CPU_ARCH_ABI64;
-pub const CPU_TYPE_MIPS: u32 = 8;
-pub const CPU_TYPE_MC98000: u32 = 10;
-pub const CPU_TYPE_HPPA: u32 = 11;
-pub const CPU_TYPE_ARM: u32 = 12;
-pub const CPU_TYPE_ARM64: u32 = CPU_TYPE_ARM | CPU_ARCH_ABI64;
-pub const CPU_TYPE_ARM64_32: u32 = CPU_TYPE_ARM | CPU_ARCH_ABI64_32;
-pub const CPU_TYPE_MC88000: u32 = 13;
-pub const CPU_TYPE_SPARC: u32 = 14;
-pub const CPU_TYPE_I860: u32 = 15;
-pub const CPU_TYPE_ALPHA: u32 = 16;
-pub const CPU_TYPE_POWERPC: u32 = 18;
-pub const CPU_TYPE_POWERPC64: u32 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64;
-
-/*
- * Capability bits used in the definition of cpu_subtype.
- */
-/// mask for feature flags
-pub const CPU_SUBTYPE_MASK: u32 = 0xff00_0000;
-/// 64 bit libraries
-pub const CPU_SUBTYPE_LIB64: u32 = 0x8000_0000;
-/// pointer authentication with versioned ABI
-pub const CPU_SUBTYPE_PTRAUTH_ABI: u32 = 0x8000_0000;
-
-/// When selecting a slice, ANY will pick the slice with the best
-/// grading for the selected cpu_type_t, unlike the "ALL" subtypes,
-/// which are the slices that can run on any hardware for that cpu type.
-pub const CPU_SUBTYPE_ANY: u32 = !0;
-
-/*
- * Object files that are hand-crafted to run on any
- * implementation of an architecture are tagged with
- * CPU_SUBTYPE_MULTIPLE. This functions essentially the same as
- * the "ALL" subtype of an architecture except that it allows us
- * to easily find object files that may need to be modified
- * whenever a new implementation of an architecture comes out.
- *
- * It is the responsibility of the implementor to make sure the
- * software handles unsupported implementations elegantly.
- */
-pub const CPU_SUBTYPE_MULTIPLE: u32 = !0;
-pub const CPU_SUBTYPE_LITTLE_ENDIAN: u32 = 0;
-pub const CPU_SUBTYPE_BIG_ENDIAN: u32 = 1;
-
-/*
- * VAX subtypes (these do *not* necessary conform to the actual cpu
- * ID assigned by DEC available via the SID register).
- */
-
-pub const CPU_SUBTYPE_VAX_ALL: u32 = 0;
-pub const CPU_SUBTYPE_VAX780: u32 = 1;
-pub const CPU_SUBTYPE_VAX785: u32 = 2;
-pub const CPU_SUBTYPE_VAX750: u32 = 3;
-pub const CPU_SUBTYPE_VAX730: u32 = 4;
-pub const CPU_SUBTYPE_UVAXI: u32 = 5;
-pub const CPU_SUBTYPE_UVAXII: u32 = 6;
-pub const CPU_SUBTYPE_VAX8200: u32 = 7;
-pub const CPU_SUBTYPE_VAX8500: u32 = 8;
-pub const CPU_SUBTYPE_VAX8600: u32 = 9;
-pub const CPU_SUBTYPE_VAX8650: u32 = 10;
-pub const CPU_SUBTYPE_VAX8800: u32 = 11;
-pub const CPU_SUBTYPE_UVAXIII: u32 = 12;
-
-/*
- * 680x0 subtypes
- *
- * The subtype definitions here are unusual for historical reasons.
- * NeXT used to consider 68030 code as generic 68000 code. For
- * backwards compatibility:
- *
- * CPU_SUBTYPE_MC68030 symbol has been preserved for source code
- * compatibility.
- *
- * CPU_SUBTYPE_MC680x0_ALL has been defined to be the same
- * subtype as CPU_SUBTYPE_MC68030 for binary comatability.
- *
- * CPU_SUBTYPE_MC68030_ONLY has been added to allow new object
- * files to be tagged as containing 68030-specific instructions.
- */
-
-pub const CPU_SUBTYPE_MC680X0_ALL: u32 = 1;
-// compat
-pub const CPU_SUBTYPE_MC68030: u32 = 1;
-pub const CPU_SUBTYPE_MC68040: u32 = 2;
-pub const CPU_SUBTYPE_MC68030_ONLY: u32 = 3;
-
-/*
- * I386 subtypes
- */
-
-#[inline]
-pub const fn cpu_subtype_intel(f: u32, m: u32) -> u32 {
- f + (m << 4)
-}
-
-pub const CPU_SUBTYPE_I386_ALL: u32 = cpu_subtype_intel(3, 0);
-pub const CPU_SUBTYPE_386: u32 = cpu_subtype_intel(3, 0);
-pub const CPU_SUBTYPE_486: u32 = cpu_subtype_intel(4, 0);
-pub const CPU_SUBTYPE_486SX: u32 = cpu_subtype_intel(4, 8);
-pub const CPU_SUBTYPE_586: u32 = cpu_subtype_intel(5, 0);
-pub const CPU_SUBTYPE_PENT: u32 = cpu_subtype_intel(5, 0);
-pub const CPU_SUBTYPE_PENTPRO: u32 = cpu_subtype_intel(6, 1);
-pub const CPU_SUBTYPE_PENTII_M3: u32 = cpu_subtype_intel(6, 3);
-pub const CPU_SUBTYPE_PENTII_M5: u32 = cpu_subtype_intel(6, 5);
-pub const CPU_SUBTYPE_CELERON: u32 = cpu_subtype_intel(7, 6);
-pub const CPU_SUBTYPE_CELERON_MOBILE: u32 = cpu_subtype_intel(7, 7);
-pub const CPU_SUBTYPE_PENTIUM_3: u32 = cpu_subtype_intel(8, 0);
-pub const CPU_SUBTYPE_PENTIUM_3_M: u32 = cpu_subtype_intel(8, 1);
-pub const CPU_SUBTYPE_PENTIUM_3_XEON: u32 = cpu_subtype_intel(8, 2);
-pub const CPU_SUBTYPE_PENTIUM_M: u32 = cpu_subtype_intel(9, 0);
-pub const CPU_SUBTYPE_PENTIUM_4: u32 = cpu_subtype_intel(10, 0);
-pub const CPU_SUBTYPE_PENTIUM_4_M: u32 = cpu_subtype_intel(10, 1);
-pub const CPU_SUBTYPE_ITANIUM: u32 = cpu_subtype_intel(11, 0);
-pub const CPU_SUBTYPE_ITANIUM_2: u32 = cpu_subtype_intel(11, 1);
-pub const CPU_SUBTYPE_XEON: u32 = cpu_subtype_intel(12, 0);
-pub const CPU_SUBTYPE_XEON_MP: u32 = cpu_subtype_intel(12, 1);
-
-#[inline]
-pub const fn cpu_subtype_intel_family(x: u32) -> u32 {
- x & 15
-}
-pub const CPU_SUBTYPE_INTEL_FAMILY_MAX: u32 = 15;
-
-#[inline]
-pub const fn cpu_subtype_intel_model(x: u32) -> u32 {
- x >> 4
-}
-pub const CPU_SUBTYPE_INTEL_MODEL_ALL: u32 = 0;
-
-/*
- * X86 subtypes.
- */
-
-pub const CPU_SUBTYPE_X86_ALL: u32 = 3;
-pub const CPU_SUBTYPE_X86_64_ALL: u32 = 3;
-pub const CPU_SUBTYPE_X86_ARCH1: u32 = 4;
-/// Haswell feature subset
-pub const CPU_SUBTYPE_X86_64_H: u32 = 8;
-
-/*
- * Mips subtypes.
- */
-
-pub const CPU_SUBTYPE_MIPS_ALL: u32 = 0;
-pub const CPU_SUBTYPE_MIPS_R2300: u32 = 1;
-pub const CPU_SUBTYPE_MIPS_R2600: u32 = 2;
-pub const CPU_SUBTYPE_MIPS_R2800: u32 = 3;
-/// pmax
-pub const CPU_SUBTYPE_MIPS_R2000A: u32 = 4;
-pub const CPU_SUBTYPE_MIPS_R2000: u32 = 5;
-/// 3max
-pub const CPU_SUBTYPE_MIPS_R3000A: u32 = 6;
-pub const CPU_SUBTYPE_MIPS_R3000: u32 = 7;
-
-/*
- * MC98000 (PowerPC) subtypes
- */
-pub const CPU_SUBTYPE_MC98000_ALL: u32 = 0;
-pub const CPU_SUBTYPE_MC98601: u32 = 1;
-
-/*
- * HPPA subtypes for Hewlett-Packard HP-PA family of
- * risc processors. Port by NeXT to 700 series.
- */
-
-pub const CPU_SUBTYPE_HPPA_ALL: u32 = 0;
-pub const CPU_SUBTYPE_HPPA_7100LC: u32 = 1;
-
-/*
- * MC88000 subtypes.
- */
-pub const CPU_SUBTYPE_MC88000_ALL: u32 = 0;
-pub const CPU_SUBTYPE_MC88100: u32 = 1;
-pub const CPU_SUBTYPE_MC88110: u32 = 2;
-
-/*
- * SPARC subtypes
- */
-pub const CPU_SUBTYPE_SPARC_ALL: u32 = 0;
-
-/*
- * I860 subtypes
- */
-pub const CPU_SUBTYPE_I860_ALL: u32 = 0;
-pub const CPU_SUBTYPE_I860_860: u32 = 1;
-
-/*
- * PowerPC subtypes
- */
-pub const CPU_SUBTYPE_POWERPC_ALL: u32 = 0;
-pub const CPU_SUBTYPE_POWERPC_601: u32 = 1;
-pub const CPU_SUBTYPE_POWERPC_602: u32 = 2;
-pub const CPU_SUBTYPE_POWERPC_603: u32 = 3;
-pub const CPU_SUBTYPE_POWERPC_603E: u32 = 4;
-pub const CPU_SUBTYPE_POWERPC_603EV: u32 = 5;
-pub const CPU_SUBTYPE_POWERPC_604: u32 = 6;
-pub const CPU_SUBTYPE_POWERPC_604E: u32 = 7;
-pub const CPU_SUBTYPE_POWERPC_620: u32 = 8;
-pub const CPU_SUBTYPE_POWERPC_750: u32 = 9;
-pub const CPU_SUBTYPE_POWERPC_7400: u32 = 10;
-pub const CPU_SUBTYPE_POWERPC_7450: u32 = 11;
-pub const CPU_SUBTYPE_POWERPC_970: u32 = 100;
-
-/*
- * ARM subtypes
- */
-pub const CPU_SUBTYPE_ARM_ALL: u32 = 0;
-pub const CPU_SUBTYPE_ARM_V4T: u32 = 5;
-pub const CPU_SUBTYPE_ARM_V6: u32 = 6;
-pub const CPU_SUBTYPE_ARM_V5TEJ: u32 = 7;
-pub const CPU_SUBTYPE_ARM_XSCALE: u32 = 8;
-/// ARMv7-A and ARMv7-R
-pub const CPU_SUBTYPE_ARM_V7: u32 = 9;
-/// Cortex A9
-pub const CPU_SUBTYPE_ARM_V7F: u32 = 10;
-/// Swift
-pub const CPU_SUBTYPE_ARM_V7S: u32 = 11;
-pub const CPU_SUBTYPE_ARM_V7K: u32 = 12;
-pub const CPU_SUBTYPE_ARM_V8: u32 = 13;
-/// Not meant to be run under xnu
-pub const CPU_SUBTYPE_ARM_V6M: u32 = 14;
-/// Not meant to be run under xnu
-pub const CPU_SUBTYPE_ARM_V7M: u32 = 15;
-/// Not meant to be run under xnu
-pub const CPU_SUBTYPE_ARM_V7EM: u32 = 16;
-/// Not meant to be run under xnu
-pub const CPU_SUBTYPE_ARM_V8M: u32 = 17;
-
-/*
- * ARM64 subtypes
- */
-pub const CPU_SUBTYPE_ARM64_ALL: u32 = 0;
-pub const CPU_SUBTYPE_ARM64_V8: u32 = 1;
-pub const CPU_SUBTYPE_ARM64E: u32 = 2;
-
-/*
- * ARM64_32 subtypes
- */
-pub const CPU_SUBTYPE_ARM64_32_ALL: u32 = 0;
-pub const CPU_SUBTYPE_ARM64_32_V8: u32 = 1;
-
-// Definitions from "/usr/include/mach/vm_prot.h".
-
-/// read permission
-pub const VM_PROT_READ: u32 = 0x01;
-/// write permission
-pub const VM_PROT_WRITE: u32 = 0x02;
-/// execute permission
-pub const VM_PROT_EXECUTE: u32 = 0x04;
-
-// Definitions from https://opensource.apple.com/source/dyld/dyld-210.2.3/launch-cache/dyld_cache_format.h.auto.html
-
-/// The dyld cache header.
-/// Corresponds to struct dyld_cache_header from dyld_cache_format.h.
-/// This header has grown over time. Only the fields up to and including dyld_base_address
-/// are guaranteed to be present. For all other fields, check the header size before
-/// accessing the field. The header size is stored in mapping_offset; the mappings start
-/// right after the theader.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DyldCacheHeader<E: Endian> {
- /// e.g. "dyld_v0 i386"
- pub magic: [u8; 16],
- /// file offset to first dyld_cache_mapping_info
- pub mapping_offset: U32<E>, // offset: 0x10
- /// number of dyld_cache_mapping_info entries
- pub mapping_count: U32<E>, // offset: 0x14
- /// file offset to first dyld_cache_image_info
- pub images_offset: U32<E>, // offset: 0x18
- /// number of dyld_cache_image_info entries
- pub images_count: U32<E>, // offset: 0x1c
- /// base address of dyld when cache was built
- pub dyld_base_address: U64<E>, // offset: 0x20
- ///
- reserved1: [u8; 32], // offset: 0x28
- /// file offset of where local symbols are stored
- pub local_symbols_offset: U64<E>, // offset: 0x48
- /// size of local symbols information
- pub local_symbols_size: U64<E>, // offset: 0x50
- /// unique value for each shared cache file
- pub uuid: [u8; 16], // offset: 0x58
- ///
- reserved2: [u8; 32], // offset: 0x68
- ///
- reserved3: [u8; 32], // offset: 0x88
- ///
- reserved4: [u8; 32], // offset: 0xa8
- ///
- reserved5: [u8; 32], // offset: 0xc8
- ///
- reserved6: [u8; 32], // offset: 0xe8
- ///
- reserved7: [u8; 32], // offset: 0x108
- ///
- reserved8: [u8; 32], // offset: 0x128
- ///
- reserved9: [u8; 32], // offset: 0x148
- ///
- reserved10: [u8; 32], // offset: 0x168
- /// file offset to first dyld_subcache_info
- pub subcaches_offset: U32<E>, // offset: 0x188
- /// number of dyld_subcache_info entries
- pub subcaches_count: U32<E>, // offset: 0x18c
- /// the UUID of the .symbols subcache
- pub symbols_subcache_uuid: [u8; 16], // offset: 0x190
- ///
- reserved11: [u8; 32], // offset: 0x1a0
- /// file offset to first dyld_cache_image_info
- /// Use this instead of images_offset if mapping_offset is at least 0x1c4.
- pub images_across_all_subcaches_offset: U32<E>, // offset: 0x1c0
- /// number of dyld_cache_image_info entries
- /// Use this instead of images_count if mapping_offset is at least 0x1c4.
- pub images_across_all_subcaches_count: U32<E>, // offset: 0x1c4
-}
-
-/// Corresponds to struct dyld_cache_mapping_info from dyld_cache_format.h.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DyldCacheMappingInfo<E: Endian> {
- ///
- pub address: U64<E>,
- ///
- pub size: U64<E>,
- ///
- pub file_offset: U64<E>,
- ///
- pub max_prot: U32<E>,
- ///
- pub init_prot: U32<E>,
-}
-
-/// Corresponds to struct dyld_cache_image_info from dyld_cache_format.h.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DyldCacheImageInfo<E: Endian> {
- ///
- pub address: U64<E>,
- ///
- pub mod_time: U64<E>,
- ///
- pub inode: U64<E>,
- ///
- pub path_file_offset: U32<E>,
- ///
- pub pad: U32<E>,
-}
-
-/// Corresponds to a struct whose source code has not been published as of Nov 2021.
-/// Added in the dyld cache version which shipped with macOS 12 / iOS 15.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DyldSubCacheInfo<E: Endian> {
- /// The UUID of this subcache.
- pub uuid: [u8; 16],
- /// The size of this subcache plus all previous subcaches.
- pub cumulative_size: U64<E>,
-}
-
-// Definitions from "/usr/include/mach-o/loader.h".
-
-/*
- * This header file describes the structures of the file format for "fat"
- * architecture specific file (wrapper design). At the beginning of the file
- * there is one `FatHeader` structure followed by a number of `FatArch*`
- * structures. For each architecture in the file, specified by a pair of
- * cputype and cpusubtype, the `FatHeader` describes the file offset, file
- * size and alignment in the file of the architecture specific member.
- * The padded bytes in the file to place each member on it's specific alignment
- * are defined to be read as zeros and can be left as "holes" if the file system
- * can support them as long as they read as zeros.
- *
- * All structures defined here are always written and read to/from disk
- * in big-endian order.
- */
-
-pub const FAT_MAGIC: u32 = 0xcafe_babe;
-/// NXSwapLong(FAT_MAGIC)
-pub const FAT_CIGAM: u32 = 0xbeba_feca;
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FatHeader {
- /// FAT_MAGIC or FAT_MAGIC_64
- pub magic: U32<BigEndian>,
- /// number of structs that follow
- pub nfat_arch: U32<BigEndian>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FatArch32 {
- /// cpu specifier (int)
- pub cputype: U32<BigEndian>,
- /// machine specifier (int)
- pub cpusubtype: U32<BigEndian>,
- /// file offset to this object file
- pub offset: U32<BigEndian>,
- /// size of this object file
- pub size: U32<BigEndian>,
- /// alignment as a power of 2
- pub align: U32<BigEndian>,
-}
-
-/*
- * The support for the 64-bit fat file format described here is a work in
- * progress and not yet fully supported in all the Apple Developer Tools.
- *
- * When a slice is greater than 4mb or an offset to a slice is greater than 4mb
- * then the 64-bit fat file format is used.
- */
-pub const FAT_MAGIC_64: u32 = 0xcafe_babf;
-/// NXSwapLong(FAT_MAGIC_64)
-pub const FAT_CIGAM_64: u32 = 0xbfba_feca;
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FatArch64 {
- /// cpu specifier (int)
- pub cputype: U32<BigEndian>,
- /// machine specifier (int)
- pub cpusubtype: U32<BigEndian>,
- /// file offset to this object file
- pub offset: U64<BigEndian>,
- /// size of this object file
- pub size: U64<BigEndian>,
- /// alignment as a power of 2
- pub align: U32<BigEndian>,
- /// reserved
- pub reserved: U32<BigEndian>,
-}
-
-// Definitions from "/usr/include/mach-o/loader.h".
-
-/// The 32-bit mach header.
-///
-/// Appears at the very beginning of the object file for 32-bit architectures.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct MachHeader32<E: Endian> {
- /// mach magic number identifier
- pub magic: U32<BigEndian>,
- /// cpu specifier
- pub cputype: U32<E>,
- /// machine specifier
- pub cpusubtype: U32<E>,
- /// type of file
- pub filetype: U32<E>,
- /// number of load commands
- pub ncmds: U32<E>,
- /// the size of all the load commands
- pub sizeofcmds: U32<E>,
- /// flags
- pub flags: U32<E>,
-}
-
-// Values for `MachHeader32::magic`.
-/// the mach magic number
-pub const MH_MAGIC: u32 = 0xfeed_face;
-/// NXSwapInt(MH_MAGIC)
-pub const MH_CIGAM: u32 = 0xcefa_edfe;
-
-/// The 64-bit mach header.
-///
-/// Appears at the very beginning of object files for 64-bit architectures.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct MachHeader64<E: Endian> {
- /// mach magic number identifier
- pub magic: U32<BigEndian>,
- /// cpu specifier
- pub cputype: U32<E>,
- /// machine specifier
- pub cpusubtype: U32<E>,
- /// type of file
- pub filetype: U32<E>,
- /// number of load commands
- pub ncmds: U32<E>,
- /// the size of all the load commands
- pub sizeofcmds: U32<E>,
- /// flags
- pub flags: U32<E>,
- /// reserved
- pub reserved: U32<E>,
-}
-
-// Values for `MachHeader64::magic`.
-/// the 64-bit mach magic number
-pub const MH_MAGIC_64: u32 = 0xfeed_facf;
-/// NXSwapInt(MH_MAGIC_64)
-pub const MH_CIGAM_64: u32 = 0xcffa_edfe;
-
-/*
- * The layout of the file depends on the filetype. For all but the MH_OBJECT
- * file type the segments are padded out and aligned on a segment alignment
- * boundary for efficient demand pageing. The MH_EXECUTE, MH_FVMLIB, MH_DYLIB,
- * MH_DYLINKER and MH_BUNDLE file types also have the headers included as part
- * of their first segment.
- *
- * The file type MH_OBJECT is a compact format intended as output of the
- * assembler and input (and possibly output) of the link editor (the .o
- * format). All sections are in one unnamed segment with no segment padding.
- * This format is used as an executable format when the file is so small the
- * segment padding greatly increases its size.
- *
- * The file type MH_PRELOAD is an executable format intended for things that
- * are not executed under the kernel (proms, stand alones, kernels, etc). The
- * format can be executed under the kernel but may demand paged it and not
- * preload it before execution.
- *
- * A core file is in MH_CORE format and can be any in an arbritray legal
- * Mach-O file.
- */
-
-// Values for `MachHeader*::filetype`.
-/// relocatable object file
-pub const MH_OBJECT: u32 = 0x1;
-/// demand paged executable file
-pub const MH_EXECUTE: u32 = 0x2;
-/// fixed VM shared library file
-pub const MH_FVMLIB: u32 = 0x3;
-/// core file
-pub const MH_CORE: u32 = 0x4;
-/// preloaded executable file
-pub const MH_PRELOAD: u32 = 0x5;
-/// dynamically bound shared library
-pub const MH_DYLIB: u32 = 0x6;
-/// dynamic link editor
-pub const MH_DYLINKER: u32 = 0x7;
-/// dynamically bound bundle file
-pub const MH_BUNDLE: u32 = 0x8;
-/// shared library stub for static linking only, no section contents
-pub const MH_DYLIB_STUB: u32 = 0x9;
-/// companion file with only debug sections
-pub const MH_DSYM: u32 = 0xa;
-/// x86_64 kexts
-pub const MH_KEXT_BUNDLE: u32 = 0xb;
-/// set of mach-o's
-pub const MH_FILESET: u32 = 0xc;
-
-// Values for `MachHeader*::flags`.
-/// the object file has no undefined references
-pub const MH_NOUNDEFS: u32 = 0x1;
-/// the object file is the output of an incremental link against a base file and can't be link edited again
-pub const MH_INCRLINK: u32 = 0x2;
-/// the object file is input for the dynamic linker and can't be statically link edited again
-pub const MH_DYLDLINK: u32 = 0x4;
-/// the object file's undefined references are bound by the dynamic linker when loaded.
-pub const MH_BINDATLOAD: u32 = 0x8;
-/// the file has its dynamic undefined references prebound.
-pub const MH_PREBOUND: u32 = 0x10;
-/// the file has its read-only and read-write segments split
-pub const MH_SPLIT_SEGS: u32 = 0x20;
-/// the shared library init routine is to be run lazily via catching memory faults to its writeable segments (obsolete)
-pub const MH_LAZY_INIT: u32 = 0x40;
-/// the image is using two-level name space bindings
-pub const MH_TWOLEVEL: u32 = 0x80;
-/// the executable is forcing all images to use flat name space bindings
-pub const MH_FORCE_FLAT: u32 = 0x100;
-/// this umbrella guarantees no multiple definitions of symbols in its sub-images so the two-level namespace hints can always be used.
-pub const MH_NOMULTIDEFS: u32 = 0x200;
-/// do not have dyld notify the prebinding agent about this executable
-pub const MH_NOFIXPREBINDING: u32 = 0x400;
-/// the binary is not prebound but can have its prebinding redone. only used when MH_PREBOUND is not set.
-pub const MH_PREBINDABLE: u32 = 0x800;
-/// indicates that this binary binds to all two-level namespace modules of its dependent libraries. only used when MH_PREBINDABLE and MH_TWOLEVEL are both set.
-pub const MH_ALLMODSBOUND: u32 = 0x1000;
-/// safe to divide up the sections into sub-sections via symbols for dead code stripping
-pub const MH_SUBSECTIONS_VIA_SYMBOLS: u32 = 0x2000;
-/// the binary has been canonicalized via the unprebind operation
-pub const MH_CANONICAL: u32 = 0x4000;
-/// the final linked image contains external weak symbols
-pub const MH_WEAK_DEFINES: u32 = 0x8000;
-/// the final linked image uses weak symbols
-pub const MH_BINDS_TO_WEAK: u32 = 0x10000;
-/// When this bit is set, all stacks in the task will be given stack execution privilege. Only used in MH_EXECUTE filetypes.
-pub const MH_ALLOW_STACK_EXECUTION: u32 = 0x20000;
-/// When this bit is set, the binary declares it is safe for use in processes with uid zero
-pub const MH_ROOT_SAFE: u32 = 0x40000;
-/// When this bit is set, the binary declares it is safe for use in processes when issetugid() is true
-pub const MH_SETUID_SAFE: u32 = 0x80000;
-/// When this bit is set on a dylib, the static linker does not need to examine dependent dylibs to see if any are re-exported
-pub const MH_NO_REEXPORTED_DYLIBS: u32 = 0x10_0000;
-/// When this bit is set, the OS will load the main executable at a random address. Only used in MH_EXECUTE filetypes.
-pub const MH_PIE: u32 = 0x20_0000;
-/// Only for use on dylibs. When linking against a dylib that has this bit set, the static linker will automatically not create a LC_LOAD_DYLIB load command to the dylib if no symbols are being referenced from the dylib.
-pub const MH_DEAD_STRIPPABLE_DYLIB: u32 = 0x40_0000;
-/// Contains a section of type S_THREAD_LOCAL_VARIABLES
-pub const MH_HAS_TLV_DESCRIPTORS: u32 = 0x80_0000;
-/// When this bit is set, the OS will run the main executable with a non-executable heap even on platforms (e.g. i386) that don't require it. Only used in MH_EXECUTE filetypes.
-pub const MH_NO_HEAP_EXECUTION: u32 = 0x100_0000;
-/// The code was linked for use in an application extension.
-pub const MH_APP_EXTENSION_SAFE: u32 = 0x0200_0000;
-/// The external symbols listed in the nlist symbol table do not include all the symbols listed in the dyld info.
-pub const MH_NLIST_OUTOFSYNC_WITH_DYLDINFO: u32 = 0x0400_0000;
-/// Allow LC_MIN_VERSION_MACOS and LC_BUILD_VERSION load commands with
-/// the platforms macOS, iOSMac, iOSSimulator, tvOSSimulator and watchOSSimulator.
-pub const MH_SIM_SUPPORT: u32 = 0x0800_0000;
-/// Only for use on dylibs. When this bit is set, the dylib is part of the dyld
-/// shared cache, rather than loose in the filesystem.
-pub const MH_DYLIB_IN_CACHE: u32 = 0x8000_0000;
-
-/// Common fields at the start of every load command.
-///
-/// The load commands directly follow the mach_header. The total size of all
-/// of the commands is given by the sizeofcmds field in the mach_header. All
-/// load commands must have as their first two fields `cmd` and `cmdsize`. The `cmd`
-/// field is filled in with a constant for that command type. Each command type
-/// has a structure specifically for it. The `cmdsize` field is the size in bytes
-/// of the particular load command structure plus anything that follows it that
-/// is a part of the load command (i.e. section structures, strings, etc.). To
-/// advance to the next load command the `cmdsize` can be added to the offset or
-/// pointer of the current load command. The `cmdsize` for 32-bit architectures
-/// MUST be a multiple of 4 bytes and for 64-bit architectures MUST be a multiple
-/// of 8 bytes (these are forever the maximum alignment of any load commands).
-/// The padded bytes must be zero. All tables in the object file must also
-/// follow these rules so the file can be memory mapped. Otherwise the pointers
-/// to these tables will not work well or at all on some machines. With all
-/// padding zeroed like objects will compare byte for byte.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct LoadCommand<E: Endian> {
- /// Type of load command.
- ///
- /// One of the `LC_*` constants.
- pub cmd: U32<E>,
- /// Total size of command in bytes.
- pub cmdsize: U32<E>,
-}
-
-/*
- * After MacOS X 10.1 when a new load command is added that is required to be
- * understood by the dynamic linker for the image to execute properly the
- * LC_REQ_DYLD bit will be or'ed into the load command constant. If the dynamic
- * linker sees such a load command it it does not understand will issue a
- * "unknown load command required for execution" error and refuse to use the
- * image. Other load commands without this bit that are not understood will
- * simply be ignored.
- */
-pub const LC_REQ_DYLD: u32 = 0x8000_0000;
-
-/* Constants for the cmd field of all load commands, the type */
-/// segment of this file to be mapped
-pub const LC_SEGMENT: u32 = 0x1;
-/// link-edit stab symbol table info
-pub const LC_SYMTAB: u32 = 0x2;
-/// link-edit gdb symbol table info (obsolete)
-pub const LC_SYMSEG: u32 = 0x3;
-/// thread
-pub const LC_THREAD: u32 = 0x4;
-/// unix thread (includes a stack)
-pub const LC_UNIXTHREAD: u32 = 0x5;
-/// load a specified fixed VM shared library
-pub const LC_LOADFVMLIB: u32 = 0x6;
-/// fixed VM shared library identification
-pub const LC_IDFVMLIB: u32 = 0x7;
-/// object identification info (obsolete)
-pub const LC_IDENT: u32 = 0x8;
-/// fixed VM file inclusion (internal use)
-pub const LC_FVMFILE: u32 = 0x9;
-/// prepage command (internal use)
-pub const LC_PREPAGE: u32 = 0xa;
-/// dynamic link-edit symbol table info
-pub const LC_DYSYMTAB: u32 = 0xb;
-/// load a dynamically linked shared library
-pub const LC_LOAD_DYLIB: u32 = 0xc;
-/// dynamically linked shared lib ident
-pub const LC_ID_DYLIB: u32 = 0xd;
-/// load a dynamic linker
-pub const LC_LOAD_DYLINKER: u32 = 0xe;
-/// dynamic linker identification
-pub const LC_ID_DYLINKER: u32 = 0xf;
-/// modules prebound for a dynamically linked shared library
-pub const LC_PREBOUND_DYLIB: u32 = 0x10;
-/// image routines
-pub const LC_ROUTINES: u32 = 0x11;
-/// sub framework
-pub const LC_SUB_FRAMEWORK: u32 = 0x12;
-/// sub umbrella
-pub const LC_SUB_UMBRELLA: u32 = 0x13;
-/// sub client
-pub const LC_SUB_CLIENT: u32 = 0x14;
-/// sub library
-pub const LC_SUB_LIBRARY: u32 = 0x15;
-/// two-level namespace lookup hints
-pub const LC_TWOLEVEL_HINTS: u32 = 0x16;
-/// prebind checksum
-pub const LC_PREBIND_CKSUM: u32 = 0x17;
-/// load a dynamically linked shared library that is allowed to be missing
-/// (all symbols are weak imported).
-pub const LC_LOAD_WEAK_DYLIB: u32 = 0x18 | LC_REQ_DYLD;
-/// 64-bit segment of this file to be mapped
-pub const LC_SEGMENT_64: u32 = 0x19;
-/// 64-bit image routines
-pub const LC_ROUTINES_64: u32 = 0x1a;
-/// the uuid
-pub const LC_UUID: u32 = 0x1b;
-/// runpath additions
-pub const LC_RPATH: u32 = 0x1c | LC_REQ_DYLD;
-/// local of code signature
-pub const LC_CODE_SIGNATURE: u32 = 0x1d;
-/// local of info to split segments
-pub const LC_SEGMENT_SPLIT_INFO: u32 = 0x1e;
-/// load and re-export dylib
-pub const LC_REEXPORT_DYLIB: u32 = 0x1f | LC_REQ_DYLD;
-/// delay load of dylib until first use
-pub const LC_LAZY_LOAD_DYLIB: u32 = 0x20;
-/// encrypted segment information
-pub const LC_ENCRYPTION_INFO: u32 = 0x21;
-/// compressed dyld information
-pub const LC_DYLD_INFO: u32 = 0x22;
-/// compressed dyld information only
-pub const LC_DYLD_INFO_ONLY: u32 = 0x22 | LC_REQ_DYLD;
-/// load upward dylib
-pub const LC_LOAD_UPWARD_DYLIB: u32 = 0x23 | LC_REQ_DYLD;
-/// build for MacOSX min OS version
-pub const LC_VERSION_MIN_MACOSX: u32 = 0x24;
-/// build for iPhoneOS min OS version
-pub const LC_VERSION_MIN_IPHONEOS: u32 = 0x25;
-/// compressed table of function start addresses
-pub const LC_FUNCTION_STARTS: u32 = 0x26;
-/// string for dyld to treat like environment variable
-pub const LC_DYLD_ENVIRONMENT: u32 = 0x27;
-/// replacement for LC_UNIXTHREAD
-pub const LC_MAIN: u32 = 0x28 | LC_REQ_DYLD;
-/// table of non-instructions in __text
-pub const LC_DATA_IN_CODE: u32 = 0x29;
-/// source version used to build binary
-pub const LC_SOURCE_VERSION: u32 = 0x2A;
-/// Code signing DRs copied from linked dylibs
-pub const LC_DYLIB_CODE_SIGN_DRS: u32 = 0x2B;
-/// 64-bit encrypted segment information
-pub const LC_ENCRYPTION_INFO_64: u32 = 0x2C;
-/// linker options in MH_OBJECT files
-pub const LC_LINKER_OPTION: u32 = 0x2D;
-/// optimization hints in MH_OBJECT files
-pub const LC_LINKER_OPTIMIZATION_HINT: u32 = 0x2E;
-/// build for AppleTV min OS version
-pub const LC_VERSION_MIN_TVOS: u32 = 0x2F;
-/// build for Watch min OS version
-pub const LC_VERSION_MIN_WATCHOS: u32 = 0x30;
-/// arbitrary data included within a Mach-O file
-pub const LC_NOTE: u32 = 0x31;
-/// build for platform min OS version
-pub const LC_BUILD_VERSION: u32 = 0x32;
-/// used with `LinkeditDataCommand`, payload is trie
-pub const LC_DYLD_EXPORTS_TRIE: u32 = 0x33 | LC_REQ_DYLD;
-/// used with `LinkeditDataCommand`
-pub const LC_DYLD_CHAINED_FIXUPS: u32 = 0x34 | LC_REQ_DYLD;
-/// used with `FilesetEntryCommand`
-pub const LC_FILESET_ENTRY: u32 = 0x35 | LC_REQ_DYLD;
-
-/// A variable length string in a load command.
-///
-/// The strings are stored just after the load command structure and
-/// the offset is from the start of the load command structure. The size
-/// of the string is reflected in the `cmdsize` field of the load command.
-/// Once again any padded bytes to bring the `cmdsize` field to a multiple
-/// of 4 bytes must be zero.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct LcStr<E: Endian> {
- /// offset to the string
- pub offset: U32<E>,
-}
-
-/// 32-bit segment load command.
-///
-/// The segment load command indicates that a part of this file is to be
-/// mapped into the task's address space. The size of this segment in memory,
-/// vmsize, maybe equal to or larger than the amount to map from this file,
-/// filesize. The file is mapped starting at fileoff to the beginning of
-/// the segment in memory, vmaddr. The rest of the memory of the segment,
-/// if any, is allocated zero fill on demand. The segment's maximum virtual
-/// memory protection and initial virtual memory protection are specified
-/// by the maxprot and initprot fields. If the segment has sections then the
-/// `Section32` structures directly follow the segment command and their size is
-/// reflected in `cmdsize`.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct SegmentCommand32<E: Endian> {
- /// LC_SEGMENT
- pub cmd: U32<E>,
- /// includes sizeof section structs
- pub cmdsize: U32<E>,
- /// segment name
- pub segname: [u8; 16],
- /// memory address of this segment
- pub vmaddr: U32<E>,
- /// memory size of this segment
- pub vmsize: U32<E>,
- /// file offset of this segment
- pub fileoff: U32<E>,
- /// amount to map from the file
- pub filesize: U32<E>,
- /// maximum VM protection
- pub maxprot: U32<E>,
- /// initial VM protection
- pub initprot: U32<E>,
- /// number of sections in segment
- pub nsects: U32<E>,
- /// flags
- pub flags: U32<E>,
-}
-
-/// 64-bit segment load command.
-///
-/// The 64-bit segment load command indicates that a part of this file is to be
-/// mapped into a 64-bit task's address space. If the 64-bit segment has
-/// sections then `Section64` structures directly follow the 64-bit segment
-/// command and their size is reflected in `cmdsize`.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct SegmentCommand64<E: Endian> {
- /// LC_SEGMENT_64
- pub cmd: U32<E>,
- /// includes sizeof section_64 structs
- pub cmdsize: U32<E>,
- /// segment name
- pub segname: [u8; 16],
- /// memory address of this segment
- pub vmaddr: U64<E>,
- /// memory size of this segment
- pub vmsize: U64<E>,
- /// file offset of this segment
- pub fileoff: U64<E>,
- /// amount to map from the file
- pub filesize: U64<E>,
- /// maximum VM protection
- pub maxprot: U32<E>,
- /// initial VM protection
- pub initprot: U32<E>,
- /// number of sections in segment
- pub nsects: U32<E>,
- /// flags
- pub flags: U32<E>,
-}
-
-// Values for `SegmentCommand*::flags`.
-/// the file contents for this segment is for the high part of the VM space, the low part is zero filled (for stacks in core files)
-pub const SG_HIGHVM: u32 = 0x1;
-/// this segment is the VM that is allocated by a fixed VM library, for overlap checking in the link editor
-pub const SG_FVMLIB: u32 = 0x2;
-/// this segment has nothing that was relocated in it and nothing relocated to it, that is it maybe safely replaced without relocation
-pub const SG_NORELOC: u32 = 0x4;
-/// This segment is protected. If the segment starts at file offset 0, the first page of the segment is not protected. All other pages of the segment are protected.
-pub const SG_PROTECTED_VERSION_1: u32 = 0x8;
-/// This segment is made read-only after fixups
-pub const SG_READ_ONLY: u32 = 0x10;
-
-/*
- * A segment is made up of zero or more sections. Non-MH_OBJECT files have
- * all of their segments with the proper sections in each, and padded to the
- * specified segment alignment when produced by the link editor. The first
- * segment of a MH_EXECUTE and MH_FVMLIB format file contains the mach_header
- * and load commands of the object file before its first section. The zero
- * fill sections are always last in their segment (in all formats). This
- * allows the zeroed segment padding to be mapped into memory where zero fill
- * sections might be. The gigabyte zero fill sections, those with the section
- * type S_GB_ZEROFILL, can only be in a segment with sections of this type.
- * These segments are then placed after all other segments.
- *
- * The MH_OBJECT format has all of its sections in one segment for
- * compactness. There is no padding to a specified segment boundary and the
- * mach_header and load commands are not part of the segment.
- *
- * Sections with the same section name, sectname, going into the same segment,
- * segname, are combined by the link editor. The resulting section is aligned
- * to the maximum alignment of the combined sections and is the new section's
- * alignment. The combined sections are aligned to their original alignment in
- * the combined section. Any padded bytes to get the specified alignment are
- * zeroed.
- *
- * The format of the relocation entries referenced by the reloff and nreloc
- * fields of the section structure for mach object files is described in the
- * header file <reloc.h>.
- */
-/// 32-bit section.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Section32<E: Endian> {
- /// name of this section
- pub sectname: [u8; 16],
- /// segment this section goes in
- pub segname: [u8; 16],
- /// memory address of this section
- pub addr: U32<E>,
- /// size in bytes of this section
- pub size: U32<E>,
- /// file offset of this section
- pub offset: U32<E>,
- /// section alignment (power of 2)
- pub align: U32<E>,
- /// file offset of relocation entries
- pub reloff: U32<E>,
- /// number of relocation entries
- pub nreloc: U32<E>,
- /// flags (section type and attributes)
- pub flags: U32<E>,
- /// reserved (for offset or index)
- pub reserved1: U32<E>,
- /// reserved (for count or sizeof)
- pub reserved2: U32<E>,
-}
-
-/// 64-bit section.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Section64<E: Endian> {
- /// name of this section
- pub sectname: [u8; 16],
- /// segment this section goes in
- pub segname: [u8; 16],
- /// memory address of this section
- pub addr: U64<E>,
- /// size in bytes of this section
- pub size: U64<E>,
- /// file offset of this section
- pub offset: U32<E>,
- /// section alignment (power of 2)
- pub align: U32<E>,
- /// file offset of relocation entries
- pub reloff: U32<E>,
- /// number of relocation entries
- pub nreloc: U32<E>,
- /// flags (section type and attributes)
- pub flags: U32<E>,
- /// reserved (for offset or index)
- pub reserved1: U32<E>,
- /// reserved (for count or sizeof)
- pub reserved2: U32<E>,
- /// reserved
- pub reserved3: U32<E>,
-}
-
-/*
- * The flags field of a section structure is separated into two parts a section
- * type and section attributes. The section types are mutually exclusive (it
- * can only have one type) but the section attributes are not (it may have more
- * than one attribute).
- */
-/// 256 section types
-pub const SECTION_TYPE: u32 = 0x0000_00ff;
-/// 24 section attributes
-pub const SECTION_ATTRIBUTES: u32 = 0xffff_ff00;
-
-/* Constants for the type of a section */
-/// regular section
-pub const S_REGULAR: u32 = 0x0;
-/// zero fill on demand section
-pub const S_ZEROFILL: u32 = 0x1;
-/// section with only literal C strings
-pub const S_CSTRING_LITERALS: u32 = 0x2;
-/// section with only 4 byte literals
-pub const S_4BYTE_LITERALS: u32 = 0x3;
-/// section with only 8 byte literals
-pub const S_8BYTE_LITERALS: u32 = 0x4;
-/// section with only pointers to literals
-pub const S_LITERAL_POINTERS: u32 = 0x5;
-/*
- * For the two types of symbol pointers sections and the symbol stubs section
- * they have indirect symbol table entries. For each of the entries in the
- * section the indirect symbol table entries, in corresponding order in the
- * indirect symbol table, start at the index stored in the reserved1 field
- * of the section structure. Since the indirect symbol table entries
- * correspond to the entries in the section the number of indirect symbol table
- * entries is inferred from the size of the section divided by the size of the
- * entries in the section. For symbol pointers sections the size of the entries
- * in the section is 4 bytes and for symbol stubs sections the byte size of the
- * stubs is stored in the reserved2 field of the section structure.
- */
-/// section with only non-lazy symbol pointers
-pub const S_NON_LAZY_SYMBOL_POINTERS: u32 = 0x6;
-/// section with only lazy symbol pointers
-pub const S_LAZY_SYMBOL_POINTERS: u32 = 0x7;
-/// section with only symbol stubs, byte size of stub in the reserved2 field
-pub const S_SYMBOL_STUBS: u32 = 0x8;
-/// section with only function pointers for initialization
-pub const S_MOD_INIT_FUNC_POINTERS: u32 = 0x9;
-/// section with only function pointers for termination
-pub const S_MOD_TERM_FUNC_POINTERS: u32 = 0xa;
-/// section contains symbols that are to be coalesced
-pub const S_COALESCED: u32 = 0xb;
-/// zero fill on demand section (that can be larger than 4 gigabytes)
-pub const S_GB_ZEROFILL: u32 = 0xc;
-/// section with only pairs of function pointers for interposing
-pub const S_INTERPOSING: u32 = 0xd;
-/// section with only 16 byte literals
-pub const S_16BYTE_LITERALS: u32 = 0xe;
-/// section contains DTrace Object Format
-pub const S_DTRACE_DOF: u32 = 0xf;
-/// section with only lazy symbol pointers to lazy loaded dylibs
-pub const S_LAZY_DYLIB_SYMBOL_POINTERS: u32 = 0x10;
-/*
- * Section types to support thread local variables
- */
-/// template of initial values for TLVs
-pub const S_THREAD_LOCAL_REGULAR: u32 = 0x11;
-/// template of initial values for TLVs
-pub const S_THREAD_LOCAL_ZEROFILL: u32 = 0x12;
-/// TLV descriptors
-pub const S_THREAD_LOCAL_VARIABLES: u32 = 0x13;
-/// pointers to TLV descriptors
-pub const S_THREAD_LOCAL_VARIABLE_POINTERS: u32 = 0x14;
-/// functions to call to initialize TLV values
-pub const S_THREAD_LOCAL_INIT_FUNCTION_POINTERS: u32 = 0x15;
-/// 32-bit offsets to initializers
-pub const S_INIT_FUNC_OFFSETS: u32 = 0x16;
-
-/*
- * Constants for the section attributes part of the flags field of a section
- * structure.
- */
-/// User setable attributes
-pub const SECTION_ATTRIBUTES_USR: u32 = 0xff00_0000;
-/// section contains only true machine instructions
-pub const S_ATTR_PURE_INSTRUCTIONS: u32 = 0x8000_0000;
-/// section contains coalesced symbols that are not to be in a ranlib table of contents
-pub const S_ATTR_NO_TOC: u32 = 0x4000_0000;
-/// ok to strip static symbols in this section in files with the MH_DYLDLINK flag
-pub const S_ATTR_STRIP_STATIC_SYMS: u32 = 0x2000_0000;
-/// no dead stripping
-pub const S_ATTR_NO_DEAD_STRIP: u32 = 0x1000_0000;
-/// blocks are live if they reference live blocks
-pub const S_ATTR_LIVE_SUPPORT: u32 = 0x0800_0000;
-/// Used with i386 code stubs written on by dyld
-pub const S_ATTR_SELF_MODIFYING_CODE: u32 = 0x0400_0000;
-/*
- * If a segment contains any sections marked with S_ATTR_DEBUG then all
- * sections in that segment must have this attribute. No section other than
- * a section marked with this attribute may reference the contents of this
- * section. A section with this attribute may contain no symbols and must have
- * a section type S_REGULAR. The static linker will not copy section contents
- * from sections with this attribute into its output file. These sections
- * generally contain DWARF debugging info.
- */
-/// a debug section
-pub const S_ATTR_DEBUG: u32 = 0x0200_0000;
-/// system setable attributes
-pub const SECTION_ATTRIBUTES_SYS: u32 = 0x00ff_ff00;
-/// section contains some machine instructions
-pub const S_ATTR_SOME_INSTRUCTIONS: u32 = 0x0000_0400;
-/// section has external relocation entries
-pub const S_ATTR_EXT_RELOC: u32 = 0x0000_0200;
-/// section has local relocation entries
-pub const S_ATTR_LOC_RELOC: u32 = 0x0000_0100;
-
-/*
- * The names of segments and sections in them are mostly meaningless to the
- * link-editor. But there are few things to support traditional UNIX
- * executables that require the link-editor and assembler to use some names
- * agreed upon by convention.
- *
- * The initial protection of the "__TEXT" segment has write protection turned
- * off (not writeable).
- *
- * The link-editor will allocate common symbols at the end of the "__common"
- * section in the "__DATA" segment. It will create the section and segment
- * if needed.
- */
-
-/* The currently known segment names and the section names in those segments */
-
-/// the pagezero segment which has no protections and catches NULL references for MH_EXECUTE files
-pub const SEG_PAGEZERO: &str = "__PAGEZERO";
-
-/// the tradition UNIX text segment
-pub const SEG_TEXT: &str = "__TEXT";
-/// the real text part of the text section no headers, and no padding
-pub const SECT_TEXT: &str = "__text";
-/// the fvmlib initialization section
-pub const SECT_FVMLIB_INIT0: &str = "__fvmlib_init0";
-/// the section following the fvmlib initialization section
-pub const SECT_FVMLIB_INIT1: &str = "__fvmlib_init1";
-
-/// the tradition UNIX data segment
-pub const SEG_DATA: &str = "__DATA";
-/// the real initialized data section no padding, no bss overlap
-pub const SECT_DATA: &str = "__data";
-/// the real uninitialized data section no padding
-pub const SECT_BSS: &str = "__bss";
-/// the section common symbols are allocated in by the link editor
-pub const SECT_COMMON: &str = "__common";
-
-/// objective-C runtime segment
-pub const SEG_OBJC: &str = "__OBJC";
-/// symbol table
-pub const SECT_OBJC_SYMBOLS: &str = "__symbol_table";
-/// module information
-pub const SECT_OBJC_MODULES: &str = "__module_info";
-/// string table
-pub const SECT_OBJC_STRINGS: &str = "__selector_strs";
-/// string table
-pub const SECT_OBJC_REFS: &str = "__selector_refs";
-
-/// the icon segment
-pub const SEG_ICON: &str = "__ICON";
-/// the icon headers
-pub const SECT_ICON_HEADER: &str = "__header";
-/// the icons in tiff format
-pub const SECT_ICON_TIFF: &str = "__tiff";
-
-/// the segment containing all structs created and maintained by the link editor. Created with -seglinkedit option to ld(1) for MH_EXECUTE and FVMLIB file types only
-pub const SEG_LINKEDIT: &str = "__LINKEDIT";
-
-/// the segment overlapping with linkedit containing linking information
-pub const SEG_LINKINFO: &str = "__LINKINFO";
-
-/// the unix stack segment
-pub const SEG_UNIXSTACK: &str = "__UNIXSTACK";
-
-/// the segment for the self (dyld) modifying code stubs that has read, write and execute permissions
-pub const SEG_IMPORT: &str = "__IMPORT";
-
-/*
- * Fixed virtual memory shared libraries are identified by two things. The
- * target pathname (the name of the library as found for execution), and the
- * minor version number. The address of where the headers are loaded is in
- * header_addr. (THIS IS OBSOLETE and no longer supported).
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Fvmlib<E: Endian> {
- /// library's target pathname
- pub name: LcStr<E>,
- /// library's minor version number
- pub minor_version: U32<E>,
- /// library's header address
- pub header_addr: U32<E>,
-}
-
-/*
- * A fixed virtual shared library (filetype == MH_FVMLIB in the mach header)
- * contains a `FvmlibCommand` (cmd == LC_IDFVMLIB) to identify the library.
- * An object that uses a fixed virtual shared library also contains a
- * `FvmlibCommand` (cmd == LC_LOADFVMLIB) for each library it uses.
- * (THIS IS OBSOLETE and no longer supported).
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FvmlibCommand<E: Endian> {
- /// LC_IDFVMLIB or LC_LOADFVMLIB
- pub cmd: U32<E>,
- /// includes pathname string
- pub cmdsize: U32<E>,
- /// the library identification
- pub fvmlib: Fvmlib<E>,
-}
-
-/*
- * Dynamically linked shared libraries are identified by two things. The
- * pathname (the name of the library as found for execution), and the
- * compatibility version number. The pathname must match and the compatibility
- * number in the user of the library must be greater than or equal to the
- * library being used. The time stamp is used to record the time a library was
- * built and copied into user so it can be use to determined if the library used
- * at runtime is exactly the same as used to built the program.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Dylib<E: Endian> {
- /// library's path name
- pub name: LcStr<E>,
- /// library's build time stamp
- pub timestamp: U32<E>,
- /// library's current version number
- pub current_version: U32<E>,
- /// library's compatibility vers number
- pub compatibility_version: U32<E>,
-}
-
-/*
- * A dynamically linked shared library (filetype == MH_DYLIB in the mach header)
- * contains a `DylibCommand` (cmd == LC_ID_DYLIB) to identify the library.
- * An object that uses a dynamically linked shared library also contains a
- * `DylibCommand` (cmd == LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, or
- * LC_REEXPORT_DYLIB) for each library it uses.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DylibCommand<E: Endian> {
- /// LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB, LC_REEXPORT_DYLIB
- pub cmd: U32<E>,
- /// includes pathname string
- pub cmdsize: U32<E>,
- /// the library identification
- pub dylib: Dylib<E>,
-}
-
-/*
- * A dynamically linked shared library may be a subframework of an umbrella
- * framework. If so it will be linked with "-umbrella umbrella_name" where
- * Where "umbrella_name" is the name of the umbrella framework. A subframework
- * can only be linked against by its umbrella framework or other subframeworks
- * that are part of the same umbrella framework. Otherwise the static link
- * editor produces an error and states to link against the umbrella framework.
- * The name of the umbrella framework for subframeworks is recorded in the
- * following structure.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct SubFrameworkCommand<E: Endian> {
- /// LC_SUB_FRAMEWORK
- pub cmd: U32<E>,
- /// includes umbrella string
- pub cmdsize: U32<E>,
- /// the umbrella framework name
- pub umbrella: LcStr<E>,
-}
-
-/*
- * For dynamically linked shared libraries that are subframework of an umbrella
- * framework they can allow clients other than the umbrella framework or other
- * subframeworks in the same umbrella framework. To do this the subframework
- * is built with "-allowable_client client_name" and an LC_SUB_CLIENT load
- * command is created for each -allowable_client flag. The client_name is
- * usually a framework name. It can also be a name used for bundles clients
- * where the bundle is built with "-client_name client_name".
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct SubClientCommand<E: Endian> {
- /// LC_SUB_CLIENT
- pub cmd: U32<E>,
- /// includes client string
- pub cmdsize: U32<E>,
- /// the client name
- pub client: LcStr<E>,
-}
-
-/*
- * A dynamically linked shared library may be a sub_umbrella of an umbrella
- * framework. If so it will be linked with "-sub_umbrella umbrella_name" where
- * Where "umbrella_name" is the name of the sub_umbrella framework. When
- * statically linking when -twolevel_namespace is in effect a twolevel namespace
- * umbrella framework will only cause its subframeworks and those frameworks
- * listed as sub_umbrella frameworks to be implicited linked in. Any other
- * dependent dynamic libraries will not be linked it when -twolevel_namespace
- * is in effect. The primary library recorded by the static linker when
- * resolving a symbol in these libraries will be the umbrella framework.
- * Zero or more sub_umbrella frameworks may be use by an umbrella framework.
- * The name of a sub_umbrella framework is recorded in the following structure.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct SubUmbrellaCommand<E: Endian> {
- /// LC_SUB_UMBRELLA
- pub cmd: U32<E>,
- /// includes sub_umbrella string
- pub cmdsize: U32<E>,
- /// the sub_umbrella framework name
- pub sub_umbrella: LcStr<E>,
-}
-
-/*
- * A dynamically linked shared library may be a sub_library of another shared
- * library. If so it will be linked with "-sub_library library_name" where
- * Where "library_name" is the name of the sub_library shared library. When
- * statically linking when -twolevel_namespace is in effect a twolevel namespace
- * shared library will only cause its subframeworks and those frameworks
- * listed as sub_umbrella frameworks and libraries listed as sub_libraries to
- * be implicited linked in. Any other dependent dynamic libraries will not be
- * linked it when -twolevel_namespace is in effect. The primary library
- * recorded by the static linker when resolving a symbol in these libraries
- * will be the umbrella framework (or dynamic library). Zero or more sub_library
- * shared libraries may be use by an umbrella framework or (or dynamic library).
- * The name of a sub_library framework is recorded in the following structure.
- * For example /usr/lib/libobjc_profile.A.dylib would be recorded as "libobjc".
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct SubLibraryCommand<E: Endian> {
- /// LC_SUB_LIBRARY
- pub cmd: U32<E>,
- /// includes sub_library string
- pub cmdsize: U32<E>,
- /// the sub_library name
- pub sub_library: LcStr<E>,
-}
-
-/*
- * A program (filetype == MH_EXECUTE) that is
- * prebound to its dynamic libraries has one of these for each library that
- * the static linker used in prebinding. It contains a bit vector for the
- * modules in the library. The bits indicate which modules are bound (1) and
- * which are not (0) from the library. The bit for module 0 is the low bit
- * of the first byte. So the bit for the Nth module is:
- * (linked_modules[N/8] >> N%8) & 1
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct PreboundDylibCommand<E: Endian> {
- /// LC_PREBOUND_DYLIB
- pub cmd: U32<E>,
- /// includes strings
- pub cmdsize: U32<E>,
- /// library's path name
- pub name: LcStr<E>,
- /// number of modules in library
- pub nmodules: U32<E>,
- /// bit vector of linked modules
- pub linked_modules: LcStr<E>,
-}
-
-/*
- * A program that uses a dynamic linker contains a `DylinkerCommand` to identify
- * the name of the dynamic linker (LC_LOAD_DYLINKER). And a dynamic linker
- * contains a `DylinkerCommand` to identify the dynamic linker (LC_ID_DYLINKER).
- * A file can have at most one of these.
- * This struct is also used for the LC_DYLD_ENVIRONMENT load command and
- * contains string for dyld to treat like environment variable.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DylinkerCommand<E: Endian> {
- /// LC_ID_DYLINKER, LC_LOAD_DYLINKER or LC_DYLD_ENVIRONMENT
- pub cmd: U32<E>,
- /// includes pathname string
- pub cmdsize: U32<E>,
- /// dynamic linker's path name
- pub name: LcStr<E>,
-}
-
-/*
- * Thread commands contain machine-specific data structures suitable for
- * use in the thread state primitives. The machine specific data structures
- * follow the struct `ThreadCommand` as follows.
- * Each flavor of machine specific data structure is preceded by an uint32_t
- * constant for the flavor of that data structure, an uint32_t that is the
- * count of uint32_t's of the size of the state data structure and then
- * the state data structure follows. This triple may be repeated for many
- * flavors. The constants for the flavors, counts and state data structure
- * definitions are expected to be in the header file <machine/thread_status.h>.
- * These machine specific data structures sizes must be multiples of
- * 4 bytes. The `cmdsize` reflects the total size of the `ThreadCommand`
- * and all of the sizes of the constants for the flavors, counts and state
- * data structures.
- *
- * For executable objects that are unix processes there will be one
- * `ThreadCommand` (cmd == LC_UNIXTHREAD) created for it by the link-editor.
- * This is the same as a LC_THREAD, except that a stack is automatically
- * created (based on the shell's limit for the stack size). Command arguments
- * and environment variables are copied onto that stack.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ThreadCommand<E: Endian> {
- /// LC_THREAD or LC_UNIXTHREAD
- pub cmd: U32<E>,
- /// total size of this command
- pub cmdsize: U32<E>,
- /* uint32_t flavor flavor of thread state */
- /* uint32_t count count of uint32_t's in thread state */
- /* struct XXX_thread_state state thread state for this flavor */
- /* ... */
-}
-
-/*
- * The routines command contains the address of the dynamic shared library
- * initialization routine and an index into the module table for the module
- * that defines the routine. Before any modules are used from the library the
- * dynamic linker fully binds the module that defines the initialization routine
- * and then calls it. This gets called before any module initialization
- * routines (used for C++ static constructors) in the library.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct RoutinesCommand32<E: Endian> {
- /* for 32-bit architectures */
- /// LC_ROUTINES
- pub cmd: U32<E>,
- /// total size of this command
- pub cmdsize: U32<E>,
- /// address of initialization routine
- pub init_address: U32<E>,
- /// index into the module table that the init routine is defined in
- pub init_module: U32<E>,
- pub reserved1: U32<E>,
- pub reserved2: U32<E>,
- pub reserved3: U32<E>,
- pub reserved4: U32<E>,
- pub reserved5: U32<E>,
- pub reserved6: U32<E>,
-}
-
-/*
- * The 64-bit routines command. Same use as above.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct RoutinesCommand64<E: Endian> {
- /* for 64-bit architectures */
- /// LC_ROUTINES_64
- pub cmd: U32<E>,
- /// total size of this command
- pub cmdsize: U32<E>,
- /// address of initialization routine
- pub init_address: U64<E>,
- /// index into the module table that the init routine is defined in
- pub init_module: U64<E>,
- pub reserved1: U64<E>,
- pub reserved2: U64<E>,
- pub reserved3: U64<E>,
- pub reserved4: U64<E>,
- pub reserved5: U64<E>,
- pub reserved6: U64<E>,
-}
-
-/*
- * The `SymtabCommand` contains the offsets and sizes of the link-edit 4.3BSD
- * "stab" style symbol table information as described in the header files
- * <nlist.h> and <stab.h>.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct SymtabCommand<E: Endian> {
- /// LC_SYMTAB
- pub cmd: U32<E>,
- /// sizeof(struct SymtabCommand)
- pub cmdsize: U32<E>,
- /// symbol table offset
- pub symoff: U32<E>,
- /// number of symbol table entries
- pub nsyms: U32<E>,
- /// string table offset
- pub stroff: U32<E>,
- /// string table size in bytes
- pub strsize: U32<E>,
-}
-
-/*
- * This is the second set of the symbolic information which is used to support
- * the data structures for the dynamically link editor.
- *
- * The original set of symbolic information in the `SymtabCommand` which contains
- * the symbol and string tables must also be present when this load command is
- * present. When this load command is present the symbol table is organized
- * into three groups of symbols:
- * local symbols (static and debugging symbols) - grouped by module
- * defined external symbols - grouped by module (sorted by name if not lib)
- * undefined external symbols (sorted by name if MH_BINDATLOAD is not set,
- * and in order the were seen by the static
- * linker if MH_BINDATLOAD is set)
- * In this load command there are offsets and counts to each of the three groups
- * of symbols.
- *
- * This load command contains a the offsets and sizes of the following new
- * symbolic information tables:
- * table of contents
- * module table
- * reference symbol table
- * indirect symbol table
- * The first three tables above (the table of contents, module table and
- * reference symbol table) are only present if the file is a dynamically linked
- * shared library. For executable and object modules, which are files
- * containing only one module, the information that would be in these three
- * tables is determined as follows:
- * table of contents - the defined external symbols are sorted by name
- * module table - the file contains only one module so everything in the
- * file is part of the module.
- * reference symbol table - is the defined and undefined external symbols
- *
- * For dynamically linked shared library files this load command also contains
- * offsets and sizes to the pool of relocation entries for all sections
- * separated into two groups:
- * external relocation entries
- * local relocation entries
- * For executable and object modules the relocation entries continue to hang
- * off the section structures.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DysymtabCommand<E: Endian> {
- /// LC_DYSYMTAB
- pub cmd: U32<E>,
- /// sizeof(struct DysymtabCommand)
- pub cmdsize: U32<E>,
-
- /*
- * The symbols indicated by symoff and nsyms of the LC_SYMTAB load command
- * are grouped into the following three groups:
- * local symbols (further grouped by the module they are from)
- * defined external symbols (further grouped by the module they are from)
- * undefined symbols
- *
- * The local symbols are used only for debugging. The dynamic binding
- * process may have to use them to indicate to the debugger the local
- * symbols for a module that is being bound.
- *
- * The last two groups are used by the dynamic binding process to do the
- * binding (indirectly through the module table and the reference symbol
- * table when this is a dynamically linked shared library file).
- */
- /// index to local symbols
- pub ilocalsym: U32<E>,
- /// number of local symbols
- pub nlocalsym: U32<E>,
-
- /// index to externally defined symbols
- pub iextdefsym: U32<E>,
- /// number of externally defined symbols
- pub nextdefsym: U32<E>,
-
- /// index to undefined symbols
- pub iundefsym: U32<E>,
- /// number of undefined symbols
- pub nundefsym: U32<E>,
-
- /*
- * For the for the dynamic binding process to find which module a symbol
- * is defined in the table of contents is used (analogous to the ranlib
- * structure in an archive) which maps defined external symbols to modules
- * they are defined in. This exists only in a dynamically linked shared
- * library file. For executable and object modules the defined external
- * symbols are sorted by name and is use as the table of contents.
- */
- /// file offset to table of contents
- pub tocoff: U32<E>,
- /// number of entries in table of contents
- pub ntoc: U32<E>,
-
- /*
- * To support dynamic binding of "modules" (whole object files) the symbol
- * table must reflect the modules that the file was created from. This is
- * done by having a module table that has indexes and counts into the merged
- * tables for each module. The module structure that these two entries
- * refer to is described below. This exists only in a dynamically linked
- * shared library file. For executable and object modules the file only
- * contains one module so everything in the file belongs to the module.
- */
- /// file offset to module table
- pub modtaboff: U32<E>,
- /// number of module table entries
- pub nmodtab: U32<E>,
-
- /*
- * To support dynamic module binding the module structure for each module
- * indicates the external references (defined and undefined) each module
- * makes. For each module there is an offset and a count into the
- * reference symbol table for the symbols that the module references.
- * This exists only in a dynamically linked shared library file. For
- * executable and object modules the defined external symbols and the
- * undefined external symbols indicates the external references.
- */
- /// offset to referenced symbol table
- pub extrefsymoff: U32<E>,
- /// number of referenced symbol table entries
- pub nextrefsyms: U32<E>,
-
- /*
- * The sections that contain "symbol pointers" and "routine stubs" have
- * indexes and (implied counts based on the size of the section and fixed
- * size of the entry) into the "indirect symbol" table for each pointer
- * and stub. For every section of these two types the index into the
- * indirect symbol table is stored in the section header in the field
- * reserved1. An indirect symbol table entry is simply a 32bit index into
- * the symbol table to the symbol that the pointer or stub is referring to.
- * The indirect symbol table is ordered to match the entries in the section.
- */
- /// file offset to the indirect symbol table
- pub indirectsymoff: U32<E>,
- /// number of indirect symbol table entries
- pub nindirectsyms: U32<E>,
-
- /*
- * To support relocating an individual module in a library file quickly the
- * external relocation entries for each module in the library need to be
- * accessed efficiently. Since the relocation entries can't be accessed
- * through the section headers for a library file they are separated into
- * groups of local and external entries further grouped by module. In this
- * case the presents of this load command who's extreloff, nextrel,
- * locreloff and nlocrel fields are non-zero indicates that the relocation
- * entries of non-merged sections are not referenced through the section
- * structures (and the reloff and nreloc fields in the section headers are
- * set to zero).
- *
- * Since the relocation entries are not accessed through the section headers
- * this requires the r_address field to be something other than a section
- * offset to identify the item to be relocated. In this case r_address is
- * set to the offset from the vmaddr of the first LC_SEGMENT command.
- * For MH_SPLIT_SEGS images r_address is set to the the offset from the
- * vmaddr of the first read-write LC_SEGMENT command.
- *
- * The relocation entries are grouped by module and the module table
- * entries have indexes and counts into them for the group of external
- * relocation entries for that the module.
- *
- * For sections that are merged across modules there must not be any
- * remaining external relocation entries for them (for merged sections
- * remaining relocation entries must be local).
- */
- /// offset to external relocation entries
- pub extreloff: U32<E>,
- /// number of external relocation entries
- pub nextrel: U32<E>,
-
- /*
- * All the local relocation entries are grouped together (they are not
- * grouped by their module since they are only used if the object is moved
- * from it statically link edited address).
- */
- /// offset to local relocation entries
- pub locreloff: U32<E>,
- /// number of local relocation entries
- pub nlocrel: U32<E>,
-}
-
-/*
- * An indirect symbol table entry is simply a 32bit index into the symbol table
- * to the symbol that the pointer or stub is referring to. Unless it is for a
- * non-lazy symbol pointer section for a defined symbol which strip(1) as
- * removed. In which case it has the value INDIRECT_SYMBOL_LOCAL. If the
- * symbol was also absolute INDIRECT_SYMBOL_ABS is or'ed with that.
- */
-pub const INDIRECT_SYMBOL_LOCAL: u32 = 0x8000_0000;
-pub const INDIRECT_SYMBOL_ABS: u32 = 0x4000_0000;
-
-/* a table of contents entry */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DylibTableOfContents<E: Endian> {
- /// the defined external symbol (index into the symbol table)
- pub symbol_index: U32<E>,
- /// index into the module table this symbol is defined in
- pub module_index: U32<E>,
-}
-
-/* a module table entry */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DylibModule32<E: Endian> {
- /// the module name (index into string table)
- pub module_name: U32<E>,
-
- /// index into externally defined symbols
- pub iextdefsym: U32<E>,
- /// number of externally defined symbols
- pub nextdefsym: U32<E>,
- /// index into reference symbol table
- pub irefsym: U32<E>,
- /// number of reference symbol table entries
- pub nrefsym: U32<E>,
- /// index into symbols for local symbols
- pub ilocalsym: U32<E>,
- /// number of local symbols
- pub nlocalsym: U32<E>,
-
- /// index into external relocation entries
- pub iextrel: U32<E>,
- /// number of external relocation entries
- pub nextrel: U32<E>,
-
- /// low 16 bits are the index into the init section, high 16 bits are the index into the term section
- pub iinit_iterm: U32<E>,
- /// low 16 bits are the number of init section entries, high 16 bits are the number of term section entries
- pub ninit_nterm: U32<E>,
-
- /// for this module address of the start of the (__OBJC,__module_info) section
- pub objc_module_info_addr: U32<E>,
- /// for this module size of the (__OBJC,__module_info) section
- pub objc_module_info_size: U32<E>,
-}
-
-/* a 64-bit module table entry */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DylibModule64<E: Endian> {
- /// the module name (index into string table)
- pub module_name: U32<E>,
-
- /// index into externally defined symbols
- pub iextdefsym: U32<E>,
- /// number of externally defined symbols
- pub nextdefsym: U32<E>,
- /// index into reference symbol table
- pub irefsym: U32<E>,
- /// number of reference symbol table entries
- pub nrefsym: U32<E>,
- /// index into symbols for local symbols
- pub ilocalsym: U32<E>,
- /// number of local symbols
- pub nlocalsym: U32<E>,
-
- /// index into external relocation entries
- pub iextrel: U32<E>,
- /// number of external relocation entries
- pub nextrel: U32<E>,
-
- /// low 16 bits are the index into the init section, high 16 bits are the index into the term section
- pub iinit_iterm: U32<E>,
- /// low 16 bits are the number of init section entries, high 16 bits are the number of term section entries
- pub ninit_nterm: U32<E>,
-
- /// for this module size of the (__OBJC,__module_info) section
- pub objc_module_info_size: U32<E>,
- /// for this module address of the start of the (__OBJC,__module_info) section
- pub objc_module_info_addr: U64<E>,
-}
-
-/*
- * The entries in the reference symbol table are used when loading the module
- * (both by the static and dynamic link editors) and if the module is unloaded
- * or replaced. Therefore all external symbols (defined and undefined) are
- * listed in the module's reference table. The flags describe the type of
- * reference that is being made. The constants for the flags are defined in
- * <mach-o/nlist.h> as they are also used for symbol table entries.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DylibReference<E: Endian> {
- /* TODO:
- uint32_t isym:24, /* index into the symbol table */
- flags:8; /* flags to indicate the type of reference */
- */
- pub bitfield: U32<E>,
-}
-
-/*
- * The TwolevelHintsCommand contains the offset and number of hints in the
- * two-level namespace lookup hints table.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct TwolevelHintsCommand<E: Endian> {
- /// LC_TWOLEVEL_HINTS
- pub cmd: U32<E>,
- /// sizeof(struct TwolevelHintsCommand)
- pub cmdsize: U32<E>,
- /// offset to the hint table
- pub offset: U32<E>,
- /// number of hints in the hint table
- pub nhints: U32<E>,
-}
-
-/*
- * The entries in the two-level namespace lookup hints table are TwolevelHint
- * structs. These provide hints to the dynamic link editor where to start
- * looking for an undefined symbol in a two-level namespace image. The
- * isub_image field is an index into the sub-images (sub-frameworks and
- * sub-umbrellas list) that made up the two-level image that the undefined
- * symbol was found in when it was built by the static link editor. If
- * isub-image is 0 the the symbol is expected to be defined in library and not
- * in the sub-images. If isub-image is non-zero it is an index into the array
- * of sub-images for the umbrella with the first index in the sub-images being
- * 1. The array of sub-images is the ordered list of sub-images of the umbrella
- * that would be searched for a symbol that has the umbrella recorded as its
- * primary library. The table of contents index is an index into the
- * library's table of contents. This is used as the starting point of the
- * binary search or a directed linear search.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct TwolevelHint<E: Endian> {
- /* TODO:
- uint32_t
- isub_image:8, /* index into the sub images */
- itoc:24; /* index into the table of contents */
- */
- pub bitfield: U32<E>,
-}
-
-/*
- * The PrebindCksumCommand contains the value of the original check sum for
- * prebound files or zero. When a prebound file is first created or modified
- * for other than updating its prebinding information the value of the check sum
- * is set to zero. When the file has it prebinding re-done and if the value of
- * the check sum is zero the original check sum is calculated and stored in
- * cksum field of this load command in the output file. If when the prebinding
- * is re-done and the cksum field is non-zero it is left unchanged from the
- * input file.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct PrebindCksumCommand<E: Endian> {
- /// LC_PREBIND_CKSUM
- pub cmd: U32<E>,
- /// sizeof(struct PrebindCksumCommand)
- pub cmdsize: U32<E>,
- /// the check sum or zero
- pub cksum: U32<E>,
-}
-
-/*
- * The uuid load command contains a single 128-bit unique random number that
- * identifies an object produced by the static link editor.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct UuidCommand<E: Endian> {
- /// LC_UUID
- pub cmd: U32<E>,
- /// sizeof(struct UuidCommand)
- pub cmdsize: U32<E>,
- /// the 128-bit uuid
- pub uuid: [u8; 16],
-}
-
-/*
- * The RpathCommand contains a path which at runtime should be added to
- * the current run path used to find @rpath prefixed dylibs.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct RpathCommand<E: Endian> {
- /// LC_RPATH
- pub cmd: U32<E>,
- /// includes string
- pub cmdsize: U32<E>,
- /// path to add to run path
- pub path: LcStr<E>,
-}
-
-/*
- * The LinkeditDataCommand contains the offsets and sizes of a blob
- * of data in the __LINKEDIT segment.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct LinkeditDataCommand<E: Endian> {
- /// `LC_CODE_SIGNATURE`, `LC_SEGMENT_SPLIT_INFO`, `LC_FUNCTION_STARTS`,
- /// `LC_DATA_IN_CODE`, `LC_DYLIB_CODE_SIGN_DRS`, `LC_LINKER_OPTIMIZATION_HINT`,
- /// `LC_DYLD_EXPORTS_TRIE`, or `LC_DYLD_CHAINED_FIXUPS`.
- pub cmd: U32<E>,
- /// sizeof(struct LinkeditDataCommand)
- pub cmdsize: U32<E>,
- /// file offset of data in __LINKEDIT segment
- pub dataoff: U32<E>,
- /// file size of data in __LINKEDIT segment
- pub datasize: U32<E>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FilesetEntryCommand<E: Endian> {
- // LC_FILESET_ENTRY
- pub cmd: U32<E>,
- /// includes id string
- pub cmdsize: U32<E>,
- /// memory address of the dylib
- pub vmaddr: U64<E>,
- /// file offset of the dylib
- pub fileoff: U64<E>,
- /// contained entry id
- pub entry_id: LcStr<E>,
- /// entry_id is 32-bits long, so this is the reserved padding
- pub reserved: U32<E>,
-}
-
-/*
- * The EncryptionInfoCommand32 contains the file offset and size of an
- * of an encrypted segment.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct EncryptionInfoCommand32<E: Endian> {
- /// LC_ENCRYPTION_INFO
- pub cmd: U32<E>,
- /// sizeof(struct EncryptionInfoCommand32)
- pub cmdsize: U32<E>,
- /// file offset of encrypted range
- pub cryptoff: U32<E>,
- /// file size of encrypted range
- pub cryptsize: U32<E>,
- /// which enryption system, 0 means not-encrypted yet
- pub cryptid: U32<E>,
-}
-
-/*
- * The EncryptionInfoCommand64 contains the file offset and size of an
- * of an encrypted segment (for use in x86_64 targets).
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct EncryptionInfoCommand64<E: Endian> {
- /// LC_ENCRYPTION_INFO_64
- pub cmd: U32<E>,
- /// sizeof(struct EncryptionInfoCommand64)
- pub cmdsize: U32<E>,
- /// file offset of encrypted range
- pub cryptoff: U32<E>,
- /// file size of encrypted range
- pub cryptsize: U32<E>,
- /// which enryption system, 0 means not-encrypted yet
- pub cryptid: U32<E>,
- /// padding to make this struct's size a multiple of 8 bytes
- pub pad: U32<E>,
-}
-
-/*
- * The VersionMinCommand contains the min OS version on which this
- * binary was built to run.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct VersionMinCommand<E: Endian> {
- /// LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS or LC_VERSION_MIN_WATCHOS or LC_VERSION_MIN_TVOS
- pub cmd: U32<E>,
- /// sizeof(struct VersionMinCommand)
- pub cmdsize: U32<E>,
- /// X.Y.Z is encoded in nibbles xxxx.yy.zz
- pub version: U32<E>,
- /// X.Y.Z is encoded in nibbles xxxx.yy.zz
- pub sdk: U32<E>,
-}
-
-/*
- * The BuildVersionCommand contains the min OS version on which this
- * binary was built to run for its platform. The list of known platforms and
- * tool values following it.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct BuildVersionCommand<E: Endian> {
- /// LC_BUILD_VERSION
- pub cmd: U32<E>,
- /// sizeof(struct BuildVersionCommand) plus ntools * sizeof(struct BuildToolVersion)
- pub cmdsize: U32<E>,
- /// platform
- pub platform: U32<E>,
- /// X.Y.Z is encoded in nibbles xxxx.yy.zz
- pub minos: U32<E>,
- /// X.Y.Z is encoded in nibbles xxxx.yy.zz
- pub sdk: U32<E>,
- /// number of tool entries following this
- pub ntools: U32<E>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct BuildToolVersion<E: Endian> {
- /// enum for the tool
- pub tool: U32<E>,
- /// version number of the tool
- pub version: U32<E>,
-}
-
-/* Known values for the platform field above. */
-pub const PLATFORM_MACOS: u32 = 1;
-pub const PLATFORM_IOS: u32 = 2;
-pub const PLATFORM_TVOS: u32 = 3;
-pub const PLATFORM_WATCHOS: u32 = 4;
-pub const PLATFORM_BRIDGEOS: u32 = 5;
-pub const PLATFORM_MACCATALYST: u32 = 6;
-pub const PLATFORM_IOSSIMULATOR: u32 = 7;
-pub const PLATFORM_TVOSSIMULATOR: u32 = 8;
-pub const PLATFORM_WATCHOSSIMULATOR: u32 = 9;
-pub const PLATFORM_DRIVERKIT: u32 = 10;
-
-/* Known values for the tool field above. */
-pub const TOOL_CLANG: u32 = 1;
-pub const TOOL_SWIFT: u32 = 2;
-pub const TOOL_LD: u32 = 3;
-
-/*
- * The DyldInfoCommand contains the file offsets and sizes of
- * the new compressed form of the information dyld needs to
- * load the image. This information is used by dyld on Mac OS X
- * 10.6 and later. All information pointed to by this command
- * is encoded using byte streams, so no endian swapping is needed
- * to interpret it.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DyldInfoCommand<E: Endian> {
- /// LC_DYLD_INFO or LC_DYLD_INFO_ONLY
- pub cmd: U32<E>,
- /// sizeof(struct DyldInfoCommand)
- pub cmdsize: U32<E>,
-
- /*
- * Dyld rebases an image whenever dyld loads it at an address different
- * from its preferred address. The rebase information is a stream
- * of byte sized opcodes whose symbolic names start with REBASE_OPCODE_.
- * Conceptually the rebase information is a table of tuples:
- * <seg-index, seg-offset, type>
- * The opcodes are a compressed way to encode the table by only
- * encoding when a column changes. In addition simple patterns
- * like "every n'th offset for m times" can be encoded in a few
- * bytes.
- */
- /// file offset to rebase info
- pub rebase_off: U32<E>,
- /// size of rebase info
- pub rebase_size: U32<E>,
-
- /*
- * Dyld binds an image during the loading process, if the image
- * requires any pointers to be initialized to symbols in other images.
- * The bind information is a stream of byte sized
- * opcodes whose symbolic names start with BIND_OPCODE_.
- * Conceptually the bind information is a table of tuples:
- * <seg-index, seg-offset, type, symbol-library-ordinal, symbol-name, addend>
- * The opcodes are a compressed way to encode the table by only
- * encoding when a column changes. In addition simple patterns
- * like for runs of pointers initialized to the same value can be
- * encoded in a few bytes.
- */
- /// file offset to binding info
- pub bind_off: U32<E>,
- /// size of binding info
- pub bind_size: U32<E>,
-
- /*
- * Some C++ programs require dyld to unique symbols so that all
- * images in the process use the same copy of some code/data.
- * This step is done after binding. The content of the weak_bind
- * info is an opcode stream like the bind_info. But it is sorted
- * alphabetically by symbol name. This enable dyld to walk
- * all images with weak binding information in order and look
- * for collisions. If there are no collisions, dyld does
- * no updating. That means that some fixups are also encoded
- * in the bind_info. For instance, all calls to "operator new"
- * are first bound to libstdc++.dylib using the information
- * in bind_info. Then if some image overrides operator new
- * that is detected when the weak_bind information is processed
- * and the call to operator new is then rebound.
- */
- /// file offset to weak binding info
- pub weak_bind_off: U32<E>,
- /// size of weak binding info
- pub weak_bind_size: U32<E>,
-
- /*
- * Some uses of external symbols do not need to be bound immediately.
- * Instead they can be lazily bound on first use. The lazy_bind
- * are contains a stream of BIND opcodes to bind all lazy symbols.
- * Normal use is that dyld ignores the lazy_bind section when
- * loading an image. Instead the static linker arranged for the
- * lazy pointer to initially point to a helper function which
- * pushes the offset into the lazy_bind area for the symbol
- * needing to be bound, then jumps to dyld which simply adds
- * the offset to lazy_bind_off to get the information on what
- * to bind.
- */
- /// file offset to lazy binding info
- pub lazy_bind_off: U32<E>,
- /// size of lazy binding infs
- pub lazy_bind_size: U32<E>,
-
- /*
- * The symbols exported by a dylib are encoded in a trie. This
- * is a compact representation that factors out common prefixes.
- * It also reduces LINKEDIT pages in RAM because it encodes all
- * information (name, address, flags) in one small, contiguous range.
- * The export area is a stream of nodes. The first node sequentially
- * is the start node for the trie.
- *
- * Nodes for a symbol start with a uleb128 that is the length of
- * the exported symbol information for the string so far.
- * If there is no exported symbol, the node starts with a zero byte.
- * If there is exported info, it follows the length.
- *
- * First is a uleb128 containing flags. Normally, it is followed by
- * a uleb128 encoded offset which is location of the content named
- * by the symbol from the mach_header for the image. If the flags
- * is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is
- * a uleb128 encoded library ordinal, then a zero terminated
- * UTF8 string. If the string is zero length, then the symbol
- * is re-export from the specified dylib with the same name.
- * If the flags is EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER, then following
- * the flags is two uleb128s: the stub offset and the resolver offset.
- * The stub is used by non-lazy pointers. The resolver is used
- * by lazy pointers and must be called to get the actual address to use.
- *
- * After the optional exported symbol information is a byte of
- * how many edges (0-255) that this node has leaving it,
- * followed by each edge.
- * Each edge is a zero terminated UTF8 of the addition chars
- * in the symbol, followed by a uleb128 offset for the node that
- * edge points to.
- *
- */
- /// file offset to lazy binding info
- pub export_off: U32<E>,
- /// size of lazy binding infs
- pub export_size: U32<E>,
-}
-
-/*
- * The following are used to encode rebasing information
- */
-pub const REBASE_TYPE_POINTER: u8 = 1;
-pub const REBASE_TYPE_TEXT_ABSOLUTE32: u8 = 2;
-pub const REBASE_TYPE_TEXT_PCREL32: u8 = 3;
-
-pub const REBASE_OPCODE_MASK: u8 = 0xF0;
-pub const REBASE_IMMEDIATE_MASK: u8 = 0x0F;
-pub const REBASE_OPCODE_DONE: u8 = 0x00;
-pub const REBASE_OPCODE_SET_TYPE_IMM: u8 = 0x10;
-pub const REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: u8 = 0x20;
-pub const REBASE_OPCODE_ADD_ADDR_ULEB: u8 = 0x30;
-pub const REBASE_OPCODE_ADD_ADDR_IMM_SCALED: u8 = 0x40;
-pub const REBASE_OPCODE_DO_REBASE_IMM_TIMES: u8 = 0x50;
-pub const REBASE_OPCODE_DO_REBASE_ULEB_TIMES: u8 = 0x60;
-pub const REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: u8 = 0x70;
-pub const REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: u8 = 0x80;
-
-/*
- * The following are used to encode binding information
- */
-pub const BIND_TYPE_POINTER: u8 = 1;
-pub const BIND_TYPE_TEXT_ABSOLUTE32: u8 = 2;
-pub const BIND_TYPE_TEXT_PCREL32: u8 = 3;
-
-pub const BIND_SPECIAL_DYLIB_SELF: i8 = 0;
-pub const BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE: i8 = -1;
-pub const BIND_SPECIAL_DYLIB_FLAT_LOOKUP: i8 = -2;
-pub const BIND_SPECIAL_DYLIB_WEAK_LOOKUP: i8 = -3;
-
-pub const BIND_SYMBOL_FLAGS_WEAK_IMPORT: u8 = 0x1;
-pub const BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION: u8 = 0x8;
-
-pub const BIND_OPCODE_MASK: u8 = 0xF0;
-pub const BIND_IMMEDIATE_MASK: u8 = 0x0F;
-pub const BIND_OPCODE_DONE: u8 = 0x00;
-pub const BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: u8 = 0x10;
-pub const BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: u8 = 0x20;
-pub const BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: u8 = 0x30;
-pub const BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: u8 = 0x40;
-pub const BIND_OPCODE_SET_TYPE_IMM: u8 = 0x50;
-pub const BIND_OPCODE_SET_ADDEND_SLEB: u8 = 0x60;
-pub const BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: u8 = 0x70;
-pub const BIND_OPCODE_ADD_ADDR_ULEB: u8 = 0x80;
-pub const BIND_OPCODE_DO_BIND: u8 = 0x90;
-pub const BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: u8 = 0xA0;
-pub const BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: u8 = 0xB0;
-pub const BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: u8 = 0xC0;
-pub const BIND_OPCODE_THREADED: u8 = 0xD0;
-pub const BIND_SUBOPCODE_THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB: u8 = 0x00;
-pub const BIND_SUBOPCODE_THREADED_APPLY: u8 = 0x01;
-
-/*
- * The following are used on the flags byte of a terminal node
- * in the export information.
- */
-pub const EXPORT_SYMBOL_FLAGS_KIND_MASK: u32 = 0x03;
-pub const EXPORT_SYMBOL_FLAGS_KIND_REGULAR: u32 = 0x00;
-pub const EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL: u32 = 0x01;
-pub const EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE: u32 = 0x02;
-pub const EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION: u32 = 0x04;
-pub const EXPORT_SYMBOL_FLAGS_REEXPORT: u32 = 0x08;
-pub const EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER: u32 = 0x10;
-
-/*
- * The LinkerOptionCommand contains linker options embedded in object files.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct LinkerOptionCommand<E: Endian> {
- /// LC_LINKER_OPTION only used in MH_OBJECT filetypes
- pub cmd: U32<E>,
- pub cmdsize: U32<E>,
- /// number of strings
- pub count: U32<E>,
- /* concatenation of zero terminated UTF8 strings.
- Zero filled at end to align */
-}
-
-/*
- * The SymsegCommand contains the offset and size of the GNU style
- * symbol table information as described in the header file <symseg.h>.
- * The symbol roots of the symbol segments must also be aligned properly
- * in the file. So the requirement of keeping the offsets aligned to a
- * multiple of a 4 bytes translates to the length field of the symbol
- * roots also being a multiple of a long. Also the padding must again be
- * zeroed. (THIS IS OBSOLETE and no longer supported).
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct SymsegCommand<E: Endian> {
- /// LC_SYMSEG
- pub cmd: U32<E>,
- /// sizeof(struct SymsegCommand)
- pub cmdsize: U32<E>,
- /// symbol segment offset
- pub offset: U32<E>,
- /// symbol segment size in bytes
- pub size: U32<E>,
-}
-
-/*
- * The IdentCommand contains a free format string table following the
- * IdentCommand structure. The strings are null terminated and the size of
- * the command is padded out with zero bytes to a multiple of 4 bytes/
- * (THIS IS OBSOLETE and no longer supported).
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct IdentCommand<E: Endian> {
- /// LC_IDENT
- pub cmd: U32<E>,
- /// strings that follow this command
- pub cmdsize: U32<E>,
-}
-
-/*
- * The FvmfileCommand contains a reference to a file to be loaded at the
- * specified virtual address. (Presently, this command is reserved for
- * internal use. The kernel ignores this command when loading a program into
- * memory).
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FvmfileCommand<E: Endian> {
- /// LC_FVMFILE
- pub cmd: U32<E>,
- /// includes pathname string
- pub cmdsize: U32<E>,
- /// files pathname
- pub name: LcStr<E>,
- /// files virtual address
- pub header_addr: U32<E>,
-}
-
-/*
- * The EntryPointCommand is a replacement for thread_command.
- * It is used for main executables to specify the location (file offset)
- * of main(). If -stack_size was used at link time, the stacksize
- * field will contain the stack size need for the main thread.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct EntryPointCommand<E: Endian> {
- /// LC_MAIN only used in MH_EXECUTE filetypes
- pub cmd: U32<E>,
- /// 24
- pub cmdsize: U32<E>,
- /// file (__TEXT) offset of main()
- pub entryoff: U64<E>,
- /// if not zero, initial stack size
- pub stacksize: U64<E>,
-}
-
-/*
- * The SourceVersionCommand is an optional load command containing
- * the version of the sources used to build the binary.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct SourceVersionCommand<E: Endian> {
- /// LC_SOURCE_VERSION
- pub cmd: U32<E>,
- /// 16
- pub cmdsize: U32<E>,
- /// A.B.C.D.E packed as a24.b10.c10.d10.e10
- pub version: U64<E>,
-}
-
-/*
- * The LC_DATA_IN_CODE load commands uses a LinkeditDataCommand
- * to point to an array of DataInCodeEntry entries. Each entry
- * describes a range of data in a code section.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DataInCodeEntry<E: Endian> {
- /// from mach_header to start of data range
- pub offset: U32<E>,
- /// number of bytes in data range
- pub length: U16<E>,
- /// a DICE_KIND_* value
- pub kind: U16<E>,
-}
-pub const DICE_KIND_DATA: u32 = 0x0001;
-pub const DICE_KIND_JUMP_TABLE8: u32 = 0x0002;
-pub const DICE_KIND_JUMP_TABLE16: u32 = 0x0003;
-pub const DICE_KIND_JUMP_TABLE32: u32 = 0x0004;
-pub const DICE_KIND_ABS_JUMP_TABLE32: u32 = 0x0005;
-
-/*
- * Sections of type S_THREAD_LOCAL_VARIABLES contain an array
- * of TlvDescriptor structures.
- */
-/* TODO:
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct TlvDescriptor<E: Endian>
-{
- void* (*thunk)(struct TlvDescriptor*);
- unsigned long key;
- unsigned long offset;
-}
-*/
-
-/*
- * LC_NOTE commands describe a region of arbitrary data included in a Mach-O
- * file. Its initial use is to record extra data in MH_CORE files.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct NoteCommand<E: Endian> {
- /// LC_NOTE
- pub cmd: U32<E>,
- /// sizeof(struct NoteCommand)
- pub cmdsize: U32<E>,
- /// owner name for this LC_NOTE
- pub data_owner: [u8; 16],
- /// file offset of this data
- pub offset: U64<E>,
- /// length of data region
- pub size: U64<E>,
-}
-
-// Definitions from "/usr/include/mach-o/nlist.h".
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Nlist32<E: Endian> {
- /// index into the string table
- pub n_strx: U32<E>,
- /// type flag, see below
- pub n_type: u8,
- /// section number or NO_SECT
- pub n_sect: u8,
- /// see <mach-o/stab.h>
- pub n_desc: U16<E>,
- /// value of this symbol (or stab offset)
- pub n_value: U32<E>,
-}
-
-/*
- * This is the symbol table entry structure for 64-bit architectures.
- */
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Nlist64<E: Endian> {
- /// index into the string table
- pub n_strx: U32<E>,
- /// type flag, see below
- pub n_type: u8,
- /// section number or NO_SECT
- pub n_sect: u8,
- /// see <mach-o/stab.h>
- pub n_desc: U16<E>,
- /// value of this symbol (or stab offset)
- // Note: 4 byte alignment has been observed in practice.
- pub n_value: U64Bytes<E>,
-}
-
-/*
- * Symbols with a index into the string table of zero (n_un.n_strx == 0) are
- * defined to have a null, "", name. Therefore all string indexes to non null
- * names must not have a zero string index. This is bit historical information
- * that has never been well documented.
- */
-
-/*
- * The n_type field really contains four fields:
- * unsigned char N_STAB:3,
- * N_PEXT:1,
- * N_TYPE:3,
- * N_EXT:1;
- * which are used via the following masks.
- */
-/// if any of these bits set, a symbolic debugging entry
-pub const N_STAB: u8 = 0xe0;
-/// private external symbol bit
-pub const N_PEXT: u8 = 0x10;
-/// mask for the type bits
-pub const N_TYPE: u8 = 0x0e;
-/// external symbol bit, set for external symbols
-pub const N_EXT: u8 = 0x01;
-
-/*
- * Only symbolic debugging entries have some of the N_STAB bits set and if any
- * of these bits are set then it is a symbolic debugging entry (a stab). In
- * which case then the values of the n_type field (the entire field) are given
- * in <mach-o/stab.h>
- */
-
-/*
- * Values for N_TYPE bits of the n_type field.
- */
-/// undefined, n_sect == NO_SECT
-pub const N_UNDF: u8 = 0x0;
-/// absolute, n_sect == NO_SECT
-pub const N_ABS: u8 = 0x2;
-/// defined in section number n_sect
-pub const N_SECT: u8 = 0xe;
-/// prebound undefined (defined in a dylib)
-pub const N_PBUD: u8 = 0xc;
-/// indirect
-pub const N_INDR: u8 = 0xa;
-
-/*
- * If the type is N_INDR then the symbol is defined to be the same as another
- * symbol. In this case the n_value field is an index into the string table
- * of the other symbol's name. When the other symbol is defined then they both
- * take on the defined type and value.
- */
-
-/*
- * If the type is N_SECT then the n_sect field contains an ordinal of the
- * section the symbol is defined in. The sections are numbered from 1 and
- * refer to sections in order they appear in the load commands for the file
- * they are in. This means the same ordinal may very well refer to different
- * sections in different files.
- *
- * The n_value field for all symbol table entries (including N_STAB's) gets
- * updated by the link editor based on the value of it's n_sect field and where
- * the section n_sect references gets relocated. If the value of the n_sect
- * field is NO_SECT then it's n_value field is not changed by the link editor.
- */
-/// symbol is not in any section
-pub const NO_SECT: u8 = 0;
-/// 1 thru 255 inclusive
-pub const MAX_SECT: u8 = 255;
-
-/*
- * Common symbols are represented by undefined (N_UNDF) external (N_EXT) types
- * who's values (n_value) are non-zero. In which case the value of the n_value
- * field is the size (in bytes) of the common symbol. The n_sect field is set
- * to NO_SECT. The alignment of a common symbol may be set as a power of 2
- * between 2^1 and 2^15 as part of the n_desc field using the macros below. If
- * the alignment is not set (a value of zero) then natural alignment based on
- * the size is used.
- */
-/* TODO:
-#define GET_COMM_ALIGN(n_desc) (((n_desc) >> 8) & 0x0f)
-#define SET_COMM_ALIGN(n_desc,align) \
- (n_desc) = (((n_desc) & 0xf0ff) | (((align) & 0x0f) << 8))
- */
-
-/*
- * To support the lazy binding of undefined symbols in the dynamic link-editor,
- * the undefined symbols in the symbol table (the nlist structures) are marked
- * with the indication if the undefined reference is a lazy reference or
- * non-lazy reference. If both a non-lazy reference and a lazy reference is
- * made to the same symbol the non-lazy reference takes precedence. A reference
- * is lazy only when all references to that symbol are made through a symbol
- * pointer in a lazy symbol pointer section.
- *
- * The implementation of marking nlist structures in the symbol table for
- * undefined symbols will be to use some of the bits of the n_desc field as a
- * reference type. The mask REFERENCE_TYPE will be applied to the n_desc field
- * of an nlist structure for an undefined symbol to determine the type of
- * undefined reference (lazy or non-lazy).
- *
- * The constants for the REFERENCE FLAGS are propagated to the reference table
- * in a shared library file. In that case the constant for a defined symbol,
- * REFERENCE_FLAG_DEFINED, is also used.
- */
-/* Reference type bits of the n_desc field of undefined symbols */
-pub const REFERENCE_TYPE: u16 = 0x7;
-/* types of references */
-pub const REFERENCE_FLAG_UNDEFINED_NON_LAZY: u16 = 0;
-pub const REFERENCE_FLAG_UNDEFINED_LAZY: u16 = 1;
-pub const REFERENCE_FLAG_DEFINED: u16 = 2;
-pub const REFERENCE_FLAG_PRIVATE_DEFINED: u16 = 3;
-pub const REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY: u16 = 4;
-pub const REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY: u16 = 5;
-
-/*
- * To simplify stripping of objects that use are used with the dynamic link
- * editor, the static link editor marks the symbols defined an object that are
- * referenced by a dynamically bound object (dynamic shared libraries, bundles).
- * With this marking strip knows not to strip these symbols.
- */
-pub const REFERENCED_DYNAMICALLY: u16 = 0x0010;
-
-/*
- * For images created by the static link editor with the -twolevel_namespace
- * option in effect the flags field of the mach header is marked with
- * MH_TWOLEVEL. And the binding of the undefined references of the image are
- * determined by the static link editor. Which library an undefined symbol is
- * bound to is recorded by the static linker in the high 8 bits of the n_desc
- * field using the SET_LIBRARY_ORDINAL macro below. The ordinal recorded
- * references the libraries listed in the Mach-O's LC_LOAD_DYLIB,
- * LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_LOAD_UPWARD_DYLIB, and
- * LC_LAZY_LOAD_DYLIB, etc. load commands in the order they appear in the
- * headers. The library ordinals start from 1.
- * For a dynamic library that is built as a two-level namespace image the
- * undefined references from module defined in another use the same nlist struct
- * an in that case SELF_LIBRARY_ORDINAL is used as the library ordinal. For
- * defined symbols in all images they also must have the library ordinal set to
- * SELF_LIBRARY_ORDINAL. The EXECUTABLE_ORDINAL refers to the executable
- * image for references from plugins that refer to the executable that loads
- * them.
- *
- * The DYNAMIC_LOOKUP_ORDINAL is for undefined symbols in a two-level namespace
- * image that are looked up by the dynamic linker with flat namespace semantics.
- * This ordinal was added as a feature in Mac OS X 10.3 by reducing the
- * value of MAX_LIBRARY_ORDINAL by one. So it is legal for existing binaries
- * or binaries built with older tools to have 0xfe (254) dynamic libraries. In
- * this case the ordinal value 0xfe (254) must be treated as a library ordinal
- * for compatibility.
- */
-/* TODO:
-#define GET_LIBRARY_ORDINAL(n_desc) (((n_desc) >> 8) & 0xff)
-#define SET_LIBRARY_ORDINAL(n_desc,ordinal) \
- (n_desc) = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8))
- */
-pub const SELF_LIBRARY_ORDINAL: u8 = 0x0;
-pub const MAX_LIBRARY_ORDINAL: u8 = 0xfd;
-pub const DYNAMIC_LOOKUP_ORDINAL: u8 = 0xfe;
-pub const EXECUTABLE_ORDINAL: u8 = 0xff;
-
-/*
- * The bit 0x0020 of the n_desc field is used for two non-overlapping purposes
- * and has two different symbolic names, N_NO_DEAD_STRIP and N_DESC_DISCARDED.
- */
-
-/*
- * The N_NO_DEAD_STRIP bit of the n_desc field only ever appears in a
- * relocatable .o file (MH_OBJECT filetype). And is used to indicate to the
- * static link editor it is never to dead strip the symbol.
- */
-/// symbol is not to be dead stripped
-pub const N_NO_DEAD_STRIP: u16 = 0x0020;
-
-/*
- * The N_DESC_DISCARDED bit of the n_desc field never appears in linked image.
- * But is used in very rare cases by the dynamic link editor to mark an in
- * memory symbol as discared and longer used for linking.
- */
-/// symbol is discarded
-pub const N_DESC_DISCARDED: u16 = 0x0020;
-
-/*
- * The N_WEAK_REF bit of the n_desc field indicates to the dynamic linker that
- * the undefined symbol is allowed to be missing and is to have the address of
- * zero when missing.
- */
-/// symbol is weak referenced
-pub const N_WEAK_REF: u16 = 0x0040;
-
-/*
- * The N_WEAK_DEF bit of the n_desc field indicates to the static and dynamic
- * linkers that the symbol definition is weak, allowing a non-weak symbol to
- * also be used which causes the weak definition to be discared. Currently this
- * is only supported for symbols in coalesced sections.
- */
-/// coalesced symbol is a weak definition
-pub const N_WEAK_DEF: u16 = 0x0080;
-
-/*
- * The N_REF_TO_WEAK bit of the n_desc field indicates to the dynamic linker
- * that the undefined symbol should be resolved using flat namespace searching.
- */
-/// reference to a weak symbol
-pub const N_REF_TO_WEAK: u16 = 0x0080;
-
-/*
- * The N_ARM_THUMB_DEF bit of the n_desc field indicates that the symbol is
- * a definition of a Thumb function.
- */
-/// symbol is a Thumb function (ARM)
-pub const N_ARM_THUMB_DEF: u16 = 0x0008;
-
-/*
- * The N_SYMBOL_RESOLVER bit of the n_desc field indicates that the
- * that the function is actually a resolver function and should
- * be called to get the address of the real function to use.
- * This bit is only available in .o files (MH_OBJECT filetype)
- */
-pub const N_SYMBOL_RESOLVER: u16 = 0x0100;
-
-/*
- * The N_ALT_ENTRY bit of the n_desc field indicates that the
- * symbol is pinned to the previous content.
- */
-pub const N_ALT_ENTRY: u16 = 0x0200;
-
-// Definitions from "/usr/include/mach-o/stab.h".
-
-/*
- * This file gives definitions supplementing <nlist.h> for permanent symbol
- * table entries of Mach-O files. Modified from the BSD definitions. The
- * modifications from the original definitions were changing what the values of
- * what was the n_other field (an unused field) which is now the n_sect field.
- * These modifications are required to support symbols in an arbitrary number of
- * sections not just the three sections (text, data and bss) in a BSD file.
- * The values of the defined constants have NOT been changed.
- *
- * These must have one of the N_STAB bits on. The n_value fields are subject
- * to relocation according to the value of their n_sect field. So for types
- * that refer to things in sections the n_sect field must be filled in with the
- * proper section ordinal. For types that are not to have their n_value field
- * relocatated the n_sect field must be NO_SECT.
- */
-
-/*
- * Symbolic debugger symbols. The comments give the conventional use for
- *
- * .stabs "n_name", n_type, n_sect, n_desc, n_value
- *
- * where n_type is the defined constant and not listed in the comment. Other
- * fields not listed are zero. n_sect is the section ordinal the entry is
- * referring to.
- */
-/// global symbol: name,,NO_SECT,type,0
-pub const N_GSYM: u8 = 0x20;
-/// procedure name (f77 kludge): name,,NO_SECT,0,0
-pub const N_FNAME: u8 = 0x22;
-/// procedure: name,,n_sect,linenumber,address
-pub const N_FUN: u8 = 0x24;
-/// static symbol: name,,n_sect,type,address
-pub const N_STSYM: u8 = 0x26;
-/// .lcomm symbol: name,,n_sect,type,address
-pub const N_LCSYM: u8 = 0x28;
-/// begin nsect sym: 0,,n_sect,0,address
-pub const N_BNSYM: u8 = 0x2e;
-/// AST file path: name,,NO_SECT,0,0
-pub const N_AST: u8 = 0x32;
-/// emitted with gcc2_compiled and in gcc source
-pub const N_OPT: u8 = 0x3c;
-/// register sym: name,,NO_SECT,type,register
-pub const N_RSYM: u8 = 0x40;
-/// src line: 0,,n_sect,linenumber,address
-pub const N_SLINE: u8 = 0x44;
-/// end nsect sym: 0,,n_sect,0,address
-pub const N_ENSYM: u8 = 0x4e;
-/// structure elt: name,,NO_SECT,type,struct_offset
-pub const N_SSYM: u8 = 0x60;
-/// source file name: name,,n_sect,0,address
-pub const N_SO: u8 = 0x64;
-/// object file name: name,,0,0,st_mtime
-pub const N_OSO: u8 = 0x66;
-/// local sym: name,,NO_SECT,type,offset
-pub const N_LSYM: u8 = 0x80;
-/// include file beginning: name,,NO_SECT,0,sum
-pub const N_BINCL: u8 = 0x82;
-/// #included file name: name,,n_sect,0,address
-pub const N_SOL: u8 = 0x84;
-/// compiler parameters: name,,NO_SECT,0,0
-pub const N_PARAMS: u8 = 0x86;
-/// compiler version: name,,NO_SECT,0,0
-pub const N_VERSION: u8 = 0x88;
-/// compiler -O level: name,,NO_SECT,0,0
-pub const N_OLEVEL: u8 = 0x8A;
-/// parameter: name,,NO_SECT,type,offset
-pub const N_PSYM: u8 = 0xa0;
-/// include file end: name,,NO_SECT,0,0
-pub const N_EINCL: u8 = 0xa2;
-/// alternate entry: name,,n_sect,linenumber,address
-pub const N_ENTRY: u8 = 0xa4;
-/// left bracket: 0,,NO_SECT,nesting level,address
-pub const N_LBRAC: u8 = 0xc0;
-/// deleted include file: name,,NO_SECT,0,sum
-pub const N_EXCL: u8 = 0xc2;
-/// right bracket: 0,,NO_SECT,nesting level,address
-pub const N_RBRAC: u8 = 0xe0;
-/// begin common: name,,NO_SECT,0,0
-pub const N_BCOMM: u8 = 0xe2;
-/// end common: name,,n_sect,0,0
-pub const N_ECOMM: u8 = 0xe4;
-/// end common (local name): 0,,n_sect,0,address
-pub const N_ECOML: u8 = 0xe8;
-/// second stab entry with length information
-pub const N_LENG: u8 = 0xfe;
-
-/*
- * for the berkeley pascal compiler, pc(1):
- */
-/// global pascal symbol: name,,NO_SECT,subtype,line
-pub const N_PC: u8 = 0x30;
-
-// Definitions from "/usr/include/mach-o/reloc.h".
-
-/// A relocation entry.
-///
-/// Mach-O relocations have plain and scattered variants, with the
-/// meaning of the fields depending on the variant.
-///
-/// This type provides functions for determining whether the relocation
-/// is scattered, and for accessing the fields of each variant.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Relocation<E: Endian> {
- pub r_word0: U32<E>,
- pub r_word1: U32<E>,
-}
-
-impl<E: Endian> Relocation<E> {
- /// Determine whether this is a scattered relocation.
- #[inline]
- pub fn r_scattered(self, endian: E, cputype: u32) -> bool {
- if cputype == CPU_TYPE_X86_64 {
- false
- } else {
- self.r_word0.get(endian) & R_SCATTERED != 0
- }
- }
-
- /// Return the fields of a plain relocation.
- pub fn info(self, endian: E) -> RelocationInfo {
- let r_address = self.r_word0.get(endian);
- let r_word1 = self.r_word1.get(endian);
- if endian.is_little_endian() {
- RelocationInfo {
- r_address,
- r_symbolnum: r_word1 & 0x00ff_ffff,
- r_pcrel: ((r_word1 >> 24) & 0x1) != 0,
- r_length: ((r_word1 >> 25) & 0x3) as u8,
- r_extern: ((r_word1 >> 27) & 0x1) != 0,
- r_type: (r_word1 >> 28) as u8,
- }
- } else {
- RelocationInfo {
- r_address,
- r_symbolnum: r_word1 >> 8,
- r_pcrel: ((r_word1 >> 7) & 0x1) != 0,
- r_length: ((r_word1 >> 5) & 0x3) as u8,
- r_extern: ((r_word1 >> 4) & 0x1) != 0,
- r_type: (r_word1 & 0xf) as u8,
- }
- }
- }
-
- /// Return the fields of a scattered relocation.
- pub fn scattered_info(self, endian: E) -> ScatteredRelocationInfo {
- let r_word0 = self.r_word0.get(endian);
- let r_value = self.r_word1.get(endian);
- ScatteredRelocationInfo {
- r_address: r_word0 & 0x00ff_ffff,
- r_type: ((r_word0 >> 24) & 0xf) as u8,
- r_length: ((r_word0 >> 28) & 0x3) as u8,
- r_pcrel: ((r_word0 >> 30) & 0x1) != 0,
- r_value,
- }
- }
-}
-
-/*
- * Format of a relocation entry of a Mach-O file. Modified from the 4.3BSD
- * format. The modifications from the original format were changing the value
- * of the r_symbolnum field for "local" (r_extern == 0) relocation entries.
- * This modification is required to support symbols in an arbitrary number of
- * sections not just the three sections (text, data and bss) in a 4.3BSD file.
- * Also the last 4 bits have had the r_type tag added to them.
- */
-
-#[derive(Debug, Clone, Copy)]
-pub struct RelocationInfo {
- /// offset in the section to what is being relocated
- pub r_address: u32,
- /// symbol index if r_extern == 1 or section ordinal if r_extern == 0
- pub r_symbolnum: u32,
- /// was relocated pc relative already
- pub r_pcrel: bool,
- /// 0=byte, 1=word, 2=long, 3=quad
- pub r_length: u8,
- /// does not include value of sym referenced
- pub r_extern: bool,
- /// if not 0, machine specific relocation type
- pub r_type: u8,
-}
-
-impl RelocationInfo {
- /// Combine the fields into a `Relocation`.
- pub fn relocation<E: Endian>(self, endian: E) -> Relocation<E> {
- let r_word0 = U32::new(endian, self.r_address);
- let r_word1 = U32::new(
- endian,
- if endian.is_little_endian() {
- self.r_symbolnum & 0x00ff_ffff
- | u32::from(self.r_pcrel) << 24
- | u32::from(self.r_length & 0x3) << 25
- | u32::from(self.r_extern) << 27
- | u32::from(self.r_type) << 28
- } else {
- self.r_symbolnum >> 8
- | u32::from(self.r_pcrel) << 7
- | u32::from(self.r_length & 0x3) << 5
- | u32::from(self.r_extern) << 4
- | u32::from(self.r_type) & 0xf
- },
- );
- Relocation { r_word0, r_word1 }
- }
-}
-
-/// absolute relocation type for Mach-O files
-pub const R_ABS: u8 = 0;
-
-/*
- * The r_address is not really the address as it's name indicates but an offset.
- * In 4.3BSD a.out objects this offset is from the start of the "segment" for
- * which relocation entry is for (text or data). For Mach-O object files it is
- * also an offset but from the start of the "section" for which the relocation
- * entry is for. See comments in <mach-o/loader.h> about the r_address feild
- * in images for used with the dynamic linker.
- *
- * In 4.3BSD a.out objects if r_extern is zero then r_symbolnum is an ordinal
- * for the segment the symbol being relocated is in. These ordinals are the
- * symbol types N_TEXT, N_DATA, N_BSS or N_ABS. In Mach-O object files these
- * ordinals refer to the sections in the object file in the order their section
- * structures appear in the headers of the object file they are in. The first
- * section has the ordinal 1, the second 2, and so on. This means that the
- * same ordinal in two different object files could refer to two different
- * sections. And further could have still different ordinals when combined
- * by the link-editor. The value R_ABS is used for relocation entries for
- * absolute symbols which need no further relocation.
- */
-
-/*
- * For RISC machines some of the references are split across two instructions
- * and the instruction does not contain the complete value of the reference.
- * In these cases a second, or paired relocation entry, follows each of these
- * relocation entries, using a PAIR r_type, which contains the other part of the
- * reference not contained in the instruction. This other part is stored in the
- * pair's r_address field. The exact number of bits of the other part of the
- * reference store in the r_address field is dependent on the particular
- * relocation type for the particular architecture.
- */
-
-/*
- * To make scattered loading by the link editor work correctly "local"
- * relocation entries can't be used when the item to be relocated is the value
- * of a symbol plus an offset (where the resulting expression is outside the
- * block the link editor is moving, a blocks are divided at symbol addresses).
- * In this case. where the item is a symbol value plus offset, the link editor
- * needs to know more than just the section the symbol was defined. What is
- * needed is the actual value of the symbol without the offset so it can do the
- * relocation correctly based on where the value of the symbol got relocated to
- * not the value of the expression (with the offset added to the symbol value).
- * So for the NeXT 2.0 release no "local" relocation entries are ever used when
- * there is a non-zero offset added to a symbol. The "external" and "local"
- * relocation entries remain unchanged.
- *
- * The implementation is quite messy given the compatibility with the existing
- * relocation entry format. The ASSUMPTION is that a section will never be
- * bigger than 2**24 - 1 (0x00ffffff or 16,777,215) bytes. This assumption
- * allows the r_address (which is really an offset) to fit in 24 bits and high
- * bit of the r_address field in the relocation_info structure to indicate
- * it is really a scattered_relocation_info structure. Since these are only
- * used in places where "local" relocation entries are used and not where
- * "external" relocation entries are used the r_extern field has been removed.
- *
- * For scattered loading to work on a RISC machine where some of the references
- * are split across two instructions the link editor needs to be assured that
- * each reference has a unique 32 bit reference (that more than one reference is
- * NOT sharing the same high 16 bits for example) so it move each referenced
- * item independent of each other. Some compilers guarantees this but the
- * compilers don't so scattered loading can be done on those that do guarantee
- * this.
- */
-
-/// Bit set in `Relocation::r_word0` for scattered relocations.
-pub const R_SCATTERED: u32 = 0x8000_0000;
-
-#[derive(Debug, Clone, Copy)]
-pub struct ScatteredRelocationInfo {
- /// offset in the section to what is being relocated
- pub r_address: u32,
- /// if not 0, machine specific relocation type
- pub r_type: u8,
- /// 0=byte, 1=word, 2=long, 3=quad
- pub r_length: u8,
- /// was relocated pc relative already
- pub r_pcrel: bool,
- /// the value the item to be relocated is referring to (without any offset added)
- pub r_value: u32,
-}
-
-impl ScatteredRelocationInfo {
- /// Combine the fields into a `Relocation`.
- pub fn relocation<E: Endian>(self, endian: E) -> Relocation<E> {
- let r_word0 = U32::new(
- endian,
- self.r_address & 0x00ff_ffff
- | u32::from(self.r_type & 0xf) << 24
- | u32::from(self.r_length & 0x3) << 28
- | u32::from(self.r_pcrel) << 30
- | R_SCATTERED,
- );
- let r_word1 = U32::new(endian, self.r_value);
- Relocation { r_word0, r_word1 }
- }
-}
-
-/*
- * Relocation types used in a generic implementation. Relocation entries for
- * normal things use the generic relocation as described above and their r_type
- * is GENERIC_RELOC_VANILLA (a value of zero).
- *
- * Another type of generic relocation, GENERIC_RELOC_SECTDIFF, is to support
- * the difference of two symbols defined in different sections. That is the
- * expression "symbol1 - symbol2 + constant" is a relocatable expression when
- * both symbols are defined in some section. For this type of relocation the
- * both relocations entries are scattered relocation entries. The value of
- * symbol1 is stored in the first relocation entry's r_value field and the
- * value of symbol2 is stored in the pair's r_value field.
- *
- * A special case for a prebound lazy pointer is needed to beable to set the
- * value of the lazy pointer back to its non-prebound state. This is done
- * using the GENERIC_RELOC_PB_LA_PTR r_type. This is a scattered relocation
- * entry where the r_value feild is the value of the lazy pointer not prebound.
- */
-/// generic relocation as described above
-pub const GENERIC_RELOC_VANILLA: u8 = 0;
-/// Only follows a GENERIC_RELOC_SECTDIFF
-pub const GENERIC_RELOC_PAIR: u8 = 1;
-pub const GENERIC_RELOC_SECTDIFF: u8 = 2;
-/// prebound lazy pointer
-pub const GENERIC_RELOC_PB_LA_PTR: u8 = 3;
-pub const GENERIC_RELOC_LOCAL_SECTDIFF: u8 = 4;
-/// thread local variables
-pub const GENERIC_RELOC_TLV: u8 = 5;
-
-// Definitions from "/usr/include/mach-o/arm/reloc.h".
-
-/*
- * Relocation types used in the arm implementation. Relocation entries for
- * things other than instructions use the same generic relocation as described
- * in <mach-o/reloc.h> and their r_type is ARM_RELOC_VANILLA, one of the
- * *_SECTDIFF or the *_PB_LA_PTR types. The rest of the relocation types are
- * for instructions. Since they are for instructions the r_address field
- * indicates the 32 bit instruction that the relocation is to be performed on.
- */
-/// generic relocation as described above
-pub const ARM_RELOC_VANILLA: u8 = 0;
-/// the second relocation entry of a pair
-pub const ARM_RELOC_PAIR: u8 = 1;
-/// a PAIR follows with subtract symbol value
-pub const ARM_RELOC_SECTDIFF: u8 = 2;
-/// like ARM_RELOC_SECTDIFF, but the symbol referenced was local.
-pub const ARM_RELOC_LOCAL_SECTDIFF: u8 = 3;
-/// prebound lazy pointer
-pub const ARM_RELOC_PB_LA_PTR: u8 = 4;
-/// 24 bit branch displacement (to a word address)
-pub const ARM_RELOC_BR24: u8 = 5;
-/// 22 bit branch displacement (to a half-word address)
-pub const ARM_THUMB_RELOC_BR22: u8 = 6;
-/// obsolete - a thumb 32-bit branch instruction possibly needing page-spanning branch workaround
-pub const ARM_THUMB_32BIT_BRANCH: u8 = 7;
-
-/*
- * For these two r_type relocations they always have a pair following them
- * and the r_length bits are used differently. The encoding of the
- * r_length is as follows:
- * low bit of r_length:
- * 0 - :lower16: for movw instructions
- * 1 - :upper16: for movt instructions
- * high bit of r_length:
- * 0 - arm instructions
- * 1 - thumb instructions
- * the other half of the relocated expression is in the following pair
- * relocation entry in the the low 16 bits of r_address field.
- */
-pub const ARM_RELOC_HALF: u8 = 8;
-pub const ARM_RELOC_HALF_SECTDIFF: u8 = 9;
-
-// Definitions from "/usr/include/mach-o/arm64/reloc.h".
-
-/*
- * Relocation types used in the arm64 implementation.
- */
-/// for pointers
-pub const ARM64_RELOC_UNSIGNED: u8 = 0;
-/// must be followed by a ARM64_RELOC_UNSIGNED
-pub const ARM64_RELOC_SUBTRACTOR: u8 = 1;
-/// a B/BL instruction with 26-bit displacement
-pub const ARM64_RELOC_BRANCH26: u8 = 2;
-/// pc-rel distance to page of target
-pub const ARM64_RELOC_PAGE21: u8 = 3;
-/// offset within page, scaled by r_length
-pub const ARM64_RELOC_PAGEOFF12: u8 = 4;
-/// pc-rel distance to page of GOT slot
-pub const ARM64_RELOC_GOT_LOAD_PAGE21: u8 = 5;
-/// offset within page of GOT slot, scaled by r_length
-pub const ARM64_RELOC_GOT_LOAD_PAGEOFF12: u8 = 6;
-/// for pointers to GOT slots
-pub const ARM64_RELOC_POINTER_TO_GOT: u8 = 7;
-/// pc-rel distance to page of TLVP slot
-pub const ARM64_RELOC_TLVP_LOAD_PAGE21: u8 = 8;
-/// offset within page of TLVP slot, scaled by r_length
-pub const ARM64_RELOC_TLVP_LOAD_PAGEOFF12: u8 = 9;
-/// must be followed by PAGE21 or PAGEOFF12
-pub const ARM64_RELOC_ADDEND: u8 = 10;
-
-// An arm64e authenticated pointer.
-//
-// Represents a pointer to a symbol (like ARM64_RELOC_UNSIGNED).
-// Additionally, the resulting pointer is signed. The signature is
-// specified in the target location: the addend is restricted to the lower
-// 32 bits (instead of the full 64 bits for ARM64_RELOC_UNSIGNED):
-//
-// |63|62|61-51|50-49| 48 |47 - 32|31 - 0|
-// | 1| 0| 0 | key | addr | discriminator | addend |
-//
-// The key is one of:
-// IA: 00 IB: 01
-// DA: 10 DB: 11
-//
-// The discriminator field is used as extra signature diversification.
-//
-// The addr field indicates whether the target address should be blended
-// into the discriminator.
-//
-pub const ARM64_RELOC_AUTHENTICATED_POINTER: u8 = 11;
-
-// Definitions from "/usr/include/mach-o/ppc/reloc.h".
-
-/*
- * Relocation types used in the ppc implementation. Relocation entries for
- * things other than instructions use the same generic relocation as described
- * above and their r_type is RELOC_VANILLA. The rest of the relocation types
- * are for instructions. Since they are for instructions the r_address field
- * indicates the 32 bit instruction that the relocation is to be performed on.
- * The fields r_pcrel and r_length are ignored for non-RELOC_VANILLA r_types
- * except for PPC_RELOC_BR14.
- *
- * For PPC_RELOC_BR14 if the r_length is the unused value 3, then the branch was
- * statically predicted setting or clearing the Y-bit based on the sign of the
- * displacement or the opcode. If this is the case the static linker must flip
- * the value of the Y-bit if the sign of the displacement changes for non-branch
- * always conditions.
- */
-/// generic relocation as described above
-pub const PPC_RELOC_VANILLA: u8 = 0;
-/// the second relocation entry of a pair
-pub const PPC_RELOC_PAIR: u8 = 1;
-/// 14 bit branch displacement (to a word address)
-pub const PPC_RELOC_BR14: u8 = 2;
-/// 24 bit branch displacement (to a word address)
-pub const PPC_RELOC_BR24: u8 = 3;
-/// a PAIR follows with the low half
-pub const PPC_RELOC_HI16: u8 = 4;
-/// a PAIR follows with the high half
-pub const PPC_RELOC_LO16: u8 = 5;
-/// Same as the RELOC_HI16 except the low 16 bits and the high 16 bits are added together
-/// with the low 16 bits sign extended first. This means if bit 15 of the low 16 bits is
-/// set the high 16 bits stored in the instruction will be adjusted.
-pub const PPC_RELOC_HA16: u8 = 6;
-/// Same as the LO16 except that the low 2 bits are not stored in the instruction and are
-/// always zero. This is used in double word load/store instructions.
-pub const PPC_RELOC_LO14: u8 = 7;
-/// a PAIR follows with subtract symbol value
-pub const PPC_RELOC_SECTDIFF: u8 = 8;
-/// prebound lazy pointer
-pub const PPC_RELOC_PB_LA_PTR: u8 = 9;
-/// section difference forms of above. a PAIR
-pub const PPC_RELOC_HI16_SECTDIFF: u8 = 10;
-/// follows these with subtract symbol value
-pub const PPC_RELOC_LO16_SECTDIFF: u8 = 11;
-pub const PPC_RELOC_HA16_SECTDIFF: u8 = 12;
-pub const PPC_RELOC_JBSR: u8 = 13;
-pub const PPC_RELOC_LO14_SECTDIFF: u8 = 14;
-/// like PPC_RELOC_SECTDIFF, but the symbol referenced was local.
-pub const PPC_RELOC_LOCAL_SECTDIFF: u8 = 15;
-
-// Definitions from "/usr/include/mach-o/x86_64/reloc.h".
-
-/*
- * Relocations for x86_64 are a bit different than for other architectures in
- * Mach-O: Scattered relocations are not used. Almost all relocations produced
- * by the compiler are external relocations. An external relocation has the
- * r_extern bit set to 1 and the r_symbolnum field contains the symbol table
- * index of the target label.
- *
- * When the assembler is generating relocations, if the target label is a local
- * label (begins with 'L'), then the previous non-local label in the same
- * section is used as the target of the external relocation. An addend is used
- * with the distance from that non-local label to the target label. Only when
- * there is no previous non-local label in the section is an internal
- * relocation used.
- *
- * The addend (i.e. the 4 in _foo+4) is encoded in the instruction (Mach-O does
- * not have RELA relocations). For PC-relative relocations, the addend is
- * stored directly in the instruction. This is different from other Mach-O
- * architectures, which encode the addend minus the current section offset.
- *
- * The relocation types are:
- *
- * X86_64_RELOC_UNSIGNED // for absolute addresses
- * X86_64_RELOC_SIGNED // for signed 32-bit displacement
- * X86_64_RELOC_BRANCH // a CALL/JMP instruction with 32-bit displacement
- * X86_64_RELOC_GOT_LOAD // a MOVQ load of a GOT entry
- * X86_64_RELOC_GOT // other GOT references
- * X86_64_RELOC_SUBTRACTOR // must be followed by a X86_64_RELOC_UNSIGNED
- *
- * The following are sample assembly instructions, followed by the relocation
- * and section content they generate in an object file:
- *
- * call _foo
- * r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
- * E8 00 00 00 00
- *
- * call _foo+4
- * r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
- * E8 04 00 00 00
- *
- * movq _foo@GOTPCREL(%rip), %rax
- * r_type=X86_64_RELOC_GOT_LOAD, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
- * 48 8B 05 00 00 00 00
- *
- * pushq _foo@GOTPCREL(%rip)
- * r_type=X86_64_RELOC_GOT, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
- * FF 35 00 00 00 00
- *
- * movl _foo(%rip), %eax
- * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
- * 8B 05 00 00 00 00
- *
- * movl _foo+4(%rip), %eax
- * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
- * 8B 05 04 00 00 00
- *
- * movb $0x12, _foo(%rip)
- * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
- * C6 05 FF FF FF FF 12
- *
- * movl $0x12345678, _foo(%rip)
- * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
- * C7 05 FC FF FF FF 78 56 34 12
- *
- * .quad _foo
- * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
- * 00 00 00 00 00 00 00 00
- *
- * .quad _foo+4
- * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
- * 04 00 00 00 00 00 00 00
- *
- * .quad _foo - _bar
- * r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar
- * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
- * 00 00 00 00 00 00 00 00
- *
- * .quad _foo - _bar + 4
- * r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar
- * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
- * 04 00 00 00 00 00 00 00
- *
- * .long _foo - _bar
- * r_type=X86_64_RELOC_SUBTRACTOR, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_bar
- * r_type=X86_64_RELOC_UNSIGNED, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo
- * 00 00 00 00
- *
- * lea L1(%rip), %rax
- * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_prev
- * 48 8d 05 12 00 00 00
- * // assumes _prev is the first non-local label 0x12 bytes before L1
- *
- * lea L0(%rip), %rax
- * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3
- * 48 8d 05 56 00 00 00
- * // assumes L0 is in third section and there is no previous non-local label.
- * // The rip-relative-offset of 0x00000056 is L0-address_of_next_instruction.
- * // address_of_next_instruction is the address of the relocation + 4.
- *
- * add $6,L0(%rip)
- * r_type=X86_64_RELOC_SIGNED_1, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3
- * 83 05 18 00 00 00 06
- * // assumes L0 is in third section and there is no previous non-local label.
- * // The rip-relative-offset of 0x00000018 is L0-address_of_next_instruction.
- * // address_of_next_instruction is the address of the relocation + 4 + 1.
- * // The +1 comes from SIGNED_1. This is used because the relocation is not
- * // at the end of the instruction.
- *
- * .quad L1
- * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
- * 12 00 00 00 00 00 00 00
- * // assumes _prev is the first non-local label 0x12 bytes before L1
- *
- * .quad L0
- * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=0, r_pcrel=0, r_symbolnum=3
- * 56 00 00 00 00 00 00 00
- * // assumes L0 is in third section, has an address of 0x00000056 in .o
- * // file, and there is no previous non-local label
- *
- * .quad _foo - .
- * r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
- * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
- * EE FF FF FF FF FF FF FF
- * // assumes _prev is the first non-local label 0x12 bytes before this
- * // .quad
- *
- * .quad _foo - L1
- * r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
- * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
- * EE FF FF FF FF FF FF FF
- * // assumes _prev is the first non-local label 0x12 bytes before L1
- *
- * .quad L1 - _prev
- * // No relocations. This is an assembly time constant.
- * 12 00 00 00 00 00 00 00
- * // assumes _prev is the first non-local label 0x12 bytes before L1
- *
- *
- *
- * In final linked images, there are only two valid relocation kinds:
- *
- * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=1, r_symbolnum=sym_index
- * This tells dyld to add the address of a symbol to a pointer sized (8-byte)
- * piece of data (i.e on disk the 8-byte piece of data contains the addend). The
- * r_symbolnum contains the index into the symbol table of the target symbol.
- *
- * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=0, r_symbolnum=0
- * This tells dyld to adjust the pointer sized (8-byte) piece of data by the amount
- * the containing image was loaded from its base address (e.g. slide).
- *
- */
-/// for absolute addresses
-pub const X86_64_RELOC_UNSIGNED: u8 = 0;
-/// for signed 32-bit displacement
-pub const X86_64_RELOC_SIGNED: u8 = 1;
-/// a CALL/JMP instruction with 32-bit displacement
-pub const X86_64_RELOC_BRANCH: u8 = 2;
-/// a MOVQ load of a GOT entry
-pub const X86_64_RELOC_GOT_LOAD: u8 = 3;
-/// other GOT references
-pub const X86_64_RELOC_GOT: u8 = 4;
-/// must be followed by a X86_64_RELOC_UNSIGNED
-pub const X86_64_RELOC_SUBTRACTOR: u8 = 5;
-/// for signed 32-bit displacement with a -1 addend
-pub const X86_64_RELOC_SIGNED_1: u8 = 6;
-/// for signed 32-bit displacement with a -2 addend
-pub const X86_64_RELOC_SIGNED_2: u8 = 7;
-/// for signed 32-bit displacement with a -4 addend
-pub const X86_64_RELOC_SIGNED_4: u8 = 8;
-/// for thread local variables
-pub const X86_64_RELOC_TLV: u8 = 9;
-
-unsafe_impl_pod!(FatHeader, FatArch32, FatArch64,);
-unsafe_impl_endian_pod!(
- DyldCacheHeader,
- DyldCacheMappingInfo,
- DyldCacheImageInfo,
- DyldSubCacheInfo,
- MachHeader32,
- MachHeader64,
- LoadCommand,
- LcStr,
- SegmentCommand32,
- SegmentCommand64,
- Section32,
- Section64,
- Fvmlib,
- FvmlibCommand,
- Dylib,
- DylibCommand,
- SubFrameworkCommand,
- SubClientCommand,
- SubUmbrellaCommand,
- SubLibraryCommand,
- PreboundDylibCommand,
- DylinkerCommand,
- ThreadCommand,
- RoutinesCommand32,
- RoutinesCommand64,
- SymtabCommand,
- DysymtabCommand,
- DylibTableOfContents,
- DylibModule32,
- DylibModule64,
- DylibReference,
- TwolevelHintsCommand,
- TwolevelHint,
- PrebindCksumCommand,
- UuidCommand,
- RpathCommand,
- LinkeditDataCommand,
- FilesetEntryCommand,
- EncryptionInfoCommand32,
- EncryptionInfoCommand64,
- VersionMinCommand,
- BuildVersionCommand,
- BuildToolVersion,
- DyldInfoCommand,
- LinkerOptionCommand,
- SymsegCommand,
- IdentCommand,
- FvmfileCommand,
- EntryPointCommand,
- SourceVersionCommand,
- DataInCodeEntry,
- //TlvDescriptor,
- NoteCommand,
- Nlist32,
- Nlist64,
- Relocation,
-);
diff --git a/vendor/object/src/pe.rs b/vendor/object/src/pe.rs
deleted file mode 100644
index 64ccf06..0000000
--- a/vendor/object/src/pe.rs
+++ /dev/null
@@ -1,3056 +0,0 @@
-//! PE/COFF definitions.
-//!
-//! These definitions are independent of read/write support, although we do implement
-//! some traits useful for those.
-//!
-//! This module is based heavily on "winnt.h" (10.0.17763.0).
-
-#![allow(missing_docs)]
-
-use core::convert::TryInto;
-
-use crate::endian::{I32Bytes, LittleEndian as LE, U16Bytes, U32Bytes, I32, U16, U32, U64};
-use crate::pod::Pod;
-
-/// MZ
-pub const IMAGE_DOS_SIGNATURE: u16 = 0x5A4D;
-/// NE
-pub const IMAGE_OS2_SIGNATURE: u16 = 0x454E;
-/// LE
-pub const IMAGE_OS2_SIGNATURE_LE: u16 = 0x454C;
-/// LE
-pub const IMAGE_VXD_SIGNATURE: u16 = 0x454C;
-/// PE00
-pub const IMAGE_NT_SIGNATURE: u32 = 0x0000_4550;
-
-/// DOS .EXE header
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageDosHeader {
- /// Magic number
- pub e_magic: U16<LE>,
- /// Bytes on last page of file
- pub e_cblp: U16<LE>,
- /// Pages in file
- pub e_cp: U16<LE>,
- /// Relocations
- pub e_crlc: U16<LE>,
- /// Size of header in paragraphs
- pub e_cparhdr: U16<LE>,
- /// Minimum extra paragraphs needed
- pub e_minalloc: U16<LE>,
- /// Maximum extra paragraphs needed
- pub e_maxalloc: U16<LE>,
- /// Initial (relative) SS value
- pub e_ss: U16<LE>,
- /// Initial SP value
- pub e_sp: U16<LE>,
- /// Checksum
- pub e_csum: U16<LE>,
- /// Initial IP value
- pub e_ip: U16<LE>,
- /// Initial (relative) CS value
- pub e_cs: U16<LE>,
- /// File address of relocation table
- pub e_lfarlc: U16<LE>,
- /// Overlay number
- pub e_ovno: U16<LE>,
- /// Reserved words
- pub e_res: [U16<LE>; 4],
- /// OEM identifier (for e_oeminfo)
- pub e_oemid: U16<LE>,
- /// OEM information; e_oemid specific
- pub e_oeminfo: U16<LE>,
- /// Reserved words
- pub e_res2: [U16<LE>; 10],
- /// File address of new exe header
- pub e_lfanew: U32<LE>,
-}
-
-/// OS/2 .EXE header
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageOs2Header {
- /// Magic number
- pub ne_magic: U16<LE>,
- /// Version number
- pub ne_ver: i8,
- /// Revision number
- pub ne_rev: i8,
- /// Offset of Entry Table
- pub ne_enttab: U16<LE>,
- /// Number of bytes in Entry Table
- pub ne_cbenttab: U16<LE>,
- /// Checksum of whole file
- pub ne_crc: I32<LE>,
- /// Flag word
- pub ne_flags: U16<LE>,
- /// Automatic data segment number
- pub ne_autodata: U16<LE>,
- /// Initial heap allocation
- pub ne_heap: U16<LE>,
- /// Initial stack allocation
- pub ne_stack: U16<LE>,
- /// Initial CS:IP setting
- pub ne_csip: I32<LE>,
- /// Initial SS:SP setting
- pub ne_sssp: I32<LE>,
- /// Count of file segments
- pub ne_cseg: U16<LE>,
- /// Entries in Module Reference Table
- pub ne_cmod: U16<LE>,
- /// Size of non-resident name table
- pub ne_cbnrestab: U16<LE>,
- /// Offset of Segment Table
- pub ne_segtab: U16<LE>,
- /// Offset of Resource Table
- pub ne_rsrctab: U16<LE>,
- /// Offset of resident name table
- pub ne_restab: U16<LE>,
- /// Offset of Module Reference Table
- pub ne_modtab: U16<LE>,
- /// Offset of Imported Names Table
- pub ne_imptab: U16<LE>,
- /// Offset of Non-resident Names Table
- pub ne_nrestab: I32<LE>,
- /// Count of movable entries
- pub ne_cmovent: U16<LE>,
- /// Segment alignment shift count
- pub ne_align: U16<LE>,
- /// Count of resource segments
- pub ne_cres: U16<LE>,
- /// Target Operating system
- pub ne_exetyp: u8,
- /// Other .EXE flags
- pub ne_flagsothers: u8,
- /// offset to return thunks
- pub ne_pretthunks: U16<LE>,
- /// offset to segment ref. bytes
- pub ne_psegrefbytes: U16<LE>,
- /// Minimum code swap area size
- pub ne_swaparea: U16<LE>,
- /// Expected Windows version number
- pub ne_expver: U16<LE>,
-}
-
-/// Windows VXD header
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageVxdHeader {
- /// Magic number
- pub e32_magic: U16<LE>,
- /// The byte ordering for the VXD
- pub e32_border: u8,
- /// The word ordering for the VXD
- pub e32_worder: u8,
- /// The EXE format level for now = 0
- pub e32_level: U32<LE>,
- /// The CPU type
- pub e32_cpu: U16<LE>,
- /// The OS type
- pub e32_os: U16<LE>,
- /// Module version
- pub e32_ver: U32<LE>,
- /// Module flags
- pub e32_mflags: U32<LE>,
- /// Module # pages
- pub e32_mpages: U32<LE>,
- /// Object # for instruction pointer
- pub e32_startobj: U32<LE>,
- /// Extended instruction pointer
- pub e32_eip: U32<LE>,
- /// Object # for stack pointer
- pub e32_stackobj: U32<LE>,
- /// Extended stack pointer
- pub e32_esp: U32<LE>,
- /// VXD page size
- pub e32_pagesize: U32<LE>,
- /// Last page size in VXD
- pub e32_lastpagesize: U32<LE>,
- /// Fixup section size
- pub e32_fixupsize: U32<LE>,
- /// Fixup section checksum
- pub e32_fixupsum: U32<LE>,
- /// Loader section size
- pub e32_ldrsize: U32<LE>,
- /// Loader section checksum
- pub e32_ldrsum: U32<LE>,
- /// Object table offset
- pub e32_objtab: U32<LE>,
- /// Number of objects in module
- pub e32_objcnt: U32<LE>,
- /// Object page map offset
- pub e32_objmap: U32<LE>,
- /// Object iterated data map offset
- pub e32_itermap: U32<LE>,
- /// Offset of Resource Table
- pub e32_rsrctab: U32<LE>,
- /// Number of resource entries
- pub e32_rsrccnt: U32<LE>,
- /// Offset of resident name table
- pub e32_restab: U32<LE>,
- /// Offset of Entry Table
- pub e32_enttab: U32<LE>,
- /// Offset of Module Directive Table
- pub e32_dirtab: U32<LE>,
- /// Number of module directives
- pub e32_dircnt: U32<LE>,
- /// Offset of Fixup Page Table
- pub e32_fpagetab: U32<LE>,
- /// Offset of Fixup Record Table
- pub e32_frectab: U32<LE>,
- /// Offset of Import Module Name Table
- pub e32_impmod: U32<LE>,
- /// Number of entries in Import Module Name Table
- pub e32_impmodcnt: U32<LE>,
- /// Offset of Import Procedure Name Table
- pub e32_impproc: U32<LE>,
- /// Offset of Per-Page Checksum Table
- pub e32_pagesum: U32<LE>,
- /// Offset of Enumerated Data Pages
- pub e32_datapage: U32<LE>,
- /// Number of preload pages
- pub e32_preload: U32<LE>,
- /// Offset of Non-resident Names Table
- pub e32_nrestab: U32<LE>,
- /// Size of Non-resident Name Table
- pub e32_cbnrestab: U32<LE>,
- /// Non-resident Name Table Checksum
- pub e32_nressum: U32<LE>,
- /// Object # for automatic data object
- pub e32_autodata: U32<LE>,
- /// Offset of the debugging information
- pub e32_debuginfo: U32<LE>,
- /// The length of the debugging info. in bytes
- pub e32_debuglen: U32<LE>,
- /// Number of instance pages in preload section of VXD file
- pub e32_instpreload: U32<LE>,
- /// Number of instance pages in demand load section of VXD file
- pub e32_instdemand: U32<LE>,
- /// Size of heap - for 16-bit apps
- pub e32_heapsize: U32<LE>,
- /// Reserved words
- pub e32_res3: [u8; 12],
- pub e32_winresoff: U32<LE>,
- pub e32_winreslen: U32<LE>,
- /// Device ID for VxD
- pub e32_devid: U16<LE>,
- /// DDK version for VxD
- pub e32_ddkver: U16<LE>,
-}
-
-/// A PE rich header entry.
-///
-/// Rich headers have no official documentation, but have been heavily
-/// reversed-engineered and documented in the wild, e.g.:
-/// * `http://www.ntcore.com/files/richsign.htm`
-/// * `https://www.researchgate.net/figure/Structure-of-the-Rich-Header_fig1_318145388`
-///
-/// This data is "masked", i.e. XORed with a checksum derived from the file data.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct MaskedRichHeaderEntry {
- pub masked_comp_id: U32<LE>,
- pub masked_count: U32<LE>,
-}
-
-//
-// File header format.
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageFileHeader {
- pub machine: U16<LE>,
- pub number_of_sections: U16<LE>,
- pub time_date_stamp: U32<LE>,
- pub pointer_to_symbol_table: U32<LE>,
- pub number_of_symbols: U32<LE>,
- pub size_of_optional_header: U16<LE>,
- pub characteristics: U16<LE>,
-}
-
-pub const IMAGE_SIZEOF_FILE_HEADER: usize = 20;
-
-/// Relocation info stripped from file.
-pub const IMAGE_FILE_RELOCS_STRIPPED: u16 = 0x0001;
-/// File is executable (i.e. no unresolved external references).
-pub const IMAGE_FILE_EXECUTABLE_IMAGE: u16 = 0x0002;
-/// Line numbers stripped from file.
-pub const IMAGE_FILE_LINE_NUMS_STRIPPED: u16 = 0x0004;
-/// Local symbols stripped from file.
-pub const IMAGE_FILE_LOCAL_SYMS_STRIPPED: u16 = 0x0008;
-/// Aggressively trim working set
-pub const IMAGE_FILE_AGGRESIVE_WS_TRIM: u16 = 0x0010;
-/// App can handle >2gb addresses
-pub const IMAGE_FILE_LARGE_ADDRESS_AWARE: u16 = 0x0020;
-/// Bytes of machine word are reversed.
-pub const IMAGE_FILE_BYTES_REVERSED_LO: u16 = 0x0080;
-/// 32 bit word machine.
-pub const IMAGE_FILE_32BIT_MACHINE: u16 = 0x0100;
-/// Debugging info stripped from file in .DBG file
-pub const IMAGE_FILE_DEBUG_STRIPPED: u16 = 0x0200;
-/// If Image is on removable media, copy and run from the swap file.
-pub const IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP: u16 = 0x0400;
-/// If Image is on Net, copy and run from the swap file.
-pub const IMAGE_FILE_NET_RUN_FROM_SWAP: u16 = 0x0800;
-/// System File.
-pub const IMAGE_FILE_SYSTEM: u16 = 0x1000;
-/// File is a DLL.
-pub const IMAGE_FILE_DLL: u16 = 0x2000;
-/// File should only be run on a UP machine
-pub const IMAGE_FILE_UP_SYSTEM_ONLY: u16 = 0x4000;
-/// Bytes of machine word are reversed.
-pub const IMAGE_FILE_BYTES_REVERSED_HI: u16 = 0x8000;
-
-pub const IMAGE_FILE_MACHINE_UNKNOWN: u16 = 0;
-/// Useful for indicating we want to interact with the host and not a WoW guest.
-pub const IMAGE_FILE_MACHINE_TARGET_HOST: u16 = 0x0001;
-/// Intel 386.
-pub const IMAGE_FILE_MACHINE_I386: u16 = 0x014c;
-/// MIPS little-endian, 0x160 big-endian
-pub const IMAGE_FILE_MACHINE_R3000: u16 = 0x0162;
-/// MIPS little-endian
-pub const IMAGE_FILE_MACHINE_R4000: u16 = 0x0166;
-/// MIPS little-endian
-pub const IMAGE_FILE_MACHINE_R10000: u16 = 0x0168;
-/// MIPS little-endian WCE v2
-pub const IMAGE_FILE_MACHINE_WCEMIPSV2: u16 = 0x0169;
-/// Alpha_AXP
-pub const IMAGE_FILE_MACHINE_ALPHA: u16 = 0x0184;
-/// SH3 little-endian
-pub const IMAGE_FILE_MACHINE_SH3: u16 = 0x01a2;
-pub const IMAGE_FILE_MACHINE_SH3DSP: u16 = 0x01a3;
-/// SH3E little-endian
-pub const IMAGE_FILE_MACHINE_SH3E: u16 = 0x01a4;
-/// SH4 little-endian
-pub const IMAGE_FILE_MACHINE_SH4: u16 = 0x01a6;
-/// SH5
-pub const IMAGE_FILE_MACHINE_SH5: u16 = 0x01a8;
-/// ARM Little-Endian
-pub const IMAGE_FILE_MACHINE_ARM: u16 = 0x01c0;
-/// ARM Thumb/Thumb-2 Little-Endian
-pub const IMAGE_FILE_MACHINE_THUMB: u16 = 0x01c2;
-/// ARM Thumb-2 Little-Endian
-pub const IMAGE_FILE_MACHINE_ARMNT: u16 = 0x01c4;
-pub const IMAGE_FILE_MACHINE_AM33: u16 = 0x01d3;
-/// IBM PowerPC Little-Endian
-pub const IMAGE_FILE_MACHINE_POWERPC: u16 = 0x01F0;
-pub const IMAGE_FILE_MACHINE_POWERPCFP: u16 = 0x01f1;
-/// Intel 64
-pub const IMAGE_FILE_MACHINE_IA64: u16 = 0x0200;
-/// MIPS
-pub const IMAGE_FILE_MACHINE_MIPS16: u16 = 0x0266;
-/// ALPHA64
-pub const IMAGE_FILE_MACHINE_ALPHA64: u16 = 0x0284;
-/// MIPS
-pub const IMAGE_FILE_MACHINE_MIPSFPU: u16 = 0x0366;
-/// MIPS
-pub const IMAGE_FILE_MACHINE_MIPSFPU16: u16 = 0x0466;
-pub const IMAGE_FILE_MACHINE_AXP64: u16 = IMAGE_FILE_MACHINE_ALPHA64;
-/// Infineon
-pub const IMAGE_FILE_MACHINE_TRICORE: u16 = 0x0520;
-pub const IMAGE_FILE_MACHINE_CEF: u16 = 0x0CEF;
-/// EFI Byte Code
-pub const IMAGE_FILE_MACHINE_EBC: u16 = 0x0EBC;
-/// AMD64 (K8)
-pub const IMAGE_FILE_MACHINE_AMD64: u16 = 0x8664;
-/// M32R little-endian
-pub const IMAGE_FILE_MACHINE_M32R: u16 = 0x9041;
-/// ARM64 Little-Endian
-pub const IMAGE_FILE_MACHINE_ARM64: u16 = 0xAA64;
-/// ARM64EC ("Emulation Compatible")
-pub const IMAGE_FILE_MACHINE_ARM64EC: u16 = 0xA641;
-pub const IMAGE_FILE_MACHINE_CEE: u16 = 0xC0EE;
-/// RISCV32
-pub const IMAGE_FILE_MACHINE_RISCV32: u16 = 0x5032;
-/// RISCV64
-pub const IMAGE_FILE_MACHINE_RISCV64: u16 = 0x5064;
-/// RISCV128
-pub const IMAGE_FILE_MACHINE_RISCV128: u16 = 0x5128;
-
-//
-// Directory format.
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageDataDirectory {
- pub virtual_address: U32<LE>,
- pub size: U32<LE>,
-}
-
-pub const IMAGE_NUMBEROF_DIRECTORY_ENTRIES: usize = 16;
-
-//
-// Optional header format.
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageOptionalHeader32 {
- // Standard fields.
- pub magic: U16<LE>,
- pub major_linker_version: u8,
- pub minor_linker_version: u8,
- pub size_of_code: U32<LE>,
- pub size_of_initialized_data: U32<LE>,
- pub size_of_uninitialized_data: U32<LE>,
- pub address_of_entry_point: U32<LE>,
- pub base_of_code: U32<LE>,
- pub base_of_data: U32<LE>,
-
- // NT additional fields.
- pub image_base: U32<LE>,
- pub section_alignment: U32<LE>,
- pub file_alignment: U32<LE>,
- pub major_operating_system_version: U16<LE>,
- pub minor_operating_system_version: U16<LE>,
- pub major_image_version: U16<LE>,
- pub minor_image_version: U16<LE>,
- pub major_subsystem_version: U16<LE>,
- pub minor_subsystem_version: U16<LE>,
- pub win32_version_value: U32<LE>,
- pub size_of_image: U32<LE>,
- pub size_of_headers: U32<LE>,
- pub check_sum: U32<LE>,
- pub subsystem: U16<LE>,
- pub dll_characteristics: U16<LE>,
- pub size_of_stack_reserve: U32<LE>,
- pub size_of_stack_commit: U32<LE>,
- pub size_of_heap_reserve: U32<LE>,
- pub size_of_heap_commit: U32<LE>,
- pub loader_flags: U32<LE>,
- pub number_of_rva_and_sizes: U32<LE>,
- //pub data_directory: [ImageDataDirectory; IMAGE_NUMBEROF_DIRECTORY_ENTRIES],
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageRomOptionalHeader {
- pub magic: U16<LE>,
- pub major_linker_version: u8,
- pub minor_linker_version: u8,
- pub size_of_code: U32<LE>,
- pub size_of_initialized_data: U32<LE>,
- pub size_of_uninitialized_data: U32<LE>,
- pub address_of_entry_point: U32<LE>,
- pub base_of_code: U32<LE>,
- pub base_of_data: U32<LE>,
- pub base_of_bss: U32<LE>,
- pub gpr_mask: U32<LE>,
- pub cpr_mask: [U32<LE>; 4],
- pub gp_value: U32<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageOptionalHeader64 {
- pub magic: U16<LE>,
- pub major_linker_version: u8,
- pub minor_linker_version: u8,
- pub size_of_code: U32<LE>,
- pub size_of_initialized_data: U32<LE>,
- pub size_of_uninitialized_data: U32<LE>,
- pub address_of_entry_point: U32<LE>,
- pub base_of_code: U32<LE>,
- pub image_base: U64<LE>,
- pub section_alignment: U32<LE>,
- pub file_alignment: U32<LE>,
- pub major_operating_system_version: U16<LE>,
- pub minor_operating_system_version: U16<LE>,
- pub major_image_version: U16<LE>,
- pub minor_image_version: U16<LE>,
- pub major_subsystem_version: U16<LE>,
- pub minor_subsystem_version: U16<LE>,
- pub win32_version_value: U32<LE>,
- pub size_of_image: U32<LE>,
- pub size_of_headers: U32<LE>,
- pub check_sum: U32<LE>,
- pub subsystem: U16<LE>,
- pub dll_characteristics: U16<LE>,
- pub size_of_stack_reserve: U64<LE>,
- pub size_of_stack_commit: U64<LE>,
- pub size_of_heap_reserve: U64<LE>,
- pub size_of_heap_commit: U64<LE>,
- pub loader_flags: U32<LE>,
- pub number_of_rva_and_sizes: U32<LE>,
- //pub data_directory: [ImageDataDirectory; IMAGE_NUMBEROF_DIRECTORY_ENTRIES],
-}
-
-pub const IMAGE_NT_OPTIONAL_HDR32_MAGIC: u16 = 0x10b;
-pub const IMAGE_NT_OPTIONAL_HDR64_MAGIC: u16 = 0x20b;
-pub const IMAGE_ROM_OPTIONAL_HDR_MAGIC: u16 = 0x107;
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageNtHeaders64 {
- pub signature: U32<LE>,
- pub file_header: ImageFileHeader,
- pub optional_header: ImageOptionalHeader64,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageNtHeaders32 {
- pub signature: U32<LE>,
- pub file_header: ImageFileHeader,
- pub optional_header: ImageOptionalHeader32,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageRomHeaders {
- pub file_header: ImageFileHeader,
- pub optional_header: ImageRomOptionalHeader,
-}
-
-// Values for `ImageOptionalHeader*::subsystem`.
-
-/// Unknown subsystem.
-pub const IMAGE_SUBSYSTEM_UNKNOWN: u16 = 0;
-/// Image doesn't require a subsystem.
-pub const IMAGE_SUBSYSTEM_NATIVE: u16 = 1;
-/// Image runs in the Windows GUI subsystem.
-pub const IMAGE_SUBSYSTEM_WINDOWS_GUI: u16 = 2;
-/// Image runs in the Windows character subsystem.
-pub const IMAGE_SUBSYSTEM_WINDOWS_CUI: u16 = 3;
-/// image runs in the OS/2 character subsystem.
-pub const IMAGE_SUBSYSTEM_OS2_CUI: u16 = 5;
-/// image runs in the Posix character subsystem.
-pub const IMAGE_SUBSYSTEM_POSIX_CUI: u16 = 7;
-/// image is a native Win9x driver.
-pub const IMAGE_SUBSYSTEM_NATIVE_WINDOWS: u16 = 8;
-/// Image runs in the Windows CE subsystem.
-pub const IMAGE_SUBSYSTEM_WINDOWS_CE_GUI: u16 = 9;
-pub const IMAGE_SUBSYSTEM_EFI_APPLICATION: u16 = 10;
-pub const IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER: u16 = 11;
-pub const IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER: u16 = 12;
-pub const IMAGE_SUBSYSTEM_EFI_ROM: u16 = 13;
-pub const IMAGE_SUBSYSTEM_XBOX: u16 = 14;
-pub const IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION: u16 = 16;
-pub const IMAGE_SUBSYSTEM_XBOX_CODE_CATALOG: u16 = 17;
-
-// Values for `ImageOptionalHeader*::dll_characteristics`.
-
-// IMAGE_LIBRARY_PROCESS_INIT 0x0001 // Reserved.
-// IMAGE_LIBRARY_PROCESS_TERM 0x0002 // Reserved.
-// IMAGE_LIBRARY_THREAD_INIT 0x0004 // Reserved.
-// IMAGE_LIBRARY_THREAD_TERM 0x0008 // Reserved.
-/// Image can handle a high entropy 64-bit virtual address space.
-pub const IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA: u16 = 0x0020;
-/// DLL can move.
-pub const IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE: u16 = 0x0040;
-/// Code Integrity Image
-pub const IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY: u16 = 0x0080;
-/// Image is NX compatible
-pub const IMAGE_DLLCHARACTERISTICS_NX_COMPAT: u16 = 0x0100;
-/// Image understands isolation and doesn't want it
-pub const IMAGE_DLLCHARACTERISTICS_NO_ISOLATION: u16 = 0x0200;
-/// Image does not use SEH. No SE handler may reside in this image
-pub const IMAGE_DLLCHARACTERISTICS_NO_SEH: u16 = 0x0400;
-/// Do not bind this image.
-pub const IMAGE_DLLCHARACTERISTICS_NO_BIND: u16 = 0x0800;
-/// Image should execute in an AppContainer
-pub const IMAGE_DLLCHARACTERISTICS_APPCONTAINER: u16 = 0x1000;
-/// Driver uses WDM model
-pub const IMAGE_DLLCHARACTERISTICS_WDM_DRIVER: u16 = 0x2000;
-/// Image supports Control Flow Guard.
-pub const IMAGE_DLLCHARACTERISTICS_GUARD_CF: u16 = 0x4000;
-pub const IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE: u16 = 0x8000;
-
-// Indices for `ImageOptionalHeader*::data_directory`.
-
-/// Export Directory
-pub const IMAGE_DIRECTORY_ENTRY_EXPORT: usize = 0;
-/// Import Directory
-pub const IMAGE_DIRECTORY_ENTRY_IMPORT: usize = 1;
-/// Resource Directory
-pub const IMAGE_DIRECTORY_ENTRY_RESOURCE: usize = 2;
-/// Exception Directory
-pub const IMAGE_DIRECTORY_ENTRY_EXCEPTION: usize = 3;
-/// Security Directory
-pub const IMAGE_DIRECTORY_ENTRY_SECURITY: usize = 4;
-/// Base Relocation Table
-pub const IMAGE_DIRECTORY_ENTRY_BASERELOC: usize = 5;
-/// Debug Directory
-pub const IMAGE_DIRECTORY_ENTRY_DEBUG: usize = 6;
-// IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage)
-/// Architecture Specific Data
-pub const IMAGE_DIRECTORY_ENTRY_ARCHITECTURE: usize = 7;
-/// RVA of GP
-pub const IMAGE_DIRECTORY_ENTRY_GLOBALPTR: usize = 8;
-/// TLS Directory
-pub const IMAGE_DIRECTORY_ENTRY_TLS: usize = 9;
-/// Load Configuration Directory
-pub const IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG: usize = 10;
-/// Bound Import Directory in headers
-pub const IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT: usize = 11;
-/// Import Address Table
-pub const IMAGE_DIRECTORY_ENTRY_IAT: usize = 12;
-/// Delay Load Import Descriptors
-pub const IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT: usize = 13;
-/// COM Runtime descriptor
-pub const IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR: usize = 14;
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-#[repr(C)]
-pub struct Guid(pub [u8; 16]);
-
-impl Guid {
- #[inline]
- pub fn data1(self) -> U32<LE> {
- U32::from_bytes(self.0[0..4].try_into().unwrap())
- }
-
- #[inline]
- pub fn data2(self) -> U16<LE> {
- U16::from_bytes(self.0[4..6].try_into().unwrap())
- }
-
- #[inline]
- pub fn data3(self) -> U16<LE> {
- U16::from_bytes(self.0[6..8].try_into().unwrap())
- }
-
- #[inline]
- pub fn data4(self) -> [u8; 8] {
- self.0[8..16].try_into().unwrap()
- }
-}
-
-pub use Guid as ClsId;
-
-/// Non-COFF Object file header
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct AnonObjectHeader {
- /// Must be IMAGE_FILE_MACHINE_UNKNOWN
- pub sig1: U16<LE>,
- /// Must be 0xffff
- pub sig2: U16<LE>,
- /// >= 1 (implies the ClsId field is present)
- pub version: U16<LE>,
- pub machine: U16<LE>,
- pub time_date_stamp: U32<LE>,
- /// Used to invoke CoCreateInstance
- pub class_id: ClsId,
- /// Size of data that follows the header
- pub size_of_data: U32<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct AnonObjectHeaderV2 {
- /// Must be IMAGE_FILE_MACHINE_UNKNOWN
- pub sig1: U16<LE>,
- /// Must be 0xffff
- pub sig2: U16<LE>,
- /// >= 2 (implies the Flags field is present - otherwise V1)
- pub version: U16<LE>,
- pub machine: U16<LE>,
- pub time_date_stamp: U32<LE>,
- /// Used to invoke CoCreateInstance
- pub class_id: ClsId,
- /// Size of data that follows the header
- pub size_of_data: U32<LE>,
- /// 0x1 -> contains metadata
- pub flags: U32<LE>,
- /// Size of CLR metadata
- pub meta_data_size: U32<LE>,
- /// Offset of CLR metadata
- pub meta_data_offset: U32<LE>,
-}
-
-/// The required value of `AnonObjectHeaderBigobj::class_id`.
-pub const ANON_OBJECT_HEADER_BIGOBJ_CLASS_ID: ClsId = ClsId([
- 0xC7, 0xA1, 0xBA, 0xD1, 0xEE, 0xBA, 0xA9, 0x4B, 0xAF, 0x20, 0xFA, 0xF6, 0x6A, 0xA4, 0xDC, 0xB8,
-]);
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct AnonObjectHeaderBigobj {
- /* same as ANON_OBJECT_HEADER_V2 */
- /// Must be IMAGE_FILE_MACHINE_UNKNOWN
- pub sig1: U16<LE>,
- /// Must be 0xffff
- pub sig2: U16<LE>,
- /// >= 2 (implies the Flags field is present)
- pub version: U16<LE>,
- /// Actual machine - IMAGE_FILE_MACHINE_xxx
- pub machine: U16<LE>,
- pub time_date_stamp: U32<LE>,
- /// Must be `ANON_OBJECT_HEADER_BIGOBJ_CLASS_ID`.
- pub class_id: ClsId,
- /// Size of data that follows the header
- pub size_of_data: U32<LE>,
- /// 0x1 -> contains metadata
- pub flags: U32<LE>,
- /// Size of CLR metadata
- pub meta_data_size: U32<LE>,
- /// Offset of CLR metadata
- pub meta_data_offset: U32<LE>,
-
- /* bigobj specifics */
- /// extended from WORD
- pub number_of_sections: U32<LE>,
- pub pointer_to_symbol_table: U32<LE>,
- pub number_of_symbols: U32<LE>,
-}
-
-pub const IMAGE_SIZEOF_SHORT_NAME: usize = 8;
-
-//
-// Section header format.
-//
-
-#[derive(Debug, Default, Clone, Copy)]
-#[repr(C)]
-pub struct ImageSectionHeader {
- pub name: [u8; IMAGE_SIZEOF_SHORT_NAME],
- pub virtual_size: U32<LE>,
- pub virtual_address: U32<LE>,
- pub size_of_raw_data: U32<LE>,
- pub pointer_to_raw_data: U32<LE>,
- pub pointer_to_relocations: U32<LE>,
- pub pointer_to_linenumbers: U32<LE>,
- pub number_of_relocations: U16<LE>,
- pub number_of_linenumbers: U16<LE>,
- pub characteristics: U32<LE>,
-}
-
-pub const IMAGE_SIZEOF_SECTION_HEADER: usize = 40;
-
-// Values for `ImageSectionHeader::characteristics`.
-
-// IMAGE_SCN_TYPE_REG 0x00000000 // Reserved.
-// IMAGE_SCN_TYPE_DSECT 0x00000001 // Reserved.
-// IMAGE_SCN_TYPE_NOLOAD 0x00000002 // Reserved.
-// IMAGE_SCN_TYPE_GROUP 0x00000004 // Reserved.
-/// Reserved.
-pub const IMAGE_SCN_TYPE_NO_PAD: u32 = 0x0000_0008;
-// IMAGE_SCN_TYPE_COPY 0x00000010 // Reserved.
-
-/// Section contains code.
-pub const IMAGE_SCN_CNT_CODE: u32 = 0x0000_0020;
-/// Section contains initialized data.
-pub const IMAGE_SCN_CNT_INITIALIZED_DATA: u32 = 0x0000_0040;
-/// Section contains uninitialized data.
-pub const IMAGE_SCN_CNT_UNINITIALIZED_DATA: u32 = 0x0000_0080;
-
-/// Reserved.
-pub const IMAGE_SCN_LNK_OTHER: u32 = 0x0000_0100;
-/// Section contains comments or some other type of information.
-pub const IMAGE_SCN_LNK_INFO: u32 = 0x0000_0200;
-// IMAGE_SCN_TYPE_OVER 0x00000400 // Reserved.
-/// Section contents will not become part of image.
-pub const IMAGE_SCN_LNK_REMOVE: u32 = 0x0000_0800;
-/// Section contents comdat.
-pub const IMAGE_SCN_LNK_COMDAT: u32 = 0x0000_1000;
-// 0x00002000 // Reserved.
-// IMAGE_SCN_MEM_PROTECTED - Obsolete 0x00004000
-/// Reset speculative exceptions handling bits in the TLB entries for this section.
-pub const IMAGE_SCN_NO_DEFER_SPEC_EXC: u32 = 0x0000_4000;
-/// Section content can be accessed relative to GP
-pub const IMAGE_SCN_GPREL: u32 = 0x0000_8000;
-pub const IMAGE_SCN_MEM_FARDATA: u32 = 0x0000_8000;
-// IMAGE_SCN_MEM_SYSHEAP - Obsolete 0x00010000
-pub const IMAGE_SCN_MEM_PURGEABLE: u32 = 0x0002_0000;
-pub const IMAGE_SCN_MEM_16BIT: u32 = 0x0002_0000;
-pub const IMAGE_SCN_MEM_LOCKED: u32 = 0x0004_0000;
-pub const IMAGE_SCN_MEM_PRELOAD: u32 = 0x0008_0000;
-
-pub const IMAGE_SCN_ALIGN_1BYTES: u32 = 0x0010_0000;
-pub const IMAGE_SCN_ALIGN_2BYTES: u32 = 0x0020_0000;
-pub const IMAGE_SCN_ALIGN_4BYTES: u32 = 0x0030_0000;
-pub const IMAGE_SCN_ALIGN_8BYTES: u32 = 0x0040_0000;
-/// Default alignment if no others are specified.
-pub const IMAGE_SCN_ALIGN_16BYTES: u32 = 0x0050_0000;
-pub const IMAGE_SCN_ALIGN_32BYTES: u32 = 0x0060_0000;
-pub const IMAGE_SCN_ALIGN_64BYTES: u32 = 0x0070_0000;
-pub const IMAGE_SCN_ALIGN_128BYTES: u32 = 0x0080_0000;
-pub const IMAGE_SCN_ALIGN_256BYTES: u32 = 0x0090_0000;
-pub const IMAGE_SCN_ALIGN_512BYTES: u32 = 0x00A0_0000;
-pub const IMAGE_SCN_ALIGN_1024BYTES: u32 = 0x00B0_0000;
-pub const IMAGE_SCN_ALIGN_2048BYTES: u32 = 0x00C0_0000;
-pub const IMAGE_SCN_ALIGN_4096BYTES: u32 = 0x00D0_0000;
-pub const IMAGE_SCN_ALIGN_8192BYTES: u32 = 0x00E0_0000;
-// Unused 0x00F0_0000
-pub const IMAGE_SCN_ALIGN_MASK: u32 = 0x00F0_0000;
-
-/// Section contains extended relocations.
-pub const IMAGE_SCN_LNK_NRELOC_OVFL: u32 = 0x0100_0000;
-/// Section can be discarded.
-pub const IMAGE_SCN_MEM_DISCARDABLE: u32 = 0x0200_0000;
-/// Section is not cacheable.
-pub const IMAGE_SCN_MEM_NOT_CACHED: u32 = 0x0400_0000;
-/// Section is not pageable.
-pub const IMAGE_SCN_MEM_NOT_PAGED: u32 = 0x0800_0000;
-/// Section is shareable.
-pub const IMAGE_SCN_MEM_SHARED: u32 = 0x1000_0000;
-/// Section is executable.
-pub const IMAGE_SCN_MEM_EXECUTE: u32 = 0x2000_0000;
-/// Section is readable.
-pub const IMAGE_SCN_MEM_READ: u32 = 0x4000_0000;
-/// Section is writeable.
-pub const IMAGE_SCN_MEM_WRITE: u32 = 0x8000_0000;
-
-//
-// TLS Characteristic Flags
-//
-/// Tls index is scaled
-pub const IMAGE_SCN_SCALE_INDEX: u32 = 0x0000_0001;
-
-//
-// Symbol format.
-//
-
-// This struct has alignment 1.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageSymbol {
- /// If first 4 bytes are 0, then second 4 bytes are offset into string table.
- pub name: [u8; 8],
- pub value: U32Bytes<LE>,
- pub section_number: U16Bytes<LE>,
- pub typ: U16Bytes<LE>,
- pub storage_class: u8,
- pub number_of_aux_symbols: u8,
-}
-
-pub const IMAGE_SIZEOF_SYMBOL: usize = 18;
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageSymbolBytes(pub [u8; IMAGE_SIZEOF_SYMBOL]);
-
-// This struct has alignment 1.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageSymbolEx {
- /// If first 4 bytes are 0, then second 4 bytes are offset into string table.
- pub name: [u8; 8],
- pub value: U32Bytes<LE>,
- pub section_number: I32Bytes<LE>,
- pub typ: U16Bytes<LE>,
- pub storage_class: u8,
- pub number_of_aux_symbols: u8,
-}
-
-pub const IMAGE_SIZEOF_SYMBOL_EX: usize = 20;
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageSymbolExBytes(pub [u8; IMAGE_SIZEOF_SYMBOL_EX]);
-
-// Values for `ImageSymbol::section_number`.
-//
-// Symbols have a section number of the section in which they are
-// defined. Otherwise, section numbers have the following meanings:
-
-/// Symbol is undefined or is common.
-pub const IMAGE_SYM_UNDEFINED: i32 = 0;
-/// Symbol is an absolute value.
-pub const IMAGE_SYM_ABSOLUTE: i32 = -1;
-/// Symbol is a special debug item.
-pub const IMAGE_SYM_DEBUG: i32 = -2;
-/// Values 0xFF00-0xFFFF are special
-pub const IMAGE_SYM_SECTION_MAX: u16 = 0xFEFF;
-pub const IMAGE_SYM_SECTION_MAX_EX: u32 = 0x7fff_ffff;
-
-// Values for `ImageSymbol::typ` (basic component).
-
-/// no type.
-pub const IMAGE_SYM_TYPE_NULL: u16 = 0x0000;
-pub const IMAGE_SYM_TYPE_VOID: u16 = 0x0001;
-/// type character.
-pub const IMAGE_SYM_TYPE_CHAR: u16 = 0x0002;
-/// type short integer.
-pub const IMAGE_SYM_TYPE_SHORT: u16 = 0x0003;
-pub const IMAGE_SYM_TYPE_INT: u16 = 0x0004;
-pub const IMAGE_SYM_TYPE_LONG: u16 = 0x0005;
-pub const IMAGE_SYM_TYPE_FLOAT: u16 = 0x0006;
-pub const IMAGE_SYM_TYPE_DOUBLE: u16 = 0x0007;
-pub const IMAGE_SYM_TYPE_STRUCT: u16 = 0x0008;
-pub const IMAGE_SYM_TYPE_UNION: u16 = 0x0009;
-/// enumeration.
-pub const IMAGE_SYM_TYPE_ENUM: u16 = 0x000A;
-/// member of enumeration.
-pub const IMAGE_SYM_TYPE_MOE: u16 = 0x000B;
-pub const IMAGE_SYM_TYPE_BYTE: u16 = 0x000C;
-pub const IMAGE_SYM_TYPE_WORD: u16 = 0x000D;
-pub const IMAGE_SYM_TYPE_UINT: u16 = 0x000E;
-pub const IMAGE_SYM_TYPE_DWORD: u16 = 0x000F;
-pub const IMAGE_SYM_TYPE_PCODE: u16 = 0x8000;
-
-// Values for `ImageSymbol::typ` (derived component).
-
-/// no derived type.
-pub const IMAGE_SYM_DTYPE_NULL: u16 = 0;
-/// pointer.
-pub const IMAGE_SYM_DTYPE_POINTER: u16 = 1;
-/// function.
-pub const IMAGE_SYM_DTYPE_FUNCTION: u16 = 2;
-/// array.
-pub const IMAGE_SYM_DTYPE_ARRAY: u16 = 3;
-
-// Values for `ImageSymbol::storage_class`.
-pub const IMAGE_SYM_CLASS_END_OF_FUNCTION: u8 = 0xff;
-pub const IMAGE_SYM_CLASS_NULL: u8 = 0x00;
-pub const IMAGE_SYM_CLASS_AUTOMATIC: u8 = 0x01;
-pub const IMAGE_SYM_CLASS_EXTERNAL: u8 = 0x02;
-pub const IMAGE_SYM_CLASS_STATIC: u8 = 0x03;
-pub const IMAGE_SYM_CLASS_REGISTER: u8 = 0x04;
-pub const IMAGE_SYM_CLASS_EXTERNAL_DEF: u8 = 0x05;
-pub const IMAGE_SYM_CLASS_LABEL: u8 = 0x06;
-pub const IMAGE_SYM_CLASS_UNDEFINED_LABEL: u8 = 0x07;
-pub const IMAGE_SYM_CLASS_MEMBER_OF_STRUCT: u8 = 0x08;
-pub const IMAGE_SYM_CLASS_ARGUMENT: u8 = 0x09;
-pub const IMAGE_SYM_CLASS_STRUCT_TAG: u8 = 0x0A;
-pub const IMAGE_SYM_CLASS_MEMBER_OF_UNION: u8 = 0x0B;
-pub const IMAGE_SYM_CLASS_UNION_TAG: u8 = 0x0C;
-pub const IMAGE_SYM_CLASS_TYPE_DEFINITION: u8 = 0x0D;
-pub const IMAGE_SYM_CLASS_UNDEFINED_STATIC: u8 = 0x0E;
-pub const IMAGE_SYM_CLASS_ENUM_TAG: u8 = 0x0F;
-pub const IMAGE_SYM_CLASS_MEMBER_OF_ENUM: u8 = 0x10;
-pub const IMAGE_SYM_CLASS_REGISTER_PARAM: u8 = 0x11;
-pub const IMAGE_SYM_CLASS_BIT_FIELD: u8 = 0x12;
-
-pub const IMAGE_SYM_CLASS_FAR_EXTERNAL: u8 = 0x44;
-
-pub const IMAGE_SYM_CLASS_BLOCK: u8 = 0x64;
-pub const IMAGE_SYM_CLASS_FUNCTION: u8 = 0x65;
-pub const IMAGE_SYM_CLASS_END_OF_STRUCT: u8 = 0x66;
-pub const IMAGE_SYM_CLASS_FILE: u8 = 0x67;
-// new
-pub const IMAGE_SYM_CLASS_SECTION: u8 = 0x68;
-pub const IMAGE_SYM_CLASS_WEAK_EXTERNAL: u8 = 0x69;
-
-pub const IMAGE_SYM_CLASS_CLR_TOKEN: u8 = 0x6B;
-
-// type packing constants
-
-pub const N_BTMASK: u16 = 0x000F;
-pub const N_TMASK: u16 = 0x0030;
-pub const N_TMASK1: u16 = 0x00C0;
-pub const N_TMASK2: u16 = 0x00F0;
-pub const N_BTSHFT: usize = 4;
-pub const N_TSHIFT: usize = 2;
-
-pub const IMAGE_SYM_DTYPE_SHIFT: usize = N_BTSHFT;
-
-//
-// Auxiliary entry format.
-//
-
-// Used for both ImageSymbol and ImageSymbolEx (with padding).
-// This struct has alignment 1.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageAuxSymbolTokenDef {
- /// IMAGE_AUX_SYMBOL_TYPE
- pub aux_type: u8,
- /// Must be 0
- pub reserved1: u8,
- pub symbol_table_index: U32Bytes<LE>,
- /// Must be 0
- pub reserved2: [u8; 12],
-}
-
-pub const IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF: u16 = 1;
-
-/// Auxiliary symbol format 1: function definitions.
-// This struct has alignment 1.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageAuxSymbolFunction {
- pub tag_index: U32Bytes<LE>,
- pub total_size: U32Bytes<LE>,
- pub pointer_to_linenumber: U32Bytes<LE>,
- pub pointer_to_next_function: U32Bytes<LE>,
- pub unused: [u8; 2],
-}
-
-/// Auxiliary symbol format 2: .bf and .ef symbols.
-// This struct has alignment 1.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageAuxSymbolFunctionBeginEnd {
- pub unused1: [u8; 4],
- /// declaration line number
- pub linenumber: U16Bytes<LE>,
- pub unused2: [u8; 6],
- pub pointer_to_next_function: U32Bytes<LE>,
- pub unused3: [u8; 2],
-}
-
-/// Auxiliary symbol format 3: weak externals.
-///
-/// Used for both `ImageSymbol` and `ImageSymbolEx` (both with padding).
-// This struct has alignment 1.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageAuxSymbolWeak {
- /// the weak extern default symbol index
- pub weak_default_sym_index: U32Bytes<LE>,
- pub weak_search_type: U32Bytes<LE>,
-}
-
-/// Auxiliary symbol format 5: sections.
-///
-/// Used for both `ImageSymbol` and `ImageSymbolEx` (with padding).
-// This struct has alignment 1.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageAuxSymbolSection {
- /// section length
- pub length: U32Bytes<LE>,
- /// number of relocation entries
- pub number_of_relocations: U16Bytes<LE>,
- /// number of line numbers
- pub number_of_linenumbers: U16Bytes<LE>,
- /// checksum for communal
- pub check_sum: U32Bytes<LE>,
- /// section number to associate with
- pub number: U16Bytes<LE>,
- /// communal selection type
- pub selection: u8,
- pub reserved: u8,
- /// high bits of the section number
- pub high_number: U16Bytes<LE>,
-}
-
-// Used for both ImageSymbol and ImageSymbolEx (both with padding).
-// This struct has alignment 1.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageAuxSymbolCrc {
- pub crc: U32Bytes<LE>,
-}
-
-//
-// Communal selection types.
-//
-
-pub const IMAGE_COMDAT_SELECT_NODUPLICATES: u8 = 1;
-pub const IMAGE_COMDAT_SELECT_ANY: u8 = 2;
-pub const IMAGE_COMDAT_SELECT_SAME_SIZE: u8 = 3;
-pub const IMAGE_COMDAT_SELECT_EXACT_MATCH: u8 = 4;
-pub const IMAGE_COMDAT_SELECT_ASSOCIATIVE: u8 = 5;
-pub const IMAGE_COMDAT_SELECT_LARGEST: u8 = 6;
-pub const IMAGE_COMDAT_SELECT_NEWEST: u8 = 7;
-
-pub const IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY: u16 = 1;
-pub const IMAGE_WEAK_EXTERN_SEARCH_LIBRARY: u16 = 2;
-pub const IMAGE_WEAK_EXTERN_SEARCH_ALIAS: u16 = 3;
-pub const IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY: u16 = 4;
-
-//
-// Relocation format.
-//
-
-// This struct has alignment 1.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageRelocation {
- /// Also `RelocCount` when IMAGE_SCN_LNK_NRELOC_OVFL is set
- pub virtual_address: U32Bytes<LE>,
- pub symbol_table_index: U32Bytes<LE>,
- pub typ: U16Bytes<LE>,
-}
-
-//
-// I386 relocation types.
-//
-/// Reference is absolute, no relocation is necessary
-pub const IMAGE_REL_I386_ABSOLUTE: u16 = 0x0000;
-/// Direct 16-bit reference to the symbols virtual address
-pub const IMAGE_REL_I386_DIR16: u16 = 0x0001;
-/// PC-relative 16-bit reference to the symbols virtual address
-pub const IMAGE_REL_I386_REL16: u16 = 0x0002;
-/// Direct 32-bit reference to the symbols virtual address
-pub const IMAGE_REL_I386_DIR32: u16 = 0x0006;
-/// Direct 32-bit reference to the symbols virtual address, base not included
-pub const IMAGE_REL_I386_DIR32NB: u16 = 0x0007;
-/// Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
-pub const IMAGE_REL_I386_SEG12: u16 = 0x0009;
-pub const IMAGE_REL_I386_SECTION: u16 = 0x000A;
-pub const IMAGE_REL_I386_SECREL: u16 = 0x000B;
-/// clr token
-pub const IMAGE_REL_I386_TOKEN: u16 = 0x000C;
-/// 7 bit offset from base of section containing target
-pub const IMAGE_REL_I386_SECREL7: u16 = 0x000D;
-/// PC-relative 32-bit reference to the symbols virtual address
-pub const IMAGE_REL_I386_REL32: u16 = 0x0014;
-
-//
-// MIPS relocation types.
-//
-/// Reference is absolute, no relocation is necessary
-pub const IMAGE_REL_MIPS_ABSOLUTE: u16 = 0x0000;
-pub const IMAGE_REL_MIPS_REFHALF: u16 = 0x0001;
-pub const IMAGE_REL_MIPS_REFWORD: u16 = 0x0002;
-pub const IMAGE_REL_MIPS_JMPADDR: u16 = 0x0003;
-pub const IMAGE_REL_MIPS_REFHI: u16 = 0x0004;
-pub const IMAGE_REL_MIPS_REFLO: u16 = 0x0005;
-pub const IMAGE_REL_MIPS_GPREL: u16 = 0x0006;
-pub const IMAGE_REL_MIPS_LITERAL: u16 = 0x0007;
-pub const IMAGE_REL_MIPS_SECTION: u16 = 0x000A;
-pub const IMAGE_REL_MIPS_SECREL: u16 = 0x000B;
-/// Low 16-bit section relative reference (used for >32k TLS)
-pub const IMAGE_REL_MIPS_SECRELLO: u16 = 0x000C;
-/// High 16-bit section relative reference (used for >32k TLS)
-pub const IMAGE_REL_MIPS_SECRELHI: u16 = 0x000D;
-/// clr token
-pub const IMAGE_REL_MIPS_TOKEN: u16 = 0x000E;
-pub const IMAGE_REL_MIPS_JMPADDR16: u16 = 0x0010;
-pub const IMAGE_REL_MIPS_REFWORDNB: u16 = 0x0022;
-pub const IMAGE_REL_MIPS_PAIR: u16 = 0x0025;
-
-//
-// Alpha Relocation types.
-//
-pub const IMAGE_REL_ALPHA_ABSOLUTE: u16 = 0x0000;
-pub const IMAGE_REL_ALPHA_REFLONG: u16 = 0x0001;
-pub const IMAGE_REL_ALPHA_REFQUAD: u16 = 0x0002;
-pub const IMAGE_REL_ALPHA_GPREL32: u16 = 0x0003;
-pub const IMAGE_REL_ALPHA_LITERAL: u16 = 0x0004;
-pub const IMAGE_REL_ALPHA_LITUSE: u16 = 0x0005;
-pub const IMAGE_REL_ALPHA_GPDISP: u16 = 0x0006;
-pub const IMAGE_REL_ALPHA_BRADDR: u16 = 0x0007;
-pub const IMAGE_REL_ALPHA_HINT: u16 = 0x0008;
-pub const IMAGE_REL_ALPHA_INLINE_REFLONG: u16 = 0x0009;
-pub const IMAGE_REL_ALPHA_REFHI: u16 = 0x000A;
-pub const IMAGE_REL_ALPHA_REFLO: u16 = 0x000B;
-pub const IMAGE_REL_ALPHA_PAIR: u16 = 0x000C;
-pub const IMAGE_REL_ALPHA_MATCH: u16 = 0x000D;
-pub const IMAGE_REL_ALPHA_SECTION: u16 = 0x000E;
-pub const IMAGE_REL_ALPHA_SECREL: u16 = 0x000F;
-pub const IMAGE_REL_ALPHA_REFLONGNB: u16 = 0x0010;
-/// Low 16-bit section relative reference
-pub const IMAGE_REL_ALPHA_SECRELLO: u16 = 0x0011;
-/// High 16-bit section relative reference
-pub const IMAGE_REL_ALPHA_SECRELHI: u16 = 0x0012;
-/// High 16 bits of 48 bit reference
-pub const IMAGE_REL_ALPHA_REFQ3: u16 = 0x0013;
-/// Middle 16 bits of 48 bit reference
-pub const IMAGE_REL_ALPHA_REFQ2: u16 = 0x0014;
-/// Low 16 bits of 48 bit reference
-pub const IMAGE_REL_ALPHA_REFQ1: u16 = 0x0015;
-/// Low 16-bit GP relative reference
-pub const IMAGE_REL_ALPHA_GPRELLO: u16 = 0x0016;
-/// High 16-bit GP relative reference
-pub const IMAGE_REL_ALPHA_GPRELHI: u16 = 0x0017;
-
-//
-// IBM PowerPC relocation types.
-//
-/// NOP
-pub const IMAGE_REL_PPC_ABSOLUTE: u16 = 0x0000;
-/// 64-bit address
-pub const IMAGE_REL_PPC_ADDR64: u16 = 0x0001;
-/// 32-bit address
-pub const IMAGE_REL_PPC_ADDR32: u16 = 0x0002;
-/// 26-bit address, shifted left 2 (branch absolute)
-pub const IMAGE_REL_PPC_ADDR24: u16 = 0x0003;
-/// 16-bit address
-pub const IMAGE_REL_PPC_ADDR16: u16 = 0x0004;
-/// 16-bit address, shifted left 2 (load doubleword)
-pub const IMAGE_REL_PPC_ADDR14: u16 = 0x0005;
-/// 26-bit PC-relative offset, shifted left 2 (branch relative)
-pub const IMAGE_REL_PPC_REL24: u16 = 0x0006;
-/// 16-bit PC-relative offset, shifted left 2 (br cond relative)
-pub const IMAGE_REL_PPC_REL14: u16 = 0x0007;
-/// 16-bit offset from TOC base
-pub const IMAGE_REL_PPC_TOCREL16: u16 = 0x0008;
-/// 16-bit offset from TOC base, shifted left 2 (load doubleword)
-pub const IMAGE_REL_PPC_TOCREL14: u16 = 0x0009;
-
-/// 32-bit addr w/o image base
-pub const IMAGE_REL_PPC_ADDR32NB: u16 = 0x000A;
-/// va of containing section (as in an image sectionhdr)
-pub const IMAGE_REL_PPC_SECREL: u16 = 0x000B;
-/// sectionheader number
-pub const IMAGE_REL_PPC_SECTION: u16 = 0x000C;
-/// substitute TOC restore instruction iff symbol is glue code
-pub const IMAGE_REL_PPC_IFGLUE: u16 = 0x000D;
-/// symbol is glue code; virtual address is TOC restore instruction
-pub const IMAGE_REL_PPC_IMGLUE: u16 = 0x000E;
-/// va of containing section (limited to 16 bits)
-pub const IMAGE_REL_PPC_SECREL16: u16 = 0x000F;
-pub const IMAGE_REL_PPC_REFHI: u16 = 0x0010;
-pub const IMAGE_REL_PPC_REFLO: u16 = 0x0011;
-pub const IMAGE_REL_PPC_PAIR: u16 = 0x0012;
-/// Low 16-bit section relative reference (used for >32k TLS)
-pub const IMAGE_REL_PPC_SECRELLO: u16 = 0x0013;
-/// High 16-bit section relative reference (used for >32k TLS)
-pub const IMAGE_REL_PPC_SECRELHI: u16 = 0x0014;
-pub const IMAGE_REL_PPC_GPREL: u16 = 0x0015;
-/// clr token
-pub const IMAGE_REL_PPC_TOKEN: u16 = 0x0016;
-
-/// mask to isolate above values in IMAGE_RELOCATION.Type
-pub const IMAGE_REL_PPC_TYPEMASK: u16 = 0x00FF;
-
-// Flag bits in `ImageRelocation::typ`.
-
-/// subtract reloc value rather than adding it
-pub const IMAGE_REL_PPC_NEG: u16 = 0x0100;
-/// fix branch prediction bit to predict branch taken
-pub const IMAGE_REL_PPC_BRTAKEN: u16 = 0x0200;
-/// fix branch prediction bit to predict branch not taken
-pub const IMAGE_REL_PPC_BRNTAKEN: u16 = 0x0400;
-/// toc slot defined in file (or, data in toc)
-pub const IMAGE_REL_PPC_TOCDEFN: u16 = 0x0800;
-
-//
-// Hitachi SH3 relocation types.
-//
-/// No relocation
-pub const IMAGE_REL_SH3_ABSOLUTE: u16 = 0x0000;
-/// 16 bit direct
-pub const IMAGE_REL_SH3_DIRECT16: u16 = 0x0001;
-/// 32 bit direct
-pub const IMAGE_REL_SH3_DIRECT32: u16 = 0x0002;
-/// 8 bit direct, -128..255
-pub const IMAGE_REL_SH3_DIRECT8: u16 = 0x0003;
-/// 8 bit direct .W (0 ext.)
-pub const IMAGE_REL_SH3_DIRECT8_WORD: u16 = 0x0004;
-/// 8 bit direct .L (0 ext.)
-pub const IMAGE_REL_SH3_DIRECT8_LONG: u16 = 0x0005;
-/// 4 bit direct (0 ext.)
-pub const IMAGE_REL_SH3_DIRECT4: u16 = 0x0006;
-/// 4 bit direct .W (0 ext.)
-pub const IMAGE_REL_SH3_DIRECT4_WORD: u16 = 0x0007;
-/// 4 bit direct .L (0 ext.)
-pub const IMAGE_REL_SH3_DIRECT4_LONG: u16 = 0x0008;
-/// 8 bit PC relative .W
-pub const IMAGE_REL_SH3_PCREL8_WORD: u16 = 0x0009;
-/// 8 bit PC relative .L
-pub const IMAGE_REL_SH3_PCREL8_LONG: u16 = 0x000A;
-/// 12 LSB PC relative .W
-pub const IMAGE_REL_SH3_PCREL12_WORD: u16 = 0x000B;
-/// Start of EXE section
-pub const IMAGE_REL_SH3_STARTOF_SECTION: u16 = 0x000C;
-/// Size of EXE section
-pub const IMAGE_REL_SH3_SIZEOF_SECTION: u16 = 0x000D;
-/// Section table index
-pub const IMAGE_REL_SH3_SECTION: u16 = 0x000E;
-/// Offset within section
-pub const IMAGE_REL_SH3_SECREL: u16 = 0x000F;
-/// 32 bit direct not based
-pub const IMAGE_REL_SH3_DIRECT32_NB: u16 = 0x0010;
-/// GP-relative addressing
-pub const IMAGE_REL_SH3_GPREL4_LONG: u16 = 0x0011;
-/// clr token
-pub const IMAGE_REL_SH3_TOKEN: u16 = 0x0012;
-/// Offset from current instruction in longwords
-/// if not NOMODE, insert the inverse of the low bit at bit 32 to select PTA/PTB
-pub const IMAGE_REL_SHM_PCRELPT: u16 = 0x0013;
-/// Low bits of 32-bit address
-pub const IMAGE_REL_SHM_REFLO: u16 = 0x0014;
-/// High bits of 32-bit address
-pub const IMAGE_REL_SHM_REFHALF: u16 = 0x0015;
-/// Low bits of relative reference
-pub const IMAGE_REL_SHM_RELLO: u16 = 0x0016;
-/// High bits of relative reference
-pub const IMAGE_REL_SHM_RELHALF: u16 = 0x0017;
-/// offset operand for relocation
-pub const IMAGE_REL_SHM_PAIR: u16 = 0x0018;
-
-/// relocation ignores section mode
-pub const IMAGE_REL_SH_NOMODE: u16 = 0x8000;
-
-/// No relocation required
-pub const IMAGE_REL_ARM_ABSOLUTE: u16 = 0x0000;
-/// 32 bit address
-pub const IMAGE_REL_ARM_ADDR32: u16 = 0x0001;
-/// 32 bit address w/o image base
-pub const IMAGE_REL_ARM_ADDR32NB: u16 = 0x0002;
-/// 24 bit offset << 2 & sign ext.
-pub const IMAGE_REL_ARM_BRANCH24: u16 = 0x0003;
-/// Thumb: 2 11 bit offsets
-pub const IMAGE_REL_ARM_BRANCH11: u16 = 0x0004;
-/// clr token
-pub const IMAGE_REL_ARM_TOKEN: u16 = 0x0005;
-/// GP-relative addressing (ARM)
-pub const IMAGE_REL_ARM_GPREL12: u16 = 0x0006;
-/// GP-relative addressing (Thumb)
-pub const IMAGE_REL_ARM_GPREL7: u16 = 0x0007;
-pub const IMAGE_REL_ARM_BLX24: u16 = 0x0008;
-pub const IMAGE_REL_ARM_BLX11: u16 = 0x0009;
-/// 32-bit relative address from byte following reloc
-pub const IMAGE_REL_ARM_REL32: u16 = 0x000A;
-/// Section table index
-pub const IMAGE_REL_ARM_SECTION: u16 = 0x000E;
-/// Offset within section
-pub const IMAGE_REL_ARM_SECREL: u16 = 0x000F;
-/// ARM: MOVW/MOVT
-pub const IMAGE_REL_ARM_MOV32A: u16 = 0x0010;
-/// ARM: MOVW/MOVT (deprecated)
-pub const IMAGE_REL_ARM_MOV32: u16 = 0x0010;
-/// Thumb: MOVW/MOVT
-pub const IMAGE_REL_ARM_MOV32T: u16 = 0x0011;
-/// Thumb: MOVW/MOVT (deprecated)
-pub const IMAGE_REL_THUMB_MOV32: u16 = 0x0011;
-/// Thumb: 32-bit conditional B
-pub const IMAGE_REL_ARM_BRANCH20T: u16 = 0x0012;
-/// Thumb: 32-bit conditional B (deprecated)
-pub const IMAGE_REL_THUMB_BRANCH20: u16 = 0x0012;
-/// Thumb: 32-bit B or BL
-pub const IMAGE_REL_ARM_BRANCH24T: u16 = 0x0014;
-/// Thumb: 32-bit B or BL (deprecated)
-pub const IMAGE_REL_THUMB_BRANCH24: u16 = 0x0014;
-/// Thumb: BLX immediate
-pub const IMAGE_REL_ARM_BLX23T: u16 = 0x0015;
-/// Thumb: BLX immediate (deprecated)
-pub const IMAGE_REL_THUMB_BLX23: u16 = 0x0015;
-
-pub const IMAGE_REL_AM_ABSOLUTE: u16 = 0x0000;
-pub const IMAGE_REL_AM_ADDR32: u16 = 0x0001;
-pub const IMAGE_REL_AM_ADDR32NB: u16 = 0x0002;
-pub const IMAGE_REL_AM_CALL32: u16 = 0x0003;
-pub const IMAGE_REL_AM_FUNCINFO: u16 = 0x0004;
-pub const IMAGE_REL_AM_REL32_1: u16 = 0x0005;
-pub const IMAGE_REL_AM_REL32_2: u16 = 0x0006;
-pub const IMAGE_REL_AM_SECREL: u16 = 0x0007;
-pub const IMAGE_REL_AM_SECTION: u16 = 0x0008;
-pub const IMAGE_REL_AM_TOKEN: u16 = 0x0009;
-
-//
-// ARM64 relocations types.
-//
-
-/// No relocation required
-pub const IMAGE_REL_ARM64_ABSOLUTE: u16 = 0x0000;
-/// 32 bit address. Review! do we need it?
-pub const IMAGE_REL_ARM64_ADDR32: u16 = 0x0001;
-/// 32 bit address w/o image base (RVA: for Data/PData/XData)
-pub const IMAGE_REL_ARM64_ADDR32NB: u16 = 0x0002;
-/// 26 bit offset << 2 & sign ext. for B & BL
-pub const IMAGE_REL_ARM64_BRANCH26: u16 = 0x0003;
-/// ADRP
-pub const IMAGE_REL_ARM64_PAGEBASE_REL21: u16 = 0x0004;
-/// ADR
-pub const IMAGE_REL_ARM64_REL21: u16 = 0x0005;
-/// ADD/ADDS (immediate) with zero shift, for page offset
-pub const IMAGE_REL_ARM64_PAGEOFFSET_12A: u16 = 0x0006;
-/// LDR (indexed, unsigned immediate), for page offset
-pub const IMAGE_REL_ARM64_PAGEOFFSET_12L: u16 = 0x0007;
-/// Offset within section
-pub const IMAGE_REL_ARM64_SECREL: u16 = 0x0008;
-/// ADD/ADDS (immediate) with zero shift, for bit 0:11 of section offset
-pub const IMAGE_REL_ARM64_SECREL_LOW12A: u16 = 0x0009;
-/// ADD/ADDS (immediate) with zero shift, for bit 12:23 of section offset
-pub const IMAGE_REL_ARM64_SECREL_HIGH12A: u16 = 0x000A;
-/// LDR (indexed, unsigned immediate), for bit 0:11 of section offset
-pub const IMAGE_REL_ARM64_SECREL_LOW12L: u16 = 0x000B;
-pub const IMAGE_REL_ARM64_TOKEN: u16 = 0x000C;
-/// Section table index
-pub const IMAGE_REL_ARM64_SECTION: u16 = 0x000D;
-/// 64 bit address
-pub const IMAGE_REL_ARM64_ADDR64: u16 = 0x000E;
-/// 19 bit offset << 2 & sign ext. for conditional B
-pub const IMAGE_REL_ARM64_BRANCH19: u16 = 0x000F;
-/// TBZ/TBNZ
-pub const IMAGE_REL_ARM64_BRANCH14: u16 = 0x0010;
-/// 32-bit relative address from byte following reloc
-pub const IMAGE_REL_ARM64_REL32: u16 = 0x0011;
-
-//
-// x64 relocations
-//
-/// Reference is absolute, no relocation is necessary
-pub const IMAGE_REL_AMD64_ABSOLUTE: u16 = 0x0000;
-/// 64-bit address (VA).
-pub const IMAGE_REL_AMD64_ADDR64: u16 = 0x0001;
-/// 32-bit address (VA).
-pub const IMAGE_REL_AMD64_ADDR32: u16 = 0x0002;
-/// 32-bit address w/o image base (RVA).
-pub const IMAGE_REL_AMD64_ADDR32NB: u16 = 0x0003;
-/// 32-bit relative address from byte following reloc
-pub const IMAGE_REL_AMD64_REL32: u16 = 0x0004;
-/// 32-bit relative address from byte distance 1 from reloc
-pub const IMAGE_REL_AMD64_REL32_1: u16 = 0x0005;
-/// 32-bit relative address from byte distance 2 from reloc
-pub const IMAGE_REL_AMD64_REL32_2: u16 = 0x0006;
-/// 32-bit relative address from byte distance 3 from reloc
-pub const IMAGE_REL_AMD64_REL32_3: u16 = 0x0007;
-/// 32-bit relative address from byte distance 4 from reloc
-pub const IMAGE_REL_AMD64_REL32_4: u16 = 0x0008;
-/// 32-bit relative address from byte distance 5 from reloc
-pub const IMAGE_REL_AMD64_REL32_5: u16 = 0x0009;
-/// Section index
-pub const IMAGE_REL_AMD64_SECTION: u16 = 0x000A;
-/// 32 bit offset from base of section containing target
-pub const IMAGE_REL_AMD64_SECREL: u16 = 0x000B;
-/// 7 bit unsigned offset from base of section containing target
-pub const IMAGE_REL_AMD64_SECREL7: u16 = 0x000C;
-/// 32 bit metadata token
-pub const IMAGE_REL_AMD64_TOKEN: u16 = 0x000D;
-/// 32 bit signed span-dependent value emitted into object
-pub const IMAGE_REL_AMD64_SREL32: u16 = 0x000E;
-pub const IMAGE_REL_AMD64_PAIR: u16 = 0x000F;
-/// 32 bit signed span-dependent value applied at link time
-pub const IMAGE_REL_AMD64_SSPAN32: u16 = 0x0010;
-pub const IMAGE_REL_AMD64_EHANDLER: u16 = 0x0011;
-/// Indirect branch to an import
-pub const IMAGE_REL_AMD64_IMPORT_BR: u16 = 0x0012;
-/// Indirect call to an import
-pub const IMAGE_REL_AMD64_IMPORT_CALL: u16 = 0x0013;
-/// Indirect branch to a CFG check
-pub const IMAGE_REL_AMD64_CFG_BR: u16 = 0x0014;
-/// Indirect branch to a CFG check, with REX.W prefix
-pub const IMAGE_REL_AMD64_CFG_BR_REX: u16 = 0x0015;
-/// Indirect call to a CFG check
-pub const IMAGE_REL_AMD64_CFG_CALL: u16 = 0x0016;
-/// Indirect branch to a target in RAX (no CFG)
-pub const IMAGE_REL_AMD64_INDIR_BR: u16 = 0x0017;
-/// Indirect branch to a target in RAX, with REX.W prefix (no CFG)
-pub const IMAGE_REL_AMD64_INDIR_BR_REX: u16 = 0x0018;
-/// Indirect call to a target in RAX (no CFG)
-pub const IMAGE_REL_AMD64_INDIR_CALL: u16 = 0x0019;
-/// Indirect branch for a switch table using Reg 0 (RAX)
-pub const IMAGE_REL_AMD64_INDIR_BR_SWITCHTABLE_FIRST: u16 = 0x0020;
-/// Indirect branch for a switch table using Reg 15 (R15)
-pub const IMAGE_REL_AMD64_INDIR_BR_SWITCHTABLE_LAST: u16 = 0x002F;
-
-//
-// IA64 relocation types.
-//
-pub const IMAGE_REL_IA64_ABSOLUTE: u16 = 0x0000;
-pub const IMAGE_REL_IA64_IMM14: u16 = 0x0001;
-pub const IMAGE_REL_IA64_IMM22: u16 = 0x0002;
-pub const IMAGE_REL_IA64_IMM64: u16 = 0x0003;
-pub const IMAGE_REL_IA64_DIR32: u16 = 0x0004;
-pub const IMAGE_REL_IA64_DIR64: u16 = 0x0005;
-pub const IMAGE_REL_IA64_PCREL21B: u16 = 0x0006;
-pub const IMAGE_REL_IA64_PCREL21M: u16 = 0x0007;
-pub const IMAGE_REL_IA64_PCREL21F: u16 = 0x0008;
-pub const IMAGE_REL_IA64_GPREL22: u16 = 0x0009;
-pub const IMAGE_REL_IA64_LTOFF22: u16 = 0x000A;
-pub const IMAGE_REL_IA64_SECTION: u16 = 0x000B;
-pub const IMAGE_REL_IA64_SECREL22: u16 = 0x000C;
-pub const IMAGE_REL_IA64_SECREL64I: u16 = 0x000D;
-pub const IMAGE_REL_IA64_SECREL32: u16 = 0x000E;
-//
-pub const IMAGE_REL_IA64_DIR32NB: u16 = 0x0010;
-pub const IMAGE_REL_IA64_SREL14: u16 = 0x0011;
-pub const IMAGE_REL_IA64_SREL22: u16 = 0x0012;
-pub const IMAGE_REL_IA64_SREL32: u16 = 0x0013;
-pub const IMAGE_REL_IA64_UREL32: u16 = 0x0014;
-/// This is always a BRL and never converted
-pub const IMAGE_REL_IA64_PCREL60X: u16 = 0x0015;
-/// If possible, convert to MBB bundle with NOP.B in slot 1
-pub const IMAGE_REL_IA64_PCREL60B: u16 = 0x0016;
-/// If possible, convert to MFB bundle with NOP.F in slot 1
-pub const IMAGE_REL_IA64_PCREL60F: u16 = 0x0017;
-/// If possible, convert to MIB bundle with NOP.I in slot 1
-pub const IMAGE_REL_IA64_PCREL60I: u16 = 0x0018;
-/// If possible, convert to MMB bundle with NOP.M in slot 1
-pub const IMAGE_REL_IA64_PCREL60M: u16 = 0x0019;
-pub const IMAGE_REL_IA64_IMMGPREL64: u16 = 0x001A;
-/// clr token
-pub const IMAGE_REL_IA64_TOKEN: u16 = 0x001B;
-pub const IMAGE_REL_IA64_GPREL32: u16 = 0x001C;
-pub const IMAGE_REL_IA64_ADDEND: u16 = 0x001F;
-
-//
-// CEF relocation types.
-//
-/// Reference is absolute, no relocation is necessary
-pub const IMAGE_REL_CEF_ABSOLUTE: u16 = 0x0000;
-/// 32-bit address (VA).
-pub const IMAGE_REL_CEF_ADDR32: u16 = 0x0001;
-/// 64-bit address (VA).
-pub const IMAGE_REL_CEF_ADDR64: u16 = 0x0002;
-/// 32-bit address w/o image base (RVA).
-pub const IMAGE_REL_CEF_ADDR32NB: u16 = 0x0003;
-/// Section index
-pub const IMAGE_REL_CEF_SECTION: u16 = 0x0004;
-/// 32 bit offset from base of section containing target
-pub const IMAGE_REL_CEF_SECREL: u16 = 0x0005;
-/// 32 bit metadata token
-pub const IMAGE_REL_CEF_TOKEN: u16 = 0x0006;
-
-//
-// clr relocation types.
-//
-/// Reference is absolute, no relocation is necessary
-pub const IMAGE_REL_CEE_ABSOLUTE: u16 = 0x0000;
-/// 32-bit address (VA).
-pub const IMAGE_REL_CEE_ADDR32: u16 = 0x0001;
-/// 64-bit address (VA).
-pub const IMAGE_REL_CEE_ADDR64: u16 = 0x0002;
-/// 32-bit address w/o image base (RVA).
-pub const IMAGE_REL_CEE_ADDR32NB: u16 = 0x0003;
-/// Section index
-pub const IMAGE_REL_CEE_SECTION: u16 = 0x0004;
-/// 32 bit offset from base of section containing target
-pub const IMAGE_REL_CEE_SECREL: u16 = 0x0005;
-/// 32 bit metadata token
-pub const IMAGE_REL_CEE_TOKEN: u16 = 0x0006;
-
-/// No relocation required
-pub const IMAGE_REL_M32R_ABSOLUTE: u16 = 0x0000;
-/// 32 bit address
-pub const IMAGE_REL_M32R_ADDR32: u16 = 0x0001;
-/// 32 bit address w/o image base
-pub const IMAGE_REL_M32R_ADDR32NB: u16 = 0x0002;
-/// 24 bit address
-pub const IMAGE_REL_M32R_ADDR24: u16 = 0x0003;
-/// GP relative addressing
-pub const IMAGE_REL_M32R_GPREL16: u16 = 0x0004;
-/// 24 bit offset << 2 & sign ext.
-pub const IMAGE_REL_M32R_PCREL24: u16 = 0x0005;
-/// 16 bit offset << 2 & sign ext.
-pub const IMAGE_REL_M32R_PCREL16: u16 = 0x0006;
-/// 8 bit offset << 2 & sign ext.
-pub const IMAGE_REL_M32R_PCREL8: u16 = 0x0007;
-/// 16 MSBs
-pub const IMAGE_REL_M32R_REFHALF: u16 = 0x0008;
-/// 16 MSBs; adj for LSB sign ext.
-pub const IMAGE_REL_M32R_REFHI: u16 = 0x0009;
-/// 16 LSBs
-pub const IMAGE_REL_M32R_REFLO: u16 = 0x000A;
-/// Link HI and LO
-pub const IMAGE_REL_M32R_PAIR: u16 = 0x000B;
-/// Section table index
-pub const IMAGE_REL_M32R_SECTION: u16 = 0x000C;
-/// 32 bit section relative reference
-pub const IMAGE_REL_M32R_SECREL32: u16 = 0x000D;
-/// clr token
-pub const IMAGE_REL_M32R_TOKEN: u16 = 0x000E;
-
-/// No relocation required
-pub const IMAGE_REL_EBC_ABSOLUTE: u16 = 0x0000;
-/// 32 bit address w/o image base
-pub const IMAGE_REL_EBC_ADDR32NB: u16 = 0x0001;
-/// 32-bit relative address from byte following reloc
-pub const IMAGE_REL_EBC_REL32: u16 = 0x0002;
-/// Section table index
-pub const IMAGE_REL_EBC_SECTION: u16 = 0x0003;
-/// Offset within section
-pub const IMAGE_REL_EBC_SECREL: u16 = 0x0004;
-
-/*
-// TODO?
-#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) /* Intel-IA64-Filler */ \
- Value |= (((ULONGLONG)((*(Address) >> InstPos) & (((ULONGLONG)1 << Size) - 1))) << ValPos) // Intel-IA64-Filler
-
-#define INS_IMM64(Value, Address, Size, InstPos, ValPos) /* Intel-IA64-Filler */\
- *(PDWORD)Address = (*(PDWORD)Address & ~(((1 << Size) - 1) << InstPos)) | /* Intel-IA64-Filler */\
- ((DWORD)((((ULONGLONG)Value >> ValPos) & (((ULONGLONG)1 << Size) - 1))) << InstPos) // Intel-IA64-Filler
-*/
-
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM7B_INST_WORD_X: u16 = 3;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM7B_SIZE_X: u16 = 7;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM7B_INST_WORD_POS_X: u16 = 4;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM7B_VAL_POS_X: u16 = 0;
-
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM9D_INST_WORD_X: u16 = 3;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM9D_SIZE_X: u16 = 9;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM9D_INST_WORD_POS_X: u16 = 18;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM9D_VAL_POS_X: u16 = 7;
-
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM5C_INST_WORD_X: u16 = 3;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM5C_SIZE_X: u16 = 5;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM5C_INST_WORD_POS_X: u16 = 13;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM5C_VAL_POS_X: u16 = 16;
-
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IC_INST_WORD_X: u16 = 3;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IC_SIZE_X: u16 = 1;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IC_INST_WORD_POS_X: u16 = 12;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IC_VAL_POS_X: u16 = 21;
-
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM41A_INST_WORD_X: u16 = 1;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM41A_SIZE_X: u16 = 10;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM41A_INST_WORD_POS_X: u16 = 14;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM41A_VAL_POS_X: u16 = 22;
-
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM41B_INST_WORD_X: u16 = 1;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM41B_SIZE_X: u16 = 8;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM41B_INST_WORD_POS_X: u16 = 24;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM41B_VAL_POS_X: u16 = 32;
-
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM41C_INST_WORD_X: u16 = 2;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM41C_SIZE_X: u16 = 23;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM41C_INST_WORD_POS_X: u16 = 0;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_IMM41C_VAL_POS_X: u16 = 40;
-
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_SIGN_INST_WORD_X: u16 = 3;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_SIGN_SIZE_X: u16 = 1;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_SIGN_INST_WORD_POS_X: u16 = 27;
-/// Intel-IA64-Filler
-pub const EMARCH_ENC_I17_SIGN_VAL_POS_X: u16 = 63;
-
-/// Intel-IA64-Filler
-pub const X3_OPCODE_INST_WORD_X: u16 = 3;
-/// Intel-IA64-Filler
-pub const X3_OPCODE_SIZE_X: u16 = 4;
-/// Intel-IA64-Filler
-pub const X3_OPCODE_INST_WORD_POS_X: u16 = 28;
-/// Intel-IA64-Filler
-pub const X3_OPCODE_SIGN_VAL_POS_X: u16 = 0;
-
-/// Intel-IA64-Filler
-pub const X3_I_INST_WORD_X: u16 = 3;
-/// Intel-IA64-Filler
-pub const X3_I_SIZE_X: u16 = 1;
-/// Intel-IA64-Filler
-pub const X3_I_INST_WORD_POS_X: u16 = 27;
-/// Intel-IA64-Filler
-pub const X3_I_SIGN_VAL_POS_X: u16 = 59;
-
-/// Intel-IA64-Filler
-pub const X3_D_WH_INST_WORD_X: u16 = 3;
-/// Intel-IA64-Filler
-pub const X3_D_WH_SIZE_X: u16 = 3;
-/// Intel-IA64-Filler
-pub const X3_D_WH_INST_WORD_POS_X: u16 = 24;
-/// Intel-IA64-Filler
-pub const X3_D_WH_SIGN_VAL_POS_X: u16 = 0;
-
-/// Intel-IA64-Filler
-pub const X3_IMM20_INST_WORD_X: u16 = 3;
-/// Intel-IA64-Filler
-pub const X3_IMM20_SIZE_X: u16 = 20;
-/// Intel-IA64-Filler
-pub const X3_IMM20_INST_WORD_POS_X: u16 = 4;
-/// Intel-IA64-Filler
-pub const X3_IMM20_SIGN_VAL_POS_X: u16 = 0;
-
-/// Intel-IA64-Filler
-pub const X3_IMM39_1_INST_WORD_X: u16 = 2;
-/// Intel-IA64-Filler
-pub const X3_IMM39_1_SIZE_X: u16 = 23;
-/// Intel-IA64-Filler
-pub const X3_IMM39_1_INST_WORD_POS_X: u16 = 0;
-/// Intel-IA64-Filler
-pub const X3_IMM39_1_SIGN_VAL_POS_X: u16 = 36;
-
-/// Intel-IA64-Filler
-pub const X3_IMM39_2_INST_WORD_X: u16 = 1;
-/// Intel-IA64-Filler
-pub const X3_IMM39_2_SIZE_X: u16 = 16;
-/// Intel-IA64-Filler
-pub const X3_IMM39_2_INST_WORD_POS_X: u16 = 16;
-/// Intel-IA64-Filler
-pub const X3_IMM39_2_SIGN_VAL_POS_X: u16 = 20;
-
-/// Intel-IA64-Filler
-pub const X3_P_INST_WORD_X: u16 = 3;
-/// Intel-IA64-Filler
-pub const X3_P_SIZE_X: u16 = 4;
-/// Intel-IA64-Filler
-pub const X3_P_INST_WORD_POS_X: u16 = 0;
-/// Intel-IA64-Filler
-pub const X3_P_SIGN_VAL_POS_X: u16 = 0;
-
-/// Intel-IA64-Filler
-pub const X3_TMPLT_INST_WORD_X: u16 = 0;
-/// Intel-IA64-Filler
-pub const X3_TMPLT_SIZE_X: u16 = 4;
-/// Intel-IA64-Filler
-pub const X3_TMPLT_INST_WORD_POS_X: u16 = 0;
-/// Intel-IA64-Filler
-pub const X3_TMPLT_SIGN_VAL_POS_X: u16 = 0;
-
-/// Intel-IA64-Filler
-pub const X3_BTYPE_QP_INST_WORD_X: u16 = 2;
-/// Intel-IA64-Filler
-pub const X3_BTYPE_QP_SIZE_X: u16 = 9;
-/// Intel-IA64-Filler
-pub const X3_BTYPE_QP_INST_WORD_POS_X: u16 = 23;
-/// Intel-IA64-Filler
-pub const X3_BTYPE_QP_INST_VAL_POS_X: u16 = 0;
-
-/// Intel-IA64-Filler
-pub const X3_EMPTY_INST_WORD_X: u16 = 1;
-/// Intel-IA64-Filler
-pub const X3_EMPTY_SIZE_X: u16 = 2;
-/// Intel-IA64-Filler
-pub const X3_EMPTY_INST_WORD_POS_X: u16 = 14;
-/// Intel-IA64-Filler
-pub const X3_EMPTY_INST_VAL_POS_X: u16 = 0;
-
-//
-// Line number format.
-//
-
-// This struct has alignment 1.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageLinenumber {
- /// Symbol table index of function name if Linenumber is 0.
- /// Otherwise virtual address of line number.
- pub symbol_table_index_or_virtual_address: U32Bytes<LE>,
- /// Line number.
- pub linenumber: U16Bytes<LE>,
-}
-
-//
-// Based relocation format.
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageBaseRelocation {
- pub virtual_address: U32<LE>,
- pub size_of_block: U32<LE>,
- // pub type_offset[1]: U16<LE>,
-}
-
-//
-// Based relocation types.
-//
-
-pub const IMAGE_REL_BASED_ABSOLUTE: u16 = 0;
-pub const IMAGE_REL_BASED_HIGH: u16 = 1;
-pub const IMAGE_REL_BASED_LOW: u16 = 2;
-pub const IMAGE_REL_BASED_HIGHLOW: u16 = 3;
-pub const IMAGE_REL_BASED_HIGHADJ: u16 = 4;
-pub const IMAGE_REL_BASED_MACHINE_SPECIFIC_5: u16 = 5;
-pub const IMAGE_REL_BASED_RESERVED: u16 = 6;
-pub const IMAGE_REL_BASED_MACHINE_SPECIFIC_7: u16 = 7;
-pub const IMAGE_REL_BASED_MACHINE_SPECIFIC_8: u16 = 8;
-pub const IMAGE_REL_BASED_MACHINE_SPECIFIC_9: u16 = 9;
-pub const IMAGE_REL_BASED_DIR64: u16 = 10;
-
-//
-// Platform-specific based relocation types.
-//
-
-pub const IMAGE_REL_BASED_IA64_IMM64: u16 = 9;
-
-pub const IMAGE_REL_BASED_MIPS_JMPADDR: u16 = 5;
-pub const IMAGE_REL_BASED_MIPS_JMPADDR16: u16 = 9;
-
-pub const IMAGE_REL_BASED_ARM_MOV32: u16 = 5;
-pub const IMAGE_REL_BASED_THUMB_MOV32: u16 = 7;
-
-pub const IMAGE_REL_BASED_RISCV_HIGH20: u16 = 5;
-pub const IMAGE_REL_BASED_RISCV_LOW12I: u16 = 7;
-pub const IMAGE_REL_BASED_RISCV_LOW12S: u16 = 8;
-
-//
-// Archive format.
-//
-
-pub const IMAGE_ARCHIVE_START_SIZE: usize = 8;
-pub const IMAGE_ARCHIVE_START: &[u8; 8] = b"!<arch>\n";
-pub const IMAGE_ARCHIVE_END: &[u8] = b"`\n";
-pub const IMAGE_ARCHIVE_PAD: &[u8] = b"\n";
-pub const IMAGE_ARCHIVE_LINKER_MEMBER: &[u8; 16] = b"/ ";
-pub const IMAGE_ARCHIVE_LONGNAMES_MEMBER: &[u8; 16] = b"// ";
-pub const IMAGE_ARCHIVE_HYBRIDMAP_MEMBER: &[u8; 16] = b"/<HYBRIDMAP>/ ";
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageArchiveMemberHeader {
- /// File member name - `/' terminated.
- pub name: [u8; 16],
- /// File member date - decimal.
- pub date: [u8; 12],
- /// File member user id - decimal.
- pub user_id: [u8; 6],
- /// File member group id - decimal.
- pub group_id: [u8; 6],
- /// File member mode - octal.
- pub mode: [u8; 8],
- /// File member size - decimal.
- pub size: [u8; 10],
- /// String to end header.
- pub end_header: [u8; 2],
-}
-
-pub const IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR: u16 = 60;
-
-//
-// DLL support.
-//
-
-//
-// Export Format
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageExportDirectory {
- pub characteristics: U32<LE>,
- pub time_date_stamp: U32<LE>,
- pub major_version: U16<LE>,
- pub minor_version: U16<LE>,
- pub name: U32<LE>,
- pub base: U32<LE>,
- pub number_of_functions: U32<LE>,
- pub number_of_names: U32<LE>,
- /// RVA from base of image
- pub address_of_functions: U32<LE>,
- /// RVA from base of image
- pub address_of_names: U32<LE>,
- /// RVA from base of image
- pub address_of_name_ordinals: U32<LE>,
-}
-
-//
-// Import Format
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageImportByName {
- pub hint: U16<LE>,
- //pub name: [i8; 1],
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageThunkData64(pub U64<LE>);
-/*
- union {
-/// PBYTE
- pub forwarder_string: U64<LE>,
-/// PDWORD
- pub function: U64<LE>,
- pub ordinal: U64<LE>,
-/// PIMAGE_IMPORT_BY_NAME
- pub address_of_data: U64<LE>,
- } u1;
-*/
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageThunkData32(pub U32<LE>);
-/*
- union {
-/// PBYTE
- pub forwarder_string: U32<LE>,
-/// PDWORD
- pub function: U32<LE>,
- pub ordinal: U32<LE>,
-/// PIMAGE_IMPORT_BY_NAME
- pub address_of_data: U32<LE>,
- } u1;
-}
-*/
-
-pub const IMAGE_ORDINAL_FLAG64: u64 = 0x8000000000000000;
-pub const IMAGE_ORDINAL_FLAG32: u32 = 0x80000000;
-
-/*
-#define IMAGE_ORDINAL64(Ordinal) (Ordinal & 0xffff)
-#define IMAGE_ORDINAL32(Ordinal) (Ordinal & 0xffff)
-#define IMAGE_SNAP_BY_ORDINAL64(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG64) != 0)
-#define IMAGE_SNAP_BY_ORDINAL32(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG32) != 0)
-
-*/
-
-//
-// Thread Local Storage
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageTlsDirectory64 {
- pub start_address_of_raw_data: U64<LE>,
- pub end_address_of_raw_data: U64<LE>,
- /// PDWORD
- pub address_of_index: U64<LE>,
- /// PIMAGE_TLS_CALLBACK *;
- pub address_of_call_backs: U64<LE>,
- pub size_of_zero_fill: U32<LE>,
- pub characteristics: U32<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageTlsDirectory32 {
- pub start_address_of_raw_data: U32<LE>,
- pub end_address_of_raw_data: U32<LE>,
- /// PDWORD
- pub address_of_index: U32<LE>,
- /// PIMAGE_TLS_CALLBACK *
- pub address_of_call_backs: U32<LE>,
- pub size_of_zero_fill: U32<LE>,
- pub characteristics: U32<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageImportDescriptor {
- /// RVA to original unbound IAT (`ImageThunkData32`/`ImageThunkData64`)
- /// 0 for terminating null import descriptor
- pub original_first_thunk: U32Bytes<LE>,
- /// 0 if not bound,
- /// -1 if bound, and real date\time stamp
- /// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
- /// O.W. date/time stamp of DLL bound to (Old BIND)
- pub time_date_stamp: U32Bytes<LE>,
- /// -1 if no forwarders
- pub forwarder_chain: U32Bytes<LE>,
- pub name: U32Bytes<LE>,
- /// RVA to IAT (if bound this IAT has actual addresses)
- pub first_thunk: U32Bytes<LE>,
-}
-
-impl ImageImportDescriptor {
- /// Tell whether this import descriptor is the null descriptor
- /// (used to mark the end of the iterator array in a PE)
- pub fn is_null(&self) -> bool {
- self.original_first_thunk.get(LE) == 0
- && self.time_date_stamp.get(LE) == 0
- && self.forwarder_chain.get(LE) == 0
- && self.name.get(LE) == 0
- && self.first_thunk.get(LE) == 0
- }
-}
-
-//
-// New format import descriptors pointed to by DataDirectory[ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ]
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageBoundImportDescriptor {
- pub time_date_stamp: U32<LE>,
- pub offset_module_name: U16<LE>,
- pub number_of_module_forwarder_refs: U16<LE>,
- // Array of zero or more IMAGE_BOUND_FORWARDER_REF follows
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageBoundForwarderRef {
- pub time_date_stamp: U32<LE>,
- pub offset_module_name: U16<LE>,
- pub reserved: U16<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageDelayloadDescriptor {
- pub attributes: U32<LE>,
-
- /// RVA to the name of the target library (NULL-terminate ASCII string)
- pub dll_name_rva: U32<LE>,
- /// RVA to the HMODULE caching location (PHMODULE)
- pub module_handle_rva: U32<LE>,
- /// RVA to the start of the IAT (PIMAGE_THUNK_DATA)
- pub import_address_table_rva: U32<LE>,
- /// RVA to the start of the name table (PIMAGE_THUNK_DATA::AddressOfData)
- pub import_name_table_rva: U32<LE>,
- /// RVA to an optional bound IAT
- pub bound_import_address_table_rva: U32<LE>,
- /// RVA to an optional unload info table
- pub unload_information_table_rva: U32<LE>,
- /// 0 if not bound, otherwise, date/time of the target DLL
- pub time_date_stamp: U32<LE>,
-}
-
-impl ImageDelayloadDescriptor {
- /// Tell whether this delay-load import descriptor is the null descriptor
- /// (used to mark the end of the iterator array in a PE)
- pub fn is_null(&self) -> bool {
- self.attributes.get(LE) == 0
- && self.dll_name_rva.get(LE) == 0
- && self.module_handle_rva.get(LE) == 0
- && self.import_address_table_rva.get(LE) == 0
- && self.import_name_table_rva.get(LE) == 0
- && self.bound_import_address_table_rva.get(LE) == 0
- && self.unload_information_table_rva.get(LE) == 0
- && self.time_date_stamp.get(LE) == 0
- }
-}
-
-/// Delay load version 2 flag for `ImageDelayloadDescriptor::attributes`.
-pub const IMAGE_DELAYLOAD_RVA_BASED: u32 = 0x8000_0000;
-
-//
-// Resource Format.
-//
-
-//
-// Resource directory consists of two counts, following by a variable length
-// array of directory entries. The first count is the number of entries at
-// beginning of the array that have actual names associated with each entry.
-// The entries are in ascending order, case insensitive strings. The second
-// count is the number of entries that immediately follow the named entries.
-// This second count identifies the number of entries that have 16-bit integer
-// Ids as their name. These entries are also sorted in ascending order.
-//
-// This structure allows fast lookup by either name or number, but for any
-// given resource entry only one form of lookup is supported, not both.
-// This is consistent with the syntax of the .RC file and the .RES file.
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageResourceDirectory {
- pub characteristics: U32<LE>,
- pub time_date_stamp: U32<LE>,
- pub major_version: U16<LE>,
- pub minor_version: U16<LE>,
- pub number_of_named_entries: U16<LE>,
- pub number_of_id_entries: U16<LE>,
-}
-
-pub const IMAGE_RESOURCE_NAME_IS_STRING: u32 = 0x8000_0000;
-pub const IMAGE_RESOURCE_DATA_IS_DIRECTORY: u32 = 0x8000_0000;
-//
-// Each directory contains the 32-bit Name of the entry and an offset,
-// relative to the beginning of the resource directory of the data associated
-// with this directory entry. If the name of the entry is an actual text
-// string instead of an integer Id, then the high order bit of the name field
-// is set to one and the low order 31-bits are an offset, relative to the
-// beginning of the resource directory of the string, which is of type
-// IMAGE_RESOURCE_DIRECTORY_STRING. Otherwise the high bit is clear and the
-// low-order 16-bits are the integer Id that identify this resource directory
-// entry. If the directory entry is yet another resource directory (i.e. a
-// subdirectory), then the high order bit of the offset field will be
-// set to indicate this. Otherwise the high bit is clear and the offset
-// field points to a resource data entry.
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageResourceDirectoryEntry {
- pub name_or_id: U32<LE>,
- pub offset_to_data_or_directory: U32<LE>,
-}
-
-//
-// For resource directory entries that have actual string names, the Name
-// field of the directory entry points to an object of the following type.
-// All of these string objects are stored together after the last resource
-// directory entry and before the first resource data object. This minimizes
-// the impact of these variable length objects on the alignment of the fixed
-// size directory entry objects.
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageResourceDirectoryString {
- pub length: U16<LE>,
- //pub name_string: [i8; 1],
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageResourceDirStringU {
- pub length: U16<LE>,
- //pub name_string: [U16<LE>; 1],
-}
-
-//
-// Each resource data entry describes a leaf node in the resource directory
-// tree. It contains an offset, relative to the beginning of the resource
-// directory of the data for the resource, a size field that gives the number
-// of bytes of data at that offset, a CodePage that should be used when
-// decoding code point values within the resource data. Typically for new
-// applications the code page would be the unicode code page.
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageResourceDataEntry {
- /// RVA of the data.
- pub offset_to_data: U32<LE>,
- pub size: U32<LE>,
- pub code_page: U32<LE>,
- pub reserved: U32<LE>,
-}
-
-// Resource type: https://docs.microsoft.com/en-us/windows/win32/menurc/resource-types
-
-/// ID for: Hardware-dependent cursor resource.
-pub const RT_CURSOR: u16 = 1;
-/// ID for: Bitmap resource.
-pub const RT_BITMAP: u16 = 2;
-/// ID for: Hardware-dependent icon resource.
-pub const RT_ICON: u16 = 3;
-/// ID for: Menu resource.
-pub const RT_MENU: u16 = 4;
-/// ID for: Dialog box.
-pub const RT_DIALOG: u16 = 5;
-/// ID for: String-table entry.
-pub const RT_STRING: u16 = 6;
-/// ID for: Font directory resource.
-pub const RT_FONTDIR: u16 = 7;
-/// ID for: Font resource.
-pub const RT_FONT: u16 = 8;
-/// ID for: Accelerator table.
-pub const RT_ACCELERATOR: u16 = 9;
-/// ID for: Application-defined resource (raw data).
-pub const RT_RCDATA: u16 = 10;
-/// ID for: Message-table entry.
-pub const RT_MESSAGETABLE: u16 = 11;
-/// ID for: Hardware-independent cursor resource.
-pub const RT_GROUP_CURSOR: u16 = 12;
-/// ID for: Hardware-independent icon resource.
-pub const RT_GROUP_ICON: u16 = 14;
-/// ID for: Version resource.
-pub const RT_VERSION: u16 = 16;
-/// ID for: Allows a resource editing tool to associate a string with an .rc file.
-pub const RT_DLGINCLUDE: u16 = 17;
-/// ID for: Plug and Play resource.
-pub const RT_PLUGPLAY: u16 = 19;
-/// ID for: VXD.
-pub const RT_VXD: u16 = 20;
-/// ID for: Animated cursor.
-pub const RT_ANICURSOR: u16 = 21;
-/// ID for: Animated icon.
-pub const RT_ANIICON: u16 = 22;
-/// ID for: HTML resource.
-pub const RT_HTML: u16 = 23;
-/// ID for: Side-by-Side Assembly Manifest.
-pub const RT_MANIFEST: u16 = 24;
-
-//
-// Code Integrity in loadconfig (CI)
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageLoadConfigCodeIntegrity {
- /// Flags to indicate if CI information is available, etc.
- pub flags: U16<LE>,
- /// 0xFFFF means not available
- pub catalog: U16<LE>,
- pub catalog_offset: U32<LE>,
- /// Additional bitmask to be defined later
- pub reserved: U32<LE>,
-}
-
-//
-// Dynamic value relocation table in loadconfig
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageDynamicRelocationTable {
- pub version: U32<LE>,
- pub size: U32<LE>,
- // DynamicRelocations: [ImageDynamicRelocation; 0],
-}
-
-//
-// Dynamic value relocation entries following IMAGE_DYNAMIC_RELOCATION_TABLE
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageDynamicRelocation32 {
- pub symbol: U32<LE>,
- pub base_reloc_size: U32<LE>,
- // BaseRelocations: [ImageBaseRelocation; 0],
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageDynamicRelocation64 {
- pub symbol: U64<LE>,
- pub base_reloc_size: U32<LE>,
- // BaseRelocations: [ImageBaseRelocation; 0],
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageDynamicRelocation32V2 {
- pub header_size: U32<LE>,
- pub fixup_info_size: U32<LE>,
- pub symbol: U32<LE>,
- pub symbol_group: U32<LE>,
- pub flags: U32<LE>,
- // ... variable length header fields
- // pub fixup_info: [u8; fixup_info_size]
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageDynamicRelocation64V2 {
- pub header_size: U32<LE>,
- pub fixup_info_size: U32<LE>,
- pub symbol: U64<LE>,
- pub symbol_group: U32<LE>,
- pub flags: U32<LE>,
- // ... variable length header fields
- // pub fixup_info[u8; fixup_info_size]
-}
-
-//
-// Defined symbolic dynamic relocation entries.
-//
-
-pub const IMAGE_DYNAMIC_RELOCATION_GUARD_RF_PROLOGUE: u32 = 0x0000_0001;
-pub const IMAGE_DYNAMIC_RELOCATION_GUARD_RF_EPILOGUE: u32 = 0x0000_0002;
-pub const IMAGE_DYNAMIC_RELOCATION_GUARD_IMPORT_CONTROL_TRANSFER: u32 = 0x0000_0003;
-pub const IMAGE_DYNAMIC_RELOCATION_GUARD_INDIR_CONTROL_TRANSFER: u32 = 0x0000_0004;
-pub const IMAGE_DYNAMIC_RELOCATION_GUARD_SWITCHTABLE_BRANCH: u32 = 0x0000_0005;
-
-// This struct has alignment 1.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImagePrologueDynamicRelocationHeader {
- pub prologue_byte_count: u8,
- // pub prologue_bytes: [u8; prologue_byte_count],
-}
-
-// This struct has alignment 1.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageEpilogueDynamicRelocationHeader {
- pub epilogue_count: U32Bytes<LE>,
- pub epilogue_byte_count: u8,
- pub branch_descriptor_element_size: u8,
- pub branch_descriptor_count: U16Bytes<LE>,
- // pub branch_descriptors[...],
- // pub branch_descriptor_bit_map[...],
-}
-
-/*
-// TODO? bitfields
-// TODO: unaligned?
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageImportControlTransferDynamicRelocation {
- DWORD PageRelativeOffset : 12;
- DWORD IndirectCall : 1;
- DWORD IATIndex : 19;
-}
-
-// TODO: unaligned?
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageIndirControlTransferDynamicRelocation {
- WORD PageRelativeOffset : 12;
- WORD IndirectCall : 1;
- WORD RexWPrefix : 1;
- WORD CfgCheck : 1;
- WORD Reserved : 1;
-}
-
-// TODO: unaligned?
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageSwitchtableBranchDynamicRelocation {
- WORD PageRelativeOffset : 12;
- WORD RegisterNumber : 4;
-}
-*/
-
-//
-// Load Configuration Directory Entry
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageLoadConfigDirectory32 {
- pub size: U32<LE>,
- pub time_date_stamp: U32<LE>,
- pub major_version: U16<LE>,
- pub minor_version: U16<LE>,
- pub global_flags_clear: U32<LE>,
- pub global_flags_set: U32<LE>,
- pub critical_section_default_timeout: U32<LE>,
- pub de_commit_free_block_threshold: U32<LE>,
- pub de_commit_total_free_threshold: U32<LE>,
- /// VA
- pub lock_prefix_table: U32<LE>,
- pub maximum_allocation_size: U32<LE>,
- pub virtual_memory_threshold: U32<LE>,
- pub process_heap_flags: U32<LE>,
- pub process_affinity_mask: U32<LE>,
- pub csd_version: U16<LE>,
- pub dependent_load_flags: U16<LE>,
- /// VA
- pub edit_list: U32<LE>,
- /// VA
- pub security_cookie: U32<LE>,
- /// VA
- pub sehandler_table: U32<LE>,
- pub sehandler_count: U32<LE>,
- /// VA
- pub guard_cf_check_function_pointer: U32<LE>,
- /// VA
- pub guard_cf_dispatch_function_pointer: U32<LE>,
- /// VA
- pub guard_cf_function_table: U32<LE>,
- pub guard_cf_function_count: U32<LE>,
- pub guard_flags: U32<LE>,
- pub code_integrity: ImageLoadConfigCodeIntegrity,
- /// VA
- pub guard_address_taken_iat_entry_table: U32<LE>,
- pub guard_address_taken_iat_entry_count: U32<LE>,
- /// VA
- pub guard_long_jump_target_table: U32<LE>,
- pub guard_long_jump_target_count: U32<LE>,
- /// VA
- pub dynamic_value_reloc_table: U32<LE>,
- pub chpe_metadata_pointer: U32<LE>,
- /// VA
- pub guard_rf_failure_routine: U32<LE>,
- /// VA
- pub guard_rf_failure_routine_function_pointer: U32<LE>,
- pub dynamic_value_reloc_table_offset: U32<LE>,
- pub dynamic_value_reloc_table_section: U16<LE>,
- pub reserved2: U16<LE>,
- /// VA
- pub guard_rf_verify_stack_pointer_function_pointer: U32<LE>,
- pub hot_patch_table_offset: U32<LE>,
- pub reserved3: U32<LE>,
- /// VA
- pub enclave_configuration_pointer: U32<LE>,
- /// VA
- pub volatile_metadata_pointer: U32<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageLoadConfigDirectory64 {
- pub size: U32<LE>,
- pub time_date_stamp: U32<LE>,
- pub major_version: U16<LE>,
- pub minor_version: U16<LE>,
- pub global_flags_clear: U32<LE>,
- pub global_flags_set: U32<LE>,
- pub critical_section_default_timeout: U32<LE>,
- pub de_commit_free_block_threshold: U64<LE>,
- pub de_commit_total_free_threshold: U64<LE>,
- /// VA
- pub lock_prefix_table: U64<LE>,
- pub maximum_allocation_size: U64<LE>,
- pub virtual_memory_threshold: U64<LE>,
- pub process_affinity_mask: U64<LE>,
- pub process_heap_flags: U32<LE>,
- pub csd_version: U16<LE>,
- pub dependent_load_flags: U16<LE>,
- /// VA
- pub edit_list: U64<LE>,
- /// VA
- pub security_cookie: U64<LE>,
- /// VA
- pub sehandler_table: U64<LE>,
- pub sehandler_count: U64<LE>,
- /// VA
- pub guard_cf_check_function_pointer: U64<LE>,
- /// VA
- pub guard_cf_dispatch_function_pointer: U64<LE>,
- /// VA
- pub guard_cf_function_table: U64<LE>,
- pub guard_cf_function_count: U64<LE>,
- pub guard_flags: U32<LE>,
- pub code_integrity: ImageLoadConfigCodeIntegrity,
- /// VA
- pub guard_address_taken_iat_entry_table: U64<LE>,
- pub guard_address_taken_iat_entry_count: U64<LE>,
- /// VA
- pub guard_long_jump_target_table: U64<LE>,
- pub guard_long_jump_target_count: U64<LE>,
- /// VA
- pub dynamic_value_reloc_table: U64<LE>,
- /// VA
- pub chpe_metadata_pointer: U64<LE>,
- /// VA
- pub guard_rf_failure_routine: U64<LE>,
- /// VA
- pub guard_rf_failure_routine_function_pointer: U64<LE>,
- pub dynamic_value_reloc_table_offset: U32<LE>,
- pub dynamic_value_reloc_table_section: U16<LE>,
- pub reserved2: U16<LE>,
- /// VA
- pub guard_rf_verify_stack_pointer_function_pointer: U64<LE>,
- pub hot_patch_table_offset: U32<LE>,
- pub reserved3: U32<LE>,
- /// VA
- pub enclave_configuration_pointer: U64<LE>,
- /// VA
- pub volatile_metadata_pointer: U64<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageHotPatchInfo {
- pub version: U32<LE>,
- pub size: U32<LE>,
- pub sequence_number: U32<LE>,
- pub base_image_list: U32<LE>,
- pub base_image_count: U32<LE>,
- /// Version 2 and later
- pub buffer_offset: U32<LE>,
- /// Version 3 and later
- pub extra_patch_size: U32<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageHotPatchBase {
- pub sequence_number: U32<LE>,
- pub flags: U32<LE>,
- pub original_time_date_stamp: U32<LE>,
- pub original_check_sum: U32<LE>,
- pub code_integrity_info: U32<LE>,
- pub code_integrity_size: U32<LE>,
- pub patch_table: U32<LE>,
- /// Version 2 and later
- pub buffer_offset: U32<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageHotPatchHashes {
- pub sha256: [u8; 32],
- pub sha1: [u8; 20],
-}
-
-pub const IMAGE_HOT_PATCH_BASE_OBLIGATORY: u32 = 0x0000_0001;
-pub const IMAGE_HOT_PATCH_BASE_CAN_ROLL_BACK: u32 = 0x0000_0002;
-
-pub const IMAGE_HOT_PATCH_CHUNK_INVERSE: u32 = 0x8000_0000;
-pub const IMAGE_HOT_PATCH_CHUNK_OBLIGATORY: u32 = 0x4000_0000;
-pub const IMAGE_HOT_PATCH_CHUNK_RESERVED: u32 = 0x3FF0_3000;
-pub const IMAGE_HOT_PATCH_CHUNK_TYPE: u32 = 0x000F_C000;
-pub const IMAGE_HOT_PATCH_CHUNK_SOURCE_RVA: u32 = 0x0000_8000;
-pub const IMAGE_HOT_PATCH_CHUNK_TARGET_RVA: u32 = 0x0000_4000;
-pub const IMAGE_HOT_PATCH_CHUNK_SIZE: u32 = 0x0000_0FFF;
-
-pub const IMAGE_HOT_PATCH_NONE: u32 = 0x0000_0000;
-pub const IMAGE_HOT_PATCH_FUNCTION: u32 = 0x0001_C000;
-pub const IMAGE_HOT_PATCH_ABSOLUTE: u32 = 0x0002_C000;
-pub const IMAGE_HOT_PATCH_REL32: u32 = 0x0003_C000;
-pub const IMAGE_HOT_PATCH_CALL_TARGET: u32 = 0x0004_4000;
-pub const IMAGE_HOT_PATCH_INDIRECT: u32 = 0x0005_C000;
-pub const IMAGE_HOT_PATCH_NO_CALL_TARGET: u32 = 0x0006_4000;
-pub const IMAGE_HOT_PATCH_DYNAMIC_VALUE: u32 = 0x0007_8000;
-
-/// Module performs control flow integrity checks using system-supplied support
-pub const IMAGE_GUARD_CF_INSTRUMENTED: u32 = 0x0000_0100;
-/// Module performs control flow and write integrity checks
-pub const IMAGE_GUARD_CFW_INSTRUMENTED: u32 = 0x0000_0200;
-/// Module contains valid control flow target metadata
-pub const IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT: u32 = 0x0000_0400;
-/// Module does not make use of the /GS security cookie
-pub const IMAGE_GUARD_SECURITY_COOKIE_UNUSED: u32 = 0x0000_0800;
-/// Module supports read only delay load IAT
-pub const IMAGE_GUARD_PROTECT_DELAYLOAD_IAT: u32 = 0x0000_1000;
-/// Delayload import table in its own .didat section (with nothing else in it) that can be freely reprotected
-pub const IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION: u32 = 0x0000_2000;
-/// Module contains suppressed export information.
-///
-/// This also infers that the address taken taken IAT table is also present in the load config.
-pub const IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT: u32 = 0x0000_4000;
-/// Module enables suppression of exports
-pub const IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION: u32 = 0x0000_8000;
-/// Module contains longjmp target information
-pub const IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT: u32 = 0x0001_0000;
-/// Module contains return flow instrumentation and metadata
-pub const IMAGE_GUARD_RF_INSTRUMENTED: u32 = 0x0002_0000;
-/// Module requests that the OS enable return flow protection
-pub const IMAGE_GUARD_RF_ENABLE: u32 = 0x0004_0000;
-/// Module requests that the OS enable return flow protection in strict mode
-pub const IMAGE_GUARD_RF_STRICT: u32 = 0x0008_0000;
-/// Module was built with retpoline support
-pub const IMAGE_GUARD_RETPOLINE_PRESENT: u32 = 0x0010_0000;
-
-/// Stride of Guard CF function table encoded in these bits (additional count of bytes per element)
-pub const IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK: u32 = 0xF000_0000;
-/// Shift to right-justify Guard CF function table stride
-pub const IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT: u32 = 28;
-
-//
-// GFIDS table entry flags.
-//
-
-/// The containing GFID entry is suppressed
-pub const IMAGE_GUARD_FLAG_FID_SUPPRESSED: u16 = 0x01;
-/// The containing GFID entry is export suppressed
-pub const IMAGE_GUARD_FLAG_EXPORT_SUPPRESSED: u16 = 0x02;
-
-//
-// WIN CE Exception table format
-//
-
-//
-// Function table entry format. Function table is pointed to by the
-// IMAGE_DIRECTORY_ENTRY_EXCEPTION directory entry.
-//
-
-/*
-// TODO? bitfields
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageCeRuntimeFunctionEntry {
- pub func_start: U32<LE>,
- DWORD PrologLen : 8;
- DWORD FuncLen : 22;
- DWORD ThirtyTwoBit : 1;
- DWORD ExceptionFlag : 1;
-}
-*/
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageArmRuntimeFunctionEntry {
- pub begin_address: U32<LE>,
- pub unwind_data: U32<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageArm64RuntimeFunctionEntry {
- pub begin_address: U32<LE>,
- pub unwind_data: U32<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageAlpha64RuntimeFunctionEntry {
- pub begin_address: U64<LE>,
- pub end_address: U64<LE>,
- pub exception_handler: U64<LE>,
- pub handler_data: U64<LE>,
- pub prolog_end_address: U64<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageAlphaRuntimeFunctionEntry {
- pub begin_address: U32<LE>,
- pub end_address: U32<LE>,
- pub exception_handler: U32<LE>,
- pub handler_data: U32<LE>,
- pub prolog_end_address: U32<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageRuntimeFunctionEntry {
- pub begin_address: U32<LE>,
- pub end_address: U32<LE>,
- pub unwind_info_address_or_data: U32<LE>,
-}
-
-//
-// Software enclave information
-//
-
-pub const IMAGE_ENCLAVE_LONG_ID_LENGTH: usize = 32;
-pub const IMAGE_ENCLAVE_SHORT_ID_LENGTH: usize = 16;
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageEnclaveConfig32 {
- pub size: U32<LE>,
- pub minimum_required_config_size: U32<LE>,
- pub policy_flags: U32<LE>,
- pub number_of_imports: U32<LE>,
- pub import_list: U32<LE>,
- pub import_entry_size: U32<LE>,
- pub family_id: [u8; IMAGE_ENCLAVE_SHORT_ID_LENGTH],
- pub image_id: [u8; IMAGE_ENCLAVE_SHORT_ID_LENGTH],
- pub image_version: U32<LE>,
- pub security_version: U32<LE>,
- pub enclave_size: U32<LE>,
- pub number_of_threads: U32<LE>,
- pub enclave_flags: U32<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageEnclaveConfig64 {
- pub size: U32<LE>,
- pub minimum_required_config_size: U32<LE>,
- pub policy_flags: U32<LE>,
- pub number_of_imports: U32<LE>,
- pub import_list: U32<LE>,
- pub import_entry_size: U32<LE>,
- pub family_id: [u8; IMAGE_ENCLAVE_SHORT_ID_LENGTH],
- pub image_id: [u8; IMAGE_ENCLAVE_SHORT_ID_LENGTH],
- pub image_version: U32<LE>,
- pub security_version: U32<LE>,
- pub enclave_size: U64<LE>,
- pub number_of_threads: U32<LE>,
- pub enclave_flags: U32<LE>,
-}
-
-//pub const IMAGE_ENCLAVE_MINIMUM_CONFIG_SIZE: usize = FIELD_OFFSET(IMAGE_ENCLAVE_CONFIG, EnclaveFlags);
-
-pub const IMAGE_ENCLAVE_POLICY_DEBUGGABLE: u32 = 0x0000_0001;
-
-pub const IMAGE_ENCLAVE_FLAG_PRIMARY_IMAGE: u32 = 0x0000_0001;
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageEnclaveImport {
- pub match_type: U32<LE>,
- pub minimum_security_version: U32<LE>,
- pub unique_or_author_id: [u8; IMAGE_ENCLAVE_LONG_ID_LENGTH],
- pub family_id: [u8; IMAGE_ENCLAVE_SHORT_ID_LENGTH],
- pub image_id: [u8; IMAGE_ENCLAVE_SHORT_ID_LENGTH],
- pub import_name: U32<LE>,
- pub reserved: U32<LE>,
-}
-
-pub const IMAGE_ENCLAVE_IMPORT_MATCH_NONE: u32 = 0x0000_0000;
-pub const IMAGE_ENCLAVE_IMPORT_MATCH_UNIQUE_ID: u32 = 0x0000_0001;
-pub const IMAGE_ENCLAVE_IMPORT_MATCH_AUTHOR_ID: u32 = 0x0000_0002;
-pub const IMAGE_ENCLAVE_IMPORT_MATCH_FAMILY_ID: u32 = 0x0000_0003;
-pub const IMAGE_ENCLAVE_IMPORT_MATCH_IMAGE_ID: u32 = 0x0000_0004;
-
-//
-// Debug Format
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageDebugDirectory {
- pub characteristics: U32<LE>,
- pub time_date_stamp: U32<LE>,
- pub major_version: U16<LE>,
- pub minor_version: U16<LE>,
- pub typ: U32<LE>,
- pub size_of_data: U32<LE>,
- pub address_of_raw_data: U32<LE>,
- pub pointer_to_raw_data: U32<LE>,
-}
-
-pub const IMAGE_DEBUG_TYPE_UNKNOWN: u32 = 0;
-pub const IMAGE_DEBUG_TYPE_COFF: u32 = 1;
-pub const IMAGE_DEBUG_TYPE_CODEVIEW: u32 = 2;
-pub const IMAGE_DEBUG_TYPE_FPO: u32 = 3;
-pub const IMAGE_DEBUG_TYPE_MISC: u32 = 4;
-pub const IMAGE_DEBUG_TYPE_EXCEPTION: u32 = 5;
-pub const IMAGE_DEBUG_TYPE_FIXUP: u32 = 6;
-pub const IMAGE_DEBUG_TYPE_OMAP_TO_SRC: u32 = 7;
-pub const IMAGE_DEBUG_TYPE_OMAP_FROM_SRC: u32 = 8;
-pub const IMAGE_DEBUG_TYPE_BORLAND: u32 = 9;
-pub const IMAGE_DEBUG_TYPE_RESERVED10: u32 = 10;
-pub const IMAGE_DEBUG_TYPE_CLSID: u32 = 11;
-pub const IMAGE_DEBUG_TYPE_VC_FEATURE: u32 = 12;
-pub const IMAGE_DEBUG_TYPE_POGO: u32 = 13;
-pub const IMAGE_DEBUG_TYPE_ILTCG: u32 = 14;
-pub const IMAGE_DEBUG_TYPE_MPX: u32 = 15;
-pub const IMAGE_DEBUG_TYPE_REPRO: u32 = 16;
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageCoffSymbolsHeader {
- pub number_of_symbols: U32<LE>,
- pub lva_to_first_symbol: U32<LE>,
- pub number_of_linenumbers: U32<LE>,
- pub lva_to_first_linenumber: U32<LE>,
- pub rva_to_first_byte_of_code: U32<LE>,
- pub rva_to_last_byte_of_code: U32<LE>,
- pub rva_to_first_byte_of_data: U32<LE>,
- pub rva_to_last_byte_of_data: U32<LE>,
-}
-
-pub const FRAME_FPO: u16 = 0;
-pub const FRAME_TRAP: u16 = 1;
-pub const FRAME_TSS: u16 = 2;
-pub const FRAME_NONFPO: u16 = 3;
-
-/*
-// TODO? bitfields
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FpoData {
-/// offset 1st byte of function code
- pub ul_off_start: U32<LE>,
-/// # bytes in function
- pub cb_proc_size: U32<LE>,
-/// # bytes in locals/4
- pub cdw_locals: U32<LE>,
-/// # bytes in params/4
- pub cdw_params: U16<LE>,
-/// # bytes in prolog
- WORD cbProlog : 8;
-/// # regs saved
- WORD cbRegs : 3;
-/// TRUE if SEH in func
- WORD fHasSEH : 1;
-/// TRUE if EBP has been allocated
- WORD fUseBP : 1;
-/// reserved for future use
- WORD reserved : 1;
-/// frame type
- WORD cbFrame : 2;
-}
-pub const SIZEOF_RFPO_DATA: usize = 16;
-*/
-
-pub const IMAGE_DEBUG_MISC_EXENAME: u16 = 1;
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageDebugMisc {
- /// type of misc data, see defines
- pub data_type: U32<LE>,
- /// total length of record, rounded to four byte multiple.
- pub length: U32<LE>,
- /// TRUE if data is unicode string
- pub unicode: u8,
- pub reserved: [u8; 3],
- // Actual data
- //pub data: [u8; 1],
-}
-
-//
-// Function table extracted from MIPS/ALPHA/IA64 images. Does not contain
-// information needed only for runtime support. Just those fields for
-// each entry needed by a debugger.
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageFunctionEntry {
- pub starting_address: U32<LE>,
- pub ending_address: U32<LE>,
- pub end_of_prologue: U32<LE>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageFunctionEntry64 {
- pub starting_address: U64<LE>,
- pub ending_address: U64<LE>,
- pub end_of_prologue_or_unwind_info_address: U64<LE>,
-}
-
-//
-// Debugging information can be stripped from an image file and placed
-// in a separate .DBG file, whose file name part is the same as the
-// image file name part (e.g. symbols for CMD.EXE could be stripped
-// and placed in CMD.DBG). This is indicated by the IMAGE_FILE_DEBUG_STRIPPED
-// flag in the Characteristics field of the file header. The beginning of
-// the .DBG file contains the following structure which captures certain
-// information from the image file. This allows a debug to proceed even if
-// the original image file is not accessible. This header is followed by
-// zero of more IMAGE_SECTION_HEADER structures, followed by zero or more
-// IMAGE_DEBUG_DIRECTORY structures. The latter structures and those in
-// the image file contain file offsets relative to the beginning of the
-// .DBG file.
-//
-// If symbols have been stripped from an image, the IMAGE_DEBUG_MISC structure
-// is left in the image file, but not mapped. This allows a debugger to
-// compute the name of the .DBG file, from the name of the image in the
-// IMAGE_DEBUG_MISC structure.
-//
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageSeparateDebugHeader {
- pub signature: U16<LE>,
- pub flags: U16<LE>,
- pub machine: U16<LE>,
- pub characteristics: U16<LE>,
- pub time_date_stamp: U32<LE>,
- pub check_sum: U32<LE>,
- pub image_base: U32<LE>,
- pub size_of_image: U32<LE>,
- pub number_of_sections: U32<LE>,
- pub exported_names_size: U32<LE>,
- pub debug_directory_size: U32<LE>,
- pub section_alignment: U32<LE>,
- pub reserved: [U32<LE>; 2],
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct NonPagedDebugInfo {
- pub signature: U16<LE>,
- pub flags: U16<LE>,
- pub size: U32<LE>,
- pub machine: U16<LE>,
- pub characteristics: U16<LE>,
- pub time_date_stamp: U32<LE>,
- pub check_sum: U32<LE>,
- pub size_of_image: U32<LE>,
- pub image_base: U64<LE>,
- //debug_directory_size
- //ImageDebugDirectory
-}
-
-pub const IMAGE_SEPARATE_DEBUG_SIGNATURE: u16 = 0x4944;
-pub const NON_PAGED_DEBUG_SIGNATURE: u16 = 0x494E;
-
-pub const IMAGE_SEPARATE_DEBUG_FLAGS_MASK: u16 = 0x8000;
-/// when DBG was updated, the old checksum didn't match.
-pub const IMAGE_SEPARATE_DEBUG_MISMATCH: u16 = 0x8000;
-
-//
-// The .arch section is made up of headers, each describing an amask position/value
-// pointing to an array of IMAGE_ARCHITECTURE_ENTRY's. Each "array" (both the header
-// and entry arrays) are terminiated by a quadword of 0xffffffffL.
-//
-// NOTE: There may be quadwords of 0 sprinkled around and must be skipped.
-//
-
-/*
-// TODO? bitfields
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageArchitectureHeader {
- /// 1 -> code section depends on mask bit
- /// 0 -> new instruction depends on mask bit
- unsigned int AmaskValue: 1;
- /// MBZ
- int :7;
- /// Amask bit in question for this fixup
- unsigned int AmaskShift: 8;
- /// MBZ
- int :16;
- /// RVA into .arch section to array of ARCHITECTURE_ENTRY's
- pub first_entry_rva: U32<LE>,
-}
-*/
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageArchitectureEntry {
- /// RVA of instruction to fixup
- pub fixup_inst_rva: U32<LE>,
- /// fixup instruction (see alphaops.h)
- pub new_inst: U32<LE>,
-}
-
-// The following structure defines the new import object. Note the values of the first two fields,
-// which must be set as stated in order to differentiate old and new import members.
-// Following this structure, the linker emits two null-terminated strings used to recreate the
-// import at the time of use. The first string is the import's name, the second is the dll's name.
-
-pub const IMPORT_OBJECT_HDR_SIG2: u16 = 0xffff;
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImportObjectHeader {
- /// Must be IMAGE_FILE_MACHINE_UNKNOWN
- pub sig1: U16<LE>,
- /// Must be IMPORT_OBJECT_HDR_SIG2.
- pub sig2: U16<LE>,
- pub version: U16<LE>,
- pub machine: U16<LE>,
- /// Time/date stamp
- pub time_date_stamp: U32<LE>,
- /// particularly useful for incremental links
- pub size_of_data: U32<LE>,
-
- /// if grf & IMPORT_OBJECT_ORDINAL
- pub ordinal_or_hint: U16<LE>,
-
- // WORD Type : 2;
- // WORD NameType : 3;
- // WORD Reserved : 11;
- pub name_type: U16<LE>,
-}
-
-pub const IMPORT_OBJECT_TYPE_MASK: u16 = 0b11;
-pub const IMPORT_OBJECT_TYPE_SHIFT: u16 = 0;
-pub const IMPORT_OBJECT_CODE: u16 = 0;
-pub const IMPORT_OBJECT_DATA: u16 = 1;
-pub const IMPORT_OBJECT_CONST: u16 = 2;
-
-pub const IMPORT_OBJECT_NAME_MASK: u16 = 0b111;
-pub const IMPORT_OBJECT_NAME_SHIFT: u16 = 2;
-/// Import by ordinal
-pub const IMPORT_OBJECT_ORDINAL: u16 = 0;
-/// Import name == public symbol name.
-pub const IMPORT_OBJECT_NAME: u16 = 1;
-/// Import name == public symbol name skipping leading ?, @, or optionally _.
-pub const IMPORT_OBJECT_NAME_NO_PREFIX: u16 = 2;
-/// Import name == public symbol name skipping leading ?, @, or optionally _ and truncating at first @.
-pub const IMPORT_OBJECT_NAME_UNDECORATE: u16 = 3;
-/// Import name == a name is explicitly provided after the DLL name.
-pub const IMPORT_OBJECT_NAME_EXPORTAS: u16 = 4;
-
-// COM+ Header entry point flags.
-pub const COMIMAGE_FLAGS_ILONLY: u32 = 0x0000_0001;
-pub const COMIMAGE_FLAGS_32BITREQUIRED: u32 = 0x0000_0002;
-pub const COMIMAGE_FLAGS_IL_LIBRARY: u32 = 0x0000_0004;
-pub const COMIMAGE_FLAGS_STRONGNAMESIGNED: u32 = 0x0000_0008;
-pub const COMIMAGE_FLAGS_NATIVE_ENTRYPOINT: u32 = 0x0000_0010;
-pub const COMIMAGE_FLAGS_TRACKDEBUGDATA: u32 = 0x0001_0000;
-pub const COMIMAGE_FLAGS_32BITPREFERRED: u32 = 0x0002_0000;
-
-// Version flags for image.
-pub const COR_VERSION_MAJOR_V2: u16 = 2;
-pub const COR_VERSION_MAJOR: u16 = COR_VERSION_MAJOR_V2;
-pub const COR_VERSION_MINOR: u16 = 5;
-pub const COR_DELETED_NAME_LENGTH: usize = 8;
-pub const COR_VTABLEGAP_NAME_LENGTH: usize = 8;
-
-// Maximum size of a NativeType descriptor.
-pub const NATIVE_TYPE_MAX_CB: u16 = 1;
-pub const COR_ILMETHOD_SECT_SMALL_MAX_DATASIZE: u16 = 0xFF;
-
-// Consts for the MIH FLAGS
-pub const IMAGE_COR_MIH_METHODRVA: u16 = 0x01;
-pub const IMAGE_COR_MIH_EHRVA: u16 = 0x02;
-pub const IMAGE_COR_MIH_BASICBLOCK: u16 = 0x08;
-
-// V-table constants
-/// V-table slots are 32-bits in size.
-pub const COR_VTABLE_32BIT: u16 = 0x01;
-/// V-table slots are 64-bits in size.
-pub const COR_VTABLE_64BIT: u16 = 0x02;
-/// If set, transition from unmanaged.
-pub const COR_VTABLE_FROM_UNMANAGED: u16 = 0x04;
-/// If set, transition from unmanaged with keeping the current appdomain.
-pub const COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN: u16 = 0x08;
-/// Call most derived method described by
-pub const COR_VTABLE_CALL_MOST_DERIVED: u16 = 0x10;
-
-// EATJ constants
-/// Size of a jump thunk reserved range.
-pub const IMAGE_COR_EATJ_THUNK_SIZE: usize = 32;
-
-// Max name lengths
-pub const MAX_CLASS_NAME: usize = 1024;
-pub const MAX_PACKAGE_NAME: usize = 1024;
-
-// CLR 2.0 header structure.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ImageCor20Header {
- // Header versioning
- pub cb: U32<LE>,
- pub major_runtime_version: U16<LE>,
- pub minor_runtime_version: U16<LE>,
-
- // Symbol table and startup information
- pub meta_data: ImageDataDirectory,
- pub flags: U32<LE>,
-
- // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is not set, EntryPointToken represents a managed entrypoint.
- // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is set, EntryPointRVA represents an RVA to a native entrypoint.
- pub entry_point_token_or_rva: U32<LE>,
-
- // Binding information
- pub resources: ImageDataDirectory,
- pub strong_name_signature: ImageDataDirectory,
-
- // Regular fixup and binding information
- pub code_manager_table: ImageDataDirectory,
- pub vtable_fixups: ImageDataDirectory,
- pub export_address_table_jumps: ImageDataDirectory,
-
- // Precompiled image info (internal use only - set to zero)
- pub managed_native_header: ImageDataDirectory,
-}
-
-unsafe_impl_pod!(
- ImageDosHeader,
- ImageOs2Header,
- ImageVxdHeader,
- ImageFileHeader,
- ImageDataDirectory,
- ImageOptionalHeader32,
- ImageRomOptionalHeader,
- ImageOptionalHeader64,
- ImageNtHeaders64,
- ImageNtHeaders32,
- ImageRomHeaders,
- Guid,
- AnonObjectHeader,
- AnonObjectHeaderV2,
- AnonObjectHeaderBigobj,
- ImageSectionHeader,
- ImageSymbol,
- ImageSymbolBytes,
- ImageSymbolEx,
- ImageSymbolExBytes,
- ImageAuxSymbolTokenDef,
- ImageAuxSymbolFunction,
- ImageAuxSymbolFunctionBeginEnd,
- ImageAuxSymbolWeak,
- ImageAuxSymbolSection,
- ImageAuxSymbolCrc,
- ImageRelocation,
- ImageLinenumber,
- ImageBaseRelocation,
- ImageArchiveMemberHeader,
- ImageExportDirectory,
- ImageImportByName,
- ImageThunkData64,
- ImageThunkData32,
- ImageTlsDirectory64,
- ImageTlsDirectory32,
- ImageImportDescriptor,
- ImageBoundImportDescriptor,
- ImageBoundForwarderRef,
- ImageDelayloadDescriptor,
- ImageResourceDirectory,
- ImageResourceDirectoryEntry,
- ImageResourceDirectoryString,
- ImageResourceDirStringU,
- ImageResourceDataEntry,
- ImageLoadConfigCodeIntegrity,
- ImageDynamicRelocationTable,
- ImageDynamicRelocation32,
- ImageDynamicRelocation64,
- ImageDynamicRelocation32V2,
- ImageDynamicRelocation64V2,
- ImagePrologueDynamicRelocationHeader,
- ImageEpilogueDynamicRelocationHeader,
- //ImageImportControlTransferDynamicRelocation,
- //ImageIndirControlTransferDynamicRelocation,
- //ImageSwitchtableBranchDynamicRelocation,
- ImageLoadConfigDirectory32,
- ImageLoadConfigDirectory64,
- ImageHotPatchInfo,
- ImageHotPatchBase,
- ImageHotPatchHashes,
- //ImageCeRuntimeFunctionEntry,
- ImageArmRuntimeFunctionEntry,
- ImageArm64RuntimeFunctionEntry,
- ImageAlpha64RuntimeFunctionEntry,
- ImageAlphaRuntimeFunctionEntry,
- ImageRuntimeFunctionEntry,
- ImageEnclaveConfig32,
- ImageEnclaveConfig64,
- ImageEnclaveImport,
- ImageDebugDirectory,
- ImageCoffSymbolsHeader,
- //FpoData,
- ImageDebugMisc,
- ImageFunctionEntry,
- ImageFunctionEntry64,
- ImageSeparateDebugHeader,
- NonPagedDebugInfo,
- //ImageArchitectureHeader,
- ImageArchitectureEntry,
- ImportObjectHeader,
- ImageCor20Header,
- MaskedRichHeaderEntry,
-);
diff --git a/vendor/object/src/pod.rs b/vendor/object/src/pod.rs
deleted file mode 100644
index 8ee7816..0000000
--- a/vendor/object/src/pod.rs
+++ /dev/null
@@ -1,239 +0,0 @@
-//! Tools for converting file format structures to and from bytes.
-//!
-//! This module should be replaced once rust provides safe transmutes.
-
-// This module provides functions for both read and write features.
-#![cfg_attr(
- not(all(feature = "read_core", feature = "write_core")),
- allow(dead_code)
-)]
-
-use core::{mem, result, slice};
-
-type Result<T> = result::Result<T, ()>;
-
-/// A trait for types that can safely be converted from and to byte slices.
-///
-/// # Safety
-/// A type that is `Pod` must:
-/// - be `#[repr(C)]` or `#[repr(transparent)]`
-/// - have no invalid byte values
-/// - have no padding
-pub unsafe trait Pod: Copy + 'static {}
-
-/// Cast a byte slice to a `Pod` type.
-///
-/// Returns the type and the tail of the slice.
-#[inline]
-pub fn from_bytes<T: Pod>(data: &[u8]) -> Result<(&T, &[u8])> {
- let size = mem::size_of::<T>();
- let tail = data.get(size..).ok_or(())?;
- let ptr = data.as_ptr();
- if (ptr as usize) % mem::align_of::<T>() != 0 {
- return Err(());
- }
- // Safety:
- // The alignment and size are checked by this function.
- // The Pod trait ensures the type is valid to cast from bytes.
- let val = unsafe { &*ptr.cast() };
- Ok((val, tail))
-}
-
-/// Cast a mutable byte slice to a `Pod` type.
-///
-/// Returns the type and the tail of the slice.
-#[inline]
-pub fn from_bytes_mut<T: Pod>(data: &mut [u8]) -> Result<(&mut T, &mut [u8])> {
- let size = mem::size_of::<T>();
- if size > data.len() {
- return Err(());
- }
- let (data, tail) = data.split_at_mut(size);
- let ptr = data.as_mut_ptr();
- if (ptr as usize) % mem::align_of::<T>() != 0 {
- return Err(());
- }
- // Safety:
- // The alignment and size are checked by this function.
- // The Pod trait ensures the type is valid to cast from bytes.
- let val = unsafe { &mut *ptr.cast() };
- Ok((val, tail))
-}
-
-/// Cast a byte slice to a slice of a `Pod` type.
-///
-/// Returns the type slice and the tail of the byte slice.
-#[inline]
-pub fn slice_from_bytes<T: Pod>(data: &[u8], count: usize) -> Result<(&[T], &[u8])> {
- let size = count.checked_mul(mem::size_of::<T>()).ok_or(())?;
- let tail = data.get(size..).ok_or(())?;
- let ptr = data.as_ptr();
- if (ptr as usize) % mem::align_of::<T>() != 0 {
- return Err(());
- }
- // Safety:
- // The alignment and size are checked by this function.
- // The Pod trait ensures the type is valid to cast from bytes.
- let slice = unsafe { slice::from_raw_parts(ptr.cast(), count) };
- Ok((slice, tail))
-}
-
-/// Cast a mutable byte slice to a slice of a `Pod` type.
-///
-/// Returns the type slice and the tail of the byte slice.
-#[inline]
-pub fn slice_from_bytes_mut<T: Pod>(
- data: &mut [u8],
- count: usize,
-) -> Result<(&mut [T], &mut [u8])> {
- let size = count.checked_mul(mem::size_of::<T>()).ok_or(())?;
- if size > data.len() {
- return Err(());
- }
- let (data, tail) = data.split_at_mut(size);
- let ptr = data.as_mut_ptr();
- if (ptr as usize) % mem::align_of::<T>() != 0 {
- return Err(());
- }
- // Safety:
- // The alignment and size are checked by this function.
- // The Pod trait ensures the type is valid to cast from bytes.
- let slice = unsafe { slice::from_raw_parts_mut(ptr.cast(), count) };
- Ok((slice, tail))
-}
-
-/// Cast a `Pod` type to a byte slice.
-#[inline]
-pub fn bytes_of<T: Pod>(val: &T) -> &[u8] {
- let size = mem::size_of::<T>();
- // Safety:
- // Any alignment is allowed.
- // The size is determined in this function.
- // The Pod trait ensures the type is valid to cast to bytes.
- unsafe { slice::from_raw_parts(slice::from_ref(val).as_ptr().cast(), size) }
-}
-
-/// Cast a `Pod` type to a mutable byte slice.
-#[inline]
-pub fn bytes_of_mut<T: Pod>(val: &mut T) -> &mut [u8] {
- let size = mem::size_of::<T>();
- // Safety:
- // Any alignment is allowed.
- // The size is determined in this function.
- // The Pod trait ensures the type is valid to cast to bytes.
- unsafe { slice::from_raw_parts_mut(slice::from_mut(val).as_mut_ptr().cast(), size) }
-}
-
-/// Cast a slice of a `Pod` type to a byte slice.
-#[inline]
-pub fn bytes_of_slice<T: Pod>(val: &[T]) -> &[u8] {
- let size = val.len().wrapping_mul(mem::size_of::<T>());
- // Safety:
- // Any alignment is allowed.
- // The size is determined in this function.
- // The Pod trait ensures the type is valid to cast to bytes.
- unsafe { slice::from_raw_parts(val.as_ptr().cast(), size) }
-}
-
-/// Cast a slice of a `Pod` type to a mutable byte slice.
-#[inline]
-pub fn bytes_of_slice_mut<T: Pod>(val: &mut [T]) -> &mut [u8] {
- let size = val.len().wrapping_mul(mem::size_of::<T>());
- // Safety:
- // Any alignment is allowed.
- // The size is determined in this function.
- // The Pod trait ensures the type is valid to cast to bytes.
- unsafe { slice::from_raw_parts_mut(val.as_mut_ptr().cast(), size) }
-}
-
-macro_rules! unsafe_impl_pod {
- ($($struct_name:ident),+ $(,)?) => {
- $(
- unsafe impl Pod for $struct_name { }
- )+
- }
-}
-
-unsafe_impl_pod!(u8, u16, u32, u64);
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn single() {
- let x = u32::to_be(0x0123_4567);
- let mut x_mut = x;
- let bytes = bytes_of(&x);
- let bytes_mut = bytes_of_mut(&mut x_mut);
- assert_eq!(bytes, [0x01, 0x23, 0x45, 0x67]);
- assert_eq!(bytes, bytes_mut);
-
- let x16 = [u16::to_be(0x0123), u16::to_be(0x4567)];
-
- let (y, tail) = from_bytes::<u32>(bytes).unwrap();
- let (y_mut, tail_mut) = from_bytes_mut::<u32>(bytes_mut).unwrap();
- assert_eq!(*y, x);
- assert_eq!(y, y_mut);
- assert_eq!(tail, &[]);
- assert_eq!(tail, tail_mut);
-
- let (y, tail) = from_bytes::<u16>(bytes).unwrap();
- let (y_mut, tail_mut) = from_bytes_mut::<u16>(bytes_mut).unwrap();
- assert_eq!(*y, x16[0]);
- assert_eq!(y, y_mut);
- assert_eq!(tail, &bytes[2..]);
- assert_eq!(tail, tail_mut);
-
- let (y, tail) = from_bytes::<u16>(&bytes[2..]).unwrap();
- let (y_mut, tail_mut) = from_bytes_mut::<u16>(&mut bytes_mut[2..]).unwrap();
- assert_eq!(*y, x16[1]);
- assert_eq!(y, y_mut);
- assert_eq!(tail, &[]);
- assert_eq!(tail, tail_mut);
-
- assert_eq!(from_bytes::<u16>(&bytes[1..]), Err(()));
- assert_eq!(from_bytes::<u16>(&bytes[3..]), Err(()));
- assert_eq!(from_bytes::<u16>(&bytes[4..]), Err(()));
- assert_eq!(from_bytes_mut::<u16>(&mut bytes_mut[1..]), Err(()));
- assert_eq!(from_bytes_mut::<u16>(&mut bytes_mut[3..]), Err(()));
- assert_eq!(from_bytes_mut::<u16>(&mut bytes_mut[4..]), Err(()));
- }
-
- #[test]
- fn slice() {
- let x = [
- u16::to_be(0x0123),
- u16::to_be(0x4567),
- u16::to_be(0x89ab),
- u16::to_be(0xcdef),
- ];
- let mut x_mut = x;
-
- let bytes = bytes_of_slice(&x);
- let bytes_mut = bytes_of_slice_mut(&mut x_mut);
- assert_eq!(bytes, [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
- assert_eq!(bytes, bytes_mut);
-
- let (y, tail) = slice_from_bytes::<u16>(bytes, 4).unwrap();
- let (y_mut, tail_mut) = slice_from_bytes_mut::<u16>(bytes_mut, 4).unwrap();
- assert_eq!(y, x);
- assert_eq!(y, y_mut);
- assert_eq!(tail, &[]);
- assert_eq!(tail, tail_mut);
-
- let (y, tail) = slice_from_bytes::<u16>(&bytes[2..], 2).unwrap();
- let (y_mut, tail_mut) = slice_from_bytes::<u16>(&mut bytes_mut[2..], 2).unwrap();
- assert_eq!(y, &x[1..3]);
- assert_eq!(y, y_mut);
- assert_eq!(tail, &bytes[6..]);
- assert_eq!(tail, tail_mut);
-
- assert_eq!(slice_from_bytes::<u16>(bytes, 5), Err(()));
- assert_eq!(slice_from_bytes::<u16>(&bytes[2..], 4), Err(()));
- assert_eq!(slice_from_bytes::<u16>(&bytes[1..], 2), Err(()));
- assert_eq!(slice_from_bytes_mut::<u16>(bytes_mut, 5), Err(()));
- assert_eq!(slice_from_bytes_mut::<u16>(&mut bytes_mut[2..], 4), Err(()));
- assert_eq!(slice_from_bytes_mut::<u16>(&mut bytes_mut[1..], 2), Err(()));
- }
-}
diff --git a/vendor/object/src/read/any.rs b/vendor/object/src/read/any.rs
deleted file mode 100644
index a14e56d..0000000
--- a/vendor/object/src/read/any.rs
+++ /dev/null
@@ -1,1328 +0,0 @@
-use alloc::fmt;
-use alloc::vec::Vec;
-use core::marker::PhantomData;
-
-#[cfg(feature = "coff")]
-use crate::read::coff;
-#[cfg(feature = "elf")]
-use crate::read::elf;
-#[cfg(feature = "macho")]
-use crate::read::macho;
-#[cfg(feature = "pe")]
-use crate::read::pe;
-#[cfg(feature = "wasm")]
-use crate::read::wasm;
-#[cfg(feature = "xcoff")]
-use crate::read::xcoff;
-use crate::read::{
- self, Architecture, BinaryFormat, CodeView, ComdatKind, CompressedData, CompressedFileRange,
- Error, Export, FileFlags, FileKind, Import, Object, ObjectComdat, ObjectKind, ObjectMap,
- ObjectSection, ObjectSegment, ObjectSymbol, ObjectSymbolTable, ReadRef, Relocation, Result,
- SectionFlags, SectionIndex, SectionKind, SegmentFlags, SymbolFlags, SymbolIndex, SymbolKind,
- SymbolMap, SymbolMapName, SymbolScope, SymbolSection,
-};
-#[allow(unused_imports)]
-use crate::{AddressSize, Endian, Endianness, SubArchitecture};
-
-/// Evaluate an expression on the contents of a file format enum.
-///
-/// This is a hack to avoid virtual calls.
-macro_rules! with_inner {
- ($inner:expr, $enum:ident, | $var:ident | $body:expr) => {
- match $inner {
- #[cfg(feature = "coff")]
- $enum::Coff(ref $var) => $body,
- #[cfg(feature = "coff")]
- $enum::CoffBig(ref $var) => $body,
- #[cfg(feature = "elf")]
- $enum::Elf32(ref $var) => $body,
- #[cfg(feature = "elf")]
- $enum::Elf64(ref $var) => $body,
- #[cfg(feature = "macho")]
- $enum::MachO32(ref $var) => $body,
- #[cfg(feature = "macho")]
- $enum::MachO64(ref $var) => $body,
- #[cfg(feature = "pe")]
- $enum::Pe32(ref $var) => $body,
- #[cfg(feature = "pe")]
- $enum::Pe64(ref $var) => $body,
- #[cfg(feature = "wasm")]
- $enum::Wasm(ref $var) => $body,
- #[cfg(feature = "xcoff")]
- $enum::Xcoff32(ref $var) => $body,
- #[cfg(feature = "xcoff")]
- $enum::Xcoff64(ref $var) => $body,
- }
- };
-}
-
-macro_rules! with_inner_mut {
- ($inner:expr, $enum:ident, | $var:ident | $body:expr) => {
- match $inner {
- #[cfg(feature = "coff")]
- $enum::Coff(ref mut $var) => $body,
- #[cfg(feature = "coff")]
- $enum::CoffBig(ref mut $var) => $body,
- #[cfg(feature = "elf")]
- $enum::Elf32(ref mut $var) => $body,
- #[cfg(feature = "elf")]
- $enum::Elf64(ref mut $var) => $body,
- #[cfg(feature = "macho")]
- $enum::MachO32(ref mut $var) => $body,
- #[cfg(feature = "macho")]
- $enum::MachO64(ref mut $var) => $body,
- #[cfg(feature = "pe")]
- $enum::Pe32(ref mut $var) => $body,
- #[cfg(feature = "pe")]
- $enum::Pe64(ref mut $var) => $body,
- #[cfg(feature = "wasm")]
- $enum::Wasm(ref mut $var) => $body,
- #[cfg(feature = "xcoff")]
- $enum::Xcoff32(ref mut $var) => $body,
- #[cfg(feature = "xcoff")]
- $enum::Xcoff64(ref mut $var) => $body,
- }
- };
-}
-
-/// Like `with_inner!`, but wraps the result in another enum.
-macro_rules! map_inner {
- ($inner:expr, $from:ident, $to:ident, | $var:ident | $body:expr) => {
- match $inner {
- #[cfg(feature = "coff")]
- $from::Coff(ref $var) => $to::Coff($body),
- #[cfg(feature = "coff")]
- $from::CoffBig(ref $var) => $to::CoffBig($body),
- #[cfg(feature = "elf")]
- $from::Elf32(ref $var) => $to::Elf32($body),
- #[cfg(feature = "elf")]
- $from::Elf64(ref $var) => $to::Elf64($body),
- #[cfg(feature = "macho")]
- $from::MachO32(ref $var) => $to::MachO32($body),
- #[cfg(feature = "macho")]
- $from::MachO64(ref $var) => $to::MachO64($body),
- #[cfg(feature = "pe")]
- $from::Pe32(ref $var) => $to::Pe32($body),
- #[cfg(feature = "pe")]
- $from::Pe64(ref $var) => $to::Pe64($body),
- #[cfg(feature = "wasm")]
- $from::Wasm(ref $var) => $to::Wasm($body),
- #[cfg(feature = "xcoff")]
- $from::Xcoff32(ref $var) => $to::Xcoff32($body),
- #[cfg(feature = "xcoff")]
- $from::Xcoff64(ref $var) => $to::Xcoff64($body),
- }
- };
-}
-
-/// Like `map_inner!`, but the result is a Result or Option.
-macro_rules! map_inner_option {
- ($inner:expr, $from:ident, $to:ident, | $var:ident | $body:expr) => {
- match $inner {
- #[cfg(feature = "coff")]
- $from::Coff(ref $var) => $body.map($to::Coff),
- #[cfg(feature = "coff")]
- $from::CoffBig(ref $var) => $body.map($to::CoffBig),
- #[cfg(feature = "elf")]
- $from::Elf32(ref $var) => $body.map($to::Elf32),
- #[cfg(feature = "elf")]
- $from::Elf64(ref $var) => $body.map($to::Elf64),
- #[cfg(feature = "macho")]
- $from::MachO32(ref $var) => $body.map($to::MachO32),
- #[cfg(feature = "macho")]
- $from::MachO64(ref $var) => $body.map($to::MachO64),
- #[cfg(feature = "pe")]
- $from::Pe32(ref $var) => $body.map($to::Pe32),
- #[cfg(feature = "pe")]
- $from::Pe64(ref $var) => $body.map($to::Pe64),
- #[cfg(feature = "wasm")]
- $from::Wasm(ref $var) => $body.map($to::Wasm),
- #[cfg(feature = "xcoff")]
- $from::Xcoff32(ref $var) => $body.map($to::Xcoff32),
- #[cfg(feature = "xcoff")]
- $from::Xcoff64(ref $var) => $body.map($to::Xcoff64),
- }
- };
-}
-
-macro_rules! map_inner_option_mut {
- ($inner:expr, $from:ident, $to:ident, | $var:ident | $body:expr) => {
- match $inner {
- #[cfg(feature = "coff")]
- $from::Coff(ref mut $var) => $body.map($to::Coff),
- #[cfg(feature = "coff")]
- $from::CoffBig(ref mut $var) => $body.map($to::CoffBig),
- #[cfg(feature = "elf")]
- $from::Elf32(ref mut $var) => $body.map($to::Elf32),
- #[cfg(feature = "elf")]
- $from::Elf64(ref mut $var) => $body.map($to::Elf64),
- #[cfg(feature = "macho")]
- $from::MachO32(ref mut $var) => $body.map($to::MachO32),
- #[cfg(feature = "macho")]
- $from::MachO64(ref mut $var) => $body.map($to::MachO64),
- #[cfg(feature = "pe")]
- $from::Pe32(ref mut $var) => $body.map($to::Pe32),
- #[cfg(feature = "pe")]
- $from::Pe64(ref mut $var) => $body.map($to::Pe64),
- #[cfg(feature = "wasm")]
- $from::Wasm(ref mut $var) => $body.map($to::Wasm),
- #[cfg(feature = "xcoff")]
- $from::Xcoff32(ref mut $var) => $body.map($to::Xcoff32),
- #[cfg(feature = "xcoff")]
- $from::Xcoff64(ref mut $var) => $body.map($to::Xcoff64),
- }
- };
-}
-
-/// Call `next` for a file format iterator.
-macro_rules! next_inner {
- ($inner:expr, $from:ident, $to:ident) => {
- match $inner {
- #[cfg(feature = "coff")]
- $from::Coff(ref mut iter) => iter.next().map($to::Coff),
- #[cfg(feature = "coff")]
- $from::CoffBig(ref mut iter) => iter.next().map($to::CoffBig),
- #[cfg(feature = "elf")]
- $from::Elf32(ref mut iter) => iter.next().map($to::Elf32),
- #[cfg(feature = "elf")]
- $from::Elf64(ref mut iter) => iter.next().map($to::Elf64),
- #[cfg(feature = "macho")]
- $from::MachO32(ref mut iter) => iter.next().map($to::MachO32),
- #[cfg(feature = "macho")]
- $from::MachO64(ref mut iter) => iter.next().map($to::MachO64),
- #[cfg(feature = "pe")]
- $from::Pe32(ref mut iter) => iter.next().map($to::Pe32),
- #[cfg(feature = "pe")]
- $from::Pe64(ref mut iter) => iter.next().map($to::Pe64),
- #[cfg(feature = "wasm")]
- $from::Wasm(ref mut iter) => iter.next().map($to::Wasm),
- #[cfg(feature = "xcoff")]
- $from::Xcoff32(ref mut iter) => iter.next().map($to::Xcoff32),
- #[cfg(feature = "xcoff")]
- $from::Xcoff64(ref mut iter) => iter.next().map($to::Xcoff64),
- }
- };
-}
-
-/// An object file that can be any supported file format.
-///
-/// Most functionality is provided by the [`Object`] trait implementation.
-#[derive(Debug)]
-#[non_exhaustive]
-#[allow(missing_docs)]
-pub enum File<'data, R: ReadRef<'data> = &'data [u8]> {
- #[cfg(feature = "coff")]
- Coff(coff::CoffFile<'data, R>),
- #[cfg(feature = "coff")]
- CoffBig(coff::CoffBigFile<'data, R>),
- #[cfg(feature = "elf")]
- Elf32(elf::ElfFile32<'data, Endianness, R>),
- #[cfg(feature = "elf")]
- Elf64(elf::ElfFile64<'data, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO32(macho::MachOFile32<'data, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO64(macho::MachOFile64<'data, Endianness, R>),
- #[cfg(feature = "pe")]
- Pe32(pe::PeFile32<'data, R>),
- #[cfg(feature = "pe")]
- Pe64(pe::PeFile64<'data, R>),
- #[cfg(feature = "wasm")]
- Wasm(wasm::WasmFile<'data, R>),
- #[cfg(feature = "xcoff")]
- Xcoff32(xcoff::XcoffFile32<'data, R>),
- #[cfg(feature = "xcoff")]
- Xcoff64(xcoff::XcoffFile64<'data, R>),
-}
-
-impl<'data, R: ReadRef<'data>> File<'data, R> {
- /// Parse the raw file data.
- pub fn parse(data: R) -> Result<Self> {
- Ok(match FileKind::parse(data)? {
- #[cfg(feature = "elf")]
- FileKind::Elf32 => File::Elf32(elf::ElfFile32::parse(data)?),
- #[cfg(feature = "elf")]
- FileKind::Elf64 => File::Elf64(elf::ElfFile64::parse(data)?),
- #[cfg(feature = "macho")]
- FileKind::MachO32 => File::MachO32(macho::MachOFile32::parse(data)?),
- #[cfg(feature = "macho")]
- FileKind::MachO64 => File::MachO64(macho::MachOFile64::parse(data)?),
- #[cfg(feature = "wasm")]
- FileKind::Wasm => File::Wasm(wasm::WasmFile::parse(data)?),
- #[cfg(feature = "pe")]
- FileKind::Pe32 => File::Pe32(pe::PeFile32::parse(data)?),
- #[cfg(feature = "pe")]
- FileKind::Pe64 => File::Pe64(pe::PeFile64::parse(data)?),
- #[cfg(feature = "coff")]
- FileKind::Coff => File::Coff(coff::CoffFile::parse(data)?),
- #[cfg(feature = "coff")]
- FileKind::CoffBig => File::CoffBig(coff::CoffBigFile::parse(data)?),
- #[cfg(feature = "xcoff")]
- FileKind::Xcoff32 => File::Xcoff32(xcoff::XcoffFile32::parse(data)?),
- #[cfg(feature = "xcoff")]
- FileKind::Xcoff64 => File::Xcoff64(xcoff::XcoffFile64::parse(data)?),
- #[allow(unreachable_patterns)]
- _ => return Err(Error("Unsupported file format")),
- })
- }
-
- /// Parse a Mach-O image from the dyld shared cache.
- #[cfg(feature = "macho")]
- pub fn parse_dyld_cache_image<'cache, E: Endian>(
- image: &macho::DyldCacheImage<'data, 'cache, E, R>,
- ) -> Result<Self> {
- Ok(match image.cache.architecture().address_size() {
- Some(AddressSize::U64) => {
- File::MachO64(macho::MachOFile64::parse_dyld_cache_image(image)?)
- }
- Some(AddressSize::U32) => {
- File::MachO32(macho::MachOFile32::parse_dyld_cache_image(image)?)
- }
- _ => return Err(Error("Unsupported file format")),
- })
- }
-
- /// Return the file format.
- pub fn format(&self) -> BinaryFormat {
- match self {
- #[cfg(feature = "coff")]
- File::Coff(_) | File::CoffBig(_) => BinaryFormat::Coff,
- #[cfg(feature = "elf")]
- File::Elf32(_) | File::Elf64(_) => BinaryFormat::Elf,
- #[cfg(feature = "macho")]
- File::MachO32(_) | File::MachO64(_) => BinaryFormat::MachO,
- #[cfg(feature = "pe")]
- File::Pe32(_) | File::Pe64(_) => BinaryFormat::Pe,
- #[cfg(feature = "wasm")]
- File::Wasm(_) => BinaryFormat::Wasm,
- #[cfg(feature = "xcoff")]
- File::Xcoff32(_) | File::Xcoff64(_) => BinaryFormat::Xcoff,
- }
- }
-}
-
-impl<'data, R: ReadRef<'data>> read::private::Sealed for File<'data, R> {}
-
-impl<'data, 'file, R> Object<'data, 'file> for File<'data, R>
-where
- 'data: 'file,
- R: 'file + ReadRef<'data>,
-{
- type Segment = Segment<'data, 'file, R>;
- type SegmentIterator = SegmentIterator<'data, 'file, R>;
- type Section = Section<'data, 'file, R>;
- type SectionIterator = SectionIterator<'data, 'file, R>;
- type Comdat = Comdat<'data, 'file, R>;
- type ComdatIterator = ComdatIterator<'data, 'file, R>;
- type Symbol = Symbol<'data, 'file, R>;
- type SymbolIterator = SymbolIterator<'data, 'file, R>;
- type SymbolTable = SymbolTable<'data, 'file, R>;
- type DynamicRelocationIterator = DynamicRelocationIterator<'data, 'file, R>;
-
- fn architecture(&self) -> Architecture {
- with_inner!(self, File, |x| x.architecture())
- }
-
- fn sub_architecture(&self) -> Option<SubArchitecture> {
- with_inner!(self, File, |x| x.sub_architecture())
- }
-
- fn is_little_endian(&self) -> bool {
- with_inner!(self, File, |x| x.is_little_endian())
- }
-
- fn is_64(&self) -> bool {
- with_inner!(self, File, |x| x.is_64())
- }
-
- fn kind(&self) -> ObjectKind {
- with_inner!(self, File, |x| x.kind())
- }
-
- fn segments(&'file self) -> SegmentIterator<'data, 'file, R> {
- SegmentIterator {
- inner: map_inner!(self, File, SegmentIteratorInternal, |x| x.segments()),
- }
- }
-
- fn section_by_name_bytes(&'file self, section_name: &[u8]) -> Option<Section<'data, 'file, R>> {
- map_inner_option!(self, File, SectionInternal, |x| x
- .section_by_name_bytes(section_name))
- .map(|inner| Section { inner })
- }
-
- fn section_by_index(&'file self, index: SectionIndex) -> Result<Section<'data, 'file, R>> {
- map_inner_option!(self, File, SectionInternal, |x| x.section_by_index(index))
- .map(|inner| Section { inner })
- }
-
- fn sections(&'file self) -> SectionIterator<'data, 'file, R> {
- SectionIterator {
- inner: map_inner!(self, File, SectionIteratorInternal, |x| x.sections()),
- }
- }
-
- fn comdats(&'file self) -> ComdatIterator<'data, 'file, R> {
- ComdatIterator {
- inner: map_inner!(self, File, ComdatIteratorInternal, |x| x.comdats()),
- }
- }
-
- fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<Symbol<'data, 'file, R>> {
- map_inner_option!(self, File, SymbolInternal, |x| x
- .symbol_by_index(index)
- .map(|x| (x, PhantomData)))
- .map(|inner| Symbol { inner })
- }
-
- fn symbols(&'file self) -> SymbolIterator<'data, 'file, R> {
- SymbolIterator {
- inner: map_inner!(self, File, SymbolIteratorInternal, |x| (
- x.symbols(),
- PhantomData
- )),
- }
- }
-
- fn symbol_table(&'file self) -> Option<SymbolTable<'data, 'file, R>> {
- map_inner_option!(self, File, SymbolTableInternal, |x| x
- .symbol_table()
- .map(|x| (x, PhantomData)))
- .map(|inner| SymbolTable { inner })
- }
-
- fn dynamic_symbols(&'file self) -> SymbolIterator<'data, 'file, R> {
- SymbolIterator {
- inner: map_inner!(self, File, SymbolIteratorInternal, |x| (
- x.dynamic_symbols(),
- PhantomData
- )),
- }
- }
-
- fn dynamic_symbol_table(&'file self) -> Option<SymbolTable<'data, 'file, R>> {
- map_inner_option!(self, File, SymbolTableInternal, |x| x
- .dynamic_symbol_table()
- .map(|x| (x, PhantomData)))
- .map(|inner| SymbolTable { inner })
- }
-
- #[cfg(feature = "elf")]
- fn dynamic_relocations(&'file self) -> Option<DynamicRelocationIterator<'data, 'file, R>> {
- let inner = match self {
- File::Elf32(ref elf) => {
- DynamicRelocationIteratorInternal::Elf32(elf.dynamic_relocations()?)
- }
- File::Elf64(ref elf) => {
- DynamicRelocationIteratorInternal::Elf64(elf.dynamic_relocations()?)
- }
- #[allow(unreachable_patterns)]
- _ => return None,
- };
- Some(DynamicRelocationIterator { inner })
- }
-
- #[cfg(not(feature = "elf"))]
- fn dynamic_relocations(&'file self) -> Option<DynamicRelocationIterator<'data, 'file, R>> {
- None
- }
-
- fn symbol_map(&self) -> SymbolMap<SymbolMapName<'data>> {
- with_inner!(self, File, |x| x.symbol_map())
- }
-
- fn object_map(&self) -> ObjectMap<'data> {
- with_inner!(self, File, |x| x.object_map())
- }
-
- fn imports(&self) -> Result<Vec<Import<'data>>> {
- with_inner!(self, File, |x| x.imports())
- }
-
- fn exports(&self) -> Result<Vec<Export<'data>>> {
- with_inner!(self, File, |x| x.exports())
- }
-
- fn has_debug_symbols(&self) -> bool {
- with_inner!(self, File, |x| x.has_debug_symbols())
- }
-
- #[inline]
- fn mach_uuid(&self) -> Result<Option<[u8; 16]>> {
- with_inner!(self, File, |x| x.mach_uuid())
- }
-
- #[inline]
- fn build_id(&self) -> Result<Option<&'data [u8]>> {
- with_inner!(self, File, |x| x.build_id())
- }
-
- #[inline]
- fn gnu_debuglink(&self) -> Result<Option<(&'data [u8], u32)>> {
- with_inner!(self, File, |x| x.gnu_debuglink())
- }
-
- #[inline]
- fn gnu_debugaltlink(&self) -> Result<Option<(&'data [u8], &'data [u8])>> {
- with_inner!(self, File, |x| x.gnu_debugaltlink())
- }
-
- #[inline]
- fn pdb_info(&self) -> Result<Option<CodeView<'_>>> {
- with_inner!(self, File, |x| x.pdb_info())
- }
-
- fn relative_address_base(&self) -> u64 {
- with_inner!(self, File, |x| x.relative_address_base())
- }
-
- fn entry(&self) -> u64 {
- with_inner!(self, File, |x| x.entry())
- }
-
- fn flags(&self) -> FileFlags {
- with_inner!(self, File, |x| x.flags())
- }
-}
-
-/// An iterator for the loadable segments in a [`File`].
-#[derive(Debug)]
-pub struct SegmentIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
- inner: SegmentIteratorInternal<'data, 'file, R>,
-}
-
-#[derive(Debug)]
-enum SegmentIteratorInternal<'data, 'file, R: ReadRef<'data>> {
- #[cfg(feature = "coff")]
- Coff(coff::CoffSegmentIterator<'data, 'file, R>),
- #[cfg(feature = "coff")]
- CoffBig(coff::CoffBigSegmentIterator<'data, 'file, R>),
- #[cfg(feature = "elf")]
- Elf32(elf::ElfSegmentIterator32<'data, 'file, Endianness, R>),
- #[cfg(feature = "elf")]
- Elf64(elf::ElfSegmentIterator64<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO32(macho::MachOSegmentIterator32<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO64(macho::MachOSegmentIterator64<'data, 'file, Endianness, R>),
- #[cfg(feature = "pe")]
- Pe32(pe::PeSegmentIterator32<'data, 'file, R>),
- #[cfg(feature = "pe")]
- Pe64(pe::PeSegmentIterator64<'data, 'file, R>),
- #[cfg(feature = "wasm")]
- Wasm(wasm::WasmSegmentIterator<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff32(xcoff::XcoffSegmentIterator32<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff64(xcoff::XcoffSegmentIterator64<'data, 'file, R>),
-}
-
-impl<'data, 'file, R: ReadRef<'data>> Iterator for SegmentIterator<'data, 'file, R> {
- type Item = Segment<'data, 'file, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- next_inner!(self.inner, SegmentIteratorInternal, SegmentInternal)
- .map(|inner| Segment { inner })
- }
-}
-
-/// A loadable segment in a [`File`].
-///
-/// Most functionality is provided by the [`ObjectSegment`] trait implementation.
-pub struct Segment<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
- inner: SegmentInternal<'data, 'file, R>,
-}
-
-#[derive(Debug)]
-enum SegmentInternal<'data, 'file, R: ReadRef<'data>> {
- #[cfg(feature = "coff")]
- Coff(coff::CoffSegment<'data, 'file, R>),
- #[cfg(feature = "coff")]
- CoffBig(coff::CoffBigSegment<'data, 'file, R>),
- #[cfg(feature = "elf")]
- Elf32(elf::ElfSegment32<'data, 'file, Endianness, R>),
- #[cfg(feature = "elf")]
- Elf64(elf::ElfSegment64<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO32(macho::MachOSegment32<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO64(macho::MachOSegment64<'data, 'file, Endianness, R>),
- #[cfg(feature = "pe")]
- Pe32(pe::PeSegment32<'data, 'file, R>),
- #[cfg(feature = "pe")]
- Pe64(pe::PeSegment64<'data, 'file, R>),
- #[cfg(feature = "wasm")]
- Wasm(wasm::WasmSegment<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff32(xcoff::XcoffSegment32<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff64(xcoff::XcoffSegment64<'data, 'file, R>),
-}
-
-impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Segment<'data, 'file, R> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- // It's painful to do much better than this
- let mut s = f.debug_struct("Segment");
- match self.name() {
- Ok(Some(ref name)) => {
- s.field("name", name);
- }
- Ok(None) => {}
- Err(_) => {
- s.field("name", &"<invalid>");
- }
- }
- s.field("address", &self.address())
- .field("size", &self.size())
- .finish()
- }
-}
-
-impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Segment<'data, 'file, R> {}
-
-impl<'data, 'file, R: ReadRef<'data>> ObjectSegment<'data> for Segment<'data, 'file, R> {
- fn address(&self) -> u64 {
- with_inner!(self.inner, SegmentInternal, |x| x.address())
- }
-
- fn size(&self) -> u64 {
- with_inner!(self.inner, SegmentInternal, |x| x.size())
- }
-
- fn align(&self) -> u64 {
- with_inner!(self.inner, SegmentInternal, |x| x.align())
- }
-
- fn file_range(&self) -> (u64, u64) {
- with_inner!(self.inner, SegmentInternal, |x| x.file_range())
- }
-
- fn data(&self) -> Result<&'data [u8]> {
- with_inner!(self.inner, SegmentInternal, |x| x.data())
- }
-
- fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> {
- with_inner!(self.inner, SegmentInternal, |x| x.data_range(address, size))
- }
-
- fn name_bytes(&self) -> Result<Option<&[u8]>> {
- with_inner!(self.inner, SegmentInternal, |x| x.name_bytes())
- }
-
- fn name(&self) -> Result<Option<&str>> {
- with_inner!(self.inner, SegmentInternal, |x| x.name())
- }
-
- fn flags(&self) -> SegmentFlags {
- with_inner!(self.inner, SegmentInternal, |x| x.flags())
- }
-}
-
-/// An iterator for the sections in a [`File`].
-#[derive(Debug)]
-pub struct SectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
- inner: SectionIteratorInternal<'data, 'file, R>,
-}
-
-// we wrap our enums in a struct so that they are kept private.
-#[derive(Debug)]
-enum SectionIteratorInternal<'data, 'file, R: ReadRef<'data>> {
- #[cfg(feature = "coff")]
- Coff(coff::CoffSectionIterator<'data, 'file, R>),
- #[cfg(feature = "coff")]
- CoffBig(coff::CoffBigSectionIterator<'data, 'file, R>),
- #[cfg(feature = "elf")]
- Elf32(elf::ElfSectionIterator32<'data, 'file, Endianness, R>),
- #[cfg(feature = "elf")]
- Elf64(elf::ElfSectionIterator64<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO32(macho::MachOSectionIterator32<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO64(macho::MachOSectionIterator64<'data, 'file, Endianness, R>),
- #[cfg(feature = "pe")]
- Pe32(pe::PeSectionIterator32<'data, 'file, R>),
- #[cfg(feature = "pe")]
- Pe64(pe::PeSectionIterator64<'data, 'file, R>),
- #[cfg(feature = "wasm")]
- Wasm(wasm::WasmSectionIterator<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff32(xcoff::XcoffSectionIterator32<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff64(xcoff::XcoffSectionIterator64<'data, 'file, R>),
-}
-
-impl<'data, 'file, R: ReadRef<'data>> Iterator for SectionIterator<'data, 'file, R> {
- type Item = Section<'data, 'file, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- next_inner!(self.inner, SectionIteratorInternal, SectionInternal)
- .map(|inner| Section { inner })
- }
-}
-
-/// A section in a [`File`].
-///
-/// Most functionality is provided by the [`ObjectSection`] trait implementation.
-pub struct Section<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
- inner: SectionInternal<'data, 'file, R>,
-}
-
-enum SectionInternal<'data, 'file, R: ReadRef<'data>> {
- #[cfg(feature = "coff")]
- Coff(coff::CoffSection<'data, 'file, R>),
- #[cfg(feature = "coff")]
- CoffBig(coff::CoffBigSection<'data, 'file, R>),
- #[cfg(feature = "elf")]
- Elf32(elf::ElfSection32<'data, 'file, Endianness, R>),
- #[cfg(feature = "elf")]
- Elf64(elf::ElfSection64<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO32(macho::MachOSection32<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO64(macho::MachOSection64<'data, 'file, Endianness, R>),
- #[cfg(feature = "pe")]
- Pe32(pe::PeSection32<'data, 'file, R>),
- #[cfg(feature = "pe")]
- Pe64(pe::PeSection64<'data, 'file, R>),
- #[cfg(feature = "wasm")]
- Wasm(wasm::WasmSection<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff32(xcoff::XcoffSection32<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff64(xcoff::XcoffSection64<'data, 'file, R>),
-}
-
-impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Section<'data, 'file, R> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- // It's painful to do much better than this
- let mut s = f.debug_struct("Section");
- match self.segment_name() {
- Ok(Some(ref name)) => {
- s.field("segment", name);
- }
- Ok(None) => {}
- Err(_) => {
- s.field("segment", &"<invalid>");
- }
- }
- s.field("name", &self.name().unwrap_or("<invalid>"))
- .field("address", &self.address())
- .field("size", &self.size())
- .field("align", &self.align())
- .field("kind", &self.kind())
- .field("flags", &self.flags())
- .finish()
- }
-}
-
-impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Section<'data, 'file, R> {}
-
-impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for Section<'data, 'file, R> {
- type RelocationIterator = SectionRelocationIterator<'data, 'file, R>;
-
- fn index(&self) -> SectionIndex {
- with_inner!(self.inner, SectionInternal, |x| x.index())
- }
-
- fn address(&self) -> u64 {
- with_inner!(self.inner, SectionInternal, |x| x.address())
- }
-
- fn size(&self) -> u64 {
- with_inner!(self.inner, SectionInternal, |x| x.size())
- }
-
- fn align(&self) -> u64 {
- with_inner!(self.inner, SectionInternal, |x| x.align())
- }
-
- fn file_range(&self) -> Option<(u64, u64)> {
- with_inner!(self.inner, SectionInternal, |x| x.file_range())
- }
-
- fn data(&self) -> Result<&'data [u8]> {
- with_inner!(self.inner, SectionInternal, |x| x.data())
- }
-
- fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> {
- with_inner!(self.inner, SectionInternal, |x| x.data_range(address, size))
- }
-
- fn compressed_file_range(&self) -> Result<CompressedFileRange> {
- with_inner!(self.inner, SectionInternal, |x| x.compressed_file_range())
- }
-
- fn compressed_data(&self) -> Result<CompressedData<'data>> {
- with_inner!(self.inner, SectionInternal, |x| x.compressed_data())
- }
-
- fn name_bytes(&self) -> Result<&[u8]> {
- with_inner!(self.inner, SectionInternal, |x| x.name_bytes())
- }
-
- fn name(&self) -> Result<&str> {
- with_inner!(self.inner, SectionInternal, |x| x.name())
- }
-
- fn segment_name_bytes(&self) -> Result<Option<&[u8]>> {
- with_inner!(self.inner, SectionInternal, |x| x.segment_name_bytes())
- }
-
- fn segment_name(&self) -> Result<Option<&str>> {
- with_inner!(self.inner, SectionInternal, |x| x.segment_name())
- }
-
- fn kind(&self) -> SectionKind {
- with_inner!(self.inner, SectionInternal, |x| x.kind())
- }
-
- fn relocations(&self) -> SectionRelocationIterator<'data, 'file, R> {
- SectionRelocationIterator {
- inner: map_inner!(
- self.inner,
- SectionInternal,
- SectionRelocationIteratorInternal,
- |x| x.relocations()
- ),
- }
- }
-
- fn flags(&self) -> SectionFlags {
- with_inner!(self.inner, SectionInternal, |x| x.flags())
- }
-}
-
-/// An iterator for the COMDAT section groups in a [`File`].
-#[derive(Debug)]
-pub struct ComdatIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
- inner: ComdatIteratorInternal<'data, 'file, R>,
-}
-
-#[derive(Debug)]
-enum ComdatIteratorInternal<'data, 'file, R: ReadRef<'data>> {
- #[cfg(feature = "coff")]
- Coff(coff::CoffComdatIterator<'data, 'file, R>),
- #[cfg(feature = "coff")]
- CoffBig(coff::CoffBigComdatIterator<'data, 'file, R>),
- #[cfg(feature = "elf")]
- Elf32(elf::ElfComdatIterator32<'data, 'file, Endianness, R>),
- #[cfg(feature = "elf")]
- Elf64(elf::ElfComdatIterator64<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO32(macho::MachOComdatIterator32<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO64(macho::MachOComdatIterator64<'data, 'file, Endianness, R>),
- #[cfg(feature = "pe")]
- Pe32(pe::PeComdatIterator32<'data, 'file, R>),
- #[cfg(feature = "pe")]
- Pe64(pe::PeComdatIterator64<'data, 'file, R>),
- #[cfg(feature = "wasm")]
- Wasm(wasm::WasmComdatIterator<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff32(xcoff::XcoffComdatIterator32<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff64(xcoff::XcoffComdatIterator64<'data, 'file, R>),
-}
-
-impl<'data, 'file, R: ReadRef<'data>> Iterator for ComdatIterator<'data, 'file, R> {
- type Item = Comdat<'data, 'file, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- next_inner!(self.inner, ComdatIteratorInternal, ComdatInternal)
- .map(|inner| Comdat { inner })
- }
-}
-
-/// A COMDAT section group in a [`File`].
-///
-/// Most functionality is provided by the [`ObjectComdat`] trait implementation.
-pub struct Comdat<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
- inner: ComdatInternal<'data, 'file, R>,
-}
-
-enum ComdatInternal<'data, 'file, R: ReadRef<'data>> {
- #[cfg(feature = "coff")]
- Coff(coff::CoffComdat<'data, 'file, R>),
- #[cfg(feature = "coff")]
- CoffBig(coff::CoffBigComdat<'data, 'file, R>),
- #[cfg(feature = "elf")]
- Elf32(elf::ElfComdat32<'data, 'file, Endianness, R>),
- #[cfg(feature = "elf")]
- Elf64(elf::ElfComdat64<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO32(macho::MachOComdat32<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO64(macho::MachOComdat64<'data, 'file, Endianness, R>),
- #[cfg(feature = "pe")]
- Pe32(pe::PeComdat32<'data, 'file, R>),
- #[cfg(feature = "pe")]
- Pe64(pe::PeComdat64<'data, 'file, R>),
- #[cfg(feature = "wasm")]
- Wasm(wasm::WasmComdat<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff32(xcoff::XcoffComdat32<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff64(xcoff::XcoffComdat64<'data, 'file, R>),
-}
-
-impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Comdat<'data, 'file, R> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut s = f.debug_struct("Comdat");
- s.field("symbol", &self.symbol())
- .field("name", &self.name().unwrap_or("<invalid>"))
- .field("kind", &self.kind())
- .finish()
- }
-}
-
-impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Comdat<'data, 'file, R> {}
-
-impl<'data, 'file, R: ReadRef<'data>> ObjectComdat<'data> for Comdat<'data, 'file, R> {
- type SectionIterator = ComdatSectionIterator<'data, 'file, R>;
-
- fn kind(&self) -> ComdatKind {
- with_inner!(self.inner, ComdatInternal, |x| x.kind())
- }
-
- fn symbol(&self) -> SymbolIndex {
- with_inner!(self.inner, ComdatInternal, |x| x.symbol())
- }
-
- fn name_bytes(&self) -> Result<&[u8]> {
- with_inner!(self.inner, ComdatInternal, |x| x.name_bytes())
- }
-
- fn name(&self) -> Result<&str> {
- with_inner!(self.inner, ComdatInternal, |x| x.name())
- }
-
- fn sections(&self) -> ComdatSectionIterator<'data, 'file, R> {
- ComdatSectionIterator {
- inner: map_inner!(
- self.inner,
- ComdatInternal,
- ComdatSectionIteratorInternal,
- |x| x.sections()
- ),
- }
- }
-}
-
-/// An iterator for the sections in a [`Comdat`].
-#[derive(Debug)]
-pub struct ComdatSectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
- inner: ComdatSectionIteratorInternal<'data, 'file, R>,
-}
-
-#[derive(Debug)]
-enum ComdatSectionIteratorInternal<'data, 'file, R: ReadRef<'data>> {
- #[cfg(feature = "coff")]
- Coff(coff::CoffComdatSectionIterator<'data, 'file, R>),
- #[cfg(feature = "coff")]
- CoffBig(coff::CoffBigComdatSectionIterator<'data, 'file, R>),
- #[cfg(feature = "elf")]
- Elf32(elf::ElfComdatSectionIterator32<'data, 'file, Endianness, R>),
- #[cfg(feature = "elf")]
- Elf64(elf::ElfComdatSectionIterator64<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO32(macho::MachOComdatSectionIterator32<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO64(macho::MachOComdatSectionIterator64<'data, 'file, Endianness, R>),
- #[cfg(feature = "pe")]
- Pe32(pe::PeComdatSectionIterator32<'data, 'file, R>),
- #[cfg(feature = "pe")]
- Pe64(pe::PeComdatSectionIterator64<'data, 'file, R>),
- #[cfg(feature = "wasm")]
- Wasm(wasm::WasmComdatSectionIterator<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff32(xcoff::XcoffComdatSectionIterator32<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff64(xcoff::XcoffComdatSectionIterator64<'data, 'file, R>),
-}
-
-impl<'data, 'file, R: ReadRef<'data>> Iterator for ComdatSectionIterator<'data, 'file, R> {
- type Item = SectionIndex;
-
- fn next(&mut self) -> Option<Self::Item> {
- with_inner_mut!(self.inner, ComdatSectionIteratorInternal, |x| x.next())
- }
-}
-
-/// A symbol table in a [`File`].
-///
-/// Most functionality is provided by the [`ObjectSymbolTable`] trait implementation.
-#[derive(Debug)]
-pub struct SymbolTable<'data, 'file, R = &'data [u8]>
-where
- R: ReadRef<'data>,
-{
- inner: SymbolTableInternal<'data, 'file, R>,
-}
-
-#[derive(Debug)]
-enum SymbolTableInternal<'data, 'file, R>
-where
- R: ReadRef<'data>,
-{
- #[cfg(feature = "coff")]
- Coff((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)),
- #[cfg(feature = "coff")]
- CoffBig((coff::CoffBigSymbolTable<'data, 'file, R>, PhantomData<R>)),
- #[cfg(feature = "elf")]
- Elf32(
- (
- elf::ElfSymbolTable32<'data, 'file, Endianness, R>,
- PhantomData<R>,
- ),
- ),
- #[cfg(feature = "elf")]
- Elf64(
- (
- elf::ElfSymbolTable64<'data, 'file, Endianness, R>,
- PhantomData<R>,
- ),
- ),
- #[cfg(feature = "macho")]
- MachO32(
- (
- macho::MachOSymbolTable32<'data, 'file, Endianness, R>,
- PhantomData<()>,
- ),
- ),
- #[cfg(feature = "macho")]
- MachO64(
- (
- macho::MachOSymbolTable64<'data, 'file, Endianness, R>,
- PhantomData<()>,
- ),
- ),
- #[cfg(feature = "pe")]
- Pe32((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)),
- #[cfg(feature = "pe")]
- Pe64((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)),
- #[cfg(feature = "wasm")]
- Wasm((wasm::WasmSymbolTable<'data, 'file>, PhantomData<R>)),
- #[cfg(feature = "xcoff")]
- Xcoff32((xcoff::XcoffSymbolTable32<'data, 'file, R>, PhantomData<R>)),
- #[cfg(feature = "xcoff")]
- Xcoff64((xcoff::XcoffSymbolTable64<'data, 'file, R>, PhantomData<R>)),
-}
-
-impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for SymbolTable<'data, 'file, R> {}
-
-impl<'data, 'file, R: ReadRef<'data>> ObjectSymbolTable<'data> for SymbolTable<'data, 'file, R> {
- type Symbol = Symbol<'data, 'file, R>;
- type SymbolIterator = SymbolIterator<'data, 'file, R>;
-
- fn symbols(&self) -> Self::SymbolIterator {
- SymbolIterator {
- inner: map_inner!(
- self.inner,
- SymbolTableInternal,
- SymbolIteratorInternal,
- |x| (x.0.symbols(), PhantomData)
- ),
- }
- }
-
- fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol> {
- map_inner_option!(self.inner, SymbolTableInternal, SymbolInternal, |x| x
- .0
- .symbol_by_index(index)
- .map(|x| (x, PhantomData)))
- .map(|inner| Symbol { inner })
- }
-}
-
-/// An iterator for the symbols in a [`SymbolTable`].
-#[derive(Debug)]
-pub struct SymbolIterator<'data, 'file, R = &'data [u8]>
-where
- R: ReadRef<'data>,
-{
- inner: SymbolIteratorInternal<'data, 'file, R>,
-}
-
-#[derive(Debug)]
-enum SymbolIteratorInternal<'data, 'file, R>
-where
- R: ReadRef<'data>,
-{
- #[cfg(feature = "coff")]
- Coff((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)),
- #[cfg(feature = "coff")]
- CoffBig((coff::CoffBigSymbolIterator<'data, 'file, R>, PhantomData<R>)),
- #[cfg(feature = "elf")]
- Elf32(
- (
- elf::ElfSymbolIterator32<'data, 'file, Endianness, R>,
- PhantomData<R>,
- ),
- ),
- #[cfg(feature = "elf")]
- Elf64(
- (
- elf::ElfSymbolIterator64<'data, 'file, Endianness, R>,
- PhantomData<R>,
- ),
- ),
- #[cfg(feature = "macho")]
- MachO32(
- (
- macho::MachOSymbolIterator32<'data, 'file, Endianness, R>,
- PhantomData<()>,
- ),
- ),
- #[cfg(feature = "macho")]
- MachO64(
- (
- macho::MachOSymbolIterator64<'data, 'file, Endianness, R>,
- PhantomData<()>,
- ),
- ),
- #[cfg(feature = "pe")]
- Pe32((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)),
- #[cfg(feature = "pe")]
- Pe64((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)),
- #[cfg(feature = "wasm")]
- Wasm((wasm::WasmSymbolIterator<'data, 'file>, PhantomData<R>)),
- #[cfg(feature = "xcoff")]
- Xcoff32(
- (
- xcoff::XcoffSymbolIterator32<'data, 'file, R>,
- PhantomData<R>,
- ),
- ),
- #[cfg(feature = "xcoff")]
- Xcoff64(
- (
- xcoff::XcoffSymbolIterator64<'data, 'file, R>,
- PhantomData<R>,
- ),
- ),
-}
-
-impl<'data, 'file, R: ReadRef<'data>> Iterator for SymbolIterator<'data, 'file, R> {
- type Item = Symbol<'data, 'file, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- map_inner_option_mut!(self.inner, SymbolIteratorInternal, SymbolInternal, |iter| {
- iter.0.next().map(|x| (x, PhantomData))
- })
- .map(|inner| Symbol { inner })
- }
-}
-
-/// An symbol in a [`SymbolTable`].
-///
-/// Most functionality is provided by the [`ObjectSymbol`] trait implementation.
-pub struct Symbol<'data, 'file, R = &'data [u8]>
-where
- R: ReadRef<'data>,
-{
- inner: SymbolInternal<'data, 'file, R>,
-}
-
-enum SymbolInternal<'data, 'file, R>
-where
- R: ReadRef<'data>,
-{
- #[cfg(feature = "coff")]
- Coff((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)),
- #[cfg(feature = "coff")]
- CoffBig((coff::CoffBigSymbol<'data, 'file, R>, PhantomData<R>)),
- #[cfg(feature = "elf")]
- Elf32(
- (
- elf::ElfSymbol32<'data, 'file, Endianness, R>,
- PhantomData<R>,
- ),
- ),
- #[cfg(feature = "elf")]
- Elf64(
- (
- elf::ElfSymbol64<'data, 'file, Endianness, R>,
- PhantomData<R>,
- ),
- ),
- #[cfg(feature = "macho")]
- MachO32(
- (
- macho::MachOSymbol32<'data, 'file, Endianness, R>,
- PhantomData<()>,
- ),
- ),
- #[cfg(feature = "macho")]
- MachO64(
- (
- macho::MachOSymbol64<'data, 'file, Endianness, R>,
- PhantomData<()>,
- ),
- ),
- #[cfg(feature = "pe")]
- Pe32((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)),
- #[cfg(feature = "pe")]
- Pe64((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)),
- #[cfg(feature = "wasm")]
- Wasm((wasm::WasmSymbol<'data, 'file>, PhantomData<R>)),
- #[cfg(feature = "xcoff")]
- Xcoff32((xcoff::XcoffSymbol32<'data, 'file, R>, PhantomData<R>)),
- #[cfg(feature = "xcoff")]
- Xcoff64((xcoff::XcoffSymbol64<'data, 'file, R>, PhantomData<R>)),
-}
-
-impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Symbol<'data, 'file, R> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Symbol")
- .field("name", &self.name().unwrap_or("<invalid>"))
- .field("address", &self.address())
- .field("size", &self.size())
- .field("kind", &self.kind())
- .field("section", &self.section())
- .field("scope", &self.scope())
- .field("weak", &self.is_weak())
- .field("flags", &self.flags())
- .finish()
- }
-}
-
-impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Symbol<'data, 'file, R> {}
-
-impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for Symbol<'data, 'file, R> {
- fn index(&self) -> SymbolIndex {
- with_inner!(self.inner, SymbolInternal, |x| x.0.index())
- }
-
- fn name_bytes(&self) -> Result<&'data [u8]> {
- with_inner!(self.inner, SymbolInternal, |x| x.0.name_bytes())
- }
-
- fn name(&self) -> Result<&'data str> {
- with_inner!(self.inner, SymbolInternal, |x| x.0.name())
- }
-
- fn address(&self) -> u64 {
- with_inner!(self.inner, SymbolInternal, |x| x.0.address())
- }
-
- fn size(&self) -> u64 {
- with_inner!(self.inner, SymbolInternal, |x| x.0.size())
- }
-
- fn kind(&self) -> SymbolKind {
- with_inner!(self.inner, SymbolInternal, |x| x.0.kind())
- }
-
- fn section(&self) -> SymbolSection {
- with_inner!(self.inner, SymbolInternal, |x| x.0.section())
- }
-
- fn is_undefined(&self) -> bool {
- with_inner!(self.inner, SymbolInternal, |x| x.0.is_undefined())
- }
-
- fn is_definition(&self) -> bool {
- with_inner!(self.inner, SymbolInternal, |x| x.0.is_definition())
- }
-
- fn is_common(&self) -> bool {
- with_inner!(self.inner, SymbolInternal, |x| x.0.is_common())
- }
-
- fn is_weak(&self) -> bool {
- with_inner!(self.inner, SymbolInternal, |x| x.0.is_weak())
- }
-
- fn scope(&self) -> SymbolScope {
- with_inner!(self.inner, SymbolInternal, |x| x.0.scope())
- }
-
- fn is_global(&self) -> bool {
- with_inner!(self.inner, SymbolInternal, |x| x.0.is_global())
- }
-
- fn is_local(&self) -> bool {
- with_inner!(self.inner, SymbolInternal, |x| x.0.is_local())
- }
-
- fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> {
- with_inner!(self.inner, SymbolInternal, |x| x.0.flags())
- }
-}
-
-/// An iterator for the dynamic relocation entries in a [`File`].
-#[derive(Debug)]
-pub struct DynamicRelocationIterator<'data, 'file, R = &'data [u8]>
-where
- R: ReadRef<'data>,
-{
- inner: DynamicRelocationIteratorInternal<'data, 'file, R>,
-}
-
-#[derive(Debug)]
-enum DynamicRelocationIteratorInternal<'data, 'file, R>
-where
- R: ReadRef<'data>,
-{
- #[cfg(feature = "elf")]
- Elf32(elf::ElfDynamicRelocationIterator32<'data, 'file, Endianness, R>),
- #[cfg(feature = "elf")]
- Elf64(elf::ElfDynamicRelocationIterator64<'data, 'file, Endianness, R>),
- // We need to always use the lifetime parameters.
- #[allow(unused)]
- None(PhantomData<(&'data (), &'file (), R)>),
-}
-
-impl<'data, 'file, R: ReadRef<'data>> Iterator for DynamicRelocationIterator<'data, 'file, R> {
- type Item = (u64, Relocation);
-
- fn next(&mut self) -> Option<Self::Item> {
- match self.inner {
- #[cfg(feature = "elf")]
- DynamicRelocationIteratorInternal::Elf32(ref mut elf) => elf.next(),
- #[cfg(feature = "elf")]
- DynamicRelocationIteratorInternal::Elf64(ref mut elf) => elf.next(),
- DynamicRelocationIteratorInternal::None(_) => None,
- }
- }
-}
-
-/// An iterator for the relocation entries in a [`Section`].
-#[derive(Debug)]
-pub struct SectionRelocationIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
- inner: SectionRelocationIteratorInternal<'data, 'file, R>,
-}
-
-#[derive(Debug)]
-enum SectionRelocationIteratorInternal<'data, 'file, R: ReadRef<'data>> {
- #[cfg(feature = "coff")]
- Coff(coff::CoffRelocationIterator<'data, 'file, R>),
- #[cfg(feature = "coff")]
- CoffBig(coff::CoffBigRelocationIterator<'data, 'file, R>),
- #[cfg(feature = "elf")]
- Elf32(elf::ElfSectionRelocationIterator32<'data, 'file, Endianness, R>),
- #[cfg(feature = "elf")]
- Elf64(elf::ElfSectionRelocationIterator64<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO32(macho::MachORelocationIterator32<'data, 'file, Endianness, R>),
- #[cfg(feature = "macho")]
- MachO64(macho::MachORelocationIterator64<'data, 'file, Endianness, R>),
- #[cfg(feature = "pe")]
- Pe32(pe::PeRelocationIterator<'data, 'file, R>),
- #[cfg(feature = "pe")]
- Pe64(pe::PeRelocationIterator<'data, 'file, R>),
- #[cfg(feature = "wasm")]
- Wasm(wasm::WasmRelocationIterator<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff32(xcoff::XcoffRelocationIterator32<'data, 'file, R>),
- #[cfg(feature = "xcoff")]
- Xcoff64(xcoff::XcoffRelocationIterator64<'data, 'file, R>),
-}
-
-impl<'data, 'file, R: ReadRef<'data>> Iterator for SectionRelocationIterator<'data, 'file, R> {
- type Item = (u64, Relocation);
-
- fn next(&mut self) -> Option<Self::Item> {
- with_inner_mut!(self.inner, SectionRelocationIteratorInternal, |x| x.next())
- }
-}
diff --git a/vendor/object/src/read/archive.rs b/vendor/object/src/read/archive.rs
deleted file mode 100644
index 5d4ec4a..0000000
--- a/vendor/object/src/read/archive.rs
+++ /dev/null
@@ -1,759 +0,0 @@
-//! Support for archive files.
-//!
-//! ## Example
-//! ```no_run
-//! use object::{Object, ObjectSection};
-//! use std::error::Error;
-//! use std::fs;
-//!
-//! /// Reads an archive and displays the name of each member.
-//! fn main() -> Result<(), Box<dyn Error>> {
-//! # #[cfg(feature = "std")] {
-//! let data = fs::read("path/to/binary")?;
-//! let file = object::read::archive::ArchiveFile::parse(&*data)?;
-//! for member in file.members() {
-//! let member = member?;
-//! println!("{}", String::from_utf8_lossy(member.name()));
-//! }
-//! # }
-//! Ok(())
-//! }
-//! ```
-
-use core::convert::TryInto;
-
-use crate::archive;
-use crate::read::{self, Bytes, Error, ReadError, ReadRef};
-
-/// The kind of archive format.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum ArchiveKind {
- /// There are no special files that indicate the archive format.
- Unknown,
- /// The GNU (or System V) archive format.
- Gnu,
- /// The GNU (or System V) archive format with 64-bit symbol table.
- Gnu64,
- /// The BSD archive format.
- Bsd,
- /// The BSD archive format with 64-bit symbol table.
- ///
- /// This is used for Darwin.
- Bsd64,
- /// The Windows COFF archive format.
- Coff,
- /// The AIX big archive format.
- AixBig,
-}
-
-/// The list of members in the archive.
-#[derive(Debug, Clone, Copy)]
-enum Members<'data> {
- Common {
- offset: u64,
- end_offset: u64,
- },
- AixBig {
- index: &'data [archive::AixMemberOffset],
- },
-}
-
-/// A partially parsed archive file.
-#[derive(Debug, Clone, Copy)]
-pub struct ArchiveFile<'data, R: ReadRef<'data> = &'data [u8]> {
- data: R,
- kind: ArchiveKind,
- members: Members<'data>,
- symbols: (u64, u64),
- names: &'data [u8],
-}
-
-impl<'data, R: ReadRef<'data>> ArchiveFile<'data, R> {
- /// Parse the archive header and special members.
- pub fn parse(data: R) -> read::Result<Self> {
- let len = data.len().read_error("Unknown archive length")?;
- let mut tail = 0;
- let magic = data
- .read_bytes(&mut tail, archive::MAGIC.len() as u64)
- .read_error("Invalid archive size")?;
-
- if magic == archive::AIX_BIG_MAGIC {
- return Self::parse_aixbig(data);
- } else if magic != archive::MAGIC {
- return Err(Error("Unsupported archive identifier"));
- }
-
- let mut members_offset = tail;
- let members_end_offset = len;
-
- let mut file = ArchiveFile {
- data,
- kind: ArchiveKind::Unknown,
- members: Members::Common {
- offset: 0,
- end_offset: 0,
- },
- symbols: (0, 0),
- names: &[],
- };
-
- // The first few members may be special, so parse them.
- // GNU has:
- // - "/" or "/SYM64/": symbol table (optional)
- // - "//": names table (optional)
- // COFF has:
- // - "/": first linker member
- // - "/": second linker member
- // - "//": names table
- // BSD has:
- // - "__.SYMDEF" or "__.SYMDEF SORTED": symbol table (optional)
- // BSD 64-bit has:
- // - "__.SYMDEF_64" or "__.SYMDEF_64 SORTED": symbol table (optional)
- // BSD may use the extended name for the symbol table. This is handled
- // by `ArchiveMember::parse`.
- if tail < len {
- let member = ArchiveMember::parse(data, &mut tail, &[])?;
- if member.name == b"/" {
- // GNU symbol table (unless we later determine this is COFF).
- file.kind = ArchiveKind::Gnu;
- file.symbols = member.file_range();
- members_offset = tail;
-
- if tail < len {
- let member = ArchiveMember::parse(data, &mut tail, &[])?;
- if member.name == b"/" {
- // COFF linker member.
- file.kind = ArchiveKind::Coff;
- file.symbols = member.file_range();
- members_offset = tail;
-
- if tail < len {
- let member = ArchiveMember::parse(data, &mut tail, &[])?;
- if member.name == b"//" {
- // COFF names table.
- file.names = member.data(data)?;
- members_offset = tail;
- }
- }
- } else if member.name == b"//" {
- // GNU names table.
- file.names = member.data(data)?;
- members_offset = tail;
- }
- }
- } else if member.name == b"/SYM64/" {
- // GNU 64-bit symbol table.
- file.kind = ArchiveKind::Gnu64;
- file.symbols = member.file_range();
- members_offset = tail;
-
- if tail < len {
- let member = ArchiveMember::parse(data, &mut tail, &[])?;
- if member.name == b"//" {
- // GNU names table.
- file.names = member.data(data)?;
- members_offset = tail;
- }
- }
- } else if member.name == b"//" {
- // GNU names table.
- file.kind = ArchiveKind::Gnu;
- file.names = member.data(data)?;
- members_offset = tail;
- } else if member.name == b"__.SYMDEF" || member.name == b"__.SYMDEF SORTED" {
- // BSD symbol table.
- file.kind = ArchiveKind::Bsd;
- file.symbols = member.file_range();
- members_offset = tail;
- } else if member.name == b"__.SYMDEF_64" || member.name == b"__.SYMDEF_64 SORTED" {
- // BSD 64-bit symbol table.
- file.kind = ArchiveKind::Bsd64;
- file.symbols = member.file_range();
- members_offset = tail;
- } else {
- // TODO: This could still be a BSD file. We leave this as unknown for now.
- }
- }
- file.members = Members::Common {
- offset: members_offset,
- end_offset: members_end_offset,
- };
- Ok(file)
- }
-
- fn parse_aixbig(data: R) -> read::Result<Self> {
- let mut tail = 0;
-
- let file_header = data
- .read::<archive::AixFileHeader>(&mut tail)
- .read_error("Invalid AIX big archive file header")?;
- // Caller already validated this.
- debug_assert_eq!(file_header.magic, archive::AIX_BIG_MAGIC);
-
- let mut file = ArchiveFile {
- data,
- kind: ArchiveKind::AixBig,
- members: Members::AixBig { index: &[] },
- symbols: (0, 0),
- names: &[],
- };
-
- // Read the span of symbol table.
- let symtbl64 = parse_u64_digits(&file_header.gst64off, 10)
- .read_error("Invalid offset to 64-bit symbol table in AIX big archive")?;
- if symtbl64 > 0 {
- // The symbol table is also a file with header.
- let member = ArchiveMember::parse_aixbig(data, symtbl64)?;
- file.symbols = member.file_range();
- } else {
- let symtbl = parse_u64_digits(&file_header.gstoff, 10)
- .read_error("Invalid offset to symbol table in AIX big archive")?;
- if symtbl > 0 {
- // The symbol table is also a file with header.
- let member = ArchiveMember::parse_aixbig(data, symtbl)?;
- file.symbols = member.file_range();
- }
- }
-
- // Big archive member index table lists file entries with offsets and names.
- // To avoid potential infinite loop (members are double-linked list), the
- // iterator goes through the index instead of real members.
- let member_table_offset = parse_u64_digits(&file_header.memoff, 10)
- .read_error("Invalid offset for member table of AIX big archive")?;
- if member_table_offset == 0 {
- // The offset would be zero if archive contains no file.
- return Ok(file);
- }
-
- // The member index table is also a file with header.
- let member = ArchiveMember::parse_aixbig(data, member_table_offset)?;
- let mut member_data = Bytes(member.data(data)?);
-
- // Structure of member index table:
- // Number of entries (20 bytes)
- // Offsets of each entry (20*N bytes)
- // Names string table (the rest of bytes to fill size defined in header)
- let members_count_bytes = member_data
- .read_slice::<u8>(20)
- .read_error("Missing member count in AIX big archive")?;
- let members_count = parse_u64_digits(members_count_bytes, 10)
- .and_then(|size| size.try_into().ok())
- .read_error("Invalid member count in AIX big archive")?;
- let index = member_data
- .read_slice::<archive::AixMemberOffset>(members_count)
- .read_error("Member count overflow in AIX big archive")?;
- file.members = Members::AixBig { index };
-
- Ok(file)
- }
-
- /// Return the archive format.
- #[inline]
- pub fn kind(&self) -> ArchiveKind {
- self.kind
- }
-
- /// Iterate over the members of the archive.
- ///
- /// This does not return special members.
- #[inline]
- pub fn members(&self) -> ArchiveMemberIterator<'data, R> {
- ArchiveMemberIterator {
- data: self.data,
- members: self.members,
- names: self.names,
- }
- }
-}
-
-/// An iterator over the members of an archive.
-#[derive(Debug)]
-pub struct ArchiveMemberIterator<'data, R: ReadRef<'data> = &'data [u8]> {
- data: R,
- members: Members<'data>,
- names: &'data [u8],
-}
-
-impl<'data, R: ReadRef<'data>> Iterator for ArchiveMemberIterator<'data, R> {
- type Item = read::Result<ArchiveMember<'data>>;
-
- fn next(&mut self) -> Option<Self::Item> {
- match &mut self.members {
- Members::Common {
- ref mut offset,
- ref mut end_offset,
- } => {
- if *offset >= *end_offset {
- return None;
- }
- let member = ArchiveMember::parse(self.data, offset, self.names);
- if member.is_err() {
- *offset = *end_offset;
- }
- Some(member)
- }
- Members::AixBig { ref mut index } => match **index {
- [] => None,
- [ref first, ref rest @ ..] => {
- *index = rest;
- let member = ArchiveMember::parse_aixbig_index(self.data, first);
- if member.is_err() {
- *index = &[];
- }
- Some(member)
- }
- },
- }
- }
-}
-
-/// An archive member header.
-#[derive(Debug, Clone, Copy)]
-enum MemberHeader<'data> {
- /// Common header used by many formats.
- Common(&'data archive::Header),
- /// AIX big archive header
- AixBig(&'data archive::AixHeader),
-}
-
-/// A partially parsed archive member.
-#[derive(Debug)]
-pub struct ArchiveMember<'data> {
- header: MemberHeader<'data>,
- name: &'data [u8],
- offset: u64,
- size: u64,
-}
-
-impl<'data> ArchiveMember<'data> {
- /// Parse the member header, name, and file data in an archive with the common format.
- ///
- /// This reads the extended name (if any) and adjusts the file size.
- fn parse<R: ReadRef<'data>>(
- data: R,
- offset: &mut u64,
- names: &'data [u8],
- ) -> read::Result<Self> {
- let header = data
- .read::<archive::Header>(offset)
- .read_error("Invalid archive member header")?;
- if header.terminator != archive::TERMINATOR {
- return Err(Error("Invalid archive terminator"));
- }
-
- let mut file_offset = *offset;
- let mut file_size =
- parse_u64_digits(&header.size, 10).read_error("Invalid archive member size")?;
- *offset = offset
- .checked_add(file_size)
- .read_error("Archive member size is too large")?;
- // Entries are padded to an even number of bytes.
- if (file_size & 1) != 0 {
- *offset = offset.saturating_add(1);
- }
-
- let name = if header.name[0] == b'/' && (header.name[1] as char).is_ascii_digit() {
- // Read file name from the names table.
- parse_sysv_extended_name(&header.name[1..], names)
- .read_error("Invalid archive extended name offset")?
- } else if &header.name[..3] == b"#1/" && (header.name[3] as char).is_ascii_digit() {
- // Read file name from the start of the file data.
- parse_bsd_extended_name(&header.name[3..], data, &mut file_offset, &mut file_size)
- .read_error("Invalid archive extended name length")?
- } else if header.name[0] == b'/' {
- let name_len = memchr::memchr(b' ', &header.name).unwrap_or(header.name.len());
- &header.name[..name_len]
- } else {
- let name_len = memchr::memchr(b'/', &header.name)
- .or_else(|| memchr::memchr(b' ', &header.name))
- .unwrap_or(header.name.len());
- &header.name[..name_len]
- };
-
- Ok(ArchiveMember {
- header: MemberHeader::Common(header),
- name,
- offset: file_offset,
- size: file_size,
- })
- }
-
- /// Parse a member index entry in an AIX big archive,
- /// and then parse the member header, name, and file data.
- fn parse_aixbig_index<R: ReadRef<'data>>(
- data: R,
- index: &archive::AixMemberOffset,
- ) -> read::Result<Self> {
- let offset = parse_u64_digits(&index.0, 10)
- .read_error("Invalid AIX big archive file member offset")?;
- Self::parse_aixbig(data, offset)
- }
-
- /// Parse the member header, name, and file data in an AIX big archive.
- fn parse_aixbig<R: ReadRef<'data>>(data: R, mut offset: u64) -> read::Result<Self> {
- // The format was described at
- // https://www.ibm.com/docs/en/aix/7.3?topic=formats-ar-file-format-big
- let header = data
- .read::<archive::AixHeader>(&mut offset)
- .read_error("Invalid AIX big archive member header")?;
- let name_length = parse_u64_digits(&header.namlen, 10)
- .read_error("Invalid AIX big archive member name length")?;
- let name = data
- .read_bytes(&mut offset, name_length)
- .read_error("Invalid AIX big archive member name")?;
-
- // The actual data for a file member begins at the first even-byte boundary beyond the
- // member header and continues for the number of bytes specified by the ar_size field. The
- // ar command inserts null bytes for padding where necessary.
- if offset & 1 != 0 {
- offset = offset.saturating_add(1);
- }
- // Because of the even-byte boundary, we have to read and check terminator after header.
- let terminator = data
- .read_bytes(&mut offset, 2)
- .read_error("Invalid AIX big archive terminator")?;
- if terminator != archive::TERMINATOR {
- return Err(Error("Invalid AIX big archive terminator"));
- }
-
- let size = parse_u64_digits(&header.size, 10)
- .read_error("Invalid archive member size in AIX big archive")?;
- Ok(ArchiveMember {
- header: MemberHeader::AixBig(header),
- name,
- offset,
- size,
- })
- }
-
- /// Return the raw header that is common to many archive formats.
- ///
- /// Returns `None` if this archive does not use the common header format.
- #[inline]
- pub fn header(&self) -> Option<&'data archive::Header> {
- match self.header {
- MemberHeader::Common(header) => Some(header),
- _ => None,
- }
- }
-
- /// Return the raw header for AIX big archives.
- ///
- /// Returns `None` if this is not an AIX big archive.
- #[inline]
- pub fn aix_header(&self) -> Option<&'data archive::AixHeader> {
- match self.header {
- MemberHeader::AixBig(header) => Some(header),
- _ => None,
- }
- }
-
- /// Return the parsed file name.
- ///
- /// This may be an extended file name.
- #[inline]
- pub fn name(&self) -> &'data [u8] {
- self.name
- }
-
- /// Parse the file modification timestamp from the header.
- #[inline]
- pub fn date(&self) -> Option<u64> {
- match &self.header {
- MemberHeader::Common(header) => parse_u64_digits(&header.date, 10),
- MemberHeader::AixBig(header) => parse_u64_digits(&header.date, 10),
- }
- }
-
- /// Parse the user ID from the header.
- #[inline]
- pub fn uid(&self) -> Option<u64> {
- match &self.header {
- MemberHeader::Common(header) => parse_u64_digits(&header.uid, 10),
- MemberHeader::AixBig(header) => parse_u64_digits(&header.uid, 10),
- }
- }
-
- /// Parse the group ID from the header.
- #[inline]
- pub fn gid(&self) -> Option<u64> {
- match &self.header {
- MemberHeader::Common(header) => parse_u64_digits(&header.gid, 10),
- MemberHeader::AixBig(header) => parse_u64_digits(&header.gid, 10),
- }
- }
-
- /// Parse the file mode from the header.
- #[inline]
- pub fn mode(&self) -> Option<u64> {
- match &self.header {
- MemberHeader::Common(header) => parse_u64_digits(&header.mode, 8),
- MemberHeader::AixBig(header) => parse_u64_digits(&header.mode, 8),
- }
- }
-
- /// Return the offset and size of the file data.
- pub fn file_range(&self) -> (u64, u64) {
- (self.offset, self.size)
- }
-
- /// Return the file data.
- #[inline]
- pub fn data<R: ReadRef<'data>>(&self, data: R) -> read::Result<&'data [u8]> {
- data.read_bytes_at(self.offset, self.size)
- .read_error("Archive member size is too large")
- }
-}
-
-// Ignores bytes starting from the first space.
-fn parse_u64_digits(digits: &[u8], radix: u32) -> Option<u64> {
- if let [b' ', ..] = digits {
- return None;
- }
- let mut result: u64 = 0;
- for &c in digits {
- if c == b' ' {
- return Some(result);
- } else {
- let x = (c as char).to_digit(radix)?;
- result = result
- .checked_mul(u64::from(radix))?
- .checked_add(u64::from(x))?;
- }
- }
- Some(result)
-}
-
-fn parse_sysv_extended_name<'data>(digits: &[u8], names: &'data [u8]) -> Result<&'data [u8], ()> {
- let offset = parse_u64_digits(digits, 10).ok_or(())?;
- let offset = offset.try_into().map_err(|_| ())?;
- let name_data = names.get(offset..).ok_or(())?;
- let name = match memchr::memchr2(b'/', b'\0', name_data) {
- Some(len) => &name_data[..len],
- None => name_data,
- };
- Ok(name)
-}
-
-/// Modifies `data` to start after the extended name.
-fn parse_bsd_extended_name<'data, R: ReadRef<'data>>(
- digits: &[u8],
- data: R,
- offset: &mut u64,
- size: &mut u64,
-) -> Result<&'data [u8], ()> {
- let len = parse_u64_digits(digits, 10).ok_or(())?;
- *size = size.checked_sub(len).ok_or(())?;
- let name_data = data.read_bytes(offset, len)?;
- let name = match memchr::memchr(b'\0', name_data) {
- Some(len) => &name_data[..len],
- None => name_data,
- };
- Ok(name)
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn kind() {
- let data = b"!<arch>\n";
- let archive = ArchiveFile::parse(&data[..]).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Unknown);
-
- let data = b"\
- !<arch>\n\
- / 4 `\n\
- 0000";
- let archive = ArchiveFile::parse(&data[..]).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Gnu);
-
- let data = b"\
- !<arch>\n\
- // 4 `\n\
- 0000";
- let archive = ArchiveFile::parse(&data[..]).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Gnu);
-
- let data = b"\
- !<arch>\n\
- / 4 `\n\
- 0000\
- // 4 `\n\
- 0000";
- let archive = ArchiveFile::parse(&data[..]).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Gnu);
-
- let data = b"\
- !<arch>\n\
- /SYM64/ 4 `\n\
- 0000";
- let archive = ArchiveFile::parse(&data[..]).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Gnu64);
-
- let data = b"\
- !<arch>\n\
- /SYM64/ 4 `\n\
- 0000\
- // 4 `\n\
- 0000";
- let archive = ArchiveFile::parse(&data[..]).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Gnu64);
-
- let data = b"\
- !<arch>\n\
- __.SYMDEF 4 `\n\
- 0000";
- let archive = ArchiveFile::parse(&data[..]).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Bsd);
-
- let data = b"\
- !<arch>\n\
- #1/9 13 `\n\
- __.SYMDEF0000";
- let archive = ArchiveFile::parse(&data[..]).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Bsd);
-
- let data = b"\
- !<arch>\n\
- #1/16 20 `\n\
- __.SYMDEF SORTED0000";
- let archive = ArchiveFile::parse(&data[..]).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Bsd);
-
- let data = b"\
- !<arch>\n\
- __.SYMDEF_64 4 `\n\
- 0000";
- let archive = ArchiveFile::parse(&data[..]).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Bsd64);
-
- let data = b"\
- !<arch>\n\
- #1/12 16 `\n\
- __.SYMDEF_640000";
- let archive = ArchiveFile::parse(&data[..]).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Bsd64);
-
- let data = b"\
- !<arch>\n\
- #1/19 23 `\n\
- __.SYMDEF_64 SORTED0000";
- let archive = ArchiveFile::parse(&data[..]).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Bsd64);
-
- let data = b"\
- !<arch>\n\
- / 4 `\n\
- 0000\
- / 4 `\n\
- 0000\
- // 4 `\n\
- 0000";
- let archive = ArchiveFile::parse(&data[..]).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Coff);
-
- let data = b"\
- <bigaf>\n\
- 0 0 \
- 0 0 \
- 0 128 \
- 6 0 \
- 0 \0\0\0\0\0\0\0\0\0\0\0\0\
- \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
- \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
- \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
- let archive = ArchiveFile::parse(&data[..]).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::AixBig);
- }
-
- #[test]
- fn gnu_names() {
- let data = b"\
- !<arch>\n\
- // 18 `\n\
- 0123456789abcdef/\n\
- s p a c e/ 0 0 0 644 4 `\n\
- 0000\
- 0123456789abcde/0 0 0 644 3 `\n\
- odd\n\
- /0 0 0 0 644 4 `\n\
- even";
- let data = &data[..];
- let archive = ArchiveFile::parse(data).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Gnu);
- let mut members = archive.members();
-
- let member = members.next().unwrap().unwrap();
- assert_eq!(member.name(), b"s p a c e");
- assert_eq!(member.data(data).unwrap(), &b"0000"[..]);
-
- let member = members.next().unwrap().unwrap();
- assert_eq!(member.name(), b"0123456789abcde");
- assert_eq!(member.data(data).unwrap(), &b"odd"[..]);
-
- let member = members.next().unwrap().unwrap();
- assert_eq!(member.name(), b"0123456789abcdef");
- assert_eq!(member.data(data).unwrap(), &b"even"[..]);
-
- assert!(members.next().is_none());
- }
-
- #[test]
- fn bsd_names() {
- let data = b"\
- !<arch>\n\
- 0123456789abcde 0 0 0 644 3 `\n\
- odd\n\
- #1/16 0 0 0 644 20 `\n\
- 0123456789abcdefeven";
- let data = &data[..];
- let archive = ArchiveFile::parse(data).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::Unknown);
- let mut members = archive.members();
-
- let member = members.next().unwrap().unwrap();
- assert_eq!(member.name(), b"0123456789abcde");
- assert_eq!(member.data(data).unwrap(), &b"odd"[..]);
-
- let member = members.next().unwrap().unwrap();
- assert_eq!(member.name(), b"0123456789abcdef");
- assert_eq!(member.data(data).unwrap(), &b"even"[..]);
-
- assert!(members.next().is_none());
- }
-
- #[test]
- fn aix_names() {
- let data = b"\
- <bigaf>\n\
- 396 0 0 \
- 128 262 0 \
- 4 262 0 \
- 1662610370 223 1 644 16 \
- 0123456789abcdef`\nord\n\
- 4 396 128 \
- 1662610374 223 1 644 16 \
- fedcba9876543210`\nrev\n\
- 94 0 262 \
- 0 0 0 0 0 \
- `\n2 128 \
- 262 0123456789abcdef\0fedcba9876543210\0";
- let data = &data[..];
- let archive = ArchiveFile::parse(data).unwrap();
- assert_eq!(archive.kind(), ArchiveKind::AixBig);
- let mut members = archive.members();
-
- let member = members.next().unwrap().unwrap();
- assert_eq!(member.name(), b"0123456789abcdef");
- assert_eq!(member.data(data).unwrap(), &b"ord\n"[..]);
-
- let member = members.next().unwrap().unwrap();
- assert_eq!(member.name(), b"fedcba9876543210");
- assert_eq!(member.data(data).unwrap(), &b"rev\n"[..]);
-
- assert!(members.next().is_none());
- }
-}
diff --git a/vendor/object/src/read/coff/comdat.rs b/vendor/object/src/read/coff/comdat.rs
deleted file mode 100644
index 90c29be..0000000
--- a/vendor/object/src/read/coff/comdat.rs
+++ /dev/null
@@ -1,211 +0,0 @@
-use core::str;
-
-use crate::endian::LittleEndian as LE;
-use crate::pe;
-use crate::read::{
- self, ComdatKind, ObjectComdat, ReadError, ReadRef, Result, SectionIndex, SymbolIndex,
-};
-
-use super::{CoffFile, CoffHeader, ImageSymbol};
-
-/// An iterator for the COMDAT section groups in a [`CoffBigFile`](super::CoffBigFile).
-pub type CoffBigComdatIterator<'data, 'file, R = &'data [u8]> =
- CoffComdatIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>;
-
-/// An iterator for the COMDAT section groups in a [`CoffFile`].
-#[derive(Debug)]
-pub struct CoffComdatIterator<
- 'data,
- 'file,
- R: ReadRef<'data> = &'data [u8],
- Coff: CoffHeader = pe::ImageFileHeader,
-> {
- pub(super) file: &'file CoffFile<'data, R, Coff>,
- pub(super) index: usize,
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator
- for CoffComdatIterator<'data, 'file, R, Coff>
-{
- type Item = CoffComdat<'data, 'file, R, Coff>;
-
- fn next(&mut self) -> Option<Self::Item> {
- loop {
- let index = self.index;
- let symbol = self.file.common.symbols.symbol(index).ok()?;
- self.index += 1 + symbol.number_of_aux_symbols() as usize;
- if let Some(comdat) = CoffComdat::parse(self.file, symbol, index) {
- return Some(comdat);
- }
- }
- }
-}
-
-/// A COMDAT section group in a [`CoffBigFile`](super::CoffBigFile).
-///
-/// Most functionality is provided by the [`ObjectComdat`] trait implementation.
-pub type CoffBigComdat<'data, 'file, R = &'data [u8]> =
- CoffComdat<'data, 'file, R, pe::AnonObjectHeaderBigobj>;
-
-/// A COMDAT section group in a [`CoffFile`].
-///
-/// Most functionality is provided by the [`ObjectComdat`] trait implementation.
-#[derive(Debug)]
-pub struct CoffComdat<
- 'data,
- 'file,
- R: ReadRef<'data> = &'data [u8],
- Coff: CoffHeader = pe::ImageFileHeader,
-> {
- file: &'file CoffFile<'data, R, Coff>,
- symbol_index: SymbolIndex,
- symbol: &'data Coff::ImageSymbol,
- selection: u8,
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> CoffComdat<'data, 'file, R, Coff> {
- fn parse(
- file: &'file CoffFile<'data, R, Coff>,
- section_symbol: &'data Coff::ImageSymbol,
- index: usize,
- ) -> Option<CoffComdat<'data, 'file, R, Coff>> {
- // Must be a section symbol.
- if !section_symbol.has_aux_section() {
- return None;
- }
-
- // Auxiliary record must have a non-associative selection.
- let aux = file.common.symbols.aux_section(index).ok()?;
- let selection = aux.selection;
- if selection == 0 || selection == pe::IMAGE_COMDAT_SELECT_ASSOCIATIVE {
- return None;
- }
-
- // Find the COMDAT symbol.
- let mut symbol_index = index;
- let mut symbol = section_symbol;
- let section_number = section_symbol.section_number();
- loop {
- symbol_index += 1 + symbol.number_of_aux_symbols() as usize;
- symbol = file.common.symbols.symbol(symbol_index).ok()?;
- if section_number == symbol.section_number() {
- break;
- }
- }
-
- Some(CoffComdat {
- file,
- symbol_index: SymbolIndex(symbol_index),
- symbol,
- selection,
- })
- }
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed
- for CoffComdat<'data, 'file, R, Coff>
-{
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectComdat<'data>
- for CoffComdat<'data, 'file, R, Coff>
-{
- type SectionIterator = CoffComdatSectionIterator<'data, 'file, R, Coff>;
-
- #[inline]
- fn kind(&self) -> ComdatKind {
- match self.selection {
- pe::IMAGE_COMDAT_SELECT_NODUPLICATES => ComdatKind::NoDuplicates,
- pe::IMAGE_COMDAT_SELECT_ANY => ComdatKind::Any,
- pe::IMAGE_COMDAT_SELECT_SAME_SIZE => ComdatKind::SameSize,
- pe::IMAGE_COMDAT_SELECT_EXACT_MATCH => ComdatKind::ExactMatch,
- pe::IMAGE_COMDAT_SELECT_LARGEST => ComdatKind::Largest,
- pe::IMAGE_COMDAT_SELECT_NEWEST => ComdatKind::Newest,
- _ => ComdatKind::Unknown,
- }
- }
-
- #[inline]
- fn symbol(&self) -> SymbolIndex {
- self.symbol_index
- }
-
- #[inline]
- fn name_bytes(&self) -> Result<&[u8]> {
- // Find the name of first symbol referring to the section.
- self.symbol.name(self.file.common.symbols.strings())
- }
-
- #[inline]
- fn name(&self) -> Result<&str> {
- let bytes = self.name_bytes()?;
- str::from_utf8(bytes)
- .ok()
- .read_error("Non UTF-8 COFF COMDAT name")
- }
-
- #[inline]
- fn sections(&self) -> Self::SectionIterator {
- CoffComdatSectionIterator {
- file: self.file,
- section_number: self.symbol.section_number(),
- index: 0,
- }
- }
-}
-
-/// An iterator for the sections in a COMDAT section group in a [`CoffBigFile`](super::CoffBigFile).
-pub type CoffBigComdatSectionIterator<'data, 'file, R = &'data [u8]> =
- CoffComdatSectionIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>;
-
-/// An iterator for the sections in a COMDAT section group in a [`CoffFile`].
-#[derive(Debug)]
-pub struct CoffComdatSectionIterator<
- 'data,
- 'file,
- R: ReadRef<'data> = &'data [u8],
- Coff: CoffHeader = pe::ImageFileHeader,
-> {
- file: &'file CoffFile<'data, R, Coff>,
- section_number: i32,
- index: usize,
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator
- for CoffComdatSectionIterator<'data, 'file, R, Coff>
-{
- type Item = SectionIndex;
-
- fn next(&mut self) -> Option<Self::Item> {
- // Find associated COMDAT symbols.
- // TODO: it seems gcc doesn't use associated symbols for this
- loop {
- let index = self.index;
- let symbol = self.file.common.symbols.symbol(index).ok()?;
- self.index += 1 + symbol.number_of_aux_symbols() as usize;
-
- // Must be a section symbol.
- if !symbol.has_aux_section() {
- continue;
- }
-
- let section_number = symbol.section_number();
-
- let aux = self.file.common.symbols.aux_section(index).ok()?;
- if aux.selection == pe::IMAGE_COMDAT_SELECT_ASSOCIATIVE {
- let number = if Coff::is_type_bigobj() {
- u32::from(aux.number.get(LE)) | (u32::from(aux.high_number.get(LE)) << 16)
- } else {
- u32::from(aux.number.get(LE))
- };
- if number as i32 == self.section_number {
- return Some(SectionIndex(section_number as usize));
- }
- } else if aux.selection != 0 {
- if section_number == self.section_number {
- return Some(SectionIndex(section_number as usize));
- }
- }
- }
- }
-}
diff --git a/vendor/object/src/read/coff/file.rs b/vendor/object/src/read/coff/file.rs
deleted file mode 100644
index 40b9e70..0000000
--- a/vendor/object/src/read/coff/file.rs
+++ /dev/null
@@ -1,381 +0,0 @@
-use alloc::vec::Vec;
-use core::fmt::Debug;
-
-use crate::read::{
- self, Architecture, Export, FileFlags, Import, NoDynamicRelocationIterator, Object, ObjectKind,
- ObjectSection, ReadError, ReadRef, Result, SectionIndex, SubArchitecture, SymbolIndex,
-};
-use crate::{pe, LittleEndian as LE, Pod};
-
-use super::{
- CoffComdat, CoffComdatIterator, CoffSection, CoffSectionIterator, CoffSegment,
- CoffSegmentIterator, CoffSymbol, CoffSymbolIterator, CoffSymbolTable, ImageSymbol,
- SectionTable, SymbolTable,
-};
-
-/// The common parts of `PeFile` and `CoffFile`.
-#[derive(Debug)]
-pub(crate) struct CoffCommon<'data, R: ReadRef<'data>, Coff: CoffHeader = pe::ImageFileHeader> {
- pub(crate) sections: SectionTable<'data>,
- pub(crate) symbols: SymbolTable<'data, R, Coff>,
- pub(crate) image_base: u64,
-}
-
-/// A COFF bigobj object file with 32-bit section numbers.
-///
-/// This is a file that starts with [`pe::AnonObjectHeaderBigobj`], and corresponds
-/// to [`crate::FileKind::CoffBig`].
-///
-/// Most functionality is provided by the [`Object`] trait implementation.
-pub type CoffBigFile<'data, R = &'data [u8]> = CoffFile<'data, R, pe::AnonObjectHeaderBigobj>;
-
-/// A COFF object file.
-///
-/// This is a file that starts with [`pe::ImageFileHeader`], and corresponds
-/// to [`crate::FileKind::Coff`].
-///
-/// Most functionality is provided by the [`Object`] trait implementation.
-#[derive(Debug)]
-pub struct CoffFile<'data, R: ReadRef<'data> = &'data [u8], Coff: CoffHeader = pe::ImageFileHeader>
-{
- pub(super) header: &'data Coff,
- pub(super) common: CoffCommon<'data, R, Coff>,
- pub(super) data: R,
-}
-
-impl<'data, R: ReadRef<'data>, Coff: CoffHeader> CoffFile<'data, R, Coff> {
- /// Parse the raw COFF file data.
- pub fn parse(data: R) -> Result<Self> {
- let mut offset = 0;
- let header = Coff::parse(data, &mut offset)?;
- let sections = header.sections(data, offset)?;
- let symbols = header.symbols(data)?;
-
- Ok(CoffFile {
- header,
- common: CoffCommon {
- sections,
- symbols,
- image_base: 0,
- },
- data,
- })
- }
-}
-
-impl<'data, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed
- for CoffFile<'data, R, Coff>
-{
-}
-
-impl<'data, 'file, R, Coff> Object<'data, 'file> for CoffFile<'data, R, Coff>
-where
- 'data: 'file,
- R: 'file + ReadRef<'data>,
- Coff: CoffHeader,
-{
- type Segment = CoffSegment<'data, 'file, R, Coff>;
- type SegmentIterator = CoffSegmentIterator<'data, 'file, R, Coff>;
- type Section = CoffSection<'data, 'file, R, Coff>;
- type SectionIterator = CoffSectionIterator<'data, 'file, R, Coff>;
- type Comdat = CoffComdat<'data, 'file, R, Coff>;
- type ComdatIterator = CoffComdatIterator<'data, 'file, R, Coff>;
- type Symbol = CoffSymbol<'data, 'file, R, Coff>;
- type SymbolIterator = CoffSymbolIterator<'data, 'file, R, Coff>;
- type SymbolTable = CoffSymbolTable<'data, 'file, R, Coff>;
- type DynamicRelocationIterator = NoDynamicRelocationIterator;
-
- fn architecture(&self) -> Architecture {
- match self.header.machine() {
- pe::IMAGE_FILE_MACHINE_ARMNT => Architecture::Arm,
- pe::IMAGE_FILE_MACHINE_ARM64 | pe::IMAGE_FILE_MACHINE_ARM64EC => Architecture::Aarch64,
- pe::IMAGE_FILE_MACHINE_I386 => Architecture::I386,
- pe::IMAGE_FILE_MACHINE_AMD64 => Architecture::X86_64,
- _ => Architecture::Unknown,
- }
- }
-
- fn sub_architecture(&self) -> Option<SubArchitecture> {
- match self.header.machine() {
- pe::IMAGE_FILE_MACHINE_ARM64EC => Some(SubArchitecture::Arm64EC),
- _ => None,
- }
- }
-
- #[inline]
- fn is_little_endian(&self) -> bool {
- true
- }
-
- #[inline]
- fn is_64(&self) -> bool {
- // Windows COFF is always 32-bit, even for 64-bit architectures. This could be confusing.
- false
- }
-
- fn kind(&self) -> ObjectKind {
- ObjectKind::Relocatable
- }
-
- fn segments(&'file self) -> CoffSegmentIterator<'data, 'file, R, Coff> {
- CoffSegmentIterator {
- file: self,
- iter: self.common.sections.iter(),
- }
- }
-
- fn section_by_name_bytes(
- &'file self,
- section_name: &[u8],
- ) -> Option<CoffSection<'data, 'file, R, Coff>> {
- self.sections()
- .find(|section| section.name_bytes() == Ok(section_name))
- }
-
- fn section_by_index(
- &'file self,
- index: SectionIndex,
- ) -> Result<CoffSection<'data, 'file, R, Coff>> {
- let section = self.common.sections.section(index.0)?;
- Ok(CoffSection {
- file: self,
- index,
- section,
- })
- }
-
- fn sections(&'file self) -> CoffSectionIterator<'data, 'file, R, Coff> {
- CoffSectionIterator {
- file: self,
- iter: self.common.sections.iter().enumerate(),
- }
- }
-
- fn comdats(&'file self) -> CoffComdatIterator<'data, 'file, R, Coff> {
- CoffComdatIterator {
- file: self,
- index: 0,
- }
- }
-
- fn symbol_by_index(
- &'file self,
- index: SymbolIndex,
- ) -> Result<CoffSymbol<'data, 'file, R, Coff>> {
- let symbol = self.common.symbols.symbol(index.0)?;
- Ok(CoffSymbol {
- file: &self.common,
- index,
- symbol,
- })
- }
-
- fn symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R, Coff> {
- CoffSymbolIterator {
- file: &self.common,
- index: 0,
- }
- }
-
- #[inline]
- fn symbol_table(&'file self) -> Option<CoffSymbolTable<'data, 'file, R, Coff>> {
- Some(CoffSymbolTable { file: &self.common })
- }
-
- fn dynamic_symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R, Coff> {
- CoffSymbolIterator {
- file: &self.common,
- // Hack: don't return any.
- index: self.common.symbols.len(),
- }
- }
-
- #[inline]
- fn dynamic_symbol_table(&'file self) -> Option<CoffSymbolTable<'data, 'file, R, Coff>> {
- None
- }
-
- #[inline]
- fn dynamic_relocations(&'file self) -> Option<NoDynamicRelocationIterator> {
- None
- }
-
- #[inline]
- fn imports(&self) -> Result<Vec<Import<'data>>> {
- // TODO: this could return undefined symbols, but not needed yet.
- Ok(Vec::new())
- }
-
- #[inline]
- fn exports(&self) -> Result<Vec<Export<'data>>> {
- // TODO: this could return global symbols, but not needed yet.
- Ok(Vec::new())
- }
-
- fn has_debug_symbols(&self) -> bool {
- self.section_by_name(".debug_info").is_some()
- }
-
- fn relative_address_base(&self) -> u64 {
- 0
- }
-
- #[inline]
- fn entry(&self) -> u64 {
- 0
- }
-
- fn flags(&self) -> FileFlags {
- FileFlags::Coff {
- characteristics: self.header.characteristics(),
- }
- }
-}
-
-/// Read the `class_id` field from a [`pe::AnonObjectHeader`].
-///
-/// This can be used to determine the format of the header.
-pub fn anon_object_class_id<'data, R: ReadRef<'data>>(data: R) -> Result<pe::ClsId> {
- let header = data
- .read_at::<pe::AnonObjectHeader>(0)
- .read_error("Invalid anon object header size or alignment")?;
- Ok(header.class_id)
-}
-
-/// A trait for generic access to [`pe::ImageFileHeader`] and [`pe::AnonObjectHeaderBigobj`].
-#[allow(missing_docs)]
-pub trait CoffHeader: Debug + Pod {
- type ImageSymbol: ImageSymbol;
- type ImageSymbolBytes: Debug + Pod;
-
- /// Return true if this type is [`pe::AnonObjectHeaderBigobj`].
- ///
- /// This is a property of the type, not a value in the header data.
- fn is_type_bigobj() -> bool;
-
- fn machine(&self) -> u16;
- fn number_of_sections(&self) -> u32;
- fn pointer_to_symbol_table(&self) -> u32;
- fn number_of_symbols(&self) -> u32;
- fn characteristics(&self) -> u16;
-
- /// Read the file header.
- ///
- /// `data` must be the entire file data.
- /// `offset` must be the file header offset. It is updated to point after the optional header,
- /// which is where the section headers are located.
- fn parse<'data, R: ReadRef<'data>>(data: R, offset: &mut u64) -> read::Result<&'data Self>;
-
- /// Read the section table.
- ///
- /// `data` must be the entire file data.
- /// `offset` must be after the optional file header.
- #[inline]
- fn sections<'data, R: ReadRef<'data>>(
- &self,
- data: R,
- offset: u64,
- ) -> read::Result<SectionTable<'data>> {
- SectionTable::parse(self, data, offset)
- }
-
- /// Read the symbol table and string table.
- ///
- /// `data` must be the entire file data.
- #[inline]
- fn symbols<'data, R: ReadRef<'data>>(
- &self,
- data: R,
- ) -> read::Result<SymbolTable<'data, R, Self>> {
- SymbolTable::parse(self, data)
- }
-}
-
-impl CoffHeader for pe::ImageFileHeader {
- type ImageSymbol = pe::ImageSymbol;
- type ImageSymbolBytes = pe::ImageSymbolBytes;
-
- fn is_type_bigobj() -> bool {
- false
- }
-
- fn machine(&self) -> u16 {
- self.machine.get(LE)
- }
-
- fn number_of_sections(&self) -> u32 {
- self.number_of_sections.get(LE).into()
- }
-
- fn pointer_to_symbol_table(&self) -> u32 {
- self.pointer_to_symbol_table.get(LE)
- }
-
- fn number_of_symbols(&self) -> u32 {
- self.number_of_symbols.get(LE)
- }
-
- fn characteristics(&self) -> u16 {
- self.characteristics.get(LE)
- }
-
- fn parse<'data, R: ReadRef<'data>>(data: R, offset: &mut u64) -> read::Result<&'data Self> {
- let header = data
- .read::<pe::ImageFileHeader>(offset)
- .read_error("Invalid COFF file header size or alignment")?;
-
- // Skip over the optional header.
- *offset = offset
- .checked_add(header.size_of_optional_header.get(LE).into())
- .read_error("Invalid COFF optional header size")?;
-
- // TODO: maybe validate that the machine is known?
- Ok(header)
- }
-}
-
-impl CoffHeader for pe::AnonObjectHeaderBigobj {
- type ImageSymbol = pe::ImageSymbolEx;
- type ImageSymbolBytes = pe::ImageSymbolExBytes;
-
- fn is_type_bigobj() -> bool {
- true
- }
-
- fn machine(&self) -> u16 {
- self.machine.get(LE)
- }
-
- fn number_of_sections(&self) -> u32 {
- self.number_of_sections.get(LE)
- }
-
- fn pointer_to_symbol_table(&self) -> u32 {
- self.pointer_to_symbol_table.get(LE)
- }
-
- fn number_of_symbols(&self) -> u32 {
- self.number_of_symbols.get(LE)
- }
-
- fn characteristics(&self) -> u16 {
- 0
- }
-
- fn parse<'data, R: ReadRef<'data>>(data: R, offset: &mut u64) -> read::Result<&'data Self> {
- let header = data
- .read::<pe::AnonObjectHeaderBigobj>(offset)
- .read_error("Invalid COFF bigobj file header size or alignment")?;
-
- if header.sig1.get(LE) != pe::IMAGE_FILE_MACHINE_UNKNOWN
- || header.sig2.get(LE) != 0xffff
- || header.version.get(LE) < 2
- || header.class_id != pe::ANON_OBJECT_HEADER_BIGOBJ_CLASS_ID
- {
- return Err(read::Error("Invalid COFF bigobj header values"));
- }
-
- // TODO: maybe validate that the machine is known?
- Ok(header)
- }
-}
diff --git a/vendor/object/src/read/coff/import.rs b/vendor/object/src/read/coff/import.rs
deleted file mode 100644
index a296ac3..0000000
--- a/vendor/object/src/read/coff/import.rs
+++ /dev/null
@@ -1,220 +0,0 @@
-//! Support for reading short import files.
-//!
-//! These are used by some Windows linkers as a more compact way to describe
-//! dynamically imported symbols.
-
-use crate::read::{Architecture, Error, ReadError, ReadRef, Result};
-use crate::{pe, ByteString, Bytes, LittleEndian as LE, SubArchitecture};
-
-/// A Windows short form description of a symbol to import.
-///
-/// Used in Windows import libraries to provide a mapping from
-/// a symbol name to a DLL export. This is not an object file.
-///
-/// This is a file that starts with [`pe::ImportObjectHeader`], and corresponds
-/// to [`crate::FileKind::CoffImport`].
-#[derive(Debug, Clone)]
-pub struct ImportFile<'data> {
- header: &'data pe::ImportObjectHeader,
- kind: ImportType,
- dll: ByteString<'data>,
- symbol: ByteString<'data>,
- import: Option<ByteString<'data>>,
-}
-
-impl<'data> ImportFile<'data> {
- /// Parse it.
- pub fn parse<R: ReadRef<'data>>(data: R) -> Result<Self> {
- let mut offset = 0;
- let header = pe::ImportObjectHeader::parse(data, &mut offset)?;
- let data = header.parse_data(data, &mut offset)?;
-
- // Unmangles a name by removing a `?`, `@` or `_` prefix.
- fn strip_prefix(s: &[u8]) -> &[u8] {
- match s.split_first() {
- Some((b, rest)) if [b'?', b'@', b'_'].contains(b) => rest,
- _ => s,
- }
- }
- Ok(Self {
- header,
- dll: data.dll,
- symbol: data.symbol,
- kind: match header.import_type() {
- pe::IMPORT_OBJECT_CODE => ImportType::Code,
- pe::IMPORT_OBJECT_DATA => ImportType::Data,
- pe::IMPORT_OBJECT_CONST => ImportType::Const,
- _ => return Err(Error("Invalid COFF import library import type")),
- },
- import: match header.name_type() {
- pe::IMPORT_OBJECT_ORDINAL => None,
- pe::IMPORT_OBJECT_NAME => Some(data.symbol()),
- pe::IMPORT_OBJECT_NAME_NO_PREFIX => Some(strip_prefix(data.symbol())),
- pe::IMPORT_OBJECT_NAME_UNDECORATE => Some(
- strip_prefix(data.symbol())
- .split(|&b| b == b'@')
- .next()
- .unwrap(),
- ),
- pe::IMPORT_OBJECT_NAME_EXPORTAS => data.export(),
- _ => return Err(Error("Unknown COFF import library name type")),
- }
- .map(ByteString),
- })
- }
-
- /// Get the machine type.
- pub fn architecture(&self) -> Architecture {
- match self.header.machine.get(LE) {
- pe::IMAGE_FILE_MACHINE_ARMNT => Architecture::Arm,
- pe::IMAGE_FILE_MACHINE_ARM64 | pe::IMAGE_FILE_MACHINE_ARM64EC => Architecture::Aarch64,
- pe::IMAGE_FILE_MACHINE_I386 => Architecture::I386,
- pe::IMAGE_FILE_MACHINE_AMD64 => Architecture::X86_64,
- _ => Architecture::Unknown,
- }
- }
-
- /// Get the sub machine type, if available.
- pub fn sub_architecture(&self) -> Option<SubArchitecture> {
- match self.header.machine.get(LE) {
- pe::IMAGE_FILE_MACHINE_ARM64EC => Some(SubArchitecture::Arm64EC),
- _ => None,
- }
- }
-
- /// The public symbol name.
- pub fn symbol(&self) -> &'data [u8] {
- self.symbol.0
- }
-
- /// The name of the DLL to import the symbol from.
- pub fn dll(&self) -> &'data [u8] {
- self.dll.0
- }
-
- /// The name exported from the DLL.
- pub fn import(&self) -> ImportName<'data> {
- match self.import {
- Some(name) => ImportName::Name(name.0),
- None => ImportName::Ordinal(self.header.ordinal_or_hint.get(LE)),
- }
- }
-
- /// The type of import. Usually either a function or data.
- pub fn import_type(&self) -> ImportType {
- self.kind
- }
-}
-
-/// The name or ordinal to import from a DLL.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum ImportName<'data> {
- /// Import by ordinal. Ordinarily this is a 1-based index.
- Ordinal(u16),
- /// Import by name.
- Name(&'data [u8]),
-}
-
-/// The kind of import symbol.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub enum ImportType {
- /// An executable code symbol.
- Code,
- /// A data symbol.
- Data,
- /// A constant value.
- Const,
-}
-
-impl pe::ImportObjectHeader {
- /// Read the short import header.
- ///
- /// Also checks that the signature and version are valid.
- /// Directly following this header will be the string data.
- pub fn parse<'data, R: ReadRef<'data>>(data: R, offset: &mut u64) -> Result<&'data Self> {
- let header = data
- .read::<pe::ImportObjectHeader>(offset)
- .read_error("Invalid COFF import library header size")?;
- if header.sig1.get(LE) != 0 || header.sig2.get(LE) != pe::IMPORT_OBJECT_HDR_SIG2 {
- Err(Error("Invalid COFF import library header"))
- } else if header.version.get(LE) != 0 {
- Err(Error("Unknown COFF import library header version"))
- } else {
- Ok(header)
- }
- }
-
- /// Parse the data following the header.
- pub fn parse_data<'data, R: ReadRef<'data>>(
- &self,
- data: R,
- offset: &mut u64,
- ) -> Result<ImportObjectData<'data>> {
- let mut data = Bytes(
- data.read_bytes(offset, u64::from(self.size_of_data.get(LE)))
- .read_error("Invalid COFF import library data size")?,
- );
- let symbol = data
- .read_string()
- .map(ByteString)
- .read_error("Could not read COFF import library symbol name")?;
- let dll = data
- .read_string()
- .map(ByteString)
- .read_error("Could not read COFF import library DLL name")?;
- let export = if self.name_type() == pe::IMPORT_OBJECT_NAME_EXPORTAS {
- data.read_string()
- .map(ByteString)
- .map(Some)
- .read_error("Could not read COFF import library export name")?
- } else {
- None
- };
- Ok(ImportObjectData {
- symbol,
- dll,
- export,
- })
- }
-
- /// The type of import.
- ///
- /// This is one of the `IMPORT_OBJECT_*` constants.
- pub fn import_type(&self) -> u16 {
- self.name_type.get(LE) & pe::IMPORT_OBJECT_TYPE_MASK
- }
-
- /// The type of import name.
- ///
- /// This is one of the `IMPORT_OBJECT_*` constants.
- pub fn name_type(&self) -> u16 {
- (self.name_type.get(LE) >> pe::IMPORT_OBJECT_NAME_SHIFT) & pe::IMPORT_OBJECT_NAME_MASK
- }
-}
-
-/// The data following [`pe::ImportObjectHeader`].
-#[derive(Debug, Clone)]
-pub struct ImportObjectData<'data> {
- symbol: ByteString<'data>,
- dll: ByteString<'data>,
- export: Option<ByteString<'data>>,
-}
-
-impl<'data> ImportObjectData<'data> {
- /// The public symbol name.
- pub fn symbol(&self) -> &'data [u8] {
- self.symbol.0
- }
-
- /// The name of the DLL to import the symbol from.
- pub fn dll(&self) -> &'data [u8] {
- self.dll.0
- }
-
- /// The name exported from the DLL.
- ///
- /// This is only set if the name is not derived from the symbol name.
- pub fn export(&self) -> Option<&'data [u8]> {
- self.export.map(|export| export.0)
- }
-}
diff --git a/vendor/object/src/read/coff/mod.rs b/vendor/object/src/read/coff/mod.rs
deleted file mode 100644
index de397da..0000000
--- a/vendor/object/src/read/coff/mod.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-//! Support for reading Windows COFF files.
-//!
-//! Traits are used to abstract over the difference between COFF object files
-//! and COFF bigobj files. The primary trait for this is [`CoffHeader`].
-//!
-//! ## High level API
-//!
-//! [`CoffFile`] implements the [`Object`](crate::read::Object) trait for
-//! COFF files. [`CoffFile`] is parameterised by [`CoffHeader`].
-//! The default parameter allows reading regular COFF object files,
-//! while the type alias [`CoffBigFile`] allows reading COFF bigobj files.
-//!
-//! [`ImportFile`] allows reading COFF short imports that are used in import
-//! libraries. Currently these are not integrated with the unified read API.
-//!
-//! ## Low level API
-//!
-//! The [`CoffHeader`] trait can be directly used to parse both COFF
-//! object files (which start with [`pe::ImageFileHeader`]) and COFF bigobj
-//! files (which start with [`pe::AnonObjectHeaderBigobj`]).
-//!
-//! ### Example for low level API
-//! ```no_run
-//! use object::pe;
-//! use object::read::coff::{CoffHeader, ImageSymbol as _};
-//! use std::error::Error;
-//! use std::fs;
-//!
-//! /// Reads a file and displays the name of each section and symbol.
-//! fn main() -> Result<(), Box<dyn Error>> {
-//! # #[cfg(feature = "std")] {
-//! let data = fs::read("path/to/binary")?;
-//! let mut offset = 0;
-//! let header = pe::ImageFileHeader::parse(&*data, &mut offset)?;
-//! let sections = header.sections(&*data, offset)?;
-//! let symbols = header.symbols(&*data)?;
-//! for section in sections.iter() {
-//! println!("{}", String::from_utf8_lossy(section.name(symbols.strings())?));
-//! }
-//! for (_index, symbol) in symbols.iter() {
-//! println!("{}", String::from_utf8_lossy(symbol.name(symbols.strings())?));
-//! }
-//! # }
-//! Ok(())
-//! }
-//! ```
-#[cfg(doc)]
-use crate::pe;
-
-mod file;
-pub use file::*;
-
-mod section;
-pub use section::*;
-
-mod symbol;
-pub use symbol::*;
-
-mod relocation;
-pub use relocation::*;
-
-mod comdat;
-pub use comdat::*;
-
-mod import;
-pub use import::*;
diff --git a/vendor/object/src/read/coff/relocation.rs b/vendor/object/src/read/coff/relocation.rs
deleted file mode 100644
index e990944..0000000
--- a/vendor/object/src/read/coff/relocation.rs
+++ /dev/null
@@ -1,106 +0,0 @@
-use alloc::fmt;
-use core::slice;
-
-use crate::endian::LittleEndian as LE;
-use crate::pe;
-use crate::read::{
- ReadRef, Relocation, RelocationEncoding, RelocationKind, RelocationTarget, SymbolIndex,
-};
-
-use super::{CoffFile, CoffHeader};
-
-/// An iterator for the relocations in a [`CoffBigSection`](super::CoffBigSection).
-pub type CoffBigRelocationIterator<'data, 'file, R = &'data [u8]> =
- CoffRelocationIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>;
-
-/// An iterator for the relocations in a [`CoffSection`](super::CoffSection).
-pub struct CoffRelocationIterator<
- 'data,
- 'file,
- R: ReadRef<'data> = &'data [u8],
- Coff: CoffHeader = pe::ImageFileHeader,
-> {
- pub(super) file: &'file CoffFile<'data, R, Coff>,
- pub(super) iter: slice::Iter<'data, pe::ImageRelocation>,
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator
- for CoffRelocationIterator<'data, 'file, R, Coff>
-{
- type Item = (u64, Relocation);
-
- fn next(&mut self) -> Option<Self::Item> {
- self.iter.next().map(|relocation| {
- let (kind, size, addend) = match self.file.header.machine() {
- pe::IMAGE_FILE_MACHINE_ARMNT => match relocation.typ.get(LE) {
- pe::IMAGE_REL_ARM_ADDR32 => (RelocationKind::Absolute, 32, 0),
- pe::IMAGE_REL_ARM_ADDR32NB => (RelocationKind::ImageOffset, 32, 0),
- pe::IMAGE_REL_ARM_REL32 => (RelocationKind::Relative, 32, -4),
- pe::IMAGE_REL_ARM_SECTION => (RelocationKind::SectionIndex, 16, 0),
- pe::IMAGE_REL_ARM_SECREL => (RelocationKind::SectionOffset, 32, 0),
- typ => (RelocationKind::Coff(typ), 0, 0),
- },
- pe::IMAGE_FILE_MACHINE_ARM64 | pe::IMAGE_FILE_MACHINE_ARM64EC => {
- match relocation.typ.get(LE) {
- pe::IMAGE_REL_ARM64_ADDR32 => (RelocationKind::Absolute, 32, 0),
- pe::IMAGE_REL_ARM64_ADDR32NB => (RelocationKind::ImageOffset, 32, 0),
- pe::IMAGE_REL_ARM64_SECREL => (RelocationKind::SectionOffset, 32, 0),
- pe::IMAGE_REL_ARM64_SECTION => (RelocationKind::SectionIndex, 16, 0),
- pe::IMAGE_REL_ARM64_ADDR64 => (RelocationKind::Absolute, 64, 0),
- pe::IMAGE_REL_ARM64_REL32 => (RelocationKind::Relative, 32, -4),
- typ => (RelocationKind::Coff(typ), 0, 0),
- }
- }
- pe::IMAGE_FILE_MACHINE_I386 => match relocation.typ.get(LE) {
- pe::IMAGE_REL_I386_DIR16 => (RelocationKind::Absolute, 16, 0),
- pe::IMAGE_REL_I386_REL16 => (RelocationKind::Relative, 16, 0),
- pe::IMAGE_REL_I386_DIR32 => (RelocationKind::Absolute, 32, 0),
- pe::IMAGE_REL_I386_DIR32NB => (RelocationKind::ImageOffset, 32, 0),
- pe::IMAGE_REL_I386_SECTION => (RelocationKind::SectionIndex, 16, 0),
- pe::IMAGE_REL_I386_SECREL => (RelocationKind::SectionOffset, 32, 0),
- pe::IMAGE_REL_I386_SECREL7 => (RelocationKind::SectionOffset, 7, 0),
- pe::IMAGE_REL_I386_REL32 => (RelocationKind::Relative, 32, -4),
- typ => (RelocationKind::Coff(typ), 0, 0),
- },
- pe::IMAGE_FILE_MACHINE_AMD64 => match relocation.typ.get(LE) {
- pe::IMAGE_REL_AMD64_ADDR64 => (RelocationKind::Absolute, 64, 0),
- pe::IMAGE_REL_AMD64_ADDR32 => (RelocationKind::Absolute, 32, 0),
- pe::IMAGE_REL_AMD64_ADDR32NB => (RelocationKind::ImageOffset, 32, 0),
- pe::IMAGE_REL_AMD64_REL32 => (RelocationKind::Relative, 32, -4),
- pe::IMAGE_REL_AMD64_REL32_1 => (RelocationKind::Relative, 32, -5),
- pe::IMAGE_REL_AMD64_REL32_2 => (RelocationKind::Relative, 32, -6),
- pe::IMAGE_REL_AMD64_REL32_3 => (RelocationKind::Relative, 32, -7),
- pe::IMAGE_REL_AMD64_REL32_4 => (RelocationKind::Relative, 32, -8),
- pe::IMAGE_REL_AMD64_REL32_5 => (RelocationKind::Relative, 32, -9),
- pe::IMAGE_REL_AMD64_SECTION => (RelocationKind::SectionIndex, 16, 0),
- pe::IMAGE_REL_AMD64_SECREL => (RelocationKind::SectionOffset, 32, 0),
- pe::IMAGE_REL_AMD64_SECREL7 => (RelocationKind::SectionOffset, 7, 0),
- typ => (RelocationKind::Coff(typ), 0, 0),
- },
- _ => (RelocationKind::Coff(relocation.typ.get(LE)), 0, 0),
- };
- let target = RelocationTarget::Symbol(SymbolIndex(
- relocation.symbol_table_index.get(LE) as usize,
- ));
- (
- u64::from(relocation.virtual_address.get(LE)),
- Relocation {
- kind,
- encoding: RelocationEncoding::Generic,
- size,
- target,
- addend,
- implicit_addend: true,
- },
- )
- })
- }
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> fmt::Debug
- for CoffRelocationIterator<'data, 'file, R, Coff>
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("CoffRelocationIterator").finish()
- }
-}
diff --git a/vendor/object/src/read/coff/section.rs b/vendor/object/src/read/coff/section.rs
deleted file mode 100644
index 84a3fa9..0000000
--- a/vendor/object/src/read/coff/section.rs
+++ /dev/null
@@ -1,585 +0,0 @@
-use core::convert::TryFrom;
-use core::{iter, result, slice, str};
-
-use crate::endian::LittleEndian as LE;
-use crate::pe;
-use crate::read::util::StringTable;
-use crate::read::{
- self, CompressedData, CompressedFileRange, Error, ObjectSection, ObjectSegment, ReadError,
- ReadRef, Result, SectionFlags, SectionIndex, SectionKind, SegmentFlags,
-};
-
-use super::{CoffFile, CoffHeader, CoffRelocationIterator};
-
-/// The table of section headers in a COFF or PE file.
-///
-/// Returned by [`CoffHeader::sections`] and
-/// [`ImageNtHeaders::sections`](crate::read::pe::ImageNtHeaders::sections).
-#[derive(Debug, Default, Clone, Copy)]
-pub struct SectionTable<'data> {
- sections: &'data [pe::ImageSectionHeader],
-}
-
-impl<'data> SectionTable<'data> {
- /// Parse the section table.
- ///
- /// `data` must be the entire file data.
- /// `offset` must be after the optional file header.
- pub fn parse<Coff: CoffHeader, R: ReadRef<'data>>(
- header: &Coff,
- data: R,
- offset: u64,
- ) -> Result<Self> {
- let sections = data
- .read_slice_at(offset, header.number_of_sections() as usize)
- .read_error("Invalid COFF/PE section headers")?;
- Ok(SectionTable { sections })
- }
-
- /// Iterate over the section headers.
- ///
- /// Warning: sections indices start at 1.
- #[inline]
- pub fn iter(&self) -> slice::Iter<'data, pe::ImageSectionHeader> {
- self.sections.iter()
- }
-
- /// Return true if the section table is empty.
- #[inline]
- pub fn is_empty(&self) -> bool {
- self.sections.is_empty()
- }
-
- /// The number of section headers.
- #[inline]
- pub fn len(&self) -> usize {
- self.sections.len()
- }
-
- /// Return the section header at the given index.
- ///
- /// The index is 1-based.
- pub fn section(&self, index: usize) -> read::Result<&'data pe::ImageSectionHeader> {
- self.sections
- .get(index.wrapping_sub(1))
- .read_error("Invalid COFF/PE section index")
- }
-
- /// Return the section header with the given name.
- ///
- /// The returned index is 1-based.
- ///
- /// Ignores sections with invalid names.
- pub fn section_by_name<R: ReadRef<'data>>(
- &self,
- strings: StringTable<'data, R>,
- name: &[u8],
- ) -> Option<(usize, &'data pe::ImageSectionHeader)> {
- self.sections
- .iter()
- .enumerate()
- .find(|(_, section)| section.name(strings) == Ok(name))
- .map(|(index, section)| (index + 1, section))
- }
-
- /// Compute the maximum file offset used by sections.
- ///
- /// This will usually match the end of file, unless the PE file has a
- /// [data overlay](https://security.stackexchange.com/questions/77336/how-is-the-file-overlay-read-by-an-exe-virus)
- pub fn max_section_file_offset(&self) -> u64 {
- let mut max = 0;
- for section in self.iter() {
- match (section.pointer_to_raw_data.get(LE) as u64)
- .checked_add(section.size_of_raw_data.get(LE) as u64)
- {
- None => {
- // This cannot happen, we're suming two u32 into a u64
- continue;
- }
- Some(end_of_section) => {
- if end_of_section > max {
- max = end_of_section;
- }
- }
- }
- }
- max
- }
-}
-
-/// An iterator for the loadable sections in a [`CoffBigFile`](super::CoffBigFile).
-pub type CoffBigSegmentIterator<'data, 'file, R = &'data [u8]> =
- CoffSegmentIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>;
-
-/// An iterator for the loadable sections in a [`CoffFile`].
-#[derive(Debug)]
-pub struct CoffSegmentIterator<
- 'data,
- 'file,
- R: ReadRef<'data> = &'data [u8],
- Coff: CoffHeader = pe::ImageFileHeader,
-> {
- pub(super) file: &'file CoffFile<'data, R, Coff>,
- pub(super) iter: slice::Iter<'data, pe::ImageSectionHeader>,
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator
- for CoffSegmentIterator<'data, 'file, R, Coff>
-{
- type Item = CoffSegment<'data, 'file, R, Coff>;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.iter.next().map(|section| CoffSegment {
- file: self.file,
- section,
- })
- }
-}
-
-/// A loadable section in a [`CoffBigFile`](super::CoffBigFile).
-///
-/// Most functionality is provided by the [`ObjectSegment`] trait implementation.
-pub type CoffBigSegment<'data, 'file, R = &'data [u8]> =
- CoffSegment<'data, 'file, R, pe::AnonObjectHeaderBigobj>;
-
-/// A loadable section in a [`CoffFile`].
-///
-/// Most functionality is provided by the [`ObjectSegment`] trait implementation.
-#[derive(Debug)]
-pub struct CoffSegment<
- 'data,
- 'file,
- R: ReadRef<'data> = &'data [u8],
- Coff: CoffHeader = pe::ImageFileHeader,
-> {
- pub(super) file: &'file CoffFile<'data, R, Coff>,
- pub(super) section: &'data pe::ImageSectionHeader,
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> CoffSegment<'data, 'file, R, Coff> {
- fn bytes(&self) -> Result<&'data [u8]> {
- self.section
- .coff_data(self.file.data)
- .read_error("Invalid COFF section offset or size")
- }
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed
- for CoffSegment<'data, 'file, R, Coff>
-{
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSegment<'data>
- for CoffSegment<'data, 'file, R, Coff>
-{
- #[inline]
- fn address(&self) -> u64 {
- u64::from(self.section.virtual_address.get(LE))
- }
-
- #[inline]
- fn size(&self) -> u64 {
- u64::from(self.section.virtual_size.get(LE))
- }
-
- #[inline]
- fn align(&self) -> u64 {
- self.section.coff_alignment()
- }
-
- #[inline]
- fn file_range(&self) -> (u64, u64) {
- let (offset, size) = self.section.coff_file_range().unwrap_or((0, 0));
- (u64::from(offset), u64::from(size))
- }
-
- fn data(&self) -> Result<&'data [u8]> {
- self.bytes()
- }
-
- fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> {
- Ok(read::util::data_range(
- self.bytes()?,
- self.address(),
- address,
- size,
- ))
- }
-
- #[inline]
- fn name_bytes(&self) -> Result<Option<&[u8]>> {
- self.section
- .name(self.file.common.symbols.strings())
- .map(Some)
- }
-
- #[inline]
- fn name(&self) -> Result<Option<&str>> {
- let name = self.section.name(self.file.common.symbols.strings())?;
- str::from_utf8(name)
- .ok()
- .read_error("Non UTF-8 COFF section name")
- .map(Some)
- }
-
- #[inline]
- fn flags(&self) -> SegmentFlags {
- let characteristics = self.section.characteristics.get(LE);
- SegmentFlags::Coff { characteristics }
- }
-}
-
-/// An iterator for the sections in a [`CoffBigFile`](super::CoffBigFile).
-pub type CoffBigSectionIterator<'data, 'file, R = &'data [u8]> =
- CoffSectionIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>;
-
-/// An iterator for the sections in a [`CoffFile`].
-#[derive(Debug)]
-pub struct CoffSectionIterator<
- 'data,
- 'file,
- R: ReadRef<'data> = &'data [u8],
- Coff: CoffHeader = pe::ImageFileHeader,
-> {
- pub(super) file: &'file CoffFile<'data, R, Coff>,
- pub(super) iter: iter::Enumerate<slice::Iter<'data, pe::ImageSectionHeader>>,
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator
- for CoffSectionIterator<'data, 'file, R, Coff>
-{
- type Item = CoffSection<'data, 'file, R, Coff>;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.iter.next().map(|(index, section)| CoffSection {
- file: self.file,
- index: SectionIndex(index + 1),
- section,
- })
- }
-}
-
-/// A section in a [`CoffBigFile`](super::CoffBigFile).
-///
-/// Most functionality is provided by the [`ObjectSection`] trait implementation.
-pub type CoffBigSection<'data, 'file, R = &'data [u8]> =
- CoffSection<'data, 'file, R, pe::AnonObjectHeaderBigobj>;
-
-/// A section in a [`CoffFile`].
-///
-/// Most functionality is provided by the [`ObjectSection`] trait implementation.
-#[derive(Debug)]
-pub struct CoffSection<
- 'data,
- 'file,
- R: ReadRef<'data> = &'data [u8],
- Coff: CoffHeader = pe::ImageFileHeader,
-> {
- pub(super) file: &'file CoffFile<'data, R, Coff>,
- pub(super) index: SectionIndex,
- pub(super) section: &'data pe::ImageSectionHeader,
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> CoffSection<'data, 'file, R, Coff> {
- fn bytes(&self) -> Result<&'data [u8]> {
- self.section
- .coff_data(self.file.data)
- .read_error("Invalid COFF section offset or size")
- }
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed
- for CoffSection<'data, 'file, R, Coff>
-{
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSection<'data>
- for CoffSection<'data, 'file, R, Coff>
-{
- type RelocationIterator = CoffRelocationIterator<'data, 'file, R, Coff>;
-
- #[inline]
- fn index(&self) -> SectionIndex {
- self.index
- }
-
- #[inline]
- fn address(&self) -> u64 {
- u64::from(self.section.virtual_address.get(LE))
- }
-
- #[inline]
- fn size(&self) -> u64 {
- // TODO: This may need to be the length from the auxiliary symbol for this section.
- u64::from(self.section.size_of_raw_data.get(LE))
- }
-
- #[inline]
- fn align(&self) -> u64 {
- self.section.coff_alignment()
- }
-
- #[inline]
- fn file_range(&self) -> Option<(u64, u64)> {
- let (offset, size) = self.section.coff_file_range()?;
- Some((u64::from(offset), u64::from(size)))
- }
-
- fn data(&self) -> Result<&'data [u8]> {
- self.bytes()
- }
-
- fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> {
- Ok(read::util::data_range(
- self.bytes()?,
- self.address(),
- address,
- size,
- ))
- }
-
- #[inline]
- fn compressed_file_range(&self) -> Result<CompressedFileRange> {
- Ok(CompressedFileRange::none(self.file_range()))
- }
-
- #[inline]
- fn compressed_data(&self) -> Result<CompressedData<'data>> {
- self.data().map(CompressedData::none)
- }
-
- #[inline]
- fn name_bytes(&self) -> Result<&[u8]> {
- self.section.name(self.file.common.symbols.strings())
- }
-
- #[inline]
- fn name(&self) -> Result<&str> {
- let name = self.name_bytes()?;
- str::from_utf8(name)
- .ok()
- .read_error("Non UTF-8 COFF section name")
- }
-
- #[inline]
- fn segment_name_bytes(&self) -> Result<Option<&[u8]>> {
- Ok(None)
- }
-
- #[inline]
- fn segment_name(&self) -> Result<Option<&str>> {
- Ok(None)
- }
-
- #[inline]
- fn kind(&self) -> SectionKind {
- self.section.kind()
- }
-
- fn relocations(&self) -> CoffRelocationIterator<'data, 'file, R, Coff> {
- let relocations = self.section.coff_relocations(self.file.data).unwrap_or(&[]);
- CoffRelocationIterator {
- file: self.file,
- iter: relocations.iter(),
- }
- }
-
- fn flags(&self) -> SectionFlags {
- SectionFlags::Coff {
- characteristics: self.section.characteristics.get(LE),
- }
- }
-}
-
-impl pe::ImageSectionHeader {
- pub(crate) fn kind(&self) -> SectionKind {
- let characteristics = self.characteristics.get(LE);
- if characteristics & (pe::IMAGE_SCN_CNT_CODE | pe::IMAGE_SCN_MEM_EXECUTE) != 0 {
- SectionKind::Text
- } else if characteristics & pe::IMAGE_SCN_CNT_INITIALIZED_DATA != 0 {
- if characteristics & pe::IMAGE_SCN_MEM_DISCARDABLE != 0 {
- SectionKind::Other
- } else if characteristics & pe::IMAGE_SCN_MEM_WRITE != 0 {
- SectionKind::Data
- } else {
- SectionKind::ReadOnlyData
- }
- } else if characteristics & pe::IMAGE_SCN_CNT_UNINITIALIZED_DATA != 0 {
- SectionKind::UninitializedData
- } else if characteristics & pe::IMAGE_SCN_LNK_INFO != 0 {
- SectionKind::Linker
- } else {
- SectionKind::Unknown
- }
- }
-}
-
-impl pe::ImageSectionHeader {
- /// Return the string table offset of the section name.
- ///
- /// Returns `Ok(None)` if the name doesn't use the string table
- /// and can be obtained with `raw_name` instead.
- pub fn name_offset(&self) -> Result<Option<u32>> {
- let bytes = &self.name;
- if bytes[0] != b'/' {
- return Ok(None);
- }
-
- if bytes[1] == b'/' {
- let mut offset = 0;
- for byte in bytes[2..].iter() {
- let digit = match byte {
- b'A'..=b'Z' => byte - b'A',
- b'a'..=b'z' => byte - b'a' + 26,
- b'0'..=b'9' => byte - b'0' + 52,
- b'+' => 62,
- b'/' => 63,
- _ => return Err(Error("Invalid COFF section name base-64 offset")),
- };
- offset = offset * 64 + digit as u64;
- }
- u32::try_from(offset)
- .ok()
- .read_error("Invalid COFF section name base-64 offset")
- .map(Some)
- } else {
- let mut offset = 0;
- for byte in bytes[1..].iter() {
- let digit = match byte {
- b'0'..=b'9' => byte - b'0',
- 0 => break,
- _ => return Err(Error("Invalid COFF section name base-10 offset")),
- };
- offset = offset * 10 + digit as u32;
- }
- Ok(Some(offset))
- }
- }
-
- /// Return the section name.
- ///
- /// This handles decoding names that are offsets into the symbol string table.
- pub fn name<'data, R: ReadRef<'data>>(
- &'data self,
- strings: StringTable<'data, R>,
- ) -> Result<&'data [u8]> {
- if let Some(offset) = self.name_offset()? {
- strings
- .get(offset)
- .read_error("Invalid COFF section name offset")
- } else {
- Ok(self.raw_name())
- }
- }
-
- /// Return the raw section name.
- pub fn raw_name(&self) -> &[u8] {
- let bytes = &self.name;
- match memchr::memchr(b'\0', bytes) {
- Some(end) => &bytes[..end],
- None => &bytes[..],
- }
- }
-
- /// Return the offset and size of the section in a COFF file.
- ///
- /// Returns `None` for sections that have no data in the file.
- pub fn coff_file_range(&self) -> Option<(u32, u32)> {
- if self.characteristics.get(LE) & pe::IMAGE_SCN_CNT_UNINITIALIZED_DATA != 0 {
- None
- } else {
- let offset = self.pointer_to_raw_data.get(LE);
- // Note: virtual size is not used for COFF.
- let size = self.size_of_raw_data.get(LE);
- Some((offset, size))
- }
- }
-
- /// Return the section data in a COFF file.
- ///
- /// Returns `Ok(&[])` if the section has no data.
- /// Returns `Err` for invalid values.
- pub fn coff_data<'data, R: ReadRef<'data>>(&self, data: R) -> result::Result<&'data [u8], ()> {
- if let Some((offset, size)) = self.coff_file_range() {
- data.read_bytes_at(offset.into(), size.into())
- } else {
- Ok(&[])
- }
- }
-
- /// Return the section alignment in bytes.
- ///
- /// This is only valid for sections in a COFF file.
- pub fn coff_alignment(&self) -> u64 {
- match self.characteristics.get(LE) & pe::IMAGE_SCN_ALIGN_MASK {
- pe::IMAGE_SCN_ALIGN_1BYTES => 1,
- pe::IMAGE_SCN_ALIGN_2BYTES => 2,
- pe::IMAGE_SCN_ALIGN_4BYTES => 4,
- pe::IMAGE_SCN_ALIGN_8BYTES => 8,
- pe::IMAGE_SCN_ALIGN_16BYTES => 16,
- pe::IMAGE_SCN_ALIGN_32BYTES => 32,
- pe::IMAGE_SCN_ALIGN_64BYTES => 64,
- pe::IMAGE_SCN_ALIGN_128BYTES => 128,
- pe::IMAGE_SCN_ALIGN_256BYTES => 256,
- pe::IMAGE_SCN_ALIGN_512BYTES => 512,
- pe::IMAGE_SCN_ALIGN_1024BYTES => 1024,
- pe::IMAGE_SCN_ALIGN_2048BYTES => 2048,
- pe::IMAGE_SCN_ALIGN_4096BYTES => 4096,
- pe::IMAGE_SCN_ALIGN_8192BYTES => 8192,
- _ => 16,
- }
- }
-
- /// Read the relocations in a COFF file.
- ///
- /// `data` must be the entire file data.
- pub fn coff_relocations<'data, R: ReadRef<'data>>(
- &self,
- data: R,
- ) -> read::Result<&'data [pe::ImageRelocation]> {
- let mut pointer = self.pointer_to_relocations.get(LE).into();
- let mut number: usize = self.number_of_relocations.get(LE).into();
- if number == core::u16::MAX.into()
- && self.characteristics.get(LE) & pe::IMAGE_SCN_LNK_NRELOC_OVFL != 0
- {
- // Extended relocations. Read first relocation (which contains extended count) & adjust
- // relocations pointer.
- let extended_relocation_info = data
- .read_at::<pe::ImageRelocation>(pointer)
- .read_error("Invalid COFF relocation offset or number")?;
- number = extended_relocation_info.virtual_address.get(LE) as usize;
- if number == 0 {
- return Err(Error("Invalid COFF relocation number"));
- }
- pointer += core::mem::size_of::<pe::ImageRelocation>() as u64;
- // Extended relocation info does not contribute to the count of sections.
- number -= 1;
- }
- data.read_slice_at(pointer, number)
- .read_error("Invalid COFF relocation offset or number")
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn name_offset() {
- let mut section = pe::ImageSectionHeader::default();
- section.name = *b"xxxxxxxx";
- assert_eq!(section.name_offset(), Ok(None));
- section.name = *b"/0\0\0\0\0\0\0";
- assert_eq!(section.name_offset(), Ok(Some(0)));
- section.name = *b"/9999999";
- assert_eq!(section.name_offset(), Ok(Some(999_9999)));
- section.name = *b"//AAAAAA";
- assert_eq!(section.name_offset(), Ok(Some(0)));
- section.name = *b"//D/////";
- assert_eq!(section.name_offset(), Ok(Some(0xffff_ffff)));
- section.name = *b"//EAAAAA";
- assert!(section.name_offset().is_err());
- section.name = *b"////////";
- assert!(section.name_offset().is_err());
- }
-}
diff --git a/vendor/object/src/read/coff/symbol.rs b/vendor/object/src/read/coff/symbol.rs
deleted file mode 100644
index 4f8a0c6..0000000
--- a/vendor/object/src/read/coff/symbol.rs
+++ /dev/null
@@ -1,635 +0,0 @@
-use alloc::fmt;
-use alloc::vec::Vec;
-use core::convert::TryInto;
-use core::fmt::Debug;
-use core::str;
-
-use super::{CoffCommon, CoffHeader, SectionTable};
-use crate::endian::{LittleEndian as LE, U32Bytes};
-use crate::pe;
-use crate::pod::{bytes_of, bytes_of_slice, Pod};
-use crate::read::util::StringTable;
-use crate::read::{
- self, Bytes, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Result, SectionIndex,
- SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, SymbolMapEntry, SymbolScope, SymbolSection,
-};
-
-/// A table of symbol entries in a COFF or PE file.
-///
-/// Also includes the string table used for the symbol names.
-///
-/// Returned by [`CoffHeader::symbols`] and
-/// [`ImageNtHeaders::symbols`](crate::read::pe::ImageNtHeaders::symbols).
-#[derive(Debug)]
-pub struct SymbolTable<'data, R = &'data [u8], Coff = pe::ImageFileHeader>
-where
- R: ReadRef<'data>,
- Coff: CoffHeader,
-{
- symbols: &'data [Coff::ImageSymbolBytes],
- strings: StringTable<'data, R>,
-}
-
-impl<'data, R: ReadRef<'data>, Coff: CoffHeader> Default for SymbolTable<'data, R, Coff> {
- fn default() -> Self {
- Self {
- symbols: &[],
- strings: StringTable::default(),
- }
- }
-}
-
-impl<'data, R: ReadRef<'data>, Coff: CoffHeader> SymbolTable<'data, R, Coff> {
- /// Read the symbol table.
- pub fn parse(header: &Coff, data: R) -> Result<Self> {
- // The symbol table may not be present.
- let mut offset = header.pointer_to_symbol_table().into();
- let (symbols, strings) = if offset != 0 {
- let symbols = data
- .read_slice(&mut offset, header.number_of_symbols() as usize)
- .read_error("Invalid COFF symbol table offset or size")?;
-
- // Note: don't update data when reading length; the length includes itself.
- let length = data
- .read_at::<U32Bytes<_>>(offset)
- .read_error("Missing COFF string table")?
- .get(LE);
- let str_end = offset
- .checked_add(length as u64)
- .read_error("Invalid COFF string table length")?;
- let strings = StringTable::new(data, offset, str_end);
-
- (symbols, strings)
- } else {
- (&[][..], StringTable::default())
- };
-
- Ok(SymbolTable { symbols, strings })
- }
-
- /// Return the string table used for the symbol names.
- #[inline]
- pub fn strings(&self) -> StringTable<'data, R> {
- self.strings
- }
-
- /// Return true if the symbol table is empty.
- #[inline]
- pub fn is_empty(&self) -> bool {
- self.symbols.is_empty()
- }
-
- /// The number of symbol table entries.
- ///
- /// This includes auxiliary symbol table entries.
- #[inline]
- pub fn len(&self) -> usize {
- self.symbols.len()
- }
-
- /// Iterate over the symbols.
- #[inline]
- pub fn iter<'table>(&'table self) -> SymbolIterator<'data, 'table, R, Coff> {
- SymbolIterator {
- symbols: self,
- index: 0,
- }
- }
-
- /// Return the symbol table entry at the given index.
- #[inline]
- pub fn symbol(&self, index: usize) -> Result<&'data Coff::ImageSymbol> {
- self.get::<Coff::ImageSymbol>(index, 0)
- }
-
- /// Return the auxiliary function symbol for the symbol table entry at the given index.
- ///
- /// Note that the index is of the symbol, not the first auxiliary record.
- #[inline]
- pub fn aux_function(&self, index: usize) -> Result<&'data pe::ImageAuxSymbolFunction> {
- self.get::<pe::ImageAuxSymbolFunction>(index, 1)
- }
-
- /// Return the auxiliary section symbol for the symbol table entry at the given index.
- ///
- /// Note that the index is of the symbol, not the first auxiliary record.
- #[inline]
- pub fn aux_section(&self, index: usize) -> Result<&'data pe::ImageAuxSymbolSection> {
- self.get::<pe::ImageAuxSymbolSection>(index, 1)
- }
-
- /// Return the auxiliary file name for the symbol table entry at the given index.
- ///
- /// Note that the index is of the symbol, not the first auxiliary record.
- pub fn aux_file_name(&self, index: usize, aux_count: u8) -> Result<&'data [u8]> {
- let entries = index
- .checked_add(1)
- .and_then(|x| Some(x..x.checked_add(aux_count.into())?))
- .and_then(|x| self.symbols.get(x))
- .read_error("Invalid COFF symbol index")?;
- let bytes = bytes_of_slice(entries);
- // The name is padded with nulls.
- Ok(match memchr::memchr(b'\0', bytes) {
- Some(end) => &bytes[..end],
- None => bytes,
- })
- }
-
- /// Return the symbol table entry or auxiliary record at the given index and offset.
- pub fn get<T: Pod>(&self, index: usize, offset: usize) -> Result<&'data T> {
- let bytes = index
- .checked_add(offset)
- .and_then(|x| self.symbols.get(x))
- .read_error("Invalid COFF symbol index")?;
- Bytes(bytes_of(bytes))
- .read()
- .read_error("Invalid COFF symbol data")
- }
-
- /// Construct a map from addresses to a user-defined map entry.
- pub fn map<Entry: SymbolMapEntry, F: Fn(&'data Coff::ImageSymbol) -> Option<Entry>>(
- &self,
- f: F,
- ) -> SymbolMap<Entry> {
- let mut symbols = Vec::with_capacity(self.symbols.len());
- for (_, symbol) in self.iter() {
- if !symbol.is_definition() {
- continue;
- }
- if let Some(entry) = f(symbol) {
- symbols.push(entry);
- }
- }
- SymbolMap::new(symbols)
- }
-}
-
-/// An iterator for symbol entries in a COFF or PE file.
-///
-/// Yields the index and symbol structure for each symbol.
-#[derive(Debug)]
-pub struct SymbolIterator<'data, 'table, R = &'data [u8], Coff = pe::ImageFileHeader>
-where
- R: ReadRef<'data>,
- Coff: CoffHeader,
-{
- symbols: &'table SymbolTable<'data, R, Coff>,
- index: usize,
-}
-
-impl<'data, 'table, R: ReadRef<'data>, Coff: CoffHeader> Iterator
- for SymbolIterator<'data, 'table, R, Coff>
-{
- type Item = (usize, &'data Coff::ImageSymbol);
-
- fn next(&mut self) -> Option<Self::Item> {
- let index = self.index;
- let symbol = self.symbols.symbol(index).ok()?;
- self.index += 1 + symbol.number_of_aux_symbols() as usize;
- Some((index, symbol))
- }
-}
-
-/// A symbol table in a [`CoffBigFile`](super::CoffBigFile).
-pub type CoffBigSymbolTable<'data, 'file, R = &'data [u8]> =
- CoffSymbolTable<'data, 'file, R, pe::AnonObjectHeaderBigobj>;
-
-/// A symbol table in a [`CoffFile`](super::CoffFile)
-/// or [`PeFile`](crate::read::pe::PeFile).
-#[derive(Debug, Clone, Copy)]
-pub struct CoffSymbolTable<'data, 'file, R = &'data [u8], Coff = pe::ImageFileHeader>
-where
- R: ReadRef<'data>,
- Coff: CoffHeader,
-{
- pub(crate) file: &'file CoffCommon<'data, R, Coff>,
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed
- for CoffSymbolTable<'data, 'file, R, Coff>
-{
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSymbolTable<'data>
- for CoffSymbolTable<'data, 'file, R, Coff>
-{
- type Symbol = CoffSymbol<'data, 'file, R, Coff>;
- type SymbolIterator = CoffSymbolIterator<'data, 'file, R, Coff>;
-
- fn symbols(&self) -> Self::SymbolIterator {
- CoffSymbolIterator {
- file: self.file,
- index: 0,
- }
- }
-
- fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol> {
- let symbol = self.file.symbols.symbol(index.0)?;
- Ok(CoffSymbol {
- file: self.file,
- index,
- symbol,
- })
- }
-}
-
-/// An iterator for the symbols in a [`CoffBigFile`](super::CoffBigFile).
-pub type CoffBigSymbolIterator<'data, 'file, R = &'data [u8]> =
- CoffSymbolIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>;
-
-/// An iterator for the symbols in a [`CoffFile`](super::CoffFile)
-/// or [`PeFile`](crate::read::pe::PeFile).
-pub struct CoffSymbolIterator<'data, 'file, R = &'data [u8], Coff = pe::ImageFileHeader>
-where
- R: ReadRef<'data>,
- Coff: CoffHeader,
-{
- pub(crate) file: &'file CoffCommon<'data, R, Coff>,
- pub(crate) index: usize,
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> fmt::Debug
- for CoffSymbolIterator<'data, 'file, R, Coff>
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("CoffSymbolIterator").finish()
- }
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator
- for CoffSymbolIterator<'data, 'file, R, Coff>
-{
- type Item = CoffSymbol<'data, 'file, R, Coff>;
-
- fn next(&mut self) -> Option<Self::Item> {
- let index = self.index;
- let symbol = self.file.symbols.symbol(index).ok()?;
- self.index += 1 + symbol.number_of_aux_symbols() as usize;
- Some(CoffSymbol {
- file: self.file,
- index: SymbolIndex(index),
- symbol,
- })
- }
-}
-
-/// A symbol in a [`CoffBigFile`](super::CoffBigFile).
-///
-/// Most functionality is provided by the [`ObjectSymbol`] trait implementation.
-pub type CoffBigSymbol<'data, 'file, R = &'data [u8]> =
- CoffSymbol<'data, 'file, R, pe::AnonObjectHeaderBigobj>;
-
-/// A symbol in a [`CoffFile`](super::CoffFile) or [`PeFile`](crate::read::pe::PeFile).
-///
-/// Most functionality is provided by the [`ObjectSymbol`] trait implementation.
-#[derive(Debug, Clone, Copy)]
-pub struct CoffSymbol<'data, 'file, R = &'data [u8], Coff = pe::ImageFileHeader>
-where
- R: ReadRef<'data>,
- Coff: CoffHeader,
-{
- pub(crate) file: &'file CoffCommon<'data, R, Coff>,
- pub(crate) index: SymbolIndex,
- pub(crate) symbol: &'data Coff::ImageSymbol,
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> CoffSymbol<'data, 'file, R, Coff> {
- #[inline]
- /// Get the raw `ImageSymbol` struct.
- pub fn raw_symbol(&self) -> &'data Coff::ImageSymbol {
- self.symbol
- }
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> read::private::Sealed
- for CoffSymbol<'data, 'file, R, Coff>
-{
-}
-
-impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSymbol<'data>
- for CoffSymbol<'data, 'file, R, Coff>
-{
- #[inline]
- fn index(&self) -> SymbolIndex {
- self.index
- }
-
- fn name_bytes(&self) -> read::Result<&'data [u8]> {
- if self.symbol.has_aux_file_name() {
- self.file
- .symbols
- .aux_file_name(self.index.0, self.symbol.number_of_aux_symbols())
- } else {
- self.symbol.name(self.file.symbols.strings())
- }
- }
-
- fn name(&self) -> read::Result<&'data str> {
- let name = self.name_bytes()?;
- str::from_utf8(name)
- .ok()
- .read_error("Non UTF-8 COFF symbol name")
- }
-
- fn address(&self) -> u64 {
- // Only return an address for storage classes that we know use an address.
- match self.symbol.storage_class() {
- pe::IMAGE_SYM_CLASS_STATIC
- | pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL
- | pe::IMAGE_SYM_CLASS_LABEL => {}
- pe::IMAGE_SYM_CLASS_EXTERNAL => {
- if self.symbol.section_number() == pe::IMAGE_SYM_UNDEFINED {
- // Undefined or common data, neither of which have an address.
- return 0;
- }
- }
- _ => return 0,
- }
- self.symbol
- .address(self.file.image_base, &self.file.sections)
- .unwrap_or(0)
- }
-
- fn size(&self) -> u64 {
- match self.symbol.storage_class() {
- pe::IMAGE_SYM_CLASS_STATIC => {
- // Section symbols may duplicate the size from the section table.
- if self.symbol.has_aux_section() {
- if let Ok(aux) = self.file.symbols.aux_section(self.index.0) {
- u64::from(aux.length.get(LE))
- } else {
- 0
- }
- } else {
- 0
- }
- }
- pe::IMAGE_SYM_CLASS_EXTERNAL => {
- if self.symbol.section_number() == pe::IMAGE_SYM_UNDEFINED {
- // For undefined symbols, symbol.value is 0 and the size is 0.
- // For common data, symbol.value is the size.
- u64::from(self.symbol.value())
- } else if self.symbol.has_aux_function() {
- // Function symbols may have a size.
- if let Ok(aux) = self.file.symbols.aux_function(self.index.0) {
- u64::from(aux.total_size.get(LE))
- } else {
- 0
- }
- } else {
- 0
- }
- }
- // Most symbols don't have sizes.
- _ => 0,
- }
- }
-
- fn kind(&self) -> SymbolKind {
- let derived_kind = if self.symbol.derived_type() == pe::IMAGE_SYM_DTYPE_FUNCTION {
- SymbolKind::Text
- } else {
- SymbolKind::Data
- };
- match self.symbol.storage_class() {
- pe::IMAGE_SYM_CLASS_STATIC => {
- if self.symbol.has_aux_section() {
- SymbolKind::Section
- } else {
- derived_kind
- }
- }
- pe::IMAGE_SYM_CLASS_EXTERNAL | pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL => derived_kind,
- pe::IMAGE_SYM_CLASS_SECTION => SymbolKind::Section,
- pe::IMAGE_SYM_CLASS_FILE => SymbolKind::File,
- pe::IMAGE_SYM_CLASS_LABEL => SymbolKind::Label,
- _ => SymbolKind::Unknown,
- }
- }
-
- fn section(&self) -> SymbolSection {
- match self.symbol.section_number() {
- pe::IMAGE_SYM_UNDEFINED => {
- if self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_EXTERNAL {
- if self.symbol.value() == 0 {
- SymbolSection::Undefined
- } else {
- SymbolSection::Common
- }
- } else if self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_SECTION {
- SymbolSection::Undefined
- } else {
- SymbolSection::Unknown
- }
- }
- pe::IMAGE_SYM_ABSOLUTE => SymbolSection::Absolute,
- pe::IMAGE_SYM_DEBUG => {
- if self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_FILE {
- SymbolSection::None
- } else {
- SymbolSection::Unknown
- }
- }
- index if index > 0 => SymbolSection::Section(SectionIndex(index as usize)),
- _ => SymbolSection::Unknown,
- }
- }
-
- #[inline]
- fn is_undefined(&self) -> bool {
- self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_EXTERNAL
- && self.symbol.section_number() == pe::IMAGE_SYM_UNDEFINED
- && self.symbol.value() == 0
- }
-
- #[inline]
- fn is_definition(&self) -> bool {
- self.symbol.is_definition()
- }
-
- #[inline]
- fn is_common(&self) -> bool {
- self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_EXTERNAL
- && self.symbol.section_number() == pe::IMAGE_SYM_UNDEFINED
- && self.symbol.value() != 0
- }
-
- #[inline]
- fn is_weak(&self) -> bool {
- self.symbol.storage_class() == pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL
- }
-
- #[inline]
- fn scope(&self) -> SymbolScope {
- match self.symbol.storage_class() {
- pe::IMAGE_SYM_CLASS_EXTERNAL | pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL => {
- // TODO: determine if symbol is exported
- SymbolScope::Linkage
- }
- _ => SymbolScope::Compilation,
- }
- }
-
- #[inline]
- fn is_global(&self) -> bool {
- match self.symbol.storage_class() {
- pe::IMAGE_SYM_CLASS_EXTERNAL | pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL => true,
- _ => false,
- }
- }
-
- #[inline]
- fn is_local(&self) -> bool {
- !self.is_global()
- }
-
- fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> {
- if self.symbol.has_aux_section() {
- if let Ok(aux) = self.file.symbols.aux_section(self.index.0) {
- let number = if Coff::is_type_bigobj() {
- u32::from(aux.number.get(LE)) | (u32::from(aux.high_number.get(LE)) << 16)
- } else {
- u32::from(aux.number.get(LE))
- };
- return SymbolFlags::CoffSection {
- selection: aux.selection,
- associative_section: if number == 0 {
- None
- } else {
- Some(SectionIndex(number as usize))
- },
- };
- }
- }
- SymbolFlags::None
- }
-}
-
-/// A trait for generic access to [`pe::ImageSymbol`] and [`pe::ImageSymbolEx`].
-#[allow(missing_docs)]
-pub trait ImageSymbol: Debug + Pod {
- fn raw_name(&self) -> &[u8; 8];
- fn value(&self) -> u32;
- fn section_number(&self) -> i32;
- fn typ(&self) -> u16;
- fn storage_class(&self) -> u8;
- fn number_of_aux_symbols(&self) -> u8;
-
- /// Parse a COFF symbol name.
- ///
- /// `strings` must be the string table used for symbol names.
- fn name<'data, R: ReadRef<'data>>(
- &'data self,
- strings: StringTable<'data, R>,
- ) -> Result<&'data [u8]> {
- let name = self.raw_name();
- if name[0] == 0 {
- // If the name starts with 0 then the last 4 bytes are a string table offset.
- let offset = u32::from_le_bytes(name[4..8].try_into().unwrap());
- strings
- .get(offset)
- .read_error("Invalid COFF symbol name offset")
- } else {
- // The name is inline and padded with nulls.
- Ok(match memchr::memchr(b'\0', name) {
- Some(end) => &name[..end],
- None => &name[..],
- })
- }
- }
-
- /// Return the symbol address.
- ///
- /// This takes into account the image base and the section address.
- fn address(&self, image_base: u64, sections: &SectionTable<'_>) -> Result<u64> {
- let section_number = self.section_number() as usize;
- let section = sections.section(section_number)?;
- let virtual_address = u64::from(section.virtual_address.get(LE));
- let value = u64::from(self.value());
- Ok(image_base + virtual_address + value)
- }
-
- /// Return true if the symbol is a definition of a function or data object.
- fn is_definition(&self) -> bool {
- if self.section_number() <= 0 {
- return false;
- }
- match self.storage_class() {
- pe::IMAGE_SYM_CLASS_STATIC => !self.has_aux_section(),
- pe::IMAGE_SYM_CLASS_EXTERNAL | pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL => true,
- _ => false,
- }
- }
-
- /// Return true if the symbol has an auxiliary file name.
- fn has_aux_file_name(&self) -> bool {
- self.number_of_aux_symbols() > 0 && self.storage_class() == pe::IMAGE_SYM_CLASS_FILE
- }
-
- /// Return true if the symbol has an auxiliary function symbol.
- fn has_aux_function(&self) -> bool {
- self.number_of_aux_symbols() > 0 && self.derived_type() == pe::IMAGE_SYM_DTYPE_FUNCTION
- }
-
- /// Return true if the symbol has an auxiliary section symbol.
- fn has_aux_section(&self) -> bool {
- self.number_of_aux_symbols() > 0
- && self.storage_class() == pe::IMAGE_SYM_CLASS_STATIC
- && self.typ() == 0
- }
-
- fn base_type(&self) -> u16 {
- self.typ() & pe::N_BTMASK
- }
-
- fn derived_type(&self) -> u16 {
- (self.typ() & pe::N_TMASK) >> pe::N_BTSHFT
- }
-}
-
-impl ImageSymbol for pe::ImageSymbol {
- fn raw_name(&self) -> &[u8; 8] {
- &self.name
- }
- fn value(&self) -> u32 {
- self.value.get(LE)
- }
- fn section_number(&self) -> i32 {
- let section_number = self.section_number.get(LE);
- if section_number >= pe::IMAGE_SYM_SECTION_MAX {
- (section_number as i16) as i32
- } else {
- section_number as i32
- }
- }
- fn typ(&self) -> u16 {
- self.typ.get(LE)
- }
- fn storage_class(&self) -> u8 {
- self.storage_class
- }
- fn number_of_aux_symbols(&self) -> u8 {
- self.number_of_aux_symbols
- }
-}
-
-impl ImageSymbol for pe::ImageSymbolEx {
- fn raw_name(&self) -> &[u8; 8] {
- &self.name
- }
- fn value(&self) -> u32 {
- self.value.get(LE)
- }
- fn section_number(&self) -> i32 {
- self.section_number.get(LE)
- }
- fn typ(&self) -> u16 {
- self.typ.get(LE)
- }
- fn storage_class(&self) -> u8 {
- self.storage_class
- }
- fn number_of_aux_symbols(&self) -> u8 {
- self.number_of_aux_symbols
- }
-}
diff --git a/vendor/object/src/read/elf/attributes.rs b/vendor/object/src/read/elf/attributes.rs
deleted file mode 100644
index bf6f35c..0000000
--- a/vendor/object/src/read/elf/attributes.rs
+++ /dev/null
@@ -1,307 +0,0 @@
-use core::convert::TryInto;
-
-use crate::elf;
-use crate::endian;
-use crate::read::{Bytes, Error, ReadError, Result};
-
-use super::FileHeader;
-
-/// An ELF attributes section.
-///
-/// This may be a GNU attributes section, or an architecture specific attributes section.
-///
-/// An attributes section contains a series of [`AttributesSubsection`].
-///
-/// Returned by [`SectionHeader::attributes`](super::SectionHeader::attributes)
-/// and [`SectionHeader::gnu_attributes`](super::SectionHeader::gnu_attributes).
-#[derive(Debug, Clone)]
-pub struct AttributesSection<'data, Elf: FileHeader> {
- endian: Elf::Endian,
- version: u8,
- data: Bytes<'data>,
-}
-
-impl<'data, Elf: FileHeader> AttributesSection<'data, Elf> {
- /// Parse an ELF attributes section given the section data.
- pub fn new(endian: Elf::Endian, data: &'data [u8]) -> Result<Self> {
- let mut data = Bytes(data);
-
- // Skip the version field that is one byte long.
- let version = *data
- .read::<u8>()
- .read_error("Invalid ELF attributes section offset or size")?;
-
- Ok(AttributesSection {
- endian,
- version,
- data,
- })
- }
-
- /// Return the version of the attributes section.
- pub fn version(&self) -> u8 {
- self.version
- }
-
- /// Return an iterator over the subsections.
- pub fn subsections(&self) -> Result<AttributesSubsectionIterator<'data, Elf>> {
- // There is currently only one format version.
- if self.version != b'A' {
- return Err(Error("Unsupported ELF attributes section version"));
- }
-
- Ok(AttributesSubsectionIterator {
- endian: self.endian,
- data: self.data,
- })
- }
-}
-
-/// An iterator for the subsections in an [`AttributesSection`].
-#[derive(Debug, Clone)]
-pub struct AttributesSubsectionIterator<'data, Elf: FileHeader> {
- endian: Elf::Endian,
- data: Bytes<'data>,
-}
-
-impl<'data, Elf: FileHeader> AttributesSubsectionIterator<'data, Elf> {
- /// Return the next subsection.
- pub fn next(&mut self) -> Result<Option<AttributesSubsection<'data, Elf>>> {
- if self.data.is_empty() {
- return Ok(None);
- }
-
- let result = self.parse();
- if result.is_err() {
- self.data = Bytes(&[]);
- }
- result
- }
-
- fn parse(&mut self) -> Result<Option<AttributesSubsection<'data, Elf>>> {
- // First read the subsection length.
- let mut data = self.data;
- let length = data
- .read::<endian::U32Bytes<Elf::Endian>>()
- .read_error("ELF attributes section is too short")?
- .get(self.endian);
-
- // Now read the entire subsection, updating self.data.
- let mut data = self
- .data
- .read_bytes(length as usize)
- .read_error("Invalid ELF attributes subsection length")?;
- // Skip the subsection length field.
- data.skip(4)
- .read_error("Invalid ELF attributes subsection length")?;
-
- let vendor = data
- .read_string()
- .read_error("Invalid ELF attributes vendor")?;
-
- Ok(Some(AttributesSubsection {
- endian: self.endian,
- length,
- vendor,
- data,
- }))
- }
-}
-
-/// A subsection in an [`AttributesSection`].
-///
-/// A subsection is identified by a vendor name. It contains a series of
-/// [`AttributesSubsubsection`].
-#[derive(Debug, Clone)]
-pub struct AttributesSubsection<'data, Elf: FileHeader> {
- endian: Elf::Endian,
- length: u32,
- vendor: &'data [u8],
- data: Bytes<'data>,
-}
-
-impl<'data, Elf: FileHeader> AttributesSubsection<'data, Elf> {
- /// Return the length of the attributes subsection.
- pub fn length(&self) -> u32 {
- self.length
- }
-
- /// Return the vendor name of the attributes subsection.
- pub fn vendor(&self) -> &'data [u8] {
- self.vendor
- }
-
- /// Return an iterator over the sub-subsections.
- pub fn subsubsections(&self) -> AttributesSubsubsectionIterator<'data, Elf> {
- AttributesSubsubsectionIterator {
- endian: self.endian,
- data: self.data,
- }
- }
-}
-
-/// An iterator for the sub-subsections in an [`AttributesSubsection`].
-#[derive(Debug, Clone)]
-pub struct AttributesSubsubsectionIterator<'data, Elf: FileHeader> {
- endian: Elf::Endian,
- data: Bytes<'data>,
-}
-
-impl<'data, Elf: FileHeader> AttributesSubsubsectionIterator<'data, Elf> {
- /// Return the next sub-subsection.
- pub fn next(&mut self) -> Result<Option<AttributesSubsubsection<'data>>> {
- if self.data.is_empty() {
- return Ok(None);
- }
-
- let result = self.parse();
- if result.is_err() {
- self.data = Bytes(&[]);
- }
- result
- }
-
- fn parse(&mut self) -> Result<Option<AttributesSubsubsection<'data>>> {
- // The format of a sub-section looks like this:
- //
- // <file-tag> <size> <attribute>*
- // | <section-tag> <size> <section-number>* 0 <attribute>*
- // | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
- let mut data = self.data;
- let tag = *data
- .read::<u8>()
- .read_error("ELF attributes subsection is too short")?;
- let length = data
- .read::<endian::U32Bytes<Elf::Endian>>()
- .read_error("ELF attributes subsection is too short")?
- .get(self.endian);
-
- // Now read the entire sub-subsection, updating self.data.
- let mut data = self
- .data
- .read_bytes(length as usize)
- .read_error("Invalid ELF attributes sub-subsection length")?;
- // Skip the tag and sub-subsection size field.
- data.skip(1 + 4)
- .read_error("Invalid ELF attributes sub-subsection length")?;
-
- let indices = if tag == elf::Tag_Section || tag == elf::Tag_Symbol {
- data.read_string()
- .map(Bytes)
- .read_error("Missing ELF attributes sub-subsection indices")?
- } else if tag == elf::Tag_File {
- Bytes(&[])
- } else {
- return Err(Error("Unimplemented ELF attributes sub-subsection tag"));
- };
-
- Ok(Some(AttributesSubsubsection {
- tag,
- length,
- indices,
- data,
- }))
- }
-}
-
-/// A sub-subsection in an [`AttributesSubsection`].
-///
-/// A sub-subsection is identified by a tag. It contains an optional series of indices,
-/// followed by a series of attributes.
-#[derive(Debug, Clone)]
-pub struct AttributesSubsubsection<'data> {
- tag: u8,
- length: u32,
- indices: Bytes<'data>,
- data: Bytes<'data>,
-}
-
-impl<'data> AttributesSubsubsection<'data> {
- /// Return the tag of the attributes sub-subsection.
- pub fn tag(&self) -> u8 {
- self.tag
- }
-
- /// Return the length of the attributes sub-subsection.
- pub fn length(&self) -> u32 {
- self.length
- }
-
- /// Return the data containing the indices.
- pub fn indices_data(&self) -> &'data [u8] {
- self.indices.0
- }
-
- /// Return the indices.
- ///
- /// This will be section indices if the tag is `Tag_Section`,
- /// or symbol indices if the tag is `Tag_Symbol`,
- /// and otherwise it will be empty.
- pub fn indices(&self) -> AttributeIndexIterator<'data> {
- AttributeIndexIterator { data: self.indices }
- }
-
- /// Return the data containing the attributes.
- pub fn attributes_data(&self) -> &'data [u8] {
- self.data.0
- }
-
- /// Return a parser for the data containing the attributes.
- pub fn attributes(&self) -> AttributeReader<'data> {
- AttributeReader { data: self.data }
- }
-}
-
-/// An iterator over the indices in an [`AttributesSubsubsection`].
-#[derive(Debug, Clone)]
-pub struct AttributeIndexIterator<'data> {
- data: Bytes<'data>,
-}
-
-impl<'data> AttributeIndexIterator<'data> {
- /// Parse the next index.
- pub fn next(&mut self) -> Result<Option<u32>> {
- if self.data.is_empty() {
- return Ok(None);
- }
- let err = "Invalid ELF attribute index";
- self.data
- .read_uleb128()
- .read_error(err)?
- .try_into()
- .map_err(|_| ())
- .read_error(err)
- .map(Some)
- }
-}
-
-/// A parser for the attributes in an [`AttributesSubsubsection`].
-///
-/// The parser relies on the caller to know the format of the data for each attribute tag.
-#[derive(Debug, Clone)]
-pub struct AttributeReader<'data> {
- data: Bytes<'data>,
-}
-
-impl<'data> AttributeReader<'data> {
- /// Parse a tag.
- pub fn read_tag(&mut self) -> Result<Option<u64>> {
- if self.data.is_empty() {
- return Ok(None);
- }
- let err = "Invalid ELF attribute tag";
- self.data.read_uleb128().read_error(err).map(Some)
- }
-
- /// Parse an integer value.
- pub fn read_integer(&mut self) -> Result<u64> {
- let err = "Invalid ELF attribute integer value";
- self.data.read_uleb128().read_error(err)
- }
-
- /// Parse a string value.
- pub fn read_string(&mut self) -> Result<&'data [u8]> {
- let err = "Invalid ELF attribute string value";
- self.data.read_string().read_error(err)
- }
-}
diff --git a/vendor/object/src/read/elf/comdat.rs b/vendor/object/src/read/elf/comdat.rs
deleted file mode 100644
index 882d253..0000000
--- a/vendor/object/src/read/elf/comdat.rs
+++ /dev/null
@@ -1,162 +0,0 @@
-use core::fmt::Debug;
-use core::{iter, slice, str};
-
-use crate::elf;
-use crate::endian::{Endianness, U32Bytes};
-use crate::read::{self, ComdatKind, ObjectComdat, ReadError, ReadRef, SectionIndex, SymbolIndex};
-
-use super::{ElfFile, FileHeader, SectionHeader, Sym};
-
-/// An iterator for the COMDAT section groups in an [`ElfFile32`](super::ElfFile32).
-pub type ElfComdatIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfComdatIterator<'data, 'file, elf::FileHeader32<Endian>, R>;
-/// An iterator for the COMDAT section groups in an [`ElfFile64`](super::ElfFile64).
-pub type ElfComdatIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfComdatIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
-
-/// An iterator for the COMDAT section groups in an [`ElfFile`].
-#[derive(Debug)]
-pub struct ElfComdatIterator<'data, 'file, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file ElfFile<'data, Elf, R>,
- pub(super) iter: iter::Enumerate<slice::Iter<'data, Elf::SectionHeader>>,
-}
-
-impl<'data, 'file, Elf, R> Iterator for ElfComdatIterator<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- type Item = ElfComdat<'data, 'file, Elf, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- for (_index, section) in self.iter.by_ref() {
- if let Some(comdat) = ElfComdat::parse(self.file, section) {
- return Some(comdat);
- }
- }
- None
- }
-}
-
-/// A COMDAT section group in an [`ElfFile32`](super::ElfFile32).
-pub type ElfComdat32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfComdat<'data, 'file, elf::FileHeader32<Endian>, R>;
-/// A COMDAT section group in an [`ElfFile64`](super::ElfFile64).
-pub type ElfComdat64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfComdat<'data, 'file, elf::FileHeader64<Endian>, R>;
-
-/// A COMDAT section group in an [`ElfFile`].
-///
-/// Most functionality is provided by the [`ObjectComdat`] trait implementation.
-#[derive(Debug)]
-pub struct ElfComdat<'data, 'file, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- file: &'file ElfFile<'data, Elf, R>,
- section: &'data Elf::SectionHeader,
- sections: &'data [U32Bytes<Elf::Endian>],
-}
-
-impl<'data, 'file, Elf, R> ElfComdat<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- fn parse(
- file: &'file ElfFile<'data, Elf, R>,
- section: &'data Elf::SectionHeader,
- ) -> Option<ElfComdat<'data, 'file, Elf, R>> {
- let (flag, sections) = section.group(file.endian, file.data).ok()??;
- if flag != elf::GRP_COMDAT {
- return None;
- }
- Some(ElfComdat {
- file,
- section,
- sections,
- })
- }
-}
-
-impl<'data, 'file, Elf, R> read::private::Sealed for ElfComdat<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Elf, R> ObjectComdat<'data> for ElfComdat<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- type SectionIterator = ElfComdatSectionIterator<'data, 'file, Elf, R>;
-
- #[inline]
- fn kind(&self) -> ComdatKind {
- ComdatKind::Any
- }
-
- #[inline]
- fn symbol(&self) -> SymbolIndex {
- SymbolIndex(self.section.sh_info(self.file.endian) as usize)
- }
-
- fn name_bytes(&self) -> read::Result<&[u8]> {
- // FIXME: check sh_link
- let index = self.section.sh_info(self.file.endian) as usize;
- let symbol = self.file.symbols.symbol(index)?;
- symbol.name(self.file.endian, self.file.symbols.strings())
- }
-
- fn name(&self) -> read::Result<&str> {
- let name = self.name_bytes()?;
- str::from_utf8(name)
- .ok()
- .read_error("Non UTF-8 ELF COMDAT name")
- }
-
- fn sections(&self) -> Self::SectionIterator {
- ElfComdatSectionIterator {
- file: self.file,
- sections: self.sections.iter(),
- }
- }
-}
-
-/// An iterator for the sections in a COMDAT section group in an [`ElfFile32`](super::ElfFile32).
-pub type ElfComdatSectionIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfComdatSectionIterator<'data, 'file, elf::FileHeader32<Endian>, R>;
-/// An iterator for the sections in a COMDAT section group in an [`ElfFile64`](super::ElfFile64).
-pub type ElfComdatSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfComdatSectionIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
-
-/// An iterator for the sections in a COMDAT section group in an [`ElfFile`].
-#[derive(Debug)]
-pub struct ElfComdatSectionIterator<'data, 'file, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- file: &'file ElfFile<'data, Elf, R>,
- sections: slice::Iter<'data, U32Bytes<Elf::Endian>>,
-}
-
-impl<'data, 'file, Elf, R> Iterator for ElfComdatSectionIterator<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- type Item = SectionIndex;
-
- fn next(&mut self) -> Option<Self::Item> {
- let index = self.sections.next()?;
- Some(SectionIndex(index.get(self.file.endian) as usize))
- }
-}
diff --git a/vendor/object/src/read/elf/compression.rs b/vendor/object/src/read/elf/compression.rs
deleted file mode 100644
index de2533f..0000000
--- a/vendor/object/src/read/elf/compression.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-use core::fmt::Debug;
-
-use crate::elf;
-use crate::endian;
-use crate::pod::Pod;
-
-/// A trait for generic access to [`elf::CompressionHeader32`] and [`elf::CompressionHeader64`].
-#[allow(missing_docs)]
-pub trait CompressionHeader: Debug + Pod {
- type Word: Into<u64>;
- type Endian: endian::Endian;
-
- fn ch_type(&self, endian: Self::Endian) -> u32;
- fn ch_size(&self, endian: Self::Endian) -> Self::Word;
- fn ch_addralign(&self, endian: Self::Endian) -> Self::Word;
-}
-
-impl<Endian: endian::Endian> CompressionHeader for elf::CompressionHeader32<Endian> {
- type Word = u32;
- type Endian = Endian;
-
- #[inline]
- fn ch_type(&self, endian: Self::Endian) -> u32 {
- self.ch_type.get(endian)
- }
-
- #[inline]
- fn ch_size(&self, endian: Self::Endian) -> Self::Word {
- self.ch_size.get(endian)
- }
-
- #[inline]
- fn ch_addralign(&self, endian: Self::Endian) -> Self::Word {
- self.ch_addralign.get(endian)
- }
-}
-
-impl<Endian: endian::Endian> CompressionHeader for elf::CompressionHeader64<Endian> {
- type Word = u64;
- type Endian = Endian;
-
- #[inline]
- fn ch_type(&self, endian: Self::Endian) -> u32 {
- self.ch_type.get(endian)
- }
-
- #[inline]
- fn ch_size(&self, endian: Self::Endian) -> Self::Word {
- self.ch_size.get(endian)
- }
-
- #[inline]
- fn ch_addralign(&self, endian: Self::Endian) -> Self::Word {
- self.ch_addralign.get(endian)
- }
-}
diff --git a/vendor/object/src/read/elf/dynamic.rs b/vendor/object/src/read/elf/dynamic.rs
deleted file mode 100644
index 1661434..0000000
--- a/vendor/object/src/read/elf/dynamic.rs
+++ /dev/null
@@ -1,117 +0,0 @@
-use core::convert::TryInto;
-use core::fmt::Debug;
-
-use crate::elf;
-use crate::endian;
-use crate::pod::Pod;
-use crate::read::{ReadError, Result, StringTable};
-
-/// A trait for generic access to [`elf::Dyn32`] and [`elf::Dyn64`].
-#[allow(missing_docs)]
-pub trait Dyn: Debug + Pod {
- type Word: Into<u64>;
- type Endian: endian::Endian;
-
- fn d_tag(&self, endian: Self::Endian) -> Self::Word;
- fn d_val(&self, endian: Self::Endian) -> Self::Word;
-
- /// Try to convert the tag to a `u32`.
- fn tag32(&self, endian: Self::Endian) -> Option<u32> {
- self.d_tag(endian).into().try_into().ok()
- }
-
- /// Try to convert the value to a `u32`.
- fn val32(&self, endian: Self::Endian) -> Option<u32> {
- self.d_val(endian).into().try_into().ok()
- }
-
- /// Return true if the value is an offset in the dynamic string table.
- fn is_string(&self, endian: Self::Endian) -> bool {
- if let Some(tag) = self.tag32(endian) {
- match tag {
- elf::DT_NEEDED
- | elf::DT_SONAME
- | elf::DT_RPATH
- | elf::DT_RUNPATH
- | elf::DT_AUXILIARY
- | elf::DT_FILTER => true,
- _ => false,
- }
- } else {
- false
- }
- }
-
- /// Use the value to get a string in a string table.
- ///
- /// Does not check for an appropriate tag.
- fn string<'data>(
- &self,
- endian: Self::Endian,
- strings: StringTable<'data>,
- ) -> Result<&'data [u8]> {
- self.val32(endian)
- .and_then(|val| strings.get(val).ok())
- .read_error("Invalid ELF dyn string")
- }
-
- /// Return true if the value is an address.
- fn is_address(&self, endian: Self::Endian) -> bool {
- if let Some(tag) = self.tag32(endian) {
- match tag {
- elf::DT_PLTGOT
- | elf::DT_HASH
- | elf::DT_STRTAB
- | elf::DT_SYMTAB
- | elf::DT_RELA
- | elf::DT_INIT
- | elf::DT_FINI
- | elf::DT_SYMBOLIC
- | elf::DT_REL
- | elf::DT_DEBUG
- | elf::DT_JMPREL
- | elf::DT_FINI_ARRAY
- | elf::DT_INIT_ARRAY
- | elf::DT_PREINIT_ARRAY
- | elf::DT_SYMTAB_SHNDX
- | elf::DT_VERDEF
- | elf::DT_VERNEED
- | elf::DT_VERSYM
- | elf::DT_ADDRRNGLO..=elf::DT_ADDRRNGHI => true,
- _ => false,
- }
- } else {
- false
- }
- }
-}
-
-impl<Endian: endian::Endian> Dyn for elf::Dyn32<Endian> {
- type Word = u32;
- type Endian = Endian;
-
- #[inline]
- fn d_tag(&self, endian: Self::Endian) -> Self::Word {
- self.d_tag.get(endian)
- }
-
- #[inline]
- fn d_val(&self, endian: Self::Endian) -> Self::Word {
- self.d_val.get(endian)
- }
-}
-
-impl<Endian: endian::Endian> Dyn for elf::Dyn64<Endian> {
- type Word = u64;
- type Endian = Endian;
-
- #[inline]
- fn d_tag(&self, endian: Self::Endian) -> Self::Word {
- self.d_tag.get(endian)
- }
-
- #[inline]
- fn d_val(&self, endian: Self::Endian) -> Self::Word {
- self.d_val.get(endian)
- }
-}
diff --git a/vendor/object/src/read/elf/file.rs b/vendor/object/src/read/elf/file.rs
deleted file mode 100644
index 14ba568..0000000
--- a/vendor/object/src/read/elf/file.rs
+++ /dev/null
@@ -1,916 +0,0 @@
-use alloc::vec::Vec;
-use core::convert::TryInto;
-use core::fmt::Debug;
-use core::mem;
-
-use crate::read::{
- self, util, Architecture, ByteString, Bytes, Error, Export, FileFlags, Import, Object,
- ObjectKind, ReadError, ReadRef, SectionIndex, StringTable, SymbolIndex,
-};
-use crate::{elf, endian, Endian, Endianness, Pod, U32};
-
-use super::{
- CompressionHeader, Dyn, ElfComdat, ElfComdatIterator, ElfDynamicRelocationIterator, ElfSection,
- ElfSectionIterator, ElfSegment, ElfSegmentIterator, ElfSymbol, ElfSymbolIterator,
- ElfSymbolTable, NoteHeader, ProgramHeader, Rel, Rela, RelocationSections, SectionHeader,
- SectionTable, Sym, SymbolTable,
-};
-
-/// A 32-bit ELF object file.
-///
-/// This is a file that starts with [`elf::FileHeader32`], and corresponds
-/// to [`crate::FileKind::Elf32`].
-pub type ElfFile32<'data, Endian = Endianness, R = &'data [u8]> =
- ElfFile<'data, elf::FileHeader32<Endian>, R>;
-/// A 64-bit ELF object file.
-///
-/// This is a file that starts with [`elf::FileHeader64`], and corresponds
-/// to [`crate::FileKind::Elf64`].
-pub type ElfFile64<'data, Endian = Endianness, R = &'data [u8]> =
- ElfFile<'data, elf::FileHeader64<Endian>, R>;
-
-/// A partially parsed ELF file.
-///
-/// Most functionality is provided by the [`Object`] trait implementation.
-#[derive(Debug)]
-pub struct ElfFile<'data, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) endian: Elf::Endian,
- pub(super) data: R,
- pub(super) header: &'data Elf,
- pub(super) segments: &'data [Elf::ProgramHeader],
- pub(super) sections: SectionTable<'data, Elf, R>,
- pub(super) relocations: RelocationSections,
- pub(super) symbols: SymbolTable<'data, Elf, R>,
- pub(super) dynamic_symbols: SymbolTable<'data, Elf, R>,
-}
-
-impl<'data, Elf, R> ElfFile<'data, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- /// Parse the raw ELF file data.
- pub fn parse(data: R) -> read::Result<Self> {
- let header = Elf::parse(data)?;
- let endian = header.endian()?;
- let segments = header.program_headers(endian, data)?;
- let sections = header.sections(endian, data)?;
- let symbols = sections.symbols(endian, data, elf::SHT_SYMTAB)?;
- // TODO: get dynamic symbols from DT_SYMTAB if there are no sections
- let dynamic_symbols = sections.symbols(endian, data, elf::SHT_DYNSYM)?;
- // The API we provide requires a mapping from section to relocations, so build it now.
- let relocations = sections.relocation_sections(endian, symbols.section())?;
-
- Ok(ElfFile {
- endian,
- data,
- header,
- segments,
- sections,
- relocations,
- symbols,
- dynamic_symbols,
- })
- }
-
- /// Returns the endianness.
- pub fn endian(&self) -> Elf::Endian {
- self.endian
- }
-
- /// Returns the raw data.
- pub fn data(&self) -> R {
- self.data
- }
-
- /// Returns the raw ELF file header.
- pub fn raw_header(&self) -> &'data Elf {
- self.header
- }
-
- /// Returns the raw ELF segments.
- pub fn raw_segments(&self) -> &'data [Elf::ProgramHeader] {
- self.segments
- }
-
- fn raw_section_by_name<'file>(
- &'file self,
- section_name: &[u8],
- ) -> Option<ElfSection<'data, 'file, Elf, R>> {
- self.sections
- .section_by_name(self.endian, section_name)
- .map(|(index, section)| ElfSection {
- file: self,
- index: SectionIndex(index),
- section,
- })
- }
-
- #[cfg(feature = "compression")]
- fn zdebug_section_by_name<'file>(
- &'file self,
- section_name: &[u8],
- ) -> Option<ElfSection<'data, 'file, Elf, R>> {
- if !section_name.starts_with(b".debug_") {
- return None;
- }
- let mut name = Vec::with_capacity(section_name.len() + 1);
- name.extend_from_slice(b".zdebug_");
- name.extend_from_slice(&section_name[7..]);
- self.raw_section_by_name(&name)
- }
-
- #[cfg(not(feature = "compression"))]
- fn zdebug_section_by_name<'file>(
- &'file self,
- _section_name: &[u8],
- ) -> Option<ElfSection<'data, 'file, Elf, R>> {
- None
- }
-}
-
-impl<'data, Elf, R> read::private::Sealed for ElfFile<'data, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Elf, R> Object<'data, 'file> for ElfFile<'data, Elf, R>
-where
- 'data: 'file,
- Elf: FileHeader,
- R: 'file + ReadRef<'data>,
-{
- type Segment = ElfSegment<'data, 'file, Elf, R>;
- type SegmentIterator = ElfSegmentIterator<'data, 'file, Elf, R>;
- type Section = ElfSection<'data, 'file, Elf, R>;
- type SectionIterator = ElfSectionIterator<'data, 'file, Elf, R>;
- type Comdat = ElfComdat<'data, 'file, Elf, R>;
- type ComdatIterator = ElfComdatIterator<'data, 'file, Elf, R>;
- type Symbol = ElfSymbol<'data, 'file, Elf, R>;
- type SymbolIterator = ElfSymbolIterator<'data, 'file, Elf, R>;
- type SymbolTable = ElfSymbolTable<'data, 'file, Elf, R>;
- type DynamicRelocationIterator = ElfDynamicRelocationIterator<'data, 'file, Elf, R>;
-
- fn architecture(&self) -> Architecture {
- match (
- self.header.e_machine(self.endian),
- self.header.is_class_64(),
- ) {
- (elf::EM_AARCH64, true) => Architecture::Aarch64,
- (elf::EM_AARCH64, false) => Architecture::Aarch64_Ilp32,
- (elf::EM_ARM, _) => Architecture::Arm,
- (elf::EM_AVR, _) => Architecture::Avr,
- (elf::EM_BPF, _) => Architecture::Bpf,
- (elf::EM_CSKY, _) => Architecture::Csky,
- (elf::EM_386, _) => Architecture::I386,
- (elf::EM_X86_64, false) => Architecture::X86_64_X32,
- (elf::EM_X86_64, true) => Architecture::X86_64,
- (elf::EM_HEXAGON, _) => Architecture::Hexagon,
- (elf::EM_LOONGARCH, true) => Architecture::LoongArch64,
- (elf::EM_MIPS, false) => Architecture::Mips,
- (elf::EM_MIPS, true) => Architecture::Mips64,
- (elf::EM_MSP430, _) => Architecture::Msp430,
- (elf::EM_PPC, _) => Architecture::PowerPc,
- (elf::EM_PPC64, _) => Architecture::PowerPc64,
- (elf::EM_RISCV, false) => Architecture::Riscv32,
- (elf::EM_RISCV, true) => Architecture::Riscv64,
- // This is either s390 or s390x, depending on the ELF class.
- // We only support the 64-bit variant s390x here.
- (elf::EM_S390, true) => Architecture::S390x,
- (elf::EM_SBF, _) => Architecture::Sbf,
- (elf::EM_SHARC, false) => Architecture::Sharc,
- (elf::EM_SPARCV9, true) => Architecture::Sparc64,
- (elf::EM_XTENSA, false) => Architecture::Xtensa,
- _ => Architecture::Unknown,
- }
- }
-
- #[inline]
- fn is_little_endian(&self) -> bool {
- self.header.is_little_endian()
- }
-
- #[inline]
- fn is_64(&self) -> bool {
- self.header.is_class_64()
- }
-
- fn kind(&self) -> ObjectKind {
- match self.header.e_type(self.endian) {
- elf::ET_REL => ObjectKind::Relocatable,
- elf::ET_EXEC => ObjectKind::Executable,
- // TODO: check for `DF_1_PIE`?
- elf::ET_DYN => ObjectKind::Dynamic,
- elf::ET_CORE => ObjectKind::Core,
- _ => ObjectKind::Unknown,
- }
- }
-
- fn segments(&'file self) -> ElfSegmentIterator<'data, 'file, Elf, R> {
- ElfSegmentIterator {
- file: self,
- iter: self.segments.iter(),
- }
- }
-
- fn section_by_name_bytes(
- &'file self,
- section_name: &[u8],
- ) -> Option<ElfSection<'data, 'file, Elf, R>> {
- self.raw_section_by_name(section_name)
- .or_else(|| self.zdebug_section_by_name(section_name))
- }
-
- fn section_by_index(
- &'file self,
- index: SectionIndex,
- ) -> read::Result<ElfSection<'data, 'file, Elf, R>> {
- let section = self.sections.section(index)?;
- Ok(ElfSection {
- file: self,
- index,
- section,
- })
- }
-
- fn sections(&'file self) -> ElfSectionIterator<'data, 'file, Elf, R> {
- ElfSectionIterator {
- file: self,
- iter: self.sections.iter().enumerate(),
- }
- }
-
- fn comdats(&'file self) -> ElfComdatIterator<'data, 'file, Elf, R> {
- ElfComdatIterator {
- file: self,
- iter: self.sections.iter().enumerate(),
- }
- }
-
- fn symbol_by_index(
- &'file self,
- index: SymbolIndex,
- ) -> read::Result<ElfSymbol<'data, 'file, Elf, R>> {
- let symbol = self.symbols.symbol(index.0)?;
- Ok(ElfSymbol {
- endian: self.endian,
- symbols: &self.symbols,
- index,
- symbol,
- })
- }
-
- fn symbols(&'file self) -> ElfSymbolIterator<'data, 'file, Elf, R> {
- ElfSymbolIterator {
- endian: self.endian,
- symbols: &self.symbols,
- index: 0,
- }
- }
-
- fn symbol_table(&'file self) -> Option<ElfSymbolTable<'data, 'file, Elf, R>> {
- if self.symbols.is_empty() {
- return None;
- }
- Some(ElfSymbolTable {
- endian: self.endian,
- symbols: &self.symbols,
- })
- }
-
- fn dynamic_symbols(&'file self) -> ElfSymbolIterator<'data, 'file, Elf, R> {
- ElfSymbolIterator {
- endian: self.endian,
- symbols: &self.dynamic_symbols,
- index: 0,
- }
- }
-
- fn dynamic_symbol_table(&'file self) -> Option<ElfSymbolTable<'data, 'file, Elf, R>> {
- if self.dynamic_symbols.is_empty() {
- return None;
- }
- Some(ElfSymbolTable {
- endian: self.endian,
- symbols: &self.dynamic_symbols,
- })
- }
-
- fn dynamic_relocations(
- &'file self,
- ) -> Option<ElfDynamicRelocationIterator<'data, 'file, Elf, R>> {
- Some(ElfDynamicRelocationIterator {
- section_index: SectionIndex(1),
- file: self,
- relocations: None,
- })
- }
-
- fn imports(&self) -> read::Result<Vec<Import<'data>>> {
- let mut imports = Vec::new();
- for symbol in self.dynamic_symbols.iter() {
- if symbol.is_undefined(self.endian) {
- let name = symbol.name(self.endian, self.dynamic_symbols.strings())?;
- if !name.is_empty() {
- // TODO: use symbol versioning to determine library
- imports.push(Import {
- name: ByteString(name),
- library: ByteString(&[]),
- });
- }
- }
- }
- Ok(imports)
- }
-
- fn exports(&self) -> read::Result<Vec<Export<'data>>> {
- let mut exports = Vec::new();
- for symbol in self.dynamic_symbols.iter() {
- if symbol.is_definition(self.endian) {
- let name = symbol.name(self.endian, self.dynamic_symbols.strings())?;
- let address = symbol.st_value(self.endian).into();
- exports.push(Export {
- name: ByteString(name),
- address,
- });
- }
- }
- Ok(exports)
- }
-
- fn has_debug_symbols(&self) -> bool {
- for section in self.sections.iter() {
- if let Ok(name) = self.sections.section_name(self.endian, section) {
- if name == b".debug_info" || name == b".zdebug_info" {
- return true;
- }
- }
- }
- false
- }
-
- fn build_id(&self) -> read::Result<Option<&'data [u8]>> {
- let endian = self.endian;
- // Use section headers if present, otherwise use program headers.
- if !self.sections.is_empty() {
- for section in self.sections.iter() {
- if let Some(mut notes) = section.notes(endian, self.data)? {
- while let Some(note) = notes.next()? {
- if note.name() == elf::ELF_NOTE_GNU
- && note.n_type(endian) == elf::NT_GNU_BUILD_ID
- {
- return Ok(Some(note.desc()));
- }
- }
- }
- }
- } else {
- for segment in self.segments {
- if let Some(mut notes) = segment.notes(endian, self.data)? {
- while let Some(note) = notes.next()? {
- if note.name() == elf::ELF_NOTE_GNU
- && note.n_type(endian) == elf::NT_GNU_BUILD_ID
- {
- return Ok(Some(note.desc()));
- }
- }
- }
- }
- }
- Ok(None)
- }
-
- fn gnu_debuglink(&self) -> read::Result<Option<(&'data [u8], u32)>> {
- let section = match self.raw_section_by_name(b".gnu_debuglink") {
- Some(section) => section,
- None => return Ok(None),
- };
- let data = section
- .section
- .data(self.endian, self.data)
- .read_error("Invalid ELF .gnu_debuglink section offset or size")
- .map(Bytes)?;
- let filename = data
- .read_string_at(0)
- .read_error("Missing ELF .gnu_debuglink filename")?;
- let crc_offset = util::align(filename.len() + 1, 4);
- let crc = data
- .read_at::<U32<_>>(crc_offset)
- .read_error("Missing ELF .gnu_debuglink crc")?
- .get(self.endian);
- Ok(Some((filename, crc)))
- }
-
- fn gnu_debugaltlink(&self) -> read::Result<Option<(&'data [u8], &'data [u8])>> {
- let section = match self.raw_section_by_name(b".gnu_debugaltlink") {
- Some(section) => section,
- None => return Ok(None),
- };
- let mut data = section
- .section
- .data(self.endian, self.data)
- .read_error("Invalid ELF .gnu_debugaltlink section offset or size")
- .map(Bytes)?;
- let filename = data
- .read_string()
- .read_error("Missing ELF .gnu_debugaltlink filename")?;
- let build_id = data.0;
- Ok(Some((filename, build_id)))
- }
-
- fn relative_address_base(&self) -> u64 {
- 0
- }
-
- fn entry(&self) -> u64 {
- self.header.e_entry(self.endian).into()
- }
-
- fn flags(&self) -> FileFlags {
- FileFlags::Elf {
- os_abi: self.header.e_ident().os_abi,
- abi_version: self.header.e_ident().abi_version,
- e_flags: self.header.e_flags(self.endian),
- }
- }
-}
-
-/// A trait for generic access to [`elf::FileHeader32`] and [`elf::FileHeader64`].
-#[allow(missing_docs)]
-pub trait FileHeader: Debug + Pod {
- // Ideally this would be a `u64: From<Word>`, but can't express that.
- type Word: Into<u64>;
- type Sword: Into<i64>;
- type Endian: endian::Endian;
- type ProgramHeader: ProgramHeader<Elf = Self, Endian = Self::Endian, Word = Self::Word>;
- type SectionHeader: SectionHeader<Elf = Self, Endian = Self::Endian, Word = Self::Word>;
- type CompressionHeader: CompressionHeader<Endian = Self::Endian, Word = Self::Word>;
- type NoteHeader: NoteHeader<Endian = Self::Endian>;
- type Dyn: Dyn<Endian = Self::Endian, Word = Self::Word>;
- type Sym: Sym<Endian = Self::Endian, Word = Self::Word>;
- type Rel: Rel<Endian = Self::Endian, Word = Self::Word>;
- type Rela: Rela<Endian = Self::Endian, Word = Self::Word> + From<Self::Rel>;
-
- /// Return true if this type is a 64-bit header.
- ///
- /// This is a property of the type, not a value in the header data.
- fn is_type_64(&self) -> bool;
-
- /// Return true if this type is a 64-bit header.
- ///
- /// This is a property of the type, not a value in the header data.
- ///
- /// This is the same as [`Self::is_type_64`], but is non-dispatchable.
- fn is_type_64_sized() -> bool
- where
- Self: Sized;
-
- fn e_ident(&self) -> &elf::Ident;
- fn e_type(&self, endian: Self::Endian) -> u16;
- fn e_machine(&self, endian: Self::Endian) -> u16;
- fn e_version(&self, endian: Self::Endian) -> u32;
- fn e_entry(&self, endian: Self::Endian) -> Self::Word;
- fn e_phoff(&self, endian: Self::Endian) -> Self::Word;
- fn e_shoff(&self, endian: Self::Endian) -> Self::Word;
- fn e_flags(&self, endian: Self::Endian) -> u32;
- fn e_ehsize(&self, endian: Self::Endian) -> u16;
- fn e_phentsize(&self, endian: Self::Endian) -> u16;
- fn e_phnum(&self, endian: Self::Endian) -> u16;
- fn e_shentsize(&self, endian: Self::Endian) -> u16;
- fn e_shnum(&self, endian: Self::Endian) -> u16;
- fn e_shstrndx(&self, endian: Self::Endian) -> u16;
-
- // Provided methods.
-
- /// Read the file header.
- ///
- /// Also checks that the ident field in the file header is a supported format.
- fn parse<'data, R: ReadRef<'data>>(data: R) -> read::Result<&'data Self> {
- let header = data
- .read_at::<Self>(0)
- .read_error("Invalid ELF header size or alignment")?;
- if !header.is_supported() {
- return Err(Error("Unsupported ELF header"));
- }
- // TODO: Check self.e_ehsize?
- Ok(header)
- }
-
- /// Check that the ident field in the file header is a supported format.
- ///
- /// This checks the magic number, version, class, and endianness.
- fn is_supported(&self) -> bool {
- let ident = self.e_ident();
- // TODO: Check self.e_version too? Requires endian though.
- ident.magic == elf::ELFMAG
- && (self.is_type_64() || self.is_class_32())
- && (!self.is_type_64() || self.is_class_64())
- && (self.is_little_endian() || self.is_big_endian())
- && ident.version == elf::EV_CURRENT
- }
-
- fn is_class_32(&self) -> bool {
- self.e_ident().class == elf::ELFCLASS32
- }
-
- fn is_class_64(&self) -> bool {
- self.e_ident().class == elf::ELFCLASS64
- }
-
- fn is_little_endian(&self) -> bool {
- self.e_ident().data == elf::ELFDATA2LSB
- }
-
- fn is_big_endian(&self) -> bool {
- self.e_ident().data == elf::ELFDATA2MSB
- }
-
- fn endian(&self) -> read::Result<Self::Endian> {
- Self::Endian::from_big_endian(self.is_big_endian()).read_error("Unsupported ELF endian")
- }
-
- /// Return the first section header, if present.
- ///
- /// Section 0 is a special case because getting the section headers normally
- /// requires `shnum`, but `shnum` may be in the first section header.
- fn section_0<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<&'data Self::SectionHeader>> {
- let shoff: u64 = self.e_shoff(endian).into();
- if shoff == 0 {
- // No section headers is ok.
- return Ok(None);
- }
- let shentsize = usize::from(self.e_shentsize(endian));
- if shentsize != mem::size_of::<Self::SectionHeader>() {
- // Section header size must match.
- return Err(Error("Invalid ELF section header entry size"));
- }
- data.read_at(shoff)
- .map(Some)
- .read_error("Invalid ELF section header offset or size")
- }
-
- /// Return the `e_phnum` field of the header. Handles extended values.
- ///
- /// Returns `Err` for invalid values.
- fn phnum<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<usize> {
- let e_phnum = self.e_phnum(endian);
- if e_phnum < elf::PN_XNUM {
- Ok(e_phnum as usize)
- } else if let Some(section_0) = self.section_0(endian, data)? {
- Ok(section_0.sh_info(endian) as usize)
- } else {
- // Section 0 must exist if e_phnum overflows.
- Err(Error("Missing ELF section headers for e_phnum overflow"))
- }
- }
-
- /// Return the `e_shnum` field of the header. Handles extended values.
- ///
- /// Returns `Err` for invalid values.
- fn shnum<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<usize> {
- let e_shnum = self.e_shnum(endian);
- if e_shnum > 0 {
- Ok(e_shnum as usize)
- } else if let Some(section_0) = self.section_0(endian, data)? {
- section_0
- .sh_size(endian)
- .into()
- .try_into()
- .ok()
- .read_error("Invalid ELF extended e_shnum")
- } else {
- // No section headers is ok.
- Ok(0)
- }
- }
-
- /// Return the `e_shstrndx` field of the header. Handles extended values.
- ///
- /// Returns `Err` for invalid values (including if the index is 0).
- fn shstrndx<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<u32> {
- let e_shstrndx = self.e_shstrndx(endian);
- let index = if e_shstrndx != elf::SHN_XINDEX {
- e_shstrndx.into()
- } else if let Some(section_0) = self.section_0(endian, data)? {
- section_0.sh_link(endian)
- } else {
- // Section 0 must exist if we're trying to read e_shstrndx.
- return Err(Error("Missing ELF section headers for e_shstrndx overflow"));
- };
- if index == 0 {
- return Err(Error("Missing ELF e_shstrndx"));
- }
- Ok(index)
- }
-
- /// Return the slice of program headers.
- ///
- /// Returns `Ok(&[])` if there are no program headers.
- /// Returns `Err` for invalid values.
- fn program_headers<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<&'data [Self::ProgramHeader]> {
- let phoff: u64 = self.e_phoff(endian).into();
- if phoff == 0 {
- // No program headers is ok.
- return Ok(&[]);
- }
- let phnum = self.phnum(endian, data)?;
- if phnum == 0 {
- // No program headers is ok.
- return Ok(&[]);
- }
- let phentsize = self.e_phentsize(endian) as usize;
- if phentsize != mem::size_of::<Self::ProgramHeader>() {
- // Program header size must match.
- return Err(Error("Invalid ELF program header entry size"));
- }
- data.read_slice_at(phoff, phnum)
- .read_error("Invalid ELF program header size or alignment")
- }
-
- /// Return the slice of section headers.
- ///
- /// Returns `Ok(&[])` if there are no section headers.
- /// Returns `Err` for invalid values.
- fn section_headers<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<&'data [Self::SectionHeader]> {
- let shoff: u64 = self.e_shoff(endian).into();
- if shoff == 0 {
- // No section headers is ok.
- return Ok(&[]);
- }
- let shnum = self.shnum(endian, data)?;
- if shnum == 0 {
- // No section headers is ok.
- return Ok(&[]);
- }
- let shentsize = usize::from(self.e_shentsize(endian));
- if shentsize != mem::size_of::<Self::SectionHeader>() {
- // Section header size must match.
- return Err(Error("Invalid ELF section header entry size"));
- }
- data.read_slice_at(shoff, shnum)
- .read_error("Invalid ELF section header offset/size/alignment")
- }
-
- /// Return the string table for the section headers.
- fn section_strings<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- sections: &[Self::SectionHeader],
- ) -> read::Result<StringTable<'data, R>> {
- if sections.is_empty() {
- return Ok(StringTable::default());
- }
- let index = self.shstrndx(endian, data)? as usize;
- let shstrtab = sections.get(index).read_error("Invalid ELF e_shstrndx")?;
- let strings = if let Some((shstrtab_offset, shstrtab_size)) = shstrtab.file_range(endian) {
- let shstrtab_end = shstrtab_offset
- .checked_add(shstrtab_size)
- .read_error("Invalid ELF shstrtab size")?;
- StringTable::new(data, shstrtab_offset, shstrtab_end)
- } else {
- StringTable::default()
- };
- Ok(strings)
- }
-
- /// Return the section table.
- fn sections<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<SectionTable<'data, Self, R>> {
- let sections = self.section_headers(endian, data)?;
- let strings = self.section_strings(endian, data, sections)?;
- Ok(SectionTable::new(sections, strings))
- }
-
- /// Returns whether this is a mips64el elf file.
- fn is_mips64el(&self, endian: Self::Endian) -> bool {
- self.is_class_64() && self.is_little_endian() && self.e_machine(endian) == elf::EM_MIPS
- }
-}
-
-impl<Endian: endian::Endian> FileHeader for elf::FileHeader32<Endian> {
- type Word = u32;
- type Sword = i32;
- type Endian = Endian;
- type ProgramHeader = elf::ProgramHeader32<Endian>;
- type SectionHeader = elf::SectionHeader32<Endian>;
- type CompressionHeader = elf::CompressionHeader32<Endian>;
- type NoteHeader = elf::NoteHeader32<Endian>;
- type Dyn = elf::Dyn32<Endian>;
- type Sym = elf::Sym32<Endian>;
- type Rel = elf::Rel32<Endian>;
- type Rela = elf::Rela32<Endian>;
-
- #[inline]
- fn is_type_64(&self) -> bool {
- false
- }
-
- #[inline]
- fn is_type_64_sized() -> bool
- where
- Self: Sized,
- {
- false
- }
-
- #[inline]
- fn e_ident(&self) -> &elf::Ident {
- &self.e_ident
- }
-
- #[inline]
- fn e_type(&self, endian: Self::Endian) -> u16 {
- self.e_type.get(endian)
- }
-
- #[inline]
- fn e_machine(&self, endian: Self::Endian) -> u16 {
- self.e_machine.get(endian)
- }
-
- #[inline]
- fn e_version(&self, endian: Self::Endian) -> u32 {
- self.e_version.get(endian)
- }
-
- #[inline]
- fn e_entry(&self, endian: Self::Endian) -> Self::Word {
- self.e_entry.get(endian)
- }
-
- #[inline]
- fn e_phoff(&self, endian: Self::Endian) -> Self::Word {
- self.e_phoff.get(endian)
- }
-
- #[inline]
- fn e_shoff(&self, endian: Self::Endian) -> Self::Word {
- self.e_shoff.get(endian)
- }
-
- #[inline]
- fn e_flags(&self, endian: Self::Endian) -> u32 {
- self.e_flags.get(endian)
- }
-
- #[inline]
- fn e_ehsize(&self, endian: Self::Endian) -> u16 {
- self.e_ehsize.get(endian)
- }
-
- #[inline]
- fn e_phentsize(&self, endian: Self::Endian) -> u16 {
- self.e_phentsize.get(endian)
- }
-
- #[inline]
- fn e_phnum(&self, endian: Self::Endian) -> u16 {
- self.e_phnum.get(endian)
- }
-
- #[inline]
- fn e_shentsize(&self, endian: Self::Endian) -> u16 {
- self.e_shentsize.get(endian)
- }
-
- #[inline]
- fn e_shnum(&self, endian: Self::Endian) -> u16 {
- self.e_shnum.get(endian)
- }
-
- #[inline]
- fn e_shstrndx(&self, endian: Self::Endian) -> u16 {
- self.e_shstrndx.get(endian)
- }
-}
-
-impl<Endian: endian::Endian> FileHeader for elf::FileHeader64<Endian> {
- type Word = u64;
- type Sword = i64;
- type Endian = Endian;
- type ProgramHeader = elf::ProgramHeader64<Endian>;
- type SectionHeader = elf::SectionHeader64<Endian>;
- type CompressionHeader = elf::CompressionHeader64<Endian>;
- type NoteHeader = elf::NoteHeader32<Endian>;
- type Dyn = elf::Dyn64<Endian>;
- type Sym = elf::Sym64<Endian>;
- type Rel = elf::Rel64<Endian>;
- type Rela = elf::Rela64<Endian>;
-
- #[inline]
- fn is_type_64(&self) -> bool {
- true
- }
-
- #[inline]
- fn is_type_64_sized() -> bool
- where
- Self: Sized,
- {
- true
- }
-
- #[inline]
- fn e_ident(&self) -> &elf::Ident {
- &self.e_ident
- }
-
- #[inline]
- fn e_type(&self, endian: Self::Endian) -> u16 {
- self.e_type.get(endian)
- }
-
- #[inline]
- fn e_machine(&self, endian: Self::Endian) -> u16 {
- self.e_machine.get(endian)
- }
-
- #[inline]
- fn e_version(&self, endian: Self::Endian) -> u32 {
- self.e_version.get(endian)
- }
-
- #[inline]
- fn e_entry(&self, endian: Self::Endian) -> Self::Word {
- self.e_entry.get(endian)
- }
-
- #[inline]
- fn e_phoff(&self, endian: Self::Endian) -> Self::Word {
- self.e_phoff.get(endian)
- }
-
- #[inline]
- fn e_shoff(&self, endian: Self::Endian) -> Self::Word {
- self.e_shoff.get(endian)
- }
-
- #[inline]
- fn e_flags(&self, endian: Self::Endian) -> u32 {
- self.e_flags.get(endian)
- }
-
- #[inline]
- fn e_ehsize(&self, endian: Self::Endian) -> u16 {
- self.e_ehsize.get(endian)
- }
-
- #[inline]
- fn e_phentsize(&self, endian: Self::Endian) -> u16 {
- self.e_phentsize.get(endian)
- }
-
- #[inline]
- fn e_phnum(&self, endian: Self::Endian) -> u16 {
- self.e_phnum.get(endian)
- }
-
- #[inline]
- fn e_shentsize(&self, endian: Self::Endian) -> u16 {
- self.e_shentsize.get(endian)
- }
-
- #[inline]
- fn e_shnum(&self, endian: Self::Endian) -> u16 {
- self.e_shnum.get(endian)
- }
-
- #[inline]
- fn e_shstrndx(&self, endian: Self::Endian) -> u16 {
- self.e_shstrndx.get(endian)
- }
-}
diff --git a/vendor/object/src/read/elf/hash.rs b/vendor/object/src/read/elf/hash.rs
deleted file mode 100644
index b0130cc..0000000
--- a/vendor/object/src/read/elf/hash.rs
+++ /dev/null
@@ -1,224 +0,0 @@
-use core::mem;
-
-use crate::elf;
-use crate::read::{ReadError, ReadRef, Result};
-use crate::{U32, U64};
-
-use super::{FileHeader, Sym, SymbolTable, Version, VersionTable};
-
-/// A SysV symbol hash table in an ELF file.
-///
-/// Returned by [`SectionHeader::hash`](super::SectionHeader::hash).
-#[derive(Debug)]
-pub struct HashTable<'data, Elf: FileHeader> {
- buckets: &'data [U32<Elf::Endian>],
- chains: &'data [U32<Elf::Endian>],
-}
-
-impl<'data, Elf: FileHeader> HashTable<'data, Elf> {
- /// Parse a SysV hash table.
- ///
- /// `data` should be from an [`elf::SHT_HASH`] section, or from a
- /// segment pointed to via the [`elf::DT_HASH`] entry.
- ///
- /// The header is read at offset 0 in the given `data`.
- pub fn parse(endian: Elf::Endian, data: &'data [u8]) -> Result<Self> {
- let mut offset = 0;
- let header = data
- .read::<elf::HashHeader<Elf::Endian>>(&mut offset)
- .read_error("Invalid hash header")?;
- let buckets = data
- .read_slice(&mut offset, header.bucket_count.get(endian) as usize)
- .read_error("Invalid hash buckets")?;
- let chains = data
- .read_slice(&mut offset, header.chain_count.get(endian) as usize)
- .read_error("Invalid hash chains")?;
- Ok(HashTable { buckets, chains })
- }
-
- /// Return the symbol table length.
- pub fn symbol_table_length(&self) -> u32 {
- self.chains.len() as u32
- }
-
- /// Use the hash table to find the symbol table entry with the given name, hash and version.
- pub fn find<R: ReadRef<'data>>(
- &self,
- endian: Elf::Endian,
- name: &[u8],
- hash: u32,
- version: Option<&Version<'_>>,
- symbols: &SymbolTable<'data, Elf, R>,
- versions: &VersionTable<'data, Elf>,
- ) -> Option<(usize, &'data Elf::Sym)> {
- // Get the chain start from the bucket for this hash.
- let mut index = self.buckets[(hash as usize) % self.buckets.len()].get(endian) as usize;
- // Avoid infinite loop.
- let mut i = 0;
- let strings = symbols.strings();
- while index != 0 && i < self.chains.len() {
- if let Ok(symbol) = symbols.symbol(index) {
- if symbol.name(endian, strings) == Ok(name)
- && versions.matches(endian, index, version)
- {
- return Some((index, symbol));
- }
- }
- index = self.chains.get(index)?.get(endian) as usize;
- i += 1;
- }
- None
- }
-}
-
-/// A GNU symbol hash table in an ELF file.
-///
-/// Returned by [`SectionHeader::gnu_hash`](super::SectionHeader::gnu_hash).
-#[derive(Debug)]
-pub struct GnuHashTable<'data, Elf: FileHeader> {
- symbol_base: u32,
- bloom_shift: u32,
- bloom_filters: &'data [u8],
- buckets: &'data [U32<Elf::Endian>],
- values: &'data [U32<Elf::Endian>],
-}
-
-impl<'data, Elf: FileHeader> GnuHashTable<'data, Elf> {
- /// Parse a GNU hash table.
- ///
- /// `data` should be from an [`elf::SHT_GNU_HASH`] section, or from a
- /// segment pointed to via the [`elf::DT_GNU_HASH`] entry.
- ///
- /// The header is read at offset 0 in the given `data`.
- ///
- /// The header does not contain a length field, and so all of `data`
- /// will be used as the hash table values. It does not matter if this
- /// is longer than needed, and this will often the case when accessing
- /// the hash table via the [`elf::DT_GNU_HASH`] entry.
- pub fn parse(endian: Elf::Endian, data: &'data [u8]) -> Result<Self> {
- let mut offset = 0;
- let header = data
- .read::<elf::GnuHashHeader<Elf::Endian>>(&mut offset)
- .read_error("Invalid GNU hash header")?;
- let bloom_len =
- u64::from(header.bloom_count.get(endian)) * mem::size_of::<Elf::Word>() as u64;
- let bloom_filters = data
- .read_bytes(&mut offset, bloom_len)
- .read_error("Invalid GNU hash bloom filters")?;
- let buckets = data
- .read_slice(&mut offset, header.bucket_count.get(endian) as usize)
- .read_error("Invalid GNU hash buckets")?;
- let chain_count = (data.len() - offset as usize) / 4;
- let values = data
- .read_slice(&mut offset, chain_count)
- .read_error("Invalid GNU hash values")?;
- Ok(GnuHashTable {
- symbol_base: header.symbol_base.get(endian),
- bloom_shift: header.bloom_shift.get(endian),
- bloom_filters,
- buckets,
- values,
- })
- }
-
- /// Return the symbol table index of the first symbol in the hash table.
- pub fn symbol_base(&self) -> u32 {
- self.symbol_base
- }
-
- /// Determine the symbol table length by finding the last entry in the hash table.
- ///
- /// Returns `None` if the hash table is empty or invalid.
- pub fn symbol_table_length(&self, endian: Elf::Endian) -> Option<u32> {
- // Ensure we find a non-empty bucket.
- if self.symbol_base == 0 {
- return None;
- }
-
- // Find the highest chain index in a bucket.
- let mut max_symbol = 0;
- for bucket in self.buckets {
- let bucket = bucket.get(endian);
- if max_symbol < bucket {
- max_symbol = bucket;
- }
- }
-
- // Find the end of the chain.
- for value in self
- .values
- .get(max_symbol.checked_sub(self.symbol_base)? as usize..)?
- {
- max_symbol += 1;
- if value.get(endian) & 1 != 0 {
- return Some(max_symbol);
- }
- }
-
- None
- }
-
- /// Use the hash table to find the symbol table entry with the given name, hash, and version.
- pub fn find<R: ReadRef<'data>>(
- &self,
- endian: Elf::Endian,
- name: &[u8],
- hash: u32,
- version: Option<&Version<'_>>,
- symbols: &SymbolTable<'data, Elf, R>,
- versions: &VersionTable<'data, Elf>,
- ) -> Option<(usize, &'data Elf::Sym)> {
- let word_bits = mem::size_of::<Elf::Word>() as u32 * 8;
-
- // Test against bloom filter.
- let bloom_count = self.bloom_filters.len() / mem::size_of::<Elf::Word>();
- let offset =
- ((hash / word_bits) & (bloom_count as u32 - 1)) * mem::size_of::<Elf::Word>() as u32;
- let filter = if word_bits == 64 {
- self.bloom_filters
- .read_at::<U64<Elf::Endian>>(offset.into())
- .ok()?
- .get(endian)
- } else {
- self.bloom_filters
- .read_at::<U32<Elf::Endian>>(offset.into())
- .ok()?
- .get(endian)
- .into()
- };
- if filter & (1 << (hash % word_bits)) == 0 {
- return None;
- }
- if filter & (1 << ((hash >> self.bloom_shift) % word_bits)) == 0 {
- return None;
- }
-
- // Get the chain start from the bucket for this hash.
- let mut index = self.buckets[(hash as usize) % self.buckets.len()].get(endian) as usize;
- if index == 0 {
- return None;
- }
-
- // Test symbols in the chain.
- let strings = symbols.strings();
- let symbols = symbols.symbols().get(index..)?;
- let values = self
- .values
- .get(index.checked_sub(self.symbol_base as usize)?..)?;
- for (symbol, value) in symbols.iter().zip(values.iter()) {
- let value = value.get(endian);
- if value | 1 == hash | 1 {
- if symbol.name(endian, strings) == Ok(name)
- && versions.matches(endian, index, version)
- {
- return Some((index, symbol));
- }
- }
- if value & 1 != 0 {
- break;
- }
- index += 1;
- }
- None
- }
-}
diff --git a/vendor/object/src/read/elf/mod.rs b/vendor/object/src/read/elf/mod.rs
deleted file mode 100644
index 66931bd..0000000
--- a/vendor/object/src/read/elf/mod.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-//! Support for reading ELF files.
-//!
-//! Traits are used to abstract over the difference between 32-bit and 64-bit ELF.
-//! The primary trait for this is [`FileHeader`].
-//!
-//! ## High level API
-//!
-//! [`ElfFile`] implements the [`Object`](crate::read::Object) trait for ELF files.
-//! [`ElfFile`] is parameterised by [`FileHeader`] to allow reading both 32-bit and
-//! 64-bit ELF. There are type aliases for these parameters ([`ElfFile32`] and
-//! [`ElfFile64`]).
-//!
-//! ## Low level API
-//!
-//! The [`FileHeader`] trait can be directly used to parse both [`elf::FileHeader32`]
-//! and [`elf::FileHeader64`].
-//!
-//! ### Example for low level API
-//! ```no_run
-//! use object::elf;
-//! use object::read::elf::{FileHeader, Sym};
-//! use std::error::Error;
-//! use std::fs;
-//!
-//! /// Reads a file and displays the name of each symbol.
-//! fn main() -> Result<(), Box<dyn Error>> {
-//! # #[cfg(feature = "std")] {
-//! let data = fs::read("path/to/binary")?;
-//! let elf = elf::FileHeader64::<object::Endianness>::parse(&*data)?;
-//! let endian = elf.endian()?;
-//! let sections = elf.sections(endian, &*data)?;
-//! let symbols = sections.symbols(endian, &*data, elf::SHT_SYMTAB)?;
-//! for symbol in symbols.iter() {
-//! let name = symbol.name(endian, symbols.strings())?;
-//! println!("{}", String::from_utf8_lossy(name));
-//! }
-//! # }
-//! Ok(())
-//! }
-//! ```
-#[cfg(doc)]
-use crate::elf;
-
-mod file;
-pub use file::*;
-
-mod segment;
-pub use segment::*;
-
-mod section;
-pub use section::*;
-
-mod symbol;
-pub use symbol::*;
-
-mod relocation;
-pub use relocation::*;
-
-mod comdat;
-pub use comdat::*;
-
-mod dynamic;
-pub use dynamic::*;
-
-mod compression;
-pub use compression::*;
-
-mod note;
-pub use note::*;
-
-mod hash;
-pub use hash::*;
-
-mod version;
-pub use version::*;
-
-mod attributes;
-pub use attributes::*;
diff --git a/vendor/object/src/read/elf/note.rs b/vendor/object/src/read/elf/note.rs
deleted file mode 100644
index e2beef9..0000000
--- a/vendor/object/src/read/elf/note.rs
+++ /dev/null
@@ -1,271 +0,0 @@
-use core::fmt::Debug;
-use core::mem;
-
-use crate::elf;
-use crate::endian::{self, U32};
-use crate::pod::Pod;
-use crate::read::util;
-use crate::read::{self, Bytes, Error, ReadError};
-
-use super::FileHeader;
-
-/// An iterator over the notes in an ELF section or segment.
-///
-/// Returned [`ProgramHeader::notes`](super::ProgramHeader::notes)
-/// and [`SectionHeader::notes`](super::SectionHeader::notes).
-#[derive(Debug)]
-pub struct NoteIterator<'data, Elf>
-where
- Elf: FileHeader,
-{
- endian: Elf::Endian,
- align: usize,
- data: Bytes<'data>,
-}
-
-impl<'data, Elf> NoteIterator<'data, Elf>
-where
- Elf: FileHeader,
-{
- /// An iterator over the notes in an ELF section or segment.
- ///
- /// `align` should be from the `p_align` field of the segment,
- /// or the `sh_addralign` field of the section. Supported values are
- /// either 4 or 8, but values less than 4 are treated as 4.
- /// This matches the behaviour of binutils.
- ///
- /// Returns `Err` if `align` is invalid.
- pub fn new(endian: Elf::Endian, align: Elf::Word, data: &'data [u8]) -> read::Result<Self> {
- let align = match align.into() {
- 0u64..=4 => 4,
- 8 => 8,
- _ => return Err(Error("Invalid ELF note alignment")),
- };
- // TODO: check data alignment?
- Ok(NoteIterator {
- endian,
- align,
- data: Bytes(data),
- })
- }
-
- /// Returns the next note.
- pub fn next(&mut self) -> read::Result<Option<Note<'data, Elf>>> {
- let mut data = self.data;
- if data.is_empty() {
- return Ok(None);
- }
-
- let header = data
- .read_at::<Elf::NoteHeader>(0)
- .read_error("ELF note is too short")?;
-
- // The name has no alignment requirement.
- let offset = mem::size_of::<Elf::NoteHeader>();
- let namesz = header.n_namesz(self.endian) as usize;
- let name = data
- .read_bytes_at(offset, namesz)
- .read_error("Invalid ELF note namesz")?
- .0;
-
- // The descriptor must be aligned.
- let offset = util::align(offset + namesz, self.align);
- let descsz = header.n_descsz(self.endian) as usize;
- let desc = data
- .read_bytes_at(offset, descsz)
- .read_error("Invalid ELF note descsz")?
- .0;
-
- // The next note (if any) must be aligned.
- let offset = util::align(offset + descsz, self.align);
- if data.skip(offset).is_err() {
- data = Bytes(&[]);
- }
- self.data = data;
-
- Ok(Some(Note { header, name, desc }))
- }
-}
-
-/// A parsed [`NoteHeader`].
-#[derive(Debug)]
-pub struct Note<'data, Elf>
-where
- Elf: FileHeader,
-{
- header: &'data Elf::NoteHeader,
- name: &'data [u8],
- desc: &'data [u8],
-}
-
-impl<'data, Elf: FileHeader> Note<'data, Elf> {
- /// Return the `n_type` field of the `NoteHeader`.
- ///
- /// The meaning of this field is determined by `name`.
- pub fn n_type(&self, endian: Elf::Endian) -> u32 {
- self.header.n_type(endian)
- }
-
- /// Return the `n_namesz` field of the `NoteHeader`.
- pub fn n_namesz(&self, endian: Elf::Endian) -> u32 {
- self.header.n_namesz(endian)
- }
-
- /// Return the `n_descsz` field of the `NoteHeader`.
- pub fn n_descsz(&self, endian: Elf::Endian) -> u32 {
- self.header.n_descsz(endian)
- }
-
- /// Return the bytes for the name field following the `NoteHeader`.
- ///
- /// This field is usually a string including one or more trailing null bytes
- /// (but it is not required to be).
- ///
- /// The length of this field is given by `n_namesz`.
- pub fn name_bytes(&self) -> &'data [u8] {
- self.name
- }
-
- /// Return the bytes for the name field following the `NoteHeader`,
- /// excluding all trailing null bytes.
- pub fn name(&self) -> &'data [u8] {
- let mut name = self.name;
- while let [rest @ .., 0] = name {
- name = rest;
- }
- name
- }
-
- /// Return the bytes for the desc field following the `NoteHeader`.
- ///
- /// The length of this field is given by `n_descsz`. The meaning
- /// of this field is determined by `name` and `n_type`.
- pub fn desc(&self) -> &'data [u8] {
- self.desc
- }
-
- /// Return an iterator for properties if this note's type is [`elf::NT_GNU_PROPERTY_TYPE_0`].
- pub fn gnu_properties(
- &self,
- endian: Elf::Endian,
- ) -> Option<GnuPropertyIterator<'data, Elf::Endian>> {
- if self.name() != elf::ELF_NOTE_GNU || self.n_type(endian) != elf::NT_GNU_PROPERTY_TYPE_0 {
- return None;
- }
- // Use the ELF class instead of the section alignment.
- // This matches what other parsers do.
- let align = if Elf::is_type_64_sized() { 8 } else { 4 };
- Some(GnuPropertyIterator {
- endian,
- align,
- data: Bytes(self.desc),
- })
- }
-}
-
-/// A trait for generic access to [`elf::NoteHeader32`] and [`elf::NoteHeader64`].
-#[allow(missing_docs)]
-pub trait NoteHeader: Debug + Pod {
- type Endian: endian::Endian;
-
- fn n_namesz(&self, endian: Self::Endian) -> u32;
- fn n_descsz(&self, endian: Self::Endian) -> u32;
- fn n_type(&self, endian: Self::Endian) -> u32;
-}
-
-impl<Endian: endian::Endian> NoteHeader for elf::NoteHeader32<Endian> {
- type Endian = Endian;
-
- #[inline]
- fn n_namesz(&self, endian: Self::Endian) -> u32 {
- self.n_namesz.get(endian)
- }
-
- #[inline]
- fn n_descsz(&self, endian: Self::Endian) -> u32 {
- self.n_descsz.get(endian)
- }
-
- #[inline]
- fn n_type(&self, endian: Self::Endian) -> u32 {
- self.n_type.get(endian)
- }
-}
-
-impl<Endian: endian::Endian> NoteHeader for elf::NoteHeader64<Endian> {
- type Endian = Endian;
-
- #[inline]
- fn n_namesz(&self, endian: Self::Endian) -> u32 {
- self.n_namesz.get(endian)
- }
-
- #[inline]
- fn n_descsz(&self, endian: Self::Endian) -> u32 {
- self.n_descsz.get(endian)
- }
-
- #[inline]
- fn n_type(&self, endian: Self::Endian) -> u32 {
- self.n_type.get(endian)
- }
-}
-
-/// An iterator for the properties in a [`elf::NT_GNU_PROPERTY_TYPE_0`] note.
-///
-/// Returned by [`Note::gnu_properties`].
-#[derive(Debug)]
-pub struct GnuPropertyIterator<'data, Endian: endian::Endian> {
- endian: Endian,
- align: usize,
- data: Bytes<'data>,
-}
-
-impl<'data, Endian: endian::Endian> GnuPropertyIterator<'data, Endian> {
- /// Returns the next property.
- pub fn next(&mut self) -> read::Result<Option<GnuProperty<'data>>> {
- let mut data = self.data;
- if data.is_empty() {
- return Ok(None);
- }
-
- (|| -> Result<_, ()> {
- let pr_type = data.read_at::<U32<Endian>>(0)?.get(self.endian);
- let pr_datasz = data.read_at::<U32<Endian>>(4)?.get(self.endian) as usize;
- let pr_data = data.read_bytes_at(8, pr_datasz)?.0;
- data.skip(util::align(8 + pr_datasz, self.align))?;
- self.data = data;
- Ok(Some(GnuProperty { pr_type, pr_data }))
- })()
- .read_error("Invalid ELF GNU property")
- }
-}
-
-/// A property in a [`elf::NT_GNU_PROPERTY_TYPE_0`] note.
-#[derive(Debug)]
-pub struct GnuProperty<'data> {
- pr_type: u32,
- pr_data: &'data [u8],
-}
-
-impl<'data> GnuProperty<'data> {
- /// Return the property type.
- ///
- /// This is one of the `GNU_PROPERTY_*` constants.
- pub fn pr_type(&self) -> u32 {
- self.pr_type
- }
-
- /// Return the property data.
- pub fn pr_data(&self) -> &'data [u8] {
- self.pr_data
- }
-
- /// Parse the property data as an unsigned 32-bit integer.
- pub fn data_u32<E: endian::Endian>(&self, endian: E) -> read::Result<u32> {
- Bytes(self.pr_data)
- .read_at::<U32<E>>(0)
- .read_error("Invalid ELF GNU property data")
- .map(|val| val.get(endian))
- }
-}
diff --git a/vendor/object/src/read/elf/relocation.rs b/vendor/object/src/read/elf/relocation.rs
deleted file mode 100644
index aac1574..0000000
--- a/vendor/object/src/read/elf/relocation.rs
+++ /dev/null
@@ -1,628 +0,0 @@
-use alloc::fmt;
-use alloc::vec::Vec;
-use core::fmt::Debug;
-use core::slice;
-
-use crate::elf;
-use crate::endian::{self, Endianness};
-use crate::pod::Pod;
-use crate::read::{
- self, Error, ReadRef, Relocation, RelocationEncoding, RelocationKind, RelocationTarget,
- SectionIndex, SymbolIndex,
-};
-
-use super::{ElfFile, FileHeader, SectionHeader, SectionTable};
-
-/// A mapping from section index to associated relocation sections.
-#[derive(Debug)]
-pub struct RelocationSections {
- relocations: Vec<usize>,
-}
-
-impl RelocationSections {
- /// Create a new mapping using the section table.
- ///
- /// Skips relocation sections that do not use the given symbol table section.
- pub fn parse<'data, Elf: FileHeader, R: ReadRef<'data>>(
- endian: Elf::Endian,
- sections: &SectionTable<'data, Elf, R>,
- symbol_section: SectionIndex,
- ) -> read::Result<Self> {
- let mut relocations = vec![0; sections.len()];
- for (index, section) in sections.iter().enumerate().rev() {
- let sh_type = section.sh_type(endian);
- if sh_type == elf::SHT_REL || sh_type == elf::SHT_RELA {
- // The symbol indices used in relocations must be for the symbol table
- // we are expecting to use.
- let sh_link = SectionIndex(section.sh_link(endian) as usize);
- if sh_link != symbol_section {
- continue;
- }
-
- let sh_info = section.sh_info(endian) as usize;
- if sh_info == 0 {
- // Skip dynamic relocations.
- continue;
- }
- if sh_info >= relocations.len() {
- return Err(Error("Invalid ELF sh_info for relocation section"));
- }
-
- // Handle multiple relocation sections by chaining them.
- let next = relocations[sh_info];
- relocations[sh_info] = index;
- relocations[index] = next;
- }
- }
- Ok(Self { relocations })
- }
-
- /// Given a section index, return the section index of the associated relocation section.
- ///
- /// This may also be called with a relocation section index, and it will return the
- /// next associated relocation section.
- pub fn get(&self, index: usize) -> Option<usize> {
- self.relocations.get(index).cloned().filter(|x| *x != 0)
- }
-}
-
-pub(super) enum ElfRelaIterator<'data, Elf: FileHeader> {
- Rel(slice::Iter<'data, Elf::Rel>),
- Rela(slice::Iter<'data, Elf::Rela>),
-}
-
-impl<'data, Elf: FileHeader> ElfRelaIterator<'data, Elf> {
- fn is_rel(&self) -> bool {
- match self {
- ElfRelaIterator::Rel(_) => true,
- ElfRelaIterator::Rela(_) => false,
- }
- }
-}
-
-impl<'data, Elf: FileHeader> Iterator for ElfRelaIterator<'data, Elf> {
- type Item = Elf::Rela;
-
- fn next(&mut self) -> Option<Self::Item> {
- match self {
- ElfRelaIterator::Rel(ref mut i) => i.next().cloned().map(Self::Item::from),
- ElfRelaIterator::Rela(ref mut i) => i.next().cloned(),
- }
- }
-}
-
-/// An iterator for the dynamic relocations in an [`ElfFile32`](super::ElfFile32).
-pub type ElfDynamicRelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfDynamicRelocationIterator<'data, 'file, elf::FileHeader32<Endian>, R>;
-/// An iterator for the dynamic relocations in an [`ElfFile64`](super::ElfFile64).
-pub type ElfDynamicRelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfDynamicRelocationIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
-
-/// An iterator for the dynamic relocations in an [`ElfFile`].
-pub struct ElfDynamicRelocationIterator<'data, 'file, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- /// The current relocation section index.
- pub(super) section_index: SectionIndex,
- pub(super) file: &'file ElfFile<'data, Elf, R>,
- pub(super) relocations: Option<ElfRelaIterator<'data, Elf>>,
-}
-
-impl<'data, 'file, Elf, R> Iterator for ElfDynamicRelocationIterator<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- type Item = (u64, Relocation);
-
- fn next(&mut self) -> Option<Self::Item> {
- let endian = self.file.endian;
- loop {
- if let Some(ref mut relocations) = self.relocations {
- if let Some(reloc) = relocations.next() {
- let relocation =
- parse_relocation(self.file.header, endian, reloc, relocations.is_rel());
- return Some((reloc.r_offset(endian).into(), relocation));
- }
- self.relocations = None;
- }
-
- let section = self.file.sections.section(self.section_index).ok()?;
- self.section_index.0 += 1;
-
- let sh_link = SectionIndex(section.sh_link(endian) as usize);
- if sh_link != self.file.dynamic_symbols.section() {
- continue;
- }
-
- match section.sh_type(endian) {
- elf::SHT_REL => {
- if let Ok(relocations) = section.data_as_array(endian, self.file.data) {
- self.relocations = Some(ElfRelaIterator::Rel(relocations.iter()));
- }
- }
- elf::SHT_RELA => {
- if let Ok(relocations) = section.data_as_array(endian, self.file.data) {
- self.relocations = Some(ElfRelaIterator::Rela(relocations.iter()));
- }
- }
- _ => {}
- }
- }
- }
-}
-
-impl<'data, 'file, Elf, R> fmt::Debug for ElfDynamicRelocationIterator<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("ElfDynamicRelocationIterator").finish()
- }
-}
-
-/// An iterator for the relocations for an [`ElfSection32`](super::ElfSection32).
-pub type ElfSectionRelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSectionRelocationIterator<'data, 'file, elf::FileHeader32<Endian>, R>;
-/// An iterator for the relocations for an [`ElfSection64`](super::ElfSection64).
-pub type ElfSectionRelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSectionRelocationIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
-
-/// An iterator for the relocations for an [`ElfSection`](super::ElfSection).
-pub struct ElfSectionRelocationIterator<'data, 'file, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- /// The current pointer in the chain of relocation sections.
- pub(super) section_index: SectionIndex,
- pub(super) file: &'file ElfFile<'data, Elf, R>,
- pub(super) relocations: Option<ElfRelaIterator<'data, Elf>>,
-}
-
-impl<'data, 'file, Elf, R> Iterator for ElfSectionRelocationIterator<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- type Item = (u64, Relocation);
-
- fn next(&mut self) -> Option<Self::Item> {
- let endian = self.file.endian;
- loop {
- if let Some(ref mut relocations) = self.relocations {
- if let Some(reloc) = relocations.next() {
- let relocation =
- parse_relocation(self.file.header, endian, reloc, relocations.is_rel());
- return Some((reloc.r_offset(endian).into(), relocation));
- }
- self.relocations = None;
- }
- self.section_index = SectionIndex(self.file.relocations.get(self.section_index.0)?);
- // The construction of RelocationSections ensures section_index is valid.
- let section = self.file.sections.section(self.section_index).unwrap();
- match section.sh_type(endian) {
- elf::SHT_REL => {
- if let Ok(relocations) = section.data_as_array(endian, self.file.data) {
- self.relocations = Some(ElfRelaIterator::Rel(relocations.iter()));
- }
- }
- elf::SHT_RELA => {
- if let Ok(relocations) = section.data_as_array(endian, self.file.data) {
- self.relocations = Some(ElfRelaIterator::Rela(relocations.iter()));
- }
- }
- _ => {}
- }
- }
- }
-}
-
-impl<'data, 'file, Elf, R> fmt::Debug for ElfSectionRelocationIterator<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("ElfSectionRelocationIterator").finish()
- }
-}
-
-fn parse_relocation<Elf: FileHeader>(
- header: &Elf,
- endian: Elf::Endian,
- reloc: Elf::Rela,
- implicit_addend: bool,
-) -> Relocation {
- let mut encoding = RelocationEncoding::Generic;
- let is_mips64el = header.is_mips64el(endian);
- let (kind, size) = match header.e_machine(endian) {
- elf::EM_AARCH64 => {
- if header.is_type_64() {
- match reloc.r_type(endian, false) {
- elf::R_AARCH64_ABS64 => (RelocationKind::Absolute, 64),
- elf::R_AARCH64_ABS32 => (RelocationKind::Absolute, 32),
- elf::R_AARCH64_ABS16 => (RelocationKind::Absolute, 16),
- elf::R_AARCH64_PREL64 => (RelocationKind::Relative, 64),
- elf::R_AARCH64_PREL32 => (RelocationKind::Relative, 32),
- elf::R_AARCH64_PREL16 => (RelocationKind::Relative, 16),
- elf::R_AARCH64_CALL26 => {
- encoding = RelocationEncoding::AArch64Call;
- (RelocationKind::PltRelative, 26)
- }
- r_type => (RelocationKind::Elf(r_type), 0),
- }
- } else {
- match reloc.r_type(endian, false) {
- elf::R_AARCH64_P32_ABS32 => (RelocationKind::Absolute, 32),
- r_type => (RelocationKind::Elf(r_type), 0),
- }
- }
- }
- elf::EM_ARM => match reloc.r_type(endian, false) {
- elf::R_ARM_ABS32 => (RelocationKind::Absolute, 32),
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_AVR => match reloc.r_type(endian, false) {
- elf::R_AVR_32 => (RelocationKind::Absolute, 32),
- elf::R_AVR_16 => (RelocationKind::Absolute, 16),
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_BPF => match reloc.r_type(endian, false) {
- elf::R_BPF_64_64 => (RelocationKind::Absolute, 64),
- elf::R_BPF_64_32 => (RelocationKind::Absolute, 32),
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_CSKY => match reloc.r_type(endian, false) {
- elf::R_CKCORE_ADDR32 => (RelocationKind::Absolute, 32),
- elf::R_CKCORE_PCREL32 => (RelocationKind::Relative, 32),
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_386 => match reloc.r_type(endian, false) {
- elf::R_386_32 => (RelocationKind::Absolute, 32),
- elf::R_386_PC32 => (RelocationKind::Relative, 32),
- elf::R_386_GOT32 => (RelocationKind::Got, 32),
- elf::R_386_PLT32 => (RelocationKind::PltRelative, 32),
- elf::R_386_GOTOFF => (RelocationKind::GotBaseOffset, 32),
- elf::R_386_GOTPC => (RelocationKind::GotBaseRelative, 32),
- elf::R_386_16 => (RelocationKind::Absolute, 16),
- elf::R_386_PC16 => (RelocationKind::Relative, 16),
- elf::R_386_8 => (RelocationKind::Absolute, 8),
- elf::R_386_PC8 => (RelocationKind::Relative, 8),
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_X86_64 => match reloc.r_type(endian, false) {
- elf::R_X86_64_64 => (RelocationKind::Absolute, 64),
- elf::R_X86_64_PC32 => (RelocationKind::Relative, 32),
- elf::R_X86_64_GOT32 => (RelocationKind::Got, 32),
- elf::R_X86_64_PLT32 => (RelocationKind::PltRelative, 32),
- elf::R_X86_64_GOTPCREL => (RelocationKind::GotRelative, 32),
- elf::R_X86_64_32 => (RelocationKind::Absolute, 32),
- elf::R_X86_64_32S => {
- encoding = RelocationEncoding::X86Signed;
- (RelocationKind::Absolute, 32)
- }
- elf::R_X86_64_16 => (RelocationKind::Absolute, 16),
- elf::R_X86_64_PC16 => (RelocationKind::Relative, 16),
- elf::R_X86_64_8 => (RelocationKind::Absolute, 8),
- elf::R_X86_64_PC8 => (RelocationKind::Relative, 8),
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_HEXAGON => match reloc.r_type(endian, false) {
- elf::R_HEX_32 => (RelocationKind::Absolute, 32),
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_LOONGARCH => match reloc.r_type(endian, false) {
- elf::R_LARCH_32 => (RelocationKind::Absolute, 32),
- elf::R_LARCH_64 => (RelocationKind::Absolute, 64),
- elf::R_LARCH_32_PCREL => (RelocationKind::Relative, 32),
- elf::R_LARCH_64_PCREL => (RelocationKind::Relative, 64),
- elf::R_LARCH_B16 => {
- encoding = RelocationEncoding::LoongArchBranch;
- (RelocationKind::Relative, 16)
- }
- elf::R_LARCH_B21 => {
- encoding = RelocationEncoding::LoongArchBranch;
- (RelocationKind::Relative, 21)
- }
- elf::R_LARCH_B26 => {
- encoding = RelocationEncoding::LoongArchBranch;
- (RelocationKind::Relative, 26)
- }
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_MIPS => match reloc.r_type(endian, is_mips64el) {
- elf::R_MIPS_16 => (RelocationKind::Absolute, 16),
- elf::R_MIPS_32 => (RelocationKind::Absolute, 32),
- elf::R_MIPS_64 => (RelocationKind::Absolute, 64),
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_MSP430 => match reloc.r_type(endian, false) {
- elf::R_MSP430_32 => (RelocationKind::Absolute, 32),
- elf::R_MSP430_16_BYTE => (RelocationKind::Absolute, 16),
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_PPC => match reloc.r_type(endian, false) {
- elf::R_PPC_ADDR32 => (RelocationKind::Absolute, 32),
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_PPC64 => match reloc.r_type(endian, false) {
- elf::R_PPC64_ADDR32 => (RelocationKind::Absolute, 32),
- elf::R_PPC64_ADDR64 => (RelocationKind::Absolute, 64),
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_RISCV => match reloc.r_type(endian, false) {
- elf::R_RISCV_32 => (RelocationKind::Absolute, 32),
- elf::R_RISCV_64 => (RelocationKind::Absolute, 64),
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_S390 => match reloc.r_type(endian, false) {
- elf::R_390_8 => (RelocationKind::Absolute, 8),
- elf::R_390_16 => (RelocationKind::Absolute, 16),
- elf::R_390_32 => (RelocationKind::Absolute, 32),
- elf::R_390_64 => (RelocationKind::Absolute, 64),
- elf::R_390_PC16 => (RelocationKind::Relative, 16),
- elf::R_390_PC32 => (RelocationKind::Relative, 32),
- elf::R_390_PC64 => (RelocationKind::Relative, 64),
- elf::R_390_PC16DBL => {
- encoding = RelocationEncoding::S390xDbl;
- (RelocationKind::Relative, 16)
- }
- elf::R_390_PC32DBL => {
- encoding = RelocationEncoding::S390xDbl;
- (RelocationKind::Relative, 32)
- }
- elf::R_390_PLT16DBL => {
- encoding = RelocationEncoding::S390xDbl;
- (RelocationKind::PltRelative, 16)
- }
- elf::R_390_PLT32DBL => {
- encoding = RelocationEncoding::S390xDbl;
- (RelocationKind::PltRelative, 32)
- }
- elf::R_390_GOT16 => (RelocationKind::Got, 16),
- elf::R_390_GOT32 => (RelocationKind::Got, 32),
- elf::R_390_GOT64 => (RelocationKind::Got, 64),
- elf::R_390_GOTENT => {
- encoding = RelocationEncoding::S390xDbl;
- (RelocationKind::GotRelative, 32)
- }
- elf::R_390_GOTOFF16 => (RelocationKind::GotBaseOffset, 16),
- elf::R_390_GOTOFF32 => (RelocationKind::GotBaseOffset, 32),
- elf::R_390_GOTOFF64 => (RelocationKind::GotBaseOffset, 64),
- elf::R_390_GOTPC => (RelocationKind::GotBaseRelative, 64),
- elf::R_390_GOTPCDBL => {
- encoding = RelocationEncoding::S390xDbl;
- (RelocationKind::GotBaseRelative, 32)
- }
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_SBF => match reloc.r_type(endian, false) {
- elf::R_SBF_64_64 => (RelocationKind::Absolute, 64),
- elf::R_SBF_64_32 => (RelocationKind::Absolute, 32),
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_SHARC => match reloc.r_type(endian, false) {
- elf::R_SHARC_ADDR24_V3 => {
- encoding = RelocationEncoding::SharcTypeA;
- (RelocationKind::Absolute, 24)
- }
- elf::R_SHARC_ADDR32_V3 => {
- encoding = RelocationEncoding::SharcTypeA;
- (RelocationKind::Absolute, 32)
- }
- elf::R_SHARC_ADDR_VAR_V3 => {
- encoding = RelocationEncoding::Generic;
- (RelocationKind::Absolute, 32)
- }
- elf::R_SHARC_PCRSHORT_V3 => {
- encoding = RelocationEncoding::SharcTypeA;
- (RelocationKind::Relative, 6)
- }
- elf::R_SHARC_PCRLONG_V3 => {
- encoding = RelocationEncoding::SharcTypeA;
- (RelocationKind::Relative, 24)
- }
- elf::R_SHARC_DATA6_V3 => {
- encoding = RelocationEncoding::SharcTypeA;
- (RelocationKind::Absolute, 6)
- }
- elf::R_SHARC_DATA16_V3 => {
- encoding = RelocationEncoding::SharcTypeA;
- (RelocationKind::Absolute, 16)
- }
- elf::R_SHARC_DATA6_VISA_V3 => {
- encoding = RelocationEncoding::SharcTypeB;
- (RelocationKind::Absolute, 6)
- }
- elf::R_SHARC_DATA7_VISA_V3 => {
- encoding = RelocationEncoding::SharcTypeB;
- (RelocationKind::Absolute, 7)
- }
- elf::R_SHARC_DATA16_VISA_V3 => {
- encoding = RelocationEncoding::SharcTypeB;
- (RelocationKind::Absolute, 16)
- }
- elf::R_SHARC_PCR6_VISA_V3 => {
- encoding = RelocationEncoding::SharcTypeB;
- (RelocationKind::Relative, 16)
- }
- elf::R_SHARC_ADDR_VAR16_V3 => {
- encoding = RelocationEncoding::Generic;
- (RelocationKind::Absolute, 16)
- }
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- elf::EM_SPARC | elf::EM_SPARC32PLUS | elf::EM_SPARCV9 => {
- match reloc.r_type(endian, false) {
- elf::R_SPARC_32 | elf::R_SPARC_UA32 => (RelocationKind::Absolute, 32),
- elf::R_SPARC_64 | elf::R_SPARC_UA64 => (RelocationKind::Absolute, 64),
- r_type => (RelocationKind::Elf(r_type), 0),
- }
- }
- elf::EM_XTENSA => match reloc.r_type(endian, false) {
- elf::R_XTENSA_32 => (RelocationKind::Absolute, 32),
- elf::R_XTENSA_32_PCREL => (RelocationKind::Relative, 32),
- r_type => (RelocationKind::Elf(r_type), 0),
- },
- _ => (RelocationKind::Elf(reloc.r_type(endian, false)), 0),
- };
- let sym = reloc.r_sym(endian, is_mips64el) as usize;
- let target = if sym == 0 {
- RelocationTarget::Absolute
- } else {
- RelocationTarget::Symbol(SymbolIndex(sym))
- };
- Relocation {
- kind,
- encoding,
- size,
- target,
- addend: reloc.r_addend(endian).into(),
- implicit_addend,
- }
-}
-
-/// A trait for generic access to [`elf::Rel32`] and [`elf::Rel64`].
-#[allow(missing_docs)]
-pub trait Rel: Debug + Pod + Clone {
- type Word: Into<u64>;
- type Sword: Into<i64>;
- type Endian: endian::Endian;
-
- fn r_offset(&self, endian: Self::Endian) -> Self::Word;
- fn r_info(&self, endian: Self::Endian) -> Self::Word;
- fn r_sym(&self, endian: Self::Endian) -> u32;
- fn r_type(&self, endian: Self::Endian) -> u32;
-}
-
-impl<Endian: endian::Endian> Rel for elf::Rel32<Endian> {
- type Word = u32;
- type Sword = i32;
- type Endian = Endian;
-
- #[inline]
- fn r_offset(&self, endian: Self::Endian) -> Self::Word {
- self.r_offset.get(endian)
- }
-
- #[inline]
- fn r_info(&self, endian: Self::Endian) -> Self::Word {
- self.r_info.get(endian)
- }
-
- #[inline]
- fn r_sym(&self, endian: Self::Endian) -> u32 {
- self.r_sym(endian)
- }
-
- #[inline]
- fn r_type(&self, endian: Self::Endian) -> u32 {
- self.r_type(endian)
- }
-}
-
-impl<Endian: endian::Endian> Rel for elf::Rel64<Endian> {
- type Word = u64;
- type Sword = i64;
- type Endian = Endian;
-
- #[inline]
- fn r_offset(&self, endian: Self::Endian) -> Self::Word {
- self.r_offset.get(endian)
- }
-
- #[inline]
- fn r_info(&self, endian: Self::Endian) -> Self::Word {
- self.r_info.get(endian)
- }
-
- #[inline]
- fn r_sym(&self, endian: Self::Endian) -> u32 {
- self.r_sym(endian)
- }
-
- #[inline]
- fn r_type(&self, endian: Self::Endian) -> u32 {
- self.r_type(endian)
- }
-}
-
-/// A trait for generic access to [`elf::Rela32`] and [`elf::Rela64`].
-#[allow(missing_docs)]
-pub trait Rela: Debug + Pod + Clone {
- type Word: Into<u64>;
- type Sword: Into<i64>;
- type Endian: endian::Endian;
-
- fn r_offset(&self, endian: Self::Endian) -> Self::Word;
- fn r_info(&self, endian: Self::Endian, is_mips64el: bool) -> Self::Word;
- fn r_addend(&self, endian: Self::Endian) -> Self::Sword;
- fn r_sym(&self, endian: Self::Endian, is_mips64el: bool) -> u32;
- fn r_type(&self, endian: Self::Endian, is_mips64el: bool) -> u32;
-}
-
-impl<Endian: endian::Endian> Rela for elf::Rela32<Endian> {
- type Word = u32;
- type Sword = i32;
- type Endian = Endian;
-
- #[inline]
- fn r_offset(&self, endian: Self::Endian) -> Self::Word {
- self.r_offset.get(endian)
- }
-
- #[inline]
- fn r_info(&self, endian: Self::Endian, _is_mips64el: bool) -> Self::Word {
- self.r_info.get(endian)
- }
-
- #[inline]
- fn r_addend(&self, endian: Self::Endian) -> Self::Sword {
- self.r_addend.get(endian)
- }
-
- #[inline]
- fn r_sym(&self, endian: Self::Endian, _is_mips64el: bool) -> u32 {
- self.r_sym(endian)
- }
-
- #[inline]
- fn r_type(&self, endian: Self::Endian, _is_mips64el: bool) -> u32 {
- self.r_type(endian)
- }
-}
-
-impl<Endian: endian::Endian> Rela for elf::Rela64<Endian> {
- type Word = u64;
- type Sword = i64;
- type Endian = Endian;
-
- #[inline]
- fn r_offset(&self, endian: Self::Endian) -> Self::Word {
- self.r_offset.get(endian)
- }
-
- #[inline]
- fn r_info(&self, endian: Self::Endian, is_mips64el: bool) -> Self::Word {
- self.get_r_info(endian, is_mips64el)
- }
-
- #[inline]
- fn r_addend(&self, endian: Self::Endian) -> Self::Sword {
- self.r_addend.get(endian)
- }
-
- #[inline]
- fn r_sym(&self, endian: Self::Endian, is_mips64el: bool) -> u32 {
- self.r_sym(endian, is_mips64el)
- }
-
- #[inline]
- fn r_type(&self, endian: Self::Endian, is_mips64el: bool) -> u32 {
- self.r_type(endian, is_mips64el)
- }
-}
diff --git a/vendor/object/src/read/elf/section.rs b/vendor/object/src/read/elf/section.rs
deleted file mode 100644
index 2b5ae01..0000000
--- a/vendor/object/src/read/elf/section.rs
+++ /dev/null
@@ -1,1150 +0,0 @@
-use core::fmt::Debug;
-use core::{iter, mem, slice, str};
-
-use crate::elf;
-use crate::endian::{self, Endianness, U32Bytes};
-use crate::pod::Pod;
-use crate::read::{
- self, Bytes, CompressedData, CompressedFileRange, CompressionFormat, Error, ObjectSection,
- ReadError, ReadRef, SectionFlags, SectionIndex, SectionKind, StringTable,
-};
-
-use super::{
- AttributesSection, CompressionHeader, ElfFile, ElfSectionRelocationIterator, FileHeader,
- GnuHashTable, HashTable, NoteIterator, RelocationSections, SymbolTable, VerdefIterator,
- VerneedIterator, VersionTable,
-};
-
-/// The table of section headers in an ELF file.
-///
-/// Also includes the string table used for the section names.
-///
-/// Returned by [`FileHeader::sections`].
-#[derive(Debug, Default, Clone, Copy)]
-pub struct SectionTable<'data, Elf: FileHeader, R = &'data [u8]>
-where
- R: ReadRef<'data>,
-{
- sections: &'data [Elf::SectionHeader],
- strings: StringTable<'data, R>,
-}
-
-impl<'data, Elf: FileHeader, R: ReadRef<'data>> SectionTable<'data, Elf, R> {
- /// Create a new section table.
- #[inline]
- pub fn new(sections: &'data [Elf::SectionHeader], strings: StringTable<'data, R>) -> Self {
- SectionTable { sections, strings }
- }
-
- /// Iterate over the section headers.
- #[inline]
- pub fn iter(&self) -> slice::Iter<'data, Elf::SectionHeader> {
- self.sections.iter()
- }
-
- /// Return true if the section table is empty.
- #[inline]
- pub fn is_empty(&self) -> bool {
- self.sections.is_empty()
- }
-
- /// The number of section headers.
- #[inline]
- pub fn len(&self) -> usize {
- self.sections.len()
- }
-
- /// Return the section header at the given index.
- pub fn section(&self, index: SectionIndex) -> read::Result<&'data Elf::SectionHeader> {
- self.sections
- .get(index.0)
- .read_error("Invalid ELF section index")
- }
-
- /// Return the section header with the given name.
- ///
- /// Ignores sections with invalid names.
- pub fn section_by_name(
- &self,
- endian: Elf::Endian,
- name: &[u8],
- ) -> Option<(usize, &'data Elf::SectionHeader)> {
- self.sections
- .iter()
- .enumerate()
- .find(|(_, section)| self.section_name(endian, section) == Ok(name))
- }
-
- /// Return the section name for the given section header.
- pub fn section_name(
- &self,
- endian: Elf::Endian,
- section: &'data Elf::SectionHeader,
- ) -> read::Result<&'data [u8]> {
- section.name(endian, self.strings)
- }
-
- /// Return the string table at the given section index.
- ///
- /// Returns an error if the section is not a string table.
- #[inline]
- pub fn strings(
- &self,
- endian: Elf::Endian,
- data: R,
- index: SectionIndex,
- ) -> read::Result<StringTable<'data, R>> {
- self.section(index)?
- .strings(endian, data)?
- .read_error("Invalid ELF string section type")
- }
-
- /// Return the symbol table of the given section type.
- ///
- /// Returns an empty symbol table if the symbol table does not exist.
- #[inline]
- pub fn symbols(
- &self,
- endian: Elf::Endian,
- data: R,
- sh_type: u32,
- ) -> read::Result<SymbolTable<'data, Elf, R>> {
- debug_assert!(sh_type == elf::SHT_DYNSYM || sh_type == elf::SHT_SYMTAB);
-
- let (index, section) = match self
- .iter()
- .enumerate()
- .find(|s| s.1.sh_type(endian) == sh_type)
- {
- Some(s) => s,
- None => return Ok(SymbolTable::default()),
- };
-
- SymbolTable::parse(endian, data, self, SectionIndex(index), section)
- }
-
- /// Return the symbol table at the given section index.
- ///
- /// Returns an error if the section is not a symbol table.
- #[inline]
- pub fn symbol_table_by_index(
- &self,
- endian: Elf::Endian,
- data: R,
- index: SectionIndex,
- ) -> read::Result<SymbolTable<'data, Elf, R>> {
- let section = self.section(index)?;
- match section.sh_type(endian) {
- elf::SHT_DYNSYM | elf::SHT_SYMTAB => {}
- _ => return Err(Error("Invalid ELF symbol table section type")),
- }
- SymbolTable::parse(endian, data, self, index, section)
- }
-
- /// Create a mapping from section index to associated relocation sections.
- #[inline]
- pub fn relocation_sections(
- &self,
- endian: Elf::Endian,
- symbol_section: SectionIndex,
- ) -> read::Result<RelocationSections> {
- RelocationSections::parse(endian, self, symbol_section)
- }
-
- /// Return the contents of a dynamic section.
- ///
- /// Also returns the linked string table index.
- ///
- /// Returns `Ok(None)` if there is no `SHT_DYNAMIC` section.
- /// Returns `Err` for invalid values.
- pub fn dynamic(
- &self,
- endian: Elf::Endian,
- data: R,
- ) -> read::Result<Option<(&'data [Elf::Dyn], SectionIndex)>> {
- for section in self.sections {
- if let Some(dynamic) = section.dynamic(endian, data)? {
- return Ok(Some(dynamic));
- }
- }
- Ok(None)
- }
-
- /// Return the header of a SysV hash section.
- ///
- /// Returns `Ok(None)` if there is no SysV GNU hash section.
- /// Returns `Err` for invalid values.
- pub fn hash_header(
- &self,
- endian: Elf::Endian,
- data: R,
- ) -> read::Result<Option<&'data elf::HashHeader<Elf::Endian>>> {
- for section in self.sections {
- if let Some(hash) = section.hash_header(endian, data)? {
- return Ok(Some(hash));
- }
- }
- Ok(None)
- }
-
- /// Return the contents of a SysV hash section.
- ///
- /// Also returns the linked symbol table index.
- ///
- /// Returns `Ok(None)` if there is no SysV hash section.
- /// Returns `Err` for invalid values.
- pub fn hash(
- &self,
- endian: Elf::Endian,
- data: R,
- ) -> read::Result<Option<(HashTable<'data, Elf>, SectionIndex)>> {
- for section in self.sections {
- if let Some(hash) = section.hash(endian, data)? {
- return Ok(Some(hash));
- }
- }
- Ok(None)
- }
-
- /// Return the header of a GNU hash section.
- ///
- /// Returns `Ok(None)` if there is no GNU hash section.
- /// Returns `Err` for invalid values.
- pub fn gnu_hash_header(
- &self,
- endian: Elf::Endian,
- data: R,
- ) -> read::Result<Option<&'data elf::GnuHashHeader<Elf::Endian>>> {
- for section in self.sections {
- if let Some(hash) = section.gnu_hash_header(endian, data)? {
- return Ok(Some(hash));
- }
- }
- Ok(None)
- }
-
- /// Return the contents of a GNU hash section.
- ///
- /// Also returns the linked symbol table index.
- ///
- /// Returns `Ok(None)` if there is no GNU hash section.
- /// Returns `Err` for invalid values.
- pub fn gnu_hash(
- &self,
- endian: Elf::Endian,
- data: R,
- ) -> read::Result<Option<(GnuHashTable<'data, Elf>, SectionIndex)>> {
- for section in self.sections {
- if let Some(hash) = section.gnu_hash(endian, data)? {
- return Ok(Some(hash));
- }
- }
- Ok(None)
- }
-
- /// Return the contents of a `SHT_GNU_VERSYM` section.
- ///
- /// Also returns the linked symbol table index.
- ///
- /// Returns `Ok(None)` if there is no `SHT_GNU_VERSYM` section.
- /// Returns `Err` for invalid values.
- pub fn gnu_versym(
- &self,
- endian: Elf::Endian,
- data: R,
- ) -> read::Result<Option<(&'data [elf::Versym<Elf::Endian>], SectionIndex)>> {
- for section in self.sections {
- if let Some(syms) = section.gnu_versym(endian, data)? {
- return Ok(Some(syms));
- }
- }
- Ok(None)
- }
-
- /// Return the contents of a `SHT_GNU_VERDEF` section.
- ///
- /// Also returns the linked string table index.
- ///
- /// Returns `Ok(None)` if there is no `SHT_GNU_VERDEF` section.
- /// Returns `Err` for invalid values.
- pub fn gnu_verdef(
- &self,
- endian: Elf::Endian,
- data: R,
- ) -> read::Result<Option<(VerdefIterator<'data, Elf>, SectionIndex)>> {
- for section in self.sections {
- if let Some(defs) = section.gnu_verdef(endian, data)? {
- return Ok(Some(defs));
- }
- }
- Ok(None)
- }
-
- /// Return the contents of a `SHT_GNU_VERNEED` section.
- ///
- /// Also returns the linked string table index.
- ///
- /// Returns `Ok(None)` if there is no `SHT_GNU_VERNEED` section.
- /// Returns `Err` for invalid values.
- pub fn gnu_verneed(
- &self,
- endian: Elf::Endian,
- data: R,
- ) -> read::Result<Option<(VerneedIterator<'data, Elf>, SectionIndex)>> {
- for section in self.sections {
- if let Some(needs) = section.gnu_verneed(endian, data)? {
- return Ok(Some(needs));
- }
- }
- Ok(None)
- }
-
- /// Returns the symbol version table.
- ///
- /// Returns `Ok(None)` if there is no `SHT_GNU_VERSYM` section.
- /// Returns `Err` for invalid values.
- pub fn versions(
- &self,
- endian: Elf::Endian,
- data: R,
- ) -> read::Result<Option<VersionTable<'data, Elf>>> {
- let (versyms, link) = match self.gnu_versym(endian, data)? {
- Some(val) => val,
- None => return Ok(None),
- };
- let strings = self.symbol_table_by_index(endian, data, link)?.strings();
- // TODO: check links?
- let verdefs = self.gnu_verdef(endian, data)?.map(|x| x.0);
- let verneeds = self.gnu_verneed(endian, data)?.map(|x| x.0);
- VersionTable::parse(endian, versyms, verdefs, verneeds, strings).map(Some)
- }
-}
-
-/// An iterator for the sections in an [`ElfFile32`](super::ElfFile32).
-pub type ElfSectionIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSectionIterator<'data, 'file, elf::FileHeader32<Endian>, R>;
-/// An iterator for the sections in an [`ElfFile64`](super::ElfFile64).
-pub type ElfSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSectionIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
-
-/// An iterator for the sections in an [`ElfFile`].
-#[derive(Debug)]
-pub struct ElfSectionIterator<'data, 'file, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file ElfFile<'data, Elf, R>,
- pub(super) iter: iter::Enumerate<slice::Iter<'data, Elf::SectionHeader>>,
-}
-
-impl<'data, 'file, Elf, R> Iterator for ElfSectionIterator<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- type Item = ElfSection<'data, 'file, Elf, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.iter.next().map(|(index, section)| ElfSection {
- index: SectionIndex(index),
- file: self.file,
- section,
- })
- }
-}
-
-/// A section in an [`ElfFile32`](super::ElfFile32).
-pub type ElfSection32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSection<'data, 'file, elf::FileHeader32<Endian>, R>;
-/// A section in an [`ElfFile64`](super::ElfFile64).
-pub type ElfSection64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSection<'data, 'file, elf::FileHeader64<Endian>, R>;
-
-/// A section in an [`ElfFile`].
-///
-/// Most functionality is provided by the [`ObjectSection`] trait implementation.
-#[derive(Debug)]
-pub struct ElfSection<'data, 'file, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file ElfFile<'data, Elf, R>,
- pub(super) index: SectionIndex,
- pub(super) section: &'data Elf::SectionHeader,
-}
-
-impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ElfSection<'data, 'file, Elf, R> {
- fn bytes(&self) -> read::Result<&'data [u8]> {
- self.section
- .data(self.file.endian, self.file.data)
- .read_error("Invalid ELF section size or offset")
- }
-
- fn maybe_compressed(&self) -> read::Result<Option<CompressedFileRange>> {
- let endian = self.file.endian;
- if let Some((header, offset, compressed_size)) =
- self.section.compression(endian, self.file.data)?
- {
- let format = match header.ch_type(endian) {
- elf::ELFCOMPRESS_ZLIB => CompressionFormat::Zlib,
- elf::ELFCOMPRESS_ZSTD => CompressionFormat::Zstandard,
- _ => return Err(Error("Unsupported ELF compression type")),
- };
- let uncompressed_size = header.ch_size(endian).into();
- Ok(Some(CompressedFileRange {
- format,
- offset,
- compressed_size,
- uncompressed_size,
- }))
- } else {
- Ok(None)
- }
- }
-
- /// Try GNU-style "ZLIB" header decompression.
- fn maybe_compressed_gnu(&self) -> read::Result<Option<CompressedFileRange>> {
- let name = match self.name() {
- Ok(name) => name,
- // I think it's ok to ignore this error?
- Err(_) => return Ok(None),
- };
- if !name.starts_with(".zdebug_") {
- return Ok(None);
- }
- let (section_offset, section_size) = self
- .section
- .file_range(self.file.endian)
- .read_error("Invalid ELF GNU compressed section type")?;
- let mut offset = section_offset;
- let data = self.file.data;
- // Assume ZLIB-style uncompressed data is no more than 4GB to avoid accidentally
- // huge allocations. This also reduces the chance of accidentally matching on a
- // .debug_str that happens to start with "ZLIB".
- if data
- .read_bytes(&mut offset, 8)
- .read_error("ELF GNU compressed section is too short")?
- != b"ZLIB\0\0\0\0"
- {
- return Err(Error("Invalid ELF GNU compressed section header"));
- }
- let uncompressed_size = data
- .read::<U32Bytes<_>>(&mut offset)
- .read_error("ELF GNU compressed section is too short")?
- .get(endian::BigEndian)
- .into();
- let compressed_size = section_size
- .checked_sub(offset - section_offset)
- .read_error("ELF GNU compressed section is too short")?;
- Ok(Some(CompressedFileRange {
- format: CompressionFormat::Zlib,
- offset,
- compressed_size,
- uncompressed_size,
- }))
- }
-}
-
-impl<'data, 'file, Elf, R> read::private::Sealed for ElfSection<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Elf, R> ObjectSection<'data> for ElfSection<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- type RelocationIterator = ElfSectionRelocationIterator<'data, 'file, Elf, R>;
-
- #[inline]
- fn index(&self) -> SectionIndex {
- self.index
- }
-
- #[inline]
- fn address(&self) -> u64 {
- self.section.sh_addr(self.file.endian).into()
- }
-
- #[inline]
- fn size(&self) -> u64 {
- self.section.sh_size(self.file.endian).into()
- }
-
- #[inline]
- fn align(&self) -> u64 {
- self.section.sh_addralign(self.file.endian).into()
- }
-
- #[inline]
- fn file_range(&self) -> Option<(u64, u64)> {
- self.section.file_range(self.file.endian)
- }
-
- #[inline]
- fn data(&self) -> read::Result<&'data [u8]> {
- self.bytes()
- }
-
- fn data_range(&self, address: u64, size: u64) -> read::Result<Option<&'data [u8]>> {
- Ok(read::util::data_range(
- self.bytes()?,
- self.address(),
- address,
- size,
- ))
- }
-
- fn compressed_file_range(&self) -> read::Result<CompressedFileRange> {
- Ok(if let Some(data) = self.maybe_compressed()? {
- data
- } else if let Some(data) = self.maybe_compressed_gnu()? {
- data
- } else {
- CompressedFileRange::none(self.file_range())
- })
- }
-
- fn compressed_data(&self) -> read::Result<CompressedData<'data>> {
- self.compressed_file_range()?.data(self.file.data)
- }
-
- fn name_bytes(&self) -> read::Result<&[u8]> {
- self.file
- .sections
- .section_name(self.file.endian, self.section)
- }
-
- fn name(&self) -> read::Result<&str> {
- let name = self.name_bytes()?;
- str::from_utf8(name)
- .ok()
- .read_error("Non UTF-8 ELF section name")
- }
-
- #[inline]
- fn segment_name_bytes(&self) -> read::Result<Option<&[u8]>> {
- Ok(None)
- }
-
- #[inline]
- fn segment_name(&self) -> read::Result<Option<&str>> {
- Ok(None)
- }
-
- fn kind(&self) -> SectionKind {
- let flags = self.section.sh_flags(self.file.endian).into();
- let sh_type = self.section.sh_type(self.file.endian);
- match sh_type {
- elf::SHT_PROGBITS => {
- if flags & u64::from(elf::SHF_ALLOC) != 0 {
- if flags & u64::from(elf::SHF_EXECINSTR) != 0 {
- SectionKind::Text
- } else if flags & u64::from(elf::SHF_TLS) != 0 {
- SectionKind::Tls
- } else if flags & u64::from(elf::SHF_WRITE) != 0 {
- SectionKind::Data
- } else if flags & u64::from(elf::SHF_STRINGS) != 0 {
- SectionKind::ReadOnlyString
- } else {
- SectionKind::ReadOnlyData
- }
- } else if flags & u64::from(elf::SHF_STRINGS) != 0 {
- SectionKind::OtherString
- } else {
- SectionKind::Other
- }
- }
- elf::SHT_NOBITS => {
- if flags & u64::from(elf::SHF_TLS) != 0 {
- SectionKind::UninitializedTls
- } else {
- SectionKind::UninitializedData
- }
- }
- elf::SHT_NOTE => SectionKind::Note,
- elf::SHT_NULL
- | elf::SHT_SYMTAB
- | elf::SHT_STRTAB
- | elf::SHT_RELA
- | elf::SHT_HASH
- | elf::SHT_DYNAMIC
- | elf::SHT_REL
- | elf::SHT_DYNSYM
- | elf::SHT_GROUP => SectionKind::Metadata,
- _ => SectionKind::Elf(sh_type),
- }
- }
-
- fn relocations(&self) -> ElfSectionRelocationIterator<'data, 'file, Elf, R> {
- ElfSectionRelocationIterator {
- section_index: self.index,
- file: self.file,
- relocations: None,
- }
- }
-
- fn flags(&self) -> SectionFlags {
- SectionFlags::Elf {
- sh_flags: self.section.sh_flags(self.file.endian).into(),
- }
- }
-}
-
-/// A trait for generic access to [`elf::SectionHeader32`] and [`elf::SectionHeader64`].
-#[allow(missing_docs)]
-pub trait SectionHeader: Debug + Pod {
- type Elf: FileHeader<SectionHeader = Self, Endian = Self::Endian, Word = Self::Word>;
- type Word: Into<u64>;
- type Endian: endian::Endian;
-
- fn sh_name(&self, endian: Self::Endian) -> u32;
- fn sh_type(&self, endian: Self::Endian) -> u32;
- fn sh_flags(&self, endian: Self::Endian) -> Self::Word;
- fn sh_addr(&self, endian: Self::Endian) -> Self::Word;
- fn sh_offset(&self, endian: Self::Endian) -> Self::Word;
- fn sh_size(&self, endian: Self::Endian) -> Self::Word;
- fn sh_link(&self, endian: Self::Endian) -> u32;
- fn sh_info(&self, endian: Self::Endian) -> u32;
- fn sh_addralign(&self, endian: Self::Endian) -> Self::Word;
- fn sh_entsize(&self, endian: Self::Endian) -> Self::Word;
-
- /// Parse the section name from the string table.
- fn name<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- strings: StringTable<'data, R>,
- ) -> read::Result<&'data [u8]> {
- strings
- .get(self.sh_name(endian))
- .read_error("Invalid ELF section name offset")
- }
-
- /// Return the offset and size of the section in the file.
- ///
- /// Returns `None` for sections that have no data in the file.
- fn file_range(&self, endian: Self::Endian) -> Option<(u64, u64)> {
- if self.sh_type(endian) == elf::SHT_NOBITS {
- None
- } else {
- Some((self.sh_offset(endian).into(), self.sh_size(endian).into()))
- }
- }
-
- /// Return the section data.
- ///
- /// Returns `Ok(&[])` if the section has no data.
- /// Returns `Err` for invalid values.
- fn data<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<&'data [u8]> {
- if let Some((offset, size)) = self.file_range(endian) {
- data.read_bytes_at(offset, size)
- .read_error("Invalid ELF section size or offset")
- } else {
- Ok(&[])
- }
- }
-
- /// Return the section data as a slice of the given type.
- ///
- /// Allows padding at the end of the data.
- /// Returns `Ok(&[])` if the section has no data.
- /// Returns `Err` for invalid values, including bad alignment.
- fn data_as_array<'data, T: Pod, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<&'data [T]> {
- let mut data = self.data(endian, data).map(Bytes)?;
- data.read_slice(data.len() / mem::size_of::<T>())
- .read_error("Invalid ELF section size or offset")
- }
-
- /// Return the strings in the section.
- ///
- /// Returns `Ok(None)` if the section does not contain strings.
- /// Returns `Err` for invalid values.
- fn strings<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<StringTable<'data, R>>> {
- if self.sh_type(endian) != elf::SHT_STRTAB {
- return Ok(None);
- }
- let str_offset = self.sh_offset(endian).into();
- let str_size = self.sh_size(endian).into();
- let str_end = str_offset
- .checked_add(str_size)
- .read_error("Invalid ELF string section offset or size")?;
- Ok(Some(StringTable::new(data, str_offset, str_end)))
- }
-
- /// Return the symbols in the section.
- ///
- /// Also finds the linked string table in `sections`.
- ///
- /// `section_index` must be the 0-based index of this section, and is used
- /// to find the corresponding extended section index table in `sections`.
- ///
- /// Returns `Ok(None)` if the section does not contain symbols.
- /// Returns `Err` for invalid values.
- fn symbols<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- sections: &SectionTable<'data, Self::Elf, R>,
- section_index: SectionIndex,
- ) -> read::Result<Option<SymbolTable<'data, Self::Elf, R>>> {
- let sh_type = self.sh_type(endian);
- if sh_type != elf::SHT_SYMTAB && sh_type != elf::SHT_DYNSYM {
- return Ok(None);
- }
- SymbolTable::parse(endian, data, sections, section_index, self).map(Some)
- }
-
- /// Return the `Elf::Rel` entries in the section.
- ///
- /// Also returns the linked symbol table index.
- ///
- /// Returns `Ok(None)` if the section does not contain relocations.
- /// Returns `Err` for invalid values.
- fn rel<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<(&'data [<Self::Elf as FileHeader>::Rel], SectionIndex)>> {
- if self.sh_type(endian) != elf::SHT_REL {
- return Ok(None);
- }
- let rel = self
- .data_as_array(endian, data)
- .read_error("Invalid ELF relocation section offset or size")?;
- let link = SectionIndex(self.sh_link(endian) as usize);
- Ok(Some((rel, link)))
- }
-
- /// Return the `Elf::Rela` entries in the section.
- ///
- /// Also returns the linked symbol table index.
- ///
- /// Returns `Ok(None)` if the section does not contain relocations.
- /// Returns `Err` for invalid values.
- fn rela<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<(&'data [<Self::Elf as FileHeader>::Rela], SectionIndex)>> {
- if self.sh_type(endian) != elf::SHT_RELA {
- return Ok(None);
- }
- let rela = self
- .data_as_array(endian, data)
- .read_error("Invalid ELF relocation section offset or size")?;
- let link = SectionIndex(self.sh_link(endian) as usize);
- Ok(Some((rela, link)))
- }
-
- /// Return entries in a dynamic section.
- ///
- /// Also returns the linked string table index.
- ///
- /// Returns `Ok(None)` if the section type is not `SHT_DYNAMIC`.
- /// Returns `Err` for invalid values.
- fn dynamic<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<(&'data [<Self::Elf as FileHeader>::Dyn], SectionIndex)>> {
- if self.sh_type(endian) != elf::SHT_DYNAMIC {
- return Ok(None);
- }
- let dynamic = self
- .data_as_array(endian, data)
- .read_error("Invalid ELF dynamic section offset or size")?;
- let link = SectionIndex(self.sh_link(endian) as usize);
- Ok(Some((dynamic, link)))
- }
-
- /// Return a note iterator for the section data.
- ///
- /// Returns `Ok(None)` if the section does not contain notes.
- /// Returns `Err` for invalid values.
- fn notes<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<NoteIterator<'data, Self::Elf>>> {
- if self.sh_type(endian) != elf::SHT_NOTE {
- return Ok(None);
- }
- let data = self
- .data(endian, data)
- .read_error("Invalid ELF note section offset or size")?;
- let notes = NoteIterator::new(endian, self.sh_addralign(endian), data)?;
- Ok(Some(notes))
- }
-
- /// Return the contents of a group section.
- ///
- /// The first value is a `GRP_*` value, and the remaining values
- /// are section indices.
- ///
- /// Returns `Ok(None)` if the section does not define a group.
- /// Returns `Err` for invalid values.
- fn group<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<(u32, &'data [U32Bytes<Self::Endian>])>> {
- if self.sh_type(endian) != elf::SHT_GROUP {
- return Ok(None);
- }
- let mut data = self
- .data(endian, data)
- .read_error("Invalid ELF group section offset or size")
- .map(Bytes)?;
- let flag = data
- .read::<U32Bytes<_>>()
- .read_error("Invalid ELF group section offset or size")?
- .get(endian);
- let count = data.len() / mem::size_of::<U32Bytes<Self::Endian>>();
- let sections = data
- .read_slice(count)
- .read_error("Invalid ELF group section offset or size")?;
- Ok(Some((flag, sections)))
- }
-
- /// Return the header of a SysV hash section.
- ///
- /// Returns `Ok(None)` if the section does not contain a SysV hash.
- /// Returns `Err` for invalid values.
- fn hash_header<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<&'data elf::HashHeader<Self::Endian>>> {
- if self.sh_type(endian) != elf::SHT_HASH {
- return Ok(None);
- }
- let data = self
- .data(endian, data)
- .read_error("Invalid ELF hash section offset or size")?;
- let header = data
- .read_at::<elf::HashHeader<Self::Endian>>(0)
- .read_error("Invalid hash header")?;
- Ok(Some(header))
- }
-
- /// Return the contents of a SysV hash section.
- ///
- /// Also returns the linked symbol table index.
- ///
- /// Returns `Ok(None)` if the section does not contain a SysV hash.
- /// Returns `Err` for invalid values.
- fn hash<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<(HashTable<'data, Self::Elf>, SectionIndex)>> {
- if self.sh_type(endian) != elf::SHT_HASH {
- return Ok(None);
- }
- let data = self
- .data(endian, data)
- .read_error("Invalid ELF hash section offset or size")?;
- let hash = HashTable::parse(endian, data)?;
- let link = SectionIndex(self.sh_link(endian) as usize);
- Ok(Some((hash, link)))
- }
-
- /// Return the header of a GNU hash section.
- ///
- /// Returns `Ok(None)` if the section does not contain a GNU hash.
- /// Returns `Err` for invalid values.
- fn gnu_hash_header<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<&'data elf::GnuHashHeader<Self::Endian>>> {
- if self.sh_type(endian) != elf::SHT_GNU_HASH {
- return Ok(None);
- }
- let data = self
- .data(endian, data)
- .read_error("Invalid ELF GNU hash section offset or size")?;
- let header = data
- .read_at::<elf::GnuHashHeader<Self::Endian>>(0)
- .read_error("Invalid GNU hash header")?;
- Ok(Some(header))
- }
-
- /// Return the contents of a GNU hash section.
- ///
- /// Also returns the linked symbol table index.
- ///
- /// Returns `Ok(None)` if the section does not contain a GNU hash.
- /// Returns `Err` for invalid values.
- fn gnu_hash<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<(GnuHashTable<'data, Self::Elf>, SectionIndex)>> {
- if self.sh_type(endian) != elf::SHT_GNU_HASH {
- return Ok(None);
- }
- let data = self
- .data(endian, data)
- .read_error("Invalid ELF GNU hash section offset or size")?;
- let hash = GnuHashTable::parse(endian, data)?;
- let link = SectionIndex(self.sh_link(endian) as usize);
- Ok(Some((hash, link)))
- }
-
- /// Return the contents of a `SHT_GNU_VERSYM` section.
- ///
- /// Also returns the linked symbol table index.
- ///
- /// Returns `Ok(None)` if the section type is not `SHT_GNU_VERSYM`.
- /// Returns `Err` for invalid values.
- fn gnu_versym<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<(&'data [elf::Versym<Self::Endian>], SectionIndex)>> {
- if self.sh_type(endian) != elf::SHT_GNU_VERSYM {
- return Ok(None);
- }
- let versym = self
- .data_as_array(endian, data)
- .read_error("Invalid ELF GNU versym section offset or size")?;
- let link = SectionIndex(self.sh_link(endian) as usize);
- Ok(Some((versym, link)))
- }
-
- /// Return an iterator for the entries of a `SHT_GNU_VERDEF` section.
- ///
- /// Also returns the linked string table index.
- ///
- /// Returns `Ok(None)` if the section type is not `SHT_GNU_VERDEF`.
- /// Returns `Err` for invalid values.
- fn gnu_verdef<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<(VerdefIterator<'data, Self::Elf>, SectionIndex)>> {
- if self.sh_type(endian) != elf::SHT_GNU_VERDEF {
- return Ok(None);
- }
- let verdef = self
- .data(endian, data)
- .read_error("Invalid ELF GNU verdef section offset or size")?;
- let link = SectionIndex(self.sh_link(endian) as usize);
- Ok(Some((VerdefIterator::new(endian, verdef), link)))
- }
-
- /// Return an iterator for the entries of a `SHT_GNU_VERNEED` section.
- ///
- /// Also returns the linked string table index.
- ///
- /// Returns `Ok(None)` if the section type is not `SHT_GNU_VERNEED`.
- /// Returns `Err` for invalid values.
- fn gnu_verneed<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<(VerneedIterator<'data, Self::Elf>, SectionIndex)>> {
- if self.sh_type(endian) != elf::SHT_GNU_VERNEED {
- return Ok(None);
- }
- let verneed = self
- .data(endian, data)
- .read_error("Invalid ELF GNU verneed section offset or size")?;
- let link = SectionIndex(self.sh_link(endian) as usize);
- Ok(Some((VerneedIterator::new(endian, verneed), link)))
- }
-
- /// Return the contents of a `SHT_GNU_ATTRIBUTES` section.
- ///
- /// Returns `Ok(None)` if the section type is not `SHT_GNU_ATTRIBUTES`.
- /// Returns `Err` for invalid values.
- fn gnu_attributes<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<AttributesSection<'data, Self::Elf>>> {
- if self.sh_type(endian) != elf::SHT_GNU_ATTRIBUTES {
- return Ok(None);
- }
- self.attributes(endian, data).map(Some)
- }
-
- /// Parse the contents of the section as attributes.
- ///
- /// This function does not check whether section type corresponds
- /// to a section that contains attributes.
- ///
- /// Returns `Err` for invalid values.
- fn attributes<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<AttributesSection<'data, Self::Elf>> {
- let data = self.data(endian, data)?;
- AttributesSection::new(endian, data)
- }
-
- /// Parse the compression header if present.
- ///
- /// Returns the header, and the offset and size of the compressed section data
- /// in the file.
- ///
- /// Returns `Ok(None)` if the section flags do not have `SHF_COMPRESSED`.
- /// Returns `Err` for invalid values.
- fn compression<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<
- Option<(
- &'data <Self::Elf as FileHeader>::CompressionHeader,
- u64,
- u64,
- )>,
- > {
- if (self.sh_flags(endian).into() & u64::from(elf::SHF_COMPRESSED)) == 0 {
- return Ok(None);
- }
- let (section_offset, section_size) = self
- .file_range(endian)
- .read_error("Invalid ELF compressed section type")?;
- let mut offset = section_offset;
- let header = data
- .read::<<Self::Elf as FileHeader>::CompressionHeader>(&mut offset)
- .read_error("Invalid ELF compressed section offset")?;
- let compressed_size = section_size
- .checked_sub(offset - section_offset)
- .read_error("Invalid ELF compressed section size")?;
- Ok(Some((header, offset, compressed_size)))
- }
-}
-
-impl<Endian: endian::Endian> SectionHeader for elf::SectionHeader32<Endian> {
- type Elf = elf::FileHeader32<Endian>;
- type Word = u32;
- type Endian = Endian;
-
- #[inline]
- fn sh_name(&self, endian: Self::Endian) -> u32 {
- self.sh_name.get(endian)
- }
-
- #[inline]
- fn sh_type(&self, endian: Self::Endian) -> u32 {
- self.sh_type.get(endian)
- }
-
- #[inline]
- fn sh_flags(&self, endian: Self::Endian) -> Self::Word {
- self.sh_flags.get(endian)
- }
-
- #[inline]
- fn sh_addr(&self, endian: Self::Endian) -> Self::Word {
- self.sh_addr.get(endian)
- }
-
- #[inline]
- fn sh_offset(&self, endian: Self::Endian) -> Self::Word {
- self.sh_offset.get(endian)
- }
-
- #[inline]
- fn sh_size(&self, endian: Self::Endian) -> Self::Word {
- self.sh_size.get(endian)
- }
-
- #[inline]
- fn sh_link(&self, endian: Self::Endian) -> u32 {
- self.sh_link.get(endian)
- }
-
- #[inline]
- fn sh_info(&self, endian: Self::Endian) -> u32 {
- self.sh_info.get(endian)
- }
-
- #[inline]
- fn sh_addralign(&self, endian: Self::Endian) -> Self::Word {
- self.sh_addralign.get(endian)
- }
-
- #[inline]
- fn sh_entsize(&self, endian: Self::Endian) -> Self::Word {
- self.sh_entsize.get(endian)
- }
-}
-
-impl<Endian: endian::Endian> SectionHeader for elf::SectionHeader64<Endian> {
- type Word = u64;
- type Endian = Endian;
- type Elf = elf::FileHeader64<Endian>;
-
- #[inline]
- fn sh_name(&self, endian: Self::Endian) -> u32 {
- self.sh_name.get(endian)
- }
-
- #[inline]
- fn sh_type(&self, endian: Self::Endian) -> u32 {
- self.sh_type.get(endian)
- }
-
- #[inline]
- fn sh_flags(&self, endian: Self::Endian) -> Self::Word {
- self.sh_flags.get(endian)
- }
-
- #[inline]
- fn sh_addr(&self, endian: Self::Endian) -> Self::Word {
- self.sh_addr.get(endian)
- }
-
- #[inline]
- fn sh_offset(&self, endian: Self::Endian) -> Self::Word {
- self.sh_offset.get(endian)
- }
-
- #[inline]
- fn sh_size(&self, endian: Self::Endian) -> Self::Word {
- self.sh_size.get(endian)
- }
-
- #[inline]
- fn sh_link(&self, endian: Self::Endian) -> u32 {
- self.sh_link.get(endian)
- }
-
- #[inline]
- fn sh_info(&self, endian: Self::Endian) -> u32 {
- self.sh_info.get(endian)
- }
-
- #[inline]
- fn sh_addralign(&self, endian: Self::Endian) -> Self::Word {
- self.sh_addralign.get(endian)
- }
-
- #[inline]
- fn sh_entsize(&self, endian: Self::Endian) -> Self::Word {
- self.sh_entsize.get(endian)
- }
-}
diff --git a/vendor/object/src/read/elf/segment.rs b/vendor/object/src/read/elf/segment.rs
deleted file mode 100644
index 957117a..0000000
--- a/vendor/object/src/read/elf/segment.rs
+++ /dev/null
@@ -1,334 +0,0 @@
-use core::fmt::Debug;
-use core::{mem, slice, str};
-
-use crate::elf;
-use crate::endian::{self, Endianness};
-use crate::pod::Pod;
-use crate::read::{self, Bytes, ObjectSegment, ReadError, ReadRef, SegmentFlags};
-
-use super::{ElfFile, FileHeader, NoteIterator};
-
-/// An iterator for the segments in an [`ElfFile32`](super::ElfFile32).
-pub type ElfSegmentIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSegmentIterator<'data, 'file, elf::FileHeader32<Endian>, R>;
-/// An iterator for the segments in an [`ElfFile64`](super::ElfFile64).
-pub type ElfSegmentIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSegmentIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
-
-/// An iterator for the segments in an [`ElfFile`].
-#[derive(Debug)]
-pub struct ElfSegmentIterator<'data, 'file, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file ElfFile<'data, Elf, R>,
- pub(super) iter: slice::Iter<'data, Elf::ProgramHeader>,
-}
-
-impl<'data, 'file, Elf, R> Iterator for ElfSegmentIterator<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- type Item = ElfSegment<'data, 'file, Elf, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- for segment in self.iter.by_ref() {
- if segment.p_type(self.file.endian) == elf::PT_LOAD {
- return Some(ElfSegment {
- file: self.file,
- segment,
- });
- }
- }
- None
- }
-}
-
-/// A segment in an [`ElfFile32`](super::ElfFile32).
-pub type ElfSegment32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSegment<'data, 'file, elf::FileHeader32<Endian>, R>;
-/// A segment in an [`ElfFile64`](super::ElfFile64).
-pub type ElfSegment64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSegment<'data, 'file, elf::FileHeader64<Endian>, R>;
-
-/// A segment in an [`ElfFile`].
-///
-/// Most functionality is provided by the [`ObjectSegment`] trait implementation.
-#[derive(Debug)]
-pub struct ElfSegment<'data, 'file, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file ElfFile<'data, Elf, R>,
- pub(super) segment: &'data Elf::ProgramHeader,
-}
-
-impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ElfSegment<'data, 'file, Elf, R> {
- fn bytes(&self) -> read::Result<&'data [u8]> {
- self.segment
- .data(self.file.endian, self.file.data)
- .read_error("Invalid ELF segment size or offset")
- }
-}
-
-impl<'data, 'file, Elf, R> read::private::Sealed for ElfSegment<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Elf, R> ObjectSegment<'data> for ElfSegment<'data, 'file, Elf, R>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- #[inline]
- fn address(&self) -> u64 {
- self.segment.p_vaddr(self.file.endian).into()
- }
-
- #[inline]
- fn size(&self) -> u64 {
- self.segment.p_memsz(self.file.endian).into()
- }
-
- #[inline]
- fn align(&self) -> u64 {
- self.segment.p_align(self.file.endian).into()
- }
-
- #[inline]
- fn file_range(&self) -> (u64, u64) {
- self.segment.file_range(self.file.endian)
- }
-
- #[inline]
- fn data(&self) -> read::Result<&'data [u8]> {
- self.bytes()
- }
-
- fn data_range(&self, address: u64, size: u64) -> read::Result<Option<&'data [u8]>> {
- Ok(read::util::data_range(
- self.bytes()?,
- self.address(),
- address,
- size,
- ))
- }
-
- #[inline]
- fn name_bytes(&self) -> read::Result<Option<&[u8]>> {
- Ok(None)
- }
-
- #[inline]
- fn name(&self) -> read::Result<Option<&str>> {
- Ok(None)
- }
-
- #[inline]
- fn flags(&self) -> SegmentFlags {
- let p_flags = self.segment.p_flags(self.file.endian);
- SegmentFlags::Elf { p_flags }
- }
-}
-
-/// A trait for generic access to [`elf::ProgramHeader32`] and [`elf::ProgramHeader64`].
-#[allow(missing_docs)]
-pub trait ProgramHeader: Debug + Pod {
- type Elf: FileHeader<ProgramHeader = Self, Endian = Self::Endian, Word = Self::Word>;
- type Word: Into<u64>;
- type Endian: endian::Endian;
-
- fn p_type(&self, endian: Self::Endian) -> u32;
- fn p_flags(&self, endian: Self::Endian) -> u32;
- fn p_offset(&self, endian: Self::Endian) -> Self::Word;
- fn p_vaddr(&self, endian: Self::Endian) -> Self::Word;
- fn p_paddr(&self, endian: Self::Endian) -> Self::Word;
- fn p_filesz(&self, endian: Self::Endian) -> Self::Word;
- fn p_memsz(&self, endian: Self::Endian) -> Self::Word;
- fn p_align(&self, endian: Self::Endian) -> Self::Word;
-
- /// Return the offset and size of the segment in the file.
- fn file_range(&self, endian: Self::Endian) -> (u64, u64) {
- (self.p_offset(endian).into(), self.p_filesz(endian).into())
- }
-
- /// Return the segment data.
- ///
- /// Returns `Err` for invalid values.
- fn data<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> Result<&'data [u8], ()> {
- let (offset, size) = self.file_range(endian);
- data.read_bytes_at(offset, size)
- }
-
- /// Return the segment data as a slice of the given type.
- ///
- /// Allows padding at the end of the data.
- /// Returns `Ok(&[])` if the segment has no data.
- /// Returns `Err` for invalid values, including bad alignment.
- fn data_as_array<'data, T: Pod, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> Result<&'data [T], ()> {
- let mut data = self.data(endian, data).map(Bytes)?;
- data.read_slice(data.len() / mem::size_of::<T>())
- }
-
- /// Return the segment data in the given virtual address range
- ///
- /// Returns `Ok(None)` if the segment does not contain the address.
- /// Returns `Err` for invalid values.
- fn data_range<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- address: u64,
- size: u64,
- ) -> Result<Option<&'data [u8]>, ()> {
- Ok(read::util::data_range(
- self.data(endian, data)?,
- self.p_vaddr(endian).into(),
- address,
- size,
- ))
- }
-
- /// Return entries in a dynamic segment.
- ///
- /// Returns `Ok(None)` if the segment is not `PT_DYNAMIC`.
- /// Returns `Err` for invalid values.
- fn dynamic<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<&'data [<Self::Elf as FileHeader>::Dyn]>> {
- if self.p_type(endian) != elf::PT_DYNAMIC {
- return Ok(None);
- }
- let dynamic = self
- .data_as_array(endian, data)
- .read_error("Invalid ELF dynamic segment offset or size")?;
- Ok(Some(dynamic))
- }
-
- /// Return a note iterator for the segment data.
- ///
- /// Returns `Ok(None)` if the segment does not contain notes.
- /// Returns `Err` for invalid values.
- fn notes<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> read::Result<Option<NoteIterator<'data, Self::Elf>>> {
- if self.p_type(endian) != elf::PT_NOTE {
- return Ok(None);
- }
- let data = self
- .data(endian, data)
- .read_error("Invalid ELF note segment offset or size")?;
- let notes = NoteIterator::new(endian, self.p_align(endian), data)?;
- Ok(Some(notes))
- }
-}
-
-impl<Endian: endian::Endian> ProgramHeader for elf::ProgramHeader32<Endian> {
- type Word = u32;
- type Endian = Endian;
- type Elf = elf::FileHeader32<Endian>;
-
- #[inline]
- fn p_type(&self, endian: Self::Endian) -> u32 {
- self.p_type.get(endian)
- }
-
- #[inline]
- fn p_flags(&self, endian: Self::Endian) -> u32 {
- self.p_flags.get(endian)
- }
-
- #[inline]
- fn p_offset(&self, endian: Self::Endian) -> Self::Word {
- self.p_offset.get(endian)
- }
-
- #[inline]
- fn p_vaddr(&self, endian: Self::Endian) -> Self::Word {
- self.p_vaddr.get(endian)
- }
-
- #[inline]
- fn p_paddr(&self, endian: Self::Endian) -> Self::Word {
- self.p_paddr.get(endian)
- }
-
- #[inline]
- fn p_filesz(&self, endian: Self::Endian) -> Self::Word {
- self.p_filesz.get(endian)
- }
-
- #[inline]
- fn p_memsz(&self, endian: Self::Endian) -> Self::Word {
- self.p_memsz.get(endian)
- }
-
- #[inline]
- fn p_align(&self, endian: Self::Endian) -> Self::Word {
- self.p_align.get(endian)
- }
-}
-
-impl<Endian: endian::Endian> ProgramHeader for elf::ProgramHeader64<Endian> {
- type Word = u64;
- type Endian = Endian;
- type Elf = elf::FileHeader64<Endian>;
-
- #[inline]
- fn p_type(&self, endian: Self::Endian) -> u32 {
- self.p_type.get(endian)
- }
-
- #[inline]
- fn p_flags(&self, endian: Self::Endian) -> u32 {
- self.p_flags.get(endian)
- }
-
- #[inline]
- fn p_offset(&self, endian: Self::Endian) -> Self::Word {
- self.p_offset.get(endian)
- }
-
- #[inline]
- fn p_vaddr(&self, endian: Self::Endian) -> Self::Word {
- self.p_vaddr.get(endian)
- }
-
- #[inline]
- fn p_paddr(&self, endian: Self::Endian) -> Self::Word {
- self.p_paddr.get(endian)
- }
-
- #[inline]
- fn p_filesz(&self, endian: Self::Endian) -> Self::Word {
- self.p_filesz.get(endian)
- }
-
- #[inline]
- fn p_memsz(&self, endian: Self::Endian) -> Self::Word {
- self.p_memsz.get(endian)
- }
-
- #[inline]
- fn p_align(&self, endian: Self::Endian) -> Self::Word {
- self.p_align.get(endian)
- }
-}
diff --git a/vendor/object/src/read/elf/symbol.rs b/vendor/object/src/read/elf/symbol.rs
deleted file mode 100644
index 8ba707f..0000000
--- a/vendor/object/src/read/elf/symbol.rs
+++ /dev/null
@@ -1,595 +0,0 @@
-use alloc::fmt;
-use alloc::vec::Vec;
-use core::fmt::Debug;
-use core::slice;
-use core::str;
-
-use crate::endian::{self, Endianness};
-use crate::pod::Pod;
-use crate::read::util::StringTable;
-use crate::read::{
- self, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, SectionIndex, SymbolFlags,
- SymbolIndex, SymbolKind, SymbolMap, SymbolMapEntry, SymbolScope, SymbolSection,
-};
-use crate::{elf, U32};
-
-use super::{FileHeader, SectionHeader, SectionTable};
-
-/// A table of symbol entries in an ELF file.
-///
-/// Also includes the string table used for the symbol names.
-///
-/// Returned by [`SectionTable::symbols`].
-#[derive(Debug, Clone, Copy)]
-pub struct SymbolTable<'data, Elf: FileHeader, R = &'data [u8]>
-where
- R: ReadRef<'data>,
-{
- section: SectionIndex,
- string_section: SectionIndex,
- shndx_section: SectionIndex,
- symbols: &'data [Elf::Sym],
- strings: StringTable<'data, R>,
- shndx: &'data [U32<Elf::Endian>],
-}
-
-impl<'data, Elf: FileHeader, R: ReadRef<'data>> Default for SymbolTable<'data, Elf, R> {
- fn default() -> Self {
- SymbolTable {
- section: SectionIndex(0),
- string_section: SectionIndex(0),
- shndx_section: SectionIndex(0),
- symbols: &[],
- strings: Default::default(),
- shndx: &[],
- }
- }
-}
-
-impl<'data, Elf: FileHeader, R: ReadRef<'data>> SymbolTable<'data, Elf, R> {
- /// Parse the given symbol table section.
- pub fn parse(
- endian: Elf::Endian,
- data: R,
- sections: &SectionTable<'data, Elf, R>,
- section_index: SectionIndex,
- section: &Elf::SectionHeader,
- ) -> read::Result<SymbolTable<'data, Elf, R>> {
- debug_assert!(
- section.sh_type(endian) == elf::SHT_DYNSYM
- || section.sh_type(endian) == elf::SHT_SYMTAB
- );
-
- let symbols = section
- .data_as_array(endian, data)
- .read_error("Invalid ELF symbol table data")?;
-
- let link = SectionIndex(section.sh_link(endian) as usize);
- let strings = sections.strings(endian, data, link)?;
-
- let mut shndx_section = SectionIndex(0);
- let mut shndx = &[][..];
- for (i, s) in sections.iter().enumerate() {
- if s.sh_type(endian) == elf::SHT_SYMTAB_SHNDX
- && s.sh_link(endian) as usize == section_index.0
- {
- shndx_section = SectionIndex(i);
- shndx = s
- .data_as_array(endian, data)
- .read_error("Invalid ELF symtab_shndx data")?;
- }
- }
-
- Ok(SymbolTable {
- section: section_index,
- string_section: link,
- symbols,
- strings,
- shndx,
- shndx_section,
- })
- }
-
- /// Return the section index of this symbol table.
- #[inline]
- pub fn section(&self) -> SectionIndex {
- self.section
- }
-
- /// Return the section index of the shndx table.
- #[inline]
- pub fn shndx_section(&self) -> SectionIndex {
- self.shndx_section
- }
-
- /// Return the section index of the linked string table.
- #[inline]
- pub fn string_section(&self) -> SectionIndex {
- self.string_section
- }
-
- /// Return the string table used for the symbol names.
- #[inline]
- pub fn strings(&self) -> StringTable<'data, R> {
- self.strings
- }
-
- /// Return the symbol table.
- #[inline]
- pub fn symbols(&self) -> &'data [Elf::Sym] {
- self.symbols
- }
-
- /// Iterate over the symbols.
- #[inline]
- pub fn iter(&self) -> slice::Iter<'data, Elf::Sym> {
- self.symbols.iter()
- }
-
- /// Return true if the symbol table is empty.
- #[inline]
- pub fn is_empty(&self) -> bool {
- self.symbols.is_empty()
- }
-
- /// The number of symbols.
- #[inline]
- pub fn len(&self) -> usize {
- self.symbols.len()
- }
-
- /// Return the symbol at the given index.
- pub fn symbol(&self, index: usize) -> read::Result<&'data Elf::Sym> {
- self.symbols
- .get(index)
- .read_error("Invalid ELF symbol index")
- }
-
- /// Return the extended section index for the given symbol if present.
- #[inline]
- pub fn shndx(&self, endian: Elf::Endian, index: usize) -> Option<u32> {
- self.shndx.get(index).map(|x| x.get(endian))
- }
-
- /// Return the section index for the given symbol.
- ///
- /// This uses the extended section index if present.
- pub fn symbol_section(
- &self,
- endian: Elf::Endian,
- symbol: &'data Elf::Sym,
- index: usize,
- ) -> read::Result<Option<SectionIndex>> {
- match symbol.st_shndx(endian) {
- elf::SHN_UNDEF => Ok(None),
- elf::SHN_XINDEX => self
- .shndx(endian, index)
- .read_error("Missing ELF symbol extended index")
- .map(|index| Some(SectionIndex(index as usize))),
- shndx if shndx < elf::SHN_LORESERVE => Ok(Some(SectionIndex(shndx.into()))),
- _ => Ok(None),
- }
- }
-
- /// Return the symbol name for the given symbol.
- pub fn symbol_name(
- &self,
- endian: Elf::Endian,
- symbol: &'data Elf::Sym,
- ) -> read::Result<&'data [u8]> {
- symbol.name(endian, self.strings)
- }
-
- /// Construct a map from addresses to a user-defined map entry.
- pub fn map<Entry: SymbolMapEntry, F: Fn(&'data Elf::Sym) -> Option<Entry>>(
- &self,
- endian: Elf::Endian,
- f: F,
- ) -> SymbolMap<Entry> {
- let mut symbols = Vec::with_capacity(self.symbols.len());
- for symbol in self.symbols {
- if !symbol.is_definition(endian) {
- continue;
- }
- if let Some(entry) = f(symbol) {
- symbols.push(entry);
- }
- }
- SymbolMap::new(symbols)
- }
-}
-
-/// A symbol table in an [`ElfFile32`](super::ElfFile32).
-pub type ElfSymbolTable32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSymbolTable<'data, 'file, elf::FileHeader32<Endian>, R>;
-/// A symbol table in an [`ElfFile32`](super::ElfFile32).
-pub type ElfSymbolTable64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSymbolTable<'data, 'file, elf::FileHeader64<Endian>, R>;
-
-/// A symbol table in an [`ElfFile`](super::ElfFile).
-#[derive(Debug, Clone, Copy)]
-pub struct ElfSymbolTable<'data, 'file, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) endian: Elf::Endian,
- pub(super) symbols: &'file SymbolTable<'data, Elf, R>,
-}
-
-impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> read::private::Sealed
- for ElfSymbolTable<'data, 'file, Elf, R>
-{
-}
-
-impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ObjectSymbolTable<'data>
- for ElfSymbolTable<'data, 'file, Elf, R>
-{
- type Symbol = ElfSymbol<'data, 'file, Elf, R>;
- type SymbolIterator = ElfSymbolIterator<'data, 'file, Elf, R>;
-
- fn symbols(&self) -> Self::SymbolIterator {
- ElfSymbolIterator {
- endian: self.endian,
- symbols: self.symbols,
- index: 0,
- }
- }
-
- fn symbol_by_index(&self, index: SymbolIndex) -> read::Result<Self::Symbol> {
- let symbol = self.symbols.symbol(index.0)?;
- Ok(ElfSymbol {
- endian: self.endian,
- symbols: self.symbols,
- index,
- symbol,
- })
- }
-}
-
-/// An iterator for the symbols in an [`ElfFile32`](super::ElfFile32).
-pub type ElfSymbolIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSymbolIterator<'data, 'file, elf::FileHeader32<Endian>, R>;
-/// An iterator for the symbols in an [`ElfFile64`](super::ElfFile64).
-pub type ElfSymbolIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSymbolIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
-
-/// An iterator for the symbols in an [`ElfFile`](super::ElfFile).
-pub struct ElfSymbolIterator<'data, 'file, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) endian: Elf::Endian,
- pub(super) symbols: &'file SymbolTable<'data, Elf, R>,
- pub(super) index: usize,
-}
-
-impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> fmt::Debug
- for ElfSymbolIterator<'data, 'file, Elf, R>
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("ElfSymbolIterator").finish()
- }
-}
-
-impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> Iterator
- for ElfSymbolIterator<'data, 'file, Elf, R>
-{
- type Item = ElfSymbol<'data, 'file, Elf, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- let index = self.index;
- let symbol = self.symbols.symbols.get(index)?;
- self.index += 1;
- Some(ElfSymbol {
- endian: self.endian,
- symbols: self.symbols,
- index: SymbolIndex(index),
- symbol,
- })
- }
-}
-
-/// A symbol in an [`ElfFile32`](super::ElfFile32).
-pub type ElfSymbol32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSymbol<'data, 'file, elf::FileHeader32<Endian>, R>;
-/// A symbol in an [`ElfFile64`](super::ElfFile64).
-pub type ElfSymbol64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- ElfSymbol<'data, 'file, elf::FileHeader64<Endian>, R>;
-
-/// A symbol in an [`ElfFile`](super::ElfFile).
-///
-/// Most functionality is provided by the [`ObjectSymbol`] trait implementation.
-#[derive(Debug, Clone, Copy)]
-pub struct ElfSymbol<'data, 'file, Elf, R = &'data [u8]>
-where
- Elf: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) endian: Elf::Endian,
- pub(super) symbols: &'file SymbolTable<'data, Elf, R>,
- pub(super) index: SymbolIndex,
- pub(super) symbol: &'data Elf::Sym,
-}
-
-impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ElfSymbol<'data, 'file, Elf, R> {
- /// Return a reference to the raw symbol structure.
- #[inline]
- pub fn raw_symbol(&self) -> &'data Elf::Sym {
- self.symbol
- }
-}
-
-impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> read::private::Sealed
- for ElfSymbol<'data, 'file, Elf, R>
-{
-}
-
-impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data>
- for ElfSymbol<'data, 'file, Elf, R>
-{
- #[inline]
- fn index(&self) -> SymbolIndex {
- self.index
- }
-
- fn name_bytes(&self) -> read::Result<&'data [u8]> {
- self.symbol.name(self.endian, self.symbols.strings())
- }
-
- fn name(&self) -> read::Result<&'data str> {
- let name = self.name_bytes()?;
- str::from_utf8(name)
- .ok()
- .read_error("Non UTF-8 ELF symbol name")
- }
-
- #[inline]
- fn address(&self) -> u64 {
- self.symbol.st_value(self.endian).into()
- }
-
- #[inline]
- fn size(&self) -> u64 {
- self.symbol.st_size(self.endian).into()
- }
-
- fn kind(&self) -> SymbolKind {
- match self.symbol.st_type() {
- elf::STT_NOTYPE if self.index.0 == 0 => SymbolKind::Null,
- elf::STT_NOTYPE => SymbolKind::Unknown,
- elf::STT_OBJECT | elf::STT_COMMON => SymbolKind::Data,
- elf::STT_FUNC | elf::STT_GNU_IFUNC => SymbolKind::Text,
- elf::STT_SECTION => SymbolKind::Section,
- elf::STT_FILE => SymbolKind::File,
- elf::STT_TLS => SymbolKind::Tls,
- _ => SymbolKind::Unknown,
- }
- }
-
- fn section(&self) -> SymbolSection {
- match self.symbol.st_shndx(self.endian) {
- elf::SHN_UNDEF => SymbolSection::Undefined,
- elf::SHN_ABS => {
- if self.symbol.st_type() == elf::STT_FILE {
- SymbolSection::None
- } else {
- SymbolSection::Absolute
- }
- }
- elf::SHN_COMMON => SymbolSection::Common,
- elf::SHN_XINDEX => match self.symbols.shndx(self.endian, self.index.0) {
- Some(index) => SymbolSection::Section(SectionIndex(index as usize)),
- None => SymbolSection::Unknown,
- },
- index if index < elf::SHN_LORESERVE => {
- SymbolSection::Section(SectionIndex(index as usize))
- }
- _ => SymbolSection::Unknown,
- }
- }
-
- #[inline]
- fn is_undefined(&self) -> bool {
- self.symbol.st_shndx(self.endian) == elf::SHN_UNDEF
- }
-
- #[inline]
- fn is_definition(&self) -> bool {
- self.symbol.is_definition(self.endian)
- }
-
- #[inline]
- fn is_common(&self) -> bool {
- self.symbol.st_shndx(self.endian) == elf::SHN_COMMON
- }
-
- #[inline]
- fn is_weak(&self) -> bool {
- self.symbol.st_bind() == elf::STB_WEAK
- }
-
- fn scope(&self) -> SymbolScope {
- if self.symbol.st_shndx(self.endian) == elf::SHN_UNDEF {
- SymbolScope::Unknown
- } else {
- match self.symbol.st_bind() {
- elf::STB_LOCAL => SymbolScope::Compilation,
- elf::STB_GLOBAL | elf::STB_WEAK => {
- if self.symbol.st_visibility() == elf::STV_HIDDEN {
- SymbolScope::Linkage
- } else {
- SymbolScope::Dynamic
- }
- }
- _ => SymbolScope::Unknown,
- }
- }
- }
-
- #[inline]
- fn is_global(&self) -> bool {
- self.symbol.st_bind() != elf::STB_LOCAL
- }
-
- #[inline]
- fn is_local(&self) -> bool {
- self.symbol.st_bind() == elf::STB_LOCAL
- }
-
- #[inline]
- fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> {
- SymbolFlags::Elf {
- st_info: self.symbol.st_info(),
- st_other: self.symbol.st_other(),
- }
- }
-}
-
-/// A trait for generic access to [`elf::Sym32`] and [`elf::Sym64`].
-#[allow(missing_docs)]
-pub trait Sym: Debug + Pod {
- type Word: Into<u64>;
- type Endian: endian::Endian;
-
- fn st_name(&self, endian: Self::Endian) -> u32;
- fn st_info(&self) -> u8;
- fn st_bind(&self) -> u8;
- fn st_type(&self) -> u8;
- fn st_other(&self) -> u8;
- fn st_visibility(&self) -> u8;
- fn st_shndx(&self, endian: Self::Endian) -> u16;
- fn st_value(&self, endian: Self::Endian) -> Self::Word;
- fn st_size(&self, endian: Self::Endian) -> Self::Word;
-
- /// Parse the symbol name from the string table.
- fn name<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- strings: StringTable<'data, R>,
- ) -> read::Result<&'data [u8]> {
- strings
- .get(self.st_name(endian))
- .read_error("Invalid ELF symbol name offset")
- }
-
- /// Return true if the symbol is undefined.
- #[inline]
- fn is_undefined(&self, endian: Self::Endian) -> bool {
- self.st_shndx(endian) == elf::SHN_UNDEF
- }
-
- /// Return true if the symbol is a definition of a function or data object.
- fn is_definition(&self, endian: Self::Endian) -> bool {
- let shndx = self.st_shndx(endian);
- if shndx == elf::SHN_UNDEF || (shndx >= elf::SHN_LORESERVE && shndx != elf::SHN_XINDEX) {
- return false;
- }
- match self.st_type() {
- elf::STT_NOTYPE => self.st_size(endian).into() != 0,
- elf::STT_FUNC | elf::STT_OBJECT => true,
- _ => false,
- }
- }
-}
-
-impl<Endian: endian::Endian> Sym for elf::Sym32<Endian> {
- type Word = u32;
- type Endian = Endian;
-
- #[inline]
- fn st_name(&self, endian: Self::Endian) -> u32 {
- self.st_name.get(endian)
- }
-
- #[inline]
- fn st_info(&self) -> u8 {
- self.st_info
- }
-
- #[inline]
- fn st_bind(&self) -> u8 {
- self.st_bind()
- }
-
- #[inline]
- fn st_type(&self) -> u8 {
- self.st_type()
- }
-
- #[inline]
- fn st_other(&self) -> u8 {
- self.st_other
- }
-
- #[inline]
- fn st_visibility(&self) -> u8 {
- self.st_visibility()
- }
-
- #[inline]
- fn st_shndx(&self, endian: Self::Endian) -> u16 {
- self.st_shndx.get(endian)
- }
-
- #[inline]
- fn st_value(&self, endian: Self::Endian) -> Self::Word {
- self.st_value.get(endian)
- }
-
- #[inline]
- fn st_size(&self, endian: Self::Endian) -> Self::Word {
- self.st_size.get(endian)
- }
-}
-
-impl<Endian: endian::Endian> Sym for elf::Sym64<Endian> {
- type Word = u64;
- type Endian = Endian;
-
- #[inline]
- fn st_name(&self, endian: Self::Endian) -> u32 {
- self.st_name.get(endian)
- }
-
- #[inline]
- fn st_info(&self) -> u8 {
- self.st_info
- }
-
- #[inline]
- fn st_bind(&self) -> u8 {
- self.st_bind()
- }
-
- #[inline]
- fn st_type(&self) -> u8 {
- self.st_type()
- }
-
- #[inline]
- fn st_other(&self) -> u8 {
- self.st_other
- }
-
- #[inline]
- fn st_visibility(&self) -> u8 {
- self.st_visibility()
- }
-
- #[inline]
- fn st_shndx(&self, endian: Self::Endian) -> u16 {
- self.st_shndx.get(endian)
- }
-
- #[inline]
- fn st_value(&self, endian: Self::Endian) -> Self::Word {
- self.st_value.get(endian)
- }
-
- #[inline]
- fn st_size(&self, endian: Self::Endian) -> Self::Word {
- self.st_size.get(endian)
- }
-}
diff --git a/vendor/object/src/read/elf/version.rs b/vendor/object/src/read/elf/version.rs
deleted file mode 100644
index 28eeed0..0000000
--- a/vendor/object/src/read/elf/version.rs
+++ /dev/null
@@ -1,424 +0,0 @@
-use alloc::vec::Vec;
-
-use crate::read::{Bytes, ReadError, ReadRef, Result, StringTable};
-use crate::{elf, endian};
-
-use super::FileHeader;
-
-/// A version index.
-#[derive(Debug, Default, Clone, Copy)]
-pub struct VersionIndex(pub u16);
-
-impl VersionIndex {
- /// Return the version index.
- pub fn index(&self) -> u16 {
- self.0 & elf::VERSYM_VERSION
- }
-
- /// Return true if it is the local index.
- pub fn is_local(&self) -> bool {
- self.index() == elf::VER_NDX_LOCAL
- }
-
- /// Return true if it is the global index.
- pub fn is_global(&self) -> bool {
- self.index() == elf::VER_NDX_GLOBAL
- }
-
- /// Return the hidden flag.
- pub fn is_hidden(&self) -> bool {
- self.0 & elf::VERSYM_HIDDEN != 0
- }
-}
-
-/// A version definition or requirement.
-///
-/// This is derived from entries in the [`elf::SHT_GNU_VERDEF`] and [`elf::SHT_GNU_VERNEED`] sections.
-#[derive(Debug, Default, Clone, Copy)]
-pub struct Version<'data> {
- name: &'data [u8],
- hash: u32,
- // Used to keep track of valid indices in `VersionTable`.
- valid: bool,
-}
-
-impl<'data> Version<'data> {
- /// Return the version name.
- pub fn name(&self) -> &'data [u8] {
- self.name
- }
-
- /// Return hash of the version name.
- pub fn hash(&self) -> u32 {
- self.hash
- }
-}
-
-/// A table of version definitions and requirements.
-///
-/// It allows looking up the version information for a given symbol index.
-///
-/// This is derived from entries in the [`elf::SHT_GNU_VERSYM`], [`elf::SHT_GNU_VERDEF`]
-/// and [`elf::SHT_GNU_VERNEED`] sections.
-///
-/// Returned by [`SectionTable::versions`](super::SectionTable::versions).
-#[derive(Debug, Clone)]
-pub struct VersionTable<'data, Elf: FileHeader> {
- symbols: &'data [elf::Versym<Elf::Endian>],
- versions: Vec<Version<'data>>,
-}
-
-impl<'data, Elf: FileHeader> Default for VersionTable<'data, Elf> {
- fn default() -> Self {
- VersionTable {
- symbols: &[],
- versions: Vec::new(),
- }
- }
-}
-
-impl<'data, Elf: FileHeader> VersionTable<'data, Elf> {
- /// Parse the version sections.
- pub fn parse<R: ReadRef<'data>>(
- endian: Elf::Endian,
- versyms: &'data [elf::Versym<Elf::Endian>],
- verdefs: Option<VerdefIterator<'data, Elf>>,
- verneeds: Option<VerneedIterator<'data, Elf>>,
- strings: StringTable<'data, R>,
- ) -> Result<Self> {
- let mut max_index = 0;
- if let Some(mut verdefs) = verdefs.clone() {
- while let Some((verdef, _)) = verdefs.next()? {
- if verdef.vd_flags.get(endian) & elf::VER_FLG_BASE != 0 {
- continue;
- }
- let index = verdef.vd_ndx.get(endian) & elf::VERSYM_VERSION;
- if max_index < index {
- max_index = index;
- }
- }
- }
- if let Some(mut verneeds) = verneeds.clone() {
- while let Some((_, mut vernauxs)) = verneeds.next()? {
- while let Some(vernaux) = vernauxs.next()? {
- let index = vernaux.vna_other.get(endian) & elf::VERSYM_VERSION;
- if max_index < index {
- max_index = index;
- }
- }
- }
- }
-
- // Indices should be sequential, but this could be up to
- // 32k * size_of::<Version>() if max_index is bad.
- let mut versions = vec![Version::default(); max_index as usize + 1];
-
- if let Some(mut verdefs) = verdefs {
- while let Some((verdef, mut verdauxs)) = verdefs.next()? {
- if verdef.vd_flags.get(endian) & elf::VER_FLG_BASE != 0 {
- continue;
- }
- let index = verdef.vd_ndx.get(endian) & elf::VERSYM_VERSION;
- if index <= elf::VER_NDX_GLOBAL {
- // TODO: return error?
- continue;
- }
- if let Some(verdaux) = verdauxs.next()? {
- versions[usize::from(index)] = Version {
- name: verdaux.name(endian, strings)?,
- hash: verdef.vd_hash.get(endian),
- valid: true,
- };
- }
- }
- }
- if let Some(mut verneeds) = verneeds {
- while let Some((_, mut vernauxs)) = verneeds.next()? {
- while let Some(vernaux) = vernauxs.next()? {
- let index = vernaux.vna_other.get(endian) & elf::VERSYM_VERSION;
- if index <= elf::VER_NDX_GLOBAL {
- // TODO: return error?
- continue;
- }
- versions[usize::from(index)] = Version {
- name: vernaux.name(endian, strings)?,
- hash: vernaux.vna_hash.get(endian),
- valid: true,
- };
- }
- }
- }
-
- Ok(VersionTable {
- symbols: versyms,
- versions,
- })
- }
-
- /// Return true if the version table is empty.
- pub fn is_empty(&self) -> bool {
- self.symbols.is_empty()
- }
-
- /// Return version index for a given symbol index.
- pub fn version_index(&self, endian: Elf::Endian, index: usize) -> VersionIndex {
- let version_index = match self.symbols.get(index) {
- Some(x) => x.0.get(endian),
- // Ideally this would be VER_NDX_LOCAL for undefined symbols,
- // but currently there are no checks that need this distinction.
- None => elf::VER_NDX_GLOBAL,
- };
- VersionIndex(version_index)
- }
-
- /// Return version information for a given symbol version index.
- ///
- /// Returns `Ok(None)` for local and global versions.
- /// Returns `Err(_)` if index is invalid.
- pub fn version(&self, index: VersionIndex) -> Result<Option<&Version<'data>>> {
- if index.index() <= elf::VER_NDX_GLOBAL {
- return Ok(None);
- }
- self.versions
- .get(usize::from(index.index()))
- .filter(|version| version.valid)
- .read_error("Invalid ELF symbol version index")
- .map(Some)
- }
-
- /// Return true if the given symbol index satisfies the requirements of `need`.
- ///
- /// Returns false for any error.
- ///
- /// Note: this function hasn't been fully tested and is likely to be incomplete.
- pub fn matches(&self, endian: Elf::Endian, index: usize, need: Option<&Version<'_>>) -> bool {
- let version_index = self.version_index(endian, index);
- let def = match self.version(version_index) {
- Ok(def) => def,
- Err(_) => return false,
- };
- match (def, need) {
- (Some(def), Some(need)) => need.hash == def.hash && need.name == def.name,
- (None, Some(_need)) => {
- // Version must be present if needed.
- false
- }
- (Some(_def), None) => {
- // For a dlsym call, use the newest version.
- // TODO: if not a dlsym call, then use the oldest version.
- !version_index.is_hidden()
- }
- (None, None) => true,
- }
- }
-}
-
-/// An iterator for the entries in an ELF [`elf::SHT_GNU_VERDEF`] section.
-#[derive(Debug, Clone)]
-pub struct VerdefIterator<'data, Elf: FileHeader> {
- endian: Elf::Endian,
- data: Bytes<'data>,
-}
-
-impl<'data, Elf: FileHeader> VerdefIterator<'data, Elf> {
- pub(super) fn new(endian: Elf::Endian, data: &'data [u8]) -> Self {
- VerdefIterator {
- endian,
- data: Bytes(data),
- }
- }
-
- /// Return the next `Verdef` entry.
- pub fn next(
- &mut self,
- ) -> Result<Option<(&'data elf::Verdef<Elf::Endian>, VerdauxIterator<'data, Elf>)>> {
- if self.data.is_empty() {
- return Ok(None);
- }
-
- let verdef = self
- .data
- .read_at::<elf::Verdef<_>>(0)
- .read_error("ELF verdef is too short")?;
-
- let mut verdaux_data = self.data;
- verdaux_data
- .skip(verdef.vd_aux.get(self.endian) as usize)
- .read_error("Invalid ELF vd_aux")?;
- let verdaux =
- VerdauxIterator::new(self.endian, verdaux_data.0, verdef.vd_cnt.get(self.endian));
-
- let next = verdef.vd_next.get(self.endian);
- if next != 0 {
- self.data
- .skip(next as usize)
- .read_error("Invalid ELF vd_next")?;
- } else {
- self.data = Bytes(&[]);
- }
- Ok(Some((verdef, verdaux)))
- }
-}
-
-/// An iterator for the auxiliary records for an entry in an ELF [`elf::SHT_GNU_VERDEF`] section.
-#[derive(Debug, Clone)]
-pub struct VerdauxIterator<'data, Elf: FileHeader> {
- endian: Elf::Endian,
- data: Bytes<'data>,
- count: u16,
-}
-
-impl<'data, Elf: FileHeader> VerdauxIterator<'data, Elf> {
- pub(super) fn new(endian: Elf::Endian, data: &'data [u8], count: u16) -> Self {
- VerdauxIterator {
- endian,
- data: Bytes(data),
- count,
- }
- }
-
- /// Return the next `Verdaux` entry.
- pub fn next(&mut self) -> Result<Option<&'data elf::Verdaux<Elf::Endian>>> {
- if self.count == 0 {
- return Ok(None);
- }
-
- let verdaux = self
- .data
- .read_at::<elf::Verdaux<_>>(0)
- .read_error("ELF verdaux is too short")?;
-
- self.data
- .skip(verdaux.vda_next.get(self.endian) as usize)
- .read_error("Invalid ELF vda_next")?;
- self.count -= 1;
- Ok(Some(verdaux))
- }
-}
-
-/// An iterator for the entries in an ELF [`elf::SHT_GNU_VERNEED`] section.
-#[derive(Debug, Clone)]
-pub struct VerneedIterator<'data, Elf: FileHeader> {
- endian: Elf::Endian,
- data: Bytes<'data>,
-}
-
-impl<'data, Elf: FileHeader> VerneedIterator<'data, Elf> {
- pub(super) fn new(endian: Elf::Endian, data: &'data [u8]) -> Self {
- VerneedIterator {
- endian,
- data: Bytes(data),
- }
- }
-
- /// Return the next `Verneed` entry.
- pub fn next(
- &mut self,
- ) -> Result<
- Option<(
- &'data elf::Verneed<Elf::Endian>,
- VernauxIterator<'data, Elf>,
- )>,
- > {
- if self.data.is_empty() {
- return Ok(None);
- }
-
- let verneed = self
- .data
- .read_at::<elf::Verneed<_>>(0)
- .read_error("ELF verneed is too short")?;
-
- let mut vernaux_data = self.data;
- vernaux_data
- .skip(verneed.vn_aux.get(self.endian) as usize)
- .read_error("Invalid ELF vn_aux")?;
- let vernaux =
- VernauxIterator::new(self.endian, vernaux_data.0, verneed.vn_cnt.get(self.endian));
-
- let next = verneed.vn_next.get(self.endian);
- if next != 0 {
- self.data
- .skip(next as usize)
- .read_error("Invalid ELF vn_next")?;
- } else {
- self.data = Bytes(&[]);
- }
- Ok(Some((verneed, vernaux)))
- }
-}
-
-/// An iterator for the auxiliary records for an entry in an ELF [`elf::SHT_GNU_VERNEED`] section.
-#[derive(Debug, Clone)]
-pub struct VernauxIterator<'data, Elf: FileHeader> {
- endian: Elf::Endian,
- data: Bytes<'data>,
- count: u16,
-}
-
-impl<'data, Elf: FileHeader> VernauxIterator<'data, Elf> {
- pub(super) fn new(endian: Elf::Endian, data: &'data [u8], count: u16) -> Self {
- VernauxIterator {
- endian,
- data: Bytes(data),
- count,
- }
- }
-
- /// Return the next `Vernaux` entry.
- pub fn next(&mut self) -> Result<Option<&'data elf::Vernaux<Elf::Endian>>> {
- if self.count == 0 {
- return Ok(None);
- }
-
- let vernaux = self
- .data
- .read_at::<elf::Vernaux<_>>(0)
- .read_error("ELF vernaux is too short")?;
-
- self.data
- .skip(vernaux.vna_next.get(self.endian) as usize)
- .read_error("Invalid ELF vna_next")?;
- self.count -= 1;
- Ok(Some(vernaux))
- }
-}
-
-impl<Endian: endian::Endian> elf::Verdaux<Endian> {
- /// Parse the version name from the string table.
- pub fn name<'data, R: ReadRef<'data>>(
- &self,
- endian: Endian,
- strings: StringTable<'data, R>,
- ) -> Result<&'data [u8]> {
- strings
- .get(self.vda_name.get(endian))
- .read_error("Invalid ELF vda_name")
- }
-}
-
-impl<Endian: endian::Endian> elf::Verneed<Endian> {
- /// Parse the file from the string table.
- pub fn file<'data, R: ReadRef<'data>>(
- &self,
- endian: Endian,
- strings: StringTable<'data, R>,
- ) -> Result<&'data [u8]> {
- strings
- .get(self.vn_file.get(endian))
- .read_error("Invalid ELF vn_file")
- }
-}
-
-impl<Endian: endian::Endian> elf::Vernaux<Endian> {
- /// Parse the version name from the string table.
- pub fn name<'data, R: ReadRef<'data>>(
- &self,
- endian: Endian,
- strings: StringTable<'data, R>,
- ) -> Result<&'data [u8]> {
- strings
- .get(self.vna_name.get(endian))
- .read_error("Invalid ELF vna_name")
- }
-}
diff --git a/vendor/object/src/read/macho/dyld_cache.rs b/vendor/object/src/read/macho/dyld_cache.rs
deleted file mode 100644
index 0f5dfc5..0000000
--- a/vendor/object/src/read/macho/dyld_cache.rs
+++ /dev/null
@@ -1,344 +0,0 @@
-use alloc::vec::Vec;
-use core::slice;
-
-use crate::read::{Error, File, ReadError, ReadRef, Result};
-use crate::{macho, Architecture, Endian, Endianness};
-
-/// A parsed representation of the dyld shared cache.
-#[derive(Debug)]
-pub struct DyldCache<'data, E = Endianness, R = &'data [u8]>
-where
- E: Endian,
- R: ReadRef<'data>,
-{
- endian: E,
- data: R,
- subcaches: Vec<DyldSubCache<'data, E, R>>,
- mappings: &'data [macho::DyldCacheMappingInfo<E>],
- images: &'data [macho::DyldCacheImageInfo<E>],
- arch: Architecture,
-}
-
-/// Information about a subcache.
-#[derive(Debug)]
-pub struct DyldSubCache<'data, E = Endianness, R = &'data [u8]>
-where
- E: Endian,
- R: ReadRef<'data>,
-{
- data: R,
- mappings: &'data [macho::DyldCacheMappingInfo<E>],
-}
-
-// This is the offset of the images_across_all_subcaches_count field.
-const MIN_HEADER_SIZE_SUBCACHES: u32 = 0x1c4;
-
-impl<'data, E, R> DyldCache<'data, E, R>
-where
- E: Endian,
- R: ReadRef<'data>,
-{
- /// Parse the raw dyld shared cache data.
- ///
- /// For shared caches from macOS 12 / iOS 15 and above, the subcache files need to be
- /// supplied as well, in the correct order, with the `.symbols` subcache last (if present).
- /// For example, `data` would be the data for `dyld_shared_cache_x86_64`,
- /// and `subcache_data` would be the data for `[dyld_shared_cache_x86_64.1, dyld_shared_cache_x86_64.2, ...]`.
- pub fn parse(data: R, subcache_data: &[R]) -> Result<Self> {
- let header = macho::DyldCacheHeader::parse(data)?;
- let (arch, endian) = header.parse_magic()?;
- let mappings = header.mappings(endian, data)?;
-
- let symbols_subcache_uuid = header.symbols_subcache_uuid(endian);
- let subcaches_info = header.subcaches(endian, data)?.unwrap_or(&[]);
-
- if subcache_data.len() != subcaches_info.len() + symbols_subcache_uuid.is_some() as usize {
- return Err(Error("Incorrect number of SubCaches"));
- }
-
- // Split out the .symbols subcache data from the other subcaches.
- let (symbols_subcache_data_and_uuid, subcache_data) =
- if let Some(symbols_uuid) = symbols_subcache_uuid {
- let (sym_data, rest_data) = subcache_data.split_last().unwrap();
- (Some((*sym_data, symbols_uuid)), rest_data)
- } else {
- (None, subcache_data)
- };
-
- // Read the regular SubCaches (.1, .2, ...), if present.
- let mut subcaches = Vec::new();
- for (&data, info) in subcache_data.iter().zip(subcaches_info.iter()) {
- let sc_header = macho::DyldCacheHeader::<E>::parse(data)?;
- if sc_header.uuid != info.uuid {
- return Err(Error("Unexpected SubCache UUID"));
- }
- let mappings = sc_header.mappings(endian, data)?;
- subcaches.push(DyldSubCache { data, mappings });
- }
-
- // Read the .symbols SubCache, if present.
- // Other than the UUID verification, the symbols SubCache is currently unused.
- let _symbols_subcache = match symbols_subcache_data_and_uuid {
- Some((data, uuid)) => {
- let sc_header = macho::DyldCacheHeader::<E>::parse(data)?;
- if sc_header.uuid != uuid {
- return Err(Error("Unexpected .symbols SubCache UUID"));
- }
- let mappings = sc_header.mappings(endian, data)?;
- Some(DyldSubCache { data, mappings })
- }
- None => None,
- };
-
- let images = header.images(endian, data)?;
- Ok(DyldCache {
- endian,
- data,
- subcaches,
- mappings,
- images,
- arch,
- })
- }
-
- /// Get the architecture type of the file.
- pub fn architecture(&self) -> Architecture {
- self.arch
- }
-
- /// Get the endianness of the file.
- #[inline]
- pub fn endianness(&self) -> Endianness {
- if self.is_little_endian() {
- Endianness::Little
- } else {
- Endianness::Big
- }
- }
-
- /// Return true if the file is little endian, false if it is big endian.
- pub fn is_little_endian(&self) -> bool {
- self.endian.is_little_endian()
- }
-
- /// Iterate over the images in this cache.
- pub fn images<'cache>(&'cache self) -> DyldCacheImageIterator<'data, 'cache, E, R> {
- DyldCacheImageIterator {
- cache: self,
- iter: self.images.iter(),
- }
- }
-
- /// Find the address in a mapping and return the cache or subcache data it was found in,
- /// together with the translated file offset.
- pub fn data_and_offset_for_address(&self, address: u64) -> Option<(R, u64)> {
- if let Some(file_offset) = address_to_file_offset(address, self.endian, self.mappings) {
- return Some((self.data, file_offset));
- }
- for subcache in &self.subcaches {
- if let Some(file_offset) =
- address_to_file_offset(address, self.endian, subcache.mappings)
- {
- return Some((subcache.data, file_offset));
- }
- }
- None
- }
-}
-
-/// An iterator over all the images (dylibs) in the dyld shared cache.
-#[derive(Debug)]
-pub struct DyldCacheImageIterator<'data, 'cache, E = Endianness, R = &'data [u8]>
-where
- E: Endian,
- R: ReadRef<'data>,
-{
- cache: &'cache DyldCache<'data, E, R>,
- iter: slice::Iter<'data, macho::DyldCacheImageInfo<E>>,
-}
-
-impl<'data, 'cache, E, R> Iterator for DyldCacheImageIterator<'data, 'cache, E, R>
-where
- E: Endian,
- R: ReadRef<'data>,
-{
- type Item = DyldCacheImage<'data, 'cache, E, R>;
-
- fn next(&mut self) -> Option<DyldCacheImage<'data, 'cache, E, R>> {
- let image_info = self.iter.next()?;
- Some(DyldCacheImage {
- cache: self.cache,
- image_info,
- })
- }
-}
-
-/// One image (dylib) from inside the dyld shared cache.
-#[derive(Debug)]
-pub struct DyldCacheImage<'data, 'cache, E = Endianness, R = &'data [u8]>
-where
- E: Endian,
- R: ReadRef<'data>,
-{
- pub(crate) cache: &'cache DyldCache<'data, E, R>,
- image_info: &'data macho::DyldCacheImageInfo<E>,
-}
-
-impl<'data, 'cache, E, R> DyldCacheImage<'data, 'cache, E, R>
-where
- E: Endian,
- R: ReadRef<'data>,
-{
- /// The file system path of this image.
- pub fn path(&self) -> Result<&'data str> {
- let path = self.image_info.path(self.cache.endian, self.cache.data)?;
- // The path should always be ascii, so from_utf8 should always succeed.
- let path = core::str::from_utf8(path).map_err(|_| Error("Path string not valid utf-8"))?;
- Ok(path)
- }
-
- /// The subcache data which contains the Mach-O header for this image,
- /// together with the file offset at which this image starts.
- pub fn image_data_and_offset(&self) -> Result<(R, u64)> {
- let address = self.image_info.address.get(self.cache.endian);
- self.cache
- .data_and_offset_for_address(address)
- .ok_or(Error("Address not found in any mapping"))
- }
-
- /// Parse this image into an Object.
- pub fn parse_object(&self) -> Result<File<'data, R>> {
- File::parse_dyld_cache_image(self)
- }
-}
-
-impl<E: Endian> macho::DyldCacheHeader<E> {
- /// Read the dyld cache header.
- pub fn parse<'data, R: ReadRef<'data>>(data: R) -> Result<&'data Self> {
- data.read_at::<macho::DyldCacheHeader<E>>(0)
- .read_error("Invalid dyld cache header size or alignment")
- }
-
- /// Returns (arch, endian) based on the magic string.
- pub fn parse_magic(&self) -> Result<(Architecture, E)> {
- let (arch, is_big_endian) = match &self.magic {
- b"dyld_v1 i386\0" => (Architecture::I386, false),
- b"dyld_v1 x86_64\0" => (Architecture::X86_64, false),
- b"dyld_v1 x86_64h\0" => (Architecture::X86_64, false),
- b"dyld_v1 ppc\0" => (Architecture::PowerPc, true),
- b"dyld_v1 armv6\0" => (Architecture::Arm, false),
- b"dyld_v1 armv7\0" => (Architecture::Arm, false),
- b"dyld_v1 armv7f\0" => (Architecture::Arm, false),
- b"dyld_v1 armv7s\0" => (Architecture::Arm, false),
- b"dyld_v1 armv7k\0" => (Architecture::Arm, false),
- b"dyld_v1 arm64\0" => (Architecture::Aarch64, false),
- b"dyld_v1 arm64e\0" => (Architecture::Aarch64, false),
- _ => return Err(Error("Unrecognized dyld cache magic")),
- };
- let endian =
- E::from_big_endian(is_big_endian).read_error("Unsupported dyld cache endian")?;
- Ok((arch, endian))
- }
-
- /// Return the mapping information table.
- pub fn mappings<'data, R: ReadRef<'data>>(
- &self,
- endian: E,
- data: R,
- ) -> Result<&'data [macho::DyldCacheMappingInfo<E>]> {
- data.read_slice_at::<macho::DyldCacheMappingInfo<E>>(
- self.mapping_offset.get(endian).into(),
- self.mapping_count.get(endian) as usize,
- )
- .read_error("Invalid dyld cache mapping size or alignment")
- }
-
- /// Return the information about subcaches, if present.
- pub fn subcaches<'data, R: ReadRef<'data>>(
- &self,
- endian: E,
- data: R,
- ) -> Result<Option<&'data [macho::DyldSubCacheInfo<E>]>> {
- if self.mapping_offset.get(endian) >= MIN_HEADER_SIZE_SUBCACHES {
- let subcaches = data
- .read_slice_at::<macho::DyldSubCacheInfo<E>>(
- self.subcaches_offset.get(endian).into(),
- self.subcaches_count.get(endian) as usize,
- )
- .read_error("Invalid dyld subcaches size or alignment")?;
- Ok(Some(subcaches))
- } else {
- Ok(None)
- }
- }
-
- /// Return the UUID for the .symbols subcache, if present.
- pub fn symbols_subcache_uuid(&self, endian: E) -> Option<[u8; 16]> {
- if self.mapping_offset.get(endian) >= MIN_HEADER_SIZE_SUBCACHES {
- let uuid = self.symbols_subcache_uuid;
- if uuid != [0; 16] {
- return Some(uuid);
- }
- }
- None
- }
-
- /// Return the image information table.
- pub fn images<'data, R: ReadRef<'data>>(
- &self,
- endian: E,
- data: R,
- ) -> Result<&'data [macho::DyldCacheImageInfo<E>]> {
- if self.mapping_offset.get(endian) >= MIN_HEADER_SIZE_SUBCACHES {
- data.read_slice_at::<macho::DyldCacheImageInfo<E>>(
- self.images_across_all_subcaches_offset.get(endian).into(),
- self.images_across_all_subcaches_count.get(endian) as usize,
- )
- .read_error("Invalid dyld cache image size or alignment")
- } else {
- data.read_slice_at::<macho::DyldCacheImageInfo<E>>(
- self.images_offset.get(endian).into(),
- self.images_count.get(endian) as usize,
- )
- .read_error("Invalid dyld cache image size or alignment")
- }
- }
-}
-
-impl<E: Endian> macho::DyldCacheImageInfo<E> {
- /// The file system path of this image.
- pub fn path<'data, R: ReadRef<'data>>(&self, endian: E, data: R) -> Result<&'data [u8]> {
- let r_start = self.path_file_offset.get(endian).into();
- let r_end = data.len().read_error("Couldn't get data len()")?;
- data.read_bytes_at_until(r_start..r_end, 0)
- .read_error("Couldn't read dyld cache image path")
- }
-
- /// Find the file offset of the image by looking up its address in the mappings.
- pub fn file_offset(
- &self,
- endian: E,
- mappings: &[macho::DyldCacheMappingInfo<E>],
- ) -> Result<u64> {
- let address = self.address.get(endian);
- address_to_file_offset(address, endian, mappings)
- .read_error("Invalid dyld cache image address")
- }
-}
-
-/// Find the file offset of the image by looking up its address in the mappings.
-pub fn address_to_file_offset<E: Endian>(
- address: u64,
- endian: E,
- mappings: &[macho::DyldCacheMappingInfo<E>],
-) -> Option<u64> {
- for mapping in mappings {
- let mapping_address = mapping.address.get(endian);
- if address >= mapping_address
- && address < mapping_address.wrapping_add(mapping.size.get(endian))
- {
- return Some(address - mapping_address + mapping.file_offset.get(endian));
- }
- }
- None
-}
diff --git a/vendor/object/src/read/macho/fat.rs b/vendor/object/src/read/macho/fat.rs
deleted file mode 100644
index a481351..0000000
--- a/vendor/object/src/read/macho/fat.rs
+++ /dev/null
@@ -1,122 +0,0 @@
-use crate::read::{Architecture, Error, ReadError, ReadRef, Result};
-use crate::{macho, BigEndian, Pod};
-
-pub use macho::{FatArch32, FatArch64, FatHeader};
-
-impl FatHeader {
- /// Attempt to parse a fat header.
- ///
- /// Does not validate the magic value.
- pub fn parse<'data, R: ReadRef<'data>>(file: R) -> Result<&'data FatHeader> {
- file.read_at::<FatHeader>(0)
- .read_error("Invalid fat header size or alignment")
- }
-
- /// Attempt to parse a fat header and 32-bit fat arches.
- pub fn parse_arch32<'data, R: ReadRef<'data>>(file: R) -> Result<&'data [FatArch32]> {
- let mut offset = 0;
- let header = file
- .read::<FatHeader>(&mut offset)
- .read_error("Invalid fat header size or alignment")?;
- if header.magic.get(BigEndian) != macho::FAT_MAGIC {
- return Err(Error("Invalid 32-bit fat magic"));
- }
- file.read_slice::<FatArch32>(&mut offset, header.nfat_arch.get(BigEndian) as usize)
- .read_error("Invalid nfat_arch")
- }
-
- /// Attempt to parse a fat header and 64-bit fat arches.
- pub fn parse_arch64<'data, R: ReadRef<'data>>(file: R) -> Result<&'data [FatArch64]> {
- let mut offset = 0;
- let header = file
- .read::<FatHeader>(&mut offset)
- .read_error("Invalid fat header size or alignment")?;
- if header.magic.get(BigEndian) != macho::FAT_MAGIC_64 {
- return Err(Error("Invalid 64-bit fat magic"));
- }
- file.read_slice::<FatArch64>(&mut offset, header.nfat_arch.get(BigEndian) as usize)
- .read_error("Invalid nfat_arch")
- }
-}
-
-/// A trait for generic access to [`macho::FatArch32`] and [`macho::FatArch64`].
-#[allow(missing_docs)]
-pub trait FatArch: Pod {
- type Word: Into<u64>;
-
- fn cputype(&self) -> u32;
- fn cpusubtype(&self) -> u32;
- fn offset(&self) -> Self::Word;
- fn size(&self) -> Self::Word;
- fn align(&self) -> u32;
-
- fn architecture(&self) -> Architecture {
- match self.cputype() {
- macho::CPU_TYPE_ARM => Architecture::Arm,
- macho::CPU_TYPE_ARM64 => Architecture::Aarch64,
- macho::CPU_TYPE_X86 => Architecture::I386,
- macho::CPU_TYPE_X86_64 => Architecture::X86_64,
- macho::CPU_TYPE_MIPS => Architecture::Mips,
- macho::CPU_TYPE_POWERPC => Architecture::PowerPc,
- macho::CPU_TYPE_POWERPC64 => Architecture::PowerPc64,
- _ => Architecture::Unknown,
- }
- }
-
- fn file_range(&self) -> (u64, u64) {
- (self.offset().into(), self.size().into())
- }
-
- fn data<'data, R: ReadRef<'data>>(&self, file: R) -> Result<&'data [u8]> {
- file.read_bytes_at(self.offset().into(), self.size().into())
- .read_error("Invalid fat arch offset or size")
- }
-}
-
-impl FatArch for FatArch32 {
- type Word = u32;
-
- fn cputype(&self) -> u32 {
- self.cputype.get(BigEndian)
- }
-
- fn cpusubtype(&self) -> u32 {
- self.cpusubtype.get(BigEndian)
- }
-
- fn offset(&self) -> Self::Word {
- self.offset.get(BigEndian)
- }
-
- fn size(&self) -> Self::Word {
- self.size.get(BigEndian)
- }
-
- fn align(&self) -> u32 {
- self.align.get(BigEndian)
- }
-}
-
-impl FatArch for FatArch64 {
- type Word = u64;
-
- fn cputype(&self) -> u32 {
- self.cputype.get(BigEndian)
- }
-
- fn cpusubtype(&self) -> u32 {
- self.cpusubtype.get(BigEndian)
- }
-
- fn offset(&self) -> Self::Word {
- self.offset.get(BigEndian)
- }
-
- fn size(&self) -> Self::Word {
- self.size.get(BigEndian)
- }
-
- fn align(&self) -> u32 {
- self.align.get(BigEndian)
- }
-}
diff --git a/vendor/object/src/read/macho/file.rs b/vendor/object/src/read/macho/file.rs
deleted file mode 100644
index 0e04477..0000000
--- a/vendor/object/src/read/macho/file.rs
+++ /dev/null
@@ -1,781 +0,0 @@
-use alloc::vec::Vec;
-use core::fmt::Debug;
-use core::{mem, str};
-
-use crate::read::{
- self, Architecture, ComdatKind, Error, Export, FileFlags, Import, NoDynamicRelocationIterator,
- Object, ObjectComdat, ObjectKind, ObjectMap, ObjectSection, ReadError, ReadRef, Result,
- SectionIndex, SubArchitecture, SymbolIndex,
-};
-use crate::{endian, macho, BigEndian, ByteString, Endian, Endianness, Pod};
-
-use super::{
- DyldCacheImage, LoadCommandIterator, MachOSection, MachOSectionInternal, MachOSectionIterator,
- MachOSegment, MachOSegmentInternal, MachOSegmentIterator, MachOSymbol, MachOSymbolIterator,
- MachOSymbolTable, Nlist, Section, Segment, SymbolTable,
-};
-
-/// A 32-bit Mach-O object file.
-///
-/// This is a file that starts with [`macho::MachHeader32`], and corresponds
-/// to [`crate::FileKind::MachO32`].
-pub type MachOFile32<'data, Endian = Endianness, R = &'data [u8]> =
- MachOFile<'data, macho::MachHeader32<Endian>, R>;
-/// A 64-bit Mach-O object file.
-///
-/// This is a file that starts with [`macho::MachHeader64`], and corresponds
-/// to [`crate::FileKind::MachO64`].
-pub type MachOFile64<'data, Endian = Endianness, R = &'data [u8]> =
- MachOFile<'data, macho::MachHeader64<Endian>, R>;
-
-/// A partially parsed Mach-O file.
-///
-/// Most of the functionality of this type is provided by the [`Object`] trait implementation.
-#[derive(Debug)]
-pub struct MachOFile<'data, Mach, R = &'data [u8]>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- pub(super) endian: Mach::Endian,
- pub(super) data: R,
- pub(super) header_offset: u64,
- pub(super) header: &'data Mach,
- pub(super) segments: Vec<MachOSegmentInternal<'data, Mach, R>>,
- pub(super) sections: Vec<MachOSectionInternal<'data, Mach>>,
- pub(super) symbols: SymbolTable<'data, Mach, R>,
-}
-
-impl<'data, Mach, R> MachOFile<'data, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- /// Parse the raw Mach-O file data.
- pub fn parse(data: R) -> Result<Self> {
- let header = Mach::parse(data, 0)?;
- let endian = header.endian()?;
-
- // Build a list of segments and sections to make some operations more efficient.
- let mut segments = Vec::new();
- let mut sections = Vec::new();
- let mut symbols = SymbolTable::default();
- if let Ok(mut commands) = header.load_commands(endian, data, 0) {
- while let Ok(Some(command)) = commands.next() {
- if let Some((segment, section_data)) = Mach::Segment::from_command(command)? {
- let segment_index = segments.len();
- segments.push(MachOSegmentInternal { segment, data });
- for section in segment.sections(endian, section_data)? {
- let index = SectionIndex(sections.len() + 1);
- sections.push(MachOSectionInternal::parse(index, segment_index, section));
- }
- } else if let Some(symtab) = command.symtab()? {
- symbols = symtab.symbols(endian, data)?;
- }
- }
- }
-
- Ok(MachOFile {
- endian,
- data,
- header_offset: 0,
- header,
- segments,
- sections,
- symbols,
- })
- }
-
- /// Parse the Mach-O file for the given image from the dyld shared cache.
- /// This will read different sections from different subcaches, if necessary.
- pub fn parse_dyld_cache_image<'cache, E: Endian>(
- image: &DyldCacheImage<'data, 'cache, E, R>,
- ) -> Result<Self> {
- let (data, header_offset) = image.image_data_and_offset()?;
- let header = Mach::parse(data, header_offset)?;
- let endian = header.endian()?;
-
- // Build a list of sections to make some operations more efficient.
- // Also build a list of segments, because we need to remember which ReadRef
- // to read each section's data from. Only the DyldCache knows this information,
- // and we won't have access to it once we've exited this function.
- let mut segments = Vec::new();
- let mut sections = Vec::new();
- let mut linkedit_data: Option<R> = None;
- let mut symtab = None;
- if let Ok(mut commands) = header.load_commands(endian, data, header_offset) {
- while let Ok(Some(command)) = commands.next() {
- if let Some((segment, section_data)) = Mach::Segment::from_command(command)? {
- // Each segment can be stored in a different subcache. Get the segment's
- // address and look it up in the cache mappings, to find the correct cache data.
- let addr = segment.vmaddr(endian).into();
- let (data, _offset) = image
- .cache
- .data_and_offset_for_address(addr)
- .read_error("Could not find segment data in dyld shared cache")?;
- if segment.name() == macho::SEG_LINKEDIT.as_bytes() {
- linkedit_data = Some(data);
- }
- let segment_index = segments.len();
- segments.push(MachOSegmentInternal { segment, data });
-
- for section in segment.sections(endian, section_data)? {
- let index = SectionIndex(sections.len() + 1);
- sections.push(MachOSectionInternal::parse(index, segment_index, section));
- }
- } else if let Some(st) = command.symtab()? {
- symtab = Some(st);
- }
- }
- }
-
- // The symbols are found in the __LINKEDIT segment, so make sure to read them from the
- // correct subcache.
- let symbols = match (symtab, linkedit_data) {
- (Some(symtab), Some(linkedit_data)) => symtab.symbols(endian, linkedit_data)?,
- _ => SymbolTable::default(),
- };
-
- Ok(MachOFile {
- endian,
- data,
- header_offset,
- header,
- segments,
- sections,
- symbols,
- })
- }
-
- /// Return the section at the given index.
- #[inline]
- pub(super) fn section_internal(
- &self,
- index: SectionIndex,
- ) -> Result<&MachOSectionInternal<'data, Mach>> {
- index
- .0
- .checked_sub(1)
- .and_then(|index| self.sections.get(index))
- .read_error("Invalid Mach-O section index")
- }
-
- pub(super) fn segment_internal(
- &self,
- index: usize,
- ) -> Result<&MachOSegmentInternal<'data, Mach, R>> {
- self.segments
- .get(index)
- .read_error("Invalid Mach-O segment index")
- }
-
- /// Returns the endianness.
- pub fn endian(&self) -> Mach::Endian {
- self.endian
- }
-
- /// Returns the raw data.
- pub fn data(&self) -> R {
- self.data
- }
-
- /// Returns the raw Mach-O file header.
- pub fn raw_header(&self) -> &'data Mach {
- self.header
- }
-
- /// Return the `LC_BUILD_VERSION` load command if present.
- pub fn build_version(&self) -> Result<Option<&'data macho::BuildVersionCommand<Mach::Endian>>> {
- let mut commands = self
- .header
- .load_commands(self.endian, self.data, self.header_offset)?;
- while let Some(command) = commands.next()? {
- if let Some(build_version) = command.build_version()? {
- return Ok(Some(build_version));
- }
- }
- Ok(None)
- }
-}
-
-impl<'data, Mach, R> read::private::Sealed for MachOFile<'data, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Mach, R> Object<'data, 'file> for MachOFile<'data, Mach, R>
-where
- 'data: 'file,
- Mach: MachHeader,
- R: 'file + ReadRef<'data>,
-{
- type Segment = MachOSegment<'data, 'file, Mach, R>;
- type SegmentIterator = MachOSegmentIterator<'data, 'file, Mach, R>;
- type Section = MachOSection<'data, 'file, Mach, R>;
- type SectionIterator = MachOSectionIterator<'data, 'file, Mach, R>;
- type Comdat = MachOComdat<'data, 'file, Mach, R>;
- type ComdatIterator = MachOComdatIterator<'data, 'file, Mach, R>;
- type Symbol = MachOSymbol<'data, 'file, Mach, R>;
- type SymbolIterator = MachOSymbolIterator<'data, 'file, Mach, R>;
- type SymbolTable = MachOSymbolTable<'data, 'file, Mach, R>;
- type DynamicRelocationIterator = NoDynamicRelocationIterator;
-
- fn architecture(&self) -> Architecture {
- match self.header.cputype(self.endian) {
- macho::CPU_TYPE_ARM => Architecture::Arm,
- macho::CPU_TYPE_ARM64 => Architecture::Aarch64,
- macho::CPU_TYPE_ARM64_32 => Architecture::Aarch64_Ilp32,
- macho::CPU_TYPE_X86 => Architecture::I386,
- macho::CPU_TYPE_X86_64 => Architecture::X86_64,
- macho::CPU_TYPE_MIPS => Architecture::Mips,
- macho::CPU_TYPE_POWERPC => Architecture::PowerPc,
- macho::CPU_TYPE_POWERPC64 => Architecture::PowerPc64,
- _ => Architecture::Unknown,
- }
- }
-
- fn sub_architecture(&self) -> Option<SubArchitecture> {
- match (
- self.header.cputype(self.endian),
- self.header.cpusubtype(self.endian),
- ) {
- (macho::CPU_TYPE_ARM64, macho::CPU_SUBTYPE_ARM64E) => Some(SubArchitecture::Arm64E),
- _ => None,
- }
- }
-
- #[inline]
- fn is_little_endian(&self) -> bool {
- self.header.is_little_endian()
- }
-
- #[inline]
- fn is_64(&self) -> bool {
- self.header.is_type_64()
- }
-
- fn kind(&self) -> ObjectKind {
- match self.header.filetype(self.endian) {
- macho::MH_OBJECT => ObjectKind::Relocatable,
- macho::MH_EXECUTE => ObjectKind::Executable,
- macho::MH_CORE => ObjectKind::Core,
- macho::MH_DYLIB => ObjectKind::Dynamic,
- _ => ObjectKind::Unknown,
- }
- }
-
- fn segments(&'file self) -> MachOSegmentIterator<'data, 'file, Mach, R> {
- MachOSegmentIterator {
- file: self,
- iter: self.segments.iter(),
- }
- }
-
- fn section_by_name_bytes(
- &'file self,
- section_name: &[u8],
- ) -> Option<MachOSection<'data, 'file, Mach, R>> {
- // Translate the "." prefix to the "__" prefix used by OSX/Mach-O, eg
- // ".debug_info" to "__debug_info", and limit to 16 bytes total.
- let system_name = if section_name.starts_with(b".") {
- if section_name.len() > 15 {
- Some(&section_name[1..15])
- } else {
- Some(&section_name[1..])
- }
- } else {
- None
- };
- let cmp_section_name = |section: &MachOSection<'data, 'file, Mach, R>| {
- section
- .name_bytes()
- .map(|name| {
- section_name == name
- || system_name
- .filter(|system_name| {
- name.starts_with(b"__") && name[2..] == **system_name
- })
- .is_some()
- })
- .unwrap_or(false)
- };
-
- self.sections().find(cmp_section_name)
- }
-
- fn section_by_index(
- &'file self,
- index: SectionIndex,
- ) -> Result<MachOSection<'data, 'file, Mach, R>> {
- let internal = *self.section_internal(index)?;
- Ok(MachOSection {
- file: self,
- internal,
- })
- }
-
- fn sections(&'file self) -> MachOSectionIterator<'data, 'file, Mach, R> {
- MachOSectionIterator {
- file: self,
- iter: self.sections.iter(),
- }
- }
-
- fn comdats(&'file self) -> MachOComdatIterator<'data, 'file, Mach, R> {
- MachOComdatIterator { file: self }
- }
-
- fn symbol_by_index(
- &'file self,
- index: SymbolIndex,
- ) -> Result<MachOSymbol<'data, 'file, Mach, R>> {
- let nlist = self.symbols.symbol(index.0)?;
- MachOSymbol::new(self, index, nlist).read_error("Unsupported Mach-O symbol index")
- }
-
- fn symbols(&'file self) -> MachOSymbolIterator<'data, 'file, Mach, R> {
- MachOSymbolIterator {
- file: self,
- index: 0,
- }
- }
-
- #[inline]
- fn symbol_table(&'file self) -> Option<MachOSymbolTable<'data, 'file, Mach, R>> {
- Some(MachOSymbolTable { file: self })
- }
-
- fn dynamic_symbols(&'file self) -> MachOSymbolIterator<'data, 'file, Mach, R> {
- MachOSymbolIterator {
- file: self,
- index: self.symbols.len(),
- }
- }
-
- #[inline]
- fn dynamic_symbol_table(&'file self) -> Option<MachOSymbolTable<'data, 'file, Mach, R>> {
- None
- }
-
- fn object_map(&'file self) -> ObjectMap<'data> {
- self.symbols.object_map(self.endian)
- }
-
- fn imports(&self) -> Result<Vec<Import<'data>>> {
- let mut dysymtab = None;
- let mut libraries = Vec::new();
- let twolevel = self.header.flags(self.endian) & macho::MH_TWOLEVEL != 0;
- if twolevel {
- libraries.push(&[][..]);
- }
- let mut commands = self
- .header
- .load_commands(self.endian, self.data, self.header_offset)?;
- while let Some(command) = commands.next()? {
- if let Some(command) = command.dysymtab()? {
- dysymtab = Some(command);
- }
- if twolevel {
- if let Some(dylib) = command.dylib()? {
- libraries.push(command.string(self.endian, dylib.dylib.name)?);
- }
- }
- }
-
- let mut imports = Vec::new();
- if let Some(dysymtab) = dysymtab {
- let index = dysymtab.iundefsym.get(self.endian) as usize;
- let number = dysymtab.nundefsym.get(self.endian) as usize;
- for i in index..(index.wrapping_add(number)) {
- let symbol = self.symbols.symbol(i)?;
- let name = symbol.name(self.endian, self.symbols.strings())?;
- let library = if twolevel {
- libraries
- .get(symbol.library_ordinal(self.endian) as usize)
- .copied()
- .read_error("Invalid Mach-O symbol library ordinal")?
- } else {
- &[]
- };
- imports.push(Import {
- name: ByteString(name),
- library: ByteString(library),
- });
- }
- }
- Ok(imports)
- }
-
- fn exports(&self) -> Result<Vec<Export<'data>>> {
- let mut dysymtab = None;
- let mut commands = self
- .header
- .load_commands(self.endian, self.data, self.header_offset)?;
- while let Some(command) = commands.next()? {
- if let Some(command) = command.dysymtab()? {
- dysymtab = Some(command);
- break;
- }
- }
-
- let mut exports = Vec::new();
- if let Some(dysymtab) = dysymtab {
- let index = dysymtab.iextdefsym.get(self.endian) as usize;
- let number = dysymtab.nextdefsym.get(self.endian) as usize;
- for i in index..(index.wrapping_add(number)) {
- let symbol = self.symbols.symbol(i)?;
- let name = symbol.name(self.endian, self.symbols.strings())?;
- let address = symbol.n_value(self.endian).into();
- exports.push(Export {
- name: ByteString(name),
- address,
- });
- }
- }
- Ok(exports)
- }
-
- #[inline]
- fn dynamic_relocations(&'file self) -> Option<NoDynamicRelocationIterator> {
- None
- }
-
- fn has_debug_symbols(&self) -> bool {
- self.section_by_name(".debug_info").is_some()
- }
-
- fn mach_uuid(&self) -> Result<Option<[u8; 16]>> {
- self.header.uuid(self.endian, self.data, self.header_offset)
- }
-
- fn relative_address_base(&self) -> u64 {
- 0
- }
-
- fn entry(&self) -> u64 {
- if let Ok(mut commands) =
- self.header
- .load_commands(self.endian, self.data, self.header_offset)
- {
- while let Ok(Some(command)) = commands.next() {
- if let Ok(Some(command)) = command.entry_point() {
- return command.entryoff.get(self.endian);
- }
- }
- }
- 0
- }
-
- fn flags(&self) -> FileFlags {
- FileFlags::MachO {
- flags: self.header.flags(self.endian),
- }
- }
-}
-
-/// An iterator for the COMDAT section groups in a [`MachOFile64`].
-pub type MachOComdatIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOComdatIterator<'data, 'file, macho::MachHeader32<Endian>, R>;
-/// An iterator for the COMDAT section groups in a [`MachOFile64`].
-pub type MachOComdatIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOComdatIterator<'data, 'file, macho::MachHeader64<Endian>, R>;
-
-/// An iterator for the COMDAT section groups in a [`MachOFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct MachOComdatIterator<'data, 'file, Mach, R = &'data [u8]>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- #[allow(unused)]
- file: &'file MachOFile<'data, Mach, R>,
-}
-
-impl<'data, 'file, Mach, R> Iterator for MachOComdatIterator<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- type Item = MachOComdat<'data, 'file, Mach, R>;
-
- #[inline]
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
-}
-
-/// A COMDAT section group in a [`MachOFile32`].
-pub type MachOComdat32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOComdat<'data, 'file, macho::MachHeader32<Endian>, R>;
-
-/// A COMDAT section group in a [`MachOFile64`].
-pub type MachOComdat64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOComdat<'data, 'file, macho::MachHeader64<Endian>, R>;
-
-/// A COMDAT section group in a [`MachOFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct MachOComdat<'data, 'file, Mach, R = &'data [u8]>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- #[allow(unused)]
- file: &'file MachOFile<'data, Mach, R>,
-}
-
-impl<'data, 'file, Mach, R> read::private::Sealed for MachOComdat<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Mach, R> ObjectComdat<'data> for MachOComdat<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- type SectionIterator = MachOComdatSectionIterator<'data, 'file, Mach, R>;
-
- #[inline]
- fn kind(&self) -> ComdatKind {
- unreachable!();
- }
-
- #[inline]
- fn symbol(&self) -> SymbolIndex {
- unreachable!();
- }
-
- #[inline]
- fn name_bytes(&self) -> Result<&[u8]> {
- unreachable!();
- }
-
- #[inline]
- fn name(&self) -> Result<&str> {
- unreachable!();
- }
-
- #[inline]
- fn sections(&self) -> Self::SectionIterator {
- unreachable!();
- }
-}
-
-/// An iterator for the sections in a COMDAT section group in a [`MachOFile32`].
-pub type MachOComdatSectionIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOComdatSectionIterator<'data, 'file, macho::MachHeader32<Endian>, R>;
-/// An iterator for the sections in a COMDAT section group in a [`MachOFile64`].
-pub type MachOComdatSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOComdatSectionIterator<'data, 'file, macho::MachHeader64<Endian>, R>;
-
-/// An iterator for the sections in a COMDAT section group in a [`MachOFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct MachOComdatSectionIterator<'data, 'file, Mach, R = &'data [u8]>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- #[allow(unused)]
- file: &'file MachOFile<'data, Mach, R>,
-}
-
-impl<'data, 'file, Mach, R> Iterator for MachOComdatSectionIterator<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- type Item = SectionIndex;
-
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
-}
-
-/// A trait for generic access to [`macho::MachHeader32`] and [`macho::MachHeader64`].
-#[allow(missing_docs)]
-pub trait MachHeader: Debug + Pod {
- type Word: Into<u64>;
- type Endian: endian::Endian;
- type Segment: Segment<Endian = Self::Endian, Section = Self::Section>;
- type Section: Section<Endian = Self::Endian>;
- type Nlist: Nlist<Endian = Self::Endian>;
-
- /// Return true if this type is a 64-bit header.
- ///
- /// This is a property of the type, not a value in the header data.
- fn is_type_64(&self) -> bool;
-
- /// Return true if the `magic` field signifies big-endian.
- fn is_big_endian(&self) -> bool;
-
- /// Return true if the `magic` field signifies little-endian.
- fn is_little_endian(&self) -> bool;
-
- fn magic(&self) -> u32;
- fn cputype(&self, endian: Self::Endian) -> u32;
- fn cpusubtype(&self, endian: Self::Endian) -> u32;
- fn filetype(&self, endian: Self::Endian) -> u32;
- fn ncmds(&self, endian: Self::Endian) -> u32;
- fn sizeofcmds(&self, endian: Self::Endian) -> u32;
- fn flags(&self, endian: Self::Endian) -> u32;
-
- // Provided methods.
-
- /// Read the file header.
- ///
- /// Also checks that the magic field in the file header is a supported format.
- fn parse<'data, R: ReadRef<'data>>(data: R, offset: u64) -> read::Result<&'data Self> {
- let header = data
- .read_at::<Self>(offset)
- .read_error("Invalid Mach-O header size or alignment")?;
- if !header.is_supported() {
- return Err(Error("Unsupported Mach-O header"));
- }
- Ok(header)
- }
-
- fn is_supported(&self) -> bool {
- self.is_little_endian() || self.is_big_endian()
- }
-
- fn endian(&self) -> Result<Self::Endian> {
- Self::Endian::from_big_endian(self.is_big_endian()).read_error("Unsupported Mach-O endian")
- }
-
- fn load_commands<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- header_offset: u64,
- ) -> Result<LoadCommandIterator<'data, Self::Endian>> {
- let data = data
- .read_bytes_at(
- header_offset + mem::size_of::<Self>() as u64,
- self.sizeofcmds(endian).into(),
- )
- .read_error("Invalid Mach-O load command table size")?;
- Ok(LoadCommandIterator::new(endian, data, self.ncmds(endian)))
- }
-
- /// Return the UUID from the `LC_UUID` load command, if one is present.
- fn uuid<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- header_offset: u64,
- ) -> Result<Option<[u8; 16]>> {
- let mut commands = self.load_commands(endian, data, header_offset)?;
- while let Some(command) = commands.next()? {
- if let Ok(Some(uuid)) = command.uuid() {
- return Ok(Some(uuid.uuid));
- }
- }
- Ok(None)
- }
-}
-
-impl<Endian: endian::Endian> MachHeader for macho::MachHeader32<Endian> {
- type Word = u32;
- type Endian = Endian;
- type Segment = macho::SegmentCommand32<Endian>;
- type Section = macho::Section32<Endian>;
- type Nlist = macho::Nlist32<Endian>;
-
- fn is_type_64(&self) -> bool {
- false
- }
-
- fn is_big_endian(&self) -> bool {
- self.magic() == macho::MH_MAGIC
- }
-
- fn is_little_endian(&self) -> bool {
- self.magic() == macho::MH_CIGAM
- }
-
- fn magic(&self) -> u32 {
- self.magic.get(BigEndian)
- }
-
- fn cputype(&self, endian: Self::Endian) -> u32 {
- self.cputype.get(endian)
- }
-
- fn cpusubtype(&self, endian: Self::Endian) -> u32 {
- self.cpusubtype.get(endian)
- }
-
- fn filetype(&self, endian: Self::Endian) -> u32 {
- self.filetype.get(endian)
- }
-
- fn ncmds(&self, endian: Self::Endian) -> u32 {
- self.ncmds.get(endian)
- }
-
- fn sizeofcmds(&self, endian: Self::Endian) -> u32 {
- self.sizeofcmds.get(endian)
- }
-
- fn flags(&self, endian: Self::Endian) -> u32 {
- self.flags.get(endian)
- }
-}
-
-impl<Endian: endian::Endian> MachHeader for macho::MachHeader64<Endian> {
- type Word = u64;
- type Endian = Endian;
- type Segment = macho::SegmentCommand64<Endian>;
- type Section = macho::Section64<Endian>;
- type Nlist = macho::Nlist64<Endian>;
-
- fn is_type_64(&self) -> bool {
- true
- }
-
- fn is_big_endian(&self) -> bool {
- self.magic() == macho::MH_MAGIC_64
- }
-
- fn is_little_endian(&self) -> bool {
- self.magic() == macho::MH_CIGAM_64
- }
-
- fn magic(&self) -> u32 {
- self.magic.get(BigEndian)
- }
-
- fn cputype(&self, endian: Self::Endian) -> u32 {
- self.cputype.get(endian)
- }
-
- fn cpusubtype(&self, endian: Self::Endian) -> u32 {
- self.cpusubtype.get(endian)
- }
-
- fn filetype(&self, endian: Self::Endian) -> u32 {
- self.filetype.get(endian)
- }
-
- fn ncmds(&self, endian: Self::Endian) -> u32 {
- self.ncmds.get(endian)
- }
-
- fn sizeofcmds(&self, endian: Self::Endian) -> u32 {
- self.sizeofcmds.get(endian)
- }
-
- fn flags(&self, endian: Self::Endian) -> u32 {
- self.flags.get(endian)
- }
-}
diff --git a/vendor/object/src/read/macho/load_command.rs b/vendor/object/src/read/macho/load_command.rs
deleted file mode 100644
index 7225fbd..0000000
--- a/vendor/object/src/read/macho/load_command.rs
+++ /dev/null
@@ -1,382 +0,0 @@
-use core::marker::PhantomData;
-use core::mem;
-
-use crate::endian::Endian;
-use crate::macho;
-use crate::pod::Pod;
-use crate::read::macho::{MachHeader, SymbolTable};
-use crate::read::{Bytes, Error, ReadError, ReadRef, Result, StringTable};
-
-/// An iterator for the load commands from a [`MachHeader`].
-#[derive(Debug, Default, Clone, Copy)]
-pub struct LoadCommandIterator<'data, E: Endian> {
- endian: E,
- data: Bytes<'data>,
- ncmds: u32,
-}
-
-impl<'data, E: Endian> LoadCommandIterator<'data, E> {
- pub(super) fn new(endian: E, data: &'data [u8], ncmds: u32) -> Self {
- LoadCommandIterator {
- endian,
- data: Bytes(data),
- ncmds,
- }
- }
-
- /// Return the next load command.
- pub fn next(&mut self) -> Result<Option<LoadCommandData<'data, E>>> {
- if self.ncmds == 0 {
- return Ok(None);
- }
- let header = self
- .data
- .read_at::<macho::LoadCommand<E>>(0)
- .read_error("Invalid Mach-O load command header")?;
- let cmd = header.cmd.get(self.endian);
- let cmdsize = header.cmdsize.get(self.endian) as usize;
- if cmdsize < mem::size_of::<macho::LoadCommand<E>>() {
- return Err(Error("Invalid Mach-O load command size"));
- }
- let data = self
- .data
- .read_bytes(cmdsize)
- .read_error("Invalid Mach-O load command size")?;
- self.ncmds -= 1;
- Ok(Some(LoadCommandData {
- cmd,
- data,
- marker: Default::default(),
- }))
- }
-}
-
-/// The data for a [`macho::LoadCommand`].
-#[derive(Debug, Clone, Copy)]
-pub struct LoadCommandData<'data, E: Endian> {
- cmd: u32,
- // Includes the header.
- data: Bytes<'data>,
- marker: PhantomData<E>,
-}
-
-impl<'data, E: Endian> LoadCommandData<'data, E> {
- /// Return the `cmd` field of the [`macho::LoadCommand`].
- ///
- /// This is one of the `LC_` constants.
- pub fn cmd(&self) -> u32 {
- self.cmd
- }
-
- /// Return the `cmdsize` field of the [`macho::LoadCommand`].
- pub fn cmdsize(&self) -> u32 {
- self.data.len() as u32
- }
-
- /// Parse the data as the given type.
- #[inline]
- pub fn data<T: Pod>(&self) -> Result<&'data T> {
- self.data
- .read_at(0)
- .read_error("Invalid Mach-O command size")
- }
-
- /// Raw bytes of this [`macho::LoadCommand`] structure.
- pub fn raw_data(&self) -> &'data [u8] {
- self.data.0
- }
-
- /// Parse a load command string value.
- ///
- /// Strings used by load commands are specified by offsets that are
- /// relative to the load command header.
- pub fn string(&self, endian: E, s: macho::LcStr<E>) -> Result<&'data [u8]> {
- self.data
- .read_string_at(s.offset.get(endian) as usize)
- .read_error("Invalid load command string offset")
- }
-
- /// Parse the command data according to the `cmd` field.
- pub fn variant(&self) -> Result<LoadCommandVariant<'data, E>> {
- Ok(match self.cmd {
- macho::LC_SEGMENT => {
- let mut data = self.data;
- let segment = data.read().read_error("Invalid Mach-O command size")?;
- LoadCommandVariant::Segment32(segment, data.0)
- }
- macho::LC_SYMTAB => LoadCommandVariant::Symtab(self.data()?),
- macho::LC_THREAD | macho::LC_UNIXTHREAD => {
- let mut data = self.data;
- let thread = data.read().read_error("Invalid Mach-O command size")?;
- LoadCommandVariant::Thread(thread, data.0)
- }
- macho::LC_DYSYMTAB => LoadCommandVariant::Dysymtab(self.data()?),
- macho::LC_LOAD_DYLIB
- | macho::LC_LOAD_WEAK_DYLIB
- | macho::LC_REEXPORT_DYLIB
- | macho::LC_LAZY_LOAD_DYLIB
- | macho::LC_LOAD_UPWARD_DYLIB => LoadCommandVariant::Dylib(self.data()?),
- macho::LC_ID_DYLIB => LoadCommandVariant::IdDylib(self.data()?),
- macho::LC_LOAD_DYLINKER => LoadCommandVariant::LoadDylinker(self.data()?),
- macho::LC_ID_DYLINKER => LoadCommandVariant::IdDylinker(self.data()?),
- macho::LC_PREBOUND_DYLIB => LoadCommandVariant::PreboundDylib(self.data()?),
- macho::LC_ROUTINES => LoadCommandVariant::Routines32(self.data()?),
- macho::LC_SUB_FRAMEWORK => LoadCommandVariant::SubFramework(self.data()?),
- macho::LC_SUB_UMBRELLA => LoadCommandVariant::SubUmbrella(self.data()?),
- macho::LC_SUB_CLIENT => LoadCommandVariant::SubClient(self.data()?),
- macho::LC_SUB_LIBRARY => LoadCommandVariant::SubLibrary(self.data()?),
- macho::LC_TWOLEVEL_HINTS => LoadCommandVariant::TwolevelHints(self.data()?),
- macho::LC_PREBIND_CKSUM => LoadCommandVariant::PrebindCksum(self.data()?),
- macho::LC_SEGMENT_64 => {
- let mut data = self.data;
- let segment = data.read().read_error("Invalid Mach-O command size")?;
- LoadCommandVariant::Segment64(segment, data.0)
- }
- macho::LC_ROUTINES_64 => LoadCommandVariant::Routines64(self.data()?),
- macho::LC_UUID => LoadCommandVariant::Uuid(self.data()?),
- macho::LC_RPATH => LoadCommandVariant::Rpath(self.data()?),
- macho::LC_CODE_SIGNATURE
- | macho::LC_SEGMENT_SPLIT_INFO
- | macho::LC_FUNCTION_STARTS
- | macho::LC_DATA_IN_CODE
- | macho::LC_DYLIB_CODE_SIGN_DRS
- | macho::LC_LINKER_OPTIMIZATION_HINT
- | macho::LC_DYLD_EXPORTS_TRIE
- | macho::LC_DYLD_CHAINED_FIXUPS => LoadCommandVariant::LinkeditData(self.data()?),
- macho::LC_ENCRYPTION_INFO => LoadCommandVariant::EncryptionInfo32(self.data()?),
- macho::LC_DYLD_INFO | macho::LC_DYLD_INFO_ONLY => {
- LoadCommandVariant::DyldInfo(self.data()?)
- }
- macho::LC_VERSION_MIN_MACOSX
- | macho::LC_VERSION_MIN_IPHONEOS
- | macho::LC_VERSION_MIN_TVOS
- | macho::LC_VERSION_MIN_WATCHOS => LoadCommandVariant::VersionMin(self.data()?),
- macho::LC_DYLD_ENVIRONMENT => LoadCommandVariant::DyldEnvironment(self.data()?),
- macho::LC_MAIN => LoadCommandVariant::EntryPoint(self.data()?),
- macho::LC_SOURCE_VERSION => LoadCommandVariant::SourceVersion(self.data()?),
- macho::LC_ENCRYPTION_INFO_64 => LoadCommandVariant::EncryptionInfo64(self.data()?),
- macho::LC_LINKER_OPTION => LoadCommandVariant::LinkerOption(self.data()?),
- macho::LC_NOTE => LoadCommandVariant::Note(self.data()?),
- macho::LC_BUILD_VERSION => LoadCommandVariant::BuildVersion(self.data()?),
- macho::LC_FILESET_ENTRY => LoadCommandVariant::FilesetEntry(self.data()?),
- _ => LoadCommandVariant::Other,
- })
- }
-
- /// Try to parse this command as a [`macho::SegmentCommand32`].
- ///
- /// Returns the segment command and the data containing the sections.
- pub fn segment_32(self) -> Result<Option<(&'data macho::SegmentCommand32<E>, &'data [u8])>> {
- if self.cmd == macho::LC_SEGMENT {
- let mut data = self.data;
- let segment = data.read().read_error("Invalid Mach-O command size")?;
- Ok(Some((segment, data.0)))
- } else {
- Ok(None)
- }
- }
-
- /// Try to parse this command as a [`macho::SymtabCommand`].
- ///
- /// Returns the segment command and the data containing the sections.
- pub fn symtab(self) -> Result<Option<&'data macho::SymtabCommand<E>>> {
- if self.cmd == macho::LC_SYMTAB {
- Some(self.data()).transpose()
- } else {
- Ok(None)
- }
- }
-
- /// Try to parse this command as a [`macho::DysymtabCommand`].
- pub fn dysymtab(self) -> Result<Option<&'data macho::DysymtabCommand<E>>> {
- if self.cmd == macho::LC_DYSYMTAB {
- Some(self.data()).transpose()
- } else {
- Ok(None)
- }
- }
-
- /// Try to parse this command as a [`macho::DylibCommand`].
- pub fn dylib(self) -> Result<Option<&'data macho::DylibCommand<E>>> {
- if self.cmd == macho::LC_LOAD_DYLIB
- || self.cmd == macho::LC_LOAD_WEAK_DYLIB
- || self.cmd == macho::LC_REEXPORT_DYLIB
- || self.cmd == macho::LC_LAZY_LOAD_DYLIB
- || self.cmd == macho::LC_LOAD_UPWARD_DYLIB
- {
- Some(self.data()).transpose()
- } else {
- Ok(None)
- }
- }
-
- /// Try to parse this command as a [`macho::UuidCommand`].
- pub fn uuid(self) -> Result<Option<&'data macho::UuidCommand<E>>> {
- if self.cmd == macho::LC_UUID {
- Some(self.data()).transpose()
- } else {
- Ok(None)
- }
- }
-
- /// Try to parse this command as a [`macho::SegmentCommand64`].
- pub fn segment_64(self) -> Result<Option<(&'data macho::SegmentCommand64<E>, &'data [u8])>> {
- if self.cmd == macho::LC_SEGMENT_64 {
- let mut data = self.data;
- let command = data.read().read_error("Invalid Mach-O command size")?;
- Ok(Some((command, data.0)))
- } else {
- Ok(None)
- }
- }
-
- /// Try to parse this command as a [`macho::DyldInfoCommand`].
- pub fn dyld_info(self) -> Result<Option<&'data macho::DyldInfoCommand<E>>> {
- if self.cmd == macho::LC_DYLD_INFO || self.cmd == macho::LC_DYLD_INFO_ONLY {
- Some(self.data()).transpose()
- } else {
- Ok(None)
- }
- }
-
- /// Try to parse this command as an [`macho::EntryPointCommand`].
- pub fn entry_point(self) -> Result<Option<&'data macho::EntryPointCommand<E>>> {
- if self.cmd == macho::LC_MAIN {
- Some(self.data()).transpose()
- } else {
- Ok(None)
- }
- }
-
- /// Try to parse this command as a [`macho::BuildVersionCommand`].
- pub fn build_version(self) -> Result<Option<&'data macho::BuildVersionCommand<E>>> {
- if self.cmd == macho::LC_BUILD_VERSION {
- Some(self.data()).transpose()
- } else {
- Ok(None)
- }
- }
-}
-
-/// A [`macho::LoadCommand`] that has been interpreted according to its `cmd` field.
-#[derive(Debug, Clone, Copy)]
-#[non_exhaustive]
-pub enum LoadCommandVariant<'data, E: Endian> {
- /// `LC_SEGMENT`
- Segment32(&'data macho::SegmentCommand32<E>, &'data [u8]),
- /// `LC_SYMTAB`
- Symtab(&'data macho::SymtabCommand<E>),
- // obsolete: `LC_SYMSEG`
- //Symseg(&'data macho::SymsegCommand<E>),
- /// `LC_THREAD` or `LC_UNIXTHREAD`
- Thread(&'data macho::ThreadCommand<E>, &'data [u8]),
- // obsolete: `LC_IDFVMLIB` or `LC_LOADFVMLIB`
- //Fvmlib(&'data macho::FvmlibCommand<E>),
- // obsolete: `LC_IDENT`
- //Ident(&'data macho::IdentCommand<E>),
- // internal: `LC_FVMFILE`
- //Fvmfile(&'data macho::FvmfileCommand<E>),
- // internal: `LC_PREPAGE`
- /// `LC_DYSYMTAB`
- Dysymtab(&'data macho::DysymtabCommand<E>),
- /// `LC_LOAD_DYLIB`, `LC_LOAD_WEAK_DYLIB`, `LC_REEXPORT_DYLIB`,
- /// `LC_LAZY_LOAD_DYLIB`, or `LC_LOAD_UPWARD_DYLIB`
- Dylib(&'data macho::DylibCommand<E>),
- /// `LC_ID_DYLIB`
- IdDylib(&'data macho::DylibCommand<E>),
- /// `LC_LOAD_DYLINKER`
- LoadDylinker(&'data macho::DylinkerCommand<E>),
- /// `LC_ID_DYLINKER`
- IdDylinker(&'data macho::DylinkerCommand<E>),
- /// `LC_PREBOUND_DYLIB`
- PreboundDylib(&'data macho::PreboundDylibCommand<E>),
- /// `LC_ROUTINES`
- Routines32(&'data macho::RoutinesCommand32<E>),
- /// `LC_SUB_FRAMEWORK`
- SubFramework(&'data macho::SubFrameworkCommand<E>),
- /// `LC_SUB_UMBRELLA`
- SubUmbrella(&'data macho::SubUmbrellaCommand<E>),
- /// `LC_SUB_CLIENT`
- SubClient(&'data macho::SubClientCommand<E>),
- /// `LC_SUB_LIBRARY`
- SubLibrary(&'data macho::SubLibraryCommand<E>),
- /// `LC_TWOLEVEL_HINTS`
- TwolevelHints(&'data macho::TwolevelHintsCommand<E>),
- /// `LC_PREBIND_CKSUM`
- PrebindCksum(&'data macho::PrebindCksumCommand<E>),
- /// `LC_SEGMENT_64`
- Segment64(&'data macho::SegmentCommand64<E>, &'data [u8]),
- /// `LC_ROUTINES_64`
- Routines64(&'data macho::RoutinesCommand64<E>),
- /// `LC_UUID`
- Uuid(&'data macho::UuidCommand<E>),
- /// `LC_RPATH`
- Rpath(&'data macho::RpathCommand<E>),
- /// `LC_CODE_SIGNATURE`, `LC_SEGMENT_SPLIT_INFO`, `LC_FUNCTION_STARTS`,
- /// `LC_DATA_IN_CODE`, `LC_DYLIB_CODE_SIGN_DRS`, `LC_LINKER_OPTIMIZATION_HINT`,
- /// `LC_DYLD_EXPORTS_TRIE`, or `LC_DYLD_CHAINED_FIXUPS`.
- LinkeditData(&'data macho::LinkeditDataCommand<E>),
- /// `LC_ENCRYPTION_INFO`
- EncryptionInfo32(&'data macho::EncryptionInfoCommand32<E>),
- /// `LC_DYLD_INFO` or `LC_DYLD_INFO_ONLY`
- DyldInfo(&'data macho::DyldInfoCommand<E>),
- /// `LC_VERSION_MIN_MACOSX`, `LC_VERSION_MIN_IPHONEOS`, `LC_VERSION_MIN_WATCHOS`,
- /// or `LC_VERSION_MIN_TVOS`
- VersionMin(&'data macho::VersionMinCommand<E>),
- /// `LC_DYLD_ENVIRONMENT`
- DyldEnvironment(&'data macho::DylinkerCommand<E>),
- /// `LC_MAIN`
- EntryPoint(&'data macho::EntryPointCommand<E>),
- /// `LC_SOURCE_VERSION`
- SourceVersion(&'data macho::SourceVersionCommand<E>),
- /// `LC_ENCRYPTION_INFO_64`
- EncryptionInfo64(&'data macho::EncryptionInfoCommand64<E>),
- /// `LC_LINKER_OPTION`
- LinkerOption(&'data macho::LinkerOptionCommand<E>),
- /// `LC_NOTE`
- Note(&'data macho::NoteCommand<E>),
- /// `LC_BUILD_VERSION`
- BuildVersion(&'data macho::BuildVersionCommand<E>),
- /// `LC_FILESET_ENTRY`
- FilesetEntry(&'data macho::FilesetEntryCommand<E>),
- /// An unrecognized or obsolete load command.
- Other,
-}
-
-impl<E: Endian> macho::SymtabCommand<E> {
- /// Return the symbol table that this command references.
- pub fn symbols<'data, Mach: MachHeader<Endian = E>, R: ReadRef<'data>>(
- &self,
- endian: E,
- data: R,
- ) -> Result<SymbolTable<'data, Mach, R>> {
- let symbols = data
- .read_slice_at(
- self.symoff.get(endian).into(),
- self.nsyms.get(endian) as usize,
- )
- .read_error("Invalid Mach-O symbol table offset or size")?;
- let str_start: u64 = self.stroff.get(endian).into();
- let str_end = str_start
- .checked_add(self.strsize.get(endian).into())
- .read_error("Invalid Mach-O string table length")?;
- let strings = StringTable::new(data, str_start, str_end);
- Ok(SymbolTable::new(symbols, strings))
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::LittleEndian;
-
- #[test]
- fn cmd_size_invalid() {
- let mut commands = LoadCommandIterator::new(LittleEndian, &[0; 8], 10);
- assert!(commands.next().is_err());
- let mut commands = LoadCommandIterator::new(LittleEndian, &[0, 0, 0, 0, 7, 0, 0, 0, 0], 10);
- assert!(commands.next().is_err());
- let mut commands = LoadCommandIterator::new(LittleEndian, &[0, 0, 0, 0, 8, 0, 0, 0, 0], 10);
- assert!(commands.next().is_ok());
- }
-}
diff --git a/vendor/object/src/read/macho/mod.rs b/vendor/object/src/read/macho/mod.rs
deleted file mode 100644
index ab51ff3..0000000
--- a/vendor/object/src/read/macho/mod.rs
+++ /dev/null
@@ -1,72 +0,0 @@
-//! Support for reading Mach-O files.
-//!
-//! Traits are used to abstract over the difference between 32-bit and 64-bit Mach-O
-//! files. The primary trait for this is [`MachHeader`].
-//!
-//! ## High level API
-//!
-//! [`MachOFile`] implements the [`Object`](crate::read::Object) trait for Mach-O files.
-//! [`MachOFile`] is parameterised by [`MachHeader`] to allow reading both 32-bit and
-//! 64-bit Mach-O files. There are type aliases for these parameters ([`MachOFile32`] and
-//! [`MachOFile64`]).
-//!
-//! ## Low level API
-//!
-//! The [`MachHeader`] trait can be directly used to parse both [`macho::MachHeader32`]
-//! and [`macho::MachHeader64`]. Additionally, [`FatHeader`] and the [`FatArch`] trait
-//! can be used to iterate images in multi-architecture binaries, and [`DyldCache`] can
-//! be used to locate images in a dyld shared cache.
-//!
-//! ### Example for low level API
-//! ```no_run
-//! use object::macho;
-//! use object::read::macho::{MachHeader, Nlist};
-//! use std::error::Error;
-//! use std::fs;
-//!
-//! /// Reads a file and displays the name of each symbol.
-//! fn main() -> Result<(), Box<dyn Error>> {
-//! # #[cfg(feature = "std")] {
-//! let data = fs::read("path/to/binary")?;
-//! let header = macho::MachHeader64::<object::Endianness>::parse(&*data, 0)?;
-//! let endian = header.endian()?;
-//! let mut commands = header.load_commands(endian, &*data, 0)?;
-//! while let Some(command) = commands.next()? {
-//! if let Some(symtab_command) = command.symtab()? {
-//! let symbols = symtab_command.symbols::<macho::MachHeader64<_>, _>(endian, &*data)?;
-//! for symbol in symbols.iter() {
-//! let name = symbol.name(endian, symbols.strings())?;
-//! println!("{}", String::from_utf8_lossy(name));
-//! }
-//! }
-//! }
-//! # }
-//! Ok(())
-//! }
-//! ```
-#[cfg(doc)]
-use crate::macho;
-
-mod dyld_cache;
-pub use dyld_cache::*;
-
-mod fat;
-pub use fat::*;
-
-mod file;
-pub use file::*;
-
-mod load_command;
-pub use load_command::*;
-
-mod segment;
-pub use segment::*;
-
-mod section;
-pub use section::*;
-
-mod symbol;
-pub use symbol::*;
-
-mod relocation;
-pub use relocation::*;
diff --git a/vendor/object/src/read/macho/relocation.rs b/vendor/object/src/read/macho/relocation.rs
deleted file mode 100644
index 709f1a4..0000000
--- a/vendor/object/src/read/macho/relocation.rs
+++ /dev/null
@@ -1,158 +0,0 @@
-use core::{fmt, slice};
-
-use crate::endian::Endianness;
-use crate::macho;
-use crate::read::{
- ReadRef, Relocation, RelocationEncoding, RelocationKind, RelocationTarget, SectionIndex,
- SymbolIndex,
-};
-
-use super::{MachHeader, MachOFile};
-
-/// An iterator for the relocations in a [`MachOSection32`](super::MachOSection32).
-pub type MachORelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachORelocationIterator<'data, 'file, macho::MachHeader32<Endian>, R>;
-/// An iterator for the relocations in a [`MachOSection64`](super::MachOSection64).
-pub type MachORelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachORelocationIterator<'data, 'file, macho::MachHeader64<Endian>, R>;
-
-/// An iterator for the relocations in a [`MachOSection`](super::MachOSection).
-pub struct MachORelocationIterator<'data, 'file, Mach, R = &'data [u8]>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file MachOFile<'data, Mach, R>,
- pub(super) relocations: slice::Iter<'data, macho::Relocation<Mach::Endian>>,
-}
-
-impl<'data, 'file, Mach, R> Iterator for MachORelocationIterator<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- type Item = (u64, Relocation);
-
- fn next(&mut self) -> Option<Self::Item> {
- let mut paired_addend = 0;
- loop {
- let reloc = self.relocations.next()?;
- let endian = self.file.endian;
- let cputype = self.file.header.cputype(endian);
- if reloc.r_scattered(endian, cputype) {
- // FIXME: handle scattered relocations
- // We need to add `RelocationTarget::Address` for this.
- continue;
- }
- let reloc = reloc.info(self.file.endian);
- let mut encoding = RelocationEncoding::Generic;
- let kind = match cputype {
- macho::CPU_TYPE_ARM => match (reloc.r_type, reloc.r_pcrel) {
- (macho::ARM_RELOC_VANILLA, false) => RelocationKind::Absolute,
- _ => RelocationKind::MachO {
- value: reloc.r_type,
- relative: reloc.r_pcrel,
- },
- },
- macho::CPU_TYPE_ARM64 | macho::CPU_TYPE_ARM64_32 => {
- match (reloc.r_type, reloc.r_pcrel) {
- (macho::ARM64_RELOC_UNSIGNED, false) => RelocationKind::Absolute,
- (macho::ARM64_RELOC_ADDEND, _) => {
- paired_addend = i64::from(reloc.r_symbolnum)
- .wrapping_shl(64 - 24)
- .wrapping_shr(64 - 24);
- continue;
- }
- _ => RelocationKind::MachO {
- value: reloc.r_type,
- relative: reloc.r_pcrel,
- },
- }
- }
- macho::CPU_TYPE_X86 => match (reloc.r_type, reloc.r_pcrel) {
- (macho::GENERIC_RELOC_VANILLA, false) => RelocationKind::Absolute,
- _ => RelocationKind::MachO {
- value: reloc.r_type,
- relative: reloc.r_pcrel,
- },
- },
- macho::CPU_TYPE_X86_64 => match (reloc.r_type, reloc.r_pcrel) {
- (macho::X86_64_RELOC_UNSIGNED, false) => RelocationKind::Absolute,
- (macho::X86_64_RELOC_SIGNED, true) => {
- encoding = RelocationEncoding::X86RipRelative;
- RelocationKind::Relative
- }
- (macho::X86_64_RELOC_BRANCH, true) => {
- encoding = RelocationEncoding::X86Branch;
- RelocationKind::Relative
- }
- (macho::X86_64_RELOC_GOT, true) => RelocationKind::GotRelative,
- (macho::X86_64_RELOC_GOT_LOAD, true) => {
- encoding = RelocationEncoding::X86RipRelativeMovq;
- RelocationKind::GotRelative
- }
- _ => RelocationKind::MachO {
- value: reloc.r_type,
- relative: reloc.r_pcrel,
- },
- },
- _ => RelocationKind::MachO {
- value: reloc.r_type,
- relative: reloc.r_pcrel,
- },
- };
- let size = 8 << reloc.r_length;
- let target = if reloc.r_extern {
- RelocationTarget::Symbol(SymbolIndex(reloc.r_symbolnum as usize))
- } else {
- RelocationTarget::Section(SectionIndex(reloc.r_symbolnum as usize))
- };
- let implicit_addend = paired_addend == 0;
- let mut addend = paired_addend;
- if reloc.r_pcrel {
- // For PC relative relocations on some architectures, the
- // addend does not include the offset required due to the
- // PC being different from the place of the relocation.
- // This differs from other file formats, so adjust the
- // addend here to account for this.
- match cputype {
- macho::CPU_TYPE_X86 => {
- addend -= 1 << reloc.r_length;
- }
- macho::CPU_TYPE_X86_64 => {
- addend -= 1 << reloc.r_length;
- match reloc.r_type {
- macho::X86_64_RELOC_SIGNED_1 => addend -= 1,
- macho::X86_64_RELOC_SIGNED_2 => addend -= 2,
- macho::X86_64_RELOC_SIGNED_4 => addend -= 4,
- _ => {}
- }
- }
- // TODO: maybe missing support for some architectures and relocations
- _ => {}
- }
- }
- return Some((
- reloc.r_address as u64,
- Relocation {
- kind,
- encoding,
- size,
- target,
- addend,
- implicit_addend,
- },
- ));
- }
- }
-}
-
-impl<'data, 'file, Mach, R> fmt::Debug for MachORelocationIterator<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("MachORelocationIterator").finish()
- }
-}
diff --git a/vendor/object/src/read/macho/section.rs b/vendor/object/src/read/macho/section.rs
deleted file mode 100644
index 7c79123..0000000
--- a/vendor/object/src/read/macho/section.rs
+++ /dev/null
@@ -1,389 +0,0 @@
-use core::fmt::Debug;
-use core::{fmt, result, slice, str};
-
-use crate::endian::{self, Endianness};
-use crate::macho;
-use crate::pod::Pod;
-use crate::read::{
- self, CompressedData, CompressedFileRange, ObjectSection, ReadError, ReadRef, Result,
- SectionFlags, SectionIndex, SectionKind,
-};
-
-use super::{MachHeader, MachOFile, MachORelocationIterator};
-
-/// An iterator for the sections in a [`MachOFile32`](super::MachOFile32).
-pub type MachOSectionIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOSectionIterator<'data, 'file, macho::MachHeader32<Endian>, R>;
-/// An iterator for the sections in a [`MachOFile64`](super::MachOFile64).
-pub type MachOSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOSectionIterator<'data, 'file, macho::MachHeader64<Endian>, R>;
-
-/// An iterator for the sections in a [`MachOFile`].
-pub struct MachOSectionIterator<'data, 'file, Mach, R = &'data [u8]>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file MachOFile<'data, Mach, R>,
- pub(super) iter: slice::Iter<'file, MachOSectionInternal<'data, Mach>>,
-}
-
-impl<'data, 'file, Mach, R> fmt::Debug for MachOSectionIterator<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- // It's painful to do much better than this
- f.debug_struct("MachOSectionIterator").finish()
- }
-}
-
-impl<'data, 'file, Mach, R> Iterator for MachOSectionIterator<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- type Item = MachOSection<'data, 'file, Mach, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.iter.next().map(|&internal| MachOSection {
- file: self.file,
- internal,
- })
- }
-}
-
-/// A section in a [`MachOFile32`](super::MachOFile32).
-pub type MachOSection32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOSection<'data, 'file, macho::MachHeader32<Endian>, R>;
-/// A section in a [`MachOFile64`](super::MachOFile64).
-pub type MachOSection64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOSection<'data, 'file, macho::MachHeader64<Endian>, R>;
-
-/// A section in a [`MachOFile`].
-///
-/// Most functionality is provided by the [`ObjectSection`] trait implementation.
-#[derive(Debug)]
-pub struct MachOSection<'data, 'file, Mach, R = &'data [u8]>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file MachOFile<'data, Mach, R>,
- pub(super) internal: MachOSectionInternal<'data, Mach>,
-}
-
-impl<'data, 'file, Mach, R> MachOSection<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- fn bytes(&self) -> Result<&'data [u8]> {
- let segment_index = self.internal.segment_index;
- let segment = self.file.segment_internal(segment_index)?;
- self.internal
- .section
- .data(self.file.endian, segment.data)
- .read_error("Invalid Mach-O section size or offset")
- }
-}
-
-impl<'data, 'file, Mach, R> read::private::Sealed for MachOSection<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Mach, R> ObjectSection<'data> for MachOSection<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- type RelocationIterator = MachORelocationIterator<'data, 'file, Mach, R>;
-
- #[inline]
- fn index(&self) -> SectionIndex {
- self.internal.index
- }
-
- #[inline]
- fn address(&self) -> u64 {
- self.internal.section.addr(self.file.endian).into()
- }
-
- #[inline]
- fn size(&self) -> u64 {
- self.internal.section.size(self.file.endian).into()
- }
-
- #[inline]
- fn align(&self) -> u64 {
- let align = self.internal.section.align(self.file.endian);
- if align < 64 {
- 1 << align
- } else {
- 0
- }
- }
-
- #[inline]
- fn file_range(&self) -> Option<(u64, u64)> {
- self.internal.section.file_range(self.file.endian)
- }
-
- #[inline]
- fn data(&self) -> Result<&'data [u8]> {
- self.bytes()
- }
-
- fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> {
- Ok(read::util::data_range(
- self.bytes()?,
- self.address(),
- address,
- size,
- ))
- }
-
- #[inline]
- fn compressed_file_range(&self) -> Result<CompressedFileRange> {
- Ok(CompressedFileRange::none(self.file_range()))
- }
-
- #[inline]
- fn compressed_data(&self) -> Result<CompressedData<'data>> {
- self.data().map(CompressedData::none)
- }
-
- #[inline]
- fn name_bytes(&self) -> Result<&[u8]> {
- Ok(self.internal.section.name())
- }
-
- #[inline]
- fn name(&self) -> Result<&str> {
- str::from_utf8(self.internal.section.name())
- .ok()
- .read_error("Non UTF-8 Mach-O section name")
- }
-
- #[inline]
- fn segment_name_bytes(&self) -> Result<Option<&[u8]>> {
- Ok(Some(self.internal.section.segment_name()))
- }
-
- #[inline]
- fn segment_name(&self) -> Result<Option<&str>> {
- Ok(Some(
- str::from_utf8(self.internal.section.segment_name())
- .ok()
- .read_error("Non UTF-8 Mach-O segment name")?,
- ))
- }
-
- fn kind(&self) -> SectionKind {
- self.internal.kind
- }
-
- fn relocations(&self) -> MachORelocationIterator<'data, 'file, Mach, R> {
- MachORelocationIterator {
- file: self.file,
- relocations: self
- .internal
- .section
- .relocations(self.file.endian, self.file.data)
- .unwrap_or(&[])
- .iter(),
- }
- }
-
- fn flags(&self) -> SectionFlags {
- SectionFlags::MachO {
- flags: self.internal.section.flags(self.file.endian),
- }
- }
-}
-
-#[derive(Debug, Clone, Copy)]
-pub(super) struct MachOSectionInternal<'data, Mach: MachHeader> {
- pub index: SectionIndex,
- pub segment_index: usize,
- pub kind: SectionKind,
- pub section: &'data Mach::Section,
-}
-
-impl<'data, Mach: MachHeader> MachOSectionInternal<'data, Mach> {
- pub(super) fn parse(
- index: SectionIndex,
- segment_index: usize,
- section: &'data Mach::Section,
- ) -> Self {
- // TODO: we don't validate flags, should we?
- let kind = match (section.segment_name(), section.name()) {
- (b"__TEXT", b"__text") => SectionKind::Text,
- (b"__TEXT", b"__const") => SectionKind::ReadOnlyData,
- (b"__TEXT", b"__cstring") => SectionKind::ReadOnlyString,
- (b"__TEXT", b"__literal4") => SectionKind::ReadOnlyData,
- (b"__TEXT", b"__literal8") => SectionKind::ReadOnlyData,
- (b"__TEXT", b"__literal16") => SectionKind::ReadOnlyData,
- (b"__TEXT", b"__eh_frame") => SectionKind::ReadOnlyData,
- (b"__TEXT", b"__gcc_except_tab") => SectionKind::ReadOnlyData,
- (b"__DATA", b"__data") => SectionKind::Data,
- (b"__DATA", b"__const") => SectionKind::ReadOnlyData,
- (b"__DATA", b"__bss") => SectionKind::UninitializedData,
- (b"__DATA", b"__common") => SectionKind::Common,
- (b"__DATA", b"__thread_data") => SectionKind::Tls,
- (b"__DATA", b"__thread_bss") => SectionKind::UninitializedTls,
- (b"__DATA", b"__thread_vars") => SectionKind::TlsVariables,
- (b"__DWARF", _) => SectionKind::Debug,
- _ => SectionKind::Unknown,
- };
- MachOSectionInternal {
- index,
- segment_index,
- kind,
- section,
- }
- }
-}
-
-/// A trait for generic access to [`macho::Section32`] and [`macho::Section64`].
-#[allow(missing_docs)]
-pub trait Section: Debug + Pod {
- type Word: Into<u64>;
- type Endian: endian::Endian;
-
- fn sectname(&self) -> &[u8; 16];
- fn segname(&self) -> &[u8; 16];
- fn addr(&self, endian: Self::Endian) -> Self::Word;
- fn size(&self, endian: Self::Endian) -> Self::Word;
- fn offset(&self, endian: Self::Endian) -> u32;
- fn align(&self, endian: Self::Endian) -> u32;
- fn reloff(&self, endian: Self::Endian) -> u32;
- fn nreloc(&self, endian: Self::Endian) -> u32;
- fn flags(&self, endian: Self::Endian) -> u32;
-
- /// Return the `sectname` bytes up until the null terminator.
- fn name(&self) -> &[u8] {
- let sectname = &self.sectname()[..];
- match memchr::memchr(b'\0', sectname) {
- Some(end) => &sectname[..end],
- None => sectname,
- }
- }
-
- /// Return the `segname` bytes up until the null terminator.
- fn segment_name(&self) -> &[u8] {
- let segname = &self.segname()[..];
- match memchr::memchr(b'\0', segname) {
- Some(end) => &segname[..end],
- None => segname,
- }
- }
-
- /// Return the offset and size of the section in the file.
- ///
- /// Returns `None` for sections that have no data in the file.
- fn file_range(&self, endian: Self::Endian) -> Option<(u64, u64)> {
- match self.flags(endian) & macho::SECTION_TYPE {
- macho::S_ZEROFILL | macho::S_GB_ZEROFILL | macho::S_THREAD_LOCAL_ZEROFILL => None,
- _ => Some((self.offset(endian).into(), self.size(endian).into())),
- }
- }
-
- /// Return the section data.
- ///
- /// Returns `Ok(&[])` if the section has no data.
- /// Returns `Err` for invalid values.
- fn data<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> result::Result<&'data [u8], ()> {
- if let Some((offset, size)) = self.file_range(endian) {
- data.read_bytes_at(offset, size)
- } else {
- Ok(&[])
- }
- }
-
- /// Return the relocation array.
- ///
- /// Returns `Err` for invalid values.
- fn relocations<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> Result<&'data [macho::Relocation<Self::Endian>]> {
- data.read_slice_at(self.reloff(endian).into(), self.nreloc(endian) as usize)
- .read_error("Invalid Mach-O relocations offset or number")
- }
-}
-
-impl<Endian: endian::Endian> Section for macho::Section32<Endian> {
- type Word = u32;
- type Endian = Endian;
-
- fn sectname(&self) -> &[u8; 16] {
- &self.sectname
- }
- fn segname(&self) -> &[u8; 16] {
- &self.segname
- }
- fn addr(&self, endian: Self::Endian) -> Self::Word {
- self.addr.get(endian)
- }
- fn size(&self, endian: Self::Endian) -> Self::Word {
- self.size.get(endian)
- }
- fn offset(&self, endian: Self::Endian) -> u32 {
- self.offset.get(endian)
- }
- fn align(&self, endian: Self::Endian) -> u32 {
- self.align.get(endian)
- }
- fn reloff(&self, endian: Self::Endian) -> u32 {
- self.reloff.get(endian)
- }
- fn nreloc(&self, endian: Self::Endian) -> u32 {
- self.nreloc.get(endian)
- }
- fn flags(&self, endian: Self::Endian) -> u32 {
- self.flags.get(endian)
- }
-}
-
-impl<Endian: endian::Endian> Section for macho::Section64<Endian> {
- type Word = u64;
- type Endian = Endian;
-
- fn sectname(&self) -> &[u8; 16] {
- &self.sectname
- }
- fn segname(&self) -> &[u8; 16] {
- &self.segname
- }
- fn addr(&self, endian: Self::Endian) -> Self::Word {
- self.addr.get(endian)
- }
- fn size(&self, endian: Self::Endian) -> Self::Word {
- self.size.get(endian)
- }
- fn offset(&self, endian: Self::Endian) -> u32 {
- self.offset.get(endian)
- }
- fn align(&self, endian: Self::Endian) -> u32 {
- self.align.get(endian)
- }
- fn reloff(&self, endian: Self::Endian) -> u32 {
- self.reloff.get(endian)
- }
- fn nreloc(&self, endian: Self::Endian) -> u32 {
- self.nreloc.get(endian)
- }
- fn flags(&self, endian: Self::Endian) -> u32 {
- self.flags.get(endian)
- }
-}
diff --git a/vendor/object/src/read/macho/segment.rs b/vendor/object/src/read/macho/segment.rs
deleted file mode 100644
index c889ad2..0000000
--- a/vendor/object/src/read/macho/segment.rs
+++ /dev/null
@@ -1,303 +0,0 @@
-use core::fmt::Debug;
-use core::{result, slice, str};
-
-use crate::endian::{self, Endianness};
-use crate::macho;
-use crate::pod::Pod;
-use crate::read::{self, ObjectSegment, ReadError, ReadRef, Result, SegmentFlags};
-
-use super::{LoadCommandData, MachHeader, MachOFile, Section};
-
-/// An iterator for the segments in a [`MachOFile32`](super::MachOFile32).
-pub type MachOSegmentIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOSegmentIterator<'data, 'file, macho::MachHeader32<Endian>, R>;
-/// An iterator for the segments in a [`MachOFile64`](super::MachOFile64).
-pub type MachOSegmentIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOSegmentIterator<'data, 'file, macho::MachHeader64<Endian>, R>;
-
-/// An iterator for the segments in a [`MachOFile`].
-#[derive(Debug)]
-pub struct MachOSegmentIterator<'data, 'file, Mach, R = &'data [u8]>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file MachOFile<'data, Mach, R>,
- pub(super) iter: slice::Iter<'file, MachOSegmentInternal<'data, Mach, R>>,
-}
-
-impl<'data, 'file, Mach, R> Iterator for MachOSegmentIterator<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- type Item = MachOSegment<'data, 'file, Mach, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.iter.next().map(|internal| MachOSegment {
- file: self.file,
- internal,
- })
- }
-}
-
-/// A segment in a [`MachOFile32`](super::MachOFile32).
-pub type MachOSegment32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOSegment<'data, 'file, macho::MachHeader32<Endian>, R>;
-/// A segment in a [`MachOFile64`](super::MachOFile64).
-pub type MachOSegment64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOSegment<'data, 'file, macho::MachHeader64<Endian>, R>;
-
-/// A segment in a [`MachOFile`].
-///
-/// Most functionality is provided by the [`ObjectSegment`] trait implementation.
-#[derive(Debug)]
-pub struct MachOSegment<'data, 'file, Mach, R = &'data [u8]>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- file: &'file MachOFile<'data, Mach, R>,
- internal: &'file MachOSegmentInternal<'data, Mach, R>,
-}
-
-impl<'data, 'file, Mach, R> MachOSegment<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- fn bytes(&self) -> Result<&'data [u8]> {
- self.internal
- .segment
- .data(self.file.endian, self.file.data)
- .read_error("Invalid Mach-O segment size or offset")
- }
-}
-
-impl<'data, 'file, Mach, R> read::private::Sealed for MachOSegment<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Mach, R> ObjectSegment<'data> for MachOSegment<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- #[inline]
- fn address(&self) -> u64 {
- self.internal.segment.vmaddr(self.file.endian).into()
- }
-
- #[inline]
- fn size(&self) -> u64 {
- self.internal.segment.vmsize(self.file.endian).into()
- }
-
- #[inline]
- fn align(&self) -> u64 {
- // Page size.
- 0x1000
- }
-
- #[inline]
- fn file_range(&self) -> (u64, u64) {
- self.internal.segment.file_range(self.file.endian)
- }
-
- fn data(&self) -> Result<&'data [u8]> {
- self.bytes()
- }
-
- fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> {
- Ok(read::util::data_range(
- self.bytes()?,
- self.address(),
- address,
- size,
- ))
- }
-
- #[inline]
- fn name_bytes(&self) -> Result<Option<&[u8]>> {
- Ok(Some(self.internal.segment.name()))
- }
-
- #[inline]
- fn name(&self) -> Result<Option<&str>> {
- Ok(Some(
- str::from_utf8(self.internal.segment.name())
- .ok()
- .read_error("Non UTF-8 Mach-O segment name")?,
- ))
- }
-
- #[inline]
- fn flags(&self) -> SegmentFlags {
- let flags = self.internal.segment.flags(self.file.endian);
- let maxprot = self.internal.segment.maxprot(self.file.endian);
- let initprot = self.internal.segment.initprot(self.file.endian);
- SegmentFlags::MachO {
- flags,
- maxprot,
- initprot,
- }
- }
-}
-
-#[derive(Debug, Clone, Copy)]
-pub(super) struct MachOSegmentInternal<'data, Mach: MachHeader, R: ReadRef<'data>> {
- pub data: R,
- pub segment: &'data Mach::Segment,
-}
-
-/// A trait for generic access to [`macho::SegmentCommand32`] and [`macho::SegmentCommand64`].
-#[allow(missing_docs)]
-pub trait Segment: Debug + Pod {
- type Word: Into<u64>;
- type Endian: endian::Endian;
- type Section: Section<Endian = Self::Endian>;
-
- fn from_command(command: LoadCommandData<'_, Self::Endian>) -> Result<Option<(&Self, &[u8])>>;
-
- fn cmd(&self, endian: Self::Endian) -> u32;
- fn cmdsize(&self, endian: Self::Endian) -> u32;
- fn segname(&self) -> &[u8; 16];
- fn vmaddr(&self, endian: Self::Endian) -> Self::Word;
- fn vmsize(&self, endian: Self::Endian) -> Self::Word;
- fn fileoff(&self, endian: Self::Endian) -> Self::Word;
- fn filesize(&self, endian: Self::Endian) -> Self::Word;
- fn maxprot(&self, endian: Self::Endian) -> u32;
- fn initprot(&self, endian: Self::Endian) -> u32;
- fn nsects(&self, endian: Self::Endian) -> u32;
- fn flags(&self, endian: Self::Endian) -> u32;
-
- /// Return the `segname` bytes up until the null terminator.
- fn name(&self) -> &[u8] {
- let segname = &self.segname()[..];
- match memchr::memchr(b'\0', segname) {
- Some(end) => &segname[..end],
- None => segname,
- }
- }
-
- /// Return the offset and size of the segment in the file.
- fn file_range(&self, endian: Self::Endian) -> (u64, u64) {
- (self.fileoff(endian).into(), self.filesize(endian).into())
- }
-
- /// Get the segment data from the file data.
- ///
- /// Returns `Err` for invalid values.
- fn data<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- data: R,
- ) -> result::Result<&'data [u8], ()> {
- let (offset, size) = self.file_range(endian);
- data.read_bytes_at(offset, size)
- }
-
- /// Get the array of sections from the data following the segment command.
- ///
- /// Returns `Err` for invalid values.
- fn sections<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- section_data: R,
- ) -> Result<&'data [Self::Section]> {
- section_data
- .read_slice_at(0, self.nsects(endian) as usize)
- .read_error("Invalid Mach-O number of sections")
- }
-}
-
-impl<Endian: endian::Endian> Segment for macho::SegmentCommand32<Endian> {
- type Word = u32;
- type Endian = Endian;
- type Section = macho::Section32<Self::Endian>;
-
- fn from_command(command: LoadCommandData<'_, Self::Endian>) -> Result<Option<(&Self, &[u8])>> {
- command.segment_32()
- }
-
- fn cmd(&self, endian: Self::Endian) -> u32 {
- self.cmd.get(endian)
- }
- fn cmdsize(&self, endian: Self::Endian) -> u32 {
- self.cmdsize.get(endian)
- }
- fn segname(&self) -> &[u8; 16] {
- &self.segname
- }
- fn vmaddr(&self, endian: Self::Endian) -> Self::Word {
- self.vmaddr.get(endian)
- }
- fn vmsize(&self, endian: Self::Endian) -> Self::Word {
- self.vmsize.get(endian)
- }
- fn fileoff(&self, endian: Self::Endian) -> Self::Word {
- self.fileoff.get(endian)
- }
- fn filesize(&self, endian: Self::Endian) -> Self::Word {
- self.filesize.get(endian)
- }
- fn maxprot(&self, endian: Self::Endian) -> u32 {
- self.maxprot.get(endian)
- }
- fn initprot(&self, endian: Self::Endian) -> u32 {
- self.initprot.get(endian)
- }
- fn nsects(&self, endian: Self::Endian) -> u32 {
- self.nsects.get(endian)
- }
- fn flags(&self, endian: Self::Endian) -> u32 {
- self.flags.get(endian)
- }
-}
-
-impl<Endian: endian::Endian> Segment for macho::SegmentCommand64<Endian> {
- type Word = u64;
- type Endian = Endian;
- type Section = macho::Section64<Self::Endian>;
-
- fn from_command(command: LoadCommandData<'_, Self::Endian>) -> Result<Option<(&Self, &[u8])>> {
- command.segment_64()
- }
-
- fn cmd(&self, endian: Self::Endian) -> u32 {
- self.cmd.get(endian)
- }
- fn cmdsize(&self, endian: Self::Endian) -> u32 {
- self.cmdsize.get(endian)
- }
- fn segname(&self) -> &[u8; 16] {
- &self.segname
- }
- fn vmaddr(&self, endian: Self::Endian) -> Self::Word {
- self.vmaddr.get(endian)
- }
- fn vmsize(&self, endian: Self::Endian) -> Self::Word {
- self.vmsize.get(endian)
- }
- fn fileoff(&self, endian: Self::Endian) -> Self::Word {
- self.fileoff.get(endian)
- }
- fn filesize(&self, endian: Self::Endian) -> Self::Word {
- self.filesize.get(endian)
- }
- fn maxprot(&self, endian: Self::Endian) -> u32 {
- self.maxprot.get(endian)
- }
- fn initprot(&self, endian: Self::Endian) -> u32 {
- self.initprot.get(endian)
- }
- fn nsects(&self, endian: Self::Endian) -> u32 {
- self.nsects.get(endian)
- }
- fn flags(&self, endian: Self::Endian) -> u32 {
- self.flags.get(endian)
- }
-}
diff --git a/vendor/object/src/read/macho/symbol.rs b/vendor/object/src/read/macho/symbol.rs
deleted file mode 100644
index 434361f..0000000
--- a/vendor/object/src/read/macho/symbol.rs
+++ /dev/null
@@ -1,492 +0,0 @@
-use alloc::vec::Vec;
-use core::fmt::Debug;
-use core::{fmt, slice, str};
-
-use crate::endian::{self, Endianness};
-use crate::macho;
-use crate::pod::Pod;
-use crate::read::util::StringTable;
-use crate::read::{
- self, ObjectMap, ObjectMapEntry, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Result,
- SectionIndex, SectionKind, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, SymbolMapEntry,
- SymbolScope, SymbolSection,
-};
-
-use super::{MachHeader, MachOFile};
-
-/// A table of symbol entries in a Mach-O file.
-///
-/// Also includes the string table used for the symbol names.
-///
-/// Returned by [`macho::SymtabCommand::symbols`].
-#[derive(Debug, Clone, Copy)]
-pub struct SymbolTable<'data, Mach: MachHeader, R = &'data [u8]>
-where
- R: ReadRef<'data>,
-{
- symbols: &'data [Mach::Nlist],
- strings: StringTable<'data, R>,
-}
-
-impl<'data, Mach: MachHeader, R: ReadRef<'data>> Default for SymbolTable<'data, Mach, R> {
- fn default() -> Self {
- SymbolTable {
- symbols: &[],
- strings: Default::default(),
- }
- }
-}
-
-impl<'data, Mach: MachHeader, R: ReadRef<'data>> SymbolTable<'data, Mach, R> {
- #[inline]
- pub(super) fn new(symbols: &'data [Mach::Nlist], strings: StringTable<'data, R>) -> Self {
- SymbolTable { symbols, strings }
- }
-
- /// Return the string table used for the symbol names.
- #[inline]
- pub fn strings(&self) -> StringTable<'data, R> {
- self.strings
- }
-
- /// Iterate over the symbols.
- #[inline]
- pub fn iter(&self) -> slice::Iter<'data, Mach::Nlist> {
- self.symbols.iter()
- }
-
- /// Return true if the symbol table is empty.
- #[inline]
- pub fn is_empty(&self) -> bool {
- self.symbols.is_empty()
- }
-
- /// The number of symbols.
- #[inline]
- pub fn len(&self) -> usize {
- self.symbols.len()
- }
-
- /// Return the symbol at the given index.
- pub fn symbol(&self, index: usize) -> Result<&'data Mach::Nlist> {
- self.symbols
- .get(index)
- .read_error("Invalid Mach-O symbol index")
- }
-
- /// Construct a map from addresses to a user-defined map entry.
- pub fn map<Entry: SymbolMapEntry, F: Fn(&'data Mach::Nlist) -> Option<Entry>>(
- &self,
- f: F,
- ) -> SymbolMap<Entry> {
- let mut symbols = Vec::new();
- for nlist in self.symbols {
- if !nlist.is_definition() {
- continue;
- }
- if let Some(entry) = f(nlist) {
- symbols.push(entry);
- }
- }
- SymbolMap::new(symbols)
- }
-
- /// Construct a map from addresses to symbol names and object file names.
- pub fn object_map(&self, endian: Mach::Endian) -> ObjectMap<'data> {
- let mut symbols = Vec::new();
- let mut objects = Vec::new();
- let mut object = None;
- let mut current_function = None;
- // Each module starts with one or two N_SO symbols (path, or directory + filename)
- // and one N_OSO symbol. The module is terminated by an empty N_SO symbol.
- for nlist in self.symbols {
- let n_type = nlist.n_type();
- if n_type & macho::N_STAB == 0 {
- continue;
- }
- // TODO: includes variables too (N_GSYM, N_STSYM). These may need to get their
- // address from regular symbols though.
- match n_type {
- macho::N_SO => {
- object = None;
- }
- macho::N_OSO => {
- object = None;
- if let Ok(name) = nlist.name(endian, self.strings) {
- if !name.is_empty() {
- object = Some(objects.len());
- objects.push(name);
- }
- }
- }
- macho::N_FUN => {
- if let Ok(name) = nlist.name(endian, self.strings) {
- if !name.is_empty() {
- current_function = Some((name, nlist.n_value(endian).into()))
- } else if let Some((name, address)) = current_function.take() {
- if let Some(object) = object {
- symbols.push(ObjectMapEntry {
- address,
- size: nlist.n_value(endian).into(),
- name,
- object,
- });
- }
- }
- }
- }
- _ => {}
- }
- }
- ObjectMap {
- symbols: SymbolMap::new(symbols),
- objects,
- }
- }
-}
-
-/// A symbol table in a [`MachOFile32`](super::MachOFile32).
-pub type MachOSymbolTable32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOSymbolTable<'data, 'file, macho::MachHeader32<Endian>, R>;
-/// A symbol table in a [`MachOFile64`](super::MachOFile64).
-pub type MachOSymbolTable64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOSymbolTable<'data, 'file, macho::MachHeader64<Endian>, R>;
-
-/// A symbol table in a [`MachOFile`].
-#[derive(Debug, Clone, Copy)]
-pub struct MachOSymbolTable<'data, 'file, Mach, R = &'data [u8]>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file MachOFile<'data, Mach, R>,
-}
-
-impl<'data, 'file, Mach, R> read::private::Sealed for MachOSymbolTable<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Mach, R> ObjectSymbolTable<'data> for MachOSymbolTable<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- type Symbol = MachOSymbol<'data, 'file, Mach, R>;
- type SymbolIterator = MachOSymbolIterator<'data, 'file, Mach, R>;
-
- fn symbols(&self) -> Self::SymbolIterator {
- MachOSymbolIterator {
- file: self.file,
- index: 0,
- }
- }
-
- fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol> {
- let nlist = self.file.symbols.symbol(index.0)?;
- MachOSymbol::new(self.file, index, nlist).read_error("Unsupported Mach-O symbol index")
- }
-}
-
-/// An iterator for the symbols in a [`MachOFile32`](super::MachOFile32).
-pub type MachOSymbolIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOSymbolIterator<'data, 'file, macho::MachHeader32<Endian>, R>;
-/// An iterator for the symbols in a [`MachOFile64`](super::MachOFile64).
-pub type MachOSymbolIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOSymbolIterator<'data, 'file, macho::MachHeader64<Endian>, R>;
-
-/// An iterator for the symbols in a [`MachOFile`].
-pub struct MachOSymbolIterator<'data, 'file, Mach, R = &'data [u8]>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file MachOFile<'data, Mach, R>,
- pub(super) index: usize,
-}
-
-impl<'data, 'file, Mach, R> fmt::Debug for MachOSymbolIterator<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("MachOSymbolIterator").finish()
- }
-}
-
-impl<'data, 'file, Mach, R> Iterator for MachOSymbolIterator<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- type Item = MachOSymbol<'data, 'file, Mach, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- loop {
- let index = self.index;
- let nlist = self.file.symbols.symbols.get(index)?;
- self.index += 1;
- if let Some(symbol) = MachOSymbol::new(self.file, SymbolIndex(index), nlist) {
- return Some(symbol);
- }
- }
- }
-}
-
-/// A symbol in a [`MachOFile32`](super::MachOFile32).
-pub type MachOSymbol32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOSymbol<'data, 'file, macho::MachHeader32<Endian>, R>;
-/// A symbol in a [`MachOFile64`](super::MachOFile64).
-pub type MachOSymbol64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
- MachOSymbol<'data, 'file, macho::MachHeader64<Endian>, R>;
-
-/// A symbol in a [`MachOFile`].
-///
-/// Most functionality is provided by the [`ObjectSymbol`] trait implementation.
-#[derive(Debug, Clone, Copy)]
-pub struct MachOSymbol<'data, 'file, Mach, R = &'data [u8]>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- file: &'file MachOFile<'data, Mach, R>,
- index: SymbolIndex,
- nlist: &'data Mach::Nlist,
-}
-
-impl<'data, 'file, Mach, R> MachOSymbol<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- pub(super) fn new(
- file: &'file MachOFile<'data, Mach, R>,
- index: SymbolIndex,
- nlist: &'data Mach::Nlist,
- ) -> Option<Self> {
- if nlist.n_type() & macho::N_STAB != 0 {
- return None;
- }
- Some(MachOSymbol { file, index, nlist })
- }
-}
-
-impl<'data, 'file, Mach, R> read::private::Sealed for MachOSymbol<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Mach, R> ObjectSymbol<'data> for MachOSymbol<'data, 'file, Mach, R>
-where
- Mach: MachHeader,
- R: ReadRef<'data>,
-{
- #[inline]
- fn index(&self) -> SymbolIndex {
- self.index
- }
-
- fn name_bytes(&self) -> Result<&'data [u8]> {
- self.nlist.name(self.file.endian, self.file.symbols.strings)
- }
-
- fn name(&self) -> Result<&'data str> {
- let name = self.name_bytes()?;
- str::from_utf8(name)
- .ok()
- .read_error("Non UTF-8 Mach-O symbol name")
- }
-
- #[inline]
- fn address(&self) -> u64 {
- self.nlist.n_value(self.file.endian).into()
- }
-
- #[inline]
- fn size(&self) -> u64 {
- 0
- }
-
- fn kind(&self) -> SymbolKind {
- self.section()
- .index()
- .and_then(|index| self.file.section_internal(index).ok())
- .map(|section| match section.kind {
- SectionKind::Text => SymbolKind::Text,
- SectionKind::Data
- | SectionKind::ReadOnlyData
- | SectionKind::ReadOnlyString
- | SectionKind::UninitializedData
- | SectionKind::Common => SymbolKind::Data,
- SectionKind::Tls | SectionKind::UninitializedTls | SectionKind::TlsVariables => {
- SymbolKind::Tls
- }
- _ => SymbolKind::Unknown,
- })
- .unwrap_or(SymbolKind::Unknown)
- }
-
- fn section(&self) -> SymbolSection {
- match self.nlist.n_type() & macho::N_TYPE {
- macho::N_UNDF => SymbolSection::Undefined,
- macho::N_ABS => SymbolSection::Absolute,
- macho::N_SECT => {
- let n_sect = self.nlist.n_sect();
- if n_sect != 0 {
- SymbolSection::Section(SectionIndex(n_sect as usize))
- } else {
- SymbolSection::Unknown
- }
- }
- _ => SymbolSection::Unknown,
- }
- }
-
- #[inline]
- fn is_undefined(&self) -> bool {
- self.nlist.n_type() & macho::N_TYPE == macho::N_UNDF
- }
-
- #[inline]
- fn is_definition(&self) -> bool {
- self.nlist.is_definition()
- }
-
- #[inline]
- fn is_common(&self) -> bool {
- // Mach-O common symbols are based on section, not symbol
- false
- }
-
- #[inline]
- fn is_weak(&self) -> bool {
- self.nlist.n_desc(self.file.endian) & (macho::N_WEAK_REF | macho::N_WEAK_DEF) != 0
- }
-
- fn scope(&self) -> SymbolScope {
- let n_type = self.nlist.n_type();
- if n_type & macho::N_TYPE == macho::N_UNDF {
- SymbolScope::Unknown
- } else if n_type & macho::N_EXT == 0 {
- SymbolScope::Compilation
- } else if n_type & macho::N_PEXT != 0 {
- SymbolScope::Linkage
- } else {
- SymbolScope::Dynamic
- }
- }
-
- #[inline]
- fn is_global(&self) -> bool {
- self.scope() != SymbolScope::Compilation
- }
-
- #[inline]
- fn is_local(&self) -> bool {
- self.scope() == SymbolScope::Compilation
- }
-
- #[inline]
- fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> {
- let n_desc = self.nlist.n_desc(self.file.endian);
- SymbolFlags::MachO { n_desc }
- }
-}
-
-/// A trait for generic access to [`macho::Nlist32`] and [`macho::Nlist64`].
-#[allow(missing_docs)]
-pub trait Nlist: Debug + Pod {
- type Word: Into<u64>;
- type Endian: endian::Endian;
-
- fn n_strx(&self, endian: Self::Endian) -> u32;
- fn n_type(&self) -> u8;
- fn n_sect(&self) -> u8;
- fn n_desc(&self, endian: Self::Endian) -> u16;
- fn n_value(&self, endian: Self::Endian) -> Self::Word;
-
- fn name<'data, R: ReadRef<'data>>(
- &self,
- endian: Self::Endian,
- strings: StringTable<'data, R>,
- ) -> Result<&'data [u8]> {
- strings
- .get(self.n_strx(endian))
- .read_error("Invalid Mach-O symbol name offset")
- }
-
- /// Return true if this is a STAB symbol.
- ///
- /// This determines the meaning of the `n_type` field.
- fn is_stab(&self) -> bool {
- self.n_type() & macho::N_STAB != 0
- }
-
- /// Return true if this is an undefined symbol.
- fn is_undefined(&self) -> bool {
- let n_type = self.n_type();
- n_type & macho::N_STAB == 0 && n_type & macho::N_TYPE == macho::N_UNDF
- }
-
- /// Return true if the symbol is a definition of a function or data object.
- fn is_definition(&self) -> bool {
- let n_type = self.n_type();
- n_type & macho::N_STAB == 0 && n_type & macho::N_TYPE == macho::N_SECT
- }
-
- /// Return the library ordinal.
- ///
- /// This is either a 1-based index into the dylib load commands,
- /// or a special ordinal.
- #[inline]
- fn library_ordinal(&self, endian: Self::Endian) -> u8 {
- (self.n_desc(endian) >> 8) as u8
- }
-}
-
-impl<Endian: endian::Endian> Nlist for macho::Nlist32<Endian> {
- type Word = u32;
- type Endian = Endian;
-
- fn n_strx(&self, endian: Self::Endian) -> u32 {
- self.n_strx.get(endian)
- }
- fn n_type(&self) -> u8 {
- self.n_type
- }
- fn n_sect(&self) -> u8 {
- self.n_sect
- }
- fn n_desc(&self, endian: Self::Endian) -> u16 {
- self.n_desc.get(endian)
- }
- fn n_value(&self, endian: Self::Endian) -> Self::Word {
- self.n_value.get(endian)
- }
-}
-
-impl<Endian: endian::Endian> Nlist for macho::Nlist64<Endian> {
- type Word = u64;
- type Endian = Endian;
-
- fn n_strx(&self, endian: Self::Endian) -> u32 {
- self.n_strx.get(endian)
- }
- fn n_type(&self) -> u8 {
- self.n_type
- }
- fn n_sect(&self) -> u8 {
- self.n_sect
- }
- fn n_desc(&self, endian: Self::Endian) -> u16 {
- self.n_desc.get(endian)
- }
- fn n_value(&self, endian: Self::Endian) -> Self::Word {
- self.n_value.get(endian)
- }
-}
diff --git a/vendor/object/src/read/mod.rs b/vendor/object/src/read/mod.rs
deleted file mode 100644
index c13e309..0000000
--- a/vendor/object/src/read/mod.rs
+++ /dev/null
@@ -1,860 +0,0 @@
-//! Interface for reading object files.
-//!
-//! ## Unified read API
-//!
-//! The [`Object`] trait provides a unified read API for accessing common features of
-//! object files, such as sections and symbols. There is an implementation of this
-//! trait for [`File`], which allows reading any file format, as well as implementations
-//! for each file format:
-//! [`ElfFile`](elf::ElfFile), [`MachOFile`](macho::MachOFile), [`CoffFile`](coff::CoffFile),
-//! [`PeFile`](pe::PeFile), [`WasmFile`](wasm::WasmFile), [`XcoffFile`](xcoff::XcoffFile).
-//!
-//! ## Low level read API
-//!
-//! The submodules for each file format define helpers that operate on the raw structs.
-//! These can be used instead of the unified API, or in conjunction with it to access
-//! details that are not available via the unified API.
-//!
-//! See the [submodules](#modules) for examples of the low level read API.
-//!
-//! ## Naming Convention
-//!
-//! Types that form part of the unified API for a file format are prefixed with the
-//! name of the file format.
-//!
-//! ## Example for unified read API
-//! ```no_run
-//! use object::{Object, ObjectSection};
-//! use std::error::Error;
-//! use std::fs;
-//!
-//! /// Reads a file and displays the name of each section.
-//! fn main() -> Result<(), Box<dyn Error>> {
-//! # #[cfg(feature = "std")] {
-//! let data = fs::read("path/to/binary")?;
-//! let file = object::File::parse(&*data)?;
-//! for section in file.sections() {
-//! println!("{}", section.name()?);
-//! }
-//! # }
-//! Ok(())
-//! }
-//! ```
-
-use alloc::borrow::Cow;
-use alloc::vec::Vec;
-use core::{fmt, result};
-
-use crate::common::*;
-
-mod read_ref;
-pub use read_ref::*;
-
-#[cfg(feature = "std")]
-mod read_cache;
-#[cfg(feature = "std")]
-pub use read_cache::*;
-
-mod util;
-pub use util::*;
-
-#[cfg(any(
- feature = "coff",
- feature = "elf",
- feature = "macho",
- feature = "pe",
- feature = "wasm",
- feature = "xcoff"
-))]
-mod any;
-#[cfg(any(
- feature = "coff",
- feature = "elf",
- feature = "macho",
- feature = "pe",
- feature = "wasm",
- feature = "xcoff"
-))]
-pub use any::*;
-
-#[cfg(feature = "archive")]
-pub mod archive;
-
-#[cfg(feature = "coff")]
-pub mod coff;
-
-#[cfg(feature = "elf")]
-pub mod elf;
-
-#[cfg(feature = "macho")]
-pub mod macho;
-
-#[cfg(feature = "pe")]
-pub mod pe;
-
-#[cfg(feature = "wasm")]
-pub mod wasm;
-
-#[cfg(feature = "xcoff")]
-pub mod xcoff;
-
-mod traits;
-pub use traits::*;
-
-mod private {
- pub trait Sealed {}
-}
-
-/// The error type used within the read module.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub struct Error(&'static str);
-
-impl fmt::Display for Error {
- #[inline]
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(self.0)
- }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for Error {}
-
-/// The result type used within the read module.
-pub type Result<T> = result::Result<T, Error>;
-
-trait ReadError<T> {
- fn read_error(self, error: &'static str) -> Result<T>;
-}
-
-impl<T> ReadError<T> for result::Result<T, ()> {
- fn read_error(self, error: &'static str) -> Result<T> {
- self.map_err(|()| Error(error))
- }
-}
-
-impl<T> ReadError<T> for result::Result<T, Error> {
- fn read_error(self, error: &'static str) -> Result<T> {
- self.map_err(|_| Error(error))
- }
-}
-
-impl<T> ReadError<T> for Option<T> {
- fn read_error(self, error: &'static str) -> Result<T> {
- self.ok_or(Error(error))
- }
-}
-
-/// The native executable file for the target platform.
-#[cfg(all(
- unix,
- not(target_os = "macos"),
- target_pointer_width = "32",
- feature = "elf"
-))]
-pub type NativeFile<'data, R = &'data [u8]> = elf::ElfFile32<'data, crate::Endianness, R>;
-
-/// The native executable file for the target platform.
-#[cfg(all(
- unix,
- not(target_os = "macos"),
- target_pointer_width = "64",
- feature = "elf"
-))]
-pub type NativeFile<'data, R = &'data [u8]> = elf::ElfFile64<'data, crate::Endianness, R>;
-
-/// The native executable file for the target platform.
-#[cfg(all(target_os = "macos", target_pointer_width = "32", feature = "macho"))]
-pub type NativeFile<'data, R = &'data [u8]> = macho::MachOFile32<'data, crate::Endianness, R>;
-
-/// The native executable file for the target platform.
-#[cfg(all(target_os = "macos", target_pointer_width = "64", feature = "macho"))]
-pub type NativeFile<'data, R = &'data [u8]> = macho::MachOFile64<'data, crate::Endianness, R>;
-
-/// The native executable file for the target platform.
-#[cfg(all(target_os = "windows", target_pointer_width = "32", feature = "pe"))]
-pub type NativeFile<'data, R = &'data [u8]> = pe::PeFile32<'data, R>;
-
-/// The native executable file for the target platform.
-#[cfg(all(target_os = "windows", target_pointer_width = "64", feature = "pe"))]
-pub type NativeFile<'data, R = &'data [u8]> = pe::PeFile64<'data, R>;
-
-/// The native executable file for the target platform.
-#[cfg(all(feature = "wasm", target_arch = "wasm32", feature = "wasm"))]
-pub type NativeFile<'data, R = &'data [u8]> = wasm::WasmFile<'data, R>;
-
-/// A file format kind.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum FileKind {
- /// A Unix archive.
- ///
- /// See [`archive::ArchiveFile`].
- #[cfg(feature = "archive")]
- Archive,
- /// A COFF object file.
- ///
- /// See [`coff::CoffFile`].
- #[cfg(feature = "coff")]
- Coff,
- /// A COFF bigobj object file.
- ///
- /// This supports a larger number of sections.
- ///
- /// See [`coff::CoffBigFile`].
- #[cfg(feature = "coff")]
- CoffBig,
- /// A Windows short import file.
- ///
- /// See [`coff::ImportFile`].
- #[cfg(feature = "coff")]
- CoffImport,
- /// A dyld cache file containing Mach-O images.
- ///
- /// See [`macho::DyldCache`]
- #[cfg(feature = "macho")]
- DyldCache,
- /// A 32-bit ELF file.
- ///
- /// See [`elf::ElfFile32`].
- #[cfg(feature = "elf")]
- Elf32,
- /// A 64-bit ELF file.
- ///
- /// See [`elf::ElfFile64`].
- #[cfg(feature = "elf")]
- Elf64,
- /// A 32-bit Mach-O file.
- ///
- /// See [`macho::MachOFile32`].
- #[cfg(feature = "macho")]
- MachO32,
- /// A 64-bit Mach-O file.
- ///
- /// See [`macho::MachOFile64`].
- #[cfg(feature = "macho")]
- MachO64,
- /// A 32-bit Mach-O fat binary.
- ///
- /// See [`macho::FatHeader::parse_arch32`].
- #[cfg(feature = "macho")]
- MachOFat32,
- /// A 64-bit Mach-O fat binary.
- ///
- /// See [`macho::FatHeader::parse_arch64`].
- #[cfg(feature = "macho")]
- MachOFat64,
- /// A 32-bit PE file.
- ///
- /// See [`pe::PeFile32`].
- #[cfg(feature = "pe")]
- Pe32,
- /// A 64-bit PE file.
- ///
- /// See [`pe::PeFile64`].
- #[cfg(feature = "pe")]
- Pe64,
- /// A Wasm file.
- ///
- /// See [`wasm::WasmFile`].
- #[cfg(feature = "wasm")]
- Wasm,
- /// A 32-bit XCOFF file.
- ///
- /// See [`xcoff::XcoffFile32`].
- #[cfg(feature = "xcoff")]
- Xcoff32,
- /// A 64-bit XCOFF file.
- ///
- /// See [`xcoff::XcoffFile64`].
- #[cfg(feature = "xcoff")]
- Xcoff64,
-}
-
-impl FileKind {
- /// Determine a file kind by parsing the start of the file.
- pub fn parse<'data, R: ReadRef<'data>>(data: R) -> Result<FileKind> {
- Self::parse_at(data, 0)
- }
-
- /// Determine a file kind by parsing at the given offset.
- pub fn parse_at<'data, R: ReadRef<'data>>(data: R, offset: u64) -> Result<FileKind> {
- let magic = data
- .read_bytes_at(offset, 16)
- .read_error("Could not read file magic")?;
- if magic.len() < 16 {
- return Err(Error("File too short"));
- }
-
- let kind = match [magic[0], magic[1], magic[2], magic[3], magic[4], magic[5], magic[6], magic[7]] {
- #[cfg(feature = "archive")]
- [b'!', b'<', b'a', b'r', b'c', b'h', b'>', b'\n'] => FileKind::Archive,
- #[cfg(feature = "macho")]
- [b'd', b'y', b'l', b'd', b'_', b'v', b'1', b' '] => FileKind::DyldCache,
- #[cfg(feature = "elf")]
- [0x7f, b'E', b'L', b'F', 1, ..] => FileKind::Elf32,
- #[cfg(feature = "elf")]
- [0x7f, b'E', b'L', b'F', 2, ..] => FileKind::Elf64,
- #[cfg(feature = "macho")]
- [0xfe, 0xed, 0xfa, 0xce, ..]
- | [0xce, 0xfa, 0xed, 0xfe, ..] => FileKind::MachO32,
- #[cfg(feature = "macho")]
- | [0xfe, 0xed, 0xfa, 0xcf, ..]
- | [0xcf, 0xfa, 0xed, 0xfe, ..] => FileKind::MachO64,
- #[cfg(feature = "macho")]
- [0xca, 0xfe, 0xba, 0xbe, ..] => FileKind::MachOFat32,
- #[cfg(feature = "macho")]
- [0xca, 0xfe, 0xba, 0xbf, ..] => FileKind::MachOFat64,
- #[cfg(feature = "wasm")]
- [0x00, b'a', b's', b'm', ..] => FileKind::Wasm,
- #[cfg(feature = "pe")]
- [b'M', b'Z', ..] if offset == 0 => {
- // offset == 0 restriction is because optional_header_magic only looks at offset 0
- match pe::optional_header_magic(data) {
- Ok(crate::pe::IMAGE_NT_OPTIONAL_HDR32_MAGIC) => {
- FileKind::Pe32
- }
- Ok(crate::pe::IMAGE_NT_OPTIONAL_HDR64_MAGIC) => {
- FileKind::Pe64
- }
- _ => return Err(Error("Unknown MS-DOS file")),
- }
- }
- // TODO: more COFF machines
- #[cfg(feature = "coff")]
- // COFF arm
- [0xc4, 0x01, ..]
- // COFF arm64
- | [0x64, 0xaa, ..]
- // COFF arm64ec
- | [0x41, 0xa6, ..]
- // COFF x86
- | [0x4c, 0x01, ..]
- // COFF x86-64
- | [0x64, 0x86, ..] => FileKind::Coff,
- #[cfg(feature = "coff")]
- [0x00, 0x00, 0xff, 0xff, 0x00, 0x00, ..] => FileKind::CoffImport,
- #[cfg(feature = "coff")]
- [0x00, 0x00, 0xff, 0xff, 0x02, 0x00, ..] if offset == 0 => {
- // offset == 0 restriction is because anon_object_class_id only looks at offset 0
- match coff::anon_object_class_id(data) {
- Ok(crate::pe::ANON_OBJECT_HEADER_BIGOBJ_CLASS_ID) => FileKind::CoffBig,
- _ => return Err(Error("Unknown anon object file")),
- }
- }
- #[cfg(feature = "xcoff")]
- [0x01, 0xdf, ..] => FileKind::Xcoff32,
- #[cfg(feature = "xcoff")]
- [0x01, 0xf7, ..] => FileKind::Xcoff64,
- _ => return Err(Error("Unknown file magic")),
- };
- Ok(kind)
- }
-}
-
-/// An object kind.
-///
-/// Returned by [`Object::kind`].
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum ObjectKind {
- /// The object kind is unknown.
- Unknown,
- /// Relocatable object.
- Relocatable,
- /// Executable.
- Executable,
- /// Dynamic shared object.
- Dynamic,
- /// Core.
- Core,
-}
-
-/// The index used to identify a section in a file.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct SectionIndex(pub usize);
-
-/// The index used to identify a symbol in a symbol table.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct SymbolIndex(pub usize);
-
-/// The section where an [`ObjectSymbol`] is defined.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum SymbolSection {
- /// The section is unknown.
- Unknown,
- /// The section is not applicable for this symbol (such as file symbols).
- None,
- /// The symbol is undefined.
- Undefined,
- /// The symbol has an absolute value.
- Absolute,
- /// The symbol is a zero-initialized symbol that will be combined with duplicate definitions.
- Common,
- /// The symbol is defined in the given section.
- Section(SectionIndex),
-}
-
-impl SymbolSection {
- /// Returns the section index for the section where the symbol is defined.
- ///
- /// May return `None` if the symbol is not defined in a section.
- #[inline]
- pub fn index(self) -> Option<SectionIndex> {
- if let SymbolSection::Section(index) = self {
- Some(index)
- } else {
- None
- }
- }
-}
-
-/// An entry in a [`SymbolMap`].
-pub trait SymbolMapEntry {
- /// The symbol address.
- fn address(&self) -> u64;
-}
-
-/// A map from addresses to symbol information.
-///
-/// The symbol information depends on the chosen entry type, such as [`SymbolMapName`].
-///
-/// Returned by [`Object::symbol_map`].
-#[derive(Debug, Default, Clone)]
-pub struct SymbolMap<T: SymbolMapEntry> {
- symbols: Vec<T>,
-}
-
-impl<T: SymbolMapEntry> SymbolMap<T> {
- /// Construct a new symbol map.
- ///
- /// This function will sort the symbols by address.
- pub fn new(mut symbols: Vec<T>) -> Self {
- symbols.sort_by_key(|s| s.address());
- SymbolMap { symbols }
- }
-
- /// Get the symbol before the given address.
- pub fn get(&self, address: u64) -> Option<&T> {
- let index = match self
- .symbols
- .binary_search_by_key(&address, |symbol| symbol.address())
- {
- Ok(index) => index,
- Err(index) => index.checked_sub(1)?,
- };
- self.symbols.get(index)
- }
-
- /// Get all symbols in the map.
- #[inline]
- pub fn symbols(&self) -> &[T] {
- &self.symbols
- }
-}
-
-/// The type used for entries in a [`SymbolMap`] that maps from addresses to names.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct SymbolMapName<'data> {
- address: u64,
- name: &'data str,
-}
-
-impl<'data> SymbolMapName<'data> {
- /// Construct a `SymbolMapName`.
- pub fn new(address: u64, name: &'data str) -> Self {
- SymbolMapName { address, name }
- }
-
- /// The symbol address.
- #[inline]
- pub fn address(&self) -> u64 {
- self.address
- }
-
- /// The symbol name.
- #[inline]
- pub fn name(&self) -> &'data str {
- self.name
- }
-}
-
-impl<'data> SymbolMapEntry for SymbolMapName<'data> {
- #[inline]
- fn address(&self) -> u64 {
- self.address
- }
-}
-
-/// A map from addresses to symbol names and object files.
-///
-/// This is derived from STAB entries in Mach-O files.
-///
-/// Returned by [`Object::object_map`].
-#[derive(Debug, Default, Clone)]
-pub struct ObjectMap<'data> {
- symbols: SymbolMap<ObjectMapEntry<'data>>,
- objects: Vec<&'data [u8]>,
-}
-
-impl<'data> ObjectMap<'data> {
- /// Get the entry containing the given address.
- pub fn get(&self, address: u64) -> Option<&ObjectMapEntry<'data>> {
- self.symbols
- .get(address)
- .filter(|entry| entry.size == 0 || address.wrapping_sub(entry.address) < entry.size)
- }
-
- /// Get all symbols in the map.
- #[inline]
- pub fn symbols(&self) -> &[ObjectMapEntry<'data>] {
- self.symbols.symbols()
- }
-
- /// Get all objects in the map.
- #[inline]
- pub fn objects(&self) -> &[&'data [u8]] {
- &self.objects
- }
-}
-
-/// An [`ObjectMap`] entry.
-#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct ObjectMapEntry<'data> {
- address: u64,
- size: u64,
- name: &'data [u8],
- object: usize,
-}
-
-impl<'data> ObjectMapEntry<'data> {
- /// Get the symbol address.
- #[inline]
- pub fn address(&self) -> u64 {
- self.address
- }
-
- /// Get the symbol size.
- ///
- /// This may be 0 if the size is unknown.
- #[inline]
- pub fn size(&self) -> u64 {
- self.size
- }
-
- /// Get the symbol name.
- #[inline]
- pub fn name(&self) -> &'data [u8] {
- self.name
- }
-
- /// Get the index of the object file name.
- #[inline]
- pub fn object_index(&self) -> usize {
- self.object
- }
-
- /// Get the object file name.
- #[inline]
- pub fn object(&self, map: &ObjectMap<'data>) -> &'data [u8] {
- map.objects[self.object]
- }
-}
-
-impl<'data> SymbolMapEntry for ObjectMapEntry<'data> {
- #[inline]
- fn address(&self) -> u64 {
- self.address
- }
-}
-
-/// An imported symbol.
-///
-/// Returned by [`Object::imports`].
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub struct Import<'data> {
- library: ByteString<'data>,
- // TODO: or ordinal
- name: ByteString<'data>,
-}
-
-impl<'data> Import<'data> {
- /// The symbol name.
- #[inline]
- pub fn name(&self) -> &'data [u8] {
- self.name.0
- }
-
- /// The name of the library to import the symbol from.
- #[inline]
- pub fn library(&self) -> &'data [u8] {
- self.library.0
- }
-}
-
-/// An exported symbol.
-///
-/// Returned by [`Object::exports`].
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub struct Export<'data> {
- // TODO: and ordinal?
- name: ByteString<'data>,
- address: u64,
-}
-
-impl<'data> Export<'data> {
- /// The symbol name.
- #[inline]
- pub fn name(&self) -> &'data [u8] {
- self.name.0
- }
-
- /// The virtual address of the symbol.
- #[inline]
- pub fn address(&self) -> u64 {
- self.address
- }
-}
-
-/// PDB information from the debug directory in a PE file.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub struct CodeView<'data> {
- guid: [u8; 16],
- path: ByteString<'data>,
- age: u32,
-}
-
-impl<'data> CodeView<'data> {
- /// The path to the PDB as stored in CodeView.
- #[inline]
- pub fn path(&self) -> &'data [u8] {
- self.path.0
- }
-
- /// The age of the PDB.
- #[inline]
- pub fn age(&self) -> u32 {
- self.age
- }
-
- /// The GUID of the PDB.
- #[inline]
- pub fn guid(&self) -> [u8; 16] {
- self.guid
- }
-}
-
-/// The target referenced by a [`Relocation`].
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum RelocationTarget {
- /// The target is a symbol.
- Symbol(SymbolIndex),
- /// The target is a section.
- Section(SectionIndex),
- /// The offset is an absolute address.
- Absolute,
-}
-
-/// A relocation entry.
-///
-/// Returned by [`Object::dynamic_relocations`] or [`ObjectSection::relocations`].
-#[derive(Debug)]
-pub struct Relocation {
- kind: RelocationKind,
- encoding: RelocationEncoding,
- size: u8,
- target: RelocationTarget,
- addend: i64,
- implicit_addend: bool,
-}
-
-impl Relocation {
- /// The operation used to calculate the result of the relocation.
- #[inline]
- pub fn kind(&self) -> RelocationKind {
- self.kind
- }
-
- /// Information about how the result of the relocation operation is encoded in the place.
- #[inline]
- pub fn encoding(&self) -> RelocationEncoding {
- self.encoding
- }
-
- /// The size in bits of the place of the relocation.
- ///
- /// If 0, then the size is determined by the relocation kind.
- #[inline]
- pub fn size(&self) -> u8 {
- self.size
- }
-
- /// The target of the relocation.
- #[inline]
- pub fn target(&self) -> RelocationTarget {
- self.target
- }
-
- /// The addend to use in the relocation calculation.
- #[inline]
- pub fn addend(&self) -> i64 {
- self.addend
- }
-
- /// Set the addend to use in the relocation calculation.
- #[inline]
- pub fn set_addend(&mut self, addend: i64) {
- self.addend = addend
- }
-
- /// Returns true if there is an implicit addend stored in the data at the offset
- /// to be relocated.
- #[inline]
- pub fn has_implicit_addend(&self) -> bool {
- self.implicit_addend
- }
-}
-
-/// A data compression format.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum CompressionFormat {
- /// The data is uncompressed.
- None,
- /// The data is compressed, but the compression format is unknown.
- Unknown,
- /// ZLIB/DEFLATE.
- ///
- /// Used for ELF compression and GNU compressed debug information.
- Zlib,
- /// Zstandard.
- ///
- /// Used for ELF compression.
- Zstandard,
-}
-
-/// A range in a file that may be compressed.
-///
-/// Returned by [`ObjectSection::compressed_file_range`].
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct CompressedFileRange {
- /// The data compression format.
- pub format: CompressionFormat,
- /// The file offset of the compressed data.
- pub offset: u64,
- /// The compressed data size.
- pub compressed_size: u64,
- /// The uncompressed data size.
- pub uncompressed_size: u64,
-}
-
-impl CompressedFileRange {
- /// Data that is uncompressed.
- #[inline]
- pub fn none(range: Option<(u64, u64)>) -> Self {
- if let Some((offset, size)) = range {
- CompressedFileRange {
- format: CompressionFormat::None,
- offset,
- compressed_size: size,
- uncompressed_size: size,
- }
- } else {
- CompressedFileRange {
- format: CompressionFormat::None,
- offset: 0,
- compressed_size: 0,
- uncompressed_size: 0,
- }
- }
- }
-
- /// Convert to [`CompressedData`] by reading from the file.
- pub fn data<'data, R: ReadRef<'data>>(self, file: R) -> Result<CompressedData<'data>> {
- let data = file
- .read_bytes_at(self.offset, self.compressed_size)
- .read_error("Invalid compressed data size or offset")?;
- Ok(CompressedData {
- format: self.format,
- data,
- uncompressed_size: self.uncompressed_size,
- })
- }
-}
-
-/// Data that may be compressed.
-///
-/// Returned by [`ObjectSection::compressed_data`].
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct CompressedData<'data> {
- /// The data compression format.
- pub format: CompressionFormat,
- /// The compressed data.
- pub data: &'data [u8],
- /// The uncompressed data size.
- pub uncompressed_size: u64,
-}
-
-impl<'data> CompressedData<'data> {
- /// Data that is uncompressed.
- #[inline]
- pub fn none(data: &'data [u8]) -> Self {
- CompressedData {
- format: CompressionFormat::None,
- data,
- uncompressed_size: data.len() as u64,
- }
- }
-
- /// Return the uncompressed data.
- ///
- /// Returns an error for invalid data or unsupported compression.
- /// This includes if the data is compressed but the `compression` feature
- /// for this crate is disabled.
- pub fn decompress(self) -> Result<Cow<'data, [u8]>> {
- match self.format {
- CompressionFormat::None => Ok(Cow::Borrowed(self.data)),
- #[cfg(feature = "compression")]
- CompressionFormat::Zlib => {
- use core::convert::TryInto;
- let size = self
- .uncompressed_size
- .try_into()
- .ok()
- .read_error("Uncompressed data size is too large.")?;
- let mut decompressed = Vec::with_capacity(size);
- let mut decompress = flate2::Decompress::new(true);
- decompress
- .decompress_vec(
- self.data,
- &mut decompressed,
- flate2::FlushDecompress::Finish,
- )
- .ok()
- .read_error("Invalid zlib compressed data")?;
- Ok(Cow::Owned(decompressed))
- }
- #[cfg(feature = "compression")]
- CompressionFormat::Zstandard => {
- use core::convert::TryInto;
- use std::io::Read;
- let size = self
- .uncompressed_size
- .try_into()
- .ok()
- .read_error("Uncompressed data size is too large.")?;
- let mut decompressed = Vec::with_capacity(size);
- let mut decoder = ruzstd::StreamingDecoder::new(self.data)
- .ok()
- .read_error("Invalid zstd compressed data")?;
- decoder
- .read_to_end(&mut decompressed)
- .ok()
- .read_error("Invalid zstd compressed data")?;
- Ok(Cow::Owned(decompressed))
- }
- _ => Err(Error("Unsupported compressed data.")),
- }
- }
-}
diff --git a/vendor/object/src/read/pe/data_directory.rs b/vendor/object/src/read/pe/data_directory.rs
deleted file mode 100644
index a17179f..0000000
--- a/vendor/object/src/read/pe/data_directory.rs
+++ /dev/null
@@ -1,213 +0,0 @@
-use core::slice;
-
-use crate::read::{Error, ReadError, ReadRef, Result};
-use crate::{pe, LittleEndian as LE};
-
-use super::{
- DelayLoadImportTable, ExportTable, ImportTable, RelocationBlockIterator, ResourceDirectory,
- SectionTable,
-};
-
-/// The table of data directories in a PE file.
-///
-/// Returned by [`ImageNtHeaders::parse`](super::ImageNtHeaders::parse).
-#[derive(Debug, Clone, Copy)]
-pub struct DataDirectories<'data> {
- entries: &'data [pe::ImageDataDirectory],
-}
-
-impl<'data> DataDirectories<'data> {
- /// Parse the data directory table.
- ///
- /// `data` must be the remaining optional data following the
- /// [optional header](pe::ImageOptionalHeader64). `number` must be from the
- /// [`number_of_rva_and_sizes`](pe::ImageOptionalHeader64::number_of_rva_and_sizes)
- /// field of the optional header.
- pub fn parse(data: &'data [u8], number: u32) -> Result<Self> {
- let entries = data
- .read_slice_at(0, number as usize)
- .read_error("Invalid PE number of RVA and sizes")?;
- Ok(DataDirectories { entries })
- }
-
- /// The number of data directories.
- #[allow(clippy::len_without_is_empty)]
- pub fn len(&self) -> usize {
- self.entries.len()
- }
-
- /// Iterator over the data directories.
- pub fn iter(&self) -> slice::Iter<'data, pe::ImageDataDirectory> {
- self.entries.iter()
- }
-
- /// Iterator which gives the directories as well as their index (one of the IMAGE_DIRECTORY_ENTRY_* constants).
- pub fn enumerate(&self) -> core::iter::Enumerate<slice::Iter<'data, pe::ImageDataDirectory>> {
- self.entries.iter().enumerate()
- }
-
- /// Returns the data directory at the given index.
- ///
- /// Index should be one of the `IMAGE_DIRECTORY_ENTRY_*` constants.
- ///
- /// Returns `None` if the index is larger than the table size,
- /// or if the entry at the index has a zero virtual address.
- pub fn get(&self, index: usize) -> Option<&'data pe::ImageDataDirectory> {
- self.entries
- .get(index)
- .filter(|d| d.virtual_address.get(LE) != 0)
- }
-
- /// Returns the unparsed export directory.
- ///
- /// `data` must be the entire file data.
- pub fn export_directory<R: ReadRef<'data>>(
- &self,
- data: R,
- sections: &SectionTable<'data>,
- ) -> Result<Option<&'data pe::ImageExportDirectory>> {
- let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_EXPORT) {
- Some(data_dir) => data_dir,
- None => return Ok(None),
- };
- let export_data = data_dir.data(data, sections)?;
- ExportTable::parse_directory(export_data).map(Some)
- }
-
- /// Returns the partially parsed export directory.
- ///
- /// `data` must be the entire file data.
- pub fn export_table<R: ReadRef<'data>>(
- &self,
- data: R,
- sections: &SectionTable<'data>,
- ) -> Result<Option<ExportTable<'data>>> {
- let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_EXPORT) {
- Some(data_dir) => data_dir,
- None => return Ok(None),
- };
- let export_va = data_dir.virtual_address.get(LE);
- let export_data = data_dir.data(data, sections)?;
- ExportTable::parse(export_data, export_va).map(Some)
- }
-
- /// Returns the partially parsed import directory.
- ///
- /// `data` must be the entire file data.
- pub fn import_table<R: ReadRef<'data>>(
- &self,
- data: R,
- sections: &SectionTable<'data>,
- ) -> Result<Option<ImportTable<'data>>> {
- let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_IMPORT) {
- Some(data_dir) => data_dir,
- None => return Ok(None),
- };
- let import_va = data_dir.virtual_address.get(LE);
- let (section_data, section_va) = sections
- .pe_data_containing(data, import_va)
- .read_error("Invalid import data dir virtual address")?;
- Ok(Some(ImportTable::new(section_data, section_va, import_va)))
- }
-
- /// Returns the partially parsed delay-load import directory.
- ///
- /// `data` must be the entire file data.
- pub fn delay_load_import_table<R: ReadRef<'data>>(
- &self,
- data: R,
- sections: &SectionTable<'data>,
- ) -> Result<Option<DelayLoadImportTable<'data>>> {
- let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT) {
- Some(data_dir) => data_dir,
- None => return Ok(None),
- };
- let import_va = data_dir.virtual_address.get(LE);
- let (section_data, section_va) = sections
- .pe_data_containing(data, import_va)
- .read_error("Invalid import data dir virtual address")?;
- Ok(Some(DelayLoadImportTable::new(
- section_data,
- section_va,
- import_va,
- )))
- }
-
- /// Returns the blocks in the base relocation directory.
- ///
- /// `data` must be the entire file data.
- pub fn relocation_blocks<R: ReadRef<'data>>(
- &self,
- data: R,
- sections: &SectionTable<'data>,
- ) -> Result<Option<RelocationBlockIterator<'data>>> {
- let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_BASERELOC) {
- Some(data_dir) => data_dir,
- None => return Ok(None),
- };
- let reloc_data = data_dir.data(data, sections)?;
- Ok(Some(RelocationBlockIterator::new(reloc_data)))
- }
-
- /// Returns the resource directory.
- ///
- /// `data` must be the entire file data.
- pub fn resource_directory<R: ReadRef<'data>>(
- &self,
- data: R,
- sections: &SectionTable<'data>,
- ) -> Result<Option<ResourceDirectory<'data>>> {
- let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_RESOURCE) {
- Some(data_dir) => data_dir,
- None => return Ok(None),
- };
- let rsrc_data = data_dir.data(data, sections)?;
- Ok(Some(ResourceDirectory::new(rsrc_data)))
- }
-}
-
-impl pe::ImageDataDirectory {
- /// Return the virtual address range of this directory entry.
- pub fn address_range(&self) -> (u32, u32) {
- (self.virtual_address.get(LE), self.size.get(LE))
- }
-
- /// Return the file offset and size of this directory entry.
- ///
- /// This function has some limitations:
- /// - It requires that the data is contained in a single section.
- /// - It uses the size field of the directory entry, which is
- /// not desirable for all data directories.
- /// - It uses the `virtual_address` of the directory entry as an address,
- /// which is not valid for `IMAGE_DIRECTORY_ENTRY_SECURITY`.
- pub fn file_range(&self, sections: &SectionTable<'_>) -> Result<(u32, u32)> {
- let (offset, section_size) = sections
- .pe_file_range_at(self.virtual_address.get(LE))
- .read_error("Invalid data dir virtual address")?;
- let size = self.size.get(LE);
- if size > section_size {
- return Err(Error("Invalid data dir size"));
- }
- Ok((offset, size))
- }
-
- /// Get the data referenced by this directory entry.
- ///
- /// This function has some limitations:
- /// - It requires that the data is contained in a single section.
- /// - It uses the size field of the directory entry, which is
- /// not desirable for all data directories.
- /// - It uses the `virtual_address` of the directory entry as an address,
- /// which is not valid for `IMAGE_DIRECTORY_ENTRY_SECURITY`.
- pub fn data<'data, R: ReadRef<'data>>(
- &self,
- data: R,
- sections: &SectionTable<'data>,
- ) -> Result<&'data [u8]> {
- sections
- .pe_data_at(data, self.virtual_address.get(LE))
- .read_error("Invalid data dir virtual address")?
- .get(..self.size.get(LE) as usize)
- .read_error("Invalid data dir size")
- }
-}
diff --git a/vendor/object/src/read/pe/export.rs b/vendor/object/src/read/pe/export.rs
deleted file mode 100644
index 1aba844..0000000
--- a/vendor/object/src/read/pe/export.rs
+++ /dev/null
@@ -1,333 +0,0 @@
-use alloc::vec::Vec;
-use core::fmt::Debug;
-
-use crate::read::{ByteString, Bytes, Error, ReadError, ReadRef, Result};
-use crate::{pe, LittleEndian as LE, U16Bytes, U32Bytes};
-
-/// Where an export is pointing to.
-#[derive(Clone, Copy)]
-pub enum ExportTarget<'data> {
- /// The address of the export, relative to the image base.
- Address(u32),
- /// Forwarded to an export ordinal in another DLL.
- ///
- /// This gives the name of the DLL, and the ordinal.
- ForwardByOrdinal(&'data [u8], u32),
- /// Forwarded to an export name in another DLL.
- ///
- /// This gives the name of the DLL, and the export name.
- ForwardByName(&'data [u8], &'data [u8]),
-}
-
-impl<'data> ExportTarget<'data> {
- /// Returns true if the target is an address.
- pub fn is_address(&self) -> bool {
- match self {
- ExportTarget::Address(_) => true,
- _ => false,
- }
- }
-
- /// Returns true if the export is forwarded to another DLL.
- pub fn is_forward(&self) -> bool {
- !self.is_address()
- }
-}
-
-/// An export from a PE file.
-///
-/// There are multiple kinds of PE exports (with or without a name, and local or forwarded).
-#[derive(Clone, Copy)]
-pub struct Export<'data> {
- /// The ordinal of the export.
- ///
- /// These are sequential, starting at a base specified in the DLL.
- pub ordinal: u32,
- /// The name of the export, if known.
- pub name: Option<&'data [u8]>,
- /// The target of this export.
- pub target: ExportTarget<'data>,
-}
-
-impl<'a> Debug for Export<'a> {
- fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::result::Result<(), core::fmt::Error> {
- f.debug_struct("Export")
- .field("ordinal", &self.ordinal)
- .field("name", &self.name.map(ByteString))
- .field("target", &self.target)
- .finish()
- }
-}
-
-impl<'a> Debug for ExportTarget<'a> {
- fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::result::Result<(), core::fmt::Error> {
- match self {
- ExportTarget::Address(address) => write!(f, "Address({:#x})", address),
- ExportTarget::ForwardByOrdinal(library, ordinal) => write!(
- f,
- "ForwardByOrdinal({:?}.#{})",
- ByteString(library),
- ordinal
- ),
- ExportTarget::ForwardByName(library, name) => write!(
- f,
- "ForwardByName({:?}.{:?})",
- ByteString(library),
- ByteString(name)
- ),
- }
- }
-}
-
-/// A partially parsed PE export table.
-///
-/// Returned by [`DataDirectories::export_table`](super::DataDirectories::export_table).
-#[derive(Debug, Clone)]
-pub struct ExportTable<'data> {
- data: Bytes<'data>,
- virtual_address: u32,
- directory: &'data pe::ImageExportDirectory,
- addresses: &'data [U32Bytes<LE>],
- names: &'data [U32Bytes<LE>],
- name_ordinals: &'data [U16Bytes<LE>],
-}
-
-impl<'data> ExportTable<'data> {
- /// Parse the export table given its section data and address.
- pub fn parse(data: &'data [u8], virtual_address: u32) -> Result<Self> {
- let directory = Self::parse_directory(data)?;
- let data = Bytes(data);
-
- let mut addresses = &[][..];
- let address_of_functions = directory.address_of_functions.get(LE);
- if address_of_functions != 0 {
- addresses = data
- .read_slice_at::<U32Bytes<_>>(
- address_of_functions.wrapping_sub(virtual_address) as usize,
- directory.number_of_functions.get(LE) as usize,
- )
- .read_error("Invalid PE export address table")?;
- }
-
- let mut names = &[][..];
- let mut name_ordinals = &[][..];
- let address_of_names = directory.address_of_names.get(LE);
- let address_of_name_ordinals = directory.address_of_name_ordinals.get(LE);
- if address_of_names != 0 {
- if address_of_name_ordinals == 0 {
- return Err(Error("Missing PE export ordinal table"));
- }
-
- let number = directory.number_of_names.get(LE) as usize;
- names = data
- .read_slice_at::<U32Bytes<_>>(
- address_of_names.wrapping_sub(virtual_address) as usize,
- number,
- )
- .read_error("Invalid PE export name pointer table")?;
- name_ordinals = data
- .read_slice_at::<U16Bytes<_>>(
- address_of_name_ordinals.wrapping_sub(virtual_address) as usize,
- number,
- )
- .read_error("Invalid PE export ordinal table")?;
- }
-
- Ok(ExportTable {
- data,
- virtual_address,
- directory,
- addresses,
- names,
- name_ordinals,
- })
- }
-
- /// Parse the export directory given its section data.
- pub fn parse_directory(data: &'data [u8]) -> Result<&'data pe::ImageExportDirectory> {
- data.read_at::<pe::ImageExportDirectory>(0)
- .read_error("Invalid PE export dir size")
- }
-
- /// Returns the header of the export table.
- pub fn directory(&self) -> &'data pe::ImageExportDirectory {
- self.directory
- }
-
- /// Returns the base value of ordinals.
- ///
- /// Adding this to an address index will give an ordinal.
- pub fn ordinal_base(&self) -> u32 {
- self.directory.base.get(LE)
- }
-
- /// Returns the unparsed address table.
- ///
- /// An address table entry may be a local address, or the address of a forwarded export entry.
- /// See [`Self::is_forward`] and [`Self::target_from_address`].
- pub fn addresses(&self) -> &'data [U32Bytes<LE>] {
- self.addresses
- }
-
- /// Returns the unparsed name pointer table.
- ///
- /// A name pointer table entry can be used with [`Self::name_from_pointer`].
- pub fn name_pointers(&self) -> &'data [U32Bytes<LE>] {
- self.names
- }
-
- /// Returns the unparsed ordinal table.
- ///
- /// An ordinal table entry is a 0-based index into the address table.
- /// See [`Self::address_by_index`] and [`Self::target_by_index`].
- pub fn name_ordinals(&self) -> &'data [U16Bytes<LE>] {
- self.name_ordinals
- }
-
- /// Returns an iterator for the entries in the name pointer table and ordinal table.
- ///
- /// A name pointer table entry can be used with [`Self::name_from_pointer`].
- ///
- /// An ordinal table entry is a 0-based index into the address table.
- /// See [`Self::address_by_index`] and [`Self::target_by_index`].
- pub fn name_iter(&self) -> impl Iterator<Item = (u32, u16)> + 'data {
- self.names
- .iter()
- .map(|x| x.get(LE))
- .zip(self.name_ordinals.iter().map(|x| x.get(LE)))
- }
-
- /// Returns the export address table entry at the given address index.
- ///
- /// This may be a local address, or the address of a forwarded export entry.
- /// See [`Self::is_forward`] and [`Self::target_from_address`].
- ///
- /// `index` is a 0-based index into the export address table.
- pub fn address_by_index(&self, index: u32) -> Result<u32> {
- Ok(self
- .addresses
- .get(index as usize)
- .read_error("Invalid PE export address index")?
- .get(LE))
- }
-
- /// Returns the export address table entry at the given ordinal.
- ///
- /// This may be a local address, or the address of a forwarded export entry.
- /// See [`Self::is_forward`] and [`Self::target_from_address`].
- pub fn address_by_ordinal(&self, ordinal: u32) -> Result<u32> {
- self.address_by_index(ordinal.wrapping_sub(self.ordinal_base()))
- }
-
- /// Returns the target of the export at the given address index.
- ///
- /// `index` is a 0-based index into the export address table.
- pub fn target_by_index(&self, index: u32) -> Result<ExportTarget<'data>> {
- self.target_from_address(self.address_by_index(index)?)
- }
-
- /// Returns the target of the export at the given ordinal.
- pub fn target_by_ordinal(&self, ordinal: u32) -> Result<ExportTarget<'data>> {
- self.target_from_address(self.address_by_ordinal(ordinal)?)
- }
-
- /// Convert an export address table entry into a target.
- pub fn target_from_address(&self, address: u32) -> Result<ExportTarget<'data>> {
- Ok(if let Some(forward) = self.forward_string(address)? {
- let i = forward
- .iter()
- .position(|x| *x == b'.')
- .read_error("Missing PE forwarded export separator")?;
- let library = &forward[..i];
- match &forward[i + 1..] {
- [b'#', digits @ ..] => {
- let ordinal =
- parse_ordinal(digits).read_error("Invalid PE forwarded export ordinal")?;
- ExportTarget::ForwardByOrdinal(library, ordinal)
- }
- [] => {
- return Err(Error("Missing PE forwarded export name"));
- }
- name => ExportTarget::ForwardByName(library, name),
- }
- } else {
- ExportTarget::Address(address)
- })
- }
-
- fn forward_offset(&self, address: u32) -> Option<usize> {
- let offset = address.wrapping_sub(self.virtual_address) as usize;
- if offset < self.data.len() {
- Some(offset)
- } else {
- None
- }
- }
-
- /// Return true if the export address table entry is a forward.
- pub fn is_forward(&self, address: u32) -> bool {
- self.forward_offset(address).is_some()
- }
-
- /// Return the forward string if the export address table entry is a forward.
- pub fn forward_string(&self, address: u32) -> Result<Option<&'data [u8]>> {
- if let Some(offset) = self.forward_offset(address) {
- self.data
- .read_string_at(offset)
- .read_error("Invalid PE forwarded export address")
- .map(Some)
- } else {
- Ok(None)
- }
- }
-
- /// Convert an export name pointer table entry into a name.
- pub fn name_from_pointer(&self, name_pointer: u32) -> Result<&'data [u8]> {
- let offset = name_pointer.wrapping_sub(self.virtual_address);
- self.data
- .read_string_at(offset as usize)
- .read_error("Invalid PE export name pointer")
- }
-
- /// Returns the parsed exports in this table.
- pub fn exports(&self) -> Result<Vec<Export<'data>>> {
- // First, let's list all exports.
- let mut exports = Vec::new();
- let ordinal_base = self.ordinal_base();
- for (i, address) in self.addresses.iter().enumerate() {
- // Convert from an array index to an ordinal.
- let ordinal = ordinal_base.wrapping_add(i as u32);
- let target = self.target_from_address(address.get(LE))?;
- exports.push(Export {
- ordinal,
- target,
- // Might be populated later.
- name: None,
- });
- }
-
- // Now, check whether some (or all) of them have an associated name.
- // `ordinal_index` is a 0-based index into `addresses`.
- for (name_pointer, ordinal_index) in self.name_iter() {
- let name = self.name_from_pointer(name_pointer)?;
- exports
- .get_mut(ordinal_index as usize)
- .read_error("Invalid PE export ordinal")?
- .name = Some(name);
- }
-
- Ok(exports)
- }
-}
-
-fn parse_ordinal(digits: &[u8]) -> Option<u32> {
- if digits.is_empty() {
- return None;
- }
- let mut result: u32 = 0;
- for &c in digits {
- let x = (c as char).to_digit(10)?;
- result = result.checked_mul(10)?.checked_add(x)?;
- }
- Some(result)
-}
diff --git a/vendor/object/src/read/pe/file.rs b/vendor/object/src/read/pe/file.rs
deleted file mode 100644
index 5372bdd..0000000
--- a/vendor/object/src/read/pe/file.rs
+++ /dev/null
@@ -1,1050 +0,0 @@
-use alloc::vec::Vec;
-use core::fmt::Debug;
-use core::{mem, str};
-
-use core::convert::TryInto;
-
-use crate::read::coff::{CoffCommon, CoffSymbol, CoffSymbolIterator, CoffSymbolTable, SymbolTable};
-use crate::read::{
- self, Architecture, ComdatKind, Error, Export, FileFlags, Import, NoDynamicRelocationIterator,
- Object, ObjectComdat, ObjectKind, ReadError, ReadRef, Result, SectionIndex, SymbolIndex,
-};
-use crate::{pe, ByteString, Bytes, CodeView, LittleEndian as LE, Pod, SubArchitecture, U32};
-
-use super::{
- DataDirectories, ExportTable, ImageThunkData, ImportTable, PeSection, PeSectionIterator,
- PeSegment, PeSegmentIterator, RichHeaderInfo, SectionTable,
-};
-
-/// A PE32 (32-bit) image file.
-///
-/// This is a file that starts with [`pe::ImageNtHeaders32`], and corresponds
-/// to [`crate::FileKind::Pe32`].
-pub type PeFile32<'data, R = &'data [u8]> = PeFile<'data, pe::ImageNtHeaders32, R>;
-/// A PE32+ (64-bit) image file.
-///
-/// This is a file that starts with [`pe::ImageNtHeaders64`], and corresponds
-/// to [`crate::FileKind::Pe64`].
-pub type PeFile64<'data, R = &'data [u8]> = PeFile<'data, pe::ImageNtHeaders64, R>;
-
-/// A PE image file.
-///
-/// Most functionality is provided by the [`Object`] trait implementation.
-#[derive(Debug)]
-pub struct PeFile<'data, Pe, R = &'data [u8]>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- pub(super) dos_header: &'data pe::ImageDosHeader,
- pub(super) nt_headers: &'data Pe,
- pub(super) data_directories: DataDirectories<'data>,
- pub(super) common: CoffCommon<'data, R>,
- pub(super) data: R,
-}
-
-impl<'data, Pe, R> PeFile<'data, Pe, R>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- /// Parse the raw PE file data.
- pub fn parse(data: R) -> Result<Self> {
- let dos_header = pe::ImageDosHeader::parse(data)?;
- let mut offset = dos_header.nt_headers_offset().into();
- let (nt_headers, data_directories) = Pe::parse(data, &mut offset)?;
- let sections = nt_headers.sections(data, offset)?;
- let coff_symbols = nt_headers.symbols(data);
- let image_base = nt_headers.optional_header().image_base();
-
- Ok(PeFile {
- dos_header,
- nt_headers,
- data_directories,
- common: CoffCommon {
- sections,
- // The PE file format deprecates the COFF symbol table (https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#coff-file-header-object-and-image)
- // We do not want to prevent parsing the rest of the PE file for a corrupt COFF header, but rather return an empty symbol table
- symbols: coff_symbols.unwrap_or_default(),
- image_base,
- },
- data,
- })
- }
-
- /// Returns this binary data.
- pub fn data(&self) -> R {
- self.data
- }
-
- /// Return the DOS header of this file.
- pub fn dos_header(&self) -> &'data pe::ImageDosHeader {
- self.dos_header
- }
-
- /// Return the NT Headers of this file.
- pub fn nt_headers(&self) -> &'data Pe {
- self.nt_headers
- }
-
- /// Returns information about the rich header of this file (if any).
- pub fn rich_header_info(&self) -> Option<RichHeaderInfo<'_>> {
- RichHeaderInfo::parse(self.data, self.dos_header.nt_headers_offset().into())
- }
-
- /// Returns the section table of this binary.
- pub fn section_table(&self) -> SectionTable<'data> {
- self.common.sections
- }
-
- /// Returns the data directories of this file.
- pub fn data_directories(&self) -> DataDirectories<'data> {
- self.data_directories
- }
-
- /// Returns the data directory at the given index.
- pub fn data_directory(&self, id: usize) -> Option<&'data pe::ImageDataDirectory> {
- self.data_directories.get(id)
- }
-
- /// Returns the export table of this file.
- ///
- /// The export table is located using the data directory.
- pub fn export_table(&self) -> Result<Option<ExportTable<'data>>> {
- self.data_directories
- .export_table(self.data, &self.common.sections)
- }
-
- /// Returns the import table of this file.
- ///
- /// The import table is located using the data directory.
- pub fn import_table(&self) -> Result<Option<ImportTable<'data>>> {
- self.data_directories
- .import_table(self.data, &self.common.sections)
- }
-
- pub(super) fn section_alignment(&self) -> u64 {
- u64::from(self.nt_headers.optional_header().section_alignment())
- }
-}
-
-impl<'data, Pe, R> read::private::Sealed for PeFile<'data, Pe, R>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Pe, R> Object<'data, 'file> for PeFile<'data, Pe, R>
-where
- 'data: 'file,
- Pe: ImageNtHeaders,
- R: 'file + ReadRef<'data>,
-{
- type Segment = PeSegment<'data, 'file, Pe, R>;
- type SegmentIterator = PeSegmentIterator<'data, 'file, Pe, R>;
- type Section = PeSection<'data, 'file, Pe, R>;
- type SectionIterator = PeSectionIterator<'data, 'file, Pe, R>;
- type Comdat = PeComdat<'data, 'file, Pe, R>;
- type ComdatIterator = PeComdatIterator<'data, 'file, Pe, R>;
- type Symbol = CoffSymbol<'data, 'file, R>;
- type SymbolIterator = CoffSymbolIterator<'data, 'file, R>;
- type SymbolTable = CoffSymbolTable<'data, 'file, R>;
- type DynamicRelocationIterator = NoDynamicRelocationIterator;
-
- fn architecture(&self) -> Architecture {
- match self.nt_headers.file_header().machine.get(LE) {
- pe::IMAGE_FILE_MACHINE_ARMNT => Architecture::Arm,
- pe::IMAGE_FILE_MACHINE_ARM64 | pe::IMAGE_FILE_MACHINE_ARM64EC => Architecture::Aarch64,
- pe::IMAGE_FILE_MACHINE_I386 => Architecture::I386,
- pe::IMAGE_FILE_MACHINE_AMD64 => Architecture::X86_64,
- _ => Architecture::Unknown,
- }
- }
-
- fn sub_architecture(&self) -> Option<SubArchitecture> {
- match self.nt_headers.file_header().machine.get(LE) {
- pe::IMAGE_FILE_MACHINE_ARM64EC => Some(SubArchitecture::Arm64EC),
- _ => None,
- }
- }
-
- #[inline]
- fn is_little_endian(&self) -> bool {
- // Only little endian is supported.
- true
- }
-
- #[inline]
- fn is_64(&self) -> bool {
- self.nt_headers.is_type_64()
- }
-
- fn kind(&self) -> ObjectKind {
- let characteristics = self.nt_headers.file_header().characteristics.get(LE);
- if characteristics & pe::IMAGE_FILE_DLL != 0 {
- ObjectKind::Dynamic
- } else if characteristics & pe::IMAGE_FILE_SYSTEM != 0 {
- ObjectKind::Unknown
- } else {
- ObjectKind::Executable
- }
- }
-
- fn segments(&'file self) -> PeSegmentIterator<'data, 'file, Pe, R> {
- PeSegmentIterator {
- file: self,
- iter: self.common.sections.iter(),
- }
- }
-
- fn section_by_name_bytes(
- &'file self,
- section_name: &[u8],
- ) -> Option<PeSection<'data, 'file, Pe, R>> {
- self.common
- .sections
- .section_by_name(self.common.symbols.strings(), section_name)
- .map(|(index, section)| PeSection {
- file: self,
- index: SectionIndex(index),
- section,
- })
- }
-
- fn section_by_index(
- &'file self,
- index: SectionIndex,
- ) -> Result<PeSection<'data, 'file, Pe, R>> {
- let section = self.common.sections.section(index.0)?;
- Ok(PeSection {
- file: self,
- index,
- section,
- })
- }
-
- fn sections(&'file self) -> PeSectionIterator<'data, 'file, Pe, R> {
- PeSectionIterator {
- file: self,
- iter: self.common.sections.iter().enumerate(),
- }
- }
-
- fn comdats(&'file self) -> PeComdatIterator<'data, 'file, Pe, R> {
- PeComdatIterator { file: self }
- }
-
- fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<CoffSymbol<'data, 'file, R>> {
- let symbol = self.common.symbols.symbol(index.0)?;
- Ok(CoffSymbol {
- file: &self.common,
- index,
- symbol,
- })
- }
-
- fn symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R> {
- CoffSymbolIterator {
- file: &self.common,
- index: 0,
- }
- }
-
- fn symbol_table(&'file self) -> Option<CoffSymbolTable<'data, 'file, R>> {
- Some(CoffSymbolTable { file: &self.common })
- }
-
- fn dynamic_symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R> {
- CoffSymbolIterator {
- file: &self.common,
- // Hack: don't return any.
- index: self.common.symbols.len(),
- }
- }
-
- fn dynamic_symbol_table(&'file self) -> Option<CoffSymbolTable<'data, 'file, R>> {
- None
- }
-
- fn dynamic_relocations(&'file self) -> Option<NoDynamicRelocationIterator> {
- None
- }
-
- fn imports(&self) -> Result<Vec<Import<'data>>> {
- let mut imports = Vec::new();
- if let Some(import_table) = self.import_table()? {
- let mut import_descs = import_table.descriptors()?;
- while let Some(import_desc) = import_descs.next()? {
- let library = import_table.name(import_desc.name.get(LE))?;
- let mut first_thunk = import_desc.original_first_thunk.get(LE);
- if first_thunk == 0 {
- first_thunk = import_desc.first_thunk.get(LE);
- }
- let mut thunks = import_table.thunks(first_thunk)?;
- while let Some(thunk) = thunks.next::<Pe>()? {
- if !thunk.is_ordinal() {
- let (_hint, name) = import_table.hint_name(thunk.address())?;
- imports.push(Import {
- library: ByteString(library),
- name: ByteString(name),
- });
- }
- }
- }
- }
- Ok(imports)
- }
-
- fn exports(&self) -> Result<Vec<Export<'data>>> {
- let mut exports = Vec::new();
- if let Some(export_table) = self.export_table()? {
- for (name_pointer, address_index) in export_table.name_iter() {
- let name = export_table.name_from_pointer(name_pointer)?;
- let address = export_table.address_by_index(address_index.into())?;
- if !export_table.is_forward(address) {
- exports.push(Export {
- name: ByteString(name),
- address: self.common.image_base.wrapping_add(address.into()),
- })
- }
- }
- }
- Ok(exports)
- }
-
- fn pdb_info(&self) -> Result<Option<CodeView<'_>>> {
- let data_dir = match self.data_directory(pe::IMAGE_DIRECTORY_ENTRY_DEBUG) {
- Some(data_dir) => data_dir,
- None => return Ok(None),
- };
- let debug_data = data_dir.data(self.data, &self.common.sections).map(Bytes)?;
- let debug_data_size = data_dir.size.get(LE) as usize;
-
- let count = debug_data_size / mem::size_of::<pe::ImageDebugDirectory>();
- let rem = debug_data_size % mem::size_of::<pe::ImageDebugDirectory>();
- if rem != 0 || count < 1 {
- return Err(Error("Invalid PE debug dir size"));
- }
-
- let debug_dirs = debug_data
- .read_slice_at::<pe::ImageDebugDirectory>(0, count)
- .read_error("Invalid PE debug dir size")?;
-
- for debug_dir in debug_dirs {
- if debug_dir.typ.get(LE) != pe::IMAGE_DEBUG_TYPE_CODEVIEW {
- continue;
- }
-
- let info = self
- .data
- .read_slice_at::<u8>(
- debug_dir.pointer_to_raw_data.get(LE) as u64,
- debug_dir.size_of_data.get(LE) as usize,
- )
- .read_error("Invalid CodeView Info address")?;
-
- let mut info = Bytes(info);
-
- let sig = info
- .read_bytes(4)
- .read_error("Invalid CodeView signature")?;
- if sig.0 != b"RSDS" {
- continue;
- }
-
- let guid: [u8; 16] = info
- .read_bytes(16)
- .read_error("Invalid CodeView GUID")?
- .0
- .try_into()
- .unwrap();
-
- let age = info.read::<U32<LE>>().read_error("Invalid CodeView Age")?;
-
- let path = info
- .read_string()
- .read_error("Invalid CodeView file path")?;
-
- return Ok(Some(CodeView {
- path: ByteString(path),
- guid,
- age: age.get(LE),
- }));
- }
- Ok(None)
- }
-
- fn has_debug_symbols(&self) -> bool {
- self.section_by_name(".debug_info").is_some()
- }
-
- fn relative_address_base(&self) -> u64 {
- self.common.image_base
- }
-
- fn entry(&self) -> u64 {
- u64::from(self.nt_headers.optional_header().address_of_entry_point())
- .wrapping_add(self.common.image_base)
- }
-
- fn flags(&self) -> FileFlags {
- FileFlags::Coff {
- characteristics: self.nt_headers.file_header().characteristics.get(LE),
- }
- }
-}
-
-/// An iterator for the COMDAT section groups in a [`PeFile32`].
-pub type PeComdatIterator32<'data, 'file, R = &'data [u8]> =
- PeComdatIterator<'data, 'file, pe::ImageNtHeaders32, R>;
-/// An iterator for the COMDAT section groups in a [`PeFile64`].
-pub type PeComdatIterator64<'data, 'file, R = &'data [u8]> =
- PeComdatIterator<'data, 'file, pe::ImageNtHeaders64, R>;
-
-/// An iterator for the COMDAT section groups in a [`PeFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct PeComdatIterator<'data, 'file, Pe, R = &'data [u8]>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- #[allow(unused)]
- file: &'file PeFile<'data, Pe, R>,
-}
-
-impl<'data, 'file, Pe, R> Iterator for PeComdatIterator<'data, 'file, Pe, R>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- type Item = PeComdat<'data, 'file, Pe, R>;
-
- #[inline]
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
-}
-
-/// A COMDAT section group in a [`PeFile32`].
-pub type PeComdat32<'data, 'file, R = &'data [u8]> =
- PeComdat<'data, 'file, pe::ImageNtHeaders32, R>;
-/// A COMDAT section group in a [`PeFile64`].
-pub type PeComdat64<'data, 'file, R = &'data [u8]> =
- PeComdat<'data, 'file, pe::ImageNtHeaders64, R>;
-
-/// A COMDAT section group in a [`PeFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct PeComdat<'data, 'file, Pe, R = &'data [u8]>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- #[allow(unused)]
- file: &'file PeFile<'data, Pe, R>,
-}
-
-impl<'data, 'file, Pe, R> read::private::Sealed for PeComdat<'data, 'file, Pe, R>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Pe, R> ObjectComdat<'data> for PeComdat<'data, 'file, Pe, R>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- type SectionIterator = PeComdatSectionIterator<'data, 'file, Pe, R>;
-
- #[inline]
- fn kind(&self) -> ComdatKind {
- unreachable!();
- }
-
- #[inline]
- fn symbol(&self) -> SymbolIndex {
- unreachable!();
- }
-
- #[inline]
- fn name_bytes(&self) -> Result<&[u8]> {
- unreachable!();
- }
-
- #[inline]
- fn name(&self) -> Result<&str> {
- unreachable!();
- }
-
- #[inline]
- fn sections(&self) -> Self::SectionIterator {
- unreachable!();
- }
-}
-
-/// An iterator for the sections in a COMDAT section group in a [`PeFile32`].
-pub type PeComdatSectionIterator32<'data, 'file, R = &'data [u8]> =
- PeComdatSectionIterator<'data, 'file, pe::ImageNtHeaders32, R>;
-/// An iterator for the sections in a COMDAT section group in a [`PeFile64`].
-pub type PeComdatSectionIterator64<'data, 'file, R = &'data [u8]> =
- PeComdatSectionIterator<'data, 'file, pe::ImageNtHeaders64, R>;
-
-/// An iterator for the sections in a COMDAT section group in a [`PeFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct PeComdatSectionIterator<'data, 'file, Pe, R = &'data [u8]>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- #[allow(unused)]
- file: &'file PeFile<'data, Pe, R>,
-}
-
-impl<'data, 'file, Pe, R> Iterator for PeComdatSectionIterator<'data, 'file, Pe, R>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- type Item = SectionIndex;
-
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
-}
-
-impl pe::ImageDosHeader {
- /// Read the DOS header.
- ///
- /// Also checks that the `e_magic` field in the header is valid.
- pub fn parse<'data, R: ReadRef<'data>>(data: R) -> read::Result<&'data Self> {
- // DOS header comes first.
- let dos_header = data
- .read_at::<pe::ImageDosHeader>(0)
- .read_error("Invalid DOS header size or alignment")?;
- if dos_header.e_magic.get(LE) != pe::IMAGE_DOS_SIGNATURE {
- return Err(Error("Invalid DOS magic"));
- }
- Ok(dos_header)
- }
-
- /// Return the file offset of the nt_headers.
- #[inline]
- pub fn nt_headers_offset(&self) -> u32 {
- self.e_lfanew.get(LE)
- }
-}
-
-/// Find the optional header and read its `magic` field.
-///
-/// It can be useful to know this magic value before trying to
-/// fully parse the NT headers.
-pub fn optional_header_magic<'data, R: ReadRef<'data>>(data: R) -> Result<u16> {
- let dos_header = pe::ImageDosHeader::parse(data)?;
- // NT headers are at an offset specified in the DOS header.
- let offset = dos_header.nt_headers_offset().into();
- // It doesn't matter which NT header type is used for the purpose
- // of reading the optional header magic.
- let nt_headers = data
- .read_at::<pe::ImageNtHeaders32>(offset)
- .read_error("Invalid NT headers offset, size, or alignment")?;
- if nt_headers.signature() != pe::IMAGE_NT_SIGNATURE {
- return Err(Error("Invalid PE magic"));
- }
- Ok(nt_headers.optional_header().magic())
-}
-
-/// A trait for generic access to [`pe::ImageNtHeaders32`] and [`pe::ImageNtHeaders64`].
-#[allow(missing_docs)]
-pub trait ImageNtHeaders: Debug + Pod {
- type ImageOptionalHeader: ImageOptionalHeader;
- type ImageThunkData: ImageThunkData;
-
- /// Return true if this type is a 64-bit header.
- ///
- /// This is a property of the type, not a value in the header data.
- fn is_type_64(&self) -> bool;
-
- /// Return true if the magic field in the optional header is valid.
- fn is_valid_optional_magic(&self) -> bool;
-
- /// Return the signature
- fn signature(&self) -> u32;
-
- /// Return the file header.
- fn file_header(&self) -> &pe::ImageFileHeader;
-
- /// Return the optional header.
- fn optional_header(&self) -> &Self::ImageOptionalHeader;
-
- // Provided methods.
-
- /// Read the NT headers, including the data directories.
- ///
- /// `data` must be for the entire file.
- ///
- /// `offset` must be headers offset, which can be obtained from [`pe::ImageDosHeader::nt_headers_offset`].
- /// It is updated to point after the optional header, which is where the section headers are located.
- ///
- /// Also checks that the `signature` and `magic` fields in the headers are valid.
- fn parse<'data, R: ReadRef<'data>>(
- data: R,
- offset: &mut u64,
- ) -> read::Result<(&'data Self, DataDirectories<'data>)> {
- // Note that this does not include the data directories in the optional header.
- let nt_headers = data
- .read::<Self>(offset)
- .read_error("Invalid PE headers offset or size")?;
- if nt_headers.signature() != pe::IMAGE_NT_SIGNATURE {
- return Err(Error("Invalid PE magic"));
- }
- if !nt_headers.is_valid_optional_magic() {
- return Err(Error("Invalid PE optional header magic"));
- }
-
- // Read the rest of the optional header, and then read the data directories from that.
- let optional_data_size =
- u64::from(nt_headers.file_header().size_of_optional_header.get(LE))
- .checked_sub(mem::size_of::<Self::ImageOptionalHeader>() as u64)
- .read_error("PE optional header size is too small")?;
- let optional_data = data
- .read_bytes(offset, optional_data_size)
- .read_error("Invalid PE optional header size")?;
- let data_directories = DataDirectories::parse(
- optional_data,
- nt_headers.optional_header().number_of_rva_and_sizes(),
- )?;
-
- Ok((nt_headers, data_directories))
- }
-
- /// Read the section table.
- ///
- /// `data` must be for the entire file.
- /// `offset` must be after the optional file header.
- #[inline]
- fn sections<'data, R: ReadRef<'data>>(
- &self,
- data: R,
- offset: u64,
- ) -> read::Result<SectionTable<'data>> {
- SectionTable::parse(self.file_header(), data, offset)
- }
-
- /// Read the COFF symbol table and string table.
- ///
- /// `data` must be the entire file data.
- #[inline]
- fn symbols<'data, R: ReadRef<'data>>(&self, data: R) -> read::Result<SymbolTable<'data, R>> {
- SymbolTable::parse(self.file_header(), data)
- }
-}
-
-/// A trait for generic access to [`pe::ImageOptionalHeader32`] and [`pe::ImageOptionalHeader64`].
-#[allow(missing_docs)]
-pub trait ImageOptionalHeader: Debug + Pod {
- // Standard fields.
- fn magic(&self) -> u16;
- fn major_linker_version(&self) -> u8;
- fn minor_linker_version(&self) -> u8;
- fn size_of_code(&self) -> u32;
- fn size_of_initialized_data(&self) -> u32;
- fn size_of_uninitialized_data(&self) -> u32;
- fn address_of_entry_point(&self) -> u32;
- fn base_of_code(&self) -> u32;
- fn base_of_data(&self) -> Option<u32>;
-
- // NT additional fields.
- fn image_base(&self) -> u64;
- fn section_alignment(&self) -> u32;
- fn file_alignment(&self) -> u32;
- fn major_operating_system_version(&self) -> u16;
- fn minor_operating_system_version(&self) -> u16;
- fn major_image_version(&self) -> u16;
- fn minor_image_version(&self) -> u16;
- fn major_subsystem_version(&self) -> u16;
- fn minor_subsystem_version(&self) -> u16;
- fn win32_version_value(&self) -> u32;
- fn size_of_image(&self) -> u32;
- fn size_of_headers(&self) -> u32;
- fn check_sum(&self) -> u32;
- fn subsystem(&self) -> u16;
- fn dll_characteristics(&self) -> u16;
- fn size_of_stack_reserve(&self) -> u64;
- fn size_of_stack_commit(&self) -> u64;
- fn size_of_heap_reserve(&self) -> u64;
- fn size_of_heap_commit(&self) -> u64;
- fn loader_flags(&self) -> u32;
- fn number_of_rva_and_sizes(&self) -> u32;
-}
-
-impl ImageNtHeaders for pe::ImageNtHeaders32 {
- type ImageOptionalHeader = pe::ImageOptionalHeader32;
- type ImageThunkData = pe::ImageThunkData32;
-
- #[inline]
- fn is_type_64(&self) -> bool {
- false
- }
-
- #[inline]
- fn is_valid_optional_magic(&self) -> bool {
- self.optional_header.magic.get(LE) == pe::IMAGE_NT_OPTIONAL_HDR32_MAGIC
- }
-
- #[inline]
- fn signature(&self) -> u32 {
- self.signature.get(LE)
- }
-
- #[inline]
- fn file_header(&self) -> &pe::ImageFileHeader {
- &self.file_header
- }
-
- #[inline]
- fn optional_header(&self) -> &Self::ImageOptionalHeader {
- &self.optional_header
- }
-}
-
-impl ImageOptionalHeader for pe::ImageOptionalHeader32 {
- #[inline]
- fn magic(&self) -> u16 {
- self.magic.get(LE)
- }
-
- #[inline]
- fn major_linker_version(&self) -> u8 {
- self.major_linker_version
- }
-
- #[inline]
- fn minor_linker_version(&self) -> u8 {
- self.minor_linker_version
- }
-
- #[inline]
- fn size_of_code(&self) -> u32 {
- self.size_of_code.get(LE)
- }
-
- #[inline]
- fn size_of_initialized_data(&self) -> u32 {
- self.size_of_initialized_data.get(LE)
- }
-
- #[inline]
- fn size_of_uninitialized_data(&self) -> u32 {
- self.size_of_uninitialized_data.get(LE)
- }
-
- #[inline]
- fn address_of_entry_point(&self) -> u32 {
- self.address_of_entry_point.get(LE)
- }
-
- #[inline]
- fn base_of_code(&self) -> u32 {
- self.base_of_code.get(LE)
- }
-
- #[inline]
- fn base_of_data(&self) -> Option<u32> {
- Some(self.base_of_data.get(LE))
- }
-
- #[inline]
- fn image_base(&self) -> u64 {
- self.image_base.get(LE).into()
- }
-
- #[inline]
- fn section_alignment(&self) -> u32 {
- self.section_alignment.get(LE)
- }
-
- #[inline]
- fn file_alignment(&self) -> u32 {
- self.file_alignment.get(LE)
- }
-
- #[inline]
- fn major_operating_system_version(&self) -> u16 {
- self.major_operating_system_version.get(LE)
- }
-
- #[inline]
- fn minor_operating_system_version(&self) -> u16 {
- self.minor_operating_system_version.get(LE)
- }
-
- #[inline]
- fn major_image_version(&self) -> u16 {
- self.major_image_version.get(LE)
- }
-
- #[inline]
- fn minor_image_version(&self) -> u16 {
- self.minor_image_version.get(LE)
- }
-
- #[inline]
- fn major_subsystem_version(&self) -> u16 {
- self.major_subsystem_version.get(LE)
- }
-
- #[inline]
- fn minor_subsystem_version(&self) -> u16 {
- self.minor_subsystem_version.get(LE)
- }
-
- #[inline]
- fn win32_version_value(&self) -> u32 {
- self.win32_version_value.get(LE)
- }
-
- #[inline]
- fn size_of_image(&self) -> u32 {
- self.size_of_image.get(LE)
- }
-
- #[inline]
- fn size_of_headers(&self) -> u32 {
- self.size_of_headers.get(LE)
- }
-
- #[inline]
- fn check_sum(&self) -> u32 {
- self.check_sum.get(LE)
- }
-
- #[inline]
- fn subsystem(&self) -> u16 {
- self.subsystem.get(LE)
- }
-
- #[inline]
- fn dll_characteristics(&self) -> u16 {
- self.dll_characteristics.get(LE)
- }
-
- #[inline]
- fn size_of_stack_reserve(&self) -> u64 {
- self.size_of_stack_reserve.get(LE).into()
- }
-
- #[inline]
- fn size_of_stack_commit(&self) -> u64 {
- self.size_of_stack_commit.get(LE).into()
- }
-
- #[inline]
- fn size_of_heap_reserve(&self) -> u64 {
- self.size_of_heap_reserve.get(LE).into()
- }
-
- #[inline]
- fn size_of_heap_commit(&self) -> u64 {
- self.size_of_heap_commit.get(LE).into()
- }
-
- #[inline]
- fn loader_flags(&self) -> u32 {
- self.loader_flags.get(LE)
- }
-
- #[inline]
- fn number_of_rva_and_sizes(&self) -> u32 {
- self.number_of_rva_and_sizes.get(LE)
- }
-}
-
-impl ImageNtHeaders for pe::ImageNtHeaders64 {
- type ImageOptionalHeader = pe::ImageOptionalHeader64;
- type ImageThunkData = pe::ImageThunkData64;
-
- #[inline]
- fn is_type_64(&self) -> bool {
- true
- }
-
- #[inline]
- fn is_valid_optional_magic(&self) -> bool {
- self.optional_header.magic.get(LE) == pe::IMAGE_NT_OPTIONAL_HDR64_MAGIC
- }
-
- #[inline]
- fn signature(&self) -> u32 {
- self.signature.get(LE)
- }
-
- #[inline]
- fn file_header(&self) -> &pe::ImageFileHeader {
- &self.file_header
- }
-
- #[inline]
- fn optional_header(&self) -> &Self::ImageOptionalHeader {
- &self.optional_header
- }
-}
-
-impl ImageOptionalHeader for pe::ImageOptionalHeader64 {
- #[inline]
- fn magic(&self) -> u16 {
- self.magic.get(LE)
- }
-
- #[inline]
- fn major_linker_version(&self) -> u8 {
- self.major_linker_version
- }
-
- #[inline]
- fn minor_linker_version(&self) -> u8 {
- self.minor_linker_version
- }
-
- #[inline]
- fn size_of_code(&self) -> u32 {
- self.size_of_code.get(LE)
- }
-
- #[inline]
- fn size_of_initialized_data(&self) -> u32 {
- self.size_of_initialized_data.get(LE)
- }
-
- #[inline]
- fn size_of_uninitialized_data(&self) -> u32 {
- self.size_of_uninitialized_data.get(LE)
- }
-
- #[inline]
- fn address_of_entry_point(&self) -> u32 {
- self.address_of_entry_point.get(LE)
- }
-
- #[inline]
- fn base_of_code(&self) -> u32 {
- self.base_of_code.get(LE)
- }
-
- #[inline]
- fn base_of_data(&self) -> Option<u32> {
- None
- }
-
- #[inline]
- fn image_base(&self) -> u64 {
- self.image_base.get(LE)
- }
-
- #[inline]
- fn section_alignment(&self) -> u32 {
- self.section_alignment.get(LE)
- }
-
- #[inline]
- fn file_alignment(&self) -> u32 {
- self.file_alignment.get(LE)
- }
-
- #[inline]
- fn major_operating_system_version(&self) -> u16 {
- self.major_operating_system_version.get(LE)
- }
-
- #[inline]
- fn minor_operating_system_version(&self) -> u16 {
- self.minor_operating_system_version.get(LE)
- }
-
- #[inline]
- fn major_image_version(&self) -> u16 {
- self.major_image_version.get(LE)
- }
-
- #[inline]
- fn minor_image_version(&self) -> u16 {
- self.minor_image_version.get(LE)
- }
-
- #[inline]
- fn major_subsystem_version(&self) -> u16 {
- self.major_subsystem_version.get(LE)
- }
-
- #[inline]
- fn minor_subsystem_version(&self) -> u16 {
- self.minor_subsystem_version.get(LE)
- }
-
- #[inline]
- fn win32_version_value(&self) -> u32 {
- self.win32_version_value.get(LE)
- }
-
- #[inline]
- fn size_of_image(&self) -> u32 {
- self.size_of_image.get(LE)
- }
-
- #[inline]
- fn size_of_headers(&self) -> u32 {
- self.size_of_headers.get(LE)
- }
-
- #[inline]
- fn check_sum(&self) -> u32 {
- self.check_sum.get(LE)
- }
-
- #[inline]
- fn subsystem(&self) -> u16 {
- self.subsystem.get(LE)
- }
-
- #[inline]
- fn dll_characteristics(&self) -> u16 {
- self.dll_characteristics.get(LE)
- }
-
- #[inline]
- fn size_of_stack_reserve(&self) -> u64 {
- self.size_of_stack_reserve.get(LE)
- }
-
- #[inline]
- fn size_of_stack_commit(&self) -> u64 {
- self.size_of_stack_commit.get(LE)
- }
-
- #[inline]
- fn size_of_heap_reserve(&self) -> u64 {
- self.size_of_heap_reserve.get(LE)
- }
-
- #[inline]
- fn size_of_heap_commit(&self) -> u64 {
- self.size_of_heap_commit.get(LE)
- }
-
- #[inline]
- fn loader_flags(&self) -> u32 {
- self.loader_flags.get(LE)
- }
-
- #[inline]
- fn number_of_rva_and_sizes(&self) -> u32 {
- self.number_of_rva_and_sizes.get(LE)
- }
-}
diff --git a/vendor/object/src/read/pe/import.rs b/vendor/object/src/read/pe/import.rs
deleted file mode 100644
index 8e9a9a9..0000000
--- a/vendor/object/src/read/pe/import.rs
+++ /dev/null
@@ -1,337 +0,0 @@
-use core::fmt::Debug;
-use core::mem;
-
-use crate::read::{Bytes, ReadError, Result};
-use crate::{pe, LittleEndian as LE, Pod, U16Bytes};
-
-use super::ImageNtHeaders;
-
-/// Information for parsing a PE import table.
-///
-/// Returned by [`DataDirectories::import_table`](super::DataDirectories::import_table).
-#[derive(Debug, Clone)]
-pub struct ImportTable<'data> {
- section_data: Bytes<'data>,
- section_address: u32,
- import_address: u32,
-}
-
-impl<'data> ImportTable<'data> {
- /// Create a new import table parser.
- ///
- /// The import descriptors start at `import_address`.
- /// The size declared in the `IMAGE_DIRECTORY_ENTRY_IMPORT` data directory is
- /// ignored by the Windows loader, and so descriptors will be parsed until a null entry.
- ///
- /// `section_data` should be from the section containing `import_address`, and
- /// `section_address` should be the address of that section. Pointers within the
- /// descriptors and thunks may point to anywhere within the section data.
- pub fn new(section_data: &'data [u8], section_address: u32, import_address: u32) -> Self {
- ImportTable {
- section_data: Bytes(section_data),
- section_address,
- import_address,
- }
- }
-
- /// Return an iterator for the import descriptors.
- pub fn descriptors(&self) -> Result<ImportDescriptorIterator<'data>> {
- let offset = self.import_address.wrapping_sub(self.section_address);
- let mut data = self.section_data;
- data.skip(offset as usize)
- .read_error("Invalid PE import descriptor address")?;
- Ok(ImportDescriptorIterator { data })
- }
-
- /// Return a library name given its address.
- ///
- /// This address may be from [`pe::ImageImportDescriptor::name`].
- pub fn name(&self, address: u32) -> Result<&'data [u8]> {
- self.section_data
- .read_string_at(address.wrapping_sub(self.section_address) as usize)
- .read_error("Invalid PE import descriptor name")
- }
-
- /// Return a list of thunks given its address.
- ///
- /// This address may be from [`pe::ImageImportDescriptor::original_first_thunk`]
- /// or [`pe::ImageImportDescriptor::first_thunk`].
- pub fn thunks(&self, address: u32) -> Result<ImportThunkList<'data>> {
- let offset = address.wrapping_sub(self.section_address);
- let mut data = self.section_data;
- data.skip(offset as usize)
- .read_error("Invalid PE import thunk table address")?;
- Ok(ImportThunkList { data })
- }
-
- /// Parse a thunk.
- pub fn import<Pe: ImageNtHeaders>(&self, thunk: Pe::ImageThunkData) -> Result<Import<'data>> {
- if thunk.is_ordinal() {
- Ok(Import::Ordinal(thunk.ordinal()))
- } else {
- let (hint, name) = self.hint_name(thunk.address())?;
- Ok(Import::Name(hint, name))
- }
- }
-
- /// Return the hint and name at the given address.
- ///
- /// This address may be from [`pe::ImageThunkData32`] or [`pe::ImageThunkData64`].
- ///
- /// The hint is an index into the export name pointer table in the target library.
- pub fn hint_name(&self, address: u32) -> Result<(u16, &'data [u8])> {
- let offset = address.wrapping_sub(self.section_address);
- let mut data = self.section_data;
- data.skip(offset as usize)
- .read_error("Invalid PE import thunk address")?;
- let hint = data
- .read::<U16Bytes<LE>>()
- .read_error("Missing PE import thunk hint")?
- .get(LE);
- let name = data
- .read_string()
- .read_error("Missing PE import thunk name")?;
- Ok((hint, name))
- }
-}
-
-/// A fallible iterator for the descriptors in the import data directory.
-#[derive(Debug, Clone)]
-pub struct ImportDescriptorIterator<'data> {
- data: Bytes<'data>,
-}
-
-impl<'data> ImportDescriptorIterator<'data> {
- /// Return the next descriptor.
- ///
- /// Returns `Ok(None)` when a null descriptor is found.
- pub fn next(&mut self) -> Result<Option<&'data pe::ImageImportDescriptor>> {
- let import_desc = self
- .data
- .read::<pe::ImageImportDescriptor>()
- .read_error("Missing PE null import descriptor")?;
- if import_desc.is_null() {
- Ok(None)
- } else {
- Ok(Some(import_desc))
- }
- }
-}
-
-/// A list of import thunks.
-///
-/// These may be in the import lookup table, or the import address table.
-#[derive(Debug, Clone)]
-pub struct ImportThunkList<'data> {
- data: Bytes<'data>,
-}
-
-impl<'data> ImportThunkList<'data> {
- /// Get the thunk at the given index.
- pub fn get<Pe: ImageNtHeaders>(&self, index: usize) -> Result<Pe::ImageThunkData> {
- let thunk = self
- .data
- .read_at(index * mem::size_of::<Pe::ImageThunkData>())
- .read_error("Invalid PE import thunk index")?;
- Ok(*thunk)
- }
-
- /// Return the first thunk in the list, and update `self` to point after it.
- ///
- /// Returns `Ok(None)` when a null thunk is found.
- pub fn next<Pe: ImageNtHeaders>(&mut self) -> Result<Option<Pe::ImageThunkData>> {
- let thunk = self
- .data
- .read::<Pe::ImageThunkData>()
- .read_error("Missing PE null import thunk")?;
- if thunk.address() == 0 {
- Ok(None)
- } else {
- Ok(Some(*thunk))
- }
- }
-}
-
-/// A parsed import thunk.
-#[derive(Debug, Clone, Copy)]
-pub enum Import<'data> {
- /// Import by ordinal.
- Ordinal(u16),
- /// Import by name.
- ///
- /// Includes a hint for the index into the export name pointer table in the target library.
- Name(u16, &'data [u8]),
-}
-
-/// A trait for generic access to [`pe::ImageThunkData32`] and [`pe::ImageThunkData64`].
-#[allow(missing_docs)]
-pub trait ImageThunkData: Debug + Pod {
- /// Return the raw thunk value.
- fn raw(self) -> u64;
-
- /// Returns true if the ordinal flag is set.
- fn is_ordinal(self) -> bool;
-
- /// Return the ordinal portion of the thunk.
- ///
- /// Does not check the ordinal flag.
- fn ordinal(self) -> u16;
-
- /// Return the RVA portion of the thunk.
- ///
- /// Does not check the ordinal flag.
- fn address(self) -> u32;
-}
-
-impl ImageThunkData for pe::ImageThunkData64 {
- fn raw(self) -> u64 {
- self.0.get(LE)
- }
-
- fn is_ordinal(self) -> bool {
- self.0.get(LE) & pe::IMAGE_ORDINAL_FLAG64 != 0
- }
-
- fn ordinal(self) -> u16 {
- self.0.get(LE) as u16
- }
-
- fn address(self) -> u32 {
- self.0.get(LE) as u32 & 0x7fff_ffff
- }
-}
-
-impl ImageThunkData for pe::ImageThunkData32 {
- fn raw(self) -> u64 {
- self.0.get(LE).into()
- }
-
- fn is_ordinal(self) -> bool {
- self.0.get(LE) & pe::IMAGE_ORDINAL_FLAG32 != 0
- }
-
- fn ordinal(self) -> u16 {
- self.0.get(LE) as u16
- }
-
- fn address(self) -> u32 {
- self.0.get(LE) & 0x7fff_ffff
- }
-}
-
-/// Information for parsing a PE delay-load import table.
-///
-/// Returned by
-/// [`DataDirectories::delay_load_import_table`](super::DataDirectories::delay_load_import_table).
-#[derive(Debug, Clone)]
-pub struct DelayLoadImportTable<'data> {
- section_data: Bytes<'data>,
- section_address: u32,
- import_address: u32,
-}
-
-impl<'data> DelayLoadImportTable<'data> {
- /// Create a new delay load import table parser.
- ///
- /// The import descriptors start at `import_address`.
- /// This table works in the same way the import table does: descriptors will be
- /// parsed until a null entry.
- ///
- /// `section_data` should be from the section containing `import_address`, and
- /// `section_address` should be the address of that section. Pointers within the
- /// descriptors and thunks may point to anywhere within the section data.
- pub fn new(section_data: &'data [u8], section_address: u32, import_address: u32) -> Self {
- DelayLoadImportTable {
- section_data: Bytes(section_data),
- section_address,
- import_address,
- }
- }
-
- /// Return an iterator for the import descriptors.
- pub fn descriptors(&self) -> Result<DelayLoadDescriptorIterator<'data>> {
- let offset = self.import_address.wrapping_sub(self.section_address);
- let mut data = self.section_data;
- data.skip(offset as usize)
- .read_error("Invalid PE delay-load import descriptor address")?;
- Ok(DelayLoadDescriptorIterator { data })
- }
-
- /// Return a library name given its address.
- ///
- /// This address may be from [`pe::ImageDelayloadDescriptor::dll_name_rva`].
- pub fn name(&self, address: u32) -> Result<&'data [u8]> {
- self.section_data
- .read_string_at(address.wrapping_sub(self.section_address) as usize)
- .read_error("Invalid PE import descriptor name")
- }
-
- /// Return a list of thunks given its address.
- ///
- /// This address may be from the INT, i.e. from
- /// [`pe::ImageDelayloadDescriptor::import_name_table_rva`].
- ///
- /// Please note that others RVA values from [`pe::ImageDelayloadDescriptor`] are used
- /// by the delay loader at runtime to store values, and thus do not point inside the same
- /// section as the INT. Calling this function on those addresses will fail.
- pub fn thunks(&self, address: u32) -> Result<ImportThunkList<'data>> {
- let offset = address.wrapping_sub(self.section_address);
- let mut data = self.section_data;
- data.skip(offset as usize)
- .read_error("Invalid PE delay load import thunk table address")?;
- Ok(ImportThunkList { data })
- }
-
- /// Parse a thunk.
- pub fn import<Pe: ImageNtHeaders>(&self, thunk: Pe::ImageThunkData) -> Result<Import<'data>> {
- if thunk.is_ordinal() {
- Ok(Import::Ordinal(thunk.ordinal()))
- } else {
- let (hint, name) = self.hint_name(thunk.address())?;
- Ok(Import::Name(hint, name))
- }
- }
-
- /// Return the hint and name at the given address.
- ///
- /// This address may be from [`pe::ImageThunkData32`] or [`pe::ImageThunkData64`].
- ///
- /// The hint is an index into the export name pointer table in the target library.
- pub fn hint_name(&self, address: u32) -> Result<(u16, &'data [u8])> {
- let offset = address.wrapping_sub(self.section_address);
- let mut data = self.section_data;
- data.skip(offset as usize)
- .read_error("Invalid PE delay load import thunk address")?;
- let hint = data
- .read::<U16Bytes<LE>>()
- .read_error("Missing PE delay load import thunk hint")?
- .get(LE);
- let name = data
- .read_string()
- .read_error("Missing PE delay load import thunk name")?;
- Ok((hint, name))
- }
-}
-
-/// A fallible iterator for the descriptors in the delay-load data directory.
-#[derive(Debug, Clone)]
-pub struct DelayLoadDescriptorIterator<'data> {
- data: Bytes<'data>,
-}
-
-impl<'data> DelayLoadDescriptorIterator<'data> {
- /// Return the next descriptor.
- ///
- /// Returns `Ok(None)` when a null descriptor is found.
- pub fn next(&mut self) -> Result<Option<&'data pe::ImageDelayloadDescriptor>> {
- let import_desc = self
- .data
- .read::<pe::ImageDelayloadDescriptor>()
- .read_error("Missing PE null delay-load import descriptor")?;
- if import_desc.is_null() {
- Ok(None)
- } else {
- Ok(Some(import_desc))
- }
- }
-}
diff --git a/vendor/object/src/read/pe/mod.rs b/vendor/object/src/read/pe/mod.rs
deleted file mode 100644
index ab6011c..0000000
--- a/vendor/object/src/read/pe/mod.rs
+++ /dev/null
@@ -1,68 +0,0 @@
-//! Support for reading PE files.
-//!
-//! Traits are used to abstract over the difference between PE32 and PE32+.
-//! The primary trait for this is [`ImageNtHeaders`].
-//!
-//! ## High level API
-//!
-//! [`PeFile`] implements the [`Object`](crate::read::Object) trait for
-//! PE files. [`PeFile`] is parameterised by [`ImageNtHeaders`] to allow
-//! reading both PE32 and PE32+. There are type aliases for these parameters
-//! ([`PeFile32`] and [`PeFile64`]).
-//!
-//! ## Low level API
-//!
-//! The [`ImageNtHeaders`] trait can be directly used to parse both
-//! [`pe::ImageNtHeaders32`] and [`pe::ImageNtHeaders64`].
-//!
-//! ### Example for low level API
-//! ```no_run
-//! use object::pe;
-//! use object::read::pe::ImageNtHeaders;
-//! use std::error::Error;
-//! use std::fs;
-//!
-//! /// Reads a file and displays the name of each section.
-//! fn main() -> Result<(), Box<dyn Error>> {
-//! # #[cfg(feature = "std")] {
-//! let data = fs::read("path/to/binary")?;
-//! let dos_header = pe::ImageDosHeader::parse(&*data)?;
-//! let mut offset = dos_header.nt_headers_offset().into();
-//! let (nt_headers, data_directories) = pe::ImageNtHeaders64::parse(&*data, &mut offset)?;
-//! let sections = nt_headers.sections(&*data, offset)?;
-//! let symbols = nt_headers.symbols(&*data)?;
-//! for section in sections.iter() {
-//! println!("{}", String::from_utf8_lossy(section.name(symbols.strings())?));
-//! }
-//! # }
-//! Ok(())
-//! }
-//! ```
-#[cfg(doc)]
-use crate::pe;
-
-mod file;
-pub use file::*;
-
-mod section;
-pub use section::*;
-
-mod data_directory;
-pub use data_directory::*;
-
-mod export;
-pub use export::*;
-
-mod import;
-pub use import::*;
-
-mod relocation;
-pub use relocation::*;
-
-mod resource;
-pub use resource::*;
-
-mod rich;
-pub use rich::*;
-
-pub use super::coff::{SectionTable, SymbolTable};
diff --git a/vendor/object/src/read/pe/relocation.rs b/vendor/object/src/read/pe/relocation.rs
deleted file mode 100644
index 77421b7..0000000
--- a/vendor/object/src/read/pe/relocation.rs
+++ /dev/null
@@ -1,92 +0,0 @@
-use core::slice;
-
-use crate::endian::{LittleEndian as LE, U16};
-use crate::pe;
-use crate::read::{Bytes, Error, ReadError, Result};
-
-/// An iterator over the relocation blocks in the `.reloc` section of a PE file.
-///
-/// Returned by [`DataDirectories::relocation_blocks`](super::DataDirectories::relocation_blocks).
-#[derive(Debug, Default, Clone, Copy)]
-pub struct RelocationBlockIterator<'data> {
- data: Bytes<'data>,
-}
-
-impl<'data> RelocationBlockIterator<'data> {
- /// Construct a new iterator from the data of the `.reloc` section.
- pub fn new(data: &'data [u8]) -> Self {
- RelocationBlockIterator { data: Bytes(data) }
- }
-
- /// Read the next relocation page.
- pub fn next(&mut self) -> Result<Option<RelocationIterator<'data>>> {
- if self.data.is_empty() {
- return Ok(None);
- }
- let header = self
- .data
- .read::<pe::ImageBaseRelocation>()
- .read_error("Invalid PE reloc section size")?;
- let virtual_address = header.virtual_address.get(LE);
- let size = header.size_of_block.get(LE);
- if size <= 8 || size & 3 != 0 {
- return Err(Error("Invalid PE reloc block size"));
- }
- let count = (size - 8) / 2;
- let relocs = self
- .data
- .read_slice::<U16<LE>>(count as usize)
- .read_error("Invalid PE reloc block size")?
- .iter();
- Ok(Some(RelocationIterator {
- virtual_address,
- size,
- relocs,
- }))
- }
-}
-
-/// An iterator of the relocations in a block in the `.reloc` section of a PE file.
-#[derive(Debug, Clone)]
-pub struct RelocationIterator<'data> {
- virtual_address: u32,
- size: u32,
- relocs: slice::Iter<'data, U16<LE>>,
-}
-
-impl<'data> RelocationIterator<'data> {
- /// Return the virtual address of the page that this block of relocations applies to.
- pub fn virtual_address(&self) -> u32 {
- self.virtual_address
- }
-
- /// Return the size in bytes of this block of relocations.
- pub fn size(&self) -> u32 {
- self.size
- }
-}
-
-impl<'data> Iterator for RelocationIterator<'data> {
- type Item = Relocation;
-
- fn next(&mut self) -> Option<Relocation> {
- loop {
- let reloc = self.relocs.next()?.get(LE);
- if reloc != 0 {
- return Some(Relocation {
- virtual_address: self.virtual_address.wrapping_add((reloc & 0xfff) as u32),
- typ: reloc >> 12,
- });
- }
- }
- }
-}
-
-/// A relocation in the `.reloc` section of a PE file.
-#[derive(Debug, Default, Clone, Copy)]
-pub struct Relocation {
- /// The virtual address of the relocation.
- pub virtual_address: u32,
- /// One of the `pe::IMAGE_REL_BASED_*` constants.
- pub typ: u16,
-}
diff --git a/vendor/object/src/read/pe/resource.rs b/vendor/object/src/read/pe/resource.rs
deleted file mode 100644
index 331da3f..0000000
--- a/vendor/object/src/read/pe/resource.rs
+++ /dev/null
@@ -1,209 +0,0 @@
-use alloc::string::String;
-use core::char;
-
-use crate::read::{ReadError, ReadRef, Result};
-use crate::{pe, LittleEndian as LE, U16Bytes};
-
-/// The `.rsrc` section of a PE file.
-///
-/// Returned by [`DataDirectories::resource_directory`](super::DataDirectories::resource_directory).
-#[derive(Debug, Clone, Copy)]
-pub struct ResourceDirectory<'data> {
- data: &'data [u8],
-}
-
-impl<'data> ResourceDirectory<'data> {
- /// Construct from the data of the `.rsrc` section.
- pub fn new(data: &'data [u8]) -> Self {
- ResourceDirectory { data }
- }
-
- /// Parses the root resource directory.
- pub fn root(&self) -> Result<ResourceDirectoryTable<'data>> {
- ResourceDirectoryTable::parse(self.data, 0)
- }
-}
-
-/// A table of resource entries.
-#[derive(Debug, Clone)]
-pub struct ResourceDirectoryTable<'data> {
- /// The table header.
- pub header: &'data pe::ImageResourceDirectory,
- /// The table entries.
- pub entries: &'data [pe::ImageResourceDirectoryEntry],
-}
-
-impl<'data> ResourceDirectoryTable<'data> {
- fn parse(data: &'data [u8], offset: u32) -> Result<Self> {
- let mut offset = u64::from(offset);
- let header = data
- .read::<pe::ImageResourceDirectory>(&mut offset)
- .read_error("Invalid resource table header")?;
- let entries_count = header.number_of_id_entries.get(LE) as usize
- + header.number_of_named_entries.get(LE) as usize;
- let entries = data
- .read_slice::<pe::ImageResourceDirectoryEntry>(&mut offset, entries_count)
- .read_error("Invalid resource table entries")?;
- Ok(Self { header, entries })
- }
-}
-
-impl pe::ImageResourceDirectoryEntry {
- /// Returns true if the entry has a name, rather than an ID.
- pub fn has_name(&self) -> bool {
- self.name_or_id.get(LE) & pe::IMAGE_RESOURCE_NAME_IS_STRING != 0
- }
-
- /// Returns the section offset of the name.
- ///
- /// Valid if `has_name()` returns true.
- fn name(&self) -> ResourceName {
- let offset = self.name_or_id.get(LE) & !pe::IMAGE_RESOURCE_NAME_IS_STRING;
- ResourceName { offset }
- }
-
- /// Returns the ID.
- ///
- /// Valid if `has_string_name()` returns false.
- fn id(&self) -> u16 {
- (self.name_or_id.get(LE) & 0x0000_FFFF) as u16
- }
-
- /// Returns the entry name
- pub fn name_or_id(&self) -> ResourceNameOrId {
- if self.has_name() {
- ResourceNameOrId::Name(self.name())
- } else {
- ResourceNameOrId::Id(self.id())
- }
- }
-
- /// Returns true if the entry is a subtable.
- pub fn is_table(&self) -> bool {
- self.offset_to_data_or_directory.get(LE) & pe::IMAGE_RESOURCE_DATA_IS_DIRECTORY != 0
- }
-
- /// Returns the section offset of the associated table or data.
- pub fn data_offset(&self) -> u32 {
- self.offset_to_data_or_directory.get(LE) & !pe::IMAGE_RESOURCE_DATA_IS_DIRECTORY
- }
-
- /// Returns the data associated to this directory entry.
- pub fn data<'data>(
- &self,
- section: ResourceDirectory<'data>,
- ) -> Result<ResourceDirectoryEntryData<'data>> {
- if self.is_table() {
- ResourceDirectoryTable::parse(section.data, self.data_offset())
- .map(ResourceDirectoryEntryData::Table)
- } else {
- section
- .data
- .read_at::<pe::ImageResourceDataEntry>(self.data_offset().into())
- .read_error("Invalid resource entry")
- .map(ResourceDirectoryEntryData::Data)
- }
- }
-}
-
-/// Data associated with a resource directory entry.
-#[derive(Debug, Clone)]
-pub enum ResourceDirectoryEntryData<'data> {
- /// A subtable entry.
- Table(ResourceDirectoryTable<'data>),
- /// A resource data entry.
- Data(&'data pe::ImageResourceDataEntry),
-}
-
-impl<'data> ResourceDirectoryEntryData<'data> {
- /// Converts to an option of table.
- ///
- /// Helper for iterator filtering.
- pub fn table(self) -> Option<ResourceDirectoryTable<'data>> {
- match self {
- Self::Table(dir) => Some(dir),
- _ => None,
- }
- }
-
- /// Converts to an option of data entry.
- ///
- /// Helper for iterator filtering.
- pub fn data(self) -> Option<&'data pe::ImageResourceDataEntry> {
- match self {
- Self::Data(rsc) => Some(rsc),
- _ => None,
- }
- }
-}
-
-/// A resource name.
-#[derive(Debug, Clone, Copy)]
-pub struct ResourceName {
- offset: u32,
-}
-
-impl ResourceName {
- /// Converts to a `String`.
- pub fn to_string_lossy(&self, directory: ResourceDirectory<'_>) -> Result<String> {
- let d = self.data(directory)?.iter().map(|c| c.get(LE));
-
- Ok(char::decode_utf16(d)
- .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER))
- .collect::<String>())
- }
-
- /// Returns the string unicode buffer.
- pub fn data<'data>(
- &self,
- directory: ResourceDirectory<'data>,
- ) -> Result<&'data [U16Bytes<LE>]> {
- let mut offset = u64::from(self.offset);
- let len = directory
- .data
- .read::<U16Bytes<LE>>(&mut offset)
- .read_error("Invalid resource name offset")?;
- directory
- .data
- .read_slice::<U16Bytes<LE>>(&mut offset, len.get(LE).into())
- .read_error("Invalid resource name length")
- }
-
- /// Returns the string buffer as raw bytes.
- pub fn raw_data<'data>(&self, directory: ResourceDirectory<'data>) -> Result<&'data [u8]> {
- self.data(directory).map(crate::pod::bytes_of_slice)
- }
-}
-
-/// A resource name or ID.
-///
-/// Can be either a string or a numeric ID.
-#[derive(Debug)]
-pub enum ResourceNameOrId {
- /// A resource name.
- Name(ResourceName),
- /// A resource ID.
- Id(u16),
-}
-
-impl ResourceNameOrId {
- /// Converts to an option of name.
- ///
- /// Helper for iterator filtering.
- pub fn name(self) -> Option<ResourceName> {
- match self {
- Self::Name(name) => Some(name),
- _ => None,
- }
- }
-
- /// Converts to an option of ID.
- ///
- /// Helper for iterator filtering.
- pub fn id(self) -> Option<u16> {
- match self {
- Self::Id(id) => Some(id),
- _ => None,
- }
- }
-}
diff --git a/vendor/object/src/read/pe/rich.rs b/vendor/object/src/read/pe/rich.rs
deleted file mode 100644
index 33dd039..0000000
--- a/vendor/object/src/read/pe/rich.rs
+++ /dev/null
@@ -1,91 +0,0 @@
-//! PE rich header handling
-
-use core::mem;
-
-use crate::pod::bytes_of_slice;
-use crate::read::Bytes;
-use crate::{pe, LittleEndian as LE, ReadRef, U32};
-
-/// Parsed information about a Rich Header.
-#[derive(Debug, Clone, Copy)]
-pub struct RichHeaderInfo<'data> {
- /// The offset at which the rich header starts.
- pub offset: usize,
- /// The length (in bytes) of the rich header.
- ///
- /// This includes the payload, but also the 16-byte start sequence and the
- /// 8-byte final "Rich" and XOR key.
- pub length: usize,
- /// The XOR key used to mask the rich header.
- ///
- /// Unless the file has been tampered with, it should be equal to a checksum
- /// of the file header.
- pub xor_key: u32,
- masked_entries: &'data [pe::MaskedRichHeaderEntry],
-}
-
-/// A PE rich header entry after it has been unmasked.
-///
-/// See [`pe::MaskedRichHeaderEntry`].
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct RichHeaderEntry {
- /// ID of the component.
- pub comp_id: u32,
- /// Number of times this component has been used when building this PE.
- pub count: u32,
-}
-
-impl<'data> RichHeaderInfo<'data> {
- /// Try to locate a rich header and its entries in the current PE file.
- pub fn parse<R: ReadRef<'data>>(data: R, nt_header_offset: u64) -> Option<Self> {
- // Locate the rich header, if any.
- // It ends with the "Rich" string and an XOR key, before the NT header.
- let data = data.read_bytes_at(0, nt_header_offset).map(Bytes).ok()?;
- let end_marker_offset = memmem(data.0, b"Rich", 4)?;
- let xor_key = *data.read_at::<U32<LE>>(end_marker_offset + 4).ok()?;
-
- // It starts at the masked "DanS" string and 3 masked zeroes.
- let masked_start_marker = U32::new(LE, 0x536e_6144 ^ xor_key.get(LE));
- let start_header = [masked_start_marker, xor_key, xor_key, xor_key];
- let start_sequence = bytes_of_slice(&start_header);
- let start_marker_offset = memmem(&data.0[..end_marker_offset], start_sequence, 4)?;
-
- // Extract the items between the markers.
- let items_offset = start_marker_offset + start_sequence.len();
- let items_len = end_marker_offset - items_offset;
- let item_count = items_len / mem::size_of::<pe::MaskedRichHeaderEntry>();
- let items = data.read_slice_at(items_offset, item_count).ok()?;
- Some(RichHeaderInfo {
- offset: start_marker_offset,
- // Includes "Rich" marker and the XOR key.
- length: end_marker_offset - start_marker_offset + 8,
- xor_key: xor_key.get(LE),
- masked_entries: items,
- })
- }
-
- /// Returns an iterator over the unmasked entries.
- pub fn unmasked_entries(&self) -> impl Iterator<Item = RichHeaderEntry> + 'data {
- let xor_key = self.xor_key;
- self.masked_entries
- .iter()
- .map(move |entry| RichHeaderEntry {
- comp_id: entry.masked_comp_id.get(LE) ^ xor_key,
- count: entry.masked_count.get(LE) ^ xor_key,
- })
- }
-}
-
-/// Find the offset of the first occurrence of needle in the data.
-///
-/// The offset must have the given alignment.
-fn memmem(data: &[u8], needle: &[u8], align: usize) -> Option<usize> {
- let mut offset = 0;
- loop {
- if data.get(offset..)?.get(..needle.len())? == needle {
- return Some(offset);
- }
- offset += align;
- }
-}
diff --git a/vendor/object/src/read/pe/section.rs b/vendor/object/src/read/pe/section.rs
deleted file mode 100644
index 74c9d7f..0000000
--- a/vendor/object/src/read/pe/section.rs
+++ /dev/null
@@ -1,440 +0,0 @@
-use core::marker::PhantomData;
-use core::{cmp, iter, slice, str};
-
-use crate::endian::LittleEndian as LE;
-use crate::pe;
-use crate::pe::ImageSectionHeader;
-use crate::read::{
- self, CompressedData, CompressedFileRange, ObjectSection, ObjectSegment, ReadError, ReadRef,
- Relocation, Result, SectionFlags, SectionIndex, SectionKind, SegmentFlags,
-};
-
-use super::{ImageNtHeaders, PeFile, SectionTable};
-
-/// An iterator for the loadable sections in a [`PeFile32`](super::PeFile32).
-pub type PeSegmentIterator32<'data, 'file, R = &'data [u8]> =
- PeSegmentIterator<'data, 'file, pe::ImageNtHeaders32, R>;
-/// An iterator for the loadable sections in a [`PeFile64`](super::PeFile64).
-pub type PeSegmentIterator64<'data, 'file, R = &'data [u8]> =
- PeSegmentIterator<'data, 'file, pe::ImageNtHeaders64, R>;
-
-/// An iterator for the loadable sections in a [`PeFile`].
-#[derive(Debug)]
-pub struct PeSegmentIterator<'data, 'file, Pe, R = &'data [u8]>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file PeFile<'data, Pe, R>,
- pub(super) iter: slice::Iter<'data, pe::ImageSectionHeader>,
-}
-
-impl<'data, 'file, Pe, R> Iterator for PeSegmentIterator<'data, 'file, Pe, R>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- type Item = PeSegment<'data, 'file, Pe, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.iter.next().map(|section| PeSegment {
- file: self.file,
- section,
- })
- }
-}
-
-/// A loadable section in a [`PeFile32`](super::PeFile32).
-pub type PeSegment32<'data, 'file, R = &'data [u8]> =
- PeSegment<'data, 'file, pe::ImageNtHeaders32, R>;
-/// A loadable section in a [`PeFile64`](super::PeFile64).
-pub type PeSegment64<'data, 'file, R = &'data [u8]> =
- PeSegment<'data, 'file, pe::ImageNtHeaders64, R>;
-
-/// A loadable section in a [`PeFile`].
-///
-/// Most functionality is provided by the [`ObjectSegment`] trait implementation.
-#[derive(Debug)]
-pub struct PeSegment<'data, 'file, Pe, R = &'data [u8]>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- file: &'file PeFile<'data, Pe, R>,
- section: &'data pe::ImageSectionHeader,
-}
-
-impl<'data, 'file, Pe, R> read::private::Sealed for PeSegment<'data, 'file, Pe, R>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Pe, R> ObjectSegment<'data> for PeSegment<'data, 'file, Pe, R>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- #[inline]
- fn address(&self) -> u64 {
- u64::from(self.section.virtual_address.get(LE)).wrapping_add(self.file.common.image_base)
- }
-
- #[inline]
- fn size(&self) -> u64 {
- u64::from(self.section.virtual_size.get(LE))
- }
-
- #[inline]
- fn align(&self) -> u64 {
- self.file.section_alignment()
- }
-
- #[inline]
- fn file_range(&self) -> (u64, u64) {
- let (offset, size) = self.section.pe_file_range();
- (u64::from(offset), u64::from(size))
- }
-
- fn data(&self) -> Result<&'data [u8]> {
- self.section.pe_data(self.file.data)
- }
-
- fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> {
- Ok(read::util::data_range(
- self.data()?,
- self.address(),
- address,
- size,
- ))
- }
-
- #[inline]
- fn name_bytes(&self) -> Result<Option<&[u8]>> {
- self.section
- .name(self.file.common.symbols.strings())
- .map(Some)
- }
-
- #[inline]
- fn name(&self) -> Result<Option<&str>> {
- let name = self.section.name(self.file.common.symbols.strings())?;
- Ok(Some(
- str::from_utf8(name)
- .ok()
- .read_error("Non UTF-8 PE section name")?,
- ))
- }
-
- #[inline]
- fn flags(&self) -> SegmentFlags {
- let characteristics = self.section.characteristics.get(LE);
- SegmentFlags::Coff { characteristics }
- }
-}
-
-/// An iterator for the sections in a [`PeFile32`](super::PeFile32).
-pub type PeSectionIterator32<'data, 'file, R = &'data [u8]> =
- PeSectionIterator<'data, 'file, pe::ImageNtHeaders32, R>;
-/// An iterator for the sections in a [`PeFile64`](super::PeFile64).
-pub type PeSectionIterator64<'data, 'file, R = &'data [u8]> =
- PeSectionIterator<'data, 'file, pe::ImageNtHeaders64, R>;
-
-/// An iterator for the sections in a [`PeFile`].
-#[derive(Debug)]
-pub struct PeSectionIterator<'data, 'file, Pe, R = &'data [u8]>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file PeFile<'data, Pe, R>,
- pub(super) iter: iter::Enumerate<slice::Iter<'data, pe::ImageSectionHeader>>,
-}
-
-impl<'data, 'file, Pe, R> Iterator for PeSectionIterator<'data, 'file, Pe, R>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- type Item = PeSection<'data, 'file, Pe, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.iter.next().map(|(index, section)| PeSection {
- file: self.file,
- index: SectionIndex(index + 1),
- section,
- })
- }
-}
-
-/// A section in a [`PeFile32`](super::PeFile32).
-pub type PeSection32<'data, 'file, R = &'data [u8]> =
- PeSection<'data, 'file, pe::ImageNtHeaders32, R>;
-/// A section in a [`PeFile64`](super::PeFile64).
-pub type PeSection64<'data, 'file, R = &'data [u8]> =
- PeSection<'data, 'file, pe::ImageNtHeaders64, R>;
-
-/// A section in a [`PeFile`].
-///
-/// Most functionality is provided by the [`ObjectSection`] trait implementation.
-#[derive(Debug)]
-pub struct PeSection<'data, 'file, Pe, R = &'data [u8]>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file PeFile<'data, Pe, R>,
- pub(super) index: SectionIndex,
- pub(super) section: &'data pe::ImageSectionHeader,
-}
-
-impl<'data, 'file, Pe, R> read::private::Sealed for PeSection<'data, 'file, Pe, R>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Pe, R> ObjectSection<'data> for PeSection<'data, 'file, Pe, R>
-where
- Pe: ImageNtHeaders,
- R: ReadRef<'data>,
-{
- type RelocationIterator = PeRelocationIterator<'data, 'file, R>;
-
- #[inline]
- fn index(&self) -> SectionIndex {
- self.index
- }
-
- #[inline]
- fn address(&self) -> u64 {
- u64::from(self.section.virtual_address.get(LE)).wrapping_add(self.file.common.image_base)
- }
-
- #[inline]
- fn size(&self) -> u64 {
- u64::from(self.section.virtual_size.get(LE))
- }
-
- #[inline]
- fn align(&self) -> u64 {
- self.file.section_alignment()
- }
-
- #[inline]
- fn file_range(&self) -> Option<(u64, u64)> {
- let (offset, size) = self.section.pe_file_range();
- if size == 0 {
- None
- } else {
- Some((u64::from(offset), u64::from(size)))
- }
- }
-
- fn data(&self) -> Result<&'data [u8]> {
- self.section.pe_data(self.file.data)
- }
-
- fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> {
- Ok(read::util::data_range(
- self.data()?,
- self.address(),
- address,
- size,
- ))
- }
-
- #[inline]
- fn compressed_file_range(&self) -> Result<CompressedFileRange> {
- Ok(CompressedFileRange::none(self.file_range()))
- }
-
- #[inline]
- fn compressed_data(&self) -> Result<CompressedData<'data>> {
- self.data().map(CompressedData::none)
- }
-
- #[inline]
- fn name_bytes(&self) -> Result<&[u8]> {
- self.section.name(self.file.common.symbols.strings())
- }
-
- #[inline]
- fn name(&self) -> Result<&str> {
- let name = self.name_bytes()?;
- str::from_utf8(name)
- .ok()
- .read_error("Non UTF-8 PE section name")
- }
-
- #[inline]
- fn segment_name_bytes(&self) -> Result<Option<&[u8]>> {
- Ok(None)
- }
-
- #[inline]
- fn segment_name(&self) -> Result<Option<&str>> {
- Ok(None)
- }
-
- #[inline]
- fn kind(&self) -> SectionKind {
- self.section.kind()
- }
-
- fn relocations(&self) -> PeRelocationIterator<'data, 'file, R> {
- PeRelocationIterator(PhantomData)
- }
-
- fn flags(&self) -> SectionFlags {
- SectionFlags::Coff {
- characteristics: self.section.characteristics.get(LE),
- }
- }
-}
-
-impl<'data> SectionTable<'data> {
- /// Return the file offset of the given virtual address, and the size up
- /// to the end of the section containing it.
- ///
- /// Returns `None` if no section contains the address.
- pub fn pe_file_range_at(&self, va: u32) -> Option<(u32, u32)> {
- self.iter().find_map(|section| section.pe_file_range_at(va))
- }
-
- /// Return the data starting at the given virtual address, up to the end of the
- /// section containing it.
- ///
- /// Ignores sections with invalid data.
- ///
- /// Returns `None` if no section contains the address.
- pub fn pe_data_at<R: ReadRef<'data>>(&self, data: R, va: u32) -> Option<&'data [u8]> {
- self.iter().find_map(|section| section.pe_data_at(data, va))
- }
-
- /// Return the data of the section that contains the given virtual address in a PE file.
- ///
- /// Also returns the virtual address of that section.
- ///
- /// Ignores sections with invalid data.
- pub fn pe_data_containing<R: ReadRef<'data>>(
- &self,
- data: R,
- va: u32,
- ) -> Option<(&'data [u8], u32)> {
- self.iter()
- .find_map(|section| section.pe_data_containing(data, va))
- }
-
- /// Return the section that contains a given virtual address.
- pub fn section_containing(&self, va: u32) -> Option<&'data ImageSectionHeader> {
- self.iter().find(|section| section.contains_rva(va))
- }
-}
-
-impl pe::ImageSectionHeader {
- /// Return the offset and size of the section in a PE file.
- ///
- /// The size of the range will be the minimum of the file size and virtual size.
- pub fn pe_file_range(&self) -> (u32, u32) {
- // Pointer and size will be zero for uninitialized data; we don't need to validate this.
- let offset = self.pointer_to_raw_data.get(LE);
- let size = cmp::min(self.virtual_size.get(LE), self.size_of_raw_data.get(LE));
- (offset, size)
- }
-
- /// Return the file offset of the given virtual address, and the remaining size up
- /// to the end of the section.
- ///
- /// Returns `None` if the section does not contain the address.
- pub fn pe_file_range_at(&self, va: u32) -> Option<(u32, u32)> {
- let section_va = self.virtual_address.get(LE);
- let offset = va.checked_sub(section_va)?;
- let (section_offset, section_size) = self.pe_file_range();
- // Address must be within section (and not at its end).
- if offset < section_size {
- Some((section_offset.checked_add(offset)?, section_size - offset))
- } else {
- None
- }
- }
-
- /// Return the virtual address and size of the section.
- pub fn pe_address_range(&self) -> (u32, u32) {
- (self.virtual_address.get(LE), self.virtual_size.get(LE))
- }
-
- /// Return the section data in a PE file.
- ///
- /// The length of the data will be the minimum of the file size and virtual size.
- pub fn pe_data<'data, R: ReadRef<'data>>(&self, data: R) -> Result<&'data [u8]> {
- let (offset, size) = self.pe_file_range();
- data.read_bytes_at(offset.into(), size.into())
- .read_error("Invalid PE section offset or size")
- }
-
- /// Return the data starting at the given virtual address, up to the end of the
- /// section.
- ///
- /// Ignores sections with invalid data.
- ///
- /// Returns `None` if the section does not contain the address.
- pub fn pe_data_at<'data, R: ReadRef<'data>>(&self, data: R, va: u32) -> Option<&'data [u8]> {
- let (offset, size) = self.pe_file_range_at(va)?;
- data.read_bytes_at(offset.into(), size.into()).ok()
- }
-
- /// Tests whether a given RVA is part of this section
- pub fn contains_rva(&self, va: u32) -> bool {
- let section_va = self.virtual_address.get(LE);
- match va.checked_sub(section_va) {
- None => false,
- Some(offset) => {
- // Address must be within section (and not at its end).
- offset < self.virtual_size.get(LE)
- }
- }
- }
-
- /// Return the section data if it contains the given virtual address.
- ///
- /// Also returns the virtual address of that section.
- ///
- /// Ignores sections with invalid data.
- pub fn pe_data_containing<'data, R: ReadRef<'data>>(
- &self,
- data: R,
- va: u32,
- ) -> Option<(&'data [u8], u32)> {
- let section_va = self.virtual_address.get(LE);
- let offset = va.checked_sub(section_va)?;
- let (section_offset, section_size) = self.pe_file_range();
- // Address must be within section (and not at its end).
- if offset < section_size {
- let section_data = data
- .read_bytes_at(section_offset.into(), section_size.into())
- .ok()?;
- Some((section_data, section_va))
- } else {
- None
- }
- }
-}
-
-/// An iterator for the relocations in an [`PeSection`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct PeRelocationIterator<'data, 'file, R = &'data [u8]>(
- PhantomData<(&'data (), &'file (), R)>,
-);
-
-impl<'data, 'file, R> Iterator for PeRelocationIterator<'data, 'file, R> {
- type Item = (u64, Relocation);
-
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
-}
diff --git a/vendor/object/src/read/read_cache.rs b/vendor/object/src/read/read_cache.rs
deleted file mode 100644
index d1377f1..0000000
--- a/vendor/object/src/read/read_cache.rs
+++ /dev/null
@@ -1,178 +0,0 @@
-use core::ops::Range;
-use std::boxed::Box;
-use std::cell::RefCell;
-use std::collections::hash_map::Entry;
-use std::collections::HashMap;
-use std::convert::TryInto;
-use std::io::{Read, Seek, SeekFrom};
-use std::mem;
-use std::vec::Vec;
-
-use crate::read::ReadRef;
-
-/// An implementation of [`ReadRef`] for data in a stream that implements
-/// `Read + Seek`.
-///
-/// Contains a cache of read-only blocks of data, allowing references to
-/// them to be returned. Entries in the cache are never removed.
-/// Entries are keyed on the offset and size of the read.
-/// Currently overlapping reads are considered separate reads.
-#[derive(Debug)]
-pub struct ReadCache<R: Read + Seek> {
- cache: RefCell<ReadCacheInternal<R>>,
-}
-
-#[derive(Debug)]
-struct ReadCacheInternal<R: Read + Seek> {
- read: R,
- bufs: HashMap<(u64, u64), Box<[u8]>>,
- strings: HashMap<(u64, u8), Box<[u8]>>,
-}
-
-impl<R: Read + Seek> ReadCache<R> {
- /// Create an empty `ReadCache` for the given stream.
- pub fn new(read: R) -> Self {
- ReadCache {
- cache: RefCell::new(ReadCacheInternal {
- read,
- bufs: HashMap::new(),
- strings: HashMap::new(),
- }),
- }
- }
-
- /// Return an implementation of `ReadRef` that restricts reads
- /// to the given range of the stream.
- pub fn range(&self, offset: u64, size: u64) -> ReadCacheRange<'_, R> {
- ReadCacheRange {
- r: self,
- offset,
- size,
- }
- }
-
- /// Free buffers used by the cache.
- pub fn clear(&mut self) {
- self.cache.borrow_mut().bufs.clear();
- }
-
- /// Unwrap this `ReadCache<R>`, returning the underlying reader.
- pub fn into_inner(self) -> R {
- self.cache.into_inner().read
- }
-}
-
-impl<'a, R: Read + Seek> ReadRef<'a> for &'a ReadCache<R> {
- fn len(self) -> Result<u64, ()> {
- let cache = &mut *self.cache.borrow_mut();
- cache.read.seek(SeekFrom::End(0)).map_err(|_| ())
- }
-
- fn read_bytes_at(self, offset: u64, size: u64) -> Result<&'a [u8], ()> {
- if size == 0 {
- return Ok(&[]);
- }
- let cache = &mut *self.cache.borrow_mut();
- let buf = match cache.bufs.entry((offset, size)) {
- Entry::Occupied(entry) => entry.into_mut(),
- Entry::Vacant(entry) => {
- let size = size.try_into().map_err(|_| ())?;
- cache.read.seek(SeekFrom::Start(offset)).map_err(|_| ())?;
- let mut bytes = vec![0; size].into_boxed_slice();
- cache.read.read_exact(&mut bytes).map_err(|_| ())?;
- entry.insert(bytes)
- }
- };
- // Extend the lifetime to that of self.
- // This is OK because we never mutate or remove entries.
- Ok(unsafe { mem::transmute::<&[u8], &[u8]>(buf) })
- }
-
- fn read_bytes_at_until(self, range: Range<u64>, delimiter: u8) -> Result<&'a [u8], ()> {
- let cache = &mut *self.cache.borrow_mut();
- let buf = match cache.strings.entry((range.start, delimiter)) {
- Entry::Occupied(entry) => entry.into_mut(),
- Entry::Vacant(entry) => {
- cache
- .read
- .seek(SeekFrom::Start(range.start))
- .map_err(|_| ())?;
-
- let max_check: usize = (range.end - range.start).try_into().map_err(|_| ())?;
- // Strings should be relatively small.
- // TODO: make this configurable?
- let max_check = max_check.min(4096);
-
- let mut bytes = Vec::new();
- let mut checked = 0;
- loop {
- bytes.resize((checked + 256).min(max_check), 0);
- let read = cache.read.read(&mut bytes[checked..]).map_err(|_| ())?;
- if read == 0 {
- return Err(());
- }
- if let Some(len) = memchr::memchr(delimiter, &bytes[checked..][..read]) {
- bytes.truncate(checked + len);
- break entry.insert(bytes.into_boxed_slice());
- }
- checked += read;
- if checked >= max_check {
- return Err(());
- }
- }
- }
- };
- // Extend the lifetime to that of self.
- // This is OK because we never mutate or remove entries.
- Ok(unsafe { mem::transmute::<&[u8], &[u8]>(buf) })
- }
-}
-
-/// An implementation of [`ReadRef`] for a range of data in a stream that
-/// implements `Read + Seek`.
-///
-/// Shares an underlying `ReadCache` with a lifetime of `'a`.
-#[derive(Debug)]
-pub struct ReadCacheRange<'a, R: Read + Seek> {
- r: &'a ReadCache<R>,
- offset: u64,
- size: u64,
-}
-
-impl<'a, R: Read + Seek> Clone for ReadCacheRange<'a, R> {
- fn clone(&self) -> Self {
- *self
- }
-}
-
-impl<'a, R: Read + Seek> Copy for ReadCacheRange<'a, R> {}
-
-impl<'a, R: Read + Seek> ReadRef<'a> for ReadCacheRange<'a, R> {
- fn len(self) -> Result<u64, ()> {
- Ok(self.size)
- }
-
- fn read_bytes_at(self, offset: u64, size: u64) -> Result<&'a [u8], ()> {
- if size == 0 {
- return Ok(&[]);
- }
- let end = offset.checked_add(size).ok_or(())?;
- if end > self.size {
- return Err(());
- }
- let r_offset = self.offset.checked_add(offset).ok_or(())?;
- self.r.read_bytes_at(r_offset, size)
- }
-
- fn read_bytes_at_until(self, range: Range<u64>, delimiter: u8) -> Result<&'a [u8], ()> {
- let r_start = self.offset.checked_add(range.start).ok_or(())?;
- let r_end = self.offset.checked_add(range.end).ok_or(())?;
- let bytes = self.r.read_bytes_at_until(r_start..r_end, delimiter)?;
- let size = bytes.len().try_into().map_err(|_| ())?;
- let end = range.start.checked_add(size).ok_or(())?;
- if end > self.size {
- return Err(());
- }
- Ok(bytes)
- }
-}
diff --git a/vendor/object/src/read/read_ref.rs b/vendor/object/src/read/read_ref.rs
deleted file mode 100644
index 8b87cba..0000000
--- a/vendor/object/src/read/read_ref.rs
+++ /dev/null
@@ -1,137 +0,0 @@
-#![allow(clippy::len_without_is_empty)]
-
-use core::convert::TryInto;
-use core::ops::Range;
-use core::{mem, result};
-
-use crate::pod::{from_bytes, slice_from_bytes, Pod};
-
-type Result<T> = result::Result<T, ()>;
-
-/// A trait for reading references to [`Pod`] types from a block of data.
-///
-/// This allows parsers to handle both of these cases:
-/// - the block of data exists in memory, and it is desirable
-/// to use references to this block instead of copying it,
-/// - the block of data exists in storage, and it is desirable
-/// to read on demand to minimize I/O and memory usage.
-///
-/// The methods accept `self` by value because `Self` is expected to behave
-/// similar to a reference: it may be a reference with a lifetime of `'a`,
-/// or it may be a wrapper of a reference.
-///
-/// The `Clone` and `Copy` bounds are for convenience, and since `Self` is
-/// expected to be similar to a reference, these are easily satisfied.
-///
-/// Object file parsers typically use offsets to locate the structures
-/// in the block, and will most commonly use the `*_at` methods to
-/// read a structure at a known offset.
-///
-/// Occasionally file parsers will need to treat the block as a stream,
-/// and so convenience methods are provided that update an offset with
-/// the size that was read.
-//
-// An alternative would be for methods to accept `&mut self` and use a
-// `seek` method instead of the `offset` parameters, but this is less
-// convenient for implementers.
-pub trait ReadRef<'a>: Clone + Copy {
- /// The total size of the block of data.
- fn len(self) -> Result<u64>;
-
- /// Get a reference to a `u8` slice at the given offset.
- ///
- /// Returns an error if offset or size are out of bounds.
- fn read_bytes_at(self, offset: u64, size: u64) -> Result<&'a [u8]>;
-
- /// Get a reference to a delimited `u8` slice which starts at range.start.
- ///
- /// Does not include the delimiter.
- ///
- /// Returns an error if the range is out of bounds or the delimiter is
- /// not found in the range.
- fn read_bytes_at_until(self, range: Range<u64>, delimiter: u8) -> Result<&'a [u8]>;
-
- /// Get a reference to a `u8` slice at the given offset, and update the offset.
- ///
- /// Returns an error if offset or size are out of bounds.
- fn read_bytes(self, offset: &mut u64, size: u64) -> Result<&'a [u8]> {
- let bytes = self.read_bytes_at(*offset, size)?;
- *offset = offset.wrapping_add(size);
- Ok(bytes)
- }
-
- /// Get a reference to a `Pod` type at the given offset, and update the offset.
- ///
- /// Returns an error if offset or size are out of bounds.
- ///
- /// The default implementation uses `read_bytes`, and returns an error if
- /// `read_bytes` does not return bytes with the correct alignment for `T`.
- /// Implementors may want to provide their own implementation that ensures
- /// the alignment can be satisfied. Alternatively, only use this method with
- /// types that do not need alignment (see the `unaligned` feature of this crate).
- fn read<T: Pod>(self, offset: &mut u64) -> Result<&'a T> {
- let size = mem::size_of::<T>().try_into().map_err(|_| ())?;
- let bytes = self.read_bytes(offset, size)?;
- let (t, _) = from_bytes(bytes)?;
- Ok(t)
- }
-
- /// Get a reference to a `Pod` type at the given offset.
- ///
- /// Returns an error if offset or size are out of bounds.
- ///
- /// Also see the `read` method for information regarding alignment of `T`.
- fn read_at<T: Pod>(self, mut offset: u64) -> Result<&'a T> {
- self.read(&mut offset)
- }
-
- /// Get a reference to a slice of a `Pod` type at the given offset, and update the offset.
- ///
- /// Returns an error if offset or size are out of bounds.
- ///
- /// Also see the `read` method for information regarding alignment of `T`.
- fn read_slice<T: Pod>(self, offset: &mut u64, count: usize) -> Result<&'a [T]> {
- let size = count
- .checked_mul(mem::size_of::<T>())
- .ok_or(())?
- .try_into()
- .map_err(|_| ())?;
- let bytes = self.read_bytes(offset, size)?;
- let (t, _) = slice_from_bytes(bytes, count)?;
- Ok(t)
- }
-
- /// Get a reference to a slice of a `Pod` type at the given offset.
- ///
- /// Returns an error if offset or size are out of bounds.
- ///
- /// Also see the `read` method for information regarding alignment of `T`.
- fn read_slice_at<T: Pod>(self, mut offset: u64, count: usize) -> Result<&'a [T]> {
- self.read_slice(&mut offset, count)
- }
-}
-
-impl<'a> ReadRef<'a> for &'a [u8] {
- fn len(self) -> Result<u64> {
- self.len().try_into().map_err(|_| ())
- }
-
- fn read_bytes_at(self, offset: u64, size: u64) -> Result<&'a [u8]> {
- let offset: usize = offset.try_into().map_err(|_| ())?;
- let size: usize = size.try_into().map_err(|_| ())?;
- self.get(offset..).ok_or(())?.get(..size).ok_or(())
- }
-
- fn read_bytes_at_until(self, range: Range<u64>, delimiter: u8) -> Result<&'a [u8]> {
- let start: usize = range.start.try_into().map_err(|_| ())?;
- let end: usize = range.end.try_into().map_err(|_| ())?;
- let bytes = self.get(start..end).ok_or(())?;
- match memchr::memchr(delimiter, bytes) {
- Some(len) => {
- // This will never fail.
- bytes.get(..len).ok_or(())
- }
- None => Err(()),
- }
- }
-}
diff --git a/vendor/object/src/read/traits.rs b/vendor/object/src/read/traits.rs
deleted file mode 100644
index 67105d3..0000000
--- a/vendor/object/src/read/traits.rs
+++ /dev/null
@@ -1,551 +0,0 @@
-use alloc::borrow::Cow;
-use alloc::vec::Vec;
-
-use crate::read::{
- self, Architecture, CodeView, ComdatKind, CompressedData, CompressedFileRange, Export,
- FileFlags, Import, ObjectKind, ObjectMap, Relocation, Result, SectionFlags, SectionIndex,
- SectionKind, SegmentFlags, SubArchitecture, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap,
- SymbolMapName, SymbolScope, SymbolSection,
-};
-use crate::Endianness;
-
-/// An object file.
-///
-/// This is the primary trait for the unified read API.
-pub trait Object<'data: 'file, 'file>: read::private::Sealed {
- /// A loadable segment in the object file.
- type Segment: ObjectSegment<'data>;
-
- /// An iterator for the loadable segments in the object file.
- type SegmentIterator: Iterator<Item = Self::Segment>;
-
- /// A section in the object file.
- type Section: ObjectSection<'data>;
-
- /// An iterator for the sections in the object file.
- type SectionIterator: Iterator<Item = Self::Section>;
-
- /// A COMDAT section group in the object file.
- type Comdat: ObjectComdat<'data>;
-
- /// An iterator for the COMDAT section groups in the object file.
- type ComdatIterator: Iterator<Item = Self::Comdat>;
-
- /// A symbol in the object file.
- type Symbol: ObjectSymbol<'data>;
-
- /// An iterator for symbols in the object file.
- type SymbolIterator: Iterator<Item = Self::Symbol>;
-
- /// A symbol table in the object file.
- type SymbolTable: ObjectSymbolTable<
- 'data,
- Symbol = Self::Symbol,
- SymbolIterator = Self::SymbolIterator,
- >;
-
- /// An iterator for the dynamic relocations in the file.
- ///
- /// The first field in the item tuple is the address
- /// that the relocation applies to.
- type DynamicRelocationIterator: Iterator<Item = (u64, Relocation)>;
-
- /// Get the architecture type of the file.
- fn architecture(&self) -> Architecture;
-
- /// Get the sub-architecture type of the file if known.
- ///
- /// A value of `None` has a range of meanings: the file supports all
- /// sub-architectures, the file does not explicitly specify a
- /// sub-architecture, or the sub-architecture is currently unrecognized.
- fn sub_architecture(&self) -> Option<SubArchitecture> {
- None
- }
-
- /// Get the endianness of the file.
- #[inline]
- fn endianness(&self) -> Endianness {
- if self.is_little_endian() {
- Endianness::Little
- } else {
- Endianness::Big
- }
- }
-
- /// Return true if the file is little endian, false if it is big endian.
- fn is_little_endian(&self) -> bool;
-
- /// Return true if the file can contain 64-bit addresses.
- fn is_64(&self) -> bool;
-
- /// Return the kind of this object.
- fn kind(&self) -> ObjectKind;
-
- /// Get an iterator for the loadable segments in the file.
- ///
- /// For ELF, this is program headers with type [`PT_LOAD`](crate::elf::PT_LOAD).
- /// For Mach-O, this is load commands with type [`LC_SEGMENT`](crate::macho::LC_SEGMENT)
- /// or [`LC_SEGMENT_64`](crate::macho::LC_SEGMENT_64).
- /// For PE, this is all sections.
- fn segments(&'file self) -> Self::SegmentIterator;
-
- /// Get the section named `section_name`, if such a section exists.
- ///
- /// If `section_name` starts with a '.' then it is treated as a system section name,
- /// and is compared using the conventions specific to the object file format. This
- /// includes:
- /// - if ".debug_str_offsets" is requested for a Mach-O object file, then the actual
- /// section name that is searched for is "__debug_str_offs".
- /// - if ".debug_info" is requested for an ELF object file, then
- /// ".zdebug_info" may be returned (and similarly for other debug sections).
- ///
- /// For some object files, multiple segments may contain sections with the same
- /// name. In this case, the first matching section will be used.
- ///
- /// This method skips over sections with invalid names.
- fn section_by_name(&'file self, section_name: &str) -> Option<Self::Section> {
- self.section_by_name_bytes(section_name.as_bytes())
- }
-
- /// Like [`Self::section_by_name`], but allows names that are not UTF-8.
- fn section_by_name_bytes(&'file self, section_name: &[u8]) -> Option<Self::Section>;
-
- /// Get the section at the given index.
- ///
- /// The meaning of the index depends on the object file.
- ///
- /// For some object files, this requires iterating through all sections.
- ///
- /// Returns an error if the index is invalid.
- fn section_by_index(&'file self, index: SectionIndex) -> Result<Self::Section>;
-
- /// Get an iterator for the sections in the file.
- fn sections(&'file self) -> Self::SectionIterator;
-
- /// Get an iterator for the COMDAT section groups in the file.
- fn comdats(&'file self) -> Self::ComdatIterator;
-
- /// Get the debugging symbol table, if any.
- fn symbol_table(&'file self) -> Option<Self::SymbolTable>;
-
- /// Get the debugging symbol at the given index.
- ///
- /// The meaning of the index depends on the object file.
- ///
- /// Returns an error if the index is invalid.
- fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<Self::Symbol>;
-
- /// Get an iterator for the debugging symbols in the file.
- ///
- /// This may skip over symbols that are malformed or unsupported.
- ///
- /// For Mach-O files, this does not include STAB entries.
- fn symbols(&'file self) -> Self::SymbolIterator;
-
- /// Get the symbol named `symbol_name`, if the symbol exists.
- fn symbol_by_name(&'file self, symbol_name: &str) -> Option<Self::Symbol> {
- self.symbol_by_name_bytes(symbol_name.as_bytes())
- }
-
- /// Like [`Self::symbol_by_name`], but allows names that are not UTF-8.
- fn symbol_by_name_bytes(&'file self, symbol_name: &[u8]) -> Option<Self::Symbol> {
- self.symbols()
- .find(|sym| sym.name_bytes() == Ok(symbol_name))
- }
-
- /// Get the dynamic linking symbol table, if any.
- ///
- /// Only ELF has a separate dynamic linking symbol table.
- /// Consider using [`Self::exports`] or [`Self::imports`] instead.
- fn dynamic_symbol_table(&'file self) -> Option<Self::SymbolTable>;
-
- /// Get an iterator for the dynamic linking symbols in the file.
- ///
- /// This may skip over symbols that are malformed or unsupported.
- ///
- /// Only ELF has dynamic linking symbols.
- /// Other file formats will return an empty iterator.
- /// Consider using [`Self::exports`] or [`Self::imports`] instead.
- fn dynamic_symbols(&'file self) -> Self::SymbolIterator;
-
- /// Get the dynamic relocations for this file.
- ///
- /// Symbol indices in these relocations refer to the dynamic symbol table.
- ///
- /// Only ELF has dynamic relocations.
- fn dynamic_relocations(&'file self) -> Option<Self::DynamicRelocationIterator>;
-
- /// Construct a map from addresses to symbol names.
- ///
- /// The map will only contain defined text and data symbols.
- /// The dynamic symbol table will only be used if there are no debugging symbols.
- fn symbol_map(&'file self) -> SymbolMap<SymbolMapName<'data>> {
- let mut symbols = Vec::new();
- if let Some(table) = self.symbol_table().or_else(|| self.dynamic_symbol_table()) {
- // Sometimes symbols share addresses. Collect them all then choose the "best".
- let mut all_symbols = Vec::new();
- for symbol in table.symbols() {
- // Must have an address.
- if !symbol.is_definition() {
- continue;
- }
- // Must have a name.
- let name = match symbol.name() {
- Ok(name) => name,
- _ => continue,
- };
- if name.is_empty() {
- continue;
- }
-
- // Lower is better.
- let mut priority = 0u32;
-
- // Prefer known kind.
- match symbol.kind() {
- SymbolKind::Text | SymbolKind::Data => {}
- SymbolKind::Unknown => priority += 1,
- _ => continue,
- }
- priority *= 2;
-
- // Prefer global visibility.
- priority += match symbol.scope() {
- SymbolScope::Unknown => 3,
- SymbolScope::Compilation => 2,
- SymbolScope::Linkage => 1,
- SymbolScope::Dynamic => 0,
- };
- priority *= 4;
-
- // Prefer later entries (earlier symbol is likely to be less specific).
- let index = !0 - symbol.index().0;
-
- // Tuple is ordered for sort.
- all_symbols.push((symbol.address(), priority, index, name));
- }
- // Unstable sort is okay because tuple includes index.
- all_symbols.sort_unstable();
-
- let mut previous_address = !0;
- for (address, _priority, _index, name) in all_symbols {
- if address != previous_address {
- symbols.push(SymbolMapName::new(address, name));
- previous_address = address;
- }
- }
- }
- SymbolMap::new(symbols)
- }
-
- /// Construct a map from addresses to symbol names and object file names.
- ///
- /// This is derived from Mach-O STAB entries.
- fn object_map(&'file self) -> ObjectMap<'data> {
- ObjectMap::default()
- }
-
- /// Get the imported symbols.
- fn imports(&self) -> Result<Vec<Import<'data>>>;
-
- /// Get the exported symbols that expose both a name and an address.
- ///
- /// Some file formats may provide other kinds of symbols that can be retrieved using
- /// the low level API.
- fn exports(&self) -> Result<Vec<Export<'data>>>;
-
- /// Return true if the file contains DWARF debug information sections, false if not.
- fn has_debug_symbols(&self) -> bool;
-
- /// The UUID from a Mach-O [`LC_UUID`](crate::macho::LC_UUID) load command.
- #[inline]
- fn mach_uuid(&self) -> Result<Option<[u8; 16]>> {
- Ok(None)
- }
-
- /// The build ID from an ELF [`NT_GNU_BUILD_ID`](crate::elf::NT_GNU_BUILD_ID) note.
- #[inline]
- fn build_id(&self) -> Result<Option<&'data [u8]>> {
- Ok(None)
- }
-
- /// The filename and CRC from a `.gnu_debuglink` section.
- #[inline]
- fn gnu_debuglink(&self) -> Result<Option<(&'data [u8], u32)>> {
- Ok(None)
- }
-
- /// The filename and build ID from a `.gnu_debugaltlink` section.
- #[inline]
- fn gnu_debugaltlink(&self) -> Result<Option<(&'data [u8], &'data [u8])>> {
- Ok(None)
- }
-
- /// The filename and GUID from the PE CodeView section.
- #[inline]
- fn pdb_info(&self) -> Result<Option<CodeView<'_>>> {
- Ok(None)
- }
-
- /// Get the base address used for relative virtual addresses.
- ///
- /// Currently this is only non-zero for PE.
- fn relative_address_base(&'file self) -> u64;
-
- /// Get the virtual address of the entry point of the binary.
- fn entry(&'file self) -> u64;
-
- /// File flags that are specific to each file format.
- fn flags(&self) -> FileFlags;
-}
-
-/// A loadable segment in an [`Object`].
-///
-/// This trait is part of the unified read API.
-pub trait ObjectSegment<'data>: read::private::Sealed {
- /// Returns the virtual address of the segment.
- fn address(&self) -> u64;
-
- /// Returns the size of the segment in memory.
- fn size(&self) -> u64;
-
- /// Returns the alignment of the segment in memory.
- fn align(&self) -> u64;
-
- /// Returns the offset and size of the segment in the file.
- fn file_range(&self) -> (u64, u64);
-
- /// Returns a reference to the file contents of the segment.
- ///
- /// The length of this data may be different from the size of the
- /// segment in memory.
- fn data(&self) -> Result<&'data [u8]>;
-
- /// Return the segment data in the given range.
- ///
- /// Returns `Ok(None)` if the segment does not contain the given range.
- fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>>;
-
- /// Returns the name of the segment.
- fn name_bytes(&self) -> Result<Option<&[u8]>>;
-
- /// Returns the name of the segment.
- ///
- /// Returns an error if the name is not UTF-8.
- fn name(&self) -> Result<Option<&str>>;
-
- /// Return the flags of segment.
- fn flags(&self) -> SegmentFlags;
-}
-
-/// A section in an [`Object`].
-///
-/// This trait is part of the unified read API.
-pub trait ObjectSection<'data>: read::private::Sealed {
- /// An iterator for the relocations for a section.
- ///
- /// The first field in the item tuple is the section offset
- /// that the relocation applies to.
- type RelocationIterator: Iterator<Item = (u64, Relocation)>;
-
- /// Returns the section index.
- fn index(&self) -> SectionIndex;
-
- /// Returns the address of the section.
- fn address(&self) -> u64;
-
- /// Returns the size of the section in memory.
- fn size(&self) -> u64;
-
- /// Returns the alignment of the section in memory.
- fn align(&self) -> u64;
-
- /// Returns offset and size of on-disk segment (if any).
- fn file_range(&self) -> Option<(u64, u64)>;
-
- /// Returns the raw contents of the section.
- ///
- /// The length of this data may be different from the size of the
- /// section in memory.
- ///
- /// This does not do any decompression.
- fn data(&self) -> Result<&'data [u8]>;
-
- /// Return the raw contents of the section data in the given range.
- ///
- /// This does not do any decompression.
- ///
- /// Returns `Ok(None)` if the section does not contain the given range.
- fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>>;
-
- /// Returns the potentially compressed file range of the section,
- /// along with information about the compression.
- fn compressed_file_range(&self) -> Result<CompressedFileRange>;
-
- /// Returns the potentially compressed contents of the section,
- /// along with information about the compression.
- fn compressed_data(&self) -> Result<CompressedData<'data>>;
-
- /// Returns the uncompressed contents of the section.
- ///
- /// The length of this data may be different from the size of the
- /// section in memory.
- ///
- /// If no compression is detected, then returns the data unchanged.
- /// Returns `Err` if decompression fails.
- fn uncompressed_data(&self) -> Result<Cow<'data, [u8]>> {
- self.compressed_data()?.decompress()
- }
-
- /// Returns the name of the section.
- fn name_bytes(&self) -> Result<&[u8]>;
-
- /// Returns the name of the section.
- ///
- /// Returns an error if the name is not UTF-8.
- fn name(&self) -> Result<&str>;
-
- /// Returns the name of the segment for this section.
- fn segment_name_bytes(&self) -> Result<Option<&[u8]>>;
-
- /// Returns the name of the segment for this section.
- ///
- /// Returns an error if the name is not UTF-8.
- fn segment_name(&self) -> Result<Option<&str>>;
-
- /// Return the kind of this section.
- fn kind(&self) -> SectionKind;
-
- /// Get the relocations for this section.
- fn relocations(&self) -> Self::RelocationIterator;
-
- /// Section flags that are specific to each file format.
- fn flags(&self) -> SectionFlags;
-}
-
-/// A COMDAT section group in an [`Object`].
-///
-/// This trait is part of the unified read API.
-pub trait ObjectComdat<'data>: read::private::Sealed {
- /// An iterator for the sections in the section group.
- type SectionIterator: Iterator<Item = SectionIndex>;
-
- /// Returns the COMDAT selection kind.
- fn kind(&self) -> ComdatKind;
-
- /// Returns the index of the symbol used for the name of COMDAT section group.
- fn symbol(&self) -> SymbolIndex;
-
- /// Returns the name of the COMDAT section group.
- fn name_bytes(&self) -> Result<&[u8]>;
-
- /// Returns the name of the COMDAT section group.
- ///
- /// Returns an error if the name is not UTF-8.
- fn name(&self) -> Result<&str>;
-
- /// Get the sections in this section group.
- fn sections(&self) -> Self::SectionIterator;
-}
-
-/// A symbol table in an [`Object`].
-///
-/// This trait is part of the unified read API.
-pub trait ObjectSymbolTable<'data>: read::private::Sealed {
- /// A symbol table entry.
- type Symbol: ObjectSymbol<'data>;
-
- /// An iterator for the symbols in a symbol table.
- type SymbolIterator: Iterator<Item = Self::Symbol>;
-
- /// Get an iterator for the symbols in the table.
- ///
- /// This may skip over symbols that are malformed or unsupported.
- fn symbols(&self) -> Self::SymbolIterator;
-
- /// Get the symbol at the given index.
- ///
- /// The meaning of the index depends on the object file.
- ///
- /// Returns an error if the index is invalid.
- fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol>;
-}
-
-/// A symbol table entry in an [`Object`].
-///
-/// This trait is part of the unified read API.
-pub trait ObjectSymbol<'data>: read::private::Sealed {
- /// The index of the symbol.
- fn index(&self) -> SymbolIndex;
-
- /// The name of the symbol.
- fn name_bytes(&self) -> Result<&'data [u8]>;
-
- /// The name of the symbol.
- ///
- /// Returns an error if the name is not UTF-8.
- fn name(&self) -> Result<&'data str>;
-
- /// The address of the symbol. May be zero if the address is unknown.
- fn address(&self) -> u64;
-
- /// The size of the symbol. May be zero if the size is unknown.
- fn size(&self) -> u64;
-
- /// Return the kind of this symbol.
- fn kind(&self) -> SymbolKind;
-
- /// Returns the section where the symbol is defined.
- fn section(&self) -> SymbolSection;
-
- /// Returns the section index for the section containing this symbol.
- ///
- /// May return `None` if the symbol is not defined in a section.
- fn section_index(&self) -> Option<SectionIndex> {
- self.section().index()
- }
-
- /// Return true if the symbol is undefined.
- fn is_undefined(&self) -> bool;
-
- /// Return true if the symbol is a definition of a function or data object
- /// that has a known address.
- ///
- /// This is primarily used to implement [`Object::symbol_map`].
- fn is_definition(&self) -> bool;
-
- /// Return true if the symbol is common data.
- ///
- /// Note: does not check for [`SymbolSection::Section`] with [`SectionKind::Common`].
- fn is_common(&self) -> bool;
-
- /// Return true if the symbol is weak.
- fn is_weak(&self) -> bool;
-
- /// Returns the symbol scope.
- fn scope(&self) -> SymbolScope;
-
- /// Return true if the symbol visible outside of the compilation unit.
- ///
- /// This treats [`SymbolScope::Unknown`] as global.
- fn is_global(&self) -> bool;
-
- /// Return true if the symbol is only visible within the compilation unit.
- fn is_local(&self) -> bool;
-
- /// Symbol flags that are specific to each file format.
- fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex>;
-}
-
-/// An iterator for files that don't have dynamic relocations.
-#[derive(Debug)]
-pub struct NoDynamicRelocationIterator;
-
-impl Iterator for NoDynamicRelocationIterator {
- type Item = (u64, Relocation);
-
- #[inline]
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
-}
diff --git a/vendor/object/src/read/util.rs b/vendor/object/src/read/util.rs
deleted file mode 100644
index 7d85b27..0000000
--- a/vendor/object/src/read/util.rs
+++ /dev/null
@@ -1,425 +0,0 @@
-use alloc::string::String;
-use core::convert::TryInto;
-use core::fmt;
-use core::marker::PhantomData;
-
-use crate::pod::{from_bytes, slice_from_bytes, Pod};
-use crate::ReadRef;
-
-/// A newtype for byte slices.
-///
-/// It has these important features:
-/// - no methods that can panic, such as `Index`
-/// - convenience methods for `Pod` types
-/// - a useful `Debug` implementation
-#[derive(Default, Clone, Copy, PartialEq, Eq)]
-pub struct Bytes<'data>(pub &'data [u8]);
-
-impl<'data> fmt::Debug for Bytes<'data> {
- fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- debug_list_bytes(self.0, fmt)
- }
-}
-
-impl<'data> Bytes<'data> {
- /// Return the length of the byte slice.
- #[inline]
- pub fn len(&self) -> usize {
- self.0.len()
- }
-
- /// Return true if the byte slice is empty.
- #[inline]
- pub fn is_empty(&self) -> bool {
- self.0.is_empty()
- }
-
- /// Skip over the given number of bytes at the start of the byte slice.
- ///
- /// Modifies the byte slice to start after the bytes.
- ///
- /// Returns an error if there are too few bytes.
- #[inline]
- pub fn skip(&mut self, offset: usize) -> Result<(), ()> {
- match self.0.get(offset..) {
- Some(tail) => {
- self.0 = tail;
- Ok(())
- }
- None => {
- self.0 = &[];
- Err(())
- }
- }
- }
-
- /// Return a reference to the given number of bytes at the start of the byte slice.
- ///
- /// Modifies the byte slice to start after the bytes.
- ///
- /// Returns an error if there are too few bytes.
- #[inline]
- pub fn read_bytes(&mut self, count: usize) -> Result<Bytes<'data>, ()> {
- match (self.0.get(..count), self.0.get(count..)) {
- (Some(head), Some(tail)) => {
- self.0 = tail;
- Ok(Bytes(head))
- }
- _ => {
- self.0 = &[];
- Err(())
- }
- }
- }
-
- /// Return a reference to the given number of bytes at the given offset of the byte slice.
- ///
- /// Returns an error if the offset is invalid or there are too few bytes.
- #[inline]
- pub fn read_bytes_at(mut self, offset: usize, count: usize) -> Result<Bytes<'data>, ()> {
- self.skip(offset)?;
- self.read_bytes(count)
- }
-
- /// Return a reference to a `Pod` struct at the start of the byte slice.
- ///
- /// Modifies the byte slice to start after the bytes.
- ///
- /// Returns an error if there are too few bytes or the slice is incorrectly aligned.
- #[inline]
- pub fn read<T: Pod>(&mut self) -> Result<&'data T, ()> {
- match from_bytes(self.0) {
- Ok((value, tail)) => {
- self.0 = tail;
- Ok(value)
- }
- Err(()) => {
- self.0 = &[];
- Err(())
- }
- }
- }
-
- /// Return a reference to a `Pod` struct at the given offset of the byte slice.
- ///
- /// Returns an error if there are too few bytes or the offset is incorrectly aligned.
- #[inline]
- pub fn read_at<T: Pod>(mut self, offset: usize) -> Result<&'data T, ()> {
- self.skip(offset)?;
- self.read()
- }
-
- /// Return a reference to a slice of `Pod` structs at the start of the byte slice.
- ///
- /// Modifies the byte slice to start after the bytes.
- ///
- /// Returns an error if there are too few bytes or the offset is incorrectly aligned.
- #[inline]
- pub fn read_slice<T: Pod>(&mut self, count: usize) -> Result<&'data [T], ()> {
- match slice_from_bytes(self.0, count) {
- Ok((value, tail)) => {
- self.0 = tail;
- Ok(value)
- }
- Err(()) => {
- self.0 = &[];
- Err(())
- }
- }
- }
-
- /// Return a reference to a slice of `Pod` structs at the given offset of the byte slice.
- ///
- /// Returns an error if there are too few bytes or the offset is incorrectly aligned.
- #[inline]
- pub fn read_slice_at<T: Pod>(mut self, offset: usize, count: usize) -> Result<&'data [T], ()> {
- self.skip(offset)?;
- self.read_slice(count)
- }
-
- /// Read a null terminated string.
- ///
- /// Does not assume any encoding.
- /// Reads past the null byte, but doesn't return it.
- #[inline]
- pub fn read_string(&mut self) -> Result<&'data [u8], ()> {
- match memchr::memchr(b'\0', self.0) {
- Some(null) => {
- // These will never fail.
- let bytes = self.read_bytes(null)?;
- self.skip(1)?;
- Ok(bytes.0)
- }
- None => {
- self.0 = &[];
- Err(())
- }
- }
- }
-
- /// Read a null terminated string at an offset.
- ///
- /// Does not assume any encoding. Does not return the null byte.
- #[inline]
- pub fn read_string_at(mut self, offset: usize) -> Result<&'data [u8], ()> {
- self.skip(offset)?;
- self.read_string()
- }
-
- /// Read an unsigned LEB128 number.
- pub fn read_uleb128(&mut self) -> Result<u64, ()> {
- let mut result = 0;
- let mut shift = 0;
-
- loop {
- let byte = *self.read::<u8>()?;
- if shift == 63 && byte != 0x00 && byte != 0x01 {
- return Err(());
- }
- result |= u64::from(byte & 0x7f) << shift;
- shift += 7;
-
- if byte & 0x80 == 0 {
- return Ok(result);
- }
- }
- }
-
- /// Read a signed LEB128 number.
- pub fn read_sleb128(&mut self) -> Result<i64, ()> {
- let mut result = 0;
- let mut shift = 0;
-
- loop {
- let byte = *self.read::<u8>()?;
- if shift == 63 && byte != 0x00 && byte != 0x7f {
- return Err(());
- }
- result |= i64::from(byte & 0x7f) << shift;
- shift += 7;
-
- if byte & 0x80 == 0 {
- if shift < 64 && (byte & 0x40) != 0 {
- // Sign extend the result.
- result |= !0 << shift;
- }
- return Ok(result);
- }
- }
- }
-}
-
-// Only for Debug impl of `Bytes`.
-fn debug_list_bytes(bytes: &[u8], fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut list = fmt.debug_list();
- list.entries(bytes.iter().take(8).copied().map(DebugByte));
- if bytes.len() > 8 {
- list.entry(&DebugLen(bytes.len()));
- }
- list.finish()
-}
-
-struct DebugByte(u8);
-
-impl fmt::Debug for DebugByte {
- fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(fmt, "0x{:02x}", self.0)
- }
-}
-
-struct DebugLen(usize);
-
-impl fmt::Debug for DebugLen {
- fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(fmt, "...; {}", self.0)
- }
-}
-
-/// A newtype for byte strings.
-///
-/// For byte slices that are strings of an unknown encoding.
-///
-/// Provides a `Debug` implementation that interprets the bytes as UTF-8.
-#[derive(Default, Clone, Copy, PartialEq, Eq)]
-pub(crate) struct ByteString<'data>(pub &'data [u8]);
-
-impl<'data> fmt::Debug for ByteString<'data> {
- fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(fmt, "\"{}\"", String::from_utf8_lossy(self.0))
- }
-}
-
-#[allow(dead_code)]
-#[inline]
-pub(crate) fn align(offset: usize, size: usize) -> usize {
- (offset + (size - 1)) & !(size - 1)
-}
-
-#[allow(dead_code)]
-pub(crate) fn data_range(
- data: &[u8],
- data_address: u64,
- range_address: u64,
- size: u64,
-) -> Option<&[u8]> {
- let offset = range_address.checked_sub(data_address)?;
- data.get(offset.try_into().ok()?..)?
- .get(..size.try_into().ok()?)
-}
-
-/// A table of zero-terminated strings.
-///
-/// This is used by most file formats for strings such as section names and symbol names.
-#[derive(Debug, Clone, Copy)]
-pub struct StringTable<'data, R = &'data [u8]>
-where
- R: ReadRef<'data>,
-{
- data: Option<R>,
- start: u64,
- end: u64,
- marker: PhantomData<&'data ()>,
-}
-
-impl<'data, R: ReadRef<'data>> StringTable<'data, R> {
- /// Interpret the given data as a string table.
- pub fn new(data: R, start: u64, end: u64) -> Self {
- StringTable {
- data: Some(data),
- start,
- end,
- marker: PhantomData,
- }
- }
-
- /// Return the string at the given offset.
- pub fn get(&self, offset: u32) -> Result<&'data [u8], ()> {
- match self.data {
- Some(data) => {
- let r_start = self.start.checked_add(offset.into()).ok_or(())?;
- data.read_bytes_at_until(r_start..self.end, 0)
- }
- None => Err(()),
- }
- }
-}
-
-impl<'data, R: ReadRef<'data>> Default for StringTable<'data, R> {
- fn default() -> Self {
- StringTable {
- data: None,
- start: 0,
- end: 0,
- marker: PhantomData,
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::pod::bytes_of;
-
- #[test]
- fn bytes() {
- let x = u32::to_be(0x0123_4567);
- let data = Bytes(bytes_of(&x));
-
- let mut bytes = data;
- assert_eq!(bytes.skip(0), Ok(()));
- assert_eq!(bytes, data);
-
- let mut bytes = data;
- assert_eq!(bytes.skip(4), Ok(()));
- assert_eq!(bytes, Bytes(&[]));
-
- let mut bytes = data;
- assert_eq!(bytes.skip(5), Err(()));
- assert_eq!(bytes, Bytes(&[]));
-
- let mut bytes = data;
- assert_eq!(bytes.read_bytes(0), Ok(Bytes(&[])));
- assert_eq!(bytes, data);
-
- let mut bytes = data;
- assert_eq!(bytes.read_bytes(4), Ok(data));
- assert_eq!(bytes, Bytes(&[]));
-
- let mut bytes = data;
- assert_eq!(bytes.read_bytes(5), Err(()));
- assert_eq!(bytes, Bytes(&[]));
-
- assert_eq!(data.read_bytes_at(0, 0), Ok(Bytes(&[])));
- assert_eq!(data.read_bytes_at(4, 0), Ok(Bytes(&[])));
- assert_eq!(data.read_bytes_at(0, 4), Ok(data));
- assert_eq!(data.read_bytes_at(1, 4), Err(()));
-
- let mut bytes = data;
- assert_eq!(bytes.read::<u16>(), Ok(&u16::to_be(0x0123)));
- assert_eq!(bytes, Bytes(&[0x45, 0x67]));
- assert_eq!(data.read_at::<u16>(2), Ok(&u16::to_be(0x4567)));
- assert_eq!(data.read_at::<u16>(3), Err(()));
- assert_eq!(data.read_at::<u16>(4), Err(()));
-
- let mut bytes = data;
- assert_eq!(bytes.read::<u32>(), Ok(&x));
- assert_eq!(bytes, Bytes(&[]));
-
- let mut bytes = data;
- assert_eq!(bytes.read::<u64>(), Err(()));
- assert_eq!(bytes, Bytes(&[]));
-
- let mut bytes = data;
- assert_eq!(bytes.read_slice::<u8>(0), Ok(&[][..]));
- assert_eq!(bytes, data);
-
- let mut bytes = data;
- assert_eq!(bytes.read_slice::<u8>(4), Ok(data.0));
- assert_eq!(bytes, Bytes(&[]));
-
- let mut bytes = data;
- assert_eq!(bytes.read_slice::<u8>(5), Err(()));
- assert_eq!(bytes, Bytes(&[]));
-
- assert_eq!(data.read_slice_at::<u8>(0, 0), Ok(&[][..]));
- assert_eq!(data.read_slice_at::<u8>(4, 0), Ok(&[][..]));
- assert_eq!(data.read_slice_at::<u8>(0, 4), Ok(data.0));
- assert_eq!(data.read_slice_at::<u8>(1, 4), Err(()));
-
- let data = Bytes(&[0x01, 0x02, 0x00, 0x04]);
-
- let mut bytes = data;
- assert_eq!(bytes.read_string(), Ok(&data.0[..2]));
- assert_eq!(bytes.0, &data.0[3..]);
-
- let mut bytes = data;
- bytes.skip(3).unwrap();
- assert_eq!(bytes.read_string(), Err(()));
- assert_eq!(bytes.0, &[]);
-
- assert_eq!(data.read_string_at(0), Ok(&data.0[..2]));
- assert_eq!(data.read_string_at(1), Ok(&data.0[1..2]));
- assert_eq!(data.read_string_at(2), Ok(&[][..]));
- assert_eq!(data.read_string_at(3), Err(()));
- }
-
- #[test]
- fn bytes_debug() {
- assert_eq!(format!("{:?}", Bytes(&[])), "[]");
- assert_eq!(format!("{:?}", Bytes(&[0x01])), "[0x01]");
- assert_eq!(
- format!(
- "{:?}",
- Bytes(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08])
- ),
- "[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]"
- );
- assert_eq!(
- format!(
- "{:?}",
- Bytes(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09])
- ),
- "[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, ...; 9]"
- );
- }
-}
diff --git a/vendor/object/src/read/wasm.rs b/vendor/object/src/read/wasm.rs
deleted file mode 100644
index 4d034bc..0000000
--- a/vendor/object/src/read/wasm.rs
+++ /dev/null
@@ -1,966 +0,0 @@
-//! Support for reading Wasm files.
-//!
-//! [`WasmFile`] implements the [`Object`] trait for Wasm files.
-use alloc::boxed::Box;
-use alloc::vec::Vec;
-use core::marker::PhantomData;
-use core::ops::Range;
-use core::{slice, str};
-use wasmparser as wp;
-
-use crate::read::{
- self, Architecture, ComdatKind, CompressedData, CompressedFileRange, Error, Export, FileFlags,
- Import, NoDynamicRelocationIterator, Object, ObjectComdat, ObjectKind, ObjectSection,
- ObjectSegment, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Relocation, Result,
- SectionFlags, SectionIndex, SectionKind, SegmentFlags, SymbolFlags, SymbolIndex, SymbolKind,
- SymbolScope, SymbolSection,
-};
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-#[repr(usize)]
-enum SectionId {
- Custom = 0,
- Type = 1,
- Import = 2,
- Function = 3,
- Table = 4,
- Memory = 5,
- Global = 6,
- Export = 7,
- Start = 8,
- Element = 9,
- Code = 10,
- Data = 11,
- DataCount = 12,
-}
-// Update this constant when adding new section id:
-const MAX_SECTION_ID: usize = SectionId::DataCount as usize;
-
-/// A WebAssembly object file.
-#[derive(Debug)]
-pub struct WasmFile<'data, R = &'data [u8]> {
- data: &'data [u8],
- has_memory64: bool,
- // All sections, including custom sections.
- sections: Vec<SectionHeader<'data>>,
- // Indices into `sections` of sections with a non-zero id.
- id_sections: Box<[Option<usize>; MAX_SECTION_ID + 1]>,
- // Whether the file has DWARF information.
- has_debug_symbols: bool,
- // Symbols collected from imports, exports, code and name sections.
- symbols: Vec<WasmSymbolInternal<'data>>,
- // Address of the function body for the entry point.
- entry: u64,
- marker: PhantomData<R>,
-}
-
-#[derive(Debug)]
-struct SectionHeader<'data> {
- id: SectionId,
- range: Range<usize>,
- name: &'data str,
-}
-
-#[derive(Clone)]
-enum LocalFunctionKind {
- Unknown,
- Exported { symbol_ids: Vec<u32> },
- Local { symbol_id: u32 },
-}
-
-impl<T> ReadError<T> for wasmparser::Result<T> {
- fn read_error(self, error: &'static str) -> Result<T> {
- self.map_err(|_| Error(error))
- }
-}
-
-impl<'data, R: ReadRef<'data>> WasmFile<'data, R> {
- /// Parse the raw wasm data.
- pub fn parse(data: R) -> Result<Self> {
- let len = data.len().read_error("Unknown Wasm file size")?;
- let data = data.read_bytes_at(0, len).read_error("Wasm read failed")?;
- let parser = wp::Parser::new(0).parse_all(data);
-
- let mut file = WasmFile {
- data,
- has_memory64: false,
- sections: Vec::new(),
- id_sections: Default::default(),
- has_debug_symbols: false,
- symbols: Vec::new(),
- entry: 0,
- marker: PhantomData,
- };
-
- let mut main_file_symbol = Some(WasmSymbolInternal {
- name: "",
- address: 0,
- size: 0,
- kind: SymbolKind::File,
- section: SymbolSection::None,
- scope: SymbolScope::Compilation,
- });
-
- let mut imported_funcs_count = 0;
- let mut local_func_kinds = Vec::new();
- let mut entry_func_id = None;
- let mut code_range_start = 0;
- let mut code_func_index = 0;
- // One-to-one mapping of globals to their value (if the global is a constant integer).
- let mut global_values = Vec::new();
-
- for payload in parser {
- let payload = payload.read_error("Invalid Wasm section header")?;
-
- match payload {
- wp::Payload::TypeSection(section) => {
- file.add_section(SectionId::Type, section.range(), "");
- }
- wp::Payload::ImportSection(section) => {
- file.add_section(SectionId::Import, section.range(), "");
- let mut last_module_name = None;
-
- for import in section {
- let import = import.read_error("Couldn't read an import item")?;
- let module_name = import.module;
-
- if last_module_name != Some(module_name) {
- file.symbols.push(WasmSymbolInternal {
- name: module_name,
- address: 0,
- size: 0,
- kind: SymbolKind::File,
- section: SymbolSection::None,
- scope: SymbolScope::Dynamic,
- });
- last_module_name = Some(module_name);
- }
-
- let kind = match import.ty {
- wp::TypeRef::Func(_) => {
- imported_funcs_count += 1;
- SymbolKind::Text
- }
- wp::TypeRef::Memory(memory) => {
- file.has_memory64 |= memory.memory64;
- SymbolKind::Data
- }
- wp::TypeRef::Table(_) | wp::TypeRef::Global(_) => SymbolKind::Data,
- wp::TypeRef::Tag(_) => SymbolKind::Unknown,
- };
-
- file.symbols.push(WasmSymbolInternal {
- name: import.name,
- address: 0,
- size: 0,
- kind,
- section: SymbolSection::Undefined,
- scope: SymbolScope::Dynamic,
- });
- }
- }
- wp::Payload::FunctionSection(section) => {
- file.add_section(SectionId::Function, section.range(), "");
- local_func_kinds =
- vec![LocalFunctionKind::Unknown; section.into_iter().count()];
- }
- wp::Payload::TableSection(section) => {
- file.add_section(SectionId::Table, section.range(), "");
- }
- wp::Payload::MemorySection(section) => {
- file.add_section(SectionId::Memory, section.range(), "");
- for memory in section {
- let memory = memory.read_error("Couldn't read a memory item")?;
- file.has_memory64 |= memory.memory64;
- }
- }
- wp::Payload::GlobalSection(section) => {
- file.add_section(SectionId::Global, section.range(), "");
- for global in section {
- let global = global.read_error("Couldn't read a global item")?;
- let mut address = None;
- if !global.ty.mutable {
- // There should be exactly one instruction.
- let init = global.init_expr.get_operators_reader().read();
- address = match init.read_error("Couldn't read a global init expr")? {
- wp::Operator::I32Const { value } => Some(value as u64),
- wp::Operator::I64Const { value } => Some(value as u64),
- _ => None,
- };
- }
- global_values.push(address);
- }
- }
- wp::Payload::ExportSection(section) => {
- file.add_section(SectionId::Export, section.range(), "");
- if let Some(main_file_symbol) = main_file_symbol.take() {
- file.symbols.push(main_file_symbol);
- }
-
- for export in section {
- let export = export.read_error("Couldn't read an export item")?;
-
- let (kind, section_idx) = match export.kind {
- wp::ExternalKind::Func => {
- if let Some(local_func_id) =
- export.index.checked_sub(imported_funcs_count)
- {
- let local_func_kind =
- &mut local_func_kinds[local_func_id as usize];
- if let LocalFunctionKind::Unknown = local_func_kind {
- *local_func_kind = LocalFunctionKind::Exported {
- symbol_ids: Vec::new(),
- };
- }
- let symbol_ids = match local_func_kind {
- LocalFunctionKind::Exported { symbol_ids } => symbol_ids,
- _ => unreachable!(),
- };
- symbol_ids.push(file.symbols.len() as u32);
- }
- (SymbolKind::Text, SectionId::Code)
- }
- wp::ExternalKind::Table
- | wp::ExternalKind::Memory
- | wp::ExternalKind::Global => (SymbolKind::Data, SectionId::Data),
- // TODO
- wp::ExternalKind::Tag => continue,
- };
-
- // Try to guess the symbol address. Rust and C export a global containing
- // the address in linear memory of the symbol.
- let mut address = 0;
- if export.kind == wp::ExternalKind::Global {
- if let Some(&Some(x)) = global_values.get(export.index as usize) {
- address = x;
- }
- }
-
- file.symbols.push(WasmSymbolInternal {
- name: export.name,
- address,
- size: 0,
- kind,
- section: SymbolSection::Section(SectionIndex(section_idx as usize)),
- scope: SymbolScope::Dynamic,
- });
- }
- }
- wp::Payload::StartSection { func, range, .. } => {
- file.add_section(SectionId::Start, range, "");
- entry_func_id = Some(func);
- }
- wp::Payload::ElementSection(section) => {
- file.add_section(SectionId::Element, section.range(), "");
- }
- wp::Payload::CodeSectionStart { range, .. } => {
- code_range_start = range.start;
- file.add_section(SectionId::Code, range, "");
- if let Some(main_file_symbol) = main_file_symbol.take() {
- file.symbols.push(main_file_symbol);
- }
- }
- wp::Payload::CodeSectionEntry(body) => {
- let i = code_func_index;
- code_func_index += 1;
-
- let range = body.range();
-
- let address = range.start as u64 - code_range_start as u64;
- let size = (range.end - range.start) as u64;
-
- if entry_func_id == Some(i as u32) {
- file.entry = address;
- }
-
- let local_func_kind = &mut local_func_kinds[i];
- match local_func_kind {
- LocalFunctionKind::Unknown => {
- *local_func_kind = LocalFunctionKind::Local {
- symbol_id: file.symbols.len() as u32,
- };
- file.symbols.push(WasmSymbolInternal {
- name: "",
- address,
- size,
- kind: SymbolKind::Text,
- section: SymbolSection::Section(SectionIndex(
- SectionId::Code as usize,
- )),
- scope: SymbolScope::Compilation,
- });
- }
- LocalFunctionKind::Exported { symbol_ids } => {
- for symbol_id in core::mem::take(symbol_ids) {
- let export_symbol = &mut file.symbols[symbol_id as usize];
- export_symbol.address = address;
- export_symbol.size = size;
- }
- }
- _ => unreachable!(),
- }
- }
- wp::Payload::DataSection(section) => {
- file.add_section(SectionId::Data, section.range(), "");
- }
- wp::Payload::DataCountSection { range, .. } => {
- file.add_section(SectionId::DataCount, range, "");
- }
- wp::Payload::CustomSection(section) => {
- let name = section.name();
- let size = section.data().len();
- let mut range = section.range();
- range.start = range.end - size;
- file.add_section(SectionId::Custom, range, name);
- if name == "name" {
- for name in
- wp::NameSectionReader::new(section.data(), section.data_offset())
- {
- // TODO: Right now, ill-formed name subsections
- // are silently ignored in order to maintain
- // compatibility with extended name sections, which
- // are not yet supported by the version of
- // `wasmparser` currently used.
- // A better fix would be to update `wasmparser` to
- // the newest version, but this requires
- // a major rewrite of this file.
- if let Ok(wp::Name::Function(name_map)) = name {
- for naming in name_map {
- let naming =
- naming.read_error("Couldn't read a function name")?;
- if let Some(local_index) =
- naming.index.checked_sub(imported_funcs_count)
- {
- if let LocalFunctionKind::Local { symbol_id } =
- local_func_kinds[local_index as usize]
- {
- file.symbols[symbol_id as usize].name = naming.name;
- }
- }
- }
- }
- }
- } else if name.starts_with(".debug_") {
- file.has_debug_symbols = true;
- }
- }
- _ => {}
- }
- }
-
- Ok(file)
- }
-
- fn add_section(&mut self, id: SectionId, range: Range<usize>, name: &'data str) {
- let section = SectionHeader { id, range, name };
- self.id_sections[id as usize] = Some(self.sections.len());
- self.sections.push(section);
- }
-}
-
-impl<'data, R> read::private::Sealed for WasmFile<'data, R> {}
-
-impl<'data, 'file, R: ReadRef<'data>> Object<'data, 'file> for WasmFile<'data, R>
-where
- 'data: 'file,
- R: 'file,
-{
- type Segment = WasmSegment<'data, 'file, R>;
- type SegmentIterator = WasmSegmentIterator<'data, 'file, R>;
- type Section = WasmSection<'data, 'file, R>;
- type SectionIterator = WasmSectionIterator<'data, 'file, R>;
- type Comdat = WasmComdat<'data, 'file, R>;
- type ComdatIterator = WasmComdatIterator<'data, 'file, R>;
- type Symbol = WasmSymbol<'data, 'file>;
- type SymbolIterator = WasmSymbolIterator<'data, 'file>;
- type SymbolTable = WasmSymbolTable<'data, 'file>;
- type DynamicRelocationIterator = NoDynamicRelocationIterator;
-
- #[inline]
- fn architecture(&self) -> Architecture {
- if self.has_memory64 {
- Architecture::Wasm64
- } else {
- Architecture::Wasm32
- }
- }
-
- #[inline]
- fn is_little_endian(&self) -> bool {
- true
- }
-
- #[inline]
- fn is_64(&self) -> bool {
- self.has_memory64
- }
-
- fn kind(&self) -> ObjectKind {
- // TODO: check for `linking` custom section
- ObjectKind::Unknown
- }
-
- fn segments(&'file self) -> Self::SegmentIterator {
- WasmSegmentIterator { file: self }
- }
-
- fn section_by_name_bytes(
- &'file self,
- section_name: &[u8],
- ) -> Option<WasmSection<'data, 'file, R>> {
- self.sections()
- .find(|section| section.name_bytes() == Ok(section_name))
- }
-
- fn section_by_index(&'file self, index: SectionIndex) -> Result<WasmSection<'data, 'file, R>> {
- // TODO: Missing sections should return an empty section.
- let id_section = self
- .id_sections
- .get(index.0)
- .and_then(|x| *x)
- .read_error("Invalid Wasm section index")?;
- let section = self.sections.get(id_section).unwrap();
- Ok(WasmSection {
- file: self,
- section,
- })
- }
-
- fn sections(&'file self) -> Self::SectionIterator {
- WasmSectionIterator {
- file: self,
- sections: self.sections.iter(),
- }
- }
-
- fn comdats(&'file self) -> Self::ComdatIterator {
- WasmComdatIterator { file: self }
- }
-
- #[inline]
- fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<WasmSymbol<'data, 'file>> {
- let symbol = self
- .symbols
- .get(index.0)
- .read_error("Invalid Wasm symbol index")?;
- Ok(WasmSymbol { index, symbol })
- }
-
- fn symbols(&'file self) -> Self::SymbolIterator {
- WasmSymbolIterator {
- symbols: self.symbols.iter().enumerate(),
- }
- }
-
- fn symbol_table(&'file self) -> Option<WasmSymbolTable<'data, 'file>> {
- Some(WasmSymbolTable {
- symbols: &self.symbols,
- })
- }
-
- fn dynamic_symbols(&'file self) -> Self::SymbolIterator {
- WasmSymbolIterator {
- symbols: [].iter().enumerate(),
- }
- }
-
- #[inline]
- fn dynamic_symbol_table(&'file self) -> Option<WasmSymbolTable<'data, 'file>> {
- None
- }
-
- #[inline]
- fn dynamic_relocations(&self) -> Option<NoDynamicRelocationIterator> {
- None
- }
-
- fn imports(&self) -> Result<Vec<Import<'data>>> {
- // TODO: return entries in the import section
- Ok(Vec::new())
- }
-
- fn exports(&self) -> Result<Vec<Export<'data>>> {
- // TODO: return entries in the export section
- Ok(Vec::new())
- }
-
- fn has_debug_symbols(&self) -> bool {
- self.has_debug_symbols
- }
-
- fn relative_address_base(&self) -> u64 {
- 0
- }
-
- #[inline]
- fn entry(&'file self) -> u64 {
- self.entry
- }
-
- #[inline]
- fn flags(&self) -> FileFlags {
- FileFlags::None
- }
-}
-
-/// An iterator for the segments in a [`WasmFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct WasmSegmentIterator<'data, 'file, R = &'data [u8]> {
- #[allow(unused)]
- file: &'file WasmFile<'data, R>,
-}
-
-impl<'data, 'file, R> Iterator for WasmSegmentIterator<'data, 'file, R> {
- type Item = WasmSegment<'data, 'file, R>;
-
- #[inline]
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
-}
-
-/// A segment in a [`WasmFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct WasmSegment<'data, 'file, R = &'data [u8]> {
- #[allow(unused)]
- file: &'file WasmFile<'data, R>,
-}
-
-impl<'data, 'file, R> read::private::Sealed for WasmSegment<'data, 'file, R> {}
-
-impl<'data, 'file, R> ObjectSegment<'data> for WasmSegment<'data, 'file, R> {
- #[inline]
- fn address(&self) -> u64 {
- unreachable!()
- }
-
- #[inline]
- fn size(&self) -> u64 {
- unreachable!()
- }
-
- #[inline]
- fn align(&self) -> u64 {
- unreachable!()
- }
-
- #[inline]
- fn file_range(&self) -> (u64, u64) {
- unreachable!()
- }
-
- fn data(&self) -> Result<&'data [u8]> {
- unreachable!()
- }
-
- fn data_range(&self, _address: u64, _size: u64) -> Result<Option<&'data [u8]>> {
- unreachable!()
- }
-
- #[inline]
- fn name_bytes(&self) -> Result<Option<&[u8]>> {
- unreachable!()
- }
-
- #[inline]
- fn name(&self) -> Result<Option<&str>> {
- unreachable!()
- }
-
- #[inline]
- fn flags(&self) -> SegmentFlags {
- unreachable!()
- }
-}
-
-/// An iterator for the sections in a [`WasmFile`].
-#[derive(Debug)]
-pub struct WasmSectionIterator<'data, 'file, R = &'data [u8]> {
- file: &'file WasmFile<'data, R>,
- sections: slice::Iter<'file, SectionHeader<'data>>,
-}
-
-impl<'data, 'file, R> Iterator for WasmSectionIterator<'data, 'file, R> {
- type Item = WasmSection<'data, 'file, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- let section = self.sections.next()?;
- Some(WasmSection {
- file: self.file,
- section,
- })
- }
-}
-
-/// A section in a [`WasmFile`].
-///
-/// Most functionality is provided by the [`ObjectSection`] trait implementation.
-#[derive(Debug)]
-pub struct WasmSection<'data, 'file, R = &'data [u8]> {
- file: &'file WasmFile<'data, R>,
- section: &'file SectionHeader<'data>,
-}
-
-impl<'data, 'file, R> read::private::Sealed for WasmSection<'data, 'file, R> {}
-
-impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for WasmSection<'data, 'file, R> {
- type RelocationIterator = WasmRelocationIterator<'data, 'file, R>;
-
- #[inline]
- fn index(&self) -> SectionIndex {
- // Note that we treat all custom sections as index 0.
- // This is ok because they are never looked up by index.
- SectionIndex(self.section.id as usize)
- }
-
- #[inline]
- fn address(&self) -> u64 {
- 0
- }
-
- #[inline]
- fn size(&self) -> u64 {
- let range = &self.section.range;
- (range.end - range.start) as u64
- }
-
- #[inline]
- fn align(&self) -> u64 {
- 1
- }
-
- #[inline]
- fn file_range(&self) -> Option<(u64, u64)> {
- let range = &self.section.range;
- Some((range.start as _, range.end as _))
- }
-
- #[inline]
- fn data(&self) -> Result<&'data [u8]> {
- let range = &self.section.range;
- self.file
- .data
- .read_bytes_at(range.start as u64, range.end as u64 - range.start as u64)
- .read_error("Invalid Wasm section size or offset")
- }
-
- fn data_range(&self, _address: u64, _size: u64) -> Result<Option<&'data [u8]>> {
- unimplemented!()
- }
-
- #[inline]
- fn compressed_file_range(&self) -> Result<CompressedFileRange> {
- Ok(CompressedFileRange::none(self.file_range()))
- }
-
- #[inline]
- fn compressed_data(&self) -> Result<CompressedData<'data>> {
- self.data().map(CompressedData::none)
- }
-
- #[inline]
- fn name_bytes(&self) -> Result<&[u8]> {
- self.name().map(str::as_bytes)
- }
-
- #[inline]
- fn name(&self) -> Result<&str> {
- Ok(match self.section.id {
- SectionId::Custom => self.section.name,
- SectionId::Type => "<type>",
- SectionId::Import => "<import>",
- SectionId::Function => "<function>",
- SectionId::Table => "<table>",
- SectionId::Memory => "<memory>",
- SectionId::Global => "<global>",
- SectionId::Export => "<export>",
- SectionId::Start => "<start>",
- SectionId::Element => "<element>",
- SectionId::Code => "<code>",
- SectionId::Data => "<data>",
- SectionId::DataCount => "<data_count>",
- })
- }
-
- #[inline]
- fn segment_name_bytes(&self) -> Result<Option<&[u8]>> {
- Ok(None)
- }
-
- #[inline]
- fn segment_name(&self) -> Result<Option<&str>> {
- Ok(None)
- }
-
- #[inline]
- fn kind(&self) -> SectionKind {
- match self.section.id {
- SectionId::Custom => match self.section.name {
- "reloc." | "linking" => SectionKind::Linker,
- _ => SectionKind::Other,
- },
- SectionId::Type => SectionKind::Metadata,
- SectionId::Import => SectionKind::Linker,
- SectionId::Function => SectionKind::Metadata,
- SectionId::Table => SectionKind::UninitializedData,
- SectionId::Memory => SectionKind::UninitializedData,
- SectionId::Global => SectionKind::Data,
- SectionId::Export => SectionKind::Linker,
- SectionId::Start => SectionKind::Linker,
- SectionId::Element => SectionKind::Data,
- SectionId::Code => SectionKind::Text,
- SectionId::Data => SectionKind::Data,
- SectionId::DataCount => SectionKind::UninitializedData,
- }
- }
-
- #[inline]
- fn relocations(&self) -> WasmRelocationIterator<'data, 'file, R> {
- WasmRelocationIterator(PhantomData)
- }
-
- #[inline]
- fn flags(&self) -> SectionFlags {
- SectionFlags::None
- }
-}
-
-/// An iterator for the COMDAT section groups in a [`WasmFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct WasmComdatIterator<'data, 'file, R = &'data [u8]> {
- #[allow(unused)]
- file: &'file WasmFile<'data, R>,
-}
-
-impl<'data, 'file, R> Iterator for WasmComdatIterator<'data, 'file, R> {
- type Item = WasmComdat<'data, 'file, R>;
-
- #[inline]
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
-}
-
-/// A COMDAT section group in a [`WasmFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct WasmComdat<'data, 'file, R = &'data [u8]> {
- #[allow(unused)]
- file: &'file WasmFile<'data, R>,
-}
-
-impl<'data, 'file, R> read::private::Sealed for WasmComdat<'data, 'file, R> {}
-
-impl<'data, 'file, R> ObjectComdat<'data> for WasmComdat<'data, 'file, R> {
- type SectionIterator = WasmComdatSectionIterator<'data, 'file, R>;
-
- #[inline]
- fn kind(&self) -> ComdatKind {
- unreachable!();
- }
-
- #[inline]
- fn symbol(&self) -> SymbolIndex {
- unreachable!();
- }
-
- #[inline]
- fn name_bytes(&self) -> Result<&[u8]> {
- unreachable!();
- }
-
- #[inline]
- fn name(&self) -> Result<&str> {
- unreachable!();
- }
-
- #[inline]
- fn sections(&self) -> Self::SectionIterator {
- unreachable!();
- }
-}
-
-/// An iterator for the sections in a COMDAT section group in a [`WasmFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct WasmComdatSectionIterator<'data, 'file, R = &'data [u8]> {
- #[allow(unused)]
- file: &'file WasmFile<'data, R>,
-}
-
-impl<'data, 'file, R> Iterator for WasmComdatSectionIterator<'data, 'file, R> {
- type Item = SectionIndex;
-
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
-}
-
-/// A symbol table in a [`WasmFile`].
-#[derive(Debug)]
-pub struct WasmSymbolTable<'data, 'file> {
- symbols: &'file [WasmSymbolInternal<'data>],
-}
-
-impl<'data, 'file> read::private::Sealed for WasmSymbolTable<'data, 'file> {}
-
-impl<'data, 'file> ObjectSymbolTable<'data> for WasmSymbolTable<'data, 'file> {
- type Symbol = WasmSymbol<'data, 'file>;
- type SymbolIterator = WasmSymbolIterator<'data, 'file>;
-
- fn symbols(&self) -> Self::SymbolIterator {
- WasmSymbolIterator {
- symbols: self.symbols.iter().enumerate(),
- }
- }
-
- fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol> {
- let symbol = self
- .symbols
- .get(index.0)
- .read_error("Invalid Wasm symbol index")?;
- Ok(WasmSymbol { index, symbol })
- }
-}
-
-/// An iterator for the symbols in a [`WasmFile`].
-#[derive(Debug)]
-pub struct WasmSymbolIterator<'data, 'file> {
- symbols: core::iter::Enumerate<slice::Iter<'file, WasmSymbolInternal<'data>>>,
-}
-
-impl<'data, 'file> Iterator for WasmSymbolIterator<'data, 'file> {
- type Item = WasmSymbol<'data, 'file>;
-
- fn next(&mut self) -> Option<Self::Item> {
- let (index, symbol) = self.symbols.next()?;
- Some(WasmSymbol {
- index: SymbolIndex(index),
- symbol,
- })
- }
-}
-
-/// A symbol in a [`WasmFile`].
-///
-/// Most functionality is provided by the [`ObjectSymbol`] trait implementation.
-#[derive(Clone, Copy, Debug)]
-pub struct WasmSymbol<'data, 'file> {
- index: SymbolIndex,
- symbol: &'file WasmSymbolInternal<'data>,
-}
-
-#[derive(Clone, Debug)]
-struct WasmSymbolInternal<'data> {
- name: &'data str,
- address: u64,
- size: u64,
- kind: SymbolKind,
- section: SymbolSection,
- scope: SymbolScope,
-}
-
-impl<'data, 'file> read::private::Sealed for WasmSymbol<'data, 'file> {}
-
-impl<'data, 'file> ObjectSymbol<'data> for WasmSymbol<'data, 'file> {
- #[inline]
- fn index(&self) -> SymbolIndex {
- self.index
- }
-
- #[inline]
- fn name_bytes(&self) -> read::Result<&'data [u8]> {
- Ok(self.symbol.name.as_bytes())
- }
-
- #[inline]
- fn name(&self) -> read::Result<&'data str> {
- Ok(self.symbol.name)
- }
-
- #[inline]
- fn address(&self) -> u64 {
- self.symbol.address
- }
-
- #[inline]
- fn size(&self) -> u64 {
- self.symbol.size
- }
-
- #[inline]
- fn kind(&self) -> SymbolKind {
- self.symbol.kind
- }
-
- #[inline]
- fn section(&self) -> SymbolSection {
- self.symbol.section
- }
-
- #[inline]
- fn is_undefined(&self) -> bool {
- self.symbol.section == SymbolSection::Undefined
- }
-
- #[inline]
- fn is_definition(&self) -> bool {
- (self.symbol.kind == SymbolKind::Text || self.symbol.kind == SymbolKind::Data)
- && self.symbol.section != SymbolSection::Undefined
- }
-
- #[inline]
- fn is_common(&self) -> bool {
- self.symbol.section == SymbolSection::Common
- }
-
- #[inline]
- fn is_weak(&self) -> bool {
- false
- }
-
- #[inline]
- fn scope(&self) -> SymbolScope {
- self.symbol.scope
- }
-
- #[inline]
- fn is_global(&self) -> bool {
- self.symbol.scope != SymbolScope::Compilation
- }
-
- #[inline]
- fn is_local(&self) -> bool {
- self.symbol.scope == SymbolScope::Compilation
- }
-
- #[inline]
- fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> {
- SymbolFlags::None
- }
-}
-
-/// An iterator for the relocations for a [`WasmSection`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct WasmRelocationIterator<'data, 'file, R = &'data [u8]>(
- PhantomData<(&'data (), &'file (), R)>,
-);
-
-impl<'data, 'file, R> Iterator for WasmRelocationIterator<'data, 'file, R> {
- type Item = (u64, Relocation);
-
- #[inline]
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
-}
diff --git a/vendor/object/src/read/xcoff/comdat.rs b/vendor/object/src/read/xcoff/comdat.rs
deleted file mode 100644
index 03e52bf..0000000
--- a/vendor/object/src/read/xcoff/comdat.rs
+++ /dev/null
@@ -1,135 +0,0 @@
-//! XCOFF doesn't support the COMDAT section.
-
-use core::fmt::Debug;
-
-use crate::xcoff;
-
-use crate::read::{self, ComdatKind, ObjectComdat, ReadRef, Result, SectionIndex, SymbolIndex};
-
-use super::{FileHeader, XcoffFile};
-
-/// An iterator for the COMDAT section groups in a [`XcoffFile32`](super::XcoffFile32).
-pub type XcoffComdatIterator32<'data, 'file, R = &'data [u8]> =
- XcoffComdatIterator<'data, 'file, xcoff::FileHeader32, R>;
-/// An iterator for the COMDAT section groups in a [`XcoffFile64`](super::XcoffFile64).
-pub type XcoffComdatIterator64<'data, 'file, R = &'data [u8]> =
- XcoffComdatIterator<'data, 'file, xcoff::FileHeader64, R>;
-
-/// An iterator for the COMDAT section groups in a [`XcoffFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct XcoffComdatIterator<'data, 'file, Xcoff, R = &'data [u8]>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- #[allow(unused)]
- pub(crate) file: &'file XcoffFile<'data, Xcoff, R>,
-}
-
-impl<'data, 'file, Xcoff, R> Iterator for XcoffComdatIterator<'data, 'file, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- type Item = XcoffComdat<'data, 'file, Xcoff, R>;
-
- #[inline]
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
-}
-
-/// A COMDAT section group in a [`XcoffFile32`](super::XcoffFile32).
-pub type XcoffComdat32<'data, 'file, R = &'data [u8]> =
- XcoffComdat<'data, 'file, xcoff::FileHeader32, R>;
-
-/// A COMDAT section group in a [`XcoffFile64`](super::XcoffFile64).
-pub type XcoffComdat64<'data, 'file, R = &'data [u8]> =
- XcoffComdat<'data, 'file, xcoff::FileHeader64, R>;
-
-/// A COMDAT section group in a [`XcoffFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct XcoffComdat<'data, 'file, Xcoff, R = &'data [u8]>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- #[allow(unused)]
- file: &'file XcoffFile<'data, Xcoff, R>,
-}
-
-impl<'data, 'file, Xcoff, R> read::private::Sealed for XcoffComdat<'data, 'file, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Xcoff, R> ObjectComdat<'data> for XcoffComdat<'data, 'file, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- type SectionIterator = XcoffComdatSectionIterator<'data, 'file, Xcoff, R>;
-
- #[inline]
- fn kind(&self) -> ComdatKind {
- unreachable!();
- }
-
- #[inline]
- fn symbol(&self) -> SymbolIndex {
- unreachable!();
- }
-
- #[inline]
- fn name_bytes(&self) -> Result<&[u8]> {
- unreachable!();
- }
-
- #[inline]
- fn name(&self) -> Result<&str> {
- unreachable!();
- }
-
- #[inline]
- fn sections(&self) -> Self::SectionIterator {
- unreachable!();
- }
-}
-
-/// An iterator for the sections in a COMDAT section group in a [`XcoffFile32`](super::XcoffFile32).
-pub type XcoffComdatSectionIterator32<'data, 'file, R = &'data [u8]> =
- XcoffComdatSectionIterator<'data, 'file, xcoff::FileHeader32, R>;
-/// An iterator for the sections in a COMDAT section group in a [`XcoffFile64`](super::XcoffFile64).
-pub type XcoffComdatSectionIterator64<'data, 'file, R = &'data [u8]> =
- XcoffComdatSectionIterator<'data, 'file, xcoff::FileHeader64, R>;
-
-/// An iterator for the sections in a COMDAT section group in a [`XcoffFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct XcoffComdatSectionIterator<'data, 'file, Xcoff, R = &'data [u8]>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- #[allow(unused)]
- file: &'file XcoffFile<'data, Xcoff, R>,
-}
-
-impl<'data, 'file, Xcoff, R> Iterator for XcoffComdatSectionIterator<'data, 'file, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- type Item = SectionIndex;
-
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
-}
diff --git a/vendor/object/src/read/xcoff/file.rs b/vendor/object/src/read/xcoff/file.rs
deleted file mode 100644
index 70d980a..0000000
--- a/vendor/object/src/read/xcoff/file.rs
+++ /dev/null
@@ -1,696 +0,0 @@
-use core::fmt::Debug;
-use core::mem;
-
-use alloc::vec::Vec;
-
-use crate::read::{self, Error, NoDynamicRelocationIterator, Object, ReadError, ReadRef, Result};
-
-use crate::{
- xcoff, Architecture, BigEndian as BE, FileFlags, ObjectKind, ObjectSection, Pod, SectionIndex,
- SymbolIndex,
-};
-
-use super::{
- CsectAux, FileAux, SectionHeader, SectionTable, Symbol, SymbolTable, XcoffComdat,
- XcoffComdatIterator, XcoffSection, XcoffSectionIterator, XcoffSegment, XcoffSegmentIterator,
- XcoffSymbol, XcoffSymbolIterator, XcoffSymbolTable,
-};
-
-/// A 32-bit XCOFF object file.
-///
-/// This is a file that starts with [`xcoff::FileHeader32`], and corresponds
-/// to [`crate::FileKind::Xcoff32`].
-pub type XcoffFile32<'data, R = &'data [u8]> = XcoffFile<'data, xcoff::FileHeader32, R>;
-/// A 64-bit XCOFF object file.
-///
-/// This is a file that starts with [`xcoff::FileHeader64`], and corresponds
-/// to [`crate::FileKind::Xcoff64`].
-pub type XcoffFile64<'data, R = &'data [u8]> = XcoffFile<'data, xcoff::FileHeader64, R>;
-
-/// A partially parsed XCOFF file.
-///
-/// Most functionality is provided by the [`Object`] trait implementation.
-#[derive(Debug)]
-pub struct XcoffFile<'data, Xcoff, R = &'data [u8]>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) data: R,
- pub(super) header: &'data Xcoff,
- pub(super) aux_header: Option<&'data Xcoff::AuxHeader>,
- pub(super) sections: SectionTable<'data, Xcoff>,
- pub(super) symbols: SymbolTable<'data, Xcoff, R>,
-}
-
-impl<'data, Xcoff, R> XcoffFile<'data, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- /// Parse the raw XCOFF file data.
- pub fn parse(data: R) -> Result<Self> {
- let mut offset = 0;
- let header = Xcoff::parse(data, &mut offset)?;
- let aux_header = header.aux_header(data, &mut offset)?;
- let sections = header.sections(data, &mut offset)?;
- let symbols = header.symbols(data)?;
-
- Ok(XcoffFile {
- data,
- header,
- aux_header,
- sections,
- symbols,
- })
- }
-
- /// Returns the raw data.
- pub fn data(&self) -> R {
- self.data
- }
-
- /// Returns the raw XCOFF file header.
- pub fn raw_header(&self) -> &'data Xcoff {
- self.header
- }
-}
-
-impl<'data, Xcoff, R> read::private::Sealed for XcoffFile<'data, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Xcoff, R> Object<'data, 'file> for XcoffFile<'data, Xcoff, R>
-where
- 'data: 'file,
- Xcoff: FileHeader,
- R: 'file + ReadRef<'data>,
-{
- type Segment = XcoffSegment<'data, 'file, Xcoff, R>;
- type SegmentIterator = XcoffSegmentIterator<'data, 'file, Xcoff, R>;
- type Section = XcoffSection<'data, 'file, Xcoff, R>;
- type SectionIterator = XcoffSectionIterator<'data, 'file, Xcoff, R>;
- type Comdat = XcoffComdat<'data, 'file, Xcoff, R>;
- type ComdatIterator = XcoffComdatIterator<'data, 'file, Xcoff, R>;
- type Symbol = XcoffSymbol<'data, 'file, Xcoff, R>;
- type SymbolIterator = XcoffSymbolIterator<'data, 'file, Xcoff, R>;
- type SymbolTable = XcoffSymbolTable<'data, 'file, Xcoff, R>;
- type DynamicRelocationIterator = NoDynamicRelocationIterator;
-
- fn architecture(&self) -> crate::Architecture {
- if self.is_64() {
- Architecture::PowerPc64
- } else {
- Architecture::PowerPc
- }
- }
-
- fn is_little_endian(&self) -> bool {
- false
- }
-
- fn is_64(&self) -> bool {
- self.header.is_type_64()
- }
-
- fn kind(&self) -> ObjectKind {
- let flags = self.header.f_flags();
- if flags & xcoff::F_EXEC != 0 {
- ObjectKind::Executable
- } else if flags & xcoff::F_SHROBJ != 0 {
- ObjectKind::Dynamic
- } else if flags & xcoff::F_RELFLG == 0 {
- ObjectKind::Relocatable
- } else {
- ObjectKind::Unknown
- }
- }
-
- fn segments(&'file self) -> XcoffSegmentIterator<'data, 'file, Xcoff, R> {
- XcoffSegmentIterator { file: self }
- }
-
- fn section_by_name_bytes(
- &'file self,
- section_name: &[u8],
- ) -> Option<XcoffSection<'data, 'file, Xcoff, R>> {
- self.sections()
- .find(|section| section.name_bytes() == Ok(section_name))
- }
-
- fn section_by_index(
- &'file self,
- index: SectionIndex,
- ) -> Result<XcoffSection<'data, 'file, Xcoff, R>> {
- let section = self.sections.section(index)?;
- Ok(XcoffSection {
- file: self,
- section,
- index,
- })
- }
-
- fn sections(&'file self) -> XcoffSectionIterator<'data, 'file, Xcoff, R> {
- XcoffSectionIterator {
- file: self,
- iter: self.sections.iter().enumerate(),
- }
- }
-
- fn comdats(&'file self) -> XcoffComdatIterator<'data, 'file, Xcoff, R> {
- XcoffComdatIterator { file: self }
- }
-
- fn symbol_table(&'file self) -> Option<XcoffSymbolTable<'data, 'file, Xcoff, R>> {
- if self.symbols.is_empty() {
- return None;
- }
- Some(XcoffSymbolTable {
- symbols: &self.symbols,
- file: self,
- })
- }
-
- fn symbol_by_index(
- &'file self,
- index: SymbolIndex,
- ) -> Result<XcoffSymbol<'data, 'file, Xcoff, R>> {
- let symbol = self.symbols.symbol(index.0)?;
- Ok(XcoffSymbol {
- symbols: &self.symbols,
- index,
- symbol,
- file: self,
- })
- }
-
- fn symbols(&'file self) -> XcoffSymbolIterator<'data, 'file, Xcoff, R> {
- XcoffSymbolIterator {
- file: self,
- symbols: self.symbols.iter(),
- }
- }
-
- fn dynamic_symbol_table(&'file self) -> Option<XcoffSymbolTable<'data, 'file, Xcoff, R>> {
- None
- }
-
- fn dynamic_symbols(&'file self) -> XcoffSymbolIterator<'data, 'file, Xcoff, R> {
- // TODO: return the symbols in the STYP_LOADER section.
- XcoffSymbolIterator {
- file: self,
- symbols: self.symbols.iter_none(),
- }
- }
-
- fn dynamic_relocations(&'file self) -> Option<Self::DynamicRelocationIterator> {
- // TODO: return the relocations in the STYP_LOADER section.
- None
- }
-
- fn imports(&self) -> Result<alloc::vec::Vec<crate::Import<'data>>> {
- // TODO: return the imports in the STYP_LOADER section.
- Ok(Vec::new())
- }
-
- fn exports(&self) -> Result<alloc::vec::Vec<crate::Export<'data>>> {
- // TODO: return the exports in the STYP_LOADER section.
- Ok(Vec::new())
- }
-
- fn has_debug_symbols(&self) -> bool {
- self.section_by_name(".debug").is_some() || self.section_by_name(".dwinfo").is_some()
- }
-
- fn relative_address_base(&'file self) -> u64 {
- 0
- }
-
- fn entry(&'file self) -> u64 {
- if let Some(aux_header) = self.aux_header {
- aux_header.o_entry().into()
- } else {
- 0
- }
- }
-
- fn flags(&self) -> FileFlags {
- FileFlags::Xcoff {
- f_flags: self.header.f_flags(),
- }
- }
-}
-
-/// A trait for generic access to [`xcoff::FileHeader32`] and [`xcoff::FileHeader64`].
-#[allow(missing_docs)]
-pub trait FileHeader: Debug + Pod {
- type Word: Into<u64>;
- type AuxHeader: AuxHeader<Word = Self::Word>;
- type SectionHeader: SectionHeader<Word = Self::Word>;
- type Symbol: Symbol<Word = Self::Word>;
- type FileAux: FileAux;
- type CsectAux: CsectAux;
-
- /// Return true if this type is a 64-bit header.
- fn is_type_64(&self) -> bool;
-
- fn f_magic(&self) -> u16;
- fn f_nscns(&self) -> u16;
- fn f_timdat(&self) -> u32;
- fn f_symptr(&self) -> Self::Word;
- fn f_nsyms(&self) -> u32;
- fn f_opthdr(&self) -> u16;
- fn f_flags(&self) -> u16;
-
- // Provided methods.
-
- /// Read the file header.
- ///
- /// Also checks that the magic field in the file header is a supported format.
- fn parse<'data, R: ReadRef<'data>>(data: R, offset: &mut u64) -> Result<&'data Self> {
- let header = data
- .read::<Self>(offset)
- .read_error("Invalid XCOFF header size or alignment")?;
- if !header.is_supported() {
- return Err(Error("Unsupported XCOFF header"));
- }
- Ok(header)
- }
-
- fn is_supported(&self) -> bool {
- (self.is_type_64() && self.f_magic() == xcoff::MAGIC_64)
- || (!self.is_type_64() && self.f_magic() == xcoff::MAGIC_32)
- }
-
- /// Read the auxiliary file header.
- fn aux_header<'data, R: ReadRef<'data>>(
- &self,
- data: R,
- offset: &mut u64,
- ) -> Result<Option<&'data Self::AuxHeader>> {
- let aux_header_size = self.f_opthdr();
- if self.f_flags() & xcoff::F_EXEC == 0 {
- // No auxiliary header is required for an object file that is not an executable.
- // TODO: Some AIX programs generate auxiliary headers for 32-bit object files
- // that end after the data_start field.
- *offset += u64::from(aux_header_size);
- return Ok(None);
- }
- // Executables, however, must have auxiliary headers that include the
- // full structure definitions.
- if aux_header_size != mem::size_of::<Self::AuxHeader>() as u16 {
- *offset += u64::from(aux_header_size);
- return Ok(None);
- }
- let aux_header = data
- .read::<Self::AuxHeader>(offset)
- .read_error("Invalid XCOFF auxiliary header size")?;
- Ok(Some(aux_header))
- }
-
- /// Read the section table.
- #[inline]
- fn sections<'data, R: ReadRef<'data>>(
- &self,
- data: R,
- offset: &mut u64,
- ) -> Result<SectionTable<'data, Self>> {
- SectionTable::parse(self, data, offset)
- }
-
- /// Return the symbol table.
- #[inline]
- fn symbols<'data, R: ReadRef<'data>>(&self, data: R) -> Result<SymbolTable<'data, Self, R>> {
- SymbolTable::parse(*self, data)
- }
-}
-
-impl FileHeader for xcoff::FileHeader32 {
- type Word = u32;
- type AuxHeader = xcoff::AuxHeader32;
- type SectionHeader = xcoff::SectionHeader32;
- type Symbol = xcoff::Symbol32;
- type FileAux = xcoff::FileAux32;
- type CsectAux = xcoff::CsectAux32;
-
- fn is_type_64(&self) -> bool {
- false
- }
-
- fn f_magic(&self) -> u16 {
- self.f_magic.get(BE)
- }
-
- fn f_nscns(&self) -> u16 {
- self.f_nscns.get(BE)
- }
-
- fn f_timdat(&self) -> u32 {
- self.f_timdat.get(BE)
- }
-
- fn f_symptr(&self) -> Self::Word {
- self.f_symptr.get(BE)
- }
-
- fn f_nsyms(&self) -> u32 {
- self.f_nsyms.get(BE)
- }
-
- fn f_opthdr(&self) -> u16 {
- self.f_opthdr.get(BE)
- }
-
- fn f_flags(&self) -> u16 {
- self.f_flags.get(BE)
- }
-}
-
-impl FileHeader for xcoff::FileHeader64 {
- type Word = u64;
- type AuxHeader = xcoff::AuxHeader64;
- type SectionHeader = xcoff::SectionHeader64;
- type Symbol = xcoff::Symbol64;
- type FileAux = xcoff::FileAux64;
- type CsectAux = xcoff::CsectAux64;
-
- fn is_type_64(&self) -> bool {
- true
- }
-
- fn f_magic(&self) -> u16 {
- self.f_magic.get(BE)
- }
-
- fn f_nscns(&self) -> u16 {
- self.f_nscns.get(BE)
- }
-
- fn f_timdat(&self) -> u32 {
- self.f_timdat.get(BE)
- }
-
- fn f_symptr(&self) -> Self::Word {
- self.f_symptr.get(BE)
- }
-
- fn f_nsyms(&self) -> u32 {
- self.f_nsyms.get(BE)
- }
-
- fn f_opthdr(&self) -> u16 {
- self.f_opthdr.get(BE)
- }
-
- fn f_flags(&self) -> u16 {
- self.f_flags.get(BE)
- }
-}
-
-/// A trait for generic access to [`xcoff::AuxHeader32`] and [`xcoff::AuxHeader64`].
-#[allow(missing_docs)]
-pub trait AuxHeader: Debug + Pod {
- type Word: Into<u64>;
-
- fn o_mflag(&self) -> u16;
- fn o_vstamp(&self) -> u16;
- fn o_tsize(&self) -> Self::Word;
- fn o_dsize(&self) -> Self::Word;
- fn o_bsize(&self) -> Self::Word;
- fn o_entry(&self) -> Self::Word;
- fn o_text_start(&self) -> Self::Word;
- fn o_data_start(&self) -> Self::Word;
- fn o_toc(&self) -> Self::Word;
- fn o_snentry(&self) -> u16;
- fn o_sntext(&self) -> u16;
- fn o_sndata(&self) -> u16;
- fn o_sntoc(&self) -> u16;
- fn o_snloader(&self) -> u16;
- fn o_snbss(&self) -> u16;
- fn o_algntext(&self) -> u16;
- fn o_algndata(&self) -> u16;
- fn o_modtype(&self) -> u16;
- fn o_cpuflag(&self) -> u8;
- fn o_cputype(&self) -> u8;
- fn o_maxstack(&self) -> Self::Word;
- fn o_maxdata(&self) -> Self::Word;
- fn o_debugger(&self) -> u32;
- fn o_textpsize(&self) -> u8;
- fn o_datapsize(&self) -> u8;
- fn o_stackpsize(&self) -> u8;
- fn o_flags(&self) -> u8;
- fn o_sntdata(&self) -> u16;
- fn o_sntbss(&self) -> u16;
- fn o_x64flags(&self) -> Option<u16>;
-}
-
-impl AuxHeader for xcoff::AuxHeader32 {
- type Word = u32;
-
- fn o_mflag(&self) -> u16 {
- self.o_mflag.get(BE)
- }
-
- fn o_vstamp(&self) -> u16 {
- self.o_vstamp.get(BE)
- }
-
- fn o_tsize(&self) -> Self::Word {
- self.o_tsize.get(BE)
- }
-
- fn o_dsize(&self) -> Self::Word {
- self.o_dsize.get(BE)
- }
-
- fn o_bsize(&self) -> Self::Word {
- self.o_bsize.get(BE)
- }
-
- fn o_entry(&self) -> Self::Word {
- self.o_entry.get(BE)
- }
-
- fn o_text_start(&self) -> Self::Word {
- self.o_text_start.get(BE)
- }
-
- fn o_data_start(&self) -> Self::Word {
- self.o_data_start.get(BE)
- }
-
- fn o_toc(&self) -> Self::Word {
- self.o_toc.get(BE)
- }
-
- fn o_snentry(&self) -> u16 {
- self.o_snentry.get(BE)
- }
-
- fn o_sntext(&self) -> u16 {
- self.o_sntext.get(BE)
- }
-
- fn o_sndata(&self) -> u16 {
- self.o_sndata.get(BE)
- }
-
- fn o_sntoc(&self) -> u16 {
- self.o_sntoc.get(BE)
- }
-
- fn o_snloader(&self) -> u16 {
- self.o_snloader.get(BE)
- }
-
- fn o_snbss(&self) -> u16 {
- self.o_snbss.get(BE)
- }
-
- fn o_algntext(&self) -> u16 {
- self.o_algntext.get(BE)
- }
-
- fn o_algndata(&self) -> u16 {
- self.o_algndata.get(BE)
- }
-
- fn o_modtype(&self) -> u16 {
- self.o_modtype.get(BE)
- }
-
- fn o_cpuflag(&self) -> u8 {
- self.o_cpuflag
- }
-
- fn o_cputype(&self) -> u8 {
- self.o_cputype
- }
-
- fn o_maxstack(&self) -> Self::Word {
- self.o_maxstack.get(BE)
- }
-
- fn o_maxdata(&self) -> Self::Word {
- self.o_maxdata.get(BE)
- }
-
- fn o_debugger(&self) -> u32 {
- self.o_debugger.get(BE)
- }
-
- fn o_textpsize(&self) -> u8 {
- self.o_textpsize
- }
-
- fn o_datapsize(&self) -> u8 {
- self.o_datapsize
- }
-
- fn o_stackpsize(&self) -> u8 {
- self.o_stackpsize
- }
-
- fn o_flags(&self) -> u8 {
- self.o_flags
- }
-
- fn o_sntdata(&self) -> u16 {
- self.o_sntdata.get(BE)
- }
-
- fn o_sntbss(&self) -> u16 {
- self.o_sntbss.get(BE)
- }
-
- fn o_x64flags(&self) -> Option<u16> {
- None
- }
-}
-
-impl AuxHeader for xcoff::AuxHeader64 {
- type Word = u64;
-
- fn o_mflag(&self) -> u16 {
- self.o_mflag.get(BE)
- }
-
- fn o_vstamp(&self) -> u16 {
- self.o_vstamp.get(BE)
- }
-
- fn o_tsize(&self) -> Self::Word {
- self.o_tsize.get(BE)
- }
-
- fn o_dsize(&self) -> Self::Word {
- self.o_dsize.get(BE)
- }
-
- fn o_bsize(&self) -> Self::Word {
- self.o_bsize.get(BE)
- }
-
- fn o_entry(&self) -> Self::Word {
- self.o_entry.get(BE)
- }
-
- fn o_text_start(&self) -> Self::Word {
- self.o_text_start.get(BE)
- }
-
- fn o_data_start(&self) -> Self::Word {
- self.o_data_start.get(BE)
- }
-
- fn o_toc(&self) -> Self::Word {
- self.o_toc.get(BE)
- }
-
- fn o_snentry(&self) -> u16 {
- self.o_snentry.get(BE)
- }
-
- fn o_sntext(&self) -> u16 {
- self.o_sntext.get(BE)
- }
-
- fn o_sndata(&self) -> u16 {
- self.o_sndata.get(BE)
- }
-
- fn o_sntoc(&self) -> u16 {
- self.o_sntoc.get(BE)
- }
-
- fn o_snloader(&self) -> u16 {
- self.o_snloader.get(BE)
- }
-
- fn o_snbss(&self) -> u16 {
- self.o_snbss.get(BE)
- }
-
- fn o_algntext(&self) -> u16 {
- self.o_algntext.get(BE)
- }
-
- fn o_algndata(&self) -> u16 {
- self.o_algndata.get(BE)
- }
-
- fn o_modtype(&self) -> u16 {
- self.o_modtype.get(BE)
- }
-
- fn o_cpuflag(&self) -> u8 {
- self.o_cpuflag
- }
-
- fn o_cputype(&self) -> u8 {
- self.o_cputype
- }
-
- fn o_maxstack(&self) -> Self::Word {
- self.o_maxstack.get(BE)
- }
-
- fn o_maxdata(&self) -> Self::Word {
- self.o_maxdata.get(BE)
- }
-
- fn o_debugger(&self) -> u32 {
- self.o_debugger.get(BE)
- }
-
- fn o_textpsize(&self) -> u8 {
- self.o_textpsize
- }
-
- fn o_datapsize(&self) -> u8 {
- self.o_datapsize
- }
-
- fn o_stackpsize(&self) -> u8 {
- self.o_stackpsize
- }
-
- fn o_flags(&self) -> u8 {
- self.o_flags
- }
-
- fn o_sntdata(&self) -> u16 {
- self.o_sntdata.get(BE)
- }
-
- fn o_sntbss(&self) -> u16 {
- self.o_sntbss.get(BE)
- }
-
- fn o_x64flags(&self) -> Option<u16> {
- Some(self.o_x64flags.get(BE))
- }
-}
diff --git a/vendor/object/src/read/xcoff/mod.rs b/vendor/object/src/read/xcoff/mod.rs
deleted file mode 100644
index b75c4da..0000000
--- a/vendor/object/src/read/xcoff/mod.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-//! Support for reading AIX XCOFF files.
-//!
-//! Traits are used to abstract over the difference between 32-bit and 64-bit XCOFF.
-//! The primary trait for this is [`FileHeader`].
-//!
-//! ## High level API
-//!
-//! [`XcoffFile`] implements the [`Object`](crate::read::Object) trait for XCOFF files.
-//! [`XcoffFile`] is parameterised by [`FileHeader`] to allow reading both 32-bit and
-//! 64-bit XCOFF. There are type aliases for these parameters ([`XcoffFile32`] and
-//! [`XcoffFile64`]).
-//!
-//! ## Low level API
-//!
-//! The [`FileHeader`] trait can be directly used to parse both [`xcoff::FileHeader32`]
-//! and [`xcoff::FileHeader64`].
-//!
-//! ### Example for low level API
-//! ```no_run
-//! use object::xcoff;
-//! use object::read::xcoff::{FileHeader, SectionHeader, Symbol};
-//! use std::error::Error;
-//! use std::fs;
-//!
-//! /// Reads a file and displays the name of each section and symbol.
-//! fn main() -> Result<(), Box<dyn Error>> {
-//! # #[cfg(feature = "std")] {
-//! let data = fs::read("path/to/binary")?;
-//! let mut offset = 0;
-//! let header = xcoff::FileHeader64::parse(&*data, &mut offset)?;
-//! let aux_header = header.aux_header(&*data, &mut offset)?;
-//! let sections = header.sections(&*data, &mut offset)?;
-//! let symbols = header.symbols(&*data)?;
-//! for section in sections.iter() {
-//! println!("{}", String::from_utf8_lossy(section.name()));
-//! }
-//! for (_index, symbol) in symbols.iter() {
-//! println!("{}", String::from_utf8_lossy(symbol.name(symbols.strings())?));
-//! }
-//! # }
-//! Ok(())
-//! }
-//! ```
-#[cfg(doc)]
-use crate::xcoff;
-
-mod file;
-pub use file::*;
-
-mod section;
-pub use section::*;
-
-mod symbol;
-pub use symbol::*;
-
-mod relocation;
-pub use relocation::*;
-
-mod comdat;
-pub use comdat::*;
-
-mod segment;
-pub use segment::*;
diff --git a/vendor/object/src/read/xcoff/relocation.rs b/vendor/object/src/read/xcoff/relocation.rs
deleted file mode 100644
index a655ccc..0000000
--- a/vendor/object/src/read/xcoff/relocation.rs
+++ /dev/null
@@ -1,127 +0,0 @@
-use alloc::fmt;
-use core::fmt::Debug;
-use core::slice;
-
-use crate::pod::Pod;
-use crate::{xcoff, BigEndian as BE, Relocation};
-
-use crate::read::{ReadRef, RelocationEncoding, RelocationKind, RelocationTarget, SymbolIndex};
-
-use super::{FileHeader, SectionHeader, XcoffFile};
-
-/// An iterator for the relocations in an [`XcoffSection32`](super::XcoffSection32).
-pub type XcoffRelocationIterator32<'data, 'file, R = &'data [u8]> =
- XcoffRelocationIterator<'data, 'file, xcoff::FileHeader32, R>;
-/// An iterator for the relocations in an [`XcoffSection64`](super::XcoffSection64).
-pub type XcoffRelocationIterator64<'data, 'file, R = &'data [u8]> =
- XcoffRelocationIterator<'data, 'file, xcoff::FileHeader64, R>;
-
-/// An iterator for the relocations in an [`XcoffSection`](super::XcoffSection).
-pub struct XcoffRelocationIterator<'data, 'file, Xcoff, R = &'data [u8]>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- #[allow(unused)]
- pub(super) file: &'file XcoffFile<'data, Xcoff, R>,
- pub(super) relocations:
- slice::Iter<'data, <<Xcoff as FileHeader>::SectionHeader as SectionHeader>::Rel>,
-}
-
-impl<'data, 'file, Xcoff, R> Iterator for XcoffRelocationIterator<'data, 'file, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- type Item = (u64, Relocation);
-
- fn next(&mut self) -> Option<Self::Item> {
- self.relocations.next().map(|relocation| {
- let encoding = RelocationEncoding::Generic;
- let (kind, addend) = match relocation.r_rtype() {
- xcoff::R_POS
- | xcoff::R_RL
- | xcoff::R_RLA
- | xcoff::R_BA
- | xcoff::R_RBA
- | xcoff::R_TLS => (RelocationKind::Absolute, 0),
- xcoff::R_REL | xcoff::R_BR | xcoff::R_RBR => (RelocationKind::Relative, -4),
- xcoff::R_TOC | xcoff::R_TOCL | xcoff::R_TOCU => (RelocationKind::Got, 0),
- r_type => (RelocationKind::Xcoff(r_type), 0),
- };
- let size = (relocation.r_rsize() & 0x3F) + 1;
- let target = RelocationTarget::Symbol(SymbolIndex(relocation.r_symndx() as usize));
- (
- relocation.r_vaddr().into(),
- Relocation {
- kind,
- encoding,
- size,
- target,
- addend,
- implicit_addend: true,
- },
- )
- })
- }
-}
-
-impl<'data, 'file, Xcoff, R> fmt::Debug for XcoffRelocationIterator<'data, 'file, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("XcoffRelocationIterator").finish()
- }
-}
-
-/// A trait for generic access to [`xcoff::Rel32`] and [`xcoff::Rel64`].
-#[allow(missing_docs)]
-pub trait Rel: Debug + Pod {
- type Word: Into<u64>;
- fn r_vaddr(&self) -> Self::Word;
- fn r_symndx(&self) -> u32;
- fn r_rsize(&self) -> u8;
- fn r_rtype(&self) -> u8;
-}
-
-impl Rel for xcoff::Rel32 {
- type Word = u32;
-
- fn r_vaddr(&self) -> Self::Word {
- self.r_vaddr.get(BE)
- }
-
- fn r_symndx(&self) -> u32 {
- self.r_symndx.get(BE)
- }
-
- fn r_rsize(&self) -> u8 {
- self.r_rsize
- }
-
- fn r_rtype(&self) -> u8 {
- self.r_rtype
- }
-}
-
-impl Rel for xcoff::Rel64 {
- type Word = u64;
-
- fn r_vaddr(&self) -> Self::Word {
- self.r_vaddr.get(BE)
- }
-
- fn r_symndx(&self) -> u32 {
- self.r_symndx.get(BE)
- }
-
- fn r_rsize(&self) -> u8 {
- self.r_rsize
- }
-
- fn r_rtype(&self) -> u8 {
- self.r_rtype
- }
-}
diff --git a/vendor/object/src/read/xcoff/section.rs b/vendor/object/src/read/xcoff/section.rs
deleted file mode 100644
index 8a36bcf..0000000
--- a/vendor/object/src/read/xcoff/section.rs
+++ /dev/null
@@ -1,431 +0,0 @@
-use core::fmt::Debug;
-use core::{iter, result, slice, str};
-
-use crate::{
- xcoff, BigEndian as BE, CompressedData, CompressedFileRange, Pod, SectionFlags, SectionKind,
-};
-
-use crate::read::{self, Error, ObjectSection, ReadError, ReadRef, Result, SectionIndex};
-
-use super::{AuxHeader, FileHeader, Rel, XcoffFile, XcoffRelocationIterator};
-
-/// An iterator for the sections in an [`XcoffFile32`](super::XcoffFile32).
-pub type XcoffSectionIterator32<'data, 'file, R = &'data [u8]> =
- XcoffSectionIterator<'data, 'file, xcoff::FileHeader32, R>;
-/// An iterator for the sections in an [`XcoffFile64`](super::XcoffFile64).
-pub type XcoffSectionIterator64<'data, 'file, R = &'data [u8]> =
- XcoffSectionIterator<'data, 'file, xcoff::FileHeader64, R>;
-
-/// An iterator for the sections in an [`XcoffFile`].
-#[derive(Debug)]
-pub struct XcoffSectionIterator<'data, 'file, Xcoff, R = &'data [u8]>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file XcoffFile<'data, Xcoff, R>,
- pub(super) iter: iter::Enumerate<slice::Iter<'data, Xcoff::SectionHeader>>,
-}
-
-impl<'data, 'file, Xcoff, R> Iterator for XcoffSectionIterator<'data, 'file, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- type Item = XcoffSection<'data, 'file, Xcoff, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.iter.next().map(|(index, section)| XcoffSection {
- index: SectionIndex(index + 1),
- file: self.file,
- section,
- })
- }
-}
-
-/// A section in an [`XcoffFile32`](super::XcoffFile32).
-pub type XcoffSection32<'data, 'file, R = &'data [u8]> =
- XcoffSection<'data, 'file, xcoff::FileHeader32, R>;
-/// A section in an [`XcoffFile64`](super::XcoffFile64).
-pub type XcoffSection64<'data, 'file, R = &'data [u8]> =
- XcoffSection<'data, 'file, xcoff::FileHeader64, R>;
-
-/// A section in an [`XcoffFile`].
-///
-/// Most functionality is provided by the [`ObjectSection`] trait implementation.
-#[derive(Debug)]
-pub struct XcoffSection<'data, 'file, Xcoff, R = &'data [u8]>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file XcoffFile<'data, Xcoff, R>,
- pub(super) section: &'data Xcoff::SectionHeader,
- pub(super) index: SectionIndex,
-}
-
-impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> XcoffSection<'data, 'file, Xcoff, R> {
- fn bytes(&self) -> Result<&'data [u8]> {
- self.section
- .data(self.file.data)
- .read_error("Invalid XCOFF section offset or size")
- }
-}
-
-impl<'data, 'file, Xcoff, R> read::private::Sealed for XcoffSection<'data, 'file, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Xcoff, R> ObjectSection<'data> for XcoffSection<'data, 'file, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- type RelocationIterator = XcoffRelocationIterator<'data, 'file, Xcoff, R>;
-
- fn index(&self) -> SectionIndex {
- self.index
- }
-
- fn address(&self) -> u64 {
- self.section.s_paddr().into()
- }
-
- fn size(&self) -> u64 {
- self.section.s_size().into()
- }
-
- fn align(&self) -> u64 {
- // The default section alignment is 4.
- if let Some(aux_header) = self.file.aux_header {
- match self.kind() {
- SectionKind::Text => aux_header.o_algntext().into(),
- SectionKind::Data => aux_header.o_algndata().into(),
- _ => 4,
- }
- } else {
- 4
- }
- }
-
- fn file_range(&self) -> Option<(u64, u64)> {
- self.section.file_range()
- }
-
- fn data(&self) -> Result<&'data [u8]> {
- self.bytes()
- }
-
- fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> {
- Ok(read::util::data_range(
- self.bytes()?,
- self.address(),
- address,
- size,
- ))
- }
-
- fn compressed_file_range(&self) -> Result<CompressedFileRange> {
- Ok(CompressedFileRange::none(self.file_range()))
- }
-
- fn compressed_data(&self) -> Result<CompressedData<'data>> {
- self.data().map(CompressedData::none)
- }
-
- fn name_bytes(&self) -> read::Result<&[u8]> {
- Ok(self.section.name())
- }
-
- fn name(&self) -> read::Result<&str> {
- let name = self.name_bytes()?;
- str::from_utf8(name)
- .ok()
- .read_error("Non UTF-8 XCOFF section name")
- }
-
- fn segment_name_bytes(&self) -> Result<Option<&[u8]>> {
- Ok(None)
- }
-
- fn segment_name(&self) -> Result<Option<&str>> {
- Ok(None)
- }
-
- fn kind(&self) -> SectionKind {
- let section_type = self.section.s_flags() as u16;
- if section_type & xcoff::STYP_TEXT != 0 {
- SectionKind::Text
- } else if section_type & xcoff::STYP_DATA != 0 {
- SectionKind::Data
- } else if section_type & xcoff::STYP_TDATA != 0 {
- SectionKind::Tls
- } else if section_type & xcoff::STYP_BSS != 0 {
- SectionKind::UninitializedData
- } else if section_type & xcoff::STYP_TBSS != 0 {
- SectionKind::UninitializedTls
- } else if section_type & (xcoff::STYP_DEBUG | xcoff::STYP_DWARF) != 0 {
- SectionKind::Debug
- } else if section_type & (xcoff::STYP_LOADER | xcoff::STYP_OVRFLO) != 0 {
- SectionKind::Metadata
- } else if section_type
- & (xcoff::STYP_INFO | xcoff::STYP_EXCEPT | xcoff::STYP_PAD | xcoff::STYP_TYPCHK)
- != 0
- {
- SectionKind::Other
- } else {
- SectionKind::Unknown
- }
- }
-
- fn relocations(&self) -> Self::RelocationIterator {
- let rel = self.section.relocations(self.file.data).unwrap_or(&[]);
- XcoffRelocationIterator {
- file: self.file,
- relocations: rel.iter(),
- }
- }
-
- fn flags(&self) -> SectionFlags {
- SectionFlags::Xcoff {
- s_flags: self.section.s_flags(),
- }
- }
-
- fn uncompressed_data(&self) -> Result<alloc::borrow::Cow<'data, [u8]>> {
- self.compressed_data()?.decompress()
- }
-}
-
-/// The table of section headers in an XCOFF file.
-///
-/// Returned by [`FileHeader::sections`].
-#[derive(Debug, Clone, Copy)]
-pub struct SectionTable<'data, Xcoff: FileHeader> {
- sections: &'data [Xcoff::SectionHeader],
-}
-
-impl<'data, Xcoff> Default for SectionTable<'data, Xcoff>
-where
- Xcoff: FileHeader,
-{
- fn default() -> Self {
- Self { sections: &[] }
- }
-}
-
-impl<'data, Xcoff> SectionTable<'data, Xcoff>
-where
- Xcoff: FileHeader,
-{
- /// Parse the section table.
- ///
- /// `data` must be the entire file data.
- /// `offset` must be after the optional file header.
- pub fn parse<R: ReadRef<'data>>(header: &Xcoff, data: R, offset: &mut u64) -> Result<Self> {
- let section_num = header.f_nscns();
- if section_num == 0 {
- return Ok(SectionTable::default());
- }
- let sections = data
- .read_slice(offset, section_num as usize)
- .read_error("Invalid XCOFF section headers")?;
- Ok(SectionTable { sections })
- }
-
- /// Iterate over the section headers.
- #[inline]
- pub fn iter(&self) -> slice::Iter<'data, Xcoff::SectionHeader> {
- self.sections.iter()
- }
-
- /// Return true if the section table is empty.
- #[inline]
- pub fn is_empty(&self) -> bool {
- self.sections.is_empty()
- }
-
- /// The number of section headers.
- #[inline]
- pub fn len(&self) -> usize {
- self.sections.len()
- }
-
- /// Return the section header at the given index.
- ///
- /// The index is 1-based.
- pub fn section(&self, index: SectionIndex) -> read::Result<&'data Xcoff::SectionHeader> {
- self.sections
- .get(index.0.wrapping_sub(1))
- .read_error("Invalid XCOFF section index")
- }
-}
-
-/// A trait for generic access to [`xcoff::SectionHeader32`] and [`xcoff::SectionHeader64`].
-#[allow(missing_docs)]
-pub trait SectionHeader: Debug + Pod {
- type Word: Into<u64>;
- type HalfWord: Into<u32>;
- type Xcoff: FileHeader<SectionHeader = Self, Word = Self::Word>;
- type Rel: Rel<Word = Self::Word>;
-
- fn s_name(&self) -> &[u8; 8];
- fn s_paddr(&self) -> Self::Word;
- fn s_vaddr(&self) -> Self::Word;
- fn s_size(&self) -> Self::Word;
- fn s_scnptr(&self) -> Self::Word;
- fn s_relptr(&self) -> Self::Word;
- fn s_lnnoptr(&self) -> Self::Word;
- fn s_nreloc(&self) -> Self::HalfWord;
- fn s_nlnno(&self) -> Self::HalfWord;
- fn s_flags(&self) -> u32;
-
- /// Return the section name.
- fn name(&self) -> &[u8] {
- let sectname = &self.s_name()[..];
- match memchr::memchr(b'\0', sectname) {
- Some(end) => &sectname[..end],
- None => sectname,
- }
- }
-
- /// Return the offset and size of the section in the file.
- fn file_range(&self) -> Option<(u64, u64)> {
- Some((self.s_scnptr().into(), self.s_size().into()))
- }
-
- /// Return the section data.
- ///
- /// Returns `Ok(&[])` if the section has no data.
- /// Returns `Err` for invalid values.
- fn data<'data, R: ReadRef<'data>>(&self, data: R) -> result::Result<&'data [u8], ()> {
- if let Some((offset, size)) = self.file_range() {
- data.read_bytes_at(offset, size)
- } else {
- Ok(&[])
- }
- }
-
- /// Read the relocations.
- fn relocations<'data, R: ReadRef<'data>>(&self, data: R) -> read::Result<&'data [Self::Rel]>;
-}
-
-impl SectionHeader for xcoff::SectionHeader32 {
- type Word = u32;
- type HalfWord = u16;
- type Xcoff = xcoff::FileHeader32;
- type Rel = xcoff::Rel32;
-
- fn s_name(&self) -> &[u8; 8] {
- &self.s_name
- }
-
- fn s_paddr(&self) -> Self::Word {
- self.s_paddr.get(BE)
- }
-
- fn s_vaddr(&self) -> Self::Word {
- self.s_vaddr.get(BE)
- }
-
- fn s_size(&self) -> Self::Word {
- self.s_size.get(BE)
- }
-
- fn s_scnptr(&self) -> Self::Word {
- self.s_scnptr.get(BE)
- }
-
- fn s_relptr(&self) -> Self::Word {
- self.s_relptr.get(BE)
- }
-
- fn s_lnnoptr(&self) -> Self::Word {
- self.s_lnnoptr.get(BE)
- }
-
- fn s_nreloc(&self) -> Self::HalfWord {
- self.s_nreloc.get(BE)
- }
-
- fn s_nlnno(&self) -> Self::HalfWord {
- self.s_nlnno.get(BE)
- }
-
- fn s_flags(&self) -> u32 {
- self.s_flags.get(BE)
- }
-
- /// Read the relocations in a XCOFF32 file.
- ///
- /// `data` must be the entire file data.
- fn relocations<'data, R: ReadRef<'data>>(&self, data: R) -> read::Result<&'data [Self::Rel]> {
- let reloc_num = self.s_nreloc() as usize;
- // TODO: If more than 65,534 relocation entries are required, the field value will be 65535,
- // and an STYP_OVRFLO section header will contain the actual count of relocation entries in
- // the s_paddr field.
- if reloc_num == 65535 {
- return Err(Error("Overflow section is not supported yet."));
- }
- data.read_slice_at(self.s_relptr().into(), reloc_num)
- .read_error("Invalid XCOFF relocation offset or number")
- }
-}
-
-impl SectionHeader for xcoff::SectionHeader64 {
- type Word = u64;
- type HalfWord = u32;
- type Xcoff = xcoff::FileHeader64;
- type Rel = xcoff::Rel64;
-
- fn s_name(&self) -> &[u8; 8] {
- &self.s_name
- }
-
- fn s_paddr(&self) -> Self::Word {
- self.s_paddr.get(BE)
- }
-
- fn s_vaddr(&self) -> Self::Word {
- self.s_vaddr.get(BE)
- }
-
- fn s_size(&self) -> Self::Word {
- self.s_size.get(BE)
- }
-
- fn s_scnptr(&self) -> Self::Word {
- self.s_scnptr.get(BE)
- }
-
- fn s_relptr(&self) -> Self::Word {
- self.s_relptr.get(BE)
- }
-
- fn s_lnnoptr(&self) -> Self::Word {
- self.s_lnnoptr.get(BE)
- }
-
- fn s_nreloc(&self) -> Self::HalfWord {
- self.s_nreloc.get(BE)
- }
-
- fn s_nlnno(&self) -> Self::HalfWord {
- self.s_nlnno.get(BE)
- }
-
- fn s_flags(&self) -> u32 {
- self.s_flags.get(BE)
- }
-
- /// Read the relocations in a XCOFF64 file.
- ///
- /// `data` must be the entire file data.
- fn relocations<'data, R: ReadRef<'data>>(&self, data: R) -> read::Result<&'data [Self::Rel]> {
- data.read_slice_at(self.s_relptr(), self.s_nreloc() as usize)
- .read_error("Invalid XCOFF relocation offset or number")
- }
-}
diff --git a/vendor/object/src/read/xcoff/segment.rs b/vendor/object/src/read/xcoff/segment.rs
deleted file mode 100644
index d30d7d8..0000000
--- a/vendor/object/src/read/xcoff/segment.rs
+++ /dev/null
@@ -1,117 +0,0 @@
-//! TODO: Support the segment for XCOFF when auxiliary file header and loader section is ready.
-
-use core::fmt::Debug;
-use core::str;
-
-use crate::read::{self, ObjectSegment, ReadRef, Result};
-use crate::xcoff;
-
-use super::{FileHeader, XcoffFile};
-
-/// An iterator for the segments in an [`XcoffFile32`](super::XcoffFile32).
-pub type XcoffSegmentIterator32<'data, 'file, R = &'data [u8]> =
- XcoffSegmentIterator<'data, 'file, xcoff::FileHeader32, R>;
-/// An iterator for the segments in an [`XcoffFile64`](super::XcoffFile64).
-pub type XcoffSegmentIterator64<'data, 'file, R = &'data [u8]> =
- XcoffSegmentIterator<'data, 'file, xcoff::FileHeader64, R>;
-
-/// An iterator for the segments in an [`XcoffFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct XcoffSegmentIterator<'data, 'file, Xcoff, R = &'data [u8]>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- #[allow(unused)]
- pub(super) file: &'file XcoffFile<'data, Xcoff, R>,
-}
-
-impl<'data, 'file, Xcoff, R> Iterator for XcoffSegmentIterator<'data, 'file, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- type Item = XcoffSegment<'data, 'file, Xcoff, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
-}
-
-/// A segment in an [`XcoffFile32`](super::XcoffFile32).
-pub type XcoffSegment32<'data, 'file, R = &'data [u8]> =
- XcoffSegment<'data, 'file, xcoff::FileHeader32, R>;
-/// A segment in an [`XcoffFile64`](super::XcoffFile64).
-pub type XcoffSegment64<'data, 'file, R = &'data [u8]> =
- XcoffSegment<'data, 'file, xcoff::FileHeader64, R>;
-
-/// A loadable section in an [`XcoffFile`].
-///
-/// This is a stub that doesn't implement any functionality.
-#[derive(Debug)]
-pub struct XcoffSegment<'data, 'file, Xcoff, R = &'data [u8]>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- #[allow(unused)]
- pub(super) file: &'file XcoffFile<'data, Xcoff, R>,
-}
-
-impl<'data, 'file, Xcoff, R> XcoffSegment<'data, 'file, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Xcoff, R> read::private::Sealed for XcoffSegment<'data, 'file, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
-}
-
-impl<'data, 'file, Xcoff, R> ObjectSegment<'data> for XcoffSegment<'data, 'file, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- fn address(&self) -> u64 {
- unreachable!();
- }
-
- fn size(&self) -> u64 {
- unreachable!();
- }
-
- fn align(&self) -> u64 {
- unreachable!();
- }
-
- fn file_range(&self) -> (u64, u64) {
- unreachable!();
- }
-
- fn data(&self) -> Result<&'data [u8]> {
- unreachable!();
- }
-
- fn data_range(&self, _address: u64, _size: u64) -> Result<Option<&'data [u8]>> {
- unreachable!();
- }
-
- fn name_bytes(&self) -> Result<Option<&[u8]>> {
- unreachable!();
- }
-
- fn name(&self) -> Result<Option<&str>> {
- unreachable!();
- }
-
- fn flags(&self) -> crate::SegmentFlags {
- unreachable!();
- }
-}
diff --git a/vendor/object/src/read/xcoff/symbol.rs b/vendor/object/src/read/xcoff/symbol.rs
deleted file mode 100644
index 72651c3..0000000
--- a/vendor/object/src/read/xcoff/symbol.rs
+++ /dev/null
@@ -1,786 +0,0 @@
-use alloc::fmt;
-use core::convert::TryInto;
-use core::fmt::Debug;
-use core::marker::PhantomData;
-use core::str;
-
-use crate::endian::{BigEndian as BE, U32Bytes};
-use crate::pod::{bytes_of, Pod};
-use crate::read::util::StringTable;
-use crate::xcoff;
-
-use crate::read::{
- self, Bytes, Error, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Result, SectionIndex,
- SymbolFlags, SymbolIndex, SymbolKind, SymbolScope, SymbolSection,
-};
-
-use super::{FileHeader, XcoffFile};
-
-/// A table of symbol entries in an XCOFF file.
-///
-/// Also includes the string table used for the symbol names.
-///
-/// Returned by [`FileHeader::symbols`].
-#[derive(Debug)]
-pub struct SymbolTable<'data, Xcoff, R = &'data [u8]>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- symbols: &'data [xcoff::SymbolBytes],
- strings: StringTable<'data, R>,
- header: PhantomData<Xcoff>,
-}
-
-impl<'data, Xcoff, R> Default for SymbolTable<'data, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- fn default() -> Self {
- Self {
- symbols: &[],
- strings: StringTable::default(),
- header: PhantomData,
- }
- }
-}
-
-impl<'data, Xcoff, R> SymbolTable<'data, Xcoff, R>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- /// Parse the symbol table.
- pub fn parse(header: Xcoff, data: R) -> Result<Self> {
- let mut offset = header.f_symptr().into();
- let (symbols, strings) = if offset != 0 {
- let symbols = data
- .read_slice(&mut offset, header.f_nsyms() as usize)
- .read_error("Invalid XCOFF symbol table offset or size")?;
-
- // Parse the string table.
- // Note: don't update data when reading length; the length includes itself.
- let length = data
- .read_at::<U32Bytes<_>>(offset)
- .read_error("Missing XCOFF string table")?
- .get(BE);
- let str_end = offset
- .checked_add(length as u64)
- .read_error("Invalid XCOFF string table length")?;
- let strings = StringTable::new(data, offset, str_end);
-
- (symbols, strings)
- } else {
- (&[][..], StringTable::default())
- };
-
- Ok(SymbolTable {
- symbols,
- strings,
- header: PhantomData,
- })
- }
-
- /// Return the string table used for the symbol names.
- #[inline]
- pub fn strings(&self) -> StringTable<'data, R> {
- self.strings
- }
-
- /// Iterate over the symbols.
- #[inline]
- pub fn iter<'table>(&'table self) -> SymbolIterator<'data, 'table, Xcoff, R> {
- SymbolIterator {
- symbols: self,
- index: 0,
- }
- }
-
- /// Empty symbol iterator.
- #[inline]
- pub(super) fn iter_none<'table>(&'table self) -> SymbolIterator<'data, 'table, Xcoff, R> {
- SymbolIterator {
- symbols: self,
- index: self.symbols.len(),
- }
- }
-
- /// Return the symbol entry at the given index and offset.
- pub fn get<T: Pod>(&self, index: usize, offset: usize) -> Result<&'data T> {
- let entry = index
- .checked_add(offset)
- .and_then(|x| self.symbols.get(x))
- .read_error("Invalid XCOFF symbol index")?;
- let bytes = bytes_of(entry);
- Bytes(bytes).read().read_error("Invalid XCOFF symbol data")
- }
-
- /// Return the symbol at the given index.
- pub fn symbol(&self, index: usize) -> Result<&'data Xcoff::Symbol> {
- self.get::<Xcoff::Symbol>(index, 0)
- }
-
- /// Return a file auxiliary symbol.
- pub fn aux_file(&self, index: usize, offset: usize) -> Result<&'data Xcoff::FileAux> {
- debug_assert!(self.symbol(index)?.has_aux_file());
- let aux_file = self.get::<Xcoff::FileAux>(index, offset)?;
- if let Some(aux_type) = aux_file.x_auxtype() {
- if aux_type != xcoff::AUX_FILE {
- return Err(Error("Invalid index for file auxiliary symbol."));
- }
- }
- Ok(aux_file)
- }
-
- /// Return the csect auxiliary symbol.
- pub fn aux_csect(&self, index: usize, offset: usize) -> Result<&'data Xcoff::CsectAux> {
- debug_assert!(self.symbol(index)?.has_aux_csect());
- let aux_csect = self.get::<Xcoff::CsectAux>(index, offset)?;
- if let Some(aux_type) = aux_csect.x_auxtype() {
- if aux_type != xcoff::AUX_CSECT {
- return Err(Error("Invalid index/offset for csect auxiliary symbol."));
- }
- }
- Ok(aux_csect)
- }
-
- /// Return true if the symbol table is empty.
- #[inline]
- pub fn is_empty(&self) -> bool {
- self.symbols.is_empty()
- }
-
- /// The number of symbol table entries.
- ///
- /// This includes auxiliary symbol table entries.
- #[inline]
- pub fn len(&self) -> usize {
- self.symbols.len()
- }
-}
-
-/// An iterator for symbol entries in an XCOFF file.
-///
-/// Yields the index and symbol structure for each symbol.
-#[derive(Debug)]
-pub struct SymbolIterator<'data, 'table, Xcoff, R = &'data [u8]>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- symbols: &'table SymbolTable<'data, Xcoff, R>,
- index: usize,
-}
-
-impl<'data, 'table, Xcoff: FileHeader, R: ReadRef<'data>> Iterator
- for SymbolIterator<'data, 'table, Xcoff, R>
-{
- type Item = (SymbolIndex, &'data Xcoff::Symbol);
-
- fn next(&mut self) -> Option<Self::Item> {
- let index = self.index;
- let symbol = self.symbols.symbol(index).ok()?;
- self.index += 1 + symbol.n_numaux() as usize;
- Some((SymbolIndex(index), symbol))
- }
-}
-
-/// A symbol table in an [`XcoffFile32`](super::XcoffFile32).
-pub type XcoffSymbolTable32<'data, 'file, R = &'data [u8]> =
- XcoffSymbolTable<'data, 'file, xcoff::FileHeader32, R>;
-/// A symbol table in an [`XcoffFile64`](super::XcoffFile64).
-pub type XcoffSymbolTable64<'data, 'file, R = &'data [u8]> =
- XcoffSymbolTable<'data, 'file, xcoff::FileHeader64, R>;
-
-/// A symbol table in an [`XcoffFile`].
-#[derive(Debug, Clone, Copy)]
-pub struct XcoffSymbolTable<'data, 'file, Xcoff, R = &'data [u8]>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file XcoffFile<'data, Xcoff, R>,
- pub(super) symbols: &'file SymbolTable<'data, Xcoff, R>,
-}
-
-impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> read::private::Sealed
- for XcoffSymbolTable<'data, 'file, Xcoff, R>
-{
-}
-
-impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbolTable<'data>
- for XcoffSymbolTable<'data, 'file, Xcoff, R>
-{
- type Symbol = XcoffSymbol<'data, 'file, Xcoff, R>;
- type SymbolIterator = XcoffSymbolIterator<'data, 'file, Xcoff, R>;
-
- fn symbols(&self) -> Self::SymbolIterator {
- XcoffSymbolIterator {
- file: self.file,
- symbols: self.symbols.iter(),
- }
- }
-
- fn symbol_by_index(&self, index: SymbolIndex) -> read::Result<Self::Symbol> {
- let symbol = self.symbols.symbol(index.0)?;
- Ok(XcoffSymbol {
- file: self.file,
- symbols: self.symbols,
- index,
- symbol,
- })
- }
-}
-
-/// An iterator for the symbols in an [`XcoffFile32`](super::XcoffFile32).
-pub type XcoffSymbolIterator32<'data, 'file, R = &'data [u8]> =
- XcoffSymbolIterator<'data, 'file, xcoff::FileHeader32, R>;
-/// An iterator for the symbols in an [`XcoffFile64`](super::XcoffFile64).
-pub type XcoffSymbolIterator64<'data, 'file, R = &'data [u8]> =
- XcoffSymbolIterator<'data, 'file, xcoff::FileHeader64, R>;
-
-/// An iterator for the symbols in an [`XcoffFile`].
-pub struct XcoffSymbolIterator<'data, 'file, Xcoff, R = &'data [u8]>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file XcoffFile<'data, Xcoff, R>,
- pub(super) symbols: SymbolIterator<'data, 'file, Xcoff, R>,
-}
-
-impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> fmt::Debug
- for XcoffSymbolIterator<'data, 'file, Xcoff, R>
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("XcoffSymbolIterator").finish()
- }
-}
-
-impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> Iterator
- for XcoffSymbolIterator<'data, 'file, Xcoff, R>
-{
- type Item = XcoffSymbol<'data, 'file, Xcoff, R>;
-
- fn next(&mut self) -> Option<Self::Item> {
- let (index, symbol) = self.symbols.next()?;
- Some(XcoffSymbol {
- file: self.file,
- symbols: self.symbols.symbols,
- index,
- symbol,
- })
- }
-}
-
-/// A symbol in an [`XcoffFile32`](super::XcoffFile32).
-pub type XcoffSymbol32<'data, 'file, R = &'data [u8]> =
- XcoffSymbol<'data, 'file, xcoff::FileHeader32, R>;
-/// A symbol in an [`XcoffFile64`](super::XcoffFile64).
-pub type XcoffSymbol64<'data, 'file, R = &'data [u8]> =
- XcoffSymbol<'data, 'file, xcoff::FileHeader64, R>;
-
-/// A symbol in an [`XcoffFile`].
-///
-/// Most functionality is provided by the [`ObjectSymbol`] trait implementation.
-#[derive(Debug, Clone, Copy)]
-pub struct XcoffSymbol<'data, 'file, Xcoff, R = &'data [u8]>
-where
- Xcoff: FileHeader,
- R: ReadRef<'data>,
-{
- pub(super) file: &'file XcoffFile<'data, Xcoff, R>,
- pub(super) symbols: &'file SymbolTable<'data, Xcoff, R>,
- pub(super) index: SymbolIndex,
- pub(super) symbol: &'data Xcoff::Symbol,
-}
-
-impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> read::private::Sealed
- for XcoffSymbol<'data, 'file, Xcoff, R>
-{
-}
-
-impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data>
- for XcoffSymbol<'data, 'file, Xcoff, R>
-{
- #[inline]
- fn index(&self) -> SymbolIndex {
- self.index
- }
-
- fn name_bytes(&self) -> Result<&'data [u8]> {
- if self.symbol.has_aux_file() {
- // By convention the file name is in the first auxiliary entry.
- self.symbols
- .aux_file(self.index.0, 1)?
- .fname(self.symbols.strings)
- } else {
- self.symbol.name(self.symbols.strings)
- }
- }
-
- fn name(&self) -> Result<&'data str> {
- let name = self.name_bytes()?;
- str::from_utf8(name)
- .ok()
- .read_error("Non UTF-8 XCOFF symbol name")
- }
-
- #[inline]
- fn address(&self) -> u64 {
- match self.symbol.n_sclass() {
- // Relocatable address.
- xcoff::C_EXT
- | xcoff::C_WEAKEXT
- | xcoff::C_HIDEXT
- | xcoff::C_FCN
- | xcoff::C_BLOCK
- | xcoff::C_STAT
- | xcoff::C_INFO => self.symbol.n_value().into(),
- _ => 0,
- }
- }
-
- #[inline]
- fn size(&self) -> u64 {
- if self.symbol.has_aux_csect() {
- // XCOFF32 must have the csect auxiliary entry as the last auxiliary entry.
- // XCOFF64 doesn't require this, but conventionally does.
- if let Ok(aux_csect) = self
- .file
- .symbols
- .aux_csect(self.index.0, self.symbol.n_numaux() as usize)
- {
- let sym_type = aux_csect.sym_type();
- if sym_type == xcoff::XTY_SD || sym_type == xcoff::XTY_CM {
- return aux_csect.x_scnlen();
- }
- }
- }
- 0
- }
-
- fn kind(&self) -> SymbolKind {
- if self.symbol.has_aux_csect() {
- if let Ok(aux_csect) = self
- .file
- .symbols
- .aux_csect(self.index.0, self.symbol.n_numaux() as usize)
- {
- let sym_type = aux_csect.sym_type();
- if sym_type == xcoff::XTY_SD || sym_type == xcoff::XTY_CM {
- return match aux_csect.x_smclas() {
- xcoff::XMC_PR | xcoff::XMC_GL => SymbolKind::Text,
- xcoff::XMC_RO | xcoff::XMC_RW | xcoff::XMC_TD | xcoff::XMC_BS => {
- SymbolKind::Data
- }
- xcoff::XMC_TL | xcoff::XMC_UL => SymbolKind::Tls,
- xcoff::XMC_DS | xcoff::XMC_TC0 | xcoff::XMC_TC => {
- // `Metadata` might be a better kind for these if we had it.
- SymbolKind::Data
- }
- _ => SymbolKind::Unknown,
- };
- } else if sym_type == xcoff::XTY_LD {
- // A function entry point. Neither `Text` nor `Label` are a good fit for this.
- return SymbolKind::Text;
- } else if sym_type == xcoff::XTY_ER {
- return SymbolKind::Unknown;
- }
- }
- }
- match self.symbol.n_sclass() {
- xcoff::C_NULL => SymbolKind::Null,
- xcoff::C_FILE => SymbolKind::File,
- _ => SymbolKind::Unknown,
- }
- }
-
- fn section(&self) -> SymbolSection {
- match self.symbol.n_scnum() {
- xcoff::N_ABS => SymbolSection::Absolute,
- xcoff::N_UNDEF => SymbolSection::Undefined,
- xcoff::N_DEBUG => SymbolSection::None,
- index if index > 0 => SymbolSection::Section(SectionIndex(index as usize)),
- _ => SymbolSection::Unknown,
- }
- }
-
- #[inline]
- fn is_undefined(&self) -> bool {
- self.symbol.is_undefined()
- }
-
- /// Return true if the symbol is a definition of a function or data object.
- #[inline]
- fn is_definition(&self) -> bool {
- if self.symbol.n_scnum() <= 0 {
- return false;
- }
- if self.symbol.has_aux_csect() {
- if let Ok(aux_csect) = self
- .symbols
- .aux_csect(self.index.0, self.symbol.n_numaux() as usize)
- {
- let sym_type = aux_csect.sym_type();
- sym_type == xcoff::XTY_SD || sym_type == xcoff::XTY_LD || sym_type == xcoff::XTY_CM
- } else {
- false
- }
- } else {
- false
- }
- }
-
- #[inline]
- fn is_common(&self) -> bool {
- self.symbol.n_sclass() == xcoff::C_EXT && self.symbol.n_scnum() == xcoff::N_UNDEF
- }
-
- #[inline]
- fn is_weak(&self) -> bool {
- self.symbol.n_sclass() == xcoff::C_WEAKEXT
- }
-
- fn scope(&self) -> SymbolScope {
- if self.symbol.n_scnum() == xcoff::N_UNDEF {
- SymbolScope::Unknown
- } else {
- match self.symbol.n_sclass() {
- xcoff::C_EXT | xcoff::C_WEAKEXT => {
- let visibility = self.symbol.n_type() & xcoff::SYM_V_MASK;
- if visibility == xcoff::SYM_V_HIDDEN {
- SymbolScope::Linkage
- } else {
- SymbolScope::Dynamic
- }
- }
- _ => SymbolScope::Compilation,
- }
- }
- }
-
- #[inline]
- fn is_global(&self) -> bool {
- match self.symbol.n_sclass() {
- xcoff::C_EXT | xcoff::C_WEAKEXT => true,
- _ => false,
- }
- }
-
- #[inline]
- fn is_local(&self) -> bool {
- !self.is_global()
- }
-
- #[inline]
- fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> {
- let mut x_smtyp = 0;
- let mut x_smclas = 0;
- let mut containing_csect = None;
- if self.symbol.has_aux_csect() {
- if let Ok(aux_csect) = self
- .file
- .symbols
- .aux_csect(self.index.0, self.symbol.n_numaux() as usize)
- {
- x_smtyp = aux_csect.x_smtyp();
- x_smclas = aux_csect.x_smclas();
- if aux_csect.sym_type() == xcoff::XTY_LD {
- containing_csect = Some(SymbolIndex(aux_csect.x_scnlen() as usize))
- }
- }
- }
- SymbolFlags::Xcoff {
- n_sclass: self.symbol.n_sclass(),
- x_smtyp,
- x_smclas,
- containing_csect,
- }
- }
-}
-
-/// A trait for generic access to [`xcoff::Symbol32`] and [`xcoff::Symbol64`].
-#[allow(missing_docs)]
-pub trait Symbol: Debug + Pod {
- type Word: Into<u64>;
-
- fn n_value(&self) -> Self::Word;
- fn n_scnum(&self) -> i16;
- fn n_type(&self) -> u16;
- fn n_sclass(&self) -> u8;
- fn n_numaux(&self) -> u8;
-
- fn name_offset(&self) -> Option<u32>;
- fn name<'data, R: ReadRef<'data>>(
- &'data self,
- strings: StringTable<'data, R>,
- ) -> Result<&'data [u8]>;
-
- /// Return true if the symbol is undefined.
- #[inline]
- fn is_undefined(&self) -> bool {
- let n_sclass = self.n_sclass();
- (n_sclass == xcoff::C_EXT || n_sclass == xcoff::C_WEAKEXT)
- && self.n_scnum() == xcoff::N_UNDEF
- }
-
- /// Return true if the symbol has file auxiliary entry.
- fn has_aux_file(&self) -> bool {
- self.n_numaux() > 0 && self.n_sclass() == xcoff::C_FILE
- }
-
- /// Return true if the symbol has csect auxiliary entry.
- ///
- /// A csect auxiliary entry is required for each symbol table entry that has
- /// a storage class value of C_EXT, C_WEAKEXT, or C_HIDEXT.
- fn has_aux_csect(&self) -> bool {
- let sclass = self.n_sclass();
- self.n_numaux() > 0
- && (sclass == xcoff::C_EXT || sclass == xcoff::C_WEAKEXT || sclass == xcoff::C_HIDEXT)
- }
-}
-
-impl Symbol for xcoff::Symbol64 {
- type Word = u64;
-
- fn n_value(&self) -> Self::Word {
- self.n_value.get(BE)
- }
-
- fn n_scnum(&self) -> i16 {
- self.n_scnum.get(BE)
- }
-
- fn n_type(&self) -> u16 {
- self.n_type.get(BE)
- }
-
- fn n_sclass(&self) -> u8 {
- self.n_sclass
- }
-
- fn n_numaux(&self) -> u8 {
- self.n_numaux
- }
-
- fn name_offset(&self) -> Option<u32> {
- Some(self.n_offset.get(BE))
- }
-
- /// Parse the symbol name for XCOFF64.
- fn name<'data, R: ReadRef<'data>>(
- &'data self,
- strings: StringTable<'data, R>,
- ) -> Result<&'data [u8]> {
- strings
- .get(self.n_offset.get(BE))
- .read_error("Invalid XCOFF symbol name offset")
- }
-}
-
-impl Symbol for xcoff::Symbol32 {
- type Word = u32;
-
- fn n_value(&self) -> Self::Word {
- self.n_value.get(BE)
- }
-
- fn n_scnum(&self) -> i16 {
- self.n_scnum.get(BE)
- }
-
- fn n_type(&self) -> u16 {
- self.n_type.get(BE)
- }
-
- fn n_sclass(&self) -> u8 {
- self.n_sclass
- }
-
- fn n_numaux(&self) -> u8 {
- self.n_numaux
- }
-
- fn name_offset(&self) -> Option<u32> {
- if self.n_name[0] == 0 {
- let offset = u32::from_be_bytes(self.n_name[4..8].try_into().unwrap());
- Some(offset)
- } else {
- None
- }
- }
-
- /// Parse the symbol name for XCOFF32.
- fn name<'data, R: ReadRef<'data>>(
- &'data self,
- strings: StringTable<'data, R>,
- ) -> Result<&'data [u8]> {
- if let Some(offset) = self.name_offset() {
- // If the name starts with 0 then the last 4 bytes are a string table offset.
- strings
- .get(offset)
- .read_error("Invalid XCOFF symbol name offset")
- } else {
- // The name is inline and padded with nulls.
- Ok(match memchr::memchr(b'\0', &self.n_name) {
- Some(end) => &self.n_name[..end],
- None => &self.n_name,
- })
- }
- }
-}
-
-/// A trait for generic access to [`xcoff::FileAux32`] and [`xcoff::FileAux64`].
-#[allow(missing_docs)]
-pub trait FileAux: Debug + Pod {
- fn x_fname(&self) -> &[u8; 8];
- fn x_ftype(&self) -> u8;
- fn x_auxtype(&self) -> Option<u8>;
-
- fn name_offset(&self) -> Option<u32> {
- let x_fname = self.x_fname();
- if x_fname[0] == 0 {
- Some(u32::from_be_bytes(x_fname[4..8].try_into().unwrap()))
- } else {
- None
- }
- }
-
- /// Parse the x_fname field, which may be an inline string or a string table offset.
- fn fname<'data, R: ReadRef<'data>>(
- &'data self,
- strings: StringTable<'data, R>,
- ) -> Result<&'data [u8]> {
- if let Some(offset) = self.name_offset() {
- // If the name starts with 0 then the last 4 bytes are a string table offset.
- strings
- .get(offset)
- .read_error("Invalid XCOFF symbol name offset")
- } else {
- // The name is inline and padded with nulls.
- let x_fname = self.x_fname();
- Ok(match memchr::memchr(b'\0', x_fname) {
- Some(end) => &x_fname[..end],
- None => x_fname,
- })
- }
- }
-}
-
-impl FileAux for xcoff::FileAux64 {
- fn x_fname(&self) -> &[u8; 8] {
- &self.x_fname
- }
-
- fn x_ftype(&self) -> u8 {
- self.x_ftype
- }
-
- fn x_auxtype(&self) -> Option<u8> {
- Some(self.x_auxtype)
- }
-}
-
-impl FileAux for xcoff::FileAux32 {
- fn x_fname(&self) -> &[u8; 8] {
- &self.x_fname
- }
-
- fn x_ftype(&self) -> u8 {
- self.x_ftype
- }
-
- fn x_auxtype(&self) -> Option<u8> {
- None
- }
-}
-
-/// A trait for generic access to [`xcoff::CsectAux32`] and [`xcoff::CsectAux64`].
-#[allow(missing_docs)]
-pub trait CsectAux: Debug + Pod {
- fn x_scnlen(&self) -> u64;
- fn x_parmhash(&self) -> u32;
- fn x_snhash(&self) -> u16;
- fn x_smtyp(&self) -> u8;
- fn x_smclas(&self) -> u8;
- fn x_stab(&self) -> Option<u32>;
- fn x_snstab(&self) -> Option<u16>;
- fn x_auxtype(&self) -> Option<u8>;
-
- fn alignment(&self) -> u8 {
- self.x_smtyp() >> 3
- }
- fn sym_type(&self) -> u8 {
- self.x_smtyp() & 0x07
- }
-}
-
-impl CsectAux for xcoff::CsectAux64 {
- fn x_scnlen(&self) -> u64 {
- self.x_scnlen_lo.get(BE) as u64 | ((self.x_scnlen_hi.get(BE) as u64) << 32)
- }
-
- fn x_parmhash(&self) -> u32 {
- self.x_parmhash.get(BE)
- }
-
- fn x_snhash(&self) -> u16 {
- self.x_snhash.get(BE)
- }
-
- fn x_smtyp(&self) -> u8 {
- self.x_smtyp
- }
-
- fn x_smclas(&self) -> u8 {
- self.x_smclas
- }
-
- fn x_stab(&self) -> Option<u32> {
- None
- }
-
- fn x_snstab(&self) -> Option<u16> {
- None
- }
-
- fn x_auxtype(&self) -> Option<u8> {
- Some(self.x_auxtype)
- }
-}
-
-impl CsectAux for xcoff::CsectAux32 {
- fn x_scnlen(&self) -> u64 {
- self.x_scnlen.get(BE) as u64
- }
-
- fn x_parmhash(&self) -> u32 {
- self.x_parmhash.get(BE)
- }
-
- fn x_snhash(&self) -> u16 {
- self.x_snhash.get(BE)
- }
-
- fn x_smtyp(&self) -> u8 {
- self.x_smtyp
- }
-
- fn x_smclas(&self) -> u8 {
- self.x_smclas
- }
-
- fn x_stab(&self) -> Option<u32> {
- Some(self.x_stab.get(BE))
- }
-
- fn x_snstab(&self) -> Option<u16> {
- Some(self.x_snstab.get(BE))
- }
-
- fn x_auxtype(&self) -> Option<u8> {
- None
- }
-}
diff --git a/vendor/object/src/write/coff/mod.rs b/vendor/object/src/write/coff/mod.rs
deleted file mode 100644
index 6e0f5ed..0000000
--- a/vendor/object/src/write/coff/mod.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//! Support for writing COFF files.
-//!
-//! Provides [`Writer`] for low level writing of COFF files.
-//! This is also used to provide COFF support for [`write::Object`](crate::write::Object).
-
-mod object;
-pub use self::object::*;
-
-mod writer;
-pub use writer::*;
diff --git a/vendor/object/src/write/coff/object.rs b/vendor/object/src/write/coff/object.rs
deleted file mode 100644
index 5229665..0000000
--- a/vendor/object/src/write/coff/object.rs
+++ /dev/null
@@ -1,583 +0,0 @@
-use alloc::vec::Vec;
-
-use crate::pe as coff;
-use crate::write::coff::writer;
-use crate::write::util::*;
-use crate::write::*;
-
-#[derive(Default, Clone, Copy)]
-struct SectionOffsets {
- name: writer::Name,
- offset: u32,
- reloc_offset: u32,
- selection: u8,
- associative_section: u32,
-}
-
-#[derive(Default, Clone, Copy)]
-struct SymbolOffsets {
- name: writer::Name,
- index: u32,
- aux_count: u8,
-}
-
-/// Internal format to use for the `.drectve` section containing linker
-/// directives for symbol exports.
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub enum CoffExportStyle {
- /// MSVC format supported by link.exe and LLD.
- Msvc,
- /// Gnu format supported by GNU LD and LLD.
- Gnu,
-}
-
-impl<'a> Object<'a> {
- pub(crate) fn coff_section_info(
- &self,
- section: StandardSection,
- ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) {
- match section {
- StandardSection::Text => (&[], &b".text"[..], SectionKind::Text, SectionFlags::None),
- StandardSection::Data => (&[], &b".data"[..], SectionKind::Data, SectionFlags::None),
- StandardSection::ReadOnlyData
- | StandardSection::ReadOnlyDataWithRel
- | StandardSection::ReadOnlyString => (
- &[],
- &b".rdata"[..],
- SectionKind::ReadOnlyData,
- SectionFlags::None,
- ),
- StandardSection::UninitializedData => (
- &[],
- &b".bss"[..],
- SectionKind::UninitializedData,
- SectionFlags::None,
- ),
- // TLS sections are data sections with a special name.
- StandardSection::Tls => (&[], &b".tls$"[..], SectionKind::Data, SectionFlags::None),
- StandardSection::UninitializedTls => {
- // Unsupported section.
- (&[], &[], SectionKind::UninitializedTls, SectionFlags::None)
- }
- StandardSection::TlsVariables => {
- // Unsupported section.
- (&[], &[], SectionKind::TlsVariables, SectionFlags::None)
- }
- StandardSection::Common => {
- // Unsupported section.
- (&[], &[], SectionKind::Common, SectionFlags::None)
- }
- StandardSection::GnuProperty => {
- // Unsupported section.
- (&[], &[], SectionKind::Note, SectionFlags::None)
- }
- }
- }
-
- pub(crate) fn coff_subsection_name(&self, section: &[u8], value: &[u8]) -> Vec<u8> {
- let mut name = section.to_vec();
- name.push(b'$');
- name.extend_from_slice(value);
- name
- }
-
- pub(crate) fn coff_fixup_relocation(&mut self, relocation: &mut Relocation) -> i64 {
- if relocation.kind == RelocationKind::GotRelative {
- // Use a stub symbol for the relocation instead.
- // This isn't really a GOT, but it's a similar purpose.
- // TODO: need to handle DLL imports differently?
- relocation.kind = RelocationKind::Relative;
- relocation.symbol = self.coff_add_stub_symbol(relocation.symbol);
- } else if relocation.kind == RelocationKind::PltRelative {
- // Windows doesn't need a separate relocation type for
- // references to functions in import libraries.
- // For convenience, treat this the same as Relative.
- relocation.kind = RelocationKind::Relative;
- }
-
- let constant = match self.architecture {
- Architecture::I386 | Architecture::Arm | Architecture::Aarch64 => match relocation.kind
- {
- RelocationKind::Relative => {
- // IMAGE_REL_I386_REL32, IMAGE_REL_ARM_REL32, IMAGE_REL_ARM64_REL32
- relocation.addend + 4
- }
- _ => relocation.addend,
- },
- Architecture::X86_64 => match relocation.kind {
- RelocationKind::Relative => {
- // IMAGE_REL_AMD64_REL32 through to IMAGE_REL_AMD64_REL32_5
- if relocation.addend <= -4 && relocation.addend >= -9 {
- 0
- } else {
- relocation.addend + 4
- }
- }
- _ => relocation.addend,
- },
- _ => unimplemented!(),
- };
- relocation.addend -= constant;
- constant
- }
-
- fn coff_add_stub_symbol(&mut self, symbol_id: SymbolId) -> SymbolId {
- if let Some(stub_id) = self.stub_symbols.get(&symbol_id) {
- return *stub_id;
- }
- let stub_size = self.architecture.address_size().unwrap().bytes();
-
- let name = b".rdata$.refptr".to_vec();
- let section_id = self.add_section(Vec::new(), name, SectionKind::ReadOnlyData);
- let section = self.section_mut(section_id);
- section.set_data(vec![0; stub_size as usize], u64::from(stub_size));
- section.relocations = vec![Relocation {
- offset: 0,
- size: stub_size * 8,
- kind: RelocationKind::Absolute,
- encoding: RelocationEncoding::Generic,
- symbol: symbol_id,
- addend: 0,
- }];
-
- let mut name = b".refptr.".to_vec();
- name.extend_from_slice(&self.symbol(symbol_id).name);
- let stub_id = self.add_raw_symbol(Symbol {
- name,
- value: 0,
- size: u64::from(stub_size),
- kind: SymbolKind::Data,
- scope: SymbolScope::Compilation,
- weak: false,
- section: SymbolSection::Section(section_id),
- flags: SymbolFlags::None,
- });
- self.stub_symbols.insert(symbol_id, stub_id);
-
- stub_id
- }
-
- /// Appends linker directives to the `.drectve` section to tell the linker
- /// to export all symbols with `SymbolScope::Dynamic`.
- ///
- /// This must be called after all symbols have been defined.
- pub fn add_coff_exports(&mut self, style: CoffExportStyle) {
- assert_eq!(self.format, BinaryFormat::Coff);
-
- let mut directives = vec![];
- for symbol in &self.symbols {
- if symbol.scope == SymbolScope::Dynamic {
- match style {
- CoffExportStyle::Msvc => directives.extend(b" /EXPORT:\""),
- CoffExportStyle::Gnu => directives.extend(b" -export:\""),
- }
- directives.extend(&symbol.name);
- directives.extend(b"\"");
- if symbol.kind != SymbolKind::Text {
- match style {
- CoffExportStyle::Msvc => directives.extend(b",DATA"),
- CoffExportStyle::Gnu => directives.extend(b",data"),
- }
- }
- }
- }
- let drectve = self.add_section(vec![], b".drectve".to_vec(), SectionKind::Linker);
- self.append_section_data(drectve, &directives, 1);
- }
-
- pub(crate) fn coff_write(&self, buffer: &mut dyn WritableBuffer) -> Result<()> {
- let mut writer = writer::Writer::new(buffer);
-
- // Add section strings to strtab.
- let mut section_offsets = vec![SectionOffsets::default(); self.sections.len()];
- for (index, section) in self.sections.iter().enumerate() {
- section_offsets[index].name = writer.add_name(&section.name);
- }
-
- // Set COMDAT flags.
- for comdat in &self.comdats {
- let symbol = &self.symbols[comdat.symbol.0];
- let comdat_section = match symbol.section {
- SymbolSection::Section(id) => id.0,
- _ => {
- return Err(Error(format!(
- "unsupported COMDAT symbol `{}` section {:?}",
- symbol.name().unwrap_or(""),
- symbol.section
- )));
- }
- };
- section_offsets[comdat_section].selection = match comdat.kind {
- ComdatKind::NoDuplicates => coff::IMAGE_COMDAT_SELECT_NODUPLICATES,
- ComdatKind::Any => coff::IMAGE_COMDAT_SELECT_ANY,
- ComdatKind::SameSize => coff::IMAGE_COMDAT_SELECT_SAME_SIZE,
- ComdatKind::ExactMatch => coff::IMAGE_COMDAT_SELECT_EXACT_MATCH,
- ComdatKind::Largest => coff::IMAGE_COMDAT_SELECT_LARGEST,
- ComdatKind::Newest => coff::IMAGE_COMDAT_SELECT_NEWEST,
- ComdatKind::Unknown => {
- return Err(Error(format!(
- "unsupported COMDAT symbol `{}` kind {:?}",
- symbol.name().unwrap_or(""),
- comdat.kind
- )));
- }
- };
- for id in &comdat.sections {
- let section = &self.sections[id.0];
- if section.symbol.is_none() {
- return Err(Error(format!(
- "missing symbol for COMDAT section `{}`",
- section.name().unwrap_or(""),
- )));
- }
- if id.0 != comdat_section {
- section_offsets[id.0].selection = coff::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
- section_offsets[id.0].associative_section = comdat_section as u32 + 1;
- }
- }
- }
-
- // Reserve symbol indices and add symbol strings to strtab.
- let mut symbol_offsets = vec![SymbolOffsets::default(); self.symbols.len()];
- for (index, symbol) in self.symbols.iter().enumerate() {
- symbol_offsets[index].index = writer.reserve_symbol_index();
- let mut name = &*symbol.name;
- match symbol.kind {
- SymbolKind::File => {
- // Name goes in auxiliary symbol records.
- symbol_offsets[index].aux_count = writer.reserve_aux_file_name(&symbol.name);
- name = b".file";
- }
- SymbolKind::Section if symbol.section.id().is_some() => {
- symbol_offsets[index].aux_count = writer.reserve_aux_section();
- }
- _ => {}
- };
- symbol_offsets[index].name = writer.add_name(name);
- }
-
- // Reserve file ranges.
- writer.reserve_file_header();
- writer.reserve_section_headers(self.sections.len() as u16);
- for (index, section) in self.sections.iter().enumerate() {
- section_offsets[index].offset = writer.reserve_section(section.data.len());
- section_offsets[index].reloc_offset =
- writer.reserve_relocations(section.relocations.len());
- }
- writer.reserve_symtab_strtab();
-
- // Start writing.
- writer.write_file_header(writer::FileHeader {
- machine: match (self.architecture, self.sub_architecture) {
- (Architecture::Arm, None) => coff::IMAGE_FILE_MACHINE_ARMNT,
- (Architecture::Aarch64, None) => coff::IMAGE_FILE_MACHINE_ARM64,
- (Architecture::Aarch64, Some(SubArchitecture::Arm64EC)) => {
- coff::IMAGE_FILE_MACHINE_ARM64EC
- }
- (Architecture::I386, None) => coff::IMAGE_FILE_MACHINE_I386,
- (Architecture::X86_64, None) => coff::IMAGE_FILE_MACHINE_AMD64,
- _ => {
- return Err(Error(format!(
- "unimplemented architecture {:?} with sub-architecture {:?}",
- self.architecture, self.sub_architecture
- )));
- }
- },
- time_date_stamp: 0,
- characteristics: match self.flags {
- FileFlags::Coff { characteristics } => characteristics,
- _ => 0,
- },
- })?;
-
- // Write section headers.
- for (index, section) in self.sections.iter().enumerate() {
- let mut characteristics = if let SectionFlags::Coff {
- characteristics, ..
- } = section.flags
- {
- characteristics
- } else {
- match section.kind {
- SectionKind::Text => {
- coff::IMAGE_SCN_CNT_CODE
- | coff::IMAGE_SCN_MEM_EXECUTE
- | coff::IMAGE_SCN_MEM_READ
- }
- SectionKind::Data => {
- coff::IMAGE_SCN_CNT_INITIALIZED_DATA
- | coff::IMAGE_SCN_MEM_READ
- | coff::IMAGE_SCN_MEM_WRITE
- }
- SectionKind::UninitializedData => {
- coff::IMAGE_SCN_CNT_UNINITIALIZED_DATA
- | coff::IMAGE_SCN_MEM_READ
- | coff::IMAGE_SCN_MEM_WRITE
- }
- SectionKind::ReadOnlyData
- | SectionKind::ReadOnlyDataWithRel
- | SectionKind::ReadOnlyString => {
- coff::IMAGE_SCN_CNT_INITIALIZED_DATA | coff::IMAGE_SCN_MEM_READ
- }
- SectionKind::Debug | SectionKind::Other | SectionKind::OtherString => {
- coff::IMAGE_SCN_CNT_INITIALIZED_DATA
- | coff::IMAGE_SCN_MEM_READ
- | coff::IMAGE_SCN_MEM_DISCARDABLE
- }
- SectionKind::Linker => coff::IMAGE_SCN_LNK_INFO | coff::IMAGE_SCN_LNK_REMOVE,
- SectionKind::Common
- | SectionKind::Tls
- | SectionKind::UninitializedTls
- | SectionKind::TlsVariables
- | SectionKind::Note
- | SectionKind::Unknown
- | SectionKind::Metadata
- | SectionKind::Elf(_) => {
- return Err(Error(format!(
- "unimplemented section `{}` kind {:?}",
- section.name().unwrap_or(""),
- section.kind
- )));
- }
- }
- };
- if section_offsets[index].selection != 0 {
- characteristics |= coff::IMAGE_SCN_LNK_COMDAT;
- };
- if section.relocations.len() > 0xffff {
- characteristics |= coff::IMAGE_SCN_LNK_NRELOC_OVFL;
- }
- characteristics |= match section.align {
- 1 => coff::IMAGE_SCN_ALIGN_1BYTES,
- 2 => coff::IMAGE_SCN_ALIGN_2BYTES,
- 4 => coff::IMAGE_SCN_ALIGN_4BYTES,
- 8 => coff::IMAGE_SCN_ALIGN_8BYTES,
- 16 => coff::IMAGE_SCN_ALIGN_16BYTES,
- 32 => coff::IMAGE_SCN_ALIGN_32BYTES,
- 64 => coff::IMAGE_SCN_ALIGN_64BYTES,
- 128 => coff::IMAGE_SCN_ALIGN_128BYTES,
- 256 => coff::IMAGE_SCN_ALIGN_256BYTES,
- 512 => coff::IMAGE_SCN_ALIGN_512BYTES,
- 1024 => coff::IMAGE_SCN_ALIGN_1024BYTES,
- 2048 => coff::IMAGE_SCN_ALIGN_2048BYTES,
- 4096 => coff::IMAGE_SCN_ALIGN_4096BYTES,
- 8192 => coff::IMAGE_SCN_ALIGN_8192BYTES,
- _ => {
- return Err(Error(format!(
- "unimplemented section `{}` align {}",
- section.name().unwrap_or(""),
- section.align
- )));
- }
- };
- writer.write_section_header(writer::SectionHeader {
- name: section_offsets[index].name,
- size_of_raw_data: section.size as u32,
- pointer_to_raw_data: section_offsets[index].offset,
- pointer_to_relocations: section_offsets[index].reloc_offset,
- pointer_to_linenumbers: 0,
- number_of_relocations: section.relocations.len() as u32,
- number_of_linenumbers: 0,
- characteristics,
- });
- }
-
- // Write section data and relocations.
- for section in &self.sections {
- writer.write_section(&section.data);
-
- if !section.relocations.is_empty() {
- //debug_assert_eq!(section_offsets[index].reloc_offset, buffer.len());
- writer.write_relocations_count(section.relocations.len());
- for reloc in &section.relocations {
- //assert!(reloc.implicit_addend);
- let typ = match self.architecture {
- Architecture::I386 => match (reloc.kind, reloc.size, reloc.addend) {
- (RelocationKind::Absolute, 16, 0) => coff::IMAGE_REL_I386_DIR16,
- (RelocationKind::Relative, 16, 0) => coff::IMAGE_REL_I386_REL16,
- (RelocationKind::Absolute, 32, 0) => coff::IMAGE_REL_I386_DIR32,
- (RelocationKind::ImageOffset, 32, 0) => coff::IMAGE_REL_I386_DIR32NB,
- (RelocationKind::SectionIndex, 16, 0) => coff::IMAGE_REL_I386_SECTION,
- (RelocationKind::SectionOffset, 32, 0) => coff::IMAGE_REL_I386_SECREL,
- (RelocationKind::SectionOffset, 7, 0) => coff::IMAGE_REL_I386_SECREL7,
- (RelocationKind::Relative, 32, -4) => coff::IMAGE_REL_I386_REL32,
- (RelocationKind::Coff(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::X86_64 => match (reloc.kind, reloc.size, reloc.addend) {
- (RelocationKind::Absolute, 64, 0) => coff::IMAGE_REL_AMD64_ADDR64,
- (RelocationKind::Absolute, 32, 0) => coff::IMAGE_REL_AMD64_ADDR32,
- (RelocationKind::ImageOffset, 32, 0) => coff::IMAGE_REL_AMD64_ADDR32NB,
- (RelocationKind::Relative, 32, -4) => coff::IMAGE_REL_AMD64_REL32,
- (RelocationKind::Relative, 32, -5) => coff::IMAGE_REL_AMD64_REL32_1,
- (RelocationKind::Relative, 32, -6) => coff::IMAGE_REL_AMD64_REL32_2,
- (RelocationKind::Relative, 32, -7) => coff::IMAGE_REL_AMD64_REL32_3,
- (RelocationKind::Relative, 32, -8) => coff::IMAGE_REL_AMD64_REL32_4,
- (RelocationKind::Relative, 32, -9) => coff::IMAGE_REL_AMD64_REL32_5,
- (RelocationKind::SectionIndex, 16, 0) => coff::IMAGE_REL_AMD64_SECTION,
- (RelocationKind::SectionOffset, 32, 0) => coff::IMAGE_REL_AMD64_SECREL,
- (RelocationKind::SectionOffset, 7, 0) => coff::IMAGE_REL_AMD64_SECREL7,
- (RelocationKind::Coff(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::Arm => match (reloc.kind, reloc.size, reloc.addend) {
- (RelocationKind::Absolute, 32, 0) => coff::IMAGE_REL_ARM_ADDR32,
- (RelocationKind::ImageOffset, 32, 0) => coff::IMAGE_REL_ARM_ADDR32NB,
- (RelocationKind::Relative, 32, -4) => coff::IMAGE_REL_ARM_REL32,
- (RelocationKind::SectionIndex, 16, 0) => coff::IMAGE_REL_ARM_SECTION,
- (RelocationKind::SectionOffset, 32, 0) => coff::IMAGE_REL_ARM_SECREL,
- (RelocationKind::Coff(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::Aarch64 => match (reloc.kind, reloc.size, reloc.addend) {
- (RelocationKind::Absolute, 32, 0) => coff::IMAGE_REL_ARM64_ADDR32,
- (RelocationKind::ImageOffset, 32, 0) => coff::IMAGE_REL_ARM64_ADDR32NB,
- (RelocationKind::SectionIndex, 16, 0) => coff::IMAGE_REL_ARM64_SECTION,
- (RelocationKind::SectionOffset, 32, 0) => coff::IMAGE_REL_ARM64_SECREL,
- (RelocationKind::Absolute, 64, 0) => coff::IMAGE_REL_ARM64_ADDR64,
- (RelocationKind::Relative, 32, -4) => coff::IMAGE_REL_ARM64_REL32,
- (RelocationKind::Coff(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- _ => {
- return Err(Error(format!(
- "unimplemented architecture {:?}",
- self.architecture
- )));
- }
- };
- writer.write_relocation(writer::Relocation {
- virtual_address: reloc.offset as u32,
- symbol: symbol_offsets[reloc.symbol.0].index,
- typ,
- });
- }
- }
- }
-
- // Write symbols.
- for (index, symbol) in self.symbols.iter().enumerate() {
- let section_number = match symbol.section {
- SymbolSection::None => {
- debug_assert_eq!(symbol.kind, SymbolKind::File);
- coff::IMAGE_SYM_DEBUG as u16
- }
- SymbolSection::Undefined => coff::IMAGE_SYM_UNDEFINED as u16,
- SymbolSection::Absolute => coff::IMAGE_SYM_ABSOLUTE as u16,
- SymbolSection::Common => coff::IMAGE_SYM_UNDEFINED as u16,
- SymbolSection::Section(id) => id.0 as u16 + 1,
- };
- let typ = if symbol.kind == SymbolKind::Text {
- coff::IMAGE_SYM_DTYPE_FUNCTION << coff::IMAGE_SYM_DTYPE_SHIFT
- } else {
- coff::IMAGE_SYM_TYPE_NULL
- };
- let storage_class = match symbol.kind {
- SymbolKind::File => coff::IMAGE_SYM_CLASS_FILE,
- SymbolKind::Section => {
- if symbol.section.id().is_some() {
- coff::IMAGE_SYM_CLASS_STATIC
- } else {
- coff::IMAGE_SYM_CLASS_SECTION
- }
- }
- SymbolKind::Label => coff::IMAGE_SYM_CLASS_LABEL,
- SymbolKind::Text | SymbolKind::Data | SymbolKind::Tls => {
- match symbol.section {
- SymbolSection::None => {
- return Err(Error(format!(
- "missing section for symbol `{}`",
- symbol.name().unwrap_or("")
- )));
- }
- SymbolSection::Undefined | SymbolSection::Common => {
- coff::IMAGE_SYM_CLASS_EXTERNAL
- }
- SymbolSection::Absolute | SymbolSection::Section(_) => {
- match symbol.scope {
- // TODO: does this need aux symbol records too?
- _ if symbol.weak => coff::IMAGE_SYM_CLASS_WEAK_EXTERNAL,
- SymbolScope::Unknown => {
- return Err(Error(format!(
- "unimplemented symbol `{}` scope {:?}",
- symbol.name().unwrap_or(""),
- symbol.scope
- )));
- }
- SymbolScope::Compilation => coff::IMAGE_SYM_CLASS_STATIC,
- SymbolScope::Linkage | SymbolScope::Dynamic => {
- coff::IMAGE_SYM_CLASS_EXTERNAL
- }
- }
- }
- }
- }
- SymbolKind::Unknown | SymbolKind::Null => {
- return Err(Error(format!(
- "unimplemented symbol `{}` kind {:?}",
- symbol.name().unwrap_or(""),
- symbol.kind
- )));
- }
- };
- let number_of_aux_symbols = symbol_offsets[index].aux_count;
- let value = if symbol.section == SymbolSection::Common {
- symbol.size as u32
- } else {
- symbol.value as u32
- };
- writer.write_symbol(writer::Symbol {
- name: symbol_offsets[index].name,
- value,
- section_number,
- typ,
- storage_class,
- number_of_aux_symbols,
- });
-
- // Write auxiliary symbols.
- match symbol.kind {
- SymbolKind::File => {
- writer.write_aux_file_name(&symbol.name, number_of_aux_symbols);
- }
- SymbolKind::Section if symbol.section.id().is_some() => {
- debug_assert_eq!(number_of_aux_symbols, 1);
- let section_index = symbol.section.id().unwrap().0;
- let section = &self.sections[section_index];
- writer.write_aux_section(writer::AuxSymbolSection {
- length: section.size as u32,
- number_of_relocations: section.relocations.len() as u32,
- number_of_linenumbers: 0,
- check_sum: checksum(section.data()),
- number: section_offsets[section_index].associative_section,
- selection: section_offsets[section_index].selection,
- });
- }
- _ => {
- debug_assert_eq!(number_of_aux_symbols, 0);
- }
- }
- }
-
- writer.write_strtab();
-
- debug_assert_eq!(writer.reserved_len(), writer.len());
-
- Ok(())
- }
-}
-
-// JamCRC
-fn checksum(data: &[u8]) -> u32 {
- let mut hasher = crc32fast::Hasher::new_with_initial(0xffff_ffff);
- hasher.update(data);
- !hasher.finalize()
-}
diff --git a/vendor/object/src/write/coff/writer.rs b/vendor/object/src/write/coff/writer.rs
deleted file mode 100644
index 8c7ada3..0000000
--- a/vendor/object/src/write/coff/writer.rs
+++ /dev/null
@@ -1,518 +0,0 @@
-//! Helper for writing COFF files.
-use alloc::string::String;
-use alloc::vec::Vec;
-use core::mem;
-
-use crate::endian::{LittleEndian as LE, U16Bytes, U32Bytes, U16, U32};
-use crate::pe;
-use crate::write::string::{StringId, StringTable};
-use crate::write::util;
-use crate::write::{Error, Result, WritableBuffer};
-
-/// A helper for writing COFF files.
-///
-/// Writing uses a two phase approach. The first phase builds up all of the information
-/// that may need to be known ahead of time:
-/// - build string table
-/// - reserve section indices
-/// - reserve symbol indices
-/// - reserve file ranges for headers and sections
-///
-/// Some of the information has ordering requirements. For example, strings must be added
-/// to the string table before reserving the file range for the string table. There are debug
-/// asserts to check some of these requirements.
-///
-/// The second phase writes everything out in order. Thus the caller must ensure writing
-/// is in the same order that file ranges were reserved. There are debug asserts to assist
-/// with checking this.
-#[allow(missing_debug_implementations)]
-pub struct Writer<'a> {
- buffer: &'a mut dyn WritableBuffer,
- len: usize,
-
- section_num: u16,
-
- symtab_offset: u32,
- symtab_num: u32,
-
- strtab: StringTable<'a>,
- strtab_len: usize,
- strtab_offset: u32,
- strtab_data: Vec<u8>,
-}
-
-impl<'a> Writer<'a> {
- /// Create a new `Writer`.
- pub fn new(buffer: &'a mut dyn WritableBuffer) -> Self {
- Writer {
- buffer,
- len: 0,
-
- section_num: 0,
-
- symtab_offset: 0,
- symtab_num: 0,
-
- strtab: StringTable::default(),
- strtab_len: 0,
- strtab_offset: 0,
- strtab_data: Vec::new(),
- }
- }
-
- /// Return the current file length that has been reserved.
- pub fn reserved_len(&self) -> usize {
- self.len
- }
-
- /// Return the current file length that has been written.
- #[allow(clippy::len_without_is_empty)]
- pub fn len(&self) -> usize {
- self.buffer.len()
- }
-
- /// Reserve a file range with the given size and starting alignment.
- ///
- /// Returns the aligned offset of the start of the range.
- pub fn reserve(&mut self, len: usize, align_start: usize) -> u32 {
- if align_start > 1 {
- self.len = util::align(self.len, align_start);
- }
- let offset = self.len;
- self.len += len;
- offset as u32
- }
-
- /// Write alignment padding bytes.
- pub fn write_align(&mut self, align_start: usize) {
- if align_start > 1 {
- util::write_align(self.buffer, align_start);
- }
- }
-
- /// Write data.
- pub fn write(&mut self, data: &[u8]) {
- self.buffer.write_bytes(data);
- }
-
- /// Reserve the file range up to the given file offset.
- pub fn reserve_until(&mut self, offset: usize) {
- debug_assert!(self.len <= offset);
- self.len = offset;
- }
-
- /// Write padding up to the given file offset.
- pub fn pad_until(&mut self, offset: usize) {
- debug_assert!(self.buffer.len() <= offset);
- self.buffer.resize(offset);
- }
-
- /// Reserve the range for the file header.
- ///
- /// This must be at the start of the file.
- pub fn reserve_file_header(&mut self) {
- debug_assert_eq!(self.len, 0);
- self.reserve(mem::size_of::<pe::ImageFileHeader>(), 1);
- }
-
- /// Write the file header.
- ///
- /// This must be at the start of the file.
- ///
- /// Fields that can be derived from known information are automatically set by this function.
- pub fn write_file_header(&mut self, header: FileHeader) -> Result<()> {
- debug_assert_eq!(self.buffer.len(), 0);
-
- // Start writing.
- self.buffer
- .reserve(self.len)
- .map_err(|_| Error(String::from("Cannot allocate buffer")))?;
-
- // Write file header.
- let header = pe::ImageFileHeader {
- machine: U16::new(LE, header.machine),
- number_of_sections: U16::new(LE, self.section_num),
- time_date_stamp: U32::new(LE, header.time_date_stamp),
- pointer_to_symbol_table: U32::new(LE, self.symtab_offset),
- number_of_symbols: U32::new(LE, self.symtab_num),
- size_of_optional_header: U16::default(),
- characteristics: U16::new(LE, header.characteristics),
- };
- self.buffer.write(&header);
-
- Ok(())
- }
-
- /// Reserve the range for the section headers.
- pub fn reserve_section_headers(&mut self, section_num: u16) {
- debug_assert_eq!(self.section_num, 0);
- self.section_num = section_num;
- self.reserve(
- section_num as usize * mem::size_of::<pe::ImageSectionHeader>(),
- 1,
- );
- }
-
- /// Write a section header.
- pub fn write_section_header(&mut self, section: SectionHeader) {
- let mut coff_section = pe::ImageSectionHeader {
- name: [0; 8],
- virtual_size: U32::default(),
- virtual_address: U32::default(),
- size_of_raw_data: U32::new(LE, section.size_of_raw_data),
- pointer_to_raw_data: U32::new(LE, section.pointer_to_raw_data),
- pointer_to_relocations: U32::new(LE, section.pointer_to_relocations),
- pointer_to_linenumbers: U32::new(LE, section.pointer_to_linenumbers),
- number_of_relocations: if section.number_of_relocations > 0xffff {
- U16::new(LE, 0xffff)
- } else {
- U16::new(LE, section.number_of_relocations as u16)
- },
- number_of_linenumbers: U16::default(),
- characteristics: U32::new(LE, section.characteristics),
- };
- match section.name {
- Name::Short(name) => coff_section.name = name,
- Name::Long(str_id) => {
- let mut str_offset = self.strtab.get_offset(str_id);
- if str_offset <= 9_999_999 {
- let mut name = [0; 7];
- let mut len = 0;
- if str_offset == 0 {
- name[6] = b'0';
- len = 1;
- } else {
- while str_offset != 0 {
- let rem = (str_offset % 10) as u8;
- str_offset /= 10;
- name[6 - len] = b'0' + rem;
- len += 1;
- }
- }
- coff_section.name = [0; 8];
- coff_section.name[0] = b'/';
- coff_section.name[1..][..len].copy_from_slice(&name[7 - len..]);
- } else {
- debug_assert!(str_offset as u64 <= 0xf_ffff_ffff);
- coff_section.name[0] = b'/';
- coff_section.name[1] = b'/';
- for i in 0..6 {
- let rem = (str_offset % 64) as u8;
- str_offset /= 64;
- let c = match rem {
- 0..=25 => b'A' + rem,
- 26..=51 => b'a' + rem - 26,
- 52..=61 => b'0' + rem - 52,
- 62 => b'+',
- 63 => b'/',
- _ => unreachable!(),
- };
- coff_section.name[7 - i] = c;
- }
- }
- }
- }
- self.buffer.write(&coff_section);
- }
-
- /// Reserve the range for the section data.
- ///
- /// Returns the aligned offset of the start of the range.
- /// Does nothing and returns 0 if the length is zero.
- pub fn reserve_section(&mut self, len: usize) -> u32 {
- if len == 0 {
- return 0;
- }
- // TODO: not sure what alignment is required here, but this seems to match LLVM
- self.reserve(len, 4)
- }
-
- /// Write the alignment bytes prior to section data.
- ///
- /// This is unneeded if you are using `write_section` or `write_section_zeroes`
- /// for the data.
- pub fn write_section_align(&mut self) {
- util::write_align(self.buffer, 4);
- }
-
- /// Write the section data.
- ///
- /// Writes alignment bytes prior to the data.
- /// Does nothing if the data is empty.
- pub fn write_section(&mut self, data: &[u8]) {
- if data.is_empty() {
- return;
- }
- self.write_section_align();
- self.buffer.write_bytes(data);
- }
-
- /// Write the section data using zero bytes.
- ///
- /// Writes alignment bytes prior to the data.
- /// Does nothing if the length is zero.
- pub fn write_section_zeroes(&mut self, len: usize) {
- if len == 0 {
- return;
- }
- self.write_section_align();
- self.buffer.resize(self.buffer.len() + len);
- }
-
- /// Reserve a file range for the given number of relocations.
- ///
- /// This will automatically reserve an extra relocation if there are more than 0xffff.
- ///
- /// Returns the offset of the range.
- /// Does nothing and returns 0 if the count is zero.
- pub fn reserve_relocations(&mut self, mut count: usize) -> u32 {
- if count == 0 {
- return 0;
- }
- if count > 0xffff {
- count += 1;
- }
- self.reserve(count * mem::size_of::<pe::ImageRelocation>(), 1)
- }
-
- /// Write a relocation containing the count if required.
- ///
- /// This should be called before writing the first relocation for a section.
- pub fn write_relocations_count(&mut self, count: usize) {
- if count > 0xffff {
- let coff_relocation = pe::ImageRelocation {
- virtual_address: U32Bytes::new(LE, count as u32 + 1),
- symbol_table_index: U32Bytes::new(LE, 0),
- typ: U16Bytes::new(LE, 0),
- };
- self.buffer.write(&coff_relocation);
- }
- }
-
- /// Write a relocation.
- pub fn write_relocation(&mut self, reloc: Relocation) {
- let coff_relocation = pe::ImageRelocation {
- virtual_address: U32Bytes::new(LE, reloc.virtual_address),
- symbol_table_index: U32Bytes::new(LE, reloc.symbol),
- typ: U16Bytes::new(LE, reloc.typ),
- };
- self.buffer.write(&coff_relocation);
- }
-
- /// Reserve a symbol table entry.
- ///
- /// This must be called before [`Self::reserve_symtab_strtab`].
- pub fn reserve_symbol_index(&mut self) -> u32 {
- debug_assert_eq!(self.symtab_offset, 0);
- let index = self.symtab_num;
- self.symtab_num += 1;
- index
- }
-
- /// Reserve a number of symbol table entries.
- pub fn reserve_symbol_indices(&mut self, count: u32) {
- debug_assert_eq!(self.symtab_offset, 0);
- self.symtab_num += count;
- }
-
- /// Write a symbol table entry.
- pub fn write_symbol(&mut self, symbol: Symbol) {
- let mut coff_symbol = pe::ImageSymbol {
- name: [0; 8],
- value: U32Bytes::new(LE, symbol.value),
- section_number: U16Bytes::new(LE, symbol.section_number),
- typ: U16Bytes::new(LE, symbol.typ),
- storage_class: symbol.storage_class,
- number_of_aux_symbols: symbol.number_of_aux_symbols,
- };
- match symbol.name {
- Name::Short(name) => coff_symbol.name = name,
- Name::Long(str_id) => {
- let str_offset = self.strtab.get_offset(str_id);
- coff_symbol.name[4..8].copy_from_slice(&u32::to_le_bytes(str_offset as u32));
- }
- }
- self.buffer.write(&coff_symbol);
- }
-
- /// Reserve auxiliary symbols for a file name.
- ///
- /// Returns the number of auxiliary symbols required.
- ///
- /// This must be called before [`Self::reserve_symtab_strtab`].
- pub fn reserve_aux_file_name(&mut self, name: &[u8]) -> u8 {
- debug_assert_eq!(self.symtab_offset, 0);
- let aux_count = (name.len() + pe::IMAGE_SIZEOF_SYMBOL - 1) / pe::IMAGE_SIZEOF_SYMBOL;
- self.symtab_num += aux_count as u32;
- aux_count as u8
- }
-
- /// Write auxiliary symbols for a file name.
- pub fn write_aux_file_name(&mut self, name: &[u8], aux_count: u8) {
- let aux_len = aux_count as usize * pe::IMAGE_SIZEOF_SYMBOL;
- debug_assert!(aux_len >= name.len());
- let old_len = self.buffer.len();
- self.buffer.write_bytes(name);
- self.buffer.resize(old_len + aux_len);
- }
-
- /// Reserve an auxiliary symbol for a section.
- ///
- /// Returns the number of auxiliary symbols required.
- ///
- /// This must be called before [`Self::reserve_symtab_strtab`].
- pub fn reserve_aux_section(&mut self) -> u8 {
- debug_assert_eq!(self.symtab_offset, 0);
- self.symtab_num += 1;
- 1
- }
-
- /// Write an auxiliary symbol for a section.
- pub fn write_aux_section(&mut self, section: AuxSymbolSection) {
- let aux = pe::ImageAuxSymbolSection {
- length: U32Bytes::new(LE, section.length),
- number_of_relocations: if section.number_of_relocations > 0xffff {
- U16Bytes::new(LE, 0xffff)
- } else {
- U16Bytes::new(LE, section.number_of_relocations as u16)
- },
- number_of_linenumbers: U16Bytes::new(LE, section.number_of_linenumbers),
- check_sum: U32Bytes::new(LE, section.check_sum),
- number: U16Bytes::new(LE, section.number as u16),
- selection: section.selection,
- reserved: 0,
- high_number: U16Bytes::new(LE, (section.number >> 16) as u16),
- };
- self.buffer.write(&aux);
- }
-
- /// Return the number of reserved symbol table entries.
- pub fn symbol_count(&self) -> u32 {
- self.symtab_num
- }
-
- /// Add a string to the string table.
- ///
- /// This must be called before [`Self::reserve_symtab_strtab`].
- pub fn add_string(&mut self, name: &'a [u8]) -> StringId {
- debug_assert_eq!(self.strtab_offset, 0);
- self.strtab.add(name)
- }
-
- /// Add a section or symbol name to the string table if required.
- ///
- /// This must be called before [`Self::reserve_symtab_strtab`].
- pub fn add_name(&mut self, name: &'a [u8]) -> Name {
- if name.len() > 8 {
- Name::Long(self.add_string(name))
- } else {
- let mut short_name = [0; 8];
- short_name[..name.len()].copy_from_slice(name);
- Name::Short(short_name)
- }
- }
-
- /// Reserve the range for the symbol table and string table.
- ///
- /// This must be called after functions that reserve symbol
- /// indices or add strings.
- pub fn reserve_symtab_strtab(&mut self) {
- debug_assert_eq!(self.symtab_offset, 0);
- self.symtab_offset = self.reserve(self.symtab_num as usize * pe::IMAGE_SIZEOF_SYMBOL, 1);
-
- debug_assert_eq!(self.strtab_offset, 0);
- // First 4 bytes of strtab are the length.
- self.strtab.write(4, &mut self.strtab_data);
- self.strtab_len = self.strtab_data.len() + 4;
- self.strtab_offset = self.reserve(self.strtab_len, 1);
- }
-
- /// Write the string table.
- pub fn write_strtab(&mut self) {
- debug_assert_eq!(self.strtab_offset, self.buffer.len() as u32);
- self.buffer
- .write_bytes(&u32::to_le_bytes(self.strtab_len as u32));
- self.buffer.write_bytes(&self.strtab_data);
- }
-}
-
-/// Shortened and native endian version of [`pe::ImageFileHeader`].
-#[allow(missing_docs)]
-#[derive(Debug, Default, Clone)]
-pub struct FileHeader {
- pub machine: u16,
- pub time_date_stamp: u32,
- pub characteristics: u16,
-}
-
-/// A section or symbol name.
-#[derive(Debug, Clone, Copy)]
-pub enum Name {
- /// An inline name.
- Short([u8; 8]),
- /// An id of a string table entry.
- Long(StringId),
-}
-
-impl Default for Name {
- fn default() -> Name {
- Name::Short([0; 8])
- }
-}
-
-// From isn't useful.
-#[allow(clippy::from_over_into)]
-impl<'a> Into<Name> for &'a [u8; 8] {
- fn into(self) -> Name {
- Name::Short(*self)
- }
-}
-
-/// Native endian version of [`pe::ImageSectionHeader`].
-#[allow(missing_docs)]
-#[derive(Debug, Default, Clone)]
-pub struct SectionHeader {
- pub name: Name,
- pub size_of_raw_data: u32,
- pub pointer_to_raw_data: u32,
- pub pointer_to_relocations: u32,
- pub pointer_to_linenumbers: u32,
- /// This will automatically be clamped if there are more than 0xffff.
- pub number_of_relocations: u32,
- pub number_of_linenumbers: u16,
- pub characteristics: u32,
-}
-
-/// Native endian version of [`pe::ImageSymbol`].
-#[allow(missing_docs)]
-#[derive(Debug, Default, Clone)]
-pub struct Symbol {
- pub name: Name,
- pub value: u32,
- pub section_number: u16,
- pub typ: u16,
- pub storage_class: u8,
- pub number_of_aux_symbols: u8,
-}
-
-/// Native endian version of [`pe::ImageAuxSymbolSection`].
-#[allow(missing_docs)]
-#[derive(Debug, Default, Clone)]
-pub struct AuxSymbolSection {
- pub length: u32,
- /// This will automatically be clamped if there are more than 0xffff.
- pub number_of_relocations: u32,
- pub number_of_linenumbers: u16,
- pub check_sum: u32,
- pub number: u32,
- pub selection: u8,
-}
-
-/// Native endian version of [`pe::ImageRelocation`].
-#[allow(missing_docs)]
-#[derive(Debug, Default, Clone)]
-pub struct Relocation {
- pub virtual_address: u32,
- pub symbol: u32,
- pub typ: u16,
-}
diff --git a/vendor/object/src/write/elf/mod.rs b/vendor/object/src/write/elf/mod.rs
deleted file mode 100644
index 3a4f371..0000000
--- a/vendor/object/src/write/elf/mod.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//! Support for writing ELF files.
-//!
-//! Provides [`Writer`] for low level writing of ELF files.
-//! This is also used to provide ELF support for [`write::Object`](crate::write::Object).
-
-mod object;
-
-mod writer;
-pub use writer::*;
diff --git a/vendor/object/src/write/elf/object.rs b/vendor/object/src/write/elf/object.rs
deleted file mode 100644
index 5d7a93e..0000000
--- a/vendor/object/src/write/elf/object.rs
+++ /dev/null
@@ -1,907 +0,0 @@
-use alloc::vec::Vec;
-
-use crate::write::elf::writer::*;
-use crate::write::string::StringId;
-use crate::write::*;
-use crate::AddressSize;
-use crate::{elf, pod};
-
-#[derive(Clone, Copy)]
-struct ComdatOffsets {
- offset: usize,
- str_id: StringId,
-}
-
-#[derive(Clone, Copy)]
-struct SectionOffsets {
- index: SectionIndex,
- offset: usize,
- str_id: StringId,
- reloc_offset: usize,
- reloc_str_id: Option<StringId>,
-}
-
-#[derive(Default, Clone, Copy)]
-struct SymbolOffsets {
- index: SymbolIndex,
- str_id: Option<StringId>,
-}
-
-// Public methods.
-impl<'a> Object<'a> {
- /// Add a property with a u32 value to the ELF ".note.gnu.property" section.
- ///
- /// Requires `feature = "elf"`.
- pub fn add_elf_gnu_property_u32(&mut self, property: u32, value: u32) {
- if self.format != BinaryFormat::Elf {
- return;
- }
-
- let align = if self.elf_is_64() { 8 } else { 4 };
- let mut data = Vec::with_capacity(32);
- let n_name = b"GNU\0";
- data.extend_from_slice(pod::bytes_of(&elf::NoteHeader32 {
- n_namesz: U32::new(self.endian, n_name.len() as u32),
- n_descsz: U32::new(self.endian, util::align(3 * 4, align) as u32),
- n_type: U32::new(self.endian, elf::NT_GNU_PROPERTY_TYPE_0),
- }));
- data.extend_from_slice(n_name);
- // This happens to already be aligned correctly.
- debug_assert_eq!(util::align(data.len(), align), data.len());
- data.extend_from_slice(pod::bytes_of(&U32::new(self.endian, property)));
- // Value size
- data.extend_from_slice(pod::bytes_of(&U32::new(self.endian, 4)));
- data.extend_from_slice(pod::bytes_of(&U32::new(self.endian, value)));
- util::write_align(&mut data, align);
-
- let section = self.section_id(StandardSection::GnuProperty);
- self.append_section_data(section, &data, align as u64);
- }
-}
-
-// Private methods.
-impl<'a> Object<'a> {
- pub(crate) fn elf_section_info(
- &self,
- section: StandardSection,
- ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) {
- match section {
- StandardSection::Text => (&[], &b".text"[..], SectionKind::Text, SectionFlags::None),
- StandardSection::Data => (&[], &b".data"[..], SectionKind::Data, SectionFlags::None),
- StandardSection::ReadOnlyData | StandardSection::ReadOnlyString => (
- &[],
- &b".rodata"[..],
- SectionKind::ReadOnlyData,
- SectionFlags::None,
- ),
- StandardSection::ReadOnlyDataWithRel => (
- &[],
- b".data.rel.ro",
- SectionKind::ReadOnlyDataWithRel,
- SectionFlags::None,
- ),
- StandardSection::UninitializedData => (
- &[],
- &b".bss"[..],
- SectionKind::UninitializedData,
- SectionFlags::None,
- ),
- StandardSection::Tls => (&[], &b".tdata"[..], SectionKind::Tls, SectionFlags::None),
- StandardSection::UninitializedTls => (
- &[],
- &b".tbss"[..],
- SectionKind::UninitializedTls,
- SectionFlags::None,
- ),
- StandardSection::TlsVariables => {
- // Unsupported section.
- (&[], &[], SectionKind::TlsVariables, SectionFlags::None)
- }
- StandardSection::Common => {
- // Unsupported section.
- (&[], &[], SectionKind::Common, SectionFlags::None)
- }
- StandardSection::GnuProperty => (
- &[],
- &b".note.gnu.property"[..],
- SectionKind::Note,
- SectionFlags::Elf {
- sh_flags: u64::from(elf::SHF_ALLOC),
- },
- ),
- }
- }
-
- pub(crate) fn elf_subsection_name(&self, section: &[u8], value: &[u8]) -> Vec<u8> {
- let mut name = section.to_vec();
- name.push(b'.');
- name.extend_from_slice(value);
- name
- }
-
- fn elf_has_relocation_addend(&self) -> Result<bool> {
- Ok(match self.architecture {
- Architecture::Aarch64 => true,
- Architecture::Aarch64_Ilp32 => true,
- Architecture::Arm => false,
- Architecture::Avr => true,
- Architecture::Bpf => false,
- Architecture::Csky => true,
- Architecture::I386 => false,
- Architecture::X86_64 => true,
- Architecture::X86_64_X32 => true,
- Architecture::Hexagon => true,
- Architecture::LoongArch64 => true,
- Architecture::Mips => false,
- Architecture::Mips64 => true,
- Architecture::Msp430 => true,
- Architecture::PowerPc => true,
- Architecture::PowerPc64 => true,
- Architecture::Riscv64 => true,
- Architecture::Riscv32 => true,
- Architecture::S390x => true,
- Architecture::Sbf => false,
- Architecture::Sharc => true,
- Architecture::Sparc64 => true,
- Architecture::Xtensa => true,
- _ => {
- return Err(Error(format!(
- "unimplemented architecture {:?}",
- self.architecture
- )));
- }
- })
- }
-
- pub(crate) fn elf_fixup_relocation(&mut self, relocation: &mut Relocation) -> Result<i64> {
- // Determine whether the addend is stored in the relocation or the data.
- if self.elf_has_relocation_addend()? {
- Ok(0)
- } else {
- let constant = relocation.addend;
- relocation.addend = 0;
- Ok(constant)
- }
- }
-
- pub(crate) fn elf_is_64(&self) -> bool {
- match self.architecture.address_size().unwrap() {
- AddressSize::U8 | AddressSize::U16 | AddressSize::U32 => false,
- AddressSize::U64 => true,
- }
- }
-
- pub(crate) fn elf_write(&self, buffer: &mut dyn WritableBuffer) -> Result<()> {
- // Create reloc section header names so we can reference them.
- let is_rela = self.elf_has_relocation_addend()?;
- let reloc_names: Vec<_> = self
- .sections
- .iter()
- .map(|section| {
- let mut reloc_name = Vec::with_capacity(
- if is_rela { ".rela".len() } else { ".rel".len() } + section.name.len(),
- );
- if !section.relocations.is_empty() {
- reloc_name.extend_from_slice(if is_rela {
- &b".rela"[..]
- } else {
- &b".rel"[..]
- });
- reloc_name.extend_from_slice(&section.name);
- }
- reloc_name
- })
- .collect();
-
- // Start calculating offsets of everything.
- let mut writer = Writer::new(self.endian, self.elf_is_64(), buffer);
- writer.reserve_file_header();
-
- // Calculate size of section data.
- let mut comdat_offsets = Vec::with_capacity(self.comdats.len());
- for comdat in &self.comdats {
- if comdat.kind != ComdatKind::Any {
- return Err(Error(format!(
- "unsupported COMDAT symbol `{}` kind {:?}",
- self.symbols[comdat.symbol.0].name().unwrap_or(""),
- comdat.kind
- )));
- }
-
- writer.reserve_section_index();
- let offset = writer.reserve_comdat(comdat.sections.len());
- let str_id = writer.add_section_name(b".group");
- comdat_offsets.push(ComdatOffsets { offset, str_id });
- }
- let mut section_offsets = Vec::with_capacity(self.sections.len());
- for (section, reloc_name) in self.sections.iter().zip(reloc_names.iter()) {
- let index = writer.reserve_section_index();
- let offset = writer.reserve(section.data.len(), section.align as usize);
- let str_id = writer.add_section_name(&section.name);
- let mut reloc_str_id = None;
- if !section.relocations.is_empty() {
- writer.reserve_section_index();
- reloc_str_id = Some(writer.add_section_name(reloc_name));
- }
- section_offsets.push(SectionOffsets {
- index,
- offset,
- str_id,
- // Relocation data is reserved later.
- reloc_offset: 0,
- reloc_str_id,
- });
- }
-
- // Calculate index of symbols and add symbol strings to strtab.
- let mut symbol_offsets = vec![SymbolOffsets::default(); self.symbols.len()];
- writer.reserve_null_symbol_index();
- // Local symbols must come before global.
- for (index, symbol) in self.symbols.iter().enumerate() {
- if symbol.is_local() {
- let section_index = symbol.section.id().map(|s| section_offsets[s.0].index);
- symbol_offsets[index].index = writer.reserve_symbol_index(section_index);
- }
- }
- let symtab_num_local = writer.symbol_count();
- for (index, symbol) in self.symbols.iter().enumerate() {
- if !symbol.is_local() {
- let section_index = symbol.section.id().map(|s| section_offsets[s.0].index);
- symbol_offsets[index].index = writer.reserve_symbol_index(section_index);
- }
- }
- for (index, symbol) in self.symbols.iter().enumerate() {
- if symbol.kind != SymbolKind::Section && !symbol.name.is_empty() {
- symbol_offsets[index].str_id = Some(writer.add_string(&symbol.name));
- }
- }
-
- // Calculate size of symbols.
- writer.reserve_symtab_section_index();
- writer.reserve_symtab();
- if writer.symtab_shndx_needed() {
- writer.reserve_symtab_shndx_section_index();
- }
- writer.reserve_symtab_shndx();
- writer.reserve_strtab_section_index();
- writer.reserve_strtab();
-
- // Calculate size of relocations.
- for (index, section) in self.sections.iter().enumerate() {
- let count = section.relocations.len();
- if count != 0 {
- section_offsets[index].reloc_offset = writer.reserve_relocations(count, is_rela);
- }
- }
-
- // Calculate size of section headers.
- writer.reserve_shstrtab_section_index();
- writer.reserve_shstrtab();
- writer.reserve_section_headers();
-
- // Start writing.
- let e_type = elf::ET_REL;
- let e_machine = match (self.architecture, self.sub_architecture) {
- (Architecture::Aarch64, None) => elf::EM_AARCH64,
- (Architecture::Aarch64_Ilp32, None) => elf::EM_AARCH64,
- (Architecture::Arm, None) => elf::EM_ARM,
- (Architecture::Avr, None) => elf::EM_AVR,
- (Architecture::Bpf, None) => elf::EM_BPF,
- (Architecture::Csky, None) => elf::EM_CSKY,
- (Architecture::I386, None) => elf::EM_386,
- (Architecture::X86_64, None) => elf::EM_X86_64,
- (Architecture::X86_64_X32, None) => elf::EM_X86_64,
- (Architecture::Hexagon, None) => elf::EM_HEXAGON,
- (Architecture::LoongArch64, None) => elf::EM_LOONGARCH,
- (Architecture::Mips, None) => elf::EM_MIPS,
- (Architecture::Mips64, None) => elf::EM_MIPS,
- (Architecture::Msp430, None) => elf::EM_MSP430,
- (Architecture::PowerPc, None) => elf::EM_PPC,
- (Architecture::PowerPc64, None) => elf::EM_PPC64,
- (Architecture::Riscv32, None) => elf::EM_RISCV,
- (Architecture::Riscv64, None) => elf::EM_RISCV,
- (Architecture::S390x, None) => elf::EM_S390,
- (Architecture::Sbf, None) => elf::EM_SBF,
- (Architecture::Sharc, None) => elf::EM_SHARC,
- (Architecture::Sparc64, None) => elf::EM_SPARCV9,
- (Architecture::Xtensa, None) => elf::EM_XTENSA,
- _ => {
- return Err(Error(format!(
- "unimplemented architecture {:?} with sub-architecture {:?}",
- self.architecture, self.sub_architecture
- )));
- }
- };
- let (os_abi, abi_version, e_flags) = if let FileFlags::Elf {
- os_abi,
- abi_version,
- e_flags,
- } = self.flags
- {
- (os_abi, abi_version, e_flags)
- } else {
- (elf::ELFOSABI_NONE, 0, 0)
- };
- writer.write_file_header(&FileHeader {
- os_abi,
- abi_version,
- e_type,
- e_machine,
- e_entry: 0,
- e_flags,
- })?;
-
- // Write section data.
- for comdat in &self.comdats {
- writer.write_comdat_header();
- for section in &comdat.sections {
- writer.write_comdat_entry(section_offsets[section.0].index);
- }
- }
- for (index, section) in self.sections.iter().enumerate() {
- writer.write_align(section.align as usize);
- debug_assert_eq!(section_offsets[index].offset, writer.len());
- writer.write(&section.data);
- }
-
- // Write symbols.
- writer.write_null_symbol();
- let mut write_symbol = |index: usize, symbol: &Symbol| -> Result<()> {
- let st_info = if let SymbolFlags::Elf { st_info, .. } = symbol.flags {
- st_info
- } else {
- let st_type = match symbol.kind {
- SymbolKind::Null => elf::STT_NOTYPE,
- SymbolKind::Text => {
- if symbol.is_undefined() {
- elf::STT_NOTYPE
- } else {
- elf::STT_FUNC
- }
- }
- SymbolKind::Data => {
- if symbol.is_undefined() {
- elf::STT_NOTYPE
- } else if symbol.is_common() {
- elf::STT_COMMON
- } else {
- elf::STT_OBJECT
- }
- }
- SymbolKind::Section => elf::STT_SECTION,
- SymbolKind::File => elf::STT_FILE,
- SymbolKind::Tls => elf::STT_TLS,
- SymbolKind::Label => elf::STT_NOTYPE,
- SymbolKind::Unknown => {
- if symbol.is_undefined() {
- elf::STT_NOTYPE
- } else {
- return Err(Error(format!(
- "unimplemented symbol `{}` kind {:?}",
- symbol.name().unwrap_or(""),
- symbol.kind
- )));
- }
- }
- };
- let st_bind = if symbol.weak {
- elf::STB_WEAK
- } else if symbol.is_undefined() {
- elf::STB_GLOBAL
- } else if symbol.is_local() {
- elf::STB_LOCAL
- } else {
- elf::STB_GLOBAL
- };
- (st_bind << 4) + st_type
- };
- let st_other = if let SymbolFlags::Elf { st_other, .. } = symbol.flags {
- st_other
- } else if symbol.scope == SymbolScope::Linkage {
- elf::STV_HIDDEN
- } else {
- elf::STV_DEFAULT
- };
- let (st_shndx, section) = match symbol.section {
- SymbolSection::None => {
- debug_assert_eq!(symbol.kind, SymbolKind::File);
- (elf::SHN_ABS, None)
- }
- SymbolSection::Undefined => (elf::SHN_UNDEF, None),
- SymbolSection::Absolute => (elf::SHN_ABS, None),
- SymbolSection::Common => (elf::SHN_COMMON, None),
- SymbolSection::Section(id) => (0, Some(section_offsets[id.0].index)),
- };
- writer.write_symbol(&Sym {
- name: symbol_offsets[index].str_id,
- section,
- st_info,
- st_other,
- st_shndx,
- st_value: symbol.value,
- st_size: symbol.size,
- });
- Ok(())
- };
- for (index, symbol) in self.symbols.iter().enumerate() {
- if symbol.is_local() {
- write_symbol(index, symbol)?;
- }
- }
- for (index, symbol) in self.symbols.iter().enumerate() {
- if !symbol.is_local() {
- write_symbol(index, symbol)?;
- }
- }
- writer.write_symtab_shndx();
- writer.write_strtab();
-
- // Write relocations.
- for (index, section) in self.sections.iter().enumerate() {
- if !section.relocations.is_empty() {
- writer.write_align_relocation();
- debug_assert_eq!(section_offsets[index].reloc_offset, writer.len());
- for reloc in &section.relocations {
- let r_type = match self.architecture {
- Architecture::Aarch64 => match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, RelocationEncoding::Generic, 64) => {
- elf::R_AARCH64_ABS64
- }
- (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => {
- elf::R_AARCH64_ABS32
- }
- (RelocationKind::Absolute, RelocationEncoding::Generic, 16) => {
- elf::R_AARCH64_ABS16
- }
- (RelocationKind::Relative, RelocationEncoding::Generic, 64) => {
- elf::R_AARCH64_PREL64
- }
- (RelocationKind::Relative, RelocationEncoding::Generic, 32) => {
- elf::R_AARCH64_PREL32
- }
- (RelocationKind::Relative, RelocationEncoding::Generic, 16) => {
- elf::R_AARCH64_PREL16
- }
- (RelocationKind::Relative, RelocationEncoding::AArch64Call, 26)
- | (RelocationKind::PltRelative, RelocationEncoding::AArch64Call, 26) => {
- elf::R_AARCH64_CALL26
- }
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::Aarch64_Ilp32 => {
- match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => {
- elf::R_AARCH64_P32_ABS32
- }
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!(
- "unimplemented relocation {:?}",
- reloc
- )));
- }
- }
- }
- Architecture::Arm => match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, _, 32) => elf::R_ARM_ABS32,
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::Avr => match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, _, 32) => elf::R_AVR_32,
- (RelocationKind::Absolute, _, 16) => elf::R_AVR_16,
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::Bpf => match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, _, 64) => elf::R_BPF_64_64,
- (RelocationKind::Absolute, _, 32) => elf::R_BPF_64_32,
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::Csky => match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, _, 32) => elf::R_CKCORE_ADDR32,
- (RelocationKind::Relative, RelocationEncoding::Generic, 32) => {
- elf::R_CKCORE_PCREL32
- }
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::I386 => match (reloc.kind, reloc.size) {
- (RelocationKind::Absolute, 32) => elf::R_386_32,
- (RelocationKind::Relative, 32) => elf::R_386_PC32,
- (RelocationKind::Got, 32) => elf::R_386_GOT32,
- (RelocationKind::PltRelative, 32) => elf::R_386_PLT32,
- (RelocationKind::GotBaseOffset, 32) => elf::R_386_GOTOFF,
- (RelocationKind::GotBaseRelative, 32) => elf::R_386_GOTPC,
- (RelocationKind::Absolute, 16) => elf::R_386_16,
- (RelocationKind::Relative, 16) => elf::R_386_PC16,
- (RelocationKind::Absolute, 8) => elf::R_386_8,
- (RelocationKind::Relative, 8) => elf::R_386_PC8,
- (RelocationKind::Elf(x), _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::X86_64 | Architecture::X86_64_X32 => {
- match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, RelocationEncoding::Generic, 64) => {
- elf::R_X86_64_64
- }
- (RelocationKind::Relative, RelocationEncoding::X86Branch, 32) => {
- elf::R_X86_64_PLT32
- }
- (RelocationKind::Relative, _, 32) => elf::R_X86_64_PC32,
- (RelocationKind::Got, _, 32) => elf::R_X86_64_GOT32,
- (RelocationKind::PltRelative, _, 32) => elf::R_X86_64_PLT32,
- (RelocationKind::GotRelative, _, 32) => elf::R_X86_64_GOTPCREL,
- (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => {
- elf::R_X86_64_32
- }
- (RelocationKind::Absolute, RelocationEncoding::X86Signed, 32) => {
- elf::R_X86_64_32S
- }
- (RelocationKind::Absolute, _, 16) => elf::R_X86_64_16,
- (RelocationKind::Relative, _, 16) => elf::R_X86_64_PC16,
- (RelocationKind::Absolute, _, 8) => elf::R_X86_64_8,
- (RelocationKind::Relative, _, 8) => elf::R_X86_64_PC8,
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!(
- "unimplemented relocation {:?}",
- reloc
- )));
- }
- }
- }
- Architecture::Hexagon => match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, _, 32) => elf::R_HEX_32,
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::LoongArch64 => match (reloc.kind, reloc.encoding, reloc.size)
- {
- (RelocationKind::Absolute, _, 32) => elf::R_LARCH_32,
- (RelocationKind::Absolute, _, 64) => elf::R_LARCH_64,
- (RelocationKind::Relative, _, 32) => elf::R_LARCH_32_PCREL,
- (RelocationKind::Relative, _, 64) => elf::R_LARCH_64_PCREL,
- (RelocationKind::Relative, RelocationEncoding::LoongArchBranch, 16)
- | (
- RelocationKind::PltRelative,
- RelocationEncoding::LoongArchBranch,
- 16,
- ) => elf::R_LARCH_B16,
- (RelocationKind::Relative, RelocationEncoding::LoongArchBranch, 21)
- | (
- RelocationKind::PltRelative,
- RelocationEncoding::LoongArchBranch,
- 21,
- ) => elf::R_LARCH_B21,
- (RelocationKind::Relative, RelocationEncoding::LoongArchBranch, 26)
- | (
- RelocationKind::PltRelative,
- RelocationEncoding::LoongArchBranch,
- 26,
- ) => elf::R_LARCH_B26,
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::Mips | Architecture::Mips64 => {
- match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, _, 16) => elf::R_MIPS_16,
- (RelocationKind::Absolute, _, 32) => elf::R_MIPS_32,
- (RelocationKind::Absolute, _, 64) => elf::R_MIPS_64,
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!(
- "unimplemented relocation {:?}",
- reloc
- )));
- }
- }
- }
- Architecture::Msp430 => match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, _, 32) => elf::R_MSP430_32,
- (RelocationKind::Absolute, _, 16) => elf::R_MSP430_16_BYTE,
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::PowerPc => match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, _, 32) => elf::R_PPC_ADDR32,
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::PowerPc64 => match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, _, 32) => elf::R_PPC64_ADDR32,
- (RelocationKind::Absolute, _, 64) => elf::R_PPC64_ADDR64,
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::Riscv32 | Architecture::Riscv64 => {
- match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, _, 32) => elf::R_RISCV_32,
- (RelocationKind::Absolute, _, 64) => elf::R_RISCV_64,
- (RelocationKind::Relative, RelocationEncoding::Generic, 32) => {
- elf::R_RISCV_32_PCREL
- }
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!(
- "unimplemented relocation {:?}",
- reloc
- )));
- }
- }
- }
- Architecture::S390x => match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, RelocationEncoding::Generic, 8) => {
- elf::R_390_8
- }
- (RelocationKind::Absolute, RelocationEncoding::Generic, 16) => {
- elf::R_390_16
- }
- (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => {
- elf::R_390_32
- }
- (RelocationKind::Absolute, RelocationEncoding::Generic, 64) => {
- elf::R_390_64
- }
- (RelocationKind::Relative, RelocationEncoding::Generic, 16) => {
- elf::R_390_PC16
- }
- (RelocationKind::Relative, RelocationEncoding::Generic, 32) => {
- elf::R_390_PC32
- }
- (RelocationKind::Relative, RelocationEncoding::Generic, 64) => {
- elf::R_390_PC64
- }
- (RelocationKind::Relative, RelocationEncoding::S390xDbl, 16) => {
- elf::R_390_PC16DBL
- }
- (RelocationKind::Relative, RelocationEncoding::S390xDbl, 32) => {
- elf::R_390_PC32DBL
- }
- (RelocationKind::PltRelative, RelocationEncoding::S390xDbl, 16) => {
- elf::R_390_PLT16DBL
- }
- (RelocationKind::PltRelative, RelocationEncoding::S390xDbl, 32) => {
- elf::R_390_PLT32DBL
- }
- (RelocationKind::Got, RelocationEncoding::Generic, 16) => {
- elf::R_390_GOT16
- }
- (RelocationKind::Got, RelocationEncoding::Generic, 32) => {
- elf::R_390_GOT32
- }
- (RelocationKind::Got, RelocationEncoding::Generic, 64) => {
- elf::R_390_GOT64
- }
- (RelocationKind::GotRelative, RelocationEncoding::S390xDbl, 32) => {
- elf::R_390_GOTENT
- }
- (RelocationKind::GotBaseOffset, RelocationEncoding::Generic, 16) => {
- elf::R_390_GOTOFF16
- }
- (RelocationKind::GotBaseOffset, RelocationEncoding::Generic, 32) => {
- elf::R_390_GOTOFF32
- }
- (RelocationKind::GotBaseOffset, RelocationEncoding::Generic, 64) => {
- elf::R_390_GOTOFF64
- }
- (RelocationKind::GotBaseRelative, RelocationEncoding::Generic, 64) => {
- elf::R_390_GOTPC
- }
- (RelocationKind::GotBaseRelative, RelocationEncoding::S390xDbl, 32) => {
- elf::R_390_GOTPCDBL
- }
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::Sbf => match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, _, 64) => elf::R_SBF_64_64,
- (RelocationKind::Absolute, _, 32) => elf::R_SBF_64_32,
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::Sharc => match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 32) => {
- elf::R_SHARC_ADDR32_V3
- }
- (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => {
- elf::R_SHARC_ADDR_VAR_V3
- }
- (RelocationKind::Relative, RelocationEncoding::SharcTypeA, 24) => {
- elf::R_SHARC_PCRLONG_V3
- }
- (RelocationKind::Relative, RelocationEncoding::SharcTypeA, 6) => {
- elf::R_SHARC_PCRSHORT_V3
- }
- (RelocationKind::Relative, RelocationEncoding::SharcTypeB, 6) => {
- elf::R_SHARC_PCRSHORT_V3
- }
- (RelocationKind::Absolute, RelocationEncoding::Generic, 16) => {
- elf::R_SHARC_ADDR_VAR16_V3
- }
- (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 16) => {
- elf::R_SHARC_DATA16_V3
- }
- (RelocationKind::Absolute, RelocationEncoding::SharcTypeB, 16) => {
- elf::R_SHARC_DATA16_VISA_V3
- }
- (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 24) => {
- elf::R_SHARC_ADDR24_V3
- }
- (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 6) => {
- elf::R_SHARC_DATA6_V3
- }
- (RelocationKind::Absolute, RelocationEncoding::SharcTypeB, 6) => {
- elf::R_SHARC_DATA6_VISA_V3
- }
- (RelocationKind::Absolute, RelocationEncoding::SharcTypeB, 7) => {
- elf::R_SHARC_DATA7_VISA_V3
- }
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::Sparc64 => match (reloc.kind, reloc.encoding, reloc.size) {
- // TODO: use R_SPARC_32/R_SPARC_64 if aligned.
- (RelocationKind::Absolute, _, 32) => elf::R_SPARC_UA32,
- (RelocationKind::Absolute, _, 64) => elf::R_SPARC_UA64,
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::Xtensa => match (reloc.kind, reloc.encoding, reloc.size) {
- (RelocationKind::Absolute, _, 32) => elf::R_XTENSA_32,
- (RelocationKind::Relative, RelocationEncoding::Generic, 32) => {
- elf::R_XTENSA_32_PCREL
- }
- (RelocationKind::Elf(x), _, _) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- _ => {
- if let RelocationKind::Elf(x) = reloc.kind {
- x
- } else {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- }
- };
- let r_sym = symbol_offsets[reloc.symbol.0].index.0;
- writer.write_relocation(
- is_rela,
- &Rel {
- r_offset: reloc.offset,
- r_sym,
- r_type,
- r_addend: reloc.addend,
- },
- );
- }
- }
- }
-
- writer.write_shstrtab();
-
- // Write section headers.
- writer.write_null_section_header();
-
- let symtab_index = writer.symtab_index();
- for (comdat, comdat_offset) in self.comdats.iter().zip(comdat_offsets.iter()) {
- writer.write_comdat_section_header(
- comdat_offset.str_id,
- symtab_index,
- symbol_offsets[comdat.symbol.0].index,
- comdat_offset.offset,
- comdat.sections.len(),
- );
- }
- for (index, section) in self.sections.iter().enumerate() {
- let sh_type = match section.kind {
- SectionKind::UninitializedData | SectionKind::UninitializedTls => elf::SHT_NOBITS,
- SectionKind::Note => elf::SHT_NOTE,
- SectionKind::Elf(sh_type) => sh_type,
- _ => elf::SHT_PROGBITS,
- };
- let sh_flags = if let SectionFlags::Elf { sh_flags } = section.flags {
- sh_flags
- } else {
- match section.kind {
- SectionKind::Text => elf::SHF_ALLOC | elf::SHF_EXECINSTR,
- SectionKind::Data | SectionKind::ReadOnlyDataWithRel => {
- elf::SHF_ALLOC | elf::SHF_WRITE
- }
- SectionKind::Tls => elf::SHF_ALLOC | elf::SHF_WRITE | elf::SHF_TLS,
- SectionKind::UninitializedData => elf::SHF_ALLOC | elf::SHF_WRITE,
- SectionKind::UninitializedTls => elf::SHF_ALLOC | elf::SHF_WRITE | elf::SHF_TLS,
- SectionKind::ReadOnlyData => elf::SHF_ALLOC,
- SectionKind::ReadOnlyString => {
- elf::SHF_ALLOC | elf::SHF_STRINGS | elf::SHF_MERGE
- }
- SectionKind::OtherString => elf::SHF_STRINGS | elf::SHF_MERGE,
- SectionKind::Other
- | SectionKind::Debug
- | SectionKind::Metadata
- | SectionKind::Linker
- | SectionKind::Note
- | SectionKind::Elf(_) => 0,
- SectionKind::Unknown | SectionKind::Common | SectionKind::TlsVariables => {
- return Err(Error(format!(
- "unimplemented section `{}` kind {:?}",
- section.name().unwrap_or(""),
- section.kind
- )));
- }
- }
- .into()
- };
- // TODO: not sure if this is correct, maybe user should determine this
- let sh_entsize = match section.kind {
- SectionKind::ReadOnlyString | SectionKind::OtherString => 1,
- _ => 0,
- };
- writer.write_section_header(&SectionHeader {
- name: Some(section_offsets[index].str_id),
- sh_type,
- sh_flags,
- sh_addr: 0,
- sh_offset: section_offsets[index].offset as u64,
- sh_size: section.size,
- sh_link: 0,
- sh_info: 0,
- sh_addralign: section.align,
- sh_entsize,
- });
-
- if !section.relocations.is_empty() {
- writer.write_relocation_section_header(
- section_offsets[index].reloc_str_id.unwrap(),
- section_offsets[index].index,
- symtab_index,
- section_offsets[index].reloc_offset,
- section.relocations.len(),
- is_rela,
- );
- }
- }
-
- writer.write_symtab_section_header(symtab_num_local);
- writer.write_symtab_shndx_section_header();
- writer.write_strtab_section_header();
- writer.write_shstrtab_section_header();
-
- debug_assert_eq!(writer.reserved_len(), writer.len());
-
- Ok(())
- }
-}
diff --git a/vendor/object/src/write/elf/writer.rs b/vendor/object/src/write/elf/writer.rs
deleted file mode 100644
index 9750924..0000000
--- a/vendor/object/src/write/elf/writer.rs
+++ /dev/null
@@ -1,2143 +0,0 @@
-//! Helper for writing ELF files.
-use alloc::string::String;
-use alloc::vec::Vec;
-use core::mem;
-
-use crate::elf;
-use crate::endian::*;
-use crate::pod;
-use crate::write::string::{StringId, StringTable};
-use crate::write::util;
-use crate::write::{Error, Result, WritableBuffer};
-
-/// The index of an ELF section.
-#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct SectionIndex(pub u32);
-
-/// The index of an ELF symbol.
-#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct SymbolIndex(pub u32);
-
-/// A helper for writing ELF files.
-///
-/// Writing uses a two phase approach. The first phase builds up all of the information
-/// that may need to be known ahead of time:
-/// - build string tables
-/// - reserve section indices
-/// - reserve symbol indices
-/// - reserve file ranges for headers and sections
-///
-/// Some of the information has ordering requirements. For example, strings must be added
-/// to string tables before reserving the file range for the string table. Symbol indices
-/// must be reserved after reserving the section indices they reference. There are debug
-/// asserts to check some of these requirements.
-///
-/// The second phase writes everything out in order. Thus the caller must ensure writing
-/// is in the same order that file ranges were reserved. There are debug asserts to assist
-/// with checking this.
-#[allow(missing_debug_implementations)]
-pub struct Writer<'a> {
- endian: Endianness,
- is_64: bool,
- is_mips64el: bool,
- elf_align: usize,
-
- buffer: &'a mut dyn WritableBuffer,
- len: usize,
-
- segment_offset: usize,
- segment_num: u32,
-
- section_offset: usize,
- section_num: u32,
-
- shstrtab: StringTable<'a>,
- shstrtab_str_id: Option<StringId>,
- shstrtab_index: SectionIndex,
- shstrtab_offset: usize,
- shstrtab_data: Vec<u8>,
-
- need_strtab: bool,
- strtab: StringTable<'a>,
- strtab_str_id: Option<StringId>,
- strtab_index: SectionIndex,
- strtab_offset: usize,
- strtab_data: Vec<u8>,
-
- symtab_str_id: Option<StringId>,
- symtab_index: SectionIndex,
- symtab_offset: usize,
- symtab_num: u32,
-
- need_symtab_shndx: bool,
- symtab_shndx_str_id: Option<StringId>,
- symtab_shndx_offset: usize,
- symtab_shndx_data: Vec<u8>,
-
- need_dynstr: bool,
- dynstr: StringTable<'a>,
- dynstr_str_id: Option<StringId>,
- dynstr_index: SectionIndex,
- dynstr_offset: usize,
- dynstr_data: Vec<u8>,
-
- dynsym_str_id: Option<StringId>,
- dynsym_index: SectionIndex,
- dynsym_offset: usize,
- dynsym_num: u32,
-
- dynamic_str_id: Option<StringId>,
- dynamic_offset: usize,
- dynamic_num: usize,
-
- hash_str_id: Option<StringId>,
- hash_offset: usize,
- hash_size: usize,
-
- gnu_hash_str_id: Option<StringId>,
- gnu_hash_offset: usize,
- gnu_hash_size: usize,
-
- gnu_versym_str_id: Option<StringId>,
- gnu_versym_offset: usize,
-
- gnu_verdef_str_id: Option<StringId>,
- gnu_verdef_offset: usize,
- gnu_verdef_size: usize,
- gnu_verdef_count: u16,
- gnu_verdef_remaining: u16,
- gnu_verdaux_remaining: u16,
-
- gnu_verneed_str_id: Option<StringId>,
- gnu_verneed_offset: usize,
- gnu_verneed_size: usize,
- gnu_verneed_count: u16,
- gnu_verneed_remaining: u16,
- gnu_vernaux_remaining: u16,
-
- gnu_attributes_str_id: Option<StringId>,
- gnu_attributes_offset: usize,
- gnu_attributes_size: usize,
-}
-
-impl<'a> Writer<'a> {
- /// Create a new `Writer` for the given endianness and ELF class.
- pub fn new(endian: Endianness, is_64: bool, buffer: &'a mut dyn WritableBuffer) -> Self {
- let elf_align = if is_64 { 8 } else { 4 };
- Writer {
- endian,
- is_64,
- // Determined later.
- is_mips64el: false,
- elf_align,
-
- buffer,
- len: 0,
-
- segment_offset: 0,
- segment_num: 0,
-
- section_offset: 0,
- section_num: 0,
-
- shstrtab: StringTable::default(),
- shstrtab_str_id: None,
- shstrtab_index: SectionIndex(0),
- shstrtab_offset: 0,
- shstrtab_data: Vec::new(),
-
- need_strtab: false,
- strtab: StringTable::default(),
- strtab_str_id: None,
- strtab_index: SectionIndex(0),
- strtab_offset: 0,
- strtab_data: Vec::new(),
-
- symtab_str_id: None,
- symtab_index: SectionIndex(0),
- symtab_offset: 0,
- symtab_num: 0,
-
- need_symtab_shndx: false,
- symtab_shndx_str_id: None,
- symtab_shndx_offset: 0,
- symtab_shndx_data: Vec::new(),
-
- need_dynstr: false,
- dynstr: StringTable::default(),
- dynstr_str_id: None,
- dynstr_index: SectionIndex(0),
- dynstr_offset: 0,
- dynstr_data: Vec::new(),
-
- dynsym_str_id: None,
- dynsym_index: SectionIndex(0),
- dynsym_offset: 0,
- dynsym_num: 0,
-
- dynamic_str_id: None,
- dynamic_offset: 0,
- dynamic_num: 0,
-
- hash_str_id: None,
- hash_offset: 0,
- hash_size: 0,
-
- gnu_hash_str_id: None,
- gnu_hash_offset: 0,
- gnu_hash_size: 0,
-
- gnu_versym_str_id: None,
- gnu_versym_offset: 0,
-
- gnu_verdef_str_id: None,
- gnu_verdef_offset: 0,
- gnu_verdef_size: 0,
- gnu_verdef_count: 0,
- gnu_verdef_remaining: 0,
- gnu_verdaux_remaining: 0,
-
- gnu_verneed_str_id: None,
- gnu_verneed_offset: 0,
- gnu_verneed_size: 0,
- gnu_verneed_count: 0,
- gnu_verneed_remaining: 0,
- gnu_vernaux_remaining: 0,
-
- gnu_attributes_str_id: None,
- gnu_attributes_offset: 0,
- gnu_attributes_size: 0,
- }
- }
-
- /// Return the current file length that has been reserved.
- pub fn reserved_len(&self) -> usize {
- self.len
- }
-
- /// Return the current file length that has been written.
- #[allow(clippy::len_without_is_empty)]
- pub fn len(&self) -> usize {
- self.buffer.len()
- }
-
- /// Reserve a file range with the given size and starting alignment.
- ///
- /// Returns the aligned offset of the start of the range.
- pub fn reserve(&mut self, len: usize, align_start: usize) -> usize {
- if align_start > 1 {
- self.len = util::align(self.len, align_start);
- }
- let offset = self.len;
- self.len += len;
- offset
- }
-
- /// Write alignment padding bytes.
- pub fn write_align(&mut self, align_start: usize) {
- if align_start > 1 {
- util::write_align(self.buffer, align_start);
- }
- }
-
- /// Write data.
- ///
- /// This is typically used to write section data.
- pub fn write(&mut self, data: &[u8]) {
- self.buffer.write_bytes(data);
- }
-
- /// Reserve the file range up to the given file offset.
- pub fn reserve_until(&mut self, offset: usize) {
- debug_assert!(self.len <= offset);
- self.len = offset;
- }
-
- /// Write padding up to the given file offset.
- pub fn pad_until(&mut self, offset: usize) {
- debug_assert!(self.buffer.len() <= offset);
- self.buffer.resize(offset);
- }
-
- fn file_header_size(&self) -> usize {
- if self.is_64 {
- mem::size_of::<elf::FileHeader64<Endianness>>()
- } else {
- mem::size_of::<elf::FileHeader32<Endianness>>()
- }
- }
-
- /// Reserve the range for the file header.
- ///
- /// This must be at the start of the file.
- pub fn reserve_file_header(&mut self) {
- debug_assert_eq!(self.len, 0);
- self.reserve(self.file_header_size(), 1);
- }
-
- /// Write the file header.
- ///
- /// This must be at the start of the file.
- ///
- /// Fields that can be derived from known information are automatically set by this function.
- pub fn write_file_header(&mut self, header: &FileHeader) -> Result<()> {
- debug_assert_eq!(self.buffer.len(), 0);
-
- self.is_mips64el =
- self.is_64 && self.endian.is_little_endian() && header.e_machine == elf::EM_MIPS;
-
- // Start writing.
- self.buffer
- .reserve(self.len)
- .map_err(|_| Error(String::from("Cannot allocate buffer")))?;
-
- // Write file header.
- let e_ident = elf::Ident {
- magic: elf::ELFMAG,
- class: if self.is_64 {
- elf::ELFCLASS64
- } else {
- elf::ELFCLASS32
- },
- data: if self.endian.is_little_endian() {
- elf::ELFDATA2LSB
- } else {
- elf::ELFDATA2MSB
- },
- version: elf::EV_CURRENT,
- os_abi: header.os_abi,
- abi_version: header.abi_version,
- padding: [0; 7],
- };
-
- let e_ehsize = self.file_header_size() as u16;
-
- let e_phoff = self.segment_offset as u64;
- let e_phentsize = if self.segment_num == 0 {
- 0
- } else {
- self.program_header_size() as u16
- };
- // TODO: overflow
- let e_phnum = self.segment_num as u16;
-
- let e_shoff = self.section_offset as u64;
- let e_shentsize = if self.section_num == 0 {
- 0
- } else {
- self.section_header_size() as u16
- };
- let e_shnum = if self.section_num >= elf::SHN_LORESERVE.into() {
- 0
- } else {
- self.section_num as u16
- };
- let e_shstrndx = if self.shstrtab_index.0 >= elf::SHN_LORESERVE.into() {
- elf::SHN_XINDEX
- } else {
- self.shstrtab_index.0 as u16
- };
-
- let endian = self.endian;
- if self.is_64 {
- let file = elf::FileHeader64 {
- e_ident,
- e_type: U16::new(endian, header.e_type),
- e_machine: U16::new(endian, header.e_machine),
- e_version: U32::new(endian, elf::EV_CURRENT.into()),
- e_entry: U64::new(endian, header.e_entry),
- e_phoff: U64::new(endian, e_phoff),
- e_shoff: U64::new(endian, e_shoff),
- e_flags: U32::new(endian, header.e_flags),
- e_ehsize: U16::new(endian, e_ehsize),
- e_phentsize: U16::new(endian, e_phentsize),
- e_phnum: U16::new(endian, e_phnum),
- e_shentsize: U16::new(endian, e_shentsize),
- e_shnum: U16::new(endian, e_shnum),
- e_shstrndx: U16::new(endian, e_shstrndx),
- };
- self.buffer.write(&file)
- } else {
- let file = elf::FileHeader32 {
- e_ident,
- e_type: U16::new(endian, header.e_type),
- e_machine: U16::new(endian, header.e_machine),
- e_version: U32::new(endian, elf::EV_CURRENT.into()),
- e_entry: U32::new(endian, header.e_entry as u32),
- e_phoff: U32::new(endian, e_phoff as u32),
- e_shoff: U32::new(endian, e_shoff as u32),
- e_flags: U32::new(endian, header.e_flags),
- e_ehsize: U16::new(endian, e_ehsize),
- e_phentsize: U16::new(endian, e_phentsize),
- e_phnum: U16::new(endian, e_phnum),
- e_shentsize: U16::new(endian, e_shentsize),
- e_shnum: U16::new(endian, e_shnum),
- e_shstrndx: U16::new(endian, e_shstrndx),
- };
- self.buffer.write(&file);
- }
-
- Ok(())
- }
-
- fn program_header_size(&self) -> usize {
- if self.is_64 {
- mem::size_of::<elf::ProgramHeader64<Endianness>>()
- } else {
- mem::size_of::<elf::ProgramHeader32<Endianness>>()
- }
- }
-
- /// Reserve the range for the program headers.
- pub fn reserve_program_headers(&mut self, num: u32) {
- debug_assert_eq!(self.segment_offset, 0);
- if num == 0 {
- return;
- }
- self.segment_num = num;
- self.segment_offset =
- self.reserve(num as usize * self.program_header_size(), self.elf_align);
- }
-
- /// Write alignment padding bytes prior to the program headers.
- pub fn write_align_program_headers(&mut self) {
- if self.segment_offset == 0 {
- return;
- }
- util::write_align(self.buffer, self.elf_align);
- debug_assert_eq!(self.segment_offset, self.buffer.len());
- }
-
- /// Write a program header.
- pub fn write_program_header(&mut self, header: &ProgramHeader) {
- let endian = self.endian;
- if self.is_64 {
- let header = elf::ProgramHeader64 {
- p_type: U32::new(endian, header.p_type),
- p_flags: U32::new(endian, header.p_flags),
- p_offset: U64::new(endian, header.p_offset),
- p_vaddr: U64::new(endian, header.p_vaddr),
- p_paddr: U64::new(endian, header.p_paddr),
- p_filesz: U64::new(endian, header.p_filesz),
- p_memsz: U64::new(endian, header.p_memsz),
- p_align: U64::new(endian, header.p_align),
- };
- self.buffer.write(&header);
- } else {
- let header = elf::ProgramHeader32 {
- p_type: U32::new(endian, header.p_type),
- p_offset: U32::new(endian, header.p_offset as u32),
- p_vaddr: U32::new(endian, header.p_vaddr as u32),
- p_paddr: U32::new(endian, header.p_paddr as u32),
- p_filesz: U32::new(endian, header.p_filesz as u32),
- p_memsz: U32::new(endian, header.p_memsz as u32),
- p_flags: U32::new(endian, header.p_flags),
- p_align: U32::new(endian, header.p_align as u32),
- };
- self.buffer.write(&header);
- }
- }
-
- /// Reserve the section index for the null section header.
- ///
- /// The null section header is usually automatically reserved,
- /// but this can be used to force an empty section table.
- ///
- /// This must be called before [`Self::reserve_section_headers`].
- pub fn reserve_null_section_index(&mut self) -> SectionIndex {
- debug_assert_eq!(self.section_num, 0);
- if self.section_num == 0 {
- self.section_num = 1;
- }
- SectionIndex(0)
- }
-
- /// Reserve a section table index.
- ///
- /// Automatically also reserves the null section header if required.
- ///
- /// This must be called before [`Self::reserve_section_headers`].
- pub fn reserve_section_index(&mut self) -> SectionIndex {
- debug_assert_eq!(self.section_offset, 0);
- if self.section_num == 0 {
- self.section_num = 1;
- }
- let index = self.section_num;
- self.section_num += 1;
- SectionIndex(index)
- }
-
- fn section_header_size(&self) -> usize {
- if self.is_64 {
- mem::size_of::<elf::SectionHeader64<Endianness>>()
- } else {
- mem::size_of::<elf::SectionHeader32<Endianness>>()
- }
- }
-
- /// Reserve the range for the section headers.
- ///
- /// This function does nothing if no sections were reserved.
- /// This must be called after [`Self::reserve_section_index`]
- /// and other functions that reserve section indices.
- pub fn reserve_section_headers(&mut self) {
- debug_assert_eq!(self.section_offset, 0);
- if self.section_num == 0 {
- return;
- }
- self.section_offset = self.reserve(
- self.section_num as usize * self.section_header_size(),
- self.elf_align,
- );
- }
-
- /// Write the null section header.
- ///
- /// This must be the first section header that is written.
- /// This function does nothing if no sections were reserved.
- pub fn write_null_section_header(&mut self) {
- if self.section_num == 0 {
- return;
- }
- util::write_align(self.buffer, self.elf_align);
- debug_assert_eq!(self.section_offset, self.buffer.len());
- self.write_section_header(&SectionHeader {
- name: None,
- sh_type: 0,
- sh_flags: 0,
- sh_addr: 0,
- sh_offset: 0,
- sh_size: if self.section_num >= elf::SHN_LORESERVE.into() {
- self.section_num.into()
- } else {
- 0
- },
- sh_link: if self.shstrtab_index.0 >= elf::SHN_LORESERVE.into() {
- self.shstrtab_index.0
- } else {
- 0
- },
- // TODO: e_phnum overflow
- sh_info: 0,
- sh_addralign: 0,
- sh_entsize: 0,
- });
- }
-
- /// Write a section header.
- pub fn write_section_header(&mut self, section: &SectionHeader) {
- let sh_name = if let Some(name) = section.name {
- self.shstrtab.get_offset(name) as u32
- } else {
- 0
- };
- let endian = self.endian;
- if self.is_64 {
- let section = elf::SectionHeader64 {
- sh_name: U32::new(endian, sh_name),
- sh_type: U32::new(endian, section.sh_type),
- sh_flags: U64::new(endian, section.sh_flags),
- sh_addr: U64::new(endian, section.sh_addr),
- sh_offset: U64::new(endian, section.sh_offset),
- sh_size: U64::new(endian, section.sh_size),
- sh_link: U32::new(endian, section.sh_link),
- sh_info: U32::new(endian, section.sh_info),
- sh_addralign: U64::new(endian, section.sh_addralign),
- sh_entsize: U64::new(endian, section.sh_entsize),
- };
- self.buffer.write(&section);
- } else {
- let section = elf::SectionHeader32 {
- sh_name: U32::new(endian, sh_name),
- sh_type: U32::new(endian, section.sh_type),
- sh_flags: U32::new(endian, section.sh_flags as u32),
- sh_addr: U32::new(endian, section.sh_addr as u32),
- sh_offset: U32::new(endian, section.sh_offset as u32),
- sh_size: U32::new(endian, section.sh_size as u32),
- sh_link: U32::new(endian, section.sh_link),
- sh_info: U32::new(endian, section.sh_info),
- sh_addralign: U32::new(endian, section.sh_addralign as u32),
- sh_entsize: U32::new(endian, section.sh_entsize as u32),
- };
- self.buffer.write(&section);
- }
- }
-
- /// Add a section name to the section header string table.
- ///
- /// This will be stored in the `.shstrtab` section.
- ///
- /// This must be called before [`Self::reserve_shstrtab`].
- pub fn add_section_name(&mut self, name: &'a [u8]) -> StringId {
- debug_assert_eq!(self.shstrtab_offset, 0);
- self.shstrtab.add(name)
- }
-
- /// Reserve the range for the section header string table.
- ///
- /// This range is used for a section named `.shstrtab`.
- ///
- /// This function does nothing if no sections were reserved.
- /// This must be called after [`Self::add_section_name`].
- /// and other functions that reserve section names and indices.
- pub fn reserve_shstrtab(&mut self) {
- debug_assert_eq!(self.shstrtab_offset, 0);
- if self.section_num == 0 {
- return;
- }
- // Start with null section name.
- self.shstrtab_data = vec![0];
- self.shstrtab.write(1, &mut self.shstrtab_data);
- self.shstrtab_offset = self.reserve(self.shstrtab_data.len(), 1);
- }
-
- /// Write the section header string table.
- ///
- /// This function does nothing if the section was not reserved.
- pub fn write_shstrtab(&mut self) {
- if self.shstrtab_offset == 0 {
- return;
- }
- debug_assert_eq!(self.shstrtab_offset, self.buffer.len());
- self.buffer.write_bytes(&self.shstrtab_data);
- }
-
- /// Reserve the section index for the section header string table.
- ///
- /// This must be called before [`Self::reserve_shstrtab`]
- /// and [`Self::reserve_section_headers`].
- pub fn reserve_shstrtab_section_index(&mut self) -> SectionIndex {
- debug_assert_eq!(self.shstrtab_index, SectionIndex(0));
- self.shstrtab_str_id = Some(self.add_section_name(&b".shstrtab"[..]));
- self.shstrtab_index = self.reserve_section_index();
- self.shstrtab_index
- }
-
- /// Write the section header for the section header string table.
- ///
- /// This function does nothing if the section index was not reserved.
- pub fn write_shstrtab_section_header(&mut self) {
- if self.shstrtab_index == SectionIndex(0) {
- return;
- }
- self.write_section_header(&SectionHeader {
- name: self.shstrtab_str_id,
- sh_type: elf::SHT_STRTAB,
- sh_flags: 0,
- sh_addr: 0,
- sh_offset: self.shstrtab_offset as u64,
- sh_size: self.shstrtab_data.len() as u64,
- sh_link: 0,
- sh_info: 0,
- sh_addralign: 1,
- sh_entsize: 0,
- });
- }
-
- /// Add a string to the string table.
- ///
- /// This will be stored in the `.strtab` section.
- ///
- /// This must be called before [`Self::reserve_strtab`].
- pub fn add_string(&mut self, name: &'a [u8]) -> StringId {
- debug_assert_eq!(self.strtab_offset, 0);
- self.need_strtab = true;
- self.strtab.add(name)
- }
-
- /// Return true if `.strtab` is needed.
- pub fn strtab_needed(&self) -> bool {
- self.need_strtab
- }
-
- /// Reserve the range for the string table.
- ///
- /// This range is used for a section named `.strtab`.
- ///
- /// This function does nothing if no strings or symbols were defined.
- /// This must be called after [`Self::add_string`].
- pub fn reserve_strtab(&mut self) {
- debug_assert_eq!(self.strtab_offset, 0);
- if !self.need_strtab {
- return;
- }
- // Start with null string.
- self.strtab_data = vec![0];
- self.strtab.write(1, &mut self.strtab_data);
- self.strtab_offset = self.reserve(self.strtab_data.len(), 1);
- }
-
- /// Write the string table.
- ///
- /// This function does nothing if the section was not reserved.
- pub fn write_strtab(&mut self) {
- if self.strtab_offset == 0 {
- return;
- }
- debug_assert_eq!(self.strtab_offset, self.buffer.len());
- self.buffer.write_bytes(&self.strtab_data);
- }
-
- /// Reserve the section index for the string table.
- ///
- /// This must be called before [`Self::reserve_section_headers`].
- pub fn reserve_strtab_section_index(&mut self) -> SectionIndex {
- debug_assert_eq!(self.strtab_index, SectionIndex(0));
- self.strtab_str_id = Some(self.add_section_name(&b".strtab"[..]));
- self.strtab_index = self.reserve_section_index();
- self.strtab_index
- }
-
- /// Write the section header for the string table.
- ///
- /// This function does nothing if the section index was not reserved.
- pub fn write_strtab_section_header(&mut self) {
- if self.strtab_index == SectionIndex(0) {
- return;
- }
- self.write_section_header(&SectionHeader {
- name: self.strtab_str_id,
- sh_type: elf::SHT_STRTAB,
- sh_flags: 0,
- sh_addr: 0,
- sh_offset: self.strtab_offset as u64,
- sh_size: self.strtab_data.len() as u64,
- sh_link: 0,
- sh_info: 0,
- sh_addralign: 1,
- sh_entsize: 0,
- });
- }
-
- /// Reserve the null symbol table entry.
- ///
- /// This will be stored in the `.symtab` section.
- ///
- /// The null symbol table entry is usually automatically reserved,
- /// but this can be used to force an empty symbol table.
- ///
- /// This must be called before [`Self::reserve_symtab`].
- pub fn reserve_null_symbol_index(&mut self) -> SymbolIndex {
- debug_assert_eq!(self.symtab_offset, 0);
- debug_assert_eq!(self.symtab_num, 0);
- self.symtab_num = 1;
- // The symtab must link to a strtab.
- self.need_strtab = true;
- SymbolIndex(0)
- }
-
- /// Reserve a symbol table entry.
- ///
- /// This will be stored in the `.symtab` section.
- ///
- /// `section_index` is used to determine whether `.symtab_shndx` is required.
- ///
- /// Automatically also reserves the null symbol if required.
- /// Callers may assume that the returned indices will be sequential
- /// starting at 1.
- ///
- /// This must be called before [`Self::reserve_symtab`] and
- /// [`Self::reserve_symtab_shndx`].
- pub fn reserve_symbol_index(&mut self, section_index: Option<SectionIndex>) -> SymbolIndex {
- debug_assert_eq!(self.symtab_offset, 0);
- debug_assert_eq!(self.symtab_shndx_offset, 0);
- if self.symtab_num == 0 {
- self.symtab_num = 1;
- // The symtab must link to a strtab.
- self.need_strtab = true;
- }
- let index = self.symtab_num;
- self.symtab_num += 1;
- if let Some(section_index) = section_index {
- if section_index.0 >= elf::SHN_LORESERVE.into() {
- self.need_symtab_shndx = true;
- }
- }
- SymbolIndex(index)
- }
-
- /// Return the number of reserved symbol table entries.
- ///
- /// Includes the null symbol.
- pub fn symbol_count(&self) -> u32 {
- self.symtab_num
- }
-
- fn symbol_size(&self) -> usize {
- if self.is_64 {
- mem::size_of::<elf::Sym64<Endianness>>()
- } else {
- mem::size_of::<elf::Sym32<Endianness>>()
- }
- }
-
- /// Reserve the range for the symbol table.
- ///
- /// This range is used for a section named `.symtab`.
- /// This function does nothing if no symbols were reserved.
- /// This must be called after [`Self::reserve_symbol_index`].
- pub fn reserve_symtab(&mut self) {
- debug_assert_eq!(self.symtab_offset, 0);
- if self.symtab_num == 0 {
- return;
- }
- self.symtab_offset = self.reserve(
- self.symtab_num as usize * self.symbol_size(),
- self.elf_align,
- );
- }
-
- /// Write the null symbol.
- ///
- /// This must be the first symbol that is written.
- /// This function does nothing if no symbols were reserved.
- pub fn write_null_symbol(&mut self) {
- if self.symtab_num == 0 {
- return;
- }
- util::write_align(self.buffer, self.elf_align);
- debug_assert_eq!(self.symtab_offset, self.buffer.len());
- if self.is_64 {
- self.buffer.write(&elf::Sym64::<Endianness>::default());
- } else {
- self.buffer.write(&elf::Sym32::<Endianness>::default());
- }
-
- if self.need_symtab_shndx {
- self.symtab_shndx_data.write_pod(&U32::new(self.endian, 0));
- }
- }
-
- /// Write a symbol.
- pub fn write_symbol(&mut self, sym: &Sym) {
- let st_name = if let Some(name) = sym.name {
- self.strtab.get_offset(name) as u32
- } else {
- 0
- };
- let st_shndx = if let Some(section) = sym.section {
- if section.0 >= elf::SHN_LORESERVE as u32 {
- elf::SHN_XINDEX
- } else {
- section.0 as u16
- }
- } else {
- sym.st_shndx
- };
-
- let endian = self.endian;
- if self.is_64 {
- let sym = elf::Sym64 {
- st_name: U32::new(endian, st_name),
- st_info: sym.st_info,
- st_other: sym.st_other,
- st_shndx: U16::new(endian, st_shndx),
- st_value: U64::new(endian, sym.st_value),
- st_size: U64::new(endian, sym.st_size),
- };
- self.buffer.write(&sym);
- } else {
- let sym = elf::Sym32 {
- st_name: U32::new(endian, st_name),
- st_info: sym.st_info,
- st_other: sym.st_other,
- st_shndx: U16::new(endian, st_shndx),
- st_value: U32::new(endian, sym.st_value as u32),
- st_size: U32::new(endian, sym.st_size as u32),
- };
- self.buffer.write(&sym);
- }
-
- if self.need_symtab_shndx {
- let section_index = sym.section.unwrap_or(SectionIndex(0));
- self.symtab_shndx_data
- .write_pod(&U32::new(self.endian, section_index.0));
- }
- }
-
- /// Reserve the section index for the symbol table.
- ///
- /// This must be called before [`Self::reserve_section_headers`].
- pub fn reserve_symtab_section_index(&mut self) -> SectionIndex {
- debug_assert_eq!(self.symtab_index, SectionIndex(0));
- self.symtab_str_id = Some(self.add_section_name(&b".symtab"[..]));
- self.symtab_index = self.reserve_section_index();
- self.symtab_index
- }
-
- /// Return the section index of the symbol table.
- pub fn symtab_index(&mut self) -> SectionIndex {
- self.symtab_index
- }
-
- /// Write the section header for the symbol table.
- ///
- /// This function does nothing if the section index was not reserved.
- pub fn write_symtab_section_header(&mut self, num_local: u32) {
- if self.symtab_index == SectionIndex(0) {
- return;
- }
- self.write_section_header(&SectionHeader {
- name: self.symtab_str_id,
- sh_type: elf::SHT_SYMTAB,
- sh_flags: 0,
- sh_addr: 0,
- sh_offset: self.symtab_offset as u64,
- sh_size: self.symtab_num as u64 * self.symbol_size() as u64,
- sh_link: self.strtab_index.0,
- sh_info: num_local,
- sh_addralign: self.elf_align as u64,
- sh_entsize: self.symbol_size() as u64,
- });
- }
-
- /// Return true if `.symtab_shndx` is needed.
- pub fn symtab_shndx_needed(&self) -> bool {
- self.need_symtab_shndx
- }
-
- /// Reserve the range for the extended section indices for the symbol table.
- ///
- /// This range is used for a section named `.symtab_shndx`.
- /// This also reserves a section index.
- ///
- /// This function does nothing if extended section indices are not needed.
- /// This must be called after [`Self::reserve_symbol_index`].
- pub fn reserve_symtab_shndx(&mut self) {
- debug_assert_eq!(self.symtab_shndx_offset, 0);
- if !self.need_symtab_shndx {
- return;
- }
- self.symtab_shndx_offset = self.reserve(self.symtab_num as usize * 4, 4);
- self.symtab_shndx_data.reserve(self.symtab_num as usize * 4);
- }
-
- /// Write the extended section indices for the symbol table.
- ///
- /// This function does nothing if the section was not reserved.
- pub fn write_symtab_shndx(&mut self) {
- if self.symtab_shndx_offset == 0 {
- return;
- }
- debug_assert_eq!(self.symtab_shndx_offset, self.buffer.len());
- debug_assert_eq!(self.symtab_num as usize * 4, self.symtab_shndx_data.len());
- self.buffer.write_bytes(&self.symtab_shndx_data);
- }
-
- /// Reserve the section index for the extended section indices symbol table.
- ///
- /// You should check [`Self::symtab_shndx_needed`] before calling this
- /// unless you have other means of knowing if this section is needed.
- ///
- /// This must be called before [`Self::reserve_section_headers`].
- pub fn reserve_symtab_shndx_section_index(&mut self) -> SectionIndex {
- debug_assert!(self.symtab_shndx_str_id.is_none());
- self.symtab_shndx_str_id = Some(self.add_section_name(&b".symtab_shndx"[..]));
- self.reserve_section_index()
- }
-
- /// Write the section header for the extended section indices for the symbol table.
- ///
- /// This function does nothing if the section index was not reserved.
- pub fn write_symtab_shndx_section_header(&mut self) {
- if self.symtab_shndx_str_id.is_none() {
- return;
- }
- let sh_size = if self.symtab_shndx_offset == 0 {
- 0
- } else {
- (self.symtab_num * 4) as u64
- };
- self.write_section_header(&SectionHeader {
- name: self.symtab_shndx_str_id,
- sh_type: elf::SHT_SYMTAB_SHNDX,
- sh_flags: 0,
- sh_addr: 0,
- sh_offset: self.symtab_shndx_offset as u64,
- sh_size,
- sh_link: self.symtab_index.0,
- sh_info: 0,
- sh_addralign: 4,
- sh_entsize: 4,
- });
- }
-
- /// Add a string to the dynamic string table.
- ///
- /// This will be stored in the `.dynstr` section.
- ///
- /// This must be called before [`Self::reserve_dynstr`].
- pub fn add_dynamic_string(&mut self, name: &'a [u8]) -> StringId {
- debug_assert_eq!(self.dynstr_offset, 0);
- self.need_dynstr = true;
- self.dynstr.add(name)
- }
-
- /// Get a string that was previously added to the dynamic string table.
- ///
- /// Panics if the string was not added.
- pub fn get_dynamic_string(&self, name: &'a [u8]) -> StringId {
- self.dynstr.get_id(name)
- }
-
- /// Return true if `.dynstr` is needed.
- pub fn dynstr_needed(&self) -> bool {
- self.need_dynstr
- }
-
- /// Reserve the range for the dynamic string table.
- ///
- /// This range is used for a section named `.dynstr`.
- ///
- /// This function does nothing if no dynamic strings or symbols were defined.
- /// This must be called after [`Self::add_dynamic_string`].
- pub fn reserve_dynstr(&mut self) {
- debug_assert_eq!(self.dynstr_offset, 0);
- if !self.need_dynstr {
- return;
- }
- // Start with null string.
- self.dynstr_data = vec![0];
- self.dynstr.write(1, &mut self.dynstr_data);
- self.dynstr_offset = self.reserve(self.dynstr_data.len(), 1);
- }
-
- /// Write the dynamic string table.
- ///
- /// This function does nothing if the section was not reserved.
- pub fn write_dynstr(&mut self) {
- if self.dynstr_offset == 0 {
- return;
- }
- debug_assert_eq!(self.dynstr_offset, self.buffer.len());
- self.buffer.write_bytes(&self.dynstr_data);
- }
-
- /// Reserve the section index for the dynamic string table.
- ///
- /// This must be called before [`Self::reserve_section_headers`].
- pub fn reserve_dynstr_section_index(&mut self) -> SectionIndex {
- debug_assert_eq!(self.dynstr_index, SectionIndex(0));
- self.dynstr_str_id = Some(self.add_section_name(&b".dynstr"[..]));
- self.dynstr_index = self.reserve_section_index();
- self.dynstr_index
- }
-
- /// Return the section index of the dynamic string table.
- pub fn dynstr_index(&mut self) -> SectionIndex {
- self.dynstr_index
- }
-
- /// Write the section header for the dynamic string table.
- ///
- /// This function does nothing if the section index was not reserved.
- pub fn write_dynstr_section_header(&mut self, sh_addr: u64) {
- if self.dynstr_index == SectionIndex(0) {
- return;
- }
- self.write_section_header(&SectionHeader {
- name: self.dynstr_str_id,
- sh_type: elf::SHT_STRTAB,
- sh_flags: elf::SHF_ALLOC.into(),
- sh_addr,
- sh_offset: self.dynstr_offset as u64,
- sh_size: self.dynstr_data.len() as u64,
- sh_link: 0,
- sh_info: 0,
- sh_addralign: 1,
- sh_entsize: 0,
- });
- }
-
- /// Reserve the null dynamic symbol table entry.
- ///
- /// This will be stored in the `.dynsym` section.
- ///
- /// The null dynamic symbol table entry is usually automatically reserved,
- /// but this can be used to force an empty dynamic symbol table.
- ///
- /// This must be called before [`Self::reserve_dynsym`].
- pub fn reserve_null_dynamic_symbol_index(&mut self) -> SymbolIndex {
- debug_assert_eq!(self.dynsym_offset, 0);
- debug_assert_eq!(self.dynsym_num, 0);
- self.dynsym_num = 1;
- // The symtab must link to a strtab.
- self.need_dynstr = true;
- SymbolIndex(0)
- }
-
- /// Reserve a dynamic symbol table entry.
- ///
- /// This will be stored in the `.dynsym` section.
- ///
- /// Automatically also reserves the null symbol if required.
- /// Callers may assume that the returned indices will be sequential
- /// starting at 1.
- ///
- /// This must be called before [`Self::reserve_dynsym`].
- pub fn reserve_dynamic_symbol_index(&mut self) -> SymbolIndex {
- debug_assert_eq!(self.dynsym_offset, 0);
- if self.dynsym_num == 0 {
- self.dynsym_num = 1;
- // The symtab must link to a strtab.
- self.need_dynstr = true;
- }
- let index = self.dynsym_num;
- self.dynsym_num += 1;
- SymbolIndex(index)
- }
-
- /// Return the number of reserved dynamic symbols.
- ///
- /// Includes the null symbol.
- pub fn dynamic_symbol_count(&mut self) -> u32 {
- self.dynsym_num
- }
-
- /// Reserve the range for the dynamic symbol table.
- ///
- /// This range is used for a section named `.dynsym`.
- ///
- /// This function does nothing if no dynamic symbols were reserved.
- /// This must be called after [`Self::reserve_dynamic_symbol_index`].
- pub fn reserve_dynsym(&mut self) {
- debug_assert_eq!(self.dynsym_offset, 0);
- if self.dynsym_num == 0 {
- return;
- }
- self.dynsym_offset = self.reserve(
- self.dynsym_num as usize * self.symbol_size(),
- self.elf_align,
- );
- }
-
- /// Write the null dynamic symbol.
- ///
- /// This must be the first dynamic symbol that is written.
- /// This function does nothing if no dynamic symbols were reserved.
- pub fn write_null_dynamic_symbol(&mut self) {
- if self.dynsym_num == 0 {
- return;
- }
- util::write_align(self.buffer, self.elf_align);
- debug_assert_eq!(self.dynsym_offset, self.buffer.len());
- if self.is_64 {
- self.buffer.write(&elf::Sym64::<Endianness>::default());
- } else {
- self.buffer.write(&elf::Sym32::<Endianness>::default());
- }
- }
-
- /// Write a dynamic symbol.
- pub fn write_dynamic_symbol(&mut self, sym: &Sym) {
- let st_name = if let Some(name) = sym.name {
- self.dynstr.get_offset(name) as u32
- } else {
- 0
- };
-
- let st_shndx = if let Some(section) = sym.section {
- if section.0 >= elf::SHN_LORESERVE as u32 {
- // TODO: we don't actually write out .dynsym_shndx yet.
- // This is unlikely to be needed though.
- elf::SHN_XINDEX
- } else {
- section.0 as u16
- }
- } else {
- sym.st_shndx
- };
-
- let endian = self.endian;
- if self.is_64 {
- let sym = elf::Sym64 {
- st_name: U32::new(endian, st_name),
- st_info: sym.st_info,
- st_other: sym.st_other,
- st_shndx: U16::new(endian, st_shndx),
- st_value: U64::new(endian, sym.st_value),
- st_size: U64::new(endian, sym.st_size),
- };
- self.buffer.write(&sym);
- } else {
- let sym = elf::Sym32 {
- st_name: U32::new(endian, st_name),
- st_info: sym.st_info,
- st_other: sym.st_other,
- st_shndx: U16::new(endian, st_shndx),
- st_value: U32::new(endian, sym.st_value as u32),
- st_size: U32::new(endian, sym.st_size as u32),
- };
- self.buffer.write(&sym);
- }
- }
-
- /// Reserve the section index for the dynamic symbol table.
- ///
- /// This must be called before [`Self::reserve_section_headers`].
- pub fn reserve_dynsym_section_index(&mut self) -> SectionIndex {
- debug_assert_eq!(self.dynsym_index, SectionIndex(0));
- self.dynsym_str_id = Some(self.add_section_name(&b".dynsym"[..]));
- self.dynsym_index = self.reserve_section_index();
- self.dynsym_index
- }
-
- /// Return the section index of the dynamic symbol table.
- pub fn dynsym_index(&mut self) -> SectionIndex {
- self.dynsym_index
- }
-
- /// Write the section header for the dynamic symbol table.
- ///
- /// This function does nothing if the section index was not reserved.
- pub fn write_dynsym_section_header(&mut self, sh_addr: u64, num_local: u32) {
- if self.dynsym_index == SectionIndex(0) {
- return;
- }
- self.write_section_header(&SectionHeader {
- name: self.dynsym_str_id,
- sh_type: elf::SHT_DYNSYM,
- sh_flags: elf::SHF_ALLOC.into(),
- sh_addr,
- sh_offset: self.dynsym_offset as u64,
- sh_size: self.dynsym_num as u64 * self.symbol_size() as u64,
- sh_link: self.dynstr_index.0,
- sh_info: num_local,
- sh_addralign: self.elf_align as u64,
- sh_entsize: self.symbol_size() as u64,
- });
- }
-
- fn dyn_size(&self) -> usize {
- if self.is_64 {
- mem::size_of::<elf::Dyn64<Endianness>>()
- } else {
- mem::size_of::<elf::Dyn32<Endianness>>()
- }
- }
-
- /// Reserve the range for the `.dynamic` section.
- ///
- /// This function does nothing if `dynamic_num` is zero.
- pub fn reserve_dynamic(&mut self, dynamic_num: usize) {
- debug_assert_eq!(self.dynamic_offset, 0);
- if dynamic_num == 0 {
- return;
- }
- self.dynamic_num = dynamic_num;
- self.dynamic_offset = self.reserve(dynamic_num * self.dyn_size(), self.elf_align);
- }
-
- /// Write alignment padding bytes prior to the `.dynamic` section.
- ///
- /// This function does nothing if the section was not reserved.
- pub fn write_align_dynamic(&mut self) {
- if self.dynamic_offset == 0 {
- return;
- }
- util::write_align(self.buffer, self.elf_align);
- debug_assert_eq!(self.dynamic_offset, self.buffer.len());
- }
-
- /// Write a dynamic string entry.
- pub fn write_dynamic_string(&mut self, tag: u32, id: StringId) {
- self.write_dynamic(tag, self.dynstr.get_offset(id) as u64);
- }
-
- /// Write a dynamic value entry.
- pub fn write_dynamic(&mut self, d_tag: u32, d_val: u64) {
- debug_assert!(self.dynamic_offset <= self.buffer.len());
- let endian = self.endian;
- if self.is_64 {
- let d = elf::Dyn64 {
- d_tag: U64::new(endian, d_tag.into()),
- d_val: U64::new(endian, d_val),
- };
- self.buffer.write(&d);
- } else {
- let d = elf::Dyn32 {
- d_tag: U32::new(endian, d_tag),
- d_val: U32::new(endian, d_val as u32),
- };
- self.buffer.write(&d);
- }
- debug_assert!(
- self.dynamic_offset + self.dynamic_num * self.dyn_size() >= self.buffer.len()
- );
- }
-
- /// Reserve the section index for the dynamic table.
- pub fn reserve_dynamic_section_index(&mut self) -> SectionIndex {
- debug_assert!(self.dynamic_str_id.is_none());
- self.dynamic_str_id = Some(self.add_section_name(&b".dynamic"[..]));
- self.reserve_section_index()
- }
-
- /// Write the section header for the dynamic table.
- ///
- /// This function does nothing if the section index was not reserved.
- pub fn write_dynamic_section_header(&mut self, sh_addr: u64) {
- if self.dynamic_str_id.is_none() {
- return;
- }
- self.write_section_header(&SectionHeader {
- name: self.dynamic_str_id,
- sh_type: elf::SHT_DYNAMIC,
- sh_flags: (elf::SHF_WRITE | elf::SHF_ALLOC).into(),
- sh_addr,
- sh_offset: self.dynamic_offset as u64,
- sh_size: (self.dynamic_num * self.dyn_size()) as u64,
- sh_link: self.dynstr_index.0,
- sh_info: 0,
- sh_addralign: self.elf_align as u64,
- sh_entsize: self.dyn_size() as u64,
- });
- }
-
- fn rel_size(&self, is_rela: bool) -> usize {
- if self.is_64 {
- if is_rela {
- mem::size_of::<elf::Rela64<Endianness>>()
- } else {
- mem::size_of::<elf::Rel64<Endianness>>()
- }
- } else {
- if is_rela {
- mem::size_of::<elf::Rela32<Endianness>>()
- } else {
- mem::size_of::<elf::Rel32<Endianness>>()
- }
- }
- }
-
- /// Reserve a file range for a SysV hash section.
- ///
- /// `symbol_count` is the number of symbols in the hash,
- /// not the total number of symbols.
- pub fn reserve_hash(&mut self, bucket_count: u32, chain_count: u32) {
- self.hash_size = mem::size_of::<elf::HashHeader<Endianness>>()
- + bucket_count as usize * 4
- + chain_count as usize * 4;
- self.hash_offset = self.reserve(self.hash_size, self.elf_align);
- }
-
- /// Write a SysV hash section.
- ///
- /// `chain_count` is the number of symbols in the hash.
- /// The argument to `hash` will be in the range `0..chain_count`.
- pub fn write_hash<F>(&mut self, bucket_count: u32, chain_count: u32, hash: F)
- where
- F: Fn(u32) -> Option<u32>,
- {
- let mut buckets = vec![U32::new(self.endian, 0); bucket_count as usize];
- let mut chains = vec![U32::new(self.endian, 0); chain_count as usize];
- for i in 0..chain_count {
- if let Some(hash) = hash(i) {
- let bucket = hash % bucket_count;
- chains[i as usize] = buckets[bucket as usize];
- buckets[bucket as usize] = U32::new(self.endian, i);
- }
- }
-
- util::write_align(self.buffer, self.elf_align);
- debug_assert_eq!(self.hash_offset, self.buffer.len());
- self.buffer.write(&elf::HashHeader {
- bucket_count: U32::new(self.endian, bucket_count),
- chain_count: U32::new(self.endian, chain_count),
- });
- self.buffer.write_slice(&buckets);
- self.buffer.write_slice(&chains);
- }
-
- /// Reserve the section index for the SysV hash table.
- pub fn reserve_hash_section_index(&mut self) -> SectionIndex {
- debug_assert!(self.hash_str_id.is_none());
- self.hash_str_id = Some(self.add_section_name(&b".hash"[..]));
- self.reserve_section_index()
- }
-
- /// Write the section header for the SysV hash table.
- ///
- /// This function does nothing if the section index was not reserved.
- pub fn write_hash_section_header(&mut self, sh_addr: u64) {
- if self.hash_str_id.is_none() {
- return;
- }
- self.write_section_header(&SectionHeader {
- name: self.hash_str_id,
- sh_type: elf::SHT_HASH,
- sh_flags: elf::SHF_ALLOC.into(),
- sh_addr,
- sh_offset: self.hash_offset as u64,
- sh_size: self.hash_size as u64,
- sh_link: self.dynsym_index.0,
- sh_info: 0,
- sh_addralign: self.elf_align as u64,
- sh_entsize: 4,
- });
- }
-
- /// Reserve a file range for a GNU hash section.
- ///
- /// `symbol_count` is the number of symbols in the hash,
- /// not the total number of symbols.
- pub fn reserve_gnu_hash(&mut self, bloom_count: u32, bucket_count: u32, symbol_count: u32) {
- self.gnu_hash_size = mem::size_of::<elf::GnuHashHeader<Endianness>>()
- + bloom_count as usize * self.elf_align
- + bucket_count as usize * 4
- + symbol_count as usize * 4;
- self.gnu_hash_offset = self.reserve(self.gnu_hash_size, self.elf_align);
- }
-
- /// Write a GNU hash section.
- ///
- /// `symbol_count` is the number of symbols in the hash.
- /// The argument to `hash` will be in the range `0..symbol_count`.
- ///
- /// This requires that symbols are already sorted by bucket.
- pub fn write_gnu_hash<F>(
- &mut self,
- symbol_base: u32,
- bloom_shift: u32,
- bloom_count: u32,
- bucket_count: u32,
- symbol_count: u32,
- hash: F,
- ) where
- F: Fn(u32) -> u32,
- {
- util::write_align(self.buffer, self.elf_align);
- debug_assert_eq!(self.gnu_hash_offset, self.buffer.len());
- self.buffer.write(&elf::GnuHashHeader {
- bucket_count: U32::new(self.endian, bucket_count),
- symbol_base: U32::new(self.endian, symbol_base),
- bloom_count: U32::new(self.endian, bloom_count),
- bloom_shift: U32::new(self.endian, bloom_shift),
- });
-
- // Calculate and write bloom filter.
- if self.is_64 {
- let mut bloom_filters = vec![0; bloom_count as usize];
- for i in 0..symbol_count {
- let h = hash(i);
- bloom_filters[((h / 64) & (bloom_count - 1)) as usize] |=
- 1 << (h % 64) | 1 << ((h >> bloom_shift) % 64);
- }
- for bloom_filter in bloom_filters {
- self.buffer.write(&U64::new(self.endian, bloom_filter));
- }
- } else {
- let mut bloom_filters = vec![0; bloom_count as usize];
- for i in 0..symbol_count {
- let h = hash(i);
- bloom_filters[((h / 32) & (bloom_count - 1)) as usize] |=
- 1 << (h % 32) | 1 << ((h >> bloom_shift) % 32);
- }
- for bloom_filter in bloom_filters {
- self.buffer.write(&U32::new(self.endian, bloom_filter));
- }
- }
-
- // Write buckets.
- //
- // This requires that symbols are already sorted by bucket.
- let mut bucket = 0;
- for i in 0..symbol_count {
- let symbol_bucket = hash(i) % bucket_count;
- while bucket < symbol_bucket {
- self.buffer.write(&U32::new(self.endian, 0));
- bucket += 1;
- }
- if bucket == symbol_bucket {
- self.buffer.write(&U32::new(self.endian, symbol_base + i));
- bucket += 1;
- }
- }
- while bucket < bucket_count {
- self.buffer.write(&U32::new(self.endian, 0));
- bucket += 1;
- }
-
- // Write hash values.
- for i in 0..symbol_count {
- let mut h = hash(i);
- if i == symbol_count - 1 || h % bucket_count != hash(i + 1) % bucket_count {
- h |= 1;
- } else {
- h &= !1;
- }
- self.buffer.write(&U32::new(self.endian, h));
- }
- }
-
- /// Reserve the section index for the GNU hash table.
- pub fn reserve_gnu_hash_section_index(&mut self) -> SectionIndex {
- debug_assert!(self.gnu_hash_str_id.is_none());
- self.gnu_hash_str_id = Some(self.add_section_name(&b".gnu.hash"[..]));
- self.reserve_section_index()
- }
-
- /// Write the section header for the GNU hash table.
- ///
- /// This function does nothing if the section index was not reserved.
- pub fn write_gnu_hash_section_header(&mut self, sh_addr: u64) {
- if self.gnu_hash_str_id.is_none() {
- return;
- }
- self.write_section_header(&SectionHeader {
- name: self.gnu_hash_str_id,
- sh_type: elf::SHT_GNU_HASH,
- sh_flags: elf::SHF_ALLOC.into(),
- sh_addr,
- sh_offset: self.gnu_hash_offset as u64,
- sh_size: self.gnu_hash_size as u64,
- sh_link: self.dynsym_index.0,
- sh_info: 0,
- sh_addralign: self.elf_align as u64,
- sh_entsize: 0,
- });
- }
-
- /// Reserve the range for the `.gnu.version` section.
- ///
- /// This function does nothing if no dynamic symbols were reserved.
- pub fn reserve_gnu_versym(&mut self) {
- debug_assert_eq!(self.gnu_versym_offset, 0);
- if self.dynsym_num == 0 {
- return;
- }
- self.gnu_versym_offset = self.reserve(self.dynsym_num as usize * 2, 2);
- }
-
- /// Write the null symbol version entry.
- ///
- /// This must be the first symbol version that is written.
- /// This function does nothing if no dynamic symbols were reserved.
- pub fn write_null_gnu_versym(&mut self) {
- if self.dynsym_num == 0 {
- return;
- }
- util::write_align(self.buffer, 2);
- debug_assert_eq!(self.gnu_versym_offset, self.buffer.len());
- self.write_gnu_versym(0);
- }
-
- /// Write a symbol version entry.
- pub fn write_gnu_versym(&mut self, versym: u16) {
- self.buffer.write(&U16::new(self.endian, versym));
- }
-
- /// Reserve the section index for the `.gnu.version` section.
- pub fn reserve_gnu_versym_section_index(&mut self) -> SectionIndex {
- debug_assert!(self.gnu_versym_str_id.is_none());
- self.gnu_versym_str_id = Some(self.add_section_name(&b".gnu.version"[..]));
- self.reserve_section_index()
- }
-
- /// Write the section header for the `.gnu.version` section.
- ///
- /// This function does nothing if the section index was not reserved.
- pub fn write_gnu_versym_section_header(&mut self, sh_addr: u64) {
- if self.gnu_versym_str_id.is_none() {
- return;
- }
- self.write_section_header(&SectionHeader {
- name: self.gnu_versym_str_id,
- sh_type: elf::SHT_GNU_VERSYM,
- sh_flags: elf::SHF_ALLOC.into(),
- sh_addr,
- sh_offset: self.gnu_versym_offset as u64,
- sh_size: self.dynsym_num as u64 * 2,
- sh_link: self.dynsym_index.0,
- sh_info: 0,
- sh_addralign: 2,
- sh_entsize: 2,
- });
- }
-
- /// Reserve the range for the `.gnu.version_d` section.
- pub fn reserve_gnu_verdef(&mut self, verdef_count: usize, verdaux_count: usize) {
- debug_assert_eq!(self.gnu_verdef_offset, 0);
- if verdef_count == 0 {
- return;
- }
- self.gnu_verdef_size = verdef_count * mem::size_of::<elf::Verdef<Endianness>>()
- + verdaux_count * mem::size_of::<elf::Verdaux<Endianness>>();
- self.gnu_verdef_offset = self.reserve(self.gnu_verdef_size, self.elf_align);
- self.gnu_verdef_count = verdef_count as u16;
- self.gnu_verdef_remaining = self.gnu_verdef_count;
- }
-
- /// Write alignment padding bytes prior to a `.gnu.version_d` section.
- pub fn write_align_gnu_verdef(&mut self) {
- if self.gnu_verdef_offset == 0 {
- return;
- }
- util::write_align(self.buffer, self.elf_align);
- debug_assert_eq!(self.gnu_verdef_offset, self.buffer.len());
- }
-
- /// Write a version definition entry.
- pub fn write_gnu_verdef(&mut self, verdef: &Verdef) {
- debug_assert_ne!(self.gnu_verdef_remaining, 0);
- self.gnu_verdef_remaining -= 1;
- let vd_next = if self.gnu_verdef_remaining == 0 {
- 0
- } else {
- mem::size_of::<elf::Verdef<Endianness>>() as u32
- + verdef.aux_count as u32 * mem::size_of::<elf::Verdaux<Endianness>>() as u32
- };
-
- self.gnu_verdaux_remaining = verdef.aux_count;
- let vd_aux = if verdef.aux_count == 0 {
- 0
- } else {
- mem::size_of::<elf::Verdef<Endianness>>() as u32
- };
-
- self.buffer.write(&elf::Verdef {
- vd_version: U16::new(self.endian, verdef.version),
- vd_flags: U16::new(self.endian, verdef.flags),
- vd_ndx: U16::new(self.endian, verdef.index),
- vd_cnt: U16::new(self.endian, verdef.aux_count),
- vd_hash: U32::new(self.endian, elf::hash(self.dynstr.get_string(verdef.name))),
- vd_aux: U32::new(self.endian, vd_aux),
- vd_next: U32::new(self.endian, vd_next),
- });
- self.write_gnu_verdaux(verdef.name);
- }
-
- /// Write a version definition auxiliary entry.
- pub fn write_gnu_verdaux(&mut self, name: StringId) {
- debug_assert_ne!(self.gnu_verdaux_remaining, 0);
- self.gnu_verdaux_remaining -= 1;
- let vda_next = if self.gnu_verdaux_remaining == 0 {
- 0
- } else {
- mem::size_of::<elf::Verdaux<Endianness>>() as u32
- };
- self.buffer.write(&elf::Verdaux {
- vda_name: U32::new(self.endian, self.dynstr.get_offset(name) as u32),
- vda_next: U32::new(self.endian, vda_next),
- });
- }
-
- /// Reserve the section index for the `.gnu.version_d` section.
- pub fn reserve_gnu_verdef_section_index(&mut self) -> SectionIndex {
- debug_assert!(self.gnu_verdef_str_id.is_none());
- self.gnu_verdef_str_id = Some(self.add_section_name(&b".gnu.version_d"[..]));
- self.reserve_section_index()
- }
-
- /// Write the section header for the `.gnu.version_d` section.
- ///
- /// This function does nothing if the section index was not reserved.
- pub fn write_gnu_verdef_section_header(&mut self, sh_addr: u64) {
- if self.gnu_verdef_str_id.is_none() {
- return;
- }
- self.write_section_header(&SectionHeader {
- name: self.gnu_verdef_str_id,
- sh_type: elf::SHT_GNU_VERDEF,
- sh_flags: elf::SHF_ALLOC.into(),
- sh_addr,
- sh_offset: self.gnu_verdef_offset as u64,
- sh_size: self.gnu_verdef_size as u64,
- sh_link: self.dynstr_index.0,
- sh_info: self.gnu_verdef_count.into(),
- sh_addralign: self.elf_align as u64,
- sh_entsize: 0,
- });
- }
-
- /// Reserve the range for the `.gnu.version_r` section.
- pub fn reserve_gnu_verneed(&mut self, verneed_count: usize, vernaux_count: usize) {
- debug_assert_eq!(self.gnu_verneed_offset, 0);
- if verneed_count == 0 {
- return;
- }
- self.gnu_verneed_size = verneed_count * mem::size_of::<elf::Verneed<Endianness>>()
- + vernaux_count * mem::size_of::<elf::Vernaux<Endianness>>();
- self.gnu_verneed_offset = self.reserve(self.gnu_verneed_size, self.elf_align);
- self.gnu_verneed_count = verneed_count as u16;
- self.gnu_verneed_remaining = self.gnu_verneed_count;
- }
-
- /// Write alignment padding bytes prior to a `.gnu.version_r` section.
- pub fn write_align_gnu_verneed(&mut self) {
- if self.gnu_verneed_offset == 0 {
- return;
- }
- util::write_align(self.buffer, self.elf_align);
- debug_assert_eq!(self.gnu_verneed_offset, self.buffer.len());
- }
-
- /// Write a version need entry.
- pub fn write_gnu_verneed(&mut self, verneed: &Verneed) {
- debug_assert_ne!(self.gnu_verneed_remaining, 0);
- self.gnu_verneed_remaining -= 1;
- let vn_next = if self.gnu_verneed_remaining == 0 {
- 0
- } else {
- mem::size_of::<elf::Verneed<Endianness>>() as u32
- + verneed.aux_count as u32 * mem::size_of::<elf::Vernaux<Endianness>>() as u32
- };
-
- self.gnu_vernaux_remaining = verneed.aux_count;
- let vn_aux = if verneed.aux_count == 0 {
- 0
- } else {
- mem::size_of::<elf::Verneed<Endianness>>() as u32
- };
-
- self.buffer.write(&elf::Verneed {
- vn_version: U16::new(self.endian, verneed.version),
- vn_cnt: U16::new(self.endian, verneed.aux_count),
- vn_file: U32::new(self.endian, self.dynstr.get_offset(verneed.file) as u32),
- vn_aux: U32::new(self.endian, vn_aux),
- vn_next: U32::new(self.endian, vn_next),
- });
- }
-
- /// Write a version need auxiliary entry.
- pub fn write_gnu_vernaux(&mut self, vernaux: &Vernaux) {
- debug_assert_ne!(self.gnu_vernaux_remaining, 0);
- self.gnu_vernaux_remaining -= 1;
- let vna_next = if self.gnu_vernaux_remaining == 0 {
- 0
- } else {
- mem::size_of::<elf::Vernaux<Endianness>>() as u32
- };
- self.buffer.write(&elf::Vernaux {
- vna_hash: U32::new(self.endian, elf::hash(self.dynstr.get_string(vernaux.name))),
- vna_flags: U16::new(self.endian, vernaux.flags),
- vna_other: U16::new(self.endian, vernaux.index),
- vna_name: U32::new(self.endian, self.dynstr.get_offset(vernaux.name) as u32),
- vna_next: U32::new(self.endian, vna_next),
- });
- }
-
- /// Reserve the section index for the `.gnu.version_r` section.
- pub fn reserve_gnu_verneed_section_index(&mut self) -> SectionIndex {
- debug_assert!(self.gnu_verneed_str_id.is_none());
- self.gnu_verneed_str_id = Some(self.add_section_name(&b".gnu.version_r"[..]));
- self.reserve_section_index()
- }
-
- /// Write the section header for the `.gnu.version_r` section.
- ///
- /// This function does nothing if the section index was not reserved.
- pub fn write_gnu_verneed_section_header(&mut self, sh_addr: u64) {
- if self.gnu_verneed_str_id.is_none() {
- return;
- }
- self.write_section_header(&SectionHeader {
- name: self.gnu_verneed_str_id,
- sh_type: elf::SHT_GNU_VERNEED,
- sh_flags: elf::SHF_ALLOC.into(),
- sh_addr,
- sh_offset: self.gnu_verneed_offset as u64,
- sh_size: self.gnu_verneed_size as u64,
- sh_link: self.dynstr_index.0,
- sh_info: self.gnu_verneed_count.into(),
- sh_addralign: self.elf_align as u64,
- sh_entsize: 0,
- });
- }
-
- /// Reserve the section index for the `.gnu.attributes` section.
- pub fn reserve_gnu_attributes_section_index(&mut self) -> SectionIndex {
- debug_assert!(self.gnu_attributes_str_id.is_none());
- self.gnu_attributes_str_id = Some(self.add_section_name(&b".gnu.attributes"[..]));
- self.reserve_section_index()
- }
-
- /// Reserve the range for the `.gnu.attributes` section.
- pub fn reserve_gnu_attributes(&mut self, gnu_attributes_size: usize) {
- debug_assert_eq!(self.gnu_attributes_offset, 0);
- if gnu_attributes_size == 0 {
- return;
- }
- self.gnu_attributes_size = gnu_attributes_size;
- self.gnu_attributes_offset = self.reserve(self.gnu_attributes_size, self.elf_align);
- }
-
- /// Write the section header for the `.gnu.attributes` section.
- ///
- /// This function does nothing if the section index was not reserved.
- pub fn write_gnu_attributes_section_header(&mut self) {
- if self.gnu_attributes_str_id.is_none() {
- return;
- }
- self.write_section_header(&SectionHeader {
- name: self.gnu_attributes_str_id,
- sh_type: elf::SHT_GNU_ATTRIBUTES,
- sh_flags: 0,
- sh_addr: 0,
- sh_offset: self.gnu_attributes_offset as u64,
- sh_size: self.gnu_attributes_size as u64,
- sh_link: self.dynstr_index.0,
- sh_info: 0, // TODO
- sh_addralign: self.elf_align as u64,
- sh_entsize: 0,
- });
- }
-
- /// Write the data for the `.gnu.attributes` section.
- pub fn write_gnu_attributes(&mut self, data: &[u8]) {
- if self.gnu_attributes_offset == 0 {
- return;
- }
- util::write_align(self.buffer, self.elf_align);
- debug_assert_eq!(self.gnu_attributes_offset, self.buffer.len());
- self.buffer.write_bytes(data);
- }
-
- /// Reserve a file range for the given number of relocations.
- ///
- /// Returns the offset of the range.
- pub fn reserve_relocations(&mut self, count: usize, is_rela: bool) -> usize {
- self.reserve(count * self.rel_size(is_rela), self.elf_align)
- }
-
- /// Write alignment padding bytes prior to a relocation section.
- pub fn write_align_relocation(&mut self) {
- util::write_align(self.buffer, self.elf_align);
- }
-
- /// Write a relocation.
- pub fn write_relocation(&mut self, is_rela: bool, rel: &Rel) {
- let endian = self.endian;
- if self.is_64 {
- if is_rela {
- let rel = elf::Rela64 {
- r_offset: U64::new(endian, rel.r_offset),
- r_info: elf::Rela64::r_info(endian, self.is_mips64el, rel.r_sym, rel.r_type),
- r_addend: I64::new(endian, rel.r_addend),
- };
- self.buffer.write(&rel);
- } else {
- let rel = elf::Rel64 {
- r_offset: U64::new(endian, rel.r_offset),
- r_info: elf::Rel64::r_info(endian, rel.r_sym, rel.r_type),
- };
- self.buffer.write(&rel);
- }
- } else {
- if is_rela {
- let rel = elf::Rela32 {
- r_offset: U32::new(endian, rel.r_offset as u32),
- r_info: elf::Rel32::r_info(endian, rel.r_sym, rel.r_type as u8),
- r_addend: I32::new(endian, rel.r_addend as i32),
- };
- self.buffer.write(&rel);
- } else {
- let rel = elf::Rel32 {
- r_offset: U32::new(endian, rel.r_offset as u32),
- r_info: elf::Rel32::r_info(endian, rel.r_sym, rel.r_type as u8),
- };
- self.buffer.write(&rel);
- }
- }
- }
-
- /// Write the section header for a relocation section.
- ///
- /// `section` is the index of the section the relocations apply to,
- /// or 0 if none.
- ///
- /// `symtab` is the index of the symbol table the relocations refer to,
- /// or 0 if none.
- ///
- /// `offset` is the file offset of the relocations.
- pub fn write_relocation_section_header(
- &mut self,
- name: StringId,
- section: SectionIndex,
- symtab: SectionIndex,
- offset: usize,
- count: usize,
- is_rela: bool,
- ) {
- self.write_section_header(&SectionHeader {
- name: Some(name),
- sh_type: if is_rela { elf::SHT_RELA } else { elf::SHT_REL },
- sh_flags: elf::SHF_INFO_LINK.into(),
- sh_addr: 0,
- sh_offset: offset as u64,
- sh_size: (count * self.rel_size(is_rela)) as u64,
- sh_link: symtab.0,
- sh_info: section.0,
- sh_addralign: self.elf_align as u64,
- sh_entsize: self.rel_size(is_rela) as u64,
- });
- }
-
- /// Reserve a file range for a COMDAT section.
- ///
- /// `count` is the number of sections in the COMDAT group.
- ///
- /// Returns the offset of the range.
- pub fn reserve_comdat(&mut self, count: usize) -> usize {
- self.reserve((count + 1) * 4, 4)
- }
-
- /// Write `GRP_COMDAT` at the start of the COMDAT section.
- pub fn write_comdat_header(&mut self) {
- util::write_align(self.buffer, 4);
- self.buffer.write(&U32::new(self.endian, elf::GRP_COMDAT));
- }
-
- /// Write an entry in a COMDAT section.
- pub fn write_comdat_entry(&mut self, entry: SectionIndex) {
- self.buffer.write(&U32::new(self.endian, entry.0));
- }
-
- /// Write the section header for a COMDAT section.
- pub fn write_comdat_section_header(
- &mut self,
- name: StringId,
- symtab: SectionIndex,
- symbol: SymbolIndex,
- offset: usize,
- count: usize,
- ) {
- self.write_section_header(&SectionHeader {
- name: Some(name),
- sh_type: elf::SHT_GROUP,
- sh_flags: 0,
- sh_addr: 0,
- sh_offset: offset as u64,
- sh_size: ((count + 1) * 4) as u64,
- sh_link: symtab.0,
- sh_info: symbol.0,
- sh_addralign: 4,
- sh_entsize: 4,
- });
- }
-
- /// Return a helper for writing an attributes section.
- pub fn attributes_writer(&self) -> AttributesWriter {
- AttributesWriter::new(self.endian)
- }
-}
-
-/// A helper for writing an attributes section.
-///
-/// Attributes have a variable length encoding, so it is awkward to write them in a
-/// single pass. Instead, we build the entire attributes section data in memory, using
-/// placeholders for unknown lengths that are filled in later.
-#[allow(missing_debug_implementations)]
-pub struct AttributesWriter {
- endian: Endianness,
- data: Vec<u8>,
- subsection_offset: usize,
- subsubsection_offset: usize,
-}
-
-impl AttributesWriter {
- /// Create a new `AttributesWriter` for the given endianness.
- pub fn new(endian: Endianness) -> Self {
- AttributesWriter {
- endian,
- data: vec![0x41],
- subsection_offset: 0,
- subsubsection_offset: 0,
- }
- }
-
- /// Start a new subsection with the given vendor name.
- pub fn start_subsection(&mut self, vendor: &[u8]) {
- debug_assert_eq!(self.subsection_offset, 0);
- debug_assert_eq!(self.subsubsection_offset, 0);
- self.subsection_offset = self.data.len();
- self.data.extend_from_slice(&[0; 4]);
- self.data.extend_from_slice(vendor);
- self.data.push(0);
- }
-
- /// End the subsection.
- ///
- /// The subsection length is automatically calculated and written.
- pub fn end_subsection(&mut self) {
- debug_assert_ne!(self.subsection_offset, 0);
- debug_assert_eq!(self.subsubsection_offset, 0);
- let length = self.data.len() - self.subsection_offset;
- self.data[self.subsection_offset..][..4]
- .copy_from_slice(pod::bytes_of(&U32::new(self.endian, length as u32)));
- self.subsection_offset = 0;
- }
-
- /// Start a new sub-subsection with the given tag.
- pub fn start_subsubsection(&mut self, tag: u8) {
- debug_assert_ne!(self.subsection_offset, 0);
- debug_assert_eq!(self.subsubsection_offset, 0);
- self.subsubsection_offset = self.data.len();
- self.data.push(tag);
- self.data.extend_from_slice(&[0; 4]);
- }
-
- /// Write a section or symbol index to the sub-subsection.
- ///
- /// The user must also call this function to write the terminating 0 index.
- pub fn write_subsubsection_index(&mut self, index: u32) {
- debug_assert_ne!(self.subsection_offset, 0);
- debug_assert_ne!(self.subsubsection_offset, 0);
- util::write_uleb128(&mut self.data, u64::from(index));
- }
-
- /// Write raw index data to the sub-subsection.
- ///
- /// The terminating 0 index is automatically written.
- pub fn write_subsubsection_indices(&mut self, indices: &[u8]) {
- debug_assert_ne!(self.subsection_offset, 0);
- debug_assert_ne!(self.subsubsection_offset, 0);
- self.data.extend_from_slice(indices);
- self.data.push(0);
- }
-
- /// Write an attribute tag to the sub-subsection.
- pub fn write_attribute_tag(&mut self, tag: u64) {
- debug_assert_ne!(self.subsection_offset, 0);
- debug_assert_ne!(self.subsubsection_offset, 0);
- util::write_uleb128(&mut self.data, tag);
- }
-
- /// Write an attribute integer value to the sub-subsection.
- pub fn write_attribute_integer(&mut self, value: u64) {
- debug_assert_ne!(self.subsection_offset, 0);
- debug_assert_ne!(self.subsubsection_offset, 0);
- util::write_uleb128(&mut self.data, value);
- }
-
- /// Write an attribute string value to the sub-subsection.
- ///
- /// The value must not include the null terminator.
- pub fn write_attribute_string(&mut self, value: &[u8]) {
- debug_assert_ne!(self.subsection_offset, 0);
- debug_assert_ne!(self.subsubsection_offset, 0);
- self.data.extend_from_slice(value);
- self.data.push(0);
- }
-
- /// Write raw attribute data to the sub-subsection.
- pub fn write_subsubsection_attributes(&mut self, attributes: &[u8]) {
- debug_assert_ne!(self.subsection_offset, 0);
- debug_assert_ne!(self.subsubsection_offset, 0);
- self.data.extend_from_slice(attributes);
- }
-
- /// End the sub-subsection.
- ///
- /// The sub-subsection length is automatically calculated and written.
- pub fn end_subsubsection(&mut self) {
- debug_assert_ne!(self.subsection_offset, 0);
- debug_assert_ne!(self.subsubsection_offset, 0);
- let length = self.data.len() - self.subsubsection_offset;
- self.data[self.subsubsection_offset + 1..][..4]
- .copy_from_slice(pod::bytes_of(&U32::new(self.endian, length as u32)));
- self.subsubsection_offset = 0;
- }
-
- /// Return the completed section data.
- pub fn data(self) -> Vec<u8> {
- debug_assert_eq!(self.subsection_offset, 0);
- debug_assert_eq!(self.subsubsection_offset, 0);
- self.data
- }
-}
-
-/// Native endian version of [`elf::FileHeader64`].
-#[allow(missing_docs)]
-#[derive(Debug, Clone)]
-pub struct FileHeader {
- pub os_abi: u8,
- pub abi_version: u8,
- pub e_type: u16,
- pub e_machine: u16,
- pub e_entry: u64,
- pub e_flags: u32,
-}
-
-/// Native endian version of [`elf::ProgramHeader64`].
-#[allow(missing_docs)]
-#[derive(Debug, Clone)]
-pub struct ProgramHeader {
- pub p_type: u32,
- pub p_flags: u32,
- pub p_offset: u64,
- pub p_vaddr: u64,
- pub p_paddr: u64,
- pub p_filesz: u64,
- pub p_memsz: u64,
- pub p_align: u64,
-}
-
-/// Native endian version of [`elf::SectionHeader64`].
-#[allow(missing_docs)]
-#[derive(Debug, Clone)]
-pub struct SectionHeader {
- pub name: Option<StringId>,
- pub sh_type: u32,
- pub sh_flags: u64,
- pub sh_addr: u64,
- pub sh_offset: u64,
- pub sh_size: u64,
- pub sh_link: u32,
- pub sh_info: u32,
- pub sh_addralign: u64,
- pub sh_entsize: u64,
-}
-
-/// Native endian version of [`elf::Sym64`].
-#[allow(missing_docs)]
-#[derive(Debug, Clone)]
-pub struct Sym {
- pub name: Option<StringId>,
- pub section: Option<SectionIndex>,
- pub st_info: u8,
- pub st_other: u8,
- pub st_shndx: u16,
- pub st_value: u64,
- pub st_size: u64,
-}
-
-/// Unified native endian version of [`elf::Rel64`] and [`elf::Rela64`].
-#[allow(missing_docs)]
-#[derive(Debug, Clone)]
-pub struct Rel {
- pub r_offset: u64,
- pub r_sym: u32,
- pub r_type: u32,
- pub r_addend: i64,
-}
-
-/// Information required for writing [`elf::Verdef`].
-#[allow(missing_docs)]
-#[derive(Debug, Clone)]
-pub struct Verdef {
- pub version: u16,
- pub flags: u16,
- pub index: u16,
- pub aux_count: u16,
- /// The name for the first [`elf::Verdaux`] entry.
- pub name: StringId,
-}
-
-/// Information required for writing [`elf::Verneed`].
-#[allow(missing_docs)]
-#[derive(Debug, Clone)]
-pub struct Verneed {
- pub version: u16,
- pub aux_count: u16,
- pub file: StringId,
-}
-
-/// Information required for writing [`elf::Vernaux`].
-#[allow(missing_docs)]
-#[derive(Debug, Clone)]
-pub struct Vernaux {
- pub flags: u16,
- pub index: u16,
- pub name: StringId,
-}
diff --git a/vendor/object/src/write/macho.rs b/vendor/object/src/write/macho.rs
deleted file mode 100644
index 1c61523..0000000
--- a/vendor/object/src/write/macho.rs
+++ /dev/null
@@ -1,1095 +0,0 @@
-use core::mem;
-
-use crate::endian::*;
-use crate::macho;
-use crate::write::string::*;
-use crate::write::util::*;
-use crate::write::*;
-use crate::AddressSize;
-
-#[derive(Default, Clone, Copy)]
-struct SectionOffsets {
- index: usize,
- offset: usize,
- address: u64,
- reloc_offset: usize,
- reloc_count: usize,
-}
-
-#[derive(Default, Clone, Copy)]
-struct SymbolOffsets {
- index: usize,
- str_id: Option<StringId>,
-}
-
-/// The customizable portion of a [`macho::BuildVersionCommand`].
-#[derive(Debug, Default, Clone, Copy)]
-#[non_exhaustive] // May want to add the tool list?
-pub struct MachOBuildVersion {
- /// One of the `PLATFORM_` constants (for example,
- /// [`object::macho::PLATFORM_MACOS`](macho::PLATFORM_MACOS)).
- pub platform: u32,
- /// The minimum OS version, where `X.Y.Z` is encoded in nibbles as
- /// `xxxx.yy.zz`.
- pub minos: u32,
- /// The SDK version as `X.Y.Z`, where `X.Y.Z` is encoded in nibbles as
- /// `xxxx.yy.zz`.
- pub sdk: u32,
-}
-
-impl MachOBuildVersion {
- fn cmdsize(&self) -> u32 {
- // Same size for both endianness, and we don't have `ntools`.
- let sz = mem::size_of::<macho::BuildVersionCommand<Endianness>>();
- debug_assert!(sz <= u32::MAX as usize);
- sz as u32
- }
-}
-
-// Public methods.
-impl<'a> Object<'a> {
- /// Specify the Mach-O CPU subtype.
- ///
- /// Requires `feature = "macho"`.
- #[inline]
- pub fn set_macho_cpu_subtype(&mut self, cpu_subtype: u32) {
- self.macho_cpu_subtype = Some(cpu_subtype);
- }
-
- /// Specify information for a Mach-O `LC_BUILD_VERSION` command.
- ///
- /// Requires `feature = "macho"`.
- #[inline]
- pub fn set_macho_build_version(&mut self, info: MachOBuildVersion) {
- self.macho_build_version = Some(info);
- }
-}
-
-// Private methods.
-impl<'a> Object<'a> {
- pub(crate) fn macho_set_subsections_via_symbols(&mut self) {
- let flags = match self.flags {
- FileFlags::MachO { flags } => flags,
- _ => 0,
- };
- self.flags = FileFlags::MachO {
- flags: flags | macho::MH_SUBSECTIONS_VIA_SYMBOLS,
- };
- }
-
- pub(crate) fn macho_segment_name(&self, segment: StandardSegment) -> &'static [u8] {
- match segment {
- StandardSegment::Text => &b"__TEXT"[..],
- StandardSegment::Data => &b"__DATA"[..],
- StandardSegment::Debug => &b"__DWARF"[..],
- }
- }
-
- pub(crate) fn macho_section_info(
- &self,
- section: StandardSection,
- ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) {
- match section {
- StandardSection::Text => (
- &b"__TEXT"[..],
- &b"__text"[..],
- SectionKind::Text,
- SectionFlags::None,
- ),
- StandardSection::Data => (
- &b"__DATA"[..],
- &b"__data"[..],
- SectionKind::Data,
- SectionFlags::None,
- ),
- StandardSection::ReadOnlyData => (
- &b"__TEXT"[..],
- &b"__const"[..],
- SectionKind::ReadOnlyData,
- SectionFlags::None,
- ),
- StandardSection::ReadOnlyDataWithRel => (
- &b"__DATA"[..],
- &b"__const"[..],
- SectionKind::ReadOnlyDataWithRel,
- SectionFlags::None,
- ),
- StandardSection::ReadOnlyString => (
- &b"__TEXT"[..],
- &b"__cstring"[..],
- SectionKind::ReadOnlyString,
- SectionFlags::None,
- ),
- StandardSection::UninitializedData => (
- &b"__DATA"[..],
- &b"__bss"[..],
- SectionKind::UninitializedData,
- SectionFlags::None,
- ),
- StandardSection::Tls => (
- &b"__DATA"[..],
- &b"__thread_data"[..],
- SectionKind::Tls,
- SectionFlags::None,
- ),
- StandardSection::UninitializedTls => (
- &b"__DATA"[..],
- &b"__thread_bss"[..],
- SectionKind::UninitializedTls,
- SectionFlags::None,
- ),
- StandardSection::TlsVariables => (
- &b"__DATA"[..],
- &b"__thread_vars"[..],
- SectionKind::TlsVariables,
- SectionFlags::None,
- ),
- StandardSection::Common => (
- &b"__DATA"[..],
- &b"__common"[..],
- SectionKind::Common,
- SectionFlags::None,
- ),
- StandardSection::GnuProperty => {
- // Unsupported section.
- (&[], &[], SectionKind::Note, SectionFlags::None)
- }
- }
- }
-
- fn macho_tlv_bootstrap(&mut self) -> SymbolId {
- match self.tlv_bootstrap {
- Some(id) => id,
- None => {
- let id = self.add_symbol(Symbol {
- name: b"_tlv_bootstrap".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Text,
- scope: SymbolScope::Dynamic,
- weak: false,
- section: SymbolSection::Undefined,
- flags: SymbolFlags::None,
- });
- self.tlv_bootstrap = Some(id);
- id
- }
- }
- }
-
- /// Create the `__thread_vars` entry for a TLS variable.
- ///
- /// The symbol given by `symbol_id` will be updated to point to this entry.
- ///
- /// A new `SymbolId` will be returned. The caller must update this symbol
- /// to point to the initializer.
- ///
- /// If `symbol_id` is not for a TLS variable, then it is returned unchanged.
- pub(crate) fn macho_add_thread_var(&mut self, symbol_id: SymbolId) -> SymbolId {
- let symbol = self.symbol_mut(symbol_id);
- if symbol.kind != SymbolKind::Tls {
- return symbol_id;
- }
-
- // Create the initializer symbol.
- let mut name = symbol.name.clone();
- name.extend_from_slice(b"$tlv$init");
- let init_symbol_id = self.add_raw_symbol(Symbol {
- name,
- value: 0,
- size: 0,
- kind: SymbolKind::Tls,
- scope: SymbolScope::Compilation,
- weak: false,
- section: SymbolSection::Undefined,
- flags: SymbolFlags::None,
- });
-
- // Add the tlv entry.
- // Three pointers in size:
- // - __tlv_bootstrap - used to make sure support exists
- // - spare pointer - used when mapped by the runtime
- // - pointer to symbol initializer
- let section = self.section_id(StandardSection::TlsVariables);
- let address_size = self.architecture.address_size().unwrap().bytes();
- let size = u64::from(address_size) * 3;
- let data = vec![0; size as usize];
- let offset = self.append_section_data(section, &data, u64::from(address_size));
-
- let tlv_bootstrap = self.macho_tlv_bootstrap();
- self.add_relocation(
- section,
- Relocation {
- offset,
- size: address_size * 8,
- kind: RelocationKind::Absolute,
- encoding: RelocationEncoding::Generic,
- symbol: tlv_bootstrap,
- addend: 0,
- },
- )
- .unwrap();
- self.add_relocation(
- section,
- Relocation {
- offset: offset + u64::from(address_size) * 2,
- size: address_size * 8,
- kind: RelocationKind::Absolute,
- encoding: RelocationEncoding::Generic,
- symbol: init_symbol_id,
- addend: 0,
- },
- )
- .unwrap();
-
- // Update the symbol to point to the tlv.
- let symbol = self.symbol_mut(symbol_id);
- symbol.value = offset;
- symbol.size = size;
- symbol.section = SymbolSection::Section(section);
-
- init_symbol_id
- }
-
- pub(crate) fn macho_fixup_relocation(&mut self, relocation: &mut Relocation) -> i64 {
- let relative = match relocation.kind {
- RelocationKind::Relative
- | RelocationKind::GotRelative
- | RelocationKind::PltRelative
- | RelocationKind::MachO { relative: true, .. } => true,
- _ => false,
- };
- if relative {
- // For PC relative relocations on some architectures, the
- // addend does not include the offset required due to the
- // PC being different from the place of the relocation.
- // This differs from other file formats, so adjust the
- // addend here to account for this.
- let pcrel_offset = match self.architecture {
- Architecture::I386 => 4,
- Architecture::X86_64 => match relocation.kind {
- RelocationKind::MachO {
- value: macho::X86_64_RELOC_SIGNED_1,
- ..
- } => 5,
- RelocationKind::MachO {
- value: macho::X86_64_RELOC_SIGNED_2,
- ..
- } => 6,
- RelocationKind::MachO {
- value: macho::X86_64_RELOC_SIGNED_4,
- ..
- } => 8,
- _ => 4,
- },
- // TODO: maybe missing support for some architectures and relocations
- _ => 0,
- };
- relocation.addend += pcrel_offset;
- }
- // Aarch64 relocs of these sizes act as if they are double-word length
- if self.architecture == Architecture::Aarch64 && matches!(relocation.size, 12 | 21 | 26) {
- relocation.size = 32;
- }
- // Check for relocations that use an explicit addend.
- if self.architecture == Architecture::Aarch64 {
- if relocation.encoding == RelocationEncoding::AArch64Call {
- return 0;
- }
- if let RelocationKind::MachO { value, .. } = relocation.kind {
- match value {
- macho::ARM64_RELOC_BRANCH26
- | macho::ARM64_RELOC_PAGE21
- | macho::ARM64_RELOC_PAGEOFF12 => return 0,
- _ => {}
- }
- }
- }
- // Signify implicit addend.
- let constant = relocation.addend;
- relocation.addend = 0;
- constant
- }
-
- pub(crate) fn macho_write(&self, buffer: &mut dyn WritableBuffer) -> Result<()> {
- let address_size = self.architecture.address_size().unwrap();
- let endian = self.endian;
- let macho32 = MachO32 { endian };
- let macho64 = MachO64 { endian };
- let macho: &dyn MachO = match address_size {
- AddressSize::U8 | AddressSize::U16 | AddressSize::U32 => &macho32,
- AddressSize::U64 => &macho64,
- };
- let pointer_align = address_size.bytes() as usize;
-
- // Calculate offsets of everything, and build strtab.
- let mut offset = 0;
-
- // Calculate size of Mach-O header.
- offset += macho.mach_header_size();
-
- // Calculate size of commands.
- let mut ncmds = 0;
- let command_offset = offset;
-
- // Calculate size of segment command and section headers.
- let segment_command_offset = offset;
- let segment_command_len =
- macho.segment_command_size() + self.sections.len() * macho.section_header_size();
- offset += segment_command_len;
- ncmds += 1;
-
- // Calculate size of build version.
- let build_version_offset = offset;
- if let Some(version) = &self.macho_build_version {
- offset += version.cmdsize() as usize;
- ncmds += 1;
- }
-
- // Calculate size of symtab command.
- let symtab_command_offset = offset;
- let symtab_command_len = mem::size_of::<macho::SymtabCommand<Endianness>>();
- offset += symtab_command_len;
- ncmds += 1;
-
- // Calculate size of dysymtab command.
- let dysymtab_command_offset = offset;
- let dysymtab_command_len = mem::size_of::<macho::DysymtabCommand<Endianness>>();
- offset += dysymtab_command_len;
- ncmds += 1;
-
- let sizeofcmds = offset - command_offset;
-
- // Calculate size of section data.
- // Section data can immediately follow the load commands without any alignment padding.
- let segment_file_offset = offset;
- let mut section_offsets = vec![SectionOffsets::default(); self.sections.len()];
- let mut address = 0;
- for (index, section) in self.sections.iter().enumerate() {
- section_offsets[index].index = 1 + index;
- if !section.is_bss() {
- address = align_u64(address, section.align);
- section_offsets[index].address = address;
- section_offsets[index].offset = segment_file_offset + address as usize;
- address += section.size;
- }
- }
- let segment_file_size = address as usize;
- offset += address as usize;
- for (index, section) in self.sections.iter().enumerate() {
- if section.is_bss() {
- debug_assert!(section.data.is_empty());
- address = align_u64(address, section.align);
- section_offsets[index].address = address;
- address += section.size;
- }
- }
-
- // Partition symbols and add symbol strings to strtab.
- let mut strtab = StringTable::default();
- let mut symbol_offsets = vec![SymbolOffsets::default(); self.symbols.len()];
- let mut local_symbols = vec![];
- let mut external_symbols = vec![];
- let mut undefined_symbols = vec![];
- for (index, symbol) in self.symbols.iter().enumerate() {
- // The unified API allows creating symbols that we don't emit, so filter
- // them out here.
- //
- // Since we don't actually emit the symbol kind, we validate it here too.
- match symbol.kind {
- SymbolKind::Text | SymbolKind::Data | SymbolKind::Tls | SymbolKind::Unknown => {}
- SymbolKind::File | SymbolKind::Section => continue,
- SymbolKind::Null | SymbolKind::Label => {
- return Err(Error(format!(
- "unimplemented symbol `{}` kind {:?}",
- symbol.name().unwrap_or(""),
- symbol.kind
- )));
- }
- }
- if !symbol.name.is_empty() {
- symbol_offsets[index].str_id = Some(strtab.add(&symbol.name));
- }
- if symbol.is_undefined() {
- undefined_symbols.push(index);
- } else if symbol.is_local() {
- local_symbols.push(index);
- } else {
- external_symbols.push(index);
- }
- }
-
- external_symbols.sort_by_key(|index| &*self.symbols[*index].name);
- undefined_symbols.sort_by_key(|index| &*self.symbols[*index].name);
-
- // Count symbols.
- let mut nsyms = 0;
- for index in local_symbols
- .iter()
- .copied()
- .chain(external_symbols.iter().copied())
- .chain(undefined_symbols.iter().copied())
- {
- symbol_offsets[index].index = nsyms;
- nsyms += 1;
- }
-
- // Calculate size of relocations.
- for (index, section) in self.sections.iter().enumerate() {
- let count: usize = section
- .relocations
- .iter()
- .map(|reloc| 1 + usize::from(reloc.addend != 0))
- .sum();
- if count != 0 {
- offset = align(offset, pointer_align);
- section_offsets[index].reloc_offset = offset;
- section_offsets[index].reloc_count = count;
- let len = count * mem::size_of::<macho::Relocation<Endianness>>();
- offset += len;
- }
- }
-
- // Calculate size of symtab.
- offset = align(offset, pointer_align);
- let symtab_offset = offset;
- let symtab_len = nsyms * macho.nlist_size();
- offset += symtab_len;
-
- // Calculate size of strtab.
- let strtab_offset = offset;
- // Start with null name.
- let mut strtab_data = vec![0];
- strtab.write(1, &mut strtab_data);
- write_align(&mut strtab_data, pointer_align);
- offset += strtab_data.len();
-
- // Start writing.
- buffer
- .reserve(offset)
- .map_err(|_| Error(String::from("Cannot allocate buffer")))?;
-
- // Write file header.
- let (cputype, mut cpusubtype) = match (self.architecture, self.sub_architecture) {
- (Architecture::Arm, None) => (macho::CPU_TYPE_ARM, macho::CPU_SUBTYPE_ARM_ALL),
- (Architecture::Aarch64, None) => (macho::CPU_TYPE_ARM64, macho::CPU_SUBTYPE_ARM64_ALL),
- (Architecture::Aarch64, Some(SubArchitecture::Arm64E)) => {
- (macho::CPU_TYPE_ARM64, macho::CPU_SUBTYPE_ARM64E)
- }
- (Architecture::Aarch64_Ilp32, None) => {
- (macho::CPU_TYPE_ARM64_32, macho::CPU_SUBTYPE_ARM64_32_V8)
- }
- (Architecture::I386, None) => (macho::CPU_TYPE_X86, macho::CPU_SUBTYPE_I386_ALL),
- (Architecture::X86_64, None) => (macho::CPU_TYPE_X86_64, macho::CPU_SUBTYPE_X86_64_ALL),
- (Architecture::PowerPc, None) => {
- (macho::CPU_TYPE_POWERPC, macho::CPU_SUBTYPE_POWERPC_ALL)
- }
- (Architecture::PowerPc64, None) => {
- (macho::CPU_TYPE_POWERPC64, macho::CPU_SUBTYPE_POWERPC_ALL)
- }
- _ => {
- return Err(Error(format!(
- "unimplemented architecture {:?} with sub-architecture {:?}",
- self.architecture, self.sub_architecture
- )));
- }
- };
-
- if let Some(cpu_subtype) = self.macho_cpu_subtype {
- cpusubtype = cpu_subtype;
- }
-
- let flags = match self.flags {
- FileFlags::MachO { flags } => flags,
- _ => 0,
- };
- macho.write_mach_header(
- buffer,
- MachHeader {
- cputype,
- cpusubtype,
- filetype: macho::MH_OBJECT,
- ncmds,
- sizeofcmds: sizeofcmds as u32,
- flags,
- },
- );
-
- // Write segment command.
- debug_assert_eq!(segment_command_offset, buffer.len());
- macho.write_segment_command(
- buffer,
- SegmentCommand {
- cmdsize: segment_command_len as u32,
- segname: [0; 16],
- vmaddr: 0,
- vmsize: address,
- fileoff: segment_file_offset as u64,
- filesize: segment_file_size as u64,
- maxprot: macho::VM_PROT_READ | macho::VM_PROT_WRITE | macho::VM_PROT_EXECUTE,
- initprot: macho::VM_PROT_READ | macho::VM_PROT_WRITE | macho::VM_PROT_EXECUTE,
- nsects: self.sections.len() as u32,
- flags: 0,
- },
- );
-
- // Write section headers.
- for (index, section) in self.sections.iter().enumerate() {
- let mut sectname = [0; 16];
- sectname
- .get_mut(..section.name.len())
- .ok_or_else(|| {
- Error(format!(
- "section name `{}` is too long",
- section.name().unwrap_or(""),
- ))
- })?
- .copy_from_slice(&section.name);
- let mut segname = [0; 16];
- segname
- .get_mut(..section.segment.len())
- .ok_or_else(|| {
- Error(format!(
- "segment name `{}` is too long",
- section.segment().unwrap_or(""),
- ))
- })?
- .copy_from_slice(&section.segment);
- let flags = if let SectionFlags::MachO { flags } = section.flags {
- flags
- } else {
- match section.kind {
- SectionKind::Text => {
- macho::S_ATTR_PURE_INSTRUCTIONS | macho::S_ATTR_SOME_INSTRUCTIONS
- }
- SectionKind::Data => 0,
- SectionKind::ReadOnlyData | SectionKind::ReadOnlyDataWithRel => 0,
- SectionKind::ReadOnlyString => macho::S_CSTRING_LITERALS,
- SectionKind::UninitializedData | SectionKind::Common => macho::S_ZEROFILL,
- SectionKind::Tls => macho::S_THREAD_LOCAL_REGULAR,
- SectionKind::UninitializedTls => macho::S_THREAD_LOCAL_ZEROFILL,
- SectionKind::TlsVariables => macho::S_THREAD_LOCAL_VARIABLES,
- SectionKind::Debug => macho::S_ATTR_DEBUG,
- SectionKind::OtherString => macho::S_CSTRING_LITERALS,
- SectionKind::Other | SectionKind::Linker | SectionKind::Metadata => 0,
- SectionKind::Note | SectionKind::Unknown | SectionKind::Elf(_) => {
- return Err(Error(format!(
- "unimplemented section `{}` kind {:?}",
- section.name().unwrap_or(""),
- section.kind
- )));
- }
- }
- };
- macho.write_section(
- buffer,
- SectionHeader {
- sectname,
- segname,
- addr: section_offsets[index].address,
- size: section.size,
- offset: section_offsets[index].offset as u32,
- align: section.align.trailing_zeros(),
- reloff: section_offsets[index].reloc_offset as u32,
- nreloc: section_offsets[index].reloc_count as u32,
- flags,
- },
- );
- }
-
- // Write build version.
- if let Some(version) = &self.macho_build_version {
- debug_assert_eq!(build_version_offset, buffer.len());
- buffer.write(&macho::BuildVersionCommand {
- cmd: U32::new(endian, macho::LC_BUILD_VERSION),
- cmdsize: U32::new(endian, version.cmdsize()),
- platform: U32::new(endian, version.platform),
- minos: U32::new(endian, version.minos),
- sdk: U32::new(endian, version.sdk),
- ntools: U32::new(endian, 0),
- });
- }
-
- // Write symtab command.
- debug_assert_eq!(symtab_command_offset, buffer.len());
- let symtab_command = macho::SymtabCommand {
- cmd: U32::new(endian, macho::LC_SYMTAB),
- cmdsize: U32::new(endian, symtab_command_len as u32),
- symoff: U32::new(endian, symtab_offset as u32),
- nsyms: U32::new(endian, nsyms as u32),
- stroff: U32::new(endian, strtab_offset as u32),
- strsize: U32::new(endian, strtab_data.len() as u32),
- };
- buffer.write(&symtab_command);
-
- // Write dysymtab command.
- debug_assert_eq!(dysymtab_command_offset, buffer.len());
- let dysymtab_command = macho::DysymtabCommand {
- cmd: U32::new(endian, macho::LC_DYSYMTAB),
- cmdsize: U32::new(endian, dysymtab_command_len as u32),
- ilocalsym: U32::new(endian, 0),
- nlocalsym: U32::new(endian, local_symbols.len() as u32),
- iextdefsym: U32::new(endian, local_symbols.len() as u32),
- nextdefsym: U32::new(endian, external_symbols.len() as u32),
- iundefsym: U32::new(
- endian,
- local_symbols.len() as u32 + external_symbols.len() as u32,
- ),
- nundefsym: U32::new(endian, undefined_symbols.len() as u32),
- tocoff: U32::default(),
- ntoc: U32::default(),
- modtaboff: U32::default(),
- nmodtab: U32::default(),
- extrefsymoff: U32::default(),
- nextrefsyms: U32::default(),
- indirectsymoff: U32::default(),
- nindirectsyms: U32::default(),
- extreloff: U32::default(),
- nextrel: U32::default(),
- locreloff: U32::default(),
- nlocrel: U32::default(),
- };
- buffer.write(&dysymtab_command);
-
- // Write section data.
- for (index, section) in self.sections.iter().enumerate() {
- if !section.is_bss() {
- buffer.resize(section_offsets[index].offset);
- buffer.write_bytes(&section.data);
- }
- }
- debug_assert_eq!(segment_file_offset + segment_file_size, buffer.len());
-
- // Write relocations.
- for (index, section) in self.sections.iter().enumerate() {
- if !section.relocations.is_empty() {
- write_align(buffer, pointer_align);
- debug_assert_eq!(section_offsets[index].reloc_offset, buffer.len());
- for reloc in &section.relocations {
- let r_length = match reloc.size {
- 8 => 0,
- 16 => 1,
- 32 => 2,
- 64 => 3,
- _ => return Err(Error(format!("unimplemented reloc size {:?}", reloc))),
- };
-
- // Write explicit addend.
- if reloc.addend != 0 {
- let r_type = match self.architecture {
- Architecture::Aarch64 | Architecture::Aarch64_Ilp32 => {
- macho::ARM64_RELOC_ADDEND
- }
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)))
- }
- };
-
- let reloc_info = macho::RelocationInfo {
- r_address: reloc.offset as u32,
- r_symbolnum: reloc.addend as u32,
- r_pcrel: false,
- r_length,
- r_extern: false,
- r_type,
- };
- buffer.write(&reloc_info.relocation(endian));
- }
-
- let r_extern;
- let r_symbolnum;
- let symbol = &self.symbols[reloc.symbol.0];
- if symbol.kind == SymbolKind::Section {
- r_symbolnum = section_offsets[symbol.section.id().unwrap().0].index as u32;
- r_extern = false;
- } else {
- r_symbolnum = symbol_offsets[reloc.symbol.0].index as u32;
- r_extern = true;
- }
- let (r_pcrel, r_type) = match self.architecture {
- Architecture::I386 => match reloc.kind {
- RelocationKind::Absolute => (false, macho::GENERIC_RELOC_VANILLA),
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::X86_64 => match (reloc.kind, reloc.encoding) {
- (RelocationKind::Absolute, RelocationEncoding::Generic) => {
- (false, macho::X86_64_RELOC_UNSIGNED)
- }
- (RelocationKind::Relative, RelocationEncoding::Generic) => {
- (true, macho::X86_64_RELOC_SIGNED)
- }
- (RelocationKind::Relative, RelocationEncoding::X86RipRelative) => {
- (true, macho::X86_64_RELOC_SIGNED)
- }
- (RelocationKind::Relative, RelocationEncoding::X86Branch) => {
- (true, macho::X86_64_RELOC_BRANCH)
- }
- (RelocationKind::PltRelative, RelocationEncoding::X86Branch) => {
- (true, macho::X86_64_RELOC_BRANCH)
- }
- (RelocationKind::GotRelative, RelocationEncoding::Generic) => {
- (true, macho::X86_64_RELOC_GOT)
- }
- (
- RelocationKind::GotRelative,
- RelocationEncoding::X86RipRelativeMovq,
- ) => (true, macho::X86_64_RELOC_GOT_LOAD),
- (RelocationKind::MachO { value, relative }, _) => (relative, value),
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- },
- Architecture::Aarch64 | Architecture::Aarch64_Ilp32 => {
- match (reloc.kind, reloc.encoding) {
- (RelocationKind::Absolute, RelocationEncoding::Generic) => {
- (false, macho::ARM64_RELOC_UNSIGNED)
- }
- (RelocationKind::Relative, RelocationEncoding::AArch64Call) => {
- (true, macho::ARM64_RELOC_BRANCH26)
- }
- (
- RelocationKind::MachO { value, relative },
- RelocationEncoding::Generic,
- ) => (relative, value),
- _ => {
- return Err(Error(format!(
- "unimplemented relocation {:?}",
- reloc
- )));
- }
- }
- }
- _ => {
- if let RelocationKind::MachO { value, relative } = reloc.kind {
- (relative, value)
- } else {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- }
- };
- let reloc_info = macho::RelocationInfo {
- r_address: reloc.offset as u32,
- r_symbolnum,
- r_pcrel,
- r_length,
- r_extern,
- r_type,
- };
- buffer.write(&reloc_info.relocation(endian));
- }
- }
- }
-
- // Write symtab.
- write_align(buffer, pointer_align);
- debug_assert_eq!(symtab_offset, buffer.len());
- for index in local_symbols
- .iter()
- .copied()
- .chain(external_symbols.iter().copied())
- .chain(undefined_symbols.iter().copied())
- {
- let symbol = &self.symbols[index];
- // TODO: N_STAB
- let (mut n_type, n_sect) = match symbol.section {
- SymbolSection::Undefined => (macho::N_UNDF | macho::N_EXT, 0),
- SymbolSection::Absolute => (macho::N_ABS, 0),
- SymbolSection::Section(id) => (macho::N_SECT, id.0 + 1),
- SymbolSection::None | SymbolSection::Common => {
- return Err(Error(format!(
- "unimplemented symbol `{}` section {:?}",
- symbol.name().unwrap_or(""),
- symbol.section
- )));
- }
- };
- match symbol.scope {
- SymbolScope::Unknown | SymbolScope::Compilation => {}
- SymbolScope::Linkage => {
- n_type |= macho::N_EXT | macho::N_PEXT;
- }
- SymbolScope::Dynamic => {
- n_type |= macho::N_EXT;
- }
- }
-
- let n_desc = if let SymbolFlags::MachO { n_desc } = symbol.flags {
- n_desc
- } else {
- let mut n_desc = 0;
- if symbol.weak {
- if symbol.is_undefined() {
- n_desc |= macho::N_WEAK_REF;
- } else {
- n_desc |= macho::N_WEAK_DEF;
- }
- }
- n_desc
- };
-
- let n_value = match symbol.section.id() {
- Some(section) => section_offsets[section.0].address + symbol.value,
- None => symbol.value,
- };
-
- let n_strx = symbol_offsets[index]
- .str_id
- .map(|id| strtab.get_offset(id))
- .unwrap_or(0);
-
- macho.write_nlist(
- buffer,
- Nlist {
- n_strx: n_strx as u32,
- n_type,
- n_sect: n_sect as u8,
- n_desc,
- n_value,
- },
- );
- }
-
- // Write strtab.
- debug_assert_eq!(strtab_offset, buffer.len());
- buffer.write_bytes(&strtab_data);
-
- debug_assert_eq!(offset, buffer.len());
-
- Ok(())
- }
-}
-
-struct MachHeader {
- cputype: u32,
- cpusubtype: u32,
- filetype: u32,
- ncmds: u32,
- sizeofcmds: u32,
- flags: u32,
-}
-
-struct SegmentCommand {
- cmdsize: u32,
- segname: [u8; 16],
- vmaddr: u64,
- vmsize: u64,
- fileoff: u64,
- filesize: u64,
- maxprot: u32,
- initprot: u32,
- nsects: u32,
- flags: u32,
-}
-
-pub struct SectionHeader {
- sectname: [u8; 16],
- segname: [u8; 16],
- addr: u64,
- size: u64,
- offset: u32,
- align: u32,
- reloff: u32,
- nreloc: u32,
- flags: u32,
-}
-
-struct Nlist {
- n_strx: u32,
- n_type: u8,
- n_sect: u8,
- n_desc: u16,
- n_value: u64,
-}
-
-trait MachO {
- fn mach_header_size(&self) -> usize;
- fn segment_command_size(&self) -> usize;
- fn section_header_size(&self) -> usize;
- fn nlist_size(&self) -> usize;
- fn write_mach_header(&self, buffer: &mut dyn WritableBuffer, section: MachHeader);
- fn write_segment_command(&self, buffer: &mut dyn WritableBuffer, segment: SegmentCommand);
- fn write_section(&self, buffer: &mut dyn WritableBuffer, section: SectionHeader);
- fn write_nlist(&self, buffer: &mut dyn WritableBuffer, nlist: Nlist);
-}
-
-struct MachO32<E> {
- endian: E,
-}
-
-impl<E: Endian> MachO for MachO32<E> {
- fn mach_header_size(&self) -> usize {
- mem::size_of::<macho::MachHeader32<E>>()
- }
-
- fn segment_command_size(&self) -> usize {
- mem::size_of::<macho::SegmentCommand32<E>>()
- }
-
- fn section_header_size(&self) -> usize {
- mem::size_of::<macho::Section32<E>>()
- }
-
- fn nlist_size(&self) -> usize {
- mem::size_of::<macho::Nlist32<E>>()
- }
-
- fn write_mach_header(&self, buffer: &mut dyn WritableBuffer, header: MachHeader) {
- let endian = self.endian;
- let magic = if endian.is_big_endian() {
- macho::MH_MAGIC
- } else {
- macho::MH_CIGAM
- };
- let header = macho::MachHeader32 {
- magic: U32::new(BigEndian, magic),
- cputype: U32::new(endian, header.cputype),
- cpusubtype: U32::new(endian, header.cpusubtype),
- filetype: U32::new(endian, header.filetype),
- ncmds: U32::new(endian, header.ncmds),
- sizeofcmds: U32::new(endian, header.sizeofcmds),
- flags: U32::new(endian, header.flags),
- };
- buffer.write(&header);
- }
-
- fn write_segment_command(&self, buffer: &mut dyn WritableBuffer, segment: SegmentCommand) {
- let endian = self.endian;
- let segment = macho::SegmentCommand32 {
- cmd: U32::new(endian, macho::LC_SEGMENT),
- cmdsize: U32::new(endian, segment.cmdsize),
- segname: segment.segname,
- vmaddr: U32::new(endian, segment.vmaddr as u32),
- vmsize: U32::new(endian, segment.vmsize as u32),
- fileoff: U32::new(endian, segment.fileoff as u32),
- filesize: U32::new(endian, segment.filesize as u32),
- maxprot: U32::new(endian, segment.maxprot),
- initprot: U32::new(endian, segment.initprot),
- nsects: U32::new(endian, segment.nsects),
- flags: U32::new(endian, segment.flags),
- };
- buffer.write(&segment);
- }
-
- fn write_section(&self, buffer: &mut dyn WritableBuffer, section: SectionHeader) {
- let endian = self.endian;
- let section = macho::Section32 {
- sectname: section.sectname,
- segname: section.segname,
- addr: U32::new(endian, section.addr as u32),
- size: U32::new(endian, section.size as u32),
- offset: U32::new(endian, section.offset),
- align: U32::new(endian, section.align),
- reloff: U32::new(endian, section.reloff),
- nreloc: U32::new(endian, section.nreloc),
- flags: U32::new(endian, section.flags),
- reserved1: U32::default(),
- reserved2: U32::default(),
- };
- buffer.write(&section);
- }
-
- fn write_nlist(&self, buffer: &mut dyn WritableBuffer, nlist: Nlist) {
- let endian = self.endian;
- let nlist = macho::Nlist32 {
- n_strx: U32::new(endian, nlist.n_strx),
- n_type: nlist.n_type,
- n_sect: nlist.n_sect,
- n_desc: U16::new(endian, nlist.n_desc),
- n_value: U32::new(endian, nlist.n_value as u32),
- };
- buffer.write(&nlist);
- }
-}
-
-struct MachO64<E> {
- endian: E,
-}
-
-impl<E: Endian> MachO for MachO64<E> {
- fn mach_header_size(&self) -> usize {
- mem::size_of::<macho::MachHeader64<E>>()
- }
-
- fn segment_command_size(&self) -> usize {
- mem::size_of::<macho::SegmentCommand64<E>>()
- }
-
- fn section_header_size(&self) -> usize {
- mem::size_of::<macho::Section64<E>>()
- }
-
- fn nlist_size(&self) -> usize {
- mem::size_of::<macho::Nlist64<E>>()
- }
-
- fn write_mach_header(&self, buffer: &mut dyn WritableBuffer, header: MachHeader) {
- let endian = self.endian;
- let magic = if endian.is_big_endian() {
- macho::MH_MAGIC_64
- } else {
- macho::MH_CIGAM_64
- };
- let header = macho::MachHeader64 {
- magic: U32::new(BigEndian, magic),
- cputype: U32::new(endian, header.cputype),
- cpusubtype: U32::new(endian, header.cpusubtype),
- filetype: U32::new(endian, header.filetype),
- ncmds: U32::new(endian, header.ncmds),
- sizeofcmds: U32::new(endian, header.sizeofcmds),
- flags: U32::new(endian, header.flags),
- reserved: U32::default(),
- };
- buffer.write(&header);
- }
-
- fn write_segment_command(&self, buffer: &mut dyn WritableBuffer, segment: SegmentCommand) {
- let endian = self.endian;
- let segment = macho::SegmentCommand64 {
- cmd: U32::new(endian, macho::LC_SEGMENT_64),
- cmdsize: U32::new(endian, segment.cmdsize),
- segname: segment.segname,
- vmaddr: U64::new(endian, segment.vmaddr),
- vmsize: U64::new(endian, segment.vmsize),
- fileoff: U64::new(endian, segment.fileoff),
- filesize: U64::new(endian, segment.filesize),
- maxprot: U32::new(endian, segment.maxprot),
- initprot: U32::new(endian, segment.initprot),
- nsects: U32::new(endian, segment.nsects),
- flags: U32::new(endian, segment.flags),
- };
- buffer.write(&segment);
- }
-
- fn write_section(&self, buffer: &mut dyn WritableBuffer, section: SectionHeader) {
- let endian = self.endian;
- let section = macho::Section64 {
- sectname: section.sectname,
- segname: section.segname,
- addr: U64::new(endian, section.addr),
- size: U64::new(endian, section.size),
- offset: U32::new(endian, section.offset),
- align: U32::new(endian, section.align),
- reloff: U32::new(endian, section.reloff),
- nreloc: U32::new(endian, section.nreloc),
- flags: U32::new(endian, section.flags),
- reserved1: U32::default(),
- reserved2: U32::default(),
- reserved3: U32::default(),
- };
- buffer.write(&section);
- }
-
- fn write_nlist(&self, buffer: &mut dyn WritableBuffer, nlist: Nlist) {
- let endian = self.endian;
- let nlist = macho::Nlist64 {
- n_strx: U32::new(endian, nlist.n_strx),
- n_type: nlist.n_type,
- n_sect: nlist.n_sect,
- n_desc: U16::new(endian, nlist.n_desc),
- n_value: U64Bytes::new(endian, nlist.n_value),
- };
- buffer.write(&nlist);
- }
-}
diff --git a/vendor/object/src/write/mod.rs b/vendor/object/src/write/mod.rs
deleted file mode 100644
index cea4d2e..0000000
--- a/vendor/object/src/write/mod.rs
+++ /dev/null
@@ -1,961 +0,0 @@
-//! Interface for writing object files.
-
-use alloc::borrow::Cow;
-use alloc::string::String;
-use alloc::vec::Vec;
-use core::{fmt, result, str};
-#[cfg(not(feature = "std"))]
-use hashbrown::HashMap;
-#[cfg(feature = "std")]
-use std::{boxed::Box, collections::HashMap, error, io};
-
-use crate::endian::{Endianness, U32, U64};
-use crate::{
- Architecture, BinaryFormat, ComdatKind, FileFlags, RelocationEncoding, RelocationKind,
- SectionFlags, SectionKind, SubArchitecture, SymbolFlags, SymbolKind, SymbolScope,
-};
-
-#[cfg(feature = "coff")]
-pub mod coff;
-#[cfg(feature = "coff")]
-pub use coff::CoffExportStyle;
-
-#[cfg(feature = "elf")]
-pub mod elf;
-
-#[cfg(feature = "macho")]
-mod macho;
-#[cfg(feature = "macho")]
-pub use macho::MachOBuildVersion;
-
-#[cfg(feature = "pe")]
-pub mod pe;
-
-#[cfg(feature = "xcoff")]
-mod xcoff;
-
-mod string;
-pub use string::StringId;
-
-mod util;
-pub use util::*;
-
-/// The error type used within the write module.
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct Error(String);
-
-impl fmt::Display for Error {
- #[inline]
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(&self.0)
- }
-}
-
-#[cfg(feature = "std")]
-impl error::Error for Error {}
-
-/// The result type used within the write module.
-pub type Result<T> = result::Result<T, Error>;
-
-/// A writable relocatable object file.
-#[derive(Debug)]
-pub struct Object<'a> {
- format: BinaryFormat,
- architecture: Architecture,
- sub_architecture: Option<SubArchitecture>,
- endian: Endianness,
- sections: Vec<Section<'a>>,
- standard_sections: HashMap<StandardSection, SectionId>,
- symbols: Vec<Symbol>,
- symbol_map: HashMap<Vec<u8>, SymbolId>,
- stub_symbols: HashMap<SymbolId, SymbolId>,
- comdats: Vec<Comdat>,
- /// File flags that are specific to each file format.
- pub flags: FileFlags,
- /// The symbol name mangling scheme.
- pub mangling: Mangling,
- /// Mach-O "_tlv_bootstrap" symbol.
- tlv_bootstrap: Option<SymbolId>,
- /// Mach-O CPU subtype.
- #[cfg(feature = "macho")]
- macho_cpu_subtype: Option<u32>,
- #[cfg(feature = "macho")]
- macho_build_version: Option<MachOBuildVersion>,
-}
-
-impl<'a> Object<'a> {
- /// Create an empty object file.
- pub fn new(format: BinaryFormat, architecture: Architecture, endian: Endianness) -> Object<'a> {
- Object {
- format,
- architecture,
- sub_architecture: None,
- endian,
- sections: Vec::new(),
- standard_sections: HashMap::new(),
- symbols: Vec::new(),
- symbol_map: HashMap::new(),
- stub_symbols: HashMap::new(),
- comdats: Vec::new(),
- flags: FileFlags::None,
- mangling: Mangling::default(format, architecture),
- tlv_bootstrap: None,
- #[cfg(feature = "macho")]
- macho_cpu_subtype: None,
- #[cfg(feature = "macho")]
- macho_build_version: None,
- }
- }
-
- /// Return the file format.
- #[inline]
- pub fn format(&self) -> BinaryFormat {
- self.format
- }
-
- /// Return the architecture.
- #[inline]
- pub fn architecture(&self) -> Architecture {
- self.architecture
- }
-
- /// Return the sub-architecture.
- #[inline]
- pub fn sub_architecture(&self) -> Option<SubArchitecture> {
- self.sub_architecture
- }
-
- /// Specify the sub-architecture.
- pub fn set_sub_architecture(&mut self, sub_architecture: Option<SubArchitecture>) {
- self.sub_architecture = sub_architecture;
- }
-
- /// Return the current mangling setting.
- #[inline]
- pub fn mangling(&self) -> Mangling {
- self.mangling
- }
-
- /// Specify the mangling setting.
- #[inline]
- pub fn set_mangling(&mut self, mangling: Mangling) {
- self.mangling = mangling;
- }
-
- /// Return the name for a standard segment.
- ///
- /// This will vary based on the file format.
- #[allow(unused_variables)]
- pub fn segment_name(&self, segment: StandardSegment) -> &'static [u8] {
- match self.format {
- #[cfg(feature = "coff")]
- BinaryFormat::Coff => &[],
- #[cfg(feature = "elf")]
- BinaryFormat::Elf => &[],
- #[cfg(feature = "macho")]
- BinaryFormat::MachO => self.macho_segment_name(segment),
- _ => unimplemented!(),
- }
- }
-
- /// Get the section with the given `SectionId`.
- #[inline]
- pub fn section(&self, section: SectionId) -> &Section<'a> {
- &self.sections[section.0]
- }
-
- /// Mutably get the section with the given `SectionId`.
- #[inline]
- pub fn section_mut(&mut self, section: SectionId) -> &mut Section<'a> {
- &mut self.sections[section.0]
- }
-
- /// Set the data for an existing section.
- ///
- /// Must not be called for sections that already have data, or that contain uninitialized data.
- pub fn set_section_data<T>(&mut self, section: SectionId, data: T, align: u64)
- where
- T: Into<Cow<'a, [u8]>>,
- {
- self.sections[section.0].set_data(data, align)
- }
-
- /// Append data to an existing section. Returns the section offset of the data.
- pub fn append_section_data(&mut self, section: SectionId, data: &[u8], align: u64) -> u64 {
- self.sections[section.0].append_data(data, align)
- }
-
- /// Append zero-initialized data to an existing section. Returns the section offset of the data.
- pub fn append_section_bss(&mut self, section: SectionId, size: u64, align: u64) -> u64 {
- self.sections[section.0].append_bss(size, align)
- }
-
- /// Return the `SectionId` of a standard section.
- ///
- /// If the section doesn't already exist then it is created.
- pub fn section_id(&mut self, section: StandardSection) -> SectionId {
- self.standard_sections
- .get(&section)
- .cloned()
- .unwrap_or_else(|| {
- let (segment, name, kind, flags) = self.section_info(section);
- let id = self.add_section(segment.to_vec(), name.to_vec(), kind);
- self.section_mut(id).flags = flags;
- id
- })
- }
-
- /// Add a new section and return its `SectionId`.
- ///
- /// This also creates a section symbol.
- pub fn add_section(&mut self, segment: Vec<u8>, name: Vec<u8>, kind: SectionKind) -> SectionId {
- let id = SectionId(self.sections.len());
- self.sections.push(Section {
- segment,
- name,
- kind,
- size: 0,
- align: 1,
- data: Cow::Borrowed(&[]),
- relocations: Vec::new(),
- symbol: None,
- flags: SectionFlags::None,
- });
-
- // Add to self.standard_sections if required. This may match multiple standard sections.
- let section = &self.sections[id.0];
- for standard_section in StandardSection::all() {
- if !self.standard_sections.contains_key(standard_section) {
- let (segment, name, kind, _flags) = self.section_info(*standard_section);
- if segment == &*section.segment && name == &*section.name && kind == section.kind {
- self.standard_sections.insert(*standard_section, id);
- }
- }
- }
-
- id
- }
-
- fn section_info(
- &self,
- section: StandardSection,
- ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) {
- match self.format {
- #[cfg(feature = "coff")]
- BinaryFormat::Coff => self.coff_section_info(section),
- #[cfg(feature = "elf")]
- BinaryFormat::Elf => self.elf_section_info(section),
- #[cfg(feature = "macho")]
- BinaryFormat::MachO => self.macho_section_info(section),
- #[cfg(feature = "xcoff")]
- BinaryFormat::Xcoff => self.xcoff_section_info(section),
- _ => unimplemented!(),
- }
- }
-
- /// Add a subsection. Returns the `SectionId` and section offset of the data.
- pub fn add_subsection(
- &mut self,
- section: StandardSection,
- name: &[u8],
- data: &[u8],
- align: u64,
- ) -> (SectionId, u64) {
- let section_id = if self.has_subsections_via_symbols() {
- self.set_subsections_via_symbols();
- self.section_id(section)
- } else {
- let (segment, name, kind, flags) = self.subsection_info(section, name);
- let id = self.add_section(segment.to_vec(), name, kind);
- self.section_mut(id).flags = flags;
- id
- };
- let offset = self.append_section_data(section_id, data, align);
- (section_id, offset)
- }
-
- fn has_subsections_via_symbols(&self) -> bool {
- match self.format {
- BinaryFormat::Coff | BinaryFormat::Elf | BinaryFormat::Xcoff => false,
- BinaryFormat::MachO => true,
- _ => unimplemented!(),
- }
- }
-
- fn set_subsections_via_symbols(&mut self) {
- match self.format {
- #[cfg(feature = "macho")]
- BinaryFormat::MachO => self.macho_set_subsections_via_symbols(),
- _ => unimplemented!(),
- }
- }
-
- fn subsection_info(
- &self,
- section: StandardSection,
- value: &[u8],
- ) -> (&'static [u8], Vec<u8>, SectionKind, SectionFlags) {
- let (segment, section, kind, flags) = self.section_info(section);
- let name = self.subsection_name(section, value);
- (segment, name, kind, flags)
- }
-
- #[allow(unused_variables)]
- fn subsection_name(&self, section: &[u8], value: &[u8]) -> Vec<u8> {
- debug_assert!(!self.has_subsections_via_symbols());
- match self.format {
- #[cfg(feature = "coff")]
- BinaryFormat::Coff => self.coff_subsection_name(section, value),
- #[cfg(feature = "elf")]
- BinaryFormat::Elf => self.elf_subsection_name(section, value),
- _ => unimplemented!(),
- }
- }
-
- /// Get the COMDAT section group with the given `ComdatId`.
- #[inline]
- pub fn comdat(&self, comdat: ComdatId) -> &Comdat {
- &self.comdats[comdat.0]
- }
-
- /// Mutably get the COMDAT section group with the given `ComdatId`.
- #[inline]
- pub fn comdat_mut(&mut self, comdat: ComdatId) -> &mut Comdat {
- &mut self.comdats[comdat.0]
- }
-
- /// Add a new COMDAT section group and return its `ComdatId`.
- pub fn add_comdat(&mut self, comdat: Comdat) -> ComdatId {
- let comdat_id = ComdatId(self.comdats.len());
- self.comdats.push(comdat);
- comdat_id
- }
-
- /// Get the `SymbolId` of the symbol with the given name.
- pub fn symbol_id(&self, name: &[u8]) -> Option<SymbolId> {
- self.symbol_map.get(name).cloned()
- }
-
- /// Get the symbol with the given `SymbolId`.
- #[inline]
- pub fn symbol(&self, symbol: SymbolId) -> &Symbol {
- &self.symbols[symbol.0]
- }
-
- /// Mutably get the symbol with the given `SymbolId`.
- #[inline]
- pub fn symbol_mut(&mut self, symbol: SymbolId) -> &mut Symbol {
- &mut self.symbols[symbol.0]
- }
-
- /// Add a new symbol and return its `SymbolId`.
- pub fn add_symbol(&mut self, mut symbol: Symbol) -> SymbolId {
- // Defined symbols must have a scope.
- debug_assert!(symbol.is_undefined() || symbol.scope != SymbolScope::Unknown);
- if symbol.kind == SymbolKind::Section {
- // There can only be one section symbol, but update its flags, since
- // the automatically generated section symbol will have none.
- let symbol_id = self.section_symbol(symbol.section.id().unwrap());
- if symbol.flags != SymbolFlags::None {
- self.symbol_mut(symbol_id).flags = symbol.flags;
- }
- return symbol_id;
- }
- if !symbol.name.is_empty()
- && (symbol.kind == SymbolKind::Text
- || symbol.kind == SymbolKind::Data
- || symbol.kind == SymbolKind::Tls)
- {
- let unmangled_name = symbol.name.clone();
- if let Some(prefix) = self.mangling.global_prefix() {
- symbol.name.insert(0, prefix);
- }
- let symbol_id = self.add_raw_symbol(symbol);
- self.symbol_map.insert(unmangled_name, symbol_id);
- symbol_id
- } else {
- self.add_raw_symbol(symbol)
- }
- }
-
- fn add_raw_symbol(&mut self, symbol: Symbol) -> SymbolId {
- let symbol_id = SymbolId(self.symbols.len());
- self.symbols.push(symbol);
- symbol_id
- }
-
- /// Return true if the file format supports `StandardSection::UninitializedTls`.
- #[inline]
- pub fn has_uninitialized_tls(&self) -> bool {
- self.format != BinaryFormat::Coff
- }
-
- /// Return true if the file format supports `StandardSection::Common`.
- #[inline]
- pub fn has_common(&self) -> bool {
- self.format == BinaryFormat::MachO
- }
-
- /// Add a new common symbol and return its `SymbolId`.
- ///
- /// For Mach-O, this appends the symbol to the `__common` section.
- pub fn add_common_symbol(&mut self, mut symbol: Symbol, size: u64, align: u64) -> SymbolId {
- if self.has_common() {
- let symbol_id = self.add_symbol(symbol);
- let section = self.section_id(StandardSection::Common);
- self.add_symbol_bss(symbol_id, section, size, align);
- symbol_id
- } else {
- symbol.section = SymbolSection::Common;
- symbol.size = size;
- self.add_symbol(symbol)
- }
- }
-
- /// Add a new file symbol and return its `SymbolId`.
- pub fn add_file_symbol(&mut self, name: Vec<u8>) -> SymbolId {
- self.add_raw_symbol(Symbol {
- name,
- value: 0,
- size: 0,
- kind: SymbolKind::File,
- scope: SymbolScope::Compilation,
- weak: false,
- section: SymbolSection::None,
- flags: SymbolFlags::None,
- })
- }
-
- /// Get the symbol for a section.
- pub fn section_symbol(&mut self, section_id: SectionId) -> SymbolId {
- let section = &mut self.sections[section_id.0];
- if let Some(symbol) = section.symbol {
- return symbol;
- }
- let name = if self.format == BinaryFormat::Coff {
- section.name.clone()
- } else {
- Vec::new()
- };
- let symbol_id = SymbolId(self.symbols.len());
- self.symbols.push(Symbol {
- name,
- value: 0,
- size: 0,
- kind: SymbolKind::Section,
- scope: SymbolScope::Compilation,
- weak: false,
- section: SymbolSection::Section(section_id),
- flags: SymbolFlags::None,
- });
- section.symbol = Some(symbol_id);
- symbol_id
- }
-
- /// Append data to an existing section, and update a symbol to refer to it.
- ///
- /// For Mach-O, this also creates a `__thread_vars` entry for TLS symbols, and the
- /// symbol will indirectly point to the added data via the `__thread_vars` entry.
- ///
- /// Returns the section offset of the data.
- pub fn add_symbol_data(
- &mut self,
- symbol_id: SymbolId,
- section: SectionId,
- data: &[u8],
- align: u64,
- ) -> u64 {
- let offset = self.append_section_data(section, data, align);
- self.set_symbol_data(symbol_id, section, offset, data.len() as u64);
- offset
- }
-
- /// Append zero-initialized data to an existing section, and update a symbol to refer to it.
- ///
- /// For Mach-O, this also creates a `__thread_vars` entry for TLS symbols, and the
- /// symbol will indirectly point to the added data via the `__thread_vars` entry.
- ///
- /// Returns the section offset of the data.
- pub fn add_symbol_bss(
- &mut self,
- symbol_id: SymbolId,
- section: SectionId,
- size: u64,
- align: u64,
- ) -> u64 {
- let offset = self.append_section_bss(section, size, align);
- self.set_symbol_data(symbol_id, section, offset, size);
- offset
- }
-
- /// Update a symbol to refer to the given data within a section.
- ///
- /// For Mach-O, this also creates a `__thread_vars` entry for TLS symbols, and the
- /// symbol will indirectly point to the data via the `__thread_vars` entry.
- #[allow(unused_mut)]
- pub fn set_symbol_data(
- &mut self,
- mut symbol_id: SymbolId,
- section: SectionId,
- offset: u64,
- size: u64,
- ) {
- // Defined symbols must have a scope.
- debug_assert!(self.symbol(symbol_id).scope != SymbolScope::Unknown);
- match self.format {
- #[cfg(feature = "macho")]
- BinaryFormat::MachO => symbol_id = self.macho_add_thread_var(symbol_id),
- _ => {}
- }
- let symbol = self.symbol_mut(symbol_id);
- symbol.value = offset;
- symbol.size = size;
- symbol.section = SymbolSection::Section(section);
- }
-
- /// Convert a symbol to a section symbol and offset.
- ///
- /// Returns `None` if the symbol does not have a section.
- pub fn symbol_section_and_offset(&mut self, symbol_id: SymbolId) -> Option<(SymbolId, u64)> {
- let symbol = self.symbol(symbol_id);
- if symbol.kind == SymbolKind::Section {
- return Some((symbol_id, 0));
- }
- let symbol_offset = symbol.value;
- let section = symbol.section.id()?;
- let section_symbol = self.section_symbol(section);
- Some((section_symbol, symbol_offset))
- }
-
- /// Add a relocation to a section.
- ///
- /// Relocations must only be added after the referenced symbols have been added
- /// and defined (if applicable).
- pub fn add_relocation(&mut self, section: SectionId, mut relocation: Relocation) -> Result<()> {
- let addend = match self.format {
- #[cfg(feature = "coff")]
- BinaryFormat::Coff => self.coff_fixup_relocation(&mut relocation),
- #[cfg(feature = "elf")]
- BinaryFormat::Elf => self.elf_fixup_relocation(&mut relocation)?,
- #[cfg(feature = "macho")]
- BinaryFormat::MachO => self.macho_fixup_relocation(&mut relocation),
- #[cfg(feature = "xcoff")]
- BinaryFormat::Xcoff => self.xcoff_fixup_relocation(&mut relocation),
- _ => unimplemented!(),
- };
- if addend != 0 {
- self.write_relocation_addend(section, &relocation, addend)?;
- }
- self.sections[section.0].relocations.push(relocation);
- Ok(())
- }
-
- fn write_relocation_addend(
- &mut self,
- section: SectionId,
- relocation: &Relocation,
- addend: i64,
- ) -> Result<()> {
- let data = self.sections[section.0].data_mut();
- let offset = relocation.offset as usize;
- match relocation.size {
- 32 => data.write_at(offset, &U32::new(self.endian, addend as u32)),
- 64 => data.write_at(offset, &U64::new(self.endian, addend as u64)),
- _ => {
- return Err(Error(format!(
- "unimplemented relocation addend {:?}",
- relocation
- )));
- }
- }
- .map_err(|_| {
- Error(format!(
- "invalid relocation offset {}+{} (max {})",
- relocation.offset,
- relocation.size,
- data.len()
- ))
- })
- }
-
- /// Write the object to a `Vec`.
- pub fn write(&self) -> Result<Vec<u8>> {
- let mut buffer = Vec::new();
- self.emit(&mut buffer)?;
- Ok(buffer)
- }
-
- /// Write the object to a `Write` implementation.
- ///
- /// Also flushes the writer.
- ///
- /// It is advisable to use a buffered writer like [`BufWriter`](std::io::BufWriter)
- /// instead of an unbuffered writer like [`File`](std::fs::File).
- #[cfg(feature = "std")]
- pub fn write_stream<W: io::Write>(&self, w: W) -> result::Result<(), Box<dyn error::Error>> {
- let mut stream = StreamingBuffer::new(w);
- self.emit(&mut stream)?;
- stream.result()?;
- stream.into_inner().flush()?;
- Ok(())
- }
-
- /// Write the object to a `WritableBuffer`.
- pub fn emit(&self, buffer: &mut dyn WritableBuffer) -> Result<()> {
- match self.format {
- #[cfg(feature = "coff")]
- BinaryFormat::Coff => self.coff_write(buffer),
- #[cfg(feature = "elf")]
- BinaryFormat::Elf => self.elf_write(buffer),
- #[cfg(feature = "macho")]
- BinaryFormat::MachO => self.macho_write(buffer),
- #[cfg(feature = "xcoff")]
- BinaryFormat::Xcoff => self.xcoff_write(buffer),
- _ => unimplemented!(),
- }
- }
-}
-
-/// A standard segment kind.
-#[allow(missing_docs)]
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[non_exhaustive]
-pub enum StandardSegment {
- Text,
- Data,
- Debug,
-}
-
-/// A standard section kind.
-#[allow(missing_docs)]
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[non_exhaustive]
-pub enum StandardSection {
- Text,
- Data,
- ReadOnlyData,
- ReadOnlyDataWithRel,
- ReadOnlyString,
- UninitializedData,
- Tls,
- /// Zero-fill TLS initializers. Unsupported for COFF.
- UninitializedTls,
- /// TLS variable structures. Only supported for Mach-O.
- TlsVariables,
- /// Common data. Only supported for Mach-O.
- Common,
- /// Notes for GNU properties. Only supported for ELF.
- GnuProperty,
-}
-
-impl StandardSection {
- /// Return the section kind of a standard section.
- pub fn kind(self) -> SectionKind {
- match self {
- StandardSection::Text => SectionKind::Text,
- StandardSection::Data => SectionKind::Data,
- StandardSection::ReadOnlyData => SectionKind::ReadOnlyData,
- StandardSection::ReadOnlyDataWithRel => SectionKind::ReadOnlyDataWithRel,
- StandardSection::ReadOnlyString => SectionKind::ReadOnlyString,
- StandardSection::UninitializedData => SectionKind::UninitializedData,
- StandardSection::Tls => SectionKind::Tls,
- StandardSection::UninitializedTls => SectionKind::UninitializedTls,
- StandardSection::TlsVariables => SectionKind::TlsVariables,
- StandardSection::Common => SectionKind::Common,
- StandardSection::GnuProperty => SectionKind::Note,
- }
- }
-
- // TODO: remembering to update this is error-prone, can we do better?
- fn all() -> &'static [StandardSection] {
- &[
- StandardSection::Text,
- StandardSection::Data,
- StandardSection::ReadOnlyData,
- StandardSection::ReadOnlyDataWithRel,
- StandardSection::ReadOnlyString,
- StandardSection::UninitializedData,
- StandardSection::Tls,
- StandardSection::UninitializedTls,
- StandardSection::TlsVariables,
- StandardSection::Common,
- StandardSection::GnuProperty,
- ]
- }
-}
-
-/// An identifier used to reference a section.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct SectionId(usize);
-
-/// A section in an object file.
-#[derive(Debug)]
-pub struct Section<'a> {
- segment: Vec<u8>,
- name: Vec<u8>,
- kind: SectionKind,
- size: u64,
- align: u64,
- data: Cow<'a, [u8]>,
- relocations: Vec<Relocation>,
- symbol: Option<SymbolId>,
- /// Section flags that are specific to each file format.
- pub flags: SectionFlags,
-}
-
-impl<'a> Section<'a> {
- /// Try to convert the name to a utf8 string.
- #[inline]
- pub fn name(&self) -> Option<&str> {
- str::from_utf8(&self.name).ok()
- }
-
- /// Try to convert the segment to a utf8 string.
- #[inline]
- pub fn segment(&self) -> Option<&str> {
- str::from_utf8(&self.segment).ok()
- }
-
- /// Return true if this section contains zerofill data.
- #[inline]
- pub fn is_bss(&self) -> bool {
- self.kind.is_bss()
- }
-
- /// Set the data for a section.
- ///
- /// Must not be called for sections that already have data, or that contain uninitialized data.
- pub fn set_data<T>(&mut self, data: T, align: u64)
- where
- T: Into<Cow<'a, [u8]>>,
- {
- debug_assert!(!self.is_bss());
- debug_assert_eq!(align & (align - 1), 0);
- debug_assert!(self.data.is_empty());
- self.data = data.into();
- self.size = self.data.len() as u64;
- self.align = align;
- }
-
- /// Append data to a section.
- ///
- /// Must not be called for sections that contain uninitialized data.
- pub fn append_data(&mut self, append_data: &[u8], align: u64) -> u64 {
- debug_assert!(!self.is_bss());
- debug_assert_eq!(align & (align - 1), 0);
- if self.align < align {
- self.align = align;
- }
- let align = align as usize;
- let data = self.data.to_mut();
- let mut offset = data.len();
- if offset & (align - 1) != 0 {
- offset += align - (offset & (align - 1));
- data.resize(offset, 0);
- }
- data.extend_from_slice(append_data);
- self.size = data.len() as u64;
- offset as u64
- }
-
- /// Append uninitialized data to a section.
- ///
- /// Must not be called for sections that contain initialized data.
- pub fn append_bss(&mut self, size: u64, align: u64) -> u64 {
- debug_assert!(self.is_bss());
- debug_assert_eq!(align & (align - 1), 0);
- if self.align < align {
- self.align = align;
- }
- let mut offset = self.size;
- if offset & (align - 1) != 0 {
- offset += align - (offset & (align - 1));
- self.size = offset;
- }
- self.size += size;
- offset
- }
-
- /// Returns the section as-built so far.
- ///
- /// This requires that the section is not a bss section.
- pub fn data(&self) -> &[u8] {
- debug_assert!(!self.is_bss());
- &self.data
- }
-
- /// Returns the section as-built so far.
- ///
- /// This requires that the section is not a bss section.
- pub fn data_mut(&mut self) -> &mut [u8] {
- debug_assert!(!self.is_bss());
- self.data.to_mut()
- }
-}
-
-/// The section where a symbol is defined.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum SymbolSection {
- /// The section is not applicable for this symbol (such as file symbols).
- None,
- /// The symbol is undefined.
- Undefined,
- /// The symbol has an absolute value.
- Absolute,
- /// The symbol is a zero-initialized symbol that will be combined with duplicate definitions.
- Common,
- /// The symbol is defined in the given section.
- Section(SectionId),
-}
-
-impl SymbolSection {
- /// Returns the section id for the section where the symbol is defined.
- ///
- /// May return `None` if the symbol is not defined in a section.
- #[inline]
- pub fn id(self) -> Option<SectionId> {
- if let SymbolSection::Section(id) = self {
- Some(id)
- } else {
- None
- }
- }
-}
-
-/// An identifier used to reference a symbol.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct SymbolId(usize);
-
-/// A symbol in an object file.
-#[derive(Debug)]
-pub struct Symbol {
- /// The name of the symbol.
- pub name: Vec<u8>,
- /// The value of the symbol.
- ///
- /// If the symbol defined in a section, then this is the section offset of the symbol.
- pub value: u64,
- /// The size of the symbol.
- pub size: u64,
- /// The kind of the symbol.
- pub kind: SymbolKind,
- /// The scope of the symbol.
- pub scope: SymbolScope,
- /// Whether the symbol has weak binding.
- pub weak: bool,
- /// The section containing the symbol.
- pub section: SymbolSection,
- /// Symbol flags that are specific to each file format.
- pub flags: SymbolFlags<SectionId, SymbolId>,
-}
-
-impl Symbol {
- /// Try to convert the name to a utf8 string.
- #[inline]
- pub fn name(&self) -> Option<&str> {
- str::from_utf8(&self.name).ok()
- }
-
- /// Return true if the symbol is undefined.
- #[inline]
- pub fn is_undefined(&self) -> bool {
- self.section == SymbolSection::Undefined
- }
-
- /// Return true if the symbol is common data.
- ///
- /// Note: does not check for `SymbolSection::Section` with `SectionKind::Common`.
- #[inline]
- pub fn is_common(&self) -> bool {
- self.section == SymbolSection::Common
- }
-
- /// Return true if the symbol scope is local.
- #[inline]
- pub fn is_local(&self) -> bool {
- self.scope == SymbolScope::Compilation
- }
-}
-
-/// A relocation in an object file.
-#[derive(Debug)]
-pub struct Relocation {
- /// The section offset of the place of the relocation.
- pub offset: u64,
- /// The size in bits of the place of relocation.
- pub size: u8,
- /// The operation used to calculate the result of the relocation.
- pub kind: RelocationKind,
- /// Information about how the result of the relocation operation is encoded in the place.
- pub encoding: RelocationEncoding,
- /// The symbol referred to by the relocation.
- ///
- /// This may be a section symbol.
- pub symbol: SymbolId,
- /// The addend to use in the relocation calculation.
- ///
- /// This may be in addition to an implicit addend stored at the place of the relocation.
- pub addend: i64,
-}
-
-/// An identifier used to reference a COMDAT section group.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct ComdatId(usize);
-
-/// A COMDAT section group.
-#[derive(Debug)]
-pub struct Comdat {
- /// The COMDAT selection kind.
- ///
- /// This determines the way in which the linker resolves multiple definitions of the COMDAT
- /// sections.
- pub kind: ComdatKind,
- /// The COMDAT symbol.
- ///
- /// If this symbol is referenced, then all sections in the group will be included by the
- /// linker.
- pub symbol: SymbolId,
- /// The sections in the group.
- pub sections: Vec<SectionId>,
-}
-
-/// The symbol name mangling scheme.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[non_exhaustive]
-pub enum Mangling {
- /// No symbol mangling.
- None,
- /// Windows COFF symbol mangling.
- Coff,
- /// Windows COFF i386 symbol mangling.
- CoffI386,
- /// ELF symbol mangling.
- Elf,
- /// Mach-O symbol mangling.
- MachO,
- /// Xcoff symbol mangling.
- Xcoff,
-}
-
-impl Mangling {
- /// Return the default symboling mangling for the given format and architecture.
- pub fn default(format: BinaryFormat, architecture: Architecture) -> Self {
- match (format, architecture) {
- (BinaryFormat::Coff, Architecture::I386) => Mangling::CoffI386,
- (BinaryFormat::Coff, _) => Mangling::Coff,
- (BinaryFormat::Elf, _) => Mangling::Elf,
- (BinaryFormat::MachO, _) => Mangling::MachO,
- (BinaryFormat::Xcoff, _) => Mangling::Xcoff,
- _ => Mangling::None,
- }
- }
-
- /// Return the prefix to use for global symbols.
- pub fn global_prefix(self) -> Option<u8> {
- match self {
- Mangling::None | Mangling::Elf | Mangling::Coff | Mangling::Xcoff => None,
- Mangling::CoffI386 | Mangling::MachO => Some(b'_'),
- }
- }
-}
diff --git a/vendor/object/src/write/pe.rs b/vendor/object/src/write/pe.rs
deleted file mode 100644
index 70da3a0..0000000
--- a/vendor/object/src/write/pe.rs
+++ /dev/null
@@ -1,847 +0,0 @@
-//! Helper for writing PE files.
-use alloc::string::String;
-use alloc::vec::Vec;
-use core::mem;
-
-use crate::endian::{LittleEndian as LE, *};
-use crate::pe;
-use crate::write::util;
-use crate::write::{Error, Result, WritableBuffer};
-
-/// A helper for writing PE files.
-///
-/// Writing uses a two phase approach. The first phase reserves file ranges and virtual
-/// address ranges for everything in the order that they will be written.
-///
-/// The second phase writes everything out in order. Thus the caller must ensure writing
-/// is in the same order that file ranges were reserved.
-#[allow(missing_debug_implementations)]
-pub struct Writer<'a> {
- is_64: bool,
- section_alignment: u32,
- file_alignment: u32,
-
- buffer: &'a mut dyn WritableBuffer,
- len: u32,
- virtual_len: u32,
- headers_len: u32,
-
- code_address: u32,
- data_address: u32,
- code_len: u32,
- data_len: u32,
- bss_len: u32,
-
- nt_headers_offset: u32,
- data_directories: Vec<DataDirectory>,
- section_header_num: u16,
- sections: Vec<Section>,
-
- symbol_offset: u32,
- symbol_num: u32,
-
- reloc_blocks: Vec<RelocBlock>,
- relocs: Vec<U16<LE>>,
- reloc_offset: u32,
-}
-
-impl<'a> Writer<'a> {
- /// Create a new `Writer`.
- pub fn new(
- is_64: bool,
- section_alignment: u32,
- file_alignment: u32,
- buffer: &'a mut dyn WritableBuffer,
- ) -> Self {
- Writer {
- is_64,
- section_alignment,
- file_alignment,
-
- buffer,
- len: 0,
- virtual_len: 0,
- headers_len: 0,
-
- code_address: 0,
- data_address: 0,
- code_len: 0,
- data_len: 0,
- bss_len: 0,
-
- nt_headers_offset: 0,
- data_directories: Vec::new(),
- section_header_num: 0,
- sections: Vec::new(),
-
- symbol_offset: 0,
- symbol_num: 0,
-
- reloc_blocks: Vec::new(),
- relocs: Vec::new(),
- reloc_offset: 0,
- }
- }
-
- /// Return the current virtual address size that has been reserved.
- ///
- /// This is only valid after section headers have been reserved.
- pub fn virtual_len(&self) -> u32 {
- self.virtual_len
- }
-
- /// Reserve a virtual address range with the given size.
- ///
- /// The reserved length will be increased to match the section alignment.
- ///
- /// Returns the aligned offset of the start of the range.
- pub fn reserve_virtual(&mut self, len: u32) -> u32 {
- let offset = self.virtual_len;
- self.virtual_len += len;
- self.virtual_len = util::align_u32(self.virtual_len, self.section_alignment);
- offset
- }
-
- /// Reserve up to the given virtual address.
- ///
- /// The reserved length will be increased to match the section alignment.
- pub fn reserve_virtual_until(&mut self, address: u32) {
- debug_assert!(self.virtual_len <= address);
- self.virtual_len = util::align_u32(address, self.section_alignment);
- }
-
- /// Return the current file length that has been reserved.
- pub fn reserved_len(&self) -> u32 {
- self.len
- }
-
- /// Return the current file length that has been written.
- #[allow(clippy::len_without_is_empty)]
- pub fn len(&self) -> usize {
- self.buffer.len()
- }
-
- /// Reserve a file range with the given size and starting alignment.
- ///
- /// Returns the aligned offset of the start of the range.
- pub fn reserve(&mut self, len: u32, align_start: u32) -> u32 {
- if len == 0 {
- return self.len;
- }
- self.reserve_align(align_start);
- let offset = self.len;
- self.len += len;
- offset
- }
-
- /// Reserve a file range with the given size and using the file alignment.
- ///
- /// Returns the aligned offset of the start of the range.
- pub fn reserve_file(&mut self, len: u32) -> u32 {
- self.reserve(len, self.file_alignment)
- }
-
- /// Write data.
- pub fn write(&mut self, data: &[u8]) {
- self.buffer.write_bytes(data);
- }
-
- /// Reserve alignment padding bytes.
- pub fn reserve_align(&mut self, align_start: u32) {
- self.len = util::align_u32(self.len, align_start);
- }
-
- /// Write alignment padding bytes.
- pub fn write_align(&mut self, align_start: u32) {
- util::write_align(self.buffer, align_start as usize);
- }
-
- /// Write padding up to the next multiple of file alignment.
- pub fn write_file_align(&mut self) {
- self.write_align(self.file_alignment);
- }
-
- /// Reserve the file range up to the given file offset.
- pub fn reserve_until(&mut self, offset: u32) {
- debug_assert!(self.len <= offset);
- self.len = offset;
- }
-
- /// Write padding up to the given file offset.
- pub fn pad_until(&mut self, offset: u32) {
- debug_assert!(self.buffer.len() <= offset as usize);
- self.buffer.resize(offset as usize);
- }
-
- /// Reserve the range for the DOS header.
- ///
- /// This must be at the start of the file.
- ///
- /// When writing, you may use `write_custom_dos_header` or `write_empty_dos_header`.
- pub fn reserve_dos_header(&mut self) {
- debug_assert_eq!(self.len, 0);
- self.reserve(mem::size_of::<pe::ImageDosHeader>() as u32, 1);
- }
-
- /// Write a custom DOS header.
- ///
- /// This must be at the start of the file.
- pub fn write_custom_dos_header(&mut self, dos_header: &pe::ImageDosHeader) -> Result<()> {
- debug_assert_eq!(self.buffer.len(), 0);
-
- // Start writing.
- self.buffer
- .reserve(self.len as usize)
- .map_err(|_| Error(String::from("Cannot allocate buffer")))?;
-
- self.buffer.write(dos_header);
- Ok(())
- }
-
- /// Write the DOS header for a file without a stub.
- ///
- /// This must be at the start of the file.
- ///
- /// Uses default values for all fields.
- pub fn write_empty_dos_header(&mut self) -> Result<()> {
- self.write_custom_dos_header(&pe::ImageDosHeader {
- e_magic: U16::new(LE, pe::IMAGE_DOS_SIGNATURE),
- e_cblp: U16::new(LE, 0),
- e_cp: U16::new(LE, 0),
- e_crlc: U16::new(LE, 0),
- e_cparhdr: U16::new(LE, 0),
- e_minalloc: U16::new(LE, 0),
- e_maxalloc: U16::new(LE, 0),
- e_ss: U16::new(LE, 0),
- e_sp: U16::new(LE, 0),
- e_csum: U16::new(LE, 0),
- e_ip: U16::new(LE, 0),
- e_cs: U16::new(LE, 0),
- e_lfarlc: U16::new(LE, 0),
- e_ovno: U16::new(LE, 0),
- e_res: [U16::new(LE, 0); 4],
- e_oemid: U16::new(LE, 0),
- e_oeminfo: U16::new(LE, 0),
- e_res2: [U16::new(LE, 0); 10],
- e_lfanew: U32::new(LE, self.nt_headers_offset),
- })
- }
-
- /// Reserve a fixed DOS header and stub.
- ///
- /// Use `reserve_dos_header` and `reserve` if you need a custom stub.
- pub fn reserve_dos_header_and_stub(&mut self) {
- self.reserve_dos_header();
- self.reserve(64, 1);
- }
-
- /// Write a fixed DOS header and stub.
- ///
- /// Use `write_custom_dos_header` and `write` if you need a custom stub.
- pub fn write_dos_header_and_stub(&mut self) -> Result<()> {
- self.write_custom_dos_header(&pe::ImageDosHeader {
- e_magic: U16::new(LE, pe::IMAGE_DOS_SIGNATURE),
- e_cblp: U16::new(LE, 0x90),
- e_cp: U16::new(LE, 3),
- e_crlc: U16::new(LE, 0),
- e_cparhdr: U16::new(LE, 4),
- e_minalloc: U16::new(LE, 0),
- e_maxalloc: U16::new(LE, 0xffff),
- e_ss: U16::new(LE, 0),
- e_sp: U16::new(LE, 0xb8),
- e_csum: U16::new(LE, 0),
- e_ip: U16::new(LE, 0),
- e_cs: U16::new(LE, 0),
- e_lfarlc: U16::new(LE, 0x40),
- e_ovno: U16::new(LE, 0),
- e_res: [U16::new(LE, 0); 4],
- e_oemid: U16::new(LE, 0),
- e_oeminfo: U16::new(LE, 0),
- e_res2: [U16::new(LE, 0); 10],
- e_lfanew: U32::new(LE, self.nt_headers_offset),
- })?;
-
- #[rustfmt::skip]
- self.buffer.write_bytes(&[
- 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd,
- 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68,
- 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72,
- 0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f,
- 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e,
- 0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20,
- 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a,
- 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]);
-
- Ok(())
- }
-
- fn nt_headers_size(&self) -> u32 {
- if self.is_64 {
- mem::size_of::<pe::ImageNtHeaders64>() as u32
- } else {
- mem::size_of::<pe::ImageNtHeaders32>() as u32
- }
- }
-
- fn optional_header_size(&self) -> u32 {
- let size = if self.is_64 {
- mem::size_of::<pe::ImageOptionalHeader64>() as u32
- } else {
- mem::size_of::<pe::ImageOptionalHeader32>() as u32
- };
- size + self.data_directories.len() as u32 * mem::size_of::<pe::ImageDataDirectory>() as u32
- }
-
- /// Return the offset of the NT headers, if reserved.
- pub fn nt_headers_offset(&self) -> u32 {
- self.nt_headers_offset
- }
-
- /// Reserve the range for the NT headers.
- pub fn reserve_nt_headers(&mut self, data_directory_num: usize) {
- debug_assert_eq!(self.nt_headers_offset, 0);
- self.nt_headers_offset = self.reserve(self.nt_headers_size(), 8);
- self.data_directories = vec![DataDirectory::default(); data_directory_num];
- self.reserve(
- data_directory_num as u32 * mem::size_of::<pe::ImageDataDirectory>() as u32,
- 1,
- );
- }
-
- /// Set the virtual address and size of a data directory.
- pub fn set_data_directory(&mut self, index: usize, virtual_address: u32, size: u32) {
- self.data_directories[index] = DataDirectory {
- virtual_address,
- size,
- }
- }
-
- /// Write the NT headers.
- pub fn write_nt_headers(&mut self, nt_headers: NtHeaders) {
- self.pad_until(self.nt_headers_offset);
- self.buffer.write(&U32::new(LE, pe::IMAGE_NT_SIGNATURE));
- let file_header = pe::ImageFileHeader {
- machine: U16::new(LE, nt_headers.machine),
- number_of_sections: U16::new(LE, self.section_header_num),
- time_date_stamp: U32::new(LE, nt_headers.time_date_stamp),
- pointer_to_symbol_table: U32::new(LE, self.symbol_offset),
- number_of_symbols: U32::new(LE, self.symbol_num),
- size_of_optional_header: U16::new(LE, self.optional_header_size() as u16),
- characteristics: U16::new(LE, nt_headers.characteristics),
- };
- self.buffer.write(&file_header);
- if self.is_64 {
- let optional_header = pe::ImageOptionalHeader64 {
- magic: U16::new(LE, pe::IMAGE_NT_OPTIONAL_HDR64_MAGIC),
- major_linker_version: nt_headers.major_linker_version,
- minor_linker_version: nt_headers.minor_linker_version,
- size_of_code: U32::new(LE, self.code_len),
- size_of_initialized_data: U32::new(LE, self.data_len),
- size_of_uninitialized_data: U32::new(LE, self.bss_len),
- address_of_entry_point: U32::new(LE, nt_headers.address_of_entry_point),
- base_of_code: U32::new(LE, self.code_address),
- image_base: U64::new(LE, nt_headers.image_base),
- section_alignment: U32::new(LE, self.section_alignment),
- file_alignment: U32::new(LE, self.file_alignment),
- major_operating_system_version: U16::new(
- LE,
- nt_headers.major_operating_system_version,
- ),
- minor_operating_system_version: U16::new(
- LE,
- nt_headers.minor_operating_system_version,
- ),
- major_image_version: U16::new(LE, nt_headers.major_image_version),
- minor_image_version: U16::new(LE, nt_headers.minor_image_version),
- major_subsystem_version: U16::new(LE, nt_headers.major_subsystem_version),
- minor_subsystem_version: U16::new(LE, nt_headers.minor_subsystem_version),
- win32_version_value: U32::new(LE, 0),
- size_of_image: U32::new(LE, self.virtual_len),
- size_of_headers: U32::new(LE, self.headers_len),
- check_sum: U32::new(LE, 0),
- subsystem: U16::new(LE, nt_headers.subsystem),
- dll_characteristics: U16::new(LE, nt_headers.dll_characteristics),
- size_of_stack_reserve: U64::new(LE, nt_headers.size_of_stack_reserve),
- size_of_stack_commit: U64::new(LE, nt_headers.size_of_stack_commit),
- size_of_heap_reserve: U64::new(LE, nt_headers.size_of_heap_reserve),
- size_of_heap_commit: U64::new(LE, nt_headers.size_of_heap_commit),
- loader_flags: U32::new(LE, 0),
- number_of_rva_and_sizes: U32::new(LE, self.data_directories.len() as u32),
- };
- self.buffer.write(&optional_header);
- } else {
- let optional_header = pe::ImageOptionalHeader32 {
- magic: U16::new(LE, pe::IMAGE_NT_OPTIONAL_HDR32_MAGIC),
- major_linker_version: nt_headers.major_linker_version,
- minor_linker_version: nt_headers.minor_linker_version,
- size_of_code: U32::new(LE, self.code_len),
- size_of_initialized_data: U32::new(LE, self.data_len),
- size_of_uninitialized_data: U32::new(LE, self.bss_len),
- address_of_entry_point: U32::new(LE, nt_headers.address_of_entry_point),
- base_of_code: U32::new(LE, self.code_address),
- base_of_data: U32::new(LE, self.data_address),
- image_base: U32::new(LE, nt_headers.image_base as u32),
- section_alignment: U32::new(LE, self.section_alignment),
- file_alignment: U32::new(LE, self.file_alignment),
- major_operating_system_version: U16::new(
- LE,
- nt_headers.major_operating_system_version,
- ),
- minor_operating_system_version: U16::new(
- LE,
- nt_headers.minor_operating_system_version,
- ),
- major_image_version: U16::new(LE, nt_headers.major_image_version),
- minor_image_version: U16::new(LE, nt_headers.minor_image_version),
- major_subsystem_version: U16::new(LE, nt_headers.major_subsystem_version),
- minor_subsystem_version: U16::new(LE, nt_headers.minor_subsystem_version),
- win32_version_value: U32::new(LE, 0),
- size_of_image: U32::new(LE, self.virtual_len),
- size_of_headers: U32::new(LE, self.headers_len),
- check_sum: U32::new(LE, 0),
- subsystem: U16::new(LE, nt_headers.subsystem),
- dll_characteristics: U16::new(LE, nt_headers.dll_characteristics),
- size_of_stack_reserve: U32::new(LE, nt_headers.size_of_stack_reserve as u32),
- size_of_stack_commit: U32::new(LE, nt_headers.size_of_stack_commit as u32),
- size_of_heap_reserve: U32::new(LE, nt_headers.size_of_heap_reserve as u32),
- size_of_heap_commit: U32::new(LE, nt_headers.size_of_heap_commit as u32),
- loader_flags: U32::new(LE, 0),
- number_of_rva_and_sizes: U32::new(LE, self.data_directories.len() as u32),
- };
- self.buffer.write(&optional_header);
- }
-
- for dir in &self.data_directories {
- self.buffer.write(&pe::ImageDataDirectory {
- virtual_address: U32::new(LE, dir.virtual_address),
- size: U32::new(LE, dir.size),
- })
- }
- }
-
- /// Reserve the section headers.
- ///
- /// The number of reserved section headers must be the same as the number of sections that
- /// are later reserved.
- // TODO: change this to a maximum number of sections?
- pub fn reserve_section_headers(&mut self, section_header_num: u16) {
- debug_assert_eq!(self.section_header_num, 0);
- self.section_header_num = section_header_num;
- self.reserve(
- u32::from(section_header_num) * mem::size_of::<pe::ImageSectionHeader>() as u32,
- 1,
- );
- // Padding before sections must be included in headers_len.
- self.reserve_align(self.file_alignment);
- self.headers_len = self.len;
- self.reserve_virtual(self.len);
- }
-
- /// Write the section headers.
- ///
- /// This uses information that was recorded when the sections were reserved.
- pub fn write_section_headers(&mut self) {
- debug_assert_eq!(self.section_header_num as usize, self.sections.len());
- for section in &self.sections {
- let section_header = pe::ImageSectionHeader {
- name: section.name,
- virtual_size: U32::new(LE, section.range.virtual_size),
- virtual_address: U32::new(LE, section.range.virtual_address),
- size_of_raw_data: U32::new(LE, section.range.file_size),
- pointer_to_raw_data: U32::new(LE, section.range.file_offset),
- pointer_to_relocations: U32::new(LE, 0),
- pointer_to_linenumbers: U32::new(LE, 0),
- number_of_relocations: U16::new(LE, 0),
- number_of_linenumbers: U16::new(LE, 0),
- characteristics: U32::new(LE, section.characteristics),
- };
- self.buffer.write(&section_header);
- }
- }
-
- /// Reserve a section.
- ///
- /// Returns the file range and virtual address range that are reserved
- /// for the section.
- pub fn reserve_section(
- &mut self,
- name: [u8; 8],
- characteristics: u32,
- virtual_size: u32,
- data_size: u32,
- ) -> SectionRange {
- let virtual_address = self.reserve_virtual(virtual_size);
-
- // Padding after section must be included in section file size.
- let file_size = util::align_u32(data_size, self.file_alignment);
- let file_offset = if file_size != 0 {
- self.reserve(file_size, self.file_alignment)
- } else {
- 0
- };
-
- // Sizes in optional header use the virtual size with the file alignment.
- let aligned_virtual_size = util::align_u32(virtual_size, self.file_alignment);
- if characteristics & pe::IMAGE_SCN_CNT_CODE != 0 {
- if self.code_address == 0 {
- self.code_address = virtual_address;
- }
- self.code_len += aligned_virtual_size;
- } else if characteristics & pe::IMAGE_SCN_CNT_INITIALIZED_DATA != 0 {
- if self.data_address == 0 {
- self.data_address = virtual_address;
- }
- self.data_len += aligned_virtual_size;
- } else if characteristics & pe::IMAGE_SCN_CNT_UNINITIALIZED_DATA != 0 {
- if self.data_address == 0 {
- self.data_address = virtual_address;
- }
- self.bss_len += aligned_virtual_size;
- }
-
- let range = SectionRange {
- virtual_address,
- virtual_size,
- file_offset,
- file_size,
- };
- self.sections.push(Section {
- name,
- characteristics,
- range,
- });
- range
- }
-
- /// Write the data for a section.
- pub fn write_section(&mut self, offset: u32, data: &[u8]) {
- if data.is_empty() {
- return;
- }
- self.pad_until(offset);
- self.write(data);
- self.write_align(self.file_alignment);
- }
-
- /// Reserve a `.text` section.
- ///
- /// Contains executable code.
- pub fn reserve_text_section(&mut self, size: u32) -> SectionRange {
- self.reserve_section(
- *b".text\0\0\0",
- pe::IMAGE_SCN_CNT_CODE | pe::IMAGE_SCN_MEM_EXECUTE | pe::IMAGE_SCN_MEM_READ,
- size,
- size,
- )
- }
-
- /// Reserve a `.data` section.
- ///
- /// Contains initialized data.
- ///
- /// May also contain uninitialized data if `virtual_size` is greater than `data_size`.
- pub fn reserve_data_section(&mut self, virtual_size: u32, data_size: u32) -> SectionRange {
- self.reserve_section(
- *b".data\0\0\0",
- pe::IMAGE_SCN_CNT_INITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ | pe::IMAGE_SCN_MEM_WRITE,
- virtual_size,
- data_size,
- )
- }
-
- /// Reserve a `.rdata` section.
- ///
- /// Contains read-only initialized data.
- pub fn reserve_rdata_section(&mut self, size: u32) -> SectionRange {
- self.reserve_section(
- *b".rdata\0\0",
- pe::IMAGE_SCN_CNT_INITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ,
- size,
- size,
- )
- }
-
- /// Reserve a `.bss` section.
- ///
- /// Contains uninitialized data.
- pub fn reserve_bss_section(&mut self, size: u32) -> SectionRange {
- self.reserve_section(
- *b".bss\0\0\0\0",
- pe::IMAGE_SCN_CNT_UNINITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ | pe::IMAGE_SCN_MEM_WRITE,
- size,
- 0,
- )
- }
-
- /// Reserve an `.idata` section.
- ///
- /// Contains import tables. Note that it is permissible to store import tables in a different
- /// section.
- ///
- /// This also sets the `pe::IMAGE_DIRECTORY_ENTRY_IMPORT` data directory.
- pub fn reserve_idata_section(&mut self, size: u32) -> SectionRange {
- let range = self.reserve_section(
- *b".idata\0\0",
- pe::IMAGE_SCN_CNT_INITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ | pe::IMAGE_SCN_MEM_WRITE,
- size,
- size,
- );
- let dir = &mut self.data_directories[pe::IMAGE_DIRECTORY_ENTRY_IMPORT];
- debug_assert_eq!(dir.virtual_address, 0);
- *dir = DataDirectory {
- virtual_address: range.virtual_address,
- size,
- };
- range
- }
-
- /// Reserve an `.edata` section.
- ///
- /// Contains export tables.
- ///
- /// This also sets the `pe::IMAGE_DIRECTORY_ENTRY_EXPORT` data directory.
- pub fn reserve_edata_section(&mut self, size: u32) -> SectionRange {
- let range = self.reserve_section(
- *b".edata\0\0",
- pe::IMAGE_SCN_CNT_INITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ,
- size,
- size,
- );
- let dir = &mut self.data_directories[pe::IMAGE_DIRECTORY_ENTRY_EXPORT];
- debug_assert_eq!(dir.virtual_address, 0);
- *dir = DataDirectory {
- virtual_address: range.virtual_address,
- size,
- };
- range
- }
-
- /// Reserve a `.pdata` section.
- ///
- /// Contains exception information.
- ///
- /// This also sets the `pe::IMAGE_DIRECTORY_ENTRY_EXCEPTION` data directory.
- pub fn reserve_pdata_section(&mut self, size: u32) -> SectionRange {
- let range = self.reserve_section(
- *b".pdata\0\0",
- pe::IMAGE_SCN_CNT_INITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ,
- size,
- size,
- );
- let dir = &mut self.data_directories[pe::IMAGE_DIRECTORY_ENTRY_EXCEPTION];
- debug_assert_eq!(dir.virtual_address, 0);
- *dir = DataDirectory {
- virtual_address: range.virtual_address,
- size,
- };
- range
- }
-
- /// Reserve a `.xdata` section.
- ///
- /// Contains exception information.
- pub fn reserve_xdata_section(&mut self, size: u32) -> SectionRange {
- self.reserve_section(
- *b".xdata\0\0",
- pe::IMAGE_SCN_CNT_INITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ,
- size,
- size,
- )
- }
-
- /// Reserve a `.rsrc` section.
- ///
- /// Contains the resource directory.
- ///
- /// This also sets the `pe::IMAGE_DIRECTORY_ENTRY_RESOURCE` data directory.
- pub fn reserve_rsrc_section(&mut self, size: u32) -> SectionRange {
- let range = self.reserve_section(
- *b".rsrc\0\0\0",
- pe::IMAGE_SCN_CNT_INITIALIZED_DATA | pe::IMAGE_SCN_MEM_READ,
- size,
- size,
- );
- let dir = &mut self.data_directories[pe::IMAGE_DIRECTORY_ENTRY_RESOURCE];
- debug_assert_eq!(dir.virtual_address, 0);
- *dir = DataDirectory {
- virtual_address: range.virtual_address,
- size,
- };
- range
- }
-
- /// Add a base relocation.
- ///
- /// `typ` must be one of the `IMAGE_REL_BASED_*` constants.
- pub fn add_reloc(&mut self, mut virtual_address: u32, typ: u16) {
- let reloc = U16::new(LE, typ << 12 | (virtual_address & 0xfff) as u16);
- virtual_address &= !0xfff;
- if let Some(block) = self.reloc_blocks.last_mut() {
- if block.virtual_address == virtual_address {
- self.relocs.push(reloc);
- block.count += 1;
- return;
- }
- // Blocks must have an even number of relocations.
- if block.count & 1 != 0 {
- self.relocs.push(U16::new(LE, 0));
- block.count += 1;
- }
- debug_assert!(block.virtual_address < virtual_address);
- }
- self.relocs.push(reloc);
- self.reloc_blocks.push(RelocBlock {
- virtual_address,
- count: 1,
- });
- }
-
- /// Return true if a base relocation has been added.
- pub fn has_relocs(&mut self) -> bool {
- !self.relocs.is_empty()
- }
-
- /// Reserve a `.reloc` section.
- ///
- /// This contains the base relocations that were added with `add_reloc`.
- ///
- /// This also sets the `pe::IMAGE_DIRECTORY_ENTRY_BASERELOC` data directory.
- pub fn reserve_reloc_section(&mut self) -> SectionRange {
- if let Some(block) = self.reloc_blocks.last_mut() {
- // Blocks must have an even number of relocations.
- if block.count & 1 != 0 {
- self.relocs.push(U16::new(LE, 0));
- block.count += 1;
- }
- }
- let size = self.reloc_blocks.iter().map(RelocBlock::size).sum();
- let range = self.reserve_section(
- *b".reloc\0\0",
- pe::IMAGE_SCN_CNT_INITIALIZED_DATA
- | pe::IMAGE_SCN_MEM_READ
- | pe::IMAGE_SCN_MEM_DISCARDABLE,
- size,
- size,
- );
- let dir = &mut self.data_directories[pe::IMAGE_DIRECTORY_ENTRY_BASERELOC];
- debug_assert_eq!(dir.virtual_address, 0);
- *dir = DataDirectory {
- virtual_address: range.virtual_address,
- size,
- };
- self.reloc_offset = range.file_offset;
- range
- }
-
- /// Write a `.reloc` section.
- ///
- /// This contains the base relocations that were added with `add_reloc`.
- pub fn write_reloc_section(&mut self) {
- if self.reloc_offset == 0 {
- return;
- }
- self.pad_until(self.reloc_offset);
-
- let mut total = 0;
- for block in &self.reloc_blocks {
- self.buffer.write(&pe::ImageBaseRelocation {
- virtual_address: U32::new(LE, block.virtual_address),
- size_of_block: U32::new(LE, block.size()),
- });
- self.buffer
- .write_slice(&self.relocs[total..][..block.count as usize]);
- total += block.count as usize;
- }
- debug_assert_eq!(total, self.relocs.len());
-
- self.write_align(self.file_alignment);
- }
-
- /// Reserve the certificate table.
- ///
- /// This also sets the `pe::IMAGE_DIRECTORY_ENTRY_SECURITY` data directory.
- // TODO: reserve individual certificates
- pub fn reserve_certificate_table(&mut self, size: u32) {
- let size = util::align_u32(size, 8);
- let offset = self.reserve(size, 8);
- let dir = &mut self.data_directories[pe::IMAGE_DIRECTORY_ENTRY_SECURITY];
- debug_assert_eq!(dir.virtual_address, 0);
- *dir = DataDirectory {
- virtual_address: offset,
- size,
- };
- }
-
- /// Write the certificate table.
- // TODO: write individual certificates
- pub fn write_certificate_table(&mut self, data: &[u8]) {
- let dir = self.data_directories[pe::IMAGE_DIRECTORY_ENTRY_SECURITY];
- self.pad_until(dir.virtual_address);
- self.write(data);
- self.pad_until(dir.virtual_address + dir.size);
- }
-}
-
-/// Information required for writing [`pe::ImageNtHeaders32`] or [`pe::ImageNtHeaders64`].
-#[allow(missing_docs)]
-#[derive(Debug, Clone)]
-pub struct NtHeaders {
- // ImageFileHeader
- pub machine: u16,
- pub time_date_stamp: u32,
- pub characteristics: u16,
- // ImageOptionalHeader
- pub major_linker_version: u8,
- pub minor_linker_version: u8,
- pub address_of_entry_point: u32,
- pub image_base: u64,
- pub major_operating_system_version: u16,
- pub minor_operating_system_version: u16,
- pub major_image_version: u16,
- pub minor_image_version: u16,
- pub major_subsystem_version: u16,
- pub minor_subsystem_version: u16,
- pub subsystem: u16,
- pub dll_characteristics: u16,
- pub size_of_stack_reserve: u64,
- pub size_of_stack_commit: u64,
- pub size_of_heap_reserve: u64,
- pub size_of_heap_commit: u64,
-}
-
-#[derive(Default, Clone, Copy)]
-struct DataDirectory {
- virtual_address: u32,
- size: u32,
-}
-
-/// Information required for writing [`pe::ImageSectionHeader`].
-#[allow(missing_docs)]
-#[derive(Debug, Clone)]
-pub struct Section {
- pub name: [u8; pe::IMAGE_SIZEOF_SHORT_NAME],
- pub characteristics: u32,
- pub range: SectionRange,
-}
-
-/// The file range and virtual address range for a section.
-#[allow(missing_docs)]
-#[derive(Debug, Default, Clone, Copy)]
-pub struct SectionRange {
- pub virtual_address: u32,
- pub virtual_size: u32,
- pub file_offset: u32,
- pub file_size: u32,
-}
-
-struct RelocBlock {
- virtual_address: u32,
- count: u32,
-}
-
-impl RelocBlock {
- fn size(&self) -> u32 {
- mem::size_of::<pe::ImageBaseRelocation>() as u32 + self.count * mem::size_of::<u16>() as u32
- }
-}
diff --git a/vendor/object/src/write/string.rs b/vendor/object/src/write/string.rs
deleted file mode 100644
index b23274a..0000000
--- a/vendor/object/src/write/string.rs
+++ /dev/null
@@ -1,159 +0,0 @@
-use alloc::vec::Vec;
-
-#[cfg(feature = "std")]
-type IndexSet<K> = indexmap::IndexSet<K>;
-#[cfg(not(feature = "std"))]
-type IndexSet<K> = indexmap::IndexSet<K, hashbrown::hash_map::DefaultHashBuilder>;
-
-/// An identifier for an entry in a string table.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub struct StringId(usize);
-
-#[derive(Debug, Default)]
-pub(crate) struct StringTable<'a> {
- strings: IndexSet<&'a [u8]>,
- offsets: Vec<usize>,
-}
-
-impl<'a> StringTable<'a> {
- /// Add a string to the string table.
- ///
- /// Panics if the string table has already been written, or
- /// if the string contains a null byte.
- pub fn add(&mut self, string: &'a [u8]) -> StringId {
- assert!(self.offsets.is_empty());
- assert!(!string.contains(&0));
- let id = self.strings.insert_full(string).0;
- StringId(id)
- }
-
- /// Return the id of the given string.
- ///
- /// Panics if the string is not in the string table.
- pub fn get_id(&self, string: &[u8]) -> StringId {
- let id = self.strings.get_index_of(string).unwrap();
- StringId(id)
- }
-
- /// Return the string for the given id.
- ///
- /// Panics if the string is not in the string table.
- pub fn get_string(&self, id: StringId) -> &'a [u8] {
- self.strings.get_index(id.0).unwrap()
- }
-
- /// Return the offset of the given string.
- ///
- /// Panics if the string table has not been written, or
- /// if the string is not in the string table.
- pub fn get_offset(&self, id: StringId) -> usize {
- self.offsets[id.0]
- }
-
- /// Append the string table to the given `Vec`, and
- /// calculate the list of string offsets.
- ///
- /// `base` is the initial string table offset. For example,
- /// this should be 1 for ELF, to account for the initial
- /// null byte (which must have been written by the caller).
- pub fn write(&mut self, base: usize, w: &mut Vec<u8>) {
- assert!(self.offsets.is_empty());
-
- let mut ids: Vec<_> = (0..self.strings.len()).collect();
- sort(&mut ids, 1, &self.strings);
-
- self.offsets = vec![0; ids.len()];
- let mut offset = base;
- let mut previous = &[][..];
- for id in ids {
- let string = self.strings.get_index(id).unwrap();
- if previous.ends_with(string) {
- self.offsets[id] = offset - string.len() - 1;
- } else {
- self.offsets[id] = offset;
- w.extend_from_slice(string);
- w.push(0);
- offset += string.len() + 1;
- previous = string;
- }
- }
- }
-}
-
-// Multi-key quicksort.
-//
-// Ordering is such that if a string is a suffix of at least one other string,
-// then it is placed immediately after one of those strings. That is:
-// - comparison starts at the end of the string
-// - shorter strings come later
-//
-// Based on the implementation in LLVM.
-fn sort(mut ids: &mut [usize], mut pos: usize, strings: &IndexSet<&[u8]>) {
- loop {
- if ids.len() <= 1 {
- return;
- }
-
- let pivot = byte(ids[0], pos, strings);
- let mut lower = 0;
- let mut upper = ids.len();
- let mut i = 1;
- while i < upper {
- let b = byte(ids[i], pos, strings);
- if b > pivot {
- ids.swap(lower, i);
- lower += 1;
- i += 1;
- } else if b < pivot {
- upper -= 1;
- ids.swap(upper, i);
- } else {
- i += 1;
- }
- }
-
- sort(&mut ids[..lower], pos, strings);
- sort(&mut ids[upper..], pos, strings);
-
- if pivot == 0 {
- return;
- }
- ids = &mut ids[lower..upper];
- pos += 1;
- }
-}
-
-fn byte(id: usize, pos: usize, strings: &IndexSet<&[u8]>) -> u8 {
- let string = strings.get_index(id).unwrap();
- let len = string.len();
- if len >= pos {
- string[len - pos]
- } else {
- // We know the strings don't contain null bytes.
- 0
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn string_table() {
- let mut table = StringTable::default();
- let id0 = table.add(b"");
- let id1 = table.add(b"foo");
- let id2 = table.add(b"bar");
- let id3 = table.add(b"foobar");
-
- let mut data = Vec::new();
- data.push(0);
- table.write(1, &mut data);
- assert_eq!(data, b"\0foobar\0foo\0");
-
- assert_eq!(table.get_offset(id0), 11);
- assert_eq!(table.get_offset(id1), 8);
- assert_eq!(table.get_offset(id2), 4);
- assert_eq!(table.get_offset(id3), 1);
- }
-}
diff --git a/vendor/object/src/write/util.rs b/vendor/object/src/write/util.rs
deleted file mode 100644
index f7ee2f4..0000000
--- a/vendor/object/src/write/util.rs
+++ /dev/null
@@ -1,260 +0,0 @@
-use alloc::vec::Vec;
-#[cfg(feature = "std")]
-use std::{io, mem};
-
-use crate::pod::{bytes_of, bytes_of_slice, Pod};
-
-/// Trait for writable buffer.
-#[allow(clippy::len_without_is_empty)]
-pub trait WritableBuffer {
- /// Returns position/offset for data to be written at.
- ///
- /// Should only be used in debug assertions
- fn len(&self) -> usize;
-
- /// Reserves specified number of bytes in the buffer.
- ///
- /// This will be called exactly once before writing anything to the buffer,
- /// and the given size is the exact total number of bytes that will be written.
- fn reserve(&mut self, size: usize) -> Result<(), ()>;
-
- /// Writes zero bytes at the end of the buffer until the buffer
- /// has the specified length.
- fn resize(&mut self, new_len: usize);
-
- /// Writes the specified slice of bytes at the end of the buffer.
- fn write_bytes(&mut self, val: &[u8]);
-
- /// Writes the specified `Pod` type at the end of the buffer.
- fn write_pod<T: Pod>(&mut self, val: &T)
- where
- Self: Sized,
- {
- self.write_bytes(bytes_of(val))
- }
-
- /// Writes the specified `Pod` slice at the end of the buffer.
- fn write_pod_slice<T: Pod>(&mut self, val: &[T])
- where
- Self: Sized,
- {
- self.write_bytes(bytes_of_slice(val))
- }
-}
-
-impl<'a> dyn WritableBuffer + 'a {
- /// Writes the specified `Pod` type at the end of the buffer.
- pub fn write<T: Pod>(&mut self, val: &T) {
- self.write_bytes(bytes_of(val))
- }
-
- /// Writes the specified `Pod` slice at the end of the buffer.
- pub fn write_slice<T: Pod>(&mut self, val: &[T]) {
- self.write_bytes(bytes_of_slice(val))
- }
-}
-
-impl WritableBuffer for Vec<u8> {
- #[inline]
- fn len(&self) -> usize {
- self.len()
- }
-
- #[inline]
- fn reserve(&mut self, size: usize) -> Result<(), ()> {
- debug_assert!(self.is_empty());
- self.reserve(size);
- Ok(())
- }
-
- #[inline]
- fn resize(&mut self, new_len: usize) {
- debug_assert!(new_len >= self.len());
- self.resize(new_len, 0);
- }
-
- #[inline]
- fn write_bytes(&mut self, val: &[u8]) {
- debug_assert!(self.len() + val.len() <= self.capacity());
- self.extend_from_slice(val)
- }
-}
-
-/// A [`WritableBuffer`] that streams data to a [`Write`](std::io::Write) implementation.
-///
-/// [`Self::result`] must be called to determine if an I/O error occurred during writing.
-///
-/// It is advisable to use a buffered writer like [`BufWriter`](std::io::BufWriter)
-/// instead of an unbuffered writer like [`File`](std::fs::File).
-#[cfg(feature = "std")]
-#[derive(Debug)]
-pub struct StreamingBuffer<W> {
- writer: W,
- len: usize,
- result: Result<(), io::Error>,
-}
-
-#[cfg(feature = "std")]
-impl<W> StreamingBuffer<W> {
- /// Create a new `StreamingBuffer` backed by the given writer.
- pub fn new(writer: W) -> Self {
- StreamingBuffer {
- writer,
- len: 0,
- result: Ok(()),
- }
- }
-
- /// Unwraps this [`StreamingBuffer`] giving back the original writer.
- pub fn into_inner(self) -> W {
- self.writer
- }
-
- /// Returns any error that occurred during writing.
- pub fn result(&mut self) -> Result<(), io::Error> {
- mem::replace(&mut self.result, Ok(()))
- }
-}
-
-#[cfg(feature = "std")]
-impl<W: io::Write> WritableBuffer for StreamingBuffer<W> {
- #[inline]
- fn len(&self) -> usize {
- self.len
- }
-
- #[inline]
- fn reserve(&mut self, _size: usize) -> Result<(), ()> {
- Ok(())
- }
-
- #[inline]
- fn resize(&mut self, new_len: usize) {
- debug_assert!(self.len <= new_len);
- while self.len < new_len {
- let write_amt = (new_len - self.len - 1) % 1024 + 1;
- self.write_bytes(&[0; 1024][..write_amt]);
- }
- }
-
- #[inline]
- fn write_bytes(&mut self, val: &[u8]) {
- if self.result.is_ok() {
- self.result = self.writer.write_all(val);
- }
- self.len += val.len();
- }
-}
-
-/// A trait for mutable byte slices.
-///
-/// It provides convenience methods for `Pod` types.
-pub(crate) trait BytesMut {
- fn write_at<T: Pod>(self, offset: usize, val: &T) -> Result<(), ()>;
-}
-
-impl<'a> BytesMut for &'a mut [u8] {
- #[inline]
- fn write_at<T: Pod>(self, offset: usize, val: &T) -> Result<(), ()> {
- let src = bytes_of(val);
- let dest = self.get_mut(offset..).ok_or(())?;
- let dest = dest.get_mut(..src.len()).ok_or(())?;
- dest.copy_from_slice(src);
- Ok(())
- }
-}
-
-/// Write an unsigned number using the LEB128 encoding to a buffer.
-///
-/// Returns the number of bytes written.
-pub(crate) fn write_uleb128(buf: &mut Vec<u8>, mut val: u64) -> usize {
- let mut len = 0;
- loop {
- let mut byte = (val & 0x7f) as u8;
- val >>= 7;
- let done = val == 0;
- if !done {
- byte |= 0x80;
- }
-
- buf.push(byte);
- len += 1;
-
- if done {
- return len;
- }
- }
-}
-
-/// Write a signed number using the LEB128 encoding to a buffer.
-///
-/// Returns the number of bytes written.
-#[allow(dead_code)]
-pub(crate) fn write_sleb128(buf: &mut Vec<u8>, mut val: i64) -> usize {
- let mut len = 0;
- loop {
- let mut byte = val as u8;
- // Keep the sign bit for testing
- val >>= 6;
- let done = val == 0 || val == -1;
- if done {
- byte &= !0x80;
- } else {
- // Remove the sign bit
- val >>= 1;
- byte |= 0x80;
- }
-
- buf.push(byte);
- len += 1;
-
- if done {
- return len;
- }
- }
-}
-
-pub(crate) fn align(offset: usize, size: usize) -> usize {
- (offset + (size - 1)) & !(size - 1)
-}
-
-#[allow(dead_code)]
-pub(crate) fn align_u32(offset: u32, size: u32) -> u32 {
- (offset + (size - 1)) & !(size - 1)
-}
-
-#[allow(dead_code)]
-pub(crate) fn align_u64(offset: u64, size: u64) -> u64 {
- (offset + (size - 1)) & !(size - 1)
-}
-
-pub(crate) fn write_align(buffer: &mut dyn WritableBuffer, size: usize) {
- let new_len = align(buffer.len(), size);
- buffer.resize(new_len);
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn bytes_mut() {
- let data = vec![0x01, 0x23, 0x45, 0x67];
-
- let mut bytes = data.clone();
- bytes.extend_from_slice(bytes_of(&u16::to_be(0x89ab)));
- assert_eq!(bytes, [0x01, 0x23, 0x45, 0x67, 0x89, 0xab]);
-
- let mut bytes = data.clone();
- assert_eq!(bytes.write_at(0, &u16::to_be(0x89ab)), Ok(()));
- assert_eq!(bytes, [0x89, 0xab, 0x45, 0x67]);
-
- let mut bytes = data.clone();
- assert_eq!(bytes.write_at(2, &u16::to_be(0x89ab)), Ok(()));
- assert_eq!(bytes, [0x01, 0x23, 0x89, 0xab]);
-
- assert_eq!(bytes.write_at(3, &u16::to_be(0x89ab)), Err(()));
- assert_eq!(bytes.write_at(4, &u16::to_be(0x89ab)), Err(()));
- assert_eq!(vec![].write_at(0, &u32::to_be(0x89ab)), Err(()));
- }
-}
diff --git a/vendor/object/src/write/xcoff.rs b/vendor/object/src/write/xcoff.rs
deleted file mode 100644
index fc58886..0000000
--- a/vendor/object/src/write/xcoff.rs
+++ /dev/null
@@ -1,556 +0,0 @@
-use core::mem;
-
-use crate::endian::{BigEndian as BE, I16, U16, U32};
-use crate::write::string::*;
-use crate::write::util::*;
-use crate::write::*;
-
-use crate::{xcoff, AddressSize};
-
-#[derive(Default, Clone, Copy)]
-struct SectionOffsets {
- address: u64,
- data_offset: usize,
- reloc_offset: usize,
-}
-
-#[derive(Default, Clone, Copy)]
-struct SymbolOffsets {
- index: usize,
- str_id: Option<StringId>,
- aux_count: u8,
- storage_class: u8,
-}
-
-impl<'a> Object<'a> {
- pub(crate) fn xcoff_section_info(
- &self,
- section: StandardSection,
- ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) {
- match section {
- StandardSection::Text => (&[], &b".text"[..], SectionKind::Text, SectionFlags::None),
- StandardSection::Data => (&[], &b".data"[..], SectionKind::Data, SectionFlags::None),
- StandardSection::ReadOnlyData
- | StandardSection::ReadOnlyDataWithRel
- | StandardSection::ReadOnlyString => (
- &[],
- &b".rdata"[..],
- SectionKind::ReadOnlyData,
- SectionFlags::None,
- ),
- StandardSection::UninitializedData => (
- &[],
- &b".bss"[..],
- SectionKind::UninitializedData,
- SectionFlags::None,
- ),
- StandardSection::Tls => (&[], &b".tdata"[..], SectionKind::Tls, SectionFlags::None),
- StandardSection::UninitializedTls => (
- &[],
- &b".tbss"[..],
- SectionKind::UninitializedTls,
- SectionFlags::None,
- ),
- StandardSection::TlsVariables => {
- // Unsupported section.
- (&[], &[], SectionKind::TlsVariables, SectionFlags::None)
- }
- StandardSection::Common => {
- // Unsupported section.
- (&[], &[], SectionKind::Common, SectionFlags::None)
- }
- StandardSection::GnuProperty => {
- // Unsupported section.
- (&[], &[], SectionKind::Note, SectionFlags::None)
- }
- }
- }
-
- pub(crate) fn xcoff_fixup_relocation(&mut self, relocation: &mut Relocation) -> i64 {
- let constant = match relocation.kind {
- RelocationKind::Relative => relocation.addend + 4,
- _ => relocation.addend,
- };
- relocation.addend -= constant;
- constant
- }
-
- pub(crate) fn xcoff_write(&self, buffer: &mut dyn WritableBuffer) -> Result<()> {
- let is_64 = match self.architecture.address_size().unwrap() {
- AddressSize::U8 | AddressSize::U16 | AddressSize::U32 => false,
- AddressSize::U64 => true,
- };
-
- let (hdr_size, sechdr_size, rel_size, sym_size) = if is_64 {
- (
- mem::size_of::<xcoff::FileHeader64>(),
- mem::size_of::<xcoff::SectionHeader64>(),
- mem::size_of::<xcoff::Rel64>(),
- mem::size_of::<xcoff::Symbol64>(),
- )
- } else {
- (
- mem::size_of::<xcoff::FileHeader32>(),
- mem::size_of::<xcoff::SectionHeader32>(),
- mem::size_of::<xcoff::Rel32>(),
- mem::size_of::<xcoff::Symbol32>(),
- )
- };
-
- // Calculate offsets and build strtab.
- let mut offset = 0;
- let mut strtab = StringTable::default();
- // We place the shared address 0 immediately after the section header table.
- let mut address = 0;
-
- // XCOFF file header.
- offset += hdr_size;
- // Section headers.
- offset += self.sections.len() * sechdr_size;
-
- // Calculate size of section data.
- let mut section_offsets = vec![SectionOffsets::default(); self.sections.len()];
- for (index, section) in self.sections.iter().enumerate() {
- let len = section.data.len();
- let sectype = section.kind;
- // Section address should be 0 for all sections except the .text, .data, and .bss sections.
- if sectype == SectionKind::Data
- || sectype == SectionKind::Text
- || sectype == SectionKind::UninitializedData
- {
- section_offsets[index].address = address as u64;
- address += len;
- address = align(address, 4);
- } else {
- section_offsets[index].address = 0;
- }
- if len != 0 {
- // Set the default section alignment as 4.
- offset = align(offset, 4);
- section_offsets[index].data_offset = offset;
- offset += len;
- } else {
- section_offsets[index].data_offset = 0;
- }
- }
-
- // Calculate size of relocations.
- for (index, section) in self.sections.iter().enumerate() {
- let count = section.relocations.len();
- if count != 0 {
- section_offsets[index].reloc_offset = offset;
- offset += count * rel_size;
- } else {
- section_offsets[index].reloc_offset = 0;
- }
- }
-
- // Calculate size of symbols.
- let mut file_str_id = None;
- let mut symbol_offsets = vec![SymbolOffsets::default(); self.symbols.len()];
- let mut symtab_count = 0;
- for (index, symbol) in self.symbols.iter().enumerate() {
- symbol_offsets[index].index = symtab_count;
- symtab_count += 1;
-
- let storage_class = if let SymbolFlags::Xcoff { n_sclass, .. } = symbol.flags {
- n_sclass
- } else {
- match symbol.kind {
- SymbolKind::Null => xcoff::C_NULL,
- SymbolKind::File => xcoff::C_FILE,
- SymbolKind::Text | SymbolKind::Data | SymbolKind::Tls => {
- if symbol.is_local() {
- xcoff::C_STAT
- } else if symbol.weak {
- xcoff::C_WEAKEXT
- } else {
- xcoff::C_EXT
- }
- }
- SymbolKind::Section | SymbolKind::Label | SymbolKind::Unknown => {
- return Err(Error(format!(
- "unimplemented symbol `{}` kind {:?}",
- symbol.name().unwrap_or(""),
- symbol.kind
- )));
- }
- }
- };
- symbol_offsets[index].storage_class = storage_class;
-
- if storage_class == xcoff::C_FILE {
- if is_64 && file_str_id.is_none() {
- file_str_id = Some(strtab.add(b".file"));
- }
- if symbol.name.len() > 8 {
- symbol_offsets[index].str_id = Some(strtab.add(&symbol.name));
- }
- } else if is_64 || symbol.name.len() > 8 {
- symbol_offsets[index].str_id = Some(strtab.add(&symbol.name));
- }
-
- symbol_offsets[index].aux_count = 0;
- match storage_class {
- xcoff::C_FILE => {
- symbol_offsets[index].aux_count = 1;
- symtab_count += 1;
- }
- xcoff::C_EXT | xcoff::C_WEAKEXT | xcoff::C_HIDEXT => {
- symbol_offsets[index].aux_count = 1;
- symtab_count += 1;
- }
- // TODO: support auxiliary entry for other types of symbol.
- _ => {}
- }
- }
- let symtab_offset = offset;
- let symtab_len = symtab_count * sym_size;
- offset += symtab_len;
-
- // Calculate size of strtab.
- let strtab_offset = offset;
- let mut strtab_data = Vec::new();
- // First 4 bytes of strtab are the length.
- strtab.write(4, &mut strtab_data);
- let strtab_len = strtab_data.len() + 4;
- offset += strtab_len;
-
- // Start writing.
- buffer
- .reserve(offset)
- .map_err(|_| Error(String::from("Cannot allocate buffer")))?;
-
- // Write file header.
- if is_64 {
- let header = xcoff::FileHeader64 {
- f_magic: U16::new(BE, xcoff::MAGIC_64),
- f_nscns: U16::new(BE, self.sections.len() as u16),
- f_timdat: U32::new(BE, 0),
- f_symptr: U64::new(BE, symtab_offset as u64),
- f_nsyms: U32::new(BE, symtab_count as u32),
- f_opthdr: U16::new(BE, 0),
- f_flags: match self.flags {
- FileFlags::Xcoff { f_flags } => U16::new(BE, f_flags),
- _ => U16::default(),
- },
- };
- buffer.write(&header);
- } else {
- let header = xcoff::FileHeader32 {
- f_magic: U16::new(BE, xcoff::MAGIC_32),
- f_nscns: U16::new(BE, self.sections.len() as u16),
- f_timdat: U32::new(BE, 0),
- f_symptr: U32::new(BE, symtab_offset as u32),
- f_nsyms: U32::new(BE, symtab_count as u32),
- f_opthdr: U16::new(BE, 0),
- f_flags: match self.flags {
- FileFlags::Xcoff { f_flags } => U16::new(BE, f_flags),
- _ => U16::default(),
- },
- };
- buffer.write(&header);
- }
-
- // Write section headers.
- for (index, section) in self.sections.iter().enumerate() {
- let mut sectname = [0; 8];
- sectname
- .get_mut(..section.name.len())
- .ok_or_else(|| {
- Error(format!(
- "section name `{}` is too long",
- section.name().unwrap_or(""),
- ))
- })?
- .copy_from_slice(&section.name);
- let flags = if let SectionFlags::Xcoff { s_flags } = section.flags {
- s_flags
- } else {
- match section.kind {
- SectionKind::Text
- | SectionKind::ReadOnlyData
- | SectionKind::ReadOnlyString
- | SectionKind::ReadOnlyDataWithRel => xcoff::STYP_TEXT,
- SectionKind::Data => xcoff::STYP_DATA,
- SectionKind::UninitializedData => xcoff::STYP_BSS,
- SectionKind::Tls => xcoff::STYP_TDATA,
- SectionKind::UninitializedTls => xcoff::STYP_TBSS,
- SectionKind::OtherString => xcoff::STYP_INFO,
- SectionKind::Debug => xcoff::STYP_DEBUG,
- SectionKind::Other | SectionKind::Metadata => 0,
- SectionKind::Note
- | SectionKind::Linker
- | SectionKind::Common
- | SectionKind::Unknown
- | SectionKind::TlsVariables
- | SectionKind::Elf(_) => {
- return Err(Error(format!(
- "unimplemented section `{}` kind {:?}",
- section.name().unwrap_or(""),
- section.kind
- )));
- }
- }
- .into()
- };
- if is_64 {
- let section_header = xcoff::SectionHeader64 {
- s_name: sectname,
- s_paddr: U64::new(BE, section_offsets[index].address),
- // This field has the same value as the s_paddr field.
- s_vaddr: U64::new(BE, section_offsets[index].address),
- s_size: U64::new(BE, section.data.len() as u64),
- s_scnptr: U64::new(BE, section_offsets[index].data_offset as u64),
- s_relptr: U64::new(BE, section_offsets[index].reloc_offset as u64),
- s_lnnoptr: U64::new(BE, 0),
- s_nreloc: U32::new(BE, section.relocations.len() as u32),
- s_nlnno: U32::new(BE, 0),
- s_flags: U32::new(BE, flags),
- s_reserve: U32::new(BE, 0),
- };
- buffer.write(&section_header);
- } else {
- let section_header = xcoff::SectionHeader32 {
- s_name: sectname,
- s_paddr: U32::new(BE, section_offsets[index].address as u32),
- // This field has the same value as the s_paddr field.
- s_vaddr: U32::new(BE, section_offsets[index].address as u32),
- s_size: U32::new(BE, section.data.len() as u32),
- s_scnptr: U32::new(BE, section_offsets[index].data_offset as u32),
- s_relptr: U32::new(BE, section_offsets[index].reloc_offset as u32),
- s_lnnoptr: U32::new(BE, 0),
- // TODO: If more than 65,534 relocation entries are required, the field
- // value will be 65535, and an STYP_OVRFLO section header will contain
- // the actual count of relocation entries in the s_paddr field.
- s_nreloc: U16::new(BE, section.relocations.len() as u16),
- s_nlnno: U16::new(BE, 0),
- s_flags: U32::new(BE, flags),
- };
- buffer.write(&section_header);
- }
- }
-
- // Write section data.
- for (index, section) in self.sections.iter().enumerate() {
- let len = section.data.len();
- if len != 0 {
- write_align(buffer, 4);
- debug_assert_eq!(section_offsets[index].data_offset, buffer.len());
- buffer.write_bytes(&section.data);
- }
- }
-
- // Write relocations.
- for (index, section) in self.sections.iter().enumerate() {
- if !section.relocations.is_empty() {
- debug_assert_eq!(section_offsets[index].reloc_offset, buffer.len());
- for reloc in &section.relocations {
- let rtype = match reloc.kind {
- RelocationKind::Absolute => xcoff::R_POS,
- RelocationKind::Relative => xcoff::R_REL,
- RelocationKind::Got => xcoff::R_TOC,
- RelocationKind::Xcoff(x) => x,
- _ => {
- return Err(Error(format!("unimplemented relocation {:?}", reloc)));
- }
- };
- if is_64 {
- let xcoff_rel = xcoff::Rel64 {
- r_vaddr: U64::new(BE, reloc.offset),
- r_symndx: U32::new(BE, symbol_offsets[reloc.symbol.0].index as u32),
- // Specifies the bit length of the relocatable reference minus one.
- r_rsize: (reloc.size - 1),
- r_rtype: rtype,
- };
- buffer.write(&xcoff_rel);
- } else {
- let xcoff_rel = xcoff::Rel32 {
- r_vaddr: U32::new(BE, reloc.offset as u32),
- r_symndx: U32::new(BE, symbol_offsets[reloc.symbol.0].index as u32),
- r_rsize: (reloc.size - 1),
- r_rtype: rtype,
- };
- buffer.write(&xcoff_rel);
- }
- }
- }
- }
-
- // Write symbols.
- debug_assert_eq!(symtab_offset, buffer.len());
- for (index, symbol) in self.symbols.iter().enumerate() {
- let (n_value, section_kind) = if let SymbolSection::Section(id) = symbol.section {
- (
- section_offsets[id.0].address + symbol.value,
- self.sections[id.0].kind,
- )
- } else {
- (symbol.value, SectionKind::Unknown)
- };
- let n_scnum = match symbol.section {
- SymbolSection::None => {
- debug_assert_eq!(symbol.kind, SymbolKind::File);
- xcoff::N_DEBUG
- }
- SymbolSection::Undefined | SymbolSection::Common => xcoff::N_UNDEF,
- SymbolSection::Absolute => xcoff::N_ABS,
- SymbolSection::Section(id) => id.0 as i16 + 1,
- };
- let n_sclass = symbol_offsets[index].storage_class;
- let n_type = if (symbol.scope == SymbolScope::Linkage)
- && (n_sclass == xcoff::C_EXT
- || n_sclass == xcoff::C_WEAKEXT
- || n_sclass == xcoff::C_HIDEXT)
- {
- xcoff::SYM_V_HIDDEN
- } else {
- 0
- };
- let n_numaux = symbol_offsets[index].aux_count;
- if is_64 {
- let str_id = if n_sclass == xcoff::C_FILE {
- file_str_id.unwrap()
- } else {
- symbol_offsets[index].str_id.unwrap()
- };
- let xcoff_sym = xcoff::Symbol64 {
- n_value: U64::new(BE, n_value),
- n_offset: U32::new(BE, strtab.get_offset(str_id) as u32),
- n_scnum: I16::new(BE, n_scnum),
- n_type: U16::new(BE, n_type),
- n_sclass,
- n_numaux,
- };
- buffer.write(&xcoff_sym);
- } else {
- let mut sym_name = [0; 8];
- if n_sclass == xcoff::C_FILE {
- sym_name[..5].copy_from_slice(b".file");
- } else if symbol.name.len() <= 8 {
- sym_name[..symbol.name.len()].copy_from_slice(&symbol.name[..]);
- } else {
- let str_offset = strtab.get_offset(symbol_offsets[index].str_id.unwrap());
- sym_name[4..8].copy_from_slice(&u32::to_be_bytes(str_offset as u32));
- }
- let xcoff_sym = xcoff::Symbol32 {
- n_name: sym_name,
- n_value: U32::new(BE, n_value as u32),
- n_scnum: I16::new(BE, n_scnum),
- n_type: U16::new(BE, n_type),
- n_sclass,
- n_numaux,
- };
- buffer.write(&xcoff_sym);
- }
- // Generate auxiliary entries.
- if n_sclass == xcoff::C_FILE {
- debug_assert_eq!(n_numaux, 1);
- let mut x_fname = [0; 8];
- if symbol.name.len() <= 8 {
- x_fname[..symbol.name.len()].copy_from_slice(&symbol.name[..]);
- } else {
- let str_offset = strtab.get_offset(symbol_offsets[index].str_id.unwrap());
- x_fname[4..8].copy_from_slice(&u32::to_be_bytes(str_offset as u32));
- }
- if is_64 {
- let file_aux = xcoff::FileAux64 {
- x_fname,
- x_fpad: Default::default(),
- x_ftype: xcoff::XFT_FN,
- x_freserve: Default::default(),
- x_auxtype: xcoff::AUX_FILE,
- };
- buffer.write(&file_aux);
- } else {
- let file_aux = xcoff::FileAux32 {
- x_fname,
- x_fpad: Default::default(),
- x_ftype: xcoff::XFT_FN,
- x_freserve: Default::default(),
- };
- buffer.write(&file_aux);
- }
- } else if n_sclass == xcoff::C_EXT
- || n_sclass == xcoff::C_WEAKEXT
- || n_sclass == xcoff::C_HIDEXT
- {
- debug_assert_eq!(n_numaux, 1);
- let (x_smtyp, x_smclas) = if let SymbolFlags::Xcoff {
- x_smtyp, x_smclas, ..
- } = symbol.flags
- {
- (x_smtyp, x_smclas)
- } else {
- match symbol.kind {
- SymbolKind::Text => (xcoff::XTY_SD, xcoff::XMC_PR),
- SymbolKind::Data => {
- if section_kind == SectionKind::UninitializedData {
- (xcoff::XTY_CM, xcoff::XMC_BS)
- } else if section_kind == SectionKind::ReadOnlyData {
- (xcoff::XTY_SD, xcoff::XMC_RO)
- } else {
- (xcoff::XTY_SD, xcoff::XMC_RW)
- }
- }
- SymbolKind::Tls => {
- if section_kind == SectionKind::UninitializedTls {
- (xcoff::XTY_CM, xcoff::XMC_UL)
- } else {
- (xcoff::XTY_SD, xcoff::XMC_TL)
- }
- }
- _ => {
- return Err(Error(format!(
- "unimplemented symbol `{}` kind {:?}",
- symbol.name().unwrap_or(""),
- symbol.kind
- )));
- }
- }
- };
- let scnlen = if let SymbolFlags::Xcoff {
- containing_csect: Some(containing_csect),
- ..
- } = symbol.flags
- {
- symbol_offsets[containing_csect.0].index as u64
- } else {
- symbol.size
- };
- if is_64 {
- let csect_aux = xcoff::CsectAux64 {
- x_scnlen_lo: U32::new(BE, (scnlen & 0xFFFFFFFF) as u32),
- x_scnlen_hi: U32::new(BE, ((scnlen >> 32) & 0xFFFFFFFF) as u32),
- x_parmhash: U32::new(BE, 0),
- x_snhash: U16::new(BE, 0),
- x_smtyp,
- x_smclas,
- pad: 0,
- x_auxtype: xcoff::AUX_CSECT,
- };
- buffer.write(&csect_aux);
- } else {
- let csect_aux = xcoff::CsectAux32 {
- x_scnlen: U32::new(BE, scnlen as u32),
- x_parmhash: U32::new(BE, 0),
- x_snhash: U16::new(BE, 0),
- x_smtyp,
- x_smclas,
- x_stab: U32::new(BE, 0),
- x_snstab: U16::new(BE, 0),
- };
- buffer.write(&csect_aux);
- }
- }
- }
-
- // Write string table.
- debug_assert_eq!(strtab_offset, buffer.len());
- buffer.write_bytes(&u32::to_be_bytes(strtab_len as u32));
- buffer.write_bytes(&strtab_data);
-
- debug_assert_eq!(offset, buffer.len());
- Ok(())
- }
-}
diff --git a/vendor/object/src/xcoff.rs b/vendor/object/src/xcoff.rs
deleted file mode 100644
index dbe5d73..0000000
--- a/vendor/object/src/xcoff.rs
+++ /dev/null
@@ -1,905 +0,0 @@
-//! XCOFF definitions
-//!
-//! These definitions are independent of read/write support, although we do implement
-//! some traits useful for those.
-//!
-//! This module is the equivalent of /usr/include/xcoff.h, and is based heavily on it.
-
-#![allow(missing_docs)]
-
-use crate::endian::{BigEndian as BE, I16, U16, U32, U64};
-use crate::pod::Pod;
-
-/// The header at the start of every 32-bit XCOFF file.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FileHeader32 {
- /// Magic number. Must be 0x01DF.
- pub f_magic: U16<BE>,
- /// Number of sections.
- pub f_nscns: U16<BE>,
- /// Time and date of file creation.
- pub f_timdat: U32<BE>,
- /// Byte offset to symbol table start.
- pub f_symptr: U32<BE>,
- /// Number of entries in symbol table.
- pub f_nsyms: U32<BE>,
- /// Number of bytes in optional header
- pub f_opthdr: U16<BE>,
- /// Extra flags.
- pub f_flags: U16<BE>,
-}
-
-/// The header at the start of every 64-bit XCOFF file.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FileHeader64 {
- /// Magic number. Must be 0x01F7.
- pub f_magic: U16<BE>,
- /// Number of sections.
- pub f_nscns: U16<BE>,
- /// Time and date of file creation
- pub f_timdat: U32<BE>,
- /// Byte offset to symbol table start.
- pub f_symptr: U64<BE>,
- /// Number of bytes in optional header
- pub f_opthdr: U16<BE>,
- /// Extra flags.
- pub f_flags: U16<BE>,
- /// Number of entries in symbol table.
- pub f_nsyms: U32<BE>,
-}
-
-// Values for `f_magic`.
-//
-/// the 64-bit mach magic number
-pub const MAGIC_64: u16 = 0x01F7;
-/// the 32-bit mach magic number
-pub const MAGIC_32: u16 = 0x01DF;
-
-// Values for `f_flags`.
-//
-/// Indicates that the relocation information for binding has been removed from
-/// the file.
-pub const F_RELFLG: u16 = 0x0001;
-/// Indicates that the file is executable. No unresolved external references exist.
-pub const F_EXEC: u16 = 0x0002;
-/// Indicates that line numbers have been stripped from the file by a utility program.
-pub const F_LNNO: u16 = 0x0004;
-/// Indicates that the file was profiled with the fdpr command.
-pub const F_FDPR_PROF: u16 = 0x0010;
-/// Indicates that the file was reordered with the fdpr command.
-pub const F_FDPR_OPTI: u16 = 0x0020;
-/// Indicates that the file uses Very Large Program Support.
-pub const F_DSA: u16 = 0x0040;
-/// Indicates that one of the members of the auxiliary header specifying the
-/// medium page sizes is non-zero.
-pub const F_VARPG: u16 = 0x0100;
-/// Indicates the file is dynamically loadable and executable. External references
-/// are resolved by way of imports, and the file might contain exports and loader
-/// relocation.
-pub const F_DYNLOAD: u16 = 0x1000;
-/// Indicates the file is a shared object (shared library). The file is separately
-/// loadable. That is, it is not normally bound with other objects, and its loader
-/// exports symbols are used as automatic import symbols for other object files.
-pub const F_SHROBJ: u16 = 0x2000;
-/// If the object file is a member of an archive, it can be loaded by the system
-/// loader, but the member is ignored by the binder. If the object file is not in
-/// an archive, this flag has no effect.
-pub const F_LOADONLY: u16 = 0x4000;
-
-/// The auxiliary header immediately following file header. If the value of the
-/// f_opthdr field in the file header is 0, the auxiliary header does not exist.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct AuxHeader32 {
- /// Flags.
- pub o_mflag: U16<BE>,
- /// Version.
- pub o_vstamp: U16<BE>,
- /// Text size in bytes.
- pub o_tsize: U32<BE>,
- /// Initialized data size in bytes.
- pub o_dsize: U32<BE>,
- /// Uninitialized data size in bytes.
- pub o_bsize: U32<BE>,
- /// Entry point descriptor (virtual address).
- pub o_entry: U32<BE>,
- /// Base address of text (virtual address).
- pub o_text_start: U32<BE>,
- /// Base address of data (virtual address).
- pub o_data_start: U32<BE>,
- /// Address of TOC anchor.
- pub o_toc: U32<BE>,
- /// Section number for entry point.
- pub o_snentry: U16<BE>,
- /// Section number for .text.
- pub o_sntext: U16<BE>,
- /// Section number for .data.
- pub o_sndata: U16<BE>,
- /// Section number for TOC.
- pub o_sntoc: U16<BE>,
- /// Section number for loader data.
- pub o_snloader: U16<BE>,
- /// Section number for .bss.
- pub o_snbss: U16<BE>,
- /// Maximum alignment for .text.
- pub o_algntext: U16<BE>,
- /// Maximum alignment for .data.
- pub o_algndata: U16<BE>,
- /// Module type field.
- pub o_modtype: U16<BE>,
- /// Bit flags - cpu types of objects.
- pub o_cpuflag: u8,
- /// Reserved for CPU type.
- pub o_cputype: u8,
- /// Maximum stack size allowed (bytes).
- pub o_maxstack: U32<BE>,
- /// Maximum data size allowed (bytes).
- pub o_maxdata: U32<BE>,
- /// Reserved for debuggers.
- pub o_debugger: U32<BE>,
- /// Requested text page size.
- pub o_textpsize: u8,
- /// Requested data page size.
- pub o_datapsize: u8,
- /// Requested stack page size.
- pub o_stackpsize: u8,
- /// Flags and thread-local storage alignment.
- pub o_flags: u8,
- /// Section number for .tdata.
- pub o_sntdata: U16<BE>,
- /// Section number for .tbss.
- pub o_sntbss: U16<BE>,
-}
-
-/// The auxiliary header immediately following file header. If the value of the
-/// f_opthdr field in the file header is 0, the auxiliary header does not exist.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct AuxHeader64 {
- /// Flags.
- pub o_mflag: U16<BE>,
- /// Version.
- pub o_vstamp: U16<BE>,
- /// Reserved for debuggers.
- pub o_debugger: U32<BE>,
- /// Base address of text (virtual address).
- pub o_text_start: U64<BE>,
- /// Base address of data (virtual address).
- pub o_data_start: U64<BE>,
- /// Address of TOC anchor.
- pub o_toc: U64<BE>,
- /// Section number for entry point.
- pub o_snentry: U16<BE>,
- /// Section number for .text.
- pub o_sntext: U16<BE>,
- /// Section number for .data.
- pub o_sndata: U16<BE>,
- /// Section number for TOC.
- pub o_sntoc: U16<BE>,
- /// Section number for loader data.
- pub o_snloader: U16<BE>,
- /// Section number for .bss.
- pub o_snbss: U16<BE>,
- /// Maximum alignment for .text.
- pub o_algntext: U16<BE>,
- /// Maximum alignment for .data.
- pub o_algndata: U16<BE>,
- /// Module type field.
- pub o_modtype: U16<BE>,
- /// Bit flags - cpu types of objects.
- pub o_cpuflag: u8,
- /// Reserved for CPU type.
- pub o_cputype: u8,
- /// Requested text page size.
- pub o_textpsize: u8,
- /// Requested data page size.
- pub o_datapsize: u8,
- /// Requested stack page size.
- pub o_stackpsize: u8,
- /// Flags and thread-local storage alignment.
- pub o_flags: u8,
- /// Text size in bytes.
- pub o_tsize: U64<BE>,
- /// Initialized data size in bytes.
- pub o_dsize: U64<BE>,
- /// Uninitialized data size in bytes.
- pub o_bsize: U64<BE>,
- /// Entry point descriptor (virtual address).
- pub o_entry: U64<BE>,
- /// Maximum stack size allowed (bytes).
- pub o_maxstack: U64<BE>,
- /// Maximum data size allowed (bytes).
- pub o_maxdata: U64<BE>,
- /// Section number for .tdata.
- pub o_sntdata: U16<BE>,
- /// Section number for .tbss.
- pub o_sntbss: U16<BE>,
- /// XCOFF64 flags.
- pub o_x64flags: U16<BE>,
- /// Reserved.
- pub o_resv3a: U16<BE>,
- /// Reserved.
- pub o_resv3: [U32<BE>; 2],
-}
-
-/// Some AIX programs generate auxiliary headers for 32-bit object files that
-/// end after the data_start field.
-pub const AOUTHSZ_SHORT: u16 = 28;
-
-/// Section header.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct SectionHeader32 {
- /// Section name.
- pub s_name: [u8; 8],
- /// Physical address.
- pub s_paddr: U32<BE>,
- /// Virtual address (same as physical address).
- pub s_vaddr: U32<BE>,
- /// Section size.
- pub s_size: U32<BE>,
- /// Offset in file to raw data for section.
- pub s_scnptr: U32<BE>,
- /// Offset in file to relocation entries for section.
- pub s_relptr: U32<BE>,
- /// Offset in file to line number entries for section.
- pub s_lnnoptr: U32<BE>,
- /// Number of relocation entries.
- pub s_nreloc: U16<BE>,
- /// Number of line number entries.
- pub s_nlnno: U16<BE>,
- /// Flags to define the section type.
- pub s_flags: U32<BE>,
-}
-
-/// Section header.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct SectionHeader64 {
- /// Section name.
- pub s_name: [u8; 8],
- /// Physical address.
- pub s_paddr: U64<BE>,
- /// Virtual address (same as physical address).
- pub s_vaddr: U64<BE>,
- /// Section size.
- pub s_size: U64<BE>,
- /// Offset in file to raw data for section.
- pub s_scnptr: U64<BE>,
- /// Offset in file to relocation entries for section.
- pub s_relptr: U64<BE>,
- /// Offset in file to line number entries for section.
- pub s_lnnoptr: U64<BE>,
- /// Number of relocation entries.
- pub s_nreloc: U32<BE>,
- /// Number of line number entries.
- pub s_nlnno: U32<BE>,
- /// Flags to define the section type.
- pub s_flags: U32<BE>,
- /// Reserved.
- pub s_reserve: U32<BE>,
-}
-
-// Values for `s_flags`.
-//
-/// "regular" section
-pub const STYP_REG: u16 = 0x00;
-/// Specifies a pad section. A section of this type is used to provide alignment
-/// padding between sections within an XCOFF executable object file. This section
-/// header type is obsolete since padding is allowed in an XCOFF file without a
-/// corresponding pad section header.
-pub const STYP_PAD: u16 = 0x08;
-/// Specifies a DWARF debugging section, which provide source file and symbol
-/// information for the symbolic debugger.
-pub const STYP_DWARF: u16 = 0x10;
-/// Specifies an executable text (code) section. A section of this type contains
-/// the executable instructions of a program.
-pub const STYP_TEXT: u16 = 0x20;
-/// Specifies an initialized data section. A section of this type contains the
-/// initialized data and the TOC of a program.
-pub const STYP_DATA: u16 = 0x40;
-/// Specifies an uninitialized data section. A section header of this type
-/// defines the uninitialized data of a program.
-pub const STYP_BSS: u16 = 0x80;
-/// Specifies an exception section. A section of this type provides information
-/// to identify the reason that a trap or exception occurred within an executable
-/// object program.
-pub const STYP_EXCEPT: u16 = 0x0100;
-/// Specifies a comment section. A section of this type provides comments or data
-/// to special processing utility programs.
-pub const STYP_INFO: u16 = 0x0200;
-/// Specifies an initialized thread-local data section.
-pub const STYP_TDATA: u16 = 0x0400;
-/// Specifies an uninitialized thread-local data section.
-pub const STYP_TBSS: u16 = 0x0800;
-/// Specifies a loader section. A section of this type contains object file
-/// information for the system loader to load an XCOFF executable. The information
-/// includes imported symbols, exported symbols, relocation data, type-check
-/// information, and shared object names.
-pub const STYP_LOADER: u16 = 0x1000;
-/// Specifies a debug section. A section of this type contains stabstring
-/// information used by the symbolic debugger.
-pub const STYP_DEBUG: u16 = 0x2000;
-/// Specifies a type-check section. A section of this type contains
-/// parameter/argument type-check strings used by the binder.
-pub const STYP_TYPCHK: u16 = 0x4000;
-/// Specifies a relocation or line-number field overflow section. A section
-/// header of this type contains the count of relocation entries and line
-/// number entries for some other section. This section header is required
-/// when either of the counts exceeds 65,534.
-pub const STYP_OVRFLO: u16 = 0x8000;
-
-pub const SSUBTYP_DWINFO: u32 = 0x10000;
-pub const SSUBTYP_DWLINE: u32 = 0x20000;
-pub const SSUBTYP_DWPBNMS: u32 = 0x30000;
-pub const SSUBTYP_DWPBTYP: u32 = 0x40000;
-pub const SSUBTYP_DWARNGE: u32 = 0x50000;
-pub const SSUBTYP_DWABREV: u32 = 0x60000;
-pub const SSUBTYP_DWSTR: u32 = 0x70000;
-pub const SSUBTYP_DWRNGES: u32 = 0x80000;
-pub const SSUBTYP_DWLOC: u32 = 0x90000;
-pub const SSUBTYP_DWFRAME: u32 = 0xA0000;
-pub const SSUBTYP_DWMAC: u32 = 0xB0000;
-
-pub const SIZEOF_SYMBOL: usize = 18;
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct SymbolBytes(pub [u8; SIZEOF_SYMBOL]);
-
-/// Symbol table entry.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Symbol32 {
- /// Symbol name.
- ///
- /// If first 4 bytes are 0, then second 4 bytes are offset into string table.
- pub n_name: [u8; 8],
- /// Symbol value; storage class-dependent.
- pub n_value: U32<BE>,
- /// Section number of symbol.
- pub n_scnum: I16<BE>,
- /// Basic and derived type specification.
- pub n_type: U16<BE>,
- /// Storage class of symbol.
- pub n_sclass: u8,
- /// Number of auxiliary entries.
- pub n_numaux: u8,
-}
-
-/// Symbol table entry.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Symbol64 {
- /// Symbol value; storage class-dependent.
- pub n_value: U64<BE>,
- /// Offset of the name in string table or .debug section.
- pub n_offset: U32<BE>,
- /// Section number of symbol.
- pub n_scnum: I16<BE>,
- /// Basic and derived type specification.
- pub n_type: U16<BE>,
- /// Storage class of symbol.
- pub n_sclass: u8,
- /// Number of auxiliary entries.
- pub n_numaux: u8,
-}
-
-// Values for `n_scnum`.
-//
-/// A special symbolic debugging symbol.
-pub const N_DEBUG: i16 = -2;
-/// An absolute symbol. The symbol has a value but is not relocatable.
-pub const N_ABS: i16 = -1;
-/// An undefined external symbol.
-pub const N_UNDEF: i16 = 0;
-
-// Vlaues for `n_type`.
-//
-/// Values for visibility as they would appear when encoded in the high 4 bits
-/// of the 16-bit unsigned n_type field of symbol table entries. Valid for
-/// 32-bit XCOFF only when the o_vstamp in the auxiliary header is greater than 1.
-pub const SYM_V_MASK: u16 = 0xF000;
-pub const SYM_V_INTERNAL: u16 = 0x1000;
-pub const SYM_V_HIDDEN: u16 = 0x2000;
-pub const SYM_V_PROTECTED: u16 = 0x3000;
-pub const SYM_V_EXPORTED: u16 = 0x4000;
-
-// Values for `n_sclass`.
-//
-// Storage classes used for symbolic debugging symbols.
-//
-/// Source file name and compiler information.
-pub const C_FILE: u8 = 103;
-/// Beginning of include file.
-pub const C_BINCL: u8 = 108;
-/// Ending of include file.
-pub const C_EINCL: u8 = 109;
-/// Global variable.
-pub const C_GSYM: u8 = 128;
-/// Statically allocated symbol.
-pub const C_STSYM: u8 = 133;
-/// Beginning of common block.
-pub const C_BCOMM: u8 = 135;
-/// End of common block.
-pub const C_ECOMM: u8 = 137;
-/// Alternate entry.
-pub const C_ENTRY: u8 = 141;
-/// Beginning of static block.
-pub const C_BSTAT: u8 = 143;
-/// End of static block.
-pub const C_ESTAT: u8 = 144;
-/// Global thread-local variable.
-pub const C_GTLS: u8 = 145;
-/// Static thread-local variable.
-pub const C_STTLS: u8 = 146;
-/// DWARF section symbol.
-pub const C_DWARF: u8 = 112;
-//
-// Storage classes used for absolute symbols.
-//
-/// Automatic variable allocated on stack.
-pub const C_LSYM: u8 = 129;
-/// Argument to subroutine allocated on stack.
-pub const C_PSYM: u8 = 130;
-/// Register variable.
-pub const C_RSYM: u8 = 131;
-/// Argument to function or procedure stored in register.
-pub const C_RPSYM: u8 = 132;
-/// Local member of common block.
-pub const C_ECOML: u8 = 136;
-/// Function or procedure.
-pub const C_FUN: u8 = 142;
-//
-// Storage classes used for undefined external symbols or symbols of general sections.
-//
-/// External symbol.
-pub const C_EXT: u8 = 2;
-/// Weak external symbol.
-pub const C_WEAKEXT: u8 = 111;
-//
-// Storage classes used for symbols of general sections.
-//
-/// Symbol table entry marked for deletion.
-pub const C_NULL: u8 = 0;
-/// Static.
-pub const C_STAT: u8 = 3;
-/// Beginning or end of inner block.
-pub const C_BLOCK: u8 = 100;
-/// Beginning or end of function.
-pub const C_FCN: u8 = 101;
-/// Un-named external symbol.
-pub const C_HIDEXT: u8 = 107;
-/// Comment string in .info section.
-pub const C_INFO: u8 = 110;
-/// Declaration of object (type).
-pub const C_DECL: u8 = 140;
-//
-// Storage classes - Obsolete/Undocumented.
-//
-/// Automatic variable.
-pub const C_AUTO: u8 = 1;
-/// Register variable.
-pub const C_REG: u8 = 4;
-/// External definition.
-pub const C_EXTDEF: u8 = 5;
-/// Label.
-pub const C_LABEL: u8 = 6;
-/// Undefined label.
-pub const C_ULABEL: u8 = 7;
-/// Member of structure.
-pub const C_MOS: u8 = 8;
-/// Function argument.
-pub const C_ARG: u8 = 9;
-/// Structure tag.
-pub const C_STRTAG: u8 = 10;
-/// Member of union.
-pub const C_MOU: u8 = 11;
-/// Union tag.
-pub const C_UNTAG: u8 = 12;
-/// Type definition.
-pub const C_TPDEF: u8 = 13;
-/// Undefined static.
-pub const C_USTATIC: u8 = 14;
-/// Enumeration tag.
-pub const C_ENTAG: u8 = 15;
-/// Member of enumeration.
-pub const C_MOE: u8 = 16;
-/// Register parameter.
-pub const C_REGPARM: u8 = 17;
-/// Bit field.
-pub const C_FIELD: u8 = 18;
-/// End of structure.
-pub const C_EOS: u8 = 102;
-/// Duplicate tag.
-pub const C_ALIAS: u8 = 105;
-/// Special storage class for external.
-pub const C_HIDDEN: u8 = 106;
-/// Physical end of function.
-pub const C_EFCN: u8 = 255;
-/// Reserved.
-pub const C_TCSYM: u8 = 134;
-
-/// File Auxiliary Entry for C_FILE Symbols.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FileAux32 {
- /// The source file name or compiler-related string.
- ///
- /// If first 4 bytes are 0, then second 4 bytes are offset into string table.
- pub x_fname: [u8; 8],
- /// Pad size for file name.
- pub x_fpad: [u8; 6],
- /// The source-file string type.
- pub x_ftype: u8,
- /// Reserved.
- pub x_freserve: [u8; 3],
-}
-
-/// File Auxiliary Entry for C_FILE Symbols.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FileAux64 {
- /// The source file name or compiler-related string.
- ///
- /// If first 4 bytes are 0, then second 4 bytes are offset into string table.
- pub x_fname: [u8; 8],
- /// Pad size for file name.
- pub x_fpad: [u8; 6],
- /// The source-file string type.
- pub x_ftype: u8,
- /// Reserved.
- pub x_freserve: [u8; 2],
- /// Specifies the type of auxiliary entry. Contains _AUX_FILE for this auxiliary entry.
- pub x_auxtype: u8,
-}
-
-// Values for `x_ftype`.
-//
-/// Specifies the source-file name.
-pub const XFT_FN: u8 = 0;
-/// Specifies the compiler time stamp.
-pub const XFT_CT: u8 = 1;
-/// Specifies the compiler version number.
-pub const XFT_CV: u8 = 2;
-/// Specifies compiler-defined information.
-pub const XFT_CD: u8 = 128;
-
-/// Csect auxiliary entry for C_EXT, C_WEAKEXT, and C_HIDEXT symbols.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct CsectAux32 {
- /// Section length.
- pub x_scnlen: U32<BE>,
- /// Offset of parameter type-check hash in .typchk section.
- pub x_parmhash: U32<BE>,
- /// .typchk section number.
- pub x_snhash: U16<BE>,
- /// Symbol alignment and type.
- pub x_smtyp: u8,
- /// Storage mapping class.
- pub x_smclas: u8,
- /// Reserved.
- pub x_stab: U32<BE>,
- /// x_snstab.
- pub x_snstab: U16<BE>,
-}
-
-/// Csect auxiliary entry for C_EXT, C_WEAKEXT, and C_HIDEXT symbols.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct CsectAux64 {
- /// Low 4 bytes of section length.
- pub x_scnlen_lo: U32<BE>,
- /// Offset of parameter type-check hash in .typchk section.
- pub x_parmhash: U32<BE>,
- /// .typchk section number.
- pub x_snhash: U16<BE>,
- /// Symbol alignment and type.
- pub x_smtyp: u8,
- /// Storage mapping class.
- pub x_smclas: u8,
- /// High 4 bytes of section length.
- pub x_scnlen_hi: U32<BE>,
- /// Reserved.
- pub pad: u8,
- /// Contains _AUX_CSECT; indicates type of auxiliary entry.
- pub x_auxtype: u8,
-}
-
-// Values for `x_smtyp`.
-//
-/// External reference.
-pub const XTY_ER: u8 = 0;
-/// Csect definition for initialized storage.
-pub const XTY_SD: u8 = 1;
-/// Defines an entry point to an initialized csect.
-pub const XTY_LD: u8 = 2;
-/// Common csect definition. For uninitialized storage.
-pub const XTY_CM: u8 = 3;
-
-// Values for `x_smclas`.
-//
-// READ ONLY CLASSES
-//
-/// Program Code
-pub const XMC_PR: u8 = 0;
-/// Read Only Constant
-pub const XMC_RO: u8 = 1;
-/// Debug Dictionary Table
-pub const XMC_DB: u8 = 2;
-/// Global Linkage (Interfile Interface Code)
-pub const XMC_GL: u8 = 6;
-/// Extended Operation (Pseudo Machine Instruction)
-pub const XMC_XO: u8 = 7;
-/// Supervisor Call (32-bit process only)
-pub const XMC_SV: u8 = 8;
-/// Supervisor Call for 64-bit process
-pub const XMC_SV64: u8 = 17;
-/// Supervisor Call for both 32- and 64-bit processes
-pub const XMC_SV3264: u8 = 18;
-/// Traceback Index csect
-pub const XMC_TI: u8 = 12;
-/// Traceback Table csect
-pub const XMC_TB: u8 = 13;
-//
-// READ WRITE CLASSES
-//
-/// Read Write Data
-pub const XMC_RW: u8 = 5;
-/// TOC Anchor for TOC Addressability
-pub const XMC_TC0: u8 = 15;
-/// General TOC item
-pub const XMC_TC: u8 = 3;
-/// Scalar data item in the TOC
-pub const XMC_TD: u8 = 16;
-/// Descriptor csect
-pub const XMC_DS: u8 = 10;
-/// Unclassified - Treated as Read Write
-pub const XMC_UA: u8 = 4;
-/// BSS class (uninitialized static internal)
-pub const XMC_BS: u8 = 9;
-/// Un-named Fortran Common
-pub const XMC_UC: u8 = 11;
-/// Initialized thread-local variable
-pub const XMC_TL: u8 = 20;
-/// Uninitialized thread-local variable
-pub const XMC_UL: u8 = 21;
-/// Symbol mapped at the end of TOC
-pub const XMC_TE: u8 = 22;
-
-/// Function auxiliary entry.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FunAux32 {
- /// File offset to exception table entry.
- pub x_exptr: U32<BE>,
- /// Size of function in bytes.
- pub x_fsize: U32<BE>,
- /// File pointer to line number
- pub x_lnnoptr: U32<BE>,
- /// Symbol table index of next entry beyond this function.
- pub x_endndx: U32<BE>,
- /// Pad
- pub pad: U16<BE>,
-}
-
-/// Function auxiliary entry.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct FunAux64 {
- /// File pointer to line number
- pub x_lnnoptr: U64<BE>,
- /// Size of function in bytes.
- pub x_fsize: U32<BE>,
- /// Symbol table index of next entry beyond this function.
- pub x_endndx: U32<BE>,
- /// Pad
- pub pad: u8,
- /// Contains _AUX_FCN; Type of auxiliary entry.
- pub x_auxtype: u8,
-}
-
-/// Exception auxiliary entry. (XCOFF64 only)
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct ExpAux {
- /// File offset to exception table entry.
- pub x_exptr: U64<BE>,
- /// Size of function in bytes.
- pub x_fsize: U32<BE>,
- /// Symbol table index of next entry beyond this function.
- pub x_endndx: U32<BE>,
- /// Pad
- pub pad: u8,
- /// Contains _AUX_EXCEPT; Type of auxiliary entry
- pub x_auxtype: u8,
-}
-
-/// Block auxiliary entry for the C_BLOCK and C_FCN Symbols.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct BlockAux32 {
- /// Reserved.
- pub pad: [u8; 2],
- /// High-order 2 bytes of the source line number.
- pub x_lnnohi: U16<BE>,
- /// Low-order 2 bytes of the source line number.
- pub x_lnnolo: U16<BE>,
- /// Reserved.
- pub pad2: [u8; 12],
-}
-
-/// Block auxiliary entry for the C_BLOCK and C_FCN Symbols.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct BlockAux64 {
- /// Source line number.
- pub x_lnno: U32<BE>,
- /// Reserved.
- pub pad: [u8; 13],
- /// Contains _AUX_SYM; Type of auxiliary entry.
- pub x_auxtype: u8,
-}
-
-/// Section auxiliary entry for the C_STAT Symbol. (XCOFF32 Only)
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct StatAux {
- /// Section length.
- pub x_scnlen: U32<BE>,
- /// Number of relocation entries.
- pub x_nreloc: U16<BE>,
- /// Number of line numbers.
- pub x_nlinno: U16<BE>,
- /// Reserved.
- pub pad: [u8; 10],
-}
-
-/// Section auxiliary entry Format for C_DWARF symbols.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DwarfAux32 {
- /// Length of portion of section represented by symbol.
- pub x_scnlen: U32<BE>,
- /// Reserved.
- pub pad: [u8; 4],
- /// Number of relocation entries in section.
- pub x_nreloc: U32<BE>,
- /// Reserved.
- pub pad2: [u8; 6],
-}
-
-/// Section auxiliary entry Format for C_DWARF symbols.
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct DwarfAux64 {
- /// Length of portion of section represented by symbol.
- pub x_scnlen: U64<BE>,
- /// Number of relocation entries in section.
- pub x_nreloc: U64<BE>,
- /// Reserved.
- pub pad: u8,
- /// Contains _AUX_SECT; Type of Auxiliary entry.
- pub x_auxtype: u8,
-}
-
-// Values for `x_auxtype`
-//
-/// Identifies an exception auxiliary entry.
-pub const AUX_EXCEPT: u8 = 255;
-/// Identifies a function auxiliary entry.
-pub const AUX_FCN: u8 = 254;
-/// Identifies a symbol auxiliary entry.
-pub const AUX_SYM: u8 = 253;
-/// Identifies a file auxiliary entry.
-pub const AUX_FILE: u8 = 252;
-/// Identifies a csect auxiliary entry.
-pub const AUX_CSECT: u8 = 251;
-/// Identifies a SECT auxiliary entry.
-pub const AUX_SECT: u8 = 250;
-
-/// Relocation table entry
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Rel32 {
- /// Virtual address (position) in section to be relocated.
- pub r_vaddr: U32<BE>,
- /// Symbol table index of item that is referenced.
- pub r_symndx: U32<BE>,
- /// Relocation size and information.
- pub r_rsize: u8,
- /// Relocation type.
- pub r_rtype: u8,
-}
-
-/// Relocation table entry
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Rel64 {
- /// Virtual address (position) in section to be relocated.
- pub r_vaddr: U64<BE>,
- /// Symbol table index of item that is referenced.
- pub r_symndx: U32<BE>,
- /// Relocation size and information.
- pub r_rsize: u8,
- /// Relocation type.
- pub r_rtype: u8,
-}
-
-// Values for `r_rtype`.
-//
-/// Positive relocation.
-pub const R_POS: u8 = 0x00;
-/// Positive indirect load relocation.
-pub const R_RL: u8 = 0x0c;
-/// Positive load address relocation. Modifiable instruction.
-pub const R_RLA: u8 = 0x0d;
-/// Negative relocation.
-pub const R_NEG: u8 = 0x01;
-/// Relative to self relocation.
-pub const R_REL: u8 = 0x02;
-/// Relative to the TOC relocation.
-pub const R_TOC: u8 = 0x03;
-/// TOC relative indirect load relocation.
-pub const R_TRL: u8 = 0x12;
-/// Relative to the TOC or to the thread-local storage base relocation.
-pub const R_TRLA: u8 = 0x13;
-/// Global linkage-external TOC address relocation.
-pub const R_GL: u8 = 0x05;
-/// Local object TOC address relocation.
-pub const R_TCL: u8 = 0x06;
-/// A non-relocating relocation.
-pub const R_REF: u8 = 0x0f;
-/// Branch absolute relocation. References a non-modifiable instruction.
-pub const R_BA: u8 = 0x08;
-/// Branch relative to self relocation. References a non-modifiable instruction.
-pub const R_BR: u8 = 0x0a;
-/// Branch absolute relocation. References a modifiable instruction.
-pub const R_RBA: u8 = 0x18;
-/// Branch relative to self relocation. References a modifiable instruction.
-pub const R_RBR: u8 = 0x1a;
-/// General-dynamic reference to TLS symbol.
-pub const R_TLS: u8 = 0x20;
-/// Initial-exec reference to TLS symbol.
-pub const R_TLS_IE: u8 = 0x21;
-/// Local-dynamic reference to TLS symbol.
-pub const R_TLS_LD: u8 = 0x22;
-/// Local-exec reference to TLS symbol.
-pub const R_TLS_LE: u8 = 0x23;
-/// Module reference to TLS.
-pub const R_TLSM: u8 = 0x24;
-/// Module reference to the local TLS storage.
-pub const R_TLSML: u8 = 0x25;
-/// Relative to TOC upper.
-pub const R_TOCU: u8 = 0x30;
-/// Relative to TOC lower.
-pub const R_TOCL: u8 = 0x31;
-
-unsafe_impl_pod!(
- FileHeader32,
- FileHeader64,
- AuxHeader32,
- AuxHeader64,
- SectionHeader32,
- SectionHeader64,
- SymbolBytes,
- Symbol32,
- Symbol64,
- FileAux32,
- FileAux64,
- CsectAux32,
- CsectAux64,
- FunAux32,
- FunAux64,
- ExpAux,
- BlockAux32,
- BlockAux64,
- StatAux,
- DwarfAux32,
- DwarfAux64,
- Rel32,
- Rel64,
-);
diff --git a/vendor/object/tests/integration.rs b/vendor/object/tests/integration.rs
deleted file mode 100644
index 6ebcb54..0000000
--- a/vendor/object/tests/integration.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-mod read;
-mod round_trip;
diff --git a/vendor/object/tests/parse_self.rs b/vendor/object/tests/parse_self.rs
deleted file mode 100644
index 1e7df67..0000000
--- a/vendor/object/tests/parse_self.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-#![cfg(feature = "read")]
-use object::{File, Object};
-use std::{env, fs};
-
-#[test]
-fn parse_self() {
- let exe = env::current_exe().unwrap();
- let data = fs::read(exe).unwrap();
- let object = File::parse(&*data).unwrap();
- assert!(object.entry() != 0);
- assert!(object.sections().count() != 0);
-}
-
-#[cfg(feature = "std")]
-#[test]
-fn parse_self_cache() {
- use object::read::{ReadCache, ReadRef};
- let exe = env::current_exe().unwrap();
- let file = fs::File::open(exe).unwrap();
- let cache = ReadCache::new(file);
- let data = cache.range(0, cache.len().unwrap());
- let object = File::parse(data).unwrap();
- assert!(object.entry() != 0);
- assert!(object.sections().count() != 0);
-}
diff --git a/vendor/object/tests/read/coff.rs b/vendor/object/tests/read/coff.rs
deleted file mode 100644
index dcf3b3c..0000000
--- a/vendor/object/tests/read/coff.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-use object::{pe, read, Object, ObjectSection};
-use std::fs;
-use std::path::PathBuf;
-
-#[cfg(feature = "coff")]
-#[test]
-fn coff_extended_relocations() {
- let path_to_obj: PathBuf = ["testfiles", "coff", "relocs_overflow.o"].iter().collect();
- let contents = fs::read(&path_to_obj).expect("Could not read relocs_overflow.o");
- let file =
- read::coff::CoffFile::<_>::parse(&contents[..]).expect("Could not parse relocs_overflow.o");
- let code_section = file
- .section_by_name(".text")
- .expect("Could not find .text section in relocs_overflow.o");
- match code_section.flags() {
- object::SectionFlags::Coff { characteristics } => {
- assert!(characteristics & pe::IMAGE_SCN_LNK_NRELOC_OVFL != 0)
- }
- _ => panic!("Invalid section flags flavour."),
- };
- let relocations = code_section.relocations().collect::<Vec<_>>();
- assert_eq!(relocations.len(), 65536);
-}
diff --git a/vendor/object/tests/read/mod.rs b/vendor/object/tests/read/mod.rs
deleted file mode 100644
index d60d193..0000000
--- a/vendor/object/tests/read/mod.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-#![cfg(feature = "read")]
-
-mod coff;
diff --git a/vendor/object/tests/round_trip/bss.rs b/vendor/object/tests/round_trip/bss.rs
deleted file mode 100644
index 1354fcc..0000000
--- a/vendor/object/tests/round_trip/bss.rs
+++ /dev/null
@@ -1,255 +0,0 @@
-#![cfg(all(feature = "read", feature = "write"))]
-
-use object::read::{Object, ObjectSection, ObjectSymbol};
-use object::{read, write};
-use object::{
- Architecture, BinaryFormat, Endianness, SectionKind, SymbolFlags, SymbolKind, SymbolScope,
-};
-
-#[test]
-fn coff_x86_64_bss() {
- let mut object =
- write::Object::new(BinaryFormat::Coff, Architecture::X86_64, Endianness::Little);
-
- let section = object.section_id(write::StandardSection::UninitializedData);
-
- let symbol = object.add_symbol(write::Symbol {
- name: b"v1".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- });
- object.add_symbol_bss(symbol, section, 18, 4);
-
- let symbol = object.add_symbol(write::Symbol {
- name: b"v2".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- });
- object.add_symbol_bss(symbol, section, 34, 8);
-
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"bss.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Coff);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut sections = object.sections();
-
- let bss = sections.next().unwrap();
- println!("{:?}", bss);
- let bss_index = bss.index();
- assert_eq!(bss.name(), Ok(".bss"));
- assert_eq!(bss.kind(), SectionKind::UninitializedData);
- assert_eq!(bss.size(), 58);
- assert_eq!(bss.data(), Ok(&[][..]));
-
- let section = sections.next();
- assert!(section.is_none(), "unexpected section {:?}", section);
-
- let mut symbols = object.symbols();
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("v1"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(symbol.section_index(), Some(bss_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.address(), 0);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("v2"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(symbol.section_index(), Some(bss_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.address(), 24);
-
- let symbol = symbols.next();
- assert!(symbol.is_none(), "unexpected symbol {:?}", symbol);
-}
-
-#[test]
-fn elf_x86_64_bss() {
- let mut object =
- write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
-
- let section = object.section_id(write::StandardSection::UninitializedData);
-
- let symbol = object.add_symbol(write::Symbol {
- name: b"v1".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- });
- object.add_symbol_bss(symbol, section, 18, 4);
-
- let symbol = object.add_symbol(write::Symbol {
- name: b"v2".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- });
- object.add_symbol_bss(symbol, section, 34, 8);
-
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"bss.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Elf);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut sections = object.sections();
-
- let section = sections.next().unwrap();
- println!("{:?}", section);
- assert_eq!(section.name(), Ok(""));
- assert_eq!(section.kind(), SectionKind::Metadata);
- assert_eq!(section.address(), 0);
- assert_eq!(section.size(), 0);
-
- let bss = sections.next().unwrap();
- println!("{:?}", bss);
- let bss_index = bss.index();
- assert_eq!(bss.name(), Ok(".bss"));
- assert_eq!(bss.kind(), SectionKind::UninitializedData);
- assert_eq!(bss.size(), 58);
- assert_eq!(bss.data(), Ok(&[][..]));
-
- let mut symbols = object.symbols();
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok(""));
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("v1"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(symbol.section_index(), Some(bss_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.address(), 0);
- assert_eq!(symbol.size(), 18);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("v2"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(symbol.section_index(), Some(bss_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.address(), 24);
- assert_eq!(symbol.size(), 34);
-
- let symbol = symbols.next();
- assert!(symbol.is_none(), "unexpected symbol {:?}", symbol);
-}
-
-#[test]
-fn macho_x86_64_bss() {
- let mut object = write::Object::new(
- BinaryFormat::MachO,
- Architecture::X86_64,
- Endianness::Little,
- );
-
- let section = object.section_id(write::StandardSection::UninitializedData);
-
- let symbol = object.add_symbol(write::Symbol {
- name: b"v1".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- });
- object.add_symbol_bss(symbol, section, 18, 4);
-
- let symbol = object.add_symbol(write::Symbol {
- name: b"v2".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- });
- object.add_symbol_bss(symbol, section, 34, 8);
-
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"bss.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::MachO);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut sections = object.sections();
-
- let bss = sections.next().unwrap();
- println!("{:?}", bss);
- let bss_index = bss.index();
- assert_eq!(bss.name(), Ok("__bss"));
- assert_eq!(bss.segment_name(), Ok(Some("__DATA")));
- assert_eq!(bss.kind(), SectionKind::UninitializedData);
- assert_eq!(bss.size(), 58);
- assert_eq!(bss.data(), Ok(&[][..]));
-
- let section = sections.next();
- assert!(section.is_none(), "unexpected section {:?}", section);
-
- let mut symbols = object.symbols();
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("_v1"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(symbol.section_index(), Some(bss_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.address(), 0);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("_v2"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(symbol.section_index(), Some(bss_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.address(), 24);
-
- let symbol = symbols.next();
- assert!(symbol.is_none(), "unexpected symbol {:?}", symbol);
-}
diff --git a/vendor/object/tests/round_trip/coff.rs b/vendor/object/tests/round_trip/coff.rs
deleted file mode 100644
index 6785dc3..0000000
--- a/vendor/object/tests/round_trip/coff.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-use object::read::{Object, ObjectSection};
-use object::{read, write};
-use object::{
- Architecture, BinaryFormat, Endianness, RelocationEncoding, RelocationKind, SymbolFlags,
- SymbolKind, SymbolScope,
-};
-
-#[test]
-fn reloc_overflow() {
- let mut object =
- write::Object::new(BinaryFormat::Coff, Architecture::X86_64, Endianness::Little);
- let text = object.section_id(write::StandardSection::Text);
- object.append_section_data(text, &[0; 4], 4);
- let symbol = object.add_symbol(write::Symbol {
- name: b"f".to_vec(),
- value: 0,
- size: 4,
- kind: SymbolKind::Text,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Section(text),
- flags: SymbolFlags::None,
- });
- for i in 0..0x10000 {
- object
- .add_relocation(
- text,
- write::Relocation {
- offset: i,
- size: 64,
- kind: RelocationKind::Absolute,
- encoding: RelocationEncoding::Generic,
- symbol,
- addend: 0,
- },
- )
- .unwrap();
- }
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"reloc_overflow.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Coff);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let section = object.sections().next().unwrap();
- assert_eq!(section.name(), Ok(".text"));
-
- let mut i = 0;
- for (offset, _relocation) in section.relocations() {
- assert_eq!(offset, i);
- i += 1;
- }
- assert_eq!(i, 0x10000);
-}
diff --git a/vendor/object/tests/round_trip/comdat.rs b/vendor/object/tests/round_trip/comdat.rs
deleted file mode 100644
index 7b697a0..0000000
--- a/vendor/object/tests/round_trip/comdat.rs
+++ /dev/null
@@ -1,225 +0,0 @@
-#![cfg(all(feature = "read", feature = "write"))]
-
-use object::pe;
-use object::read::{Object, ObjectComdat, ObjectSection, ObjectSymbol};
-use object::{read, write};
-use object::{
- Architecture, BinaryFormat, ComdatKind, Endianness, SectionKind, SymbolFlags, SymbolKind,
- SymbolScope,
-};
-
-#[test]
-fn coff_x86_64_comdat() {
- let mut object =
- write::Object::new(BinaryFormat::Coff, Architecture::X86_64, Endianness::Little);
-
- let (section1, offset) =
- object.add_subsection(write::StandardSection::Text, b"s1", &[0, 1, 2, 3], 4);
- object.section_symbol(section1);
- let (section2, _) =
- object.add_subsection(write::StandardSection::Data, b"s1", &[0, 1, 2, 3], 4);
- object.section_symbol(section2);
-
- let symbol = object.add_symbol(write::Symbol {
- name: b"s1".to_vec(),
- value: offset,
- size: 4,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Section(section1),
- flags: SymbolFlags::None,
- });
-
- object.add_comdat(write::Comdat {
- kind: ComdatKind::NoDuplicates,
- symbol,
- sections: vec![section1, section2],
- });
-
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"comdat.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Coff);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut sections = object.sections();
-
- let section1 = sections.next().unwrap();
- println!("{:?}", section1);
- let section1_index = section1.index();
- assert_eq!(section1.name(), Ok(".text$s1"));
- assert_eq!(section1.kind(), SectionKind::Text);
- assert_eq!(section1.address(), 0);
- assert_eq!(section1.size(), 4);
-
- let section2 = sections.next().unwrap();
- println!("{:?}", section2);
- let section2_index = section2.index();
- assert_eq!(section2.name(), Ok(".data$s1"));
- assert_eq!(section2.kind(), SectionKind::Data);
- assert_eq!(section2.address(), 0);
- assert_eq!(section2.size(), 4);
-
- let mut symbols = object.symbols();
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok(".text$s1"));
- assert_eq!(symbol.kind(), SymbolKind::Section);
- assert_eq!(
- symbol.section(),
- read::SymbolSection::Section(section1.index())
- );
- assert_eq!(
- symbol.flags(),
- SymbolFlags::CoffSection {
- selection: pe::IMAGE_COMDAT_SELECT_NODUPLICATES,
- associative_section: None
- }
- );
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok(".data$s1"));
- assert_eq!(symbol.kind(), SymbolKind::Section);
- assert_eq!(
- symbol.section(),
- read::SymbolSection::Section(section2.index())
- );
- assert_eq!(
- symbol.flags(),
- SymbolFlags::CoffSection {
- selection: pe::IMAGE_COMDAT_SELECT_ASSOCIATIVE,
- associative_section: Some(section1_index)
- }
- );
-
- let symbol = symbols.next().unwrap();
- let symbol_index = symbol.index();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("s1"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(
- symbol.section(),
- read::SymbolSection::Section(section1.index())
- );
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.address(), 0);
-
- let symbol = symbols.next();
- assert!(symbol.is_none(), "unexpected symbol {:?}", symbol);
-
- let mut comdats = object.comdats();
-
- let comdat = comdats.next().unwrap();
- println!("{:?}", comdat);
- assert_eq!(comdat.kind(), ComdatKind::NoDuplicates);
- assert_eq!(comdat.symbol(), symbol_index);
-
- let mut comdat_sections = comdat.sections();
- assert_eq!(comdat_sections.next(), Some(section1_index));
- assert_eq!(comdat_sections.next(), Some(section2_index));
- assert_eq!(comdat_sections.next(), None);
-}
-
-#[test]
-fn elf_x86_64_comdat() {
- let mut object =
- write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
-
- let (section1, offset) =
- object.add_subsection(write::StandardSection::Text, b"s1", &[0, 1, 2, 3], 4);
- let (section2, _) =
- object.add_subsection(write::StandardSection::Data, b"s1", &[0, 1, 2, 3], 4);
-
- let symbol = object.add_symbol(write::Symbol {
- name: b"s1".to_vec(),
- value: offset,
- size: 4,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Section(section1),
- flags: SymbolFlags::None,
- });
-
- object.add_comdat(write::Comdat {
- kind: ComdatKind::Any,
- symbol,
- sections: vec![section1, section2],
- });
-
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"comdat.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Elf);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut sections = object.sections();
-
- let section = sections.next().unwrap();
- println!("{:?}", section);
- assert_eq!(section.name(), Ok(""));
-
- let section = sections.next().unwrap();
- println!("{:?}", section);
- assert_eq!(section.name(), Ok(".group"));
-
- let section1 = sections.next().unwrap();
- println!("{:?}", section1);
- let section1_index = section1.index();
- assert_eq!(section1.name(), Ok(".text.s1"));
- assert_eq!(section1.kind(), SectionKind::Text);
- assert_eq!(section1.address(), 0);
- assert_eq!(section1.size(), 4);
-
- let section2 = sections.next().unwrap();
- println!("{:?}", section2);
- let section2_index = section2.index();
- assert_eq!(section2.name(), Ok(".data.s1"));
- assert_eq!(section2.kind(), SectionKind::Data);
- assert_eq!(section2.address(), 0);
- assert_eq!(section2.size(), 4);
-
- let mut symbols = object.symbols();
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok(""));
-
- let symbol = symbols.next().unwrap();
- let symbol_index = symbol.index();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("s1"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(
- symbol.section(),
- read::SymbolSection::Section(section1.index())
- );
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.address(), 0);
-
- let symbol = symbols.next();
- assert!(symbol.is_none(), "unexpected symbol {:?}", symbol);
-
- let mut comdats = object.comdats();
-
- let comdat = comdats.next().unwrap();
- println!("{:?}", comdat);
- assert_eq!(comdat.kind(), ComdatKind::Any);
- assert_eq!(comdat.symbol(), symbol_index);
-
- let mut comdat_sections = comdat.sections();
- assert_eq!(comdat_sections.next(), Some(section1_index));
- assert_eq!(comdat_sections.next(), Some(section2_index));
- assert_eq!(comdat_sections.next(), None);
-}
diff --git a/vendor/object/tests/round_trip/common.rs b/vendor/object/tests/round_trip/common.rs
deleted file mode 100644
index 74d4438..0000000
--- a/vendor/object/tests/round_trip/common.rs
+++ /dev/null
@@ -1,245 +0,0 @@
-#![cfg(all(feature = "read", feature = "write"))]
-
-use object::read::{Object, ObjectSection, ObjectSymbol};
-use object::{read, write};
-use object::{
- Architecture, BinaryFormat, Endianness, SectionKind, SymbolFlags, SymbolKind, SymbolScope,
-};
-
-#[test]
-fn coff_x86_64_common() {
- let mut object =
- write::Object::new(BinaryFormat::Coff, Architecture::X86_64, Endianness::Little);
-
- let symbol = write::Symbol {
- name: b"v1".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- };
- object.add_common_symbol(symbol, 4, 4);
-
- let symbol = write::Symbol {
- name: b"v2".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- };
- object.add_common_symbol(symbol, 8, 8);
-
- // Also check undefined symbols, which are very similar.
- let symbol = write::Symbol {
- name: b"v3".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- };
- object.add_symbol(symbol);
-
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"common.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Coff);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut symbols = object.symbols();
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("v1"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(symbol.section(), read::SymbolSection::Common);
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.address(), 0);
- assert_eq!(symbol.size(), 4);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("v2"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(symbol.section(), read::SymbolSection::Common);
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.address(), 0);
- assert_eq!(symbol.size(), 8);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("v3"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(symbol.section(), read::SymbolSection::Undefined);
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), true);
- assert_eq!(symbol.address(), 0);
- assert_eq!(symbol.size(), 0);
-
- let symbol = symbols.next();
- assert!(symbol.is_none(), "unexpected symbol {:?}", symbol);
-}
-
-#[test]
-fn elf_x86_64_common() {
- let mut object =
- write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
-
- let symbol = write::Symbol {
- name: b"v1".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- };
- object.add_common_symbol(symbol, 4, 4);
-
- let symbol = write::Symbol {
- name: b"v2".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- };
- object.add_common_symbol(symbol, 8, 8);
-
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"common.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Elf);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut symbols = object.symbols();
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok(""));
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("v1"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(symbol.section(), read::SymbolSection::Common);
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.address(), 0);
- assert_eq!(symbol.size(), 4);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("v2"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(symbol.section(), read::SymbolSection::Common);
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.address(), 0);
- assert_eq!(symbol.size(), 8);
-
- let symbol = symbols.next();
- assert!(symbol.is_none(), "unexpected symbol {:?}", symbol);
-}
-
-#[test]
-fn macho_x86_64_common() {
- let mut object = write::Object::new(
- BinaryFormat::MachO,
- Architecture::X86_64,
- Endianness::Little,
- );
-
- let symbol = write::Symbol {
- name: b"v1".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- };
- object.add_common_symbol(symbol, 4, 4);
-
- let symbol = write::Symbol {
- name: b"v2".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Data,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- };
- object.add_common_symbol(symbol, 8, 8);
-
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"common.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::MachO);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut sections = object.sections();
-
- let common = sections.next().unwrap();
- println!("{:?}", common);
- let common_index = common.index();
- assert_eq!(common.name(), Ok("__common"));
- assert_eq!(common.segment_name(), Ok(Some("__DATA")));
- assert_eq!(common.kind(), SectionKind::Common);
- assert_eq!(common.size(), 16);
- assert_eq!(common.data(), Ok(&[][..]));
-
- let section = sections.next();
- assert!(section.is_none(), "unexpected section {:?}", section);
-
- let mut symbols = object.symbols();
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("_v1"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(symbol.section_index(), Some(common_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.address(), 0);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("_v2"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(symbol.section_index(), Some(common_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.address(), 8);
-
- let symbol = symbols.next();
- assert!(symbol.is_none(), "unexpected symbol {:?}", symbol);
-}
diff --git a/vendor/object/tests/round_trip/elf.rs b/vendor/object/tests/round_trip/elf.rs
deleted file mode 100644
index 0aafadc..0000000
--- a/vendor/object/tests/round_trip/elf.rs
+++ /dev/null
@@ -1,289 +0,0 @@
-use object::read::elf::{FileHeader, SectionHeader};
-use object::read::{Object, ObjectSection, ObjectSymbol};
-use object::{
- elf, read, write, Architecture, BinaryFormat, Endianness, LittleEndian, SectionIndex,
- SectionKind, SymbolFlags, SymbolKind, SymbolScope, SymbolSection, U32,
-};
-use std::io::Write;
-
-#[test]
-fn symtab_shndx() {
- let mut object =
- write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
-
- for i in 0..0x10000 {
- let name = format!("func{}", i).into_bytes();
- let (section, offset) =
- object.add_subsection(write::StandardSection::Text, &name, &[0xcc], 1);
- object.add_symbol(write::Symbol {
- name,
- value: offset,
- size: 1,
- kind: SymbolKind::Text,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Section(section),
- flags: SymbolFlags::None,
- });
- }
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"symtab_shndx.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Elf);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- for symbol in object.symbols().skip(1) {
- assert_eq!(
- symbol.section(),
- SymbolSection::Section(SectionIndex(symbol.index().0))
- );
- }
-}
-
-#[test]
-fn aligned_sections() {
- let mut object =
- write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
-
- let text_section_id = object.add_section(vec![], b".text".to_vec(), SectionKind::Text);
- let text_section = object.section_mut(text_section_id);
- text_section.set_data(&[][..], 4096);
-
- let data_section_id = object.add_section(vec![], b".data".to_vec(), SectionKind::Data);
- let data_section = object.section_mut(data_section_id);
- data_section.set_data(&b"1234"[..], 16);
-
- let bytes = object.write().unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Elf);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut sections = object.sections();
- let _ = sections.next().unwrap();
-
- let section = sections.next().unwrap();
- assert_eq!(section.name(), Ok(".text"));
- assert_eq!(section.file_range(), Some((4096, 0)));
-
- let section = sections.next().unwrap();
- assert_eq!(section.name(), Ok(".data"));
- assert_eq!(section.file_range(), Some((4096, 4)));
-}
-
-#[cfg(feature = "compression")]
-#[test]
-fn compression_zlib() {
- use object::read::ObjectSection;
- use object::LittleEndian as LE;
-
- let data = b"test data data data";
- let len = data.len() as u64;
-
- let mut ch = object::elf::CompressionHeader64::<LE>::default();
- ch.ch_type.set(LE, object::elf::ELFCOMPRESS_ZLIB);
- ch.ch_size.set(LE, len);
- ch.ch_addralign.set(LE, 1);
-
- let mut buf = Vec::new();
- buf.write(object::bytes_of(&ch)).unwrap();
- let mut encoder = flate2::write::ZlibEncoder::new(buf, flate2::Compression::default());
- encoder.write_all(data).unwrap();
- let compressed = encoder.finish().unwrap();
-
- let mut object =
- write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
- let section = object.add_section(
- Vec::new(),
- b".debug_info".to_vec(),
- object::SectionKind::Other,
- );
- object.section_mut(section).set_data(compressed, 1);
- object.section_mut(section).flags = object::SectionFlags::Elf {
- sh_flags: object::elf::SHF_COMPRESSED.into(),
- };
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"compression.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Elf);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let section = object.section_by_name(".debug_info").unwrap();
- let uncompressed = section.uncompressed_data().unwrap();
- assert_eq!(data, &*uncompressed);
-}
-
-#[cfg(feature = "compression")]
-#[test]
-fn compression_gnu() {
- use object::read::ObjectSection;
- use std::io::Write;
-
- let data = b"test data data data";
- let len = data.len() as u32;
-
- let mut buf = Vec::new();
- buf.write_all(b"ZLIB\0\0\0\0").unwrap();
- buf.write_all(&len.to_be_bytes()).unwrap();
- let mut encoder = flate2::write::ZlibEncoder::new(buf, flate2::Compression::default());
- encoder.write_all(data).unwrap();
- let compressed = encoder.finish().unwrap();
-
- let mut object =
- write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
- let section = object.add_section(
- Vec::new(),
- b".zdebug_info".to_vec(),
- object::SectionKind::Other,
- );
- object.section_mut(section).set_data(compressed, 1);
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"compression.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Elf);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let section = object.section_by_name(".zdebug_info").unwrap();
- let uncompressed = section.uncompressed_data().unwrap();
- assert_eq!(data, &*uncompressed);
-}
-
-#[test]
-fn note() {
- let endian = Endianness::Little;
- let mut object = write::Object::new(BinaryFormat::Elf, Architecture::X86_64, endian);
-
- // Add note section with align = 4.
- let mut buffer = Vec::new();
-
- buffer
- .write(object::bytes_of(&elf::NoteHeader32 {
- n_namesz: U32::new(endian, 6),
- n_descsz: U32::new(endian, 11),
- n_type: U32::new(endian, 1),
- }))
- .unwrap();
- buffer.write(b"name1\0\0\0").unwrap();
- buffer.write(b"descriptor\0\0").unwrap();
-
- buffer
- .write(object::bytes_of(&elf::NoteHeader32 {
- n_namesz: U32::new(endian, 6),
- n_descsz: U32::new(endian, 11),
- n_type: U32::new(endian, 2),
- }))
- .unwrap();
- buffer.write(b"name2\0\0\0").unwrap();
- buffer.write(b"descriptor\0\0").unwrap();
-
- let section = object.add_section(Vec::new(), b".note4".to_vec(), SectionKind::Note);
- object.section_mut(section).set_data(buffer, 4);
-
- // Add note section with align = 8.
- let mut buffer = Vec::new();
-
- buffer
- .write(object::bytes_of(&elf::NoteHeader32 {
- n_namesz: U32::new(endian, 6),
- n_descsz: U32::new(endian, 11),
- n_type: U32::new(endian, 1),
- }))
- .unwrap();
- buffer.write(b"name1\0\0\0\0\0\0\0").unwrap();
- buffer.write(b"descriptor\0\0\0\0\0\0").unwrap();
-
- buffer
- .write(object::bytes_of(&elf::NoteHeader32 {
- n_namesz: U32::new(endian, 4),
- n_descsz: U32::new(endian, 11),
- n_type: U32::new(endian, 2),
- }))
- .unwrap();
- buffer.write(b"abc\0").unwrap();
- buffer.write(b"descriptor\0\0\0\0\0\0").unwrap();
-
- let section = object.add_section(Vec::new(), b".note8".to_vec(), SectionKind::Note);
- object.section_mut(section).set_data(buffer, 8);
-
- let bytes = &*object.write().unwrap();
-
- //std::fs::write(&"note.o", &bytes).unwrap();
-
- let header = elf::FileHeader64::parse(bytes).unwrap();
- let endian: LittleEndian = header.endian().unwrap();
- let sections = header.sections(endian, bytes).unwrap();
-
- let section = sections.section(SectionIndex(1)).unwrap();
- assert_eq!(sections.section_name(endian, section).unwrap(), b".note4");
- assert_eq!(section.sh_addralign(endian), 4);
- let mut notes = section.notes(endian, bytes).unwrap().unwrap();
- let note = notes.next().unwrap().unwrap();
- assert_eq!(note.name(), b"name1");
- assert_eq!(note.desc(), b"descriptor\0");
- assert_eq!(note.n_type(endian), 1);
- let note = notes.next().unwrap().unwrap();
- assert_eq!(note.name(), b"name2");
- assert_eq!(note.desc(), b"descriptor\0");
- assert_eq!(note.n_type(endian), 2);
- assert!(notes.next().unwrap().is_none());
-
- let section = sections.section(SectionIndex(2)).unwrap();
- assert_eq!(sections.section_name(endian, section).unwrap(), b".note8");
- assert_eq!(section.sh_addralign(endian), 8);
- let mut notes = section.notes(endian, bytes).unwrap().unwrap();
- let note = notes.next().unwrap().unwrap();
- assert_eq!(note.name(), b"name1");
- assert_eq!(note.desc(), b"descriptor\0");
- assert_eq!(note.n_type(endian), 1);
- let note = notes.next().unwrap().unwrap();
- assert_eq!(note.name(), b"abc");
- assert_eq!(note.desc(), b"descriptor\0");
- assert_eq!(note.n_type(endian), 2);
- assert!(notes.next().unwrap().is_none());
-}
-
-#[test]
-fn gnu_property() {
- gnu_property_inner::<elf::FileHeader32<Endianness>>(Architecture::I386);
- gnu_property_inner::<elf::FileHeader64<Endianness>>(Architecture::X86_64);
-}
-
-fn gnu_property_inner<Elf: FileHeader<Endian = Endianness>>(architecture: Architecture) {
- let endian = Endianness::Little;
- let mut object = write::Object::new(BinaryFormat::Elf, architecture, endian);
- object.add_elf_gnu_property_u32(
- elf::GNU_PROPERTY_X86_FEATURE_1_AND,
- elf::GNU_PROPERTY_X86_FEATURE_1_IBT | elf::GNU_PROPERTY_X86_FEATURE_1_SHSTK,
- );
-
- let bytes = &*object.write().unwrap();
-
- //std::fs::write(&"note.o", &bytes).unwrap();
-
- let header = Elf::parse(bytes).unwrap();
- assert_eq!(header.endian().unwrap(), endian);
- let sections = header.sections(endian, bytes).unwrap();
- let section = sections.section(SectionIndex(1)).unwrap();
- assert_eq!(
- sections.section_name(endian, section).unwrap(),
- b".note.gnu.property"
- );
- assert_eq!(section.sh_flags(endian).into(), u64::from(elf::SHF_ALLOC));
- let mut notes = section.notes(endian, bytes).unwrap().unwrap();
- let note = notes.next().unwrap().unwrap();
- let mut props = note.gnu_properties(endian).unwrap();
- let prop = props.next().unwrap().unwrap();
- assert_eq!(prop.pr_type(), elf::GNU_PROPERTY_X86_FEATURE_1_AND);
- assert_eq!(
- prop.data_u32(endian).unwrap(),
- elf::GNU_PROPERTY_X86_FEATURE_1_IBT | elf::GNU_PROPERTY_X86_FEATURE_1_SHSTK
- );
- assert!(props.next().unwrap().is_none());
- assert!(notes.next().unwrap().is_none());
-}
diff --git a/vendor/object/tests/round_trip/macho.rs b/vendor/object/tests/round_trip/macho.rs
deleted file mode 100644
index 1aa8156..0000000
--- a/vendor/object/tests/round_trip/macho.rs
+++ /dev/null
@@ -1,64 +0,0 @@
-use object::read::macho::MachHeader;
-use object::read::{Object, ObjectSection};
-use object::{macho, read, write, Architecture, BinaryFormat, Endianness};
-
-// Test that segment size is valid when the first section needs alignment.
-#[test]
-fn issue_286_segment_file_size() {
- let mut object = write::Object::new(
- BinaryFormat::MachO,
- Architecture::X86_64,
- Endianness::Little,
- );
-
- let text = object.section_id(write::StandardSection::Text);
- object.append_section_data(text, &[1; 30], 0x1000);
-
- let bytes = &*object.write().unwrap();
- let header = macho::MachHeader64::parse(bytes, 0).unwrap();
- let endian: Endianness = header.endian().unwrap();
- let mut commands = header.load_commands(endian, bytes, 0).unwrap();
- let command = commands.next().unwrap().unwrap();
- let (segment, _) = command.segment_64().unwrap().unwrap();
- assert_eq!(segment.vmsize.get(endian), 30);
- assert_eq!(segment.filesize.get(endian), 30);
-}
-
-// We were emitting section file alignment padding that didn't match the address alignment padding.
-#[test]
-fn issue_552_section_file_alignment() {
- let mut object = write::Object::new(
- BinaryFormat::MachO,
- Architecture::X86_64,
- Endianness::Little,
- );
-
- // The starting file offset is not a multiple of 32 (checked later).
- // Length of 32 ensures that the file offset of the end of this section is still not a
- // multiple of 32.
- let section = object.add_section(vec![], vec![], object::SectionKind::ReadOnlyDataWithRel);
- object.append_section_data(section, &vec![0u8; 32], 1);
-
- // Address is already aligned correctly, so there must not any padding,
- // even though file offset is not aligned.
- let section = object.add_section(vec![], vec![], object::SectionKind::ReadOnlyData);
- object.append_section_data(section, &vec![0u8; 1], 32);
-
- let bytes = &*object.write().unwrap();
- //std::fs::write(&"align.o", &bytes).unwrap();
- let object = read::File::parse(bytes).unwrap();
- let mut sections = object.sections();
-
- let section = sections.next().unwrap();
- let offset = section.file_range().unwrap().0;
- // Check file offset is not aligned to 32.
- assert_ne!(offset % 32, 0);
- assert_eq!(section.address(), 0);
- assert_eq!(section.size(), 32);
-
- let section = sections.next().unwrap();
- // Check there is no padding.
- assert_eq!(section.file_range(), Some((offset + 32, 1)));
- assert_eq!(section.address(), 32);
- assert_eq!(section.size(), 1);
-}
diff --git a/vendor/object/tests/round_trip/mod.rs b/vendor/object/tests/round_trip/mod.rs
deleted file mode 100644
index b92a94a..0000000
--- a/vendor/object/tests/round_trip/mod.rs
+++ /dev/null
@@ -1,686 +0,0 @@
-#![cfg(all(feature = "read", feature = "write"))]
-
-use object::read::{Object, ObjectSection, ObjectSymbol};
-use object::{read, write, SectionIndex, SubArchitecture};
-use object::{
- Architecture, BinaryFormat, Endianness, RelocationEncoding, RelocationKind, SectionKind,
- SymbolFlags, SymbolKind, SymbolScope, SymbolSection,
-};
-
-mod bss;
-mod coff;
-mod comdat;
-mod common;
-mod elf;
-mod macho;
-mod section_flags;
-mod tls;
-
-#[test]
-fn coff_any() {
- for (arch, sub_arch) in [
- (Architecture::Aarch64, None),
- (Architecture::Aarch64, Some(SubArchitecture::Arm64EC)),
- (Architecture::Arm, None),
- (Architecture::I386, None),
- (Architecture::X86_64, None),
- ]
- .iter()
- .copied()
- {
- let mut object = write::Object::new(BinaryFormat::Coff, arch, Endianness::Little);
- object.set_sub_architecture(sub_arch);
-
- object.add_file_symbol(b"file.c".to_vec());
-
- let text = object.section_id(write::StandardSection::Text);
- object.append_section_data(text, &[1; 30], 4);
-
- let func1_offset = object.append_section_data(text, &[1; 30], 4);
- assert_eq!(func1_offset, 32);
- let func1_symbol = object.add_symbol(write::Symbol {
- name: b"func1".to_vec(),
- value: func1_offset,
- size: 32,
- kind: SymbolKind::Text,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Section(text),
- flags: SymbolFlags::None,
- });
- let func2_offset = object.append_section_data(text, &[1; 30], 4);
- assert_eq!(func2_offset, 64);
- object.add_symbol(write::Symbol {
- name: b"func2_long".to_vec(),
- value: func2_offset,
- size: 32,
- kind: SymbolKind::Text,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Section(text),
- flags: SymbolFlags::None,
- });
- object
- .add_relocation(
- text,
- write::Relocation {
- offset: 8,
- size: arch.address_size().unwrap().bytes() * 8,
- kind: RelocationKind::Absolute,
- encoding: RelocationEncoding::Generic,
- symbol: func1_symbol,
- addend: 0,
- },
- )
- .unwrap();
-
- let bytes = object.write().unwrap();
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Coff);
- assert_eq!(object.architecture(), arch);
- assert_eq!(object.sub_architecture(), sub_arch);
- assert_eq!(object.endianness(), Endianness::Little);
-
- let mut sections = object.sections();
-
- let text = sections.next().unwrap();
- println!("{:?}", text);
- let text_index = text.index();
- assert_eq!(text.name(), Ok(".text"));
- assert_eq!(text.kind(), SectionKind::Text);
- assert_eq!(text.address(), 0);
- assert_eq!(text.size(), 94);
- assert_eq!(&text.data().unwrap()[..30], &[1; 30]);
- assert_eq!(&text.data().unwrap()[32..62], &[1; 30]);
-
- let mut symbols = object.symbols();
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("file.c"));
- assert_eq!(symbol.address(), 0);
- assert_eq!(symbol.kind(), SymbolKind::File);
- assert_eq!(symbol.section(), SymbolSection::None);
- assert_eq!(symbol.scope(), SymbolScope::Compilation);
- assert_eq!(symbol.is_weak(), false);
-
- let decorated_name = |name: &str| {
- if arch == Architecture::I386 {
- format!("_{name}")
- } else {
- name.to_owned()
- }
- };
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- let func1_symbol = symbol.index();
- assert_eq!(symbol.name(), Ok(decorated_name("func1").as_str()));
- assert_eq!(symbol.address(), func1_offset);
- assert_eq!(symbol.kind(), SymbolKind::Text);
- assert_eq!(symbol.section_index(), Some(text_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok(decorated_name("func2_long").as_str()));
- assert_eq!(symbol.address(), func2_offset);
- assert_eq!(symbol.kind(), SymbolKind::Text);
- assert_eq!(symbol.section_index(), Some(text_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
-
- let mut relocations = text.relocations();
-
- let (offset, relocation) = relocations.next().unwrap();
- println!("{:?}", relocation);
- assert_eq!(offset, 8);
- assert_eq!(relocation.kind(), RelocationKind::Absolute);
- assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
- assert_eq!(relocation.size(), arch.address_size().unwrap().bytes() * 8);
- assert_eq!(
- relocation.target(),
- read::RelocationTarget::Symbol(func1_symbol)
- );
- assert_eq!(relocation.addend(), 0);
-
- let map = object.symbol_map();
- let symbol = map.get(func1_offset + 1).unwrap();
- assert_eq!(symbol.address(), func1_offset);
- assert_eq!(symbol.name(), decorated_name("func1"));
- assert_eq!(map.get(func1_offset - 1), None);
- }
-}
-
-#[test]
-fn elf_x86_64() {
- let mut object =
- write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
-
- object.add_file_symbol(b"file.c".to_vec());
-
- let text = object.section_id(write::StandardSection::Text);
- object.append_section_data(text, &[1; 30], 4);
-
- let func1_offset = object.append_section_data(text, &[1; 30], 4);
- assert_eq!(func1_offset, 32);
- let func1_symbol = object.add_symbol(write::Symbol {
- name: b"func1".to_vec(),
- value: func1_offset,
- size: 32,
- kind: SymbolKind::Text,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Section(text),
- flags: SymbolFlags::None,
- });
- object
- .add_relocation(
- text,
- write::Relocation {
- offset: 8,
- size: 64,
- kind: RelocationKind::Absolute,
- encoding: RelocationEncoding::Generic,
- symbol: func1_symbol,
- addend: 0,
- },
- )
- .unwrap();
-
- let bytes = object.write().unwrap();
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Elf);
- assert_eq!(object.architecture(), Architecture::X86_64);
- assert_eq!(object.endianness(), Endianness::Little);
-
- let mut sections = object.sections();
-
- let section = sections.next().unwrap();
- println!("{:?}", section);
- assert_eq!(section.name(), Ok(""));
- assert_eq!(section.kind(), SectionKind::Metadata);
- assert_eq!(section.address(), 0);
- assert_eq!(section.size(), 0);
-
- let text = sections.next().unwrap();
- println!("{:?}", text);
- let text_index = text.index();
- assert_eq!(text.name(), Ok(".text"));
- assert_eq!(text.kind(), SectionKind::Text);
- assert_eq!(text.address(), 0);
- assert_eq!(text.size(), 62);
- assert_eq!(&text.data().unwrap()[..30], &[1; 30]);
- assert_eq!(&text.data().unwrap()[32..62], &[1; 30]);
-
- let mut symbols = object.symbols();
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok(""));
- assert_eq!(symbol.address(), 0);
- assert_eq!(symbol.kind(), SymbolKind::Null);
- assert_eq!(symbol.section_index(), None);
- assert_eq!(symbol.scope(), SymbolScope::Unknown);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), true);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("file.c"));
- assert_eq!(symbol.address(), 0);
- assert_eq!(symbol.kind(), SymbolKind::File);
- assert_eq!(symbol.section(), SymbolSection::None);
- assert_eq!(symbol.scope(), SymbolScope::Compilation);
- assert_eq!(symbol.is_weak(), false);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- let func1_symbol = symbol.index();
- assert_eq!(symbol.name(), Ok("func1"));
- assert_eq!(symbol.address(), func1_offset);
- assert_eq!(symbol.kind(), SymbolKind::Text);
- assert_eq!(symbol.section_index(), Some(text_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
-
- let mut relocations = text.relocations();
-
- let (offset, relocation) = relocations.next().unwrap();
- println!("{:?}", relocation);
- assert_eq!(offset, 8);
- assert_eq!(relocation.kind(), RelocationKind::Absolute);
- assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
- assert_eq!(relocation.size(), 64);
- assert_eq!(
- relocation.target(),
- read::RelocationTarget::Symbol(func1_symbol)
- );
- assert_eq!(relocation.addend(), 0);
-
- let map = object.symbol_map();
- let symbol = map.get(func1_offset + 1).unwrap();
- assert_eq!(symbol.address(), func1_offset);
- assert_eq!(symbol.name(), "func1");
- assert_eq!(map.get(func1_offset - 1), None);
-}
-
-#[test]
-fn elf_any() {
- for (arch, endian) in [
- (Architecture::Aarch64, Endianness::Little),
- (Architecture::Aarch64_Ilp32, Endianness::Little),
- (Architecture::Arm, Endianness::Little),
- (Architecture::Avr, Endianness::Little),
- (Architecture::Bpf, Endianness::Little),
- (Architecture::Csky, Endianness::Little),
- (Architecture::I386, Endianness::Little),
- (Architecture::X86_64, Endianness::Little),
- (Architecture::X86_64_X32, Endianness::Little),
- (Architecture::Hexagon, Endianness::Little),
- (Architecture::LoongArch64, Endianness::Little),
- (Architecture::Mips, Endianness::Little),
- (Architecture::Mips64, Endianness::Little),
- (Architecture::Msp430, Endianness::Little),
- (Architecture::PowerPc, Endianness::Big),
- (Architecture::PowerPc64, Endianness::Big),
- (Architecture::Riscv32, Endianness::Little),
- (Architecture::Riscv64, Endianness::Little),
- (Architecture::S390x, Endianness::Big),
- (Architecture::Sbf, Endianness::Little),
- (Architecture::Sparc64, Endianness::Big),
- (Architecture::Xtensa, Endianness::Little),
- ]
- .iter()
- .copied()
- {
- let mut object = write::Object::new(BinaryFormat::Elf, arch, endian);
-
- let section = object.section_id(write::StandardSection::Data);
- object.append_section_data(section, &[1; 30], 4);
- let symbol = object.section_symbol(section);
-
- object
- .add_relocation(
- section,
- write::Relocation {
- offset: 8,
- size: 32,
- kind: RelocationKind::Absolute,
- encoding: RelocationEncoding::Generic,
- symbol,
- addend: 0,
- },
- )
- .unwrap();
- if arch.address_size().unwrap().bytes() >= 8 {
- object
- .add_relocation(
- section,
- write::Relocation {
- offset: 16,
- size: 64,
- kind: RelocationKind::Absolute,
- encoding: RelocationEncoding::Generic,
- symbol,
- addend: 0,
- },
- )
- .unwrap();
- }
-
- let bytes = object.write().unwrap();
- let object = read::File::parse(&*bytes).unwrap();
- println!("{:?}", object.architecture());
- assert_eq!(object.format(), BinaryFormat::Elf);
- assert_eq!(object.architecture(), arch);
- assert_eq!(object.endianness(), endian);
-
- let mut sections = object.sections();
-
- let section = sections.next().unwrap();
- println!("{:?}", section);
- assert_eq!(section.name(), Ok(""));
- assert_eq!(section.kind(), SectionKind::Metadata);
- assert_eq!(section.address(), 0);
- assert_eq!(section.size(), 0);
-
- let data = sections.next().unwrap();
- println!("{:?}", data);
- assert_eq!(data.name(), Ok(".data"));
- assert_eq!(data.kind(), SectionKind::Data);
-
- let mut relocations = data.relocations();
-
- let (offset, relocation) = relocations.next().unwrap();
- println!("{:?}", relocation);
- assert_eq!(offset, 8);
- assert_eq!(relocation.kind(), RelocationKind::Absolute);
- assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
- assert_eq!(relocation.size(), 32);
- assert_eq!(relocation.addend(), 0);
-
- if arch.address_size().unwrap().bytes() >= 8 {
- let (offset, relocation) = relocations.next().unwrap();
- println!("{:?}", relocation);
- assert_eq!(offset, 16);
- assert_eq!(relocation.kind(), RelocationKind::Absolute);
- assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
- assert_eq!(relocation.size(), 64);
- assert_eq!(relocation.addend(), 0);
- }
- }
-}
-
-#[test]
-fn macho_x86_64() {
- let mut object = write::Object::new(
- BinaryFormat::MachO,
- Architecture::X86_64,
- Endianness::Little,
- );
-
- object.add_file_symbol(b"file.c".to_vec());
-
- let text = object.section_id(write::StandardSection::Text);
- object.append_section_data(text, &[1; 30], 4);
-
- let func1_offset = object.append_section_data(text, &[1; 30], 4);
- assert_eq!(func1_offset, 32);
- let func1_symbol = object.add_symbol(write::Symbol {
- name: b"func1".to_vec(),
- value: func1_offset,
- size: 32,
- kind: SymbolKind::Text,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Section(text),
- flags: SymbolFlags::None,
- });
- object
- .add_relocation(
- text,
- write::Relocation {
- offset: 8,
- size: 64,
- kind: RelocationKind::Absolute,
- encoding: RelocationEncoding::Generic,
- symbol: func1_symbol,
- addend: 0,
- },
- )
- .unwrap();
- object
- .add_relocation(
- text,
- write::Relocation {
- offset: 16,
- size: 32,
- kind: RelocationKind::Relative,
- encoding: RelocationEncoding::Generic,
- symbol: func1_symbol,
- addend: -4,
- },
- )
- .unwrap();
-
- let bytes = object.write().unwrap();
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::MachO);
- assert_eq!(object.architecture(), Architecture::X86_64);
- assert_eq!(object.endianness(), Endianness::Little);
-
- let mut sections = object.sections();
-
- let text = sections.next().unwrap();
- println!("{:?}", text);
- let text_index = text.index();
- assert_eq!(text.name(), Ok("__text"));
- assert_eq!(text.segment_name(), Ok(Some("__TEXT")));
- assert_eq!(text.kind(), SectionKind::Text);
- assert_eq!(text.address(), 0);
- assert_eq!(text.size(), 62);
- assert_eq!(&text.data().unwrap()[..30], &[1; 30]);
- assert_eq!(&text.data().unwrap()[32..62], &[1; 30]);
-
- let mut symbols = object.symbols();
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- let func1_symbol = symbol.index();
- assert_eq!(symbol.name(), Ok("_func1"));
- assert_eq!(symbol.address(), func1_offset);
- assert_eq!(symbol.kind(), SymbolKind::Text);
- assert_eq!(symbol.section_index(), Some(text_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
-
- let mut relocations = text.relocations();
-
- let (offset, relocation) = relocations.next().unwrap();
- println!("{:?}", relocation);
- assert_eq!(offset, 8);
- assert_eq!(relocation.kind(), RelocationKind::Absolute);
- assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
- assert_eq!(relocation.size(), 64);
- assert_eq!(
- relocation.target(),
- read::RelocationTarget::Symbol(func1_symbol)
- );
- assert_eq!(relocation.addend(), 0);
-
- let (offset, relocation) = relocations.next().unwrap();
- println!("{:?}", relocation);
- assert_eq!(offset, 16);
- assert_eq!(relocation.kind(), RelocationKind::Relative);
- assert_eq!(relocation.encoding(), RelocationEncoding::X86RipRelative);
- assert_eq!(relocation.size(), 32);
- assert_eq!(
- relocation.target(),
- read::RelocationTarget::Symbol(func1_symbol)
- );
- assert_eq!(relocation.addend(), -4);
-
- let map = object.symbol_map();
- let symbol = map.get(func1_offset + 1).unwrap();
- assert_eq!(symbol.address(), func1_offset);
- assert_eq!(symbol.name(), "_func1");
- assert_eq!(map.get(func1_offset - 1), None);
-}
-
-#[test]
-fn macho_any() {
- for (arch, subarch, endian) in [
- (Architecture::Aarch64, None, Endianness::Little),
- (
- Architecture::Aarch64,
- Some(SubArchitecture::Arm64E),
- Endianness::Little,
- ),
- (Architecture::Aarch64_Ilp32, None, Endianness::Little),
- /* TODO:
- (Architecture::Arm, None, Endianness::Little),
- */
- (Architecture::I386, None, Endianness::Little),
- (Architecture::X86_64, None, Endianness::Little),
- /* TODO:
- (Architecture::PowerPc, None, Endianness::Big),
- (Architecture::PowerPc64, None, Endianness::Big),
- */
- ]
- .iter()
- .copied()
- {
- let mut object = write::Object::new(BinaryFormat::MachO, arch, endian);
- object.set_sub_architecture(subarch);
-
- let section = object.section_id(write::StandardSection::Data);
- object.append_section_data(section, &[1; 30], 4);
- let symbol = object.section_symbol(section);
-
- object
- .add_relocation(
- section,
- write::Relocation {
- offset: 8,
- size: 32,
- kind: RelocationKind::Absolute,
- encoding: RelocationEncoding::Generic,
- symbol,
- addend: 0,
- },
- )
- .unwrap();
- if arch.address_size().unwrap().bytes() >= 8 {
- object
- .add_relocation(
- section,
- write::Relocation {
- offset: 16,
- size: 64,
- kind: RelocationKind::Absolute,
- encoding: RelocationEncoding::Generic,
- symbol,
- addend: 0,
- },
- )
- .unwrap();
- }
-
- let bytes = object.write().unwrap();
- let object = read::File::parse(&*bytes).unwrap();
- println!("{:?}", object.architecture());
- assert_eq!(object.format(), BinaryFormat::MachO);
- assert_eq!(object.architecture(), arch);
- assert_eq!(object.sub_architecture(), subarch);
- assert_eq!(object.endianness(), endian);
-
- let mut sections = object.sections();
-
- let data = sections.next().unwrap();
- println!("{:?}", data);
- assert_eq!(data.segment_name(), Ok(Some("__DATA")));
- assert_eq!(data.name(), Ok("__data"));
- assert_eq!(data.kind(), SectionKind::Data);
-
- let mut relocations = data.relocations();
-
- let (offset, relocation) = relocations.next().unwrap();
- println!("{:?}", relocation);
- assert_eq!(offset, 8);
- assert_eq!(relocation.kind(), RelocationKind::Absolute);
- assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
- assert_eq!(relocation.size(), 32);
- assert_eq!(relocation.addend(), 0);
-
- if arch.address_size().unwrap().bytes() >= 8 {
- let (offset, relocation) = relocations.next().unwrap();
- println!("{:?}", relocation);
- assert_eq!(offset, 16);
- assert_eq!(relocation.kind(), RelocationKind::Absolute);
- assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
- assert_eq!(relocation.size(), 64);
- assert_eq!(relocation.addend(), 0);
- }
- }
-}
-
-#[cfg(feature = "xcoff")]
-#[test]
-fn xcoff_powerpc() {
- for arch in [Architecture::PowerPc, Architecture::PowerPc64] {
- let mut object = write::Object::new(BinaryFormat::Xcoff, arch, Endianness::Big);
-
- object.add_file_symbol(b"file.c".to_vec());
-
- let text = object.section_id(write::StandardSection::Text);
- object.append_section_data(text, &[1; 30], 4);
-
- let func1_offset = object.append_section_data(text, &[1; 30], 4);
- assert_eq!(func1_offset, 32);
- let func1_symbol = object.add_symbol(write::Symbol {
- name: b"func1".to_vec(),
- value: func1_offset,
- size: 32,
- kind: SymbolKind::Text,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Section(text),
- flags: SymbolFlags::None,
- });
-
- object
- .add_relocation(
- text,
- write::Relocation {
- offset: 8,
- size: 64,
- kind: RelocationKind::Absolute,
- encoding: RelocationEncoding::Generic,
- symbol: func1_symbol,
- addend: 0,
- },
- )
- .unwrap();
-
- let bytes = object.write().unwrap();
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Xcoff);
- assert_eq!(object.architecture(), arch);
- assert_eq!(object.endianness(), Endianness::Big);
-
- let mut sections = object.sections();
-
- let text = sections.next().unwrap();
- println!("{:?}", text);
- let text_index = text.index().0;
- assert_eq!(text.name(), Ok(".text"));
- assert_eq!(text.kind(), SectionKind::Text);
- assert_eq!(text.address(), 0);
- assert_eq!(text.size(), 62);
- assert_eq!(&text.data().unwrap()[..30], &[1; 30]);
- assert_eq!(&text.data().unwrap()[32..62], &[1; 30]);
-
- let mut symbols = object.symbols();
-
- let mut symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("file.c"));
- assert_eq!(symbol.address(), 0);
- assert_eq!(symbol.kind(), SymbolKind::File);
- assert_eq!(symbol.section_index(), None);
- assert_eq!(symbol.scope(), SymbolScope::Compilation);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
-
- symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- let func1_symbol = symbol.index();
- assert_eq!(symbol.name(), Ok("func1"));
- assert_eq!(symbol.address(), func1_offset);
- assert_eq!(symbol.kind(), SymbolKind::Text);
- assert_eq!(symbol.section_index(), Some(SectionIndex(text_index)));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
-
- let mut relocations = text.relocations();
-
- let (offset, relocation) = relocations.next().unwrap();
- println!("{:?}", relocation);
- assert_eq!(offset, 8);
- assert_eq!(relocation.kind(), RelocationKind::Absolute);
- assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
- assert_eq!(relocation.size(), 64);
- assert_eq!(
- relocation.target(),
- read::RelocationTarget::Symbol(func1_symbol)
- );
- assert_eq!(relocation.addend(), 0);
- }
-}
diff --git a/vendor/object/tests/round_trip/section_flags.rs b/vendor/object/tests/round_trip/section_flags.rs
deleted file mode 100644
index b1ca398..0000000
--- a/vendor/object/tests/round_trip/section_flags.rs
+++ /dev/null
@@ -1,90 +0,0 @@
-#![cfg(all(feature = "read", feature = "write"))]
-
-use object::read::{Object, ObjectSection};
-use object::{read, write};
-use object::{Architecture, BinaryFormat, Endianness, SectionFlags, SectionKind};
-
-#[test]
-fn coff_x86_64_section_flags() {
- let mut object =
- write::Object::new(BinaryFormat::Coff, Architecture::X86_64, Endianness::Little);
-
- let section = object.add_section(Vec::new(), b".text".to_vec(), SectionKind::Text);
- object.section_mut(section).flags = SectionFlags::Coff {
- characteristics: object::pe::IMAGE_SCN_MEM_WRITE,
- };
-
- let bytes = object.write().unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Coff);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut sections = object.sections();
- let section = sections.next().unwrap();
- assert_eq!(section.name(), Ok(".text"));
- assert_eq!(
- section.flags(),
- SectionFlags::Coff {
- characteristics: object::pe::IMAGE_SCN_MEM_WRITE | object::pe::IMAGE_SCN_ALIGN_1BYTES,
- }
- );
-}
-
-#[test]
-fn elf_x86_64_section_flags() {
- let mut object =
- write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
-
- let section = object.add_section(Vec::new(), b".text".to_vec(), SectionKind::Text);
- object.section_mut(section).flags = SectionFlags::Elf {
- sh_flags: object::elf::SHF_WRITE.into(),
- };
-
- let bytes = object.write().unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Elf);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut sections = object.sections();
- sections.next().unwrap();
- let section = sections.next().unwrap();
- assert_eq!(section.name(), Ok(".text"));
- assert_eq!(
- section.flags(),
- SectionFlags::Elf {
- sh_flags: object::elf::SHF_WRITE.into(),
- }
- );
-}
-
-#[test]
-fn macho_x86_64_section_flags() {
- let mut object = write::Object::new(
- BinaryFormat::MachO,
- Architecture::X86_64,
- Endianness::Little,
- );
-
- let section = object.add_section(Vec::new(), b".text".to_vec(), SectionKind::Text);
- object.section_mut(section).flags = SectionFlags::MachO {
- flags: object::macho::S_ATTR_SELF_MODIFYING_CODE,
- };
-
- let bytes = object.write().unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::MachO);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut sections = object.sections();
- let section = sections.next().unwrap();
- assert_eq!(section.name(), Ok(".text"));
- assert_eq!(
- section.flags(),
- SectionFlags::MachO {
- flags: object::macho::S_ATTR_SELF_MODIFYING_CODE,
- }
- );
-}
diff --git a/vendor/object/tests/round_trip/tls.rs b/vendor/object/tests/round_trip/tls.rs
deleted file mode 100644
index 0af90bd..0000000
--- a/vendor/object/tests/round_trip/tls.rs
+++ /dev/null
@@ -1,316 +0,0 @@
-#![cfg(all(feature = "read", feature = "write"))]
-
-use object::read::{Object, ObjectSection, ObjectSymbol};
-use object::{read, write};
-use object::{
- Architecture, BinaryFormat, Endianness, RelocationEncoding, RelocationKind, SectionKind,
- SymbolFlags, SymbolKind, SymbolScope,
-};
-
-#[test]
-fn coff_x86_64_tls() {
- let mut object =
- write::Object::new(BinaryFormat::Coff, Architecture::X86_64, Endianness::Little);
-
- let section = object.section_id(write::StandardSection::Tls);
- let symbol = object.add_symbol(write::Symbol {
- name: b"tls1".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Tls,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- });
- object.add_symbol_data(symbol, section, &[1; 30], 4);
-
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"tls.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Coff);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut sections = object.sections();
-
- let section = sections.next().unwrap();
- println!("{:?}", section);
- let tls_index = section.index();
- assert_eq!(section.name(), Ok(".tls$"));
- assert_eq!(section.kind(), SectionKind::Data);
- assert_eq!(section.size(), 30);
- assert_eq!(&section.data().unwrap()[..], &[1; 30]);
-
- let mut symbols = object.symbols();
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("tls1"));
- assert_eq!(symbol.kind(), SymbolKind::Data);
- assert_eq!(symbol.section_index(), Some(tls_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
-}
-
-#[test]
-fn elf_x86_64_tls() {
- let mut object =
- write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
-
- let section = object.section_id(write::StandardSection::Tls);
- let symbol = object.add_symbol(write::Symbol {
- name: b"tls1".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Tls,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- });
- object.add_symbol_data(symbol, section, &[1; 30], 4);
-
- let section = object.section_id(write::StandardSection::UninitializedTls);
- let symbol = object.add_symbol(write::Symbol {
- name: b"tls2".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Tls,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- });
- object.add_symbol_bss(symbol, section, 31, 4);
-
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"tls.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::Elf);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut sections = object.sections();
-
- let section = sections.next().unwrap();
- println!("{:?}", section);
- assert_eq!(section.name(), Ok(""));
-
- let section = sections.next().unwrap();
- println!("{:?}", section);
- let tdata_index = section.index();
- assert_eq!(section.name(), Ok(".tdata"));
- assert_eq!(section.kind(), SectionKind::Tls);
- assert_eq!(section.size(), 30);
- assert_eq!(&section.data().unwrap()[..], &[1; 30]);
-
- let section = sections.next().unwrap();
- println!("{:?}", section);
- let tbss_index = section.index();
- assert_eq!(section.name(), Ok(".tbss"));
- assert_eq!(section.kind(), SectionKind::UninitializedTls);
- assert_eq!(section.size(), 31);
- assert_eq!(&section.data().unwrap()[..], &[]);
-
- let mut symbols = object.symbols();
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok(""));
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("tls1"));
- assert_eq!(symbol.kind(), SymbolKind::Tls);
- assert_eq!(symbol.section_index(), Some(tdata_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.size(), 30);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("tls2"));
- assert_eq!(symbol.kind(), SymbolKind::Tls);
- assert_eq!(symbol.section_index(), Some(tbss_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
- assert_eq!(symbol.size(), 31);
-}
-
-#[test]
-fn macho_x86_64_tls() {
- let mut object = write::Object::new(
- BinaryFormat::MachO,
- Architecture::X86_64,
- Endianness::Little,
- );
-
- let section = object.section_id(write::StandardSection::Tls);
- let symbol = object.add_symbol(write::Symbol {
- name: b"tls1".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Tls,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- });
- object.add_symbol_data(symbol, section, &[1; 30], 4);
-
- let section = object.section_id(write::StandardSection::UninitializedTls);
- let symbol = object.add_symbol(write::Symbol {
- name: b"tls2".to_vec(),
- value: 0,
- size: 0,
- kind: SymbolKind::Tls,
- scope: SymbolScope::Linkage,
- weak: false,
- section: write::SymbolSection::Undefined,
- flags: SymbolFlags::None,
- });
- object.add_symbol_bss(symbol, section, 31, 4);
-
- let bytes = object.write().unwrap();
-
- //std::fs::write(&"tls.o", &bytes).unwrap();
-
- let object = read::File::parse(&*bytes).unwrap();
- assert_eq!(object.format(), BinaryFormat::MachO);
- assert_eq!(object.architecture(), Architecture::X86_64);
-
- let mut sections = object.sections();
-
- let thread_data = sections.next().unwrap();
- println!("{:?}", thread_data);
- let thread_data_index = thread_data.index();
- assert_eq!(thread_data.name(), Ok("__thread_data"));
- assert_eq!(thread_data.segment_name(), Ok(Some("__DATA")));
- assert_eq!(thread_data.kind(), SectionKind::Tls);
- assert_eq!(thread_data.size(), 30);
- assert_eq!(&thread_data.data().unwrap()[..], &[1; 30]);
-
- let thread_vars = sections.next().unwrap();
- println!("{:?}", thread_vars);
- let thread_vars_index = thread_vars.index();
- assert_eq!(thread_vars.name(), Ok("__thread_vars"));
- assert_eq!(thread_vars.segment_name(), Ok(Some("__DATA")));
- assert_eq!(thread_vars.kind(), SectionKind::TlsVariables);
- assert_eq!(thread_vars.size(), 2 * 3 * 8);
- assert_eq!(&thread_vars.data().unwrap()[..], &[0; 48][..]);
-
- let thread_bss = sections.next().unwrap();
- println!("{:?}", thread_bss);
- let thread_bss_index = thread_bss.index();
- assert_eq!(thread_bss.name(), Ok("__thread_bss"));
- assert_eq!(thread_bss.segment_name(), Ok(Some("__DATA")));
- assert_eq!(thread_bss.kind(), SectionKind::UninitializedTls);
- assert_eq!(thread_bss.size(), 31);
- assert_eq!(thread_bss.data(), Ok(&[][..]));
-
- let mut symbols = object.symbols();
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- let tls1_init_symbol = symbol.index();
- assert_eq!(symbol.name(), Ok("_tls1$tlv$init"));
- assert_eq!(symbol.kind(), SymbolKind::Tls);
- assert_eq!(symbol.section_index(), Some(thread_data_index));
- assert_eq!(symbol.scope(), SymbolScope::Compilation);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- let tls2_init_symbol = symbol.index();
- assert_eq!(symbol.name(), Ok("_tls2$tlv$init"));
- assert_eq!(symbol.kind(), SymbolKind::Tls);
- assert_eq!(symbol.section_index(), Some(thread_bss_index));
- assert_eq!(symbol.scope(), SymbolScope::Compilation);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("_tls1"));
- assert_eq!(symbol.kind(), SymbolKind::Tls);
- assert_eq!(symbol.section_index(), Some(thread_vars_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- assert_eq!(symbol.name(), Ok("_tls2"));
- assert_eq!(symbol.kind(), SymbolKind::Tls);
- assert_eq!(symbol.section_index(), Some(thread_vars_index));
- assert_eq!(symbol.scope(), SymbolScope::Linkage);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), false);
-
- let symbol = symbols.next().unwrap();
- println!("{:?}", symbol);
- let tlv_bootstrap_symbol = symbol.index();
- assert_eq!(symbol.name(), Ok("__tlv_bootstrap"));
- assert_eq!(symbol.kind(), SymbolKind::Unknown);
- assert_eq!(symbol.section_index(), None);
- assert_eq!(symbol.scope(), SymbolScope::Unknown);
- assert_eq!(symbol.is_weak(), false);
- assert_eq!(symbol.is_undefined(), true);
-
- let mut relocations = thread_vars.relocations();
-
- let (offset, relocation) = relocations.next().unwrap();
- println!("{:?}", relocation);
- assert_eq!(offset, 0);
- assert_eq!(relocation.kind(), RelocationKind::Absolute);
- assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
- assert_eq!(relocation.size(), 64);
- assert_eq!(
- relocation.target(),
- read::RelocationTarget::Symbol(tlv_bootstrap_symbol)
- );
- assert_eq!(relocation.addend(), 0);
-
- let (offset, relocation) = relocations.next().unwrap();
- println!("{:?}", relocation);
- assert_eq!(offset, 16);
- assert_eq!(relocation.kind(), RelocationKind::Absolute);
- assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
- assert_eq!(relocation.size(), 64);
- assert_eq!(
- relocation.target(),
- read::RelocationTarget::Symbol(tls1_init_symbol)
- );
- assert_eq!(relocation.addend(), 0);
-
- let (offset, relocation) = relocations.next().unwrap();
- println!("{:?}", relocation);
- assert_eq!(offset, 24);
- assert_eq!(relocation.kind(), RelocationKind::Absolute);
- assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
- assert_eq!(relocation.size(), 64);
- assert_eq!(
- relocation.target(),
- read::RelocationTarget::Symbol(tlv_bootstrap_symbol)
- );
- assert_eq!(relocation.addend(), 0);
-
- let (offset, relocation) = relocations.next().unwrap();
- println!("{:?}", relocation);
- assert_eq!(offset, 40);
- assert_eq!(relocation.kind(), RelocationKind::Absolute);
- assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
- assert_eq!(relocation.size(), 64);
- assert_eq!(
- relocation.target(),
- read::RelocationTarget::Symbol(tls2_init_symbol)
- );
- assert_eq!(relocation.addend(), 0);
-}