[
  {
    "path": ".cargo/config.toml",
    "content": "[target.'cfg(all())']\nrustflags = [\n    \"-Dfuture_incompatible\",\n    \"-Dnonstandard_style\",\n    \"-Drust_2018_idioms\",\n\n    \"-Wmissing_docs\",\n    \"-Wunexpected_cfgs\",\n    \"-Wunsafe_op_in_unsafe_fn\",\n\n    \"-Wclippy::dbg_macro\",\n    \"-Wclippy::debug_assert_with_mut_call\",\n    \"-Wclippy::disallowed_types\",\n    \"-Wclippy::filter_map_next\",\n    \"-Wclippy::fn_params_excessive_bools\",\n    \"-Wclippy::imprecise_flops\",\n    \"-Wclippy::inefficient_to_string\",\n    \"-Wclippy::let_unit_value\",\n    \"-Wclippy::linkedlist\",\n    \"-Wclippy::lossy_float_literal\",\n    \"-Wclippy::macro_use_imports\",\n    \"-Wclippy::map_flatten\",\n    \"-Wclippy::needless_borrow\",\n    \"-Wclippy::needless_continue\",\n    \"-Wclippy::option_option\",\n    \"-Wclippy::ref_option_ref\",\n    \"-Wclippy::rest_pat_in_fully_bound_structs\",\n    \"-Wclippy::string_to_string\",\n    \"-Wclippy::suboptimal_flops\",\n    \"-Wclippy::verbose_file_reads\",\n#   \"-Wclippy::unused_self\", # might be interesting to explore this...\n\n    # deny explicit panic paths\n    \"-Wclippy::panic\",\n    \"-Wclippy::todo\",\n    \"-Wclippy::unimplemented\",\n    \"-Wclippy::unreachable\",\n\n    \"-Aclippy::collapsible_else_if\",\n    \"-Aclippy::collapsible_if\",\n    \"-Aclippy::too_many_arguments\",\n    \"-Aclippy::type_complexity\",\n    \"-Aclippy::bool_assert_comparison\",\n    # Primarily due to rust-lang/rust#8995\n    #\n    # If this ever gets fixed, it's be possible to rewrite complex types using\n    # inherent associated type aliases.\n    #\n    # For example, instead of writing this monstrosity:\n    #\n    #   Result<Option<MultiThreadStopReason<<Self::Arch as Arch>::Usize>>, Self::Error>\n    #\n    # ...it could be rewritten as:\n    #\n    #   type StopReason = MultiThreadStopReason<<Self::Arch as Arch>::Usize>>;\n    #   Result<Option<StopReason>, Self::Error>\n    \"-Aclippy::type_complexity\",\n    \"-Aclippy::manual_range_patterns\",\n]\n"
  },
  {
    "path": ".git-blame-ignore-revs",
    "content": "# fmt everything using imports_granularity = \"Item\"\ne2329b80c2d51ee0ab4678365a35b27b51f32235\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\nko_fi: prilik\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "### Description\n\n<!-- Please include a brief description of what is being added/changed -->\n\ne.g: This PR implements the `foobar` extension, based off the GDB documentation [here](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html).\n\nCloses #(issue number) <!-- if appropriate -->\n\n### API Stability\n\n- [ ] This PR does not require a breaking API change\n\n<!-- If it does require making a breaking API change, please elaborate why -->\n\n### Checklist\n\n<!-- CI takes care of a lot of things, but there are some things that have yet to be automated -->\n\n- Documentation\n  - [ ] Ensured any public-facing `rustdoc` formatting looks good (via `cargo doc`)\n  - [ ] (if appropriate) Added feature to \"Debugging Features\" in README.md\n- Validation\n  - [ ] Included output of running `examples/armv4t` with `RUST_LOG=trace` + any relevant GDB output under the \"Validation\" section below\n  - [ ] Included output of running `./example_no_std/check_size.sh` before/after changes under the \"Validation\" section below\n- _If implementing a new protocol extension IDET_\n  - [ ] Included a basic sample implementation in `examples/armv4t`\n  - [ ] IDET can be optimized out (confirmed via `./example_no_std/check_size.sh`)\n  - [ ] **OR** implementation requires introducing non-optional binary bloat (please elaborate under \"Description\")\n- _If upstreaming an `Arch` implementation_\n  - [ ] I have tested this code in my project, and to the best of my knowledge, it is working as intended.\n\n<!-- Oh, and if you're integrating `gdbstub` in an open-source project, do consider updating the README.md's \"Real World Examples\" section to link back to your project! -->\n\n### Validation\n\n<!-- example output, from https://github.com/daniel5151/gdbstub/pull/54 -->\n\n<details>\n<summary>GDB output</summary>\n\n```\n!!!!! EXAMPLE OUTPUT !!!!!\n\n(gdb) info mem\nUsing memory regions provided by the target.\nNum Enb Low Addr   High Addr  Attrs\n0   y  \t0x00000000 0x100000000 rw nocache\n```\n\n</details>\n\n<details>\n<summary>armv4t output</summary>\n\n```\n!!!!! EXAMPLE OUTPUT !!!!!\n\n    Finished dev [unoptimized + debuginfo] target(s) in 0.01s\n     Running `target/debug/examples/armv4t`\nloading section \".text\" into memory from [0x55550000..0x55550078]\nSetting PC to 0x55550000\nWaiting for a GDB connection on \"127.0.0.1:9001\"...\nDebugger connected from 127.0.0.1:37142\n TRACE gdbstub::gdbstub_impl > <-- +\n TRACE gdbstub::gdbstub_impl > <-- $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;xmlRegisters=i386#6a\n TRACE gdbstub::protocol::response_writer > --> $PacketSize=1000;vContSupported+;multiprocess+;QStartNoAckMode+;ReverseContinue+;ReverseStep+;QDisableRandomization+;QEnvironmentHexEncoded+;QEnvironmentUnset+;QEnvironmentReset+;QStartupWithShell+;QSetWorkingDir+;swbreak+;hwbreak+;qXfer:features:read+;qXfer:memory-map:read+#e4\n TRACE gdbstub::gdbstub_impl              > <-- +\n TRACE gdbstub::gdbstub_impl              > <-- $vMustReplyEmpty#3a\n INFO  gdbstub::gdbstub_impl              > Unknown command: vMustReplyEmpty\n TRACE gdbstub::protocol::response_writer > --> $#00\n TRACE gdbstub::gdbstub_impl              > <-- +\n TRACE gdbstub::gdbstub_impl              > <-- $QStartNoAckMode#b0\n TRACE gdbstub::protocol::response_writer > --> $OK#9a\n TRACE gdbstub::gdbstub_impl              > <-- +\n TRACE gdbstub::gdbstub_impl              > <-- $Hgp0.0#ad\n TRACE gdbstub::protocol::response_writer > --> $OK#9a\n TRACE gdbstub::gdbstub_impl              > <-- $qXfer:features:read:target.xml:0,ffb#79\n TRACE gdbstub::protocol::response_writer > --> $l<target version=\"1.0\"><!-- custom override string --><architecture>armv4t</architecture></target>#bb\n TRACE gdbstub::gdbstub_impl              > <-- $qTStatus#49\n INFO  gdbstub::gdbstub_impl              > Unknown command: qTStatus\n TRACE gdbstub::protocol::response_writer > --> $#00\n TRACE gdbstub::gdbstub_impl              > <-- $?#3f\n TRACE gdbstub::protocol::response_writer > --> $S05#b8\n TRACE gdbstub::gdbstub_impl              > <-- $qfThreadInfo#bb\n TRACE gdbstub::protocol::response_writer > --> $mp01.01#cd\n TRACE gdbstub::gdbstub_impl              > <-- $qsThreadInfo#c8\n TRACE gdbstub::protocol::response_writer > --> $l#6c\n TRACE gdbstub::gdbstub_impl              > <-- $qAttached:1#fa\nGDB queried if it was attached to a process with PID 1\n TRACE gdbstub::protocol::response_writer > --> $1#31\n TRACE gdbstub::gdbstub_impl              > <-- $Hc-1#09\n TRACE gdbstub::protocol::response_writer > --> $OK#9a\n TRACE gdbstub::gdbstub_impl              > <-- $qC#b4\n INFO  gdbstub::gdbstub_impl              > Unknown command: qC\n TRACE gdbstub::protocol::response_writer > --> $#00\n TRACE gdbstub::gdbstub_impl              > <-- $g#67\n TRACE gdbstub::protocol::response_writer > --> $00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000107856341200005555xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx10000000#66\n TRACE gdbstub::gdbstub_impl              > <-- $qfThreadInfo#bb\n TRACE gdbstub::protocol::response_writer > --> $mp01.01#cd\n TRACE gdbstub::gdbstub_impl              > <-- $qsThreadInfo#c8\n TRACE gdbstub::protocol::response_writer > --> $l#6c\n TRACE gdbstub::gdbstub_impl              > <-- $qXfer:memory-map:read::0,ffb#18\n TRACE gdbstub::protocol::response_writer > --> $l<?xml version=\"1.0\"?>\n<!DOCTYPE memory-map\n    PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\"\n            \"http://sourceware.org/gdb/gdb-memory-map.dtd\">\n<memory-map>\n    <memory type=\"ram\" start=\"0x0\" length=\"0x100000000\"/>\n</memory-map>#75\n TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61\n TRACE gdbstub::protocol::response_writer > --> $04b02de5#26\n TRACE gdbstub::gdbstub_impl              > <-- $m5554fffc,4#35\n TRACE gdbstub::protocol::response_writer > --> $00000000#7e\n TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61\n TRACE gdbstub::protocol::response_writer > --> $04b02de5#26\n TRACE gdbstub::gdbstub_impl              > <-- $m5554fffc,4#35\n TRACE gdbstub::protocol::response_writer > --> $00000000#7e\n TRACE gdbstub::gdbstub_impl              > <-- $m55550000,2#5f\n TRACE gdbstub::protocol::response_writer > --> $04b0#f6\n TRACE gdbstub::gdbstub_impl              > <-- $m5554fffe,2#35\n TRACE gdbstub::protocol::response_writer > --> $0000#7a\n TRACE gdbstub::gdbstub_impl              > <-- $m5554fffc,2#33\n TRACE gdbstub::protocol::response_writer > --> $0000#7a\n TRACE gdbstub::gdbstub_impl              > <-- $m55550000,2#5f\n TRACE gdbstub::protocol::response_writer > --> $04b0#f6\n TRACE gdbstub::gdbstub_impl              > <-- $m5554fffe,2#35\n TRACE gdbstub::protocol::response_writer > --> $0000#7a\n TRACE gdbstub::gdbstub_impl              > <-- $m5554fffc,2#33\n TRACE gdbstub::protocol::response_writer > --> $0000#7a\n TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61\n TRACE gdbstub::protocol::response_writer > --> $04b02de5#26\n TRACE gdbstub::gdbstub_impl              > <-- $m5554fffc,4#35\n TRACE gdbstub::protocol::response_writer > --> $00000000#7e\n TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61\n TRACE gdbstub::protocol::response_writer > --> $04b02de5#26\n TRACE gdbstub::gdbstub_impl              > <-- $m5554fffc,4#35\n TRACE gdbstub::protocol::response_writer > --> $00000000#7e\n TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61\n TRACE gdbstub::protocol::response_writer > --> $04b02de5#26\n TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61\n TRACE gdbstub::protocol::response_writer > --> $04b02de5#26\n TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61\n TRACE gdbstub::protocol::response_writer > --> $04b02de5#26\n TRACE gdbstub::gdbstub_impl              > <-- $m0,4#fd\n TRACE gdbstub::protocol::response_writer > --> $00000000#7e\n```\n</details>\n\n<details>\n<summary>Before/After `./example_no_std/check_size.sh` output</summary>\n\n### Before\n\n```\n!!!!! EXAMPLE OUTPUT !!!!!\n\ntarget/release/gdbstub-nostd  :\nsection               size    addr\n.interp                 28     680\n.note.gnu.build-id      36     708\n.note.ABI-tag           32     744\n.gnu.hash               36     776\n.dynsym                360     816\n.dynstr                193    1176\n.gnu.version            30    1370\n.gnu.version_r          48    1400\n.rela.dyn              408    1448\n.init                   27    4096\n.plt                    16    4128\n.plt.got                 8    4144\n.text                15253    4160\n.fini                   13   19416\n.rodata                906   20480\n.eh_frame_hdr          284   21388\n.eh_frame             1432   21672\n.init_array              8   28072\n.fini_array              8   28080\n.dynamic               448   28088\n.got                   136   28536\n.data                    8   28672\n.bss                     8   28680\n.comment                43       0\nTotal                19769\n```\n\n### After\n\n```\n!!!!! EXAMPLE OUTPUT !!!!!\n\ntarget/release/gdbstub-nostd  :\nsection               size    addr\n.interp                 28     680\n.note.gnu.build-id      36     708\n.note.ABI-tag           32     744\n.gnu.hash               36     776\n.dynsym                360     816\n.dynstr                193    1176\n.gnu.version            30    1370\n.gnu.version_r          48    1400\n.rela.dyn              408    1448\n.init                   27    4096\n.plt                    16    4128\n.plt.got                 8    4144\n.text                15253    4160\n.fini                   13   19416\n.rodata                906   20480\n.eh_frame_hdr          284   21388\n.eh_frame             1432   21672\n.init_array              8   28072\n.fini_array              8   28080\n.dynamic               448   28088\n.got                   136   28536\n.data                    8   28672\n.bss                     8   28680\n.comment                43       0\nTotal                19769\n```\n\n</details>\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "on: [push, pull_request]\n\nname: ci\n\njobs:\n  test:\n    name: clippy + tests + docs\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions-rs/toolchain@v1\n        with:\n          profile: minimal\n          toolchain: stable\n          override: true\n\n      - name: cargo clippy\n        uses: actions-rs/cargo@v1\n        with:\n          command: clippy\n          args: --workspace --tests --examples --features=std -- -D warnings\n\n      # don't forget the no_std example!\n      - name: cargo clippy (example_no_std)\n        uses: actions-rs/cargo@v1\n        with:\n          command: clippy\n          args: --manifest-path example_no_std/Cargo.toml\n\n      - name: check dyn Target delegations\n        run: ./scripts/check_target_delegation.sh\n        shell: bash\n\n      - name: cargo test\n        uses: actions-rs/cargo@v1\n        with:\n          command: test\n          args: --workspace --features=std\n\n      - name: no panics in example_no_std\n        run: ./example_no_std/dump_asm.sh\n        shell: bash\n\n      - name: cargo doc\n        run: cargo doc --workspace --features=std\n        env:\n          RUSTDOCFLAGS: \"-Dwarnings\"\n\n  rustfmt:\n    name: rustfmt (nightly)\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions-rs/toolchain@v1\n        with:\n          profile: minimal\n          toolchain: nightly\n          override: true\n          components: rustfmt\n      - name: cargo +nightly fmt\n        uses: actions-rs/cargo@v1\n        with:\n          command: fmt\n          args: --all -- --check\n      # don't forget the no_std example!\n      - name: cargo +nightly fmt (example_no_std)\n        uses: actions-rs/cargo@v1\n        with:\n          command: fmt\n          args: --manifest-path example_no_std/Cargo.toml\n"
  },
  {
    "path": ".gitignore",
    "content": "/target\n**/*.rs.bk\nCargo.lock\n\n**/.gdb_history\n# The GDB client may core dump if the target is implemented incorrectly\n**/core\n\n.vscode\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "All notable changes to this project will be documented in this file.\n\nThis project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n# 0.7.10\n\n#### New Features\n\n- `GdbStubStateMachineInner::report_stop_with_regs` - new API to pass expedited register values in the stop reply T-packet. [\\#189](https://github.com/daniel5151/gdbstub/pull/189) ([cfallin](https://github.com/cfallin))\n\n#### New Protocol Extensions\n\n- `Wasm` - (LLDB extension) Wasm-specific actions (i.e: reading Wasm call stack, and global/local/stack vars). [\\#188](https://github.com/daniel5151/gdbstub/pull/188) ([cfallin](https://github.com/cfallin))\n- `ProcessInfo` + `HostInfo` - (LLDB extension) Report key/value metadata about the host / process being debugged. [\\#190](https://github.com/daniel5151/gdbstub/pull/190) ([cfallin](https://github.com/cfallin))\n\n#### Internal Improvements\n\n- Dependencies: Switch from `paste` to `pastey`. [\\#187](https://github.com/daniel5151/gdbstub/pull/187) ([Maiux92](https://github.com/Maiux92))\n\n# 0.7.9\n\n#### New Protocol Extensions\n\n- `MultiThreadSchedulerLocking` - Support running in [Scheduler Locking](https://sourceware.org/gdb/current/onlinedocs/gdb#index-scheduler-locking-mode) mode. [\\#179](https://github.com/daniel5151/gdbstub/pull/179) ([Satar07](https://github.com/Satar07))\n- `Libraries` - List a target's loaded libraries. [\\#183](https://github.com/daniel5151/gdbstub/pull/183) ([mrexodia](https://github.com/mrexodia))\n  - _Note:_ This is a platform-agnostic version of the existing System-V/Unix-specific `LibrariesSvr4` feature, which landed in `0.7.1`\n\n#### Bugfixes\n\n- Fixed a bug in the RLE encoding where a `$` would be inserted in the packet when encoding runs of 8 chars (e.g: `00000000`). [\\#182](https://github.com/daniel5151/gdbstub/pull/182) ([mrexodia](https://github.com/mrexodia))\n\n# 0.7.8\n\n#### New Features\n\n- `HostIo` - Add HostIoErrno::{EIO,ENOSYS} variants. [\\#175](https://github.com/daniel5151/gdbstub/pull/175) ([yodel](https://github.com/yodel))\n\n# 0.7.7\n\n#### Bugfixes\n\n- Add missing `alloc::borrow::ToOwned` import when building `no_std` with `alloc`. [\\#174](https://github.com/daniel5151/gdbstub/pull/174) ([AdamKMeller](https://github.com/AdamKMeller))\n\n# 0.7.6\n\n#### New Protocol Extensions\n\n- `Flash` - Support for GDB [flash commands](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Packets.html#Packets) (e.g: `load`). [\\#172](https://github.com/daniel5151/gdbstub/pull/172) ([eulerdisk](https://github.com/eulerdisk))\n\n# 0.7.5\n\n#### New Protocol Extensions\n\n- `Tracepoints` - Basic [tracepoint extension](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Tracepoints.html) support. [\\#160](https://github.com/daniel5151/gdbstub/pull/160) ([cczetier](https://github.com/cczetier))\n  - _Note:_ Most fundamental tracepoint operations are supported, but there quite a few packets / APIs that are not yet implemented. Please see the module documentation for additional details.\n\n#### Bugfixes\n\n- Fixed case-insensitive filename collision issue [\\#166](https://github.com/daniel5151/gdbstub/issues/166) introduced in `0.7.4`\n\n# 0.7.4 (Yanked)\n\n_This version was yanked, as it introduced two files - `qTBuffer.rs` and `QTBuffer.rs` - that resulted in filename collisions when cloning `gdbstub` on case-insensitive filesystems._\n\n# 0.7.3\n\n#### New Features\n\n- Add new `core_error` feature, to have `GdbStubError` impl `core::error::Error`. [\\#154](https://github.com/daniel5151/gdbstub/pull/154) ([ultimaweapon](https://github.com/ultimaweapon))\n  - _Note:_ Out of an abundance of caution, this has been put behind a\n    feature-flag, as while `gdbstub` doesn't claim a strict MSRV at this time,\n    it seemed unwise to have a PATCH release break folks stuck on a pre-1.81\n    Rust toolchain.\n\n# 0.7.2\n\n#### Bugfixes\n\n- Add workaround for vCont packets that specify a '0' (Any) thread-id\n  - For more context, see [`e9a5296c`](https://github.com/daniel5151/gdbstub/commit/e9a5296c4d02f4b5b73d5738654a33d01afa8711)\n\n#### Internal Improvements\n\n- Various README tweaks\n- Various clippy lint fixes\n- Fix incorrect valid-addr check in armv4t example\n\n# 0.7.1\n\n#### New Protocol Extensions\n\n- `LibrariesSvr4` - List an SVR4 (System-V/Unix) target's libraries. [\\#142](https://github.com/daniel5151/gdbstub/pull/142) ([alexcrichton](https://github.com/alexcrichton))\n\n# 0.7.0\n\n#### Breaking API Changes\n\n- `stub::GdbStubError` is now an opaque `struct` with a handful of methods to extract user-defined context (as opposed to being an `enum` that directly exposed all error internals to the user).\n  - _This change will enable future versions of `gdbstub` to fearlessly improve error messages and infrastructure without making semver breaking changes. See [\\#112](https://github.com/daniel5151/gdbstub/pull/132) for more._\n- `common::Signal` is not longer an `enum`, and is instead a `struct` with a single `pub u8` field + a collection of associated constants.\n  - _As a result, yet another instance of `unsafe` could be removed from the codebase!_\n- `Arch` API:\n  - Entirely removed `single_step_behavior`. See [\\#132](https://github.com/daniel5151/gdbstub/pull/132) for details and rationale\n- `Target` APIs:\n  - `SingleThreadBase`/`MultiThreadBase`\n    - `read_addrs` now returns a `usize` instead of a `()`, allowing implementations to report cases where only a subset of memory could be read. [\\#115](https://github.com/daniel5151/gdbstub/pull/115) ([geigerzaehler](https://github.com/geigerzaehler))\n  - `HostIo`\n    - `bitflags` has been updated from `1.x` to `2.x`, affecting the type of `HostIoOpenFlags` and `HostIoOpenMode` [\\#138](https://github.com/daniel5151/gdbstub/pull/138) ([qwandor](https://github.com/qwandor))\n\n#### Internal Improvements\n\n- Reformatted codebase with nightly rustfmt using `imports_granularity = \"Item\"`\n\n# 0.6.6\n\n#### New Features\n\n- `Target::use_no_ack_mode` - toggle support for for activating \"no ack mode\" [\\#135](https://github.com/daniel5151/gdbstub/pull/135) ([bet4it](https://github.com/bet4it))\n\n# 0.6.5\n\n#### New Protocol Extensions\n\n- `ExtendedMode > CurrentActivePid` - Support reporting a non-default active PID [\\#133](https://github.com/daniel5151/gdbstub/pull/129)\n  - Required to fix `vAttach` behavior (see Bugfixes section below)\n\n#### Bugfixes\n\n- Fix for targets with no active threads [\\#127](https://github.com/daniel5151/gdbstub/pull/127) ([xobs](https://github.com/xobs))\n- Fix `vAttach` behavior when switching between multiple processes [\\#129](https://github.com/daniel5151/gdbstub/pull/129) ([xobs](https://github.com/xobs)), and [\\#133](https://github.com/daniel5151/gdbstub/pull/129)\n- Minor doc fixes\n\n# 0.6.4\n\n#### Bugfixes\n\n- Avoid truncating `X` packets that contain `:` and `,` as part of the payload. [\\#121](https://github.com/daniel5151/gdbstub/pull/121) ([709924470](https://github.com/709924470))\n\n#### Internal Improvements\n\n- Various README tweaks\n- Remove some `unsafe` code\n- CI improvements\n  - Run no-panic checks on `example_no_std`\n  - Run CI on docs\n\n# 0.6.3\n\n#### New Features\n\n- `SingleRegisterAccess`: Support reporting unavailable regs [\\#107](https://github.com/daniel5151/gdbstub/pull/107) ([ptosi](https://github.com/ptosi))\n\n# 0.6.2\n\n#### New Protocol Extensions\n\n- `MultiThreadBase > ThreadExtraInfo` - Provide extra information per-thread. [\\#106](https://github.com/daniel5151/gdbstub/pull/106) ([thefaxman](https://github.com/thefaxman))\n- `LldbRegisterInfo` - (LLDB specific) Report register information in the LLDB format. [\\#103](https://github.com/daniel5151/gdbstub/pull/103) ([jawilk](https://github.com/jawilk))\n  - This information can be statically included as part of the `Arch` implemention, or dynamically reported via the `LldbRegisterInfoOverride` IDET.\n\n#### Bugfixes\n\n- Report thread ID in response to `?` packet. [\\#105](https://github.com/daniel5151/gdbstub/pull/105) ([thefaxman](https://github.com/thefaxman))\n\n#### Internal Improvements\n\n- Tweak enabled clippy lints\n- Added a light dusting of `#[inline]` across the packet parsing code, crunching the code down even further\n- Expanded on \"no-panic guarantee\" docs\n\n# 0.6.1\n\n#### New Features\n\n- add LLDB-specific HostIoOpenFlags [\\#100](https://github.com/daniel5151/gdbstub/pull/100) ([mrk](https://github.com/mrk-its))\n\n# 0.6.0\n\nAfter over a half-year of development, `gdbstub` 0.6 has finally been released!\n\nThis massive release delivers a slew of new protocol extensions, internal improvements, and key API improvements. Some highlights include:\n\n- A new _non-blocking_ `GdbStubStateMachine` API, enabling `gdbstub` to integrate nicely with async event loops!\n  - Moreover, on `no_std` platforms, this new API enables `gdbstub` to be driven directly via breakpoint/serial interrupt handlers!\n  - This API is already being used in several Rust kernel projects, such as [`vmware-labs/node-replicated-kernel`](https://github.com/vmware-labs/node-replicated-kernel/tree/4326704/kernel/src/arch/x86_64/gdb) and [`betrusted-io/xous-core`](https://github.com/betrusted-io/xous-core/blob/7d3d710/kernel/src/debug/gdb_server.rs) to enable bare-metal, in-kernel debugging.\n- `gdbstub` is now entirely **panic free** in release builds!\n  - \\* subject to `rustc`'s compiler optimizations\n  - This was a pretty painstaking effort, but the end result is a substantial reduction in binary size on `no_std` platforms.\n- Tons of new and exciting protocol extensions, including but not limited to:\n  - Support for remote file I/O (reading/writing files to the debug target)\n  - Fetching remote memory maps\n  - Catching + reporting syscall entry/exit conditions\n  - ...and many more!\n- A new license: `gdbstub` is licensed under MIT OR Apache-2.0\n\nSee the [changelog](https://github.com/daniel5151/gdbstub/blob/dev/0.6/CHANGELOG.md) for a comprehensive rundown of all the new features.\n\nWhile this release does come with quite a few breaking changes, the core IDET-based `Target` API has remained much the same, which should make porting code over from 0.5.x to 0.6 pretty mechanical. See the [`transition_guide.md`](./docs/transition_guide.md) for guidance on upgrading from `0.5.x` to `0.6`.\n\nAnd as always, a huge shoutout to the folks who contributed PRs, Issues, and ideas to `gdbstub` - this release wouldn't have been possible without you! Special shoutouts to [gz](https://github.com/gz) and [xobs](https://github.com/xobs) for helping me test and iterate on the new bare-metal state machine API, and [bet4it](https://github.com/bet4it) for pointing out and implementing many useful API improvements and internal refactors.\n\nCheers!\n\n#### New Features\n\n- The new `GdbStubStateMachine` API gives users the power and flexibility to integrate `gdbstub` into their project-specific event loop infrastructure.\n  - e.g: A global instance of `GdbStubStateMachine` can be driven directly from bare-metal interrupt handlers in `no_std` environments\n  - e.g: A project using `async`/`await` can wrap `GdbStubStateMachine` in a task, yielding execution while waiting for the target to resume / new data to arrive down the `Connection`\n- Removed all panicking code from `gdbstub`\n  - See the [commit message](https://github.com/daniel5151/gdbstub/commit/ecbbaf72e01293b410ef3bc5970d18aa81e45599) for more details on how this was achieved.\n- Introduced strongly-typed enum for protocol defined signal numbers (instead of using bare `u8`s)\n- Added basic feature negotiation to support clients that don't support `multiprocess+` extensions.\n- Relicensed `gdbstub` under MIT OR Apache-2.0 [\\#68](https://github.com/daniel5151/gdbstub/pull/68)\n- Added several new \"guard rails\" to avoid common integration footguns:\n  - `Target::guard_rail_implicit_sw_breakpoints` - guards against the GDB client silently overriding target instructions with breakpoints if `SwBreakpoints` hasn't been implemented.\n  - `Target::guard_rail_single_step_gdb_behavior` - guards against a GDB client bug where support for single step may be required / ignored on certain platforms (e.g: required on x86, ignored on MIPS)\n- Added several new \"toggle switches\" to enable/disable parts of the protocol (all default to `true`)\n  - `Target::use_x_upcase_packet` - toggle support for the more efficient `X` memory write packet\n  - `Target::use_resume_stub` - toggle `gdbstub`'s built-in \"stub\" resume handler that returns `SIGRAP` if a target doesn't implement support for resumption\n  - `Target::use_rle` - toggle whether outgoing packets are Run Length Encoded (RLE)\n\n#### New Protocol Extensions\n\n- `MemoryMap` - Get memory map XML file from the target. [\\#54](https://github.com/daniel5151/gdbstub/pull/54) ([Tiwalun](https://github.com/Tiwalun))\n- `CatchSyscalls` - Enable and disable catching syscalls from the inferior process. [\\#57](https://github.com/daniel5151/gdbstub/pull/57) ([mchesser](https://github.com/mchesser))\n- `HostIo` - Perform I/O operations on host. [\\#66](https://github.com/daniel5151/gdbstub/pull/66) ([bet4it](https://github.com/bet4it))\n  - Support for all Host I/O operations: `open`, `close`, `pread`, `pwrite`, `fstat`, `unlink`, `readlink`, `setfs`\n- `ExecFile` - Get full absolute path of the file that was executed to create a process running on the remote system. [\\#69](https://github.com/daniel5151/gdbstub/pull/69) ([bet4it](https://github.com/bet4it))\n- `Auxv` - Access the target’s auxiliary vector. [\\#86](https://github.com/daniel5151/gdbstub/pull/86) ([bet4it](https://github.com/bet4it))\n- Implement `X` packet - More efficient bulk-write to memory (superceding the `M` packet). [\\#82](https://github.com/daniel5151/gdbstub/pull/82) ([gz](https://github.com/gz))\n\n#### Breaking API Changes\n\n- `Connection` API:\n  - Removed the `read` and `peek` methods from `Connection`\n    - These have been moved to the new `ConnectionExt` trait, which is used in the new `GdbStub::run_blocking` API\n- `Arch` API:\n  - Dynamic read_register + RegId support. [\\#85](https://github.com/daniel5151/gdbstub/pull/85) ([bet4it](https://github.com/bet4it))\n- `Target` APIs:\n  - prefix all IDET methods with `support_`\n    - _makes it far easier to tell at-a-glance whether a method is an IDET, or an actual handler method.\n  - Introduce strongly-typed enum for protocol defined signal numbers (instead of using bare `u8`s)\n  - `Base` API:\n    - Make single-stepping optional [\\#92](https://github.com/daniel5151/gdbstub/pull/92)\n    - Remove `GdbInterrupt` type (interrupt handling lifted to higher-level APIs)\n    - Remove `ResumeAction` type (in favor of separate methods for various resume types)\n  - `Breakpoints` API:\n    - `HwWatchpoint`: Plumb watchpoint `length` parameter to public API\n  - `TargetXml` API:\n    - Support for `<xi:include>` in target.xml, which required including the `annex` parameter in the handler method.\n    - `annex` is set to `b\"target.xml\"` on the fist call, though it may be set to other values in subsequent calls if `<xi:include>` is being used.\n  - Pass `PacketBuf`-backed `&mut [u8]` as a response buffer to various APIs [\\#72](https://github.com/daniel5151/gdbstub/pull/72) ([bet4it](https://github.com/bet4it))\n    - Improvement over the callback-based approach.\n    - This change is possible thanks to a clause in the GDB spec that specifies that responses will never exceed the size of the `PacketBuf`.\n    - Also see [\\#70](https://github.com/daniel5151/gdbstub/pull/70), which tracks some other methods that might be refactored to use this approach in the future.\n\n#### Internal Improvements\n\n- Documentation\n  - Fix crates.io badges [\\#71](https://github.com/daniel5151/gdbstub/pull/71) ([atouchet](https://github.com/atouchet))\n  - Add `uhyve` to real-world examples [\\#73](https://github.com/daniel5151/gdbstub/pull/73) ([mkroening](https://github.com/mkroening))\n- Use stable `clippy` in CI\n- Enable logging for responses with only alloc [\\#78](https://github.com/daniel5151/gdbstub/pull/78) ([gz](https://github.com/gz))\n- Lots of internal refactoring and cleanup\n\n# 0.5.0\n\nWhile the overall structure of the API has remained the same, `0.5.0` does introduce a few breaking API changes that require some attention. That being said, it should not be a difficult migration, and updating to `0.5.0` from `0.4` shouldn't take more than 10 mins of refactoring.\n\nCheck out [`transition_guide.md`](./docs/transition_guide.md) for guidance on upgrading from `0.4.x` to `0.5`.\n\n#### New Features\n\n- Implement Run-Length-Encoding (RLE) on outgoing packets\n  - _This significantly cuts down on the data being transferred over the wire when reading from registers/memory_\n- Add target-specific `kind: Arch::BreakpointKind` parameters to the Breakpoint API\n  - _While emulated systems typically implement breakpoints by pausing execution once the PC hits a certain value, \"real\" systems typically need to patch the instruction stream with a breakpoint instruction. On systems with variable-sized instructions, this `kind` parameter specifies the size of the instruction that should be injected._\n- Implement `ResumeAction::{Step,Continue}WithSignal`\n- Added the `Exited(u8)`, `Terminated(u8)`, and `ReplayLog(\"begin\"|\"end\")` stop reasons.\n- Added `DisconnectReason::Exited(u8)` and `DisconnectReason::Terminated(u8)`.\n- Reworked the `MultiThreadOps::resume` API to be significantly more ergonomic and efficient\n  - See the [transition guide](https://github.com/daniel5151/gdbstub/blob/master/docs/transition_guide.md#new-multithreadopsresume-api) for more details.\n\n#### New Protocol Extensions\n\n- `{Single,Multi}ThreadReverse{Step,Continue}` - Support for reverse-step and reverse-continue. [\\#48](https://github.com/daniel5151/gdbstub/pull/48 ) ([DrChat](https://github.com/DrChat))\n- `{Single,Multi}ThreadRangeStepping` - Optional optimized [range stepping](https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#range-stepping) support.\n\n#### Breaking Arch Changes\n\n- **`gdbstub::arch` has been moved into a separate `gdbstub_arch` crate**\n  - _See [\\#45](https://github.com/daniel5151/gdbstub/issues/45) for details on why this was done._\n- (x86) Break GPRs & SRs into individual fields/variants [\\#34](https://github.com/daniel5151/gdbstub/issues/34)\n\n#### Breaking API Changes\n\n- Base Protocol Refactors\n  - Reworked the `MultiThreadOps::resume` API\n  - Added a wrapper around the raw `check_gdb_interrupt` callback, hiding the underlying implementation details\n  - Extracted base protocol single-register access methods (`{read,write}_register`) into separate `SingleRegisterAccess` trait\n    - _These are optional GDB protocol methods, and as such, should be modeled as IDETs_\n- Protocol Extension Refactors\n  - Consolidated the `{Hw,Sw}Breakpoints/Watchpoints` IDETs under a single `Breakpoints` IDET + sub-IDETs\n  - Added new arch-specific `kind: Arch::BreakpointKind` parameter to `add_{hw,sw}_breakpoint` methods\n  - Renamed `target::ext::extended_mod::ConfigureASLR{Ops}` to `ConfigureAslr{Ops}` (clippy::upper_case_acronyms)\n- Added `{Step,Continue}WithSignal` variants to `target::ext::base::ResumeAction`\n- Trait Changes\n  - `arch::Arch`: Added `type BreakpointKind`. Required to support arch-specific breakpoint kinds\n  - `arch::Arch`: (very minor) Added [`num_traits::FromPrimitive`](https://docs.rs/num/0.4.0/num/traits/trait.FromPrimitive.html) bound to `Arch::Usize`\n  - `arch::Registers`: Added `type ProgramCounter` and associated `fn pc(&self) -> Self::ProgramCounter` method. Added preemptively in anticipation of future GDB Agent support\n- Removed the `Halted` stop reason (more accurate to simply return `{Exited|Terminated}(SIGSTOP)` instead).\n- Removed the `Halted` disconnect reason (replaced with the `Exited` and `Terminated` stop reasons instead).\n- Removed the implicit `ExtendedMode` attached PID tracking when `alloc` was available. See [`23b56038`](https://github.com/daniel5151/gdbstub/commit/23b56038) rationale behind this change.\n\n\n#### Internal Improvements\n\n- Split monolithic `GdbStubImpl` implementation into separate files (by protocol extension)\n- Finally rewrite + optimize `GdbStubImpl::do_vcont`, along with streamlining its interactions with the legacy `s` and `c` packets\n- Sprinkle more IDET-based dead code elimination hints (notably wrt. stop reasons)\n- Remove the default `self.current_mem_tid` hack, replacing it with a much more elegant solution\n- Packet Parser improvements\n  - Remove last remaining bit of UTF-8 related code\n  - Eliminate as much panicking bounds-checking code as possible\n  - support efficient parsing of packets that are parsed differently depending on active protocol extension (namely, the breakpoint packets)\n  - (currently unused) Zero-cost support for parsing `Z` and `z` packets with embedded agent bytecode expressions\n- Use intra-doc links whenever possible\n\n#### Bugfixes\n\n- Fix `RiscvRegId` for `arch::riscv::Riscv64` [\\#46](https://github.com/daniel5151/gdbstub/issues/46) ([fzyz999](https://github.com/fzyz999))\n\n# 0.4.5\n\n#### New Protocol Extensions\n\n- `TargetDescriptionXmlOverride` - Allow targets to override the target description XML file (`target.xml`) specified by `Target::Arch::target_description_xml`. This is useful in cases where a `Target` is expected to be generic over multiple architectures. [\\#43](https://github.com/daniel5151/gdbstub/pull/43) (with help from [DrChat](https://github.com/DrChat))\n\n# 0.4.4\n\n#### Bugfixes\n\n- use `write!` instead of `writeln!` in `output!` macro [\\#41](https://github.com/daniel5151/gdbstub/issues/41)\n\n# 0.4.3\n\n#### New Arch Implementations\n\n- Implement `RegId` for Mips/Mips64 [\\#38](https://github.com/daniel5151/gdbstub/pull/38) ([starfleetcadet75](https://github.com/starfleetcadet75))\n- Implement `RegId` for MSP430 [\\#38](https://github.com/daniel5151/gdbstub/pull/38) ([starfleetcadet75](https://github.com/starfleetcadet75))\n\n# 0.4.2\n\n#### Packaging\n\n- Exclude test object files from package [\\#37](https://github.com/daniel5151/gdbstub/pull/37) ([keiichiw](https://github.com/keiichiw))\n\n# 0.4.1\n\n#### New Arch Implementations\n\n- Implement `RegId` for x86/x86_64 [\\#34](https://github.com/daniel5151/gdbstub/pull/34) ([keiichiw](https://github.com/keiichiw))\n\n#### Bugfixes\n\n- Switch fatal error signal from `T06` to `S05`,\n- specify cfg-if 0.1.10 or later [\\#33](https://github.com/daniel5151/gdbstub/pull/33) ([keiichiw](https://github.com/keiichiw))\n  - `cargo build` fails if cfg-if is 0.1.9 or older\n\n#### Internal Improvements\n\n- Don't hard-code u64 when parsing packets (use big-endian byte arrays + late conversion to `Target::Arch::Usize`).\n\n# 0.4.0\n\nThis version includes a _major_ API overhaul, alongside a slew of new features and general improvements. While updating to `0.4.0` will require some substantial code modifications, it's well worth the effort, as `0.4.0` is the safest, leanest, and most featureful release of `gdbstub` yet!\n\nFun fact: Even after adding a _bunch_ of new features and bug-fixes, the in-tree `example_no_std` has remained just as small! The example on the `semver-fix-0.2.2` branch is `20251` bytes, while the example on `0.4.0` is `20246` bytes.\n\n#### Breaking API Changes\n\n- Rewrite the `Target` API in terms of \"Inlineable Dyn Extension Traits\" (IDETs)\n  - _By breaking up `Target` into smaller pieces which can be mixed-and-matched, it not only makes it easier to get up-and-running with `gdbstub`, but it also unlocks a lot of awesome internal optimizations:_\n    - Substantially reduces binary-size footprint by guaranteeing dead-code-elimination of parsing/handling unimplemented GDB protocol features.\n    - Compile-time enforcement that certain groups of methods are implemented in-tandem (e.g: `add_sw_breakpoint` and `remove_sw_breakpoint`).\n- Update the `Target` API with support for non-fatal error handling.\n  - _The old approach of only allowing \\*fatal\\* errors was woefully inadequate when dealing with potentially fallible operations such as reading from unauthorized memory (which GDB likes to do a bunch), or handling non-fatal `std::io::Error` that occur as a result of `ExtendedMode` operations. The new `TargetResult`/`TargetError` result is much more robust, and opens to door to supporting additional error handling extensions (such as LLDB's ASCII Errors)._\n- Update the `Connection` trait with new methods (`flush` - required, `write_all`, `on_session_start`)\n- Lift `Registers::RegId` to `Arch::RegId`, and introduce new temporary `RegIdImpl` solution for avoiding breaking API changes due to new `RegId` implementations (see [\\#29](https://github.com/daniel5151/gdbstub/pull/29))\n- Mark various `RegId` enums as `#[non_exhaustive]`, allowing more registers to be added if need be.\n- Error types are now marked as `#[non_exhaustive]`.\n\n#### New Protocol Extensions\n\n- `ExtendedMode` - Allow targets to run new processes / attach to existing processes / restart execution.\n  - Includes support for `set disable-randomization`, `set environment`, `set startup-with-shell`, and `set cwd` and `cd`.\n- `SectionOffsets` - Get section/segment relocation offsets from the target. [\\#30](https://github.com/daniel5151/gdbstub/pull/30) ([mchesser](https://github.com/mchesser))\n  - Uses the `qOffsets` packet under-the-hood.\n\n#### Bugfixes\n\n- Fix issues related to selecting the incorrect thread after hitting a breakpoint in multi-threaded targets.\n- Ensure that `set_nodelay` is set when using a `TcpStream` as a `Connection` (via the new `Connection::on_session_start` API)\n  - _This should result in a noticeable performance improvement when debugging over TCP._\n\n#### Internal Improvements\n\n- Removed `btou` dependency.\n- Removed all `UTF-8` aware `str` handling code.\n  - _GDB uses a pure ASCII protocol, so including code to deal with UTF-8 resulted in unnecessary binary bloat._\n\n# 0.3.0 (formerly 0.2.2)\n\nThis version contains a few minor breaking changes from `0.2.1`. These are only surface-level changes, and can be fixed with minimal effort.\n\nVersion `0.3.0` is identical to the yanked version `0.2.2`, except that it adheres to `cargo`'s [modified SemVer rule](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field) which states that the pre-`0.x.y` breaking changes should still bump the minor version.\n\nThanks to [h33p](https://github.com/h33p) for reporting this issue ([\\#27](https://github.com/daniel5151/gdbstub/issues/27))\n\n#### Breaking API Changes\n\n- Update `Target::resume` API to replace raw `&mut dyn Iterator` with a functionally identical concrete `Actions` iterator.\n- Mark the `StopReason` enum as `#[non_exhaustive]`, allowing further types to be added without being considered as an API breaking change.\n\n#### New Protocol Extensions\n\n- Add `Target::read/write_register` support (to support single register accesses) [\\#22](https://github.com/daniel5151/gdbstub/pull/22) ([thomashk0](https://github.com/thomashk0))\n- Add `StopReason::Signal(u8)` variant, to send arbitrary signal codes [\\#19](https://github.com/daniel5151/gdbstub/pull/19) ([mchesser](https://github.com/mchesser))\n\n#### New Arch Implementations\n\n- Add partial RISC-V support (only integer ISA at the moment) [\\#21](https://github.com/daniel5151/gdbstub/pull/21) ([thomashk0](https://github.com/thomashk0))\n- Add i386 (x86) support [\\#23](https://github.com/daniel5151/gdbstub/pull/23) ([jamcleod](https://github.com/jamcleod))\n- Add 32-bit PowerPC support [\\#25](https://github.com/daniel5151/gdbstub/pull/25) ([jamcleod](https://github.com/jamcleod))\n\n# 0.2.1\n\n#### New Arch Implementations\n\n- Add x86_64 support [\\#11](https://github.com/daniel5151/gdbstub/pull/11) ([jamcleod](https://github.com/jamcleod))\n- Add Mips and Mips64 support [\\#13](https://github.com/daniel5151/gdbstub/pull/13) ([starfleetcadet75](https://github.com/starfleetcadet75))\n\n#### Internal Improvements\n\n- Documentation improvements\n  - Document PC adjustment requirements in `Target::resume`\n  - Add docs on handling non-fatal invalid memory reads/writes in `Target::read/write_addrs`.\n\n# 0.2.0\n\n_start of changelog_\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[package]\nname = \"gdbstub\"\ndescription = \"An implementation of the GDB Remote Serial Protocol in Rust\"\nauthors = [\"Daniel Prilik <danielprilik@gmail.com>\"]\nversion = \"0.7.10\"\nlicense = \"MIT OR Apache-2.0\"\nedition = \"2018\"\nreadme = \"README.md\"\ndocumentation = \"https://docs.rs/gdbstub\"\nhomepage = \"https://github.com/daniel5151/gdbstub\"\nrepository  = \"https://github.com/daniel5151/gdbstub\"\nkeywords = [\"gdb\", \"emulation\", \"no_std\", \"debugging\"]\ncategories = [\"development-tools::debugging\", \"embedded\", \"emulators\", \"network-programming\", \"no-std\"]\nexclude = [\"examples/**/*.elf\", \"examples/**/*.o\"]\n\n[dependencies]\nbitflags = \"2.3.1\"\ncfg-if = \"1.0\"\nlog = \"0.4\"\nmanaged = { version = \"0.8\", default-features = false }\nnum-traits = { version = \"0.2\", default-features = false }\npastey = \"0.2.1\"\n\n[dev-dependencies]\ngdbstub_arch = { path = \"./gdbstub_arch/\" }\n\narmv4t_emu = \"0.1\"\npretty_env_logger = \"0.4\"\ngoblin = \"0.4\"\n\n[features]\ndefault = [\"std\", \"trace-pkt\"]\nalloc = [\"managed/alloc\"]\nstd = [\"alloc\"]\ntrace-pkt = [\"alloc\"]\nparanoid_unsafe = []\ncore_error = []\n\n# INTERNAL: enables the `__dead_code_marker!` macro.\n# used as part of the `scripts/test_dead_code_elim.sh`\n__dead_code_marker = []\n\n[[example]]\nname = \"armv4t\"\nrequired-features = [\"std\"]\n\n[[example]]\nname = \"armv4t_multicore\"\nrequired-features = [\"std\"]\n\n[workspace]\nmembers = [\"gdbstub_arch\"]\nexclude = [\"example_no_std\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "gdbstub is dual-licensed under either\n\n* MIT License (docs/LICENSE-MIT or http://opensource.org/licenses/MIT)\n* Apache License, Version 2.0 (docs/LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)\n\nat your option.\n"
  },
  {
    "path": "README.md",
    "content": "# gdbstub\n\n[![](https://img.shields.io/crates/v/gdbstub.svg)](https://crates.io/crates/gdbstub)\n[![](https://docs.rs/gdbstub/badge.svg)](https://docs.rs/gdbstub)\n[![](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)](./LICENSE)\n\nAn ergonomic, featureful, and easy-to-integrate implementation of the [GDB Remote Serial Protocol](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html#Remote-Protocol) in Rust, with _no-compromises_ `#![no_std]` support.\n\n`gdbstub`  makes it easy to integrate powerful guest debugging support to your emulator / hypervisor / debugger / embedded project. By implementing just a few basic methods of the [`gdbstub::Target`](https://docs.rs/gdbstub/latest/gdbstub/target/ext/base/singlethread/trait.SingleThreadBase.html) trait, you can have a rich GDB debugging session up and running in no time!\n\n`gdbstub`'s API makes extensive use of a technique called [**Inlineable Dyn Extension Traits**](#zero-overhead-protocol-extensions) (IDETs) to expose fine-grained, zero-cost control over enabled GDB protocol features _without_ relying on compile-time features flags. Aside from making it effortless to toggle enabled protocol features, IDETs also ensure that any unimplemented features are guaranteed to be dead-code-eliminated in release builds!\n\n**If you're looking for a quick snippet of example code to see what a featureful `gdbstub` integration might look like, check out [examples/armv4t/gdb/mod.rs](https://github.com/daniel5151/gdbstub/blob/master/examples/armv4t/gdb/mod.rs)**\n\n-   [Documentation (gdbstub)](https://docs.rs/gdbstub)\n-   [Documentation (gdbstub_arch)](https://docs.rs/gdbstub_arch)\n-   [Changelog](CHANGELOG.md)\n-   [0.5 to 0.6 Transition Guide](docs/transition_guide.md)\n\nWhy use `gdbstub`?\n\n-   **Excellent Ergonomics**\n    -   Instead of simply exposing the underlying GDB protocol \"warts and all\", `gdbstub` tries to abstract as much of the raw GDB protocol details from the user.\n        -   Instead of having to dig through [obscure XML files deep the GDB codebase](https://github.com/bminor/binutils-gdb/tree/master/gdb/features) just to read/write from CPU/architecture registers, `gdbstub` comes with a community-curated collection of [built-in architecture definitions](https://docs.rs/gdbstub_arch) for most popular platforms!\n        -   Organizes GDB's countless optional protocol extensions into a coherent, understandable, and type-safe hierarchy of traits.\n        -   Automatically handles client/server protocol feature negotiation, without needing to micro-manage the specific [`qSupported` packet](https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#qSupported) response.\n    -   `gdbstub` makes _extensive_ use of Rust's powerful type system + generics to enforce protocol invariants at compile time, minimizing the number of tricky protocol details end users have to worry about.\n    -   Using a novel technique called [**Inlineable Dyn Extension Traits**](#zero-overhead-protocol-extensions) (IDETs), `gdbstub` enables fine-grained control over active protocol extensions _without_ relying on clunky `cargo` features or the use of `unsafe` code!\n-   **Easy to Integrate**\n    -   `gdbstub`'s API is designed to be a \"drop in\" solution when you want to add debugging support into a project, and shouldn't require any large refactoring effort to integrate into an existing project.\n-   **`#![no_std]` Ready & Size Optimized**\n    -   `gdbstub` is a **`no_std` first** library, whereby all protocol features are required to be `no_std` compatible.\n    -   `gdbstub` does not require _any_ dynamic memory allocation, and can be configured to use fixed-size, pre-allocated buffers. This enables `gdbstub` to be used on even the most resource constrained, no-[`alloc`](https://doc.rust-lang.org/alloc/) platforms.\n    -   `gdbstub` is entirely **panic free** in most minimal configurations\\*, resulting in substantially smaller and more robust code.\n        -   \\*See the [Writing panic-free code](#writing-panic-free-code) section below for more details.\n    -   `gdbstub` is transport-layer agnostic, and uses a basic [`Connection`](https://docs.rs/gdbstub/latest/gdbstub/conn/trait.Connection.html) interface to communicate with the GDB server. As long as target has some method of performing in-order, serial, byte-wise I/O (e.g: putchar/getchar over UART), it's possible to run `gdbstub` on it!\n    -   \"You don't pay for what you don't use\": All code related to parsing/handling protocol extensions is guaranteed to be dead-code-eliminated from an optimized binary if left unimplemented. See the [Zero-overhead Protocol Extensions](#zero-overhead-protocol-extensions) section below for more details.\n    -   `gdbstub`'s minimal configuration has an incredibly low binary size + RAM overhead, enabling it to be used on even the most resource-constrained microcontrollers.\n        -   When compiled in release mode, using all the tricks outlined in [`min-sized-rust`](https://github.com/johnthagen/min-sized-rust), a baseline `gdbstub` implementation can weigh in at **_less than 10kb of `.text` + `.rodata`!_** \\*\n        - \\*Exact numbers vary by target platform, compiler version, and `gdbstub` revision. In mixed-language projects, cross-language LTO may be required ([\\#101](https://github.com/daniel5151/gdbstub/issues/101#issuecomment-1264444815)). Data was collected using the included `example_no_std` project compiled on x86_64.\n\n### Can I Use `gdbstub` in Production?\n\n**Yes, as long as you don't mind some API churn until `1.0.0` is released.**\n\nDue to `gdbstub`'s heavy use of Rust's type system in enforcing GDB protocol invariants at compile time, it's often been the case that implementing new GDB protocol features has required making some breaking API changes. While these changes are typically quite minor, they are nonetheless semver-breaking, and may require a code-change when moving between versions. Any particularly involved changes will typically be documented in a dedicated [transition guide](docs/transition_guide.md) document.\n\nThat being said, `gdbstub` has already been integrated into [many real-world projects](#real-world-examples) since its initial `0.1` release, and empirical evidence suggests that it seems to be doing its job quite well! Thusfar, most reported issues have been caused by improperly implemented `Target` and/or `Arch` implementations, while the core `gdbstub` library itself has proven to be reasonably bug-free.\n\nSee the [Future Plans + Roadmap to `1.0.0`](#future-plans--roadmap-to-100) for more information on what features `gdbstub` still needs to implement before committing to API stability with version `1.0.0`.\n\n## Debugging Features\n\nThe GDB Remote Serial Protocol is surprisingly complex, supporting advanced features such as remote file I/O, spawning new processes, \"rewinding\" program execution, and much, _much_ more. Thankfully, most of these features are completely optional, and getting a basic debugging session up-and-running only requires implementing a few basic methods:\n\n-   Base GDB Protocol\n    -   Read/Write memory\n    -   Read/Write registers\n    -   Enumerating threads\n\nYep, that's right! That's all it takes to get `gdb` connected!\n\nOf course, most use-cases will want to support additional debugging features as well. At the moment, `gdbstub` implements the following GDB protocol extensions:\n\n-   Automatic target architecture + feature configuration\n-   Resume\n    -   Continue\n    -   Single Step\n    -   Range Step\n    -   _Reverse_ Step/Continue\n-   Breakpoints\n    -   Software Breakpoints\n    -   Hardware Breakpoints\n    -   Read/Write/Access Watchpoints (i.e: value breakpoints)\n-   Extended Mode\n    -   Launch new processes\n    -   Attach to an existing process\n    -   Kill an existing process\n    -   Pass env vars + args to spawned processes\n    -   Change working directory\n    -   Enable/disable ASLR\n-   Read Memory Map (`info mem`)\n-   Read Section/Segment relocation offsets\n-   Handle custom `monitor` Commands\n    -   Extend the GDB protocol with custom debug commands using GDB's `monitor` command!\n-   Host I/O\n    -   Access the remote target's filesystem to read/write file\n    -   Can be used to automatically read the remote executable on attach (using `ExecFile`)\n-   Read auxiliary vector (`info auxv`)\n-   Extra thread info (`info threads`)\n-   Extra library information (`info sharedlibraries` or `info shared`)\n-   Tracepoints\n    - Configure tracepoints and actions to perform when hit\n    - Select and interrogate collected trace frames\n   - _Note:_ Feature support is not exhaustive, and many feature haven't been implemented yet.\n-   Flash operations (`load`)\n\n_Note:_ GDB features are implemented on an as-needed basis by `gdbstub`'s contributors. If there's a missing GDB feature that you'd like `gdbstub` to implement, please file an issue and/or open a PR!\n\nFor a full list of GDB remote features, check out the [GDB Remote Configuration Docs](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Configuration.html) for a table of GDB commands + their corresponding Remote Serial Protocol packets.\n\n### Zero-overhead Protocol Extensions\n\nUsing a technique called **Inlineable Dyn Extension Traits** (IDETs), `gdbstub` is able to leverage the Rust compiler's powerful optimization passes to ensure any unused features are dead-code-eliminated in release builds _without_ having to rely on compile-time features flags!\n\nFor example, if your target doesn't implement a custom GDB `monitor` command handler, the resulting binary won't include any code related to parsing / handling the underlying `qRcmd` packet!\n\nIf you're interested in the low-level technical details of how IDETs work, I've included a brief writeup in the documentation [here](https://docs.rs/gdbstub/latest/gdbstub/target/ext/index.html#how-protocol-extensions-work---inlineable-dyn-extension-traits-idets).\n\n## Feature flags\n\nBy default, the `std` and `alloc` features are enabled.\n\nWhen using `gdbstub` in `#![no_std]` contexts, make sure to set `default-features = false`.\n\n-   `alloc`\n    -   Implement `Connection` for `Box<dyn Connection>`.\n    -   Log outgoing packets via `log::trace!` (uses a heap-allocated output buffer).\n    -   Provide built-in implementations for certain protocol features:\n        -   Use a heap-allocated packet buffer in `GdbStub` (if none is provided via `GdbStubBuilder::with_packet_buffer`).\n        -   (Monitor Command) Use a heap-allocated output buffer in `ConsoleOutput`.\n-   `std` (implies `alloc`)\n    -   Implement `Connection` for [`TcpStream`](https://doc.rust-lang.org/std/net/struct.TcpStream.html) and [`UnixStream`](https://doc.rust-lang.org/std/os/unix/net/struct.UnixStream.html).\n    -   Implement [`std::error::Error`](https://doc.rust-lang.org/std/error/trait.Error.html) for `gdbstub::Error`.\n    -   Add a `TargetError::Io` variant to simplify `std::io::Error` handling from Target methods.\n-   `paranoid_unsafe`\n    -   Please refer to the [`unsafe` in `gdbstub`](#unsafe-in-gdbstub) section below for more details.\n-   `core_error`\n    -   Make `GdbStubError` implement [`core::error::Error`](https://doc.rust-lang.org/core/error/trait.Error.html) instead of `std::error::Error`.\n\n## Examples\n\n### Real-World Examples\n\nWhile some of these projects may use older versions of `gdbstub`, they can nonetheless serve as useful examples of what a typical `gdbstub` integration might look like.\n\nIf you end up using `gdbstub` in your project, consider opening a PR and adding it to this list!\n\n-   Virtual Machine Monitors (VMMs)\n    -   [OpenVMM/OpenHCL](https://openvmm.dev/reference/dev_feats/gdbstub.html) - (Microsoft) Modular, cross-platform, async-first VMM, with paravisor support\n    -   [firecracker](https://github.com/firecracker-microvm/firecracker/blob/main/docs/gdb-debugging.md) - (Amazon) Secure and fast microVMs for serverless computing\n    -   [crosvm](https://google.github.io/crosvm/running_crosvm/advanced_usage.html#gdb-support) - (Google) The Chrome OS VMM\n    -   [cloud-hypervisor](https://github.com/cloud-hypervisor/cloud-hypervisor) - A VMM for modern cloud workloads\n    -   [uhyve](https://github.com/hermitcore/uhyve) - A minimal hypervisor for [RustyHermit](https://github.com/hermitcore/rusty-hermit)\n-   OS Kernels (using `gdbstub` on `no_std`)\n    -   [COCONUT-SVSM](https://github.com/coconut-svsm/svsm) - VM Service Module (SVSM), supporting Confidential VMs (CVMs)\n    -   [`betrusted-io/xous-core`](https://github.com/betrusted-io/xous-core/blob/b471b604/kernel/src/debug/gdb.rs) - The Xous microkernel operating system\n    -   [`vmware-labs/node-replicated-kernel`](https://github.com/vmware-labs/node-replicated-kernel/tree/57f953c2/kernel/src/arch/x86_64/gdb) - An (experimental) research OS kernel for x86-64 (amd64) machines\n    -   [`patina`](https://github.com/OpenDevicePartnership/patina/blob/main/core/patina_debugger/README.md) - A UEFI compliant pure rust DXE core\n-   Emulators\n    -   [obliteration](https://github.com/obhq/obliteration) - Kernel + VMM for running PS4 software on PCs\n    -   [solana_rbpf](https://github.com/solana-labs/rbpf) - VM and JIT compiler for eBPF programs\n    -   [rustyboyadvance-ng](https://github.com/michelhe/rustboyadvance-ng/) - Nintendo Gameboy Advance emulator and debugger (ARMv4T)\n    -   [gamegirl](https://github.com/anellie/gamegirl) -  A Gameboy (Color/Advance) emulator\n    -   [bevy-atari](https://github.com/mrk-its/bevy-atari) - An Atari XL/XE Emulator (MOS 6502)\n    -   [rmips](https://github.com/starfleetcadet75/rmips) - MIPS R3000 virtual machine simulator\n    -   [clicky](https://github.com/daniel5151/clicky/) - Emulator for classic clickwheel iPods (dual-core ARMv4T)\n    -   [ts7200](https://github.com/daniel5151/ts7200/) - Emulator for the TS-7200 SoC (ARMv4T)\n    -   [vaporstation](https://github.com/Colin-Suckow/vaporstation) - A Playstation One emulator (MIPS)\n    -   [microcorruption-emu](https://github.com/sapir/microcorruption-emu) - Emulator for the microcorruption.com ctf (MSP430)\n-   Other\n    -   [probe-rs](https://probe.rs/) - A modern, embedded debugging toolkit\n    -   [udbserver](https://github.com/bet4it/udbserver) - Plug-in GDB debugging for the [Unicorn Engine](https://www.unicorn-engine.org/) (Multi Architecture)\n    -   [enarx](https://github.com/enarx/enarx) - An open source framework for running applications in Trusted Execution Environments\n    -   [icicle-emu](https://github.com/icicle-emu/icicle-emu) - An experimental fuzzing-specific, multi-architecture emulation framework\n\n### In-tree \"Toy\" Examples\n\nThese examples are built as part of the CI, and are guaranteed to be kept up to date with the latest version of `gdbstub`'s API.\n\n- `armv4t` - `./examples/armv4t/`\n    - An incredibly simple ARMv4T-based system emulator with `gdbstub` support.\n    - **Implements (almost) all available `target::ext` features.** This makes it a great resource when first implementing a new protocol extension!\n- `armv4t_multicore` - `./examples/armv4t_multicore/`\n    - A dual-core variation of the `armv4t` example.\n    - Implements the core of `gdbstub`'s multithread extensions API, but not much else.\n- `example_no_std` - `./example_no_std`\n    - An _extremely_ minimal example which shows off how `gdbstub` can be used in a `#![no_std]` project.\n    - Unlike the `armv4t/armv4t_multicore` examples, this project does _not_ include a working emulator, and simply stubs all `gdbstub` functions.\n    - Doubles as a test-bed for tracking `gdbstub`'s approximate binary footprint (via the `check_size.sh` script), as well as validating certain dead-code-elimination optimizations.\n\n## `unsafe` in `gdbstub`\n\n`gdbstub` limits its use of `unsafe` to a bare minimum, with all uses of `unsafe` required to have a corresponding `// SAFETY` comment as justification.\n\nFor those paranoid about trusting third-party unsafe code, `gdbstub` comes with an opt-in `paranoid_unsafe` feature, which enables `#![forbid(unsafe_code)]` on the entire `gdbstub` crate, swapping out all instances of `unsafe` code with equivalent (albeit less-performant) alternatives.\n\nThe following list exhaustively documents all uses of `unsafe` in `gdbstub`:\n\n- With `default` features\n  - Don't emit provably unreachable panics\n    -   `src/protocol/packet.rs`: Method in `PacketBuf` that use index using stored sub-`Range<usize>` into the buffer\n    -   `src/protocol/common/hex.rs`: `decode_hex_buf`\n\n-   When the `std` feature is enabled:\n    -   `src/connection/impls/unixstream.rs`: An implementation of `UnixStream::peek` which uses `libc::recv`. Will be removed once [rust-lang/rust#76923](https://github.com/rust-lang/rust/issues/76923) stabilizes this feature in the stdlib.\n\n\n## Writing panic-free code\n\nIdeally, the Rust compiler would have some way to opt-in to a strict \"no-panic\" mode. Unfortunately, at the time of writing (2022/04/24), no such mode exists. As such, the only way to avoid the Rust compiler + stdlib's implicit panics is by being _very careful_ when writing code, and _manually checking_ that those panicking paths get optimized out!\n\nAnd when I say \"manually checking\", I mean [checking generated asm output](example_no_std/dump_asm.sh).\n\nWhy even go through this effort?\n\n- Panic infrastructure can be _expensive_, and when you're optimizing for embedded, `no_std` use-cases, panic infrastructure brings in hundreds of additional bytes into the final binary.\n- `gdbstub` can be used to implement low-level debuggers, and if the debugger itself panics, well... it's not like you can debug it all that easily!\n\nAs such, **`gdbstub` promises to introduce zero additional panics** into an existing project, subject to the following conditions:\n\n1. The binary is compiled in release mode\n    - \\*subject to the specific `rustc` version being used (codegen and optimization vary between versions)\n    - \\*different hardware architectures may be subject to different compiler optimizations\n      - i.e: at this time, only `x86` is actively tested to be panic-free\n2. `gdbstub`'s `paranoid_unsafe` cargo feature is _disabled_\n   - LLVM is unable to omit certain `panic` checks without requiring a bit of `unsafe` code\n   - See the [`unsafe` in `gdbstub`](#unsafe-in-gdbstub) section for more details\n3. The `Arch` implementation being used doesn't include panicking code\n   - _Note:_ The arch implementations under `gdbstub_arch` are _not_ guaranteed to be panic free!\n   - If you do spot a panicking arch in `gdbstub_arch`, consider opening a PR to fix it\n\nIf you're using `gdbstub` in a no-panic project and have determined that `gdbstub` is at fault for introducing a panicking code path, please file an issue!\n\n## Future Plans + Roadmap to `1.0.0`\n\nWhile the vast majority of GDB protocol features (e.g: remote filesystem support, tracepoint packets, most query packets, etc...) should _not_ require breaking API changes, the following features will most likely require at least some breaking API changes, and should therefore be implemented prior to `1.0.0`.\n\nNot that this is _not_ an exhaustive list, and is subject to change.\n\n-   [ ] Allow fine-grained control over target features via the `Arch` trait ([\\#12](https://github.com/daniel5151/gdbstub/issues/12))\n-   [ ] Implement GDB's various high-level operating modes:\n    -   [x] Single/Multi Thread debugging\n    -   [ ] Multiprocess Debugging ([\\#124](https://github.com/daniel5151/gdbstub/issues/124)\n        -   [ ] Requires adding a new `target::ext::base::multiprocess` API.\n        -   _Note:_ `gdbstub` already implements multiprocess extensions \"under-the-hood\", and just hard-codes a fake PID, so this is mostly a matter of \"putting in the work\".\n    -   [x] [Extended Mode](https://sourceware.org/gdb/current/onlinedocs/gdb/Connecting.html) (`target extended-remote`)\n    -   [ ] [Non-Stop Mode](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Non_002dStop.html#Remote-Non_002dStop)\n-   [x] Have a working example of `gdbstub` running in a \"bare-metal\" `#![no_std]` environment.\n\nAdditionally, while not _strict_ blockers to `1.0.0`, it would be good to explore these features as well:\n\n-   [ ] Should `gdbstub` commit to a MSRV?\n-   [ ] Remove lingering instances of `RawRegId` from `gdbstub_arch` ([\\#29](https://github.com/daniel5151/gdbstub/issues/29))\n-   [x] Exposing `async/await` interfaces (particularly wrt. handling GDB client interrupts) ([\\#36](https://github.com/daniel5151/gdbstub/issues/36))\n-   [ ] How/if to support [LLDB extensions](https://raw.githubusercontent.com/llvm-mirror/lldb/master/docs/lldb-gdb-remote.txt) ([\\#99](https://github.com/daniel5151/gdbstub/issues/99))\n-   [ ] Supporting multi-arch debugging via a single target\n    -   e.g: debugging x86 and ARM processes on macOS\n-   [ ] Proper handling of \"nack\" packets (for spotty connections) ([\\#137](https://github.com/daniel5151/gdbstub/issues/137))\n\n## License\n\ngdbstub is free and open source! All code in this repository is dual-licensed under either:\n\n* MIT License ([LICENSE-MIT](docs/LICENSE-MIT) or [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT))\n* Apache License, Version 2.0 ([LICENSE-APACHE](docs/LICENSE-APACHE) or [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0))\n\nat your option. This means you can select the license you prefer! This dual-licensing approach is the de-facto standard in the Rust ecosystem and there are [very good reasons](https://github.com/daniel5151/gdbstub/issues/68) to include both.\n\nUnless 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.\n"
  },
  {
    "path": "docs/LICENSE-APACHE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n"
  },
  {
    "path": "docs/LICENSE-MIT",
    "content": "MIT License\n\nCopyright (c) 2021 Daniel Prilik\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "docs/transition_guide.md",
    "content": "# Transition Guide\n\nThis document provides a brief overview of breaking changes between major `gdbstub` releases, along with tips/tricks/suggestions on how to migrate between `gdbstub` releases.\n\nThis document does _not_ discuss any new features that might have been added between releases. For a comprehensive overview of what's been _added_ to `gdbstub` (as opposed to what's _changed_), check out the [`CHANGELOG.md`](../CHANGELOG.md).\n\n> _Note:_ after reading through this doc, you may also find it helpful to refer to the in-tree `armv4t` and `armv4t_multicore` examples when transitioning between versions.\n\n## `0.6` -> `0.7`\n\n`0.7` is a fairly minimal \"cleanup\" release, landing a collection of small breaking changes that collectively improve various ergonomic issues in `gdbstub`'s API.\n\nThe breaking changes introduced in `0.7` are generally trivial to fix, and porting from `0.6` to `0.7` shouldn't take more than ~10 minutes, at most.\n\n##### `stub::GdbStubError` Changes\n\n`stub::GdbStubError` is now an opaque `struct` with a handful of methods to extract user-defined context.\n\n**Please file an issue if your code required matching on concrete error variants aside from `TargetError` and `ConnectionError`!**.\n\nIn contrast with the old version - which was an `enum` that directly exposed all error internals to the user - this new type will enable future versions of `gdbstub` to fearlessly improve error infrastructure without requiring semver breaking changes. See [\\#112](https://github.com/daniel5151/gdbstub/pull/132) for more.\n\nAssuming you stuck to the example error handling described in the `gdbstub` getting started guide, adapting to the new type should be quite straightforward.\n\n\n```rust\n// ==== 0.6.x ==== //\n\nmatch gdb.run_blocking::<EmuGdbEventLoop>(&mut emu) {\n    Ok(disconnect_reason) => { ... },\n    Err(GdbStubError::TargetError(e)) => {\n        println!(\"target encountered a fatal error: {}\", e)\n    }\n    Err(e) => {\n        println!(\"gdbstub encountered a fatal error: {}\", e)\n    }\n}\n\n// ==== 0.7.0 ==== //\n\nmatch gdb.run_blocking::<EmuGdbEventLoop>(&mut emu) {\n    Ok(disconnect_reason) => { ... },\n    Err(e) => {\n        if e.is_target_error() {\n            println!(\n                \"target encountered a fatal error: {}\",\n                e.into_target_error().unwrap()\n            )\n        } else if e.is_connection_error() {\n            let (e, kind) = e.into_connection_error().unwrap();\n            println!(\"connection error: {:?} - {}\", kind, e,)\n        } else {\n            println!(\"gdbstub encountered a fatal error: {}\", e)\n        }\n    }\n}\n```\n\n\n##### `{Single, Multi}ThreadBase::read_addrs` return value\n\n`read_addrs` now returns a `usize` instead of a `()`, allowing implementations to report cases where only a subset of memory could be read.\n\nIn the past, the only way to handle these cases was by returning a `TargetError`. This provides an alternative mechanism, which may or may not be more appropriate for your particular use-case.\n\nWhen upgrading, the Rust compiler will emit a clear error message pointing out the updated function signature. The fix should be trivial.\n\n##### Removal of `Arch::single_step_behavior`\n\nSee [\\#132](https://github.com/daniel5151/gdbstub/pull/132) for more discussion on why this API was removed.\n\nThis change only affects you if you're maintaining a custom `Arch` implementation (vs. using a community-maintained one via `gdbstub_arch`).\n\nThe fix here is to simply remove the `Arch::single_step_behavior` impl.\n\nThat's it! It's that easy.\n\n\n## `0.5` -> `0.6`\n\n`0.6` introduces a large number of breaking changes to the public APIs, and will require quite a bit more more \"hands on\" porting than previous `gdbstub` upgrades.\n\nThe following guide is a **best-effort** attempt to document all the changes, but there are some parts that may be missing / incomplete.\n\n##### General API change - _lots_ of renaming + exported type reorganization\n\nMany types have been renamed, and many import paths have changed in `0.6`.\n\nExhaustively listing them would be nearly impossible, but suffice it to say, you will need to tweak your imports.\n\n##### `Connection` API changes\n\n> _Note:_ If you haven't implemented `Connection` yourself (i.e: you are using one of the built-in `Connection` impls on `TcpStream`/`UnixStream`), you can skip this section.\n\nThe blocking `read` method and non-blocking `peek` methods have been removed from the base `Connection` API, and have been moved to a new `ConnectionExt` type.\n\nFor more context around this change, please refer to [Moving from `GdbStub::run` to `GdbStub::run_blocking`](#moving-from-gdbstubrun-to-gdbstubrun_blocking).\n\nPorting a `0.5` `Connection` to `0.6` is incredibly straightforward - you simply split your existing implementation in two:\n\n```rust\n// ==== 0.5.x ==== //\n\nimpl Connection for MyConnection {\n    type Error = MyError;\n\n    fn write(&mut self, byte: u8) -> Result<(), Self::Error> { .. }\n    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> { .. }\n    fn read(&mut self) -> Result<u8, Self::Error> { .. }\n    fn peek(&mut self) -> Result<Option<u8>, Self::Error> { .. }\n    fn flush(&mut self) -> Result<(), Self::Error> { .. }\n    fn on_session_start(&mut self) -> Result<(), Self::Error> { .. }\n}\n\n// ==== 0.6.0 ==== //\n\nimpl Connection for MyConnection {\n    type Error = MyError;\n\n    fn write(&mut self, byte: u8) -> Result<(), Self::Error> { .. }\n    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> { .. }\n    fn flush(&mut self) -> Result<(), Self::Error> { .. }\n    fn on_session_start(&mut self) -> Result<(), Self::Error> { .. }\n}\n\nimpl ConnectionExt for MyConnection {\n    type Error = MyError;\n\n    fn read(&mut self) -> Result<u8, Self::Error> { .. }\n    fn peek(&mut self) -> Result<Option<u8>, Self::Error> { .. }\n}\n\n```\n\n##### `Arch` API - `RegId::from_raw_id`\n\n> _Note:_ If you haven't implemented `Arch` yourself (i.e: you are any of the `Arch` impls from `gdbstub_arch`), you can skip this section.\n\nThe `Arch` API has had one breaking changes: The `RegId::from_raw_id` method's \"register size\" return value has been changed from `usize` to `Option<NonZeroUsize>`.\n\nIf the register size is `Some`, `gdbstub` will include a runtime check to ensures that the target implementation does not send back more bytes than the register allows when responding to single-register read requests.\n\nIf the register size is `None`, `gdbstub` will _omit_ this runtime check, and trust that the target's implementation of `read_register` is correct.\n\n_Porting advice:_ If your `Arch` implementation targets a specific architecture, it is _highly recommended_ that you simply wrap your existing size value with `Some`. This API change was made to support dynamic `Arch` implementations, whereby the behavior of the `Arch` varies on the runtime state of the program (e.g: in multi-system emulators), and there is not \"fixed\" register size per id.\n\n##### `Target` API - IDET methods are now prefixed with `supports_`\n\nAll IDET methods have been prefixed with `supports_`, to make it easier to tell at-a-glance which methods are actual handler methods, and which are simply IDET plumbing.\n\nAs such, when porting target code from `0.5` to `0.6`, before you dive into any functional changes, you should take a moment to find and rename any methods that have had their name changed.\n\n##### `Target` API - Introducing `enum Signal`\n\nIn prior versions of `gdbstub`, signals were encoded as raw `u8` values. This wasn't very user-friendly, as it meant users had to manually locate the signal-to-integer mapping table themselves when working with signals in code.\n\n`0.6` introduces a new `enum Signal` which encodes this information within `gdbstub` itself.\n\nThis new `Signal` type has replaced `u8` in any places that a `u8` was used to represent a signal, such as in `StopReason::Signal`, or as part of the various `resume` APIs.\n\n_Porting advice:_ The Rust compiler should catch any type errors due to this change, making it easy to swap out any instances of `u8` with the new `Signal` type.\n\n##### `HwWatchpoint` API - Plumb watchpoint `length` parameter to public API\n\nThe watchpoint API has been updated to include a new `length` parameter, specifying what range of memory addresses the watchpoint should encompass.\n\n##### `TargetXmlOverride` API - Return data via `&mut [u8]` buffer\n\nIn an effort to unify the implementations of various new `qXfer`-backed protocol extensions, the existing `TargetXmlOverride` has been changed from returning a `&str` value to using a `std::io::Read`-style \"write the data into a `&mut [u8]` buffer\" API.\n\nPorting a `0.5` `TargetDescriptionXmlOverride` to `0.6` is straightforward, though a bit boilerplate-y.\n\n```rust\n// ==== 0.5.x ==== //\n\nimpl target::ext::target_description_xml_override::TargetDescriptionXmlOverride for Emu {\n    fn target_description_xml(&self) -> &str {\n        r#\"<target version=\"1.0\"><!-- custom override string --><architecture>armv4t</architecture></target>\"#\n    }\n}\n\n// ==== 0.6.0 ==== //\n\npub fn copy_to_buf(data: &[u8], buf: &mut [u8]) -> usize {\n    let len = data.len();\n    let buf = &mut buf[..len];\n    buf.copy_from_slice(data);\n    len\n}\n\npub fn copy_range_to_buf(data: &[u8], offset: u64, length: usize, buf: &mut [u8]) -> usize {\n    let offset = match usize::try_from(offset) {\n        Ok(v) => v,\n        Err(_) => return 0,\n    };\n    let len = data.len();\n    let data = &data[len.min(offset)..len.min(offset + length)];\n    copy_to_buf(data, buf)\n}\n\nimpl target::ext::target_description_xml_override::TargetDescriptionXmlOverride for Emu {\n    fn target_description_xml(\n        &self,\n        offset: u64,\n        length: usize,\n        buf: &mut [u8],\n    ) -> TargetResult<usize, Self> {\n        let xml = r#\"<target version=\"1.0\"><!-- custom override string --><architecture>armv4t</architecture></target>\"#\n            .trim()\n            .as_bytes();\n        Ok(copy_range_to_buf(xml, offset, length, buf))\n    }\n}\n```\n\n##### Updates to `{Single,Multi}ThreadOps::resume` API\n\n`0.6` includes three fairly major behavioral changes to the `resume` method:\n\n###### Support for `resume` is now entirely optional\n\nThere are quite a few use cases where it might make sense to debug a target that does _not_ support resumption, e.g: a post-mortem debugging session, or when debugging crash dumps. In these cases, past version of `gdbstub` would force the user to nonetheless implement \"stub\" methods for resuming these targets, along with forcing users to pay the \"cost\" of including all the handler code related to resumption (of which there is quite a bit.)\n\nIn `0.6`, all resume-related functionality has been extracted out of `{Single,Multi}ThreadBase`, and split into new `{Singe,Multi}ThreadResume` IDETs.\n\n###### Removing `ResumeAction`, and making single-step support optional\n\nThe GDB protocol only requires that targets implement support for _continuing_ execution - support for instruction-level single-step execution is totally optional.\n\n> Note: this isn't actually true in practice, thanks to a bug in the mainline GDB client... See the docs for `Target::use_optional_single_step` for details...\n\nTo model this behavior, `0.6` has split single-step support into its own IDET, in a manner similar to how optimized range step support was handled in `0.5`.\n\nIn doing so, the `enum ResumeAction` type could be removed entirely, as single-step resume was to be handled in its own method.\n\n###### Removing `gdb_interrupt: GdbInterrupt`, and making `resume` non-blocking\n\nIn past versions of `gdbstub`, the `resume` API would _block_ the thread waiting for the target to hit some kind of stop condition. In this model, checking for pending GDB interrupts was quite unergonomic, requiring that the thread periodically wake up and check whether an interrupt has arrived via the `GdbInterrupt` type.\n\n`gdbstub` `0.6` introduces a new paradigm of driving target execution, predicated on the idea that the target's `resume` method _does not block_, instead yielding execution immediately, and deferring the responsibility of \"selecting\" between incoming stop events and GDB interrupts to higher levels of the `gdbstub` \"stack\".\n\nIn practice, this means that much of the logic that used to live in the `resume` implementation will now move into upper-levels of the `gdbstub` API, with the `resume` API serving more of a \"bookkeeping\" purpose, recording what kind of resumption mode the GDB client has requested from the target, while not actually resuming the target itself.\n\nFor more context around this change, please refer to [Moving from `GdbStub::run` to `GdbStub::run_blocking`](#moving-from-gdbstubrun-to-gdbstubrun_blocking).\n\n###### Example: migrating `resume` from `0.5` to `0.6`\n\nMuch of the code contained within methods such as `block_until_stop_reason_or_interrupt` will be lifted into upper layers of the `gdbstub` API, leaving behind just a small bit of code in the target's `resume` method to perform \"bookkeeping\" regarding how the GDB client requested the target to be resumed.\n\n```rust\n// ==== 0.5.x ==== //\n\nimpl SingleThreadOps for Emu {\n    fn resume(\n        &mut self,\n        action: ResumeAction,\n        gdb_interrupt: GdbInterrupt<'_>,\n    ) -> Result<StopReason<u32>, Self::Error> {\n        match action {\n            ResumeAction::Step => self.do_single_step(),\n            ResumeAction::Continue => self.block_until_stop_reason_or_interrupt(action, || gdb_interrupt.pending()),\n            _ => self.handle_resume_with_signal(action),\n        }\n    }\n}\n\n// ==== 0.6.0 ==== //\n\nimpl SingleThreadBase for Emu {\n    // resume has been split into a separate IDET\n    #[inline(always)]\n    fn support_resume(\n        &mut self\n    ) -> Option<SingleThreadResumeOps<Self>> {\n        Some(self)\n    }\n}\n\n\nimpl SingleThreadResume for Emu {\n    fn resume(\n        &mut self,\n        signal: Option<Signal>,\n    ) -> Result<(), Self::Error> { // <-- no longer returns a stop reason!\n        if let Some(signal) = signal {\n            self.handle_signal(signal)?;\n        }\n\n        // upper layers of the `gdbstub` API will be responsible for \"driving\"\n        // target execution - `resume` simply performs book keeping on _how_ the\n        // target should be resumed.\n        self.set_execution_mode(ExecMode::Continue)?;\n\n        Ok(())\n    }\n\n    // single-step support has been split into a separate IDET\n    #[inline(always)]\n    fn support_single_step(\n        &mut self\n    ) -> Option<SingleThreadSingleStepOps<'_, Self>> {\n        Some(self)\n    }\n}\n\nimpl SingleThreadSingleStep for Emu {\n    fn step(&mut self, signal: Option<Signal>) -> Result<(), Self::Error> {\n        if let Some(signal) = signal {\n            self.handle_signal(signal)?;\n        }\n\n        self.set_execution_mode(ExecMode::Step)?;\n        Ok(())\n    }\n}\n```\n\n##### Moving from `GdbStub::run` to `GdbStub::run_blocking`\n\nWith the introduction of the new state-machine API, the responsibility of reading incoming has been lifted out of `gdbstub` itself, and is now something implementations are responsible for . The alternative approach would've been to have `Connection` include multiple different `read`-like methods for various kinds of paradigms - such as `async`/`await`, `epoll`, etc...\n\n> TODO. In the meantime, I would suggest looking at rustdoc for details on how to use `GdbStub::run_blocking`...\n\n## `0.4` -> `0.5`\n\nWhile the overall structure of the API has remained the same, `0.5.0` does introduce a few breaking API changes that require some attention. That being said, it should not be a difficult migration, and updating to `0.5.0` from `0.4` shouldn't take more than 10 mins of refactoring.\n\n##### Consolidating the `{Hw,Sw}Breakpoint/Watchpoint` IDETs under the newly added `Breakpoints` IDETs.\n\nThe various breakpoint IDETs that were previously directly implemented on the top-level `Target` trait have now been consolidated under a single `Breakpoints` IDET. This is purely an organizational change, and will not require rewriting any existing `{add, remove}_{sw_break,hw_break,watch}point` implementations.\n\nPorting from `0.4` to `0.5` should be as simple as:\n\n```rust\n// ==== 0.4.x ==== //\n\nimpl Target for Emu {\n    fn sw_breakpoint(&mut self) -> Option<target::ext::breakpoints::SwBreakpointOps<Self>> {\n        Some(self)\n    }\n\n    fn hw_watchpoint(&mut self) -> Option<target::ext::breakpoints::HwWatchpointOps<Self>> {\n        Some(self)\n    }\n}\n\nimpl target::ext::breakpoints::SwBreakpoint for Emu {\n    fn add_sw_breakpoint(&mut self, addr: u32) -> TargetResult<bool, Self> { ... }\n    fn remove_sw_breakpoint(&mut self, addr: u32) -> TargetResult<bool, Self> { ... }\n}\n\nimpl target::ext::breakpoints::HwWatchpoint for Emu {\n    fn add_hw_watchpoint(&mut self, addr: u32, kind: WatchKind) -> TargetResult<bool, Self> { ... }\n    fn remove_hw_watchpoint(&mut self, addr: u32, kind: WatchKind) -> TargetResult<bool, Self> { ... }\n}\n\n// ==== 0.5.0 ==== //\n\nimpl Target for Emu {\n    // (New Method) //\n    fn breakpoints(&mut self) -> Option<target::ext::breakpoints::BreakpointsOps<Self>> {\n        Some(self)\n    }\n}\n\nimpl target::ext::breakpoints::Breakpoints for Emu {\n    fn sw_breakpoint(&mut self) -> Option<target::ext::breakpoints::SwBreakpointOps<Self>> {\n        Some(self)\n    }\n\n    fn hw_watchpoint(&mut self) -> Option<target::ext::breakpoints::HwWatchpointOps<Self>> {\n        Some(self)\n    }\n}\n\n// (Almost Unchanged) //\nimpl target::ext::breakpoints::SwBreakpoint for Emu {\n    //                                            /-- New `kind` parameter\n    //                                           \\/\n    fn add_sw_breakpoint(&mut self, addr: u32, _kind: arch::arm::ArmBreakpointKind) -> TargetResult<bool, Self> { ... }\n    fn remove_sw_breakpoint(&mut self, addr: u32, _kind: arch::arm::ArmBreakpointKind) -> TargetResult<bool, Self> { ... }\n}\n\n// (Unchanged) //\nimpl target::ext::breakpoints::HwWatchpoint for Emu {\n    fn add_hw_watchpoint(&mut self, addr: u32, kind: WatchKind) -> TargetResult<bool, Self> { ... }\n    fn remove_hw_watchpoint(&mut self, addr: u32, kind: WatchKind) -> TargetResult<bool, Self> { ... }\n}\n\n```\n\n##### Single-register access methods (`{read,write}_register`) are now a separate `SingleRegisterAccess` trait\n\nSingle register access is not a required part of the GDB protocol, and as such, has been moved out into its own IDET. This is a purely organizational change, and will not require rewriting any existing `{read,write}_register` implementations.\n\nPorting from `0.4` to `0.5` should be as simple as:\n\n```rust\n// ==== 0.4.x ==== //\n\nimpl SingleThreadOps for Emu {\n    fn read_register(&mut self, reg_id: arch::arm::reg::id::ArmCoreRegId, dst: &mut [u8]) -> TargetResult<(), Self> { ... }\n    fn write_register(&mut self, reg_id: arch::arm::reg::id::ArmCoreRegId, val: &[u8]) -> TargetResult<(), Self> { ... }\n}\n\n// ==== 0.5.0 ==== //\n\nimpl SingleThreadOps for Emu {\n    // (New Method) //\n    fn single_register_access(&mut self) -> Option<target::ext::base::SingleRegisterAccessOps<(), Self>> {\n        Some(self)\n    }\n}\n\nimpl target::ext::base::SingleRegisterAccess<()> for Emu {\n    //                           /-- New `tid` parameter (ignored on single-threaded systems)\n    //                          \\/\n    fn read_register(&mut self, _tid: (), reg_id: arch::arm::reg::id::ArmCoreRegId, dst: &mut [u8]) -> TargetResult<(), Self> { ... }\n    fn write_register(&mut self, _tid: (), reg_id: arch::arm::reg::id::ArmCoreRegId, val: &[u8]) -> TargetResult<(), Self> { ... }\n}\n```\n\n##### New `MultiThreadOps::resume` API\n\nIn `0.4`, resuming a multithreaded target was done using an `Actions` iterator passed to a single `resume` method. In hindsight, this approach had a couple issues:\n\n- It was impossible to statically enforce the property that the `Actions` iterator was guaranteed to return at least one element, often forcing users to manually `unwrap`\n- The iterator machinery was quite heavy, and did not optimize very effectively\n- Handling malformed packets encountered during iteration was tricky, as the user-facing API exposed an infallible iterator, thereby complicating the internal error handling\n- Adding new kinds of `ResumeAction` (e.g: range stepping) required a breaking change, and forced users to change their `resume` method implementation regardless whether or not their target ended up using said action.\n\nIn `0.5`, the API has been refactored to address some of these issues, and the single `resume` method has now been split into multiple \"lifecycle\" methods:\n\n1. `resume`\n    - As before, when `resume` is called the target should resume execution.\n    - But how does the target know how each thread should be resumed? That's where the next method comes in...\n1. `set_resume_action`\n    - This method is called prior to `resume`, and notifies the target how a particular `Tid` should be resumed.\n1. (optionally) `set_resume_action_range_step`\n    - If the target supports optimized range-stepping, it can opt to implement the newly added `MultiThreadRangeStepping` IDET which includes this method.\n    - Targets that aren't interested in optimized range-stepping can skip this method!\n1. `clear_resume_actions`\n    - After the target returns a `ThreadStopReason` from `resume`, this method will be called to reset the previously set per-`tid` resume actions.\n\nNOTE: This change does mean that targets are now responsible for maintaining some internal state that maps `Tid`s to `ResumeAction`s. Thankfully, this isn't difficult at all, and can as simple as maintaining a `HashMap<Tid, ResumeAction>`.\n\nPlease refer to the in-tree `armv4t_multicore` example for an example of how this new `resume` flow works.\n"
  },
  {
    "path": "example_no_std/.gitignore",
    "content": "/target\n.gdb_history\n*.s\n"
  },
  {
    "path": "example_no_std/Cargo.toml",
    "content": "[package]\nname = \"gdbstub-nostd\"\nversion = \"0.1.0\"\nauthors = [\"Daniel Prilik <danielprilik@gmail.com>\"]\nedition = \"2018\"\n\n[features]\n__dead_code_marker = [\"gdbstub/__dead_code_marker\"]\n\n[dependencies]\ngdbstub = { path = \"../\", default-features = false }\ngdbstub_arch = { path = \"../gdbstub_arch\", default-features = false }\n\nlibc = { version = \"0.2\", default-features = false }\nlog = { version = \"0.4\", features = [\"release_max_level_off\"] }\n\n[profile.dev]\npanic = \"abort\"\n\n[profile.release]\npanic = \"abort\"\nopt-level = 's'  # Optimize for size.\nlto = true\ncodegen-units = 1\ndebug = true\n"
  },
  {
    "path": "example_no_std/README.md",
    "content": "# example_no_std\n\nThis basic example is used to benchmark how large `gdbstub`'s binary footprint is in `#![no_std]` contexts.\n\nIt uses many of the [`min-sized-rust`](https://github.com/johnthagen/min-sized-rust) guidelines to crunch down the binary size. This includes directly linking against `libc` to perform I/O, and avoiding and and all uses of Rust's [heavy formatting machinery](https://jamesmunns.com/blog/fmt-unreasonably-expensive/). While not perfect, this example should give a rough estimate of what a typical embedded system `gdbstub` integration might look like.\n\nOh, and please excuse the _terrible_ sockets code in `conn.rs`. I've never worked with raw C sockets, and that code was very haphazardly thrown together. If you're so inclined, I'd more than happily merge the PR that improves it's implementation!\n"
  },
  {
    "path": "example_no_std/check_size.sh",
    "content": "#!/bin/bash\nset -e\n\ncd \"$(dirname \"$(realpath $0)\")\"\n\n# checks the size of the resulting --release level binary (that's been stripped)\n\ncargo build --release\n\ncargo bloat --release --split-std -n 100\n\nstrip target/release/gdbstub-nostd\nsize -A -t target/release/gdbstub-nostd\n"
  },
  {
    "path": "example_no_std/dump_asm.sh",
    "content": "#!/bin/bash\nset -e\n\ncd \"$(dirname \"$(realpath \"$0\")\")\"\n\nif ! command -v rustfilt &> /dev/null\nthen\n    cargo install rustfilt\nfi\n\nrm -rf ./target\ncargo rustc --release -- --emit asm -C \"llvm-args=-x86-asm-syntax=intel\"\ncat ./target/release/deps/gdbstub_nostd-*.s | rustfilt > asm.s\nsed -i -E '/\\.(cfi_def_cfa_offset|cfi_offset|cfi_startproc|cfi_endproc|size)/d' asm.s\n\nif [ -n \"$EXTRA_TRIM\" ]; then\n    sed -i -E '/\\.(Ltmp|file|loc)/d' asm.s\n    sed -i -E '/.section\\t.debug_loc/,$d' asm.s\nfi\n\necho \"asm emitted to asm.s\"\n\nif grep \"core::panicking::panic_fmt\" asm.s\nthen\n    echo \"found panic in example_no_std!\"\n    exit 1\nelse\n    echo \"no panics in example_no_std\"\nfi\n"
  },
  {
    "path": "example_no_std/rustfmt.toml",
    "content": "wrap_comments = true"
  },
  {
    "path": "example_no_std/src/conn.rs",
    "content": "use gdbstub::conn::Connection;\n\npub struct TcpConnection {\n    sock: i32,\n    fd: i32,\n}\n\nimpl TcpConnection {\n    pub fn new_localhost(port: u16) -> Result<TcpConnection, &'static str> {\n        unsafe {\n            let sockaddr = libc::sockaddr_in {\n                #[cfg(any(\n                    target_os = \"macos\",\n                    target_os = \"ios\",\n                    target_os = \"freebsd\",\n                    target_os = \"netbsd\",\n                    target_os = \"openbsd\",\n                    target_os = \"dragonfly\"\n                ))]\n                sin_len: core::mem::size_of::<libc::sockaddr_in>() as _,\n                sin_family: libc::AF_INET as _,\n                sin_port: port.to_be(),\n                // 127.0.0.1\n                sin_addr: libc::in_addr {\n                    s_addr: 0x7f000001u32.to_be(),\n                },\n                sin_zero: [0; 8],\n            };\n            let socklen = core::mem::size_of::<libc::sockaddr_in>();\n\n            let sock = libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0);\n            if sock == -1 {\n                return Err(\"could not create listen socket\");\n            }\n\n            let reuseaddr: i32 = 1;\n            if libc::setsockopt(\n                sock,\n                libc::SOL_SOCKET,\n                libc::SO_REUSEADDR,\n                &reuseaddr as *const _ as *const libc::c_void,\n                core::mem::size_of::<i32>() as u32,\n            ) < 0\n            {\n                return Err(\"could not set SO_REUSEADDR\");\n            }\n\n            if libc::bind(sock, &sockaddr as *const _ as _, socklen as u32) < 0 {\n                return Err(\"could not bind socket\");\n            }\n\n            if libc::listen(sock, 1) < 0 {\n                return Err(\"could not open socket for listening\");\n            }\n\n            let fd = libc::accept(sock, core::ptr::null_mut(), &mut 0);\n            if fd < 0 {\n                return Err(\"could not accept socket connection\");\n            }\n\n            Ok(TcpConnection { sock, fd })\n        }\n    }\n\n    pub fn read(&mut self) -> Result<u8, &'static str> {\n        let mut buf = [0];\n        let ret = unsafe { libc::read(self.fd, buf.as_mut_ptr() as _, 1) };\n        if ret == -1 || ret != 1 {\n            Err(\"socket read failed\")\n        } else {\n            Ok(buf[0])\n        }\n    }\n\n    #[allow(dead_code)]\n    pub fn peek(&mut self) -> Result<Option<u8>, &'static str> {\n        let mut buf = [0];\n        let ret = unsafe {\n            libc::recv(\n                self.fd,\n                buf.as_mut_ptr() as *mut _,\n                buf.len(),\n                libc::MSG_PEEK,\n            )\n        };\n        if ret == -1 || ret != 1 {\n            Err(\"socket peek failed\")\n        } else {\n            Ok(Some(buf[0]))\n        }\n    }\n}\n\nimpl Drop for TcpConnection {\n    fn drop(&mut self) {\n        unsafe {\n            libc::close(self.fd);\n            libc::close(self.sock);\n        }\n    }\n}\n\nimpl Connection for TcpConnection {\n    type Error = &'static str;\n\n    fn write(&mut self, b: u8) -> Result<(), &'static str> {\n        let buf = [b];\n        let ret = unsafe { libc::write(self.fd, buf.as_ptr() as _, 1) };\n        if ret == -1 || ret != 1 {\n            Err(\"socket write failed\")\n        } else {\n            Ok(())\n        }\n    }\n\n    fn flush(&mut self) -> Result<(), &'static str> {\n        // huh, apparently flushing isn't a \"thing\" for Tcp streams.\n        // see https://doc.rust-lang.org/src/std/net/tcp.rs.html#592-609\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "example_no_std/src/gdb.rs",
    "content": "use crate::print_str::print_str;\nuse gdbstub::common::Signal;\nuse gdbstub::common::Tid;\nuse gdbstub::target;\nuse gdbstub::target::ext::base::multithread::MultiThreadBase;\nuse gdbstub::target::ext::base::multithread::MultiThreadResume;\nuse gdbstub::target::Target;\nuse gdbstub::target::TargetResult;\n\npub struct DummyTarget {}\n\nimpl DummyTarget {\n    pub fn new() -> DummyTarget {\n        DummyTarget {}\n    }\n}\n\nimpl Target for DummyTarget {\n    type Arch = gdbstub_arch::arm::Armv4t;\n    type Error = &'static str;\n\n    #[inline(always)]\n    fn base_ops(&mut self) -> target::ext::base::BaseOps<'_, Self::Arch, Self::Error> {\n        target::ext::base::BaseOps::MultiThread(self)\n    }\n\n    // disable `QStartNoAckMode` in order to save space\n    #[inline(always)]\n    fn use_no_ack_mode(&self) -> bool {\n        false\n    }\n\n    // disable X packet optimization in order to save space\n    #[inline(always)]\n    fn use_x_upcase_packet(&self) -> bool {\n        false\n    }\n\n    // disable fork events to save space\n    #[inline(always)]\n    fn use_fork_stop_reason(&self) -> bool {\n        false\n    }\n\n    // disable vfork events to save space\n    #[inline(always)]\n    fn use_vfork_stop_reason(&self) -> bool {\n        false\n    }\n\n    // disable vforkdone events to save space\n    #[inline(always)]\n    fn use_vforkdone_stop_reason(&self) -> bool {\n        false\n    }\n\n    #[inline(always)]\n    fn support_breakpoints(\n        &mut self,\n    ) -> Option<target::ext::breakpoints::BreakpointsOps<'_, Self>> {\n        Some(self)\n    }\n}\n\n// NOTE: to try and make this a marginally more realistic estimate of\n// `gdbstub`'s library overhead, non-IDET methods are marked as\n// `#[inline(never)]` to prevent the optimizer from too aggressively coalescing\n// the stubbed implementations.\n//\n// EXCEPTION: `list_active_threads` accepts a closure arg, and should be\n// be inlined for smaller codegen\n\nimpl MultiThreadBase for DummyTarget {\n    #[inline(never)]\n    fn read_registers(\n        &mut self,\n        _regs: &mut gdbstub_arch::arm::reg::ArmCoreRegs,\n        _tid: Tid,\n    ) -> TargetResult<(), Self> {\n        print_str(\"> read_registers\");\n        Ok(())\n    }\n\n    #[inline(never)]\n    fn write_registers(\n        &mut self,\n        _regs: &gdbstub_arch::arm::reg::ArmCoreRegs,\n        _tid: Tid,\n    ) -> TargetResult<(), Self> {\n        print_str(\"> write_registers\");\n        Ok(())\n    }\n\n    #[inline(never)]\n    fn read_addrs(\n        &mut self,\n        _start_addr: u32,\n        data: &mut [u8],\n        _tid: Tid, // same address space for each core\n    ) -> TargetResult<usize, Self> {\n        print_str(\"> read_addrs\");\n        data.iter_mut().for_each(|b| *b = 0x55);\n        Ok(data.len())\n    }\n\n    #[inline(never)]\n    fn write_addrs(\n        &mut self,\n        _start_addr: u32,\n        _data: &[u8],\n        _tid: Tid, // same address space for each core\n    ) -> TargetResult<(), Self> {\n        print_str(\"> write_addrs\");\n        Ok(())\n    }\n\n    #[inline(always)] // !! EXCEPTION !!\n    fn list_active_threads(\n        &mut self,\n        register_thread: &mut dyn FnMut(Tid),\n    ) -> Result<(), Self::Error> {\n        print_str(\"> list_active_threads\");\n        register_thread(Tid::new(1).unwrap());\n        register_thread(Tid::new(2).unwrap());\n        Ok(())\n    }\n\n    #[inline(always)]\n    fn support_resume(\n        &mut self,\n    ) -> Option<target::ext::base::multithread::MultiThreadResumeOps<'_, Self>> {\n        Some(self)\n    }\n}\n\nimpl MultiThreadResume for DummyTarget {\n    #[inline(never)]\n    fn resume(&mut self) -> Result<(), Self::Error> {\n        print_str(\"> resume\");\n        Ok(())\n    }\n\n    #[inline(never)]\n    fn clear_resume_actions(&mut self) -> Result<(), Self::Error> {\n        print_str(\"> clear_resume_actions\");\n        Ok(())\n    }\n\n    #[inline(never)]\n    fn set_resume_action_continue(\n        &mut self,\n        _tid: Tid,\n        _signal: Option<Signal>,\n    ) -> Result<(), Self::Error> {\n        print_str(\"> set_resume_action_continue\");\n        Ok(())\n    }\n}\n\nimpl target::ext::breakpoints::Breakpoints for DummyTarget {\n    #[inline(always)]\n    fn support_sw_breakpoint(\n        &mut self,\n    ) -> Option<target::ext::breakpoints::SwBreakpointOps<'_, Self>> {\n        Some(self)\n    }\n}\n\nimpl target::ext::breakpoints::SwBreakpoint for DummyTarget {\n    #[inline(never)]\n    fn add_sw_breakpoint(\n        &mut self,\n        _addr: u32,\n        _kind: gdbstub_arch::arm::ArmBreakpointKind,\n    ) -> TargetResult<bool, Self> {\n        Ok(true)\n    }\n\n    #[inline(never)]\n    fn remove_sw_breakpoint(\n        &mut self,\n        _addr: u32,\n        _kind: gdbstub_arch::arm::ArmBreakpointKind,\n    ) -> TargetResult<bool, Self> {\n        Ok(true)\n    }\n}\n"
  },
  {
    "path": "example_no_std/src/main.rs",
    "content": "//! A basic `no_std` example that's used to ballpark estimate how large\n//! `gdbstub`'s binary footprint is resource-restricted environments.\n\n#![no_std]\n#![no_main]\n\nuse crate::print_str::print_str;\nuse gdbstub::stub::state_machine::GdbStubStateMachine;\nuse gdbstub::stub::DisconnectReason;\nuse gdbstub::stub::GdbStubBuilder;\nuse gdbstub::stub::MultiThreadStopReason;\n\nmod conn;\nmod gdb;\nmod print_str;\n\n#[panic_handler]\nfn panic(_info: &core::panic::PanicInfo<'_>) -> ! {\n    loop {}\n}\n\nfn rust_main() -> Result<(), i32> {\n    print_str(\"Running example_no_std...\");\n\n    let mut target = gdb::DummyTarget::new();\n\n    let conn = match conn::TcpConnection::new_localhost(9001) {\n        Ok(c) => c,\n        Err(e) => {\n            print_str(\"could not start TCP server:\");\n            print_str(e);\n            return Err(-1);\n        }\n    };\n\n    let mut buf = [0; 4096];\n    let gdb = GdbStubBuilder::new(conn)\n        .with_packet_buffer(&mut buf)\n        .build()\n        .map_err(|_| 1)?;\n\n    print_str(\"Starting GDB session...\");\n\n    let mut gdb = gdb.run_state_machine(&mut target).map_err(|_| 1)?;\n\n    let res = loop {\n        gdb = match gdb {\n            GdbStubStateMachine::Idle(mut gdb) => {\n                let byte = gdb.borrow_conn().read().map_err(|_| 1)?;\n                match gdb.incoming_data(&mut target, byte) {\n                    Ok(gdb) => gdb,\n                    Err(e) => break Err(e),\n                }\n            }\n            GdbStubStateMachine::Running(gdb) => {\n                match gdb.report_stop(&mut target, MultiThreadStopReason::DoneStep) {\n                    Ok(gdb) => gdb,\n                    Err(e) => break Err(e),\n                }\n            }\n            GdbStubStateMachine::CtrlCInterrupt(gdb) => {\n                match gdb.interrupt_handled(&mut target, None::<MultiThreadStopReason<u32>>) {\n                    Ok(gdb) => gdb,\n                    Err(e) => break Err(e),\n                }\n            }\n            GdbStubStateMachine::Disconnected(gdb) => break Ok(gdb.get_reason()),\n        }\n    };\n\n    match res {\n        Ok(disconnect_reason) => match disconnect_reason {\n            DisconnectReason::Disconnect => print_str(\"GDB Disconnected\"),\n            DisconnectReason::TargetExited(_) => print_str(\"Target exited\"),\n            DisconnectReason::TargetTerminated(_) => print_str(\"Target halted\"),\n            DisconnectReason::Kill => print_str(\"GDB sent a kill command\"),\n        },\n        Err(e) => {\n            if e.is_target_error() {\n                print_str(\"Target raised a fatal error\");\n            } else {\n                print_str(\"gdbstub internal error\");\n            }\n        }\n    }\n\n    Ok(())\n}\n\n#[no_mangle]\nextern \"C\" fn main(_argc: isize, _argv: *const *const u8) -> isize {\n    if let Err(e) = rust_main() {\n        return e as isize;\n    }\n\n    0\n}\n"
  },
  {
    "path": "example_no_std/src/print_str.rs",
    "content": "pub fn print_str(s: &str) {\n    unsafe {\n        libc::write(1, s.as_ptr() as _, s.len());\n        libc::write(1, \"\\n\".as_ptr() as _, 1);\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/README.md",
    "content": "# armv4t\n\nAn incredibly simple emulator to run elf binaries compiled with `arm-none-eabi-cc -march=armv4t`.\n\nThis emulator isn't based off any particular system -- it's moreso just a test-bed for showing off various bits of `gdbstub` functionality.\n\n## Usage\n\nRun `gdb-arm-none-eabi` (or alternatively, `gdb-multiarch`) from the `test_bin` directory to automatically connect to the emulator + load debug symbols for the emulated binary.\n\nThis example can be run using:\n\n```bash\ncargo run --example armv4t --features=std\n```\n\n**NOTE:** If debug symbols couldn't be loaded, try rebuilding `test.elf` locally (requires the `arm-none-eabi` toolchain to be installed), and recompiling the example.\n\n### Unix Domain Sockets\n\nGDB versions since \\~2018 support running a debugging session over Unix Domain Sockets (UDS). Debugging over UDS can feel much snappier than debugging over loopback TCP.\n\nRunning the example with the `--uds` flag will bind the GdbStub to a socket at `/tmp/armv4t_gdb`.\n\nThis feature is only supported on Unix-like systems.\n"
  },
  {
    "path": "examples/armv4t/emu.rs",
    "content": "use crate::mem_sniffer::AccessKind;\nuse crate::mem_sniffer::MemSniffer;\nuse crate::DynResult;\nuse armv4t_emu::reg;\nuse armv4t_emu::Cpu;\nuse armv4t_emu::ExampleMem;\nuse armv4t_emu::Memory;\nuse armv4t_emu::Mode;\nuse gdbstub::common::Pid;\nuse gdbstub::target::ext::tracepoints::NewTracepoint;\nuse gdbstub::target::ext::tracepoints::SourceTracepoint;\nuse gdbstub::target::ext::tracepoints::Tracepoint;\nuse gdbstub::target::ext::tracepoints::TracepointAction;\nuse gdbstub::target::ext::tracepoints::TracepointEnumerateState;\nuse std::collections::BTreeMap;\n\nconst HLE_RETURN_ADDR: u32 = 0x12345678;\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\npub enum Event {\n    DoneStep,\n    Halted,\n    Break,\n    WatchWrite(u32),\n    WatchRead(u32),\n}\n\npub enum ExecMode {\n    Step,\n    Continue,\n    RangeStep(u32, u32),\n}\n\n#[derive(Debug)]\npub struct TraceFrame {\n    pub number: Tracepoint,\n    pub snapshot: Cpu,\n}\n\n/// incredibly barebones armv4t-based emulator\npub struct Emu {\n    start_addr: u32,\n\n    // example custom register. only read/written to from the GDB client\n    pub(crate) custom_reg: u32,\n\n    pub(crate) exec_mode: ExecMode,\n\n    pub(crate) cpu: Cpu,\n    pub(crate) mem: ExampleMem,\n\n    pub(crate) watchpoints: Vec<u32>,\n    pub(crate) breakpoints: Vec<u32>,\n    pub(crate) files: Vec<Option<std::fs::File>>,\n\n    pub(crate) tracepoints: BTreeMap<\n        Tracepoint,\n        (\n            NewTracepoint<u32>,\n            Vec<SourceTracepoint<'static, u32>>,\n            Vec<TracepointAction<'static, u32>>,\n        ),\n    >,\n    pub(crate) traceframes: Vec<TraceFrame>,\n    pub(crate) tracepoint_enumerate_state: TracepointEnumerateState<u32>,\n    pub(crate) tracing: bool,\n    pub(crate) selected_frame: Option<usize>,\n\n    pub(crate) reported_pid: Pid,\n}\n\nimpl Emu {\n    pub fn new(program_elf: &[u8]) -> DynResult<Emu> {\n        // set up emulated system\n        let mut cpu = Cpu::new();\n        let mut mem = ExampleMem::new();\n\n        // load ELF\n        let elf_header = goblin::elf::Elf::parse(program_elf)?;\n\n        // copy all in-memory sections from the ELF file into system RAM\n        let sections = elf_header\n            .section_headers\n            .iter()\n            .filter(|h| h.is_alloc() && h.sh_type != goblin::elf::section_header::SHT_NOBITS);\n\n        for h in sections {\n            eprintln!(\n                \"loading section {:?} into memory from [{:#010x?}..{:#010x?}]\",\n                elf_header.shdr_strtab.get_at(h.sh_name).unwrap(),\n                h.sh_addr,\n                h.sh_addr + h.sh_size,\n            );\n\n            for (i, b) in program_elf[h.file_range().unwrap()].iter().enumerate() {\n                mem.w8(h.sh_addr as u32 + i as u32, *b);\n            }\n        }\n\n        // setup execution state\n        eprintln!(\"Setting PC to {:#010x?}\", elf_header.entry);\n        cpu.reg_set(Mode::User, reg::SP, 0x10000000);\n        cpu.reg_set(Mode::User, reg::LR, HLE_RETURN_ADDR);\n        cpu.reg_set(Mode::User, reg::PC, elf_header.entry as u32);\n        cpu.reg_set(Mode::User, reg::CPSR, 0x10); // user mode\n\n        Ok(Emu {\n            start_addr: elf_header.entry as u32,\n\n            custom_reg: 0x12345678,\n\n            exec_mode: ExecMode::Continue,\n\n            cpu,\n            mem,\n\n            watchpoints: Vec::new(),\n            breakpoints: Vec::new(),\n            files: Vec::new(),\n\n            tracepoints: BTreeMap::new(),\n            traceframes: Vec::new(),\n            tracepoint_enumerate_state: Default::default(),\n            tracing: false,\n            selected_frame: None,\n\n            reported_pid: Pid::new(1).unwrap(),\n        })\n    }\n\n    pub(crate) fn reset(&mut self) {\n        self.cpu.reg_set(Mode::User, reg::SP, 0x10000000);\n        self.cpu.reg_set(Mode::User, reg::LR, HLE_RETURN_ADDR);\n        self.cpu.reg_set(Mode::User, reg::PC, self.start_addr);\n        self.cpu.reg_set(Mode::User, reg::CPSR, 0x10);\n    }\n\n    /// single-step the interpreter\n    pub fn step(&mut self) -> Option<Event> {\n        if self.tracing {\n            let pc = self.cpu.reg_get(self.cpu.mode(), reg::PC);\n            let frames: Vec<_> = self\n                .tracepoints\n                .iter()\n                .filter(|(_tracepoint, (ctp, _source, _actions))| ctp.enabled && ctp.addr == pc)\n                .map(|(tracepoint, _definition)| {\n                    // our `tracepoint_define` restricts our loaded tracepoints to only contain\n                    // register collect actions. instead of only collecting the registers requested\n                    // in the register mask and recording a minimal trace frame, we just collect\n                    // all of them by cloning the cpu itself.\n                    TraceFrame {\n                        number: *tracepoint,\n                        snapshot: self.cpu,\n                    }\n                })\n                .collect();\n            self.traceframes.extend(frames);\n        }\n\n        let mut hit_watchpoint = None;\n\n        let mut sniffer = MemSniffer::new(&mut self.mem, &self.watchpoints, |access| {\n            hit_watchpoint = Some(access)\n        });\n\n        self.cpu.step(&mut sniffer);\n        let pc = self.cpu.reg_get(Mode::User, reg::PC);\n\n        if let Some(access) = hit_watchpoint {\n            let fixup = if self.cpu.thumb_mode() { 2 } else { 4 };\n            self.cpu.reg_set(Mode::User, reg::PC, pc - fixup);\n\n            return Some(match access.kind {\n                AccessKind::Read => Event::WatchRead(access.addr),\n                AccessKind::Write => Event::WatchWrite(access.addr),\n            });\n        }\n\n        if self.breakpoints.contains(&pc) {\n            return Some(Event::Break);\n        }\n\n        if pc == HLE_RETURN_ADDR {\n            return Some(Event::Halted);\n        }\n\n        None\n    }\n\n    /// run the emulator in accordance with the currently set `ExecutionMode`.\n    ///\n    /// since the emulator runs in the same thread as the GDB loop, the emulator\n    /// will use the provided callback to poll the connection for incoming data\n    /// every 1024 steps.\n    pub fn run(&mut self, mut poll_incoming_data: impl FnMut() -> bool) -> RunEvent {\n        match self.exec_mode {\n            ExecMode::Step => RunEvent::Event(self.step().unwrap_or(Event::DoneStep)),\n            ExecMode::Continue => {\n                let mut cycles = 0;\n                loop {\n                    if cycles % 1024 == 0 {\n                        // poll for incoming data\n                        if poll_incoming_data() {\n                            break RunEvent::IncomingData;\n                        }\n                    }\n                    cycles += 1;\n\n                    if let Some(event) = self.step() {\n                        break RunEvent::Event(event);\n                    };\n                }\n            }\n            // just continue, but with an extra PC check\n            ExecMode::RangeStep(start, end) => {\n                let mut cycles = 0;\n                loop {\n                    if cycles % 1024 == 0 {\n                        // poll for incoming data\n                        if poll_incoming_data() {\n                            break RunEvent::IncomingData;\n                        }\n                    }\n                    cycles += 1;\n\n                    if let Some(event) = self.step() {\n                        break RunEvent::Event(event);\n                    };\n\n                    if !(start..end).contains(&self.cpu.reg_get(self.cpu.mode(), reg::PC)) {\n                        break RunEvent::Event(Event::DoneStep);\n                    }\n                }\n            }\n        }\n    }\n}\n\npub enum RunEvent {\n    IncomingData,\n    Event(Event),\n}\n"
  },
  {
    "path": "examples/armv4t/gdb/auxv.rs",
    "content": "use super::copy_range_to_buf;\nuse crate::emu::Emu;\nuse gdbstub::target;\nuse gdbstub::target::TargetResult;\n\nimpl target::ext::auxv::Auxv for Emu {\n    fn get_auxv(&self, offset: u64, length: usize, buf: &mut [u8]) -> TargetResult<usize, Self> {\n        let auxv = b\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\";\n        Ok(copy_range_to_buf(auxv, offset, length, buf))\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/gdb/breakpoints.rs",
    "content": "use crate::emu::Emu;\nuse gdbstub::target;\nuse gdbstub::target::ext::breakpoints::WatchKind;\nuse gdbstub::target::TargetResult;\n\nimpl target::ext::breakpoints::Breakpoints for Emu {\n    #[inline(always)]\n    fn support_sw_breakpoint(\n        &mut self,\n    ) -> Option<target::ext::breakpoints::SwBreakpointOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_hw_watchpoint(\n        &mut self,\n    ) -> Option<target::ext::breakpoints::HwWatchpointOps<'_, Self>> {\n        Some(self)\n    }\n}\n\nimpl target::ext::breakpoints::SwBreakpoint for Emu {\n    fn add_sw_breakpoint(\n        &mut self,\n        addr: u32,\n        _kind: gdbstub_arch::arm::ArmBreakpointKind,\n    ) -> TargetResult<bool, Self> {\n        self.breakpoints.push(addr);\n        Ok(true)\n    }\n\n    fn remove_sw_breakpoint(\n        &mut self,\n        addr: u32,\n        _kind: gdbstub_arch::arm::ArmBreakpointKind,\n    ) -> TargetResult<bool, Self> {\n        match self.breakpoints.iter().position(|x| *x == addr) {\n            None => return Ok(false),\n            Some(pos) => self.breakpoints.remove(pos),\n        };\n\n        Ok(true)\n    }\n}\n\nimpl target::ext::breakpoints::HwWatchpoint for Emu {\n    fn add_hw_watchpoint(\n        &mut self,\n        addr: u32,\n        len: u32,\n        kind: WatchKind,\n    ) -> TargetResult<bool, Self> {\n        for addr in addr..(addr + len) {\n            match kind {\n                WatchKind::Write => self.watchpoints.push(addr),\n                WatchKind::Read => self.watchpoints.push(addr),\n                WatchKind::ReadWrite => self.watchpoints.push(addr),\n            };\n        }\n\n        Ok(true)\n    }\n\n    fn remove_hw_watchpoint(\n        &mut self,\n        addr: u32,\n        len: u32,\n        kind: WatchKind,\n    ) -> TargetResult<bool, Self> {\n        for addr in addr..(addr + len) {\n            let pos = match self.watchpoints.iter().position(|x| *x == addr) {\n                None => return Ok(false),\n                Some(pos) => pos,\n            };\n\n            match kind {\n                WatchKind::Write => self.watchpoints.remove(pos),\n                WatchKind::Read => self.watchpoints.remove(pos),\n                WatchKind::ReadWrite => self.watchpoints.remove(pos),\n            };\n        }\n\n        Ok(true)\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/gdb/catch_syscalls.rs",
    "content": "use crate::gdb::Emu;\nuse gdbstub::target;\nuse gdbstub::target::ext::catch_syscalls::SyscallNumbers;\n\n// This implementation is for illustrative purposes only. If the target doesn't\n// support syscalls then there is no need to implement this extension\n\nimpl target::ext::catch_syscalls::CatchSyscalls for Emu {\n    fn enable_catch_syscalls(\n        &mut self,\n        filter: Option<SyscallNumbers<'_, u32>>,\n    ) -> target::TargetResult<(), Self> {\n        match filter {\n            Some(numbers) => eprintln!(\n                \"Enabled catching syscalls: {:?}\",\n                numbers.collect::<Vec<u32>>()\n            ),\n            None => eprintln!(\"Enabled catching all syscalls\"),\n        }\n        Ok(())\n    }\n\n    fn disable_catch_syscalls(&mut self) -> target::TargetResult<(), Self> {\n        eprintln!(\"Disabled catching syscalls\");\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/gdb/exec_file.rs",
    "content": "use super::copy_range_to_buf;\nuse crate::emu::Emu;\nuse gdbstub::common::Pid;\nuse gdbstub::target;\nuse gdbstub::target::TargetResult;\n\nimpl target::ext::exec_file::ExecFile for Emu {\n    fn get_exec_file(\n        &self,\n        _pid: Option<Pid>,\n        offset: u64,\n        length: usize,\n        buf: &mut [u8],\n    ) -> TargetResult<usize, Self> {\n        let filename = b\"/test.elf\";\n        Ok(copy_range_to_buf(filename, offset, length, buf))\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/gdb/extended_mode.rs",
    "content": "use crate::emu::Emu;\nuse gdbstub::common::Pid;\nuse gdbstub::target;\nuse gdbstub::target::ext::extended_mode::Args;\nuse gdbstub::target::ext::extended_mode::AttachKind;\nuse gdbstub::target::ext::extended_mode::ShouldTerminate;\nuse gdbstub::target::TargetResult;\n\n/*=====================================\n=            Extended Mode            =\n=====================================*/\n\n// This is a stub implementation of GDB's Extended Mode extensions.\n//\n// Truth be told, this particular emulator is _not_ very well suited to running\n// in extended mode, as it doesn't technically spawn/attach to any process.\n// Nonetheless, it's useful to have a stubbed implementation in-tree which can\n// be used for basic usability / regression testing.\n//\n// If you happen to implement a \"proper\" extended mode gdbstub, feel free to\n// file an issue / open a PR that links to your project!\n\nimpl target::ext::extended_mode::ExtendedMode for Emu {\n    fn kill(&mut self, pid: Option<Pid>) -> TargetResult<ShouldTerminate, Self> {\n        eprintln!(\"GDB sent a kill request for pid {:?}\", pid);\n        Ok(ShouldTerminate::No)\n    }\n\n    fn restart(&mut self) -> Result<(), Self::Error> {\n        eprintln!(\"GDB sent a restart request\");\n        Ok(())\n    }\n\n    fn attach(&mut self, pid: Pid) -> TargetResult<(), Self> {\n        eprintln!(\"GDB attached to a process with PID {}\", pid);\n        // stub implementation: just report the same code, but running under a\n        // different pid.\n        self.reported_pid = pid;\n        Ok(())\n    }\n\n    fn run(&mut self, filename: Option<&[u8]>, args: Args<'_, '_>) -> TargetResult<Pid, Self> {\n        // simplified example: assume UTF-8 filenames / args\n        //\n        // To be 100% pedantically correct, consider converting to an `OsStr` in the\n        // least lossy way possible (e.g: using the `from_bytes` extension from\n        // `std::os::unix::ffi::OsStrExt`).\n\n        let filename = match filename {\n            None => None,\n            Some(raw) => Some(core::str::from_utf8(raw).map_err(drop)?),\n        };\n        let args = args\n            .map(|raw| core::str::from_utf8(raw).map_err(drop))\n            .collect::<Result<Vec<_>, _>>()?;\n\n        eprintln!(\n            \"GDB tried to run a new process with filename {:?}, and args {:?}\",\n            filename, args\n        );\n\n        self.reset();\n\n        // when running in single-threaded mode, this PID can be anything\n        Ok(Pid::new(1337).unwrap())\n    }\n\n    fn query_if_attached(&mut self, pid: Pid) -> TargetResult<AttachKind, Self> {\n        eprintln!(\n            \"GDB queried if it was attached to a process with PID {}\",\n            pid\n        );\n        Ok(AttachKind::Attach)\n    }\n\n    #[inline(always)]\n    fn support_configure_aslr(\n        &mut self,\n    ) -> Option<target::ext::extended_mode::ConfigureAslrOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_configure_env(\n        &mut self,\n    ) -> Option<target::ext::extended_mode::ConfigureEnvOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_configure_startup_shell(\n        &mut self,\n    ) -> Option<target::ext::extended_mode::ConfigureStartupShellOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_configure_working_dir(\n        &mut self,\n    ) -> Option<target::ext::extended_mode::ConfigureWorkingDirOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_current_active_pid(\n        &mut self,\n    ) -> Option<target::ext::extended_mode::CurrentActivePidOps<'_, Self>> {\n        Some(self)\n    }\n}\n\nimpl target::ext::extended_mode::ConfigureAslr for Emu {\n    fn cfg_aslr(&mut self, enabled: bool) -> TargetResult<(), Self> {\n        eprintln!(\"GDB {} ASLR\", if enabled { \"enabled\" } else { \"disabled\" });\n        Ok(())\n    }\n}\n\nimpl target::ext::extended_mode::ConfigureEnv for Emu {\n    fn set_env(&mut self, key: &[u8], val: Option<&[u8]>) -> TargetResult<(), Self> {\n        // simplified example: assume UTF-8 key/val env vars\n        let key = core::str::from_utf8(key).map_err(drop)?;\n        let val = match val {\n            None => None,\n            Some(raw) => Some(core::str::from_utf8(raw).map_err(drop)?),\n        };\n\n        eprintln!(\"GDB tried to set a new env var: {:?}={:?}\", key, val);\n\n        Ok(())\n    }\n\n    fn remove_env(&mut self, key: &[u8]) -> TargetResult<(), Self> {\n        let key = core::str::from_utf8(key).map_err(drop)?;\n        eprintln!(\"GDB tried to set remove a env var: {:?}\", key);\n\n        Ok(())\n    }\n\n    fn reset_env(&mut self) -> TargetResult<(), Self> {\n        eprintln!(\"GDB tried to reset env vars\");\n\n        Ok(())\n    }\n}\n\nimpl target::ext::extended_mode::ConfigureStartupShell for Emu {\n    fn cfg_startup_with_shell(&mut self, enabled: bool) -> TargetResult<(), Self> {\n        eprintln!(\n            \"GDB {} startup with shell\",\n            if enabled { \"enabled\" } else { \"disabled\" }\n        );\n        Ok(())\n    }\n}\n\nimpl target::ext::extended_mode::ConfigureWorkingDir for Emu {\n    fn cfg_working_dir(&mut self, dir: Option<&[u8]>) -> TargetResult<(), Self> {\n        let dir = match dir {\n            None => None,\n            Some(raw) => Some(core::str::from_utf8(raw).map_err(drop)?),\n        };\n\n        match dir {\n            None => eprintln!(\"GDB reset the working directory\"),\n            Some(dir) => eprintln!(\"GDB set the working directory to {:?}\", dir),\n        }\n\n        Ok(())\n    }\n}\n\nimpl target::ext::extended_mode::CurrentActivePid for Emu {\n    fn current_active_pid(&mut self) -> Result<Pid, Self::Error> {\n        Ok(self.reported_pid)\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/gdb/flash.rs",
    "content": "use crate::emu::Emu;\nuse gdbstub::target;\nuse gdbstub::target::TargetResult;\n\nimpl target::ext::flash::Flash for Emu {\n    fn flash_erase(&mut self, start_addr: u32, length: u32) -> TargetResult<(), Self> {\n        log::info!(\"flash_erase start_addr: {start_addr:08x}, length: {length:08x}\");\n        Ok(())\n    }\n\n    fn flash_write(&mut self, start_addr: u32, _data: &[u8]) -> TargetResult<(), Self> {\n        log::info!(\"flash_write start_addr: {start_addr:08x}\");\n        Ok(())\n    }\n\n    fn flash_done(&mut self) -> TargetResult<(), Self> {\n        log::info!(\"flash_done\");\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/gdb/host_io.rs",
    "content": "use super::copy_range_to_buf;\nuse super::copy_to_buf;\nuse crate::emu::Emu;\nuse crate::TEST_PROGRAM_ELF;\nuse gdbstub::target;\nuse gdbstub::target::ext::host_io::FsKind;\nuse gdbstub::target::ext::host_io::HostIoErrno;\nuse gdbstub::target::ext::host_io::HostIoError;\nuse gdbstub::target::ext::host_io::HostIoOpenFlags;\nuse gdbstub::target::ext::host_io::HostIoOpenMode;\nuse gdbstub::target::ext::host_io::HostIoResult;\nuse gdbstub::target::ext::host_io::HostIoStat;\nuse std::io::Read;\nuse std::io::Seek;\nuse std::io::Write;\n\nconst FD_RESERVED: u32 = 1;\n\nimpl target::ext::host_io::HostIo for Emu {\n    #[inline(always)]\n    fn support_open(&mut self) -> Option<target::ext::host_io::HostIoOpenOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_close(&mut self) -> Option<target::ext::host_io::HostIoCloseOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_pread(&mut self) -> Option<target::ext::host_io::HostIoPreadOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_pwrite(&mut self) -> Option<target::ext::host_io::HostIoPwriteOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_fstat(&mut self) -> Option<target::ext::host_io::HostIoFstatOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_unlink(&mut self) -> Option<target::ext::host_io::HostIoUnlinkOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_readlink(&mut self) -> Option<target::ext::host_io::HostIoReadlinkOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_setfs(&mut self) -> Option<target::ext::host_io::HostIoSetfsOps<'_, Self>> {\n        Some(self)\n    }\n}\n\nimpl target::ext::host_io::HostIoOpen for Emu {\n    fn open(\n        &mut self,\n        filename: &[u8],\n        flags: HostIoOpenFlags,\n        _mode: HostIoOpenMode,\n    ) -> HostIoResult<u32, Self> {\n        if filename.starts_with(b\"/proc\") {\n            return Err(HostIoError::Errno(HostIoErrno::ENOENT));\n        }\n\n        // In this example, the test binary is compiled into the binary itself as the\n        // `TEST_PROGRAM_ELF` array using `include_bytes!`. As such, we must \"spoof\" the\n        // existence of a real file, which will actually be backed by the in-binary\n        // `TEST_PROGRAM_ELF` array.\n        if filename == b\"/test.elf\" {\n            return Ok(0);\n        }\n\n        let path =\n            std::str::from_utf8(filename).map_err(|_| HostIoError::Errno(HostIoErrno::ENOENT))?;\n\n        let mut read = false;\n        let mut write = false;\n        if flags.contains(HostIoOpenFlags::O_RDWR) {\n            read = true;\n            write = true;\n        } else if flags.contains(HostIoOpenFlags::O_WRONLY) {\n            write = true;\n        } else {\n            read = true;\n        }\n\n        let file = std::fs::OpenOptions::new()\n            .read(read)\n            .write(write)\n            .append(flags.contains(HostIoOpenFlags::O_APPEND))\n            .create(flags.contains(HostIoOpenFlags::O_CREAT))\n            .truncate(flags.contains(HostIoOpenFlags::O_TRUNC))\n            .create_new(flags.contains(HostIoOpenFlags::O_EXCL))\n            .open(path)?;\n\n        let n = match self.files.iter_mut().enumerate().find(|(_, f)| f.is_none()) {\n            Some((n, free_file)) => {\n                *free_file = Some(file);\n                n\n            }\n            None => {\n                self.files.push(Some(file));\n                self.files.len() - 1\n            }\n        };\n\n        Ok(n as u32 + FD_RESERVED)\n    }\n}\n\nimpl target::ext::host_io::HostIoClose for Emu {\n    fn close(&mut self, fd: u32) -> HostIoResult<(), Self> {\n        if fd < FD_RESERVED {\n            return Ok(());\n        }\n\n        let file = match self.files.get_mut((fd - FD_RESERVED) as usize) {\n            Some(file) => file,\n            _ => return Err(HostIoError::Errno(HostIoErrno::EBADF)),\n        };\n\n        file.take().ok_or(HostIoError::Errno(HostIoErrno::EBADF))?;\n        while let Some(None) = self.files.last() {\n            self.files.pop();\n        }\n        Ok(())\n    }\n}\n\nimpl target::ext::host_io::HostIoPread for Emu {\n    fn pread<'a>(\n        &mut self,\n        fd: u32,\n        count: usize,\n        offset: u64,\n        buf: &mut [u8],\n    ) -> HostIoResult<usize, Self> {\n        if fd < FD_RESERVED {\n            if fd == 0 {\n                return Ok(copy_range_to_buf(TEST_PROGRAM_ELF, offset, count, buf));\n            } else {\n                return Err(HostIoError::Errno(HostIoErrno::EBADF));\n            }\n        }\n\n        let file = match self.files.get_mut((fd - FD_RESERVED) as usize) {\n            Some(Some(file)) => file,\n            _ => return Err(HostIoError::Errno(HostIoErrno::EBADF)),\n        };\n\n        file.seek(std::io::SeekFrom::Start(offset))?;\n        let n = file.read(buf)?;\n        Ok(n)\n    }\n}\n\nimpl target::ext::host_io::HostIoPwrite for Emu {\n    fn pwrite(&mut self, fd: u32, offset: u32, data: &[u8]) -> HostIoResult<u32, Self> {\n        if fd < FD_RESERVED {\n            return Err(HostIoError::Errno(HostIoErrno::EACCES));\n        }\n\n        let file = match self.files.get_mut((fd - FD_RESERVED) as usize) {\n            Some(Some(file)) => file,\n            _ => return Err(HostIoError::Errno(HostIoErrno::EBADF)),\n        };\n\n        file.seek(std::io::SeekFrom::Start(offset as u64))?;\n        let n = file.write(data)?;\n        Ok(n as u32)\n    }\n}\n\nimpl target::ext::host_io::HostIoFstat for Emu {\n    fn fstat(&mut self, fd: u32) -> HostIoResult<HostIoStat, Self> {\n        if fd < FD_RESERVED {\n            if fd == 0 {\n                return Ok(HostIoStat {\n                    st_dev: 0,\n                    st_ino: 0,\n                    st_mode: HostIoOpenMode::empty(),\n                    st_nlink: 0,\n                    st_uid: 0,\n                    st_gid: 0,\n                    st_rdev: 0,\n                    st_size: TEST_PROGRAM_ELF.len() as u64,\n                    st_blksize: 0,\n                    st_blocks: 0,\n                    st_atime: 0,\n                    st_mtime: 0,\n                    st_ctime: 0,\n                });\n            } else {\n                return Err(HostIoError::Errno(HostIoErrno::EBADF));\n            }\n        }\n        let metadata = match self.files.get((fd - FD_RESERVED) as usize) {\n            Some(Some(file)) => file.metadata()?,\n            _ => return Err(HostIoError::Errno(HostIoErrno::EBADF)),\n        };\n\n        macro_rules! time_to_secs {\n            ($time:expr) => {\n                $time\n                    .map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?\n                    .duration_since(std::time::SystemTime::UNIX_EPOCH)\n                    .map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?\n                    .as_secs() as u32\n            };\n        }\n        let atime = time_to_secs!(metadata.accessed());\n        let mtime = time_to_secs!(metadata.modified());\n        let ctime = time_to_secs!(metadata.created());\n\n        Ok(HostIoStat {\n            st_dev: 0,\n            st_ino: 0,\n            st_mode: HostIoOpenMode::empty(),\n            st_nlink: 0,\n            st_uid: 0,\n            st_gid: 0,\n            st_rdev: 0,\n            st_size: metadata.len(),\n            st_blksize: 0,\n            st_blocks: 0,\n            st_atime: atime,\n            st_mtime: mtime,\n            st_ctime: ctime,\n        })\n    }\n}\n\nimpl target::ext::host_io::HostIoUnlink for Emu {\n    fn unlink(&mut self, filename: &[u8]) -> HostIoResult<(), Self> {\n        let path =\n            std::str::from_utf8(filename).map_err(|_| HostIoError::Errno(HostIoErrno::ENOENT))?;\n        std::fs::remove_file(path)?;\n        Ok(())\n    }\n}\n\nimpl target::ext::host_io::HostIoReadlink for Emu {\n    fn readlink<'a>(&mut self, filename: &[u8], buf: &mut [u8]) -> HostIoResult<usize, Self> {\n        if filename == b\"/proc/1/exe\" {\n            // Support `info proc exe` command\n            let exe = b\"/test.elf\";\n            return Ok(copy_to_buf(exe, buf));\n        } else if filename == b\"/proc/1/cwd\" {\n            // Support `info proc cwd` command\n            let cwd = b\"/\";\n            return Ok(copy_to_buf(cwd, buf));\n        } else if filename.starts_with(b\"/proc\") {\n            return Err(HostIoError::Errno(HostIoErrno::ENOENT));\n        }\n\n        let path =\n            std::str::from_utf8(filename).map_err(|_| HostIoError::Errno(HostIoErrno::ENOENT))?;\n        let link = std::fs::read_link(path)?;\n        let data = link\n            .to_str()\n            .ok_or(HostIoError::Errno(HostIoErrno::ENOENT))?\n            .as_bytes();\n        if data.len() <= buf.len() {\n            Ok(copy_to_buf(data, buf))\n        } else {\n            Err(HostIoError::Errno(HostIoErrno::ENAMETOOLONG))\n        }\n    }\n}\n\nimpl target::ext::host_io::HostIoSetfs for Emu {\n    fn setfs(&mut self, _fs: FsKind) -> HostIoResult<(), Self> {\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/gdb/libraries.rs",
    "content": "use super::copy_range_to_buf;\nuse crate::emu::Emu;\nuse gdbstub::target;\nuse gdbstub::target::TargetResult;\n\nimpl target::ext::libraries::LibrariesSvr4 for Emu {\n    fn get_libraries_svr4(\n        &self,\n        offset: u64,\n        length: usize,\n        buf: &mut [u8],\n    ) -> TargetResult<usize, Self> {\n        // `l_ld` is the address of the `PT_DYNAMIC` ELF segment, so fake an\n        // address here.\n        //\n        // The `main-lm`, `lm`, and `lmid` seem to refer to in-memory structures\n        // which gdb may read, but gdb also seems to work well enough if they're\n        // null-ish or otherwise pointing to non-present things.\n        let xml = r#\"\n<library-list-svr4 version=\"1.0\" main-lm=\"0x4\">\n    <library name=\"/test.elf\" lm=\"0x8\" l_addr=\"0\" l_ld=\"0\" lmid=\"0x14\"/>\n</library-list-svr4>\n\"#\n        .trim()\n        .as_bytes();\n        Ok(copy_range_to_buf(xml, offset, length, buf))\n    }\n}\n\nimpl target::ext::libraries::Libraries for Emu {\n    fn get_libraries(\n        &self,\n        offset: u64,\n        length: usize,\n        buf: &mut [u8],\n    ) -> TargetResult<usize, Self> {\n        // This is the Windows/generic library list format, which uses segment\n        // addresses instead of the SVR4 link_map structure.\n        //\n        // Note: on Windows, the `address` is not the image base, but the\n        // address of the first section (typically .text).\n        let xml = r#\"\n<library-list>\n    <library name=\"/test.elf\"><segment address=\"0x55550000\"/></library>\n</library-list>\n\"#\n        .trim()\n        .as_bytes();\n        Ok(copy_range_to_buf(xml, offset, length, buf))\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/gdb/lldb_register_info_override.rs",
    "content": "use crate::gdb::custom_arch::ArmCoreRegIdCustom;\nuse crate::gdb::Emu;\nuse gdbstub::arch::lldb::Encoding;\nuse gdbstub::arch::lldb::Format;\nuse gdbstub::arch::lldb::Generic;\nuse gdbstub::arch::lldb::Register;\nuse gdbstub::arch::RegId;\nuse gdbstub::target;\nuse gdbstub::target::ext::lldb_register_info_override::Callback;\nuse gdbstub::target::ext::lldb_register_info_override::CallbackToken;\nuse gdbstub_arch::arm::reg::id::ArmCoreRegId;\n\n// (LLDB extension) This implementation is for illustrative purposes only.\n//\n// Note: In this implementation, we have r0-pc from 0-16 but cpsr is at offset\n// 25*4 in the 'g'/'G' packets, so we add 8 padding registers here. Please see\n// gdbstub/examples/armv4t/gdb/target_description_xml_override.rs for more info.\nimpl target::ext::lldb_register_info_override::LldbRegisterInfoOverride for Emu {\n    fn lldb_register_info<'a>(\n        &mut self,\n        reg_id: usize,\n        reg_info: Callback<'a>,\n    ) -> Result<CallbackToken<'a>, Self::Error> {\n        match ArmCoreRegIdCustom::from_raw_id(reg_id) {\n            Some((_, None)) | None => Ok(reg_info.done()),\n            Some((r, Some(size))) => {\n                let name: String = match r {\n                    // For the purpose of demonstration, we end the qRegisterInfo packet exchange\n                    // when reaching the Time register id, so that this register can only be\n                    // explicitly queried via the single-register read packet.\n                    ArmCoreRegIdCustom::Time => return Ok(reg_info.done()),\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(i)) => match i {\n                        0 => \"r0\",\n                        1 => \"r1\",\n                        2 => \"r2\",\n                        3 => \"r3\",\n                        4 => \"r4\",\n                        5 => \"r5\",\n                        6 => \"r6\",\n                        7 => \"r7\",\n                        8 => \"r8\",\n                        9 => \"r9\",\n                        10 => \"r10\",\n                        11 => \"r11\",\n                        12 => \"r12\",\n                        _ => \"unknown\",\n                    },\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp) => \"sp\",\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Lr) => \"lr\",\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc) => \"pc\",\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Fpr(_i)) => \"padding\",\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Fps) => \"padding\",\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr) => \"cpsr\",\n                    ArmCoreRegIdCustom::Custom => \"custom\",\n                    _ => \"unknown\",\n                }\n                .into();\n                let encoding = match r {\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(_i)) => Encoding::Uint,\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp)\n                    | ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc)\n                    | ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr)\n                    | ArmCoreRegIdCustom::Custom => Encoding::Uint,\n                    _ => Encoding::Vector,\n                };\n                let format = match r {\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(_i)) => Format::Hex,\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp)\n                    | ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc)\n                    | ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr)\n                    | ArmCoreRegIdCustom::Custom => Format::Hex,\n                    _ => Format::VectorUInt8,\n                };\n                let set: String = match r {\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(_i)) => \"General Purpose Registers\",\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp)\n                    | ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc)\n                    | ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr)\n                    | ArmCoreRegIdCustom::Custom => \"General Purpose Registers\",\n                    _ => \"Floating Point Registers\",\n                }\n                .into();\n                let generic = match r {\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp) => Some(Generic::Sp),\n                    ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc) => Some(Generic::Pc),\n                    _ => None,\n                };\n                let reg = Register {\n                    name: &name,\n                    alt_name: None,\n                    bitsize: (usize::from(size)) * 8,\n                    offset: reg_id * (usize::from(size)),\n                    encoding,\n                    format,\n                    set: &set,\n                    gcc: None,\n                    dwarf: Some(reg_id),\n                    generic,\n                    container_regs: None,\n                    invalidate_regs: None,\n                };\n                Ok(reg_info.write(reg))\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/gdb/memory_map.rs",
    "content": "use super::copy_range_to_buf;\nuse crate::emu::Emu;\nuse gdbstub::target;\nuse gdbstub::target::TargetResult;\n\nimpl target::ext::memory_map::MemoryMap for Emu {\n    fn memory_map_xml(\n        &self,\n        offset: u64,\n        length: usize,\n        buf: &mut [u8],\n    ) -> TargetResult<usize, Self> {\n        let memory_map = r#\"<?xml version=\"1.0\"?>\n<!DOCTYPE memory-map\n    PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\"\n            \"http://sourceware.org/gdb/gdb-memory-map.dtd\">\n<memory-map>\n    <memory type=\"ram\" start=\"0x00000000\" length=\"0x10000000\"/>\n    <memory type=\"ram\" start=\"0x12340000\" length=\"0x10000\"/>\n    <memory type=\"flash\" start=\"0x55550000\" length=\"0x10000000\">\n        <property name=\"blocksize\">0x1000</property>\n    </memory>\n</memory-map>\"#\n            .trim()\n            .as_bytes();\n        Ok(copy_range_to_buf(memory_map, offset, length, buf))\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/gdb/mod.rs",
    "content": "use crate::emu::Emu;\nuse crate::emu::ExecMode;\nuse armv4t_emu::reg;\nuse armv4t_emu::Memory;\nuse core::convert::TryInto;\nuse gdbstub::common::Signal;\nuse gdbstub::target;\nuse gdbstub::target::ext::base::singlethread::SingleThreadBase;\nuse gdbstub::target::ext::base::singlethread::SingleThreadResume;\nuse gdbstub::target::Target;\nuse gdbstub::target::TargetError;\nuse gdbstub::target::TargetResult;\nuse gdbstub_arch::arm::reg::id::ArmCoreRegId;\n\n// Additional GDB extensions\n\nmod auxv;\nmod breakpoints;\nmod catch_syscalls;\nmod exec_file;\nmod extended_mode;\nmod flash;\nmod host_io;\nmod libraries;\nmod lldb_register_info_override;\nmod memory_map;\nmod monitor_cmd;\nmod section_offsets;\nmod target_description_xml_override;\npub(crate) mod tracepoints;\n\n/// Turn a `ArmCoreRegId` into an internal register number of `armv4t_emu`.\nfn cpu_reg_id(id: ArmCoreRegId) -> Option<u8> {\n    match id {\n        ArmCoreRegId::Gpr(i) => Some(i),\n        ArmCoreRegId::Sp => Some(reg::SP),\n        ArmCoreRegId::Lr => Some(reg::LR),\n        ArmCoreRegId::Pc => Some(reg::PC),\n        ArmCoreRegId::Cpsr => Some(reg::CPSR),\n        _ => None,\n    }\n}\n\n/// Copy all bytes of `data` to `buf`.\n/// Return the size of data copied.\npub fn copy_to_buf(data: &[u8], buf: &mut [u8]) -> usize {\n    let len = buf.len().min(data.len());\n    buf[..len].copy_from_slice(&data[..len]);\n    len\n}\n\n/// Copy a range of `data` (start at `offset` with a size of `length`) to `buf`.\n/// Return the size of data copied. Returns 0 if `offset >= buf.len()`.\n///\n/// Mainly used by qXfer:_object_:read commands.\npub fn copy_range_to_buf(data: &[u8], offset: u64, length: usize, buf: &mut [u8]) -> usize {\n    let offset = offset as usize;\n    if offset > data.len() {\n        return 0;\n    }\n\n    let start = offset;\n    let end = (offset + length).min(data.len());\n    copy_to_buf(&data[start..end], buf)\n}\n\nimpl Target for Emu {\n    // As an example, I've defined a custom architecture based off\n    // `gdbstub_arch::arm::Armv4t`. The implementation is in the `custom_arch`\n    // module at the bottom of this file.\n    //\n    // unless you're working with a particularly funky architecture that uses custom\n    // registers, you should probably stick to using the simple `target.xml`\n    // implementations from the `gdbstub_arch` repo (i.e: `target.xml` files that\n    // only specify the <architecture> and <feature>s of the arch, instead of\n    // listing out all the registers out manually).\n    type Arch = custom_arch::Armv4tCustom;\n    type Error = &'static str;\n\n    // --------------- IMPORTANT NOTE ---------------\n    // Always remember to annotate IDET enable methods with `inline(always)`!\n    // Without this annotation, LLVM might fail to dead-code-eliminate nested IDET\n    // implementations, resulting in unnecessary binary bloat.\n\n    #[inline(always)]\n    fn base_ops(&mut self) -> target::ext::base::BaseOps<'_, Self::Arch, Self::Error> {\n        target::ext::base::BaseOps::SingleThread(self)\n    }\n\n    #[inline(always)]\n    fn support_breakpoints(\n        &mut self,\n    ) -> Option<target::ext::breakpoints::BreakpointsOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_extended_mode(\n        &mut self,\n    ) -> Option<target::ext::extended_mode::ExtendedModeOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_monitor_cmd(&mut self) -> Option<target::ext::monitor_cmd::MonitorCmdOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_section_offsets(\n        &mut self,\n    ) -> Option<target::ext::section_offsets::SectionOffsetsOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_target_description_xml_override(\n        &mut self,\n    ) -> Option<\n        target::ext::target_description_xml_override::TargetDescriptionXmlOverrideOps<'_, Self>,\n    > {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_lldb_register_info_override(\n        &mut self,\n    ) -> Option<target::ext::lldb_register_info_override::LldbRegisterInfoOverrideOps<'_, Self>>\n    {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_memory_map(&mut self) -> Option<target::ext::memory_map::MemoryMapOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_catch_syscalls(\n        &mut self,\n    ) -> Option<target::ext::catch_syscalls::CatchSyscallsOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_host_io(&mut self) -> Option<target::ext::host_io::HostIoOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_exec_file(&mut self) -> Option<target::ext::exec_file::ExecFileOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_auxv(&mut self) -> Option<target::ext::auxv::AuxvOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_libraries_svr4(\n        &mut self,\n    ) -> Option<target::ext::libraries::LibrariesSvr4Ops<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_libraries(&mut self) -> Option<target::ext::libraries::LibrariesOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_tracepoints(\n        &mut self,\n    ) -> Option<target::ext::tracepoints::TracepointsOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_flash_operations(&mut self) -> Option<target::ext::flash::FlashOps<'_, Self>> {\n        Some(self)\n    }\n}\n\nimpl SingleThreadBase for Emu {\n    fn read_registers(\n        &mut self,\n        regs: &mut custom_arch::ArmCoreRegsCustom,\n    ) -> TargetResult<(), Self> {\n        // if we selected a frame from a tracepoint, return registers from that snapshot\n        let cpu = self\n            .selected_frame\n            .and_then(|selected| self.traceframes.get(selected))\n            .map(|frame| frame.snapshot)\n            .unwrap_or_else(|| self.cpu);\n        let mode = cpu.mode();\n\n        for i in 0..13 {\n            regs.core.r[i] = cpu.reg_get(mode, i as u8);\n        }\n        regs.core.sp = cpu.reg_get(mode, reg::SP);\n        regs.core.lr = cpu.reg_get(mode, reg::LR);\n        regs.core.pc = cpu.reg_get(mode, reg::PC);\n        regs.core.cpsr = cpu.reg_get(mode, reg::CPSR);\n\n        regs.custom = self.custom_reg;\n\n        Ok(())\n    }\n\n    fn write_registers(&mut self, regs: &custom_arch::ArmCoreRegsCustom) -> TargetResult<(), Self> {\n        if self.selected_frame.is_some() {\n            // we can't modify registers in a tracepoint frame\n            return Err(TargetError::NonFatal);\n        }\n        let mode = self.cpu.mode();\n\n        for i in 0..13 {\n            self.cpu.reg_set(mode, i, regs.core.r[i as usize]);\n        }\n        self.cpu.reg_set(mode, reg::SP, regs.core.sp);\n        self.cpu.reg_set(mode, reg::LR, regs.core.lr);\n        self.cpu.reg_set(mode, reg::PC, regs.core.pc);\n        self.cpu.reg_set(mode, reg::CPSR, regs.core.cpsr);\n\n        self.custom_reg = regs.custom;\n\n        Ok(())\n    }\n\n    #[inline(always)]\n    fn support_single_register_access(\n        &mut self,\n    ) -> Option<target::ext::base::single_register_access::SingleRegisterAccessOps<'_, (), Self>>\n    {\n        Some(self)\n    }\n\n    fn read_addrs(&mut self, start_addr: u32, data: &mut [u8]) -> TargetResult<usize, Self> {\n        if self.selected_frame.is_some() {\n            // we only support register collection actions for our tracepoint frames.\n            // if we have a selected frame, then we don't have any memory we can\n            // return from the frame snapshot.\n            return Ok(0);\n        }\n        // this is a simple emulator, with RAM covering the entire 32 bit address space\n        for (addr, val) in (start_addr..).zip(data.iter_mut()) {\n            *val = self.mem.r8(addr)\n        }\n        Ok(data.len())\n    }\n\n    fn write_addrs(&mut self, start_addr: u32, data: &[u8]) -> TargetResult<(), Self> {\n        if self.selected_frame.is_some() {\n            // we can't modify memory in a tracepoint frame\n            return Err(TargetError::NonFatal);\n        }\n\n        // this is a simple emulator, with RAM covering the entire 32 bit address space\n        for (addr, val) in (start_addr..).zip(data.iter().copied()) {\n            self.mem.w8(addr, val)\n        }\n        Ok(())\n    }\n\n    #[inline(always)]\n    fn support_resume(\n        &mut self,\n    ) -> Option<target::ext::base::singlethread::SingleThreadResumeOps<'_, Self>> {\n        Some(self)\n    }\n}\n\nimpl SingleThreadResume for Emu {\n    fn resume(&mut self, signal: Option<Signal>) -> Result<(), Self::Error> {\n        // Upon returning from the `resume` method, the target being debugged should be\n        // configured to run according to whatever resume actions the GDB client has\n        // specified (as specified by `set_resume_action`, `resume_range_step`,\n        // `reverse_{step, continue}`, etc...)\n        //\n        // In this basic `armv4t` example, the `resume` method simply sets the exec mode\n        // of the emulator's interpreter loop and returns.\n        //\n        // In more complex implementations, it's likely that the target being debugged\n        // will be running in another thread / process, and will require some kind of\n        // external \"orchestration\" to set it's execution mode (e.g: modifying the\n        // target's process state via platform specific debugging syscalls).\n\n        if signal.is_some() {\n            return Err(\"no support for continuing with signal\");\n        }\n\n        self.exec_mode = ExecMode::Continue;\n\n        Ok(())\n    }\n\n    #[inline(always)]\n    fn support_reverse_cont(\n        &mut self,\n    ) -> Option<target::ext::base::reverse_exec::ReverseContOps<'_, (), Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_reverse_step(\n        &mut self,\n    ) -> Option<target::ext::base::reverse_exec::ReverseStepOps<'_, (), Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_single_step(\n        &mut self,\n    ) -> Option<target::ext::base::singlethread::SingleThreadSingleStepOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_range_step(\n        &mut self,\n    ) -> Option<target::ext::base::singlethread::SingleThreadRangeSteppingOps<'_, Self>> {\n        Some(self)\n    }\n}\n\nimpl target::ext::base::singlethread::SingleThreadSingleStep for Emu {\n    fn step(&mut self, signal: Option<Signal>) -> Result<(), Self::Error> {\n        if signal.is_some() {\n            return Err(\"no support for stepping with signal\");\n        }\n\n        self.exec_mode = ExecMode::Step;\n\n        Ok(())\n    }\n}\n\nimpl target::ext::base::single_register_access::SingleRegisterAccess<()> for Emu {\n    fn read_register(\n        &mut self,\n        _tid: (),\n        reg_id: custom_arch::ArmCoreRegIdCustom,\n        buf: &mut [u8],\n    ) -> TargetResult<usize, Self> {\n        match reg_id {\n            custom_arch::ArmCoreRegIdCustom::Core(reg_id) => {\n                if let Some(i) = cpu_reg_id(reg_id) {\n                    let w = self.cpu.reg_get(self.cpu.mode(), i);\n                    buf.copy_from_slice(&w.to_le_bytes());\n                    Ok(buf.len())\n                } else {\n                    Err(().into())\n                }\n            }\n            custom_arch::ArmCoreRegIdCustom::Custom => {\n                buf.copy_from_slice(&self.custom_reg.to_le_bytes());\n                Ok(buf.len())\n            }\n            custom_arch::ArmCoreRegIdCustom::Time => {\n                buf.copy_from_slice(\n                    &(std::time::SystemTime::now()\n                        .duration_since(std::time::UNIX_EPOCH)\n                        .unwrap()\n                        .as_millis() as u32)\n                        .to_le_bytes(),\n                );\n                Ok(buf.len())\n            }\n            custom_arch::ArmCoreRegIdCustom::Unavailable => Ok(0),\n        }\n    }\n\n    fn write_register(\n        &mut self,\n        _tid: (),\n        reg_id: custom_arch::ArmCoreRegIdCustom,\n        val: &[u8],\n    ) -> TargetResult<(), Self> {\n        let w = u32::from_le_bytes(\n            val.try_into()\n                .map_err(|_| TargetError::Fatal(\"invalid data\"))?,\n        );\n        match reg_id {\n            custom_arch::ArmCoreRegIdCustom::Core(reg_id) => {\n                if let Some(i) = cpu_reg_id(reg_id) {\n                    self.cpu.reg_set(self.cpu.mode(), i, w);\n                    Ok(())\n                } else {\n                    Err(().into())\n                }\n            }\n            custom_arch::ArmCoreRegIdCustom::Custom => {\n                self.custom_reg = w;\n                Ok(())\n            }\n            // ignore writes\n            custom_arch::ArmCoreRegIdCustom::Unavailable\n            | custom_arch::ArmCoreRegIdCustom::Time => Ok(()),\n        }\n    }\n}\n\nimpl target::ext::base::reverse_exec::ReverseCont<()> for Emu {\n    fn reverse_cont(&mut self) -> Result<(), Self::Error> {\n        // FIXME: actually implement reverse step\n        eprintln!(\n            \"FIXME: Not actually reverse-continuing. Performing forwards continue instead...\"\n        );\n        self.exec_mode = ExecMode::Continue;\n        Ok(())\n    }\n}\n\nimpl target::ext::base::reverse_exec::ReverseStep<()> for Emu {\n    fn reverse_step(&mut self, _tid: ()) -> Result<(), Self::Error> {\n        // FIXME: actually implement reverse step\n        eprintln!(\n            \"FIXME: Not actually reverse-stepping. Performing single forwards step instead...\"\n        );\n        self.exec_mode = ExecMode::Step;\n        Ok(())\n    }\n}\n\nimpl target::ext::base::singlethread::SingleThreadRangeStepping for Emu {\n    fn resume_range_step(&mut self, start: u32, end: u32) -> Result<(), Self::Error> {\n        self.exec_mode = ExecMode::RangeStep(start, end);\n        Ok(())\n    }\n}\n\nmod custom_arch {\n    use core::num::NonZeroUsize;\n    use gdbstub::arch::lldb::Encoding;\n    use gdbstub::arch::lldb::Format;\n    use gdbstub::arch::lldb::Generic;\n    use gdbstub::arch::lldb::Register;\n    use gdbstub::arch::lldb::RegisterInfo;\n    use gdbstub::arch::Arch;\n    use gdbstub::arch::RegId;\n    use gdbstub::arch::Registers;\n    use gdbstub_arch::arm::reg::id::ArmCoreRegId;\n    use gdbstub_arch::arm::reg::ArmCoreRegs;\n    use gdbstub_arch::arm::ArmBreakpointKind;\n\n    /// Implements `Arch` for ARMv4T\n    pub enum Armv4tCustom {}\n\n    #[derive(Debug, Default, Clone, Eq, PartialEq)]\n    pub struct ArmCoreRegsCustom {\n        pub core: ArmCoreRegs,\n        pub custom: u32,\n    }\n\n    impl Registers for ArmCoreRegsCustom {\n        type ProgramCounter = u32;\n\n        fn pc(&self) -> Self::ProgramCounter {\n            self.core.pc\n        }\n\n        fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {\n            self.core.gdb_serialize(&mut write_byte);\n\n            macro_rules! write_bytes {\n                ($bytes:expr) => {\n                    for b in $bytes {\n                        write_byte(Some(*b))\n                    }\n                };\n            }\n\n            write_bytes!(&self.custom.to_le_bytes());\n        }\n\n        fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {\n            // ensure bytes.chunks_exact(4) won't panic\n            if !bytes.len().is_multiple_of(4) {\n                return Err(());\n            }\n\n            use core::convert::TryInto;\n            let mut regs = bytes\n                .chunks_exact(4)\n                .map(|c| u32::from_le_bytes(c.try_into().unwrap()));\n\n            // copied from ArmCoreRegs\n            {\n                for reg in self.core.r.iter_mut() {\n                    *reg = regs.next().ok_or(())?\n                }\n                self.core.sp = regs.next().ok_or(())?;\n                self.core.lr = regs.next().ok_or(())?;\n                self.core.pc = regs.next().ok_or(())?;\n\n                // Floating point registers (unused)\n                for _ in 0..25 {\n                    regs.next().ok_or(())?;\n                }\n\n                self.core.cpsr = regs.next().ok_or(())?;\n            }\n\n            self.custom = regs.next().ok_or(())?;\n\n            if regs.next().is_some() {\n                return Err(());\n            }\n\n            Ok(())\n        }\n    }\n\n    #[derive(Debug)]\n    pub enum ArmCoreRegIdCustom {\n        Core(ArmCoreRegId),\n        Custom,\n        // not sent as part of `struct ArmCoreRegsCustom`, and only accessible via the single\n        // register read/write functions\n        Time,\n        /// This pseudo-register is valid but never available\n        Unavailable,\n    }\n\n    impl RegId for ArmCoreRegIdCustom {\n        fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> {\n            let reg = match id {\n                26 => Self::Custom,\n                27 => Self::Time,\n                28 => Self::Unavailable,\n                _ => {\n                    let (reg, size) = ArmCoreRegId::from_raw_id(id)?;\n                    return Some((Self::Core(reg), size));\n                }\n            };\n            Some((reg, Some(NonZeroUsize::new(4)?)))\n        }\n    }\n\n    impl Arch for Armv4tCustom {\n        type Usize = u32;\n        type Registers = ArmCoreRegsCustom;\n        type RegId = ArmCoreRegIdCustom;\n        type BreakpointKind = ArmBreakpointKind;\n\n        // for _purely demonstrative purposes_, i'll return dummy data from this\n        // function, as it will be overwritten by TargetDescriptionXmlOverride.\n        //\n        // See `examples/armv4t/gdb/target_description_xml_override.rs`\n        //\n        // in an actual implementation, you'll want to return an actual string here!\n        fn target_description_xml() -> Option<&'static str> {\n            Some(\"never gets returned\")\n        }\n\n        // (LLDB extension)\n        //\n        // for _purely demonstrative purposes_, even though this provides a working\n        // example, it will get overwritten by RegisterInfoOverride.\n        //\n        // See `examples/armv4t/gdb/register_info_override.rs`\n        fn lldb_register_info(reg_id: usize) -> Option<RegisterInfo<'static>> {\n            match ArmCoreRegIdCustom::from_raw_id(reg_id) {\n                Some((_, None)) | None => Some(RegisterInfo::Done),\n                Some((r, Some(size))) => {\n                    let name = match r {\n                        // For the purpose of demonstration, we end the qRegisterInfo packet\n                        // exchange when reaching the Time register id, so that this register can\n                        // only be explicitly queried via the single-register read packet.\n                        ArmCoreRegIdCustom::Time => return Some(RegisterInfo::Done),\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(i)) => match i {\n                            0 => \"r0\",\n                            1 => \"r1\",\n                            2 => \"r2\",\n                            3 => \"r3\",\n                            4 => \"r4\",\n                            5 => \"r5\",\n                            6 => \"r6\",\n                            7 => \"r7\",\n                            8 => \"r8\",\n                            9 => \"r9\",\n                            10 => \"r10\",\n                            11 => \"r11\",\n                            12 => \"r12\",\n                            _ => \"unknown\",\n                        },\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp) => \"sp\",\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Lr) => \"lr\",\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc) => \"pc\",\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Fpr(_i)) => \"padding\",\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Fps) => \"padding\",\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr) => \"cpsr\",\n                        ArmCoreRegIdCustom::Custom => \"custom\",\n                        ArmCoreRegIdCustom::Unavailable => \"Unavailable\",\n                        _ => \"unknown\",\n                    };\n                    let encoding = match r {\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(_i)) => Encoding::Uint,\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp)\n                        | ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc)\n                        | ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr)\n                        | ArmCoreRegIdCustom::Unavailable\n                        | ArmCoreRegIdCustom::Custom => Encoding::Uint,\n                        _ => Encoding::Vector,\n                    };\n                    let format = match r {\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(_i)) => Format::Hex,\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp)\n                        | ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc)\n                        | ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr)\n                        | ArmCoreRegIdCustom::Unavailable\n                        | ArmCoreRegIdCustom::Custom => Format::Hex,\n                        _ => Format::VectorUInt8,\n                    };\n                    let set = match r {\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(_i)) => {\n                            \"General Purpose Registers\"\n                        }\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp)\n                        | ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc)\n                        | ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr)\n                        | ArmCoreRegIdCustom::Unavailable\n                        | ArmCoreRegIdCustom::Custom => \"General Purpose Registers\",\n                        _ => \"Floating Point Registers\",\n                    };\n                    let generic = match r {\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp) => Some(Generic::Sp),\n                        ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc) => Some(Generic::Pc),\n                        _ => None,\n                    };\n                    let reg = Register {\n                        name,\n                        alt_name: None,\n                        bitsize: (usize::from(size)) * 8,\n                        offset: reg_id * (usize::from(size)),\n                        encoding,\n                        format,\n                        set,\n                        gcc: None,\n                        dwarf: Some(reg_id),\n                        generic,\n                        container_regs: None,\n                        invalidate_regs: None,\n                    };\n                    Some(RegisterInfo::Register(reg))\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/gdb/monitor_cmd.rs",
    "content": "use crate::gdb::Emu;\nuse gdbstub::target;\nuse gdbstub::target::ext::monitor_cmd::outputln;\nuse gdbstub::target::ext::monitor_cmd::ConsoleOutput;\n\nimpl target::ext::monitor_cmd::MonitorCmd for Emu {\n    fn handle_monitor_cmd(\n        &mut self,\n        cmd: &[u8],\n        mut out: ConsoleOutput<'_>,\n    ) -> Result<(), Self::Error> {\n        let cmd = match core::str::from_utf8(cmd) {\n            Ok(cmd) => cmd,\n            Err(_) => {\n                outputln!(out, \"command must be valid UTF-8\");\n                return Ok(());\n            }\n        };\n\n        match cmd {\n            \"\" => outputln!(out, \"Sorry, didn't catch that. Try `monitor ping`!\"),\n            \"ping\" => outputln!(out, \"pong!\"),\n            _ => outputln!(out, \"I don't know how to handle '{}'\", cmd),\n        };\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/gdb/section_offsets.rs",
    "content": "use crate::gdb::Emu;\nuse gdbstub::target;\nuse gdbstub::target::ext::section_offsets::Offsets;\n\n// This implementation is for illustrative purposes only. If the offsets are\n// guaranteed to be zero, this extension does not need to be implemented.\n\nimpl target::ext::section_offsets::SectionOffsets for Emu {\n    fn get_section_offsets(&mut self) -> Result<Offsets<u32>, Self::Error> {\n        Ok(Offsets::Sections {\n            text: 0,\n            data: 0,\n            bss: None,\n        })\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/gdb/target_description_xml_override.rs",
    "content": "use super::copy_range_to_buf;\nuse crate::emu::Emu;\nuse gdbstub::target;\nuse gdbstub::target::TargetError;\nuse gdbstub::target::TargetResult;\n\nimpl target::ext::target_description_xml_override::TargetDescriptionXmlOverride for Emu {\n    fn target_description_xml(\n        &self,\n        annex: &[u8],\n        offset: u64,\n        length: usize,\n        buf: &mut [u8],\n    ) -> TargetResult<usize, Self> {\n        let xml = match annex {\n            b\"target.xml\" => TARGET_XML.trim(),\n            b\"extra.xml\" => EXTRA_XML.trim(),\n            _ => return Err(TargetError::NonFatal),\n        };\n\n        Ok(copy_range_to_buf(\n            xml.trim().as_bytes(),\n            offset,\n            length,\n            buf,\n        ))\n    }\n}\n\nconst TARGET_XML: &str = r#\"\n<?xml version=\"1.0\"?>\n<!DOCTYPE target SYSTEM \"gdb-target.dtd\">\n<target version=\"1.0\">\n    <architecture>armv4t</architecture>\n    <feature name=\"org.gnu.gdb.arm.core\">\n        <vector id=\"padding\" type=\"uint32\" count=\"25\"/>\n\n        <reg name=\"r0\" bitsize=\"32\" type=\"uint32\"/>\n        <reg name=\"r1\" bitsize=\"32\" type=\"uint32\"/>\n        <reg name=\"r2\" bitsize=\"32\" type=\"uint32\"/>\n        <reg name=\"r3\" bitsize=\"32\" type=\"uint32\"/>\n        <reg name=\"r4\" bitsize=\"32\" type=\"uint32\"/>\n        <reg name=\"r5\" bitsize=\"32\" type=\"uint32\"/>\n        <reg name=\"r6\" bitsize=\"32\" type=\"uint32\"/>\n        <reg name=\"r7\" bitsize=\"32\" type=\"uint32\"/>\n        <reg name=\"r8\" bitsize=\"32\" type=\"uint32\"/>\n        <reg name=\"r9\" bitsize=\"32\" type=\"uint32\"/>\n        <reg name=\"r10\" bitsize=\"32\" type=\"uint32\"/>\n        <reg name=\"r11\" bitsize=\"32\" type=\"uint32\"/>\n        <reg name=\"r12\" bitsize=\"32\" type=\"uint32\"/>\n        <reg name=\"sp\" bitsize=\"32\" type=\"data_ptr\"/>\n        <reg name=\"lr\" bitsize=\"32\"/>\n        <reg name=\"pc\" bitsize=\"32\" type=\"code_ptr\"/>\n\n        <!--\n            For some reason, my version of `gdb-multiarch` doesn't seem to\n            respect \"regnum\", and will not parse this custom target.xml unless I\n            manually include the padding bytes in the target description.\n\n            On the bright side, AFAIK, there aren't all that many architectures\n            that use padding bytes. Heck, the only reason armv4t uses padding is\n            for historical reasons (see comment below).\n\n            Odds are if you're defining your own custom arch, you won't run into\n            this issue, since you can just lay out all the registers in the\n            correct order.\n        -->\n        <reg name=\"padding\" type=\"padding\" bitsize=\"32\"/>\n\n        <!-- The CPSR is register 25, rather than register 16, because\n        the FPA registers historically were placed between the PC\n        and the CPSR in the \"g\" packet. -->\n        <reg name=\"cpsr\" bitsize=\"32\" regnum=\"25\"/>\n    </feature>\n    <xi:include href=\"extra.xml\"/>\n</target>\n\"#;\n\nconst EXTRA_XML: &str = r#\"\n<?xml version=\"1.0\"?>\n<!DOCTYPE target SYSTEM \"gdb-target.dtd\">\n<feature name=\"custom-armv4t-extension\">\n    <!--\n        maps to a simple scratch register within the emulator. the GDB\n        client can read the register using `p $custom` and set it using\n        `set $custom=1337`\n    -->\n    <reg name=\"custom\" bitsize=\"32\" type=\"uint32\"/>\n\n    <!--\n        pseudo-register that return the current time when read.\n\n        notably, i've set up the target to NOT send this register as part of\n        the regular register list, which means that GDB will fetch/update\n        this register via the 'p' and 'P' packets respectively\n    -->\n    <reg name=\"time\" bitsize=\"32\" type=\"uint32\"/>\n\n    <!--\n        pseudo-register that is always unavailable.\n\n        it is supposed to be reported as 'x'-ed bytes in replies to 'p' packets\n        and shown by the GDB client as \"<unavailable>\".\n    -->\n    <reg name=\"unavailable\" bitsize=\"32\" type=\"uint32\"/>\n</feature>\n\"#;\n"
  },
  {
    "path": "examples/armv4t/gdb/tracepoints.rs",
    "content": "use crate::emu::Emu;\nuse gdbstub::target;\nuse gdbstub::target::ext::tracepoints::ExperimentExplanation;\nuse gdbstub::target::ext::tracepoints::ExperimentStatus;\nuse gdbstub::target::ext::tracepoints::FrameDescription;\nuse gdbstub::target::ext::tracepoints::FrameRequest;\nuse gdbstub::target::ext::tracepoints::NewTracepoint;\nuse gdbstub::target::ext::tracepoints::SourceTracepoint;\nuse gdbstub::target::ext::tracepoints::TraceBufferConfig;\nuse gdbstub::target::ext::tracepoints::Tracepoint;\nuse gdbstub::target::ext::tracepoints::TracepointAction;\nuse gdbstub::target::ext::tracepoints::TracepointEnumerateState;\nuse gdbstub::target::ext::tracepoints::TracepointEnumerateStep;\nuse gdbstub::target::ext::tracepoints::TracepointStatus;\nuse gdbstub::target::TargetError;\nuse gdbstub::target::TargetResult;\n\nimpl Emu {\n    fn step_to_next_tracepoint(&self, tp: Tracepoint) -> TracepointEnumerateStep<u32> {\n        let next_tp = self.tracepoints.range(tp..).nth(1);\n        if let Some((tp, (new_tp, _, _))) = next_tp {\n            TracepointEnumerateStep::Next {\n                tp: *tp,\n                addr: new_tp.addr,\n            }\n        } else {\n            // No more tracepoints\n            TracepointEnumerateStep::Done\n        }\n    }\n}\n\nimpl target::ext::tracepoints::Tracepoints for Emu {\n    fn tracepoints_init(&mut self) -> TargetResult<(), Self> {\n        self.tracepoints.clear();\n        self.traceframes.clear();\n        Ok(())\n    }\n\n    fn tracepoint_create_begin(&mut self, tp: NewTracepoint<u32>) -> TargetResult<(), Self> {\n        self.tracepoints.insert(tp.number, (tp, vec![], vec![]));\n        Ok(())\n    }\n\n    fn tracepoint_create_continue(\n        &mut self,\n        tp: Tracepoint,\n        action: &TracepointAction<'_, u32>,\n    ) -> TargetResult<(), Self> {\n        if let &TracepointAction::Registers { mask: _ } = &action {\n            // we only handle register collection actions for the simple\n            // case\n        } else {\n            return Err(TargetError::NonFatal);\n        }\n        self.tracepoints\n            .get_mut(&tp)\n            .map(move |(_ctp, _source, actions)| actions.push(action.get_owned()))\n            .ok_or(TargetError::Fatal(\"extend on non-existing tracepoint\"))\n    }\n\n    fn tracepoint_create_complete(&mut self, _tp: Tracepoint) -> TargetResult<(), Self> {\n        /* nothing to do */\n        Ok(())\n    }\n\n    fn tracepoint_status(\n        &self,\n        tp: Tracepoint,\n        _addr: u32,\n    ) -> TargetResult<TracepointStatus, Self> {\n        // We don't collect \"real\" trace buffer frames, so just report hit count\n        // and say the number of bytes is always 0.\n        // Because we don't implement \"while-stepping\" actions, we don't need to\n        // also check that `addr` matches.\n        Ok(TracepointStatus {\n            hit_count: self\n                .traceframes\n                .iter()\n                .filter(|frame| frame.number.0 == tp.0)\n                .count() as u64,\n            bytes_used: 0,\n        })\n    }\n\n    fn tracepoint_enumerate_state(&mut self) -> &mut TracepointEnumerateState<u32> {\n        &mut self.tracepoint_enumerate_state\n    }\n\n    fn tracepoint_enumerate_start(\n        &mut self,\n        tp: Option<Tracepoint>,\n        f: &mut dyn FnMut(&NewTracepoint<u32>),\n    ) -> TargetResult<TracepointEnumerateStep<u32>, Self> {\n        let tp = match tp {\n            Some(tp) => tp,\n            None => {\n                // We have no tracepoints to report\n                if self.tracepoints.is_empty() {\n                    return Ok(TracepointEnumerateStep::Done);\n                } else {\n                    // Start enumerating at the first one\n                    *self.tracepoints.keys().next().unwrap()\n                }\n            }\n        };\n\n        // Report our tracepoint\n        (f)(&self.tracepoints[&tp].0);\n\n        let ret = if !self.tracepoints[&tp].1.is_empty() {\n            TracepointEnumerateStep::Source\n        } else if !self.tracepoints[&tp].2.is_empty() {\n            TracepointEnumerateStep::Action\n        } else {\n            TracepointEnumerateStep::Done\n        };\n\n        Ok(ret)\n    }\n\n    fn tracepoint_enumerate_action(\n        &mut self,\n        tp: Tracepoint,\n        step: u64,\n        f: &mut dyn FnMut(&TracepointAction<'_, u32>),\n    ) -> TargetResult<TracepointEnumerateStep<u32>, Self> {\n        // Report our next action\n        (f)(&self.tracepoints[&tp].2[step as usize]);\n\n        let ret = if self.tracepoints[&tp].2.get((step as usize) + 1).is_some() {\n            // Continue stepping\n            TracepointEnumerateStep::Action\n        } else if !self.tracepoints[&tp].1.is_empty() {\n            // We're done with this tracepoint, report source\n            TracepointEnumerateStep::Source\n        } else {\n            // No sources, move to the next tracepoint\n            self.step_to_next_tracepoint(tp)\n        };\n\n        Ok(ret)\n    }\n\n    #[inline(always)]\n    fn support_tracepoint_source(\n        &mut self,\n    ) -> Option<target::ext::tracepoints::TracepointSourceOps<'_, Self>> {\n        Some(self)\n    }\n\n    fn trace_buffer_configure(&mut self, _config: TraceBufferConfig) -> TargetResult<(), Self> {\n        // we don't collect a \"real\" trace buffer, so just ignore configuration\n        // attempts.\n        Ok(())\n    }\n\n    fn trace_buffer_request(\n        &mut self,\n        _offset: u64,\n        _len: usize,\n        _f: &mut dyn FnMut(&mut [u8]),\n    ) -> TargetResult<(), Self> {\n        // We don't have a \"real\" trace buffer, so just don't report any data\n        Ok(())\n    }\n\n    fn trace_experiment_status(\n        &self,\n        report: &mut dyn FnMut(ExperimentStatus<'_>),\n    ) -> TargetResult<(), Self> {\n        // For a bare-bones example, we don't provide in-depth status explanations.\n        (report)(if self.tracing {\n            ExperimentStatus::Running\n        } else {\n            ExperimentStatus::NotRunning\n        });\n        Ok(())\n    }\n\n    fn trace_experiment_info(\n        &self,\n        report: &mut dyn FnMut(ExperimentExplanation<'_>),\n    ) -> TargetResult<(), Self> {\n        (report)(ExperimentExplanation::Frames(self.traceframes.len()));\n\n        Ok(())\n    }\n\n    fn select_frame(\n        &mut self,\n        frame: FrameRequest<u32>,\n        report: &mut dyn FnMut(FrameDescription),\n    ) -> TargetResult<(), Self> {\n        // For a bare-bones example, we only support `tfind <number>` and `tfind\n        // tracepoint <tpnum>` style frame selection and not the more\n        // complicated ones.\n        let found = match frame {\n            FrameRequest::Select(n) => self.traceframes.get(n as usize).map(|frame| (n, frame)),\n            FrameRequest::Hit(tp) => {\n                let start = self\n                    .selected_frame\n                    .map(|selected| selected + 1)\n                    .unwrap_or(0);\n                self.traceframes.get(start..).and_then(|frames| {\n                    frames\n                        .iter()\n                        .enumerate()\n                        .filter(|(_n, frame)| frame.number == tp)\n                        .map(|(n, frame)| ((start + n) as u64, frame))\n                        .next()\n                })\n            }\n            _ => return Err(TargetError::NonFatal),\n        };\n        if let Some((n, frame)) = found {\n            (report)(FrameDescription::FrameNumber(n));\n            (report)(FrameDescription::Hit(frame.number));\n            self.selected_frame = Some(n as usize);\n        } else {\n            self.selected_frame = None;\n        }\n        Ok(())\n    }\n\n    fn trace_experiment_start(&mut self) -> TargetResult<(), Self> {\n        self.tracing = true;\n        Ok(())\n    }\n\n    fn trace_experiment_stop(&mut self) -> TargetResult<(), Self> {\n        self.tracing = false;\n        Ok(())\n    }\n}\n\nimpl target::ext::tracepoints::TracepointSource for Emu {\n    fn tracepoint_enumerate_source(\n        &mut self,\n        tp: Tracepoint,\n        step: u64,\n        f: &mut dyn FnMut(&SourceTracepoint<'_, u32>),\n    ) -> TargetResult<TracepointEnumerateStep<u32>, Self> {\n        // Report our next source item\n        (f)(&self.tracepoints[&tp].1[step as usize]);\n\n        let ret = if self.tracepoints[&tp].1.get((step as usize) + 1).is_some() {\n            // Continue stepping\n            TracepointEnumerateStep::Source\n        } else {\n            // Move to next tracepoint\n            self.step_to_next_tracepoint(tp)\n        };\n\n        Ok(ret)\n    }\n\n    fn tracepoint_attach_source(\n        &mut self,\n        src: SourceTracepoint<'_, u32>,\n    ) -> TargetResult<(), Self> {\n        self.tracepoints\n            .get_mut(&src.number)\n            .unwrap()\n            .1\n            .push(src.get_owned());\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/armv4t/main.rs",
    "content": "//! An incredibly simple emulator to run elf binaries compiled with\n//! `arm-none-eabi-cc -march=armv4t`. It's not modeled after any real-world\n//! system.\n\nuse gdbstub::common::Signal;\nuse gdbstub::conn::Connection;\nuse gdbstub::conn::ConnectionExt;\nuse gdbstub::stub::run_blocking;\nuse gdbstub::stub::DisconnectReason;\nuse gdbstub::stub::GdbStub;\nuse gdbstub::stub::SingleThreadStopReason;\nuse gdbstub::target::Target;\nuse std::net::TcpListener;\nuse std::net::TcpStream;\n#[cfg(unix)]\nuse std::os::unix::net::UnixListener;\n#[cfg(unix)]\nuse std::os::unix::net::UnixStream;\n\ntype DynResult<T> = Result<T, Box<dyn std::error::Error>>;\n\nconst TEST_PROGRAM_ELF: &[u8] = include_bytes!(\"test_bin/test.elf\");\n\nmod emu;\nmod gdb;\nmod mem_sniffer;\n\nfn wait_for_tcp(port: u16) -> DynResult<TcpStream> {\n    let sockaddr = format!(\"127.0.0.1:{}\", port);\n    eprintln!(\"Waiting for a GDB connection on {:?}...\", sockaddr);\n\n    let sock = TcpListener::bind(sockaddr)?;\n    let (stream, addr) = sock.accept()?;\n    eprintln!(\"Debugger connected from {}\", addr);\n\n    Ok(stream)\n}\n\n#[cfg(unix)]\nfn wait_for_uds(path: &str) -> DynResult<UnixStream> {\n    match std::fs::remove_file(path) {\n        Ok(_) => {}\n        Err(e) => match e.kind() {\n            std::io::ErrorKind::NotFound => {}\n            _ => return Err(e.into()),\n        },\n    }\n\n    eprintln!(\"Waiting for a GDB connection on {}...\", path);\n\n    let sock = UnixListener::bind(path)?;\n    let (stream, addr) = sock.accept()?;\n    eprintln!(\"Debugger connected from {:?}\", addr);\n\n    Ok(stream)\n}\n\nenum EmuGdbEventLoop {}\n\nimpl run_blocking::BlockingEventLoop for EmuGdbEventLoop {\n    type Target = emu::Emu;\n    type Connection = Box<dyn ConnectionExt<Error = std::io::Error>>;\n    type StopReason = SingleThreadStopReason<u32>;\n\n    #[allow(clippy::type_complexity)]\n    fn wait_for_stop_reason(\n        target: &mut emu::Emu,\n        conn: &mut Self::Connection,\n    ) -> Result<\n        run_blocking::Event<SingleThreadStopReason<u32>>,\n        run_blocking::WaitForStopReasonError<\n            <Self::Target as Target>::Error,\n            <Self::Connection as Connection>::Error,\n        >,\n    > {\n        // The `armv4t` example runs the emulator in the same thread as the GDB state\n        // machine loop. As such, it uses a simple poll-based model to check for\n        // interrupt events, whereby the emulator will check if there is any incoming\n        // data over the connection, and pause execution with a synthetic\n        // `RunEvent::IncomingData` event.\n        //\n        // In more complex integrations, the target will probably be running in a\n        // separate thread, and instead of using a poll-based model to check for\n        // incoming data, you'll want to use some kind of \"select\" based model to\n        // simultaneously wait for incoming GDB data coming over the connection, along\n        // with any target-reported stop events.\n        //\n        // The specifics of how this \"select\" mechanism work + how the target reports\n        // stop events will entirely depend on your project's architecture.\n        //\n        // Some ideas on how to implement this `select` mechanism:\n        //\n        // - A mpsc channel\n        // - epoll/kqueue\n        // - Running the target + stopping every so often to peek the connection\n        // - Driving `GdbStub` from various interrupt handlers\n\n        let poll_incoming_data = || {\n            // gdbstub takes ownership of the underlying connection, so the `borrow_conn`\n            // method is used to borrow the underlying connection back from the stub to\n            // check for incoming data.\n            conn.peek().map(|b| b.is_some()).unwrap_or(true)\n        };\n\n        match target.run(poll_incoming_data) {\n            emu::RunEvent::IncomingData => {\n                let byte = conn\n                    .read()\n                    .map_err(run_blocking::WaitForStopReasonError::Connection)?;\n                Ok(run_blocking::Event::IncomingData(byte))\n            }\n            emu::RunEvent::Event(event) => {\n                use gdbstub::target::ext::breakpoints::WatchKind;\n\n                // translate emulator stop reason into GDB stop reason\n                let stop_reason = match event {\n                    emu::Event::DoneStep => SingleThreadStopReason::DoneStep,\n                    emu::Event::Halted => SingleThreadStopReason::Terminated(Signal::SIGSTOP),\n                    emu::Event::Break => SingleThreadStopReason::SwBreak(()),\n                    emu::Event::WatchWrite(addr) => SingleThreadStopReason::Watch {\n                        tid: (),\n                        kind: WatchKind::Write,\n                        addr,\n                    },\n                    emu::Event::WatchRead(addr) => SingleThreadStopReason::Watch {\n                        tid: (),\n                        kind: WatchKind::Read,\n                        addr,\n                    },\n                };\n\n                Ok(run_blocking::Event::TargetStopped(stop_reason))\n            }\n        }\n    }\n\n    fn on_interrupt(\n        _target: &mut emu::Emu,\n    ) -> Result<Option<SingleThreadStopReason<u32>>, <emu::Emu as Target>::Error> {\n        // Because this emulator runs as part of the GDB stub loop, there isn't any\n        // special action that needs to be taken to interrupt the underlying target. It\n        // is implicitly paused whenever the stub isn't within the\n        // `wait_for_stop_reason` callback.\n        Ok(Some(SingleThreadStopReason::Signal(Signal::SIGINT)))\n    }\n}\n\nfn main() -> DynResult<()> {\n    pretty_env_logger::init();\n\n    let mut emu = emu::Emu::new(TEST_PROGRAM_ELF)?;\n\n    let connection: Box<dyn ConnectionExt<Error = std::io::Error>> = {\n        if std::env::args().nth(1) == Some(\"--uds\".to_string()) {\n            #[cfg(not(unix))]\n            {\n                return Err(\"Unix Domain Sockets can only be used on Unix\".into());\n            }\n            #[cfg(unix)]\n            {\n                Box::new(wait_for_uds(\"/tmp/armv4t_gdb\")?)\n            }\n        } else {\n            Box::new(wait_for_tcp(9001)?)\n        }\n    };\n\n    let gdb = GdbStub::new(connection);\n\n    match gdb.run_blocking::<EmuGdbEventLoop>(&mut emu) {\n        Ok(disconnect_reason) => match disconnect_reason {\n            DisconnectReason::Disconnect => {\n                println!(\"GDB client has disconnected. Running to completion...\");\n                while emu.step() != Some(emu::Event::Halted) {}\n            }\n            DisconnectReason::TargetExited(code) => {\n                println!(\"Target exited with code {}!\", code)\n            }\n            DisconnectReason::TargetTerminated(sig) => {\n                println!(\"Target terminated with signal {}!\", sig)\n            }\n            DisconnectReason::Kill => println!(\"GDB sent a kill command!\"),\n        },\n        Err(e) => {\n            if e.is_target_error() {\n                println!(\n                    \"target encountered a fatal error: {}\",\n                    e.into_target_error().unwrap()\n                )\n            } else if e.is_connection_error() {\n                let (e, kind) = e.into_connection_error().unwrap();\n                println!(\"connection error: {:?} - {}\", kind, e,)\n            } else {\n                println!(\"gdbstub encountered a fatal error: {}\", e)\n            }\n        }\n    }\n\n    let ret = emu.cpu.reg_get(armv4t_emu::Mode::User, 0);\n    println!(\"Program completed. Return value: {}\", ret);\n\n    Ok(())\n}\n"
  },
  {
    "path": "examples/armv4t/mem_sniffer.rs",
    "content": "use armv4t_emu::Memory;\n\npub enum AccessKind {\n    Read,\n    Write,\n}\n\npub struct Access {\n    pub kind: AccessKind,\n    pub addr: u32,\n    // allow(dead_code) because the emulator is so simple that it doesn't matter\n    #[allow(dead_code)]\n    pub val: u32,\n    #[allow(dead_code)]\n    pub len: usize,\n}\n\n/// Wraps a `Memory` object, logging any accesses with the provided callback.\n#[derive(Debug)]\npub struct MemSniffer<'a, M, F: FnMut(Access)> {\n    mem: &'a mut M,\n    addrs: &'a [u32],\n    on_access: F,\n}\n\nimpl<'a, M: Memory, F: FnMut(Access)> MemSniffer<'a, M, F> {\n    pub fn new(mem: &'a mut M, addrs: &'a [u32], on_access: F) -> MemSniffer<'a, M, F> {\n        MemSniffer {\n            mem,\n            addrs,\n            on_access,\n        }\n    }\n}\n\nmacro_rules! impl_memsniff_r {\n    ($fn:ident, $ret:ty) => {\n        fn $fn(&mut self, addr: u32) -> $ret {\n            let ret = self.mem.$fn(addr);\n            if self.addrs.contains(&addr) {\n                (self.on_access)(Access {\n                    kind: AccessKind::Read,\n                    addr,\n                    val: ret as u32,\n                    len: ret.to_le_bytes().len(),\n                });\n            }\n            ret\n        }\n    };\n}\n\nmacro_rules! impl_memsniff_w {\n    ($fn:ident, $val:ty) => {\n        fn $fn(&mut self, addr: u32, val: $val) {\n            self.mem.$fn(addr, val);\n            if self.addrs.contains(&addr) {\n                (self.on_access)(Access {\n                    kind: AccessKind::Write,\n                    addr,\n                    val: val as u32,\n                    len: val.to_le_bytes().len(),\n                });\n            }\n        }\n    };\n}\n\nimpl<M: Memory, F: FnMut(Access)> Memory for MemSniffer<'_, M, F> {\n    impl_memsniff_r!(r8, u8);\n    impl_memsniff_r!(r16, u16);\n    impl_memsniff_r!(r32, u32);\n    impl_memsniff_w!(w8, u8);\n    impl_memsniff_w!(w16, u16);\n    impl_memsniff_w!(w32, u32);\n}\n"
  },
  {
    "path": "examples/armv4t/test_bin/.gdbinit",
    "content": "# set remote multiprocess-feature-packet off\n\ntarget extended-remote :9001\n"
  },
  {
    "path": "examples/armv4t/test_bin/.gitignore",
    "content": "*.o\n.gdb_history\n"
  },
  {
    "path": "examples/armv4t/test_bin/compile_test.sh",
    "content": "arm-none-eabi-gcc -c test.c -march=armv4t -O0 -g -std=c11 -fdebug-prefix-map=$(pwd)=.\narm-none-eabi-ld -static -Ttest.ld test.o -o test.elf\n"
  },
  {
    "path": "examples/armv4t/test_bin/test.c",
    "content": "int main() {\n    int x = 4;\n    int y = 3;\n\n    x += 1;\n    y += 3;\n\n    // big, useless loop to test ctrl-c functionality\n    for (int i = 0; i < 1024 * 32; i++) {\n        x += 1;\n    }\n\n    return x;\n}\n"
  },
  {
    "path": "examples/armv4t/test_bin/test.ld",
    "content": "ENTRY(main)\n\nMEMORY {\n    ram : ORIGIN = 0x55550000, LENGTH = 0x10000000\n}\n\nSECTIONS {\n    . = 0x55550000;\n\n    .text : ALIGN(4)\n    {\n        __TEXT_START__ = .;\n        *(.text*);\n        . = ALIGN(4);\n        __TEXT_END__ = .;\n    } > ram\n\n    .got : ALIGN(4)\n    {\n        *(.got*);\n    } > ram\n\n    .data : ALIGN(4)\n    {\n        __DATA_START__ = .;\n        *(.data*);\n        *(.rodata*);\n        __DATA_END__ = .;\n    } > ram\n\n    .bss : ALIGN(4)\n    {\n        __BSS_START__ = .;\n        *(.bss*);\n        . = ALIGN(4);\n        __BSS_END__ = .;\n        end = __BSS_END__;\n    } > ram\n\n    /DISCARD/ :\n    {\n        *(.ARM.exidx*) /* index entries for section unwinding */\n        *(.ARM.extab*) /* exception unwinding information */\n    }\n}\n"
  },
  {
    "path": "examples/armv4t_multicore/README.md",
    "content": "# armv4t-multicore\n\nAn incredibly simple emulator to run elf binaries compiled with `arm-none-eabi-cc -march=armv4t`. Uses a dual-core architecture to show off `gdbstub`'s multi-process support. It's not modeled after any real-world system.\n\n**Note:** The actual emulator's code is pretty sloppy, since it's just a contrived example to show off what `gdbstub` is capable of.\n\nRun `gdb-arm-none-eabi` (or alternatively, `gdb-multiarch`) from the `test_bin` directory to automatically connect to the emulator + load debug symbols for the emulated binary.\n\nThis example can be run using:\n\n```bash\ncargo run --example armv4t --features=std\n```\n\n**NOTE:** If debug symbols couldn't be loaded, try rebuilding `test.elf` locally (requires the `arm-none-eabi` toolchain to be installed), and recompiling the example.\n\n## Memory Map\n\nThe entire 32-bit address space is accessible as RAM.\n\nReading from the magic memory location `0xffff_4200` returns `0xaa` if accessed by the CPU, and `0x55` if accessed by the COP.\n\n## Unix Domain Sockets\n\nGDB versions since \\~2018 support running a debugging session over Unix Domain Sockets (UDS). Debugging over UDS can feel much snappier than debugging over loopback TCP.\n\nRunning the example with the `--uds` flag will bind the GdbStub to a socket at `/tmp/armv4t_gdb`.\n\nThis feature is only supported on Unix-like systems.\n"
  },
  {
    "path": "examples/armv4t_multicore/emu.rs",
    "content": "//! ------------------------------------------------------------------------ !//\n//! ------------------------------ DISCLAIMER ------------------------------ !//\n//! ------------------------------------------------------------------------ !//\n//!\n//! This code is absolutely awful, and completely slapped together for the sake\n//! of example. The watchpoint implementation is particularly awful.\n//!\n//! While it technically \"gets the job done\" and provides a simple multicore\n//! system that can be debugged, it would really merit a re-write, since it's\n//! not a good example of \"proper Rust coding practices\"\n\nuse crate::mem_sniffer::AccessKind;\nuse crate::mem_sniffer::MemSniffer;\nuse crate::DynResult;\nuse armv4t_emu::reg;\nuse armv4t_emu::Cpu;\nuse armv4t_emu::ExampleMem;\nuse armv4t_emu::Memory;\nuse armv4t_emu::Mode;\nuse std::collections::HashMap;\n\nconst HLE_RETURN_ADDR: u32 = 0x12345678;\n\n#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]\npub enum CpuId {\n    Cpu,\n    Cop,\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\npub enum Event {\n    DoneStep,\n    Halted,\n    Break,\n    WatchWrite(u32),\n    WatchRead(u32),\n}\n\n#[derive(PartialEq)]\npub enum ExecMode {\n    Step,\n    Continue,\n    Stop,\n}\n\n/// incredibly barebones armv4t-based emulator\npub struct Emu {\n    pub(crate) cpu: Cpu,\n    pub(crate) cop: Cpu,\n    pub(crate) mem: ExampleMem,\n\n    pub(crate) exec_mode: HashMap<CpuId, ExecMode>,\n\n    pub(crate) watchpoints: Vec<u32>,\n    /// (read, write)\n    pub(crate) watchpoint_kind: HashMap<u32, (bool, bool)>,\n    pub(crate) breakpoints: Vec<u32>,\n\n    // GDB seems to get gets very confused if two threads are executing the exact same code at the\n    // exact same time. Maybe this is a bug with `gdbstub`?\n    stall_cop_cycles: usize,\n}\n\nimpl Emu {\n    pub fn new(program_elf: &[u8]) -> DynResult<Emu> {\n        // set up emulated system\n        let mut cpu = Cpu::new();\n        let mut mem = ExampleMem::new();\n\n        // load ELF\n        let elf_header = goblin::elf::Elf::parse(program_elf)?;\n\n        // copy all in-memory sections from the ELF file into system RAM\n        let sections = elf_header\n            .section_headers\n            .iter()\n            .filter(|h| h.is_alloc() && h.sh_type != goblin::elf::section_header::SHT_NOBITS);\n\n        for h in sections {\n            eprintln!(\n                \"loading section {:?} into memory from [{:#010x?}..{:#010x?}]\",\n                elf_header.shdr_strtab.get_at(h.sh_name).unwrap(),\n                h.sh_addr,\n                h.sh_addr + h.sh_size,\n            );\n\n            for (i, b) in program_elf[h.file_range().unwrap()].iter().enumerate() {\n                mem.w8(h.sh_addr as u32 + i as u32, *b);\n            }\n        }\n\n        // setup execution state\n        eprintln!(\"Setting PC to {:#010x?}\", elf_header.entry);\n        cpu.reg_set(Mode::User, reg::SP, 0x10000000);\n        cpu.reg_set(Mode::User, reg::LR, HLE_RETURN_ADDR);\n        cpu.reg_set(Mode::User, reg::PC, elf_header.entry as u32);\n        cpu.reg_set(Mode::User, reg::CPSR, 0x10); // user mode\n        let cop = cpu;\n\n        Ok(Emu {\n            cpu,\n            cop,\n            mem,\n\n            exec_mode: HashMap::new(),\n\n            watchpoints: Vec::new(),\n            watchpoint_kind: HashMap::new(),\n            breakpoints: Vec::new(),\n\n            stall_cop_cycles: 24,\n        })\n    }\n\n    pub fn step_core(&mut self, id: CpuId) -> Option<Event> {\n        let cpu = match id {\n            CpuId::Cop if self.stall_cop_cycles != 0 => {\n                self.stall_cop_cycles -= 1;\n                return None;\n            }\n            CpuId::Cop => &mut self.cop,\n            CpuId::Cpu => &mut self.cpu,\n        };\n\n        // set up magic memory location\n        self.mem.w8(\n            0xffff_4200,\n            match id {\n                CpuId::Cpu => 0xaa,\n                CpuId::Cop => 0x55,\n            },\n        );\n\n        let mut hit_watchpoint = None;\n        let mut sniffer = MemSniffer::new(&mut self.mem, &self.watchpoints, |access| {\n            hit_watchpoint = Some(access)\n        });\n\n        cpu.step(&mut sniffer);\n        let pc = cpu.reg_get(Mode::User, reg::PC);\n\n        if pc == HLE_RETURN_ADDR {\n            match id {\n                CpuId::Cpu => return Some(Event::Halted),\n                CpuId::Cop => return Some(Event::Halted),\n            }\n        }\n\n        if let Some(access) = hit_watchpoint {\n            // NOTE: this isn't a particularly elegant way to do watchpoints! This works\n            // fine for some example code, but don't use this as inspiration in your own\n            // emulator!\n            match access.kind {\n                AccessKind::Read => {\n                    if *self\n                        .watchpoint_kind\n                        .get(&access.addr)\n                        .map(|(r, _w)| r)\n                        .unwrap_or(&false)\n                    {\n                        let fixup = if cpu.thumb_mode() { 2 } else { 4 };\n                        cpu.reg_set(Mode::User, reg::PC, pc - fixup);\n                        return Some(Event::WatchRead(access.addr));\n                    }\n                }\n                AccessKind::Write => {\n                    if *self\n                        .watchpoint_kind\n                        .get(&access.addr)\n                        .map(|(_r, w)| w)\n                        .unwrap_or(&false)\n                    {\n                        let fixup = if cpu.thumb_mode() { 2 } else { 4 };\n                        cpu.reg_set(Mode::User, reg::PC, pc - fixup);\n                        return Some(Event::WatchWrite(access.addr));\n                    }\n                }\n            }\n        }\n\n        if self.breakpoints.contains(&pc) {\n            return Some(Event::Break);\n        }\n\n        None\n    }\n\n    pub fn step(&mut self) -> Option<(Event, CpuId)> {\n        let mut evt = None;\n\n        for id in [CpuId::Cpu, CpuId::Cop].iter().copied() {\n            if matches!(self.exec_mode.get(&id), Some(ExecMode::Stop)) {\n                continue;\n            }\n\n            if let Some(event) = self.step_core(id) {\n                if evt.is_none() {\n                    evt = Some((event, id));\n                }\n            }\n        }\n\n        evt\n    }\n\n    pub fn run(&mut self, mut poll_incoming_data: impl FnMut() -> bool) -> RunEvent {\n        // The underlying armv4t_multicore emulator cycles all cores in lock-step.\n        //\n        // Inside `self.step()`, we iterate through all cores and only invoke\n        // `step_core` if that core's `ExecMode` is not `Stop`.\n\n        let should_single_step = self.exec_mode.values().any(|mode| mode == &ExecMode::Step);\n\n        match should_single_step {\n            true => match self.step() {\n                Some((event, id)) => RunEvent::Event(event, id),\n                None => {\n                    let stepping_core = self\n                        .exec_mode\n                        .iter()\n                        .find(|&(_, mode)| mode == &ExecMode::Step)\n                        .map(|(id, _)| *id)\n                        .unwrap_or(CpuId::Cpu);\n                    RunEvent::Event(Event::DoneStep, stepping_core)\n                }\n            },\n            false => {\n                let mut cycles = 0;\n                loop {\n                    if cycles % 1024 == 0 {\n                        // poll for incoming data\n                        if poll_incoming_data() {\n                            break RunEvent::IncomingData;\n                        }\n                    }\n                    cycles += 1;\n\n                    if let Some((event, id)) = self.step() {\n                        break RunEvent::Event(event, id);\n                    };\n                }\n            }\n        }\n    }\n}\n\npub enum RunEvent {\n    Event(Event, CpuId),\n    IncomingData,\n}\n"
  },
  {
    "path": "examples/armv4t_multicore/gdb.rs",
    "content": "use crate::emu::CpuId;\nuse crate::emu::Emu;\nuse crate::emu::ExecMode;\nuse armv4t_emu::reg;\nuse armv4t_emu::Memory;\nuse gdbstub::common::Signal;\nuse gdbstub::common::Tid;\nuse gdbstub::target;\nuse gdbstub::target::ext::base::multithread::MultiThreadBase;\nuse gdbstub::target::ext::base::multithread::MultiThreadResume;\nuse gdbstub::target::ext::breakpoints::WatchKind;\nuse gdbstub::target::Target;\nuse gdbstub::target::TargetError;\nuse gdbstub::target::TargetResult;\n\npub fn cpuid_to_tid(id: CpuId) -> Tid {\n    match id {\n        CpuId::Cpu => Tid::new(1).unwrap(),\n        CpuId::Cop => Tid::new(2).unwrap(),\n    }\n}\n\nfn tid_to_cpuid(tid: Tid) -> Result<CpuId, &'static str> {\n    match tid.get() {\n        1 => Ok(CpuId::Cpu),\n        2 => Ok(CpuId::Cop),\n        _ => Err(\"specified invalid core\"),\n    }\n}\n\nimpl Target for Emu {\n    type Arch = gdbstub_arch::arm::Armv4t;\n    type Error = &'static str;\n\n    #[inline(always)]\n    fn base_ops(&mut self) -> target::ext::base::BaseOps<'_, Self::Arch, Self::Error> {\n        target::ext::base::BaseOps::MultiThread(self)\n    }\n\n    #[inline(always)]\n    fn support_breakpoints(\n        &mut self,\n    ) -> Option<target::ext::breakpoints::BreakpointsOps<'_, Self>> {\n        Some(self)\n    }\n}\n\nimpl MultiThreadBase for Emu {\n    fn read_registers(\n        &mut self,\n        regs: &mut gdbstub_arch::arm::reg::ArmCoreRegs,\n        tid: Tid,\n    ) -> TargetResult<(), Self> {\n        let cpu = match tid_to_cpuid(tid).map_err(TargetError::Fatal)? {\n            CpuId::Cpu => &mut self.cpu,\n            CpuId::Cop => &mut self.cop,\n        };\n\n        let mode = cpu.mode();\n\n        for i in 0..13 {\n            regs.r[i] = cpu.reg_get(mode, i as u8);\n        }\n        regs.sp = cpu.reg_get(mode, reg::SP);\n        regs.lr = cpu.reg_get(mode, reg::LR);\n        regs.pc = cpu.reg_get(mode, reg::PC);\n        regs.cpsr = cpu.reg_get(mode, reg::CPSR);\n\n        Ok(())\n    }\n\n    fn write_registers(\n        &mut self,\n        regs: &gdbstub_arch::arm::reg::ArmCoreRegs,\n        tid: Tid,\n    ) -> TargetResult<(), Self> {\n        let cpu = match tid_to_cpuid(tid).map_err(TargetError::Fatal)? {\n            CpuId::Cpu => &mut self.cpu,\n            CpuId::Cop => &mut self.cop,\n        };\n\n        let mode = cpu.mode();\n\n        for i in 0..13 {\n            cpu.reg_set(mode, i, regs.r[i as usize]);\n        }\n        cpu.reg_set(mode, reg::SP, regs.sp);\n        cpu.reg_set(mode, reg::LR, regs.lr);\n        cpu.reg_set(mode, reg::PC, regs.pc);\n        cpu.reg_set(mode, reg::CPSR, regs.cpsr);\n\n        Ok(())\n    }\n\n    fn read_addrs(\n        &mut self,\n        start_addr: u32,\n        data: &mut [u8],\n        _tid: Tid, // same address space for each core\n    ) -> TargetResult<usize, Self> {\n        for (addr, val) in (start_addr..).zip(data.iter_mut()) {\n            *val = self.mem.r8(addr)\n        }\n        Ok(data.len())\n    }\n\n    fn write_addrs(\n        &mut self,\n        start_addr: u32,\n        data: &[u8],\n        _tid: Tid, // same address space for each core\n    ) -> TargetResult<(), Self> {\n        for (addr, val) in (start_addr..).zip(data.iter().copied()) {\n            self.mem.w8(addr, val)\n        }\n        Ok(())\n    }\n\n    fn list_active_threads(\n        &mut self,\n        register_thread: &mut dyn FnMut(Tid),\n    ) -> Result<(), Self::Error> {\n        register_thread(cpuid_to_tid(CpuId::Cpu));\n        register_thread(cpuid_to_tid(CpuId::Cop));\n        Ok(())\n    }\n\n    #[inline(always)]\n    fn support_resume(\n        &mut self,\n    ) -> Option<target::ext::base::multithread::MultiThreadResumeOps<'_, Self>> {\n        Some(self)\n    }\n\n    #[inline(always)]\n    fn support_thread_extra_info(\n        &mut self,\n    ) -> Option<gdbstub::target::ext::thread_extra_info::ThreadExtraInfoOps<'_, Self>> {\n        Some(self)\n    }\n}\n\nimpl MultiThreadResume for Emu {\n    fn resume(&mut self) -> Result<(), Self::Error> {\n        // Upon returning from the `resume` method, the target being debugged should be\n        // configured to run according to whatever resume actions the GDB client has\n        // specified (as specified by `set_resume_action`, `set_resume_range_step`,\n        // `set_reverse_{step, continue}`, etc...)\n        //\n        // In this basic `armv4t_multicore` example, the `resume` method is actually a\n        // no-op, as the execution mode of the emulator's interpreter loop has already\n        // been modified via the various `set_X` methods.\n        //\n        // In more complex implementations, it's likely that the target being debugged\n        // will be running in another thread / process, and will require some kind of\n        // external \"orchestration\" to set it's execution mode (e.g: modifying the\n        // target's process state via platform specific debugging syscalls).\n\n        Ok(())\n    }\n\n    fn clear_resume_actions(&mut self) -> Result<(), Self::Error> {\n        self.exec_mode.clear();\n        Ok(())\n    }\n\n    #[inline(always)]\n    fn support_single_step(\n        &mut self,\n    ) -> Option<target::ext::base::multithread::MultiThreadSingleStepOps<'_, Self>> {\n        Some(self)\n    }\n\n    fn set_resume_action_continue(\n        &mut self,\n        tid: Tid,\n        signal: Option<Signal>,\n    ) -> Result<(), Self::Error> {\n        if signal.is_some() {\n            return Err(\"no support for continuing with signal\");\n        }\n\n        self.exec_mode\n            .insert(tid_to_cpuid(tid)?, ExecMode::Continue);\n\n        Ok(())\n    }\n\n    #[inline(always)]\n    fn support_scheduler_locking(\n        &mut self,\n    ) -> Option<target::ext::base::multithread::MultiThreadSchedulerLockingOps<'_, Self>> {\n        Some(self)\n    }\n}\n\nimpl target::ext::base::multithread::MultiThreadSingleStep for Emu {\n    fn set_resume_action_step(\n        &mut self,\n        tid: Tid,\n        signal: Option<Signal>,\n    ) -> Result<(), Self::Error> {\n        if signal.is_some() {\n            return Err(\"no support for stepping with signal\");\n        }\n\n        self.exec_mode.insert(tid_to_cpuid(tid)?, ExecMode::Step);\n\n        Ok(())\n    }\n}\n\nimpl target::ext::breakpoints::Breakpoints for Emu {\n    fn support_sw_breakpoint(\n        &mut self,\n    ) -> Option<target::ext::breakpoints::SwBreakpointOps<'_, Self>> {\n        Some(self)\n    }\n\n    fn support_hw_watchpoint(\n        &mut self,\n    ) -> Option<target::ext::breakpoints::HwWatchpointOps<'_, Self>> {\n        Some(self)\n    }\n}\n\nimpl target::ext::breakpoints::SwBreakpoint for Emu {\n    fn add_sw_breakpoint(\n        &mut self,\n        addr: u32,\n        _kind: gdbstub_arch::arm::ArmBreakpointKind,\n    ) -> TargetResult<bool, Self> {\n        self.breakpoints.push(addr);\n        Ok(true)\n    }\n\n    fn remove_sw_breakpoint(\n        &mut self,\n        addr: u32,\n        _kind: gdbstub_arch::arm::ArmBreakpointKind,\n    ) -> TargetResult<bool, Self> {\n        match self.breakpoints.iter().position(|x| *x == addr) {\n            None => return Ok(false),\n            Some(pos) => self.breakpoints.remove(pos),\n        };\n\n        Ok(true)\n    }\n}\n\nimpl target::ext::breakpoints::HwWatchpoint for Emu {\n    fn add_hw_watchpoint(\n        &mut self,\n        addr: u32,\n        _len: u32, // TODO: properly handle `len` parameter\n        kind: WatchKind,\n    ) -> TargetResult<bool, Self> {\n        self.watchpoints.push(addr);\n\n        let entry = self.watchpoint_kind.entry(addr).or_insert((false, false));\n        match kind {\n            WatchKind::Write => entry.1 = true,\n            WatchKind::Read => entry.0 = true,\n            WatchKind::ReadWrite => entry.0 = true, // arbitrary\n        };\n\n        Ok(true)\n    }\n\n    fn remove_hw_watchpoint(\n        &mut self,\n        addr: u32,\n        _len: u32, // TODO: properly handle `len` parameter\n        kind: WatchKind,\n    ) -> TargetResult<bool, Self> {\n        let entry = self.watchpoint_kind.entry(addr).or_insert((false, false));\n        match kind {\n            WatchKind::Write => entry.1 = false,\n            WatchKind::Read => entry.0 = false,\n            WatchKind::ReadWrite => entry.0 = false, // arbitrary\n        };\n\n        if !self.watchpoint_kind.contains_key(&addr) {\n            let pos = match self.watchpoints.iter().position(|x| *x == addr) {\n                None => return Ok(false),\n                Some(pos) => pos,\n            };\n            self.watchpoints.remove(pos);\n        }\n\n        Ok(true)\n    }\n}\n\nimpl target::ext::thread_extra_info::ThreadExtraInfo for Emu {\n    fn thread_extra_info(&self, tid: Tid, buf: &mut [u8]) -> Result<usize, Self::Error> {\n        let cpu_id = tid_to_cpuid(tid)?;\n        let info = format!(\"CPU {:?}\", cpu_id);\n\n        Ok(copy_to_buf(info.as_bytes(), buf))\n    }\n}\n\nimpl target::ext::base::multithread::MultiThreadSchedulerLocking for Emu {\n    fn set_resume_action_scheduler_lock(&mut self) -> Result<(), Self::Error> {\n        for id in [CpuId::Cpu, CpuId::Cop] {\n            self.exec_mode.entry(id).or_insert(ExecMode::Stop);\n        }\n        Ok(())\n    }\n}\n\n/// Copy all bytes of `data` to `buf`.\n/// Return the size of data copied.\npub fn copy_to_buf(data: &[u8], buf: &mut [u8]) -> usize {\n    let len = buf.len().min(data.len());\n    buf[..len].copy_from_slice(&data[..len]);\n    len\n}\n"
  },
  {
    "path": "examples/armv4t_multicore/main.rs",
    "content": "//! An incredibly simple emulator to run elf binaries compiled with\n//! `arm-none-eabi-cc -march=armv4t`. Uses a dual-core architecture to show off\n//! `gdbstub`'s multi-process support. It's not modeled after any real-world\n//! system.\n\nuse gdbstub::common::Signal;\nuse gdbstub::conn::Connection;\nuse gdbstub::conn::ConnectionExt;\nuse gdbstub::stub::run_blocking;\nuse gdbstub::stub::DisconnectReason;\nuse gdbstub::stub::GdbStub;\nuse gdbstub::stub::MultiThreadStopReason;\nuse gdbstub::target::Target;\nuse std::net::TcpListener;\nuse std::net::TcpStream;\n#[cfg(unix)]\nuse std::os::unix::net::UnixListener;\n#[cfg(unix)]\nuse std::os::unix::net::UnixStream;\n\ntype DynResult<T> = Result<T, Box<dyn std::error::Error>>;\n\nstatic TEST_PROGRAM_ELF: &[u8] = include_bytes!(\"test_bin/test.elf\");\n\nmod emu;\nmod gdb;\nmod mem_sniffer;\n\nfn wait_for_tcp(port: u16) -> DynResult<TcpStream> {\n    let sockaddr = format!(\"127.0.0.1:{}\", port);\n    eprintln!(\"Waiting for a GDB connection on {:?}...\", sockaddr);\n\n    let sock = TcpListener::bind(sockaddr)?;\n    let (stream, addr) = sock.accept()?;\n    eprintln!(\"Debugger connected from {}\", addr);\n\n    Ok(stream)\n}\n\n#[cfg(unix)]\nfn wait_for_uds(path: &str) -> DynResult<UnixStream> {\n    match std::fs::remove_file(path) {\n        Ok(_) => {}\n        Err(e) => match e.kind() {\n            std::io::ErrorKind::NotFound => {}\n            _ => return Err(e.into()),\n        },\n    }\n\n    eprintln!(\"Waiting for a GDB connection on {}...\", path);\n\n    let sock = UnixListener::bind(path)?;\n    let (stream, addr) = sock.accept()?;\n    eprintln!(\"Debugger connected from {:?}\", addr);\n\n    Ok(stream)\n}\n\nenum EmuGdbEventLoop {}\n\nimpl run_blocking::BlockingEventLoop for EmuGdbEventLoop {\n    type Target = emu::Emu;\n    type Connection = Box<dyn ConnectionExt<Error = std::io::Error>>;\n    type StopReason = MultiThreadStopReason<u32>;\n\n    #[allow(clippy::type_complexity)]\n    fn wait_for_stop_reason(\n        target: &mut emu::Emu,\n        conn: &mut Self::Connection,\n    ) -> Result<\n        run_blocking::Event<Self::StopReason>,\n        run_blocking::WaitForStopReasonError<\n            <Self::Target as Target>::Error,\n            <Self::Connection as Connection>::Error,\n        >,\n    > {\n        // The `armv4t_multicore` example runs the emulator in the same thread as the\n        // GDB state machine loop. As such, it uses a simple poll-based model to\n        // check for interrupt events, whereby the emulator will check if there\n        // is any incoming data over the connection, and pause execution with a\n        // synthetic `RunEvent::IncomingData` event.\n        //\n        // In more complex integrations, the target will probably be running in a\n        // separate thread, and instead of using a poll-based model to check for\n        // incoming data, you'll want to use some kind of \"select\" based model to\n        // simultaneously wait for incoming GDB data coming over the connection, along\n        // with any target-reported stop events.\n        //\n        // The specifics of how this \"select\" mechanism work + how the target reports\n        // stop events will entirely depend on your project's architecture.\n        //\n        // Some ideas on how to implement this `select` mechanism:\n        //\n        // - A mpsc channel\n        // - epoll/kqueue\n        // - Running the target + stopping every so often to peek the connection\n        // - Driving `GdbStub` from various interrupt handlers\n\n        let poll_incoming_data = || {\n            // gdbstub takes ownership of the underlying connection, so the `borrow_conn`\n            // method is used to borrow the underlying connection back from the stub to\n            // check for incoming data.\n            conn.peek().map(|b| b.is_some()).unwrap_or(true)\n        };\n\n        match target.run(poll_incoming_data) {\n            emu::RunEvent::IncomingData => {\n                let byte = conn\n                    .read()\n                    .map_err(run_blocking::WaitForStopReasonError::Connection)?;\n                Ok(run_blocking::Event::IncomingData(byte))\n            }\n            emu::RunEvent::Event(event, cpuid) => {\n                use gdbstub::target::ext::breakpoints::WatchKind;\n\n                // translate emulator stop reason into GDB stop reason\n                let tid = gdb::cpuid_to_tid(cpuid);\n                let stop_reason = match event {\n                    emu::Event::DoneStep => MultiThreadStopReason::DoneStep,\n                    emu::Event::Halted => MultiThreadStopReason::Terminated(Signal::SIGSTOP),\n                    emu::Event::Break => MultiThreadStopReason::SwBreak(tid),\n                    emu::Event::WatchWrite(addr) => MultiThreadStopReason::Watch {\n                        tid,\n                        kind: WatchKind::Write,\n                        addr,\n                    },\n                    emu::Event::WatchRead(addr) => MultiThreadStopReason::Watch {\n                        tid,\n                        kind: WatchKind::Read,\n                        addr,\n                    },\n                };\n\n                Ok(run_blocking::Event::TargetStopped(stop_reason))\n            }\n        }\n    }\n\n    fn on_interrupt(\n        _target: &mut emu::Emu,\n    ) -> Result<Option<MultiThreadStopReason<u32>>, <emu::Emu as Target>::Error> {\n        // Because this emulator runs as part of the GDB stub loop, there isn't any\n        // special action that needs to be taken to interrupt the underlying target. It\n        // is implicitly paused whenever the stub isn't within the\n        // `wait_for_stop_reason` callback.\n        Ok(Some(MultiThreadStopReason::Signal(Signal::SIGINT)))\n    }\n}\n\nfn main() -> DynResult<()> {\n    pretty_env_logger::init();\n\n    let mut emu = emu::Emu::new(TEST_PROGRAM_ELF)?;\n\n    let connection: Box<dyn ConnectionExt<Error = std::io::Error>> = {\n        if std::env::args().nth(1) == Some(\"--uds\".to_string()) {\n            #[cfg(not(unix))]\n            {\n                return Err(\"Unix Domain Sockets can only be used on Unix\".into());\n            }\n            #[cfg(unix)]\n            {\n                Box::new(wait_for_uds(\"/tmp/armv4t_gdb\")?)\n            }\n        } else {\n            Box::new(wait_for_tcp(9001)?)\n        }\n    };\n\n    let gdb = GdbStub::new(connection);\n\n    match gdb.run_blocking::<EmuGdbEventLoop>(&mut emu) {\n        Ok(disconnect_reason) => match disconnect_reason {\n            DisconnectReason::Disconnect => {\n                println!(\"GDB client has disconnected. Running to completion...\");\n                while emu.step() != Some((emu::Event::Halted, emu::CpuId::Cpu)) {}\n            }\n            DisconnectReason::TargetExited(code) => {\n                println!(\"Target exited with code {}!\", code)\n            }\n            DisconnectReason::TargetTerminated(sig) => {\n                println!(\"Target terminated with signal {}!\", sig)\n            }\n            DisconnectReason::Kill => println!(\"GDB sent a kill command!\"),\n        },\n        Err(e) => {\n            if e.is_target_error() {\n                println!(\n                    \"target encountered a fatal error: {}\",\n                    e.into_target_error().unwrap()\n                )\n            } else if e.is_connection_error() {\n                let (e, kind) = e.into_connection_error().unwrap();\n                println!(\"connection error: {:?} - {}\", kind, e,)\n            } else {\n                println!(\"gdbstub encountered a fatal error: {}\", e)\n            }\n        }\n    }\n\n    let ret = emu.cpu.reg_get(armv4t_emu::Mode::User, 0);\n    println!(\"Program completed. Return value: {}\", ret);\n\n    Ok(())\n}\n"
  },
  {
    "path": "examples/armv4t_multicore/mem_sniffer.rs",
    "content": "use armv4t_emu::Memory;\n\n#[derive(Debug)]\npub enum AccessKind {\n    Read,\n    Write,\n}\n\n#[derive(Debug)]\npub struct Access {\n    pub kind: AccessKind,\n    pub addr: u32,\n    // allow(dead_code) because the emulator is so simple that it doesn't matter\n    #[allow(dead_code)]\n    pub val: u32,\n    #[allow(dead_code)]\n    pub len: usize,\n}\n\n/// Wraps a `Memory` object, logging any accesses with the provided callback.\n#[derive(Debug)]\npub struct MemSniffer<'a, M, F: FnMut(Access)> {\n    mem: &'a mut M,\n    addrs: &'a [u32],\n    on_access: F,\n}\n\nimpl<'a, M: Memory, F: FnMut(Access)> MemSniffer<'a, M, F> {\n    pub fn new(mem: &'a mut M, addrs: &'a [u32], on_access: F) -> MemSniffer<'a, M, F> {\n        MemSniffer {\n            mem,\n            addrs,\n            on_access,\n        }\n    }\n}\n\nmacro_rules! impl_memsniff_r {\n    ($fn:ident, $ret:ty) => {\n        fn $fn(&mut self, addr: u32) -> $ret {\n            let ret = self.mem.$fn(addr);\n            if self.addrs.contains(&addr) {\n                (self.on_access)(Access {\n                    kind: AccessKind::Read,\n                    addr,\n                    val: ret as u32,\n                    len: ret.to_le_bytes().len(),\n                });\n            }\n            ret\n        }\n    };\n}\n\nmacro_rules! impl_memsniff_w {\n    ($fn:ident, $val:ty) => {\n        fn $fn(&mut self, addr: u32, val: $val) {\n            self.mem.$fn(addr, val);\n            if self.addrs.contains(&addr) {\n                (self.on_access)(Access {\n                    kind: AccessKind::Write,\n                    addr,\n                    val: val as u32,\n                    len: val.to_le_bytes().len(),\n                });\n            }\n        }\n    };\n}\n\nimpl<M: Memory, F: FnMut(Access)> Memory for MemSniffer<'_, M, F> {\n    impl_memsniff_r!(r8, u8);\n    impl_memsniff_r!(r16, u16);\n    impl_memsniff_r!(r32, u32);\n    impl_memsniff_w!(w8, u8);\n    impl_memsniff_w!(w16, u16);\n    impl_memsniff_w!(w32, u32);\n}\n"
  },
  {
    "path": "examples/armv4t_multicore/test_bin/.gdbinit",
    "content": "file test.elf\ntarget remote :9001\n"
  },
  {
    "path": "examples/armv4t_multicore/test_bin/.gitignore",
    "content": "*.o\n.gdb_history\n"
  },
  {
    "path": "examples/armv4t_multicore/test_bin/compile_test.sh",
    "content": "arm-none-eabi-gcc -c test.c -march=armv4t -O0 -g -std=c11 -fdebug-prefix-map=$(pwd)=.\narm-none-eabi-ld -static -Ttest.ld test.o -o test.elf\n"
  },
  {
    "path": "examples/armv4t_multicore/test_bin/test.c",
    "content": "#define CPU_ID *((volatile unsigned char*)0xffff4200)\n\nint main() {\n    // try switching between threads using `thread 1` and `thread 2`!\n    int done = 0;\n    int x = 0;\n\n    // diverging paths on each CPU core\n    if (CPU_ID == 0xaa) {\n        while (!done) {}\n        return x;\n    } else {\n        // big, useless loop to test ctrl-c functionality\n        for (int i = 0; i < 1024 * 32; i++) {\n            x += 1;\n        }\n        done = 1;\n        // loop forever\n        for (;;) {}\n    }\n}\n"
  },
  {
    "path": "examples/armv4t_multicore/test_bin/test.ld",
    "content": "ENTRY(main)\n\nMEMORY {\n    ram : ORIGIN = 0x55550000, LENGTH = 0x10000000\n}\n\nSECTIONS {\n    . = 0x55550000;\n\n    .text : ALIGN(4)\n    {\n        __TEXT_START__ = .;\n        *(.text*);\n        . = ALIGN(4);\n        __TEXT_END__ = .;\n    } > ram\n\n    .got : ALIGN(4)\n    {\n        *(.got*);\n    } > ram\n\n    .data : ALIGN(4)\n    {\n        __DATA_START__ = .;\n        *(.data*);\n        *(.rodata*);\n        __DATA_END__ = .;\n    } > ram\n\n    .bss : ALIGN(4)\n    {\n        __BSS_START__ = .;\n        *(.bss*);\n        . = ALIGN(4);\n        __BSS_END__ = .;\n        end = __BSS_END__;\n    } > ram\n\n    /DISCARD/ :\n    {\n        *(.ARM.exidx*) /* index entries for section unwinding */\n        *(.ARM.extab*) /* exception unwinding information */\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/CHANGELOG.md",
    "content": "All notable changes to this project will be documented in this file.\n\nThis project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n# 0.3.3\n\n- Add support for Wasm [\\#192](https://github.com/daniel5151/gdbstub/pull/192) ([cfallin](https://github.com/cfallin))\n\n# 0.3.2\n\n- x86: Remove \"padding\" bytes from x86 register packet [\\#171](https://github.com/daniel5151/gdbstub/pull/171) ([cadmic](https://github.com/cadmic))\n\n# 0.3.1\n\n- RISC-V: List all integer registers (for lldb compatibility) [\\#149](https://github.com/daniel5151/gdbstub/pull/149) ([danlehmann](https://github.com/danlehmann))\n\n# 0.3.0\n\n#### Breaking Arch Changes\n\n- Entirely removed `SingleStepGdbBehavior` APIs\n\n# 0.2.4\n\n- Add support for AArch64 [\\#109](https://github.com/daniel5151/gdbstub/pull/109) ([ptosi](https://github.com/ptosi))\n\n# 0.2.3\n\n- Fix missing reg_id mapping in `Armv4t` (24 => Fps)\n\n# 0.2.2\n\n- Remove faulty target.xml from mips64 arch\n\n# 0.2.1\n\n- Removed all remaining instances of `SingleStepGdbBehavior::Unknown` [\\#95](https://github.com/daniel5151/gdbstub/pull/95) ([bet4it](https://github.com/bet4it))\n\n# 0.2.0\n\n**Bumps required `gdbstub` version to 0.6.0**.\n\n#### Breaking Arch Changes\n\n- Improved support + fixes for `Msp430` [\\#62](https://github.com/daniel5151/gdbstub/pull/62) ([mchesser](https://github.com/mchesser))\n- `X86_64CoreRegId`: Change rip size to 8 [\\#87](https://github.com/daniel5151/gdbstub/pull/87) ([gz](https://github.com/gz))\n- Removed `RegId` template parameters from the following `Arch` implementations:\n  - x86/x64\n  - MIPS\n  - MSP-430\n\n# 0.1.0\n\n**Bumps required `gdbstub` version to 0.5.0**.\n\n- **`gdbstub::arch` has been moved into a separate `gdbstub_arch` crate**\n  - _See [\\#45](https://github.com/daniel5151/gdbstub/issues/45) for details on why this was done._\n- (x86) Break GPRs & SRs into individual fields/variants [\\#34](https://github.com/daniel5151/gdbstub/issues/34)\n"
  },
  {
    "path": "gdbstub_arch/Cargo.toml",
    "content": "[package]\nname = \"gdbstub_arch\"\ndescription = \"Implementations of `gdbstub::arch::Arch` for various architectures.\"\nauthors = [\"Daniel Prilik <danielprilik@gmail.com>\"]\nversion = \"0.3.3\"\nlicense = \"MIT OR Apache-2.0\"\nedition = \"2018\"\nreadme = \"README.md\"\ndocumentation = \"https://docs.rs/gdbstub_arch\"\nhomepage = \"https://github.com/daniel5151/gdbstub\"\nrepository  = \"https://github.com/daniel5151/gdbstub\"\nkeywords = [\"gdb\", \"emulation\", \"no_std\", \"debugging\"]\ncategories = [\"development-tools::debugging\", \"embedded\", \"emulators\", \"no-std\"]\n\n[dependencies]\ngdbstub = { path = \"../\", version = \"0.7\", default-features = false }\n\nnum-traits = { version = \"0.2\", default-features = false }\n"
  },
  {
    "path": "gdbstub_arch/LICENSE",
    "content": "gdbstub_arch is dual-licensed under either\n\n* MIT License (../docs/LICENSE-MIT or http://opensource.org/licenses/MIT)\n* Apache License, Version 2.0 (../docs/LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)\n\nat your option.\n"
  },
  {
    "path": "gdbstub_arch/README.md",
    "content": "# gdbstub_arch\n\n[![](https://img.shields.io/crates/v/gdbstub_arch.svg)](https://crates.io/crates/gdbstub_arch)\n[![](https://docs.rs/gdbstub_arch/badge.svg)](https://docs.rs/gdbstub_arch)\n[![](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)](./LICENSE)\n\nCommunity-contributed implementations of `gdbstub::arch::Arch` for various\narchitectures.\n\n_Note:_ If an architecture is missing from this crate, that does _not_ mean\nthat it can't be used with `gdbstub`! So-long as there's support for the\ntarget architecture in GDB, it should be fairly straightforward to implement\n`Arch` manually.\n\nPlease consider upstreaming any missing `Arch` implementations you happen to\nimplement yourself! Aside from the altruistic motive of improving `gdbstub`,\nupstreaming your `Arch` implementation will ensure that it's kept up-to-date\nwith any future breaking API changes.\n\n**Disclaimer:** These implementations are all community contributions, and\nwhile they are tested (by the PR's author) and code-reviewed, it's not\nparticularly feasible to write detailed tests for each architecture! If you\nspot a bug in any of the implementations, please file an issue / open a PR!\n"
  },
  {
    "path": "gdbstub_arch/src/aarch64/core.xml",
    "content": "<feature name=\"org.gnu.gdb.aarch64.core\">\n\n<!-- source: binutils-gdb/blob/master/gdb/features/aarch64-core.xml -->\n\n<!-- Copyright (C) 2009-2022 Free Software Foundation, Inc.\n     Contributed by ARM Ltd.\n     Copying and distribution of this file, with or without modification,\n     are permitted in any medium without royalty provided the copyright\n     notice and this notice are preserved.  -->\n\n  <reg name=\"x0\" bitsize=\"64\"/>\n  <reg name=\"x1\" bitsize=\"64\"/>\n  <reg name=\"x2\" bitsize=\"64\"/>\n  <reg name=\"x3\" bitsize=\"64\"/>\n  <reg name=\"x4\" bitsize=\"64\"/>\n  <reg name=\"x5\" bitsize=\"64\"/>\n  <reg name=\"x6\" bitsize=\"64\"/>\n  <reg name=\"x7\" bitsize=\"64\"/>\n  <reg name=\"x8\" bitsize=\"64\"/>\n  <reg name=\"x9\" bitsize=\"64\"/>\n  <reg name=\"x10\" bitsize=\"64\"/>\n  <reg name=\"x11\" bitsize=\"64\"/>\n  <reg name=\"x12\" bitsize=\"64\"/>\n  <reg name=\"x13\" bitsize=\"64\"/>\n  <reg name=\"x14\" bitsize=\"64\"/>\n  <reg name=\"x15\" bitsize=\"64\"/>\n  <reg name=\"x16\" bitsize=\"64\"/>\n  <reg name=\"x17\" bitsize=\"64\"/>\n  <reg name=\"x18\" bitsize=\"64\"/>\n  <reg name=\"x19\" bitsize=\"64\"/>\n  <reg name=\"x20\" bitsize=\"64\"/>\n  <reg name=\"x21\" bitsize=\"64\"/>\n  <reg name=\"x22\" bitsize=\"64\"/>\n  <reg name=\"x23\" bitsize=\"64\"/>\n  <reg name=\"x24\" bitsize=\"64\"/>\n  <reg name=\"x25\" bitsize=\"64\"/>\n  <reg name=\"x26\" bitsize=\"64\"/>\n  <reg name=\"x27\" bitsize=\"64\"/>\n  <reg name=\"x28\" bitsize=\"64\"/>\n  <reg name=\"x29\" bitsize=\"64\"/>\n  <reg name=\"x30\" bitsize=\"64\"/>\n  <reg name=\"sp\" bitsize=\"64\" type=\"data_ptr\"/>\n\n  <reg name=\"pc\" bitsize=\"64\" type=\"code_ptr\"/>\n\n  <flags id=\"cpsr_flags\" size=\"4\">\n    <!-- Stack Pointer.  -->\n    <field name=\"SP\" start=\"0\" end=\"0\"/>\n\n    <!-- Exception Level.  -->\n    <field name=\"EL\" start=\"2\" end=\"3\"/>\n    <!-- Execution state.  -->\n    <field name=\"nRW\" start=\"4\" end=\"4\"/>\n\n    <!-- FIQ interrupt mask.  -->\n    <field name=\"F\" start=\"6\" end=\"6\"/>\n    <!-- IRQ interrupt mask.  -->\n    <field name=\"I\" start=\"7\" end=\"7\"/>\n    <!-- SError interrupt mask.  -->\n    <field name=\"A\" start=\"8\" end=\"8\"/>\n    <!-- Debug exception mask.  -->\n    <field name=\"D\" start=\"9\" end=\"9\"/>\n\n    <!-- ARMv8.5-A: Branch Target Identification BTYPE.  -->\n    <field name=\"BTYPE\" start=\"10\" end=\"11\"/>\n\n    <!-- ARMv8.0-A: Speculative Store Bypass.  -->\n    <field name=\"SSBS\" start=\"12\" end=\"12\"/>\n\n    <!-- Illegal Execution state.  -->\n    <field name=\"IL\" start=\"20\" end=\"20\"/>\n    <!-- Software Step.  -->\n    <field name=\"SS\" start=\"21\" end=\"21\"/>\n    <!-- ARMv8.1-A: Privileged Access Never.  -->\n    <field name=\"PAN\" start=\"22\" end=\"22\"/>\n    <!-- ARMv8.2-A: User Access Override.  -->\n    <field name=\"UAO\" start=\"23\" end=\"23\"/>\n    <!-- ARMv8.4-A: Data Independent Timing.  -->\n    <field name=\"DIT\" start=\"24\" end=\"24\"/>\n    <!-- ARMv8.5-A: Tag Check Override.  -->\n    <field name=\"TCO\" start=\"25\" end=\"25\"/>\n\n    <!-- Overflow Condition flag.  -->\n    <field name=\"V\" start=\"28\" end=\"28\"/>\n    <!-- Carry Condition flag.  -->\n    <field name=\"C\" start=\"29\" end=\"29\"/>\n    <!-- Zero Condition flag.  -->\n    <field name=\"Z\" start=\"30\" end=\"30\"/>\n    <!-- Negative Condition flag.  -->\n    <field name=\"N\" start=\"31\" end=\"31\"/>\n  </flags>\n  <reg name=\"cpsr\" bitsize=\"32\" type=\"cpsr_flags\"/>\n\n</feature>\n"
  },
  {
    "path": "gdbstub_arch/src/aarch64/fpu.xml",
    "content": "<feature name=\"org.gnu.gdb.aarch64.fpu\">\n\n  <!-- source: binutils-gdb/blob/master/gdb/features/aarch64-fpu.xml -->\n\n  <!-- Copyright (C) 2009-2022 Free Software Foundation, Inc.\n       Contributed by ARM Ltd.\n       Copying and distribution of this file, with or without modification,\n       are permitted in any medium without royalty provided the copyright\n       notice and this notice are preserved.  -->\n\n  <vector id=\"v2d\" type=\"ieee_double\" count=\"2\"/>\n  <vector id=\"v2u\" type=\"uint64\" count=\"2\"/>\n  <vector id=\"v2i\" type=\"int64\" count=\"2\"/>\n  <vector id=\"v4f\" type=\"ieee_single\" count=\"4\"/>\n  <vector id=\"v4u\" type=\"uint32\" count=\"4\"/>\n  <vector id=\"v4i\" type=\"int32\" count=\"4\"/>\n  <vector id=\"v8f\" type=\"ieee_half\" count=\"8\"/>\n  <vector id=\"v8u\" type=\"uint16\" count=\"8\"/>\n  <vector id=\"v8i\" type=\"int16\" count=\"8\"/>\n  <vector id=\"v8bf16\" type=\"bfloat16\" count=\"8\"/>\n  <vector id=\"v16u\" type=\"uint8\" count=\"16\"/>\n  <vector id=\"v16i\" type=\"int8\" count=\"16\"/>\n  <vector id=\"v1u\" type=\"uint128\" count=\"1\"/>\n  <vector id=\"v1i\" type=\"int128\" count=\"1\"/>\n  <union id=\"vnd\">\n    <field name=\"f\" type=\"v2d\"/>\n    <field name=\"u\" type=\"v2u\"/>\n    <field name=\"s\" type=\"v2i\"/>\n  </union>\n  <union id=\"vns\">\n    <field name=\"f\" type=\"v4f\"/>\n    <field name=\"u\" type=\"v4u\"/>\n    <field name=\"s\" type=\"v4i\"/>\n  </union>\n  <union id=\"vnh\">\n    <field name=\"bf\" type=\"v8bf16\"/>\n    <field name=\"f\" type=\"v8f\"/>\n    <field name=\"u\" type=\"v8u\"/>\n    <field name=\"s\" type=\"v8i\"/>\n  </union>\n  <union id=\"vnb\">\n    <field name=\"u\" type=\"v16u\"/>\n    <field name=\"s\" type=\"v16i\"/>\n  </union>\n  <union id=\"vnq\">\n    <field name=\"u\" type=\"v1u\"/>\n    <field name=\"s\" type=\"v1i\"/>\n  </union>\n  <union id=\"aarch64v\">\n    <field name=\"d\" type=\"vnd\"/>\n    <field name=\"s\" type=\"vns\"/>\n    <field name=\"h\" type=\"vnh\"/>\n    <field name=\"b\" type=\"vnb\"/>\n    <field name=\"q\" type=\"vnq\"/>\n  </union>\n  <reg name=\"v0\" bitsize=\"128\" type=\"aarch64v\" regnum=\"34\"/>\n  <reg name=\"v1\" bitsize=\"128\" type=\"aarch64v\" />\n  <reg name=\"v2\" bitsize=\"128\" type=\"aarch64v\" />\n  <reg name=\"v3\" bitsize=\"128\" type=\"aarch64v\" />\n  <reg name=\"v4\" bitsize=\"128\" type=\"aarch64v\" />\n  <reg name=\"v5\" bitsize=\"128\" type=\"aarch64v\" />\n  <reg name=\"v6\" bitsize=\"128\" type=\"aarch64v\" />\n  <reg name=\"v7\" bitsize=\"128\" type=\"aarch64v\" />\n  <reg name=\"v8\" bitsize=\"128\" type=\"aarch64v\" />\n  <reg name=\"v9\" bitsize=\"128\" type=\"aarch64v\" />\n  <reg name=\"v10\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v11\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v12\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v13\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v14\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v15\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v16\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v17\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v18\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v19\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v20\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v21\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v22\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v23\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v24\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v25\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v26\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v27\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v28\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v29\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v30\" bitsize=\"128\" type=\"aarch64v\"/>\n  <reg name=\"v31\" bitsize=\"128\" type=\"aarch64v\"/>\n\n  <flags id=\"fpsr_flags\" size=\"4\">\n    <!-- Invalid Operation cumulative floating-point exception bit.  -->\n    <field name=\"IOC\" start=\"0\" end=\"0\"/>\n    <!-- Divide by Zero cumulative floating-point exception bit.  -->\n    <field name=\"DZC\" start=\"1\" end=\"1\"/>\n    <!-- Overflow cumulative floating-point exception bit.  -->\n    <field name=\"OFC\" start=\"2\" end=\"2\"/>\n    <!-- Underflow cumulative floating-point exception bit.  -->\n    <field name=\"UFC\" start=\"3\" end=\"3\"/>\n    <!-- Inexact cumulative floating-point exception bit..  -->\n    <field name=\"IXC\" start=\"4\" end=\"4\"/>\n    <!-- Input Denormal cumulative floating-point exception bit.  -->\n    <field name=\"IDC\" start=\"7\" end=\"7\"/>\n    <!-- Cumulative saturation bit, Advanced SIMD only.  -->\n    <field name=\"QC\" start=\"27\" end=\"27\"/>\n    <!-- When AArch32 is supported at any Exception level and AArch32\n         floating-point is implemented: Overflow condition flag for AArch32\n         floating-point comparison operations.  -->\n    <field name=\"V\" start=\"28\" end=\"28\"/>\n    <!-- When AArch32 is supported at any Exception level and AArch32\n         floating-point is implemented:\n         Carry condition flag for AArch32 floating-point comparison operations.\n         -->\n    <field name=\"C\" start=\"29\" end=\"29\"/>\n    <!-- When AArch32 is supported at any Exception level and AArch32\n         floating-point is implemented:\n         Zero condition flag for AArch32 floating-point comparison operations.\n         -->\n    <field name=\"Z\" start=\"30\" end=\"30\"/>\n    <!-- When AArch32 is supported at any Exception level and AArch32\n         floating-point is implemented:\n         Negative condition flag for AArch32 floating-point comparison\n         operations.  -->\n    <field name=\"N\" start=\"31\" end=\"31\"/>\n  </flags>\n  <reg name=\"fpsr\" bitsize=\"32\" type=\"fpsr_flags\"/>\n\n  <flags id=\"fpcr_flags\" size=\"4\">\n    <!-- Flush Inputs to Zero (part of Armv8.7).  -->\n    <field name=\"FIZ\" start=\"0\" end=\"0\"/>\n    <!-- Alternate Handling (part of Armv8.7).  -->\n    <field name=\"AH\" start=\"1\" end=\"1\"/>\n    <!-- Controls how the output elements other than the lowest element of the\n         vector are determined for Advanced SIMD scalar instructions (part of\n         Armv8.7).  -->\n    <field name=\"NEP\" start=\"2\" end=\"2\"/>\n    <!-- Invalid Operation floating-point exception trap enable.  -->\n    <field name=\"IOE\" start=\"8\" end=\"8\"/>\n    <!-- Divide by Zero floating-point exception trap enable.  -->\n    <field name=\"DZE\" start=\"9\" end=\"9\"/>\n    <!-- Overflow floating-point exception trap enable.  -->\n    <field name=\"OFE\" start=\"10\" end=\"10\"/>\n    <!-- Underflow floating-point exception trap enable.  -->\n    <field name=\"UFE\" start=\"11\" end=\"11\"/>\n    <!-- Inexact floating-point exception trap enable.  -->\n    <field name=\"IXE\" start=\"12\" end=\"12\"/>\n    <!-- Input Denormal floating-point exception trap enable.  -->\n    <field name=\"IDE\" start=\"15\" end=\"15\"/>\n    <!-- Flush-to-zero mode control bit on half-precision data-processing\n         instructions.  -->\n    <field name=\"FZ16\" start=\"19\" end=\"19\"/>\n    <!-- Rounding Mode control field.  -->\n    <field name=\"RMode\" start=\"22\" end=\"23\"/>\n    <!-- Flush-to-zero mode control bit.  -->\n    <field name=\"FZ\" start=\"24\" end=\"24\"/>\n    <!-- Default NaN mode control bit.  -->\n    <field name=\"DN\" start=\"25\" end=\"25\"/>\n    <!-- Alternative half-precision control bit.  -->\n    <field name=\"AHP\" start=\"26\" end=\"26\"/>\n  </flags>\n  <reg name=\"fpcr\" bitsize=\"32\" type=\"fpcr_flags\"/>\n</feature>\n"
  },
  {
    "path": "gdbstub_arch/src/aarch64/mod.rs",
    "content": "//! Implementation for the [AArch64](https://developer.arm.com/documentation/102374)\n//! ARM architecture.\n//!\n//! See PR [#109](https://github.com/daniel5151/gdbstub/pull/109) for more info.\n//!\n//! *Note*: doesn't support the AArch32 execution mode.\n//! *Note*: the target XML currently advertises all system registers to the GDB\n//! client.\n\nuse gdbstub::arch::Arch;\n\npub mod reg;\n\n/// Implements `Arch` for ARM AArch64.\npub struct AArch64 {}\n\nimpl Arch for AArch64 {\n    type Usize = u64;\n    type Registers = reg::AArch64CoreRegs;\n    type RegId = reg::id::AArch64RegId;\n    type BreakpointKind = usize;\n\n    fn target_description_xml() -> Option<&'static str> {\n        static DESCRIPTION_XML: &str = concat!(\n            r#\"<target version=\"1.0\">\"#,\n            \"<architecture>aarch64</architecture>\",\n            include_str!(\"core.xml\"), // feature \"org.gnu.gdb.aarch64.core\"\n            include_str!(\"fpu.xml\"),  // feature \"org.gnu.gdb.aarch64.fpu\"\n            include_str!(\"sysregs.xml\"),\n            \"</target>\",\n        );\n\n        Some(DESCRIPTION_XML)\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/aarch64/reg/aarch64_core.rs",
    "content": "use core::convert::TryInto;\nuse gdbstub::arch::Registers;\n\n/// AArch64 core registers.\n///\n/// Registers from the `org.gnu.gdb.aarch64.core` and `org.gnu.gdb.aarch64.fpu`\n/// [AArch64 Standard GDB Target Features](https://sourceware.org/gdb/onlinedocs/gdb/AArch64-Features.html).\n#[derive(Debug, Default, Clone, Eq, PartialEq)]\npub struct AArch64CoreRegs {\n    /// General Purpose Registers (X0-X30)\n    pub x: [u64; 31],\n    /// Stack Pointer\n    pub sp: u64,\n    /// Program Counter\n    pub pc: u64,\n    /// Process State (GDB uses the AArch32 CPSR name)\n    pub cpsr: u32,\n    /// FP & SIMD Registers (V0-V31)\n    pub v: [u128; 32],\n    /// Floating-point Control Register\n    pub fpcr: u32,\n    /// Floating-point Status Register\n    pub fpsr: u32,\n}\n\nimpl Registers for AArch64CoreRegs {\n    type ProgramCounter = u64;\n\n    fn pc(&self) -> Self::ProgramCounter {\n        self.pc\n    }\n\n    fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {\n        macro_rules! write_bytes {\n            ($var: expr) => {\n                for b in $var.to_le_bytes() {\n                    write_byte(Some(b))\n                }\n            };\n        }\n\n        for reg in self.x.iter() {\n            write_bytes!(reg);\n        }\n        write_bytes!(self.sp);\n        write_bytes!(self.pc);\n        write_bytes!(self.cpsr);\n        for reg in self.v.iter() {\n            write_bytes!(reg);\n        }\n        write_bytes!(self.fpcr);\n        write_bytes!(self.fpsr);\n    }\n\n    fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {\n        const CPSR_OFF: usize = core::mem::size_of::<u64>() * 33;\n        const FPSIMD_OFF: usize = CPSR_OFF + core::mem::size_of::<u32>();\n        const FPCR_OFF: usize = FPSIMD_OFF + core::mem::size_of::<u128>() * 32;\n        const END: usize = FPCR_OFF + core::mem::size_of::<u32>() * 2;\n\n        if bytes.len() < END {\n            return Err(());\n        }\n\n        let mut regs = bytes[0..CPSR_OFF]\n            .chunks_exact(core::mem::size_of::<u64>())\n            .map(|c| u64::from_le_bytes(c.try_into().unwrap()));\n\n        for reg in self.x.iter_mut() {\n            *reg = regs.next().ok_or(())?\n        }\n        self.sp = regs.next().ok_or(())?;\n        self.pc = regs.next().ok_or(())?;\n\n        let mut regs = bytes[CPSR_OFF..FPSIMD_OFF]\n            .chunks_exact(core::mem::size_of::<u32>())\n            .map(|c| u32::from_le_bytes(c.try_into().unwrap()));\n\n        self.cpsr = regs.next().ok_or(())?;\n\n        let mut regs = bytes[FPSIMD_OFF..FPCR_OFF]\n            .chunks_exact(core::mem::size_of::<u128>())\n            .map(|c| u128::from_le_bytes(c.try_into().unwrap()));\n\n        for reg in self.v.iter_mut() {\n            *reg = regs.next().ok_or(())?\n        }\n\n        let mut regs = bytes[FPCR_OFF..]\n            .chunks_exact(core::mem::size_of::<u32>())\n            .map(|c| u32::from_le_bytes(c.try_into().unwrap()));\n\n        self.fpcr = regs.next().ok_or(())?;\n        self.fpsr = regs.next().ok_or(())?;\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/aarch64/reg/id.rs",
    "content": "use core::num::NonZeroUsize;\nuse gdbstub::arch::RegId;\n\n/// AArch64 Architectural Registers.\n///\n/// Represents architectural registers as\n///\n/// - individual variants for those described in section B1.2. _Registers in\n///   AArch64 Execution state_ of the Architecture Reference Manual (DDI\n///   0487H.a), accessed through their own respective subsets of instructions\n///   _e.g._ GPRs, FP & SIMD, ...\n/// - a generic variant for system registers, accessed through MSR/MRS\n///   instructions, based on their encoding as described in section C5.1. _The\n///   System instruction class encoding space_ when `op0` is `0b10` (_Debug and\n///   trace registers_) or `0b11` (_Non-debug System registers_ and\n///   _Special-purpose registers_), as `0b0x` do not encode registers;\n/// - a variant for the abstraction of process state information, `PSTATE`\n///   (section D1.4.), which should be preferred over field-specific\n///   special-purpose registers (`NZCV`, `DAIF`, ...)\n///\n/// Provides `const` aliases for most system registers as syntactic sugar for\n/// the `System` variant. When those aren't available (_e.g._ for newly-added\n/// registers), the literal representation `System(0baa_bbb_xxxx_yyyy_cc)` may\n/// be used, similarly to the standard assembly symbol,\n/// `S<op0>_<op1>_<CRn>_<CRm>_<op2>`.\n///\n/// To future-proof and greatly simplify the implementation, the target's XML\n/// must encode system registers by using their 16-bit encoding as the `regnum`\n/// property; no clash with architectural registers is possible as the top bit\n/// of the 16-bit value is guaranteed to be set.\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\n#[non_exhaustive]\npub enum AArch64RegId {\n    /// General-purpose Register File (X0 - X30)\n    X(u8),\n    /// Stack Pointer\n    Sp,\n    /// Program Counter\n    Pc,\n    /// Process State (Pseudo-Register)\n    Pstate,\n    /// SIMD & FP Register File (V0 - V31)\n    V(u8),\n    /// System Registers encoded as (Op0:2, Op1:3, CRn:4, CRm:4, Op2:2)\n    System(u16),\n}\n\nimpl RegId for AArch64RegId {\n    fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> {\n        let reg = match id {\n            0..=30 => Self::X(id as u8),\n            31 => Self::Sp,\n            32 => Self::Pc,\n            33 => Self::Pstate,\n            34..=65 => Self::V((id - 34) as u8),\n            66 => Self::FPSR,\n            67 => Self::FPCR,\n            #[allow(clippy::unusual_byte_groupings)]\n            // We configure GDB to use regnums that correspond to the architectural u16 opcode\n            // and avoid clashes with core registers thanks to op0==0b00 and op0==0b01 not being\n            // allocated for system registers.\n            0b10_000_0000_0000_000..=0b11_111_1111_1111_111 => Self::System(id as u16),\n            _ => return None,\n        };\n\n        Some((reg, Some(NonZeroUsize::new(reg.len()?)?)))\n    }\n}\n\n#[allow(clippy::unusual_byte_groupings)]\nimpl AArch64RegId {\n    #[allow(clippy::len_without_is_empty)]\n    /// Gives the size of the register.\n    pub fn len(&self) -> Option<usize> {\n        match self {\n            Self::Pstate => Some(core::mem::size_of::<u32>()),\n            Self::X(_n @ 0..=30) => Some(core::mem::size_of::<u64>()),\n            Self::V(_n @ 0..=31) => Some(core::mem::size_of::<u128>()),\n            Self::Pc | Self::Sp | Self::System(_) => Some(core::mem::size_of::<u64>()),\n            _ => None,\n        }\n    }\n\n    /// Main ID Register\n    pub const MIDR_EL1: Self = Self::System(0b11_000_0000_0000_000);\n    /// Multiprocessor Affinity Register\n    pub const MPIDR_EL1: Self = Self::System(0b11_000_0000_0000_101);\n    /// Revision ID Register\n    pub const REVIDR_EL1: Self = Self::System(0b11_000_0000_0000_110);\n    /// AArch32 Processor Feature Register 0\n    pub const ID_PFR0_EL1: Self = Self::System(0b11_000_0000_0001_000);\n    /// AArch32 Processor Feature Register 1\n    pub const ID_PFR1_EL1: Self = Self::System(0b11_000_0000_0001_001);\n    /// AArch32 Debug Feature Register 0\n    pub const ID_DFR0_EL1: Self = Self::System(0b11_000_0000_0001_010);\n    /// AArch32 Auxiliary Feature Register 0\n    pub const ID_AFR0_EL1: Self = Self::System(0b11_000_0000_0001_011);\n    /// AArch32 Memory Model Feature Register 0\n    pub const ID_MMFR0_EL1: Self = Self::System(0b11_000_0000_0001_100);\n    /// AArch32 Memory Model Feature Register 1\n    pub const ID_MMFR1_EL1: Self = Self::System(0b11_000_0000_0001_101);\n    /// AArch32 Memory Model Feature Register 2\n    pub const ID_MMFR2_EL1: Self = Self::System(0b11_000_0000_0001_110);\n    /// AArch32 Memory Model Feature Register 3\n    pub const ID_MMFR3_EL1: Self = Self::System(0b11_000_0000_0001_111);\n    /// AArch32 Instruction Set Attribute Register 0\n    pub const ID_ISAR0_EL1: Self = Self::System(0b11_000_0000_0010_000);\n    /// AArch32 Instruction Set Attribute Register 1\n    pub const ID_ISAR1_EL1: Self = Self::System(0b11_000_0000_0010_001);\n    /// AArch32 Instruction Set Attribute Register 2\n    pub const ID_ISAR2_EL1: Self = Self::System(0b11_000_0000_0010_010);\n    /// AArch32 Instruction Set Attribute Register 3\n    pub const ID_ISAR3_EL1: Self = Self::System(0b11_000_0000_0010_011);\n    /// AArch32 Instruction Set Attribute Register 4\n    pub const ID_ISAR4_EL1: Self = Self::System(0b11_000_0000_0010_100);\n    /// AArch32 Instruction Set Attribute Register 5\n    pub const ID_ISAR5_EL1: Self = Self::System(0b11_000_0000_0010_101);\n    /// AArch32 Memory Model Feature Register 4\n    pub const ID_MMFR4_EL1: Self = Self::System(0b11_000_0000_0010_110);\n    /// AArch32 Instruction Set Attribute Register 6\n    pub const ID_ISAR6_EL1: Self = Self::System(0b11_000_0000_0010_111);\n    /// AArch32 Media And VFP Feature Register 0\n    pub const MVFR0_EL1: Self = Self::System(0b11_000_0000_0011_000);\n    /// AArch32 Media And VFP Feature Register 1\n    pub const MVFR1_EL1: Self = Self::System(0b11_000_0000_0011_001);\n    /// AArch32 Media And VFP Feature Register 2\n    pub const MVFR2_EL1: Self = Self::System(0b11_000_0000_0011_010);\n    /// AArch32 Processor Feature Register 2\n    pub const ID_PFR2_EL1: Self = Self::System(0b11_000_0000_0011_100);\n    /// Debug Feature Register 1\n    pub const ID_DFR1_EL1: Self = Self::System(0b11_000_0000_0011_101);\n    /// AArch32 Memory Model Feature Register 5\n    pub const ID_MMFR5_EL1: Self = Self::System(0b11_000_0000_0011_110);\n    /// AArch64 Processor Feature Register 0\n    pub const ID_AA64PFR0_EL1: Self = Self::System(0b11_000_0000_0100_000);\n    /// AArch64 Processor Feature Register 1\n    pub const ID_AA64PFR1_EL1: Self = Self::System(0b11_000_0000_0100_001);\n    /// SVE Feature ID Register 0\n    pub const ID_AA64ZFR0_EL1: Self = Self::System(0b11_000_0000_0100_100);\n    /// SME Feature ID Register 0\n    pub const ID_AA64SMFR0_EL1: Self = Self::System(0b11_000_0000_0100_101);\n    /// AArch64 Debug Feature Register 0\n    pub const ID_AA64DFR0_EL1: Self = Self::System(0b11_000_0000_0101_000);\n    /// AArch64 Debug Feature Register 1\n    pub const ID_AA64DFR1_EL1: Self = Self::System(0b11_000_0000_0101_001);\n    /// AArch64 Auxiliary Feature Register 0\n    pub const ID_AA64AFR0_EL1: Self = Self::System(0b11_000_0000_0101_100);\n    /// AArch64 Auxiliary Feature Register 1\n    pub const ID_AA64AFR1_EL1: Self = Self::System(0b11_000_0000_0101_101);\n    /// AArch64 Instruction Set Attribute Register 0\n    pub const ID_AA64ISAR0_EL1: Self = Self::System(0b11_000_0000_0110_000);\n    /// AArch64 Instruction Set Attribute Register 1\n    pub const ID_AA64ISAR1_EL1: Self = Self::System(0b11_000_0000_0110_001);\n    /// AArch64 Instruction Set Attribute Register 2\n    pub const ID_AA64ISAR2_EL1: Self = Self::System(0b11_000_0000_0110_010);\n    /// AArch64 Memory Model Feature Register 0\n    pub const ID_AA64MMFR0_EL1: Self = Self::System(0b11_000_0000_0111_000);\n    /// AArch64 Memory Model Feature Register 1\n    pub const ID_AA64MMFR1_EL1: Self = Self::System(0b11_000_0000_0111_001);\n    /// AArch64 Memory Model Feature Register 2\n    pub const ID_AA64MMFR2_EL1: Self = Self::System(0b11_000_0000_0111_010);\n    /// System Control Register (EL1)\n    pub const SCTLR_EL1: Self = Self::System(0b11_000_0001_0000_000);\n    /// Auxiliary Control Register (EL1)\n    pub const ACTLR_EL1: Self = Self::System(0b11_000_0001_0000_001);\n    /// Architectural Feature Access Control Register\n    pub const CPACR_EL1: Self = Self::System(0b11_000_0001_0000_010);\n    /// Random Allocation Tag Seed Register\n    pub const RGSR_EL1: Self = Self::System(0b11_000_0001_0000_101);\n    /// Tag Control Register\n    pub const GCR_EL1: Self = Self::System(0b11_000_0001_0000_110);\n    /// SVE Control Register (EL1)\n    pub const ZCR_EL1: Self = Self::System(0b11_000_0001_0010_000);\n    /// Trace Filter Control Register (EL1)\n    pub const TRFCR_EL1: Self = Self::System(0b11_000_0001_0010_001);\n    /// Streaming Mode Priority Register\n    pub const SMPRI_EL1: Self = Self::System(0b11_000_0001_0010_100);\n    /// SME Control Register (EL1)\n    pub const SMCR_EL1: Self = Self::System(0b11_000_0001_0010_110);\n    /// Translation Table Base Register 0 (EL1)\n    pub const TTBR0_EL1: Self = Self::System(0b11_000_0010_0000_000);\n    /// Translation Table Base Register 1 (EL1)\n    pub const TTBR1_EL1: Self = Self::System(0b11_000_0010_0000_001);\n    /// Translation Control Register (EL1)\n    pub const TCR_EL1: Self = Self::System(0b11_000_0010_0000_010);\n    /// Pointer Authentication Key A For Instruction (bits\\[63:0])\n    pub const APIAKEYLO_EL1: Self = Self::System(0b11_000_0010_0001_000);\n    /// Pointer Authentication Key A For Instruction (bits\\[127:64])\n    pub const APIAKEYHI_EL1: Self = Self::System(0b11_000_0010_0001_001);\n    /// Pointer Authentication Key B For Instruction (bits\\[63:0])\n    pub const APIBKEYLO_EL1: Self = Self::System(0b11_000_0010_0001_010);\n    /// Pointer Authentication Key B For Instruction (bits\\[127:64])\n    pub const APIBKEYHI_EL1: Self = Self::System(0b11_000_0010_0001_011);\n    /// Pointer Authentication Key A For Data (bits\\[63:0])\n    pub const APDAKEYLO_EL1: Self = Self::System(0b11_000_0010_0010_000);\n    /// Pointer Authentication Key A For Data (bits\\[127:64])\n    pub const APDAKEYHI_EL1: Self = Self::System(0b11_000_0010_0010_001);\n    /// Pointer Authentication Key B For Data (bits\\[63:0])\n    pub const APDBKEYLO_EL1: Self = Self::System(0b11_000_0010_0010_010);\n    /// Pointer Authentication Key B For Data (bits\\[127:64])\n    pub const APDBKEYHI_EL1: Self = Self::System(0b11_000_0010_0010_011);\n    /// Pointer Authentication Key A For Code (bits\\[63:0])\n    pub const APGAKEYLO_EL1: Self = Self::System(0b11_000_0010_0011_000);\n    /// Pointer Authentication Key A For Code (bits\\[127:64])\n    pub const APGAKEYHI_EL1: Self = Self::System(0b11_000_0010_0011_001);\n    /// Saved Program Status Register (EL1)\n    pub const SPSR_EL1: Self = Self::System(0b11_000_0100_0000_000);\n    /// Exception Link Register (EL1)\n    pub const ELR_EL1: Self = Self::System(0b11_000_0100_0000_001);\n    /// Stack Pointer (EL0)\n    pub const SP_EL0: Self = Self::System(0b11_000_0100_0001_000);\n    /// Interrupt Controller Interrupt Priority Mask Register\n    pub const ICC_PMR_EL1: Self = Self::System(0b11_000_0100_0110_000);\n    /// Interrupt Controller Virtual Interrupt Priority Mask Register\n    pub const ICV_PMR_EL1: Self = Self::System(0b11_000_0100_0110_000);\n    /// Auxiliary Fault Status Register 0 (EL1)\n    pub const AFSR0_EL1: Self = Self::System(0b11_000_0101_0001_000);\n    /// Auxiliary Fault Status Register 1 (EL1)\n    pub const AFSR1_EL1: Self = Self::System(0b11_000_0101_0001_001);\n    /// Exception Syndrome Register (EL1)\n    pub const ESR_EL1: Self = Self::System(0b11_000_0101_0010_000);\n    /// Error Record ID Register\n    pub const ERRIDR_EL1: Self = Self::System(0b11_000_0101_0011_000);\n    /// Error Record Select Register\n    pub const ERRSELR_EL1: Self = Self::System(0b11_000_0101_0011_001);\n    /// Selected Error Record Feature Register\n    pub const ERXFR_EL1: Self = Self::System(0b11_000_0101_0100_000);\n    /// Selected Error Record Control Register\n    pub const ERXCTLR_EL1: Self = Self::System(0b11_000_0101_0100_001);\n    /// Selected Error Record Primary Status Register\n    pub const ERXSTATUS_EL1: Self = Self::System(0b11_000_0101_0100_010);\n    /// Selected Error Record Address Register\n    pub const ERXADDR_EL1: Self = Self::System(0b11_000_0101_0100_011);\n    /// Selected Pseudo-fault Generation Feature Register\n    pub const ERXPFGF_EL1: Self = Self::System(0b11_000_0101_0100_100);\n    /// Selected Pseudo-fault Generation Control Register\n    pub const ERXPFGCTL_EL1: Self = Self::System(0b11_000_0101_0100_101);\n    /// Selected Pseudo-fault Generation Countdown Register\n    pub const ERXPFGCDN_EL1: Self = Self::System(0b11_000_0101_0100_110);\n    /// Selected Error Record Miscellaneous Register 0\n    pub const ERXMISC0_EL1: Self = Self::System(0b11_000_0101_0101_000);\n    /// Selected Error Record Miscellaneous Register 1\n    pub const ERXMISC1_EL1: Self = Self::System(0b11_000_0101_0101_001);\n    /// Selected Error Record Miscellaneous Register 2\n    pub const ERXMISC2_EL1: Self = Self::System(0b11_000_0101_0101_010);\n    /// Selected Error Record Miscellaneous Register 3\n    pub const ERXMISC3_EL1: Self = Self::System(0b11_000_0101_0101_011);\n    /// Tag Fault Status Register (EL1)\n    pub const TFSR_EL1: Self = Self::System(0b11_000_0101_0110_000);\n    /// Tag Fault Status Register (EL0)\n    pub const TFSRE0_EL1: Self = Self::System(0b11_000_0101_0110_001);\n    /// Fault Address Register (EL1)\n    pub const FAR_EL1: Self = Self::System(0b11_000_0110_0000_000);\n    /// Physical Address Register\n    pub const PAR_EL1: Self = Self::System(0b11_000_0111_0100_000);\n    /// Statistical Profiling Control Register (EL1)\n    pub const PMSCR_EL1: Self = Self::System(0b11_000_1001_1001_000);\n    /// Sampling Inverted Event Filter Register\n    pub const PMSNEVFR_EL1: Self = Self::System(0b11_000_1001_1001_001);\n    /// Sampling Interval Counter Register\n    pub const PMSICR_EL1: Self = Self::System(0b11_000_1001_1001_010);\n    /// Sampling Interval Reload Register\n    pub const PMSIRR_EL1: Self = Self::System(0b11_000_1001_1001_011);\n    /// Sampling Filter Control Register\n    pub const PMSFCR_EL1: Self = Self::System(0b11_000_1001_1001_100);\n    /// Sampling Event Filter Register\n    pub const PMSEVFR_EL1: Self = Self::System(0b11_000_1001_1001_101);\n    /// Sampling Latency Filter Register\n    pub const PMSLATFR_EL1: Self = Self::System(0b11_000_1001_1001_110);\n    /// Sampling Profiling ID Register\n    pub const PMSIDR_EL1: Self = Self::System(0b11_000_1001_1001_111);\n    /// Profiling Buffer Limit Address Register\n    pub const PMBLIMITR_EL1: Self = Self::System(0b11_000_1001_1010_000);\n    /// Profiling Buffer Write Pointer Register\n    pub const PMBPTR_EL1: Self = Self::System(0b11_000_1001_1010_001);\n    /// Profiling Buffer Status/syndrome Register\n    pub const PMBSR_EL1: Self = Self::System(0b11_000_1001_1010_011);\n    /// Profiling Buffer ID Register\n    pub const PMBIDR_EL1: Self = Self::System(0b11_000_1001_1010_111);\n    /// Trace Buffer Limit Address Register\n    pub const TRBLIMITR_EL1: Self = Self::System(0b11_000_1001_1011_000);\n    /// Trace Buffer Write Pointer Register\n    pub const TRBPTR_EL1: Self = Self::System(0b11_000_1001_1011_001);\n    /// Trace Buffer Base Address Register\n    pub const TRBBASER_EL1: Self = Self::System(0b11_000_1001_1011_010);\n    /// Trace Buffer Status/syndrome Register\n    pub const TRBSR_EL1: Self = Self::System(0b11_000_1001_1011_011);\n    /// Trace Buffer Memory Attribute Register\n    pub const TRBMAR_EL1: Self = Self::System(0b11_000_1001_1011_100);\n    /// Trace Buffer Trigger Counter Register\n    pub const TRBTRG_EL1: Self = Self::System(0b11_000_1001_1011_110);\n    /// Trace Buffer ID Register\n    pub const TRBIDR_EL1: Self = Self::System(0b11_000_1001_1011_111);\n    /// Performance Monitors Interrupt Enable Set Register\n    pub const PMINTENSET_EL1: Self = Self::System(0b11_000_1001_1110_001);\n    /// Performance Monitors Interrupt Enable Clear Register\n    pub const PMINTENCLR_EL1: Self = Self::System(0b11_000_1001_1110_010);\n    /// Performance Monitors Machine Identification Register\n    pub const PMMIR_EL1: Self = Self::System(0b11_000_1001_1110_110);\n    /// Memory Attribute Indirection Register (EL1)\n    pub const MAIR_EL1: Self = Self::System(0b11_000_1010_0010_000);\n    /// Auxiliary Memory Attribute Indirection Register (EL1)\n    pub const AMAIR_EL1: Self = Self::System(0b11_000_1010_0011_000);\n    /// LORegion Start Address (EL1)\n    pub const LORSA_EL1: Self = Self::System(0b11_000_1010_0100_000);\n    /// LORegion End Address (EL1)\n    pub const LOREA_EL1: Self = Self::System(0b11_000_1010_0100_001);\n    /// LORegion Number (EL1)\n    pub const LORN_EL1: Self = Self::System(0b11_000_1010_0100_010);\n    /// LORegion Control (EL1)\n    pub const LORC_EL1: Self = Self::System(0b11_000_1010_0100_011);\n    /// MPAM ID Register (EL1)\n    pub const MPAMIDR_EL1: Self = Self::System(0b11_000_1010_0100_100);\n    /// LORegionID (EL1)\n    pub const LORID_EL1: Self = Self::System(0b11_000_1010_0100_111);\n    /// MPAM1 Register (EL1)\n    pub const MPAM1_EL1: Self = Self::System(0b11_000_1010_0101_000);\n    /// MPAM0 Register (EL1)\n    pub const MPAM0_EL1: Self = Self::System(0b11_000_1010_0101_001);\n    /// MPAM Streaming Mode Register\n    pub const MPAMSM_EL1: Self = Self::System(0b11_000_1010_0101_011);\n    /// Vector Base Address Register (EL1)\n    pub const VBAR_EL1: Self = Self::System(0b11_000_1100_0000_000);\n    /// Reset Vector Base Address Register (if EL2 And EL3 Not Implemented)\n    pub const RVBAR_EL1: Self = Self::System(0b11_000_1100_0000_001);\n    /// Reset Management Register (EL1)\n    pub const RMR_EL1: Self = Self::System(0b11_000_1100_0000_010);\n    /// Interrupt Status Register\n    pub const ISR_EL1: Self = Self::System(0b11_000_1100_0001_000);\n    /// Deferred Interrupt Status Register\n    pub const DISR_EL1: Self = Self::System(0b11_000_1100_0001_001);\n    /// Interrupt Controller Interrupt Acknowledge Register 0\n    pub const ICC_IAR0_EL1: Self = Self::System(0b11_000_1100_1000_000);\n    /// Interrupt Controller Virtual Interrupt Acknowledge Register 0\n    pub const ICV_IAR0_EL1: Self = Self::System(0b11_000_1100_1000_000);\n    /// Interrupt Controller End Of Interrupt Register 0\n    pub const ICC_EOIR0_EL1: Self = Self::System(0b11_000_1100_1000_001);\n    /// Interrupt Controller Virtual End Of Interrupt Register 0\n    pub const ICV_EOIR0_EL1: Self = Self::System(0b11_000_1100_1000_001);\n    /// Interrupt Controller Highest Priority Pending Interrupt Register 0\n    pub const ICC_HPPIR0_EL1: Self = Self::System(0b11_000_1100_1000_010);\n    /// Interrupt Controller Virtual Highest Priority Pending Interrupt Register\n    /// 0\n    pub const ICV_HPPIR0_EL1: Self = Self::System(0b11_000_1100_1000_010);\n    /// Interrupt Controller Binary Point Register 0\n    pub const ICC_BPR0_EL1: Self = Self::System(0b11_000_1100_1000_011);\n    /// Interrupt Controller Virtual Binary Point Register 0\n    pub const ICV_BPR0_EL1: Self = Self::System(0b11_000_1100_1000_011);\n    /// Interrupt Controller Active Priorities Group 0 Registers - 0\n    pub const ICC_AP0R0_EL1: Self = Self::System(0b11_000_1100_1000_100);\n    /// Interrupt Controller Virtual Active Priorities Group 0 Registers - 0\n    pub const ICV_AP0R0_EL1: Self = Self::System(0b11_000_1100_1000_100);\n    /// Interrupt Controller Active Priorities Group 0 Registers - 1\n    pub const ICC_AP0R1_EL1: Self = Self::System(0b11_000_1100_1000_101);\n    /// Interrupt Controller Virtual Active Priorities Group 0 Registers - 1\n    pub const ICV_AP0R1_EL1: Self = Self::System(0b11_000_1100_1000_101);\n    /// Interrupt Controller Active Priorities Group 0 Registers - 2\n    pub const ICC_AP0R2_EL1: Self = Self::System(0b11_000_1100_1000_110);\n    /// Interrupt Controller Virtual Active Priorities Group 0 Registers - 2\n    pub const ICV_AP0R2_EL1: Self = Self::System(0b11_000_1100_1000_110);\n    /// Interrupt Controller Active Priorities Group 0 Registers - 3\n    pub const ICC_AP0R3_EL1: Self = Self::System(0b11_000_1100_1000_111);\n    /// Interrupt Controller Virtual Active Priorities Group 0 Registers - 3\n    pub const ICV_AP0R3_EL1: Self = Self::System(0b11_000_1100_1000_111);\n    /// Interrupt Controller Active Priorities Group 1 Registers - 0\n    pub const ICC_AP1R0_EL1: Self = Self::System(0b11_000_1100_1001_000);\n    /// Interrupt Controller Virtual Active Priorities Group 1 Registers - 0\n    pub const ICV_AP1R0_EL1: Self = Self::System(0b11_000_1100_1001_000);\n    /// Interrupt Controller Active Priorities Group 1 Registers - 1\n    pub const ICC_AP1R1_EL1: Self = Self::System(0b11_000_1100_1001_001);\n    /// Interrupt Controller Virtual Active Priorities Group 1 Registers - 1\n    pub const ICV_AP1R1_EL1: Self = Self::System(0b11_000_1100_1001_001);\n    /// Interrupt Controller Active Priorities Group 1 Registers - 2\n    pub const ICC_AP1R2_EL1: Self = Self::System(0b11_000_1100_1001_010);\n    /// Interrupt Controller Virtual Active Priorities Group 1 Registers - 2\n    pub const ICV_AP1R2_EL1: Self = Self::System(0b11_000_1100_1001_010);\n    /// Interrupt Controller Active Priorities Group 1 Registers - 3\n    pub const ICC_AP1R3_EL1: Self = Self::System(0b11_000_1100_1001_011);\n    /// Interrupt Controller Virtual Active Priorities Group 1 Registers - 3\n    pub const ICV_AP1R3_EL1: Self = Self::System(0b11_000_1100_1001_011);\n    /// Interrupt Controller Non-maskable Interrupt Acknowledge Register 1\n    pub const ICC_NMIAR1_EL1: Self = Self::System(0b11_000_1100_1001_101);\n    /// Interrupt Controller Virtual Non-maskable Interrupt Acknowledge Register\n    /// 1\n    pub const ICV_NMIAR1_EL1: Self = Self::System(0b11_000_1100_1001_101);\n    /// Interrupt Controller Deactivate Interrupt Register\n    pub const ICC_DIR_EL1: Self = Self::System(0b11_000_1100_1011_001);\n    /// Interrupt Controller Deactivate Virtual Interrupt Register\n    pub const ICV_DIR_EL1: Self = Self::System(0b11_000_1100_1011_001);\n    /// Interrupt Controller Running Priority Register\n    pub const ICC_RPR_EL1: Self = Self::System(0b11_000_1100_1011_011);\n    /// Interrupt Controller Virtual Running Priority Register\n    pub const ICV_RPR_EL1: Self = Self::System(0b11_000_1100_1011_011);\n    /// Interrupt Controller Software Generated Interrupt Group 1 Register\n    pub const ICC_SGI1R_EL1: Self = Self::System(0b11_000_1100_1011_101);\n    /// Interrupt Controller Alias Software Generated Interrupt Group 1 Register\n    pub const ICC_ASGI1R_EL1: Self = Self::System(0b11_000_1100_1011_110);\n    /// Interrupt Controller Software Generated Interrupt Group 0 Register\n    pub const ICC_SGI0R_EL1: Self = Self::System(0b11_000_1100_1011_111);\n    /// Interrupt Controller Interrupt Acknowledge Register 1\n    pub const ICC_IAR1_EL1: Self = Self::System(0b11_000_1100_1100_000);\n    /// Interrupt Controller Virtual Interrupt Acknowledge Register 1\n    pub const ICV_IAR1_EL1: Self = Self::System(0b11_000_1100_1100_000);\n    /// Interrupt Controller End Of Interrupt Register 1\n    pub const ICC_EOIR1_EL1: Self = Self::System(0b11_000_1100_1100_001);\n    /// Interrupt Controller Virtual End Of Interrupt Register 1\n    pub const ICV_EOIR1_EL1: Self = Self::System(0b11_000_1100_1100_001);\n    /// Interrupt Controller Highest Priority Pending Interrupt Register 1\n    pub const ICC_HPPIR1_EL1: Self = Self::System(0b11_000_1100_1100_010);\n    /// Interrupt Controller Virtual Highest Priority Pending Interrupt Register\n    /// 1\n    pub const ICV_HPPIR1_EL1: Self = Self::System(0b11_000_1100_1100_010);\n    /// Interrupt Controller Binary Point Register 1\n    pub const ICC_BPR1_EL1: Self = Self::System(0b11_000_1100_1100_011);\n    /// Interrupt Controller Virtual Binary Point Register 1\n    pub const ICV_BPR1_EL1: Self = Self::System(0b11_000_1100_1100_011);\n    /// Interrupt Controller Control Register (EL1)\n    pub const ICC_CTLR_EL1: Self = Self::System(0b11_000_1100_1100_100);\n    /// Interrupt Controller Virtual Control Register\n    pub const ICV_CTLR_EL1: Self = Self::System(0b11_000_1100_1100_100);\n    /// Interrupt Controller System Register Enable Register (EL1)\n    pub const ICC_SRE_EL1: Self = Self::System(0b11_000_1100_1100_101);\n    /// Interrupt Controller Interrupt Group 0 Enable Register\n    pub const ICC_IGRPEN0_EL1: Self = Self::System(0b11_000_1100_1100_110);\n    /// Interrupt Controller Virtual Interrupt Group 0 Enable Register\n    pub const ICV_IGRPEN0_EL1: Self = Self::System(0b11_000_1100_1100_110);\n    /// Interrupt Controller Interrupt Group 1 Enable Register\n    pub const ICC_IGRPEN1_EL1: Self = Self::System(0b11_000_1100_1100_111);\n    /// Interrupt Controller Virtual Interrupt Group 1 Enable Register\n    pub const ICV_IGRPEN1_EL1: Self = Self::System(0b11_000_1100_1100_111);\n    /// Context ID Register (EL1)\n    pub const CONTEXTIDR_EL1: Self = Self::System(0b11_000_1101_0000_001);\n    /// EL1 Software Thread ID Register\n    pub const TPIDR_EL1: Self = Self::System(0b11_000_1101_0000_100);\n    /// Accelerator Data\n    pub const ACCDATA_EL1: Self = Self::System(0b11_000_1101_0000_101);\n    /// EL1 Read/Write Software Context Number\n    pub const SCXTNUM_EL1: Self = Self::System(0b11_000_1101_0000_111);\n    /// Counter-timer Kernel Control Register\n    pub const CNTKCTL_EL1: Self = Self::System(0b11_000_1110_0001_000);\n    /// Current Cache Size ID Register\n    pub const CCSIDR_EL1: Self = Self::System(0b11_001_0000_0000_000);\n    /// Cache Level ID Register\n    pub const CLIDR_EL1: Self = Self::System(0b11_001_0000_0000_001);\n    /// Current Cache Size ID Register 2\n    pub const CCSIDR2_EL1: Self = Self::System(0b11_001_0000_0000_010);\n    /// Multiple Tag Transfer ID Register\n    pub const GMID_EL1: Self = Self::System(0b11_001_0000_0000_100);\n    /// Streaming Mode Identification Register\n    pub const SMIDR_EL1: Self = Self::System(0b11_001_0000_0000_110);\n    /// Auxiliary ID Register\n    pub const AIDR_EL1: Self = Self::System(0b11_001_0000_0000_111);\n    /// Cache Size Selection Register\n    pub const CSSELR_EL1: Self = Self::System(0b11_010_0000_0000_000);\n    /// Cache Type Register\n    pub const CTR_EL0: Self = Self::System(0b11_011_0000_0000_001);\n    /// Data Cache Zero ID Register\n    pub const DCZID_EL0: Self = Self::System(0b11_011_0000_0000_111);\n    /// Random Number\n    pub const RNDR: Self = Self::System(0b11_011_0010_0100_000);\n    /// Reseeded Random Number\n    pub const RNDRRS: Self = Self::System(0b11_011_0010_0100_001);\n    /// Streaming Vector Control Register\n    pub const SVCR: Self = Self::System(0b11_011_0100_0010_010);\n    /// Floating-point Control Register\n    pub const FPCR: Self = Self::System(0b11_011_0100_0100_000);\n    /// Floating-point Status Register\n    pub const FPSR: Self = Self::System(0b11_011_0100_0100_001);\n    /// Debug Saved Program Status Register\n    pub const DSPSR_EL0: Self = Self::System(0b11_011_0100_0101_000);\n    /// Debug Link Register\n    pub const DLR_EL0: Self = Self::System(0b11_011_0100_0101_001);\n    /// Performance Monitors Control Register\n    pub const PMCR_EL0: Self = Self::System(0b11_011_1001_1100_000);\n    /// Performance Monitors Count Enable Set Register\n    pub const PMCNTENSET_EL0: Self = Self::System(0b11_011_1001_1100_001);\n    /// Performance Monitors Count Enable Clear Register\n    pub const PMCNTENCLR_EL0: Self = Self::System(0b11_011_1001_1100_010);\n    /// Performance Monitors Overflow Flag Status Clear Register\n    pub const PMOVSCLR_EL0: Self = Self::System(0b11_011_1001_1100_011);\n    /// Performance Monitors Software Increment Register\n    pub const PMSWINC_EL0: Self = Self::System(0b11_011_1001_1100_100);\n    /// Performance Monitors Event Counter Selection Register\n    pub const PMSELR_EL0: Self = Self::System(0b11_011_1001_1100_101);\n    /// Performance Monitors Common Event Identification Register 0\n    pub const PMCEID0_EL0: Self = Self::System(0b11_011_1001_1100_110);\n    /// Performance Monitors Common Event Identification Register 1\n    pub const PMCEID1_EL0: Self = Self::System(0b11_011_1001_1100_111);\n    /// Performance Monitors Cycle Count Register\n    pub const PMCCNTR_EL0: Self = Self::System(0b11_011_1001_1101_000);\n    /// Performance Monitors Selected Event Type Register\n    pub const PMXEVTYPER_EL0: Self = Self::System(0b11_011_1001_1101_001);\n    /// Performance Monitors Selected Event Count Register\n    pub const PMXEVCNTR_EL0: Self = Self::System(0b11_011_1001_1101_010);\n    /// Performance Monitors User Enable Register\n    pub const PMUSERENR_EL0: Self = Self::System(0b11_011_1001_1110_000);\n    /// Performance Monitors Overflow Flag Status Set Register\n    pub const PMOVSSET_EL0: Self = Self::System(0b11_011_1001_1110_011);\n    /// EL0 Read/Write Software Thread ID Register\n    pub const TPIDR_EL0: Self = Self::System(0b11_011_1101_0000_010);\n    /// EL0 Read-Only Software Thread ID Register\n    pub const TPIDRRO_EL0: Self = Self::System(0b11_011_1101_0000_011);\n    /// EL0 Read/Write Software Thread ID Register 2\n    pub const TPIDR2_EL0: Self = Self::System(0b11_011_1101_0000_101);\n    /// EL0 Read/Write Software Context Number\n    pub const SCXTNUM_EL0: Self = Self::System(0b11_011_1101_0000_111);\n    /// Activity Monitors Control Register\n    pub const AMCR_EL0: Self = Self::System(0b11_011_1101_0010_000);\n    /// Activity Monitors Configuration Register\n    pub const AMCFGR_EL0: Self = Self::System(0b11_011_1101_0010_001);\n    /// Activity Monitors Counter Group Configuration Register\n    pub const AMCGCR_EL0: Self = Self::System(0b11_011_1101_0010_010);\n    /// Activity Monitors User Enable Register\n    pub const AMUSERENR_EL0: Self = Self::System(0b11_011_1101_0010_011);\n    /// Activity Monitors Count Enable Clear Register 0\n    pub const AMCNTENCLR0_EL0: Self = Self::System(0b11_011_1101_0010_100);\n    /// Activity Monitors Count Enable Set Register 0\n    pub const AMCNTENSET0_EL0: Self = Self::System(0b11_011_1101_0010_101);\n    /// Activity Monitors Counter Group 1 Identification Register\n    pub const AMCG1IDR_EL0: Self = Self::System(0b11_011_1101_0010_110);\n    /// Activity Monitors Count Enable Clear Register 1\n    pub const AMCNTENCLR1_EL0: Self = Self::System(0b11_011_1101_0011_000);\n    /// Activity Monitors Count Enable Set Register 1\n    pub const AMCNTENSET1_EL0: Self = Self::System(0b11_011_1101_0011_001);\n    /// Activity Monitors Event Counter Registers 0 - 0\n    pub const AMEVCNTR00_EL0: Self = Self::System(0b11_011_1101_0100_000);\n    /// Activity Monitors Event Counter Registers 0 - 1\n    pub const AMEVCNTR01_EL0: Self = Self::System(0b11_011_1101_0100_001);\n    /// Activity Monitors Event Counter Registers 0 - 2\n    pub const AMEVCNTR02_EL0: Self = Self::System(0b11_011_1101_0100_010);\n    /// Activity Monitors Event Counter Registers 0 - 3\n    pub const AMEVCNTR03_EL0: Self = Self::System(0b11_011_1101_0100_011);\n    /// Activity Monitors Event Type Registers 0 - 0\n    pub const AMEVTYPER00_EL0: Self = Self::System(0b11_011_1101_0110_000);\n    /// Activity Monitors Event Type Registers 0 - 1\n    pub const AMEVTYPER01_EL0: Self = Self::System(0b11_011_1101_0110_001);\n    /// Activity Monitors Event Type Registers 0 - 2\n    pub const AMEVTYPER02_EL0: Self = Self::System(0b11_011_1101_0110_010);\n    /// Activity Monitors Event Type Registers 0 - 3\n    pub const AMEVTYPER03_EL0: Self = Self::System(0b11_011_1101_0110_011);\n    /// Activity Monitors Event Counter Registers 1 - 0\n    pub const AMEVCNTR10_EL0: Self = Self::System(0b11_011_1101_1100_000);\n    /// Activity Monitors Event Counter Registers 1 - 1\n    pub const AMEVCNTR11_EL0: Self = Self::System(0b11_011_1101_1100_001);\n    /// Activity Monitors Event Counter Registers 1 - 2\n    pub const AMEVCNTR12_EL0: Self = Self::System(0b11_011_1101_1100_010);\n    /// Activity Monitors Event Counter Registers 1 - 3\n    pub const AMEVCNTR13_EL0: Self = Self::System(0b11_011_1101_1100_011);\n    /// Activity Monitors Event Counter Registers 1 - 4\n    pub const AMEVCNTR14_EL0: Self = Self::System(0b11_011_1101_1100_100);\n    /// Activity Monitors Event Counter Registers 1 - 5\n    pub const AMEVCNTR15_EL0: Self = Self::System(0b11_011_1101_1100_101);\n    /// Activity Monitors Event Counter Registers 1 - 6\n    pub const AMEVCNTR16_EL0: Self = Self::System(0b11_011_1101_1100_110);\n    /// Activity Monitors Event Counter Registers 1 - 7\n    pub const AMEVCNTR17_EL0: Self = Self::System(0b11_011_1101_1100_111);\n    /// Activity Monitors Event Counter Registers 1 - 8\n    pub const AMEVCNTR18_EL0: Self = Self::System(0b11_011_1101_1101_000);\n    /// Activity Monitors Event Counter Registers 1 - 9\n    pub const AMEVCNTR19_EL0: Self = Self::System(0b11_011_1101_1101_001);\n    /// Activity Monitors Event Counter Registers 1 - 10\n    pub const AMEVCNTR110_EL0: Self = Self::System(0b11_011_1101_1101_010);\n    /// Activity Monitors Event Counter Registers 1 - 11\n    pub const AMEVCNTR111_EL0: Self = Self::System(0b11_011_1101_1101_011);\n    /// Activity Monitors Event Counter Registers 1 - 12\n    pub const AMEVCNTR112_EL0: Self = Self::System(0b11_011_1101_1101_100);\n    /// Activity Monitors Event Counter Registers 1 - 13\n    pub const AMEVCNTR113_EL0: Self = Self::System(0b11_011_1101_1101_101);\n    /// Activity Monitors Event Counter Registers 1 - 14\n    pub const AMEVCNTR114_EL0: Self = Self::System(0b11_011_1101_1101_110);\n    /// Activity Monitors Event Counter Registers 1 - 15\n    pub const AMEVCNTR115_EL0: Self = Self::System(0b11_011_1101_1101_111);\n    /// Activity Monitors Event Type Registers 1 - 0\n    pub const AMEVTYPER10_EL0: Self = Self::System(0b11_011_1101_1110_000);\n    /// Activity Monitors Event Type Registers 1 - 1\n    pub const AMEVTYPER11_EL0: Self = Self::System(0b11_011_1101_1110_001);\n    /// Activity Monitors Event Type Registers 1 - 2\n    pub const AMEVTYPER12_EL0: Self = Self::System(0b11_011_1101_1110_010);\n    /// Activity Monitors Event Type Registers 1 - 3\n    pub const AMEVTYPER13_EL0: Self = Self::System(0b11_011_1101_1110_011);\n    /// Activity Monitors Event Type Registers 1 - 4\n    pub const AMEVTYPER14_EL0: Self = Self::System(0b11_011_1101_1110_100);\n    /// Activity Monitors Event Type Registers 1 - 5\n    pub const AMEVTYPER15_EL0: Self = Self::System(0b11_011_1101_1110_101);\n    /// Activity Monitors Event Type Registers 1 - 6\n    pub const AMEVTYPER16_EL0: Self = Self::System(0b11_011_1101_1110_110);\n    /// Activity Monitors Event Type Registers 1 - 7\n    pub const AMEVTYPER17_EL0: Self = Self::System(0b11_011_1101_1110_111);\n    /// Activity Monitors Event Type Registers 1 - 8\n    pub const AMEVTYPER18_EL0: Self = Self::System(0b11_011_1101_1111_000);\n    /// Activity Monitors Event Type Registers 1 - 9\n    pub const AMEVTYPER19_EL0: Self = Self::System(0b11_011_1101_1111_001);\n    /// Activity Monitors Event Type Registers 1 - 10\n    pub const AMEVTYPER110_EL0: Self = Self::System(0b11_011_1101_1111_010);\n    /// Activity Monitors Event Type Registers 1 - 11\n    pub const AMEVTYPER111_EL0: Self = Self::System(0b11_011_1101_1111_011);\n    /// Activity Monitors Event Type Registers 1 - 12\n    pub const AMEVTYPER112_EL0: Self = Self::System(0b11_011_1101_1111_100);\n    /// Activity Monitors Event Type Registers 1 - 13\n    pub const AMEVTYPER113_EL0: Self = Self::System(0b11_011_1101_1111_101);\n    /// Activity Monitors Event Type Registers 1 - 14\n    pub const AMEVTYPER114_EL0: Self = Self::System(0b11_011_1101_1111_110);\n    /// Activity Monitors Event Type Registers 1 - 15\n    pub const AMEVTYPER115_EL0: Self = Self::System(0b11_011_1101_1111_111);\n    /// Counter-timer Frequency Register\n    pub const CNTFRQ_EL0: Self = Self::System(0b11_011_1110_0000_000);\n    /// Counter-timer Physical Count Register\n    pub const CNTPCT_EL0: Self = Self::System(0b11_011_1110_0000_001);\n    /// Counter-timer Virtual Count Register\n    pub const CNTVCT_EL0: Self = Self::System(0b11_011_1110_0000_010);\n    /// Counter-timer Self-Synchronized Physical Count Register\n    pub const CNTPCTSS_EL0: Self = Self::System(0b11_011_1110_0000_101);\n    /// Counter-timer Self-Synchronized Virtual Count Register\n    pub const CNTVCTSS_EL0: Self = Self::System(0b11_011_1110_0000_110);\n    /// Counter-timer Physical Timer TimerValue Register\n    pub const CNTP_TVAL_EL0: Self = Self::System(0b11_011_1110_0010_000);\n    /// Counter-timer Physical Timer Control Register\n    pub const CNTP_CTL_EL0: Self = Self::System(0b11_011_1110_0010_001);\n    /// Counter-timer Physical Timer CompareValue Register\n    pub const CNTP_CVAL_EL0: Self = Self::System(0b11_011_1110_0010_010);\n    /// Counter-timer Virtual Timer TimerValue Register\n    pub const CNTV_TVAL_EL0: Self = Self::System(0b11_011_1110_0011_000);\n    /// Counter-timer Virtual Timer Control Register\n    pub const CNTV_CTL_EL0: Self = Self::System(0b11_011_1110_0011_001);\n    /// Counter-timer Virtual Timer CompareValue Register\n    pub const CNTV_CVAL_EL0: Self = Self::System(0b11_011_1110_0011_010);\n    /// Performance Monitors Event Count Registers - 0\n    pub const PMEVCNTR0_EL0: Self = Self::System(0b11_011_1110_1000_000);\n    /// Performance Monitors Event Count Registers - 1\n    pub const PMEVCNTR1_EL0: Self = Self::System(0b11_011_1110_1000_001);\n    /// Performance Monitors Event Count Registers - 2\n    pub const PMEVCNTR2_EL0: Self = Self::System(0b11_011_1110_1000_010);\n    /// Performance Monitors Event Count Registers - 3\n    pub const PMEVCNTR3_EL0: Self = Self::System(0b11_011_1110_1000_011);\n    /// Performance Monitors Event Count Registers - 4\n    pub const PMEVCNTR4_EL0: Self = Self::System(0b11_011_1110_1000_100);\n    /// Performance Monitors Event Count Registers - 5\n    pub const PMEVCNTR5_EL0: Self = Self::System(0b11_011_1110_1000_101);\n    /// Performance Monitors Event Count Registers - 6\n    pub const PMEVCNTR6_EL0: Self = Self::System(0b11_011_1110_1000_110);\n    /// Performance Monitors Event Count Registers - 7\n    pub const PMEVCNTR7_EL0: Self = Self::System(0b11_011_1110_1000_111);\n    /// Performance Monitors Event Count Registers - 8\n    pub const PMEVCNTR8_EL0: Self = Self::System(0b11_011_1110_1001_000);\n    /// Performance Monitors Event Count Registers - 9\n    pub const PMEVCNTR9_EL0: Self = Self::System(0b11_011_1110_1001_001);\n    /// Performance Monitors Event Count Registers - 10\n    pub const PMEVCNTR10_EL0: Self = Self::System(0b11_011_1110_1001_010);\n    /// Performance Monitors Event Count Registers - 11\n    pub const PMEVCNTR11_EL0: Self = Self::System(0b11_011_1110_1001_011);\n    /// Performance Monitors Event Count Registers - 12\n    pub const PMEVCNTR12_EL0: Self = Self::System(0b11_011_1110_1001_100);\n    /// Performance Monitors Event Count Registers - 13\n    pub const PMEVCNTR13_EL0: Self = Self::System(0b11_011_1110_1001_101);\n    /// Performance Monitors Event Count Registers - 14\n    pub const PMEVCNTR14_EL0: Self = Self::System(0b11_011_1110_1001_110);\n    /// Performance Monitors Event Count Registers - 15\n    pub const PMEVCNTR15_EL0: Self = Self::System(0b11_011_1110_1001_111);\n    /// Performance Monitors Event Count Registers - 16\n    pub const PMEVCNTR16_EL0: Self = Self::System(0b11_011_1110_1010_000);\n    /// Performance Monitors Event Count Registers - 17\n    pub const PMEVCNTR17_EL0: Self = Self::System(0b11_011_1110_1010_001);\n    /// Performance Monitors Event Count Registers - 18\n    pub const PMEVCNTR18_EL0: Self = Self::System(0b11_011_1110_1010_010);\n    /// Performance Monitors Event Count Registers - 19\n    pub const PMEVCNTR19_EL0: Self = Self::System(0b11_011_1110_1010_011);\n    /// Performance Monitors Event Count Registers - 20\n    pub const PMEVCNTR20_EL0: Self = Self::System(0b11_011_1110_1010_100);\n    /// Performance Monitors Event Count Registers - 21\n    pub const PMEVCNTR21_EL0: Self = Self::System(0b11_011_1110_1010_101);\n    /// Performance Monitors Event Count Registers - 22\n    pub const PMEVCNTR22_EL0: Self = Self::System(0b11_011_1110_1010_110);\n    /// Performance Monitors Event Count Registers - 23\n    pub const PMEVCNTR23_EL0: Self = Self::System(0b11_011_1110_1010_111);\n    /// Performance Monitors Event Count Registers - 24\n    pub const PMEVCNTR24_EL0: Self = Self::System(0b11_011_1110_1011_000);\n    /// Performance Monitors Event Count Registers - 25\n    pub const PMEVCNTR25_EL0: Self = Self::System(0b11_011_1110_1011_001);\n    /// Performance Monitors Event Count Registers - 26\n    pub const PMEVCNTR26_EL0: Self = Self::System(0b11_011_1110_1011_010);\n    /// Performance Monitors Event Count Registers - 27\n    pub const PMEVCNTR27_EL0: Self = Self::System(0b11_011_1110_1011_011);\n    /// Performance Monitors Event Count Registers - 28\n    pub const PMEVCNTR28_EL0: Self = Self::System(0b11_011_1110_1011_100);\n    /// Performance Monitors Event Count Registers - 29\n    pub const PMEVCNTR29_EL0: Self = Self::System(0b11_011_1110_1011_101);\n    /// Performance Monitors Event Count Registers - 30\n    pub const PMEVCNTR30_EL0: Self = Self::System(0b11_011_1110_1011_110);\n    /// Performance Monitors Event Type Registers - 0\n    pub const PMEVTYPER0_EL0: Self = Self::System(0b11_011_1110_1100_000);\n    /// Performance Monitors Event Type Registers - 1\n    pub const PMEVTYPER1_EL0: Self = Self::System(0b11_011_1110_1100_001);\n    /// Performance Monitors Event Type Registers - 2\n    pub const PMEVTYPER2_EL0: Self = Self::System(0b11_011_1110_1100_010);\n    /// Performance Monitors Event Type Registers - 3\n    pub const PMEVTYPER3_EL0: Self = Self::System(0b11_011_1110_1100_011);\n    /// Performance Monitors Event Type Registers - 4\n    pub const PMEVTYPER4_EL0: Self = Self::System(0b11_011_1110_1100_100);\n    /// Performance Monitors Event Type Registers - 5\n    pub const PMEVTYPER5_EL0: Self = Self::System(0b11_011_1110_1100_101);\n    /// Performance Monitors Event Type Registers - 6\n    pub const PMEVTYPER6_EL0: Self = Self::System(0b11_011_1110_1100_110);\n    /// Performance Monitors Event Type Registers - 7\n    pub const PMEVTYPER7_EL0: Self = Self::System(0b11_011_1110_1100_111);\n    /// Performance Monitors Event Type Registers - 8\n    pub const PMEVTYPER8_EL0: Self = Self::System(0b11_011_1110_1101_000);\n    /// Performance Monitors Event Type Registers - 9\n    pub const PMEVTYPER9_EL0: Self = Self::System(0b11_011_1110_1101_001);\n    /// Performance Monitors Event Type Registers - 10\n    pub const PMEVTYPER10_EL0: Self = Self::System(0b11_011_1110_1101_010);\n    /// Performance Monitors Event Type Registers - 11\n    pub const PMEVTYPER11_EL0: Self = Self::System(0b11_011_1110_1101_011);\n    /// Performance Monitors Event Type Registers - 12\n    pub const PMEVTYPER12_EL0: Self = Self::System(0b11_011_1110_1101_100);\n    /// Performance Monitors Event Type Registers - 13\n    pub const PMEVTYPER13_EL0: Self = Self::System(0b11_011_1110_1101_101);\n    /// Performance Monitors Event Type Registers - 14\n    pub const PMEVTYPER14_EL0: Self = Self::System(0b11_011_1110_1101_110);\n    /// Performance Monitors Event Type Registers - 15\n    pub const PMEVTYPER15_EL0: Self = Self::System(0b11_011_1110_1101_111);\n    /// Performance Monitors Event Type Registers - 16\n    pub const PMEVTYPER16_EL0: Self = Self::System(0b11_011_1110_1110_000);\n    /// Performance Monitors Event Type Registers - 17\n    pub const PMEVTYPER17_EL0: Self = Self::System(0b11_011_1110_1110_001);\n    /// Performance Monitors Event Type Registers - 18\n    pub const PMEVTYPER18_EL0: Self = Self::System(0b11_011_1110_1110_010);\n    /// Performance Monitors Event Type Registers - 19\n    pub const PMEVTYPER19_EL0: Self = Self::System(0b11_011_1110_1110_011);\n    /// Performance Monitors Event Type Registers - 20\n    pub const PMEVTYPER20_EL0: Self = Self::System(0b11_011_1110_1110_100);\n    /// Performance Monitors Event Type Registers - 21\n    pub const PMEVTYPER21_EL0: Self = Self::System(0b11_011_1110_1110_101);\n    /// Performance Monitors Event Type Registers - 22\n    pub const PMEVTYPER22_EL0: Self = Self::System(0b11_011_1110_1110_110);\n    /// Performance Monitors Event Type Registers - 23\n    pub const PMEVTYPER23_EL0: Self = Self::System(0b11_011_1110_1110_111);\n    /// Performance Monitors Event Type Registers - 24\n    pub const PMEVTYPER24_EL0: Self = Self::System(0b11_011_1110_1111_000);\n    /// Performance Monitors Event Type Registers - 25\n    pub const PMEVTYPER25_EL0: Self = Self::System(0b11_011_1110_1111_001);\n    /// Performance Monitors Event Type Registers - 26\n    pub const PMEVTYPER26_EL0: Self = Self::System(0b11_011_1110_1111_010);\n    /// Performance Monitors Event Type Registers - 27\n    pub const PMEVTYPER27_EL0: Self = Self::System(0b11_011_1110_1111_011);\n    /// Performance Monitors Event Type Registers - 28\n    pub const PMEVTYPER28_EL0: Self = Self::System(0b11_011_1110_1111_100);\n    /// Performance Monitors Event Type Registers - 29\n    pub const PMEVTYPER29_EL0: Self = Self::System(0b11_011_1110_1111_101);\n    /// Performance Monitors Event Type Registers - 30\n    pub const PMEVTYPER30_EL0: Self = Self::System(0b11_011_1110_1111_110);\n    /// Performance Monitors Cycle Count Filter Register\n    pub const PMCCFILTR_EL0: Self = Self::System(0b11_011_1110_1111_111);\n    /// Virtualization Processor ID Register\n    pub const VPIDR_EL2: Self = Self::System(0b11_100_0000_0000_000);\n    /// Virtualization Multiprocessor ID Register\n    pub const VMPIDR_EL2: Self = Self::System(0b11_100_0000_0000_101);\n    /// System Control Register (EL2)\n    pub const SCTLR_EL2: Self = Self::System(0b11_100_0001_0000_000);\n    /// Auxiliary Control Register (EL2)\n    pub const ACTLR_EL2: Self = Self::System(0b11_100_0001_0000_001);\n    /// Hypervisor Configuration Register\n    pub const HCR_EL2: Self = Self::System(0b11_100_0001_0001_000);\n    /// Monitor Debug Configuration Register (EL2)\n    pub const MDCR_EL2: Self = Self::System(0b11_100_0001_0001_001);\n    /// Architectural Feature Trap Register (EL2)\n    pub const CPTR_EL2: Self = Self::System(0b11_100_0001_0001_010);\n    /// Hypervisor System Trap Register\n    pub const HSTR_EL2: Self = Self::System(0b11_100_0001_0001_011);\n    /// Hypervisor Fine-Grained Read Trap Register\n    pub const HFGRTR_EL2: Self = Self::System(0b11_100_0001_0001_100);\n    /// Hypervisor Fine-Grained Write Trap Register\n    pub const HFGWTR_EL2: Self = Self::System(0b11_100_0001_0001_101);\n    /// Hypervisor Fine-Grained Instruction Trap Register\n    pub const HFGITR_EL2: Self = Self::System(0b11_100_0001_0001_110);\n    /// Hypervisor Auxiliary Control Register\n    pub const HACR_EL2: Self = Self::System(0b11_100_0001_0001_111);\n    /// SVE Control Register (EL2)\n    pub const ZCR_EL2: Self = Self::System(0b11_100_0001_0010_000);\n    /// Trace Filter Control Register (EL2)\n    pub const TRFCR_EL2: Self = Self::System(0b11_100_0001_0010_001);\n    /// Extended Hypervisor Configuration Register\n    pub const HCRX_EL2: Self = Self::System(0b11_100_0001_0010_010);\n    /// Streaming Mode Priority Mapping Register\n    pub const SMPRIMAP_EL2: Self = Self::System(0b11_100_0001_0010_101);\n    /// SME Control Register (EL2)\n    pub const SMCR_EL2: Self = Self::System(0b11_100_0001_0010_110);\n    /// AArch32 Secure Debug Enable Register\n    pub const SDER32_EL2: Self = Self::System(0b11_100_0001_0011_001);\n    /// Translation Table Base Register 0 (EL2)\n    pub const TTBR0_EL2: Self = Self::System(0b11_100_0010_0000_000);\n    /// Translation Table Base Register 1 (EL2)\n    pub const TTBR1_EL2: Self = Self::System(0b11_100_0010_0000_001);\n    /// Translation Control Register (EL2)\n    pub const TCR_EL2: Self = Self::System(0b11_100_0010_0000_010);\n    /// Virtualization Translation Table Base Register\n    pub const VTTBR_EL2: Self = Self::System(0b11_100_0010_0001_000);\n    /// Virtualization Translation Control Register\n    pub const VTCR_EL2: Self = Self::System(0b11_100_0010_0001_010);\n    /// Virtual Nested Control Register\n    pub const VNCR_EL2: Self = Self::System(0b11_100_0010_0010_000);\n    /// Virtualization Secure Translation Table Base Register\n    pub const VSTTBR_EL2: Self = Self::System(0b11_100_0010_0110_000);\n    /// Virtualization Secure Translation Control Register\n    pub const VSTCR_EL2: Self = Self::System(0b11_100_0010_0110_010);\n    /// Domain Access Control Register\n    pub const DACR32_EL2: Self = Self::System(0b11_100_0011_0000_000);\n    /// Hypervisor Debug Fine-Grained Read Trap Register\n    pub const HDFGRTR_EL2: Self = Self::System(0b11_100_0011_0001_100);\n    /// Hypervisor Debug Fine-Grained Write Trap Register\n    pub const HDFGWTR_EL2: Self = Self::System(0b11_100_0011_0001_101);\n    /// Hypervisor Activity Monitors Fine-Grained Read Trap Register\n    pub const HAFGRTR_EL2: Self = Self::System(0b11_100_0011_0001_110);\n    /// Saved Program Status Register (EL2)\n    pub const SPSR_EL2: Self = Self::System(0b11_100_0100_0000_000);\n    /// Exception Link Register (EL2)\n    pub const ELR_EL2: Self = Self::System(0b11_100_0100_0000_001);\n    /// Stack Pointer (EL1)\n    pub const SP_EL1: Self = Self::System(0b11_100_0100_0001_000);\n    /// Saved Program Status Register (IRQ Mode)\n    pub const SPSR_IRQ: Self = Self::System(0b11_100_0100_0011_000);\n    /// Saved Program Status Register (Abort Mode)\n    pub const SPSR_ABT: Self = Self::System(0b11_100_0100_0011_001);\n    /// Saved Program Status Register (Undefined Mode)\n    pub const SPSR_UND: Self = Self::System(0b11_100_0100_0011_010);\n    /// Saved Program Status Register (FIQ Mode)\n    pub const SPSR_FIQ: Self = Self::System(0b11_100_0100_0011_011);\n    /// Instruction Fault Status Register (EL2)\n    pub const IFSR32_EL2: Self = Self::System(0b11_100_0101_0000_001);\n    /// Auxiliary Fault Status Register 0 (EL2)\n    pub const AFSR0_EL2: Self = Self::System(0b11_100_0101_0001_000);\n    /// Auxiliary Fault Status Register 1 (EL2)\n    pub const AFSR1_EL2: Self = Self::System(0b11_100_0101_0001_001);\n    /// Exception Syndrome Register (EL2)\n    pub const ESR_EL2: Self = Self::System(0b11_100_0101_0010_000);\n    /// Virtual SError Exception Syndrome Register\n    pub const VSESR_EL2: Self = Self::System(0b11_100_0101_0010_011);\n    /// Floating-Point Exception Control Register\n    pub const FPEXC32_EL2: Self = Self::System(0b11_100_0101_0011_000);\n    /// Tag Fault Status Register (EL2)\n    pub const TFSR_EL2: Self = Self::System(0b11_100_0101_0110_000);\n    /// Fault Address Register (EL2)\n    pub const FAR_EL2: Self = Self::System(0b11_100_0110_0000_000);\n    /// Hypervisor IPA Fault Address Register\n    pub const HPFAR_EL2: Self = Self::System(0b11_100_0110_0000_100);\n    /// Statistical Profiling Control Register (EL2)\n    pub const PMSCR_EL2: Self = Self::System(0b11_100_1001_1001_000);\n    /// Memory Attribute Indirection Register (EL2)\n    pub const MAIR_EL2: Self = Self::System(0b11_100_1010_0010_000);\n    /// Auxiliary Memory Attribute Indirection Register (EL2)\n    pub const AMAIR_EL2: Self = Self::System(0b11_100_1010_0011_000);\n    /// MPAM Hypervisor Control Register (EL2)\n    pub const MPAMHCR_EL2: Self = Self::System(0b11_100_1010_0100_000);\n    /// MPAM Virtual Partition Mapping Valid Register\n    pub const MPAMVPMV_EL2: Self = Self::System(0b11_100_1010_0100_001);\n    /// MPAM2 Register (EL2)\n    pub const MPAM2_EL2: Self = Self::System(0b11_100_1010_0101_000);\n    /// MPAM Virtual PARTID Mapping Register 0\n    pub const MPAMVPM0_EL2: Self = Self::System(0b11_100_1010_0110_000);\n    /// MPAM Virtual PARTID Mapping Register 1\n    pub const MPAMVPM1_EL2: Self = Self::System(0b11_100_1010_0110_001);\n    /// MPAM Virtual PARTID Mapping Register 2\n    pub const MPAMVPM2_EL2: Self = Self::System(0b11_100_1010_0110_010);\n    /// MPAM Virtual PARTID Mapping Register 3\n    pub const MPAMVPM3_EL2: Self = Self::System(0b11_100_1010_0110_011);\n    /// MPAM Virtual PARTID Mapping Register 4\n    pub const MPAMVPM4_EL2: Self = Self::System(0b11_100_1010_0110_100);\n    /// MPAM Virtual PARTID Mapping Register 5\n    pub const MPAMVPM5_EL2: Self = Self::System(0b11_100_1010_0110_101);\n    /// MPAM Virtual PARTID Mapping Register 6\n    pub const MPAMVPM6_EL2: Self = Self::System(0b11_100_1010_0110_110);\n    /// MPAM Virtual PARTID Mapping Register 7\n    pub const MPAMVPM7_EL2: Self = Self::System(0b11_100_1010_0110_111);\n    /// Vector Base Address Register (EL2)\n    pub const VBAR_EL2: Self = Self::System(0b11_100_1100_0000_000);\n    /// Reset Vector Base Address Register (if EL3 Not Implemented)\n    pub const RVBAR_EL2: Self = Self::System(0b11_100_1100_0000_001);\n    /// Reset Management Register (EL2)\n    pub const RMR_EL2: Self = Self::System(0b11_100_1100_0000_010);\n    /// Virtual Deferred Interrupt Status Register\n    pub const VDISR_EL2: Self = Self::System(0b11_100_1100_0001_001);\n    /// Interrupt Controller Hyp Active Priorities Group 0 Registers - 0\n    pub const ICH_AP0R0_EL2: Self = Self::System(0b11_100_1100_1000_000);\n    /// Interrupt Controller Hyp Active Priorities Group 0 Registers - 1\n    pub const ICH_AP0R1_EL2: Self = Self::System(0b11_100_1100_1000_001);\n    /// Interrupt Controller Hyp Active Priorities Group 0 Registers - 2\n    pub const ICH_AP0R2_EL2: Self = Self::System(0b11_100_1100_1000_010);\n    /// Interrupt Controller Hyp Active Priorities Group 0 Registers - 3\n    pub const ICH_AP0R3_EL2: Self = Self::System(0b11_100_1100_1000_011);\n    /// Interrupt Controller Hyp Active Priorities Group 1 Registers - 0\n    pub const ICH_AP1R0_EL2: Self = Self::System(0b11_100_1100_1001_000);\n    /// Interrupt Controller Hyp Active Priorities Group 1 Registers - 1\n    pub const ICH_AP1R1_EL2: Self = Self::System(0b11_100_1100_1001_001);\n    /// Interrupt Controller Hyp Active Priorities Group 1 Registers - 2\n    pub const ICH_AP1R2_EL2: Self = Self::System(0b11_100_1100_1001_010);\n    /// Interrupt Controller Hyp Active Priorities Group 1 Registers - 3\n    pub const ICH_AP1R3_EL2: Self = Self::System(0b11_100_1100_1001_011);\n    /// Interrupt Controller System Register Enable Register (EL2)\n    pub const ICC_SRE_EL2: Self = Self::System(0b11_100_1100_1001_101);\n    /// Interrupt Controller Hyp Control Register\n    pub const ICH_HCR_EL2: Self = Self::System(0b11_100_1100_1011_000);\n    /// Interrupt Controller VGIC Type Register\n    pub const ICH_VTR_EL2: Self = Self::System(0b11_100_1100_1011_001);\n    /// Interrupt Controller Maintenance Interrupt State Register\n    pub const ICH_MISR_EL2: Self = Self::System(0b11_100_1100_1011_010);\n    /// Interrupt Controller End Of Interrupt Status Register\n    pub const ICH_EISR_EL2: Self = Self::System(0b11_100_1100_1011_011);\n    /// Interrupt Controller Empty List Register Status Register\n    pub const ICH_ELRSR_EL2: Self = Self::System(0b11_100_1100_1011_101);\n    /// Interrupt Controller Virtual Machine Control Register\n    pub const ICH_VMCR_EL2: Self = Self::System(0b11_100_1100_1011_111);\n    /// Interrupt Controller List Registers - 0\n    pub const ICH_LR0_EL2: Self = Self::System(0b11_100_1100_1100_000);\n    /// Interrupt Controller List Registers - 1\n    pub const ICH_LR1_EL2: Self = Self::System(0b11_100_1100_1100_001);\n    /// Interrupt Controller List Registers - 2\n    pub const ICH_LR2_EL2: Self = Self::System(0b11_100_1100_1100_010);\n    /// Interrupt Controller List Registers - 3\n    pub const ICH_LR3_EL2: Self = Self::System(0b11_100_1100_1100_011);\n    /// Interrupt Controller List Registers - 4\n    pub const ICH_LR4_EL2: Self = Self::System(0b11_100_1100_1100_100);\n    /// Interrupt Controller List Registers - 5\n    pub const ICH_LR5_EL2: Self = Self::System(0b11_100_1100_1100_101);\n    /// Interrupt Controller List Registers - 6\n    pub const ICH_LR6_EL2: Self = Self::System(0b11_100_1100_1100_110);\n    /// Interrupt Controller List Registers - 7\n    pub const ICH_LR7_EL2: Self = Self::System(0b11_100_1100_1100_111);\n    /// Interrupt Controller List Registers - 8\n    pub const ICH_LR8_EL2: Self = Self::System(0b11_100_1100_1101_000);\n    /// Interrupt Controller List Registers - 9\n    pub const ICH_LR9_EL2: Self = Self::System(0b11_100_1100_1101_001);\n    /// Interrupt Controller List Registers - 10\n    pub const ICH_LR10_EL2: Self = Self::System(0b11_100_1100_1101_010);\n    /// Interrupt Controller List Registers - 11\n    pub const ICH_LR11_EL2: Self = Self::System(0b11_100_1100_1101_011);\n    /// Interrupt Controller List Registers - 12\n    pub const ICH_LR12_EL2: Self = Self::System(0b11_100_1100_1101_100);\n    /// Interrupt Controller List Registers - 13\n    pub const ICH_LR13_EL2: Self = Self::System(0b11_100_1100_1101_101);\n    /// Interrupt Controller List Registers - 14\n    pub const ICH_LR14_EL2: Self = Self::System(0b11_100_1100_1101_110);\n    /// Interrupt Controller List Registers - 15\n    pub const ICH_LR15_EL2: Self = Self::System(0b11_100_1100_1101_111);\n    /// Context ID Register (EL2)\n    pub const CONTEXTIDR_EL2: Self = Self::System(0b11_100_1101_0000_001);\n    /// EL2 Software Thread ID Register\n    pub const TPIDR_EL2: Self = Self::System(0b11_100_1101_0000_010);\n    /// EL2 Read/Write Software Context Number\n    pub const SCXTNUM_EL2: Self = Self::System(0b11_100_1101_0000_111);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 0\n    pub const AMEVCNTVOFF00_EL2: Self = Self::System(0b11_100_1101_1000_000);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 1\n    pub const AMEVCNTVOFF01_EL2: Self = Self::System(0b11_100_1101_1000_001);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 2\n    pub const AMEVCNTVOFF02_EL2: Self = Self::System(0b11_100_1101_1000_010);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 3\n    pub const AMEVCNTVOFF03_EL2: Self = Self::System(0b11_100_1101_1000_011);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 4\n    pub const AMEVCNTVOFF04_EL2: Self = Self::System(0b11_100_1101_1000_100);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 5\n    pub const AMEVCNTVOFF05_EL2: Self = Self::System(0b11_100_1101_1000_101);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 6\n    pub const AMEVCNTVOFF06_EL2: Self = Self::System(0b11_100_1101_1000_110);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 7\n    pub const AMEVCNTVOFF07_EL2: Self = Self::System(0b11_100_1101_1000_111);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 8\n    pub const AMEVCNTVOFF08_EL2: Self = Self::System(0b11_100_1101_1001_000);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 9\n    pub const AMEVCNTVOFF09_EL2: Self = Self::System(0b11_100_1101_1001_001);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 10\n    pub const AMEVCNTVOFF010_EL2: Self = Self::System(0b11_100_1101_1001_010);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 11\n    pub const AMEVCNTVOFF011_EL2: Self = Self::System(0b11_100_1101_1001_011);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 12\n    pub const AMEVCNTVOFF012_EL2: Self = Self::System(0b11_100_1101_1001_100);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 13\n    pub const AMEVCNTVOFF013_EL2: Self = Self::System(0b11_100_1101_1001_101);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 14\n    pub const AMEVCNTVOFF014_EL2: Self = Self::System(0b11_100_1101_1001_110);\n    /// Activity Monitors Event Counter Virtual Offset Registers 0 - 15\n    pub const AMEVCNTVOFF015_EL2: Self = Self::System(0b11_100_1101_1001_111);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 0\n    pub const AMEVCNTVOFF10_EL2: Self = Self::System(0b11_100_1101_1010_000);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 1\n    pub const AMEVCNTVOFF11_EL2: Self = Self::System(0b11_100_1101_1010_001);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 2\n    pub const AMEVCNTVOFF12_EL2: Self = Self::System(0b11_100_1101_1010_010);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 3\n    pub const AMEVCNTVOFF13_EL2: Self = Self::System(0b11_100_1101_1010_011);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 4\n    pub const AMEVCNTVOFF14_EL2: Self = Self::System(0b11_100_1101_1010_100);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 5\n    pub const AMEVCNTVOFF15_EL2: Self = Self::System(0b11_100_1101_1010_101);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 6\n    pub const AMEVCNTVOFF16_EL2: Self = Self::System(0b11_100_1101_1010_110);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 7\n    pub const AMEVCNTVOFF17_EL2: Self = Self::System(0b11_100_1101_1010_111);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 8\n    pub const AMEVCNTVOFF18_EL2: Self = Self::System(0b11_100_1101_1011_000);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 9\n    pub const AMEVCNTVOFF19_EL2: Self = Self::System(0b11_100_1101_1011_001);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 10\n    pub const AMEVCNTVOFF110_EL2: Self = Self::System(0b11_100_1101_1011_010);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 11\n    pub const AMEVCNTVOFF111_EL2: Self = Self::System(0b11_100_1101_1011_011);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 12\n    pub const AMEVCNTVOFF112_EL2: Self = Self::System(0b11_100_1101_1011_100);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 13\n    pub const AMEVCNTVOFF113_EL2: Self = Self::System(0b11_100_1101_1011_101);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 14\n    pub const AMEVCNTVOFF114_EL2: Self = Self::System(0b11_100_1101_1011_110);\n    /// Activity Monitors Event Counter Virtual Offset Registers 1 - 15\n    pub const AMEVCNTVOFF115_EL2: Self = Self::System(0b11_100_1101_1011_111);\n    /// Counter-timer Virtual Offset Register\n    pub const CNTVOFF_EL2: Self = Self::System(0b11_100_1110_0000_011);\n    /// Counter-timer Physical Offset Register\n    pub const CNTPOFF_EL2: Self = Self::System(0b11_100_1110_0000_110);\n    /// Counter-timer Hypervisor Control Register\n    pub const CNTHCTL_EL2: Self = Self::System(0b11_100_1110_0001_000);\n    /// Counter-timer Physical Timer TimerValue Register (EL2)\n    pub const CNTHP_TVAL_EL2: Self = Self::System(0b11_100_1110_0010_000);\n    /// Counter-timer Hypervisor Physical Timer Control Register\n    pub const CNTHP_CTL_EL2: Self = Self::System(0b11_100_1110_0010_001);\n    /// Counter-timer Physical Timer CompareValue Register (EL2)\n    pub const CNTHP_CVAL_EL2: Self = Self::System(0b11_100_1110_0010_010);\n    /// Counter-timer Virtual Timer TimerValue Register (EL2)\n    pub const CNTHV_TVAL_EL2: Self = Self::System(0b11_100_1110_0011_000);\n    /// Counter-timer Virtual Timer Control Register (EL2)\n    pub const CNTHV_CTL_EL2: Self = Self::System(0b11_100_1110_0011_001);\n    /// Counter-timer Virtual Timer CompareValue Register (EL2)\n    pub const CNTHV_CVAL_EL2: Self = Self::System(0b11_100_1110_0011_010);\n    /// Counter-timer Secure Virtual Timer TimerValue Register (EL2)\n    pub const CNTHVS_TVAL_EL2: Self = Self::System(0b11_100_1110_0100_000);\n    /// Counter-timer Secure Virtual Timer Control Register (EL2)\n    pub const CNTHVS_CTL_EL2: Self = Self::System(0b11_100_1110_0100_001);\n    /// Counter-timer Secure Virtual Timer CompareValue Register (EL2)\n    pub const CNTHVS_CVAL_EL2: Self = Self::System(0b11_100_1110_0100_010);\n    /// Counter-timer Secure Physical Timer TimerValue Register (EL2)\n    pub const CNTHPS_TVAL_EL2: Self = Self::System(0b11_100_1110_0101_000);\n    /// Counter-timer Secure Physical Timer Control Register (EL2)\n    pub const CNTHPS_CTL_EL2: Self = Self::System(0b11_100_1110_0101_001);\n    /// Counter-timer Secure Physical Timer CompareValue Register (EL2)\n    pub const CNTHPS_CVAL_EL2: Self = Self::System(0b11_100_1110_0101_010);\n    /// System Control Register (EL3)\n    pub const SCTLR_EL3: Self = Self::System(0b11_110_0001_0000_000);\n    /// Auxiliary Control Register (EL3)\n    pub const ACTLR_EL3: Self = Self::System(0b11_110_0001_0000_001);\n    /// Secure Configuration Register\n    pub const SCR_EL3: Self = Self::System(0b11_110_0001_0001_000);\n    /// AArch32 Secure Debug Enable Register\n    pub const SDER32_EL3: Self = Self::System(0b11_110_0001_0001_001);\n    /// Architectural Feature Trap Register (EL3)\n    pub const CPTR_EL3: Self = Self::System(0b11_110_0001_0001_010);\n    /// SVE Control Register (EL3)\n    pub const ZCR_EL3: Self = Self::System(0b11_110_0001_0010_000);\n    /// SME Control Register (EL3)\n    pub const SMCR_EL3: Self = Self::System(0b11_110_0001_0010_110);\n    /// Monitor Debug Configuration Register (EL3)\n    pub const MDCR_EL3: Self = Self::System(0b11_110_0001_0011_001);\n    /// Translation Table Base Register 0 (EL3)\n    pub const TTBR0_EL3: Self = Self::System(0b11_110_0010_0000_000);\n    /// Translation Control Register (EL3)\n    pub const TCR_EL3: Self = Self::System(0b11_110_0010_0000_010);\n    /// Granule Protection Table Base Register\n    pub const GPTBR_EL3: Self = Self::System(0b11_110_0010_0001_100);\n    /// Granule Protection Check Control Register (EL3)\n    pub const GPCCR_EL3: Self = Self::System(0b11_110_0010_0001_110);\n    /// Saved Program Status Register (EL3)\n    pub const SPSR_EL3: Self = Self::System(0b11_110_0100_0000_000);\n    /// Exception Link Register (EL3)\n    pub const ELR_EL3: Self = Self::System(0b11_110_0100_0000_001);\n    /// Stack Pointer (EL2)\n    pub const SP_EL2: Self = Self::System(0b11_110_0100_0001_000);\n    /// Auxiliary Fault Status Register 0 (EL3)\n    pub const AFSR0_EL3: Self = Self::System(0b11_110_0101_0001_000);\n    /// Auxiliary Fault Status Register 1 (EL3)\n    pub const AFSR1_EL3: Self = Self::System(0b11_110_0101_0001_001);\n    /// Exception Syndrome Register (EL3)\n    pub const ESR_EL3: Self = Self::System(0b11_110_0101_0010_000);\n    /// Tag Fault Status Register (EL3)\n    pub const TFSR_EL3: Self = Self::System(0b11_110_0101_0110_000);\n    /// Fault Address Register (EL3)\n    pub const FAR_EL3: Self = Self::System(0b11_110_0110_0000_000);\n    /// PA Fault Address Register\n    pub const MFAR_EL3: Self = Self::System(0b11_110_0110_0000_101);\n    /// Memory Attribute Indirection Register (EL3)\n    pub const MAIR_EL3: Self = Self::System(0b11_110_1010_0010_000);\n    /// Auxiliary Memory Attribute Indirection Register (EL3)\n    pub const AMAIR_EL3: Self = Self::System(0b11_110_1010_0011_000);\n    /// MPAM3 Register (EL3)\n    pub const MPAM3_EL3: Self = Self::System(0b11_110_1010_0101_000);\n    /// Vector Base Address Register (EL3)\n    pub const VBAR_EL3: Self = Self::System(0b11_110_1100_0000_000);\n    /// Reset Vector Base Address Register (if EL3 Implemented)\n    pub const RVBAR_EL3: Self = Self::System(0b11_110_1100_0000_001);\n    /// Reset Management Register (EL3)\n    pub const RMR_EL3: Self = Self::System(0b11_110_1100_0000_010);\n    /// Interrupt Controller Control Register (EL3)\n    pub const ICC_CTLR_EL3: Self = Self::System(0b11_110_1100_1100_100);\n    /// Interrupt Controller System Register Enable Register (EL3)\n    pub const ICC_SRE_EL3: Self = Self::System(0b11_110_1100_1100_101);\n    /// Interrupt Controller Interrupt Group 1 Enable Register (EL3)\n    pub const ICC_IGRPEN1_EL3: Self = Self::System(0b11_110_1100_1100_111);\n    /// EL3 Software Thread ID Register\n    pub const TPIDR_EL3: Self = Self::System(0b11_110_1101_0000_010);\n    /// EL3 Read/Write Software Context Number\n    pub const SCXTNUM_EL3: Self = Self::System(0b11_110_1101_0000_111);\n    /// Counter-timer Physical Secure Timer TimerValue Register\n    pub const CNTPS_TVAL_EL1: Self = Self::System(0b11_111_1110_0010_000);\n    /// Counter-timer Physical Secure Timer Control Register\n    pub const CNTPS_CTL_EL1: Self = Self::System(0b11_111_1110_0010_001);\n    /// Counter-timer Physical Secure Timer CompareValue Register\n    pub const CNTPS_CVAL_EL1: Self = Self::System(0b11_111_1110_0010_010);\n\n    /// OS Lock Data Transfer Register, Receive\n    pub const OSDTRRX_EL1: Self = Self::System(0b10_000_0000_0000_010);\n    /// Debug Breakpoint Value Registers - 0\n    pub const DBGBVR0_EL1: Self = Self::System(0b10_000_0000_0000_100);\n    /// Debug Breakpoint Control Registers - 0\n    pub const DBGBCR0_EL1: Self = Self::System(0b10_000_0000_0000_101);\n    /// Debug Watchpoint Value Registers - 0\n    pub const DBGWVR0_EL1: Self = Self::System(0b10_000_0000_0000_110);\n    /// Debug Watchpoint Control Registers - 0\n    pub const DBGWCR0_EL1: Self = Self::System(0b10_000_0000_0000_111);\n    /// Debug Breakpoint Value Registers - 1\n    pub const DBGBVR1_EL1: Self = Self::System(0b10_000_0000_0001_100);\n    /// Debug Breakpoint Control Registers - 1\n    pub const DBGBCR1_EL1: Self = Self::System(0b10_000_0000_0001_101);\n    /// Debug Watchpoint Value Registers - 1\n    pub const DBGWVR1_EL1: Self = Self::System(0b10_000_0000_0001_110);\n    /// Debug Watchpoint Control Registers - 1\n    pub const DBGWCR1_EL1: Self = Self::System(0b10_000_0000_0001_111);\n    /// Monitor DCC Interrupt Enable Register\n    pub const MDCCINT_EL1: Self = Self::System(0b10_000_0000_0010_000);\n    /// Monitor Debug System Control Register\n    pub const MDSCR_EL1: Self = Self::System(0b10_000_0000_0010_010);\n    /// Debug Breakpoint Value Registers - 2\n    pub const DBGBVR2_EL1: Self = Self::System(0b10_000_0000_0010_100);\n    /// Debug Breakpoint Control Registers - 2\n    pub const DBGBCR2_EL1: Self = Self::System(0b10_000_0000_0010_101);\n    /// Debug Watchpoint Value Registers - 2\n    pub const DBGWVR2_EL1: Self = Self::System(0b10_000_0000_0010_110);\n    /// Debug Watchpoint Control Registers - 2\n    pub const DBGWCR2_EL1: Self = Self::System(0b10_000_0000_0010_111);\n    /// OS Lock Data Transfer Register, Transmit\n    pub const OSDTRTX_EL1: Self = Self::System(0b10_000_0000_0011_010);\n    /// Debug Breakpoint Value Registers - 3\n    pub const DBGBVR3_EL1: Self = Self::System(0b10_000_0000_0011_100);\n    /// Debug Breakpoint Control Registers - 3\n    pub const DBGBCR3_EL1: Self = Self::System(0b10_000_0000_0011_101);\n    /// Debug Watchpoint Value Registers - 3\n    pub const DBGWVR3_EL1: Self = Self::System(0b10_000_0000_0011_110);\n    /// Debug Watchpoint Control Registers - 3\n    pub const DBGWCR3_EL1: Self = Self::System(0b10_000_0000_0011_111);\n    /// Debug Breakpoint Value Registers - 4\n    pub const DBGBVR4_EL1: Self = Self::System(0b10_000_0000_0100_100);\n    /// Debug Breakpoint Control Registers - 4\n    pub const DBGBCR4_EL1: Self = Self::System(0b10_000_0000_0100_101);\n    /// Debug Watchpoint Value Registers - 4\n    pub const DBGWVR4_EL1: Self = Self::System(0b10_000_0000_0100_110);\n    /// Debug Watchpoint Control Registers - 4\n    pub const DBGWCR4_EL1: Self = Self::System(0b10_000_0000_0100_111);\n    /// Debug Breakpoint Value Registers - 5\n    pub const DBGBVR5_EL1: Self = Self::System(0b10_000_0000_0101_100);\n    /// Debug Breakpoint Control Registers - 5\n    pub const DBGBCR5_EL1: Self = Self::System(0b10_000_0000_0101_101);\n    /// Debug Watchpoint Value Registers - 5\n    pub const DBGWVR5_EL1: Self = Self::System(0b10_000_0000_0101_110);\n    /// Debug Watchpoint Control Registers - 5\n    pub const DBGWCR5_EL1: Self = Self::System(0b10_000_0000_0101_111);\n    /// OS Lock Exception Catch Control Register\n    pub const OSECCR_EL1: Self = Self::System(0b10_000_0000_0110_010);\n    /// Debug Breakpoint Value Registers - 6\n    pub const DBGBVR6_EL1: Self = Self::System(0b10_000_0000_0110_100);\n    /// Debug Breakpoint Control Registers - 6\n    pub const DBGBCR6_EL1: Self = Self::System(0b10_000_0000_0110_101);\n    /// Debug Watchpoint Value Registers - 6\n    pub const DBGWVR6_EL1: Self = Self::System(0b10_000_0000_0110_110);\n    /// Debug Watchpoint Control Registers - 6\n    pub const DBGWCR6_EL1: Self = Self::System(0b10_000_0000_0110_111);\n    /// Debug Breakpoint Value Registers - 7\n    pub const DBGBVR7_EL1: Self = Self::System(0b10_000_0000_0111_100);\n    /// Debug Breakpoint Control Registers - 7\n    pub const DBGBCR7_EL1: Self = Self::System(0b10_000_0000_0111_101);\n    /// Debug Watchpoint Value Registers - 7\n    pub const DBGWVR7_EL1: Self = Self::System(0b10_000_0000_0111_110);\n    /// Debug Watchpoint Control Registers - 7\n    pub const DBGWCR7_EL1: Self = Self::System(0b10_000_0000_0111_111);\n    /// Debug Breakpoint Value Registers - 8\n    pub const DBGBVR8_EL1: Self = Self::System(0b10_000_0000_1000_100);\n    /// Debug Breakpoint Control Registers - 8\n    pub const DBGBCR8_EL1: Self = Self::System(0b10_000_0000_1000_101);\n    /// Debug Watchpoint Value Registers - 8\n    pub const DBGWVR8_EL1: Self = Self::System(0b10_000_0000_1000_110);\n    /// Debug Watchpoint Control Registers - 8\n    pub const DBGWCR8_EL1: Self = Self::System(0b10_000_0000_1000_111);\n    /// Debug Breakpoint Value Registers - 9\n    pub const DBGBVR9_EL1: Self = Self::System(0b10_000_0000_1001_100);\n    /// Debug Breakpoint Control Registers - 9\n    pub const DBGBCR9_EL1: Self = Self::System(0b10_000_0000_1001_101);\n    /// Debug Watchpoint Value Registers - 9\n    pub const DBGWVR9_EL1: Self = Self::System(0b10_000_0000_1001_110);\n    /// Debug Watchpoint Control Registers - 9\n    pub const DBGWCR9_EL1: Self = Self::System(0b10_000_0000_1001_111);\n    /// Debug Breakpoint Value Registers - 10\n    pub const DBGBVR10_EL1: Self = Self::System(0b10_000_0000_1010_100);\n    /// Debug Breakpoint Control Registers - 10\n    pub const DBGBCR10_EL1: Self = Self::System(0b10_000_0000_1010_101);\n    /// Debug Watchpoint Value Registers - 10\n    pub const DBGWVR10_EL1: Self = Self::System(0b10_000_0000_1010_110);\n    /// Debug Watchpoint Control Registers - 10\n    pub const DBGWCR10_EL1: Self = Self::System(0b10_000_0000_1010_111);\n    /// Debug Breakpoint Value Registers - 11\n    pub const DBGBVR11_EL1: Self = Self::System(0b10_000_0000_1011_100);\n    /// Debug Breakpoint Control Registers - 11\n    pub const DBGBCR11_EL1: Self = Self::System(0b10_000_0000_1011_101);\n    /// Debug Watchpoint Value Registers - 11\n    pub const DBGWVR11_EL1: Self = Self::System(0b10_000_0000_1011_110);\n    /// Debug Watchpoint Control Registers - 11\n    pub const DBGWCR11_EL1: Self = Self::System(0b10_000_0000_1011_111);\n    /// Debug Breakpoint Value Registers - 12\n    pub const DBGBVR12_EL1: Self = Self::System(0b10_000_0000_1100_100);\n    /// Debug Breakpoint Control Registers - 12\n    pub const DBGBCR12_EL1: Self = Self::System(0b10_000_0000_1100_101);\n    /// Debug Watchpoint Value Registers - 12\n    pub const DBGWVR12_EL1: Self = Self::System(0b10_000_0000_1100_110);\n    /// Debug Watchpoint Control Registers - 12\n    pub const DBGWCR12_EL1: Self = Self::System(0b10_000_0000_1100_111);\n    /// Debug Breakpoint Value Registers - 13\n    pub const DBGBVR13_EL1: Self = Self::System(0b10_000_0000_1101_100);\n    /// Debug Breakpoint Control Registers - 13\n    pub const DBGBCR13_EL1: Self = Self::System(0b10_000_0000_1101_101);\n    /// Debug Watchpoint Value Registers - 13\n    pub const DBGWVR13_EL1: Self = Self::System(0b10_000_0000_1101_110);\n    /// Debug Watchpoint Control Registers - 13\n    pub const DBGWCR13_EL1: Self = Self::System(0b10_000_0000_1101_111);\n    /// Debug Breakpoint Value Registers - 14\n    pub const DBGBVR14_EL1: Self = Self::System(0b10_000_0000_1110_100);\n    /// Debug Breakpoint Control Registers - 14\n    pub const DBGBCR14_EL1: Self = Self::System(0b10_000_0000_1110_101);\n    /// Debug Watchpoint Value Registers - 14\n    pub const DBGWVR14_EL1: Self = Self::System(0b10_000_0000_1110_110);\n    /// Debug Watchpoint Control Registers - 14\n    pub const DBGWCR14_EL1: Self = Self::System(0b10_000_0000_1110_111);\n    /// Debug Breakpoint Value Registers - 15\n    pub const DBGBVR15_EL1: Self = Self::System(0b10_000_0000_1111_100);\n    /// Debug Breakpoint Control Registers - 15\n    pub const DBGBCR15_EL1: Self = Self::System(0b10_000_0000_1111_101);\n    /// Debug Watchpoint Value Registers - 15\n    pub const DBGWVR15_EL1: Self = Self::System(0b10_000_0000_1111_110);\n    /// Debug Watchpoint Control Registers - 15\n    pub const DBGWCR15_EL1: Self = Self::System(0b10_000_0000_1111_111);\n    /// Monitor Debug ROM Address Register\n    pub const MDRAR_EL1: Self = Self::System(0b10_000_0001_0000_000);\n    /// OS Lock Access Register\n    pub const OSLAR_EL1: Self = Self::System(0b10_000_0001_0000_100);\n    /// OS Lock Status Register\n    pub const OSLSR_EL1: Self = Self::System(0b10_000_0001_0001_100);\n    /// OS Double Lock Register\n    pub const OSDLR_EL1: Self = Self::System(0b10_000_0001_0011_100);\n    /// Debug Power Control Register\n    pub const DBGPRCR_EL1: Self = Self::System(0b10_000_0001_0100_100);\n    /// Debug CLAIM Tag Set Register\n    pub const DBGCLAIMSET_EL1: Self = Self::System(0b10_000_0111_1000_110);\n    /// Debug CLAIM Tag Clear Register\n    pub const DBGCLAIMCLR_EL1: Self = Self::System(0b10_000_0111_1001_110);\n    /// Debug Authentication Status Register\n    pub const DBGAUTHSTATUS_EL1: Self = Self::System(0b10_000_0111_1110_110);\n    /// Trace ID Register\n    pub const TRCTRACEIDR: Self = Self::System(0b10_001_0000_0000_001);\n    /// ViewInst Main Control Register\n    pub const TRCVICTLR: Self = Self::System(0b10_001_0000_0000_010);\n    /// Sequencer State Transition Control Register 0\n    pub const TRCSEQEVR0: Self = Self::System(0b10_001_0000_0000_100);\n    /// Counter Reload Value Register 0\n    pub const TRCCNTRLDVR0: Self = Self::System(0b10_001_0000_0000_101);\n    /// ID Register 8\n    pub const TRCIDR8: Self = Self::System(0b10_001_0000_0000_110);\n    /// IMP DEF Register 0\n    pub const TRCIMSPEC0: Self = Self::System(0b10_001_0000_0000_111);\n    /// Programming Control Register\n    pub const TRCPRGCTLR: Self = Self::System(0b10_001_0000_0001_000);\n    /// Q Element Control Register\n    pub const TRCQCTLR: Self = Self::System(0b10_001_0000_0001_001);\n    /// ViewInst Include/Exclude Control Register\n    pub const TRCVIIECTLR: Self = Self::System(0b10_001_0000_0001_010);\n    /// Sequencer State Transition Control Register 1\n    pub const TRCSEQEVR1: Self = Self::System(0b10_001_0000_0001_100);\n    /// Counter Reload Value Register 1\n    pub const TRCCNTRLDVR1: Self = Self::System(0b10_001_0000_0001_101);\n    /// ID Register 9\n    pub const TRCIDR9: Self = Self::System(0b10_001_0000_0001_110);\n    /// IMP DEF Register 1\n    pub const TRCIMSPEC1: Self = Self::System(0b10_001_0000_0001_111);\n    /// ViewInst Start/Stop Control Register\n    pub const TRCVISSCTLR: Self = Self::System(0b10_001_0000_0010_010);\n    /// Sequencer State Transition Control Register 2\n    pub const TRCSEQEVR2: Self = Self::System(0b10_001_0000_0010_100);\n    /// Counter Reload Value Register 2\n    pub const TRCCNTRLDVR2: Self = Self::System(0b10_001_0000_0010_101);\n    /// ID Register 10\n    pub const TRCIDR10: Self = Self::System(0b10_001_0000_0010_110);\n    /// IMP DEF Register 2\n    pub const TRCIMSPEC2: Self = Self::System(0b10_001_0000_0010_111);\n    /// Trace Status Register\n    pub const TRCSTATR: Self = Self::System(0b10_001_0000_0011_000);\n    /// ViewInst Start/Stop PE Comparator Control Register\n    pub const TRCVIPCSSCTLR: Self = Self::System(0b10_001_0000_0011_010);\n    /// Counter Reload Value Register 3\n    pub const TRCCNTRLDVR3: Self = Self::System(0b10_001_0000_0011_101);\n    /// ID Register 11\n    pub const TRCIDR11: Self = Self::System(0b10_001_0000_0011_110);\n    /// IMP DEF Register 3\n    pub const TRCIMSPEC3: Self = Self::System(0b10_001_0000_0011_111);\n    /// Trace Configuration Register\n    pub const TRCCONFIGR: Self = Self::System(0b10_001_0000_0100_000);\n    /// Counter Control Register 0\n    pub const TRCCNTCTLR0: Self = Self::System(0b10_001_0000_0100_101);\n    /// ID Register 12\n    pub const TRCIDR12: Self = Self::System(0b10_001_0000_0100_110);\n    /// IMP DEF Register 4\n    pub const TRCIMSPEC4: Self = Self::System(0b10_001_0000_0100_111);\n    /// Counter Control Register 1\n    pub const TRCCNTCTLR1: Self = Self::System(0b10_001_0000_0101_101);\n    /// ID Register 13\n    pub const TRCIDR13: Self = Self::System(0b10_001_0000_0101_110);\n    /// IMP DEF Register 5\n    pub const TRCIMSPEC5: Self = Self::System(0b10_001_0000_0101_111);\n    /// Auxiliary Control Register\n    pub const TRCAUXCTLR: Self = Self::System(0b10_001_0000_0110_000);\n    /// Sequencer Reset Control Register\n    pub const TRCSEQRSTEVR: Self = Self::System(0b10_001_0000_0110_100);\n    /// Counter Control Register 2\n    pub const TRCCNTCTLR2: Self = Self::System(0b10_001_0000_0110_101);\n    /// IMP DEF Register 6\n    pub const TRCIMSPEC6: Self = Self::System(0b10_001_0000_0110_111);\n    /// Sequencer State Register\n    pub const TRCSEQSTR: Self = Self::System(0b10_001_0000_0111_100);\n    /// Counter Control Register 3\n    pub const TRCCNTCTLR3: Self = Self::System(0b10_001_0000_0111_101);\n    /// IMP DEF Register 7\n    pub const TRCIMSPEC7: Self = Self::System(0b10_001_0000_0111_111);\n    /// Event Control 0 Register\n    pub const TRCEVENTCTL0R: Self = Self::System(0b10_001_0000_1000_000);\n    /// External Input Select Register 0\n    pub const TRCEXTINSELR0: Self = Self::System(0b10_001_0000_1000_100);\n    /// Counter Value Register 0\n    pub const TRCCNTVR0: Self = Self::System(0b10_001_0000_1000_101);\n    /// ID Register 0\n    pub const TRCIDR0: Self = Self::System(0b10_001_0000_1000_111);\n    /// Event Control 1 Register\n    pub const TRCEVENTCTL1R: Self = Self::System(0b10_001_0000_1001_000);\n    /// External Input Select Register 1\n    pub const TRCEXTINSELR1: Self = Self::System(0b10_001_0000_1001_100);\n    /// Counter Value Register 1\n    pub const TRCCNTVR1: Self = Self::System(0b10_001_0000_1001_101);\n    /// ID Register 1\n    pub const TRCIDR1: Self = Self::System(0b10_001_0000_1001_111);\n    /// Resources Status Register\n    pub const TRCRSR: Self = Self::System(0b10_001_0000_1010_000);\n    /// External Input Select Register 2\n    pub const TRCEXTINSELR2: Self = Self::System(0b10_001_0000_1010_100);\n    /// Counter Value Register 2\n    pub const TRCCNTVR2: Self = Self::System(0b10_001_0000_1010_101);\n    /// ID Register 2\n    pub const TRCIDR2: Self = Self::System(0b10_001_0000_1010_111);\n    /// Stall Control Register\n    pub const TRCSTALLCTLR: Self = Self::System(0b10_001_0000_1011_000);\n    /// External Input Select Register 3\n    pub const TRCEXTINSELR3: Self = Self::System(0b10_001_0000_1011_100);\n    /// Counter Value Register 3\n    pub const TRCCNTVR3: Self = Self::System(0b10_001_0000_1011_101);\n    /// ID Register 3\n    pub const TRCIDR3: Self = Self::System(0b10_001_0000_1011_111);\n    /// Timestamp Control Register\n    pub const TRCTSCTLR: Self = Self::System(0b10_001_0000_1100_000);\n    /// ID Register 4\n    pub const TRCIDR4: Self = Self::System(0b10_001_0000_1100_111);\n    /// Synchronization Period Register\n    pub const TRCSYNCPR: Self = Self::System(0b10_001_0000_1101_000);\n    /// ID Register 5\n    pub const TRCIDR5: Self = Self::System(0b10_001_0000_1101_111);\n    /// Cycle Count Control Register\n    pub const TRCCCCTLR: Self = Self::System(0b10_001_0000_1110_000);\n    /// ID Register 6\n    pub const TRCIDR6: Self = Self::System(0b10_001_0000_1110_111);\n    /// Branch Broadcast Control Register\n    pub const TRCBBCTLR: Self = Self::System(0b10_001_0000_1111_000);\n    /// ID Register 7\n    pub const TRCIDR7: Self = Self::System(0b10_001_0000_1111_111);\n    /// Resource Selection Control Register 16\n    pub const TRCRSCTLR16: Self = Self::System(0b10_001_0001_0000_001);\n    /// Single-shot Comparator Control Register 0\n    pub const TRCSSCCR0: Self = Self::System(0b10_001_0001_0000_010);\n    /// Single-shot Processing Element Comparator Input Control Register 0\n    pub const TRCSSPCICR0: Self = Self::System(0b10_001_0001_0000_011);\n    /// Resource Selection Control Register 17\n    pub const TRCRSCTLR17: Self = Self::System(0b10_001_0001_0001_001);\n    /// Single-shot Comparator Control Register 1\n    pub const TRCSSCCR1: Self = Self::System(0b10_001_0001_0001_010);\n    /// Single-shot Processing Element Comparator Input Control Register 1\n    pub const TRCSSPCICR1: Self = Self::System(0b10_001_0001_0001_011);\n    /// Trace OS Lock Status Register\n    pub const TRCOSLSR: Self = Self::System(0b10_001_0001_0001_100);\n    /// Resource Selection Control Register 2\n    pub const TRCRSCTLR2: Self = Self::System(0b10_001_0001_0010_000);\n    /// Resource Selection Control Register 18\n    pub const TRCRSCTLR18: Self = Self::System(0b10_001_0001_0010_001);\n    /// Single-shot Comparator Control Register 2\n    pub const TRCSSCCR2: Self = Self::System(0b10_001_0001_0010_010);\n    /// Single-shot Processing Element Comparator Input Control Register 2\n    pub const TRCSSPCICR2: Self = Self::System(0b10_001_0001_0010_011);\n    /// Resource Selection Control Register 3\n    pub const TRCRSCTLR3: Self = Self::System(0b10_001_0001_0011_000);\n    /// Resource Selection Control Register 19\n    pub const TRCRSCTLR19: Self = Self::System(0b10_001_0001_0011_001);\n    /// Single-shot Comparator Control Register 3\n    pub const TRCSSCCR3: Self = Self::System(0b10_001_0001_0011_010);\n    /// Single-shot Processing Element Comparator Input Control Register 3\n    pub const TRCSSPCICR3: Self = Self::System(0b10_001_0001_0011_011);\n    /// Resource Selection Control Register 4\n    pub const TRCRSCTLR4: Self = Self::System(0b10_001_0001_0100_000);\n    /// Resource Selection Control Register 20\n    pub const TRCRSCTLR20: Self = Self::System(0b10_001_0001_0100_001);\n    /// Single-shot Comparator Control Register 4\n    pub const TRCSSCCR4: Self = Self::System(0b10_001_0001_0100_010);\n    /// Single-shot Processing Element Comparator Input Control Register 4\n    pub const TRCSSPCICR4: Self = Self::System(0b10_001_0001_0100_011);\n    /// Resource Selection Control Register 5\n    pub const TRCRSCTLR5: Self = Self::System(0b10_001_0001_0101_000);\n    /// Resource Selection Control Register 21\n    pub const TRCRSCTLR21: Self = Self::System(0b10_001_0001_0101_001);\n    /// Single-shot Comparator Control Register 5\n    pub const TRCSSCCR5: Self = Self::System(0b10_001_0001_0101_010);\n    /// Single-shot Processing Element Comparator Input Control Register 5\n    pub const TRCSSPCICR5: Self = Self::System(0b10_001_0001_0101_011);\n    /// Resource Selection Control Register 6\n    pub const TRCRSCTLR6: Self = Self::System(0b10_001_0001_0110_000);\n    /// Resource Selection Control Register 22\n    pub const TRCRSCTLR22: Self = Self::System(0b10_001_0001_0110_001);\n    /// Single-shot Comparator Control Register 6\n    pub const TRCSSCCR6: Self = Self::System(0b10_001_0001_0110_010);\n    /// Single-shot Processing Element Comparator Input Control Register 6\n    pub const TRCSSPCICR6: Self = Self::System(0b10_001_0001_0110_011);\n    /// Resource Selection Control Register 7\n    pub const TRCRSCTLR7: Self = Self::System(0b10_001_0001_0111_000);\n    /// Resource Selection Control Register 23\n    pub const TRCRSCTLR23: Self = Self::System(0b10_001_0001_0111_001);\n    /// Single-shot Comparator Control Register 7\n    pub const TRCSSCCR7: Self = Self::System(0b10_001_0001_0111_010);\n    /// Single-shot Processing Element Comparator Input Control Register 7\n    pub const TRCSSPCICR7: Self = Self::System(0b10_001_0001_0111_011);\n    /// Resource Selection Control Register 8\n    pub const TRCRSCTLR8: Self = Self::System(0b10_001_0001_1000_000);\n    /// Resource Selection Control Register 24\n    pub const TRCRSCTLR24: Self = Self::System(0b10_001_0001_1000_001);\n    /// Single-shot Comparator Control Status Register 0\n    pub const TRCSSCSR0: Self = Self::System(0b10_001_0001_1000_010);\n    /// Resource Selection Control Register 9\n    pub const TRCRSCTLR9: Self = Self::System(0b10_001_0001_1001_000);\n    /// Resource Selection Control Register 25\n    pub const TRCRSCTLR25: Self = Self::System(0b10_001_0001_1001_001);\n    /// Single-shot Comparator Control Status Register 1\n    pub const TRCSSCSR1: Self = Self::System(0b10_001_0001_1001_010);\n    /// Resource Selection Control Register 10\n    pub const TRCRSCTLR10: Self = Self::System(0b10_001_0001_1010_000);\n    /// Resource Selection Control Register 26\n    pub const TRCRSCTLR26: Self = Self::System(0b10_001_0001_1010_001);\n    /// Single-shot Comparator Control Status Register 2\n    pub const TRCSSCSR2: Self = Self::System(0b10_001_0001_1010_010);\n    /// Resource Selection Control Register 11\n    pub const TRCRSCTLR11: Self = Self::System(0b10_001_0001_1011_000);\n    /// Resource Selection Control Register 27\n    pub const TRCRSCTLR27: Self = Self::System(0b10_001_0001_1011_001);\n    /// Single-shot Comparator Control Status Register 3\n    pub const TRCSSCSR3: Self = Self::System(0b10_001_0001_1011_010);\n    /// Resource Selection Control Register 12\n    pub const TRCRSCTLR12: Self = Self::System(0b10_001_0001_1100_000);\n    /// Resource Selection Control Register 28\n    pub const TRCRSCTLR28: Self = Self::System(0b10_001_0001_1100_001);\n    /// Single-shot Comparator Control Status Register 4\n    pub const TRCSSCSR4: Self = Self::System(0b10_001_0001_1100_010);\n    /// Resource Selection Control Register 13\n    pub const TRCRSCTLR13: Self = Self::System(0b10_001_0001_1101_000);\n    /// Resource Selection Control Register 29\n    pub const TRCRSCTLR29: Self = Self::System(0b10_001_0001_1101_001);\n    /// Single-shot Comparator Control Status Register 5\n    pub const TRCSSCSR5: Self = Self::System(0b10_001_0001_1101_010);\n    /// Resource Selection Control Register 14\n    pub const TRCRSCTLR14: Self = Self::System(0b10_001_0001_1110_000);\n    /// Resource Selection Control Register 30\n    pub const TRCRSCTLR30: Self = Self::System(0b10_001_0001_1110_001);\n    /// Single-shot Comparator Control Status Register 6\n    pub const TRCSSCSR6: Self = Self::System(0b10_001_0001_1110_010);\n    /// Resource Selection Control Register 15\n    pub const TRCRSCTLR15: Self = Self::System(0b10_001_0001_1111_000);\n    /// Resource Selection Control Register 31\n    pub const TRCRSCTLR31: Self = Self::System(0b10_001_0001_1111_001);\n    /// Single-shot Comparator Control Status Register 7\n    pub const TRCSSCSR7: Self = Self::System(0b10_001_0001_1111_010);\n    /// Address Comparator Value Register 0\n    pub const TRCACVR0: Self = Self::System(0b10_001_0010_0000_000);\n    /// Address Comparator Value Register 8\n    pub const TRCACVR8: Self = Self::System(0b10_001_0010_0000_001);\n    /// Address Comparator Access Type Register 0\n    pub const TRCACATR0: Self = Self::System(0b10_001_0010_0000_010);\n    /// Address Comparator Access Type Register 8\n    pub const TRCACATR8: Self = Self::System(0b10_001_0010_0000_011);\n    /// Address Comparator Value Register 1\n    pub const TRCACVR1: Self = Self::System(0b10_001_0010_0010_000);\n    /// Address Comparator Value Register 9\n    pub const TRCACVR9: Self = Self::System(0b10_001_0010_0010_001);\n    /// Address Comparator Access Type Register 1\n    pub const TRCACATR1: Self = Self::System(0b10_001_0010_0010_010);\n    /// Address Comparator Access Type Register 9\n    pub const TRCACATR9: Self = Self::System(0b10_001_0010_0010_011);\n    /// Address Comparator Value Register 2\n    pub const TRCACVR2: Self = Self::System(0b10_001_0010_0100_000);\n    /// Address Comparator Value Register 10\n    pub const TRCACVR10: Self = Self::System(0b10_001_0010_0100_001);\n    /// Address Comparator Access Type Register 2\n    pub const TRCACATR2: Self = Self::System(0b10_001_0010_0100_010);\n    /// Address Comparator Access Type Register 10\n    pub const TRCACATR10: Self = Self::System(0b10_001_0010_0100_011);\n    /// Address Comparator Value Register 3\n    pub const TRCACVR3: Self = Self::System(0b10_001_0010_0110_000);\n    /// Address Comparator Value Register 11\n    pub const TRCACVR11: Self = Self::System(0b10_001_0010_0110_001);\n    /// Address Comparator Access Type Register 3\n    pub const TRCACATR3: Self = Self::System(0b10_001_0010_0110_010);\n    /// Address Comparator Access Type Register 11\n    pub const TRCACATR11: Self = Self::System(0b10_001_0010_0110_011);\n    /// Address Comparator Value Register 4\n    pub const TRCACVR4: Self = Self::System(0b10_001_0010_1000_000);\n    /// Address Comparator Value Register 12\n    pub const TRCACVR12: Self = Self::System(0b10_001_0010_1000_001);\n    /// Address Comparator Access Type Register 4\n    pub const TRCACATR4: Self = Self::System(0b10_001_0010_1000_010);\n    /// Address Comparator Access Type Register 12\n    pub const TRCACATR12: Self = Self::System(0b10_001_0010_1000_011);\n    /// Address Comparator Value Register 5\n    pub const TRCACVR5: Self = Self::System(0b10_001_0010_1010_000);\n    /// Address Comparator Value Register 13\n    pub const TRCACVR13: Self = Self::System(0b10_001_0010_1010_001);\n    /// Address Comparator Access Type Register 5\n    pub const TRCACATR5: Self = Self::System(0b10_001_0010_1010_010);\n    /// Address Comparator Access Type Register 13\n    pub const TRCACATR13: Self = Self::System(0b10_001_0010_1010_011);\n    /// Address Comparator Value Register 6\n    pub const TRCACVR6: Self = Self::System(0b10_001_0010_1100_000);\n    /// Address Comparator Value Register 14\n    pub const TRCACVR14: Self = Self::System(0b10_001_0010_1100_001);\n    /// Address Comparator Access Type Register 6\n    pub const TRCACATR6: Self = Self::System(0b10_001_0010_1100_010);\n    /// Address Comparator Access Type Register 14\n    pub const TRCACATR14: Self = Self::System(0b10_001_0010_1100_011);\n    /// Address Comparator Value Register 7\n    pub const TRCACVR7: Self = Self::System(0b10_001_0010_1110_000);\n    /// Address Comparator Value Register 15\n    pub const TRCACVR15: Self = Self::System(0b10_001_0010_1110_001);\n    /// Address Comparator Access Type Register 7\n    pub const TRCACATR7: Self = Self::System(0b10_001_0010_1110_010);\n    /// Address Comparator Access Type Register 15\n    pub const TRCACATR15: Self = Self::System(0b10_001_0010_1110_011);\n    /// Context Identifier Comparator Value Registers 0\n    pub const TRCCIDCVR0: Self = Self::System(0b10_001_0011_0000_000);\n    /// Virtual Context Identifier Comparator Value Register 0\n    pub const TRCVMIDCVR0: Self = Self::System(0b10_001_0011_0000_001);\n    /// Context Identifier Comparator Control Register 0\n    pub const TRCCIDCCTLR0: Self = Self::System(0b10_001_0011_0000_010);\n    /// Context Identifier Comparator Control Register 1\n    pub const TRCCIDCCTLR1: Self = Self::System(0b10_001_0011_0001_010);\n    /// Context Identifier Comparator Value Registers 1\n    pub const TRCCIDCVR1: Self = Self::System(0b10_001_0011_0010_000);\n    /// Virtual Context Identifier Comparator Value Register 1\n    pub const TRCVMIDCVR1: Self = Self::System(0b10_001_0011_0010_001);\n    /// Virtual Context Identifier Comparator Control Register 0\n    pub const TRCVMIDCCTLR0: Self = Self::System(0b10_001_0011_0010_010);\n    /// Virtual Context Identifier Comparator Control Register 1\n    pub const TRCVMIDCCTLR1: Self = Self::System(0b10_001_0011_0011_010);\n    /// Context Identifier Comparator Value Registers 2\n    pub const TRCCIDCVR2: Self = Self::System(0b10_001_0011_0100_000);\n    /// Virtual Context Identifier Comparator Value Register 2\n    pub const TRCVMIDCVR2: Self = Self::System(0b10_001_0011_0100_001);\n    /// Context Identifier Comparator Value Registers 3\n    pub const TRCCIDCVR3: Self = Self::System(0b10_001_0011_0110_000);\n    /// Virtual Context Identifier Comparator Value Register 3\n    pub const TRCVMIDCVR3: Self = Self::System(0b10_001_0011_0110_001);\n    /// Context Identifier Comparator Value Registers 4\n    pub const TRCCIDCVR4: Self = Self::System(0b10_001_0011_1000_000);\n    /// Virtual Context Identifier Comparator Value Register 4\n    pub const TRCVMIDCVR4: Self = Self::System(0b10_001_0011_1000_001);\n    /// Context Identifier Comparator Value Registers 5\n    pub const TRCCIDCVR5: Self = Self::System(0b10_001_0011_1010_000);\n    /// Virtual Context Identifier Comparator Value Register 5\n    pub const TRCVMIDCVR5: Self = Self::System(0b10_001_0011_1010_001);\n    /// Context Identifier Comparator Value Registers 6\n    pub const TRCCIDCVR6: Self = Self::System(0b10_001_0011_1100_000);\n    /// Virtual Context Identifier Comparator Value Register 6\n    pub const TRCVMIDCVR6: Self = Self::System(0b10_001_0011_1100_001);\n    /// Context Identifier Comparator Value Registers 7\n    pub const TRCCIDCVR7: Self = Self::System(0b10_001_0011_1110_000);\n    /// Virtual Context Identifier Comparator Value Register 7\n    pub const TRCVMIDCVR7: Self = Self::System(0b10_001_0011_1110_001);\n    /// Device Configuration Register\n    pub const TRCDEVID: Self = Self::System(0b10_001_0111_0010_111);\n    /// Claim Tag Set Register\n    pub const TRCCLAIMSET: Self = Self::System(0b10_001_0111_1000_110);\n    /// Claim Tag Clear Register\n    pub const TRCCLAIMCLR: Self = Self::System(0b10_001_0111_1001_110);\n    /// Authentication Status Register\n    pub const TRCAUTHSTATUS: Self = Self::System(0b10_001_0111_1110_110);\n    /// Device Architecture Register\n    pub const TRCDEVARCH: Self = Self::System(0b10_001_0111_1111_110);\n    /// Branch Record Buffer Information Register 0\n    pub const BRBINF0_EL1: Self = Self::System(0b10_001_1000_0000_000);\n    /// Branch Record Buffer Source Address Register 0\n    pub const BRBSRC0_EL1: Self = Self::System(0b10_001_1000_0000_001);\n    /// Branch Record Buffer Target Address Register 0\n    pub const BRBTGT0_EL1: Self = Self::System(0b10_001_1000_0000_010);\n    /// Branch Record Buffer Information Register 16\n    pub const BRBINF16_EL1: Self = Self::System(0b10_001_1000_0000_100);\n    /// Branch Record Buffer Source Address Register 16\n    pub const BRBSRC16_EL1: Self = Self::System(0b10_001_1000_0000_101);\n    /// Branch Record Buffer Target Address Register 16\n    pub const BRBTGT16_EL1: Self = Self::System(0b10_001_1000_0000_110);\n    /// Branch Record Buffer Information Register 1\n    pub const BRBINF1_EL1: Self = Self::System(0b10_001_1000_0001_000);\n    /// Branch Record Buffer Source Address Register 1\n    pub const BRBSRC1_EL1: Self = Self::System(0b10_001_1000_0001_001);\n    /// Branch Record Buffer Target Address Register 1\n    pub const BRBTGT1_EL1: Self = Self::System(0b10_001_1000_0001_010);\n    /// Branch Record Buffer Information Register 17\n    pub const BRBINF17_EL1: Self = Self::System(0b10_001_1000_0001_100);\n    /// Branch Record Buffer Source Address Register 17\n    pub const BRBSRC17_EL1: Self = Self::System(0b10_001_1000_0001_101);\n    /// Branch Record Buffer Target Address Register 17\n    pub const BRBTGT17_EL1: Self = Self::System(0b10_001_1000_0001_110);\n    /// Branch Record Buffer Information Register 2\n    pub const BRBINF2_EL1: Self = Self::System(0b10_001_1000_0010_000);\n    /// Branch Record Buffer Source Address Register 2\n    pub const BRBSRC2_EL1: Self = Self::System(0b10_001_1000_0010_001);\n    /// Branch Record Buffer Target Address Register 2\n    pub const BRBTGT2_EL1: Self = Self::System(0b10_001_1000_0010_010);\n    /// Branch Record Buffer Information Register 18\n    pub const BRBINF18_EL1: Self = Self::System(0b10_001_1000_0010_100);\n    /// Branch Record Buffer Source Address Register 18\n    pub const BRBSRC18_EL1: Self = Self::System(0b10_001_1000_0010_101);\n    /// Branch Record Buffer Target Address Register 18\n    pub const BRBTGT18_EL1: Self = Self::System(0b10_001_1000_0010_110);\n    /// Branch Record Buffer Information Register 3\n    pub const BRBINF3_EL1: Self = Self::System(0b10_001_1000_0011_000);\n    /// Branch Record Buffer Source Address Register 3\n    pub const BRBSRC3_EL1: Self = Self::System(0b10_001_1000_0011_001);\n    /// Branch Record Buffer Target Address Register 3\n    pub const BRBTGT3_EL1: Self = Self::System(0b10_001_1000_0011_010);\n    /// Branch Record Buffer Information Register 19\n    pub const BRBINF19_EL1: Self = Self::System(0b10_001_1000_0011_100);\n    /// Branch Record Buffer Source Address Register 19\n    pub const BRBSRC19_EL1: Self = Self::System(0b10_001_1000_0011_101);\n    /// Branch Record Buffer Target Address Register 19\n    pub const BRBTGT19_EL1: Self = Self::System(0b10_001_1000_0011_110);\n    /// Branch Record Buffer Information Register 4\n    pub const BRBINF4_EL1: Self = Self::System(0b10_001_1000_0100_000);\n    /// Branch Record Buffer Source Address Register 4\n    pub const BRBSRC4_EL1: Self = Self::System(0b10_001_1000_0100_001);\n    /// Branch Record Buffer Target Address Register 4\n    pub const BRBTGT4_EL1: Self = Self::System(0b10_001_1000_0100_010);\n    /// Branch Record Buffer Information Register 20\n    pub const BRBINF20_EL1: Self = Self::System(0b10_001_1000_0100_100);\n    /// Branch Record Buffer Source Address Register 20\n    pub const BRBSRC20_EL1: Self = Self::System(0b10_001_1000_0100_101);\n    /// Branch Record Buffer Target Address Register 20\n    pub const BRBTGT20_EL1: Self = Self::System(0b10_001_1000_0100_110);\n    /// Branch Record Buffer Information Register 5\n    pub const BRBINF5_EL1: Self = Self::System(0b10_001_1000_0101_000);\n    /// Branch Record Buffer Source Address Register 5\n    pub const BRBSRC5_EL1: Self = Self::System(0b10_001_1000_0101_001);\n    /// Branch Record Buffer Target Address Register 5\n    pub const BRBTGT5_EL1: Self = Self::System(0b10_001_1000_0101_010);\n    /// Branch Record Buffer Information Register 21\n    pub const BRBINF21_EL1: Self = Self::System(0b10_001_1000_0101_100);\n    /// Branch Record Buffer Source Address Register 21\n    pub const BRBSRC21_EL1: Self = Self::System(0b10_001_1000_0101_101);\n    /// Branch Record Buffer Target Address Register 21\n    pub const BRBTGT21_EL1: Self = Self::System(0b10_001_1000_0101_110);\n    /// Branch Record Buffer Information Register 6\n    pub const BRBINF6_EL1: Self = Self::System(0b10_001_1000_0110_000);\n    /// Branch Record Buffer Source Address Register 6\n    pub const BRBSRC6_EL1: Self = Self::System(0b10_001_1000_0110_001);\n    /// Branch Record Buffer Target Address Register 6\n    pub const BRBTGT6_EL1: Self = Self::System(0b10_001_1000_0110_010);\n    /// Branch Record Buffer Information Register 22\n    pub const BRBINF22_EL1: Self = Self::System(0b10_001_1000_0110_100);\n    /// Branch Record Buffer Source Address Register 22\n    pub const BRBSRC22_EL1: Self = Self::System(0b10_001_1000_0110_101);\n    /// Branch Record Buffer Target Address Register 22\n    pub const BRBTGT22_EL1: Self = Self::System(0b10_001_1000_0110_110);\n    /// Branch Record Buffer Information Register 7\n    pub const BRBINF7_EL1: Self = Self::System(0b10_001_1000_0111_000);\n    /// Branch Record Buffer Source Address Register 7\n    pub const BRBSRC7_EL1: Self = Self::System(0b10_001_1000_0111_001);\n    /// Branch Record Buffer Target Address Register 7\n    pub const BRBTGT7_EL1: Self = Self::System(0b10_001_1000_0111_010);\n    /// Branch Record Buffer Information Register 23\n    pub const BRBINF23_EL1: Self = Self::System(0b10_001_1000_0111_100);\n    /// Branch Record Buffer Source Address Register 23\n    pub const BRBSRC23_EL1: Self = Self::System(0b10_001_1000_0111_101);\n    /// Branch Record Buffer Target Address Register 23\n    pub const BRBTGT23_EL1: Self = Self::System(0b10_001_1000_0111_110);\n    /// Branch Record Buffer Information Register 8\n    pub const BRBINF8_EL1: Self = Self::System(0b10_001_1000_1000_000);\n    /// Branch Record Buffer Source Address Register 8\n    pub const BRBSRC8_EL1: Self = Self::System(0b10_001_1000_1000_001);\n    /// Branch Record Buffer Target Address Register 8\n    pub const BRBTGT8_EL1: Self = Self::System(0b10_001_1000_1000_010);\n    /// Branch Record Buffer Information Register 24\n    pub const BRBINF24_EL1: Self = Self::System(0b10_001_1000_1000_100);\n    /// Branch Record Buffer Source Address Register 24\n    pub const BRBSRC24_EL1: Self = Self::System(0b10_001_1000_1000_101);\n    /// Branch Record Buffer Target Address Register 24\n    pub const BRBTGT24_EL1: Self = Self::System(0b10_001_1000_1000_110);\n    /// Branch Record Buffer Information Register 9\n    pub const BRBINF9_EL1: Self = Self::System(0b10_001_1000_1001_000);\n    /// Branch Record Buffer Source Address Register 9\n    pub const BRBSRC9_EL1: Self = Self::System(0b10_001_1000_1001_001);\n    /// Branch Record Buffer Target Address Register 9\n    pub const BRBTGT9_EL1: Self = Self::System(0b10_001_1000_1001_010);\n    /// Branch Record Buffer Information Register 25\n    pub const BRBINF25_EL1: Self = Self::System(0b10_001_1000_1001_100);\n    /// Branch Record Buffer Source Address Register 25\n    pub const BRBSRC25_EL1: Self = Self::System(0b10_001_1000_1001_101);\n    /// Branch Record Buffer Target Address Register 25\n    pub const BRBTGT25_EL1: Self = Self::System(0b10_001_1000_1001_110);\n    /// Branch Record Buffer Information Register 10\n    pub const BRBINF10_EL1: Self = Self::System(0b10_001_1000_1010_000);\n    /// Branch Record Buffer Source Address Register 10\n    pub const BRBSRC10_EL1: Self = Self::System(0b10_001_1000_1010_001);\n    /// Branch Record Buffer Target Address Register 10\n    pub const BRBTGT10_EL1: Self = Self::System(0b10_001_1000_1010_010);\n    /// Branch Record Buffer Information Register 26\n    pub const BRBINF26_EL1: Self = Self::System(0b10_001_1000_1010_100);\n    /// Branch Record Buffer Source Address Register 26\n    pub const BRBSRC26_EL1: Self = Self::System(0b10_001_1000_1010_101);\n    /// Branch Record Buffer Target Address Register 26\n    pub const BRBTGT26_EL1: Self = Self::System(0b10_001_1000_1010_110);\n    /// Branch Record Buffer Information Register 11\n    pub const BRBINF11_EL1: Self = Self::System(0b10_001_1000_1011_000);\n    /// Branch Record Buffer Source Address Register 11\n    pub const BRBSRC11_EL1: Self = Self::System(0b10_001_1000_1011_001);\n    /// Branch Record Buffer Target Address Register 11\n    pub const BRBTGT11_EL1: Self = Self::System(0b10_001_1000_1011_010);\n    /// Branch Record Buffer Information Register 27\n    pub const BRBINF27_EL1: Self = Self::System(0b10_001_1000_1011_100);\n    /// Branch Record Buffer Source Address Register 27\n    pub const BRBSRC27_EL1: Self = Self::System(0b10_001_1000_1011_101);\n    /// Branch Record Buffer Target Address Register 27\n    pub const BRBTGT27_EL1: Self = Self::System(0b10_001_1000_1011_110);\n    /// Branch Record Buffer Information Register 12\n    pub const BRBINF12_EL1: Self = Self::System(0b10_001_1000_1100_000);\n    /// Branch Record Buffer Source Address Register 12\n    pub const BRBSRC12_EL1: Self = Self::System(0b10_001_1000_1100_001);\n    /// Branch Record Buffer Target Address Register 12\n    pub const BRBTGT12_EL1: Self = Self::System(0b10_001_1000_1100_010);\n    /// Branch Record Buffer Information Register 28\n    pub const BRBINF28_EL1: Self = Self::System(0b10_001_1000_1100_100);\n    /// Branch Record Buffer Source Address Register 28\n    pub const BRBSRC28_EL1: Self = Self::System(0b10_001_1000_1100_101);\n    /// Branch Record Buffer Target Address Register 28\n    pub const BRBTGT28_EL1: Self = Self::System(0b10_001_1000_1100_110);\n    /// Branch Record Buffer Information Register 13\n    pub const BRBINF13_EL1: Self = Self::System(0b10_001_1000_1101_000);\n    /// Branch Record Buffer Source Address Register 13\n    pub const BRBSRC13_EL1: Self = Self::System(0b10_001_1000_1101_001);\n    /// Branch Record Buffer Target Address Register 13\n    pub const BRBTGT13_EL1: Self = Self::System(0b10_001_1000_1101_010);\n    /// Branch Record Buffer Information Register 29\n    pub const BRBINF29_EL1: Self = Self::System(0b10_001_1000_1101_100);\n    /// Branch Record Buffer Source Address Register 29\n    pub const BRBSRC29_EL1: Self = Self::System(0b10_001_1000_1101_101);\n    /// Branch Record Buffer Target Address Register 29\n    pub const BRBTGT29_EL1: Self = Self::System(0b10_001_1000_1101_110);\n    /// Branch Record Buffer Information Register 14\n    pub const BRBINF14_EL1: Self = Self::System(0b10_001_1000_1110_000);\n    /// Branch Record Buffer Source Address Register 14\n    pub const BRBSRC14_EL1: Self = Self::System(0b10_001_1000_1110_001);\n    /// Branch Record Buffer Target Address Register 14\n    pub const BRBTGT14_EL1: Self = Self::System(0b10_001_1000_1110_010);\n    /// Branch Record Buffer Information Register 30\n    pub const BRBINF30_EL1: Self = Self::System(0b10_001_1000_1110_100);\n    /// Branch Record Buffer Source Address Register 30\n    pub const BRBSRC30_EL1: Self = Self::System(0b10_001_1000_1110_101);\n    /// Branch Record Buffer Target Address Register 30\n    pub const BRBTGT30_EL1: Self = Self::System(0b10_001_1000_1110_110);\n    /// Branch Record Buffer Information Register 15\n    pub const BRBINF15_EL1: Self = Self::System(0b10_001_1000_1111_000);\n    /// Branch Record Buffer Source Address Register 15\n    pub const BRBSRC15_EL1: Self = Self::System(0b10_001_1000_1111_001);\n    /// Branch Record Buffer Target Address Register 15\n    pub const BRBTGT15_EL1: Self = Self::System(0b10_001_1000_1111_010);\n    /// Branch Record Buffer Information Register 31\n    pub const BRBINF31_EL1: Self = Self::System(0b10_001_1000_1111_100);\n    /// Branch Record Buffer Source Address Register 31\n    pub const BRBSRC31_EL1: Self = Self::System(0b10_001_1000_1111_101);\n    /// Branch Record Buffer Target Address Register 31\n    pub const BRBTGT31_EL1: Self = Self::System(0b10_001_1000_1111_110);\n    /// Branch Record Buffer Control Register (EL1)\n    pub const BRBCR_EL1: Self = Self::System(0b10_001_1001_0000_000);\n    /// Branch Record Buffer Control Register (EL2)\n    pub const BRBCR_EL2: Self = Self::System(0b10_001_1001_0000_000);\n    /// Branch Record Buffer Function Control Register\n    pub const BRBFCR_EL1: Self = Self::System(0b10_001_1001_0000_001);\n    /// Branch Record Buffer Timestamp Register\n    pub const BRBTS_EL1: Self = Self::System(0b10_001_1001_0000_010);\n    /// Branch Record Buffer Information Injection Register\n    pub const BRBINFINJ_EL1: Self = Self::System(0b10_001_1001_0001_000);\n    /// Branch Record Buffer Source Address Injection Register\n    pub const BRBSRCINJ_EL1: Self = Self::System(0b10_001_1001_0001_001);\n    /// Branch Record Buffer Target Address Injection Register\n    pub const BRBTGTINJ_EL1: Self = Self::System(0b10_001_1001_0001_010);\n    /// Branch Record Buffer ID0 Register\n    pub const BRBIDR0_EL1: Self = Self::System(0b10_001_1001_0010_000);\n    /// Monitor DCC Status Register\n    pub const MDCCSR_EL0: Self = Self::System(0b10_011_0000_0001_000);\n    /// Debug Data Transfer Register, Half-duplex\n    pub const DBGDTR_EL0: Self = Self::System(0b10_011_0000_0100_000);\n    /// Debug Data Transfer Register, Receive\n    pub const DBGDTRRX_EL0: Self = Self::System(0b10_011_0000_0101_000);\n    /// Debug Data Transfer Register, Transmit\n    pub const DBGDTRTX_EL0: Self = Self::System(0b10_011_0000_0101_000);\n    /// Debug Vector Catch Register\n    pub const DBGVCR32_EL2: Self = Self::System(0b10_100_0000_0111_000);\n}\n"
  },
  {
    "path": "gdbstub_arch/src/aarch64/reg/mod.rs",
    "content": "//! `Register` structs for the AArch64 ARM architecture.\n\n/// `RegId` definitions for the ARM AArch64 Architecture.\npub mod id;\n\nmod aarch64_core;\n\npub use aarch64_core::AArch64CoreRegs;\n"
  },
  {
    "path": "gdbstub_arch/src/aarch64/sysregs.xml",
    "content": "<feature name=\"org.rust.gdb.arm.sys.regs\">\n\n  <!-- Generated from the XML description of ARMv8-A system registers, provided\n       by ARM at https://developer.arm.com/downloads/-/exploration-tools -->\n\n  <reg name=\"OSDTRRX_EL1\" bitsize=\"64\" regnum=\"32770\" group=\"system\"/>\n  <reg name=\"DBGBVR0_EL1\" bitsize=\"64\" regnum=\"32772\" group=\"system\"/>\n  <reg name=\"DBGBCR0_EL1\" bitsize=\"64\" regnum=\"32773\" group=\"system\"/>\n  <reg name=\"DBGWVR0_EL1\" bitsize=\"64\" regnum=\"32774\" group=\"system\"/>\n  <reg name=\"DBGWCR0_EL1\" bitsize=\"64\" regnum=\"32775\" group=\"system\"/>\n  <reg name=\"DBGBVR1_EL1\" bitsize=\"64\" regnum=\"32780\" group=\"system\"/>\n  <reg name=\"DBGBCR1_EL1\" bitsize=\"64\" regnum=\"32781\" group=\"system\"/>\n  <reg name=\"DBGWVR1_EL1\" bitsize=\"64\" regnum=\"32782\" group=\"system\"/>\n  <reg name=\"DBGWCR1_EL1\" bitsize=\"64\" regnum=\"32783\" group=\"system\"/>\n  <reg name=\"MDCCINT_EL1\" bitsize=\"64\" regnum=\"32784\" group=\"system\"/>\n  <reg name=\"MDSCR_EL1\" bitsize=\"64\" regnum=\"32786\" group=\"system\"/>\n  <reg name=\"DBGBVR2_EL1\" bitsize=\"64\" regnum=\"32788\" group=\"system\"/>\n  <reg name=\"DBGBCR2_EL1\" bitsize=\"64\" regnum=\"32789\" group=\"system\"/>\n  <reg name=\"DBGWVR2_EL1\" bitsize=\"64\" regnum=\"32790\" group=\"system\"/>\n  <reg name=\"DBGWCR2_EL1\" bitsize=\"64\" regnum=\"32791\" group=\"system\"/>\n  <reg name=\"OSDTRTX_EL1\" bitsize=\"64\" regnum=\"32794\" group=\"system\"/>\n  <reg name=\"DBGBVR3_EL1\" bitsize=\"64\" regnum=\"32796\" group=\"system\"/>\n  <reg name=\"DBGBCR3_EL1\" bitsize=\"64\" regnum=\"32797\" group=\"system\"/>\n  <reg name=\"DBGWVR3_EL1\" bitsize=\"64\" regnum=\"32798\" group=\"system\"/>\n  <reg name=\"DBGWCR3_EL1\" bitsize=\"64\" regnum=\"32799\" group=\"system\"/>\n  <reg name=\"DBGBVR4_EL1\" bitsize=\"64\" regnum=\"32804\" group=\"system\"/>\n  <reg name=\"DBGBCR4_EL1\" bitsize=\"64\" regnum=\"32805\" group=\"system\"/>\n  <reg name=\"DBGWVR4_EL1\" bitsize=\"64\" regnum=\"32806\" group=\"system\"/>\n  <reg name=\"DBGWCR4_EL1\" bitsize=\"64\" regnum=\"32807\" group=\"system\"/>\n  <reg name=\"DBGBVR5_EL1\" bitsize=\"64\" regnum=\"32812\" group=\"system\"/>\n  <reg name=\"DBGBCR5_EL1\" bitsize=\"64\" regnum=\"32813\" group=\"system\"/>\n  <reg name=\"DBGWVR5_EL1\" bitsize=\"64\" regnum=\"32814\" group=\"system\"/>\n  <reg name=\"DBGWCR5_EL1\" bitsize=\"64\" regnum=\"32815\" group=\"system\"/>\n  <reg name=\"OSECCR_EL1\" bitsize=\"64\" regnum=\"32818\" group=\"system\"/>\n  <reg name=\"DBGBVR6_EL1\" bitsize=\"64\" regnum=\"32820\" group=\"system\"/>\n  <reg name=\"DBGBCR6_EL1\" bitsize=\"64\" regnum=\"32821\" group=\"system\"/>\n  <reg name=\"DBGWVR6_EL1\" bitsize=\"64\" regnum=\"32822\" group=\"system\"/>\n  <reg name=\"DBGWCR6_EL1\" bitsize=\"64\" regnum=\"32823\" group=\"system\"/>\n  <reg name=\"DBGBVR7_EL1\" bitsize=\"64\" regnum=\"32828\" group=\"system\"/>\n  <reg name=\"DBGBCR7_EL1\" bitsize=\"64\" regnum=\"32829\" group=\"system\"/>\n  <reg name=\"DBGWVR7_EL1\" bitsize=\"64\" regnum=\"32830\" group=\"system\"/>\n  <reg name=\"DBGWCR7_EL1\" bitsize=\"64\" regnum=\"32831\" group=\"system\"/>\n  <reg name=\"DBGBVR8_EL1\" bitsize=\"64\" regnum=\"32836\" group=\"system\"/>\n  <reg name=\"DBGBCR8_EL1\" bitsize=\"64\" regnum=\"32837\" group=\"system\"/>\n  <reg name=\"DBGWVR8_EL1\" bitsize=\"64\" regnum=\"32838\" group=\"system\"/>\n  <reg name=\"DBGWCR8_EL1\" bitsize=\"64\" regnum=\"32839\" group=\"system\"/>\n  <reg name=\"DBGBVR9_EL1\" bitsize=\"64\" regnum=\"32844\" group=\"system\"/>\n  <reg name=\"DBGBCR9_EL1\" bitsize=\"64\" regnum=\"32845\" group=\"system\"/>\n  <reg name=\"DBGWVR9_EL1\" bitsize=\"64\" regnum=\"32846\" group=\"system\"/>\n  <reg name=\"DBGWCR9_EL1\" bitsize=\"64\" regnum=\"32847\" group=\"system\"/>\n  <reg name=\"DBGBVR10_EL1\" bitsize=\"64\" regnum=\"32852\" group=\"system\"/>\n  <reg name=\"DBGBCR10_EL1\" bitsize=\"64\" regnum=\"32853\" group=\"system\"/>\n  <reg name=\"DBGWVR10_EL1\" bitsize=\"64\" regnum=\"32854\" group=\"system\"/>\n  <reg name=\"DBGWCR10_EL1\" bitsize=\"64\" regnum=\"32855\" group=\"system\"/>\n  <reg name=\"DBGBVR11_EL1\" bitsize=\"64\" regnum=\"32860\" group=\"system\"/>\n  <reg name=\"DBGBCR11_EL1\" bitsize=\"64\" regnum=\"32861\" group=\"system\"/>\n  <reg name=\"DBGWVR11_EL1\" bitsize=\"64\" regnum=\"32862\" group=\"system\"/>\n  <reg name=\"DBGWCR11_EL1\" bitsize=\"64\" regnum=\"32863\" group=\"system\"/>\n  <reg name=\"DBGBVR12_EL1\" bitsize=\"64\" regnum=\"32868\" group=\"system\"/>\n  <reg name=\"DBGBCR12_EL1\" bitsize=\"64\" regnum=\"32869\" group=\"system\"/>\n  <reg name=\"DBGWVR12_EL1\" bitsize=\"64\" regnum=\"32870\" group=\"system\"/>\n  <reg name=\"DBGWCR12_EL1\" bitsize=\"64\" regnum=\"32871\" group=\"system\"/>\n  <reg name=\"DBGBVR13_EL1\" bitsize=\"64\" regnum=\"32876\" group=\"system\"/>\n  <reg name=\"DBGBCR13_EL1\" bitsize=\"64\" regnum=\"32877\" group=\"system\"/>\n  <reg name=\"DBGWVR13_EL1\" bitsize=\"64\" regnum=\"32878\" group=\"system\"/>\n  <reg name=\"DBGWCR13_EL1\" bitsize=\"64\" regnum=\"32879\" group=\"system\"/>\n  <reg name=\"DBGBVR14_EL1\" bitsize=\"64\" regnum=\"32884\" group=\"system\"/>\n  <reg name=\"DBGBCR14_EL1\" bitsize=\"64\" regnum=\"32885\" group=\"system\"/>\n  <reg name=\"DBGWVR14_EL1\" bitsize=\"64\" regnum=\"32886\" group=\"system\"/>\n  <reg name=\"DBGWCR14_EL1\" bitsize=\"64\" regnum=\"32887\" group=\"system\"/>\n  <reg name=\"DBGBVR15_EL1\" bitsize=\"64\" regnum=\"32892\" group=\"system\"/>\n  <reg name=\"DBGBCR15_EL1\" bitsize=\"64\" regnum=\"32893\" group=\"system\"/>\n  <reg name=\"DBGWVR15_EL1\" bitsize=\"64\" regnum=\"32894\" group=\"system\"/>\n  <reg name=\"DBGWCR15_EL1\" bitsize=\"64\" regnum=\"32895\" group=\"system\"/>\n  <reg name=\"MDRAR_EL1\" bitsize=\"64\" regnum=\"32896\" group=\"system\"/>\n  <reg name=\"OSLAR_EL1\" bitsize=\"64\" regnum=\"32900\" group=\"system\"/>\n  <reg name=\"OSLSR_EL1\" bitsize=\"64\" regnum=\"32908\" group=\"system\"/>\n  <reg name=\"OSDLR_EL1\" bitsize=\"64\" regnum=\"32924\" group=\"system\"/>\n  <reg name=\"DBGPRCR_EL1\" bitsize=\"64\" regnum=\"32932\" group=\"system\"/>\n  <reg name=\"DBGCLAIMSET_EL1\" bitsize=\"64\" regnum=\"33734\" group=\"system\"/>\n  <reg name=\"DBGCLAIMCLR_EL1\" bitsize=\"64\" regnum=\"33742\" group=\"system\"/>\n  <reg name=\"DBGAUTHSTATUS_EL1\" bitsize=\"64\" regnum=\"33782\" group=\"system\"/>\n  <reg name=\"TRCTRACEIDR\" bitsize=\"64\" regnum=\"34817\" group=\"system\"/>\n  <reg name=\"TRCVICTLR\" bitsize=\"64\" regnum=\"34818\" group=\"system\"/>\n  <reg name=\"TRCSEQEVR0\" bitsize=\"64\" regnum=\"34820\" group=\"system\"/>\n  <reg name=\"TRCCNTRLDVR0\" bitsize=\"64\" regnum=\"34821\" group=\"system\"/>\n  <reg name=\"TRCIDR8\" bitsize=\"64\" regnum=\"34822\" group=\"system\"/>\n  <reg name=\"TRCIMSPEC0\" bitsize=\"64\" regnum=\"34823\" group=\"system\"/>\n  <reg name=\"TRCPRGCTLR\" bitsize=\"64\" regnum=\"34824\" group=\"system\"/>\n  <reg name=\"TRCQCTLR\" bitsize=\"64\" regnum=\"34825\" group=\"system\"/>\n  <reg name=\"TRCVIIECTLR\" bitsize=\"64\" regnum=\"34826\" group=\"system\"/>\n  <reg name=\"TRCSEQEVR1\" bitsize=\"64\" regnum=\"34828\" group=\"system\"/>\n  <reg name=\"TRCCNTRLDVR1\" bitsize=\"64\" regnum=\"34829\" group=\"system\"/>\n  <reg name=\"TRCIDR9\" bitsize=\"64\" regnum=\"34830\" group=\"system\"/>\n  <reg name=\"TRCIMSPEC1\" bitsize=\"64\" regnum=\"34831\" group=\"system\"/>\n  <reg name=\"TRCVISSCTLR\" bitsize=\"64\" regnum=\"34834\" group=\"system\"/>\n  <reg name=\"TRCSEQEVR2\" bitsize=\"64\" regnum=\"34836\" group=\"system\"/>\n  <reg name=\"TRCCNTRLDVR2\" bitsize=\"64\" regnum=\"34837\" group=\"system\"/>\n  <reg name=\"TRCIDR10\" bitsize=\"64\" regnum=\"34838\" group=\"system\"/>\n  <reg name=\"TRCIMSPEC2\" bitsize=\"64\" regnum=\"34839\" group=\"system\"/>\n  <reg name=\"TRCSTATR\" bitsize=\"64\" regnum=\"34840\" group=\"system\"/>\n  <reg name=\"TRCVIPCSSCTLR\" bitsize=\"64\" regnum=\"34842\" group=\"system\"/>\n  <reg name=\"TRCCNTRLDVR3\" bitsize=\"64\" regnum=\"34845\" group=\"system\"/>\n  <reg name=\"TRCIDR11\" bitsize=\"64\" regnum=\"34846\" group=\"system\"/>\n  <reg name=\"TRCIMSPEC3\" bitsize=\"64\" regnum=\"34847\" group=\"system\"/>\n  <reg name=\"TRCCONFIGR\" bitsize=\"64\" regnum=\"34848\" group=\"system\"/>\n  <reg name=\"TRCCNTCTLR0\" bitsize=\"64\" regnum=\"34853\" group=\"system\"/>\n  <reg name=\"TRCIDR12\" bitsize=\"64\" regnum=\"34854\" group=\"system\"/>\n  <reg name=\"TRCIMSPEC4\" bitsize=\"64\" regnum=\"34855\" group=\"system\"/>\n  <reg name=\"TRCCNTCTLR1\" bitsize=\"64\" regnum=\"34861\" group=\"system\"/>\n  <reg name=\"TRCIDR13\" bitsize=\"64\" regnum=\"34862\" group=\"system\"/>\n  <reg name=\"TRCIMSPEC5\" bitsize=\"64\" regnum=\"34863\" group=\"system\"/>\n  <reg name=\"TRCAUXCTLR\" bitsize=\"64\" regnum=\"34864\" group=\"system\"/>\n  <reg name=\"TRCSEQRSTEVR\" bitsize=\"64\" regnum=\"34868\" group=\"system\"/>\n  <reg name=\"TRCCNTCTLR2\" bitsize=\"64\" regnum=\"34869\" group=\"system\"/>\n  <reg name=\"TRCIMSPEC6\" bitsize=\"64\" regnum=\"34871\" group=\"system\"/>\n  <reg name=\"TRCSEQSTR\" bitsize=\"64\" regnum=\"34876\" group=\"system\"/>\n  <reg name=\"TRCCNTCTLR3\" bitsize=\"64\" regnum=\"34877\" group=\"system\"/>\n  <reg name=\"TRCIMSPEC7\" bitsize=\"64\" regnum=\"34879\" group=\"system\"/>\n  <reg name=\"TRCEVENTCTL0R\" bitsize=\"64\" regnum=\"34880\" group=\"system\"/>\n  <reg name=\"TRCEXTINSELR0\" bitsize=\"64\" regnum=\"34884\" group=\"system\"/>\n  <reg name=\"TRCCNTVR0\" bitsize=\"64\" regnum=\"34885\" group=\"system\"/>\n  <reg name=\"TRCIDR0\" bitsize=\"64\" regnum=\"34887\" group=\"system\"/>\n  <reg name=\"TRCEVENTCTL1R\" bitsize=\"64\" regnum=\"34888\" group=\"system\"/>\n  <reg name=\"TRCEXTINSELR1\" bitsize=\"64\" regnum=\"34892\" group=\"system\"/>\n  <reg name=\"TRCCNTVR1\" bitsize=\"64\" regnum=\"34893\" group=\"system\"/>\n  <reg name=\"TRCIDR1\" bitsize=\"64\" regnum=\"34895\" group=\"system\"/>\n  <reg name=\"TRCRSR\" bitsize=\"64\" regnum=\"34896\" group=\"system\"/>\n  <reg name=\"TRCEXTINSELR2\" bitsize=\"64\" regnum=\"34900\" group=\"system\"/>\n  <reg name=\"TRCCNTVR2\" bitsize=\"64\" regnum=\"34901\" group=\"system\"/>\n  <reg name=\"TRCIDR2\" bitsize=\"64\" regnum=\"34903\" group=\"system\"/>\n  <reg name=\"TRCSTALLCTLR\" bitsize=\"64\" regnum=\"34904\" group=\"system\"/>\n  <reg name=\"TRCEXTINSELR3\" bitsize=\"64\" regnum=\"34908\" group=\"system\"/>\n  <reg name=\"TRCCNTVR3\" bitsize=\"64\" regnum=\"34909\" group=\"system\"/>\n  <reg name=\"TRCIDR3\" bitsize=\"64\" regnum=\"34911\" group=\"system\"/>\n  <reg name=\"TRCTSCTLR\" bitsize=\"64\" regnum=\"34912\" group=\"system\"/>\n  <reg name=\"TRCIDR4\" bitsize=\"64\" regnum=\"34919\" group=\"system\"/>\n  <reg name=\"TRCSYNCPR\" bitsize=\"64\" regnum=\"34920\" group=\"system\"/>\n  <reg name=\"TRCIDR5\" bitsize=\"64\" regnum=\"34927\" group=\"system\"/>\n  <reg name=\"TRCCCCTLR\" bitsize=\"64\" regnum=\"34928\" group=\"system\"/>\n  <reg name=\"TRCIDR6\" bitsize=\"64\" regnum=\"34935\" group=\"system\"/>\n  <reg name=\"TRCBBCTLR\" bitsize=\"64\" regnum=\"34936\" group=\"system\"/>\n  <reg name=\"TRCIDR7\" bitsize=\"64\" regnum=\"34943\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR16\" bitsize=\"64\" regnum=\"34945\" group=\"system\"/>\n  <reg name=\"TRCSSCCR0\" bitsize=\"64\" regnum=\"34946\" group=\"system\"/>\n  <reg name=\"TRCSSPCICR0\" bitsize=\"64\" regnum=\"34947\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR17\" bitsize=\"64\" regnum=\"34953\" group=\"system\"/>\n  <reg name=\"TRCSSCCR1\" bitsize=\"64\" regnum=\"34954\" group=\"system\"/>\n  <reg name=\"TRCSSPCICR1\" bitsize=\"64\" regnum=\"34955\" group=\"system\"/>\n  <reg name=\"TRCOSLSR\" bitsize=\"64\" regnum=\"34956\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR2\" bitsize=\"64\" regnum=\"34960\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR18\" bitsize=\"64\" regnum=\"34961\" group=\"system\"/>\n  <reg name=\"TRCSSCCR2\" bitsize=\"64\" regnum=\"34962\" group=\"system\"/>\n  <reg name=\"TRCSSPCICR2\" bitsize=\"64\" regnum=\"34963\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR3\" bitsize=\"64\" regnum=\"34968\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR19\" bitsize=\"64\" regnum=\"34969\" group=\"system\"/>\n  <reg name=\"TRCSSCCR3\" bitsize=\"64\" regnum=\"34970\" group=\"system\"/>\n  <reg name=\"TRCSSPCICR3\" bitsize=\"64\" regnum=\"34971\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR4\" bitsize=\"64\" regnum=\"34976\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR20\" bitsize=\"64\" regnum=\"34977\" group=\"system\"/>\n  <reg name=\"TRCSSCCR4\" bitsize=\"64\" regnum=\"34978\" group=\"system\"/>\n  <reg name=\"TRCSSPCICR4\" bitsize=\"64\" regnum=\"34979\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR5\" bitsize=\"64\" regnum=\"34984\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR21\" bitsize=\"64\" regnum=\"34985\" group=\"system\"/>\n  <reg name=\"TRCSSCCR5\" bitsize=\"64\" regnum=\"34986\" group=\"system\"/>\n  <reg name=\"TRCSSPCICR5\" bitsize=\"64\" regnum=\"34987\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR6\" bitsize=\"64\" regnum=\"34992\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR22\" bitsize=\"64\" regnum=\"34993\" group=\"system\"/>\n  <reg name=\"TRCSSCCR6\" bitsize=\"64\" regnum=\"34994\" group=\"system\"/>\n  <reg name=\"TRCSSPCICR6\" bitsize=\"64\" regnum=\"34995\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR7\" bitsize=\"64\" regnum=\"35000\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR23\" bitsize=\"64\" regnum=\"35001\" group=\"system\"/>\n  <reg name=\"TRCSSCCR7\" bitsize=\"64\" regnum=\"35002\" group=\"system\"/>\n  <reg name=\"TRCSSPCICR7\" bitsize=\"64\" regnum=\"35003\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR8\" bitsize=\"64\" regnum=\"35008\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR24\" bitsize=\"64\" regnum=\"35009\" group=\"system\"/>\n  <reg name=\"TRCSSCSR0\" bitsize=\"64\" regnum=\"35010\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR9\" bitsize=\"64\" regnum=\"35016\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR25\" bitsize=\"64\" regnum=\"35017\" group=\"system\"/>\n  <reg name=\"TRCSSCSR1\" bitsize=\"64\" regnum=\"35018\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR10\" bitsize=\"64\" regnum=\"35024\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR26\" bitsize=\"64\" regnum=\"35025\" group=\"system\"/>\n  <reg name=\"TRCSSCSR2\" bitsize=\"64\" regnum=\"35026\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR11\" bitsize=\"64\" regnum=\"35032\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR27\" bitsize=\"64\" regnum=\"35033\" group=\"system\"/>\n  <reg name=\"TRCSSCSR3\" bitsize=\"64\" regnum=\"35034\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR12\" bitsize=\"64\" regnum=\"35040\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR28\" bitsize=\"64\" regnum=\"35041\" group=\"system\"/>\n  <reg name=\"TRCSSCSR4\" bitsize=\"64\" regnum=\"35042\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR13\" bitsize=\"64\" regnum=\"35048\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR29\" bitsize=\"64\" regnum=\"35049\" group=\"system\"/>\n  <reg name=\"TRCSSCSR5\" bitsize=\"64\" regnum=\"35050\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR14\" bitsize=\"64\" regnum=\"35056\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR30\" bitsize=\"64\" regnum=\"35057\" group=\"system\"/>\n  <reg name=\"TRCSSCSR6\" bitsize=\"64\" regnum=\"35058\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR15\" bitsize=\"64\" regnum=\"35064\" group=\"system\"/>\n  <reg name=\"TRCRSCTLR31\" bitsize=\"64\" regnum=\"35065\" group=\"system\"/>\n  <reg name=\"TRCSSCSR7\" bitsize=\"64\" regnum=\"35066\" group=\"system\"/>\n  <reg name=\"TRCACVR0\" bitsize=\"64\" regnum=\"35072\" group=\"system\"/>\n  <reg name=\"TRCACVR8\" bitsize=\"64\" regnum=\"35073\" group=\"system\"/>\n  <reg name=\"TRCACATR0\" bitsize=\"64\" regnum=\"35074\" group=\"system\"/>\n  <reg name=\"TRCACATR8\" bitsize=\"64\" regnum=\"35075\" group=\"system\"/>\n  <reg name=\"TRCACVR1\" bitsize=\"64\" regnum=\"35088\" group=\"system\"/>\n  <reg name=\"TRCACVR9\" bitsize=\"64\" regnum=\"35089\" group=\"system\"/>\n  <reg name=\"TRCACATR1\" bitsize=\"64\" regnum=\"35090\" group=\"system\"/>\n  <reg name=\"TRCACATR9\" bitsize=\"64\" regnum=\"35091\" group=\"system\"/>\n  <reg name=\"TRCACVR2\" bitsize=\"64\" regnum=\"35104\" group=\"system\"/>\n  <reg name=\"TRCACVR10\" bitsize=\"64\" regnum=\"35105\" group=\"system\"/>\n  <reg name=\"TRCACATR2\" bitsize=\"64\" regnum=\"35106\" group=\"system\"/>\n  <reg name=\"TRCACATR10\" bitsize=\"64\" regnum=\"35107\" group=\"system\"/>\n  <reg name=\"TRCACVR3\" bitsize=\"64\" regnum=\"35120\" group=\"system\"/>\n  <reg name=\"TRCACVR11\" bitsize=\"64\" regnum=\"35121\" group=\"system\"/>\n  <reg name=\"TRCACATR3\" bitsize=\"64\" regnum=\"35122\" group=\"system\"/>\n  <reg name=\"TRCACATR11\" bitsize=\"64\" regnum=\"35123\" group=\"system\"/>\n  <reg name=\"TRCACVR4\" bitsize=\"64\" regnum=\"35136\" group=\"system\"/>\n  <reg name=\"TRCACVR12\" bitsize=\"64\" regnum=\"35137\" group=\"system\"/>\n  <reg name=\"TRCACATR4\" bitsize=\"64\" regnum=\"35138\" group=\"system\"/>\n  <reg name=\"TRCACATR12\" bitsize=\"64\" regnum=\"35139\" group=\"system\"/>\n  <reg name=\"TRCACVR5\" bitsize=\"64\" regnum=\"35152\" group=\"system\"/>\n  <reg name=\"TRCACVR13\" bitsize=\"64\" regnum=\"35153\" group=\"system\"/>\n  <reg name=\"TRCACATR5\" bitsize=\"64\" regnum=\"35154\" group=\"system\"/>\n  <reg name=\"TRCACATR13\" bitsize=\"64\" regnum=\"35155\" group=\"system\"/>\n  <reg name=\"TRCACVR6\" bitsize=\"64\" regnum=\"35168\" group=\"system\"/>\n  <reg name=\"TRCACVR14\" bitsize=\"64\" regnum=\"35169\" group=\"system\"/>\n  <reg name=\"TRCACATR6\" bitsize=\"64\" regnum=\"35170\" group=\"system\"/>\n  <reg name=\"TRCACATR14\" bitsize=\"64\" regnum=\"35171\" group=\"system\"/>\n  <reg name=\"TRCACVR7\" bitsize=\"64\" regnum=\"35184\" group=\"system\"/>\n  <reg name=\"TRCACVR15\" bitsize=\"64\" regnum=\"35185\" group=\"system\"/>\n  <reg name=\"TRCACATR7\" bitsize=\"64\" regnum=\"35186\" group=\"system\"/>\n  <reg name=\"TRCACATR15\" bitsize=\"64\" regnum=\"35187\" group=\"system\"/>\n  <reg name=\"TRCCIDCVR0\" bitsize=\"64\" regnum=\"35200\" group=\"system\"/>\n  <reg name=\"TRCVMIDCVR0\" bitsize=\"64\" regnum=\"35201\" group=\"system\"/>\n  <reg name=\"TRCCIDCCTLR0\" bitsize=\"64\" regnum=\"35202\" group=\"system\"/>\n  <reg name=\"TRCCIDCCTLR1\" bitsize=\"64\" regnum=\"35210\" group=\"system\"/>\n  <reg name=\"TRCCIDCVR1\" bitsize=\"64\" regnum=\"35216\" group=\"system\"/>\n  <reg name=\"TRCVMIDCVR1\" bitsize=\"64\" regnum=\"35217\" group=\"system\"/>\n  <reg name=\"TRCVMIDCCTLR0\" bitsize=\"64\" regnum=\"35218\" group=\"system\"/>\n  <reg name=\"TRCVMIDCCTLR1\" bitsize=\"64\" regnum=\"35226\" group=\"system\"/>\n  <reg name=\"TRCCIDCVR2\" bitsize=\"64\" regnum=\"35232\" group=\"system\"/>\n  <reg name=\"TRCVMIDCVR2\" bitsize=\"64\" regnum=\"35233\" group=\"system\"/>\n  <reg name=\"TRCCIDCVR3\" bitsize=\"64\" regnum=\"35248\" group=\"system\"/>\n  <reg name=\"TRCVMIDCVR3\" bitsize=\"64\" regnum=\"35249\" group=\"system\"/>\n  <reg name=\"TRCCIDCVR4\" bitsize=\"64\" regnum=\"35264\" group=\"system\"/>\n  <reg name=\"TRCVMIDCVR4\" bitsize=\"64\" regnum=\"35265\" group=\"system\"/>\n  <reg name=\"TRCCIDCVR5\" bitsize=\"64\" regnum=\"35280\" group=\"system\"/>\n  <reg name=\"TRCVMIDCVR5\" bitsize=\"64\" regnum=\"35281\" group=\"system\"/>\n  <reg name=\"TRCCIDCVR6\" bitsize=\"64\" regnum=\"35296\" group=\"system\"/>\n  <reg name=\"TRCVMIDCVR6\" bitsize=\"64\" regnum=\"35297\" group=\"system\"/>\n  <reg name=\"TRCCIDCVR7\" bitsize=\"64\" regnum=\"35312\" group=\"system\"/>\n  <reg name=\"TRCVMIDCVR7\" bitsize=\"64\" regnum=\"35313\" group=\"system\"/>\n  <reg name=\"TRCDEVID\" bitsize=\"64\" regnum=\"35735\" group=\"system\"/>\n  <reg name=\"TRCCLAIMSET\" bitsize=\"64\" regnum=\"35782\" group=\"system\"/>\n  <reg name=\"TRCCLAIMCLR\" bitsize=\"64\" regnum=\"35790\" group=\"system\"/>\n  <reg name=\"TRCAUTHSTATUS\" bitsize=\"64\" regnum=\"35830\" group=\"system\"/>\n  <reg name=\"TRCDEVARCH\" bitsize=\"64\" regnum=\"35838\" group=\"system\"/>\n  <reg name=\"BRBINF0_EL1\" bitsize=\"64\" regnum=\"35840\" group=\"system\"/>\n  <reg name=\"BRBSRC0_EL1\" bitsize=\"64\" regnum=\"35841\" group=\"system\"/>\n  <reg name=\"BRBTGT0_EL1\" bitsize=\"64\" regnum=\"35842\" group=\"system\"/>\n  <reg name=\"BRBINF16_EL1\" bitsize=\"64\" regnum=\"35844\" group=\"system\"/>\n  <reg name=\"BRBSRC16_EL1\" bitsize=\"64\" regnum=\"35845\" group=\"system\"/>\n  <reg name=\"BRBTGT16_EL1\" bitsize=\"64\" regnum=\"35846\" group=\"system\"/>\n  <reg name=\"BRBINF1_EL1\" bitsize=\"64\" regnum=\"35848\" group=\"system\"/>\n  <reg name=\"BRBSRC1_EL1\" bitsize=\"64\" regnum=\"35849\" group=\"system\"/>\n  <reg name=\"BRBTGT1_EL1\" bitsize=\"64\" regnum=\"35850\" group=\"system\"/>\n  <reg name=\"BRBINF17_EL1\" bitsize=\"64\" regnum=\"35852\" group=\"system\"/>\n  <reg name=\"BRBSRC17_EL1\" bitsize=\"64\" regnum=\"35853\" group=\"system\"/>\n  <reg name=\"BRBTGT17_EL1\" bitsize=\"64\" regnum=\"35854\" group=\"system\"/>\n  <reg name=\"BRBINF2_EL1\" bitsize=\"64\" regnum=\"35856\" group=\"system\"/>\n  <reg name=\"BRBSRC2_EL1\" bitsize=\"64\" regnum=\"35857\" group=\"system\"/>\n  <reg name=\"BRBTGT2_EL1\" bitsize=\"64\" regnum=\"35858\" group=\"system\"/>\n  <reg name=\"BRBINF18_EL1\" bitsize=\"64\" regnum=\"35860\" group=\"system\"/>\n  <reg name=\"BRBSRC18_EL1\" bitsize=\"64\" regnum=\"35861\" group=\"system\"/>\n  <reg name=\"BRBTGT18_EL1\" bitsize=\"64\" regnum=\"35862\" group=\"system\"/>\n  <reg name=\"BRBINF3_EL1\" bitsize=\"64\" regnum=\"35864\" group=\"system\"/>\n  <reg name=\"BRBSRC3_EL1\" bitsize=\"64\" regnum=\"35865\" group=\"system\"/>\n  <reg name=\"BRBTGT3_EL1\" bitsize=\"64\" regnum=\"35866\" group=\"system\"/>\n  <reg name=\"BRBINF19_EL1\" bitsize=\"64\" regnum=\"35868\" group=\"system\"/>\n  <reg name=\"BRBSRC19_EL1\" bitsize=\"64\" regnum=\"35869\" group=\"system\"/>\n  <reg name=\"BRBTGT19_EL1\" bitsize=\"64\" regnum=\"35870\" group=\"system\"/>\n  <reg name=\"BRBINF4_EL1\" bitsize=\"64\" regnum=\"35872\" group=\"system\"/>\n  <reg name=\"BRBSRC4_EL1\" bitsize=\"64\" regnum=\"35873\" group=\"system\"/>\n  <reg name=\"BRBTGT4_EL1\" bitsize=\"64\" regnum=\"35874\" group=\"system\"/>\n  <reg name=\"BRBINF20_EL1\" bitsize=\"64\" regnum=\"35876\" group=\"system\"/>\n  <reg name=\"BRBSRC20_EL1\" bitsize=\"64\" regnum=\"35877\" group=\"system\"/>\n  <reg name=\"BRBTGT20_EL1\" bitsize=\"64\" regnum=\"35878\" group=\"system\"/>\n  <reg name=\"BRBINF5_EL1\" bitsize=\"64\" regnum=\"35880\" group=\"system\"/>\n  <reg name=\"BRBSRC5_EL1\" bitsize=\"64\" regnum=\"35881\" group=\"system\"/>\n  <reg name=\"BRBTGT5_EL1\" bitsize=\"64\" regnum=\"35882\" group=\"system\"/>\n  <reg name=\"BRBINF21_EL1\" bitsize=\"64\" regnum=\"35884\" group=\"system\"/>\n  <reg name=\"BRBSRC21_EL1\" bitsize=\"64\" regnum=\"35885\" group=\"system\"/>\n  <reg name=\"BRBTGT21_EL1\" bitsize=\"64\" regnum=\"35886\" group=\"system\"/>\n  <reg name=\"BRBINF6_EL1\" bitsize=\"64\" regnum=\"35888\" group=\"system\"/>\n  <reg name=\"BRBSRC6_EL1\" bitsize=\"64\" regnum=\"35889\" group=\"system\"/>\n  <reg name=\"BRBTGT6_EL1\" bitsize=\"64\" regnum=\"35890\" group=\"system\"/>\n  <reg name=\"BRBINF22_EL1\" bitsize=\"64\" regnum=\"35892\" group=\"system\"/>\n  <reg name=\"BRBSRC22_EL1\" bitsize=\"64\" regnum=\"35893\" group=\"system\"/>\n  <reg name=\"BRBTGT22_EL1\" bitsize=\"64\" regnum=\"35894\" group=\"system\"/>\n  <reg name=\"BRBINF7_EL1\" bitsize=\"64\" regnum=\"35896\" group=\"system\"/>\n  <reg name=\"BRBSRC7_EL1\" bitsize=\"64\" regnum=\"35897\" group=\"system\"/>\n  <reg name=\"BRBTGT7_EL1\" bitsize=\"64\" regnum=\"35898\" group=\"system\"/>\n  <reg name=\"BRBINF23_EL1\" bitsize=\"64\" regnum=\"35900\" group=\"system\"/>\n  <reg name=\"BRBSRC23_EL1\" bitsize=\"64\" regnum=\"35901\" group=\"system\"/>\n  <reg name=\"BRBTGT23_EL1\" bitsize=\"64\" regnum=\"35902\" group=\"system\"/>\n  <reg name=\"BRBINF8_EL1\" bitsize=\"64\" regnum=\"35904\" group=\"system\"/>\n  <reg name=\"BRBSRC8_EL1\" bitsize=\"64\" regnum=\"35905\" group=\"system\"/>\n  <reg name=\"BRBTGT8_EL1\" bitsize=\"64\" regnum=\"35906\" group=\"system\"/>\n  <reg name=\"BRBINF24_EL1\" bitsize=\"64\" regnum=\"35908\" group=\"system\"/>\n  <reg name=\"BRBSRC24_EL1\" bitsize=\"64\" regnum=\"35909\" group=\"system\"/>\n  <reg name=\"BRBTGT24_EL1\" bitsize=\"64\" regnum=\"35910\" group=\"system\"/>\n  <reg name=\"BRBINF9_EL1\" bitsize=\"64\" regnum=\"35912\" group=\"system\"/>\n  <reg name=\"BRBSRC9_EL1\" bitsize=\"64\" regnum=\"35913\" group=\"system\"/>\n  <reg name=\"BRBTGT9_EL1\" bitsize=\"64\" regnum=\"35914\" group=\"system\"/>\n  <reg name=\"BRBINF25_EL1\" bitsize=\"64\" regnum=\"35916\" group=\"system\"/>\n  <reg name=\"BRBSRC25_EL1\" bitsize=\"64\" regnum=\"35917\" group=\"system\"/>\n  <reg name=\"BRBTGT25_EL1\" bitsize=\"64\" regnum=\"35918\" group=\"system\"/>\n  <reg name=\"BRBINF10_EL1\" bitsize=\"64\" regnum=\"35920\" group=\"system\"/>\n  <reg name=\"BRBSRC10_EL1\" bitsize=\"64\" regnum=\"35921\" group=\"system\"/>\n  <reg name=\"BRBTGT10_EL1\" bitsize=\"64\" regnum=\"35922\" group=\"system\"/>\n  <reg name=\"BRBINF26_EL1\" bitsize=\"64\" regnum=\"35924\" group=\"system\"/>\n  <reg name=\"BRBSRC26_EL1\" bitsize=\"64\" regnum=\"35925\" group=\"system\"/>\n  <reg name=\"BRBTGT26_EL1\" bitsize=\"64\" regnum=\"35926\" group=\"system\"/>\n  <reg name=\"BRBINF11_EL1\" bitsize=\"64\" regnum=\"35928\" group=\"system\"/>\n  <reg name=\"BRBSRC11_EL1\" bitsize=\"64\" regnum=\"35929\" group=\"system\"/>\n  <reg name=\"BRBTGT11_EL1\" bitsize=\"64\" regnum=\"35930\" group=\"system\"/>\n  <reg name=\"BRBINF27_EL1\" bitsize=\"64\" regnum=\"35932\" group=\"system\"/>\n  <reg name=\"BRBSRC27_EL1\" bitsize=\"64\" regnum=\"35933\" group=\"system\"/>\n  <reg name=\"BRBTGT27_EL1\" bitsize=\"64\" regnum=\"35934\" group=\"system\"/>\n  <reg name=\"BRBINF12_EL1\" bitsize=\"64\" regnum=\"35936\" group=\"system\"/>\n  <reg name=\"BRBSRC12_EL1\" bitsize=\"64\" regnum=\"35937\" group=\"system\"/>\n  <reg name=\"BRBTGT12_EL1\" bitsize=\"64\" regnum=\"35938\" group=\"system\"/>\n  <reg name=\"BRBINF28_EL1\" bitsize=\"64\" regnum=\"35940\" group=\"system\"/>\n  <reg name=\"BRBSRC28_EL1\" bitsize=\"64\" regnum=\"35941\" group=\"system\"/>\n  <reg name=\"BRBTGT28_EL1\" bitsize=\"64\" regnum=\"35942\" group=\"system\"/>\n  <reg name=\"BRBINF13_EL1\" bitsize=\"64\" regnum=\"35944\" group=\"system\"/>\n  <reg name=\"BRBSRC13_EL1\" bitsize=\"64\" regnum=\"35945\" group=\"system\"/>\n  <reg name=\"BRBTGT13_EL1\" bitsize=\"64\" regnum=\"35946\" group=\"system\"/>\n  <reg name=\"BRBINF29_EL1\" bitsize=\"64\" regnum=\"35948\" group=\"system\"/>\n  <reg name=\"BRBSRC29_EL1\" bitsize=\"64\" regnum=\"35949\" group=\"system\"/>\n  <reg name=\"BRBTGT29_EL1\" bitsize=\"64\" regnum=\"35950\" group=\"system\"/>\n  <reg name=\"BRBINF14_EL1\" bitsize=\"64\" regnum=\"35952\" group=\"system\"/>\n  <reg name=\"BRBSRC14_EL1\" bitsize=\"64\" regnum=\"35953\" group=\"system\"/>\n  <reg name=\"BRBTGT14_EL1\" bitsize=\"64\" regnum=\"35954\" group=\"system\"/>\n  <reg name=\"BRBINF30_EL1\" bitsize=\"64\" regnum=\"35956\" group=\"system\"/>\n  <reg name=\"BRBSRC30_EL1\" bitsize=\"64\" regnum=\"35957\" group=\"system\"/>\n  <reg name=\"BRBTGT30_EL1\" bitsize=\"64\" regnum=\"35958\" group=\"system\"/>\n  <reg name=\"BRBINF15_EL1\" bitsize=\"64\" regnum=\"35960\" group=\"system\"/>\n  <reg name=\"BRBSRC15_EL1\" bitsize=\"64\" regnum=\"35961\" group=\"system\"/>\n  <reg name=\"BRBTGT15_EL1\" bitsize=\"64\" regnum=\"35962\" group=\"system\"/>\n  <reg name=\"BRBINF31_EL1\" bitsize=\"64\" regnum=\"35964\" group=\"system\"/>\n  <reg name=\"BRBSRC31_EL1\" bitsize=\"64\" regnum=\"35965\" group=\"system\"/>\n  <reg name=\"BRBTGT31_EL1\" bitsize=\"64\" regnum=\"35966\" group=\"system\"/>\n  <reg name=\"BRBCR_EL1\" bitsize=\"64\" regnum=\"35968\" group=\"system\"/>\n  <reg name=\"BRBCR_EL2\" bitsize=\"64\" regnum=\"35968\" group=\"system\"/>\n  <reg name=\"BRBFCR_EL1\" bitsize=\"64\" regnum=\"35969\" group=\"system\"/>\n  <reg name=\"BRBTS_EL1\" bitsize=\"64\" regnum=\"35970\" group=\"system\"/>\n  <reg name=\"BRBINFINJ_EL1\" bitsize=\"64\" regnum=\"35976\" group=\"system\"/>\n  <reg name=\"BRBSRCINJ_EL1\" bitsize=\"64\" regnum=\"35977\" group=\"system\"/>\n  <reg name=\"BRBTGTINJ_EL1\" bitsize=\"64\" regnum=\"35978\" group=\"system\"/>\n  <reg name=\"BRBIDR0_EL1\" bitsize=\"64\" regnum=\"35984\" group=\"system\"/>\n  <reg name=\"MDCCSR_EL0\" bitsize=\"64\" regnum=\"38920\" group=\"system\"/>\n  <reg name=\"DBGDTR_EL0\" bitsize=\"64\" regnum=\"38944\" group=\"system\"/>\n  <reg name=\"DBGDTRRX_EL0\" bitsize=\"64\" regnum=\"38952\" group=\"system\"/>\n  <reg name=\"DBGDTRTX_EL0\" bitsize=\"64\" regnum=\"38952\" group=\"system\"/>\n  <reg name=\"DBGVCR32_EL2\" bitsize=\"64\" regnum=\"41016\" group=\"system\"/>\n  <reg name=\"MIDR_EL1\" bitsize=\"64\" regnum=\"49152\" group=\"system\"/>\n  <reg name=\"MPIDR_EL1\" bitsize=\"64\" regnum=\"49157\" group=\"system\"/>\n  <reg name=\"REVIDR_EL1\" bitsize=\"64\" regnum=\"49158\" group=\"system\"/>\n  <reg name=\"ID_PFR0_EL1\" bitsize=\"64\" regnum=\"49160\" group=\"system\"/>\n  <reg name=\"ID_PFR1_EL1\" bitsize=\"64\" regnum=\"49161\" group=\"system\"/>\n  <reg name=\"ID_DFR0_EL1\" bitsize=\"64\" regnum=\"49162\" group=\"system\"/>\n  <reg name=\"ID_AFR0_EL1\" bitsize=\"64\" regnum=\"49163\" group=\"system\"/>\n  <reg name=\"ID_MMFR0_EL1\" bitsize=\"64\" regnum=\"49164\" group=\"system\"/>\n  <reg name=\"ID_MMFR1_EL1\" bitsize=\"64\" regnum=\"49165\" group=\"system\"/>\n  <reg name=\"ID_MMFR2_EL1\" bitsize=\"64\" regnum=\"49166\" group=\"system\"/>\n  <reg name=\"ID_MMFR3_EL1\" bitsize=\"64\" regnum=\"49167\" group=\"system\"/>\n  <reg name=\"ID_ISAR0_EL1\" bitsize=\"64\" regnum=\"49168\" group=\"system\"/>\n  <reg name=\"ID_ISAR1_EL1\" bitsize=\"64\" regnum=\"49169\" group=\"system\"/>\n  <reg name=\"ID_ISAR2_EL1\" bitsize=\"64\" regnum=\"49170\" group=\"system\"/>\n  <reg name=\"ID_ISAR3_EL1\" bitsize=\"64\" regnum=\"49171\" group=\"system\"/>\n  <reg name=\"ID_ISAR4_EL1\" bitsize=\"64\" regnum=\"49172\" group=\"system\"/>\n  <reg name=\"ID_ISAR5_EL1\" bitsize=\"64\" regnum=\"49173\" group=\"system\"/>\n  <reg name=\"ID_MMFR4_EL1\" bitsize=\"64\" regnum=\"49174\" group=\"system\"/>\n  <reg name=\"ID_ISAR6_EL1\" bitsize=\"64\" regnum=\"49175\" group=\"system\"/>\n  <reg name=\"MVFR0_EL1\" bitsize=\"64\" regnum=\"49176\" group=\"system\"/>\n  <reg name=\"MVFR1_EL1\" bitsize=\"64\" regnum=\"49177\" group=\"system\"/>\n  <reg name=\"MVFR2_EL1\" bitsize=\"64\" regnum=\"49178\" group=\"system\"/>\n  <reg name=\"ID_PFR2_EL1\" bitsize=\"64\" regnum=\"49180\" group=\"system\"/>\n  <reg name=\"ID_DFR1_EL1\" bitsize=\"64\" regnum=\"49181\" group=\"system\"/>\n  <reg name=\"ID_MMFR5_EL1\" bitsize=\"64\" regnum=\"49182\" group=\"system\"/>\n  <reg name=\"ID_AA64PFR0_EL1\" bitsize=\"64\" regnum=\"49184\" group=\"system\"/>\n  <reg name=\"ID_AA64PFR1_EL1\" bitsize=\"64\" regnum=\"49185\" group=\"system\"/>\n  <reg name=\"ID_AA64ZFR0_EL1\" bitsize=\"64\" regnum=\"49188\" group=\"system\"/>\n  <reg name=\"ID_AA64SMFR0_EL1\" bitsize=\"64\" regnum=\"49189\" group=\"system\"/>\n  <reg name=\"ID_AA64DFR0_EL1\" bitsize=\"64\" regnum=\"49192\" group=\"system\"/>\n  <reg name=\"ID_AA64DFR1_EL1\" bitsize=\"64\" regnum=\"49193\" group=\"system\"/>\n  <reg name=\"ID_AA64AFR0_EL1\" bitsize=\"64\" regnum=\"49196\" group=\"system\"/>\n  <reg name=\"ID_AA64AFR1_EL1\" bitsize=\"64\" regnum=\"49197\" group=\"system\"/>\n  <reg name=\"ID_AA64ISAR0_EL1\" bitsize=\"64\" regnum=\"49200\" group=\"system\"/>\n  <reg name=\"ID_AA64ISAR1_EL1\" bitsize=\"64\" regnum=\"49201\" group=\"system\"/>\n  <reg name=\"ID_AA64ISAR2_EL1\" bitsize=\"64\" regnum=\"49202\" group=\"system\"/>\n  <reg name=\"ID_AA64MMFR0_EL1\" bitsize=\"64\" regnum=\"49208\" group=\"system\"/>\n  <reg name=\"ID_AA64MMFR1_EL1\" bitsize=\"64\" regnum=\"49209\" group=\"system\"/>\n  <reg name=\"ID_AA64MMFR2_EL1\" bitsize=\"64\" regnum=\"49210\" group=\"system\"/>\n  <reg name=\"SCTLR_EL1\" bitsize=\"64\" regnum=\"49280\" group=\"system\"/>\n  <reg name=\"ACTLR_EL1\" bitsize=\"64\" regnum=\"49281\" group=\"system\"/>\n  <reg name=\"CPACR_EL1\" bitsize=\"64\" regnum=\"49282\" group=\"system\"/>\n  <reg name=\"RGSR_EL1\" bitsize=\"64\" regnum=\"49285\" group=\"system\"/>\n  <reg name=\"GCR_EL1\" bitsize=\"64\" regnum=\"49286\" group=\"system\"/>\n  <reg name=\"ZCR_EL1\" bitsize=\"64\" regnum=\"49296\" group=\"system\"/>\n  <reg name=\"TRFCR_EL1\" bitsize=\"64\" regnum=\"49297\" group=\"system\"/>\n  <reg name=\"SMPRI_EL1\" bitsize=\"64\" regnum=\"49300\" group=\"system\"/>\n  <reg name=\"SMCR_EL1\" bitsize=\"64\" regnum=\"49302\" group=\"system\"/>\n  <reg name=\"TTBR0_EL1\" bitsize=\"64\" regnum=\"49408\" group=\"system\"/>\n  <reg name=\"TTBR1_EL1\" bitsize=\"64\" regnum=\"49409\" group=\"system\"/>\n  <reg name=\"TCR_EL1\" bitsize=\"64\" regnum=\"49410\" group=\"system\"/>\n  <reg name=\"APIAKeyLo_EL1\" bitsize=\"64\" regnum=\"49416\" group=\"system\"/>\n  <reg name=\"APIAKeyHi_EL1\" bitsize=\"64\" regnum=\"49417\" group=\"system\"/>\n  <reg name=\"APIBKeyLo_EL1\" bitsize=\"64\" regnum=\"49418\" group=\"system\"/>\n  <reg name=\"APIBKeyHi_EL1\" bitsize=\"64\" regnum=\"49419\" group=\"system\"/>\n  <reg name=\"APDAKeyLo_EL1\" bitsize=\"64\" regnum=\"49424\" group=\"system\"/>\n  <reg name=\"APDAKeyHi_EL1\" bitsize=\"64\" regnum=\"49425\" group=\"system\"/>\n  <reg name=\"APDBKeyLo_EL1\" bitsize=\"64\" regnum=\"49426\" group=\"system\"/>\n  <reg name=\"APDBKeyHi_EL1\" bitsize=\"64\" regnum=\"49427\" group=\"system\"/>\n  <reg name=\"APGAKeyLo_EL1\" bitsize=\"64\" regnum=\"49432\" group=\"system\"/>\n  <reg name=\"APGAKeyHi_EL1\" bitsize=\"64\" regnum=\"49433\" group=\"system\"/>\n  <reg name=\"SPSR_EL1\" bitsize=\"64\" regnum=\"49664\" group=\"system\"/>\n  <reg name=\"ELR_EL1\" bitsize=\"64\" regnum=\"49665\" group=\"system\"/>\n  <reg name=\"SP_EL0\" bitsize=\"64\" regnum=\"49672\" group=\"system\"/>\n  <reg name=\"ICC_PMR_EL1\" bitsize=\"64\" regnum=\"49712\" group=\"system\"/>\n  <reg name=\"ICV_PMR_EL1\" bitsize=\"64\" regnum=\"49712\" group=\"system\"/>\n  <reg name=\"AFSR0_EL1\" bitsize=\"64\" regnum=\"49800\" group=\"system\"/>\n  <reg name=\"AFSR1_EL1\" bitsize=\"64\" regnum=\"49801\" group=\"system\"/>\n  <reg name=\"ESR_EL1\" bitsize=\"64\" regnum=\"49808\" group=\"system\"/>\n  <reg name=\"ERRIDR_EL1\" bitsize=\"64\" regnum=\"49816\" group=\"system\"/>\n  <reg name=\"ERRSELR_EL1\" bitsize=\"64\" regnum=\"49817\" group=\"system\"/>\n  <reg name=\"ERXFR_EL1\" bitsize=\"64\" regnum=\"49824\" group=\"system\"/>\n  <reg name=\"ERXCTLR_EL1\" bitsize=\"64\" regnum=\"49825\" group=\"system\"/>\n  <reg name=\"ERXSTATUS_EL1\" bitsize=\"64\" regnum=\"49826\" group=\"system\"/>\n  <reg name=\"ERXADDR_EL1\" bitsize=\"64\" regnum=\"49827\" group=\"system\"/>\n  <reg name=\"ERXPFGF_EL1\" bitsize=\"64\" regnum=\"49828\" group=\"system\"/>\n  <reg name=\"ERXPFGCTL_EL1\" bitsize=\"64\" regnum=\"49829\" group=\"system\"/>\n  <reg name=\"ERXPFGCDN_EL1\" bitsize=\"64\" regnum=\"49830\" group=\"system\"/>\n  <reg name=\"ERXMISC0_EL1\" bitsize=\"64\" regnum=\"49832\" group=\"system\"/>\n  <reg name=\"ERXMISC1_EL1\" bitsize=\"64\" regnum=\"49833\" group=\"system\"/>\n  <reg name=\"ERXMISC2_EL1\" bitsize=\"64\" regnum=\"49834\" group=\"system\"/>\n  <reg name=\"ERXMISC3_EL1\" bitsize=\"64\" regnum=\"49835\" group=\"system\"/>\n  <reg name=\"TFSR_EL1\" bitsize=\"64\" regnum=\"49840\" group=\"system\"/>\n  <reg name=\"TFSRE0_EL1\" bitsize=\"64\" regnum=\"49841\" group=\"system\"/>\n  <reg name=\"FAR_EL1\" bitsize=\"64\" regnum=\"49920\" group=\"system\"/>\n  <reg name=\"PAR_EL1\" bitsize=\"64\" regnum=\"50080\" group=\"system\"/>\n  <reg name=\"PMSCR_EL1\" bitsize=\"64\" regnum=\"50376\" group=\"system\"/>\n  <reg name=\"PMSNEVFR_EL1\" bitsize=\"64\" regnum=\"50377\" group=\"system\"/>\n  <reg name=\"PMSICR_EL1\" bitsize=\"64\" regnum=\"50378\" group=\"system\"/>\n  <reg name=\"PMSIRR_EL1\" bitsize=\"64\" regnum=\"50379\" group=\"system\"/>\n  <reg name=\"PMSFCR_EL1\" bitsize=\"64\" regnum=\"50380\" group=\"system\"/>\n  <reg name=\"PMSEVFR_EL1\" bitsize=\"64\" regnum=\"50381\" group=\"system\"/>\n  <reg name=\"PMSLATFR_EL1\" bitsize=\"64\" regnum=\"50382\" group=\"system\"/>\n  <reg name=\"PMSIDR_EL1\" bitsize=\"64\" regnum=\"50383\" group=\"system\"/>\n  <reg name=\"PMBLIMITR_EL1\" bitsize=\"64\" regnum=\"50384\" group=\"system\"/>\n  <reg name=\"PMBPTR_EL1\" bitsize=\"64\" regnum=\"50385\" group=\"system\"/>\n  <reg name=\"PMBSR_EL1\" bitsize=\"64\" regnum=\"50387\" group=\"system\"/>\n  <reg name=\"PMBIDR_EL1\" bitsize=\"64\" regnum=\"50391\" group=\"system\"/>\n  <reg name=\"TRBLIMITR_EL1\" bitsize=\"64\" regnum=\"50392\" group=\"system\"/>\n  <reg name=\"TRBPTR_EL1\" bitsize=\"64\" regnum=\"50393\" group=\"system\"/>\n  <reg name=\"TRBBASER_EL1\" bitsize=\"64\" regnum=\"50394\" group=\"system\"/>\n  <reg name=\"TRBSR_EL1\" bitsize=\"64\" regnum=\"50395\" group=\"system\"/>\n  <reg name=\"TRBMAR_EL1\" bitsize=\"64\" regnum=\"50396\" group=\"system\"/>\n  <reg name=\"TRBTRG_EL1\" bitsize=\"64\" regnum=\"50398\" group=\"system\"/>\n  <reg name=\"TRBIDR_EL1\" bitsize=\"64\" regnum=\"50399\" group=\"system\"/>\n  <reg name=\"PMINTENSET_EL1\" bitsize=\"64\" regnum=\"50417\" group=\"system\"/>\n  <reg name=\"PMINTENCLR_EL1\" bitsize=\"64\" regnum=\"50418\" group=\"system\"/>\n  <reg name=\"PMMIR_EL1\" bitsize=\"64\" regnum=\"50422\" group=\"system\"/>\n  <reg name=\"MAIR_EL1\" bitsize=\"64\" regnum=\"50448\" group=\"system\"/>\n  <reg name=\"AMAIR_EL1\" bitsize=\"64\" regnum=\"50456\" group=\"system\"/>\n  <reg name=\"LORSA_EL1\" bitsize=\"64\" regnum=\"50464\" group=\"system\"/>\n  <reg name=\"LOREA_EL1\" bitsize=\"64\" regnum=\"50465\" group=\"system\"/>\n  <reg name=\"LORN_EL1\" bitsize=\"64\" regnum=\"50466\" group=\"system\"/>\n  <reg name=\"LORC_EL1\" bitsize=\"64\" regnum=\"50467\" group=\"system\"/>\n  <reg name=\"MPAMIDR_EL1\" bitsize=\"64\" regnum=\"50468\" group=\"system\"/>\n  <reg name=\"LORID_EL1\" bitsize=\"64\" regnum=\"50471\" group=\"system\"/>\n  <reg name=\"MPAM1_EL1\" bitsize=\"64\" regnum=\"50472\" group=\"system\"/>\n  <reg name=\"MPAM0_EL1\" bitsize=\"64\" regnum=\"50473\" group=\"system\"/>\n  <reg name=\"MPAMSM_EL1\" bitsize=\"64\" regnum=\"50475\" group=\"system\"/>\n  <reg name=\"VBAR_EL1\" bitsize=\"64\" regnum=\"50688\" group=\"system\"/>\n  <reg name=\"RVBAR_EL1\" bitsize=\"64\" regnum=\"50689\" group=\"system\"/>\n  <reg name=\"RMR_EL1\" bitsize=\"64\" regnum=\"50690\" group=\"system\"/>\n  <reg name=\"ISR_EL1\" bitsize=\"64\" regnum=\"50696\" group=\"system\"/>\n  <reg name=\"DISR_EL1\" bitsize=\"64\" regnum=\"50697\" group=\"system\"/>\n  <reg name=\"ICC_IAR0_EL1\" bitsize=\"64\" regnum=\"50752\" group=\"system\"/>\n  <reg name=\"ICV_IAR0_EL1\" bitsize=\"64\" regnum=\"50752\" group=\"system\"/>\n  <reg name=\"ICC_EOIR0_EL1\" bitsize=\"64\" regnum=\"50753\" group=\"system\"/>\n  <reg name=\"ICV_EOIR0_EL1\" bitsize=\"64\" regnum=\"50753\" group=\"system\"/>\n  <reg name=\"ICC_HPPIR0_EL1\" bitsize=\"64\" regnum=\"50754\" group=\"system\"/>\n  <reg name=\"ICV_HPPIR0_EL1\" bitsize=\"64\" regnum=\"50754\" group=\"system\"/>\n  <reg name=\"ICC_BPR0_EL1\" bitsize=\"64\" regnum=\"50755\" group=\"system\"/>\n  <reg name=\"ICV_BPR0_EL1\" bitsize=\"64\" regnum=\"50755\" group=\"system\"/>\n  <reg name=\"ICC_AP0R0_EL1\" bitsize=\"64\" regnum=\"50756\" group=\"system\"/>\n  <reg name=\"ICV_AP0R0_EL1\" bitsize=\"64\" regnum=\"50756\" group=\"system\"/>\n  <reg name=\"ICC_AP0R1_EL1\" bitsize=\"64\" regnum=\"50757\" group=\"system\"/>\n  <reg name=\"ICV_AP0R1_EL1\" bitsize=\"64\" regnum=\"50757\" group=\"system\"/>\n  <reg name=\"ICC_AP0R2_EL1\" bitsize=\"64\" regnum=\"50758\" group=\"system\"/>\n  <reg name=\"ICV_AP0R2_EL1\" bitsize=\"64\" regnum=\"50758\" group=\"system\"/>\n  <reg name=\"ICC_AP0R3_EL1\" bitsize=\"64\" regnum=\"50759\" group=\"system\"/>\n  <reg name=\"ICV_AP0R3_EL1\" bitsize=\"64\" regnum=\"50759\" group=\"system\"/>\n  <reg name=\"ICC_AP1R0_EL1\" bitsize=\"64\" regnum=\"50760\" group=\"system\"/>\n  <reg name=\"ICV_AP1R0_EL1\" bitsize=\"64\" regnum=\"50760\" group=\"system\"/>\n  <reg name=\"ICC_AP1R1_EL1\" bitsize=\"64\" regnum=\"50761\" group=\"system\"/>\n  <reg name=\"ICV_AP1R1_EL1\" bitsize=\"64\" regnum=\"50761\" group=\"system\"/>\n  <reg name=\"ICC_AP1R2_EL1\" bitsize=\"64\" regnum=\"50762\" group=\"system\"/>\n  <reg name=\"ICV_AP1R2_EL1\" bitsize=\"64\" regnum=\"50762\" group=\"system\"/>\n  <reg name=\"ICC_AP1R3_EL1\" bitsize=\"64\" regnum=\"50763\" group=\"system\"/>\n  <reg name=\"ICV_AP1R3_EL1\" bitsize=\"64\" regnum=\"50763\" group=\"system\"/>\n  <reg name=\"ICC_NMIAR1_EL1\" bitsize=\"64\" regnum=\"50765\" group=\"system\"/>\n  <reg name=\"ICV_NMIAR1_EL1\" bitsize=\"64\" regnum=\"50765\" group=\"system\"/>\n  <reg name=\"ICC_DIR_EL1\" bitsize=\"64\" regnum=\"50777\" group=\"system\"/>\n  <reg name=\"ICV_DIR_EL1\" bitsize=\"64\" regnum=\"50777\" group=\"system\"/>\n  <reg name=\"ICC_RPR_EL1\" bitsize=\"64\" regnum=\"50779\" group=\"system\"/>\n  <reg name=\"ICV_RPR_EL1\" bitsize=\"64\" regnum=\"50779\" group=\"system\"/>\n  <reg name=\"ICC_SGI1R_EL1\" bitsize=\"64\" regnum=\"50781\" group=\"system\"/>\n  <reg name=\"ICC_ASGI1R_EL1\" bitsize=\"64\" regnum=\"50782\" group=\"system\"/>\n  <reg name=\"ICC_SGI0R_EL1\" bitsize=\"64\" regnum=\"50783\" group=\"system\"/>\n  <reg name=\"ICC_IAR1_EL1\" bitsize=\"64\" regnum=\"50784\" group=\"system\"/>\n  <reg name=\"ICV_IAR1_EL1\" bitsize=\"64\" regnum=\"50784\" group=\"system\"/>\n  <reg name=\"ICC_EOIR1_EL1\" bitsize=\"64\" regnum=\"50785\" group=\"system\"/>\n  <reg name=\"ICV_EOIR1_EL1\" bitsize=\"64\" regnum=\"50785\" group=\"system\"/>\n  <reg name=\"ICC_HPPIR1_EL1\" bitsize=\"64\" regnum=\"50786\" group=\"system\"/>\n  <reg name=\"ICV_HPPIR1_EL1\" bitsize=\"64\" regnum=\"50786\" group=\"system\"/>\n  <reg name=\"ICC_BPR1_EL1\" bitsize=\"64\" regnum=\"50787\" group=\"system\"/>\n  <reg name=\"ICV_BPR1_EL1\" bitsize=\"64\" regnum=\"50787\" group=\"system\"/>\n  <reg name=\"ICC_CTLR_EL1\" bitsize=\"64\" regnum=\"50788\" group=\"system\"/>\n  <reg name=\"ICV_CTLR_EL1\" bitsize=\"64\" regnum=\"50788\" group=\"system\"/>\n  <reg name=\"ICC_SRE_EL1\" bitsize=\"64\" regnum=\"50789\" group=\"system\"/>\n  <reg name=\"ICC_IGRPEN0_EL1\" bitsize=\"64\" regnum=\"50790\" group=\"system\"/>\n  <reg name=\"ICV_IGRPEN0_EL1\" bitsize=\"64\" regnum=\"50790\" group=\"system\"/>\n  <reg name=\"ICC_IGRPEN1_EL1\" bitsize=\"64\" regnum=\"50791\" group=\"system\"/>\n  <reg name=\"ICV_IGRPEN1_EL1\" bitsize=\"64\" regnum=\"50791\" group=\"system\"/>\n  <reg name=\"CONTEXTIDR_EL1\" bitsize=\"64\" regnum=\"50817\" group=\"system\"/>\n  <reg name=\"TPIDR_EL1\" bitsize=\"64\" regnum=\"50820\" group=\"system\"/>\n  <reg name=\"ACCDATA_EL1\" bitsize=\"64\" regnum=\"50821\" group=\"system\"/>\n  <reg name=\"SCXTNUM_EL1\" bitsize=\"64\" regnum=\"50823\" group=\"system\"/>\n  <reg name=\"CNTKCTL_EL1\" bitsize=\"64\" regnum=\"50952\" group=\"system\"/>\n  <reg name=\"CCSIDR_EL1\" bitsize=\"64\" regnum=\"51200\" group=\"system\"/>\n  <reg name=\"CLIDR_EL1\" bitsize=\"64\" regnum=\"51201\" group=\"system\"/>\n  <reg name=\"CCSIDR2_EL1\" bitsize=\"64\" regnum=\"51202\" group=\"system\"/>\n  <reg name=\"GMID_EL1\" bitsize=\"64\" regnum=\"51204\" group=\"system\"/>\n  <reg name=\"SMIDR_EL1\" bitsize=\"64\" regnum=\"51206\" group=\"system\"/>\n  <reg name=\"AIDR_EL1\" bitsize=\"64\" regnum=\"51207\" group=\"system\"/>\n  <reg name=\"CSSELR_EL1\" bitsize=\"64\" regnum=\"53248\" group=\"system\"/>\n  <reg name=\"CTR_EL0\" bitsize=\"64\" regnum=\"55297\" group=\"system\"/>\n  <reg name=\"DCZID_EL0\" bitsize=\"64\" regnum=\"55303\" group=\"system\"/>\n  <reg name=\"RNDR\" bitsize=\"64\" regnum=\"55584\" group=\"system\"/>\n  <reg name=\"RNDRRS\" bitsize=\"64\" regnum=\"55585\" group=\"system\"/>\n  <reg name=\"SVCR\" bitsize=\"64\" regnum=\"55826\" group=\"system\"/>\n  <reg name=\"FPCR\" bitsize=\"64\" regnum=\"55840\" group=\"system\"/>\n  <reg name=\"FPSR\" bitsize=\"64\" regnum=\"55841\" group=\"system\"/>\n  <reg name=\"DSPSR_EL0\" bitsize=\"64\" regnum=\"55848\" group=\"system\"/>\n  <reg name=\"DLR_EL0\" bitsize=\"64\" regnum=\"55849\" group=\"system\"/>\n  <reg name=\"PMCR_EL0\" bitsize=\"64\" regnum=\"56544\" group=\"system\"/>\n  <reg name=\"PMCNTENSET_EL0\" bitsize=\"64\" regnum=\"56545\" group=\"system\"/>\n  <reg name=\"PMCNTENCLR_EL0\" bitsize=\"64\" regnum=\"56546\" group=\"system\"/>\n  <reg name=\"PMOVSCLR_EL0\" bitsize=\"64\" regnum=\"56547\" group=\"system\"/>\n  <reg name=\"PMSWINC_EL0\" bitsize=\"64\" regnum=\"56548\" group=\"system\"/>\n  <reg name=\"PMSELR_EL0\" bitsize=\"64\" regnum=\"56549\" group=\"system\"/>\n  <reg name=\"PMCEID0_EL0\" bitsize=\"64\" regnum=\"56550\" group=\"system\"/>\n  <reg name=\"PMCEID1_EL0\" bitsize=\"64\" regnum=\"56551\" group=\"system\"/>\n  <reg name=\"PMCCNTR_EL0\" bitsize=\"64\" regnum=\"56552\" group=\"system\"/>\n  <reg name=\"PMXEVTYPER_EL0\" bitsize=\"64\" regnum=\"56553\" group=\"system\"/>\n  <reg name=\"PMXEVCNTR_EL0\" bitsize=\"64\" regnum=\"56554\" group=\"system\"/>\n  <reg name=\"PMUSERENR_EL0\" bitsize=\"64\" regnum=\"56560\" group=\"system\"/>\n  <reg name=\"PMOVSSET_EL0\" bitsize=\"64\" regnum=\"56563\" group=\"system\"/>\n  <reg name=\"TPIDR_EL0\" bitsize=\"64\" regnum=\"56962\" group=\"system\"/>\n  <reg name=\"TPIDRRO_EL0\" bitsize=\"64\" regnum=\"56963\" group=\"system\"/>\n  <reg name=\"TPIDR2_EL0\" bitsize=\"64\" regnum=\"56965\" group=\"system\"/>\n  <reg name=\"SCXTNUM_EL0\" bitsize=\"64\" regnum=\"56967\" group=\"system\"/>\n  <reg name=\"AMCR_EL0\" bitsize=\"64\" regnum=\"56976\" group=\"system\"/>\n  <reg name=\"AMCFGR_EL0\" bitsize=\"64\" regnum=\"56977\" group=\"system\"/>\n  <reg name=\"AMCGCR_EL0\" bitsize=\"64\" regnum=\"56978\" group=\"system\"/>\n  <reg name=\"AMUSERENR_EL0\" bitsize=\"64\" regnum=\"56979\" group=\"system\"/>\n  <reg name=\"AMCNTENCLR0_EL0\" bitsize=\"64\" regnum=\"56980\" group=\"system\"/>\n  <reg name=\"AMCNTENSET0_EL0\" bitsize=\"64\" regnum=\"56981\" group=\"system\"/>\n  <reg name=\"AMCG1IDR_EL0\" bitsize=\"64\" regnum=\"56982\" group=\"system\"/>\n  <reg name=\"AMCNTENCLR1_EL0\" bitsize=\"64\" regnum=\"56984\" group=\"system\"/>\n  <reg name=\"AMCNTENSET1_EL0\" bitsize=\"64\" regnum=\"56985\" group=\"system\"/>\n  <reg name=\"AMEVCNTR00_EL0\" bitsize=\"64\" regnum=\"56992\" group=\"system\"/>\n  <reg name=\"AMEVCNTR01_EL0\" bitsize=\"64\" regnum=\"56993\" group=\"system\"/>\n  <reg name=\"AMEVCNTR02_EL0\" bitsize=\"64\" regnum=\"56994\" group=\"system\"/>\n  <reg name=\"AMEVCNTR03_EL0\" bitsize=\"64\" regnum=\"56995\" group=\"system\"/>\n  <reg name=\"AMEVTYPER00_EL0\" bitsize=\"64\" regnum=\"57008\" group=\"system\"/>\n  <reg name=\"AMEVTYPER01_EL0\" bitsize=\"64\" regnum=\"57009\" group=\"system\"/>\n  <reg name=\"AMEVTYPER02_EL0\" bitsize=\"64\" regnum=\"57010\" group=\"system\"/>\n  <reg name=\"AMEVTYPER03_EL0\" bitsize=\"64\" regnum=\"57011\" group=\"system\"/>\n  <reg name=\"AMEVCNTR10_EL0\" bitsize=\"64\" regnum=\"57056\" group=\"system\"/>\n  <reg name=\"AMEVCNTR11_EL0\" bitsize=\"64\" regnum=\"57057\" group=\"system\"/>\n  <reg name=\"AMEVCNTR12_EL0\" bitsize=\"64\" regnum=\"57058\" group=\"system\"/>\n  <reg name=\"AMEVCNTR13_EL0\" bitsize=\"64\" regnum=\"57059\" group=\"system\"/>\n  <reg name=\"AMEVCNTR14_EL0\" bitsize=\"64\" regnum=\"57060\" group=\"system\"/>\n  <reg name=\"AMEVCNTR15_EL0\" bitsize=\"64\" regnum=\"57061\" group=\"system\"/>\n  <reg name=\"AMEVCNTR16_EL0\" bitsize=\"64\" regnum=\"57062\" group=\"system\"/>\n  <reg name=\"AMEVCNTR17_EL0\" bitsize=\"64\" regnum=\"57063\" group=\"system\"/>\n  <reg name=\"AMEVCNTR18_EL0\" bitsize=\"64\" regnum=\"57064\" group=\"system\"/>\n  <reg name=\"AMEVCNTR19_EL0\" bitsize=\"64\" regnum=\"57065\" group=\"system\"/>\n  <reg name=\"AMEVCNTR110_EL0\" bitsize=\"64\" regnum=\"57066\" group=\"system\"/>\n  <reg name=\"AMEVCNTR111_EL0\" bitsize=\"64\" regnum=\"57067\" group=\"system\"/>\n  <reg name=\"AMEVCNTR112_EL0\" bitsize=\"64\" regnum=\"57068\" group=\"system\"/>\n  <reg name=\"AMEVCNTR113_EL0\" bitsize=\"64\" regnum=\"57069\" group=\"system\"/>\n  <reg name=\"AMEVCNTR114_EL0\" bitsize=\"64\" regnum=\"57070\" group=\"system\"/>\n  <reg name=\"AMEVCNTR115_EL0\" bitsize=\"64\" regnum=\"57071\" group=\"system\"/>\n  <reg name=\"AMEVTYPER10_EL0\" bitsize=\"64\" regnum=\"57072\" group=\"system\"/>\n  <reg name=\"AMEVTYPER11_EL0\" bitsize=\"64\" regnum=\"57073\" group=\"system\"/>\n  <reg name=\"AMEVTYPER12_EL0\" bitsize=\"64\" regnum=\"57074\" group=\"system\"/>\n  <reg name=\"AMEVTYPER13_EL0\" bitsize=\"64\" regnum=\"57075\" group=\"system\"/>\n  <reg name=\"AMEVTYPER14_EL0\" bitsize=\"64\" regnum=\"57076\" group=\"system\"/>\n  <reg name=\"AMEVTYPER15_EL0\" bitsize=\"64\" regnum=\"57077\" group=\"system\"/>\n  <reg name=\"AMEVTYPER16_EL0\" bitsize=\"64\" regnum=\"57078\" group=\"system\"/>\n  <reg name=\"AMEVTYPER17_EL0\" bitsize=\"64\" regnum=\"57079\" group=\"system\"/>\n  <reg name=\"AMEVTYPER18_EL0\" bitsize=\"64\" regnum=\"57080\" group=\"system\"/>\n  <reg name=\"AMEVTYPER19_EL0\" bitsize=\"64\" regnum=\"57081\" group=\"system\"/>\n  <reg name=\"AMEVTYPER110_EL0\" bitsize=\"64\" regnum=\"57082\" group=\"system\"/>\n  <reg name=\"AMEVTYPER111_EL0\" bitsize=\"64\" regnum=\"57083\" group=\"system\"/>\n  <reg name=\"AMEVTYPER112_EL0\" bitsize=\"64\" regnum=\"57084\" group=\"system\"/>\n  <reg name=\"AMEVTYPER113_EL0\" bitsize=\"64\" regnum=\"57085\" group=\"system\"/>\n  <reg name=\"AMEVTYPER114_EL0\" bitsize=\"64\" regnum=\"57086\" group=\"system\"/>\n  <reg name=\"AMEVTYPER115_EL0\" bitsize=\"64\" regnum=\"57087\" group=\"system\"/>\n  <reg name=\"CNTFRQ_EL0\" bitsize=\"64\" regnum=\"57088\" group=\"system\"/>\n  <reg name=\"CNTPCT_EL0\" bitsize=\"64\" regnum=\"57089\" group=\"system\"/>\n  <reg name=\"CNTVCT_EL0\" bitsize=\"64\" regnum=\"57090\" group=\"system\"/>\n  <reg name=\"CNTPCTSS_EL0\" bitsize=\"64\" regnum=\"57093\" group=\"system\"/>\n  <reg name=\"CNTVCTSS_EL0\" bitsize=\"64\" regnum=\"57094\" group=\"system\"/>\n  <reg name=\"CNTP_TVAL_EL0\" bitsize=\"64\" regnum=\"57104\" group=\"system\"/>\n  <reg name=\"CNTP_CTL_EL0\" bitsize=\"64\" regnum=\"57105\" group=\"system\"/>\n  <reg name=\"CNTP_CVAL_EL0\" bitsize=\"64\" regnum=\"57106\" group=\"system\"/>\n  <reg name=\"CNTV_TVAL_EL0\" bitsize=\"64\" regnum=\"57112\" group=\"system\"/>\n  <reg name=\"CNTV_CTL_EL0\" bitsize=\"64\" regnum=\"57113\" group=\"system\"/>\n  <reg name=\"CNTV_CVAL_EL0\" bitsize=\"64\" regnum=\"57114\" group=\"system\"/>\n  <reg name=\"PMEVCNTR0_EL0\" bitsize=\"64\" regnum=\"57152\" group=\"system\"/>\n  <reg name=\"PMEVCNTR1_EL0\" bitsize=\"64\" regnum=\"57153\" group=\"system\"/>\n  <reg name=\"PMEVCNTR2_EL0\" bitsize=\"64\" regnum=\"57154\" group=\"system\"/>\n  <reg name=\"PMEVCNTR3_EL0\" bitsize=\"64\" regnum=\"57155\" group=\"system\"/>\n  <reg name=\"PMEVCNTR4_EL0\" bitsize=\"64\" regnum=\"57156\" group=\"system\"/>\n  <reg name=\"PMEVCNTR5_EL0\" bitsize=\"64\" regnum=\"57157\" group=\"system\"/>\n  <reg name=\"PMEVCNTR6_EL0\" bitsize=\"64\" regnum=\"57158\" group=\"system\"/>\n  <reg name=\"PMEVCNTR7_EL0\" bitsize=\"64\" regnum=\"57159\" group=\"system\"/>\n  <reg name=\"PMEVCNTR8_EL0\" bitsize=\"64\" regnum=\"57160\" group=\"system\"/>\n  <reg name=\"PMEVCNTR9_EL0\" bitsize=\"64\" regnum=\"57161\" group=\"system\"/>\n  <reg name=\"PMEVCNTR10_EL0\" bitsize=\"64\" regnum=\"57162\" group=\"system\"/>\n  <reg name=\"PMEVCNTR11_EL0\" bitsize=\"64\" regnum=\"57163\" group=\"system\"/>\n  <reg name=\"PMEVCNTR12_EL0\" bitsize=\"64\" regnum=\"57164\" group=\"system\"/>\n  <reg name=\"PMEVCNTR13_EL0\" bitsize=\"64\" regnum=\"57165\" group=\"system\"/>\n  <reg name=\"PMEVCNTR14_EL0\" bitsize=\"64\" regnum=\"57166\" group=\"system\"/>\n  <reg name=\"PMEVCNTR15_EL0\" bitsize=\"64\" regnum=\"57167\" group=\"system\"/>\n  <reg name=\"PMEVCNTR16_EL0\" bitsize=\"64\" regnum=\"57168\" group=\"system\"/>\n  <reg name=\"PMEVCNTR17_EL0\" bitsize=\"64\" regnum=\"57169\" group=\"system\"/>\n  <reg name=\"PMEVCNTR18_EL0\" bitsize=\"64\" regnum=\"57170\" group=\"system\"/>\n  <reg name=\"PMEVCNTR19_EL0\" bitsize=\"64\" regnum=\"57171\" group=\"system\"/>\n  <reg name=\"PMEVCNTR20_EL0\" bitsize=\"64\" regnum=\"57172\" group=\"system\"/>\n  <reg name=\"PMEVCNTR21_EL0\" bitsize=\"64\" regnum=\"57173\" group=\"system\"/>\n  <reg name=\"PMEVCNTR22_EL0\" bitsize=\"64\" regnum=\"57174\" group=\"system\"/>\n  <reg name=\"PMEVCNTR23_EL0\" bitsize=\"64\" regnum=\"57175\" group=\"system\"/>\n  <reg name=\"PMEVCNTR24_EL0\" bitsize=\"64\" regnum=\"57176\" group=\"system\"/>\n  <reg name=\"PMEVCNTR25_EL0\" bitsize=\"64\" regnum=\"57177\" group=\"system\"/>\n  <reg name=\"PMEVCNTR26_EL0\" bitsize=\"64\" regnum=\"57178\" group=\"system\"/>\n  <reg name=\"PMEVCNTR27_EL0\" bitsize=\"64\" regnum=\"57179\" group=\"system\"/>\n  <reg name=\"PMEVCNTR28_EL0\" bitsize=\"64\" regnum=\"57180\" group=\"system\"/>\n  <reg name=\"PMEVCNTR29_EL0\" bitsize=\"64\" regnum=\"57181\" group=\"system\"/>\n  <reg name=\"PMEVCNTR30_EL0\" bitsize=\"64\" regnum=\"57182\" group=\"system\"/>\n  <reg name=\"PMEVTYPER0_EL0\" bitsize=\"64\" regnum=\"57184\" group=\"system\"/>\n  <reg name=\"PMEVTYPER1_EL0\" bitsize=\"64\" regnum=\"57185\" group=\"system\"/>\n  <reg name=\"PMEVTYPER2_EL0\" bitsize=\"64\" regnum=\"57186\" group=\"system\"/>\n  <reg name=\"PMEVTYPER3_EL0\" bitsize=\"64\" regnum=\"57187\" group=\"system\"/>\n  <reg name=\"PMEVTYPER4_EL0\" bitsize=\"64\" regnum=\"57188\" group=\"system\"/>\n  <reg name=\"PMEVTYPER5_EL0\" bitsize=\"64\" regnum=\"57189\" group=\"system\"/>\n  <reg name=\"PMEVTYPER6_EL0\" bitsize=\"64\" regnum=\"57190\" group=\"system\"/>\n  <reg name=\"PMEVTYPER7_EL0\" bitsize=\"64\" regnum=\"57191\" group=\"system\"/>\n  <reg name=\"PMEVTYPER8_EL0\" bitsize=\"64\" regnum=\"57192\" group=\"system\"/>\n  <reg name=\"PMEVTYPER9_EL0\" bitsize=\"64\" regnum=\"57193\" group=\"system\"/>\n  <reg name=\"PMEVTYPER10_EL0\" bitsize=\"64\" regnum=\"57194\" group=\"system\"/>\n  <reg name=\"PMEVTYPER11_EL0\" bitsize=\"64\" regnum=\"57195\" group=\"system\"/>\n  <reg name=\"PMEVTYPER12_EL0\" bitsize=\"64\" regnum=\"57196\" group=\"system\"/>\n  <reg name=\"PMEVTYPER13_EL0\" bitsize=\"64\" regnum=\"57197\" group=\"system\"/>\n  <reg name=\"PMEVTYPER14_EL0\" bitsize=\"64\" regnum=\"57198\" group=\"system\"/>\n  <reg name=\"PMEVTYPER15_EL0\" bitsize=\"64\" regnum=\"57199\" group=\"system\"/>\n  <reg name=\"PMEVTYPER16_EL0\" bitsize=\"64\" regnum=\"57200\" group=\"system\"/>\n  <reg name=\"PMEVTYPER17_EL0\" bitsize=\"64\" regnum=\"57201\" group=\"system\"/>\n  <reg name=\"PMEVTYPER18_EL0\" bitsize=\"64\" regnum=\"57202\" group=\"system\"/>\n  <reg name=\"PMEVTYPER19_EL0\" bitsize=\"64\" regnum=\"57203\" group=\"system\"/>\n  <reg name=\"PMEVTYPER20_EL0\" bitsize=\"64\" regnum=\"57204\" group=\"system\"/>\n  <reg name=\"PMEVTYPER21_EL0\" bitsize=\"64\" regnum=\"57205\" group=\"system\"/>\n  <reg name=\"PMEVTYPER22_EL0\" bitsize=\"64\" regnum=\"57206\" group=\"system\"/>\n  <reg name=\"PMEVTYPER23_EL0\" bitsize=\"64\" regnum=\"57207\" group=\"system\"/>\n  <reg name=\"PMEVTYPER24_EL0\" bitsize=\"64\" regnum=\"57208\" group=\"system\"/>\n  <reg name=\"PMEVTYPER25_EL0\" bitsize=\"64\" regnum=\"57209\" group=\"system\"/>\n  <reg name=\"PMEVTYPER26_EL0\" bitsize=\"64\" regnum=\"57210\" group=\"system\"/>\n  <reg name=\"PMEVTYPER27_EL0\" bitsize=\"64\" regnum=\"57211\" group=\"system\"/>\n  <reg name=\"PMEVTYPER28_EL0\" bitsize=\"64\" regnum=\"57212\" group=\"system\"/>\n  <reg name=\"PMEVTYPER29_EL0\" bitsize=\"64\" regnum=\"57213\" group=\"system\"/>\n  <reg name=\"PMEVTYPER30_EL0\" bitsize=\"64\" regnum=\"57214\" group=\"system\"/>\n  <reg name=\"PMCCFILTR_EL0\" bitsize=\"64\" regnum=\"57215\" group=\"system\"/>\n  <reg name=\"VPIDR_EL2\" bitsize=\"64\" regnum=\"57344\" group=\"system\"/>\n  <reg name=\"VMPIDR_EL2\" bitsize=\"64\" regnum=\"57349\" group=\"system\"/>\n  <reg name=\"SCTLR_EL2\" bitsize=\"64\" regnum=\"57472\" group=\"system\"/>\n  <reg name=\"ACTLR_EL2\" bitsize=\"64\" regnum=\"57473\" group=\"system\"/>\n  <reg name=\"HCR_EL2\" bitsize=\"64\" regnum=\"57480\" group=\"system\"/>\n  <reg name=\"MDCR_EL2\" bitsize=\"64\" regnum=\"57481\" group=\"system\"/>\n  <reg name=\"CPTR_EL2\" bitsize=\"64\" regnum=\"57482\" group=\"system\"/>\n  <reg name=\"HSTR_EL2\" bitsize=\"64\" regnum=\"57483\" group=\"system\"/>\n  <reg name=\"HFGRTR_EL2\" bitsize=\"64\" regnum=\"57484\" group=\"system\"/>\n  <reg name=\"HFGWTR_EL2\" bitsize=\"64\" regnum=\"57485\" group=\"system\"/>\n  <reg name=\"HFGITR_EL2\" bitsize=\"64\" regnum=\"57486\" group=\"system\"/>\n  <reg name=\"HACR_EL2\" bitsize=\"64\" regnum=\"57487\" group=\"system\"/>\n  <reg name=\"ZCR_EL2\" bitsize=\"64\" regnum=\"57488\" group=\"system\"/>\n  <reg name=\"TRFCR_EL2\" bitsize=\"64\" regnum=\"57489\" group=\"system\"/>\n  <reg name=\"HCRX_EL2\" bitsize=\"64\" regnum=\"57490\" group=\"system\"/>\n  <reg name=\"SMPRIMAP_EL2\" bitsize=\"64\" regnum=\"57493\" group=\"system\"/>\n  <reg name=\"SMCR_EL2\" bitsize=\"64\" regnum=\"57494\" group=\"system\"/>\n  <reg name=\"SDER32_EL2\" bitsize=\"64\" regnum=\"57497\" group=\"system\"/>\n  <reg name=\"TTBR0_EL2\" bitsize=\"64\" regnum=\"57600\" group=\"system\"/>\n  <reg name=\"TTBR1_EL2\" bitsize=\"64\" regnum=\"57601\" group=\"system\"/>\n  <reg name=\"TCR_EL2\" bitsize=\"64\" regnum=\"57602\" group=\"system\"/>\n  <reg name=\"VTTBR_EL2\" bitsize=\"64\" regnum=\"57608\" group=\"system\"/>\n  <reg name=\"VTCR_EL2\" bitsize=\"64\" regnum=\"57610\" group=\"system\"/>\n  <reg name=\"VNCR_EL2\" bitsize=\"64\" regnum=\"57616\" group=\"system\"/>\n  <reg name=\"VSTTBR_EL2\" bitsize=\"64\" regnum=\"57648\" group=\"system\"/>\n  <reg name=\"VSTCR_EL2\" bitsize=\"64\" regnum=\"57650\" group=\"system\"/>\n  <reg name=\"DACR32_EL2\" bitsize=\"64\" regnum=\"57728\" group=\"system\"/>\n  <reg name=\"HDFGRTR_EL2\" bitsize=\"64\" regnum=\"57740\" group=\"system\"/>\n  <reg name=\"HDFGWTR_EL2\" bitsize=\"64\" regnum=\"57741\" group=\"system\"/>\n  <reg name=\"HAFGRTR_EL2\" bitsize=\"64\" regnum=\"57742\" group=\"system\"/>\n  <reg name=\"SPSR_EL2\" bitsize=\"64\" regnum=\"57856\" group=\"system\"/>\n  <reg name=\"ELR_EL2\" bitsize=\"64\" regnum=\"57857\" group=\"system\"/>\n  <reg name=\"SP_EL1\" bitsize=\"64\" regnum=\"57864\" group=\"system\"/>\n  <reg name=\"SPSR_irq\" bitsize=\"64\" regnum=\"57880\" group=\"system\"/>\n  <reg name=\"SPSR_abt\" bitsize=\"64\" regnum=\"57881\" group=\"system\"/>\n  <reg name=\"SPSR_und\" bitsize=\"64\" regnum=\"57882\" group=\"system\"/>\n  <reg name=\"SPSR_fiq\" bitsize=\"64\" regnum=\"57883\" group=\"system\"/>\n  <reg name=\"IFSR32_EL2\" bitsize=\"64\" regnum=\"57985\" group=\"system\"/>\n  <reg name=\"AFSR0_EL2\" bitsize=\"64\" regnum=\"57992\" group=\"system\"/>\n  <reg name=\"AFSR1_EL2\" bitsize=\"64\" regnum=\"57993\" group=\"system\"/>\n  <reg name=\"ESR_EL2\" bitsize=\"64\" regnum=\"58000\" group=\"system\"/>\n  <reg name=\"VSESR_EL2\" bitsize=\"64\" regnum=\"58003\" group=\"system\"/>\n  <reg name=\"FPEXC32_EL2\" bitsize=\"64\" regnum=\"58008\" group=\"system\"/>\n  <reg name=\"TFSR_EL2\" bitsize=\"64\" regnum=\"58032\" group=\"system\"/>\n  <reg name=\"FAR_EL2\" bitsize=\"64\" regnum=\"58112\" group=\"system\"/>\n  <reg name=\"HPFAR_EL2\" bitsize=\"64\" regnum=\"58116\" group=\"system\"/>\n  <reg name=\"PMSCR_EL2\" bitsize=\"64\" regnum=\"58568\" group=\"system\"/>\n  <reg name=\"MAIR_EL2\" bitsize=\"64\" regnum=\"58640\" group=\"system\"/>\n  <reg name=\"AMAIR_EL2\" bitsize=\"64\" regnum=\"58648\" group=\"system\"/>\n  <reg name=\"MPAMHCR_EL2\" bitsize=\"64\" regnum=\"58656\" group=\"system\"/>\n  <reg name=\"MPAMVPMV_EL2\" bitsize=\"64\" regnum=\"58657\" group=\"system\"/>\n  <reg name=\"MPAM2_EL2\" bitsize=\"64\" regnum=\"58664\" group=\"system\"/>\n  <reg name=\"MPAMVPM0_EL2\" bitsize=\"64\" regnum=\"58672\" group=\"system\"/>\n  <reg name=\"MPAMVPM1_EL2\" bitsize=\"64\" regnum=\"58673\" group=\"system\"/>\n  <reg name=\"MPAMVPM2_EL2\" bitsize=\"64\" regnum=\"58674\" group=\"system\"/>\n  <reg name=\"MPAMVPM3_EL2\" bitsize=\"64\" regnum=\"58675\" group=\"system\"/>\n  <reg name=\"MPAMVPM4_EL2\" bitsize=\"64\" regnum=\"58676\" group=\"system\"/>\n  <reg name=\"MPAMVPM5_EL2\" bitsize=\"64\" regnum=\"58677\" group=\"system\"/>\n  <reg name=\"MPAMVPM6_EL2\" bitsize=\"64\" regnum=\"58678\" group=\"system\"/>\n  <reg name=\"MPAMVPM7_EL2\" bitsize=\"64\" regnum=\"58679\" group=\"system\"/>\n  <reg name=\"VBAR_EL2\" bitsize=\"64\" regnum=\"58880\" group=\"system\"/>\n  <reg name=\"RVBAR_EL2\" bitsize=\"64\" regnum=\"58881\" group=\"system\"/>\n  <reg name=\"RMR_EL2\" bitsize=\"64\" regnum=\"58882\" group=\"system\"/>\n  <reg name=\"VDISR_EL2\" bitsize=\"64\" regnum=\"58889\" group=\"system\"/>\n  <reg name=\"ICH_AP0R0_EL2\" bitsize=\"64\" regnum=\"58944\" group=\"system\"/>\n  <reg name=\"ICH_AP0R1_EL2\" bitsize=\"64\" regnum=\"58945\" group=\"system\"/>\n  <reg name=\"ICH_AP0R2_EL2\" bitsize=\"64\" regnum=\"58946\" group=\"system\"/>\n  <reg name=\"ICH_AP0R3_EL2\" bitsize=\"64\" regnum=\"58947\" group=\"system\"/>\n  <reg name=\"ICH_AP1R0_EL2\" bitsize=\"64\" regnum=\"58952\" group=\"system\"/>\n  <reg name=\"ICH_AP1R1_EL2\" bitsize=\"64\" regnum=\"58953\" group=\"system\"/>\n  <reg name=\"ICH_AP1R2_EL2\" bitsize=\"64\" regnum=\"58954\" group=\"system\"/>\n  <reg name=\"ICH_AP1R3_EL2\" bitsize=\"64\" regnum=\"58955\" group=\"system\"/>\n  <reg name=\"ICC_SRE_EL2\" bitsize=\"64\" regnum=\"58957\" group=\"system\"/>\n  <reg name=\"ICH_HCR_EL2\" bitsize=\"64\" regnum=\"58968\" group=\"system\"/>\n  <reg name=\"ICH_VTR_EL2\" bitsize=\"64\" regnum=\"58969\" group=\"system\"/>\n  <reg name=\"ICH_MISR_EL2\" bitsize=\"64\" regnum=\"58970\" group=\"system\"/>\n  <reg name=\"ICH_EISR_EL2\" bitsize=\"64\" regnum=\"58971\" group=\"system\"/>\n  <reg name=\"ICH_ELRSR_EL2\" bitsize=\"64\" regnum=\"58973\" group=\"system\"/>\n  <reg name=\"ICH_VMCR_EL2\" bitsize=\"64\" regnum=\"58975\" group=\"system\"/>\n  <reg name=\"ICH_LR0_EL2\" bitsize=\"64\" regnum=\"58976\" group=\"system\"/>\n  <reg name=\"ICH_LR1_EL2\" bitsize=\"64\" regnum=\"58977\" group=\"system\"/>\n  <reg name=\"ICH_LR2_EL2\" bitsize=\"64\" regnum=\"58978\" group=\"system\"/>\n  <reg name=\"ICH_LR3_EL2\" bitsize=\"64\" regnum=\"58979\" group=\"system\"/>\n  <reg name=\"ICH_LR4_EL2\" bitsize=\"64\" regnum=\"58980\" group=\"system\"/>\n  <reg name=\"ICH_LR5_EL2\" bitsize=\"64\" regnum=\"58981\" group=\"system\"/>\n  <reg name=\"ICH_LR6_EL2\" bitsize=\"64\" regnum=\"58982\" group=\"system\"/>\n  <reg name=\"ICH_LR7_EL2\" bitsize=\"64\" regnum=\"58983\" group=\"system\"/>\n  <reg name=\"ICH_LR8_EL2\" bitsize=\"64\" regnum=\"58984\" group=\"system\"/>\n  <reg name=\"ICH_LR9_EL2\" bitsize=\"64\" regnum=\"58985\" group=\"system\"/>\n  <reg name=\"ICH_LR10_EL2\" bitsize=\"64\" regnum=\"58986\" group=\"system\"/>\n  <reg name=\"ICH_LR11_EL2\" bitsize=\"64\" regnum=\"58987\" group=\"system\"/>\n  <reg name=\"ICH_LR12_EL2\" bitsize=\"64\" regnum=\"58988\" group=\"system\"/>\n  <reg name=\"ICH_LR13_EL2\" bitsize=\"64\" regnum=\"58989\" group=\"system\"/>\n  <reg name=\"ICH_LR14_EL2\" bitsize=\"64\" regnum=\"58990\" group=\"system\"/>\n  <reg name=\"ICH_LR15_EL2\" bitsize=\"64\" regnum=\"58991\" group=\"system\"/>\n  <reg name=\"CONTEXTIDR_EL2\" bitsize=\"64\" regnum=\"59009\" group=\"system\"/>\n  <reg name=\"TPIDR_EL2\" bitsize=\"64\" regnum=\"59010\" group=\"system\"/>\n  <reg name=\"SCXTNUM_EL2\" bitsize=\"64\" regnum=\"59015\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF00_EL2\" bitsize=\"64\" regnum=\"59072\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF01_EL2\" bitsize=\"64\" regnum=\"59073\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF02_EL2\" bitsize=\"64\" regnum=\"59074\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF03_EL2\" bitsize=\"64\" regnum=\"59075\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF04_EL2\" bitsize=\"64\" regnum=\"59076\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF05_EL2\" bitsize=\"64\" regnum=\"59077\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF06_EL2\" bitsize=\"64\" regnum=\"59078\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF07_EL2\" bitsize=\"64\" regnum=\"59079\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF08_EL2\" bitsize=\"64\" regnum=\"59080\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF09_EL2\" bitsize=\"64\" regnum=\"59081\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF010_EL2\" bitsize=\"64\" regnum=\"59082\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF011_EL2\" bitsize=\"64\" regnum=\"59083\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF012_EL2\" bitsize=\"64\" regnum=\"59084\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF013_EL2\" bitsize=\"64\" regnum=\"59085\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF014_EL2\" bitsize=\"64\" regnum=\"59086\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF015_EL2\" bitsize=\"64\" regnum=\"59087\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF10_EL2\" bitsize=\"64\" regnum=\"59088\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF11_EL2\" bitsize=\"64\" regnum=\"59089\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF12_EL2\" bitsize=\"64\" regnum=\"59090\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF13_EL2\" bitsize=\"64\" regnum=\"59091\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF14_EL2\" bitsize=\"64\" regnum=\"59092\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF15_EL2\" bitsize=\"64\" regnum=\"59093\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF16_EL2\" bitsize=\"64\" regnum=\"59094\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF17_EL2\" bitsize=\"64\" regnum=\"59095\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF18_EL2\" bitsize=\"64\" regnum=\"59096\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF19_EL2\" bitsize=\"64\" regnum=\"59097\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF110_EL2\" bitsize=\"64\" regnum=\"59098\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF111_EL2\" bitsize=\"64\" regnum=\"59099\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF112_EL2\" bitsize=\"64\" regnum=\"59100\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF113_EL2\" bitsize=\"64\" regnum=\"59101\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF114_EL2\" bitsize=\"64\" regnum=\"59102\" group=\"system\"/>\n  <reg name=\"AMEVCNTVOFF115_EL2\" bitsize=\"64\" regnum=\"59103\" group=\"system\"/>\n  <reg name=\"CNTVOFF_EL2\" bitsize=\"64\" regnum=\"59139\" group=\"system\"/>\n  <reg name=\"CNTPOFF_EL2\" bitsize=\"64\" regnum=\"59142\" group=\"system\"/>\n  <reg name=\"CNTHCTL_EL2\" bitsize=\"64\" regnum=\"59144\" group=\"system\"/>\n  <reg name=\"CNTHP_TVAL_EL2\" bitsize=\"64\" regnum=\"59152\" group=\"system\"/>\n  <reg name=\"CNTHP_CTL_EL2\" bitsize=\"64\" regnum=\"59153\" group=\"system\"/>\n  <reg name=\"CNTHP_CVAL_EL2\" bitsize=\"64\" regnum=\"59154\" group=\"system\"/>\n  <reg name=\"CNTHV_TVAL_EL2\" bitsize=\"64\" regnum=\"59160\" group=\"system\"/>\n  <reg name=\"CNTHV_CTL_EL2\" bitsize=\"64\" regnum=\"59161\" group=\"system\"/>\n  <reg name=\"CNTHV_CVAL_EL2\" bitsize=\"64\" regnum=\"59162\" group=\"system\"/>\n  <reg name=\"CNTHVS_TVAL_EL2\" bitsize=\"64\" regnum=\"59168\" group=\"system\"/>\n  <reg name=\"CNTHVS_CTL_EL2\" bitsize=\"64\" regnum=\"59169\" group=\"system\"/>\n  <reg name=\"CNTHVS_CVAL_EL2\" bitsize=\"64\" regnum=\"59170\" group=\"system\"/>\n  <reg name=\"CNTHPS_TVAL_EL2\" bitsize=\"64\" regnum=\"59176\" group=\"system\"/>\n  <reg name=\"CNTHPS_CTL_EL2\" bitsize=\"64\" regnum=\"59177\" group=\"system\"/>\n  <reg name=\"CNTHPS_CVAL_EL2\" bitsize=\"64\" regnum=\"59178\" group=\"system\"/>\n  <reg name=\"SCTLR_EL3\" bitsize=\"64\" regnum=\"61568\" group=\"system\"/>\n  <reg name=\"ACTLR_EL3\" bitsize=\"64\" regnum=\"61569\" group=\"system\"/>\n  <reg name=\"SCR_EL3\" bitsize=\"64\" regnum=\"61576\" group=\"system\"/>\n  <reg name=\"SDER32_EL3\" bitsize=\"64\" regnum=\"61577\" group=\"system\"/>\n  <reg name=\"CPTR_EL3\" bitsize=\"64\" regnum=\"61578\" group=\"system\"/>\n  <reg name=\"ZCR_EL3\" bitsize=\"64\" regnum=\"61584\" group=\"system\"/>\n  <reg name=\"SMCR_EL3\" bitsize=\"64\" regnum=\"61590\" group=\"system\"/>\n  <reg name=\"MDCR_EL3\" bitsize=\"64\" regnum=\"61593\" group=\"system\"/>\n  <reg name=\"TTBR0_EL3\" bitsize=\"64\" regnum=\"61696\" group=\"system\"/>\n  <reg name=\"TCR_EL3\" bitsize=\"64\" regnum=\"61698\" group=\"system\"/>\n  <reg name=\"GPTBR_EL3\" bitsize=\"64\" regnum=\"61708\" group=\"system\"/>\n  <reg name=\"GPCCR_EL3\" bitsize=\"64\" regnum=\"61710\" group=\"system\"/>\n  <reg name=\"SPSR_EL3\" bitsize=\"64\" regnum=\"61952\" group=\"system\"/>\n  <reg name=\"ELR_EL3\" bitsize=\"64\" regnum=\"61953\" group=\"system\"/>\n  <reg name=\"SP_EL2\" bitsize=\"64\" regnum=\"61960\" group=\"system\"/>\n  <reg name=\"AFSR0_EL3\" bitsize=\"64\" regnum=\"62088\" group=\"system\"/>\n  <reg name=\"AFSR1_EL3\" bitsize=\"64\" regnum=\"62089\" group=\"system\"/>\n  <reg name=\"ESR_EL3\" bitsize=\"64\" regnum=\"62096\" group=\"system\"/>\n  <reg name=\"TFSR_EL3\" bitsize=\"64\" regnum=\"62128\" group=\"system\"/>\n  <reg name=\"FAR_EL3\" bitsize=\"64\" regnum=\"62208\" group=\"system\"/>\n  <reg name=\"MFAR_EL3\" bitsize=\"64\" regnum=\"62213\" group=\"system\"/>\n  <reg name=\"MAIR_EL3\" bitsize=\"64\" regnum=\"62736\" group=\"system\"/>\n  <reg name=\"AMAIR_EL3\" bitsize=\"64\" regnum=\"62744\" group=\"system\"/>\n  <reg name=\"MPAM3_EL3\" bitsize=\"64\" regnum=\"62760\" group=\"system\"/>\n  <reg name=\"VBAR_EL3\" bitsize=\"64\" regnum=\"62976\" group=\"system\"/>\n  <reg name=\"RVBAR_EL3\" bitsize=\"64\" regnum=\"62977\" group=\"system\"/>\n  <reg name=\"RMR_EL3\" bitsize=\"64\" regnum=\"62978\" group=\"system\"/>\n  <reg name=\"ICC_CTLR_EL3\" bitsize=\"64\" regnum=\"63076\" group=\"system\"/>\n  <reg name=\"ICC_SRE_EL3\" bitsize=\"64\" regnum=\"63077\" group=\"system\"/>\n  <reg name=\"ICC_IGRPEN1_EL3\" bitsize=\"64\" regnum=\"63079\" group=\"system\"/>\n  <reg name=\"TPIDR_EL3\" bitsize=\"64\" regnum=\"63106\" group=\"system\"/>\n  <reg name=\"SCXTNUM_EL3\" bitsize=\"64\" regnum=\"63111\" group=\"system\"/>\n  <reg name=\"CNTPS_TVAL_EL1\" bitsize=\"64\" regnum=\"65296\" group=\"system\"/>\n  <reg name=\"CNTPS_CTL_EL1\" bitsize=\"64\" regnum=\"65297\" group=\"system\"/>\n  <reg name=\"CNTPS_CVAL_EL1\" bitsize=\"64\" regnum=\"65298\" group=\"system\"/>\n</feature>\n"
  },
  {
    "path": "gdbstub_arch/src/arm/mod.rs",
    "content": "//! Implementations for various ARM architectures.\n\nuse gdbstub::arch::Arch;\n\npub mod reg;\n\n/// ARM-specific breakpoint kinds.\n///\n/// Extracted from the GDB documentation at\n/// [E.5.1.1 ARM Breakpoint Kinds](https://sourceware.org/gdb/current/onlinedocs/gdb/ARM-Breakpoint-Kinds.html#ARM-Breakpoint-Kinds)\n#[derive(Debug)]\npub enum ArmBreakpointKind {\n    /// 16-bit Thumb mode breakpoint.\n    Thumb16,\n    /// 32-bit Thumb mode (Thumb-2) breakpoint.\n    Thumb32,\n    /// 32-bit ARM mode breakpoint.\n    Arm32,\n}\n\nimpl gdbstub::arch::BreakpointKind for ArmBreakpointKind {\n    fn from_usize(kind: usize) -> Option<Self> {\n        let kind = match kind {\n            2 => ArmBreakpointKind::Thumb16,\n            3 => ArmBreakpointKind::Thumb32,\n            4 => ArmBreakpointKind::Arm32,\n            _ => return None,\n        };\n        Some(kind)\n    }\n}\n\n/// Implements `Arch` for the ARMv4T architecture\npub enum Armv4t {}\n\nimpl Arch for Armv4t {\n    type Usize = u32;\n    type Registers = reg::ArmCoreRegs;\n    type RegId = reg::id::ArmCoreRegId;\n    type BreakpointKind = ArmBreakpointKind;\n\n    fn target_description_xml() -> Option<&'static str> {\n        Some(r#\"<target version=\"1.0\"><architecture>armv4t</architecture></target>\"#)\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/arm/reg/arm_core.rs",
    "content": "use gdbstub::arch::Registers;\n\n/// 32-bit ARM core registers.\n///\n/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/arm/arm-core.xml>\n#[derive(Debug, Default, Clone, Eq, PartialEq)]\npub struct ArmCoreRegs {\n    /// General purpose registers (R0-R12)\n    pub r: [u32; 13],\n    /// Stack Pointer (R13)\n    pub sp: u32,\n    /// Link Register (R14)\n    pub lr: u32,\n    /// Program Counter (R15)\n    pub pc: u32,\n    /// Current Program Status Register (cpsr)\n    pub cpsr: u32,\n}\n\nimpl Registers for ArmCoreRegs {\n    type ProgramCounter = u32;\n\n    fn pc(&self) -> Self::ProgramCounter {\n        self.pc\n    }\n\n    fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {\n        macro_rules! write_bytes {\n            ($bytes:expr) => {\n                for b in $bytes {\n                    write_byte(Some(*b))\n                }\n            };\n        }\n\n        for reg in self.r.iter() {\n            write_bytes!(&reg.to_le_bytes());\n        }\n        write_bytes!(&self.sp.to_le_bytes());\n        write_bytes!(&self.lr.to_le_bytes());\n        write_bytes!(&self.pc.to_le_bytes());\n\n        // Floating point registers (unused)\n        for _ in 0..25 {\n            (0..4).for_each(|_| write_byte(None))\n        }\n\n        write_bytes!(&self.cpsr.to_le_bytes());\n    }\n\n    fn gdb_deserialize(&mut self, mut bytes: &[u8]) -> Result<(), ()> {\n        if bytes.len() != (17 + 25) * 4 {\n            return Err(());\n        }\n\n        let mut next_reg = || {\n            if bytes.len() < 4 {\n                Err(())\n            } else {\n                use core::convert::TryInto;\n\n                let (next, rest) = bytes.split_at(4);\n                bytes = rest;\n                Ok(u32::from_le_bytes(next.try_into().unwrap()))\n            }\n        };\n\n        for reg in self.r.iter_mut() {\n            *reg = next_reg()?\n        }\n        self.sp = next_reg()?;\n        self.lr = next_reg()?;\n        self.pc = next_reg()?;\n\n        // Floating point registers (unused)\n        for _ in 0..25 {\n            next_reg()?;\n        }\n\n        self.cpsr = next_reg()?;\n\n        if next_reg().is_ok() {\n            return Err(());\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/arm/reg/id.rs",
    "content": "use core::num::NonZeroUsize;\nuse gdbstub::arch::RegId;\n\n/// 32-bit ARM core register identifier.\n#[derive(Debug, Clone, Copy)]\n#[non_exhaustive]\npub enum ArmCoreRegId {\n    /// General purpose registers (R0-R12)\n    Gpr(u8),\n    /// Stack Pointer (R13)\n    Sp,\n    /// Link Register (R14)\n    Lr,\n    /// Program Counter (R15)\n    Pc,\n    /// Floating point registers (F0-F7)\n    Fpr(u8),\n    /// Floating point status\n    Fps,\n    /// Current Program Status Register (cpsr)\n    Cpsr,\n}\n\nimpl RegId for ArmCoreRegId {\n    fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> {\n        let reg = match id {\n            0..=12 => Self::Gpr(id as u8),\n            13 => Self::Sp,\n            14 => Self::Lr,\n            15 => Self::Pc,\n            16..=23 => Self::Fpr((id as u8) - 16),\n            24 => Self::Fps,\n            25 => Self::Cpsr,\n            _ => return None,\n        };\n        Some((reg, Some(NonZeroUsize::new(4)?)))\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/arm/reg/mod.rs",
    "content": "//! `Register` structs for various ARM architectures.\n\n/// `RegId` definitions for ARM architectures.\npub mod id;\n\nmod arm_core;\n\npub use arm_core::ArmCoreRegs;\n"
  },
  {
    "path": "gdbstub_arch/src/lib.rs",
    "content": "//! Community-created implementations of [`gdbstub::arch::Arch`] for various\n//! architectures.\n//!\n//! _Note:_ If an architecture is missing from this crate, that does _not_ mean\n//! that it can't be used with `gdbstub`! So-long as there's support for the\n//! target architecture in GDB, it should be fairly straightforward to implement\n//! `Arch` manually.\n//!\n//! Please consider upstreaming any missing `Arch` implementations you happen to\n//! implement yourself! Aside from the altruistic motive of improving `gdbstub`,\n//! upstreaming your `Arch` implementation will ensure that it's kept up-to-date\n//! with any future breaking API changes.\n//!\n//! **Disclaimer:** These implementations are all community contributions, and\n//! while they are tested (by the PR's author) and code-reviewed, it's not\n//! particularly feasible to write detailed tests for each architecture! If you\n//! spot a bug in any of the implementations, please file an issue / open a PR!\n//!\n//! # What's with `RegIdImpl`?\n//!\n//! Supporting the `Target::read/write_register` API required introducing a new\n//! [`RegId`] trait + [`Arch::RegId`] associated type. `RegId` is used by\n//! `gdbstub` to translate raw GDB register ids (a protocol level arch-dependent\n//! `usize`) into human-readable enum variants.\n//!\n//! Unfortunately, this API was added after several contributors had already\n//! upstreamed their `Arch` implementations, and as a result, there are several\n//! built-in arch implementations which are missing proper `RegId` enums\n//! (tracked under [issue #29](https://github.com/daniel5151/gdbstub/issues/29)).\n//!\n//! As a stop-gap measure, affected `Arch` implementations have been modified to\n//! accept a `RegIdImpl` type parameter, which requires users to manually\n//! specify a `RegId` implementation.\n//!\n//! If you're not interested in implementing the `Target::read/write_register`\n//! methods and just want to get up-and-running with `gdbstub`, it's fine to\n//! set `RegIdImpl` to `()` and use the built-in stubbed `impl RegId for ()`.\n//!\n//! A better approach would be to implement (and hopefully upstream!) a proper\n//! `RegId` enum. While this will require doing a bit of digging through the GDB\n//! docs + [architecture XML definitions](https://github.com/bminor/binutils-gdb/tree/master/gdb/features/),\n//! it's not too tricky to get a working implementation up and running, and\n//! makes it possible to safely and efficiently implement the\n//! `Target::read/write_register` API. As an example, check out\n//! [`ArmCoreRegId`](arm::reg::id::ArmCoreRegId#impl-RegId).\n//!\n//! Whenever a `RegId` enum is upstreamed, the associated `Arch`'s `RegIdImpl`\n//! parameter will be defaulted to the newly added enum. This will simplify the\n//! API without requiring an explicit breaking API change. Once all `RegIdImpl`\n//! have a default implementation, only a single breaking API change will be\n//! required to remove `RegIdImpl` entirely (along with this documentation).\n\n#![cfg_attr(not(test), no_std)]\n#![deny(missing_docs)]\n\npub mod aarch64;\npub mod arm;\npub mod mips;\npub mod msp430;\npub mod ppc;\npub mod riscv;\npub mod wasm;\npub mod x86;\n\n// used as part of intra-doc link\n#[allow(unused_imports)]\nuse gdbstub::arch::*;\n"
  },
  {
    "path": "gdbstub_arch/src/mips/mod.rs",
    "content": "//! Implementations for the MIPS architecture.\n\nuse gdbstub::arch::Arch;\n\npub mod reg;\n\n/// MIPS-specific breakpoint kinds.\n///\n/// Extracted from the GDB documentation at\n/// [E.5.1.1 MIPS Breakpoint Kinds](https://sourceware.org/gdb/current/onlinedocs/gdb/MIPS-Breakpoint-Kinds.html#MIPS-Breakpoint-Kinds)\n#[derive(Debug)]\npub enum MipsBreakpointKind {\n    /// 16-bit MIPS16 mode breakpoint.\n    Mips16,\n\n    /// 16-bit microMIPS mode breakpoint.\n    MicroMips16,\n\n    /// 32-bit standard MIPS mode breakpoint.\n    Mips32,\n\n    /// 32-bit microMIPS mode breakpoint.\n    MicroMips32,\n}\n\nimpl gdbstub::arch::BreakpointKind for MipsBreakpointKind {\n    fn from_usize(kind: usize) -> Option<Self> {\n        let kind = match kind {\n            2 => MipsBreakpointKind::Mips16,\n            3 => MipsBreakpointKind::MicroMips16,\n            4 => MipsBreakpointKind::Mips32,\n            5 => MipsBreakpointKind::MicroMips32,\n            _ => return None,\n        };\n        Some(kind)\n    }\n}\n\n/// Implements `Arch` for 32-bit MIPS.\npub enum Mips {}\n\n/// Implements `Arch` for 32-bit MIPS, with the DSP feature enabled.\npub enum MipsWithDsp {}\n\n/// Implements `Arch` for 64-bit MIPS.\n///\n/// **NOTE:** Due to GDB client behavior, this arch does _not_ include a\n/// built-in `target.xml` implementation. Consider manually implementing\n/// [`TargetDescriptionXmlOverride`].\n///\n/// See [daniel5151/gdbstub#97](https://github.com/daniel5151/gdbstub/issues/97).\n///\n/// [`TargetDescriptionXmlOverride`]: gdbstub::target::ext::target_description_xml_override::TargetDescriptionXmlOverride\npub enum Mips64 {}\n\n/// Implements `Arch` for 64-bit MIPS, with the DSP feature enabled.\n///\n/// **NOTE:** Due to GDB client behavior, this arch does _not_ include a\n/// built-in `target.xml` implementation. Consider manually implementing\n/// [`TargetDescriptionXmlOverride`].\n///\n/// See [daniel5151/gdbstub#97](https://github.com/daniel5151/gdbstub/issues/97).\n///\n/// [`TargetDescriptionXmlOverride`]: gdbstub::target::ext::target_description_xml_override::TargetDescriptionXmlOverride\npub enum Mips64WithDsp {}\n\nimpl Arch for Mips {\n    type Usize = u32;\n    type Registers = reg::MipsCoreRegs<u32>;\n    type RegId = reg::id::MipsRegId<u32>;\n    type BreakpointKind = MipsBreakpointKind;\n\n    fn target_description_xml() -> Option<&'static str> {\n        Some(r#\"<target version=\"1.0\"><architecture>mips</architecture></target>\"#)\n    }\n}\n\nimpl Arch for MipsWithDsp {\n    type Usize = u32;\n    type Registers = reg::MipsCoreRegsWithDsp<u32>;\n    type RegId = reg::id::MipsRegId<u32>;\n    type BreakpointKind = MipsBreakpointKind;\n\n    fn target_description_xml() -> Option<&'static str> {\n        Some(\n            r#\"<target version=\"1.0\"><architecture>mips</architecture><feature name=\"org.gnu.gdb.mips.dsp\"></feature></target>\"#,\n        )\n    }\n}\n\n#[allow(deprecated)]\nimpl Arch for Mips64 {\n    type Usize = u64;\n    type Registers = reg::MipsCoreRegs<u64>;\n    type RegId = reg::id::MipsRegId<u64>;\n    type BreakpointKind = MipsBreakpointKind;\n\n    fn target_description_xml() -> Option<&'static str> {\n        None\n    }\n}\n\n#[allow(deprecated)]\nimpl Arch for Mips64WithDsp {\n    type Usize = u64;\n    type Registers = reg::MipsCoreRegsWithDsp<u64>;\n    type RegId = reg::id::MipsRegId<u64>;\n    type BreakpointKind = MipsBreakpointKind;\n\n    fn target_description_xml() -> Option<&'static str> {\n        None\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/mips/reg/id.rs",
    "content": "use core::num::NonZeroUsize;\nuse gdbstub::arch::RegId;\n\n/// MIPS register identifier.\n#[derive(Debug, Clone, Copy)]\n#[non_exhaustive]\npub enum MipsRegId<U> {\n    /// General purpose registers (R0-R31)\n    Gpr(u8),\n    /// Status register\n    Status,\n    /// Low register\n    Lo,\n    /// High register\n    Hi,\n    /// Bad Virtual Address register\n    Badvaddr,\n    /// Exception Cause register\n    Cause,\n    /// Program Counter\n    Pc,\n    /// Floating point registers (F0-F31)\n    Fpr(u8),\n    /// Floating-point Control Status register\n    Fcsr,\n    /// Floating-point Implementation Register\n    Fir,\n    /// High 1 register\n    Hi1,\n    /// Low 1 register\n    Lo1,\n    /// High 2 register\n    Hi2,\n    /// Low 2 register\n    Lo2,\n    /// High 3 register\n    Hi3,\n    /// Low 3 register\n    Lo3,\n    /// DSP Control register\n    Dspctl,\n    /// Restart register\n    Restart,\n    #[doc(hidden)]\n    _Size(core::marker::PhantomData<U>),\n}\n\nfn from_raw_id<U>(id: usize) -> Option<(MipsRegId<U>, Option<NonZeroUsize>)> {\n    let reg = match id {\n        0..=31 => MipsRegId::Gpr(id as u8),\n        32 => MipsRegId::Status,\n        33 => MipsRegId::Lo,\n        34 => MipsRegId::Hi,\n        35 => MipsRegId::Badvaddr,\n        36 => MipsRegId::Cause,\n        37 => MipsRegId::Pc,\n        38..=69 => MipsRegId::Fpr((id as u8) - 38),\n        70 => MipsRegId::Fcsr,\n        71 => MipsRegId::Fir,\n        72 => MipsRegId::Hi1,\n        73 => MipsRegId::Lo1,\n        74 => MipsRegId::Hi2,\n        75 => MipsRegId::Lo2,\n        76 => MipsRegId::Hi3,\n        77 => MipsRegId::Lo3,\n        // `MipsRegId::Dspctl` is the only register that will always be 4 bytes wide\n        78 => return Some((MipsRegId::Dspctl, Some(NonZeroUsize::new(4)?))),\n        79 => MipsRegId::Restart,\n        _ => return None,\n    };\n\n    let ptrsize = core::mem::size_of::<U>();\n    Some((reg, Some(NonZeroUsize::new(ptrsize)?)))\n}\n\nimpl RegId for MipsRegId<u32> {\n    fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> {\n        from_raw_id::<u32>(id)\n    }\n}\n\nimpl RegId for MipsRegId<u64> {\n    fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> {\n        from_raw_id::<u64>(id)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use gdbstub::arch::RegId;\n    use gdbstub::arch::Registers;\n\n    fn test<Rs: Registers, RId: RegId>() {\n        // Obtain the data length written by `gdb_serialize` by passing a custom\n        // closure.\n        let mut serialized_data_len = 0;\n        let counter = |b: Option<u8>| {\n            if b.is_some() {\n                serialized_data_len += 1;\n            }\n        };\n        Rs::default().gdb_serialize(counter);\n\n        // Accumulate register sizes returned by `from_raw_id`.\n        let mut i = 0;\n        let mut sum_reg_sizes = 0;\n        while let Some((_, size)) = RId::from_raw_id(i) {\n            sum_reg_sizes += size.unwrap().get();\n            i += 1;\n        }\n\n        assert_eq!(serialized_data_len, sum_reg_sizes);\n    }\n\n    #[test]\n    fn test_mips32() {\n        test::<crate::mips::reg::MipsCoreRegsWithDsp<u32>, crate::mips::reg::id::MipsRegId<u32>>()\n    }\n\n    #[test]\n    fn test_mips64() {\n        test::<crate::mips::reg::MipsCoreRegsWithDsp<u64>, crate::mips::reg::id::MipsRegId<u64>>()\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/mips/reg/mips.rs",
    "content": "use core::convert::TryInto;\nuse gdbstub::arch::Registers;\nuse gdbstub::internal::LeBytes;\nuse num_traits::PrimInt;\n\n/// MIPS registers.\n///\n/// The register width is set to `u32` or `u64` based on the `<U>` type.\n///\n/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-cpu.xml>\n#[derive(Debug, Default, Clone, Eq, PartialEq)]\npub struct MipsCoreRegs<U> {\n    /// General purpose registers (R0-R31)\n    pub r: [U; 32],\n    /// Low register (regnum 33)\n    pub lo: U,\n    /// High register (regnum 34)\n    pub hi: U,\n    /// Program Counter (regnum 37)\n    pub pc: U,\n    /// CP0 registers\n    pub cp0: MipsCp0Regs<U>,\n    /// FPU registers\n    pub fpu: MipsFpuRegs<U>,\n}\n\n/// MIPS CP0 (coprocessor 0) registers.\n///\n/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-cp0.xml>\n#[derive(Debug, Default, Clone, Eq, PartialEq)]\npub struct MipsCp0Regs<U> {\n    /// Status register (regnum 32)\n    pub status: U,\n    /// Bad Virtual Address register (regnum 35)\n    pub badvaddr: U,\n    /// Exception Cause register (regnum 36)\n    pub cause: U,\n}\n\n/// MIPS FPU registers.\n///\n/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-fpu.xml>\n#[derive(Debug, Default, Clone, Eq, PartialEq)]\npub struct MipsFpuRegs<U> {\n    /// FP registers (F0-F31) starting at regnum 38\n    pub r: [U; 32],\n    /// Floating-point Control Status register\n    pub fcsr: U,\n    /// Floating-point Implementation Register\n    pub fir: U,\n}\n\n/// MIPS DSP registers.\n///\n/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-dsp.xml>\n#[derive(Debug, Default, Clone, Eq, PartialEq)]\npub struct MipsDspRegs<U> {\n    /// High 1 register (regnum 72)\n    pub hi1: U,\n    /// Low 1 register (regnum 73)\n    pub lo1: U,\n    /// High 2 register (regnum 74)\n    pub hi2: U,\n    /// Low 2 register (regnum 75)\n    pub lo2: U,\n    /// High 3 register (regnum 76)\n    pub hi3: U,\n    /// Low 3 register (regnum 77)\n    pub lo3: U,\n    /// DSP Control register (regnum 78)\n    /// Note: This register will always be 32-bit regardless of the target\n    /// <https://sourceware.org/gdb/current/onlinedocs/gdb/MIPS-Features.html#MIPS-Features>\n    pub dspctl: u32,\n    /// Restart register (regnum 79)\n    pub restart: U,\n}\n\n/// MIPS core and DSP registers.\n///\n/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-dsp-linux.xml>\n#[derive(Debug, Default, Clone, Eq, PartialEq)]\npub struct MipsCoreRegsWithDsp<U> {\n    /// Core registers\n    pub core: MipsCoreRegs<U>,\n    /// DSP registers\n    pub dsp: MipsDspRegs<U>,\n}\n\nimpl<U> Registers for MipsCoreRegs<U>\nwhere\n    U: PrimInt + LeBytes + Default + core::fmt::Debug,\n{\n    type ProgramCounter = U;\n\n    fn pc(&self) -> Self::ProgramCounter {\n        self.pc\n    }\n\n    fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {\n        macro_rules! write_le_bytes {\n            ($value:expr) => {\n                let mut buf = [0; 16];\n                // infallible (unless digit is a >128 bit number)\n                let len = $value.to_le_bytes(&mut buf).unwrap();\n                let buf = &buf[..len];\n                for b in buf {\n                    write_byte(Some(*b));\n                }\n            };\n        }\n\n        // Write GPRs\n        for reg in self.r.iter() {\n            write_le_bytes!(reg);\n        }\n\n        // Status register is regnum 32\n        write_le_bytes!(&self.cp0.status);\n\n        // Low and high registers are regnums 33 and 34\n        write_le_bytes!(&self.lo);\n        write_le_bytes!(&self.hi);\n\n        // Badvaddr and Cause registers are regnums 35 and 36\n        write_le_bytes!(&self.cp0.badvaddr);\n        write_le_bytes!(&self.cp0.cause);\n\n        // Program Counter is regnum 37\n        write_le_bytes!(&self.pc);\n\n        // Write FPRs\n        for reg in self.fpu.r.iter() {\n            write_le_bytes!(reg);\n        }\n\n        // Write FCSR and FIR registers\n        write_le_bytes!(&self.fpu.fcsr);\n        write_le_bytes!(&self.fpu.fir);\n    }\n\n    fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {\n        let ptrsize = core::mem::size_of::<U>();\n\n        // Ensure bytes contains enough data for all 72 registers\n        if bytes.len() < ptrsize * 72 {\n            return Err(());\n        }\n\n        // All core registers are the same size\n        let mut regs = bytes\n            .chunks_exact(ptrsize)\n            .map(|c| U::from_le_bytes(c).unwrap());\n\n        // Read GPRs\n        for reg in self.r.iter_mut() {\n            *reg = regs.next().ok_or(())?\n        }\n\n        // Read Status register\n        self.cp0.status = regs.next().ok_or(())?;\n\n        // Read Low and High registers\n        self.lo = regs.next().ok_or(())?;\n        self.hi = regs.next().ok_or(())?;\n\n        // Read Badvaddr and Cause registers\n        self.cp0.badvaddr = regs.next().ok_or(())?;\n        self.cp0.cause = regs.next().ok_or(())?;\n\n        // Read the Program Counter\n        self.pc = regs.next().ok_or(())?;\n\n        // Read FPRs\n        for reg in self.fpu.r.iter_mut() {\n            *reg = regs.next().ok_or(())?\n        }\n\n        // Read FCSR and FIR registers\n        self.fpu.fcsr = regs.next().ok_or(())?;\n        self.fpu.fir = regs.next().ok_or(())?;\n\n        Ok(())\n    }\n}\n\nimpl<U> Registers for MipsCoreRegsWithDsp<U>\nwhere\n    U: PrimInt + LeBytes + Default + core::fmt::Debug,\n{\n    type ProgramCounter = U;\n\n    fn pc(&self) -> Self::ProgramCounter {\n        self.core.pc\n    }\n\n    fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {\n        macro_rules! write_le_bytes {\n            ($value:expr) => {\n                let mut buf = [0; 16];\n                // infallible (unless digit is a >128 bit number)\n                let len = $value.to_le_bytes(&mut buf).unwrap();\n                let buf = &buf[..len];\n                for b in buf {\n                    write_byte(Some(*b));\n                }\n            };\n        }\n\n        // Serialize the core registers first\n        self.core.gdb_serialize(&mut write_byte);\n\n        // Write the DSP registers\n        write_le_bytes!(&self.dsp.hi1);\n        write_le_bytes!(&self.dsp.lo1);\n        write_le_bytes!(&self.dsp.hi2);\n        write_le_bytes!(&self.dsp.lo2);\n        write_le_bytes!(&self.dsp.hi3);\n        write_le_bytes!(&self.dsp.lo3);\n\n        for b in &self.dsp.dspctl.to_le_bytes() {\n            write_byte(Some(*b));\n        }\n\n        write_le_bytes!(&self.dsp.restart);\n    }\n\n    fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {\n        // Deserialize the core registers first\n        self.core.gdb_deserialize(bytes)?;\n\n        // Ensure bytes contains enough data for all 79 registers of target-width\n        // and the dspctl register which is always 4 bytes\n        let ptrsize = core::mem::size_of::<U>();\n        if bytes.len() < (ptrsize * 79) + 4 {\n            return Err(());\n        }\n\n        // Calculate the offsets to the DSP registers based on the ptrsize\n        let dspregs_start = ptrsize * 72;\n        let dspctl_start = ptrsize * 78;\n\n        // Read up until the dspctl register\n        let mut regs = bytes[dspregs_start..dspctl_start]\n            .chunks_exact(ptrsize)\n            .map(|c| U::from_le_bytes(c).unwrap());\n\n        self.dsp.hi1 = regs.next().ok_or(())?;\n        self.dsp.lo1 = regs.next().ok_or(())?;\n        self.dsp.hi2 = regs.next().ok_or(())?;\n        self.dsp.lo2 = regs.next().ok_or(())?;\n        self.dsp.hi3 = regs.next().ok_or(())?;\n        self.dsp.lo3 = regs.next().ok_or(())?;\n\n        // Dspctl will always be a u32\n        self.dsp.dspctl =\n            u32::from_le_bytes(bytes[dspctl_start..dspctl_start + 4].try_into().unwrap());\n\n        // Only 4 or 8 bytes should remain to be read\n        self.dsp.restart = U::from_le_bytes(\n            bytes[dspctl_start + 4..]\n                .chunks_exact(ptrsize)\n                .next()\n                .ok_or(())?,\n        )\n        .unwrap();\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/mips/reg/mod.rs",
    "content": "//! `Register` structs for MIPS architectures.\n\n/// `RegId` definitions for MIPS architectures.\npub mod id;\n\nmod mips;\n\npub use mips::MipsCoreRegs;\npub use mips::MipsCoreRegsWithDsp;\npub use mips::MipsCp0Regs;\npub use mips::MipsFpuRegs;\n"
  },
  {
    "path": "gdbstub_arch/src/msp430/mod.rs",
    "content": "//! Implementations for the TI-MSP430 family of MCUs.\n\nuse gdbstub::arch::Arch;\n\npub mod reg;\n\n/// Implements `Arch` for standard 16-bit TI-MSP430 MCUs.\npub struct Msp430 {}\n\nimpl Arch for Msp430 {\n    type Usize = u16;\n    type Registers = reg::Msp430Regs<u16>;\n    type RegId = reg::id::Msp430RegId<u16>;\n    type BreakpointKind = usize;\n\n    fn target_description_xml() -> Option<&'static str> {\n        Some(r#\"<target version=\"1.0\"><architecture>msp430</architecture></target>\"#)\n    }\n}\n\n/// Implements `Arch` for 20-bit TI-MSP430 MCUs (CPUX).\npub struct Msp430X {}\n\nimpl Arch for Msp430X {\n    type Usize = u32;\n    type Registers = reg::Msp430Regs<u32>;\n    type RegId = reg::id::Msp430RegId<u32>;\n    type BreakpointKind = usize;\n\n    fn target_description_xml() -> Option<&'static str> {\n        Some(r#\"<target version=\"1.0\"><architecture>msp430x</architecture></target>\"#)\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/msp430/reg/id.rs",
    "content": "use core::num::NonZeroUsize;\nuse gdbstub::arch::RegId;\n\n/// TI-MSP430 register identifier.\n///\n/// GDB does not provide a XML file for the MSP430.\n/// The best file to reference is [msp430-tdep.c](https://github.com/bminor/binutils-gdb/blob/master/gdb/msp430-tdep.c).\n#[derive(Debug, Clone, Copy)]\n#[non_exhaustive]\npub enum Msp430RegId<U> {\n    /// Program Counter (R0)\n    Pc,\n    /// Stack Pointer (R1)\n    Sp,\n    /// Status Register (R2)\n    Sr,\n    /// Constant Generator (R3)\n    Cg,\n    /// General Purpose Registers (R4-R15)\n    Gpr(u8),\n    #[doc(hidden)]\n    _Size(core::marker::PhantomData<U>),\n}\n\nfn from_raw_id<U>(id: usize) -> Option<(Msp430RegId<U>, Option<NonZeroUsize>)> {\n    let reg = match id {\n        0 => Msp430RegId::Pc,\n        1 => Msp430RegId::Sp,\n        2 => Msp430RegId::Sr,\n        3 => Msp430RegId::Cg,\n        4..=15 => Msp430RegId::Gpr((id as u8) - 4),\n        _ => return None,\n    };\n\n    let ptrsize = core::mem::size_of::<U>();\n    Some((reg, Some(NonZeroUsize::new(ptrsize)?)))\n}\n\nimpl RegId for Msp430RegId<u16> {\n    fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> {\n        from_raw_id::<u16>(id)\n    }\n}\n\nimpl RegId for Msp430RegId<u32> {\n    fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> {\n        from_raw_id::<u32>(id)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use gdbstub::arch::RegId;\n    use gdbstub::arch::Registers;\n\n    fn test<Rs: Registers, RId: RegId>() {\n        // Obtain the data length written by `gdb_serialize` by passing a custom\n        // closure.\n        let mut serialized_data_len = 0;\n        let counter = |b: Option<u8>| {\n            if b.is_some() {\n                serialized_data_len += 1;\n            }\n        };\n        Rs::default().gdb_serialize(counter);\n\n        // The `Msp430Regs` implementation does not increment the size for\n        // the CG register since it will always be the constant zero.\n        serialized_data_len += RId::from_raw_id(3).unwrap().1.unwrap().get();\n\n        // Accumulate register sizes returned by `from_raw_id`.\n        let mut i = 0;\n        let mut sum_reg_sizes = 0;\n        while let Some((_, size)) = RId::from_raw_id(i) {\n            sum_reg_sizes += size.unwrap().get();\n            i += 1;\n        }\n\n        assert_eq!(serialized_data_len, sum_reg_sizes);\n    }\n\n    #[test]\n    fn test_msp430() {\n        test::<crate::msp430::reg::Msp430Regs<u16>, crate::msp430::reg::id::Msp430RegId<u16>>()\n    }\n\n    #[test]\n    fn test_msp430x() {\n        test::<crate::msp430::reg::Msp430Regs<u32>, crate::msp430::reg::id::Msp430RegId<u32>>()\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/msp430/reg/mod.rs",
    "content": "//! `Register` structs for various TI-MSP430 CPUs.\n\n/// `RegId` definitions for various TI-MSP430 CPUs.\npub mod id;\n\nmod msp430;\n\npub use msp430::Msp430Regs;\n"
  },
  {
    "path": "gdbstub_arch/src/msp430/reg/msp430.rs",
    "content": "use gdbstub::arch::Registers;\nuse gdbstub::internal::LeBytes;\nuse num_traits::PrimInt;\n\n/// TI-MSP430 registers.\n///\n/// The register width is set based on the `<U>` type. For 16-bit MSP430 CPUs\n/// this should be `u16` and for 20-bit MSP430 CPUs (CPUX) this should be `u32`.\n#[derive(Debug, Default, Clone, Eq, PartialEq)]\npub struct Msp430Regs<U> {\n    /// Program Counter (R0)\n    pub pc: U,\n    /// Stack Pointer (R1)\n    pub sp: U,\n    /// Status Register (R2)\n    pub sr: U,\n    /// General Purpose Registers (R4-R15)\n    pub r: [U; 12],\n}\n\nimpl<U> Registers for Msp430Regs<U>\nwhere\n    U: PrimInt + LeBytes + Default + core::fmt::Debug,\n{\n    type ProgramCounter = U;\n\n    fn pc(&self) -> Self::ProgramCounter {\n        self.pc\n    }\n\n    fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {\n        macro_rules! write_le_bytes {\n            ($value:expr) => {\n                let mut buf = [0; 4];\n                // infallible (register size a maximum of 32-bits)\n                let len = $value.to_le_bytes(&mut buf).unwrap();\n                let buf = &buf[..len];\n                for b in buf {\n                    write_byte(Some(*b));\n                }\n            };\n        }\n\n        write_le_bytes!(&self.pc);\n        write_le_bytes!(&self.sp);\n        write_le_bytes!(&self.sr);\n        (0..core::mem::size_of::<U>()).for_each(|_| write_byte(None)); // Constant Generator (CG/R3)\n        for reg in self.r.iter() {\n            write_le_bytes!(reg);\n        }\n    }\n\n    fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {\n        let ptrsize = core::mem::size_of::<U>();\n\n        // Ensure bytes contains enough data for all 16 registers\n        if bytes.len() < ptrsize * 16 {\n            return Err(());\n        }\n\n        let mut regs = bytes\n            .chunks_exact(ptrsize)\n            .map(|c| U::from_le_bytes(c).unwrap());\n\n        self.pc = regs.next().ok_or(())?;\n        self.sp = regs.next().ok_or(())?;\n        self.sr = regs.next().ok_or(())?;\n\n        // Constant Generator (CG/R3) should always be 0\n        if regs.next().ok_or(())? != U::zero() {\n            return Err(());\n        }\n\n        for reg in self.r.iter_mut() {\n            *reg = regs.next().ok_or(())?\n        }\n\n        if regs.next().is_some() {\n            return Err(());\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/ppc/mod.rs",
    "content": "//! Implementations for various PowerPC architectures.\n\nuse gdbstub::arch::Arch;\nuse gdbstub::arch::RegId;\n\npub mod reg;\n\n/// Implements `Arch` for 32-bit PowerPC + AltiVec SIMD.\n///\n/// Check out the [module level docs](gdbstub::arch#whats-with-regidimpl) for\n/// more info about the `RegIdImpl` type parameter.\npub enum PowerPcAltivec32<RegIdImpl: RegId> {\n    #[doc(hidden)]\n    _Marker(core::marker::PhantomData<RegIdImpl>),\n}\n\nimpl<RegIdImpl: RegId> Arch for PowerPcAltivec32<RegIdImpl> {\n    type Usize = u32;\n    type Registers = reg::PowerPcCommonRegs;\n    type RegId = RegIdImpl;\n    type BreakpointKind = usize;\n\n    fn target_description_xml() -> Option<&'static str> {\n        Some(\n            r#\"<target version=\"1.0\"><architecture>powerpc:common</architecture><feature name=\"org.gnu.gdb.power.core\"></feature><feature name=\"org.gnu.gdb.power.fpu\"></feature><feature name=\"org.gnu.gdb.power.altivec\"></feature></target>\"#,\n        )\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/ppc/reg/common.rs",
    "content": "use super::PpcVector;\nuse core::convert::TryInto;\nuse gdbstub::arch::Registers;\n\n/// 32-bit PowerPC core registers, FPU registers, and AltiVec SIMD registers.\n///\n/// Sources:\n/// * <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/rs6000/powerpc-altivec32.xml>\n/// * <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/rs6000/power-core.xml>\n/// * <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/rs6000/power-fpu.xml>\n/// * <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/rs6000/power-altivec.xml>\n#[derive(Debug, Default, Clone, PartialEq)]\npub struct PowerPcCommonRegs {\n    /// General purpose registers\n    pub r: [u32; 32],\n    /// Floating Point registers\n    pub f: [f64; 32],\n    /// Program counter\n    pub pc: u32,\n    /// Machine state\n    pub msr: u32,\n    /// Condition register\n    pub cr: u32,\n    /// Link register\n    pub lr: u32,\n    /// Count register\n    pub ctr: u32,\n    /// Integer exception register\n    pub xer: u32,\n    /// Floating-point status and control register\n    pub fpscr: u32,\n    /// Vector registers\n    pub vr: [PpcVector; 32],\n    /// Vector status and control register\n    pub vscr: u32,\n    /// Vector context save register\n    pub vrsave: u32,\n}\n\nimpl Registers for PowerPcCommonRegs {\n    type ProgramCounter = u32;\n\n    fn pc(&self) -> Self::ProgramCounter {\n        self.pc\n    }\n\n    fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {\n        macro_rules! write_bytes {\n            ($bytes:expr) => {\n                for b in $bytes {\n                    write_byte(Some(*b))\n                }\n            };\n        }\n\n        macro_rules! write_regs {\n            ($($reg:ident),*) => {\n                $(\n                    write_bytes!(&self.$reg.to_be_bytes());\n                )*\n            }\n        }\n\n        for reg in &self.r {\n            write_bytes!(&reg.to_be_bytes());\n        }\n\n        for reg in &self.f {\n            write_bytes!(&reg.to_be_bytes());\n        }\n\n        write_regs!(pc, msr, cr, lr, ctr, xer, fpscr);\n\n        for &reg in &self.vr {\n            let reg: u128 = reg;\n            write_bytes!(&reg.to_be_bytes());\n        }\n\n        write_regs!(vscr, vrsave);\n    }\n\n    fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {\n        if bytes.len() < 0x3a4 {\n            return Err(());\n        }\n\n        let mut regs = bytes[0..0x80]\n            .chunks_exact(4)\n            .map(|x| u32::from_be_bytes(x.try_into().unwrap()));\n\n        for reg in &mut self.r {\n            *reg = regs.next().ok_or(())?;\n        }\n\n        let mut regs = bytes[0x80..0x180]\n            .chunks_exact(8)\n            .map(|x| f64::from_be_bytes(x.try_into().unwrap()));\n\n        for reg in &mut self.f {\n            *reg = regs.next().ok_or(())?;\n        }\n\n        macro_rules! parse_regs {\n            ($start:literal..$end:literal, $($reg:ident),*) => {\n                let mut regs = bytes[$start..$end]\n                    .chunks_exact(4)\n                    .map(|x| u32::from_be_bytes(x.try_into().unwrap()));\n                $(\n                    self.$reg = regs.next().ok_or(())?;\n                )*\n            }\n        }\n\n        parse_regs!(0x180..0x19c, pc, msr, cr, lr, ctr, xer, fpscr);\n\n        let mut regs = bytes[0x19c..0x39c]\n            .chunks_exact(0x10)\n            .map(|x| u128::from_be_bytes(x.try_into().unwrap()));\n\n        for reg in &mut self.vr {\n            *reg = regs.next().ok_or(())?;\n        }\n\n        parse_regs!(0x39c..0x3a4, vscr, vrsave);\n\n        Ok(())\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn ppc_core_round_trip() {\n        let regs_before = PowerPcCommonRegs {\n            r: [1; 32],\n            pc: 2,\n            msr: 3,\n            cr: 4,\n            lr: 5,\n            ctr: 6,\n            xer: 7,\n            fpscr: 8,\n            f: [9.0; 32],\n            vr: [52; 32],\n            vrsave: 10,\n            vscr: 11,\n        };\n\n        let mut data = vec![];\n\n        regs_before.gdb_serialize(|x| {\n            data.push(x.unwrap_or(b'x'));\n        });\n\n        assert_eq!(data.len(), 0x3a4);\n\n        let mut regs_after = PowerPcCommonRegs::default();\n        regs_after.gdb_deserialize(&data).unwrap();\n\n        assert_eq!(regs_before, regs_after);\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/ppc/reg/id.rs",
    "content": "// TODO: Add proper `RegId` implementation. See [issue #29](https://github.com/daniel5151/gdbstub/issues/29)\n// pub enum PowerPc32RegId {}\n"
  },
  {
    "path": "gdbstub_arch/src/ppc/reg/mod.rs",
    "content": "//! `Register` structs for PowerPC architectures\n\n/// `RegId` definitions for PowerPC architectures.\npub mod id;\n\nmod common;\n\npub use common::PowerPcCommonRegs;\ntype PpcVector = u128;\n"
  },
  {
    "path": "gdbstub_arch/src/riscv/mod.rs",
    "content": "//! Implementations for the [RISC-V](https://riscv.org/) architecture.\n//!\n//! *Note*: currently only supports integer versions of the ISA.\n\nuse gdbstub::arch::Arch;\n\npub mod reg;\n\n/// Implements `Arch` for 32-bit RISC-V.\npub enum Riscv32 {}\n\n/// Implements `Arch` for 64-bit RISC-V.\npub enum Riscv64 {}\n\nimpl Arch for Riscv32 {\n    type Usize = u32;\n    type Registers = reg::RiscvCoreRegs<u32>;\n    type BreakpointKind = usize;\n    type RegId = reg::id::RiscvRegId<u32>;\n\n    fn target_description_xml() -> Option<&'static str> {\n        Some(include_str!(\"rv32i.xml\"))\n    }\n}\n\nimpl Arch for Riscv64 {\n    type Usize = u64;\n    type Registers = reg::RiscvCoreRegs<u64>;\n    type BreakpointKind = usize;\n    type RegId = reg::id::RiscvRegId<u64>;\n\n    fn target_description_xml() -> Option<&'static str> {\n        Some(include_str!(\"rv64i.xml\"))\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/riscv/reg/id.rs",
    "content": "use core::num::NonZeroUsize;\nuse gdbstub::arch::RegId;\n\n/// RISC-V Register identifier.\n#[derive(Debug, Clone, Copy)]\n#[non_exhaustive]\npub enum RiscvRegId<U> {\n    /// General Purpose Register (x0-x31).\n    Gpr(u8),\n    /// Floating Point Register (f0-f31).\n    Fpr(u8),\n    /// Program Counter.\n    Pc,\n    /// Control and Status Register.\n    Csr(u16),\n    /// Privilege level.\n    Priv,\n\n    #[doc(hidden)]\n    _Marker(core::marker::PhantomData<U>),\n}\n\nmacro_rules! impl_riscv_reg_id {\n    ($usize:ty) => {\n        impl RegId for RiscvRegId<$usize> {\n            fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> {\n                const USIZE: usize = core::mem::size_of::<$usize>();\n\n                let (id, size) = match id {\n                    0..=31 => (Self::Gpr(id as u8), USIZE),\n                    32 => (Self::Pc, USIZE),\n                    33..=64 => (Self::Fpr((id - 33) as u8), USIZE),\n                    65..=4160 => (Self::Csr((id - 65) as u16), USIZE),\n                    4161 => (Self::Priv, 1),\n                    _ => return None,\n                };\n\n                Some((id, Some(NonZeroUsize::new(size)?)))\n            }\n        }\n    };\n}\n\nimpl_riscv_reg_id!(u32);\nimpl_riscv_reg_id!(u64);\n"
  },
  {
    "path": "gdbstub_arch/src/riscv/reg/mod.rs",
    "content": "//! `Register` structs for RISC-V architectures.\n\n/// `RegId` definitions for RISC-V architectures.\npub mod id;\n\nmod riscv;\n\npub use riscv::RiscvCoreRegs;\n"
  },
  {
    "path": "gdbstub_arch/src/riscv/reg/riscv.rs",
    "content": "use gdbstub::arch::Registers;\nuse gdbstub::internal::LeBytes;\nuse num_traits::PrimInt;\n\n/// RISC-V Integer registers.\n///\n/// The register width is set to `u32` or `u64` based on the `<U>` type.\n///\n/// Useful links:\n/// * [GNU binutils-gdb XML descriptions](https://github.com/bminor/binutils-gdb/blob/master/gdb/features/riscv)\n/// * [riscv-tdep.h](https://github.com/bminor/binutils-gdb/blob/master/gdb/riscv-tdep.h)\n#[derive(Debug, Default, Clone, PartialEq, Eq)]\npub struct RiscvCoreRegs<U> {\n    /// General purpose registers (x0-x31)\n    pub x: [U; 32],\n    /// Program counter\n    pub pc: U,\n}\n\nimpl<U> Registers for RiscvCoreRegs<U>\nwhere\n    U: PrimInt + LeBytes + Default + core::fmt::Debug,\n{\n    type ProgramCounter = U;\n\n    fn pc(&self) -> Self::ProgramCounter {\n        self.pc\n    }\n\n    fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {\n        macro_rules! write_le_bytes {\n            ($value:expr) => {\n                let mut buf = [0; 16];\n                // infallible (unless digit is a >128 bit number)\n                let len = $value.to_le_bytes(&mut buf).unwrap();\n                let buf = &buf[..len];\n                for b in buf {\n                    write_byte(Some(*b));\n                }\n            };\n        }\n\n        // Write GPRs\n        for reg in self.x.iter() {\n            write_le_bytes!(reg);\n        }\n\n        // Program Counter is regnum 33\n        write_le_bytes!(&self.pc);\n    }\n\n    fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {\n        let ptrsize = core::mem::size_of::<U>();\n\n        // ensure bytes.chunks_exact(ptrsize) won't panic\n        if !bytes.len().is_multiple_of(ptrsize) {\n            return Err(());\n        }\n\n        let mut regs = bytes\n            .chunks_exact(ptrsize)\n            .map(|c| U::from_le_bytes(c).unwrap());\n\n        // Read GPRs\n        for reg in self.x.iter_mut() {\n            *reg = regs.next().ok_or(())?\n        }\n        self.pc = regs.next().ok_or(())?;\n\n        if regs.next().is_some() {\n            return Err(());\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/riscv/rv32i.xml",
    "content": "<?xml version=\"1.0\"?>\n<!-- Copyright (C) 2018-2024 Free Software Foundation, Inc.\n\n     Copying and distribution of this file, with or without modification,\n     are permitted in any medium without royalty provided the copyright\n     notice and this notice are preserved.  -->\n\n<!-- Register numbers are hard-coded in order to maintain backward\n     compatibility with older versions of tools that didn't use xml\n     register descriptions.  -->\n\n<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">\n<feature name=\"org.gnu.gdb.riscv.cpu\">\n  <reg name=\"zero\" bitsize=\"32\" type=\"int\" regnum=\"0\"/>\n  <reg name=\"ra\" bitsize=\"32\" type=\"code_ptr\"/>\n  <reg name=\"sp\" bitsize=\"32\" type=\"data_ptr\"/>\n  <reg name=\"gp\" bitsize=\"32\" type=\"data_ptr\"/>\n  <reg name=\"tp\" bitsize=\"32\" type=\"data_ptr\"/>\n  <reg name=\"t0\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"t1\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"t2\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"fp\" bitsize=\"32\" type=\"data_ptr\"/>\n  <reg name=\"s1\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"a0\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"a1\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"a2\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"a3\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"a4\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"a5\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"a6\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"a7\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"s2\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"s3\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"s4\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"s5\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"s6\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"s7\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"s8\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"s9\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"s10\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"s11\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"t3\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"t4\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"t5\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"t6\" bitsize=\"32\" type=\"int\"/>\n  <reg name=\"pc\" bitsize=\"32\" type=\"code_ptr\"/>\n</feature>\n"
  },
  {
    "path": "gdbstub_arch/src/riscv/rv64i.xml",
    "content": "<?xml version=\"1.0\"?>\n<!-- Copyright (C) 2018-2024 Free Software Foundation, Inc.\n\n     Copying and distribution of this file, with or without modification,\n     are permitted in any medium without royalty provided the copyright\n     notice and this notice are preserved.  -->\n\n<!-- Register numbers are hard-coded in order to maintain backward\n     compatibility with older versions of tools that didn't use xml\n     register descriptions.  -->\n\n<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">\n<feature name=\"org.gnu.gdb.riscv.cpu\">\n  <reg name=\"zero\" bitsize=\"64\" type=\"int\" regnum=\"0\"/>\n  <reg name=\"ra\" bitsize=\"64\" type=\"code_ptr\"/>\n  <reg name=\"sp\" bitsize=\"64\" type=\"data_ptr\"/>\n  <reg name=\"gp\" bitsize=\"64\" type=\"data_ptr\"/>\n  <reg name=\"tp\" bitsize=\"64\" type=\"data_ptr\"/>\n  <reg name=\"t0\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"t1\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"t2\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"fp\" bitsize=\"64\" type=\"data_ptr\"/>\n  <reg name=\"s1\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"a0\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"a1\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"a2\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"a3\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"a4\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"a5\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"a6\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"a7\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"s2\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"s3\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"s4\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"s5\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"s6\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"s7\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"s8\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"s9\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"s10\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"s11\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"t3\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"t4\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"t5\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"t6\" bitsize=\"64\" type=\"int\"/>\n  <reg name=\"pc\" bitsize=\"64\" type=\"code_ptr\"/>\n</feature>\n"
  },
  {
    "path": "gdbstub_arch/src/wasm/addr.rs",
    "content": "//! Synthetic 64-bit Wasm address space expected by the LLDB Wasm extensions.\n//!\n//! WebAssembly is natively *multi-memory* and *multi-address-space*:\n//!\n//! - It supports zero or more \"linear memories\", and they have no canonical\n//!   mapping into a single global address space for pointers; rather, each load\n//!   and store instruction names which memory it accesses statically.\n//! - It supports one or more \"modules\" containing first-class functions, and\n//!   they have no canonical mapping into a single global code space; rather,\n//!   control flow is structured, and calls between functions in different\n//!   modules only occur via explicit strongly-typed function imports and\n//!   exports.\n//!\n//! Wasm implementations typically represent these concepts directly rather than\n//! attempt to map to a more conventional ISA model of a single flat address\n//! space with machine code and data. However, the GDB RSP assumes the latter:\n//! all of its commands, such as memory reads/writes, breakpoint updates, and\n//! the like, use integers as pointers in a single address space.\n//!\n//! The LLDB Wasm extensions to the GDB RSP thus define a canonical mapping\n//! between the multi-address-space world and a flat 64-bit address space for\n//! the purposes of the protocol only. Note that this is 64-bit even when Wasm\n//! natively has 32-bit memory offsets (the \"wasm32\" architecture), because the\n//! definition adds additional information above the 32-bit offset.\n//!\n//! The [ProcessWasm.h] header file in the LLDB source contains definitions that\n//! are as close to documentation as we can find: see the `WasmAddressType` and\n//! `wasm_addr_t` definitions.\n//!\n//! An address consists of three parts:\n//!\n//! - The type: code or data. Wasm has separate \"address spaces\" for these, so\n//!   they are mapped to different regions of the 64-bit synthetic space.\\*\n//!\n//! - The module/memory index. The engine decides an arbitrary index ordering\n//!   for all of the Wasm modules and Wasm linear memories present in a given\n//!   execution.\n//!\n//! - The offset within that Wasm module bytecode or linear memory.\n//!\n//! \\*Note that this implies that the original bytecode (the full image of the\n//! Wasm module, starting with its magic number) is present in this synthetic\n//! address space. An engine that implements debugging for Wasm should keep\n//! around the original bytecode, even if it does ahead-of-time compilation or\n//! other processing, so that the debugger can use it: LLDB will read the\n//! module bytecode from the synthetic address space, including its debug\n//! sections, rather than find the image elsewhere.\n//!\n//! [ProcessWasm.h]:\n//!     https://github.com/llvm/llvm-project/blob/074653a/lldb/source/Plugins/Process/wasm/ProcessWasm.h\n\n/// The type of an address in the synthetic address space used by the\n/// Wasm target.\n#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]\npub enum WasmAddrType {\n    /// Address in a 32-bit linear memory.\n    Memory,\n    /// Address in a `.wasm` module image.\n    ///\n    /// Used both for memory-read commands to fetch the Wasm binary\n    /// from the gdbstub host, and software-breakpoint commands.\n    Object,\n}\n\n/// An address in the synthetic address space used by the Wasm target.\n#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]\npub struct WasmAddr(u64);\n\nimpl WasmAddr {\n    const TYPE_BITS: u32 = 2;\n    const MODULE_BITS: u32 = 30;\n    const OFFSET_BITS: u32 = 32;\n\n    const MODULE_SHIFT: u32 = Self::OFFSET_BITS;\n    const TYPE_SHIFT: u32 = Self::OFFSET_BITS + Self::MODULE_BITS;\n\n    const TYPE_MASK: u64 = (1u64 << Self::TYPE_BITS) - 1;\n    const MODULE_MASK: u64 = (1u64 << Self::MODULE_BITS) - 1;\n    const OFFSET_MASK: u64 = (1u64 << Self::OFFSET_BITS) - 1;\n\n    /// Construct a `WasmAddr` from a raw 64-bit encoded address.\n    ///\n    /// Returns `None` if the encoding is invalid.\n    pub fn from_raw(raw: u64) -> Option<Self> {\n        let type_bits = (raw >> Self::TYPE_SHIFT) & Self::TYPE_MASK;\n        if type_bits > 1 {\n            return None;\n        }\n        Some(WasmAddr(raw))\n    }\n\n    /// Provide the raw 64-bit encoding of this `WasmAddr`.\n    pub fn as_raw(self) -> u64 {\n        self.0\n    }\n\n    /// Construct a `WasmAddr` from its constituent parts.\n    ///\n    /// Returns `None` if the `module_index` is out-of-range: it only supports\n    /// up to 2^30 modules.\n    pub fn new(addr_type: WasmAddrType, module_index: u32, offset: u32) -> Option<Self> {\n        // There are fewer than 32 bits in the encoding for the module\n        // index.\n        if module_index >> Self::MODULE_BITS != 0 {\n            return None;\n        }\n        let type_bits: u64 = match addr_type {\n            WasmAddrType::Memory => 0,\n            WasmAddrType::Object => 1,\n        };\n        Some(WasmAddr(\n            (type_bits << Self::TYPE_SHIFT)\n                | ((u64::from(module_index)) << Self::MODULE_SHIFT)\n                | (u64::from(offset)),\n        ))\n    }\n\n    /// Get the type of this address.\n    pub fn addr_type(self) -> WasmAddrType {\n        match (self.0 >> Self::TYPE_SHIFT) & Self::TYPE_MASK {\n            0 => WasmAddrType::Memory,\n            1 => WasmAddrType::Object,\n            // We never set other type-bits and the raw bits are fully\n            // encapsulated and checked in `from_raw`, so this is\n            // unreachable in practice and should never panic.\n            // We silence clippy's warning about this.\n            #[allow(clippy::unreachable)]\n            _ => unreachable!(),\n        }\n    }\n\n    /// Get the index of the module or memory referenced by this\n    /// address.\n    pub fn module_index(self) -> u32 {\n        ((self.0 >> Self::MODULE_SHIFT) & Self::MODULE_MASK) as u32\n    }\n\n    /// Get the offset within the module or memory referenced by this\n    /// address.\n    pub fn offset(self) -> u32 {\n        (self.0 & Self::OFFSET_MASK) as u32\n    }\n}\n\nimpl core::fmt::Display for WasmAddr {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        let type_str = match self.addr_type() {\n            WasmAddrType::Memory => \"Memory\",\n            WasmAddrType::Object => \"Object\",\n        };\n        write!(\n            f,\n            \"{}(module={}, offset={:#x})\",\n            type_str,\n            self.module_index(),\n            self.offset()\n        )\n    }\n}\n\nimpl core::fmt::Debug for WasmAddr {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        write!(f, \"WasmAddr({self})\")\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/wasm/mod.rs",
    "content": "//! Implementation for the WebAssembly architecture.\n//!\n//! This implementation follows the [LLDB-specific Wasm extensions] to the GDB\n//! RSP, which define a mapping from Wasm concepts to more classical ISA\n//! concepts.\n//!\n//! WebAssembly is somewhat *unlike* most ISAs in many of its details: for\n//! example, it uses an operand stack rather than classical registers, and has\n//! explicit concepts of function locals, of globals, and of first-class\n//! functions and a callstack, rather than a flat address space of bytes that\n//! are used to build up machine code, a stack, and storage as in most other\n//! ISAs.\n//!\n//! As such - you'll need to implement the [`Wasm`] extension trait in your\n//! `Target` implementation in order to provide LLDB access to these Wasm-native\n//! concepts.\n//!\n//! As a particularly important detail, note that the natively\n//! multi-address-space Wasm world, where multiple code modules exist without a\n//! native concept of a global PC space, and multiple linear memories exist with\n//! every load/store qualified by the memory it accesses, is mapped into a\n//! single synthesized 64-bit address space by definition of the protocol\n//! extensions. See the [`self::addr`] submodule for utilities to encode and\n//! decode these synthesized addresses.\n//!\n//! To use `gdbstub` with the LLDB Wasm GDB RSP extensions:\n//!\n//! 1. Implement the `Target` trait and the [`Wasm`], [`HostInfo`] and\n//!    [`ProcessInfo`] traits on the target implementation for your Wasm\n//!    execution engine/target.\n//! 2. Make use of this `Arch` implementation in your target.\n//! 3. Make use of the [`report_stop_with_regs`] API to report the Wasm PC with\n//!    every stop packet.\n//!    - _Note_: It seems likely that this requirement stems from a LLDB bug, as\n//!      \"expedited registers\" are not typically mandated by the GDB RSP, and\n//!      generally serve as an optional optimization to reduce roundtrips.\n//! 4. Ensure that you have a build of LLDB with the Wasm target enabled. (A\n//!    binary distribution of LLDB with your operating system may not have this,\n//!    but a build from LLVM source will, by default. Once a release of\n//!    [`wasi-sdk`] with [this PR] is made, `wasi-sdk` will distribute such a\n//!    build for all major platforms.)\n//! 5. Start up LLDB and attach it to an endpoint served by `gdbstub` with this\n//!    target:\n//!\n//!    ```text\n//!    $ .../bin/lldb\n//!    (lldb) process connect --plugin wasm connect://localhost:1234\n//!    ```\n//!\n//!    then ordinary debugging with breakpoints, step/continue, and state\n//!    examination should work.\n//!\n//! See [Wasmtime] for an example of the use of this crate.\n//!\n//! [LLDB-specific Wasm extensions]:\n//!     https://lldb.llvm.org/resources/lldbgdbremote.html#wasm-packets\n//! [`Wasm`]: gdbstub::target::ext::wasm::Wasm\n//! [`HostInfo`]: gdbstub::target::ext::host_info::HostInfo\n//! [`ProcessInfo`]: gdbstub::target::ext::process_info::ProcessInfo\n//! [`report_stop_with_regs`]:\n//!     gdbstub::stub::state_machine::GdbStubStateMachineInner::report_stop_with_regs\n//! [`wasi-sdk`]: https://github.com/WebAssembly/wasi-sdk\n//! [this PR]: https://github.com/WebAssembly/wasi-sdk/pull/596\n//! [Wasmtime]: https://github.com/bytecodealliance/wasmtime\n\nuse gdbstub::arch::Arch;\n\npub mod addr;\npub mod reg;\n\n/// Implements `Arch` for the WebAssembly architecture.\npub enum Wasm {}\n\nimpl Arch for Wasm {\n    /// Even though Wasm is nominally a 32-bit platform, LLDB's GDB RSP\n    /// extensions for Wasm uses a 64-bit address word to multiplex module\n    /// bytecode regions and linear memory regions into a single address space.\n    type Usize = u64;\n    type Registers = reg::WasmRegisters;\n    type RegId = reg::id::WasmRegId;\n    type BreakpointKind = usize;\n}\n"
  },
  {
    "path": "gdbstub_arch/src/wasm/reg/id.rs",
    "content": "use core::num::NonZeroUsize;\nuse gdbstub::arch::RegId;\n\n/// The only register exposed to GDB: `pc` (register index 0).\n#[derive(Debug, Clone, Copy)]\n#[non_exhaustive]\npub enum WasmRegId {\n    /// Program Counter.\n    Pc,\n}\n\nimpl RegId for WasmRegId {\n    fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> {\n        match id {\n            0 => Some((WasmRegId::Pc, NonZeroUsize::new(8))),\n            _ => None,\n        }\n    }\n\n    fn to_raw_id(&self) -> Option<usize> {\n        match self {\n            WasmRegId::Pc => Some(0),\n        }\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/wasm/reg/mod.rs",
    "content": "//! `Register` structs for the WebAssembly architecture.\n//!\n//! Because Wasm is mostly stack-based, it only has one \"register\":\n//! the program counter (PC) according to the gdbstub mappings for\n//! this architecture.\n\n/// `RegId` definitions for WebAssembly.\npub mod id;\n\nmod wasm_regs;\n\npub use wasm_regs::WasmRegisters;\n"
  },
  {
    "path": "gdbstub_arch/src/wasm/reg/wasm_regs.rs",
    "content": "use core::convert::TryInto;\nuse gdbstub::arch::Registers;\n\n/// The register state for WebAssembly.\n#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]\npub struct WasmRegisters {\n    /// Program Counter. See [`crate::wasm::addr`] for the 64-bit\n    /// synthetic address space in which this PC exists.\n    pub pc: u64,\n}\n\nimpl Registers for WasmRegisters {\n    type ProgramCounter = u64;\n\n    fn pc(&self) -> u64 {\n        self.pc\n    }\n\n    fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {\n        for byte in self.pc.to_le_bytes() {\n            write_byte(Some(byte));\n        }\n    }\n\n    fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {\n        if bytes.len() < 8 {\n            return Err(());\n        }\n        self.pc = u64::from_le_bytes(bytes[..8].try_into().unwrap());\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/x86/mod.rs",
    "content": "//! Implementations for various x86 architectures.\n\nuse gdbstub::arch::Arch;\n\npub mod reg;\n\n/// Implements `Arch` for 64-bit x86 + SSE Extensions.\n#[allow(non_camel_case_types, clippy::upper_case_acronyms)]\npub enum X86_64_SSE {}\n\nimpl Arch for X86_64_SSE {\n    type Usize = u64;\n    type Registers = reg::X86_64CoreRegs;\n    type RegId = reg::id::X86_64CoreRegId;\n    type BreakpointKind = usize;\n\n    fn target_description_xml() -> Option<&'static str> {\n        Some(\n            r#\"<target version=\"1.0\"><architecture>i386:x86-64</architecture><feature name=\"org.gnu.gdb.i386.sse\"></feature></target>\"#,\n        )\n    }\n}\n\n/// Implements `Arch` for 32-bit x86 + SSE Extensions.\n#[allow(non_camel_case_types, clippy::upper_case_acronyms)]\npub enum X86_SSE {}\n\nimpl Arch for X86_SSE {\n    type Usize = u32;\n    type Registers = reg::X86CoreRegs;\n    type RegId = reg::id::X86CoreRegId;\n    type BreakpointKind = usize;\n\n    fn target_description_xml() -> Option<&'static str> {\n        Some(\n            r#\"<target version=\"1.0\"><architecture>i386:intel</architecture><feature name=\"org.gnu.gdb.i386.sse\"></feature></target>\"#,\n        )\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/x86/reg/core32.rs",
    "content": "use super::X86SegmentRegs;\nuse super::X87FpuInternalRegs;\nuse super::F80;\nuse core::convert::TryInto;\nuse gdbstub::arch::Registers;\n\n/// 32-bit x86 core registers (+ SSE extensions).\n///\n/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/32bit-core.xml>\n/// Additionally: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/32bit-sse.xml>\n#[derive(Debug, Default, Clone, PartialEq, Eq)]\npub struct X86CoreRegs {\n    /// Accumulator\n    pub eax: u32,\n    /// Count register\n    pub ecx: u32,\n    /// Data register\n    pub edx: u32,\n    /// Base register\n    pub ebx: u32,\n    /// Stack pointer\n    pub esp: u32,\n    /// Base pointer\n    pub ebp: u32,\n    /// Source index\n    pub esi: u32,\n    /// Destination index\n    pub edi: u32,\n    /// Instruction pointer\n    pub eip: u32,\n    /// Status register\n    pub eflags: u32,\n    /// Segment registers: CS, SS, DS, ES, FS, GS\n    pub segments: X86SegmentRegs,\n    /// FPU registers: ST0 through ST7\n    pub st: [F80; 8],\n    /// FPU internal registers\n    pub fpu: X87FpuInternalRegs,\n    /// SIMD Registers: XMM0 through XMM7\n    pub xmm: [u128; 8],\n    /// SSE Status/Control Register\n    pub mxcsr: u32,\n}\n\nimpl Registers for X86CoreRegs {\n    type ProgramCounter = u32;\n\n    fn pc(&self) -> Self::ProgramCounter {\n        self.eip\n    }\n\n    fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {\n        macro_rules! write_bytes {\n            ($bytes:expr) => {\n                for b in $bytes {\n                    write_byte(Some(*b))\n                }\n            };\n        }\n\n        macro_rules! write_regs {\n            ($($reg:ident),*) => {\n                $(\n                    write_bytes!(&self.$reg.to_le_bytes());\n                )*\n            }\n        }\n\n        write_regs!(eax, ecx, edx, ebx, esp, ebp, esi, edi, eip, eflags);\n\n        self.segments.gdb_serialize(&mut write_byte);\n\n        // st0 to st7\n        for st_reg in &self.st {\n            write_bytes!(st_reg);\n        }\n\n        self.fpu.gdb_serialize(&mut write_byte);\n\n        // xmm0 to xmm15\n        for xmm_reg in &self.xmm {\n            write_bytes!(&xmm_reg.to_le_bytes());\n        }\n\n        // mxcsr\n        write_bytes!(&self.mxcsr.to_le_bytes());\n    }\n\n    fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {\n        if bytes.len() < 0x134 {\n            return Err(());\n        }\n\n        macro_rules! parse_regs {\n            ($($reg:ident),*) => {\n                let mut regs = bytes[0..0x28]\n                    .chunks_exact(4)\n                    .map(|x| u32::from_le_bytes(x.try_into().unwrap()));\n                $(\n                    self.$reg = regs.next().ok_or(())?;\n                )*\n            }\n        }\n\n        parse_regs!(eax, ecx, edx, ebx, esp, ebp, esi, edi, eip, eflags);\n\n        self.segments.gdb_deserialize(&bytes[0x28..0x40])?;\n\n        let mut regs = bytes[0x40..0x90].chunks_exact(10).map(TryInto::try_into);\n\n        for reg in self.st.iter_mut() {\n            *reg = regs.next().ok_or(())?.map_err(|_| ())?;\n        }\n\n        self.fpu.gdb_deserialize(&bytes[0x90..0xb0])?;\n\n        let mut regs = bytes[0xb0..0x130]\n            .chunks_exact(0x10)\n            .map(|x| u128::from_le_bytes(x.try_into().unwrap()));\n\n        for reg in self.xmm.iter_mut() {\n            *reg = regs.next().ok_or(())?;\n        }\n\n        self.mxcsr = u32::from_le_bytes(bytes[0x130..0x134].try_into().unwrap());\n\n        Ok(())\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn x86_core_round_trip() {\n        let regs_before = X86CoreRegs {\n            eax: 1,\n            ecx: 2,\n            edx: 3,\n            ebx: 4,\n            esp: 5,\n            ebp: 6,\n            esi: 7,\n            edi: 8,\n            eip: 9,\n            eflags: 10,\n            segments: X86SegmentRegs {\n                cs: 11,\n                ss: 12,\n                ds: 13,\n                es: 14,\n                fs: 15,\n                gs: 16,\n            },\n            st: Default::default(),\n            fpu: X87FpuInternalRegs {\n                fctrl: 17,\n                fstat: 18,\n                ftag: 19,\n                fiseg: 20,\n                fioff: 21,\n                foseg: 22,\n                fooff: 23,\n                fop: 24,\n            },\n            xmm: Default::default(),\n            mxcsr: 99,\n        };\n\n        let mut data = vec![];\n\n        regs_before.gdb_serialize(|x| {\n            data.push(x.unwrap_or(b'x'));\n        });\n\n        let mut regs_after = X86CoreRegs::default();\n        regs_after.gdb_deserialize(&data).unwrap();\n\n        assert_eq!(regs_before, regs_after);\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/x86/reg/core64.rs",
    "content": "use super::X86SegmentRegs;\nuse super::X87FpuInternalRegs;\nuse super::F80;\nuse core::convert::TryInto;\nuse gdbstub::arch::Registers;\n\n/// 64-bit x86 core registers (+ SSE extensions).\n///\n/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-core.xml>\n/// Additionally: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-sse.xml>\n#[derive(Debug, Default, Clone, PartialEq, Eq)]\npub struct X86_64CoreRegs {\n    /// RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, r8-r15\n    pub regs: [u64; 16],\n    /// Status register\n    pub eflags: u32,\n    /// Instruction pointer\n    pub rip: u64,\n    /// Segment registers: CS, SS, DS, ES, FS, GS\n    pub segments: X86SegmentRegs,\n    /// FPU registers: ST0 through ST7\n    pub st: [F80; 8],\n    /// FPU internal registers\n    pub fpu: X87FpuInternalRegs,\n    /// SIMD Registers: XMM0 through XMM15\n    pub xmm: [u128; 0x10],\n    /// SSE Status/Control Register\n    pub mxcsr: u32,\n}\n\nimpl Registers for X86_64CoreRegs {\n    type ProgramCounter = u64;\n\n    fn pc(&self) -> Self::ProgramCounter {\n        self.rip\n    }\n\n    fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {\n        macro_rules! write_bytes {\n            ($bytes:expr) => {\n                for b in $bytes {\n                    write_byte(Some(*b))\n                }\n            };\n        }\n\n        // rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp, r8-r15\n        for reg in &self.regs {\n            write_bytes!(&reg.to_le_bytes());\n        }\n\n        // rip\n        write_bytes!(&self.rip.to_le_bytes());\n\n        // eflags\n        write_bytes!(&self.eflags.to_le_bytes());\n\n        self.segments.gdb_serialize(&mut write_byte);\n\n        // st0 to st7\n        for st_reg in &self.st {\n            write_bytes!(st_reg);\n        }\n\n        self.fpu.gdb_serialize(&mut write_byte);\n\n        // xmm0 to xmm15\n        for xmm_reg in &self.xmm {\n            write_bytes!(&xmm_reg.to_le_bytes());\n        }\n\n        // mxcsr\n        write_bytes!(&self.mxcsr.to_le_bytes());\n    }\n\n    fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {\n        if bytes.len() < 0x218 {\n            return Err(());\n        }\n\n        let mut regs = bytes[0..0x80]\n            .chunks_exact(8)\n            .map(|x| u64::from_le_bytes(x.try_into().unwrap()));\n\n        for reg in self.regs.iter_mut() {\n            *reg = regs.next().ok_or(())?;\n        }\n\n        self.rip = u64::from_le_bytes(bytes[0x80..0x88].try_into().unwrap());\n        self.eflags = u32::from_le_bytes(bytes[0x88..0x8C].try_into().unwrap());\n\n        self.segments.gdb_deserialize(&bytes[0x8C..0xA4])?;\n\n        let mut regs = bytes[0xA4..0xF4].chunks_exact(10).map(TryInto::try_into);\n\n        for reg in self.st.iter_mut() {\n            *reg = regs.next().ok_or(())?.map_err(|_| ())?;\n        }\n\n        self.fpu.gdb_deserialize(&bytes[0xF4..0x114])?;\n\n        let mut regs = bytes[0x114..0x214]\n            .chunks_exact(0x10)\n            .map(|x| u128::from_le_bytes(x.try_into().unwrap()));\n\n        for reg in self.xmm.iter_mut() {\n            *reg = regs.next().ok_or(())?;\n        }\n\n        self.mxcsr = u32::from_le_bytes(bytes[0x214..0x218].try_into().unwrap());\n\n        Ok(())\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn x86_64_core_round_trip() {\n        let regs_before = X86_64CoreRegs {\n            regs: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],\n            eflags: 17,\n            rip: 18,\n            segments: X86SegmentRegs {\n                cs: 19,\n                ss: 20,\n                ds: 21,\n                es: 22,\n                fs: 23,\n                gs: 24,\n            },\n            st: Default::default(),\n            fpu: X87FpuInternalRegs {\n                fctrl: 25,\n                fstat: 26,\n                ftag: 27,\n                fiseg: 28,\n                fioff: 29,\n                foseg: 30,\n                fooff: 31,\n                fop: 32,\n            },\n            xmm: Default::default(),\n            mxcsr: 99,\n        };\n\n        let mut data = vec![];\n\n        regs_before.gdb_serialize(|x| {\n            data.push(x.unwrap_or(b'x'));\n        });\n\n        let mut regs_after = X86_64CoreRegs::default();\n        regs_after.gdb_deserialize(&data).unwrap();\n\n        assert_eq!(regs_before, regs_after);\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/x86/reg/id.rs",
    "content": "use core::num::NonZeroUsize;\nuse gdbstub::arch::RegId;\n\n/// FPU register identifier.\n#[derive(Debug, Clone, Copy)]\npub enum X87FpuInternalRegId {\n    /// Floating-point control register\n    Fctrl,\n    /// Floating-point status register\n    Fstat,\n    /// Tag word\n    Ftag,\n    /// FPU instruction pointer segment\n    Fiseg,\n    /// FPU instruction pointer offset\n    Fioff,\n    /// FPU operand segment\n    Foseg,\n    /// FPU operand offset\n    Fooff,\n    /// Floating-point opcode\n    Fop,\n}\n\nimpl X87FpuInternalRegId {\n    fn from_u8(val: u8) -> Option<Self> {\n        use self::X87FpuInternalRegId::*;\n\n        let r = match val {\n            0 => Fctrl,\n            1 => Fstat,\n            2 => Ftag,\n            3 => Fiseg,\n            4 => Fioff,\n            5 => Foseg,\n            6 => Fooff,\n            7 => Fop,\n            _ => return None,\n        };\n        Some(r)\n    }\n}\n\n/// Segment register identifier.\n#[derive(Debug, Clone, Copy)]\n#[allow(clippy::upper_case_acronyms)]\npub enum X86SegmentRegId {\n    /// Code Segment\n    CS,\n    /// Stack Segment\n    SS,\n    /// Data Segment\n    DS,\n    /// Extra Segment\n    ES,\n    /// General Purpose Segment\n    FS,\n    /// General Purpose Segment\n    GS,\n}\n\nimpl X86SegmentRegId {\n    fn from_u8(val: u8) -> Option<Self> {\n        use self::X86SegmentRegId::*;\n\n        let r = match val {\n            0 => CS,\n            1 => SS,\n            2 => DS,\n            3 => ES,\n            4 => FS,\n            5 => GS,\n            _ => return None,\n        };\n        Some(r)\n    }\n}\n\n/// 32-bit x86 core + SSE register identifier.\n///\n/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/32bit-core.xml>\n/// Additionally: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/32bit-sse.xml>\n#[derive(Debug, Clone, Copy)]\n#[non_exhaustive]\npub enum X86CoreRegId {\n    /// Accumulator\n    Eax,\n    /// Count register\n    Ecx,\n    /// Data register\n    Edx,\n    /// Base register\n    Ebx,\n    /// Stack pointer\n    Esp,\n    /// Base pointer\n    Ebp,\n    /// Source index\n    Esi,\n    /// Destination index\n    Edi,\n    /// Instruction pointer\n    Eip,\n    /// Status register\n    Eflags,\n    /// Segment registers\n    Segment(X86SegmentRegId),\n    /// FPU registers: ST0 through ST7\n    St(u8),\n    /// FPU internal registers\n    Fpu(X87FpuInternalRegId),\n    /// SIMD Registers: XMM0 through XMM7\n    Xmm(u8),\n    /// SSE Status/Control Register\n    Mxcsr,\n}\n\nimpl RegId for X86CoreRegId {\n    fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> {\n        use self::X86CoreRegId::*;\n\n        let (r, sz): (X86CoreRegId, usize) = match id {\n            0 => (Eax, 4),\n            1 => (Ecx, 4),\n            2 => (Edx, 4),\n            3 => (Ebx, 4),\n            4 => (Esp, 4),\n            5 => (Ebp, 4),\n            6 => (Esi, 4),\n            7 => (Edi, 4),\n            8 => (Eip, 4),\n            9 => (Eflags, 4),\n            10..=15 => (Segment(X86SegmentRegId::from_u8(id as u8 - 10)?), 4),\n            16..=23 => (St(id as u8 - 16), 10),\n            24..=31 => (Fpu(X87FpuInternalRegId::from_u8(id as u8 - 24)?), 4),\n            32..=39 => (Xmm(id as u8 - 32), 16),\n            40 => (Mxcsr, 4),\n            _ => return None,\n        };\n\n        Some((r, Some(NonZeroUsize::new(sz)?)))\n    }\n}\n\n/// 64-bit x86 core + SSE register identifier.\n///\n/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-core.xml>\n/// Additionally: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-sse.xml>\n#[derive(Debug, Clone, Copy)]\n#[non_exhaustive]\npub enum X86_64CoreRegId {\n    /// General purpose registers:\n    /// RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, r8-r15\n    Gpr(u8),\n    /// Instruction pointer\n    Rip,\n    /// Status register\n    Eflags,\n    /// Segment registers\n    Segment(X86SegmentRegId),\n    /// FPU registers: ST0 through ST7\n    St(u8),\n    /// FPU internal registers\n    Fpu(X87FpuInternalRegId),\n    /// SIMD Registers: XMM0 through XMM15\n    Xmm(u8),\n    /// SSE Status/Control Register\n    Mxcsr,\n}\n\nimpl RegId for X86_64CoreRegId {\n    fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> {\n        use self::X86_64CoreRegId::*;\n\n        let (r, sz): (X86_64CoreRegId, usize) = match id {\n            0..=15 => (Gpr(id as u8), 8),\n            16 => (Rip, 8),\n            17 => (Eflags, 4),\n            18..=23 => (Segment(X86SegmentRegId::from_u8(id as u8 - 18)?), 4),\n            24..=31 => (St(id as u8 - 24), 10),\n            32..=39 => (Fpu(X87FpuInternalRegId::from_u8(id as u8 - 32)?), 4),\n            40..=55 => (Xmm(id as u8 - 40), 16),\n            56 => (Mxcsr, 4),\n            _ => return None,\n        };\n\n        Some((r, Some(NonZeroUsize::new(sz)?)))\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use gdbstub::arch::RegId;\n    use gdbstub::arch::Registers;\n\n    /// Compare the following two values which are expected to be the same:\n    /// * length of data written by `Registers::gdb_serialize()` in byte\n    /// * sum of sizes of all registers obtained by `RegId::from_raw_id()`\n    fn test<Rs: Registers, RId: RegId>() {\n        // Obtain the data length written by `gdb_serialize` by passing a custom\n        // closure.\n        let mut serialized_data_len = 0;\n        let counter = |b: Option<u8>| {\n            if b.is_some() {\n                serialized_data_len += 1;\n            }\n        };\n        Rs::default().gdb_serialize(counter);\n\n        // Accumulate register sizes returned by `from_raw_id`.\n        let mut i = 0;\n        let mut sum_reg_sizes = 0;\n        while let Some((_, size)) = RId::from_raw_id(i) {\n            sum_reg_sizes += size.unwrap().get();\n            i += 1;\n        }\n\n        assert_eq!(serialized_data_len, sum_reg_sizes);\n    }\n\n    #[test]\n    fn test_x86() {\n        test::<crate::x86::reg::X86CoreRegs, crate::x86::reg::id::X86CoreRegId>()\n    }\n\n    #[test]\n    fn test_x86_64() {\n        test::<crate::x86::reg::X86_64CoreRegs, crate::x86::reg::id::X86_64CoreRegId>()\n    }\n}\n"
  },
  {
    "path": "gdbstub_arch/src/x86/reg/mod.rs",
    "content": "//! `Register` structs for x86 architectures.\n\nuse core::convert::TryInto;\nuse gdbstub::arch::Registers;\n\n/// `RegId` definitions for x86 architectures.\npub mod id;\n\nmod core32;\nmod core64;\n\npub use core32::X86CoreRegs;\npub use core64::X86_64CoreRegs;\n\n/// 80-bit floating point value\npub type F80 = [u8; 10];\n\n/// FPU registers\n#[derive(Debug, Default, Clone, PartialEq, Eq)]\npub struct X87FpuInternalRegs {\n    /// Floating-point control register\n    pub fctrl: u32,\n    /// Floating-point status register\n    pub fstat: u32,\n    /// Tag word\n    pub ftag: u32,\n    /// FPU instruction pointer segment\n    pub fiseg: u32,\n    /// FPU instruction pointer offset\n    pub fioff: u32,\n    /// FPU operand segment\n    pub foseg: u32,\n    /// FPU operand offset\n    pub fooff: u32,\n    /// Floating-point opcode\n    pub fop: u32,\n}\n\nimpl Registers for X87FpuInternalRegs {\n    type ProgramCounter = u32;\n\n    // HACK: this struct is never used as an architecture's main register file, so\n    // using a dummy value here is fine.\n    fn pc(&self) -> Self::ProgramCounter {\n        0\n    }\n\n    fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {\n        macro_rules! write_bytes {\n            ($bytes:expr) => {\n                for b in $bytes {\n                    write_byte(Some(*b))\n                }\n            };\n        }\n\n        // Note: GDB section names don't make sense unless you read x87 FPU section 8.1:\n        // https://web.archive.org/web/20150123212110/http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-1-manual.pdf\n        write_bytes!(&self.fctrl.to_le_bytes());\n        write_bytes!(&self.fstat.to_le_bytes());\n        write_bytes!(&self.ftag.to_le_bytes());\n        write_bytes!(&self.fiseg.to_le_bytes());\n        write_bytes!(&self.fioff.to_le_bytes());\n        write_bytes!(&self.foseg.to_le_bytes());\n        write_bytes!(&self.fooff.to_le_bytes());\n        write_bytes!(&self.fop.to_le_bytes());\n    }\n\n    fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {\n        if bytes.len() != 0x20 {\n            return Err(());\n        }\n\n        let mut regs = bytes\n            .chunks_exact(4)\n            .map(|x| u32::from_le_bytes(x.try_into().unwrap()));\n\n        self.fctrl = regs.next().ok_or(())?;\n        self.fstat = regs.next().ok_or(())?;\n        self.ftag = regs.next().ok_or(())?;\n        self.fiseg = regs.next().ok_or(())?;\n        self.fioff = regs.next().ok_or(())?;\n        self.foseg = regs.next().ok_or(())?;\n        self.fooff = regs.next().ok_or(())?;\n        self.fop = regs.next().ok_or(())?;\n\n        Ok(())\n    }\n}\n\n/// x86 segment registers.\n///\n/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-core.xml>\n#[derive(Debug, Default, Clone, PartialEq, Eq)]\npub struct X86SegmentRegs {\n    /// Code Segment\n    pub cs: u32,\n    /// Stack Segment\n    pub ss: u32,\n    /// Data Segment\n    pub ds: u32,\n    /// Extra Segment\n    pub es: u32,\n    /// General Purpose Segment\n    pub fs: u32,\n    /// General Purpose Segment\n    pub gs: u32,\n}\n\nimpl Registers for X86SegmentRegs {\n    type ProgramCounter = u32;\n\n    // HACK: this struct is never used as an architecture's main register file, so\n    // using a dummy value here is fine.\n    fn pc(&self) -> Self::ProgramCounter {\n        0\n    }\n\n    fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {\n        macro_rules! write_bytes {\n            ($bytes:expr) => {\n                for b in $bytes {\n                    write_byte(Some(*b))\n                }\n            };\n        }\n\n        write_bytes!(&self.cs.to_le_bytes());\n        write_bytes!(&self.ss.to_le_bytes());\n        write_bytes!(&self.ds.to_le_bytes());\n        write_bytes!(&self.es.to_le_bytes());\n        write_bytes!(&self.fs.to_le_bytes());\n        write_bytes!(&self.gs.to_le_bytes());\n    }\n\n    fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {\n        if bytes.len() != core::mem::size_of::<u32>() * 6 {\n            return Err(());\n        }\n\n        let mut regs = bytes\n            .chunks_exact(4)\n            .map(|x| u32::from_le_bytes(x.try_into().unwrap()));\n\n        self.cs = regs.next().ok_or(())?;\n        self.ss = regs.next().ok_or(())?;\n        self.ds = regs.next().ok_or(())?;\n        self.es = regs.next().ok_or(())?;\n        self.fs = regs.next().ok_or(())?;\n        self.gs = regs.next().ok_or(())?;\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "rustfmt.toml",
    "content": "imports_granularity = \"Item\"\nwrap_comments = true\n"
  },
  {
    "path": "scripts/check_target_delegation.sh",
    "content": "#!/bin/bash\n\nset -e\n\n# Script to enforce that each Target method has a corresponding entry in impl_dyn_target\n\n# Get the list of methods in the Target trait\ntarget_methods=$(awk '/pub trait Target {/,/^}/' src/target/mod.rs | grep '^    fn ' | sed 's/    fn \\([a-zA-Z_][a-zA-Z0-9_]*\\).*/\\1/')\n\n# Get the list of delegated methods in impl_dyn_target\ndelegated_methods=$(awk '/macro_rules! impl_dyn_target {/,/^}/' src/target/mod.rs | grep '__delegate!\\|__delegate_support!' | sed -n 's/.*fn \\([a-zA-Z_][a-zA-Z0-9_]*\\).*/\\1/p; s/__delegate_support!(\\([a-zA-Z_][a-zA-Z0-9_]*\\).*/support_\\1/p' | sed 's/^ *//')\n\n# Check for missing delegations\nmissing=\"\"\nfor method in $target_methods; do\n    if ! echo \"$delegated_methods\" | grep -q \"^$method$\"; then\n        missing=\"$missing $method\"\n    fi\ndone\n\nif [ -n \"$missing\" ]; then\n    echo \"Error: Missing delegations for methods:$missing\"\n    exit 1\nfi\n\necho \"All Target methods have corresponding delegations in impl_dyn_target.\"\n"
  },
  {
    "path": "scripts/test_dead_code_elim.sh",
    "content": "#!/bin/bash\n\n# Must be run from the project's root directory.\n\n# checks if a certain packet has been dead-code-eliminated from the resulting binary.\n# Arg 1: example to build\n# Arg 2: packet name\n\nif [ -z \"$1\" ]; then\n    echo \"Must pass example name as first argument (e.g: armv4t)\"\n    exit 1\nfi\n\nif [ -z \"$2\" ]; then\n    echo \"Must pass packet name as second argument (e.g: qRcmd)\"\n    exit 1\nfi\n\ncargo build --release --example $1 --features=\"std __dead_code_marker\"\nstrip ./target/release/examples/$1\n\noutput=$(strings ./target/release/examples/$1 | sort | grep --color=always \"<$2,\")\n\nif [[ $output ]]; then\n    echo $output\n    echo \"Dead code NOT eliminated!\"\n    exit 1\nelse\n    echo \"Dead code eliminated.\"\n    exit 0\nfi\n"
  },
  {
    "path": "src/arch.rs",
    "content": "//! Traits to encode architecture-specific target information.\n//!\n//! # Community created `Arch` Implementations\n//!\n//! Before getting your hands dirty and implementing a new `Arch` from scratch,\n//! make sure to check out [`gdbstub_arch`](https://docs.rs/gdbstub_arch), a\n//! companion crate to `gdbstub` which aggregates community-created `Arch`\n//! implementations for most common architectures!\n//!\n//! > _Note:_ Prior to `gdbstub 0.5`, `Arch` implementations were distributed as\n//! > a part of the main `gdbstub` crate (under the `gdbstub::arch` module).\n//! >\n//! > This wasn't ideal, any `gdbstub::arch`-level breaking-changes forced the\n//! > _entire_ `gdbstub` crate to release a new (potentially breaking!) version.\n//! >\n//! > Having community-created `Arch` implementations distributed in a separate\n//! > crate helps minimize any unnecessary \"version churn\" in `gdbstub` core.\n\nuse crate::internal::BeBytes;\nuse crate::internal::LeBytes;\nuse core::fmt::Debug;\nuse core::num::NonZeroUsize;\nuse num_traits::FromPrimitive;\nuse num_traits::PrimInt;\nuse num_traits::Unsigned;\n\n/// Register identifier for target registers.\n///\n/// These identifiers are used by GDB to signal which register to read/wite when\n/// performing [single register accesses].\n///\n/// [single register accesses]:\n/// crate::target::ext::base::single_register_access::SingleRegisterAccess\npub trait RegId: Sized + Debug {\n    /// Map raw GDB register number to a corresponding `RegId` and optional\n    /// register size.\n    ///\n    /// If the register size is specified here, gdbstub will include a runtime\n    /// check that ensures target implementations do not send back more\n    /// bytes than the register allows.\n    ///\n    /// Returns `None` if the register is not available.\n    fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)>;\n\n    /// Map a `RegId` back to a raw GDB register number.\n    ///\n    /// Returns `None` if this mapping direction is not implemented.\n    ///\n    /// This method currently only needs to return `Some` for a register if that\n    /// register is sent with\n    /// [`GdbStubStateMachineInner::report_stop_with_regs`].\n    ///\n    /// [`GdbStubStateMachineInner::report_stop_with_regs`]:\n    ///     crate::stub::state_machine::GdbStubStateMachineInner::report_stop_with_regs\n    fn to_raw_id(&self) -> Option<usize> {\n        None\n    }\n}\n\n/// Stub implementation -- Returns `None` for all raw IDs.\nimpl RegId for () {\n    fn from_raw_id(_id: usize) -> Option<(Self, Option<NonZeroUsize>)> {\n        None\n    }\n}\n\n/// Methods to read/write architecture-specific registers.\n///\n/// Registers must be de/serialized in the order specified by the architecture's\n/// `<target>.xml` in the GDB source tree.\n///\n/// e.g: for ARM:\n/// github.com/bminor/binutils-gdb/blob/master/gdb/features/arm/arm-core.xml\n// TODO: add way to de/serialize arbitrary \"missing\"/\"uncollected\" registers.\npub trait Registers: Default + Debug + Clone + PartialEq {\n    /// The type of the architecture's program counter / instruction pointer.\n    /// Must match with the corresponding `Arch::Usize`.\n    type ProgramCounter: Copy;\n\n    /// Return the value of the program counter / instruction pointer.\n    fn pc(&self) -> Self::ProgramCounter;\n\n    /// Serialize `self` into a GDB register bytestream.\n    ///\n    /// Missing registers are serialized by passing `None` to write_byte.\n    fn gdb_serialize(&self, write_byte: impl FnMut(Option<u8>));\n\n    /// Deserialize a GDB register bytestream into `self`.\n    #[allow(clippy::result_unit_err)]\n    fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()>;\n}\n\n/// Breakpoint kind for specific architectures.\n///\n/// This trait corresponds to the _kind_ field of the \"z\" and \"Z\" breakpoint\n/// packets, as documented [here](https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#insert-breakpoint-or-watchpoint-packet).\n///\n/// A breakpoint \"kind\" is architecture-specific and typically indicates the\n/// size of the breakpoint in bytes that should be inserted. As such, most\n/// architectures will set `BreakpointKind = usize`.\n///\n/// Some architectures, such as ARM and MIPS, have additional meanings for\n/// _kind_. See the [Architecture-Specific Protocol Details](https://sourceware.org/gdb/current/onlinedocs/gdb/Architecture_002dSpecific-Protocol-Details.html#Architecture_002dSpecific-Protocol-Details)\n/// section of the GBD documentation for more details.\n///\n/// If no architecture-specific value is being used, _kind_ should be set to\n/// '0', and the `BreakpointKind` associated type should be `()`.\npub trait BreakpointKind: Sized + Debug {\n    /// Parse `Self` from a raw usize.\n    fn from_usize(kind: usize) -> Option<Self>;\n}\n\nimpl BreakpointKind for () {\n    fn from_usize(kind: usize) -> Option<Self> {\n        if kind != 0 {\n            None\n        } else {\n            Some(())\n        }\n    }\n}\n\nimpl BreakpointKind for usize {\n    #[allow(clippy::wrong_self_convention)]\n    fn from_usize(kind: usize) -> Option<Self> {\n        Some(kind)\n    }\n}\n\n/// Encodes architecture-specific information, such as pointer size, register\n/// layout, etc...\n///\n/// Types implementing `Arch` should be\n/// [Zero-variant Enums](https://doc.rust-lang.org/reference/items/enumerations.html#zero-variant-enums),\n/// as `Arch` impls are only ever used at the type level, and should never be\n/// explicitly instantiated.\npub trait Arch {\n    /// The architecture's pointer size (e.g: `u32` on a 32-bit system).\n    type Usize: Debug + FromPrimitive + PrimInt + Unsigned + BeBytes + LeBytes;\n\n    /// The architecture's register file. See [`Registers`] for more details.\n    type Registers: Registers<ProgramCounter = Self::Usize>;\n\n    /// The architecture's breakpoint \"kind\", used to determine the \"size\"\n    /// of breakpoint to set. See [`BreakpointKind`] for more details.\n    type BreakpointKind: BreakpointKind;\n\n    /// Register identifier enum/struct.\n    ///\n    /// Used to access individual registers via `Target::read/write_register`.\n    ///\n    /// > NOTE: An arch's `RegId` type is not strictly required to have a 1:1\n    /// > correspondence with the `Registers` type, and may include register\n    /// > identifiers which are separate from the main `Registers` structure.\n    /// > (e.g: the RISC-V Control and Status registers)\n    type RegId: RegId;\n\n    /// (optional) Return the arch's description XML file (`target.xml`).\n    ///\n    /// Implementing this method enables GDB to automatically detect the\n    /// target's architecture, saving the hassle of having to run `set\n    /// architecture <arch>` when starting a debugging session.\n    ///\n    /// These descriptions can be quite succinct. For example, the target\n    /// description for an `armv4t` target can be as simple as:\n    ///\n    /// ```\n    /// r#\"<target version=\"1.0\"><architecture>armv4t</architecture></target>\"#;\n    /// ```\n    ///\n    /// See the [GDB docs](https://sourceware.org/gdb/current/onlinedocs/gdb/Target-Description-Format.html)\n    /// for details on the target description XML format.\n    #[inline(always)]\n    fn target_description_xml() -> Option<&'static str> {\n        None\n    }\n\n    /// (optional) (LLDB extension) Return register info for the specified\n    /// register.\n    ///\n    /// Implementing this method enables LLDB to dynamically query the target's\n    /// register information one by one.\n    ///\n    /// Some targets don't have register context in the compiled version of the\n    /// debugger. Help the debugger by dynamically supplying the register info\n    /// from the target. The debugger will request the register info in a\n    /// sequential manner till an error packet is received. In LLDB, the\n    /// register info search has the following\n    /// [order](https://github.com/llvm/llvm-project/blob/369ce54bb302f209239b8ebc77ad824add9df089/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp#L397-L402):\n    ///\n    /// 1. Use the target definition python file if one is specified.\n    /// 2. If the target definition doesn't have any of the info from the\n    ///    target.xml (registers) then proceed to read the `target.xml`.\n    /// 3. Fall back on the `qRegisterInfo` packets.\n    /// 4. Use hardcoded defaults if available.\n    ///\n    /// See the LLDB [gdb-remote docs](https://github.com/llvm-mirror/lldb/blob/d01083a850f577b85501a0902b52fd0930de72c7/docs/lldb-gdb-remote.txt#L396)\n    /// for more details on the available information that a single register can\n    /// be described by and [#99](https://github.com/daniel5151/gdbstub/issues/99)\n    /// for more information on LLDB compatibility.\n    #[inline(always)]\n    fn lldb_register_info(reg_id: usize) -> Option<lldb::RegisterInfo<'static>> {\n        let _ = reg_id;\n        None\n    }\n}\n\n/// LLDB-specific types supporting [`Arch::lldb_register_info`] and\n/// [`LldbRegisterInfoOverride`] APIs.\n///\n/// [`LldbRegisterInfoOverride`]: crate::target::ext::lldb_register_info_override::LldbRegisterInfoOverride\npub mod lldb {\n    /// The architecture's register information of a single register.\n    pub enum RegisterInfo<'a> {\n        /// The register info of a single register that should be written.\n        Register(Register<'a>),\n        /// The `qRegisterInfo` query shall be concluded.\n        Done,\n    }\n\n    /// Describes the register info for a single register of\n    /// the target.\n    pub struct Register<'a> {\n        /// The primary register name.\n        pub name: &'a str,\n        /// An alternate name for the register.\n        pub alt_name: Option<&'a str>,\n        /// Size in bits of a register.\n        pub bitsize: usize,\n        /// The offset within the 'g' and 'G' packet of the register data for\n        /// this register.\n        pub offset: usize,\n        /// The encoding type of the register.\n        pub encoding: Encoding,\n        /// The preferred format for display of this register.\n        pub format: Format,\n        /// The register set name this register belongs to.\n        pub set: &'a str,\n        /// The GCC compiler registers number for this register.\n        ///\n        /// _Note:_ This denotes the same `KEY:VALUE;` pair as `ehframe:VALUE;`.\n        /// See the LLDB [source](https://github.com/llvm/llvm-project/blob/b92436efcb7813fc481b30f2593a4907568d917a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp#L493).\n        pub gcc: Option<usize>,\n        /// The DWARF register number for this register that is used for this\n        /// register in the debug information.\n        pub dwarf: Option<usize>,\n        /// Specify as a generic register.\n        pub generic: Option<Generic>,\n        /// Other concrete register values this register is contained in.\n        pub container_regs: Option<&'a [usize]>,\n        /// Specifies which register values should be invalidated when this\n        /// register is modified.\n        pub invalidate_regs: Option<&'a [usize]>,\n    }\n\n    /// Describes the encoding type of the register.\n    #[non_exhaustive]\n    pub enum Encoding {\n        /// Unsigned integer\n        Uint,\n        /// Signed integer\n        Sint,\n        /// IEEE 754 float\n        IEEE754,\n        /// Vector register\n        Vector,\n    }\n\n    /// Describes the preferred format for display of this register.\n    #[non_exhaustive]\n    pub enum Format {\n        /// Binary format\n        Binary,\n        /// Decimal format\n        Decimal,\n        /// Hexadecimal format\n        Hex,\n        /// Floating point format\n        Float,\n        /// 8 bit signed int vector\n        VectorSInt8,\n        /// 8 bit unsigned int vector\n        VectorUInt8,\n        /// 16 bit signed int vector\n        VectorSInt16,\n        /// 16 bit unsigned int vector\n        VectorUInt16,\n        /// 32 bit signed int vector\n        VectorSInt32,\n        /// 32 bit unsigned int vector\n        VectorUInt32,\n        /// 32 bit floating point vector\n        VectorFloat32,\n        /// 128 bit unsigned int vector\n        VectorUInt128,\n    }\n\n    /// Describes the generic types that most CPUs have.\n    #[non_exhaustive]\n    pub enum Generic {\n        /// Program counter register\n        Pc,\n        /// Stack pointer register\n        Sp,\n        /// Frame pointer register\n        Fp,\n        /// Return address register\n        Ra,\n        /// CPU flags register\n        Flags,\n        /// Function argument 1\n        Arg1,\n        /// Function argument 2\n        Arg2,\n        /// Function argument 3\n        Arg3,\n        /// Function argument 4\n        Arg4,\n        /// Function argument 5\n        Arg5,\n        /// Function argument 6\n        Arg6,\n        /// Function argument 7\n        Arg7,\n        /// Function argument 8\n        Arg8,\n    }\n}\n"
  },
  {
    "path": "src/common/mod.rs",
    "content": "//! Common types and definitions used across `gdbstub`.\n\nmod signal;\n\npub use self::signal::Signal;\nuse core::num::NonZeroUsize;\n\n/// Thread ID (as viewed by GDB)\n///\n/// The choice to use a [`NonZeroUsize`] stems from the [GDB RSP Packet\n/// documentation], which states that thread IDs are \"positive numbers with a\n/// target-specific interpretation\".\n///\n/// Target implementations may wish to map `Tid`s to/from their own\n/// target-specific thread ID type. (e.g: an emulator might treat `Tid` as a CPU\n/// index).\n///\n/// [GDB RSP Packet documentation]:\n///     https://sourceware.org/gdb/current/onlinedocs/gdb.html/Packets.html#Packets\npub type Tid = NonZeroUsize;\n\n/// Process ID (as viewed by GDB)\n///\n/// The choice to use a [`NonZeroUsize`] stems from the [GDB RSP Packet\n/// documentation], which states that process IDs are \"positive numbers with a\n/// target-specific interpretation\".\n///\n/// Target implementations may wish to map `Pid`s to/from their own\n/// target-specific process ID type.\n///\n/// [GDB RSP Packet documentation]:\n///     https://sourceware.org/gdb/current/onlinedocs/gdb.html/Packets.html#Packets\npub type Pid = NonZeroUsize;\n\n/// Endianness.\n///\n/// This is used to report target endianness to the debugger as a\n/// response to certain commands.\n#[derive(Clone, Copy, Debug)]\npub enum Endianness {\n    /// Big-endian.\n    Big,\n    /// Little-endian.\n    Little,\n}\n"
  },
  {
    "path": "src/common/signal.rs",
    "content": "/// Cross-platform signal numbers defined by the GDB Remote Serial Protocol.\n///\n/// Transcribed from <https://github.com/bminor/binutils-gdb/blob/master/include/gdb/signals.def>\n#[repr(transparent)]\n#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]\npub struct Signal(pub u8);\n\n#[allow(clippy::upper_case_acronyms)]\n#[allow(non_camel_case_types)]\n#[rustfmt::skip]\nimpl Signal {\n    #[doc = \"Signal 0 (shouldn't be used)\"]    pub const SIGZERO:    Self = Self(0);\n    #[doc = \"Hangup\"]                          pub const SIGHUP:     Self = Self(1);\n    #[doc = \"Interrupt\"]                       pub const SIGINT:     Self = Self(2);\n    #[doc = \"Quit\"]                            pub const SIGQUIT:    Self = Self(3);\n    #[doc = \"Illegal instruction\"]             pub const SIGILL:     Self = Self(4);\n    #[doc = \"Trace/breakpoint trap\"]           pub const SIGTRAP:    Self = Self(5);\n    #[doc = \"Aborted\"]                         pub const SIGABRT:    Self = Self(6);\n    #[doc = \"Emulation trap\"]                  pub const SIGEMT:     Self = Self(7);\n    #[doc = \"Arithmetic exception\"]            pub const SIGFPE:     Self = Self(8);\n    #[doc = \"Killed\"]                          pub const SIGKILL:    Self = Self(9);\n    #[doc = \"Bus error\"]                       pub const SIGBUS:     Self = Self(10);\n    #[doc = \"Segmentation fault\"]              pub const SIGSEGV:    Self = Self(11);\n    #[doc = \"Bad system call\"]                 pub const SIGSYS:     Self = Self(12);\n    #[doc = \"Broken pipe\"]                     pub const SIGPIPE:    Self = Self(13);\n    #[doc = \"Alarm clock\"]                     pub const SIGALRM:    Self = Self(14);\n    #[doc = \"Terminated\"]                      pub const SIGTERM:    Self = Self(15);\n    #[doc = \"Urgent I/O condition\"]            pub const SIGURG:     Self = Self(16);\n    #[doc = \"Stopped (signal)\"]                pub const SIGSTOP:    Self = Self(17);\n    #[doc = \"Stopped (user)\"]                  pub const SIGTSTP:    Self = Self(18);\n    #[doc = \"Continued\"]                       pub const SIGCONT:    Self = Self(19);\n    #[doc = \"Child status changed\"]            pub const SIGCHLD:    Self = Self(20);\n    #[doc = \"Stopped (tty input)\"]             pub const SIGTTIN:    Self = Self(21);\n    #[doc = \"Stopped (tty output)\"]            pub const SIGTTOU:    Self = Self(22);\n    #[doc = \"I/O possible\"]                    pub const SIGIO:      Self = Self(23);\n    #[doc = \"CPU time limit exceeded\"]         pub const SIGXCPU:    Self = Self(24);\n    #[doc = \"File size limit exceeded\"]        pub const SIGXFSZ:    Self = Self(25);\n    #[doc = \"Virtual timer expired\"]           pub const SIGVTALRM:  Self = Self(26);\n    #[doc = \"Profiling timer expired\"]         pub const SIGPROF:    Self = Self(27);\n    #[doc = \"Window size changed\"]             pub const SIGWINCH:   Self = Self(28);\n    #[doc = \"Resource lost\"]                   pub const SIGLOST:    Self = Self(29);\n    #[doc = \"User defined signal 1\"]           pub const SIGUSR1:    Self = Self(30);\n    #[doc = \"User defined signal 2\"]           pub const SIGUSR2:    Self = Self(31);\n    #[doc = \"Power fail/restart\"]              pub const SIGPWR:     Self = Self(32);\n    /* Similar to SIGIO.  Perhaps they should have the same number. */\n    #[doc = \"Pollable event occurred\"]         pub const SIGPOLL:    Self = Self(33);\n    #[doc = \"SIGWIND\"]                         pub const SIGWIND:    Self = Self(34);\n    #[doc = \"SIGPHONE\"]                        pub const SIGPHONE:   Self = Self(35);\n    #[doc = \"Process's LWPs are blocked\"]      pub const SIGWAITING: Self = Self(36);\n    #[doc = \"Signal LWP\"]                      pub const SIGLWP:     Self = Self(37);\n    #[doc = \"Swap space dangerously low\"]      pub const SIGDANGER:  Self = Self(38);\n    #[doc = \"Monitor mode granted\"]            pub const SIGGRANT:   Self = Self(39);\n    #[doc = \"Need to relinquish monitor mode\"] pub const SIGRETRACT: Self = Self(40);\n    #[doc = \"Monitor mode data available\"]     pub const SIGMSG:     Self = Self(41);\n    #[doc = \"Sound completed\"]                 pub const SIGSOUND:   Self = Self(42);\n    #[doc = \"Secure attention\"]                pub const SIGSAK:     Self = Self(43);\n    #[doc = \"SIGPRIO\"]                         pub const SIGPRIO:    Self = Self(44);\n    #[doc = \"Real-time event 33\"]              pub const SIG33:      Self = Self(45);\n    #[doc = \"Real-time event 34\"]              pub const SIG34:      Self = Self(46);\n    #[doc = \"Real-time event 35\"]              pub const SIG35:      Self = Self(47);\n    #[doc = \"Real-time event 36\"]              pub const SIG36:      Self = Self(48);\n    #[doc = \"Real-time event 37\"]              pub const SIG37:      Self = Self(49);\n    #[doc = \"Real-time event 38\"]              pub const SIG38:      Self = Self(50);\n    #[doc = \"Real-time event 39\"]              pub const SIG39:      Self = Self(51);\n    #[doc = \"Real-time event 40\"]              pub const SIG40:      Self = Self(52);\n    #[doc = \"Real-time event 41\"]              pub const SIG41:      Self = Self(53);\n    #[doc = \"Real-time event 42\"]              pub const SIG42:      Self = Self(54);\n    #[doc = \"Real-time event 43\"]              pub const SIG43:      Self = Self(55);\n    #[doc = \"Real-time event 44\"]              pub const SIG44:      Self = Self(56);\n    #[doc = \"Real-time event 45\"]              pub const SIG45:      Self = Self(57);\n    #[doc = \"Real-time event 46\"]              pub const SIG46:      Self = Self(58);\n    #[doc = \"Real-time event 47\"]              pub const SIG47:      Self = Self(59);\n    #[doc = \"Real-time event 48\"]              pub const SIG48:      Self = Self(60);\n    #[doc = \"Real-time event 49\"]              pub const SIG49:      Self = Self(61);\n    #[doc = \"Real-time event 50\"]              pub const SIG50:      Self = Self(62);\n    #[doc = \"Real-time event 51\"]              pub const SIG51:      Self = Self(63);\n    #[doc = \"Real-time event 52\"]              pub const SIG52:      Self = Self(64);\n    #[doc = \"Real-time event 53\"]              pub const SIG53:      Self = Self(65);\n    #[doc = \"Real-time event 54\"]              pub const SIG54:      Self = Self(66);\n    #[doc = \"Real-time event 55\"]              pub const SIG55:      Self = Self(67);\n    #[doc = \"Real-time event 56\"]              pub const SIG56:      Self = Self(68);\n    #[doc = \"Real-time event 57\"]              pub const SIG57:      Self = Self(69);\n    #[doc = \"Real-time event 58\"]              pub const SIG58:      Self = Self(70);\n    #[doc = \"Real-time event 59\"]              pub const SIG59:      Self = Self(71);\n    #[doc = \"Real-time event 60\"]              pub const SIG60:      Self = Self(72);\n    #[doc = \"Real-time event 61\"]              pub const SIG61:      Self = Self(73);\n    #[doc = \"Real-time event 62\"]              pub const SIG62:      Self = Self(74);\n    #[doc = \"Real-time event 63\"]              pub const SIG63:      Self = Self(75);\n    /* Used internally by Solaris threads.  See signal(5) on Solaris. */\n    #[doc = \"LWP internal signal\"]             pub const SIGCANCEL:  Self = Self(76);\n    /* Yes, this pains me, too.  But LynxOS didn't have SIG32, and now\n    GNU/Linux does, and we can't disturb the numbering, since it's\n    part of the remote protocol.  Note that in some GDB's\n    GDB_SIGNAL_REALTIME_32 is number 76.  */\n    #[doc = \"Real-time event 32\"]              pub const SIG32:      Self = Self(77);\n    /* Yet another pain, IRIX 6 has SIG64. */\n    #[doc = \"Real-time event 64\"]              pub const SIG64:      Self = Self(78);\n    /* Yet another pain, GNU/Linux MIPS might go up to 128. */\n    #[doc = \"Real-time event 65\"]              pub const SIG65:      Self = Self(79);\n    #[doc = \"Real-time event 66\"]              pub const SIG66:      Self = Self(80);\n    #[doc = \"Real-time event 67\"]              pub const SIG67:      Self = Self(81);\n    #[doc = \"Real-time event 68\"]              pub const SIG68:      Self = Self(82);\n    #[doc = \"Real-time event 69\"]              pub const SIG69:      Self = Self(83);\n    #[doc = \"Real-time event 70\"]              pub const SIG70:      Self = Self(84);\n    #[doc = \"Real-time event 71\"]              pub const SIG71:      Self = Self(85);\n    #[doc = \"Real-time event 72\"]              pub const SIG72:      Self = Self(86);\n    #[doc = \"Real-time event 73\"]              pub const SIG73:      Self = Self(87);\n    #[doc = \"Real-time event 74\"]              pub const SIG74:      Self = Self(88);\n    #[doc = \"Real-time event 75\"]              pub const SIG75:      Self = Self(89);\n    #[doc = \"Real-time event 76\"]              pub const SIG76:      Self = Self(90);\n    #[doc = \"Real-time event 77\"]              pub const SIG77:      Self = Self(91);\n    #[doc = \"Real-time event 78\"]              pub const SIG78:      Self = Self(92);\n    #[doc = \"Real-time event 79\"]              pub const SIG79:      Self = Self(93);\n    #[doc = \"Real-time event 80\"]              pub const SIG80:      Self = Self(94);\n    #[doc = \"Real-time event 81\"]              pub const SIG81:      Self = Self(95);\n    #[doc = \"Real-time event 82\"]              pub const SIG82:      Self = Self(96);\n    #[doc = \"Real-time event 83\"]              pub const SIG83:      Self = Self(97);\n    #[doc = \"Real-time event 84\"]              pub const SIG84:      Self = Self(98);\n    #[doc = \"Real-time event 85\"]              pub const SIG85:      Self = Self(99);\n    #[doc = \"Real-time event 86\"]              pub const SIG86:      Self = Self(100);\n    #[doc = \"Real-time event 87\"]              pub const SIG87:      Self = Self(101);\n    #[doc = \"Real-time event 88\"]              pub const SIG88:      Self = Self(102);\n    #[doc = \"Real-time event 89\"]              pub const SIG89:      Self = Self(103);\n    #[doc = \"Real-time event 90\"]              pub const SIG90:      Self = Self(104);\n    #[doc = \"Real-time event 91\"]              pub const SIG91:      Self = Self(105);\n    #[doc = \"Real-time event 92\"]              pub const SIG92:      Self = Self(106);\n    #[doc = \"Real-time event 93\"]              pub const SIG93:      Self = Self(107);\n    #[doc = \"Real-time event 94\"]              pub const SIG94:      Self = Self(108);\n    #[doc = \"Real-time event 95\"]              pub const SIG95:      Self = Self(109);\n    #[doc = \"Real-time event 96\"]              pub const SIG96:      Self = Self(110);\n    #[doc = \"Real-time event 97\"]              pub const SIG97:      Self = Self(111);\n    #[doc = \"Real-time event 98\"]              pub const SIG98:      Self = Self(112);\n    #[doc = \"Real-time event 99\"]              pub const SIG99:      Self = Self(113);\n    #[doc = \"Real-time event 100\"]             pub const SIG100:     Self = Self(114);\n    #[doc = \"Real-time event 101\"]             pub const SIG101:     Self = Self(115);\n    #[doc = \"Real-time event 102\"]             pub const SIG102:     Self = Self(116);\n    #[doc = \"Real-time event 103\"]             pub const SIG103:     Self = Self(117);\n    #[doc = \"Real-time event 104\"]             pub const SIG104:     Self = Self(118);\n    #[doc = \"Real-time event 105\"]             pub const SIG105:     Self = Self(119);\n    #[doc = \"Real-time event 106\"]             pub const SIG106:     Self = Self(120);\n    #[doc = \"Real-time event 107\"]             pub const SIG107:     Self = Self(121);\n    #[doc = \"Real-time event 108\"]             pub const SIG108:     Self = Self(122);\n    #[doc = \"Real-time event 109\"]             pub const SIG109:     Self = Self(123);\n    #[doc = \"Real-time event 110\"]             pub const SIG110:     Self = Self(124);\n    #[doc = \"Real-time event 111\"]             pub const SIG111:     Self = Self(125);\n    #[doc = \"Real-time event 112\"]             pub const SIG112:     Self = Self(126);\n    #[doc = \"Real-time event 113\"]             pub const SIG113:     Self = Self(127);\n    #[doc = \"Real-time event 114\"]             pub const SIG114:     Self = Self(128);\n    #[doc = \"Real-time event 115\"]             pub const SIG115:     Self = Self(129);\n    #[doc = \"Real-time event 116\"]             pub const SIG116:     Self = Self(130);\n    #[doc = \"Real-time event 117\"]             pub const SIG117:     Self = Self(131);\n    #[doc = \"Real-time event 118\"]             pub const SIG118:     Self = Self(132);\n    #[doc = \"Real-time event 119\"]             pub const SIG119:     Self = Self(133);\n    #[doc = \"Real-time event 120\"]             pub const SIG120:     Self = Self(134);\n    #[doc = \"Real-time event 121\"]             pub const SIG121:     Self = Self(135);\n    #[doc = \"Real-time event 122\"]             pub const SIG122:     Self = Self(136);\n    #[doc = \"Real-time event 123\"]             pub const SIG123:     Self = Self(137);\n    #[doc = \"Real-time event 124\"]             pub const SIG124:     Self = Self(138);\n    #[doc = \"Real-time event 125\"]             pub const SIG125:     Self = Self(139);\n    #[doc = \"Real-time event 126\"]             pub const SIG126:     Self = Self(140);\n    #[doc = \"Real-time event 127\"]             pub const SIG127:     Self = Self(141);\n\n    #[doc = \"Information request\"]             pub const SIGINFO:    Self = Self(142);\n\n    /* Some signal we don't know about. */\n    #[doc = \"Unknown signal\"]                  pub const UNKNOWN:    Self = Self(143);\n\n    /* Use whatever signal we use when one is not specifically specified\n    (for passing to proceed and so on).  */\n    #[doc = \"Internal error: printing GDB_SIGNAL_DEFAULT\"]\n    pub const INTERNAL_DEFAULT: Self = Self(144);\n\n    /* Mach exceptions.  In versions of GDB before 5.2, these were just before\n    GDB_SIGNAL_INFO if you were compiling on a Mach host (and missing\n    otherwise).  */\n    #[doc = \"Could not access memory\"]         pub const EXC_BAD_ACCESS:      Self = Self(145);\n    #[doc = \"Illegal instruction/operand\"]     pub const EXC_BAD_INSTRUCTION: Self = Self(146);\n    #[doc = \"Arithmetic exception\"]            pub const EXC_ARITHMETIC:      Self = Self(147);\n    #[doc = \"Emulation instruction\"]           pub const EXC_EMULATION:       Self = Self(148);\n    #[doc = \"Software generated exception\"]    pub const EXC_SOFTWARE:        Self = Self(149);\n    #[doc = \"Breakpoint\"]                      pub const EXC_BREAKPOINT:      Self = Self(150);\n\n    #[doc = \"librt internal signal\"]           pub const SIGLIBRT:            Self = Self(151);\n}\n\nimpl core::fmt::Display for Signal {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        #[rustfmt::skip]\n        let s = match *self {\n            Signal::SIGZERO             => \"SIGZERO - Signal 0\",\n            Signal::SIGHUP              => \"SIGHUP - Hangup\",\n            Signal::SIGINT              => \"SIGINT - Interrupt\",\n            Signal::SIGQUIT             => \"SIGQUIT - Quit\",\n            Signal::SIGILL              => \"SIGILL - Illegal instruction\",\n            Signal::SIGTRAP             => \"SIGTRAP - Trace/breakpoint trap\",\n            Signal::SIGABRT             => \"SIGABRT - Aborted\",\n            Signal::SIGEMT              => \"SIGEMT - Emulation trap\",\n            Signal::SIGFPE              => \"SIGFPE - Arithmetic exception\",\n            Signal::SIGKILL             => \"SIGKILL - Killed\",\n            Signal::SIGBUS              => \"SIGBUS - Bus error\",\n            Signal::SIGSEGV             => \"SIGSEGV - Segmentation fault\",\n            Signal::SIGSYS              => \"SIGSYS - Bad system call\",\n            Signal::SIGPIPE             => \"SIGPIPE - Broken pipe\",\n            Signal::SIGALRM             => \"SIGALRM - Alarm clock\",\n            Signal::SIGTERM             => \"SIGTERM - Terminated\",\n            Signal::SIGURG              => \"SIGURG - Urgent I/O condition\",\n            Signal::SIGSTOP             => \"SIGSTOP - Stopped (signal)\",\n            Signal::SIGTSTP             => \"SIGTSTP - Stopped (user)\",\n            Signal::SIGCONT             => \"SIGCONT - Continued\",\n            Signal::SIGCHLD             => \"SIGCHLD - Child status changed\",\n            Signal::SIGTTIN             => \"SIGTTIN - Stopped (tty input)\",\n            Signal::SIGTTOU             => \"SIGTTOU - Stopped (tty output)\",\n            Signal::SIGIO               => \"SIGIO - I/O possible\",\n            Signal::SIGXCPU             => \"SIGXCPU - CPU time limit exceeded\",\n            Signal::SIGXFSZ             => \"SIGXFSZ - File size limit exceeded\",\n            Signal::SIGVTALRM           => \"SIGVTALRM - Virtual timer expired\",\n            Signal::SIGPROF             => \"SIGPROF - Profiling timer expired\",\n            Signal::SIGWINCH            => \"SIGWINCH - Window size changed\",\n            Signal::SIGLOST             => \"SIGLOST - Resource lost\",\n            Signal::SIGUSR1             => \"SIGUSR1 - User defined signal 1\",\n            Signal::SIGUSR2             => \"SIGUSR2 - User defined signal 2\",\n            Signal::SIGPWR              => \"SIGPWR - Power fail/restart\",\n            Signal::SIGPOLL             => \"SIGPOLL - Pollable event occurred\",\n            Signal::SIGWIND             => \"SIGWIND - SIGWIND\",\n            Signal::SIGPHONE            => \"SIGPHONE - SIGPHONE\",\n            Signal::SIGWAITING          => \"SIGWAITING - Process's LWPs are blocked\",\n            Signal::SIGLWP              => \"SIGLWP - Signal LWP\",\n            Signal::SIGDANGER           => \"SIGDANGER - Swap space dangerously low\",\n            Signal::SIGGRANT            => \"SIGGRANT - Monitor mode granted\",\n            Signal::SIGRETRACT          => \"SIGRETRACT - Need to relinquish monitor mode\",\n            Signal::SIGMSG              => \"SIGMSG - Monitor mode data available\",\n            Signal::SIGSOUND            => \"SIGSOUND - Sound completed\",\n            Signal::SIGSAK              => \"SIGSAK - Secure attention\",\n            Signal::SIGPRIO             => \"SIGPRIO - SIGPRIO\",\n            Signal::SIG33               => \"SIG33 - Real-time event 33\",\n            Signal::SIG34               => \"SIG34 - Real-time event 34\",\n            Signal::SIG35               => \"SIG35 - Real-time event 35\",\n            Signal::SIG36               => \"SIG36 - Real-time event 36\",\n            Signal::SIG37               => \"SIG37 - Real-time event 37\",\n            Signal::SIG38               => \"SIG38 - Real-time event 38\",\n            Signal::SIG39               => \"SIG39 - Real-time event 39\",\n            Signal::SIG40               => \"SIG40 - Real-time event 40\",\n            Signal::SIG41               => \"SIG41 - Real-time event 41\",\n            Signal::SIG42               => \"SIG42 - Real-time event 42\",\n            Signal::SIG43               => \"SIG43 - Real-time event 43\",\n            Signal::SIG44               => \"SIG44 - Real-time event 44\",\n            Signal::SIG45               => \"SIG45 - Real-time event 45\",\n            Signal::SIG46               => \"SIG46 - Real-time event 46\",\n            Signal::SIG47               => \"SIG47 - Real-time event 47\",\n            Signal::SIG48               => \"SIG48 - Real-time event 48\",\n            Signal::SIG49               => \"SIG49 - Real-time event 49\",\n            Signal::SIG50               => \"SIG50 - Real-time event 50\",\n            Signal::SIG51               => \"SIG51 - Real-time event 51\",\n            Signal::SIG52               => \"SIG52 - Real-time event 52\",\n            Signal::SIG53               => \"SIG53 - Real-time event 53\",\n            Signal::SIG54               => \"SIG54 - Real-time event 54\",\n            Signal::SIG55               => \"SIG55 - Real-time event 55\",\n            Signal::SIG56               => \"SIG56 - Real-time event 56\",\n            Signal::SIG57               => \"SIG57 - Real-time event 57\",\n            Signal::SIG58               => \"SIG58 - Real-time event 58\",\n            Signal::SIG59               => \"SIG59 - Real-time event 59\",\n            Signal::SIG60               => \"SIG60 - Real-time event 60\",\n            Signal::SIG61               => \"SIG61 - Real-time event 61\",\n            Signal::SIG62               => \"SIG62 - Real-time event 62\",\n            Signal::SIG63               => \"SIG63 - Real-time event 63\",\n            Signal::SIGCANCEL           => \"SIGCANCEL - LWP internal signal\",\n            Signal::SIG32               => \"SIG32 - Real-time event 32\",\n            Signal::SIG64               => \"SIG64 - Real-time event 64\",\n            Signal::SIG65               => \"SIG65 - Real-time event 65\",\n            Signal::SIG66               => \"SIG66 - Real-time event 66\",\n            Signal::SIG67               => \"SIG67 - Real-time event 67\",\n            Signal::SIG68               => \"SIG68 - Real-time event 68\",\n            Signal::SIG69               => \"SIG69 - Real-time event 69\",\n            Signal::SIG70               => \"SIG70 - Real-time event 70\",\n            Signal::SIG71               => \"SIG71 - Real-time event 71\",\n            Signal::SIG72               => \"SIG72 - Real-time event 72\",\n            Signal::SIG73               => \"SIG73 - Real-time event 73\",\n            Signal::SIG74               => \"SIG74 - Real-time event 74\",\n            Signal::SIG75               => \"SIG75 - Real-time event 75\",\n            Signal::SIG76               => \"SIG76 - Real-time event 76\",\n            Signal::SIG77               => \"SIG77 - Real-time event 77\",\n            Signal::SIG78               => \"SIG78 - Real-time event 78\",\n            Signal::SIG79               => \"SIG79 - Real-time event 79\",\n            Signal::SIG80               => \"SIG80 - Real-time event 80\",\n            Signal::SIG81               => \"SIG81 - Real-time event 81\",\n            Signal::SIG82               => \"SIG82 - Real-time event 82\",\n            Signal::SIG83               => \"SIG83 - Real-time event 83\",\n            Signal::SIG84               => \"SIG84 - Real-time event 84\",\n            Signal::SIG85               => \"SIG85 - Real-time event 85\",\n            Signal::SIG86               => \"SIG86 - Real-time event 86\",\n            Signal::SIG87               => \"SIG87 - Real-time event 87\",\n            Signal::SIG88               => \"SIG88 - Real-time event 88\",\n            Signal::SIG89               => \"SIG89 - Real-time event 89\",\n            Signal::SIG90               => \"SIG90 - Real-time event 90\",\n            Signal::SIG91               => \"SIG91 - Real-time event 91\",\n            Signal::SIG92               => \"SIG92 - Real-time event 92\",\n            Signal::SIG93               => \"SIG93 - Real-time event 93\",\n            Signal::SIG94               => \"SIG94 - Real-time event 94\",\n            Signal::SIG95               => \"SIG95 - Real-time event 95\",\n            Signal::SIG96               => \"SIG96 - Real-time event 96\",\n            Signal::SIG97               => \"SIG97 - Real-time event 97\",\n            Signal::SIG98               => \"SIG98 - Real-time event 98\",\n            Signal::SIG99               => \"SIG99 - Real-time event 99\",\n            Signal::SIG100              => \"SIG100 - Real-time event 100\",\n            Signal::SIG101              => \"SIG101 - Real-time event 101\",\n            Signal::SIG102              => \"SIG102 - Real-time event 102\",\n            Signal::SIG103              => \"SIG103 - Real-time event 103\",\n            Signal::SIG104              => \"SIG104 - Real-time event 104\",\n            Signal::SIG105              => \"SIG105 - Real-time event 105\",\n            Signal::SIG106              => \"SIG106 - Real-time event 106\",\n            Signal::SIG107              => \"SIG107 - Real-time event 107\",\n            Signal::SIG108              => \"SIG108 - Real-time event 108\",\n            Signal::SIG109              => \"SIG109 - Real-time event 109\",\n            Signal::SIG110              => \"SIG110 - Real-time event 110\",\n            Signal::SIG111              => \"SIG111 - Real-time event 111\",\n            Signal::SIG112              => \"SIG112 - Real-time event 112\",\n            Signal::SIG113              => \"SIG113 - Real-time event 113\",\n            Signal::SIG114              => \"SIG114 - Real-time event 114\",\n            Signal::SIG115              => \"SIG115 - Real-time event 115\",\n            Signal::SIG116              => \"SIG116 - Real-time event 116\",\n            Signal::SIG117              => \"SIG117 - Real-time event 117\",\n            Signal::SIG118              => \"SIG118 - Real-time event 118\",\n            Signal::SIG119              => \"SIG119 - Real-time event 119\",\n            Signal::SIG120              => \"SIG120 - Real-time event 120\",\n            Signal::SIG121              => \"SIG121 - Real-time event 121\",\n            Signal::SIG122              => \"SIG122 - Real-time event 122\",\n            Signal::SIG123              => \"SIG123 - Real-time event 123\",\n            Signal::SIG124              => \"SIG124 - Real-time event 124\",\n            Signal::SIG125              => \"SIG125 - Real-time event 125\",\n            Signal::SIG126              => \"SIG126 - Real-time event 126\",\n            Signal::SIG127              => \"SIG127 - Real-time event 127\",\n            Signal::SIGINFO             => \"SIGINFO - Information request\",\n            Signal::UNKNOWN             => \"UNKNOWN - Unknown signal\",\n            Signal::INTERNAL_DEFAULT    => \"INTERNAL_DEFAULT - Internal error: printing GDB_SIGNAL_DEFAULT\",\n            Signal::EXC_BAD_ACCESS      => \"EXC_BAD_ACCESS - Could not access memory\",\n            Signal::EXC_BAD_INSTRUCTION => \"EXC_BAD_INSTRUCTION - Illegal instruction/operand\",\n            Signal::EXC_ARITHMETIC      => \"EXC_ARITHMETIC - Arithmetic exception\",\n            Signal::EXC_EMULATION       => \"EXC_EMULATION - Emulation instruction\",\n            Signal::EXC_SOFTWARE        => \"EXC_SOFTWARE - Software generated exception\",\n            Signal::EXC_BREAKPOINT      => \"EXC_BREAKPOINT - Breakpoint\",\n            Signal::SIGLIBRT            => \"SIGLIBRT - librt internal signal\",\n\n            _ => \"custom signal (not defined in GDB's signals.def file)\"\n        };\n\n        write!(f, \"{}\", s)\n    }\n}\n"
  },
  {
    "path": "src/conn/impls/boxed.rs",
    "content": "use crate::conn::Connection;\nuse crate::conn::ConnectionExt;\nuse alloc::boxed::Box;\n\nimpl<E> Connection for Box<dyn Connection<Error = E>> {\n    type Error = E;\n\n    fn write(&mut self, byte: u8) -> Result<(), Self::Error> {\n        (**self).write(byte)\n    }\n\n    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {\n        (**self).write_all(buf)\n    }\n\n    fn flush(&mut self) -> Result<(), Self::Error> {\n        (**self).flush()\n    }\n\n    fn on_session_start(&mut self) -> Result<(), Self::Error> {\n        (**self).on_session_start()\n    }\n}\n\nimpl<E> Connection for Box<dyn ConnectionExt<Error = E>> {\n    type Error = E;\n\n    fn write(&mut self, byte: u8) -> Result<(), Self::Error> {\n        (**self).write(byte)\n    }\n\n    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {\n        (**self).write_all(buf)\n    }\n\n    fn flush(&mut self) -> Result<(), Self::Error> {\n        (**self).flush()\n    }\n\n    fn on_session_start(&mut self) -> Result<(), Self::Error> {\n        (**self).on_session_start()\n    }\n}\n\nimpl<E> ConnectionExt for Box<dyn ConnectionExt<Error = E>> {\n    fn read(&mut self) -> Result<u8, Self::Error> {\n        (**self).read()\n    }\n\n    fn peek(&mut self) -> Result<Option<u8>, Self::Error> {\n        (**self).peek()\n    }\n}\n"
  },
  {
    "path": "src/conn/impls/mod.rs",
    "content": "//! Implementations of the [`Connection`] trait for various built-in types\n// TODO: impl Connection for all `Read + Write` (blocked on specialization)\n\n#[cfg(feature = \"alloc\")]\nmod boxed;\n\n#[cfg(feature = \"std\")]\nmod tcpstream;\n\n#[cfg(all(feature = \"std\", unix))]\nmod unixstream;\n\nuse crate::conn::Connection;\nuse crate::conn::ConnectionExt;\n\nimpl<E> Connection for &mut dyn Connection<Error = E> {\n    type Error = E;\n\n    fn write(&mut self, byte: u8) -> Result<(), Self::Error> {\n        (**self).write(byte)\n    }\n\n    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {\n        (**self).write_all(buf)\n    }\n\n    fn flush(&mut self) -> Result<(), Self::Error> {\n        (**self).flush()\n    }\n\n    fn on_session_start(&mut self) -> Result<(), Self::Error> {\n        (**self).on_session_start()\n    }\n}\n\nimpl<E> Connection for &mut dyn ConnectionExt<Error = E> {\n    type Error = E;\n\n    fn write(&mut self, byte: u8) -> Result<(), Self::Error> {\n        (**self).write(byte)\n    }\n\n    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {\n        (**self).write_all(buf)\n    }\n\n    fn flush(&mut self) -> Result<(), Self::Error> {\n        (**self).flush()\n    }\n\n    fn on_session_start(&mut self) -> Result<(), Self::Error> {\n        (**self).on_session_start()\n    }\n}\n\nimpl<E> ConnectionExt for &mut dyn ConnectionExt<Error = E> {\n    fn read(&mut self) -> Result<u8, Self::Error> {\n        (**self).read()\n    }\n\n    fn peek(&mut self) -> Result<Option<u8>, Self::Error> {\n        (**self).peek()\n    }\n}\n"
  },
  {
    "path": "src/conn/impls/tcpstream.rs",
    "content": "use crate::conn::Connection;\nuse crate::conn::ConnectionExt;\nuse std::net::TcpStream;\n\nimpl Connection for TcpStream {\n    type Error = std::io::Error;\n\n    fn write(&mut self, byte: u8) -> Result<(), Self::Error> {\n        use std::io::Write;\n\n        Write::write_all(self, &[byte])\n    }\n\n    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {\n        use std::io::Write;\n\n        Write::write_all(self, buf)\n    }\n\n    fn flush(&mut self) -> Result<(), Self::Error> {\n        use std::io::Write;\n\n        Write::flush(self)\n    }\n\n    fn on_session_start(&mut self) -> Result<(), Self::Error> {\n        // see issue #28\n        self.set_nodelay(true)\n    }\n}\n\nimpl ConnectionExt for TcpStream {\n    fn read(&mut self) -> Result<u8, Self::Error> {\n        use std::io::Read;\n\n        self.set_nonblocking(false)?;\n\n        let mut buf = [0u8];\n        match Read::read_exact(self, &mut buf) {\n            Ok(_) => Ok(buf[0]),\n            Err(e) => Err(e),\n        }\n    }\n\n    fn peek(&mut self) -> Result<Option<u8>, Self::Error> {\n        self.set_nonblocking(true)?;\n\n        let mut buf = [0u8];\n        match Self::peek(self, &mut buf) {\n            Ok(_) => Ok(Some(buf[0])),\n            Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => Ok(None),\n            Err(e) => Err(e),\n        }\n    }\n}\n"
  },
  {
    "path": "src/conn/impls/unixstream.rs",
    "content": "use crate::conn::Connection;\nuse crate::conn::ConnectionExt;\nuse std::io;\nuse std::os::unix::net::UnixStream;\n\n// TODO: Remove PeekExt once rust-lang/rust#73761 is stabilized\ntrait PeekExt {\n    fn peek(&self, buf: &mut [u8]) -> io::Result<usize>;\n}\n\nimpl PeekExt for UnixStream {\n    #[cfg(feature = \"paranoid_unsafe\")]\n    #[allow(clippy::panic)]\n    fn peek(&self, _buf: &mut [u8]) -> io::Result<usize> {\n        panic!(\"cannot use `UnixStream::peek` with `paranoid_unsafe` until rust-lang/rust#73761 is stabilized\");\n    }\n\n    #[cfg(not(feature = \"paranoid_unsafe\"))]\n    #[allow(non_camel_case_types)]\n    fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {\n        use core::ffi::c_void;\n        use std::os::unix::io::AsRawFd;\n\n        // Define some libc types inline (to avoid bringing in entire libc dep)\n\n        // every platform supported by the libc crate uses c_int = i32\n        type c_int = i32;\n        type size_t = usize;\n        type ssize_t = isize;\n        const MSG_PEEK: c_int = 2;\n        extern \"C\" {\n            fn recv(socket: c_int, buf: *mut c_void, len: size_t, flags: c_int) -> ssize_t;\n        }\n\n        // from std/sys/unix/mod.rs\n        pub fn cvt(t: isize) -> io::Result<isize> {\n            if t == -1 {\n                Err(io::Error::last_os_error())\n            } else {\n                Ok(t)\n            }\n        }\n\n        // from std/sys/unix/net.rs\n        let ret = cvt(unsafe {\n            recv(\n                self.as_raw_fd(),\n                buf.as_mut_ptr() as *mut c_void,\n                buf.len(),\n                MSG_PEEK,\n            )\n        })?;\n        Ok(ret as usize)\n    }\n}\n\nimpl Connection for UnixStream {\n    type Error = std::io::Error;\n\n    fn write(&mut self, byte: u8) -> Result<(), Self::Error> {\n        use std::io::Write;\n\n        Write::write_all(self, &[byte])\n    }\n\n    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {\n        use std::io::Write;\n\n        Write::write_all(self, buf)\n    }\n\n    fn flush(&mut self) -> Result<(), Self::Error> {\n        use std::io::Write;\n\n        Write::flush(self)\n    }\n}\n\nimpl ConnectionExt for UnixStream {\n    fn read(&mut self) -> Result<u8, Self::Error> {\n        use std::io::Read;\n\n        self.set_nonblocking(false)?;\n\n        let mut buf = [0u8];\n        match Read::read_exact(self, &mut buf) {\n            Ok(_) => Ok(buf[0]),\n            Err(e) => Err(e),\n        }\n    }\n\n    fn peek(&mut self) -> Result<Option<u8>, Self::Error> {\n        self.set_nonblocking(true)?;\n\n        let mut buf = [0u8];\n        match PeekExt::peek(self, &mut buf) {\n            Ok(_) => Ok(Some(buf[0])),\n            Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => Ok(None),\n            Err(e) => Err(e),\n        }\n    }\n}\n"
  },
  {
    "path": "src/conn/mod.rs",
    "content": "//! Traits to perform in-order, serial, byte-wise I/O.\n\nmod impls;\n\n/// A trait to perform in-order, serial, byte-wise I/O.\n///\n/// When the `std` feature is enabled, this trait is automatically implemented\n/// for [`TcpStream`](std::net::TcpStream) and\n/// [`UnixStream`](std::os::unix::net::UnixStream) (on unix systems).\npub trait Connection {\n    /// Transport-specific error type.\n    type Error;\n\n    /// Write a single byte.\n    fn write(&mut self, byte: u8) -> Result<(), Self::Error>;\n\n    /// Write the entire buffer, blocking until complete.\n    ///\n    /// This method's default implementation calls `self.write()` on each byte\n    /// in the buffer. This can be quite inefficient, so if a more efficient\n    /// implementation exists (such as calling `write_all()` on an underlying\n    /// `std::io::Write` object), this method should be overwritten.\n    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {\n        for b in buf {\n            self.write(*b)?;\n        }\n        Ok(())\n    }\n\n    /// Flush this Connection, ensuring that all intermediately buffered\n    /// contents reach their destination.\n    ///\n    /// _Note:_ Not all `Connection`s have internal buffering (e.g: writing data\n    /// to a UART TX register with FIFOs disabled). In these cases, it's fine to\n    /// simply return `Ok(())`.\n    fn flush(&mut self) -> Result<(), Self::Error>;\n\n    /// Called at the start of a debugging session _before_ any GDB packets have\n    /// been sent/received.\n    ///\n    /// This method's default implementation is a no-op.\n    ///\n    /// # Example\n    ///\n    /// The `on_session_start` implementation for `TcpStream` ensures that\n    /// [`set_nodelay(true)`](std::net::TcpStream::set_nodelay)\n    /// is called. The GDB remote serial protocol requires sending/receiving\n    /// many small packets, so forgetting to enable `TCP_NODELAY` can result in\n    /// a massively degraded debugging experience.\n    fn on_session_start(&mut self) -> Result<(), Self::Error> {\n        Ok(())\n    }\n}\n\n/// Extends [`Connection`] with `read` and `peek` methods.\n///\n/// This trait is used as part of `gdbstub`'s quickstart\n/// [`GdbStub::run_blocking`](crate::stub::GdbStub::run_blocking) API.\n///\n/// When the `std` feature is enabled, this trait is automatically implemented\n/// for [`TcpStream`](std::net::TcpStream) and\n/// [`UnixStream`](std::os::unix::net::UnixStream) (on unix systems).\npub trait ConnectionExt: Connection {\n    /// Read a single byte.\n    fn read(&mut self) -> Result<u8, Self::Error>;\n\n    /// Peek a single byte. This MUST be a **non-blocking** operation, returning\n    /// `None` if no byte is available.\n    ///\n    /// Returns a byte (if one is available) without removing that byte from the\n    /// queue. Subsequent calls to `peek` MUST return the same byte.\n    fn peek(&mut self) -> Result<Option<u8>, Self::Error>;\n}\n"
  },
  {
    "path": "src/internal/be_bytes.rs",
    "content": "/// A trait for working with structs as big-endian byte arrays. Automatically\n/// implemented for all built-in signed/unsigned integers.\npub trait BeBytes: Sized {\n    /// Write the memory representation of `self` as a byte array in\n    /// big-endian (network) byte order into the provided buffer.\n    #[allow(clippy::wrong_self_convention)]\n    fn to_be_bytes(self, buf: &mut [u8]) -> Option<usize>;\n\n    /// Parse `self` from a byte array in big-endian (network) byte order.\n    /// Returns None upon overflow.\n    fn from_be_bytes(buf: &[u8]) -> Option<Self>;\n}\n\nmacro_rules! impl_to_be_bytes {\n    ($($num:ty)*) => {\n        $(\n            impl BeBytes for $num {\n                fn to_be_bytes(self, buf: &mut [u8]) -> Option<usize> {\n                    let len = core::mem::size_of::<$num>();\n                    if buf.len() < len {\n                        return None\n                    }\n                    buf[..len].copy_from_slice(&<$num>::to_be_bytes(self));\n                    Some(len)\n                }\n\n                fn from_be_bytes(buf: &[u8]) -> Option<Self> {\n                    let len = core::mem::size_of::<$num>();\n\n                    let buf = if buf.len() > len {\n                        let (extra, buf) = buf.split_at(buf.len() - len);\n                        if extra.iter().any(|&b| b != 0) {\n                            return None\n                        }\n                        buf\n                    } else {\n                        buf\n                    };\n\n                    let mut res: Self = 0;\n                    for b in buf.iter().copied() {\n                        let b: Self = b as Self;\n                        // `res <<= 8` causes the compiler to complain in the `u8` case\n                        res <<= 4;\n                        res <<= 4;\n                        res |= b;\n                    }\n\n                    Some(res)\n                }\n            }\n        )*\n    };\n}\n\nimpl_to_be_bytes!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn basic() {\n        assert_eq!(\n            0x12345678,\n            BeBytes::from_be_bytes(&[0x12, 0x34, 0x56, 0x78]).unwrap()\n        )\n    }\n\n    #[test]\n    fn small() {\n        assert_eq!(\n            0x123456,\n            BeBytes::from_be_bytes(&[0x12, 0x34, 0x56]).unwrap()\n        )\n    }\n\n    #[test]\n    fn too_big() {\n        assert_eq!(\n            0x1234_u16,\n            BeBytes::from_be_bytes(&[0xde, 0xad, 0xbe, 0xef]).unwrap_or(0x1234)\n        )\n    }\n}\n"
  },
  {
    "path": "src/internal/le_bytes.rs",
    "content": "/// A trait for working with structs as little-endian byte arrays. Automatically\n/// implemented for all built-in signed/unsigned integers.\npub trait LeBytes: Sized {\n    /// Write the memory representation of `self` as a byte array in\n    /// little-endian byte order into the provided buffer.\n    #[allow(clippy::wrong_self_convention)]\n    fn to_le_bytes(self, buf: &mut [u8]) -> Option<usize>;\n\n    /// Parse `self` from a byte array in little-endian byte order.\n    /// Returns None upon overflow.\n    fn from_le_bytes(buf: &[u8]) -> Option<Self>;\n}\n\nmacro_rules! impl_to_le_bytes {\n    ($($num:ty)*) => {\n        $(\n            impl LeBytes for $num {\n                fn to_le_bytes(self, buf: &mut [u8]) -> Option<usize> {\n                    let len = core::mem::size_of::<$num>();\n                    if buf.len() < len {\n                        return None\n                    }\n                    buf[..len].copy_from_slice(&<$num>::to_le_bytes(self));\n                    Some(len)\n                }\n\n                fn from_le_bytes(buf: &[u8]) -> Option<Self> {\n                    let len = core::mem::size_of::<$num>();\n\n                    let buf = if buf.len() > len {\n                        let (extra, buf) = buf.split_at(buf.len() - len);\n                        if extra.iter().any(|&b| b != 0) {\n                            return None\n                        }\n                        buf\n                    } else {\n                        buf\n                    };\n\n                    let mut res: Self = 0;\n                    for b in buf.iter().copied().rev() {\n                        let b: Self = b as Self;\n                        // `res <<= 8` causes the compiler to complain in the `u8` case\n                        res <<= 4;\n                        res <<= 4;\n                        res |= b;\n                    }\n\n                    Some(res)\n                }\n            }\n        )*\n    };\n}\n\nimpl_to_le_bytes!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn basic() {\n        assert_eq!(\n            0x12345678,\n            LeBytes::from_le_bytes(&[0x78, 0x56, 0x34, 0x12]).unwrap()\n        )\n    }\n\n    #[test]\n    fn small() {\n        assert_eq!(\n            0x123456,\n            LeBytes::from_le_bytes(&[0x56, 0x34, 0x12]).unwrap()\n        )\n    }\n\n    #[test]\n    fn too_big() {\n        assert_eq!(\n            0x1234_u16,\n            LeBytes::from_le_bytes(&[0xde, 0xad, 0xbe, 0xef]).unwrap_or(0x1234)\n        )\n    }\n}\n"
  },
  {
    "path": "src/internal/mod.rs",
    "content": "//! Types / traits which are part of `gdbstub`'s public API, but don't need to\n//! be implemented by consumers of the library.\n\nmod be_bytes;\nmod le_bytes;\n\npub use be_bytes::*;\npub use le_bytes::*;\n"
  },
  {
    "path": "src/lib.rs",
    "content": "//! An ergonomic, featureful, and easy-to-integrate implementation of the [GDB\n//! Remote Serial Protocol](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html#Remote-Protocol)\n//! in Rust, with no-compromises `#![no_std]` support.\n//!\n//! ## Feature flags\n//!\n//! By default, both the `std` and `alloc` features are enabled.\n//!\n//! When using `gdbstub` in `#![no_std]` contexts, make sure to set\n//! `default-features = false`.\n//!\n//! - `alloc`\n//!     - Implement `Connection` for `Box<dyn Connection>`.\n//!     - Log outgoing packets via `log::trace!` (uses a heap-allocated output\n//!       buffer).\n//!     - Provide built-in implementations for certain protocol features:\n//!         - Use a heap-allocated packet buffer in `GdbStub` (if none is\n//!           provided via `GdbStubBuilder::with_packet_buffer`).\n//!         - (Monitor Command) Use a heap-allocated output buffer in\n//!           `ConsoleOutput`.\n//! - `std` (implies `alloc`)\n//!     - Implement `Connection` for [`TcpStream`](std::net::TcpStream) and\n//!       [`UnixStream`](std::os::unix::net::UnixStream).\n//!     - Implement [`std::error::Error`] for `gdbstub::Error`.\n//!     - Add a `TargetError::Io` variant to simplify `std::io::Error` handling\n//!       from Target methods.\n//! - `paranoid_unsafe`\n//!     - Please refer to the [`unsafe` in `gdbstub`](https://github.com/daniel5151/gdbstub#unsafe-in-gdbstub)\n//!       section of the README.md for more details.\n//! - `core_error`\n//!     - Make `GdbStubError` implement [`core::error::Error`](https://doc.rust-lang.org/core/error/trait.Error.html)\n//!       instead of `std::error::Error`.\n//!\n//! ## Getting Started\n//!\n//! This section provides a brief overview of the key traits and types used in\n//! `gdbstub`, and walks though the basic steps required to integrate `gdbstub`\n//! into a project.\n//!\n//! At a high level, there are only three things that are required to get up and\n//! running with `gdbstub`: a [`Connection`](#the-connection-trait), a\n//! [`Target`](#the-target-trait), and a [event loop](#the-event-loop).\n//!\n//! > _Note:_ I _highly recommended_ referencing some of the\n//! [examples](https://github.com/daniel5151/gdbstub#examples) listed in the\n//! project README when integrating `gdbstub` into a project for the first time.\n//!\n//! > In particular, the in-tree\n//! [`armv4t`](https://github.com/daniel5151/gdbstub/tree/master/examples/armv4t)\n//! example contains basic implementations off almost all protocol extensions,\n//! making it an incredibly valuable reference when implementing protocol\n//! extensions.\n//!\n//! ### The `Connection` Trait\n//!\n//! First things first: `gdbstub` needs some way to communicate with a GDB\n//! client. To facilitate this communication, `gdbstub` uses a custom\n//! [`Connection`](conn::Connection) trait.\n//!\n//! `Connection` is automatically implemented for common `std` types such as\n//! [`TcpStream`](std::net::TcpStream) and\n//! [`UnixStream`](std::os::unix::net::UnixStream).\n//!\n//! If you're using `gdbstub` in a `#![no_std]` environment, `Connection` will\n//! most likely need to be manually implemented on top of whatever in-order,\n//! serial, byte-wise I/O your particular platform has available (e.g:\n//! putchar/getchar over UART, using an embedded TCP stack, etc.).\n//!\n//! One common way to start a remote debugging session is to simply wait for a\n//! GDB client to connect via TCP:\n//!\n//! ```rust\n//! use std::io;\n//! use std::net::{TcpListener, TcpStream};\n//!\n//! fn wait_for_gdb_connection(port: u16) -> io::Result<TcpStream> {\n//!     let sockaddr = format!(\"localhost:{}\", port);\n//!     eprintln!(\"Waiting for a GDB connection on {:?}...\", sockaddr);\n//!     let sock = TcpListener::bind(sockaddr)?;\n//!     let (stream, addr) = sock.accept()?;\n//!\n//!     // Blocks until a GDB client connects via TCP.\n//!     // i.e: Running `target remote localhost:<port>` from the GDB prompt.\n//!\n//!     eprintln!(\"Debugger connected from {}\", addr);\n//!     Ok(stream) // `TcpStream` implements `gdbstub::Connection`\n//! }\n//! ```\n//!\n//! ### The `Target` Trait\n//!\n//! The [`Target`](target::Target) trait describes how to control and modify a\n//! system's execution state during a GDB debugging session, and serves as the\n//! primary bridge between `gdbstub`'s generic GDB protocol implementation and a\n//! specific target's project/platform-specific code.\n//!\n//! At a high level, the `Target` trait is a collection of user-defined handler\n//! methods that the GDB client can invoke via the GDB remote serial protocol.\n//! For example, the `Target` trait includes methods to read/write\n//! registers/memory, start/stop execution, etc...\n//!\n//! **`Target` is the most important trait in `gdbstub`, and must be implemented\n//! by anyone integrating `gdbstub` into their project!**\n//!\n//! Please refer to the [`target` module documentation](target) for in-depth\n//! instructions on how to implement [`Target`](target::Target) for a particular\n//! platform.\n//!\n//! ## The Event Loop\n//!\n//! Once a [`Connection`](#the-connection-trait) has been established and the\n//! [`Target`](#the-target-trait) has been initialized, all that's left is to\n//! wire things up and decide what kind of event loop will be used to drive the\n//! debugging session!\n//!\n//! First things first, let's get an instance of `GdbStub` ready to run:\n//!\n//! ```rust,ignore\n//! // Set-up a valid `Target`\n//! let mut target = MyTarget::new()?; // implements `Target`\n//!\n//! // Establish a `Connection`\n//! let connection: TcpStream = wait_for_gdb_connection(9001);\n//!\n//! // Create a new `gdbstub::GdbStub` using the established `Connection`.\n//! let mut debugger = gdbstub::GdbStub::new(connection);\n//! ```\n//!\n//! Cool, but how do you actually start the debugging session?\n// use an explicit doc attribute to avoid automatic rustfmt wrapping\n#![doc = \"### `GdbStub::run_blocking`: The quick and easy way to get up and running with `gdbstub`\"]\n//!\n//! If you've got an extra thread to spare, the quickest way to get up and\n//! running with `gdbstub` is by using the\n//! [`GdbStub::run_blocking`](stub::run_blocking) API alongside the\n//! [`BlockingEventLoop`] trait.\n//!\n//! If you are on a more resource constrained platform, and/or don't wish to\n//! dedicate an entire thread to `gdbstub`, feel free to skip ahead to the\n//! [following\n//! section](#gdbstubstatemachine-driving-gdbstub-in-an-async-event-loop--via-interrupt-handlers).\n//!\n//! A basic integration of `gdbstub` into a project using the\n//! `GdbStub::run_blocking` API might look something like this:\n//!\n//! ```rust\n//! # use gdbstub::target::ext::base::BaseOps;\n//! #\n//! # struct MyTarget;\n//! #\n//! # impl Target for MyTarget {\n//! #     type Error = &'static str;\n//! #     type Arch = gdbstub_arch::arm::Armv4t; // as an example\n//! #     fn base_ops(&mut self) -> BaseOps<Self::Arch, Self::Error> { todo!() }\n//! # }\n//! #\n//! # impl MyTarget {\n//! #     fn run_and_check_for_incoming_data(\n//! #         &mut self,\n//! #         conn: &mut impl Connection\n//! #     ) -> MyTargetEvent { todo!() }\n//! #\n//! #     fn stop_in_response_to_ctrl_c_interrupt(\n//! #         &mut self\n//! #     ) -> Result<(), &'static str> { todo!() }\n//! # }\n//! #\n//! # enum MyTargetEvent {\n//! #     IncomingData,\n//! #     StopReason(SingleThreadStopReason<u32>),\n//! # }\n//! #\n//! use gdbstub::common::Signal;\n//! use gdbstub::conn::{Connection, ConnectionExt}; // note the use of `ConnectionExt`\n//! use gdbstub::stub::{run_blocking, DisconnectReason, GdbStub};\n//! use gdbstub::stub::SingleThreadStopReason;\n//! use gdbstub::target::Target;\n//!\n//! enum MyGdbBlockingEventLoop {}\n//!\n//! // The `run_blocking::BlockingEventLoop` groups together various callbacks\n//! // the `GdbStub::run_blocking` event loop requires you to implement.\n//! impl run_blocking::BlockingEventLoop for MyGdbBlockingEventLoop {\n//!     type Target = MyTarget;\n//!     type Connection = Box<dyn ConnectionExt<Error = std::io::Error>>;\n//!\n//!     // or MultiThreadStopReason on multi threaded targets\n//!     type StopReason = SingleThreadStopReason<u32>;\n//!\n//!     // Invoked immediately after the target's `resume` method has been\n//!     // called. The implementation should block until either the target\n//!     // reports a stop reason, or if new data was sent over the connection.\n//!     fn wait_for_stop_reason(\n//!         target: &mut MyTarget,\n//!         conn: &mut Self::Connection,\n//!     ) -> Result<\n//!         run_blocking::Event<SingleThreadStopReason<u32>>,\n//!         run_blocking::WaitForStopReasonError<\n//!             <Self::Target as Target>::Error,\n//!             <Self::Connection as Connection>::Error,\n//!         >,\n//!     > {\n//!         // the specific mechanism to \"select\" between incoming data and target\n//!         // events will depend on your project's architecture.\n//!         //\n//!         // some examples of how you might implement this method include: `epoll`,\n//!         // `select!` across multiple event channels, periodic polling, etc...\n//!         //\n//!         // in this example, lets assume the target has a magic method that handles\n//!         // this for us.\n//!         let event = match target.run_and_check_for_incoming_data(conn) {\n//!             MyTargetEvent::IncomingData => {\n//!                 let byte = conn\n//!                     .read() // method provided by the `ConnectionExt` trait\n//!                     .map_err(run_blocking::WaitForStopReasonError::Connection)?;\n//!\n//!                 run_blocking::Event::IncomingData(byte)\n//!             }\n//!             MyTargetEvent::StopReason(reason) => {\n//!                 run_blocking::Event::TargetStopped(reason)\n//!             }\n//!         };\n//!\n//!         Ok(event)\n//!     }\n//!\n//!     // Invoked when the GDB client sends a Ctrl-C interrupt.\n//!     fn on_interrupt(\n//!         target: &mut MyTarget,\n//!     ) -> Result<Option<SingleThreadStopReason<u32>>, <MyTarget as Target>::Error> {\n//!         // notify the target that a ctrl-c interrupt has occurred.\n//!         target.stop_in_response_to_ctrl_c_interrupt()?;\n//!\n//!         // a pretty typical stop reason in response to a Ctrl-C interrupt is to\n//!         // report a \"Signal::SIGINT\".\n//!         Ok(Some(SingleThreadStopReason::Signal(Signal::SIGINT).into()))\n//!     }\n//! }\n//!\n//! fn gdb_event_loop_thread(\n//!     debugger: GdbStub<MyTarget, Box<dyn ConnectionExt<Error = std::io::Error>>>,\n//!     mut target: MyTarget\n//! ) {\n//!     match debugger.run_blocking::<MyGdbBlockingEventLoop>(&mut target) {\n//!         Ok(disconnect_reason) => match disconnect_reason {\n//!             DisconnectReason::Disconnect => {\n//!                 println!(\"Client disconnected\")\n//!             }\n//!             DisconnectReason::TargetExited(code) => {\n//!                 println!(\"Target exited with code {}\", code)\n//!             }\n//!             DisconnectReason::TargetTerminated(sig) => {\n//!                 println!(\"Target terminated with signal {}\", sig)\n//!             }\n//!             DisconnectReason::Kill => println!(\"GDB sent a kill command\"),\n//!         },\n//!         Err(e) => {\n//!             if e.is_target_error() {\n//!                 println!(\n//!                     \"target encountered a fatal error: {}\",\n//!                     e.into_target_error().unwrap()\n//!                 )\n//!             } else if e.is_connection_error() {\n//!                 let (e, kind) = e.into_connection_error().unwrap();\n//!                 println!(\"connection error: {:?} - {}\", kind, e,)\n//!             } else {\n//!                 println!(\"gdbstub encountered a fatal error: {}\", e)\n//!             }\n//!         }\n//!     }\n//! }\n//! ```\n// use an explicit doc attribute to avoid automatic rustfmt wrapping\n#![doc = \"### `GdbStubStateMachine`: Driving `gdbstub` in an async event loop / via interrupt handlers\"]\n//!\n//! `GdbStub::run_blocking` requires that the target implement the\n//! [`BlockingEventLoop`] trait, which as the name implies, uses _blocking_ IO\n//! when handling certain events. Blocking the thread is a totally reasonable\n//! approach in most implementations, as one can simply spin up a separate\n//! thread to run the GDB stub (or in certain emulator implementations, run the\n//! emulator as part of the `wait_for_stop_reason` method).\n//!\n//! Unfortunately, this blocking behavior can be a non-starter when integrating\n//! `gdbstub` in projects that don't support / wish to avoid the traditional\n//! thread-based execution model, such as projects using `async/await`, or\n//! bare-metal `no_std` projects running on embedded hardware.\n//!\n//! In these cases, `gdbstub` provides access to the underlying\n//! [`GdbStubStateMachine`] API, which gives implementations full control over\n//! the GDB stub's \"event loop\". This API requires implementations to \"push\"\n//! data to the `gdbstub` implementation whenever new data becomes available\n//! (e.g: when a UART interrupt handler receives a byte, when the target hits a\n//! breakpoint, etc...), as opposed to the `GdbStub::run_blocking` API, which\n//! \"pulls\" these events in a blocking manner.\n//!\n//! See the [`GdbStubStateMachine`] docs for more details on how to use this\n//! API.\n//!\n//! <br>\n//!\n//! * * *\n//!\n//! <br>\n//!\n//! And with that lengthy introduction, I wish you the best of luck in your\n//! debugging adventures!\n//!\n//! If you have any suggestions, feature requests, or run into any problems,\n//! please start a discussion / open an issue over on the\n//! [`gdbstub` GitHub repo](https://github.com/daniel5151/gdbstub/).\n//!\n//! [`GdbStubStateMachine`]: stub::state_machine::GdbStubStateMachine\n//! [`BlockingEventLoop`]: stub::run_blocking::BlockingEventLoop\n\n#![cfg_attr(not(feature = \"std\"), no_std)]\n#![cfg_attr(feature = \"paranoid_unsafe\", forbid(unsafe_code))]\n#![warn(missing_docs)]\n\n#[cfg(feature = \"alloc\")]\nextern crate alloc;\n\n#[macro_use]\nextern crate log;\n\nmod protocol;\nmod util;\n\n#[doc(hidden)]\npub mod internal;\n\npub mod arch;\npub mod common;\npub mod conn;\npub mod stub;\npub mod target;\n\n// https://users.rust-lang.org/t/compile-time-const-unwrapping/51619/7\n//\n// This works from Rust 1.46.0 onwards, which stabilized branching and looping\n// in const contexts.\nmacro_rules! unwrap {\n    ($e:expr $(,)*) => {\n        match $e {\n            ::core::option::Option::Some(x) => x,\n            #[allow(clippy::out_of_bounds_indexing)]\n            ::core::option::Option::None => {\n                [\"tried to unwrap a None\"][99];\n                loop {}\n            }\n        }\n    };\n}\n\n/// (Internal) The fake Tid that's used when running in single-threaded mode.\nconst SINGLE_THREAD_TID: common::Tid = unwrap!(common::Tid::new(1));\n/// (Internal) The fake Pid reported to GDB when the target hasn't opted into\n/// reporting a custom Pid itself.\nconst FAKE_PID: common::Pid = unwrap!(common::Pid::new(1));\n\npub(crate) mod is_valid_tid {\n    pub trait IsValidTid {}\n\n    impl IsValidTid for () {}\n    impl IsValidTid for crate::common::Tid {}\n}\n"
  },
  {
    "path": "src/protocol/commands/_QAgent.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct QAgent {\n    pub value: bool,\n}\n\nimpl<'a> ParseCommand<'a> for QAgent {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        let value = match body as &[u8] {\n            b\":0\" => false,\n            b\":1\" => true,\n            _ => return None,\n        };\n        Some(QAgent { value })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QCatchSyscalls.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::common::lists::ArgListHex;\n\n#[derive(Debug)]\npub enum QCatchSyscalls<'a> {\n    Disable,\n    Enable(ArgListHex<'a>),\n    EnableAll,\n}\n\nimpl<'a> ParseCommand<'a> for QCatchSyscalls<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n\n        match body {\n            [b':', b'0'] => Some(QCatchSyscalls::Disable),\n            [b':', b'1', b';', sysno @ ..] => {\n                Some(QCatchSyscalls::Enable(ArgListHex::from_packet(sysno)?))\n            }\n            [b':', b'1'] => Some(QCatchSyscalls::EnableAll),\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QDisableRandomization.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct QDisableRandomization {\n    pub value: bool,\n}\n\nimpl<'a> ParseCommand<'a> for QDisableRandomization {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        let value = match body as &[u8] {\n            b\":0\" => false,\n            b\":1\" => true,\n            _ => return None,\n        };\n        Some(QDisableRandomization { value })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QEnvironmentHexEncoded.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct QEnvironmentHexEncoded<'a> {\n    pub key: &'a [u8],\n    pub value: Option<&'a [u8]>,\n}\n\nimpl<'a> ParseCommand<'a> for QEnvironmentHexEncoded<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n\n        let (key, value) = match body {\n            [b':', keyval @ ..] => {\n                let keyval = decode_hex_buf(keyval).ok()?;\n                let mut keyval = keyval.splitn(2, |b| *b == b'=');\n                let key = keyval.next()?;\n                let value = match keyval.next()? {\n                    [] => None,\n                    s => Some(s),\n                };\n                (key, value)\n            }\n            _ => return None,\n        };\n\n        Some(QEnvironmentHexEncoded { key, value })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QEnvironmentReset.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct QEnvironmentReset;\n\nimpl<'a> ParseCommand<'a> for QEnvironmentReset {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(QEnvironmentReset)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QEnvironmentUnset.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct QEnvironmentUnset<'a> {\n    pub key: &'a [u8],\n}\n\nimpl<'a> ParseCommand<'a> for QEnvironmentUnset<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        let key = match body {\n            [b':', key @ ..] => decode_hex_buf(key).ok()?,\n            _ => return None,\n        };\n\n        Some(QEnvironmentUnset { key })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QSetWorkingDir.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct QSetWorkingDir<'a> {\n    pub dir: Option<&'a [u8]>,\n}\n\nimpl<'a> ParseCommand<'a> for QSetWorkingDir<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        let dir = match body {\n            [b':', dir @ ..] => match decode_hex_buf(dir).ok()? {\n                [] => None,\n                s => Some(s as &[u8]),\n            },\n            _ => return None,\n        };\n\n        Some(QSetWorkingDir { dir })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QStartNoAckMode.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct QStartNoAckMode;\n\nimpl<'a> ParseCommand<'a> for QStartNoAckMode {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(QStartNoAckMode)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QStartupWithShell.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct QStartupWithShell {\n    pub value: bool,\n}\n\nimpl<'a> ParseCommand<'a> for QStartupWithShell {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        let value = match body as &[u8] {\n            b\":0\" => false,\n            b\":1\" => true,\n            _ => return None,\n        };\n        Some(QStartupWithShell { value })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QTBuffer_upcase.rs",
    "content": "use super::prelude::*;\nuse crate::target::ext::tracepoints::BufferShape;\nuse crate::target::ext::tracepoints::TraceBufferConfig;\n\n#[derive(Debug)]\npub struct QTBuffer(pub TraceBufferConfig);\n\nimpl ParseCommand<'_> for QTBuffer {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'_>) -> Option<Self> {\n        match buf.into_body() {\n            [b':', body @ ..] => {\n                let mut s = body.splitn_mut(2, |b| *b == b':');\n                let opt = s.next()?;\n                // Clippy incorrect thinks this as_ref isn't needed, but it is.\n                #[allow(clippy::useless_asref)]\n                match opt.as_ref() {\n                    b\"circular\" => {\n                        let shape = s.next()?;\n                        Some(QTBuffer(TraceBufferConfig::Shape(match shape {\n                            [b'1'] => Some(BufferShape::Circular),\n                            [b'0'] => Some(BufferShape::Linear),\n                            _ => None,\n                        }?)))\n                    }\n                    b\"size\" => {\n                        let size = s.next()?;\n                        Some(QTBuffer(TraceBufferConfig::Size(match size {\n                            [b'-', b'1'] => None,\n                            i => Some(decode_hex(i).ok()?),\n                        })))\n                    }\n                    _ => None,\n                }\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QTDP.rs",
    "content": "use super::prelude::*;\nuse crate::target::ext::tracepoints::Tracepoint;\n\n#[derive(Debug)]\n#[allow(clippy::upper_case_acronyms)]\npub enum QTDP<'a> {\n    Create(CreateTDP<'a>),\n    Extend(ExtendTDP<'a>),\n}\n\n#[derive(Debug)]\npub struct CreateTDP<'a> {\n    pub number: Tracepoint,\n    pub addr: &'a [u8],\n    pub enable: bool,\n    pub step: u64,\n    pub pass: u64,\n    pub unsupported_option: Option<u8>,\n    pub more: bool,\n}\n\n#[derive(Debug)]\npub struct ExtendTDP<'a> {\n    pub number: Tracepoint,\n    pub addr: &'a [u8],\n    pub actions: &'a mut [u8],\n}\n\nimpl<'a> ParseCommand<'a> for QTDP<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        match body {\n            [b':', b'-', actions @ ..] => {\n                let mut params = actions.splitn_mut(4, |b| *b == b':');\n                let number = Tracepoint(decode_hex(params.next()?).ok()?);\n                let addr = decode_hex_buf(params.next()?).ok()?;\n                let actions = params.next()?;\n                Some(QTDP::Extend(ExtendTDP {\n                    number,\n                    addr,\n                    actions,\n                }))\n            }\n            [b':', tracepoint @ ..] => {\n                // Strip off the trailing '-' that indicates if there will be\n                // more packets after this\n                let (tracepoint, more) = match tracepoint {\n                    [rest @ .., b'-'] => (rest, true),\n                    x => (x, false),\n                };\n                let mut params = tracepoint.splitn_mut(6, |b| *b == b':');\n                let n = Tracepoint(decode_hex(params.next()?).ok()?);\n                let addr = decode_hex_buf(params.next()?).ok()?;\n                let ena = params.next()?;\n                let step = decode_hex(params.next()?).ok()?;\n                let pass_and_end = params.next()?;\n                let pass = decode_hex(pass_and_end).ok()?;\n                // TODO: parse `F` fast tracepoint options\n                // TODO: parse `X` tracepoint conditions\n                let options = params.next();\n                let unsupported_option = match options {\n                    Some([b'F', ..]) => {\n                        /* TODO: fast tracepoints support */\n                        Some(b'F')\n                    }\n                    Some([b'S']) => {\n                        /* TODO: static tracepoint support */\n                        Some(b'S')\n                    }\n                    Some([b'X', ..]) => {\n                        /* TODO: trace conditions support */\n                        Some(b'X')\n                    }\n                    Some(_) => {\n                        /* invalid option */\n                        return None;\n                    }\n                    None => None,\n                };\n                Some(QTDP::Create(CreateTDP {\n                    number: n,\n                    addr,\n                    enable: match ena {\n                        [b'E'] => Some(true),\n                        [b'D'] => Some(false),\n                        _ => None,\n                    }?,\n                    step,\n                    pass,\n                    more,\n                    unsupported_option,\n                }))\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QTDPsrc.rs",
    "content": "use super::prelude::*;\nuse crate::target::ext::tracepoints::Tracepoint;\nuse crate::target::ext::tracepoints::TracepointSourceType;\n\npub struct QTDPsrc<'a> {\n    pub number: Tracepoint,\n    pub addr: &'a [u8],\n    pub kind: TracepointSourceType,\n    pub start: u32,\n    pub slen: u32,\n    pub bytes: &'a mut [u8],\n}\n\nimpl<'a> ParseCommand<'a> for QTDPsrc<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        match body {\n            [b':', info @ ..] => {\n                let mut params = info.splitn_mut(7, |b| *b == b':');\n                let number = Tracepoint(decode_hex(params.next()?).ok()?);\n                let addr = decode_hex_buf(params.next()?).ok()?;\n                // Clippy incorrect thinks this as_ref isn't needed, but it is.\n                #[allow(clippy::useless_asref)]\n                let kind = match params.next()?.as_ref() {\n                    b\"at\" => Some(TracepointSourceType::At),\n                    b\"cond\" => Some(TracepointSourceType::Cond),\n                    b\"cmd\" => Some(TracepointSourceType::Cmd),\n                    _ => None,\n                }?;\n                let start = decode_hex(params.next()?).ok()?;\n                let slen = decode_hex(params.next()?).ok()?;\n                let bytes = decode_hex_buf(params.next()?).ok()?;\n                Some(QTDPsrc {\n                    number,\n                    addr,\n                    kind,\n                    start,\n                    slen,\n                    bytes,\n                })\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QTFrame.rs",
    "content": "use super::prelude::*;\nuse crate::target::ext::tracepoints::FrameRequest;\nuse crate::target::ext::tracepoints::Tracepoint;\n\n#[derive(Debug)]\npub struct QTFrame<'a>(pub FrameRequest<&'a mut [u8]>);\n\nimpl<'a> ParseCommand<'a> for QTFrame<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        match body {\n            [b':', body @ ..] => {\n                let mut s = body.split_mut(|b| *b == b':');\n                let selector = s.next()?;\n                // Clippy incorrect thinks this as_ref isn't needed, but it is.\n                #[allow(clippy::useless_asref)]\n                Some(match selector.as_ref() {\n                    b\"pc\" => {\n                        let addr = decode_hex_buf(s.next()?).ok()?;\n                        QTFrame(FrameRequest::AtPC(addr))\n                    }\n                    b\"tdp\" => {\n                        let tp = Tracepoint(decode_hex(s.next()?).ok()?);\n                        QTFrame(FrameRequest::Hit(tp))\n                    }\n                    b\"range\" => {\n                        let start = decode_hex_buf(s.next()?).ok()?;\n                        let end = decode_hex_buf(s.next()?).ok()?;\n                        QTFrame(FrameRequest::Between(start, end))\n                    }\n                    b\"outside\" => {\n                        let start = decode_hex_buf(s.next()?).ok()?;\n                        let end = decode_hex_buf(s.next()?).ok()?;\n                        QTFrame(FrameRequest::Outside(start, end))\n                    }\n                    n => QTFrame(FrameRequest::Select(decode_hex(n).ok()?)),\n                })\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QTStart.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct QTStart;\n\nimpl<'a> ParseCommand<'a> for QTStart {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(QTStart)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QTStop.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct QTStop;\n\nimpl<'a> ParseCommand<'a> for QTStop {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(QTStop)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_QTinit.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct QTinit;\n\nimpl<'a> ParseCommand<'a> for QTinit {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(QTinit)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_bc.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct bc;\n\nimpl<'a> ParseCommand<'a> for bc {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(bc)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_bs.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct bs;\n\nimpl<'a> ParseCommand<'a> for bs {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(bs)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_c.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct c<'a> {\n    pub addr: Option<&'a [u8]>,\n}\n\nimpl<'a> ParseCommand<'a> for c<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        if body.is_empty() {\n            return Some(c { addr: None });\n        }\n        let addr = match body {\n            [] => None,\n            _ => Some(decode_hex_buf(body).ok()? as &[u8]),\n        };\n        Some(c { addr })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_d_upcase.rs",
    "content": "use super::prelude::*;\nuse crate::common::Pid;\n\n#[derive(Debug)]\npub struct D {\n    pub pid: Option<Pid>,\n}\n\nimpl<'a> ParseCommand<'a> for D {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        let pid = match body {\n            [b';', pid @ ..] => Some(Pid::new(decode_hex(pid).ok()?)?),\n            _ => None,\n        };\n        Some(D { pid })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_g.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct g;\n\nimpl<'a> ParseCommand<'a> for g {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(g)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_g_upcase.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct G<'a> {\n    pub vals: &'a [u8],\n}\n\nimpl<'a> ParseCommand<'a> for G<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        Some(G {\n            vals: decode_hex_buf(buf.into_body()).ok()?,\n        })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_h_upcase.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::common::thread_id::ThreadId;\n\n#[derive(Debug)]\npub enum Op {\n    StepContinue,\n    Other,\n}\n\n#[derive(Debug)]\npub struct H {\n    pub kind: Op,\n    pub thread: ThreadId,\n}\n\nimpl<'a> ParseCommand<'a> for H {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        if body.is_empty() {\n            return None;\n        }\n\n        let kind = match body[0] {\n            b'g' => Op::Other,\n            b'c' => Op::StepContinue,\n            _ => return None,\n        };\n        let thread: ThreadId = body[1..].try_into().ok()?;\n\n        Some(H { kind, thread })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_k.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct k;\n\nimpl<'a> ParseCommand<'a> for k {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(k)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_m.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct m<'a> {\n    pub addr: &'a [u8],\n    pub len: usize,\n\n    pub buf: &'a mut [u8],\n}\n\nimpl<'a> ParseCommand<'a> for m<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        // the total packet buffer currently looks like:\n        //\n        // +------+--------------------+-------------------+-------+-----------------+\n        // | \"$m\" | addr (hex-encoded) | len (hex-encoded) | \"#XX\" | empty space ... |\n        // +------+--------------------+-------------------+-------+-----------------+\n        //\n        // Unfortunately, while `len` can be hex-decoded right here and now into a\n        // `usize`, `addr` corresponds to a Target::Arch::Usize, which requires holding\n        // on to a valid &[u8] reference into the buffer.\n        //\n        // While it's not _perfectly_ efficient, simply leaving the decoded addr in\n        // place and wasting a couple bytes is probably the easiest way to tackle this\n        // problem:\n        //\n        // +------+------------------+------------------------------------------------+\n        // | \"$m\" | addr (raw bytes) | usable buffer ...                              |\n        // +------+------------------+------------------------------------------------+\n\n        let (buf, body_range) = buf.into_raw_buf();\n        let body = buf.get_mut(body_range.start..body_range.end)?;\n\n        let mut body = body.split_mut(|b| *b == b',');\n\n        let addr = decode_hex_buf(body.next()?).ok()?;\n        let addr_len = addr.len();\n        let len = decode_hex(body.next()?).ok()?;\n\n        // ensures that `split_at_mut` doesn't panic\n        if buf.len() < body_range.start + addr_len {\n            return None;\n        }\n\n        let (addr, buf) = buf.split_at_mut(body_range.start + addr_len);\n        let addr = addr.get(b\"$m\".len()..)?;\n\n        Some(m { addr, len, buf })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_m_upcase.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct M<'a> {\n    pub addr: &'a [u8],\n    pub val: &'a [u8],\n}\n\nimpl<'a> ParseCommand<'a> for M<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n\n        let mut body = body.split_mut(|&b| b == b',' || b == b':');\n        let addr = decode_hex_buf(body.next()?).ok()?;\n        // The length part of the packet doesn't appear to actually be useful,\n        // given that it can be trivially derived from the amount of data read\n        // in via `val`.\n        //\n        // As such - we'll still parse it to ensure the packet is\n        // spec-compliant, but we won't stash the parsed length anywhere.\n        //\n        // TODO?: dig into whether any GDB clients actually attempt to send over\n        // a mismatched `len` and `val` (e.g: sending a longer `val`, with `len`\n        // used to truncate the data). My gut feeling is that this would never\n        // actually occur in practice (and the fact that `gdbstub` has gotten\n        // away with not handling this for many years at this point reinforces\n        // that gut feeling).\n        let _len: usize = decode_hex(body.next()?).ok()?;\n        let val = decode_hex_buf(body.next()?).ok()?;\n\n        Some(M { addr, val })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_p.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct p<'a> {\n    pub reg_id: usize,\n\n    pub buf: &'a mut [u8],\n}\n\nimpl<'a> ParseCommand<'a> for p<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let (buf, body_range) = buf.into_raw_buf();\n        let body = buf.get(body_range.start..body_range.end)?;\n\n        if body.is_empty() {\n            return None;\n        }\n\n        let reg_id = decode_hex(body).ok()?;\n\n        Some(p { reg_id, buf })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_p_upcase.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct P<'a> {\n    pub reg_id: usize,\n    pub val: &'a [u8],\n}\n\nimpl<'a> ParseCommand<'a> for P<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        let mut body = body.split_mut(|&b| b == b'=');\n        let reg_id = decode_hex(body.next()?).ok()?;\n        let val = decode_hex_buf(body.next()?).ok()?;\n        Some(P { reg_id, val })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qAttached.rs",
    "content": "use super::prelude::*;\nuse crate::common::Pid;\n\n#[derive(Debug)]\npub struct qAttached {\n    pub pid: Option<Pid>,\n}\n\nimpl<'a> ParseCommand<'a> for qAttached {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        let pid = match body {\n            [b':', pid @ ..] => Some(Pid::new(decode_hex(pid).ok()?)?),\n            _ => None,\n        };\n        Some(qAttached { pid })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qC.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qC;\n\nimpl<'a> ParseCommand<'a> for qC {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(qC)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qHostInfo.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qHostInfo;\n\nimpl<'a> ParseCommand<'a> for qHostInfo {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(qHostInfo)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qOffsets.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qOffsets;\n\nimpl<'a> ParseCommand<'a> for qOffsets {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        crate::__dead_code_marker!(\"qOffsets\", \"from_packet\");\n\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(qOffsets)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qProcessInfo.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qProcessInfo;\n\nimpl<'a> ParseCommand<'a> for qProcessInfo {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(qProcessInfo)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qRcmd.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qRcmd<'a> {\n    pub hex_cmd: &'a [u8],\n}\n\nimpl<'a> ParseCommand<'a> for qRcmd<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        crate::__dead_code_marker!(\"qRcmd\", \"from_packet\");\n\n        let body = buf.into_body();\n        match body {\n            [] => Some(qRcmd { hex_cmd: &[] }),\n            [b',', hex_cmd @ ..] => Some(qRcmd {\n                hex_cmd: decode_hex_buf(hex_cmd).ok()?,\n            }),\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qRegisterInfo.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qRegisterInfo {\n    pub reg_id: usize,\n}\n\nimpl<'a> ParseCommand<'a> for qRegisterInfo {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n\n        let reg_id = decode_hex(body).ok()?;\n\n        Some(qRegisterInfo { reg_id })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qSupported.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qSupported<'a> {\n    pub packet_buffer_len: usize,\n    pub features: Features<'a>,\n}\n\nimpl<'a> ParseCommand<'a> for qSupported<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let packet_buffer_len = buf.full_len();\n        let body = buf.into_body();\n        match body {\n            [b':', body @ ..] => Some(qSupported {\n                packet_buffer_len,\n                features: Features(body),\n            }),\n            _ => None,\n        }\n    }\n}\n\n#[derive(Debug)]\npub struct Features<'a>(&'a [u8]);\n\nimpl<'a> Features<'a> {\n    pub fn into_iter(self) -> impl Iterator<Item = Result<Option<(Feature, bool)>, ()>> + 'a {\n        self.0.split(|b| *b == b';').map(|s| match s.last() {\n            None => Err(()),\n            Some(&c) => match c {\n                b'+' | b'-' => {\n                    let feature = match &s[..s.len() - 1] {\n                        b\"multiprocess\" => Feature::Multiprocess,\n                        // TODO: implementing other features will require IDET plumbing\n                        _ => return Ok(None),\n                    };\n                    Ok(Some((feature, c == b'+')))\n                }\n                _ => {\n                    // TODO: add support for \"xmlRegisters=\"\n                    // that's the only feature packet that uses an '=', and AFAIK, it's not really\n                    // used anymore...\n                    Ok(None)\n                }\n            },\n        })\n    }\n}\n\n#[derive(Debug)]\npub enum Feature {\n    Multiprocess,\n}\n"
  },
  {
    "path": "src/protocol/commands/_qTBuffer.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qTBuffer {\n    pub offset: u64,\n    pub length: usize,\n}\n\nimpl<'a> ParseCommand<'a> for qTBuffer {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let (buf, body_range) = buf.into_raw_buf();\n        let body = &buf[body_range];\n        match body {\n            [b':', body @ ..] => {\n                let mut req_opts = body.split(|b| *b == b',');\n                let (offset, length) = (req_opts.next()?, req_opts.next()?);\n                let offset = decode_hex(offset).ok()?;\n                let length = decode_hex(length).ok()?;\n                Some(qTBuffer { offset, length })\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qTP.rs",
    "content": "use super::prelude::*;\nuse crate::target::ext::tracepoints::Tracepoint;\n\n#[derive(Debug)]\npub struct qTP<'a> {\n    pub tracepoint: Tracepoint,\n    pub addr: &'a [u8],\n}\n\nimpl<'a> ParseCommand<'a> for qTP<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        match body {\n            [b':', body @ ..] => {\n                let mut s = body.split_mut(|b| *b == b':');\n                let tracepoint = Tracepoint(decode_hex(s.next()?).ok()?);\n                let addr = decode_hex_buf(s.next()?).ok()?;\n                Some(qTP { tracepoint, addr })\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qTStatus.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qTStatus;\n\nimpl<'a> ParseCommand<'a> for qTStatus {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(qTStatus)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qTfP.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qTfP;\n\nimpl<'a> ParseCommand<'a> for qTfP {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(qTfP)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qTfV.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qTfV;\n\nimpl<'a> ParseCommand<'a> for qTfV {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(qTfV)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qThreadExtraInfo.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::common::thread_id::ThreadId;\nuse crate::protocol::ConcreteThreadId;\n\n#[derive(Debug)]\npub struct qThreadExtraInfo<'a> {\n    pub id: ConcreteThreadId,\n\n    pub buf: &'a mut [u8],\n}\n\nimpl<'a> ParseCommand<'a> for qThreadExtraInfo<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let (buf, body_range) = buf.into_raw_buf();\n        let body = buf.get(body_range.start..body_range.end)?;\n\n        if body.is_empty() {\n            return None;\n        }\n\n        match body {\n            [b',', body @ ..] => {\n                let id = ConcreteThreadId::try_from(ThreadId::try_from(body).ok()?).ok()?;\n\n                Some(qThreadExtraInfo { id, buf })\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qTsP.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qTsP;\n\nimpl<'a> ParseCommand<'a> for qTsP {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(qTsP)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qTsV.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qTsV;\n\nimpl<'a> ParseCommand<'a> for qTsV {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(qTsV)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qWasmCallStack.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::common::thread_id::ThreadId;\nuse crate::protocol::ConcreteThreadId;\n\n#[derive(Debug)]\npub struct qWasmCallStack {\n    pub tid: ConcreteThreadId,\n}\n\nimpl<'a> ParseCommand<'a> for qWasmCallStack {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        if body.is_empty() || body[0] != b':' {\n            return None;\n        }\n        let tid = &body[1..];\n        let tid = ConcreteThreadId::try_from(ThreadId::try_from(tid).ok()?).ok()?;\n        Some(qWasmCallStack { tid })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qWasmGlobal.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qWasmGlobal<'a> {\n    pub frame: usize,\n    pub global: usize,\n    pub buf: &'a mut [u8],\n}\n\nimpl<'a> ParseCommand<'a> for qWasmGlobal<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let (buf, body_range) = buf.into_raw_buf();\n        let body = buf.get(body_range.start..body_range.end)?;\n\n        if body.is_empty() || body[0] != b':' {\n            return None;\n        }\n        let mut parts = body[1..].split(|b| *b == b';');\n        let frame = parts.next()?;\n        let frame = str::from_utf8(frame).ok()?.parse::<usize>().ok()?;\n        let global = parts.next()?;\n        let global = str::from_utf8(global).ok()?.parse::<usize>().ok()?;\n        if parts.next().is_some() {\n            // Too many parameters.\n            return None;\n        }\n\n        Some(qWasmGlobal {\n            frame,\n            global,\n            buf,\n        })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qWasmLocal.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qWasmLocal<'a> {\n    pub frame: usize,\n    pub local: usize,\n    pub buf: &'a mut [u8],\n}\n\nimpl<'a> ParseCommand<'a> for qWasmLocal<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let (buf, body_range) = buf.into_raw_buf();\n        let body = buf.get(body_range.start..body_range.end)?;\n\n        if body.is_empty() || body[0] != b':' {\n            return None;\n        }\n        let mut parts = body[1..].split(|b| *b == b';');\n        let frame = parts.next()?;\n        let frame = str::from_utf8(frame).ok()?.parse::<usize>().ok()?;\n        let local = parts.next()?;\n        let local = str::from_utf8(local).ok()?.parse::<usize>().ok()?;\n        if parts.next().is_some() {\n            // Too many parameters.\n            return None;\n        }\n\n        Some(qWasmLocal {\n            frame,\n            local,\n            buf,\n        })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qWasmStackValue.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qWasmStackValue<'a> {\n    pub frame: usize,\n    pub index: usize,\n    pub buf: &'a mut [u8],\n}\n\nimpl<'a> ParseCommand<'a> for qWasmStackValue<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let (buf, body_range) = buf.into_raw_buf();\n        let body = buf.get(body_range.start..body_range.end)?;\n\n        if body.is_empty() || body[0] != b':' {\n            return None;\n        }\n        let mut parts = body[1..].split(|b| *b == b';');\n        let frame = parts.next()?;\n        let frame = str::from_utf8(frame).ok()?.parse::<usize>().ok()?;\n        let index = parts.next()?;\n        let index = str::from_utf8(index).ok()?.parse::<usize>().ok()?;\n        if parts.next().is_some() {\n            // Too many parameters.\n            return None;\n        }\n\n        Some(qWasmStackValue {\n            frame,\n            index,\n            buf,\n        })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qXfer_auxv_read.rs",
    "content": "// use super::prelude::*; // unused\nuse crate::protocol::common::qxfer::ParseAnnex;\nuse crate::protocol::common::qxfer::QXferReadBase;\n\npub type qXferAuxvRead<'a> = QXferReadBase<'a, AuxvAnnex>;\n\n#[derive(Debug)]\npub struct AuxvAnnex;\n\nimpl ParseAnnex<'_> for AuxvAnnex {\n    #[inline(always)]\n    fn from_buf(buf: &[u8]) -> Option<Self> {\n        if buf != b\"\" {\n            return None;\n        }\n\n        Some(AuxvAnnex)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qXfer_exec_file.rs",
    "content": "use super::prelude::*;\nuse crate::common::Pid;\nuse crate::protocol::common::qxfer::ParseAnnex;\nuse crate::protocol::common::qxfer::QXferReadBase;\n\npub type qXferExecFileRead<'a> = QXferReadBase<'a, ExecFileAnnex>;\n\n#[derive(Debug)]\npub struct ExecFileAnnex {\n    pub pid: Option<Pid>,\n}\n\nimpl ParseAnnex<'_> for ExecFileAnnex {\n    #[inline(always)]\n    fn from_buf(buf: &[u8]) -> Option<Self> {\n        let pid = match buf {\n            [] => None,\n            buf => Some(Pid::new(decode_hex(buf).ok()?)?),\n        };\n\n        Some(ExecFileAnnex { pid })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qXfer_features_read.rs",
    "content": "// use super::prelude::*; // unused\nuse crate::protocol::common::qxfer::ParseAnnex;\nuse crate::protocol::common::qxfer::QXferReadBase;\n\npub type qXferFeaturesRead<'a> = QXferReadBase<'a, FeaturesAnnex<'a>>;\n\n#[derive(Debug)]\npub struct FeaturesAnnex<'a> {\n    pub name: &'a [u8],\n}\n\nimpl<'a> ParseAnnex<'a> for FeaturesAnnex<'a> {\n    #[inline(always)]\n    fn from_buf(buf: &'a [u8]) -> Option<Self> {\n        Some(FeaturesAnnex { name: buf })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qXfer_libraries_read.rs",
    "content": "use crate::protocol::common::qxfer::ParseAnnex;\nuse crate::protocol::common::qxfer::QXferReadBase;\n\npub type qXferLibrariesRead<'a> = QXferReadBase<'a, LibrariesAnnex>;\n\n#[derive(Debug)]\npub struct LibrariesAnnex;\n\nimpl ParseAnnex<'_> for LibrariesAnnex {\n    #[inline(always)]\n    fn from_buf(buf: &[u8]) -> Option<Self> {\n        if buf != b\"\" {\n            return None;\n        }\n\n        Some(LibrariesAnnex)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qXfer_libraries_svr4_read.rs",
    "content": "use crate::protocol::common::qxfer::ParseAnnex;\nuse crate::protocol::common::qxfer::QXferReadBase;\n\npub type qXferLibrariesSvr4Read<'a> = QXferReadBase<'a, LibrariesSvr4Annex>;\n\n#[derive(Debug)]\npub struct LibrariesSvr4Annex;\n\nimpl ParseAnnex<'_> for LibrariesSvr4Annex {\n    #[inline(always)]\n    fn from_buf(buf: &[u8]) -> Option<Self> {\n        if buf != b\"\" {\n            return None;\n        }\n\n        Some(LibrariesSvr4Annex)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qXfer_memory_map.rs",
    "content": "// use super::prelude::*; // unused\nuse crate::protocol::common::qxfer::ParseAnnex;\nuse crate::protocol::common::qxfer::QXferReadBase;\n\npub type qXferMemoryMapRead<'a> = QXferReadBase<'a, MemoryMapAnnex>;\n\n#[derive(Debug)]\npub struct MemoryMapAnnex;\n\nimpl ParseAnnex<'_> for MemoryMapAnnex {\n    #[inline(always)]\n    fn from_buf(buf: &[u8]) -> Option<Self> {\n        if buf != b\"\" {\n            return None;\n        }\n\n        Some(MemoryMapAnnex)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qfThreadInfo.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qfThreadInfo;\n\nimpl<'a> ParseCommand<'a> for qfThreadInfo {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(qfThreadInfo)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_qsThreadInfo.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct qsThreadInfo;\n\nimpl<'a> ParseCommand<'a> for qsThreadInfo {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(qsThreadInfo)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_r_upcase.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct R;\n\nimpl<'a> ParseCommand<'a> for R {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        crate::__dead_code_marker!(\"R\", \"from_packet\");\n\n        // Technically speaking, the `R` packet does include a hex-encoded byte as well,\n        // but even the GDB docs mention that it's unused (heck, the source-level\n        // comments in the GDB client suggest no-one really knows what it's used for).\n        //\n        // We'll pay some lip-service to this requirement by checking the body's length,\n        // but we won't actually parse the number.\n        let body = buf.into_body();\n        if body.len() != 2 {\n            None\n        } else {\n            Some(R)\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_s.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct s<'a> {\n    pub addr: Option<&'a [u8]>,\n}\n\nimpl<'a> ParseCommand<'a> for s<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        if body.is_empty() {\n            return Some(s { addr: None });\n        }\n        let addr = match body {\n            [] => None,\n            _ => Some(decode_hex_buf(body).ok()? as &[u8]),\n        };\n        Some(s { addr })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_t_upcase.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::common::thread_id::ThreadId;\n\n#[derive(Debug)]\npub struct T {\n    pub thread: ThreadId,\n}\n\nimpl<'a> ParseCommand<'a> for T {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        Some(T {\n            thread: body.try_into().ok()?,\n        })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vAttach.rs",
    "content": "use super::prelude::*;\nuse crate::common::Pid;\n\n#[derive(Debug)]\npub struct vAttach {\n    pub pid: Pid,\n}\n\nimpl<'a> ParseCommand<'a> for vAttach {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        crate::__dead_code_marker!(\"vAttach\", \"from_packet\");\n\n        let body = buf.into_body();\n        let pid = match body {\n            [b';', pid @ ..] => Pid::new(decode_hex(pid).ok()?)?,\n            _ => return None,\n        };\n        Some(vAttach { pid })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vCont.rs",
    "content": "use super::prelude::*;\nuse crate::common::Signal;\nuse crate::protocol::common::hex::HexString;\nuse crate::protocol::common::thread_id::SpecificThreadId;\nuse crate::protocol::common::thread_id::ThreadId;\nuse crate::protocol::IdKind;\n\n// TODO?: instead of lazily parsing data, parse the strings into a compressed\n// binary representations that can be stuffed back into the packet buffer and\n// return an iterator over the binary data that's _guaranteed_ to be valid. This\n// would clean up some of the code in the vCont handler.\n//\n// The interesting part would be to see whether or not the simplified error\n// handing code will compensate for all the new code required to pre-validate\n// the data...\n#[derive(Debug)]\npub enum vCont<'a> {\n    Query,\n    Actions(Actions<'a>),\n}\n\nimpl<'a> ParseCommand<'a> for vCont<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        match body as &[u8] {\n            b\"?\" => Some(vCont::Query),\n            _ => Some(vCont::Actions(Actions::new_from_buf(body))),\n        }\n    }\n}\n\n#[derive(Debug)]\npub enum Actions<'a> {\n    Buf(ActionsBuf<'a>),\n    FixedStep(SpecificThreadId),\n    FixedCont(SpecificThreadId),\n}\n\nimpl<'a> Actions<'a> {\n    fn new_from_buf(buf: &'a [u8]) -> Actions<'a> {\n        Actions::Buf(ActionsBuf(buf))\n    }\n\n    #[inline(always)]\n    pub fn new_step(tid: SpecificThreadId) -> Actions<'a> {\n        Actions::FixedStep(tid)\n    }\n\n    #[inline(always)]\n    pub fn new_continue(tid: SpecificThreadId) -> Actions<'a> {\n        Actions::FixedCont(tid)\n    }\n\n    pub fn iter(&self) -> impl Iterator<Item = Option<VContAction<'a>>> + '_ {\n        match self {\n            Actions::Buf(x) => EitherIter::A(x.iter()),\n            Actions::FixedStep(x) => EitherIter::B(core::iter::once(Some(VContAction {\n                kind: VContKind::Step,\n                thread: Some(*x),\n            }))),\n            Actions::FixedCont(x) => EitherIter::B(core::iter::once(Some(VContAction {\n                kind: VContKind::Continue,\n                thread: Some(*x),\n            }))),\n        }\n    }\n}\n\n#[derive(Debug)]\npub struct ActionsBuf<'a>(&'a [u8]);\n\nimpl<'a> ActionsBuf<'a> {\n    fn iter(&self) -> impl Iterator<Item = Option<VContAction<'a>>> + '_ {\n        self.0.split(|b| *b == b';').skip(1).map(|act| {\n            let mut s = act.split(|b| *b == b':');\n            let kind = s.next()?;\n            let thread = match s.next() {\n                Some(s) => {\n                    let mut tid = ThreadId::try_from(s).ok()?;\n\n                    // Based on my (somewhat superficial) readings of the\n                    // `gdbserver` and `gdb` codebases, it doesn't seem like\n                    // there's any consensus on how vCont packets with a TID of\n                    // `Any` should be be handled.\n                    //\n                    // `gdbserver` delegates the handling of this packet to\n                    // individual targets, and in-turn, it seems most targets\n                    // don't actually do any special handling of the 'Any' TID.\n                    // They'll explicitly check for the 'All' TID, but then\n                    // proceed to erroneously treat the 'Any' TID as though it\n                    // was simply a request for a TID with ID of '0' to be\n                    // resumed (which is prohibited by the GDB RSP spec).\n                    //\n                    // This behavior makes sense, given the context that AFAIK,\n                    // upstream GDB never actually sends vCont packets with a\n                    // 'Any' TID! Instead, upstream GDB will first query the\n                    // remote to obtain a list of valid TIDs, and then send over\n                    // a vCont packet with a specific TID selected.\n\n                    // So, with all that said - how should `gdbstub` handle\n                    // these sorts of packets?\n                    //\n                    // Unfortunately, it seems like there are some weird\n                    // third-party GDB clients out there that do in-fact send an\n                    // 'Any' TID as part of a vCont packet.\n                    //\n                    // See issue #150 for more info.\n                    //\n                    // As a workaround for these weird GDB clients, `gdbstub`\n                    // takes the pragmatic approach of treating this request as\n                    // though it the client requested _all_ threads to be\n                    // resumed.\n                    //\n                    // If this turns out to be wrong... `gdbstub` can explore a\n                    // more involved fix, whereby we bubble-up this `Any`\n                    // request to the stub code itself, whereupon the stub can\n                    // attempt to pick a \"reasonable\" TID to individually\n                    // resume.\n                    if tid.tid == IdKind::Any {\n                        tid.tid = IdKind::All;\n                    }\n\n                    Some(SpecificThreadId::try_from(tid).ok()?)\n                }\n                None => None,\n            };\n\n            Some(VContAction {\n                kind: VContKind::from_bytes(kind)?,\n                thread,\n            })\n        })\n    }\n}\n\n#[derive(Debug, Copy, Clone)]\npub struct VContAction<'a> {\n    pub kind: VContKind<'a>,\n    pub thread: Option<SpecificThreadId>,\n}\n\n#[derive(Debug, Copy, Clone)]\npub enum VContKind<'a> {\n    Continue,\n    ContinueWithSig(Signal),\n    RangeStep(HexString<'a>, HexString<'a>),\n    Step,\n    StepWithSig(Signal),\n    Stop,\n}\n\nimpl VContKind<'_> {\n    #[inline(always)]\n    fn from_bytes(s: &[u8]) -> Option<VContKind<'_>> {\n        use self::VContKind::*;\n\n        let res = match s {\n            [b'c'] => Continue,\n            [b's'] => Step,\n            [b't'] => Stop,\n            [b'C', sig @ ..] => ContinueWithSig(Signal(decode_hex(sig).ok()?)),\n            [b'S', sig @ ..] => StepWithSig(Signal(decode_hex(sig).ok()?)),\n            [b'r', range @ ..] => {\n                let mut range = range.split(|b| *b == b',');\n                RangeStep(HexString(range.next()?), HexString(range.next()?))\n            }\n            _ => return None,\n        };\n\n        Some(res)\n    }\n}\n\n/// Helper type to unify iterators that output the same type. Returned as an\n/// opaque type from `Actions::iter()`.\nenum EitherIter<A, B> {\n    A(A),\n    B(B),\n}\n\nimpl<A, B, T> Iterator for EitherIter<A, B>\nwhere\n    A: Iterator<Item = T>,\n    B: Iterator<Item = T>,\n{\n    type Item = T;\n\n    #[inline(always)]\n    fn next(&mut self) -> Option<T> {\n        match self {\n            EitherIter::A(a) => a.next(),\n            EitherIter::B(b) => b.next(),\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vFile_close.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct vFileClose {\n    pub fd: u32,\n}\n\nimpl<'a> ParseCommand<'a> for vFileClose {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        if body.is_empty() {\n            return None;\n        }\n\n        match body {\n            [b':', body @ ..] => {\n                let fd = decode_hex(body).ok()?;\n                Some(vFileClose { fd })\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vFile_fstat.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct vFileFstat {\n    pub fd: u32,\n}\n\nimpl<'a> ParseCommand<'a> for vFileFstat {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        if body.is_empty() {\n            return None;\n        }\n\n        match body {\n            [b':', body @ ..] => {\n                let fd = decode_hex(body).ok()?;\n                Some(vFileFstat { fd })\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vFile_open.rs",
    "content": "use super::prelude::*;\nuse crate::target::ext::host_io::HostIoOpenFlags;\nuse crate::target::ext::host_io::HostIoOpenMode;\n\n#[derive(Debug)]\npub struct vFileOpen<'a> {\n    pub filename: &'a [u8],\n    pub flags: HostIoOpenFlags,\n    pub mode: HostIoOpenMode,\n}\n\nimpl<'a> ParseCommand<'a> for vFileOpen<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        if body.is_empty() {\n            return None;\n        }\n\n        match body {\n            [b':', body @ ..] => {\n                let mut body = body.splitn_mut(3, |b| *b == b',');\n                let filename = decode_hex_buf(body.next()?).ok()?;\n                let flags = HostIoOpenFlags::from_bits(decode_hex(body.next()?).ok()?)?;\n                let mode = HostIoOpenMode::from_bits(decode_hex(body.next()?).ok()?)?;\n                Some(vFileOpen {\n                    filename,\n                    flags,\n                    mode,\n                })\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vFile_pread.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct vFilePread<'a> {\n    pub fd: u32,\n    pub count: usize,\n    pub offset: u64,\n\n    pub buf: &'a mut [u8],\n}\n\nimpl<'a> ParseCommand<'a> for vFilePread<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let (buf, body_range) = buf.into_raw_buf();\n        let body = buf.get_mut(body_range.start..body_range.end)?;\n\n        if body.is_empty() {\n            return None;\n        }\n\n        match body {\n            [b':', body @ ..] => {\n                let mut body = body.splitn_mut(3, |b| *b == b',');\n                let fd = decode_hex(body.next()?).ok()?;\n                let count = decode_hex(body.next()?).ok()?;\n                let offset = decode_hex(body.next()?).ok()?;\n\n                Some(vFilePread {\n                    fd,\n                    count,\n                    offset,\n                    buf,\n                })\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vFile_pwrite.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::common::hex::decode_bin_buf;\n\n#[derive(Debug)]\npub struct vFilePwrite<'a> {\n    pub fd: u32,\n    pub offset: &'a [u8],\n    pub data: &'a [u8],\n}\n\nimpl<'a> ParseCommand<'a> for vFilePwrite<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        if body.is_empty() {\n            return None;\n        }\n\n        match body {\n            [b':', body @ ..] => {\n                let mut body = body.splitn_mut(3, |b| *b == b',');\n                let fd = decode_hex(body.next()?).ok()?;\n                let offset = decode_hex_buf(body.next()?).ok()?;\n                let data = decode_bin_buf(body.next()?)?;\n                Some(vFilePwrite { fd, offset, data })\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vFile_readlink.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct vFileReadlink<'a> {\n    pub filename: &'a [u8],\n\n    pub buf: &'a mut [u8],\n}\n\nimpl<'a> ParseCommand<'a> for vFileReadlink<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let (buf, body_range) = buf.into_raw_buf();\n        // TODO: rewrite to avoid panic\n        let (body, buf) = buf[body_range.start..].split_at_mut(body_range.end - body_range.start);\n\n        if body.is_empty() {\n            return None;\n        }\n\n        match body {\n            [b':', body @ ..] => {\n                let filename = decode_hex_buf(body).ok()?;\n                Some(vFileReadlink { filename, buf })\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vFile_setfs.rs",
    "content": "use super::prelude::*;\nuse crate::target::ext::host_io::FsKind;\n\n#[derive(Debug)]\npub struct vFileSetfs {\n    pub fs: FsKind,\n}\n\nimpl<'a> ParseCommand<'a> for vFileSetfs {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        if body.is_empty() {\n            return None;\n        }\n\n        match body {\n            [b':', body @ ..] => {\n                let fs = match crate::common::Pid::new(decode_hex(body).ok()?) {\n                    None => FsKind::Stub,\n                    Some(pid) => FsKind::Pid(pid),\n                };\n                Some(vFileSetfs { fs })\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vFile_unlink.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct vFileUnlink<'a> {\n    pub filename: &'a [u8],\n}\n\nimpl<'a> ParseCommand<'a> for vFileUnlink<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        if body.is_empty() {\n            return None;\n        }\n\n        match body {\n            [b':', body @ ..] => {\n                let filename = decode_hex_buf(body).ok()?;\n                Some(vFileUnlink { filename })\n            }\n            _ => None,\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vFlashDone.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct vFlashDone;\n\nimpl<'a> ParseCommand<'a> for vFlashDone {\n    #[inline(always)]\n    fn from_packet(_buf: PacketBuf<'a>) -> Option<Self> {\n        Some(vFlashDone)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vFlashErase.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct vFlashErase<'a> {\n    pub addr: &'a [u8],\n    pub length: &'a [u8],\n}\n\nimpl<'a> ParseCommand<'a> for vFlashErase<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n\n        let mut body = body.splitn_mut(3, |&b| b == b',' || b == b':');\n        let _first_colon = body.next()?;\n        let addr = decode_hex_buf(body.next()?).ok()?;\n        let length = decode_hex_buf(body.next()?)\n            .ok()\n            .filter(|l| !l.is_empty())?;\n        Some(Self { addr, length })\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    macro_rules! test_buf {\n        ($bufname:ident, $body:literal) => {\n            let mut test = $body.to_vec();\n            let mut buf = PacketBuf::new_with_raw_body(&mut test).unwrap();\n            if !buf.strip_prefix(b\"vFlashErase\") {\n                panic!(\"invalid test\");\n            }\n            let $bufname = buf;\n        };\n    }\n\n    #[test]\n    fn valid_vFlashErase() {\n        test_buf!(buf, b\"vFlashErase:08000000,00004000\");\n\n        let pkt = vFlashErase::from_packet(buf).unwrap();\n\n        assert_eq!(pkt.addr, [0x08, 0, 0, 0]);\n        assert_eq!(pkt.length, [0, 0, 0x40, 0]);\n    }\n\n    #[test]\n    fn invalid_vFlashErase_wrong_address() {\n        test_buf!(buf, b\"vFlashErase:abcdefg:00004000\");\n\n        assert!(vFlashErase::from_packet(buf).is_none());\n    }\n\n    #[test]\n    fn invalid_vFlashErase_wrong_length() {\n        test_buf!(buf, b\"vFlashErase:08000000:abcdefg\");\n\n        assert!(vFlashErase::from_packet(buf).is_none());\n    }\n\n    #[test]\n    fn invalid_vFlashErase_missing_address() {\n        test_buf!(buf, b\"vFlashErase:\");\n\n        assert!(vFlashErase::from_packet(buf).is_none());\n    }\n\n    #[test]\n    fn invalid_vFlashErase_missing_length() {\n        test_buf!(buf, b\"vFlashErase:08000000:\");\n\n        assert!(vFlashErase::from_packet(buf).is_none());\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vFlashWrite.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::common::hex::decode_bin_buf;\n\n#[derive(Debug)]\npub struct vFlashWrite<'a> {\n    pub addr: &'a [u8],\n    pub val: &'a [u8],\n}\n\nimpl<'a> ParseCommand<'a> for vFlashWrite<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n\n        let mut body = body.splitn_mut(3, |&b| b == b':');\n        let _first_colon = body.next()?;\n        let addr = decode_hex_buf(body.next()?)\n            .ok()\n            .filter(|a| !a.is_empty())?;\n        let val = decode_bin_buf(body.next()?)?;\n\n        Some(vFlashWrite { addr, val })\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    macro_rules! test_buf {\n        ($bufname:ident, $body:literal) => {\n            let mut test = $body.to_vec();\n            let mut buf = PacketBuf::new_with_raw_body(&mut test).unwrap();\n            if !buf.strip_prefix(b\"vFlashWrite\") {\n                panic!(\"invalid test\");\n            }\n            let $bufname = buf;\n        };\n    }\n\n    #[test]\n    fn valid_vFlashWrite() {\n        test_buf!(\n            buf,\n            b\"vFlashWrite:08000000:\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0A\"\n        );\n\n        let pkt = vFlashWrite::from_packet(buf).unwrap();\n\n        assert_eq!(pkt.addr, [0x08, 0, 0, 0]);\n        assert_eq!(pkt.val, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);\n    }\n\n    #[test]\n    fn invalid_vFlashWrite_wrong_address() {\n        test_buf!(\n            buf,\n            b\"vFlashWrite:abcdefg:\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0A\"\n        );\n\n        assert!(vFlashWrite::from_packet(buf).is_none())\n    }\n\n    #[test]\n    fn invalid_vFlashWrite_missing_data() {\n        test_buf!(buf, b\"vFlashWrite:abcdefg:\");\n\n        assert!(vFlashWrite::from_packet(buf).is_none())\n    }\n\n    #[test]\n    fn invalid_vFlashWrite_missing_address() {\n        test_buf!(buf, b\"vFlashWrite:\");\n\n        assert!(vFlashWrite::from_packet(buf).is_none())\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vKill.rs",
    "content": "use super::prelude::*;\nuse crate::common::Pid;\n\n#[derive(Debug)]\npub struct vKill {\n    pub pid: Pid,\n}\n\nimpl<'a> ParseCommand<'a> for vKill {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n        let pid = match body {\n            [b';', pid @ ..] => Pid::new(decode_hex(pid).ok()?)?,\n            _ => return None,\n        };\n        Some(vKill { pid })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_vRun.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::common::lists::ArgListHex;\n\n#[derive(Debug)]\npub struct vRun<'a> {\n    pub filename: Option<&'a [u8]>,\n    pub args: ArgListHex<'a>,\n}\n\nimpl<'a> ParseCommand<'a> for vRun<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n\n        let mut body = body.splitn_mut(3, |b| *b == b';');\n\n        let _first_semi = body.next()?;\n        let filename = match decode_hex_buf(body.next()?).ok()? {\n            [] => None,\n            s => Some(s as &[u8]),\n        };\n        let args = body.next().unwrap_or(&mut []); // args are optional\n\n        Some(vRun {\n            filename,\n            args: ArgListHex::from_packet(args)?,\n        })\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    macro_rules! test_buf {\n        ($bufname:ident, $body:literal) => {\n            let mut test = $body.to_vec();\n            let mut buf = PacketBuf::new_with_raw_body(&mut test).unwrap();\n            if !buf.strip_prefix(b\"vRun\") {\n                panic!(\"invalid test\");\n            }\n            let $bufname = buf;\n        };\n    }\n\n    #[test]\n    fn valid_vRun_foobarbaz() {\n        test_buf!(buf, b\"vRun;;666f6f;626172;62617a\");\n\n        let pkt = vRun::from_packet(buf).unwrap();\n        let args = pkt.args.into_iter().collect::<Vec<_>>();\n\n        assert_eq!(pkt.filename, None);\n        assert_eq!(args, &[b\"foo\", b\"bar\", b\"baz\"]);\n    }\n\n    #[test]\n    fn valid_vRun_noname() {\n        test_buf!(buf, b\"vRun;\");\n\n        let pkt = vRun::from_packet(buf).unwrap();\n        let args = pkt.args.into_iter().collect::<Vec<_>>();\n\n        assert_eq!(pkt.filename, None);\n        assert_eq!(args, &[] as &[&[u8]]);\n    }\n\n    #[test]\n    fn valid_vRun_noargs() {\n        test_buf!(buf, b\"vRun;74657374\");\n\n        let pkt = vRun::from_packet(buf).unwrap();\n        let args = pkt.args.into_iter().collect::<Vec<_>>();\n\n        assert_eq!(pkt.filename, Some(&b\"test\"[..]));\n        assert_eq!(args, &[] as &[&[u8]]);\n    }\n\n    #[test]\n    fn valid_vRun_args() {\n        test_buf!(buf, b\"vRun;74657374;74657374\");\n\n        let pkt = vRun::from_packet(buf).unwrap();\n        let args = pkt.args.into_iter().collect::<Vec<_>>();\n\n        assert_eq!(pkt.filename, Some(&b\"test\"[..]));\n        assert_eq!(args, &[b\"test\"]);\n    }\n\n    #[test]\n    fn invalid_vRun_args() {\n        test_buf!(buf, b\"vRun;74657374;nothex\");\n\n        assert!(vRun::from_packet(buf).is_none());\n    }\n\n    #[test]\n    fn invalid_vRun() {\n        test_buf!(buf, b\"vRun;nothex;nothex\");\n\n        assert!(vRun::from_packet(buf).is_none());\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_x_lowcase.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct x<'a> {\n    pub addr: &'a [u8],\n    pub len: usize,\n\n    /// Reuse PacketBuf underlying buffer to read the binary data into it\n    pub buf: &'a mut [u8],\n}\n\nimpl<'a> ParseCommand<'a> for x<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        // the total packet buffer currently looks like:\n        //\n        // +------+--------------------+-------------------+-------+-----------------+\n        // | \"$x\" | addr (hex-encoded) | len (hex-encoded) | \"#XX\" | empty space ... |\n        // +------+--------------------+-------------------+-------+-----------------+\n        //\n        // Unfortunately, while `len` can be hex-decoded right here and now into a\n        // `usize`, `addr` corresponds to a Target::Arch::Usize, which requires holding\n        // on to a valid &[u8] reference into the buffer.\n        //\n        // While it's not _perfectly_ efficient, simply leaving the decoded addr in\n        // place and wasting a couple bytes is probably the easiest way to tackle this\n        // problem:\n        //\n        // +------+------------------+------------------------------------------------+\n        // | \"$x\" | addr (raw bytes) | usable buffer ...                              |\n        // +------+------------------+------------------------------------------------+\n\n        let (buf, body_range) = buf.into_raw_buf();\n        let body = buf.get_mut(body_range.start..body_range.end)?;\n\n        let mut body = body.split_mut(|b| *b == b',');\n\n        let addr = decode_hex_buf(body.next()?).ok()?;\n        let addr_len = addr.len();\n        let len = decode_hex(body.next()?).ok()?;\n\n        // ensures that `split_at_mut` doesn't panic\n        if buf.len() < body_range.start + addr_len {\n            return None;\n        }\n\n        let (addr, buf) = buf.split_at_mut(body_range.start + addr_len);\n        let addr = addr.get(b\"$x\".len()..)?;\n\n        Some(x { addr, len, buf })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/_x_upcase.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::common::hex::decode_bin_buf;\n\n#[derive(Debug)]\npub struct X<'a> {\n    pub addr: &'a [u8],\n    pub val: &'a [u8],\n}\n\nimpl<'a> ParseCommand<'a> for X<'a> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let body = buf.into_body();\n\n        let mut body = body.splitn_mut(3, |&b| b == b',' || b == b':');\n        let addr = decode_hex_buf(body.next()?).ok()?;\n        // See the comment in `_m_upcase.rs` for why the `len` field is handled\n        // this way. All the same rationale applies here (given that the X\n        // packet is just a new-and-improved version of the M packet).\n        let _len: usize = decode_hex(body.next()?).ok()?;\n        let val = decode_bin_buf(body.next()?)?;\n\n        Some(X { addr, val })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/breakpoint.rs",
    "content": "use crate::protocol::common::hex::decode_hex;\nuse crate::protocol::common::hex::decode_hex_buf;\n\n// Breakpoint packets are split up like this:\n//\n// Z0,addr,kind[;cond_list…][;cmds:persist,cmd_list…]\n//  \\_________/\n//       |\n//     BasicBreakpoint\n//  \\_______________________________________________/\n//                          |\n//                  BytecodeBreakpoint\n//\n// If the target does not implement the `Agent` extension, only the\n// `BasicBreakpoint` part is parsed, which helps cut down on binary bloat.\n\n#[derive(Debug)]\npub struct BasicBreakpoint<'a> {\n    pub type_: u8,\n    pub addr: &'a [u8],\n    /// architecture dependent\n    pub kind: &'a [u8],\n}\n\nimpl<'a> BasicBreakpoint<'a> {\n    pub fn from_slice(body: &'a mut [u8]) -> Option<BasicBreakpoint<'a>> {\n        let mut body = body.splitn_mut(4, |b| matches!(*b, b',' | b';'));\n        let type_ = decode_hex(body.next()?).ok()?;\n        let addr = decode_hex_buf(body.next()?).ok()?;\n        let kind = decode_hex_buf(body.next()?).ok()?;\n\n        Some(BasicBreakpoint { type_, addr, kind })\n    }\n}\n\n#[allow(dead_code)] // Bytecode hasn't yet been plumbed all the way through\n#[derive(Debug)]\npub struct BytecodeBreakpoint<'a> {\n    pub base: BasicBreakpoint<'a>,\n    pub conds: Option<BytecodeList<'a>>,\n    pub cmds_persist: Option<(BytecodeList<'a>, bool)>,\n}\n\nimpl<'a> BytecodeBreakpoint<'a> {\n    pub fn from_slice(body: &'a mut [u8]) -> Option<BytecodeBreakpoint<'a>> {\n        let mut body = body.splitn_mut(2, |b| *b == b';');\n\n        let base = BasicBreakpoint::from_slice(body.next()?)?;\n\n        let mut conds = None;\n        let mut cmds_persist = None;\n\n        if let Some(rest) = body.next() {\n            let mut s = rest.split_mut(|b| *b == b':');\n            let (raw_conds, raw_cmds) = match (s.next(), s.next()) {\n                (Some(a), Some(b)) => (Some(strip_suffix_mut(a, b\";cmds\")?), Some(b)),\n                (Some(a), None) => {\n                    if a.starts_with(b\"cmds\") {\n                        (None, Some(a))\n                    } else {\n                        (Some(a), None)\n                    }\n                }\n                _ => return None,\n            };\n\n            if let Some(raw_conds) = raw_conds {\n                conds = Some(BytecodeList(raw_conds));\n            }\n\n            if let Some(raw_cmds) = raw_cmds {\n                let mut raw_cmds = raw_cmds.split_mut(|b| *b == b',');\n                let raw_persist = decode_hex::<u8>(raw_cmds.next()?).ok()? != 0;\n                let raw_cmds = raw_cmds.next()?;\n\n                cmds_persist = Some((BytecodeList(raw_cmds), raw_persist));\n            }\n        }\n\n        Some(BytecodeBreakpoint {\n            base,\n            conds,\n            cmds_persist,\n        })\n    }\n}\n\nfn strip_suffix_mut<'a, T>(slice: &'a mut [T], suffix: &[T]) -> Option<&'a mut [T]>\nwhere\n    T: PartialEq,\n{\n    let (len, n) = (slice.len(), suffix.len());\n    if n <= len {\n        let (head, tail) = slice.split_at_mut(len - n);\n        if tail == suffix {\n            return Some(head);\n        }\n    }\n    None\n}\n\n/// A lazily evaluated iterator over a series of bytecode expressions.\n#[derive(Debug)]\npub struct BytecodeList<'a>(&'a mut [u8]);\n\nimpl<'a> BytecodeList<'a> {\n    #[allow(dead_code)]\n    pub fn into_iter(self) -> impl Iterator<Item = Option<&'a [u8]>> + 'a {\n        self.0.split_mut(|b| *b == b'X').skip(1).map(|s| {\n            let mut s = s.split_mut(|b| *b == b',');\n            let _len = s.next()?;\n            let code = decode_hex_buf(s.next()?).ok()?;\n            Some(code as &[u8])\n        })\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/exclamation_mark.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct ExclamationMark;\n\nimpl<'a> ParseCommand<'a> for ExclamationMark {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(ExclamationMark)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands/question_mark.rs",
    "content": "use super::prelude::*;\n\n#[derive(Debug)]\npub struct QuestionMark;\n\nimpl<'a> ParseCommand<'a> for QuestionMark {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        if !buf.into_body().is_empty() {\n            return None;\n        }\n        Some(QuestionMark)\n    }\n}\n"
  },
  {
    "path": "src/protocol/commands.rs",
    "content": "use crate::protocol::packet::PacketBuf;\nuse crate::target::Target;\nuse pastey::paste;\n\n/// Common imports used by >50% of all packet parsers.\n///\n/// Do not clutter this prelude with types only used by a few packets.\npub mod prelude {\n    pub use crate::protocol::commands::ParseCommand;\n    pub use crate::protocol::common::hex::decode_hex;\n    pub use crate::protocol::common::hex::decode_hex_buf;\n    pub use crate::protocol::packet::PacketBuf;\n    pub use core::convert::TryFrom;\n    pub use core::convert::TryInto;\n}\n\npub trait ParseCommand<'a>: Sized {\n    /// Try to parse a packet from the packet buffer.\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self>;\n}\n\nmacro_rules! commands {\n    (\n        $(\n            $ext:ident $(use $lt:lifetime)? {\n                $($name:literal => $mod:ident::$command:ident$(<$lifetime:lifetime>)?,)*\n            }\n        )*\n    ) => {paste! {\n        // Most packets follow a consistent model of \"only enabled when a\n        // particular IDET is implemented\", but there are some exceptions to\n        // this rule that need to be special-cased:\n        //\n        // # Breakpoint packets (z, Z)\n        //\n        // Breakpoint packets are special-cased, as the \"Z\" packet is parsed\n        // differently depending on whether or not the target implements the\n        // `Agent` extension.\n        //\n        // While it's entirely possible to eagerly parse the \"Z\" packet for\n        // bytecode, doing so would unnecessary bloat implementations that do\n        // not support evaluating agent expressions.\n\n\n        $($(\n            #[allow(non_snake_case, non_camel_case_types)]\n            pub mod $mod;\n        )*)*\n        pub mod breakpoint;\n\n        pub mod ext {\n            $(\n                #[allow(non_camel_case_types, clippy::enum_variant_names, clippy::upper_case_acronyms)]\n                pub enum [<$ext:camel>] $(<$lt>)? {\n                    $($command(super::$mod::$command<$($lifetime)?>),)*\n                }\n            )*\n\n            use super::breakpoint::{BasicBreakpoint, BytecodeBreakpoint};\n            #[allow(non_camel_case_types)]\n            pub enum Breakpoints<'a> {\n                z(BasicBreakpoint<'a>),\n                Z(BasicBreakpoint<'a>),\n                // Bytecode hasn't yet been plumbed all the way through\n                #[allow(dead_code)]\n                ZWithBytecode(BytecodeBreakpoint<'a>),\n            }\n\n        }\n\n        /// GDB commands\n        pub enum Command<'a> {\n            $(\n                [<$ext:camel>](ext::[<$ext:camel>]$(<$lt>)?),\n            )*\n            Breakpoints(ext::Breakpoints<'a>),\n            Unknown(&'a [u8]),\n        }\n\n        impl<'a> Command<'a> {\n            pub fn from_packet(\n                target: &mut impl Target,\n                mut buf: PacketBuf<'a>\n            ) -> Option<Command<'a>> {\n                // HACK: this locally-scoped trait enables using identifiers\n                // that aren't top-level `Target` IDETs to split-up the packet\n                // parsing code.\n                trait Hack {\n                    fn support_base(&mut self) -> Option<()>;\n                    fn support_target_xml(&mut self) -> Option<()>;\n                    fn support_lldb_register_info(&mut self) -> Option<()>;\n                    fn support_resume(&mut self) -> Option<()>;\n                    fn support_single_register_access(&mut self) -> Option<()>;\n                    fn support_reverse_step(&mut self) -> Option<()>;\n                    fn support_reverse_cont(&mut self) -> Option<()>;\n                    fn support_no_ack_mode(&mut self) -> Option<()>;\n                    fn support_x_lowcase_packet(&mut self) -> Option<()>;\n                    fn support_x_upcase_packet(&mut self) -> Option<()>;\n                    fn support_thread_extra_info(&mut self) -> Option<()>;\n                }\n\n                impl<T: Target> Hack for T {\n                    fn support_base(&mut self) -> Option<()> {\n                        Some(())\n                    }\n\n                    fn support_target_xml(&mut self) -> Option<()> {\n                        use crate::arch::Arch;\n                        if self.use_target_description_xml()\n                            && (T::Arch::target_description_xml().is_some()\n                                || self.support_target_description_xml_override().is_some())\n                        {\n                            Some(())\n                        } else {\n                            None\n                        }\n                    }\n\n                    fn support_lldb_register_info(&mut self) -> Option<()> {\n                        use crate::arch::Arch;\n                        if self.use_lldb_register_info()\n                            && (T::Arch::lldb_register_info(usize::MAX).is_some()\n                                || self.support_lldb_register_info_override().is_some())\n                        {\n                            Some(())\n                        } else {\n                            None\n                        }\n                    }\n\n                    fn support_resume(&mut self) -> Option<()> {\n                        self.base_ops().resume_ops().map(drop)\n                    }\n\n                    fn support_single_register_access(&mut self) -> Option<()> {\n                        use crate::target::ext::base::BaseOps;\n                        match self.base_ops() {\n                            BaseOps::SingleThread(ops) => ops.support_single_register_access().map(drop),\n                            BaseOps::MultiThread(ops) => ops.support_single_register_access().map(drop),\n                        }\n                    }\n\n                    fn support_reverse_step(&mut self) -> Option<()> {\n                        use crate::target::ext::base::ResumeOps;\n                        match self.base_ops().resume_ops()? {\n                            ResumeOps::SingleThread(ops) => ops.support_reverse_step().map(drop),\n                            ResumeOps::MultiThread(ops) => ops.support_reverse_step().map(drop),\n                        }\n                    }\n\n                    fn support_reverse_cont(&mut self) -> Option<()> {\n                        use crate::target::ext::base::ResumeOps;\n                        match self.base_ops().resume_ops()? {\n                            ResumeOps::SingleThread(ops) => ops.support_reverse_cont().map(drop),\n                            ResumeOps::MultiThread(ops) => ops.support_reverse_cont().map(drop),\n                        }\n                    }\n\n                    fn support_x_lowcase_packet(&mut self) -> Option<()> {\n                        if self.use_x_lowcase_packet() {\n                            Some(())\n                        } else {\n                            None\n                        }\n                    }\n\n                    fn support_x_upcase_packet(&mut self) -> Option<()> {\n                        if self.use_x_upcase_packet() {\n                            Some(())\n                        } else {\n                            None\n                        }\n                    }\n\n                    fn support_no_ack_mode(&mut self) -> Option<()> {\n                        if self.use_no_ack_mode() {\n                            Some(())\n                        } else {\n                            None\n                        }\n                    }\n\n                    fn support_thread_extra_info(&mut self) -> Option<()> {\n                        use crate::target::ext::base::BaseOps;\n                        match self.base_ops() {\n                            BaseOps::SingleThread(_) => None,\n                            BaseOps::MultiThread(ops) => ops.support_thread_extra_info().map(drop),\n                        }\n                    }\n                }\n\n                // TODO?: use tries for more efficient longest prefix matching\n\n                $(\n                #[allow(clippy::string_lit_as_bytes)]\n                if target.[< support_ $ext >]().is_some() {\n                    $(\n                    if buf.strip_prefix($name.as_bytes()) {\n                        crate::__dead_code_marker!($name, \"prefix_match\");\n\n                        let cmd = $mod::$command::from_packet(buf)?;\n\n                        return Some(\n                            Command::[<$ext:camel>](\n                                ext::[<$ext:camel>]::$command(cmd)\n                            )\n                        )\n                    }\n                    )*\n                }\n                )*\n\n                if let Some(_breakpoint_ops) = target.support_breakpoints() {\n                    use breakpoint::{BasicBreakpoint, BytecodeBreakpoint};\n\n                    if buf.strip_prefix(b\"z\") {\n                        let cmd = BasicBreakpoint::from_slice(buf.into_body())?;\n                        return Some(Command::Breakpoints(ext::Breakpoints::z(cmd)))\n                    }\n\n                    if buf.strip_prefix(b\"Z\") {\n                        // TODO: agent bytecode currently unimplemented\n                        if true {\n                            let cmd = BasicBreakpoint::from_slice(buf.into_body())?;\n                            return Some(Command::Breakpoints(ext::Breakpoints::Z(cmd)))\n                        } else {\n                            let cmd = BytecodeBreakpoint::from_slice(buf.into_body())?;\n                            return Some(Command::Breakpoints(ext::Breakpoints::ZWithBytecode(cmd)))\n                        }\n                    }\n                }\n\n                Some(Command::Unknown(buf.into_body()))\n            }\n        }\n    }};\n}\n\ncommands! {\n    base use 'a {\n        \"?\" => question_mark::QuestionMark,\n        \"D\" => _d_upcase::D,\n        \"g\" => _g::g,\n        \"G\" => _g_upcase::G<'a>,\n        \"H\" => _h_upcase::H,\n        \"k\" => _k::k,\n        \"m\" => _m::m<'a>,\n        \"M\" => _m_upcase::M<'a>,\n        \"qAttached\" => _qAttached::qAttached,\n        \"qfThreadInfo\" => _qfThreadInfo::qfThreadInfo,\n        \"qsThreadInfo\" => _qsThreadInfo::qsThreadInfo,\n        \"qSupported\" => _qSupported::qSupported<'a>,\n        \"T\" => _t_upcase::T,\n        \"vKill\" => _vKill::vKill,\n    }\n\n    target_xml use 'a {\n        \"qXfer:features:read\" => _qXfer_features_read::qXferFeaturesRead<'a>,\n    }\n\n    resume use 'a {\n        \"c\" => _c::c<'a>,\n        \"s\" => _s::s<'a>,\n        \"vCont\" => _vCont::vCont<'a>,\n    }\n\n    x_lowcase_packet use 'a {\n        \"x\" => _x_lowcase::x<'a>,\n    }\n\n    x_upcase_packet use 'a {\n        \"X\" => _x_upcase::X<'a>,\n    }\n\n    no_ack_mode {\n        \"QStartNoAckMode\" => _QStartNoAckMode::QStartNoAckMode,\n    }\n\n    single_register_access use 'a {\n        \"p\" => _p::p<'a>,\n        \"P\" => _p_upcase::P<'a>,\n    }\n\n    extended_mode use 'a {\n        \"!\" => exclamation_mark::ExclamationMark,\n        \"qC\" => _qC::qC,\n        \"QDisableRandomization\" => _QDisableRandomization::QDisableRandomization,\n        \"QEnvironmentHexEncoded\" => _QEnvironmentHexEncoded::QEnvironmentHexEncoded<'a>,\n        \"QEnvironmentReset\" => _QEnvironmentReset::QEnvironmentReset,\n        \"QEnvironmentUnset\" => _QEnvironmentUnset::QEnvironmentUnset<'a>,\n        \"QSetWorkingDir\" => _QSetWorkingDir::QSetWorkingDir<'a>,\n        \"QStartupWithShell\" => _QStartupWithShell::QStartupWithShell,\n        \"R\" => _r_upcase::R,\n        \"vAttach\" => _vAttach::vAttach,\n        \"vRun\" => _vRun::vRun<'a>,\n    }\n\n    monitor_cmd use 'a {\n        \"qRcmd\" => _qRcmd::qRcmd<'a>,\n    }\n\n    section_offsets {\n        \"qOffsets\" => _qOffsets::qOffsets,\n    }\n\n    reverse_cont {\n        \"bc\" => _bc::bc,\n    }\n\n    reverse_step {\n        \"bs\" => _bs::bs,\n    }\n\n    memory_map use 'a {\n        \"qXfer:memory-map:read\" => _qXfer_memory_map::qXferMemoryMapRead<'a>,\n    }\n\n    flash_operations use 'a {\n        \"vFlashErase\" => _vFlashErase::vFlashErase<'a>,\n        \"vFlashWrite\" => _vFlashWrite::vFlashWrite<'a>,\n        \"vFlashDone\" => _vFlashDone::vFlashDone,\n    }\n\n    auxv use 'a {\n        \"qXfer:auxv:read\" => _qXfer_auxv_read::qXferAuxvRead<'a>,\n    }\n\n    exec_file use 'a {\n        \"qXfer:exec-file:read\" => _qXfer_exec_file::qXferExecFileRead<'a>,\n    }\n\n    host_io use 'a {\n        \"vFile:open\" => _vFile_open::vFileOpen<'a>,\n        \"vFile:close\" => _vFile_close::vFileClose,\n        \"vFile:pread\" => _vFile_pread::vFilePread<'a>,\n        \"vFile:pwrite\" => _vFile_pwrite::vFilePwrite<'a>,\n        \"vFile:fstat\" => _vFile_fstat::vFileFstat,\n        \"vFile:unlink\" => _vFile_unlink::vFileUnlink<'a>,\n        \"vFile:readlink\" => _vFile_readlink::vFileReadlink<'a>,\n        \"vFile:setfs\" => _vFile_setfs::vFileSetfs,\n    }\n\n    catch_syscalls use 'a {\n        \"QCatchSyscalls\" => _QCatchSyscalls::QCatchSyscalls<'a>,\n    }\n\n    thread_extra_info use 'a {\n        \"qThreadExtraInfo\" => _qThreadExtraInfo::qThreadExtraInfo<'a>,\n    }\n\n    lldb_register_info {\n        \"qRegisterInfo\" => _qRegisterInfo::qRegisterInfo,\n    }\n\n    libraries_svr4 use 'a {\n        \"qXfer:libraries-svr4:read\" => _qXfer_libraries_svr4_read::qXferLibrariesSvr4Read<'a>,\n    }\n\n    libraries use 'a {\n        \"qXfer:libraries:read\" => _qXfer_libraries_read::qXferLibrariesRead<'a>,\n    }\n\n    tracepoints use 'a {\n        \"QTDPsrc\" => _QTDPsrc::QTDPsrc<'a>,\n        \"QTDP\" => _QTDP::QTDP<'a>,\n        \"QTinit\" => _QTinit::QTinit,\n        \"QTBuffer\" => _QTBuffer_upcase::QTBuffer,\n        \"QTStart\" => _QTStart::QTStart,\n        \"QTStop\" => _QTStop::QTStop,\n        \"QTFrame\" => _QTFrame::QTFrame<'a>,\n\n        \"qTBuffer\" => _qTBuffer::qTBuffer,\n        \"qTStatus\" => _qTStatus::qTStatus,\n        \"qTP\" => _qTP::qTP<'a>,\n        \"qTfP\" => _qTfP::qTfP,\n        \"qTsP\" => _qTsP::qTsP,\n\n        // QTDV is unimplemented.\n        \"qTfV\" => _qTfV::qTfV,\n        \"qTsV\" => _qTsV::qTsV,\n    }\n\n    host_info {\n        \"qHostInfo\" => _qHostInfo::qHostInfo,\n    }\n\n    process_info {\n        \"qProcessInfo\" => _qProcessInfo::qProcessInfo,\n    }\n\n    wasm use 'a {\n        \"qWasmCallStack\" => _qWasmCallStack::qWasmCallStack,\n        \"qWasmLocal\" => _qWasmLocal::qWasmLocal<'a>,\n        \"qWasmGlobal\" => _qWasmGlobal::qWasmGlobal<'a>,\n        \"qWasmStackValue\" => _qWasmStackValue::qWasmStackValue<'a>,\n    }\n}\n"
  },
  {
    "path": "src/protocol/common/hex.rs",
    "content": "use num_traits::CheckedAdd;\nuse num_traits::CheckedMul;\nuse num_traits::FromPrimitive;\nuse num_traits::Zero;\n\n#[derive(Debug)]\npub enum DecodeHexError {\n    NotAscii,\n    Empty,\n    Overflow,\n    InvalidOutput,\n}\n\n/// Decode a GDB hex string into the specified integer.\n///\n/// GDB hex strings may include \"xx\", which represent \"missing\" data. This\n/// method simply treats \"xx\" as 0x00.\npub fn decode_hex<I>(buf: &[u8]) -> Result<I, DecodeHexError>\nwhere\n    I: FromPrimitive + Zero + CheckedAdd + CheckedMul,\n{\n    use DecodeHexError::*;\n\n    let radix = I::from_u8(16).ok_or(InvalidOutput)?;\n\n    if buf.is_empty() {\n        return Err(Empty);\n    }\n\n    let mut result = I::zero();\n\n    for &digit in buf {\n        let x = I::from_u8(ascii2byte(digit).ok_or(NotAscii)?).ok_or(InvalidOutput)?;\n        result = result.checked_mul(&radix).ok_or(Overflow)?;\n        result = result.checked_add(&x).ok_or(Overflow)?\n    }\n\n    Ok(result)\n}\n\n/// Wrapper around a raw hex string. Enables \"late\" calls to `decode` from\n/// outside the `crate::protocol` module.\n#[derive(Debug, Clone, Copy)]\npub struct HexString<'a>(pub &'a [u8]);\n\nimpl HexString<'_> {\n    pub fn decode<I>(&self) -> Result<I, DecodeHexError>\n    where\n        I: FromPrimitive + Zero + CheckedAdd + CheckedMul,\n    {\n        decode_hex(self.0)\n    }\n}\n\n#[derive(Debug)]\npub enum DecodeHexBufError {\n    NotAscii,\n}\n\n#[inline]\nfn ascii2byte(c: u8) -> Option<u8> {\n    match c {\n        b'0'..=b'9' => Some(c - b'0'),\n        b'a'..=b'f' => Some(c - b'a' + 10),\n        b'A'..=b'F' => Some(c - b'A' + 10),\n        b'x' | b'X' => Some(0),\n        _ => None,\n    }\n}\n\n/// Check if the byte `c` is a valid GDB hex digit `[0-9a-fA-FxX]`\n#[inline]\npub fn is_hex(c: u8) -> bool {\n    #[allow(clippy::match_like_matches_macro)] // mirror ascii2byte\n    match c {\n        b'0'..=b'9' => true,\n        b'a'..=b'f' => true,\n        b'A'..=b'F' => true,\n        b'x' | b'X' => true,\n        _ => false,\n    }\n}\n\n/// Decode a GDB hex string into a byte slice _in place_.\n///\n/// GDB hex strings may include \"xx\", which represent \"missing\" data. This\n/// method simply treats \"xx\" as 0x00.\n// TODO: maybe don't blindly translate \"xx\" as 0x00?\n#[cfg(not(feature = \"paranoid_unsafe\"))]\npub fn decode_hex_buf(base_buf: &mut [u8]) -> Result<&mut [u8], DecodeHexBufError> {\n    use DecodeHexBufError::*;\n\n    if base_buf.is_empty() {\n        return Ok(&mut []);\n    }\n\n    let odd_adust = base_buf.len() % 2;\n    if odd_adust != 0 {\n        base_buf[0] = ascii2byte(base_buf[0]).ok_or(NotAscii)?;\n    }\n\n    let buf = &mut base_buf[odd_adust..];\n\n    let decoded_len = buf.len() / 2;\n    for i in 0..decoded_len {\n        // SAFETY: rustc isn't smart enough to automatically elide these bound checks.\n        //\n        // If buf.len() == 0 or 1: trivially safe, since the for block is never taken\n        // If buf.len() >= 2: the range of values for `i` is 0..(buf.len() / 2 - 1)\n        let (hi, lo, b) = unsafe {\n            (\n                //    (buf.len() / 2 - 1) * 2\n                // == (buf.len() - 2)\n                // since buf.len() is >2, this is in-bounds\n                *buf.get_unchecked(i * 2),\n                //    (buf.len() / 2 - 1) * 2 + 1\n                // == (buf.len() - 1)\n                // since buf.len() is >2, this is in-bounds\n                *buf.get_unchecked(i * 2 + 1),\n                // since buf.len() is >2, (buf.len() / 2 - 1) is always in-bounds\n                buf.get_unchecked_mut(i),\n            )\n        };\n\n        let hi = ascii2byte(hi).ok_or(NotAscii)?;\n        let lo = ascii2byte(lo).ok_or(NotAscii)?;\n        *b = (hi << 4) | lo;\n    }\n\n    // SAFETY: rustc isn't smart enough to automatically elide this bound check.\n    //\n    // Consider the different values (decoded_len + odd_adust) can take:\n    //\n    //  buf.len() | (decoded_len + odd_adust)\n    // -----------|---------------------------\n    //      0     | (0 + 0) == 0\n    //      1     | (0 + 1) == 1\n    //      2     | (1 + 0) == 1\n    //      3     | (1 + 1) == 2\n    //      4     | (2 + 0) == 2\n    //      5     | (2 + 1) == 3\n    //\n    // Note that the computed index is always in-bounds.\n    //\n    // If I were still in undergrad, I could probably have whipped up a proper\n    // mathematical proof by induction or whatnot, but hopefully this \"proof by\n    // example\" ought to suffice.\n    unsafe { Ok(base_buf.get_unchecked_mut(..decoded_len + odd_adust)) }\n}\n\n/// Decode a GDB hex string into a byte slice _in place_.\n///\n/// GDB hex strings may include \"xx\", which represent \"missing\" data. This\n/// method simply treats \"xx\" as 0x00.\n// TODO: maybe don't blindly translate \"xx\" as 0x00?\n#[cfg(feature = \"paranoid_unsafe\")]\npub fn decode_hex_buf(base_buf: &mut [u8]) -> Result<&mut [u8], DecodeHexBufError> {\n    use DecodeHexBufError::*;\n\n    let odd_adust = base_buf.len() % 2;\n    if odd_adust != 0 {\n        base_buf[0] = ascii2byte(base_buf[0]).ok_or(NotAscii)?;\n    }\n    let buf = &mut base_buf[odd_adust..];\n\n    let decoded_len = buf.len() / 2;\n    for i in 0..decoded_len {\n        let b = ascii2byte(buf[i * 2]).ok_or(NotAscii)? << 4\n            | ascii2byte(buf[i * 2 + 1]).ok_or(NotAscii)?;\n        buf[i] = b;\n    }\n\n    Ok(&mut base_buf[..decoded_len + odd_adust])\n}\n\n/// Decode GDB escaped binary bytes into origin bytes _in place_.\n//\n// Thanks reddit!\n// https://www.reddit.com/r/rust/comments/110qzq9/any_idea_why_rust_isnt_able_to_elide_this_bounds/\npub fn decode_bin_buf(buf: &mut [u8]) -> Option<&mut [u8]> {\n    let mut i = 0;\n    let len = buf.len();\n    for j in 0..len {\n        if i >= len {\n            return Some(&mut buf[..j]);\n        }\n\n        if buf[i] == b'}' {\n            buf[j] = buf.get(i + 1)? ^ 0x20;\n            i += 1;\n        } else {\n            buf[j] = buf[i];\n        }\n        i += 1;\n    }\n\n    Some(buf)\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn decode_hex_buf_odd() {\n        let mut payload = b\"ffffff4\".to_vec();\n        let res = decode_hex_buf(&mut payload).unwrap();\n        assert_eq!(res, [0xf, 0xff, 0xff, 0xf4]);\n    }\n\n    #[test]\n    fn decode_hex_buf_even() {\n        let mut payload = b\"0123456789abcdef\".to_vec();\n        let res = decode_hex_buf(&mut payload).unwrap();\n        assert_eq!(res, [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);\n    }\n\n    #[test]\n    fn decode_hex_buf_odd_alt() {\n        let mut payload = b\"12345\".to_vec();\n        let res = decode_hex_buf(&mut payload).unwrap();\n        assert_eq!(res, [0x1, 0x23, 0x45]);\n    }\n\n    #[test]\n    fn decode_hex_buf_short() {\n        let mut payload = b\"1\".to_vec();\n        let res = decode_hex_buf(&mut payload).unwrap();\n        assert_eq!(res, [0x1]);\n    }\n\n    #[test]\n    fn decode_hex_buf_empty() {\n        let mut payload = b\"\".to_vec();\n        let res = decode_hex_buf(&mut payload).unwrap();\n        assert_eq!(res, []);\n    }\n\n    #[test]\n    fn decode_bin_buf_escaped() {\n        let mut payload = b\"}\\x03}\\x04}]}\\n\".to_vec();\n        let res = decode_bin_buf(&mut payload).unwrap();\n        assert_eq!(res, [0x23, 0x24, 0x7d, 0x2a]);\n    }\n}\n"
  },
  {
    "path": "src/protocol/common/lists.rs",
    "content": "use crate::protocol::common::hex::decode_hex_buf;\nuse crate::protocol::common::hex::is_hex;\n\n/// A wrapper type around a list of hex encoded arguments separated by `;`.\n#[derive(Debug)]\npub struct ArgListHex<'a>(&'a mut [u8]);\n\nimpl<'a> ArgListHex<'a> {\n    pub fn from_packet(args: &'a mut [u8]) -> Option<Self> {\n        // validate that args have valid hex encoding (with ';' delimiters).\n        // this removes all the error handling from the lazy `Args` iterator.\n        if args.iter().any(|b| !(is_hex(*b) || *b == b';')) {\n            return None;\n        }\n        Some(Self(args))\n    }\n\n    pub fn into_iter(self) -> impl Iterator<Item = &'a [u8]> + 'a {\n        self.0\n            .split_mut(|b| *b == b';')\n            // the `from_packet` method guarantees that the args are valid hex ascii, so this should\n            // method should never fail.\n            .map(|raw| decode_hex_buf(raw).unwrap_or(&mut []))\n            .map(|s| s as &[u8])\n            .filter(|s| !s.is_empty())\n    }\n}\n"
  },
  {
    "path": "src/protocol/common/mod.rs",
    "content": "pub mod hex;\npub mod lists;\npub mod qxfer;\npub mod thread_id;\n"
  },
  {
    "path": "src/protocol/common/qxfer.rs",
    "content": "use crate::protocol::commands::ParseCommand;\nuse crate::protocol::common::hex::decode_hex;\nuse crate::protocol::packet::PacketBuf;\n\n/// Parse the `annex` field of a qXfer packet. Used in conjunction with\n/// `QXferBase` to cut keep qXfer packet parsing DRY.\npub trait ParseAnnex<'a>: Sized {\n    fn from_buf(buf: &'a [u8]) -> Option<Self>;\n}\n\n#[derive(Debug)]\npub struct QXferReadBase<'a, T: ParseAnnex<'a>> {\n    pub annex: T,\n    pub offset: u64,\n    pub length: usize,\n\n    pub buf: &'a mut [u8],\n}\n\nimpl<'a, T: ParseAnnex<'a>> ParseCommand<'a> for QXferReadBase<'a, T> {\n    #[inline(always)]\n    fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {\n        let (buf, body_range) = buf.into_raw_buf();\n\n        // this looks a bit wacky, but the compiler is dumb and won't elide bounds\n        // checks without it.\n        let (body, buf) = {\n            let buf = buf.get_mut(body_range.start..)?;\n            if body_range.end - body_range.start > buf.len() {\n                return None;\n            }\n            buf.split_at_mut(body_range.end - body_range.start)\n        };\n\n        if body.is_empty() {\n            return None;\n        }\n\n        let mut body = body.split(|b| *b == b':').skip(1);\n        let annex = T::from_buf(body.next()?)?;\n\n        let mut body = body.next()?.split(|b| *b == b',');\n        let offset = decode_hex(body.next()?).ok()?;\n        let length = decode_hex(body.next()?).ok()?;\n\n        Some(QXferReadBase {\n            annex,\n            offset,\n            length,\n            buf,\n        })\n    }\n}\n"
  },
  {
    "path": "src/protocol/common/thread_id.rs",
    "content": "use crate::protocol::common::hex::decode_hex;\nuse core::convert::TryFrom;\nuse core::convert::TryInto;\nuse core::num::NonZeroUsize;\n\n/// Tid/Pid Selector.\n#[derive(PartialEq, Eq, Debug, Clone, Copy)]\npub enum IdKind {\n    /// All threads (-1)\n    All,\n    /// Any thread (0)\n    Any,\n    /// Thread with specific ID (id > 0)\n    WithId(NonZeroUsize),\n}\n\n/// Unique Thread ID.\n#[derive(PartialEq, Eq, Debug, Clone, Copy)]\npub struct ThreadId {\n    /// Process ID (may or may not be present).\n    pub pid: Option<IdKind>,\n    /// Thread ID.\n    pub tid: IdKind,\n}\n\nimpl TryFrom<&[u8]> for ThreadId {\n    type Error = ();\n\n    fn try_from(s: &[u8]) -> Result<Self, ()> {\n        match s {\n            [b'p', s @ ..] => {\n                // p<pid>.<tid>\n                let mut s = s.split(|b| *b == b'.');\n                let pid: IdKind = s.next().ok_or(())?.try_into()?;\n                let tid: IdKind = match s.next() {\n                    Some(s) => s.try_into()?,\n                    None => IdKind::All, // sending only p<pid> is valid\n                };\n\n                Ok(ThreadId {\n                    pid: Some(pid),\n                    tid,\n                })\n            }\n            _ => {\n                // <tid>\n                let tid: IdKind = s.try_into()?;\n\n                Ok(ThreadId { pid: None, tid })\n            }\n        }\n    }\n}\n\nimpl TryFrom<&[u8]> for IdKind {\n    type Error = ();\n\n    fn try_from(s: &[u8]) -> Result<Self, ()> {\n        Ok(match s {\n            b\"-1\" => IdKind::All,\n            b\"0\" => IdKind::Any,\n            id => IdKind::WithId(NonZeroUsize::new(decode_hex(id).map_err(drop)?).ok_or(())?),\n        })\n    }\n}\n\nimpl TryFrom<&mut [u8]> for ThreadId {\n    type Error = ();\n\n    fn try_from(s: &mut [u8]) -> Result<Self, ()> {\n        Self::try_from(s as &[u8])\n    }\n}\n\nimpl TryFrom<&mut [u8]> for IdKind {\n    type Error = ();\n\n    fn try_from(s: &mut [u8]) -> Result<Self, ()> {\n        Self::try_from(s as &[u8])\n    }\n}\n\n/// Like [`IdKind`], without the `Any` variant. Typically used when working\n/// with vCont (i.e: where the `Any` variant wouldn't be valid).\n#[derive(PartialEq, Eq, Debug, Clone, Copy)]\npub enum SpecificIdKind {\n    /// Thread with specific ID (id > 0)\n    WithId(core::num::NonZeroUsize),\n    /// All threads (-1)\n    All,\n}\n\n/// Like [`ThreadId`], without the `Any` variants. Typically used when working\n/// with vCont (i.e: where the `Any` variant wouldn't be valid).\n#[derive(Debug, Copy, Clone)]\npub struct SpecificThreadId {\n    /// Process ID (may or may not be present).\n    pub pid: Option<SpecificIdKind>,\n    /// Thread ID.\n    pub tid: SpecificIdKind,\n}\n\nimpl TryFrom<IdKind> for SpecificIdKind {\n    type Error = ();\n\n    fn try_from(id: IdKind) -> Result<SpecificIdKind, ()> {\n        Ok(match id {\n            IdKind::All => SpecificIdKind::All,\n            IdKind::WithId(id) => SpecificIdKind::WithId(id),\n            IdKind::Any => return Err(()),\n        })\n    }\n}\n\nimpl TryFrom<ThreadId> for SpecificThreadId {\n    type Error = ();\n\n    fn try_from(thread: ThreadId) -> Result<SpecificThreadId, ()> {\n        Ok(SpecificThreadId {\n            pid: match thread.pid {\n                None => None,\n                Some(id_kind) => Some(id_kind.try_into()?),\n            },\n            tid: thread.tid.try_into()?,\n        })\n    }\n}\n\n/// Like [`ThreadId`], without the `Any`, or `All` variants.\n#[derive(Debug, Copy, Clone)]\npub struct ConcreteThreadId {\n    /// Process ID (may or may not be present).\n    pub pid: Option<NonZeroUsize>,\n    /// Thread ID.\n    pub tid: NonZeroUsize,\n}\n\nimpl TryFrom<ThreadId> for ConcreteThreadId {\n    type Error = ();\n\n    fn try_from(thread: ThreadId) -> Result<ConcreteThreadId, ()> {\n        Ok(ConcreteThreadId {\n            pid: match thread.pid {\n                None => None,\n                Some(id_kind) => Some(id_kind.try_into()?),\n            },\n            tid: thread.tid.try_into()?,\n        })\n    }\n}\n\nimpl TryFrom<IdKind> for NonZeroUsize {\n    type Error = ();\n\n    fn try_from(value: IdKind) -> Result<NonZeroUsize, ()> {\n        match value {\n            IdKind::WithId(v) => Ok(v),\n            _ => Err(()),\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/console_output.rs",
    "content": "#[cfg(feature = \"alloc\")]\nuse alloc::vec::Vec;\nuse core::fmt;\n\n/// Helper struct to send console output to GDB.\n///\n/// The recommended way to interact with `ConsoleOutput` is through the provided\n/// [`output!`] and [`outputln!`] macros.\n///\n/// On resource constrained systems which might want to avoid using Rust's\n/// [fairly \"heavy\" formatting machinery](https://jamesmunns.com/blog/fmt-unreasonably-expensive/),\n/// the `write_raw()` method can be used to write raw data directly to the GDB\n/// console.\n///\n/// When the `alloc` feature is disabled, all output buffering is disabled, and\n/// each call to `output!` will automatically flush data over the Connection.\n///\n/// [`output!`]: crate::output\n/// [`outputln!`]: crate::outputln\n// TODO: support user-provided output buffers for no-`alloc` environments.\npub struct ConsoleOutput<'a> {\n    #[cfg(feature = \"alloc\")]\n    buf: Vec<u8>,\n    callback: &'a mut dyn FnMut(&[u8]),\n}\n\nimpl fmt::Write for ConsoleOutput<'_> {\n    fn write_str(&mut self, s: &str) -> fmt::Result {\n        self.write_raw(s.as_bytes());\n        Ok(())\n    }\n}\n\nimpl<'a> ConsoleOutput<'a> {\n    pub(crate) fn new(callback: &'a mut dyn FnMut(&[u8])) -> ConsoleOutput<'a> {\n        ConsoleOutput {\n            #[cfg(feature = \"alloc\")]\n            buf: Vec::new(),\n            callback,\n        }\n    }\n\n    /// Write raw (non UTF-8) data to the GDB console.\n    pub fn write_raw(&mut self, bytes: &[u8]) {\n        cfg_if::cfg_if! {\n            if #[cfg(feature = \"alloc\")] {\n                self.buf.extend_from_slice(bytes);\n            } else {\n                (self.callback)(bytes);\n            }\n        }\n    }\n\n    /// Flush the internal output buffer.\n    ///\n    /// Only available when `alloc` is enabled.\n    #[cfg(feature = \"alloc\")]\n    pub fn flush(&mut self) {\n        if !self.buf.is_empty() {\n            (self.callback)(&self.buf);\n            self.buf.clear()\n        }\n    }\n}\n\nimpl Drop for ConsoleOutput<'_> {\n    fn drop(&mut self) {\n        #[cfg(feature = \"alloc\")]\n        self.flush()\n    }\n}\n\n/// Send formatted data to the GDB client console.\n///\n/// The first argument must be a [`ConsoleOutput`].\n#[macro_export]\nmacro_rules! output {\n    ($console_output:expr, $($args:tt)*) => {{\n        use core::fmt::Write;\n        let _ = write!($console_output, $($args)*);\n    }};\n}\n\n/// Send formatted data to the GDB client console, with a newline appended.\n///\n/// The first argument must be a [`ConsoleOutput`].\n#[macro_export]\nmacro_rules! outputln {\n    ($console_output:expr) => {{\n        use core::fmt::Write;\n        let _ = writeln!($console_output);\n    }};\n    ($console_output:expr,) => {\n        outputln!($console_output)\n    };\n    ($console_output:expr, $($args:tt)*) => {{\n        use core::fmt::Write;\n        let _ = writeln!($console_output, $($args)*);\n    }};\n}\n"
  },
  {
    "path": "src/protocol/mod.rs",
    "content": "//! GDB protocol internals.\n//!\n//! These types should _not_ leak into the public interface (with a few\n//! exceptions, as listed below).\n\npub use console_output::ConsoleOutput;\npub use packet::PacketParseError;\n\nmod common;\nmod console_output;\nmod packet;\nmod response_writer;\n\npub(crate) mod commands;\npub(crate) mod recv_packet;\npub(crate) use common::thread_id::ConcreteThreadId;\npub(crate) use common::thread_id::IdKind;\npub(crate) use common::thread_id::SpecificIdKind;\npub(crate) use common::thread_id::SpecificThreadId;\npub(crate) use packet::Packet;\npub(crate) use response_writer::Error as ResponseWriterError;\npub(crate) use response_writer::ResponseWriter;\n"
  },
  {
    "path": "src/protocol/packet.rs",
    "content": "use crate::protocol::commands::Command;\nuse crate::protocol::common::hex::decode_hex;\nuse crate::target::Target;\n\n/// Packet parse error.\n#[derive(Debug)]\npub enum PacketParseError {\n    #[allow(dead_code)] // used as part of Debug impl\n    ChecksumMismatched {\n        checksum: u8,\n        calculated: u8,\n    },\n    EmptyBuf,\n    MissingChecksum,\n    MalformedChecksum,\n    MalformedCommand,\n    #[allow(dead_code)] // used as part of Debug impl\n    UnexpectedHeader(u8),\n}\n\n/// Top-Level GDB packet\npub enum Packet<'a> {\n    Ack,\n    Nack,\n    Interrupt,\n    Command(Command<'a>),\n}\n\n/// Wrapper around a byte buffer containing a GDB packet, while also tracking\n/// the range of the buffer containing the packet's \"body\".\n///\n/// A newly constructed `PacketBuf` will have a body that spans the entire data\n/// portion of the packet (i.e: `b\"$data#checksum\"`), but this range can be\n/// further restricted as part of packet parsing.\n///\n/// Notably, `PacketBuf` will _always_ maintain a mutable reference back to the\n/// _entire_ underlying packet buffer. This makes it possible to re-use any\n/// unused buffer space as \"scratch\" space. One notable example of this use-case\n/// is the 'm' packet, which recycles unused packet buffer space as a buffer for\n/// the target's `read_memory` method.\npub struct PacketBuf<'a> {\n    buf: &'a mut [u8],\n    body_range: core::ops::Range<usize>,\n}\n\nimpl<'a> PacketBuf<'a> {\n    /// Validate the contents of the raw packet buffer, checking for checksum\n    /// consistency and structural correctness.\n    pub fn new(pkt_buf: &'a mut [u8]) -> Result<PacketBuf<'a>, PacketParseError> {\n        if pkt_buf.is_empty() {\n            return Err(PacketParseError::EmptyBuf);\n        }\n\n        // split buffer into body and checksum components\n        let mut parts = pkt_buf[1..].split(|b| *b == b'#');\n\n        let body = parts.next().unwrap(); // spit iter always returns at least one element\n        let checksum = parts\n            .next()\n            .ok_or(PacketParseError::MissingChecksum)?\n            .get(..2)\n            .ok_or(PacketParseError::MalformedChecksum)?;\n\n        // validate the checksum\n        let checksum = decode_hex(checksum).map_err(|_| PacketParseError::MalformedChecksum)?;\n        let calculated = body.iter().fold(0u8, |a, x| a.wrapping_add(*x));\n        if calculated != checksum {\n            return Err(PacketParseError::ChecksumMismatched {\n                checksum,\n                calculated,\n            });\n        }\n\n        let body_range = 1..(body.len() + 1); // compensate for the leading '$'\n\n        Ok(PacketBuf {\n            buf: pkt_buf,\n            body_range,\n        })\n    }\n\n    /// (used for tests) Create a packet buffer from a raw body buffer, skipping\n    /// the header/checksum trimming stage.\n    #[cfg(test)]\n    pub fn new_with_raw_body(body: &'a mut [u8]) -> Result<PacketBuf<'a>, PacketParseError> {\n        let len = body.len();\n        Ok(PacketBuf {\n            buf: body,\n            body_range: 0..len,\n        })\n    }\n\n    /// Strip the specified prefix from the packet buffer, returning `true` if\n    /// there was a prefix match.\n    pub fn strip_prefix(&mut self, prefix: &[u8]) -> bool {\n        let body = {\n            // SAFETY: The public interface of `PacketBuf` ensures that `self.body_range`\n            // always stays within the bounds of the provided buffer.\n            #[cfg(not(feature = \"paranoid_unsafe\"))]\n            unsafe {\n                self.buf.get_unchecked_mut(self.body_range.clone())\n            }\n\n            #[cfg(feature = \"paranoid_unsafe\")]\n            &mut self.buf[self.body_range.clone()]\n        };\n\n        if body.starts_with(prefix) {\n            // SAFETY: if the current buffer range `starts_with` the specified prefix, then\n            // it is safe to bump `body_range.start` by the prefix length.\n            self.body_range = (self.body_range.start + prefix.len())..self.body_range.end;\n            true\n        } else {\n            false\n        }\n    }\n\n    /// Return a mutable reference to slice of the packet buffer corresponding\n    /// to the current body.\n    pub fn into_body(self) -> &'a mut [u8] {\n        // SAFETY: The public interface of `PacketBuf` ensures that `self.body_range`\n        // always stays within the bounds of the provided buffer.\n        #[cfg(not(feature = \"paranoid_unsafe\"))]\n        unsafe {\n            self.buf.get_unchecked_mut(self.body_range)\n        }\n\n        #[cfg(feature = \"paranoid_unsafe\")]\n        &mut self.buf[self.body_range]\n    }\n\n    /// Return a mutable reference to the _entire_ underlying packet buffer, and\n    /// the current body's range.\n    pub fn into_raw_buf(self) -> (&'a mut [u8], core::ops::Range<usize>) {\n        (self.buf, self.body_range)\n    }\n\n    /// Returns the length of the _entire_ underlying packet buffer - not just\n    /// the length of the current range.\n    ///\n    /// This method is used when handing the `qSupported` packet in order to\n    /// obtain the maximum packet size the stub supports.\n    pub fn full_len(&self) -> usize {\n        self.buf.len()\n    }\n}\n\nimpl<'a> Packet<'a> {\n    pub fn from_buf(\n        target: &mut impl Target,\n        buf: &'a mut [u8],\n    ) -> Result<Packet<'a>, PacketParseError> {\n        // cannot have empty packet\n        if buf.is_empty() {\n            return Err(PacketParseError::EmptyBuf);\n        }\n\n        match buf[0] {\n            b'$' => Ok(Packet::Command(\n                Command::from_packet(target, PacketBuf::new(buf)?)\n                    .ok_or(PacketParseError::MalformedCommand)?,\n            )),\n            b'+' => Ok(Packet::Ack),\n            b'-' => Ok(Packet::Nack),\n            0x03 => Ok(Packet::Interrupt),\n            _ => Err(PacketParseError::UnexpectedHeader(buf[0])),\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/recv_packet.rs",
    "content": "use crate::util::managed_vec::CapacityError;\nuse crate::util::managed_vec::ManagedVec;\n#[cfg(feature = \"trace-pkt\")]\nuse alloc::string::String;\nuse managed::ManagedSlice;\n\nenum State {\n    Ready,\n    Body,\n    Checksum1,\n    Checksum2,\n}\n\n/// Receives a packet incrementally using a asynchronous state machine.\npub struct RecvPacketStateMachine {\n    state: State,\n    idx: usize,\n}\n\nimpl RecvPacketStateMachine {\n    pub fn new() -> Self {\n        RecvPacketStateMachine {\n            state: State::Ready,\n            idx: 0,\n        }\n    }\n\n    pub fn pump<'b>(\n        &mut self,\n        packet_buffer: &'b mut ManagedSlice<'_, u8>,\n        byte: u8,\n    ) -> Result<Option<&'b mut [u8]>, CapacityError<u8>> {\n        let mut buf = ManagedVec::new_with_idx(packet_buffer, self.idx);\n        buf.push(byte)?;\n        self.idx += 1;\n\n        match self.state {\n            State::Ready => {\n                if byte == b'$' {\n                    self.state = State::Body;\n                } else {\n                    self.idx = 0;\n                }\n            }\n            State::Body => {\n                if byte == b'#' {\n                    self.state = State::Checksum1;\n                }\n            }\n            State::Checksum1 => self.state = State::Checksum2,\n            State::Checksum2 => {\n                self.state = State::Ready;\n                self.idx = 0;\n            }\n        }\n\n        if matches!(self.state, State::Ready) {\n            #[cfg(feature = \"trace-pkt\")]\n            trace!(\"<-- {}\", String::from_utf8_lossy(buf.as_slice()));\n\n            Ok(Some(packet_buffer))\n        } else {\n            Ok(None)\n        }\n    }\n}\n"
  },
  {
    "path": "src/protocol/response_writer.rs",
    "content": "use crate::conn::Connection;\nuse crate::internal::BeBytes;\nuse crate::protocol::SpecificIdKind;\nuse crate::protocol::SpecificThreadId;\n#[cfg(feature = \"trace-pkt\")]\nuse alloc::string::String;\n#[cfg(feature = \"trace-pkt\")]\nuse alloc::vec::Vec;\nuse num_traits::identities::one;\nuse num_traits::CheckedRem;\nuse num_traits::PrimInt;\n\n/// Newtype around a Connection error. Having a newtype allows implementing a\n/// `From<ResponseWriterError<C>> for crate::Error<T, C>`, which greatly\n/// simplifies some of the error handling in the main gdbstub.\n#[derive(Debug, Clone)]\npub struct Error<C>(pub C);\n\n/// A wrapper around [`Connection`] that computes the single-byte checksum of\n/// incoming / outgoing data.\npub struct ResponseWriter<'a, C: Connection> {\n    inner: &'a mut C,\n    started: bool,\n    checksum: u8,\n\n    rle_enabled: bool,\n    rle_char: u8,\n    rle_repeat: u8,\n\n    // buffer to log outgoing packets. only allocates if logging is enabled.\n    #[cfg(feature = \"trace-pkt\")]\n    msg: Vec<u8>,\n}\n\nimpl<'a, C: Connection + 'a> ResponseWriter<'a, C> {\n    /// Creates a new ResponseWriter\n    pub fn new(inner: &'a mut C, rle_enabled: bool) -> Self {\n        Self {\n            inner,\n            started: false,\n            checksum: 0,\n\n            rle_enabled,\n            rle_char: 0,\n            rle_repeat: 0,\n\n            #[cfg(feature = \"trace-pkt\")]\n            msg: Vec::new(),\n        }\n    }\n\n    /// Consumes self, writing out the final '#' and checksum\n    pub fn flush(mut self) -> Result<(), Error<C::Error>> {\n        // don't include the '#' in checksum calculation\n        let checksum = if self.rle_enabled {\n            self.write(b'#')?;\n            // (note: even though `self.write` was called, the the '#' char hasn't been\n            // added to the checksum, and is just sitting in the RLE buffer)\n            self.checksum\n        } else {\n            let checksum = self.checksum;\n            self.write(b'#')?;\n            checksum\n        };\n\n        self.write_hex(checksum)?;\n\n        // HACK: \"write\" a dummy char to force an RLE flush\n        if self.rle_enabled {\n            self.write(0)?;\n        }\n\n        #[cfg(feature = \"trace-pkt\")]\n        trace!(\"--> ${}\", String::from_utf8_lossy(&self.msg));\n\n        self.inner.flush().map_err(Error)?;\n\n        Ok(())\n    }\n\n    /// Get a mutable reference to the underlying connection.\n    pub fn as_conn(&mut self) -> &mut C {\n        self.inner\n    }\n\n    fn inner_write(&mut self, byte: u8) -> Result<(), Error<C::Error>> {\n        #[cfg(feature = \"trace-pkt\")]\n        if log_enabled!(log::Level::Trace) {\n            if self.rle_enabled {\n                match self.msg.as_slice() {\n                    [.., c, b'*'] => {\n                        let c = *c;\n                        self.msg.pop();\n                        for _ in 0..(byte - 29) {\n                            self.msg.push(c);\n                        }\n                    }\n                    _ => self.msg.push(byte),\n                }\n            } else {\n                self.msg.push(byte)\n            }\n        }\n\n        if !self.started {\n            self.started = true;\n            self.inner.write(b'$').map_err(Error)?;\n        }\n\n        self.checksum = self.checksum.wrapping_add(byte);\n        self.inner.write(byte).map_err(Error)\n    }\n\n    fn write(&mut self, byte: u8) -> Result<(), Error<C::Error>> {\n        if !self.rle_enabled {\n            return self.inner_write(byte);\n        }\n\n        const ASCII_FIRST_PRINT: u8 = b' ';\n        const ASCII_LAST_PRINT: u8 = b'~';\n\n        // handle RLE\n        let rle_printable = (ASCII_FIRST_PRINT - 4 + (self.rle_repeat + 1)) <= ASCII_LAST_PRINT;\n        if byte == self.rle_char && rle_printable {\n            self.rle_repeat += 1;\n            Ok(())\n        } else {\n            loop {\n                match self.rle_repeat {\n                    0 => {} // happens once, after the first char is written\n                    // RLE doesn't win, just output the byte\n                    1 | 2 | 3 => {\n                        for _ in 0..self.rle_repeat {\n                            self.inner_write(self.rle_char)?\n                        }\n                    }\n                    // RLE would output an invalid char ('#' or '$')\n                    7 | 8 => {\n                        self.inner_write(self.rle_char)?;\n                        self.rle_repeat -= 1;\n                        continue;\n                    }\n                    // RLE wins for repetitions >4\n                    _ => {\n                        self.inner_write(self.rle_char)?;\n                        self.inner_write(b'*')?;\n                        self.inner_write(ASCII_FIRST_PRINT - 4 + self.rle_repeat)?;\n                    }\n                }\n\n                self.rle_char = byte;\n                self.rle_repeat = 1;\n\n                break Ok(());\n            }\n        }\n    }\n\n    /// Write an entire string over the connection.\n    pub fn write_str(&mut self, s: &str) -> Result<(), Error<C::Error>> {\n        for b in s.as_bytes().iter() {\n            self.write(*b)?;\n        }\n        Ok(())\n    }\n\n    /// Write a single byte as a hex string (two ascii chars)\n    fn write_hex(&mut self, byte: u8) -> Result<(), Error<C::Error>> {\n        for &digit in [(byte & 0xf0) >> 4, byte & 0x0f].iter() {\n            let c = match digit {\n                0..=9 => b'0' + digit,\n                10..=15 => b'a' + digit - 10,\n                // This match arm is unreachable, but the compiler isn't smart enough to optimize\n                // out the branch. As such, using `unreachable!` here would introduce panicking\n                // code to `gdbstub`.\n                //\n                // In this case, it'd be totally reasonable to use\n                // `unsafe { core::hint::unreachable_unchecked() }`, but i'll be honest, using some\n                // spooky unsafe compiler hints just to eek out a smidge more performance here just\n                // isn't worth the cognitive overhead.\n                //\n                // Moreover, I've played around with this code in godbolt.org, and it turns out that\n                // leaving this match arm as `=> digit` ends up generating the _exact same code_ as\n                // using `unreachable_unchecked` (at least on x86_64 targets compiled using the\n                // latest Rust compiler). YMMV on other platforms.\n                _ => digit,\n            };\n            self.write(c)?;\n        }\n        Ok(())\n    }\n\n    /// Write a byte-buffer as a hex string (i.e: two ascii chars / byte).\n    pub fn write_hex_buf(&mut self, data: &[u8]) -> Result<(), Error<C::Error>> {\n        for b in data.iter() {\n            self.write_hex(*b)?;\n        }\n        Ok(())\n    }\n\n    /// Write data using the binary protocol.\n    pub fn write_binary(&mut self, data: &[u8]) -> Result<(), Error<C::Error>> {\n        for &b in data.iter() {\n            match b {\n                b'#' | b'$' | b'}' | b'*' => {\n                    self.write(b'}')?;\n                    self.write(b ^ 0x20)?\n                }\n                _ => self.write(b)?,\n            }\n        }\n        Ok(())\n    }\n\n    /// Write a number as a big-endian hex string using the most compact\n    /// representation possible (i.e: trimming leading zeros).\n    pub fn write_num<D: BeBytes + PrimInt>(&mut self, digit: D) -> Result<(), Error<C::Error>> {\n        if digit.is_zero() {\n            return self.write_hex(0);\n        }\n\n        let mut buf = [0; 16];\n        // infallible (unless digit is a >128 bit number)\n        let len = digit.to_be_bytes(&mut buf).unwrap();\n        let buf = &buf[..len];\n        for b in buf.iter().copied().skip_while(|&b| b == 0) {\n            self.write_hex(b)?\n        }\n        Ok(())\n    }\n\n    /// Write a number as a decimal string, converting every digit to an ascii\n    /// char.\n    pub fn write_dec<D: PrimInt + CheckedRem>(\n        &mut self,\n        mut digit: D,\n    ) -> Result<(), Error<C::Error>> {\n        if digit.is_zero() {\n            return self.write(b'0');\n        }\n\n        let one: D = one();\n        let ten = (one << 3) + (one << 1);\n        let mut d = digit;\n        let mut pow_10 = one;\n        // Get the number of digits in digit\n        while d >= ten {\n            d = d / ten;\n            pow_10 = pow_10 * ten;\n        }\n\n        // Write every digit from left to right as an ascii char\n        while !pow_10.is_zero() {\n            let mut byte = 0;\n            // We have a single digit here which uses up to 4 bit\n            for i in 0..4 {\n                if !((digit / pow_10) & (one << i)).is_zero() {\n                    byte += 1 << i;\n                }\n            }\n            self.write(b'0' + byte)?;\n            digit = digit % pow_10;\n            pow_10 = pow_10 / ten;\n        }\n        Ok(())\n    }\n\n    #[inline]\n    fn write_specific_id_kind(&mut self, tid: SpecificIdKind) -> Result<(), Error<C::Error>> {\n        match tid {\n            SpecificIdKind::All => self.write_str(\"-1\")?,\n            SpecificIdKind::WithId(id) => self.write_num(id.get())?,\n        };\n        Ok(())\n    }\n\n    pub fn write_specific_thread_id(\n        &mut self,\n        tid: SpecificThreadId,\n    ) -> Result<(), Error<C::Error>> {\n        if let Some(pid) = tid.pid {\n            self.write_str(\"p\")?;\n            self.write_specific_id_kind(pid)?;\n            self.write_str(\".\")?;\n        }\n        self.write_specific_id_kind(tid.tid)?;\n        Ok(())\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use alloc::vec::Vec;\n\n    /// A mock connection that captures all written bytes\n    struct MockConnection {\n        data: Vec<u8>,\n    }\n\n    impl MockConnection {\n        fn new() -> Self {\n            Self { data: Vec::new() }\n        }\n    }\n\n    impl Connection for MockConnection {\n        type Error = ();\n\n        fn write(&mut self, byte: u8) -> Result<(), Self::Error> {\n            self.data.push(byte);\n            Ok(())\n        }\n\n        fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {\n            self.data.extend_from_slice(buf);\n            Ok(())\n        }\n\n        fn flush(&mut self) -> Result<(), Self::Error> {\n            Ok(())\n        }\n    }\n\n    /// Check that packet body (between '$' and '#') contains no '$' or '#'.\n    fn assert_no_special_chars_in_body(data: &[u8]) {\n        let hash_pos = data.iter().rposition(|&b| b == b'#').unwrap();\n        for &byte in &data[1..hash_pos] {\n            assert!(\n                byte != b'$' && byte != b'#',\n                \"found {:?} in packet body\",\n                byte as char\n            );\n        }\n    }\n\n    /// RLE must not produce '#' in packet body.\n    #[test]\n    fn rle_avoids_hash() {\n        let mut conn = MockConnection::new();\n        let mut writer = ResponseWriter::new(&mut conn, true);\n        writer.write_str(\"0000000\").unwrap();\n        writer.flush().unwrap();\n        assert_no_special_chars_in_body(&conn.data);\n    }\n\n    /// RLE must not produce '$' in packet body.\n    #[test]\n    fn rle_avoids_dollar() {\n        let mut conn = MockConnection::new();\n        let mut writer = ResponseWriter::new(&mut conn, true);\n        writer.write_str(\"00000000\").unwrap();\n        writer.flush().unwrap();\n        assert_no_special_chars_in_body(&conn.data);\n    }\n}\n"
  },
  {
    "path": "src/stub/builder.rs",
    "content": "use super::core_impl::GdbStubImpl;\nuse super::GdbStub;\nuse crate::conn::Connection;\nuse crate::target::Target;\nuse core::fmt::Display;\nuse core::fmt::{self};\nuse core::marker::PhantomData;\nuse managed::ManagedSlice;\n\n/// An error which may occur when building a [`GdbStub`].\n#[derive(Debug)]\npub enum GdbStubBuilderError {\n    /// Must provide buffer using `with_packet_buffer` in `#![no_std]` mode.\n    MissingPacketBuffer,\n    /// Custom packet buffer size is larger than the provided buffer's length.\n    PacketBufSizeMismatch,\n}\n\nimpl Display for GdbStubBuilderError {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        use self::GdbStubBuilderError::*;\n        match self {\n            MissingPacketBuffer => write!(\n                f,\n                \"Must provide buffer using `with_packet_buffer` in `#![no_std]` mode.\"\n            ),\n            PacketBufSizeMismatch => write!(\n                f,\n                \"`packet_buffer_size` is larger than `with_packet_buffer`'s size.\"\n            ),\n        }\n    }\n}\n\n#[cfg(feature = \"std\")]\nimpl std::error::Error for GdbStubBuilderError {}\n\n/// Helper to construct and customize [`GdbStub`].\npub struct GdbStubBuilder<'a, T: Target, C: Connection> {\n    conn: C,\n    packet_buffer: Option<&'a mut [u8]>,\n    packet_buffer_size: Option<usize>,\n\n    _target: PhantomData<T>,\n}\n\nimpl<'a, T: Target, C: Connection> GdbStubBuilder<'a, T, C> {\n    /// Create a new `GdbStubBuilder` using the provided Connection.\n    pub fn new(conn: C) -> GdbStubBuilder<'static, T, C> {\n        GdbStubBuilder {\n            conn,\n            packet_buffer: None,\n            packet_buffer_size: None,\n\n            _target: PhantomData,\n        }\n    }\n\n    /// Use a pre-allocated packet buffer (instead of heap-allocating).\n    ///\n    /// _Note:_ This method is _required_ when the `alloc` feature is disabled!\n    pub fn with_packet_buffer(mut self, packet_buffer: &'a mut [u8]) -> Self {\n        self.packet_buffer = Some(packet_buffer);\n        self\n    }\n\n    /// Specify a custom size for the packet buffer. Defaults to 4096 bytes.\n    ///\n    /// When used alongside `with_packet_buffer`, the provided `size` must be\n    /// less than or equal to the length of the packet buffer.\n    pub fn packet_buffer_size(mut self, size: usize) -> Self {\n        self.packet_buffer_size = Some(size);\n        self\n    }\n\n    /// Build the GdbStub, returning an error if something went wrong.\n    pub fn build(self) -> Result<GdbStub<'a, T, C>, GdbStubBuilderError> {\n        let packet_buffer = match self.packet_buffer {\n            Some(buf) => {\n                let buf = match self.packet_buffer_size {\n                    Some(custom_len) => {\n                        if custom_len > buf.len() {\n                            return Err(GdbStubBuilderError::PacketBufSizeMismatch);\n                        } else {\n                            &mut buf[..custom_len]\n                        }\n                    }\n                    None => buf,\n                };\n                ManagedSlice::Borrowed(buf)\n            }\n            None => {\n                cfg_if::cfg_if! {\n                    if #[cfg(feature = \"alloc\")] {\n                        use alloc::vec;\n                        // need to pick some arbitrary value to report to GDB\n                        // 4096 seems reasonable?\n                        let len = self.packet_buffer_size.unwrap_or(4096);\n                        ManagedSlice::Owned(vec![0; len])\n                    } else {\n                        return Err(GdbStubBuilderError::MissingPacketBuffer);\n                    }\n                }\n            }\n        };\n\n        Ok(GdbStub {\n            conn: self.conn,\n            packet_buffer,\n            inner: GdbStubImpl::new(),\n        })\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/auxv.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::commands::ext::Auxv;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_auxv(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: Auxv<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_auxv() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"auxv\", \"impl\");\n\n        let handler_status = match command {\n            Auxv::qXferAuxvRead(cmd) => {\n                let ret = ops\n                    .get_auxv(cmd.offset, cmd.length, cmd.buf)\n                    .handle_error()?;\n                if ret == 0 {\n                    res.write_str(\"l\")?;\n                } else {\n                    res.write_str(\"m\")?;\n                    // TODO: add more specific error variant?\n                    res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?;\n                }\n                HandlerStatus::Handled\n            }\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/base.rs",
    "content": "use super::prelude::*;\nuse super::DisconnectReason;\nuse crate::arch::Arch;\nuse crate::arch::Registers;\nuse crate::common::Pid;\nuse crate::common::Tid;\nuse crate::protocol::commands::ext::Base;\nuse crate::protocol::IdKind;\nuse crate::protocol::SpecificIdKind;\nuse crate::protocol::SpecificThreadId;\nuse crate::target::ext::base::BaseOps;\nuse crate::target::ext::base::ResumeOps;\nuse crate::FAKE_PID;\nuse crate::SINGLE_THREAD_TID;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    #[inline(always)]\n    fn get_sane_any_tid(\n        &mut self,\n        target: &mut T,\n    ) -> Result<Option<Tid>, Error<T::Error, C::Error>> {\n        let tid = match target.base_ops() {\n            BaseOps::SingleThread(_) => Some(SINGLE_THREAD_TID),\n            BaseOps::MultiThread(ops) => {\n                let mut first_tid = None;\n                ops.list_active_threads(&mut |tid| {\n                    if first_tid.is_none() {\n                        first_tid = Some(tid);\n                    }\n                })\n                .map_err(Error::TargetError)?;\n                // It is possible for this to be `None` in the case where the target has\n                // not yet called `register_thread()`. This can happen, for example, if\n                // there are no active threads in the current target process.\n                first_tid\n            }\n        };\n        Ok(tid)\n    }\n\n    pub(crate) fn get_current_pid(\n        &mut self,\n        target: &mut T,\n    ) -> Result<Pid, Error<T::Error, C::Error>> {\n        if let Some(ops) = target\n            .support_extended_mode()\n            .and_then(|ops| ops.support_current_active_pid())\n        {\n            ops.current_active_pid().map_err(Error::TargetError)\n        } else {\n            Ok(FAKE_PID)\n        }\n    }\n\n    // Used by `?` and `vAttach` to return a \"reasonable\" stop reason.\n    //\n    // This is a bit of an implementation wart, since this is really something\n    // the user ought to be able to customize.\n    //\n    // Works fine for now though...\n    pub(crate) fn report_reasonable_stop_reason(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        // Reply with a valid thread-id or GDB issues a warning when more\n        // than one thread is active\n        if let Some(tid) = self.get_sane_any_tid(target)? {\n            res.write_str(\"T05thread:\")?;\n            res.write_specific_thread_id(SpecificThreadId {\n                pid: self\n                    .features\n                    .multiprocess()\n                    .then_some(SpecificIdKind::WithId(self.get_current_pid(target)?)),\n                tid: SpecificIdKind::WithId(tid),\n            })?;\n        } else {\n            res.write_str(\"W00\")?;\n        }\n        res.write_str(\";\")?;\n        Ok(HandlerStatus::Handled)\n    }\n\n    pub(crate) fn handle_base(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: Base<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let handler_status = match command {\n            // ------------------ Handshaking and Queries ------------------- //\n            Base::qSupported(cmd) => {\n                use crate::protocol::commands::_qSupported::Feature;\n\n                // perform incoming feature negotiation\n                for feature in cmd.features.into_iter() {\n                    let (feature, supported) = match feature {\n                        Ok(Some(v)) => v,\n                        Ok(None) => continue,\n                        Err(()) => {\n                            return Err(Error::PacketParse(\n                                crate::protocol::PacketParseError::MalformedCommand,\n                            ))\n                        }\n                    };\n\n                    match feature {\n                        Feature::Multiprocess => self.features.set_multiprocess(supported),\n                    }\n                }\n\n                res.write_str(\"PacketSize=\")?;\n                res.write_num(cmd.packet_buffer_len)?;\n\n                // these are the few features that gdbstub unconditionally supports\n                res.write_str(concat!(\";vContSupported+\", \";multiprocess+\",))?;\n\n                if target.use_no_ack_mode() {\n                    res.write_str(\";QStartNoAckMode+\")?;\n                }\n\n                if target.use_fork_stop_reason() {\n                    res.write_str(\";fork-events+\")?;\n                }\n\n                if target.use_vfork_stop_reason() {\n                    res.write_str(\";vfork-events+\")?;\n                }\n\n                if target.use_vforkdone_stop_reason() {\n                    res.write_str(\";vforkdone-events+\")?;\n                }\n\n                if target.use_x_lowcase_packet() {\n                    res.write_str(\";binary-upload+\")?;\n                }\n\n                if let Some(resume_ops) = target.base_ops().resume_ops() {\n                    let (reverse_cont, reverse_step) = match resume_ops {\n                        ResumeOps::MultiThread(ops) => (\n                            ops.support_reverse_cont().is_some(),\n                            ops.support_reverse_step().is_some(),\n                        ),\n                        ResumeOps::SingleThread(ops) => (\n                            ops.support_reverse_cont().is_some(),\n                            ops.support_reverse_step().is_some(),\n                        ),\n                    };\n\n                    if reverse_cont {\n                        res.write_str(\";ReverseContinue+\")?;\n                    }\n\n                    if reverse_step {\n                        res.write_str(\";ReverseStep+\")?;\n                    }\n                }\n\n                if let Some(ops) = target.support_extended_mode() {\n                    if ops.support_configure_aslr().is_some() {\n                        res.write_str(\";QDisableRandomization+\")?;\n                    }\n\n                    if ops.support_configure_env().is_some() {\n                        res.write_str(\";QEnvironmentHexEncoded+\")?;\n                        res.write_str(\";QEnvironmentUnset+\")?;\n                        res.write_str(\";QEnvironmentReset+\")?;\n                    }\n\n                    if ops.support_configure_startup_shell().is_some() {\n                        res.write_str(\";QStartupWithShell+\")?;\n                    }\n\n                    if ops.support_configure_working_dir().is_some() {\n                        res.write_str(\";QSetWorkingDir+\")?;\n                    }\n                }\n\n                if let Some(ops) = target.support_breakpoints() {\n                    if ops.support_sw_breakpoint().is_some() {\n                        res.write_str(\";swbreak+\")?;\n                    }\n\n                    if ops.support_hw_breakpoint().is_some()\n                        || ops.support_hw_watchpoint().is_some()\n                    {\n                        res.write_str(\";hwbreak+\")?;\n                    }\n                }\n\n                if let Some(ops) = target.support_tracepoints() {\n                    // There are a number of optional tracepoint extensions that\n                    // gdbstub should eventually implement.\n                    // * `StaticTracepoint` for static tracepoint support.\n                    // * `EnableDisableTracepoints` for enabling/disabling tracepoints during a\n                    //   trace experiment.\n                    // * `tracenz` for the tracenz agent bytecode operation.\n                    // * The `Qbtrace:*` family for branch tracing.\n                    // * `InstallInTrace` allows for gdbstub to deliver tracepoint configuration\n                    //   commands while the trace experiment is running instead of them only taking\n                    //   affect on the next `tstart` command.\n                    //\n                    // For now, gdbstub doesn't provide trait extensions for these\n                    // options and so we don't report support. We do report support\n                    // for one extension however:\n                    // * `QTBuffer:size` for configuring the trace buffer size, since the target is\n                    //   allowed to implement it as a no-op.\n                    res.write_str(\";QTBuffer:size+\")?;\n                    if ops.support_tracepoint_source().is_some() {\n                        res.write_str(\";TracepointSource+\")?;\n                    }\n                }\n\n                if target.support_catch_syscalls().is_some() {\n                    res.write_str(\";QCatchSyscalls+\")?;\n                }\n\n                if target.use_target_description_xml()\n                    && (T::Arch::target_description_xml().is_some()\n                        || target.support_target_description_xml_override().is_some())\n                {\n                    res.write_str(\";qXfer:features:read+\")?;\n                }\n\n                if target.support_memory_map().is_some() {\n                    res.write_str(\";qXfer:memory-map:read+\")?;\n                }\n\n                if target.support_exec_file().is_some() {\n                    res.write_str(\";qXfer:exec-file:read+\")?;\n                }\n\n                if target.support_auxv().is_some() {\n                    res.write_str(\";qXfer:auxv:read+\")?;\n                }\n\n                if target.support_libraries_svr4().is_some() {\n                    res.write_str(\";qXfer:libraries-svr4:read+\")?;\n                }\n\n                if target.support_libraries().is_some() {\n                    res.write_str(\";qXfer:libraries:read+\")?;\n                }\n\n                HandlerStatus::Handled\n            }\n\n            // -------------------- \"Core\" Functionality -------------------- //\n            Base::QuestionMark(_) => {\n                // TODO: Improve the '?' response.\n                // this will be particularly relevant when working on non-stop mode.\n                self.report_reasonable_stop_reason(res, target)?\n            }\n            Base::qAttached(cmd) => {\n                let is_attached = match target.support_extended_mode() {\n                    // when _not_ running in extended mode, just report that we're attaching to an\n                    // existing process.\n                    None => true, // assume attached to an existing process\n                    // When running in extended mode, we must defer to the target\n                    Some(ops) => {\n                        match cmd.pid {\n                            Some(pid) => ops.query_if_attached(pid).handle_error()?.was_attached(),\n                            None => true, // assume attached to an existing process\n                        }\n                    }\n                };\n                res.write_str(if is_attached { \"1\" } else { \"0\" })?;\n                HandlerStatus::Handled\n            }\n            Base::g(_) => {\n                let mut regs: <T::Arch as Arch>::Registers = Default::default();\n                match target.base_ops() {\n                    BaseOps::SingleThread(ops) => ops.read_registers(&mut regs),\n                    BaseOps::MultiThread(ops) => {\n                        ops.read_registers(&mut regs, self.current_mem_tid)\n                    }\n                }\n                .handle_error()?;\n\n                let mut err = Ok(());\n                regs.gdb_serialize(|val| {\n                    let res = match val {\n                        Some(b) => res.write_hex_buf(&[b]),\n                        None => res.write_str(\"xx\"),\n                    };\n                    if let Err(e) = res {\n                        err = Err(e);\n                    }\n                });\n                err?;\n                HandlerStatus::Handled\n            }\n            Base::G(cmd) => {\n                let mut regs: <T::Arch as Arch>::Registers = Default::default();\n                regs.gdb_deserialize(cmd.vals)\n                    .map_err(|_| Error::TargetMismatch)?;\n\n                match target.base_ops() {\n                    BaseOps::SingleThread(ops) => ops.write_registers(&regs),\n                    BaseOps::MultiThread(ops) => ops.write_registers(&regs, self.current_mem_tid),\n                }\n                .handle_error()?;\n\n                HandlerStatus::NeedsOk\n            }\n            Base::m(cmd) => {\n                read_addr_handler::<C, T>(\n                    |_, data| res.write_hex_buf(data),\n                    self.current_mem_tid,\n                    target,\n                    cmd.buf,\n                    cmd.len,\n                    cmd.addr,\n                )?;\n                HandlerStatus::Handled\n            }\n            Base::M(cmd) => {\n                let addr = <T::Arch as Arch>::Usize::from_be_bytes(cmd.addr)\n                    .ok_or(Error::TargetMismatch)?;\n\n                match target.base_ops() {\n                    BaseOps::SingleThread(ops) => ops.write_addrs(addr, cmd.val),\n                    BaseOps::MultiThread(ops) => {\n                        ops.write_addrs(addr, cmd.val, self.current_mem_tid)\n                    }\n                }\n                .handle_error()?;\n\n                HandlerStatus::NeedsOk\n            }\n            Base::k(_) | Base::vKill(_) => {\n                match target.support_extended_mode() {\n                    // When not running in extended mode, stop the `GdbStub` and disconnect.\n                    None => HandlerStatus::Disconnect(DisconnectReason::Kill),\n\n                    // When running in extended mode, a kill command does not necessarily result in\n                    // a disconnect...\n                    Some(ops) => {\n                        let pid = match command {\n                            Base::vKill(cmd) => Some(cmd.pid),\n                            _ => None,\n                        };\n\n                        let should_terminate = ops.kill(pid).handle_error()?;\n                        if should_terminate.into_bool() {\n                            // manually write OK, since we need to return a DisconnectReason\n                            res.write_str(\"OK\")?;\n                            HandlerStatus::Disconnect(DisconnectReason::Kill)\n                        } else {\n                            HandlerStatus::NeedsOk\n                        }\n                    }\n                }\n            }\n            Base::D(cmd) => {\n                // TODO: plumb-through Pid when exposing full multiprocess + extended mode\n                let _pid = cmd.pid;\n                res.write_str(\"OK\")?; // manually write OK, since we need to return a DisconnectReason\n                HandlerStatus::Disconnect(DisconnectReason::Disconnect)\n            }\n\n            // ------------------- Multi-threading Support ------------------ //\n            Base::H(cmd) => {\n                use crate::protocol::commands::_h_upcase::Op;\n                match cmd.kind {\n                    Op::Other => match cmd.thread.tid {\n                        IdKind::Any => match self.get_sane_any_tid(target)? {\n                            Some(tid) => self.current_mem_tid = tid,\n                            None => {\n                                return Err(Error::NonFatalError(1));\n                            }\n                        },\n                        // \"All\" threads doesn't make sense for memory accesses\n                        IdKind::All => return Err(Error::PacketUnexpected),\n                        IdKind::WithId(tid) => self.current_mem_tid = tid,\n                    },\n                    // technically, this variant is deprecated in favor of vCont...\n                    Op::StepContinue => match cmd.thread.tid {\n                        IdKind::Any => match self.get_sane_any_tid(target)? {\n                            Some(tid) => self.current_resume_tid = SpecificIdKind::WithId(tid),\n                            None => {\n                                return Err(Error::NonFatalError(1));\n                            }\n                        },\n                        IdKind::All => self.current_resume_tid = SpecificIdKind::All,\n                        IdKind::WithId(tid) => {\n                            self.current_resume_tid = SpecificIdKind::WithId(tid)\n                        }\n                    },\n                }\n                HandlerStatus::NeedsOk\n            }\n            Base::qfThreadInfo(_) => {\n                res.write_str(\"m\")?;\n                let pid = self.get_current_pid(target)?;\n\n                match target.base_ops() {\n                    BaseOps::SingleThread(_) => res.write_specific_thread_id(SpecificThreadId {\n                        pid: self\n                            .features\n                            .multiprocess()\n                            .then_some(SpecificIdKind::WithId(pid)),\n                        tid: SpecificIdKind::WithId(SINGLE_THREAD_TID),\n                    })?,\n                    BaseOps::MultiThread(ops) => {\n                        let mut err: Result<_, Error<T::Error, C::Error>> = Ok(());\n                        let mut first = true;\n                        ops.list_active_threads(&mut |tid| {\n                            // TODO: replace this with a try block (once stabilized)\n                            let e = (|| {\n                                if !first {\n                                    res.write_str(\",\")?\n                                }\n                                first = false;\n                                res.write_specific_thread_id(SpecificThreadId {\n                                    pid: self\n                                        .features\n                                        .multiprocess()\n                                        .then_some(SpecificIdKind::WithId(pid)),\n                                    tid: SpecificIdKind::WithId(tid),\n                                })?;\n                                Ok(())\n                            })();\n\n                            if let Err(e) = e {\n                                err = Err(e)\n                            }\n                        })\n                        .map_err(Error::TargetError)?;\n                        err?;\n                    }\n                }\n\n                HandlerStatus::Handled\n            }\n            Base::qsThreadInfo(_) => {\n                res.write_str(\"l\")?;\n                HandlerStatus::Handled\n            }\n            Base::T(cmd) => {\n                let alive = match cmd.thread.tid {\n                    IdKind::WithId(tid) => match target.base_ops() {\n                        BaseOps::SingleThread(_) => tid == SINGLE_THREAD_TID,\n                        BaseOps::MultiThread(ops) => {\n                            ops.is_thread_alive(tid).map_err(Error::TargetError)?\n                        }\n                    },\n                    _ => return Err(Error::PacketUnexpected),\n                };\n                if alive {\n                    HandlerStatus::NeedsOk\n                } else {\n                    // any error code will do\n                    return Err(Error::NonFatalError(1));\n                }\n            }\n        };\n        Ok(handler_status)\n    }\n}\n\n// shared by both the 'm' and 'x' packet handlers\npub(crate) fn read_addr_handler<C: Connection, T: Target>(\n    mut write_res: impl FnMut(\n        usize,\n        &[u8],\n    ) -> Result<(), crate::protocol::ResponseWriterError<C::Error>>,\n    current_mem_tid: Tid,\n    target: &mut T,\n    buf: &mut [u8],\n    len: usize,\n    addr: &[u8],\n) -> Result<(), Error<T::Error, C::Error>> {\n    let addr = <T::Arch as Arch>::Usize::from_be_bytes(addr).ok_or(Error::TargetMismatch)?;\n    let mut i = 0;\n    let mut n = len;\n    while n != 0 {\n        let chunk_size = n.min(buf.len());\n\n        let addr = addr + num_traits::NumCast::from(i).ok_or(Error::TargetMismatch)?;\n        let data = &mut buf[..chunk_size];\n        let data_len = match target.base_ops() {\n            BaseOps::SingleThread(ops) => ops.read_addrs(addr, data),\n            BaseOps::MultiThread(ops) => ops.read_addrs(addr, data, current_mem_tid),\n        }\n        .handle_error()?;\n\n        // TODO: add more specific error variant?\n        let data = data.get(..data_len).ok_or(Error::PacketBufferOverflow)?;\n        write_res(i, data)?;\n\n        n -= chunk_size;\n        i += chunk_size;\n    }\n    Ok(())\n}\n"
  },
  {
    "path": "src/stub/core_impl/breakpoints.rs",
    "content": "use super::prelude::*;\nuse crate::arch::Arch;\nuse crate::arch::BreakpointKind;\nuse crate::protocol::commands::ext::Breakpoints;\n\nenum CmdKind {\n    Add,\n    Remove,\n}\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    #[inline(always)]\n    fn handle_breakpoint_common(\n        &mut self,\n        ops: crate::target::ext::breakpoints::BreakpointsOps<'_, T>,\n        cmd: crate::protocol::commands::breakpoint::BasicBreakpoint<'_>,\n        cmd_kind: CmdKind,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let addr =\n            <T::Arch as Arch>::Usize::from_be_bytes(cmd.addr).ok_or(Error::TargetMismatch)?;\n\n        macro_rules! bp_kind {\n            () => {\n                BeBytes::from_be_bytes(cmd.kind)\n                    .and_then(<T::Arch as Arch>::BreakpointKind::from_usize)\n                    .ok_or(Error::TargetMismatch)?\n            };\n        }\n\n        let supported = match cmd.type_ {\n            0 if ops.support_sw_breakpoint().is_some() => {\n                let ops = ops.support_sw_breakpoint().unwrap();\n                let bp_kind = bp_kind!();\n                match cmd_kind {\n                    CmdKind::Add => ops.add_sw_breakpoint(addr, bp_kind),\n                    CmdKind::Remove => ops.remove_sw_breakpoint(addr, bp_kind),\n                }\n            }\n            1 if ops.support_hw_breakpoint().is_some() => {\n                let ops = ops.support_hw_breakpoint().unwrap();\n                let bp_kind = bp_kind!();\n                match cmd_kind {\n                    CmdKind::Add => ops.add_hw_breakpoint(addr, bp_kind),\n                    CmdKind::Remove => ops.remove_hw_breakpoint(addr, bp_kind),\n                }\n            }\n            2 | 3 | 4 if ops.support_hw_watchpoint().is_some() => {\n                use crate::target::ext::breakpoints::WatchKind;\n                let kind = match cmd.type_ {\n                    2 => WatchKind::Write,\n                    3 => WatchKind::Read,\n                    4 => WatchKind::ReadWrite,\n                    #[allow(clippy::unreachable)] // will be optimized out\n                    _ => unreachable!(),\n                };\n                let len = <T::Arch as Arch>::Usize::from_be_bytes(cmd.kind)\n                    .ok_or(Error::TargetMismatch)?;\n                let ops = ops.support_hw_watchpoint().unwrap();\n                match cmd_kind {\n                    CmdKind::Add => ops.add_hw_watchpoint(addr, len, kind),\n                    CmdKind::Remove => ops.remove_hw_watchpoint(addr, len, kind),\n                }\n            }\n            // explicitly handle unguarded variants of known breakpoint types\n            0 | 1 | 2 | 3 | 4 => return Ok(HandlerStatus::Handled),\n            // warn if the GDB client ever sends a type outside the known types\n            other => {\n                warn!(\"unknown breakpoint type: {}\", other);\n                return Ok(HandlerStatus::Handled);\n            }\n        };\n\n        match supported.handle_error()? {\n            true => Ok(HandlerStatus::NeedsOk),\n            false => Err(Error::NonFatalError(22)),\n        }\n    }\n\n    pub(crate) fn handle_breakpoints(\n        &mut self,\n        _res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: Breakpoints<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_breakpoints() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"breakpoints\", \"impl\");\n\n        let handler_status = match command {\n            Breakpoints::z(cmd) => self.handle_breakpoint_common(ops, cmd, CmdKind::Remove)?,\n            Breakpoints::Z(cmd) => self.handle_breakpoint_common(ops, cmd, CmdKind::Add)?,\n            // TODO: handle ZWithBytecode once agent expressions are implemented\n            _ => HandlerStatus::Handled,\n        };\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/catch_syscalls.rs",
    "content": "use super::prelude::*;\nuse crate::arch::Arch;\nuse crate::protocol::commands::_QCatchSyscalls::QCatchSyscalls;\nuse crate::protocol::commands::ext::CatchSyscalls;\nuse crate::target::ext::catch_syscalls::SyscallNumbers;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_catch_syscalls(\n        &mut self,\n        _res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: CatchSyscalls<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_catch_syscalls() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"catch_syscalls\", \"impl\");\n\n        let handler_status = match command {\n            CatchSyscalls::QCatchSyscalls(cmd) => {\n                match cmd {\n                    QCatchSyscalls::Disable => ops.disable_catch_syscalls().handle_error()?,\n                    QCatchSyscalls::Enable(sysno) => {\n                        let mut error = false;\n                        let mut filter = sysno\n                            .into_iter()\n                            .map(<T::Arch as Arch>::Usize::from_be_bytes)\n                            .take_while(|x| {\n                                error = x.is_none();\n                                !error\n                            })\n                            .flatten();\n                        ops.enable_catch_syscalls(Some(SyscallNumbers { inner: &mut filter }))\n                            .handle_error()?;\n                        if error {\n                            return Err(Error::TargetMismatch);\n                        }\n                    }\n                    QCatchSyscalls::EnableAll => ops.enable_catch_syscalls(None).handle_error()?,\n                }\n                HandlerStatus::NeedsOk\n            }\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/exec_file.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::commands::ext::ExecFile;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_exec_file(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: ExecFile<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_exec_file() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"exec_file\", \"impl\");\n\n        let handler_status = match command {\n            ExecFile::qXferExecFileRead(cmd) => {\n                let ret = ops\n                    .get_exec_file(cmd.annex.pid, cmd.offset, cmd.length, cmd.buf)\n                    .handle_error()?;\n                if ret == 0 {\n                    res.write_str(\"l\")?;\n                } else {\n                    res.write_str(\"m\")?;\n                    // TODO: add more specific error variant?\n                    res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?;\n                }\n                HandlerStatus::Handled\n            }\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/extended_mode.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::commands::ext::ExtendedMode;\nuse crate::protocol::SpecificIdKind;\nuse crate::protocol::SpecificThreadId;\nuse crate::target::ext::base::BaseOps;\nuse crate::SINGLE_THREAD_TID;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_extended_mode(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: ExtendedMode<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_extended_mode() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"extended_mode\", \"impl\");\n\n        let handler_status = match command {\n            ExtendedMode::ExclamationMark(_cmd) => {\n                ops.on_start().map_err(Error::TargetError)?;\n                HandlerStatus::NeedsOk\n            }\n            ExtendedMode::R(_cmd) => {\n                ops.restart().map_err(Error::TargetError)?;\n                HandlerStatus::Handled\n            }\n            ExtendedMode::vAttach(cmd) => {\n                if ops.support_current_active_pid().is_none() {\n                    return Err(Error::MissingCurrentActivePidImpl);\n                }\n\n                ops.attach(cmd.pid).handle_error()?;\n                self.report_reasonable_stop_reason(res, target)?\n            }\n            ExtendedMode::qC(_cmd) if ops.support_current_active_pid().is_some() => {\n                let ops = ops.support_current_active_pid().unwrap();\n\n                res.write_str(\"QC\")?;\n                let pid = ops.current_active_pid().map_err(Error::TargetError)?;\n                let tid = match target.base_ops() {\n                    BaseOps::SingleThread(_) => SINGLE_THREAD_TID,\n                    BaseOps::MultiThread(ops) => {\n                        // HACK: gdbstub should avoid using a sentinel value here...\n                        if self.current_mem_tid == SINGLE_THREAD_TID {\n                            let mut err: Result<_, Error<T::Error, C::Error>> = Ok(());\n                            let mut first_tid = None;\n                            ops.list_active_threads(&mut |tid| {\n                                // TODO: replace this with a try block (once stabilized)\n                                let e = (|| {\n                                    if first_tid.is_some() {\n                                        return Ok(());\n                                    }\n                                    first_tid = Some(tid);\n                                    Ok(())\n                                })();\n\n                                if let Err(e) = e {\n                                    err = Err(e)\n                                }\n                            })\n                            .map_err(Error::TargetError)?;\n                            err?;\n                            first_tid.unwrap_or(SINGLE_THREAD_TID)\n                        } else {\n                            self.current_mem_tid\n                        }\n                    }\n                };\n\n                res.write_specific_thread_id(SpecificThreadId {\n                    pid: self\n                        .features\n                        .multiprocess()\n                        .then_some(SpecificIdKind::WithId(pid)),\n                    tid: SpecificIdKind::WithId(tid),\n                })?;\n\n                HandlerStatus::Handled\n            }\n            ExtendedMode::vRun(cmd) => {\n                use crate::target::ext::extended_mode::Args;\n\n                let _pid = ops\n                    .run(cmd.filename, Args::new(&mut cmd.args.into_iter()))\n                    .handle_error()?;\n\n                self.report_reasonable_stop_reason(res, target)?\n            }\n            // --------- ASLR --------- //\n            ExtendedMode::QDisableRandomization(cmd) if ops.support_configure_aslr().is_some() => {\n                let ops = ops.support_configure_aslr().unwrap();\n                ops.cfg_aslr(cmd.value).handle_error()?;\n                HandlerStatus::NeedsOk\n            }\n            // --------- Environment --------- //\n            ExtendedMode::QEnvironmentHexEncoded(cmd) if ops.support_configure_env().is_some() => {\n                let ops = ops.support_configure_env().unwrap();\n                ops.set_env(cmd.key, cmd.value).handle_error()?;\n                HandlerStatus::NeedsOk\n            }\n            ExtendedMode::QEnvironmentUnset(cmd) if ops.support_configure_env().is_some() => {\n                let ops = ops.support_configure_env().unwrap();\n                ops.remove_env(cmd.key).handle_error()?;\n                HandlerStatus::NeedsOk\n            }\n            ExtendedMode::QEnvironmentReset(_cmd) if ops.support_configure_env().is_some() => {\n                let ops = ops.support_configure_env().unwrap();\n                ops.reset_env().handle_error()?;\n                HandlerStatus::NeedsOk\n            }\n            // --------- Working Dir --------- //\n            ExtendedMode::QSetWorkingDir(cmd) if ops.support_configure_working_dir().is_some() => {\n                let ops = ops.support_configure_working_dir().unwrap();\n                ops.cfg_working_dir(cmd.dir).handle_error()?;\n                HandlerStatus::NeedsOk\n            }\n            // --------- Startup Shell --------- //\n            ExtendedMode::QStartupWithShell(cmd)\n                if ops.support_configure_startup_shell().is_some() =>\n            {\n                let ops = ops.support_configure_startup_shell().unwrap();\n                ops.cfg_startup_with_shell(cmd.value).handle_error()?;\n                HandlerStatus::NeedsOk\n            }\n\n            _ => HandlerStatus::Handled,\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/flash.rs",
    "content": "use super::prelude::*;\nuse crate::arch::Arch;\nuse crate::protocol::commands::ext::FlashOperations;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_flash_operations(\n        &mut self,\n        _res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: FlashOperations<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_flash_operations() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n        let handler_status = match command {\n            FlashOperations::vFlashErase(cmd) => {\n                let addr = <T::Arch as Arch>::Usize::from_be_bytes(cmd.addr)\n                    .ok_or(Error::TargetMismatch)?;\n\n                let length = <T::Arch as Arch>::Usize::from_be_bytes(cmd.length)\n                    .ok_or(Error::TargetMismatch)?;\n\n                ops.flash_erase(addr, length).handle_error()?;\n                HandlerStatus::NeedsOk\n            }\n            FlashOperations::vFlashWrite(cmd) => {\n                let addr = <T::Arch as Arch>::Usize::from_be_bytes(cmd.addr)\n                    .ok_or(Error::TargetMismatch)?;\n\n                ops.flash_write(addr, cmd.val).handle_error()?;\n                HandlerStatus::NeedsOk\n            }\n            FlashOperations::vFlashDone(_) => {\n                ops.flash_done().handle_error()?;\n                HandlerStatus::NeedsOk\n            }\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/host_io.rs",
    "content": "use super::prelude::*;\nuse crate::arch::Arch;\nuse crate::protocol::commands::ext::HostIo;\nuse crate::target::ext::host_io::HostIoError;\nuse crate::target::ext::host_io::HostIoStat;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_host_io(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: HostIo<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_host_io() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"host_io\", \"impl\");\n\n        macro_rules! handle_hostio_result {\n            ( if let Ok($val:pat) = $ret:expr => $callback:block ) => {{\n                match $ret {\n                    Ok($val) => $callback,\n                    Err(HostIoError::Errno(errno)) => {\n                        res.write_str(\"F-1,\")?;\n                        res.write_num(errno as u32)?;\n                    }\n                    Err(HostIoError::Fatal(e)) => return Err(Error::TargetError(e)),\n                }\n            }};\n        }\n\n        let handler_status = match command {\n            HostIo::vFileOpen(cmd) if ops.support_open().is_some() => {\n                let ops = ops.support_open().unwrap();\n                handle_hostio_result! {\n                    if let Ok(fd) = ops.open(cmd.filename, cmd.flags, cmd.mode) => {\n                        res.write_str(\"F\")?;\n                        res.write_num(fd)?;\n                    }\n                }\n                HandlerStatus::Handled\n            }\n            HostIo::vFileClose(cmd) if ops.support_close().is_some() => {\n                let ops = ops.support_close().unwrap();\n                handle_hostio_result! {\n                    if let Ok(()) = ops.close(cmd.fd) => {\n                        res.write_str(\"F0\")?;\n                    }\n                }\n                HandlerStatus::Handled\n            }\n            HostIo::vFilePread(cmd) if ops.support_pread().is_some() => {\n                let ops = ops.support_pread().unwrap();\n                handle_hostio_result! {\n                    if let Ok(ret) = ops.pread(cmd.fd, cmd.count, cmd.offset, cmd.buf) => {\n                        res.write_str(\"F\")?;\n                        res.write_num(ret)?;\n                        res.write_str(\";\")?;\n                        res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?;\n                    }\n                };\n\n                HandlerStatus::Handled\n            }\n            HostIo::vFilePwrite(cmd) if ops.support_pwrite().is_some() => {\n                let offset = <T::Arch as Arch>::Usize::from_be_bytes(cmd.offset)\n                    .ok_or(Error::TargetMismatch)?;\n                let ops = ops.support_pwrite().unwrap();\n                handle_hostio_result! {\n                    if let Ok(ret) = ops.pwrite(cmd.fd, offset, cmd.data) => {\n                        res.write_str(\"F\")?;\n                        res.write_num(ret)?;\n                    }\n                };\n                HandlerStatus::Handled\n            }\n            HostIo::vFileFstat(cmd) if ops.support_fstat().is_some() => {\n                let ops = ops.support_fstat().unwrap();\n                handle_hostio_result! {\n                    if let Ok(stat) = ops.fstat(cmd.fd) => {\n                        let size = core::mem::size_of::<HostIoStat>();\n                        res.write_str(\"F\")?;\n                        res.write_num(size)?;\n                        res.write_str(\";\")?;\n                        res.write_binary(&stat.st_dev.to_be_bytes())?;\n                        res.write_binary(&stat.st_ino.to_be_bytes())?;\n                        res.write_binary(&(stat.st_mode.bits()).to_be_bytes())?;\n                        res.write_binary(&stat.st_nlink.to_be_bytes())?;\n                        res.write_binary(&stat.st_uid.to_be_bytes())?;\n                        res.write_binary(&stat.st_gid.to_be_bytes())?;\n                        res.write_binary(&stat.st_rdev.to_be_bytes())?;\n                        res.write_binary(&stat.st_size.to_be_bytes())?;\n                        res.write_binary(&stat.st_blksize.to_be_bytes())?;\n                        res.write_binary(&stat.st_blocks.to_be_bytes())?;\n                        res.write_binary(&stat.st_atime.to_be_bytes())?;\n                        res.write_binary(&stat.st_mtime.to_be_bytes())?;\n                        res.write_binary(&stat.st_ctime.to_be_bytes())?;\n                    }\n                };\n                HandlerStatus::Handled\n            }\n            HostIo::vFileUnlink(cmd) if ops.support_unlink().is_some() => {\n                let ops = ops.support_unlink().unwrap();\n                handle_hostio_result! {\n                    if let Ok(()) = ops.unlink(cmd.filename) => {\n                        res.write_str(\"F0\")?;\n                    }\n                };\n                HandlerStatus::Handled\n            }\n            HostIo::vFileReadlink(cmd) if ops.support_readlink().is_some() => {\n                let ops = ops.support_readlink().unwrap();\n                handle_hostio_result! {\n                    if let Ok(ret) = ops.readlink(cmd.filename, cmd.buf) => {\n                        res.write_str(\"F\")?;\n                        res.write_num(ret)?;\n                        res.write_str(\";\")?;\n                        res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?;\n                    }\n                };\n\n                HandlerStatus::Handled\n            }\n            HostIo::vFileSetfs(cmd) if ops.support_setfs().is_some() => {\n                let ops = ops.support_setfs().unwrap();\n                handle_hostio_result! {\n                    if let Ok(()) = ops.setfs(cmd.fs) => {\n                        res.write_str(\"F0\")?;\n                    }\n                };\n                HandlerStatus::Handled\n            }\n            _ => HandlerStatus::Handled,\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/host_process_info.rs",
    "content": "use super::prelude::*;\nuse crate::common::Endianness;\nuse crate::common::Pid;\nuse crate::protocol::commands::ext::HostInfo;\nuse crate::protocol::commands::ext::ProcessInfo;\nuse crate::protocol::ResponseWriterError;\nuse crate::target::ext::host_info::HostInfoResponse;\nuse crate::target::ext::process_info::ProcessInfoResponse;\n\n// Convert the two distinct public enums to a single unified enum internally, so\n// that we can reuse serialization code when convenient.\npub(crate) enum InfoResponse<'a> {\n    Pid(Pid),\n    Triple(&'a str),\n    Endianness(Endianness),\n    PointerSize(usize),\n}\n\nimpl<'a> InfoResponse<'a> {\n    pub(crate) fn write_response<C: Connection>(\n        &self,\n        res: &mut ResponseWriter<'_, C>,\n    ) -> Result<(), ResponseWriterError<C::Error>> {\n        match self {\n            InfoResponse::Pid(pid) => {\n                res.write_str(\"pid:\")?;\n                res.write_dec(usize::from(*pid))?;\n            }\n            InfoResponse::Triple(triple) => {\n                res.write_str(\"triple:\")?;\n                res.write_hex_buf(triple.as_bytes())?;\n            }\n            InfoResponse::Endianness(endian) => {\n                res.write_str(\"endian:\")?;\n                res.write_str(match endian {\n                    Endianness::Big => \"big;\",\n                    Endianness::Little => \"little;\",\n                })?;\n            }\n            InfoResponse::PointerSize(p) => {\n                res.write_str(\"ptrsize:\")?;\n                res.write_dec(*p)?;\n            }\n        }\n        res.write_str(\";\")?;\n        Ok(())\n    }\n}\n\nimpl<'a> From<&HostInfoResponse<'a>> for InfoResponse<'a> {\n    fn from(resp: &HostInfoResponse<'a>) -> Self {\n        match *resp {\n            HostInfoResponse::Triple(s) => InfoResponse::Triple(s),\n            HostInfoResponse::Endianness(e) => InfoResponse::Endianness(e),\n            HostInfoResponse::PointerSize(p) => InfoResponse::PointerSize(p),\n        }\n    }\n}\n\nimpl<'a> From<&ProcessInfoResponse<'a>> for InfoResponse<'a> {\n    fn from(resp: &ProcessInfoResponse<'a>) -> Self {\n        match *resp {\n            ProcessInfoResponse::Pid(pid) => InfoResponse::Pid(pid),\n            ProcessInfoResponse::Triple(s) => InfoResponse::Triple(s),\n            ProcessInfoResponse::Endianness(e) => InfoResponse::Endianness(e),\n            ProcessInfoResponse::PointerSize(p) => InfoResponse::PointerSize(p),\n        }\n    }\n}\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_process_info(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: ProcessInfo,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_process_info() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"process_info\", \"impl\");\n\n        let mut result = Ok(());\n        let mut write_info = |info: &ProcessInfoResponse<'_>| {\n            if result.is_ok() {\n                if let Err(e) = InfoResponse::from(info).write_response(res) {\n                    result = Err(e);\n                }\n            }\n        };\n\n        match command {\n            ProcessInfo::qProcessInfo(_cmd) => {\n                ops.process_info(&mut write_info)\n                    .map_err(Error::TargetError)?;\n                result?;\n            }\n        };\n\n        Ok(HandlerStatus::Handled)\n    }\n\n    pub(crate) fn handle_host_info(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: HostInfo,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_host_info() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"host_info\", \"impl\");\n\n        let mut result = Ok(());\n        let mut write_info = |info: &HostInfoResponse<'_>| {\n            if result.is_ok() {\n                if let Err(e) = InfoResponse::from(info).write_response(res) {\n                    result = Err(e);\n                }\n            }\n        };\n\n        match command {\n            HostInfo::qHostInfo(_cmd) => {\n                ops.host_info(&mut write_info).map_err(Error::TargetError)?;\n                result?;\n            }\n        };\n\n        Ok(HandlerStatus::Handled)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/libraries.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::commands::ext::Libraries;\nuse crate::protocol::commands::ext::LibrariesSvr4;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_libraries_svr4(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: LibrariesSvr4<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_libraries_svr4() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"libraries-svr4\", \"impl\");\n\n        let handler_status = match command {\n            LibrariesSvr4::qXferLibrariesSvr4Read(cmd) => {\n                let ret = ops\n                    .get_libraries_svr4(cmd.offset, cmd.length, cmd.buf)\n                    .handle_error()?;\n                if ret == 0 {\n                    res.write_str(\"l\")?;\n                } else {\n                    res.write_str(\"m\")?;\n                    // TODO: add more specific error variant?\n                    res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?;\n                }\n                HandlerStatus::Handled\n            }\n        };\n\n        Ok(handler_status)\n    }\n\n    pub(crate) fn handle_libraries(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: Libraries<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_libraries() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"libraries\", \"impl\");\n\n        let handler_status = match command {\n            Libraries::qXferLibrariesRead(cmd) => {\n                let ret = ops\n                    .get_libraries(cmd.offset, cmd.length, cmd.buf)\n                    .handle_error()?;\n                if ret == 0 {\n                    res.write_str(\"l\")?;\n                } else {\n                    res.write_str(\"m\")?;\n                    res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?;\n                }\n                HandlerStatus::Handled\n            }\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/lldb_register_info.rs",
    "content": "use super::prelude::*;\nuse crate::arch::lldb::Encoding;\nuse crate::arch::lldb::Format;\nuse crate::arch::lldb::Generic;\nuse crate::arch::lldb::Register;\nuse crate::arch::lldb::RegisterInfo as LLDBRegisterInfo;\nuse crate::arch::Arch;\nuse crate::protocol::commands::ext::LldbRegisterInfo;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_lldb_register_info(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: LldbRegisterInfo,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        if !target.use_lldb_register_info() {\n            return Ok(HandlerStatus::Handled);\n        }\n\n        let handler_status = match command {\n            LldbRegisterInfo::qRegisterInfo(cmd) => {\n                let mut err = Ok(());\n                let cb = &mut |reg: Option<Register<'_>>| {\n                    let res = match reg {\n                        // TODO: replace this with a try block (once stabilized)\n                        Some(reg) => (|| {\n                            res.write_str(\"name:\")?;\n                            res.write_str(reg.name)?;\n                            if let Some(alt_name) = reg.alt_name {\n                                res.write_str(\";alt-name:\")?;\n                                res.write_str(alt_name)?;\n                            }\n                            res.write_str(\";bitsize:\")?;\n                            res.write_dec(reg.bitsize)?;\n                            res.write_str(\";offset:\")?;\n                            res.write_dec(reg.offset)?;\n                            res.write_str(\";encoding:\")?;\n                            res.write_str(match reg.encoding {\n                                Encoding::Uint => \"uint\",\n                                Encoding::Sint => \"sint\",\n                                Encoding::IEEE754 => \"ieee754\",\n                                Encoding::Vector => \"vector\",\n                            })?;\n                            res.write_str(\";format:\")?;\n                            res.write_str(match reg.format {\n                                Format::Binary => \"binary\",\n                                Format::Decimal => \"decimal\",\n                                Format::Hex => \"hex\",\n                                Format::Float => \"float\",\n                                Format::VectorSInt8 => \"vector-sint8\",\n                                Format::VectorUInt8 => \"vector-uint8\",\n                                Format::VectorSInt16 => \"vector-sint16\",\n                                Format::VectorUInt16 => \"vector-uint16\",\n                                Format::VectorSInt32 => \"vector-sint32\",\n                                Format::VectorUInt32 => \"vector-uint32\",\n                                Format::VectorFloat32 => \"vector-float32\",\n                                Format::VectorUInt128 => \"vector-uint128\",\n                            })?;\n                            res.write_str(\";set:\")?;\n                            res.write_str(reg.set)?;\n                            if let Some(gcc) = reg.gcc {\n                                res.write_str(\";gcc:\")?;\n                                res.write_dec(gcc)?;\n                            }\n                            if let Some(dwarf) = reg.dwarf {\n                                res.write_str(\";dwarf:\")?;\n                                res.write_dec(dwarf)?;\n                            }\n                            if let Some(generic) = reg.generic {\n                                res.write_str(\";generic:\")?;\n                                res.write_str(match generic {\n                                    Generic::Pc => \"pc\",\n                                    Generic::Sp => \"sp\",\n                                    Generic::Fp => \"fp\",\n                                    Generic::Ra => \"ra\",\n                                    Generic::Flags => \"flags\",\n                                    Generic::Arg1 => \"arg1\",\n                                    Generic::Arg2 => \"arg2\",\n                                    Generic::Arg3 => \"arg3\",\n                                    Generic::Arg4 => \"arg4\",\n                                    Generic::Arg5 => \"arg5\",\n                                    Generic::Arg6 => \"arg6\",\n                                    Generic::Arg7 => \"arg7\",\n                                    Generic::Arg8 => \"arg8\",\n                                })?;\n                            }\n                            if let Some(c_regs) = reg.container_regs {\n                                res.write_str(\";container-regs:\")?;\n                                res.write_num(c_regs[0])?;\n                                for reg in c_regs.iter().skip(1) {\n                                    res.write_str(\",\")?;\n                                    res.write_num(*reg)?;\n                                }\n                            }\n                            if let Some(i_regs) = reg.invalidate_regs {\n                                res.write_str(\";invalidate-regs:\")?;\n                                res.write_num(i_regs[0])?;\n                                for reg in i_regs.iter().skip(1) {\n                                    res.write_str(\",\")?;\n                                    res.write_num(*reg)?;\n                                }\n                            }\n                            res.write_str(\";\")\n                        })(),\n                        // In fact, this doesn't has to be E45! It could equally well be any\n                        // other error code or even an eOk, eAck or eNack! It turns out that\n                        // 0x45 == 69, so presumably the LLDB people were just having some fun\n                        // here. For a little discussion on this and LLDB source code pointers,\n                        // see https://github.com/daniel5151/gdbstub/pull/103#discussion_r888590197\n                        _ => res.write_str(\"E45\"),\n                    };\n                    if let Err(e) = res {\n                        err = Err(e);\n                    }\n                };\n                if let Some(ops) = target.support_lldb_register_info_override() {\n                    use crate::target::ext::lldb_register_info_override::Callback;\n                    use crate::target::ext::lldb_register_info_override::CallbackToken;\n\n                    ops.lldb_register_info(\n                        cmd.reg_id,\n                        Callback {\n                            cb,\n                            token: CallbackToken(core::marker::PhantomData),\n                        },\n                    )\n                    .map_err(Error::TargetError)?;\n                    err?;\n                } else if let Some(reg) = T::Arch::lldb_register_info(cmd.reg_id) {\n                    match reg {\n                        LLDBRegisterInfo::Register(reg) => cb(Some(reg)),\n                        LLDBRegisterInfo::Done => cb(None),\n                    };\n                }\n                HandlerStatus::Handled\n            }\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/memory_map.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::commands::ext::MemoryMap;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_memory_map(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: MemoryMap<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_memory_map() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"memory_map\", \"impl\");\n\n        let handler_status = match command {\n            MemoryMap::qXferMemoryMapRead(cmd) => {\n                let ret = ops\n                    .memory_map_xml(cmd.offset, cmd.length, cmd.buf)\n                    .handle_error()?;\n                if ret == 0 {\n                    res.write_str(\"l\")?;\n                } else {\n                    res.write_str(\"m\")?;\n                    // TODO: add more specific error variant?\n                    res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?;\n                }\n                HandlerStatus::Handled\n            }\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/monitor_cmd.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::commands::ext::MonitorCmd;\nuse crate::protocol::ConsoleOutput;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_monitor_cmd(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: MonitorCmd<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_monitor_cmd() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"monitor_cmd\", \"impl\");\n\n        let handler_status = match command {\n            MonitorCmd::qRcmd(cmd) => {\n                let use_rle = ops.use_rle();\n\n                let mut err: Result<_, Error<T::Error, C::Error>> = Ok(());\n                let mut callback = |msg: &[u8]| {\n                    // TODO: replace this with a try block (once stabilized)\n                    let e = (|| {\n                        let mut res = ResponseWriter::new(res.as_conn(), use_rle);\n                        res.write_str(\"O\")?;\n                        res.write_hex_buf(msg)?;\n                        res.flush()?;\n                        Ok(())\n                    })();\n\n                    if let Err(e) = e {\n                        err = Err(e)\n                    }\n                };\n\n                ops.handle_monitor_cmd(cmd.hex_cmd, ConsoleOutput::new(&mut callback))\n                    .map_err(Error::TargetError)?;\n                err?;\n\n                HandlerStatus::NeedsOk\n            }\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/no_ack_mode.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::commands::ext::NoAckMode;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_no_ack_mode(\n        &mut self,\n        _res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: NoAckMode,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        if !target.use_no_ack_mode() {\n            return Ok(HandlerStatus::Handled);\n        }\n\n        crate::__dead_code_marker!(\"no_ack_mode\", \"impl\");\n\n        let handler_status = match command {\n            NoAckMode::QStartNoAckMode(_) => {\n                self.features.set_no_ack_mode(true);\n                HandlerStatus::NeedsOk\n            }\n        };\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/resume.rs",
    "content": "use super::prelude::*;\nuse super::DisconnectReason;\nuse crate::arch::Arch;\nuse crate::common::Signal;\nuse crate::common::Tid;\nuse crate::protocol::commands::_vCont::Actions;\nuse crate::protocol::commands::ext::Resume;\nuse crate::protocol::SpecificIdKind;\nuse crate::protocol::SpecificThreadId;\nuse crate::stub::MultiThreadStopReason;\nuse crate::target::ext::base::reverse_exec::ReplayLogPosition;\nuse crate::target::ext::base::ResumeOps;\nuse crate::target::ext::catch_syscalls::CatchSyscallPosition;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_stop_resume(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: Resume<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let mut ops = match target.base_ops().resume_ops() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        let actions = match command {\n            Resume::vCont(cmd) => {\n                use crate::protocol::commands::_vCont::vCont;\n                match cmd {\n                    vCont::Query => {\n                        // Continue is part of the base protocol\n                        res.write_str(\"vCont;c;C\")?;\n\n                        // Single stepping is optional\n                        if match &mut ops {\n                            ResumeOps::SingleThread(ops) => ops.support_single_step().is_some(),\n                            ResumeOps::MultiThread(ops) => ops.support_single_step().is_some(),\n                        } {\n                            res.write_str(\";s;S\")?;\n                        }\n\n                        // Range stepping is optional\n                        if match &mut ops {\n                            ResumeOps::SingleThread(ops) => ops.support_range_step().is_some(),\n                            ResumeOps::MultiThread(ops) => ops.support_range_step().is_some(),\n                        } {\n                            res.write_str(\";r\")?;\n                        }\n\n                        // doesn't actually invoke vCont\n                        return Ok(HandlerStatus::Handled);\n                    }\n                    vCont::Actions(actions) => actions,\n                }\n            }\n            // TODO?: support custom resume addr in 'c' and 's'\n            //\n            // vCont doesn't have a notion of \"resume addr\", and since the implementation of these\n            // packets reuse vCont infrastructure, supporting this obscure feature will be a bit\n            // annoying...\n            //\n            // TODO: add `support_legacy_s_c_packets` flag (similar to `use_X_packet`)\n            Resume::c(cmd) => {\n                let _addr = cmd.addr;\n                Actions::new_continue(SpecificThreadId {\n                    pid: None,\n                    tid: self.current_resume_tid,\n                })\n            }\n            Resume::s(cmd) => {\n                let _addr = cmd.addr;\n                Actions::new_step(SpecificThreadId {\n                    pid: None,\n                    tid: self.current_resume_tid,\n                })\n            }\n        };\n\n        self.do_vcont(ops, actions)\n    }\n\n    fn do_vcont_single_thread(\n        ops: &mut dyn crate::target::ext::base::singlethread::SingleThreadResume<\n            Arch = T::Arch,\n            Error = T::Error,\n        >,\n        actions: &Actions<'_>,\n    ) -> Result<(), Error<T::Error, C::Error>> {\n        use crate::protocol::commands::_vCont::VContKind;\n\n        let mut actions = actions.iter();\n        let first_action = actions\n            .next()\n            .ok_or(Error::PacketParse(\n                crate::protocol::PacketParseError::MalformedCommand,\n            ))?\n            .ok_or(Error::PacketParse(\n                crate::protocol::PacketParseError::MalformedCommand,\n            ))?;\n\n        let invalid_second_action = match actions.next() {\n            None => false,\n            Some(act) => match act {\n                None => {\n                    return Err(Error::PacketParse(\n                        crate::protocol::PacketParseError::MalformedCommand,\n                    ))\n                }\n                Some(act) => !matches!(act.kind, VContKind::Continue),\n            },\n        };\n\n        if invalid_second_action || actions.next().is_some() {\n            return Err(Error::PacketUnexpected);\n        }\n\n        match first_action.kind {\n            VContKind::Continue | VContKind::ContinueWithSig(_) => {\n                let signal = match first_action.kind {\n                    VContKind::ContinueWithSig(sig) => Some(sig),\n                    _ => None,\n                };\n\n                ops.resume(signal).map_err(Error::TargetError)?;\n                Ok(())\n            }\n            VContKind::Step | VContKind::StepWithSig(_) if ops.support_single_step().is_some() => {\n                let ops = ops.support_single_step().unwrap();\n\n                let signal = match first_action.kind {\n                    VContKind::StepWithSig(sig) => Some(sig),\n                    _ => None,\n                };\n\n                ops.step(signal).map_err(Error::TargetError)?;\n                Ok(())\n            }\n            VContKind::RangeStep(start, end) if ops.support_range_step().is_some() => {\n                let ops = ops.support_range_step().unwrap();\n\n                let start = start.decode().map_err(|_| Error::TargetMismatch)?;\n                let end = end.decode().map_err(|_| Error::TargetMismatch)?;\n\n                ops.resume_range_step(start, end)\n                    .map_err(Error::TargetError)?;\n                Ok(())\n            }\n            // TODO: update this case when non-stop mode is implemented\n            VContKind::Stop => Err(Error::PacketUnexpected),\n\n            // Instead of using `_ =>`, explicitly list out any remaining unguarded cases.\n            VContKind::RangeStep(..) | VContKind::Step | VContKind::StepWithSig(..) => {\n                error!(\"GDB client sent resume action not reported by `vCont?`\");\n                Err(Error::PacketUnexpected)\n            }\n        }\n    }\n\n    fn do_vcont_multi_thread(\n        ops: &mut dyn crate::target::ext::base::multithread::MultiThreadResume<\n            Arch = T::Arch,\n            Error = T::Error,\n        >,\n        actions: &Actions<'_>,\n    ) -> Result<(), Error<T::Error, C::Error>> {\n        ops.clear_resume_actions().map_err(Error::TargetError)?;\n\n        // Track whether the packet contains a wildcard/default continue action\n        // (e.g., `c` or `c:-1`).\n        //\n        // Presence of this action implies \"Scheduler Locking\" is OFF.\n        // Absence implies \"Scheduler Locking\" is ON.\n        let mut has_wildcard_continue = false;\n\n        for action in actions.iter() {\n            use crate::protocol::commands::_vCont::VContKind;\n\n            let action = action.ok_or(Error::PacketParse(\n                crate::protocol::PacketParseError::MalformedCommand,\n            ))?;\n\n            match action.kind {\n                VContKind::Continue | VContKind::ContinueWithSig(_) => {\n                    let signal = match action.kind {\n                        VContKind::ContinueWithSig(sig) => Some(sig),\n                        _ => None,\n                    };\n\n                    match action.thread.map(|thread| thread.tid) {\n                        // An action with no thread-id matches all threads\n                        None | Some(SpecificIdKind::All) => {\n                            // Target API contract specifies that the default\n                            // resume action for all threads is continue.\n                            has_wildcard_continue = true;\n                        }\n                        Some(SpecificIdKind::WithId(tid)) => ops\n                            .set_resume_action_continue(tid, signal)\n                            .map_err(Error::TargetError)?,\n                    }\n                }\n                VContKind::Step | VContKind::StepWithSig(_)\n                    if ops.support_single_step().is_some() =>\n                {\n                    let ops = ops.support_single_step().unwrap();\n\n                    let signal = match action.kind {\n                        VContKind::StepWithSig(sig) => Some(sig),\n                        _ => None,\n                    };\n\n                    match action.thread.map(|thread| thread.tid) {\n                        // An action with no thread-id matches all threads\n                        None | Some(SpecificIdKind::All) => {\n                            error!(\"GDB client sent 'step' as default resume action\");\n                            return Err(Error::PacketUnexpected);\n                        }\n                        Some(SpecificIdKind::WithId(tid)) => {\n                            ops.set_resume_action_step(tid, signal)\n                                .map_err(Error::TargetError)?;\n                        }\n                    };\n                }\n\n                VContKind::RangeStep(start, end) if ops.support_range_step().is_some() => {\n                    let ops = ops.support_range_step().unwrap();\n\n                    match action.thread.map(|thread| thread.tid) {\n                        // An action with no thread-id matches all threads\n                        None | Some(SpecificIdKind::All) => {\n                            error!(\"GDB client sent 'range step' as default resume action\");\n                            return Err(Error::PacketUnexpected);\n                        }\n                        Some(SpecificIdKind::WithId(tid)) => {\n                            let start = start.decode().map_err(|_| Error::TargetMismatch)?;\n                            let end = end.decode().map_err(|_| Error::TargetMismatch)?;\n\n                            ops.set_resume_action_range_step(tid, start, end)\n                                .map_err(Error::TargetError)?;\n                        }\n                    };\n                }\n                // TODO: update this case when non-stop mode is implemented\n                VContKind::Stop => return Err(Error::PacketUnexpected),\n\n                // GDB doesn't always respect `vCont?` responses that omit `;s;S`, and will try to\n                // send step packets regardless. Inform the user of this bug by issuing a\n                // `UnexpectedStepPacket` error, which is more useful than a generic\n                // `PacketUnexpected` error.\n                VContKind::Step | VContKind::StepWithSig(..) => {\n                    return Err(Error::UnexpectedStepPacket)\n                }\n\n                // Instead of using `_ =>`, explicitly list out any remaining unguarded cases.\n                VContKind::RangeStep(..) => {\n                    error!(\"GDB client sent resume action not reported by `vCont?`\");\n                    return Err(Error::PacketUnexpected);\n                }\n            }\n        }\n\n        if !has_wildcard_continue {\n            let Some(locking_ops) = ops.support_scheduler_locking() else {\n                return Err(Error::MissingMultiThreadSchedulerLocking);\n            };\n            locking_ops\n                .set_resume_action_scheduler_lock()\n                .map_err(Error::TargetError)?;\n        }\n\n        ops.resume().map_err(Error::TargetError)\n    }\n\n    fn do_vcont(\n        &mut self,\n        ops: ResumeOps<'_, T::Arch, T::Error>,\n        actions: Actions<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        match ops {\n            ResumeOps::SingleThread(ops) => Self::do_vcont_single_thread(ops, &actions)?,\n            ResumeOps::MultiThread(ops) => Self::do_vcont_multi_thread(ops, &actions)?,\n        };\n\n        Ok(HandlerStatus::DeferredStopReason)\n    }\n\n    fn write_stop_common(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        tid: Option<Tid>,\n        signal: Signal,\n    ) -> Result<(), Error<T::Error, C::Error>> {\n        res.write_str(\"T\")?;\n        res.write_num(signal.0)?;\n\n        if let Some(tid) = tid {\n            self.current_mem_tid = tid;\n            self.current_resume_tid = SpecificIdKind::WithId(tid);\n\n            res.write_str(\"thread:\")?;\n            res.write_specific_thread_id(SpecificThreadId {\n                pid: self\n                    .features\n                    .multiprocess()\n                    .then_some(SpecificIdKind::WithId(self.get_current_pid(target)?)),\n                tid: SpecificIdKind::WithId(tid),\n            })?;\n            res.write_str(\";\")?;\n        }\n\n        Ok(())\n    }\n\n    pub(crate) fn finish_exec(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        stop_reason: MultiThreadStopReason<<T::Arch as Arch>::Usize>,\n    ) -> Result<FinishExecStatus, Error<T::Error, C::Error>> {\n        /// Helper macro to gate certain stop reasons on whether the target\n        /// supports it.\n        macro_rules! guard {\n            (reverse_exec) => {{\n                if let Some(resume_ops) = target.base_ops().resume_ops() {\n                    let (reverse_cont, reverse_step) = match resume_ops {\n                        ResumeOps::MultiThread(ops) => (\n                            ops.support_reverse_cont().is_some(),\n                            ops.support_reverse_step().is_some(),\n                        ),\n                        ResumeOps::SingleThread(ops) => (\n                            ops.support_reverse_cont().is_some(),\n                            ops.support_reverse_step().is_some(),\n                        ),\n                    };\n\n                    reverse_cont || reverse_step\n                } else {\n                    false\n                }\n            }};\n\n            (break $op:ident) => {\n                target\n                    .support_breakpoints()\n                    .and_then(|ops| ops.$op())\n                    .is_some()\n            };\n\n            (catch_syscall) => {\n                target.support_catch_syscalls().is_some()\n            };\n\n            (fork) => {\n                target.use_fork_stop_reason()\n            };\n\n            (vfork) => {\n                target.use_vfork_stop_reason()\n            };\n\n            (vforkdone) => {\n                target.use_vforkdone_stop_reason()\n            };\n        }\n\n        let status = match stop_reason {\n            MultiThreadStopReason::DoneStep => {\n                res.write_str(\"S\")?;\n                res.write_num(Signal::SIGTRAP.0)?;\n                FinishExecStatus::Handled\n            }\n            MultiThreadStopReason::Signal(sig) => {\n                res.write_str(\"S\")?;\n                res.write_num(sig.0)?;\n                FinishExecStatus::Handled\n            }\n            MultiThreadStopReason::Exited(code) => {\n                res.write_str(\"W\")?;\n                res.write_num(code)?;\n                FinishExecStatus::Disconnect(DisconnectReason::TargetExited(code))\n            }\n            MultiThreadStopReason::Terminated(sig) => {\n                res.write_str(\"X\")?;\n                res.write_num(sig.0)?;\n                FinishExecStatus::Disconnect(DisconnectReason::TargetTerminated(sig))\n            }\n            MultiThreadStopReason::SignalWithThread { tid, signal } => {\n                self.write_stop_common(res, target, Some(tid), signal)?;\n                FinishExecStatus::Handled\n            }\n            MultiThreadStopReason::SwBreak(tid) if guard!(break support_sw_breakpoint) => {\n                crate::__dead_code_marker!(\"sw_breakpoint\", \"stop_reason\");\n\n                self.write_stop_common(res, target, Some(tid), Signal::SIGTRAP)?;\n                res.write_str(\"swbreak:;\")?;\n                FinishExecStatus::Handled\n            }\n            MultiThreadStopReason::HwBreak(tid) if guard!(break support_hw_breakpoint) => {\n                crate::__dead_code_marker!(\"hw_breakpoint\", \"stop_reason\");\n\n                self.write_stop_common(res, target, Some(tid), Signal::SIGTRAP)?;\n                res.write_str(\"hwbreak:;\")?;\n                FinishExecStatus::Handled\n            }\n            MultiThreadStopReason::Watch { tid, kind, addr }\n                if guard!(break support_hw_watchpoint) =>\n            {\n                crate::__dead_code_marker!(\"hw_watchpoint\", \"stop_reason\");\n\n                self.write_stop_common(res, target, Some(tid), Signal::SIGTRAP)?;\n\n                use crate::target::ext::breakpoints::WatchKind;\n                match kind {\n                    WatchKind::Write => res.write_str(\"watch:\")?,\n                    WatchKind::Read => res.write_str(\"rwatch:\")?,\n                    WatchKind::ReadWrite => res.write_str(\"awatch:\")?,\n                }\n                res.write_num(addr)?;\n                res.write_str(\";\")?;\n                FinishExecStatus::Handled\n            }\n            MultiThreadStopReason::ReplayLog { tid, pos } if guard!(reverse_exec) => {\n                crate::__dead_code_marker!(\"reverse_exec\", \"stop_reason\");\n\n                self.write_stop_common(res, target, tid, Signal::SIGTRAP)?;\n\n                res.write_str(\"replaylog:\")?;\n                res.write_str(match pos {\n                    ReplayLogPosition::Begin => \"begin\",\n                    ReplayLogPosition::End => \"end\",\n                })?;\n                res.write_str(\";\")?;\n\n                FinishExecStatus::Handled\n            }\n            MultiThreadStopReason::CatchSyscall {\n                tid,\n                number,\n                position,\n            } if guard!(catch_syscall) => {\n                crate::__dead_code_marker!(\"catch_syscall\", \"stop_reason\");\n\n                self.write_stop_common(res, target, tid, Signal::SIGTRAP)?;\n\n                res.write_str(match position {\n                    CatchSyscallPosition::Entry => \"syscall_entry:\",\n                    CatchSyscallPosition::Return => \"syscall_return:\",\n                })?;\n                res.write_num(number)?;\n                res.write_str(\";\")?;\n\n                FinishExecStatus::Handled\n            }\n            MultiThreadStopReason::Library(tid) => {\n                self.write_stop_common(res, target, Some(tid), Signal::SIGTRAP)?;\n                res.write_str(\"library:;\")?;\n                FinishExecStatus::Handled\n            }\n            MultiThreadStopReason::Fork { cur_tid, new_tid } if guard!(fork) => {\n                crate::__dead_code_marker!(\"fork_events\", \"stop_reason\");\n                self.write_stop_common(res, target, Some(cur_tid), Signal::SIGTRAP)?;\n                res.write_str(\"fork:\")?;\n                res.write_specific_thread_id(SpecificThreadId {\n                    pid: self\n                        .features\n                        .multiprocess()\n                        .then_some(SpecificIdKind::WithId(self.get_current_pid(target)?)),\n                    tid: SpecificIdKind::WithId(new_tid),\n                })?;\n                res.write_str(\";\")?;\n                FinishExecStatus::Handled\n            }\n            MultiThreadStopReason::VFork { cur_tid, new_tid } if guard!(vfork) => {\n                crate::__dead_code_marker!(\"vfork_events\", \"stop_reason\");\n                self.write_stop_common(res, target, Some(cur_tid), Signal::SIGTRAP)?;\n                res.write_str(\"vfork:\")?;\n                res.write_specific_thread_id(SpecificThreadId {\n                    pid: self\n                        .features\n                        .multiprocess()\n                        .then_some(SpecificIdKind::WithId(self.get_current_pid(target)?)),\n                    tid: SpecificIdKind::WithId(new_tid),\n                })?;\n                res.write_str(\";\")?;\n                FinishExecStatus::Handled\n            }\n            MultiThreadStopReason::VForkDone(tid) if guard!(vforkdone) => {\n                crate::__dead_code_marker!(\"vforkdone_events\", \"stop_reason\");\n                self.write_stop_common(res, target, Some(tid), Signal::SIGTRAP)?;\n                res.write_str(\"vforkdone:;\")?;\n                FinishExecStatus::Handled\n            }\n            // Explicitly avoid using `_ =>` to handle the \"unguarded\" variants, as doing so would\n            // squelch the useful compiler error that crops up whenever stop reasons are added.\n            MultiThreadStopReason::SwBreak(_)\n            | MultiThreadStopReason::HwBreak(_)\n            | MultiThreadStopReason::Watch { .. }\n            | MultiThreadStopReason::ReplayLog { .. }\n            | MultiThreadStopReason::CatchSyscall { .. }\n            | MultiThreadStopReason::Fork { .. }\n            | MultiThreadStopReason::VFork { .. }\n            | MultiThreadStopReason::VForkDone { .. } => {\n                return Err(Error::UnsupportedStopReason);\n            }\n        };\n\n        Ok(status)\n    }\n}\n\npub(crate) enum FinishExecStatus {\n    Handled,\n    Disconnect(DisconnectReason),\n}\n"
  },
  {
    "path": "src/stub/core_impl/reverse_exec.rs",
    "content": "use super::prelude::*;\nuse crate::arch::Arch;\nuse crate::common::Tid;\nuse crate::protocol::commands::ext::ReverseCont;\nuse crate::protocol::commands::ext::ReverseStep;\nuse crate::protocol::SpecificIdKind;\nuse crate::target::ext::base::reverse_exec::ReverseCont as ReverseContTrait;\nuse crate::target::ext::base::reverse_exec::ReverseStep as ReverseStepTrait;\nuse crate::target::ext::base::ResumeOps;\n\nmacro_rules! defn_ops {\n    ($name:ident, $reverse_trait:ident, $f:ident) => {\n        enum $name<'a, A: Arch, E> {\n            SingleThread(&'a mut dyn $reverse_trait<(), Arch = A, Error = E>),\n            MultiThread(&'a mut dyn $reverse_trait<Tid, Arch = A, Error = E>),\n        }\n\n        impl<'a, A, E> $name<'a, A, E>\n        where\n            A: Arch,\n        {\n            #[inline(always)]\n            fn from_target<T>(target: &mut T) -> Option<$name<'_, T::Arch, T::Error>>\n            where\n                T: Target,\n            {\n                let ops = match target.base_ops().resume_ops()? {\n                    ResumeOps::SingleThread(ops) => $name::SingleThread(ops.$f()?),\n                    ResumeOps::MultiThread(ops) => $name::MultiThread(ops.$f()?),\n                };\n                Some(ops)\n            }\n        }\n    };\n}\n\ndefn_ops!(ReverseContOps, ReverseContTrait, support_reverse_cont);\ndefn_ops!(ReverseStepOps, ReverseStepTrait, support_reverse_step);\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_reverse_cont(\n        &mut self,\n        _res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: ReverseCont,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match ReverseContOps::<'_, T::Arch, T::Error>::from_target(target) {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"reverse_cont\", \"impl\");\n\n        let handler_status = match command {\n            ReverseCont::bc(_) => {\n                match ops {\n                    ReverseContOps::MultiThread(ops) => {\n                        ops.reverse_cont().map_err(Error::TargetError)?\n                    }\n                    ReverseContOps::SingleThread(ops) => {\n                        ops.reverse_cont().map_err(Error::TargetError)?\n                    }\n                }\n\n                HandlerStatus::DeferredStopReason\n            }\n        };\n\n        Ok(handler_status)\n    }\n\n    // FIXME: De-duplicate with above code?\n    pub(crate) fn handle_reverse_step(\n        &mut self,\n        _res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: ReverseStep,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match ReverseStepOps::<'_, T::Arch, T::Error>::from_target(target) {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"reverse_step\", \"impl\");\n\n        let handler_status = match command {\n            ReverseStep::bs(_) => {\n                let tid = match self.current_resume_tid {\n                    // NOTE: Can't single-step all cores.\n                    SpecificIdKind::All => return Err(Error::PacketUnexpected),\n                    SpecificIdKind::WithId(tid) => tid,\n                };\n\n                match ops {\n                    ReverseStepOps::MultiThread(ops) => {\n                        ops.reverse_step(tid).map_err(Error::TargetError)?\n                    }\n                    ReverseStepOps::SingleThread(ops) => {\n                        ops.reverse_step(()).map_err(Error::TargetError)?\n                    }\n                }\n\n                HandlerStatus::DeferredStopReason\n            }\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/section_offsets.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::commands::ext::SectionOffsets;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_section_offsets(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: SectionOffsets,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_section_offsets() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"section_offsets\", \"impl\");\n\n        let handler_status = match command {\n            SectionOffsets::qOffsets(_cmd) => {\n                use crate::target::ext::section_offsets::Offsets;\n\n                match ops.get_section_offsets().map_err(Error::TargetError)? {\n                    Offsets::Sections { text, data, bss } => {\n                        res.write_str(\"Text=\")?;\n                        res.write_num(text)?;\n\n                        res.write_str(\";Data=\")?;\n                        res.write_num(data)?;\n\n                        // \"Note: while a Bss offset may be included in the response,\n                        // GDB ignores this and instead applies the Data offset to the Bss section.\"\n                        //\n                        // While this would suggest that it's OK to omit `Bss=` entirely, recent\n                        // versions of GDB seem to require that `Bss=` is present.\n                        //\n                        // See https://github.com/bminor/binutils-gdb/blob/master/gdb/remote.c#L4149-L4159\n                        let bss = bss.unwrap_or(data);\n                        res.write_str(\";Bss=\")?;\n                        res.write_num(bss)?;\n                    }\n                    Offsets::Segments { text_seg, data_seg } => {\n                        res.write_str(\"TextSeg=\")?;\n                        res.write_num(text_seg)?;\n\n                        if let Some(data) = data_seg {\n                            res.write_str(\";DataSeg=\")?;\n                            res.write_num(data)?;\n                        }\n                    }\n                }\n                HandlerStatus::Handled\n            }\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/single_register_access.rs",
    "content": "use super::prelude::*;\nuse crate::arch::Arch;\nuse crate::arch::RegId;\nuse crate::protocol::commands::ext::SingleRegisterAccess;\nuse crate::target::ext::base::BaseOps;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    fn inner<Tid>(\n        res: &mut ResponseWriter<'_, C>,\n        ops: crate::target::ext::base::single_register_access::SingleRegisterAccessOps<'_, Tid, T>,\n        command: SingleRegisterAccess<'_>,\n        id: Tid,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>>\n    where\n        Tid: crate::is_valid_tid::IsValidTid,\n    {\n        let handler_status = match command {\n            SingleRegisterAccess::p(p) => {\n                let reg = <T::Arch as Arch>::RegId::from_raw_id(p.reg_id);\n                let (reg_id, reg_size) = match reg {\n                    None => {\n                        warn!(\"reg id {} does not map onto any known register\", p.reg_id);\n                        return Ok(HandlerStatus::Handled);\n                    }\n                    Some(v) => v,\n                };\n                let mut buf = p.buf;\n                if let Some(size) = reg_size {\n                    buf = buf\n                        .get_mut(..size.get())\n                        .ok_or(Error::PacketBufferOverflow)?;\n                }\n\n                let len = ops.read_register(id, reg_id, buf).handle_error()?;\n\n                if len == 0 {\n                    if let Some(size) = reg_size {\n                        for _ in 0..size.get() {\n                            res.write_str(\"xx\")?;\n                        }\n                    } else {\n                        return Err(Error::TargetMismatch);\n                    }\n                } else {\n                    if let Some(size) = reg_size {\n                        if size.get() != len {\n                            return Err(Error::TargetMismatch);\n                        }\n                    } else {\n                        buf = buf.get_mut(..len).ok_or(Error::PacketBufferOverflow)?;\n                    }\n                    res.write_hex_buf(buf)?;\n                }\n                HandlerStatus::Handled\n            }\n            SingleRegisterAccess::P(p) => {\n                let reg = <T::Arch as Arch>::RegId::from_raw_id(p.reg_id);\n                match reg {\n                    // empty packet indicates unrecognized query\n                    None => return Ok(HandlerStatus::Handled),\n                    Some((reg_id, _)) => ops.write_register(id, reg_id, p.val).handle_error()?,\n                }\n                HandlerStatus::NeedsOk\n            }\n        };\n\n        Ok(handler_status)\n    }\n\n    pub(crate) fn handle_single_register_access(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: SingleRegisterAccess<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        match target.base_ops() {\n            BaseOps::SingleThread(ops) => match ops.support_single_register_access() {\n                None => Ok(HandlerStatus::Handled),\n                Some(ops) => Self::inner(res, ops, command, ()),\n            },\n            BaseOps::MultiThread(ops) => match ops.support_single_register_access() {\n                None => Ok(HandlerStatus::Handled),\n                Some(ops) => Self::inner(res, ops, command, self.current_mem_tid),\n            },\n        }\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/target_xml.rs",
    "content": "use super::prelude::*;\nuse crate::arch::Arch;\nuse crate::protocol::commands::ext::TargetXml;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_target_xml(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: TargetXml<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        if !target.use_target_description_xml() {\n            return Ok(HandlerStatus::Handled);\n        }\n\n        let handler_status = match command {\n            TargetXml::qXferFeaturesRead(cmd) => {\n                let ret = if let Some(ops) = target.support_target_description_xml_override() {\n                    ops.target_description_xml(cmd.annex.name, cmd.offset, cmd.length, cmd.buf)\n                        .handle_error()?\n                } else if let Some(xml) = T::Arch::target_description_xml() {\n                    if cmd.annex.name != b\"target.xml\" {\n                        // TODO: not the best error... should probably report to the user the\n                        // <xi:include> isn't supported at the Arch level (yet)\n                        return Err(Error::PacketUnexpected);\n                    }\n\n                    let xml = xml.trim().as_bytes();\n                    let xml_len = xml.len();\n\n                    let start = xml_len.min(cmd.offset as usize);\n                    let end = xml_len.min((cmd.offset as usize).saturating_add(cmd.length));\n\n                    // LLVM isn't smart enough to realize that `start <= end`, and fails to elide a\n                    // `slice_end_index_len_fail` check unless we include this seemingly useless\n                    // call to `min`.\n                    let data = &xml[start.min(end)..end];\n\n                    let n = data.len().min(cmd.buf.len());\n                    cmd.buf[..n].copy_from_slice(&data[..n]);\n                    n\n                } else {\n                    // If the target hasn't provided their own XML, then the initial response to\n                    // \"qSupported\" wouldn't have included \"qXfer:features:read\", and gdb wouldn't\n                    // send this packet unless it was explicitly marked as supported.\n                    return Err(Error::PacketUnexpected);\n                };\n\n                if ret == 0 {\n                    res.write_str(\"l\")?;\n                } else {\n                    res.write_str(\"m\")?;\n                    // TODO: add more specific error variant?\n                    res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?;\n                }\n                HandlerStatus::Handled\n            }\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/thread_extra_info.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::commands::ext::ThreadExtraInfo;\nuse crate::target::ext::base::BaseOps;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_thread_extra_info(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: ThreadExtraInfo<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.base_ops() {\n            BaseOps::SingleThread(_) => return Ok(HandlerStatus::Handled),\n            BaseOps::MultiThread(ops) => match ops.support_thread_extra_info() {\n                Some(ops) => ops,\n                None => return Ok(HandlerStatus::Handled),\n            },\n        };\n\n        crate::__dead_code_marker!(\"thread_extra_info\", \"impl\");\n\n        let handler_status = match command {\n            ThreadExtraInfo::qThreadExtraInfo(info) => {\n                // TODO: plumb through PID when true multi-process support is added\n                let _pid = info.id.pid;\n\n                let size = ops\n                    .thread_extra_info(info.id.tid, info.buf)\n                    .map_err(Error::TargetError)?;\n                let data = info.buf.get(..size).ok_or(Error::PacketBufferOverflow)?;\n\n                res.write_hex_buf(data)?;\n\n                HandlerStatus::Handled\n            }\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/tracepoints.rs",
    "content": "use super::prelude::*;\nuse crate::arch::Arch;\nuse crate::internal::BeBytes;\nuse crate::protocol::commands::_QTDPsrc::QTDPsrc;\nuse crate::protocol::commands::_qTBuffer::qTBuffer;\nuse crate::protocol::commands::ext::Tracepoints;\nuse crate::protocol::commands::prelude::decode_hex;\nuse crate::protocol::commands::prelude::decode_hex_buf;\nuse crate::protocol::commands::_QTDP::CreateTDP;\nuse crate::protocol::commands::_QTDP::ExtendTDP;\nuse crate::protocol::commands::_QTDP::QTDP;\nuse crate::protocol::ResponseWriterError;\nuse crate::target::ext::tracepoints::ExperimentExplanation;\nuse crate::target::ext::tracepoints::ExperimentStatus;\nuse crate::target::ext::tracepoints::FrameDescription;\nuse crate::target::ext::tracepoints::FrameRequest;\nuse crate::target::ext::tracepoints::NewTracepoint;\nuse crate::target::ext::tracepoints::SourceTracepoint;\nuse crate::target::ext::tracepoints::Tracepoint;\nuse crate::target::ext::tracepoints::TracepointAction;\nuse crate::target::ext::tracepoints::TracepointEnumerateCursor;\nuse crate::target::ext::tracepoints::TracepointEnumerateStep;\nuse crate::target::ext::tracepoints::TracepointSourceType;\nuse crate::target::ext::tracepoints::TracepointStatus;\nuse managed::ManagedSlice;\nuse num_traits::PrimInt;\n\nimpl<U: BeBytes> NewTracepoint<U> {\n    /// Parse from a raw CreateTDP packet.\n    fn from_tdp(ctdp: CreateTDP<'_>) -> Option<(Self, bool)> {\n        Some((\n            Self {\n                number: ctdp.number,\n                addr: U::from_be_bytes(ctdp.addr)?,\n                enabled: ctdp.enable,\n                pass_count: ctdp.pass,\n                step_count: ctdp.step,\n            },\n            ctdp.more,\n        ))\n    }\n}\n\nimpl<U: crate::internal::BeBytes + num_traits::Zero + PrimInt> NewTracepoint<U> {\n    /// Write this as a qTfP/qTsP response\n    pub(crate) fn write<T: Target, C: Connection>(\n        &self,\n        res: &mut ResponseWriter<'_, C>,\n    ) -> Result<(), Error<T::Error, C::Error>> {\n        res.write_str(\"T\")?;\n        res.write_num(self.number.0)?;\n        res.write_str(\":\")?;\n        res.write_num(self.addr)?;\n        res.write_str(\":\")?;\n        res.write_str(if self.enabled { \"E\" } else { \"D\" })?;\n        res.write_str(\":\")?;\n        res.write_num(self.step_count)?;\n        res.write_str(\":\")?;\n        res.write_num(self.pass_count)?;\n\n        Ok(())\n    }\n}\n\n/// A list of actions that a tracepoint should be extended with.\n#[derive(Debug)]\npub(crate) struct ExtendTracepoint<'a, U> {\n    /// The tracepoint that is having actions appended to its definition.\n    pub number: Tracepoint,\n    /// The PC address of the tracepoint that is being extended.\n    /// This is currently unused information sent as part of the packet by GDB,\n    /// but may be required for implementing while-stepping actions later.\n    #[allow(dead_code)]\n    pub addr: U,\n    /// The unparsed action data.\n    pub data: ManagedSlice<'a, u8>,\n}\n\nimpl<'a, U: BeBytes> ExtendTracepoint<'a, U> {\n    /// Parse from a raw ExtendTDP packet.\n    fn from_tdp(dtdp: ExtendTDP<'a>) -> Option<Self> {\n        Some(Self {\n            number: dtdp.number,\n            addr: U::from_be_bytes(dtdp.addr)?,\n            data: ManagedSlice::Borrowed(dtdp.actions),\n        })\n    }\n\n    /// Parse the actions that should be added to the definition of this\n    /// tracepoint, calling `f` on each action.\n    ///\n    /// Returns `Err` if parsing of actions failed, or hit unsupported actions.\n    /// Return `Ok(more)` on success, where more indicates if more actions are\n    /// expect in later packets. If the actions weren't from a GDB packet, more\n    /// is None.\n    pub(crate) fn actions<T, C>(\n        mut self,\n        f: impl FnMut(&TracepointAction<'_, U>),\n    ) -> Result<Option<bool>, Error<T, C>> {\n        Self::parse_raw_actions(&mut self.data, f)\n    }\n\n    fn parse_raw_actions<T, C>(\n        actions: &mut [u8],\n        mut f: impl FnMut(&TracepointAction<'_, U>),\n    ) -> Result<Option<bool>, Error<T, C>> {\n        let (actions, more) = match actions {\n            [rest @ .., b'-'] => (rest, true),\n            x => (x, false),\n        };\n        // TODO: There's no \"packet unsupported\", so for now we stub out unimplemented\n        // functionality by reporting the commands malformed instead.\n        use crate::protocol::PacketParseError::MalformedCommand;\n        let mut unparsed: Option<&mut [u8]> = Some(actions);\n        loop {\n            match unparsed {\n                Some([b'S', ..]) => {\n                    // TODO: how can gdbstub even implement this? it changes how\n                    // future packets should be interpreted, but as a trait we\n                    // can't keep a flag around for that (unless we specifically\n                    // have a `mark_while_stepping` callback for the target to\n                    // keep track future tracepoint_extends should be treated different).\n                    // If we go that route we also would need to return two vectors\n                    // here, \"normal\" actions and \"while stepping\" actions...but\n                    // \"normals\" actions may still be \"while stepping\" actions,\n                    // just continued from the previous packet, which we forgot\n                    // about!\n                    //\n                    // We use 'W' to indicate \"while-stepping\", since we're already\n                    // using 'S' elsewhere for static tracepoints.\n                    return Err(Error::TracepointFeatureUnimplemented(b'W'));\n                }\n                Some([b'R', mask @ ..]) => {\n                    let mask_end = mask\n                        .iter()\n                        .enumerate()\n                        .find(|(_i, b)| matches!(b, b'S' | b'R' | b'M' | b'X'));\n                    // We may or may not have another action after our mask\n                    let mask = if let Some(mask_end) = mask_end {\n                        let (mask_bytes, next) = mask.split_at_mut(mask_end.0);\n                        unparsed = Some(next);\n                        decode_hex_buf(mask_bytes).or(Err(Error::PacketParse(MalformedCommand)))?\n                    } else {\n                        unparsed = None;\n                        decode_hex_buf(mask).or(Err(Error::PacketParse(MalformedCommand)))?\n                    };\n                    (f)(&TracepointAction::Registers {\n                        mask: ManagedSlice::Borrowed(mask),\n                    });\n                }\n                Some([b'M', _mem_args @ ..]) => {\n                    // Unimplemented: even simple actions like `collect *(int*)0x0`\n                    // are actually assembled as `X` bytecode actions\n                    return Err(Error::TracepointFeatureUnimplemented(b'M'));\n                }\n                Some([b'X', eval_args @ ..]) => {\n                    let mut len_end = eval_args.splitn_mut(2, |b| *b == b',');\n                    let (len_bytes, rem) = (\n                        len_end.next().ok_or(Error::PacketParse(MalformedCommand))?,\n                        len_end.next().ok_or(Error::PacketParse(MalformedCommand))?,\n                    );\n                    let len: usize =\n                        decode_hex(len_bytes).or(Err(Error::PacketParse(MalformedCommand)))?;\n                    if rem.len() < len * 2 {\n                        return Err(Error::PacketParse(MalformedCommand));\n                    }\n                    let (expr_bytes, next_bytes) = rem.split_at_mut(len * 2);\n                    let expr =\n                        decode_hex_buf(expr_bytes).or(Err(Error::PacketParse(MalformedCommand)))?;\n                    (f)(&TracepointAction::Expression {\n                        expr: ManagedSlice::Borrowed(expr),\n                    });\n                    unparsed = Some(next_bytes);\n                }\n                Some([]) | None => {\n                    break;\n                }\n                _ => return Err(Error::PacketParse(MalformedCommand)),\n            }\n        }\n\n        Ok(Some(more))\n    }\n}\n\nimpl<'a, U: BeBytes> SourceTracepoint<'a, U> {\n    /// Parse from a raw CreateTDP packet.\n    fn from_src(src: QTDPsrc<'a>) -> Option<Self> {\n        Some(Self {\n            number: src.number,\n            addr: U::from_be_bytes(src.addr)?,\n            kind: src.kind,\n            start: src.start,\n            slen: src.slen,\n            bytes: ManagedSlice::Borrowed(src.bytes),\n        })\n    }\n}\nimpl<U: crate::internal::BeBytes + num_traits::Zero + PrimInt> SourceTracepoint<'_, U> {\n    /// Write this as a qTfP/qTsP response\n    pub(crate) fn write<T: Target, C: Connection>(\n        &self,\n        res: &mut ResponseWriter<'_, C>,\n    ) -> Result<(), Error<T::Error, C::Error>> {\n        res.write_str(\"Z\")?;\n        res.write_num(self.number.0)?;\n        res.write_str(\":\")?;\n        res.write_num(self.addr)?;\n        res.write_str(\":\")?;\n        res.write_str(match self.kind {\n            TracepointSourceType::At => \"at\",\n            TracepointSourceType::Cond => \"cond\",\n            TracepointSourceType::Cmd => \"cmd\",\n        })?;\n        res.write_str(\":\")?;\n        // We use the start and slen from the SourceTracepoint instead of\n        // start=0 slen=bytes.len() because, although we can assume GDB to be able\n        // to handle arbitrary sized packets, the target implementation might still\n        // be giving us chunked source (such as if it's parroting the chunked source\n        // that GDB initially gave us).\n        res.write_num(self.start)?;\n        res.write_str(\":\")?;\n        res.write_num(self.slen)?;\n        res.write_str(\":\")?;\n        res.write_hex_buf(self.bytes.as_ref())?;\n\n        Ok(())\n    }\n}\n\nimpl<U: crate::internal::BeBytes + num_traits::Zero + PrimInt> TracepointAction<'_, U> {\n    /// Write this as a qTfP/qTsP response\n    pub(crate) fn write<T: Target, C: Connection>(\n        &self,\n        tp: Tracepoint,\n        addr: U,\n        res: &mut ResponseWriter<'_, C>,\n    ) -> Result<(), Error<T::Error, C::Error>> {\n        res.write_str(\"A\")?;\n        res.write_num(tp.0)?;\n        res.write_str(\":\")?;\n        res.write_num(addr)?;\n        res.write_str(\":\")?;\n\n        match self {\n            TracepointAction::Registers { mask } => {\n                res.write_str(\"R\")?;\n                res.write_hex_buf(mask)?;\n            }\n            TracepointAction::Memory {\n                basereg,\n                offset,\n                length,\n            } => {\n                res.write_str(\"M\")?;\n                match basereg {\n                    Some(r) => res.write_num(*r),\n                    None => res.write_str(\"-1\"),\n                }?;\n                res.write_str(\",\")?;\n                res.write_num(*offset)?;\n                res.write_str(\",\")?;\n                res.write_num(*length)?;\n            }\n            TracepointAction::Expression { expr } => {\n                res.write_str(\"X\")?;\n                res.write_num(expr.len())?;\n                res.write_str(\",\")?;\n                res.write_hex_buf(expr)?;\n            }\n        }\n        Ok(())\n    }\n}\n\nimpl ExperimentStatus<'_> {\n    pub(crate) fn write<C: Connection>(\n        &self,\n        res: &mut ResponseWriter<'_, C>,\n    ) -> Result<(), ResponseWriterError<C::Error>> {\n        use crate::target::ext::tracepoints::ExperimentStatus::*;\n        if let Running = self {\n            return res.write_str(\"T1\");\n        }\n        // We're stopped for some reason, and may have an explanation for why\n        res.write_str(\"T0\")?;\n        match self {\n            Running => { /* unreachable */ }\n            NotRunning => { /* no information */ }\n            NotRun => res.write_str(\";tnotrun:0\")?,\n            Stop(ref t) => match t {\n                Some(text) => {\n                    res.write_str(\";tstop:\")?;\n                    res.write_hex_buf(text)?;\n                    res.write_str(\":0\")?;\n                }\n                None => res.write_str(\";tstop:0\")?,\n            },\n            Full => res.write_str(\";tfull:0\")?,\n            Disconnected => res.write_str(\";tdisconnected:0\")?,\n            PassCount(tpnum) => {\n                res.write_str(\";tpasscount:\")?;\n                res.write_num(tpnum.0)?;\n            }\n            Error(text, tpnum) => {\n                res.write_str(\";terror:\")?;\n                res.write_hex_buf(text)?;\n                res.write_str(\":\")?;\n                res.write_num(tpnum.0)?;\n            }\n            Unknown => res.write_str(\";tunknown:0\")?,\n        }\n\n        Ok(())\n    }\n}\n\nimpl ExperimentExplanation<'_> {\n    pub(crate) fn write<T: Target, C: Connection>(\n        &self,\n        res: &mut ResponseWriter<'_, C>,\n    ) -> Result<(), Error<T::Error, C::Error>> {\n        use ExperimentExplanation::*;\n        match self {\n            Frames(u) => {\n                res.write_str(\"tframes:\")?;\n                res.write_num(*u)?;\n            }\n            Created(u) => {\n                res.write_str(\"tcreated:\")?;\n                res.write_num(*u)?;\n            }\n            Size(u) => {\n                res.write_str(\"tsize:\")?;\n                res.write_num(*u)?;\n            }\n            Free(u) => {\n                res.write_str(\"tfree:\")?;\n                res.write_num(*u)?;\n            }\n            Circular(u) => {\n                res.write_str(\"circular:\")?;\n                res.write_num(if *u { 1 } else { 0 })?;\n            }\n            DisconnectedTracing(dis) => match dis {\n                true => res.write_str(\"disconn:1\")?,\n                false => res.write_str(\"disconn:0\")?,\n            },\n            Other(body) => res.write_str(body.as_ref())?,\n        };\n\n        Ok(())\n    }\n}\n\nimpl<'a, U: crate::internal::BeBytes> From<FrameRequest<&'a mut [u8]>> for Option<FrameRequest<U>> {\n    fn from(s: FrameRequest<&'a mut [u8]>) -> Self {\n        Some(match s {\n            FrameRequest::Select(u) => FrameRequest::Select(u),\n            FrameRequest::AtPC(u) => FrameRequest::AtPC(U::from_be_bytes(u)?),\n            FrameRequest::Hit(tp) => FrameRequest::Hit(tp),\n            FrameRequest::Between(s, e) => {\n                FrameRequest::Between(U::from_be_bytes(s)?, U::from_be_bytes(e)?)\n            }\n            FrameRequest::Outside(s, e) => {\n                FrameRequest::Outside(U::from_be_bytes(s)?, U::from_be_bytes(e)?)\n            }\n        })\n    }\n}\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_tracepoints(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: Tracepoints<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_tracepoints() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"tracepoints\", \"impl\");\n\n        match command {\n            Tracepoints::QTinit(_) => {\n                ops.tracepoints_init().handle_error()?;\n                // GDB documentation doesn't say it, but this requires \"OK\" in order\n                // to signify we support tracepoints.\n                return Ok(HandlerStatus::NeedsOk);\n            }\n            Tracepoints::qTStatus(_) => {\n                let mut err: Option<Error<T::Error, C::Error>> = None;\n                let mut has_status = false;\n                ops.trace_experiment_status(&mut |status: ExperimentStatus<'_>| {\n                    // If the target implementation calls us multiple times, then\n                    // we would erroneously serialize an invalid response. Guard\n                    // against it in the simplest way.\n                    if has_status {\n                        return;\n                    }\n                    if let Err(e) = status.write(res) {\n                        err = Some(e.into())\n                    } else {\n                        has_status = true;\n                    }\n                })\n                .handle_error()?;\n                if has_status {\n                    // Only bother trying to get info if we also have a status\n                    ops.trace_experiment_info(&mut |explanation: ExperimentExplanation<'_>| {\n                        if let Err(e) = res\n                            .write_str(\";\")\n                            .map_err(|e| e.into())\n                            .and_then(|()| explanation.write::<T, C>(res))\n                        {\n                            err = Some(e)\n                        }\n                    })\n                    .handle_error()?;\n                }\n\n                if let Some(e) = err {\n                    return Err(e);\n                }\n            }\n            Tracepoints::qTP(qtp) => {\n                let addr = <T::Arch as Arch>::Usize::from_be_bytes(qtp.addr)\n                    .ok_or(Error::TargetMismatch)?;\n                let TracepointStatus {\n                    hit_count,\n                    bytes_used,\n                } = ops.tracepoint_status(qtp.tracepoint, addr).handle_error()?;\n                res.write_str(\"V\")?;\n                res.write_num(hit_count)?;\n                res.write_str(\":\")?;\n                res.write_num(bytes_used)?;\n            }\n            Tracepoints::QTDP(q) => {\n                match q {\n                    QTDP::Create(ctdp) => {\n                        if let Some(feat) = ctdp.unsupported_option {\n                            // We have some options we don't know how to process, so bail out.\n                            return Err(Error::TracepointFeatureUnimplemented(feat));\n                        }\n\n                        let (new_tracepoint, more) =\n                            NewTracepoint::<<T::Arch as Arch>::Usize>::from_tdp(ctdp)\n                                .ok_or(Error::TargetMismatch)?;\n                        let tp = new_tracepoint.number;\n                        ops.tracepoint_create_begin(new_tracepoint).handle_error()?;\n                        if !more {\n                            ops.tracepoint_create_complete(tp).handle_error()?;\n                        }\n                    }\n                    QTDP::Extend(dtdp) => {\n                        let extend_tracepoint =\n                            ExtendTracepoint::<<T::Arch as Arch>::Usize>::from_tdp(dtdp)\n                                .ok_or(Error::TargetMismatch)?;\n                        let tp = extend_tracepoint.number;\n                        let mut err: Option<Error<T::Error, C::Error>> = None;\n                        let more = extend_tracepoint.actions(|action| {\n                            if let Err(e) =\n                                ops.tracepoint_create_continue(tp, action).handle_error()\n                            {\n                                err = Some(e)\n                            }\n                        });\n                        if let Some(e) = err {\n                            return Err(e);\n                        }\n                        match more {\n                            Ok(Some(true)) => {\n                                // We expect additional QTDP packets, so don't\n                                // complete it yet.\n                            }\n                            Ok(None) | Ok(Some(false)) => {\n                                ops.tracepoint_create_complete(tp).handle_error()?;\n                            }\n                            Err(e) => {\n                                return Err(e);\n                            }\n                        }\n                    }\n                };\n                // TODO: support qRelocInsn?\n                return Ok(HandlerStatus::NeedsOk);\n            }\n            Tracepoints::QTDPsrc(src) => {\n                if let Some(supports_sources) = ops.support_tracepoint_source() {\n                    let source = SourceTracepoint::<<T::Arch as Arch>::Usize>::from_src(src)\n                        .ok_or(Error::TargetMismatch)?;\n                    supports_sources\n                        .tracepoint_attach_source(source)\n                        .handle_error()?;\n                    // Documentation doesn't mention this, but it needs OK\n                    return Ok(HandlerStatus::NeedsOk);\n                }\n            }\n            Tracepoints::qTBuffer(buf) => {\n                let qTBuffer { offset, length } = buf;\n                let mut wrote: Result<bool, Error<T::Error, C::Error>> = Ok(false);\n                ops.trace_buffer_request(offset, length, &mut |data| {\n                    if let Err(e) = res.write_hex_buf(data) {\n                        wrote = Err(e.into())\n                    } else {\n                        wrote = Ok(true)\n                    }\n                })\n                .handle_error()?;\n                if !wrote? {\n                    res.write_str(\"l\")?;\n                }\n            }\n            Tracepoints::QTBuffer(conf) => {\n                ops.trace_buffer_configure(conf.0).handle_error()?;\n                // Documentation doesn't mention this, but it needs OK\n                return Ok(HandlerStatus::NeedsOk);\n            }\n            Tracepoints::QTStart(_) => {\n                ops.trace_experiment_start().handle_error()?;\n                // Documentation doesn't mention this, but it needs OK\n                // TODO: qRelocInsn reply support?\n                return Ok(HandlerStatus::NeedsOk);\n            }\n            Tracepoints::QTStop(_) => {\n                ops.trace_experiment_stop().handle_error()?;\n                // Documentation doesn't mention this, but it needs OK\n                return Ok(HandlerStatus::NeedsOk);\n            }\n            Tracepoints::QTFrame(req) => {\n                let parsed_qtframe: Option<FrameRequest<<T::Arch as Arch>::Usize>> = req.0.into();\n                let parsed_req = parsed_qtframe.ok_or(Error::TargetMismatch)?;\n                let mut err: Result<_, Error<T::Error, C::Error>> = Ok(());\n                let mut any_results = false;\n                ops.select_frame(parsed_req, &mut |desc| {\n                    let e = (|| -> Result<_, _> {\n                        match desc {\n                            FrameDescription::FrameNumber(n) => {\n                                res.write_str(\"F\")?;\n                                res.write_num(n)?;\n                                any_results = true;\n                            }\n                            FrameDescription::Hit(tdp) => {\n                                res.write_str(\"T\")?;\n                                res.write_num(tdp.0)?;\n                            }\n                        }\n                        Ok(())\n                    })();\n                    if let Err(e) = e {\n                        err = Err(e)\n                    }\n                })\n                .handle_error()?;\n                if !any_results {\n                    res.write_str(\"F-1\")?;\n                }\n            }\n            // The GDB protocol for this is very weird: it sends this first packet\n            // to initialize a state machine on our stub, and then sends the subsequent\n            // packets N times in order to drive the state machine to the end in\n            // order to ask for all our tracepoints and their actions. gdbstub\n            // uses a target allocated state machine that it drives in response\n            // to these packets, so that it can provide a nice typed API.\n            Tracepoints::qTfP(_) => {\n                // Reset our state machine\n                let state = ops.tracepoint_enumerate_state();\n                state.cursor = None;\n\n                let mut err: Option<Error<T::Error, C::Error>> = None;\n                let mut started = None;\n                let step = ops\n                    .tracepoint_enumerate_start(None, &mut |ctp| {\n                        // We need to know what tracepoint to begin stepping, since the\n                        // target will just tell us there's TracepointEnumerateStep::More\n                        // otherwise.\n                        started = Some((ctp.number, ctp.addr));\n                        let e = ctp.write::<T, C>(res);\n                        if let Err(e) = e {\n                            err = Some(e)\n                        }\n                    })\n                    .handle_error()?;\n                if let Some(e) = err {\n                    return Err(e);\n                }\n                if let Some((tp, addr)) = started {\n                    ops.tracepoint_enumerate_state().cursor =\n                        Some(TracepointEnumerateCursor::New { tp, addr });\n                }\n                self.handle_tracepoint_state_machine_step(target, step)?;\n            }\n            Tracepoints::qTsP(_) => {\n                let state = ops.tracepoint_enumerate_state();\n                let mut err: Option<Error<T::Error, C::Error>> = None;\n                let step = match state.cursor {\n                    None => {\n                        // If we don't have a cursor, than the last\n                        // packet responded\n                        // with a TracepointEnumerateStep::Done. We don't have\n                        // anything else to report.\n                        None\n                    }\n                    Some(TracepointEnumerateCursor::New { tp, .. }) => {\n                        // If we don't have any progress, the last packet was\n                        // a Next(tp) and we need to start reporting a new tracepoint\n                        Some(\n                            ops.tracepoint_enumerate_start(Some(tp), &mut |ctp| {\n                                let e = ctp.write::<T, C>(res);\n                                if let Err(e) = e {\n                                    err = Some(e)\n                                }\n                            })\n                            .handle_error()?,\n                        )\n                    }\n                    Some(TracepointEnumerateCursor::Action { tp, addr, step }) => {\n                        // Otherwise we should be continuing the advance the current tracepoint.\n                        Some(\n                            ops.tracepoint_enumerate_action(tp, step, &mut |action| {\n                                let e = action.write::<T, C>(tp, addr, res);\n                                if let Err(e) = e {\n                                    err = Some(e)\n                                }\n                            })\n                            .handle_error()?,\n                        )\n                    }\n                    Some(TracepointEnumerateCursor::Source { tp, step, .. }) => {\n                        if let Some(supports_sources) = ops.support_tracepoint_source() {\n                            Some(\n                                supports_sources\n                                    .tracepoint_enumerate_source(tp, step, &mut |src| {\n                                        let e = src.write::<T, C>(res);\n                                        if let Err(e) = e {\n                                            err = Some(e)\n                                        }\n                                    })\n                                    .handle_error()?,\n                            )\n                        } else {\n                            // If the target doesn't support tracepoint sources but told\n                            // us to enumerate one anyways, then the target has an error.\n                            return Err(Error::TracepointUnsupportedSourceEnumeration);\n                        }\n                    }\n                };\n\n                if let Some(e) = err {\n                    return Err(e);\n                }\n                if let Some(step) = step {\n                    self.handle_tracepoint_state_machine_step(target, step)?;\n                }\n            }\n\n            // Likewise, the same type of driven state machine is used for trace\n            // state variables\n            Tracepoints::qTfV(_) => {\n                // TODO: State variables\n            }\n            Tracepoints::qTsV(_) => {\n                // TODO: State variables\n            }\n        };\n\n        Ok(HandlerStatus::Handled)\n    }\n\n    fn handle_tracepoint_state_machine_step(\n        &mut self,\n        target: &mut T,\n        step: TracepointEnumerateStep<<T::Arch as Arch>::Usize>,\n    ) -> Result<(), Error<T::Error, C::Error>> {\n        let ops = match target.support_tracepoints() {\n            Some(ops) => ops,\n            None => return Ok(()),\n        };\n        let state = ops.tracepoint_enumerate_state();\n        let next = match (state.cursor.as_ref(), step) {\n            (None, _) => None,\n            (Some(_), TracepointEnumerateStep::Done) => None,\n\n            // Transition to enumerating actions\n            (\n                Some(&TracepointEnumerateCursor::New { tp, addr }),\n                TracepointEnumerateStep::Action,\n            ) => Some(TracepointEnumerateCursor::Action { tp, addr, step: 0 }),\n            (\n                Some(&TracepointEnumerateCursor::Source { tp, addr, .. }),\n                TracepointEnumerateStep::Action,\n            ) => Some(TracepointEnumerateCursor::Action { tp, addr, step: 0 }),\n            (\n                Some(&TracepointEnumerateCursor::Action { tp, addr, step }),\n                TracepointEnumerateStep::Action,\n            ) => Some(TracepointEnumerateCursor::Action {\n                tp,\n                addr,\n                step: step + 1,\n            }),\n\n            // Transition to enumerating sources\n            (\n                Some(\n                    &TracepointEnumerateCursor::New { tp, addr }\n                    | &TracepointEnumerateCursor::Action { tp, addr, .. },\n                ),\n                TracepointEnumerateStep::Source,\n            ) => Some(TracepointEnumerateCursor::Source { tp, addr, step: 0 }),\n            (\n                Some(&TracepointEnumerateCursor::Source { tp, addr, step }),\n                TracepointEnumerateStep::Source,\n            ) => Some(TracepointEnumerateCursor::Source {\n                tp,\n                addr,\n                step: step + 1,\n            }),\n\n            // Transition to the next tracepoint\n            (Some(_), TracepointEnumerateStep::Next { tp, addr }) => {\n                Some(TracepointEnumerateCursor::New { tp, addr })\n            }\n        };\n        state.cursor = next;\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/wasm.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::commands::ext::Wasm;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_wasm(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: Wasm<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        let ops = match target.support_wasm() {\n            Some(ops) => ops,\n            None => return Ok(HandlerStatus::Handled),\n        };\n\n        crate::__dead_code_marker!(\"wasm\", \"impl\");\n\n        match command {\n            Wasm::qWasmCallStack(cmd) => {\n                let mut error: Result<(), Error<T::Error, C::Error>> = Ok(());\n                ops.wasm_call_stack(cmd.tid.tid, &mut |pc| {\n                    if let Err(e) = res.write_hex_buf(&pc.to_le_bytes()) {\n                        error = Err(e.into());\n                    }\n                })\n                .map_err(Error::TargetError)?;\n                error?;\n            }\n            Wasm::qWasmLocal(cmd) => {\n                let len = ops\n                    .read_wasm_local(self.current_mem_tid, cmd.frame, cmd.local, cmd.buf)\n                    .map_err(Error::TargetError)?;\n                res.write_hex_buf(&cmd.buf[0..len])?;\n            }\n            Wasm::qWasmGlobal(cmd) => {\n                let len = ops\n                    .read_wasm_global(self.current_mem_tid, cmd.frame, cmd.global, cmd.buf)\n                    .map_err(Error::TargetError)?;\n                res.write_hex_buf(&cmd.buf[0..len])?;\n            }\n            Wasm::qWasmStackValue(cmd) => {\n                let len = ops\n                    .read_wasm_stack(self.current_mem_tid, cmd.frame, cmd.index, cmd.buf)\n                    .map_err(Error::TargetError)?;\n                res.write_hex_buf(&cmd.buf[0..len])?;\n            }\n        };\n\n        Ok(HandlerStatus::Handled)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/x_lowcase_packet.rs",
    "content": "use super::prelude::*;\nuse crate::protocol::commands::ext::XLowcasePacket;\nuse crate::stub::core_impl::base::read_addr_handler;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_x_lowcase_packet(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: XLowcasePacket<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        if !target.use_x_lowcase_packet() {\n            return Ok(HandlerStatus::Handled);\n        }\n\n        crate::__dead_code_marker!(\"x_lowcase_packet\", \"impl\");\n\n        let handler_status = match command {\n            XLowcasePacket::x(cmd) => {\n                read_addr_handler::<C, T>(\n                    |i, data| {\n                        // Start data with 'b' to indicate binary data\n                        if i == 0 {\n                            res.write_str(\"b\")?;\n                        }\n                        res.write_binary(data)\n                    },\n                    self.current_mem_tid,\n                    target,\n                    cmd.buf,\n                    cmd.len,\n                    cmd.addr,\n                )?;\n\n                HandlerStatus::Handled\n            }\n        };\n\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl/x_upcase_packet.rs",
    "content": "use super::prelude::*;\nuse crate::arch::Arch;\nuse crate::protocol::commands::ext::XUpcasePacket;\nuse crate::target::ext::base::BaseOps;\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub(crate) fn handle_x_upcase_packet(\n        &mut self,\n        _res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        command: XUpcasePacket<'_>,\n    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {\n        if !target.use_x_upcase_packet() {\n            return Ok(HandlerStatus::Handled);\n        }\n\n        crate::__dead_code_marker!(\"x_upcase_packet\", \"impl\");\n\n        let handler_status = match command {\n            XUpcasePacket::X(cmd) => {\n                let addr = <T::Arch as Arch>::Usize::from_be_bytes(cmd.addr)\n                    .ok_or(Error::TargetMismatch)?;\n\n                match target.base_ops() {\n                    BaseOps::SingleThread(ops) => ops.write_addrs(addr, cmd.val),\n                    BaseOps::MultiThread(ops) => {\n                        ops.write_addrs(addr, cmd.val, self.current_mem_tid)\n                    }\n                }\n                .handle_error()?;\n\n                HandlerStatus::NeedsOk\n            }\n        };\n        Ok(handler_status)\n    }\n}\n"
  },
  {
    "path": "src/stub/core_impl.rs",
    "content": "use crate::common::Signal;\nuse crate::common::Tid;\nuse crate::conn::Connection;\nuse crate::protocol::commands::Command;\nuse crate::protocol::Packet;\nuse crate::protocol::ResponseWriter;\nuse crate::protocol::SpecificIdKind;\nuse crate::stub::error::InternalError;\nuse crate::target::Target;\nuse crate::SINGLE_THREAD_TID;\nuse core::marker::PhantomData;\n\n/// Common imports used by >50% of all extensions.\n///\n/// Do not clutter this prelude with types only used by a few extensions.\nmod prelude {\n    pub(super) use crate::conn::Connection;\n    pub(super) use crate::internal::BeBytes;\n    pub(super) use crate::protocol::ResponseWriter;\n    pub(super) use crate::stub::core_impl::target_result_ext::TargetResultExt;\n    pub(super) use crate::stub::core_impl::GdbStubImpl;\n    pub(super) use crate::stub::core_impl::HandlerStatus;\n    pub(super) use crate::stub::error::InternalError as Error;\n    pub(super) use crate::target::Target;\n}\n\nmod auxv;\nmod base;\nmod breakpoints;\nmod catch_syscalls;\nmod exec_file;\nmod extended_mode;\nmod flash;\nmod host_io;\nmod host_process_info;\nmod libraries;\nmod lldb_register_info;\nmod memory_map;\nmod monitor_cmd;\nmod no_ack_mode;\nmod resume;\nmod reverse_exec;\nmod section_offsets;\nmod single_register_access;\nmod target_xml;\nmod thread_extra_info;\nmod tracepoints;\nmod wasm;\nmod x_lowcase_packet;\nmod x_upcase_packet;\n\npub(crate) use resume::FinishExecStatus;\n\npub(crate) mod target_result_ext {\n    use crate::stub::error::InternalError;\n    use crate::target::TargetError;\n\n    /// Extension trait to ease working with `TargetResult` in the GdbStub\n    /// implementation.\n    pub(super) trait TargetResultExt<V, T, C> {\n        /// Encapsulates the boilerplate associated with handling\n        /// `TargetError`s, such as bailing-out on Fatal errors, or\n        /// returning response codes.\n        fn handle_error(self) -> Result<V, InternalError<T, C>>;\n    }\n\n    impl<V, T, C> TargetResultExt<V, T, C> for Result<V, TargetError<T>> {\n        fn handle_error(self) -> Result<V, InternalError<T, C>> {\n            let code = match self {\n                Ok(v) => return Ok(v),\n                Err(TargetError::Fatal(e)) => return Err(InternalError::TargetError(e)),\n                // Recoverable errors:\n                // Error code 121 corresponds to `EREMOTEIO` lol\n                Err(TargetError::NonFatal) => 121,\n                Err(TargetError::Errno(code)) => code,\n                #[cfg(feature = \"std\")]\n                Err(TargetError::Io(e)) => e.raw_os_error().unwrap_or(121) as u8,\n            };\n\n            Err(InternalError::NonFatalError(code))\n        }\n    }\n}\n\n/// Describes why the GDB session ended.\n#[derive(Clone, Copy, Debug, PartialEq, Eq)]\npub enum DisconnectReason {\n    /// Target exited with given status code\n    TargetExited(u8),\n    /// Target terminated with given signal\n    TargetTerminated(Signal),\n    /// GDB issued a disconnect command\n    Disconnect,\n    /// GDB issued a kill command\n    Kill,\n}\n\npub enum State {\n    Pump,\n    DeferredStopReason,\n    CtrlCInterrupt,\n    Disconnect(DisconnectReason),\n}\n\npub(crate) struct GdbStubImpl<T: Target, C: Connection> {\n    _target: PhantomData<T>,\n    _connection: PhantomData<C>,\n\n    current_mem_tid: Tid,\n    current_resume_tid: SpecificIdKind,\n    features: ProtocolFeatures,\n}\n\npub enum HandlerStatus {\n    Handled,\n    NeedsOk,\n    DeferredStopReason,\n    Disconnect(DisconnectReason),\n}\n\nimpl<T: Target, C: Connection> GdbStubImpl<T, C> {\n    pub fn new() -> GdbStubImpl<T, C> {\n        GdbStubImpl {\n            _target: PhantomData,\n            _connection: PhantomData,\n\n            // NOTE: `current_mem_tid` and `current_resume_tid` are never queried prior to being set\n            // by the GDB client (via the 'H' packet), so it's fine to use dummy values here.\n            //\n            // The alternative would be to use `Option`, and while this would be more \"correct\", it\n            // would introduce a _lot_ of noisy and heavy error handling logic all over the place.\n            //\n            // Plus, even if the GDB client is acting strangely and doesn't overwrite these values,\n            // the target will simply return a non-fatal error, which is totally fine.\n            current_mem_tid: SINGLE_THREAD_TID,\n            current_resume_tid: SpecificIdKind::WithId(SINGLE_THREAD_TID),\n            features: ProtocolFeatures::empty(),\n        }\n    }\n\n    pub fn handle_packet(\n        &mut self,\n        target: &mut T,\n        conn: &mut C,\n        packet: Packet<'_>,\n    ) -> Result<State, InternalError<T::Error, C::Error>> {\n        match packet {\n            Packet::Ack => Ok(State::Pump),\n            Packet::Nack => Err(InternalError::ClientSentNack),\n            Packet::Interrupt => {\n                debug!(\"<-- interrupt packet\");\n                Ok(State::CtrlCInterrupt)\n            }\n            Packet::Command(command) => {\n                // Acknowledge the command\n                if !self.features.no_ack_mode() {\n                    conn.write(b'+').map_err(InternalError::conn_write)?;\n                }\n\n                let mut res = ResponseWriter::new(conn, target.use_rle());\n                let disconnect_reason = match self.handle_command(&mut res, target, command) {\n                    Ok(HandlerStatus::Handled) => None,\n                    Ok(HandlerStatus::NeedsOk) => {\n                        res.write_str(\"OK\")?;\n                        None\n                    }\n                    Ok(HandlerStatus::DeferredStopReason) => return Ok(State::DeferredStopReason),\n                    Ok(HandlerStatus::Disconnect(reason)) => Some(reason),\n                    // HACK: handling this \"dummy\" error is required as part of the\n                    // `TargetResultExt::handle_error()` machinery.\n                    Err(InternalError::NonFatalError(code)) => {\n                        res.write_str(\"E\")?;\n                        res.write_num(code)?;\n                        None\n                    }\n                    Err(e) => return Err(e),\n                };\n\n                // every response needs to be flushed, _except_ for the response to a kill\n                // packet, but ONLY when extended mode is NOT implemented.\n                let is_kill = matches!(disconnect_reason, Some(DisconnectReason::Kill));\n                if !(target.support_extended_mode().is_none() && is_kill) {\n                    res.flush()?;\n                }\n\n                let state = match disconnect_reason {\n                    Some(reason) => State::Disconnect(reason),\n                    None => State::Pump,\n                };\n\n                Ok(state)\n            }\n        }\n    }\n\n    fn handle_command(\n        &mut self,\n        res: &mut ResponseWriter<'_, C>,\n        target: &mut T,\n        cmd: Command<'_>,\n    ) -> Result<HandlerStatus, InternalError<T::Error, C::Error>> {\n        match cmd {\n            // `handle_X` methods are defined in the `ext` module\n            Command::Base(cmd) => self.handle_base(res, target, cmd),\n            Command::TargetXml(cmd) => self.handle_target_xml(res, target, cmd),\n            Command::Resume(cmd) => self.handle_stop_resume(res, target, cmd),\n            Command::NoAckMode(cmd) => self.handle_no_ack_mode(res, target, cmd),\n            Command::XLowcasePacket(cmd) => self.handle_x_lowcase_packet(res, target, cmd),\n            Command::XUpcasePacket(cmd) => self.handle_x_upcase_packet(res, target, cmd),\n            Command::SingleRegisterAccess(cmd) => {\n                self.handle_single_register_access(res, target, cmd)\n            }\n            Command::Breakpoints(cmd) => self.handle_breakpoints(res, target, cmd),\n            Command::CatchSyscalls(cmd) => self.handle_catch_syscalls(res, target, cmd),\n            Command::ExtendedMode(cmd) => self.handle_extended_mode(res, target, cmd),\n            Command::MonitorCmd(cmd) => self.handle_monitor_cmd(res, target, cmd),\n            Command::SectionOffsets(cmd) => self.handle_section_offsets(res, target, cmd),\n            Command::ReverseCont(cmd) => self.handle_reverse_cont(res, target, cmd),\n            Command::ReverseStep(cmd) => self.handle_reverse_step(res, target, cmd),\n            Command::MemoryMap(cmd) => self.handle_memory_map(res, target, cmd),\n            Command::FlashOperations(cmd) => self.handle_flash_operations(res, target, cmd),\n            Command::HostIo(cmd) => self.handle_host_io(res, target, cmd),\n            Command::ExecFile(cmd) => self.handle_exec_file(res, target, cmd),\n            Command::Auxv(cmd) => self.handle_auxv(res, target, cmd),\n            Command::ThreadExtraInfo(cmd) => self.handle_thread_extra_info(res, target, cmd),\n            Command::LldbRegisterInfo(cmd) => self.handle_lldb_register_info(res, target, cmd),\n            Command::LibrariesSvr4(cmd) => self.handle_libraries_svr4(res, target, cmd),\n            Command::Libraries(cmd) => self.handle_libraries(res, target, cmd),\n            Command::Tracepoints(cmd) => self.handle_tracepoints(res, target, cmd),\n            Command::HostInfo(cmd) => self.handle_host_info(res, target, cmd),\n            Command::ProcessInfo(cmd) => self.handle_process_info(res, target, cmd),\n            Command::Wasm(cmd) => self.handle_wasm(res, target, cmd),\n            // in the worst case, the command could not be parsed...\n            Command::Unknown(cmd) => {\n                // HACK: if the user accidentally sends a resume command to a\n                // target without resume support, inform them of their mistake +\n                // return a dummy stop reason.\n                if target.base_ops().resume_ops().is_none() && target.use_resume_stub() {\n                    let is_resume_pkt = cmd\n                        .first()\n                        .map(|c| matches!(c, b'c' | b'C' | b's' | b'S'))\n                        .unwrap_or(false);\n\n                    if is_resume_pkt {\n                        warn!(\"attempted to resume target without resume support!\");\n\n                        // TODO: omit this message if non-stop mode is active\n                        {\n                            let mut res = ResponseWriter::new(res.as_conn(), target.use_rle());\n                            res.write_str(\"O\")?;\n                            res.write_hex_buf(b\"target has not implemented `support_resume()`\\n\")?;\n                            res.flush()?;\n                        }\n\n                        res.write_str(\"S05\")?;\n                    }\n                }\n\n                info!(\"Unknown command: {:?}\", core::str::from_utf8(cmd));\n                Ok(HandlerStatus::Handled)\n            }\n        }\n    }\n}\n\n#[derive(Copy, Clone)]\n#[repr(transparent)]\nstruct ProtocolFeatures(u8);\n\n// This bitflag is not part of the protocol - it is an internal implementation\n// detail. The alternative would be to use multiple `bool` fields, which wastes\n// space in minimal `gdbstub` configurations.\nbitflags::bitflags! {\n    impl ProtocolFeatures: u8 {\n        const NO_ACK_MODE = 1 << 0;\n        const MULTIPROCESS = 1 << 1;\n    }\n}\n\nimpl ProtocolFeatures {\n    #[inline(always)]\n    fn no_ack_mode(&self) -> bool {\n        self.contains(ProtocolFeatures::NO_ACK_MODE)\n    }\n\n    #[inline(always)]\n    fn set_no_ack_mode(&mut self, val: bool) {\n        self.set(ProtocolFeatures::NO_ACK_MODE, val)\n    }\n\n    #[inline(always)]\n    fn multiprocess(&self) -> bool {\n        self.contains(ProtocolFeatures::MULTIPROCESS)\n    }\n\n    #[inline(always)]\n    fn set_multiprocess(&mut self, val: bool) {\n        self.set(ProtocolFeatures::MULTIPROCESS, val)\n    }\n}\n"
  },
  {
    "path": "src/stub/error.rs",
    "content": "use crate::protocol::PacketParseError;\nuse crate::protocol::ResponseWriterError;\nuse crate::util::managed_vec::CapacityError;\n#[cfg(feature = \"core_error\")]\nuse core::error::Error as CoreError;\nuse core::fmt::Debug;\nuse core::fmt::Display;\nuse core::fmt::{self};\n#[cfg(all(feature = \"std\", not(feature = \"core_error\")))]\nuse std::error::Error as CoreError;\n\n/// An error that may occur while interacting with a\n/// [`Connection`](crate::conn::Connection).\n#[derive(Debug)]\npub enum ConnectionErrorKind {\n    /// Error initializing the session.\n    Init,\n    /// Error reading data.\n    Read,\n    /// Error writing data.\n    Write,\n}\n\n#[derive(Debug)]\npub(crate) enum InternalError<T, C> {\n    /// Connection Error\n    Connection(C, ConnectionErrorKind),\n    /// Target encountered a fatal error.\n    TargetError(T),\n\n    ClientSentNack,\n    PacketBufferOverflow,\n    PacketParse(PacketParseError),\n    PacketUnexpected,\n    TargetMismatch,\n    UnsupportedStopReason,\n    UnexpectedStepPacket,\n    ImplicitSwBreakpoints,\n    // DEVNOTE: this is a temporary workaround for something that can and should\n    // be caught at compile time via IDETs. That said, since i'm not sure when\n    // I'll find the time to cut a breaking release of gdbstub, I'd prefer to\n    // push out this feature as a non-breaking change now.\n    MissingCurrentActivePidImpl,\n    TracepointFeatureUnimplemented(u8),\n    TracepointUnsupportedSourceEnumeration,\n    MissingMultiThreadSchedulerLocking,\n    MissingToRawId,\n\n    // Internal - A non-fatal error occurred (with errno-style error code)\n    //\n    // This \"dummy\" error is required as part of the internal\n    // `TargetResultExt::handle_error()` machinery, and will never be\n    // propagated up to the end user.\n    #[doc(hidden)]\n    NonFatalError(u8),\n}\n\nimpl<T, C> InternalError<T, C> {\n    pub fn conn_read(e: C) -> Self {\n        InternalError::Connection(e, ConnectionErrorKind::Read)\n    }\n\n    pub fn conn_write(e: C) -> Self {\n        InternalError::Connection(e, ConnectionErrorKind::Write)\n    }\n\n    pub fn conn_init(e: C) -> Self {\n        InternalError::Connection(e, ConnectionErrorKind::Init)\n    }\n}\n\nimpl<T, C> From<ResponseWriterError<C>> for InternalError<T, C> {\n    fn from(e: ResponseWriterError<C>) -> Self {\n        InternalError::Connection(e.0, ConnectionErrorKind::Write)\n    }\n}\n\n// these macros are used to keep the docs and `Display` impl in-sync\n\nmacro_rules! unsupported_stop_reason {\n    () => {\n        \"User error: cannot report stop reason without also implementing its corresponding IDET\"\n    };\n}\n\nmacro_rules! unexpected_step_packet {\n    () => {\n        \"Received an unexpected `step` request. This is most-likely due to this GDB client bug: <https://sourceware.org/bugzilla/show_bug.cgi?id=28440>\"\n    };\n}\n\n/// An error which may occur during a GDB debugging session.\n///\n/// ## Additional Notes\n///\n/// `GdbStubError`'s inherent `Display` impl typically contains enough context\n/// for users to understand why the error occurred.\n///\n/// That said, there are a few instances where the error condition requires\n/// additional context.\n///\n/// * * *\n#[doc = concat!(\"_\", unsupported_stop_reason!(), \"_\")]\n///\n/// This is a not a bug with `gdbstub`. Rather, this is indicative of a bug in\n/// your `gdbstub` integration.\n///\n/// Certain stop reasons can only be used when their associated protocol feature\n/// has been implemented. e.g: a Target cannot return a `StopReason::HwBreak` if\n/// the hardware breakpoints IDET hasn't been implemented.\n///\n/// Please double-check that you've implemented all the necessary `supports_`\n/// methods related to the stop reason you're trying to report.\n///\n/// * * *\n#[doc = concat!(\"_\", unexpected_step_packet!(), \"_\")]\n///\n/// Unfortunately, there's nothing `gdbstub` can do to work around this bug.\n///\n/// Until the issue is fixed upstream, certain architectures are essentially\n/// forced to manually implement single-step support.\n#[derive(Debug)]\npub struct GdbStubError<T, C> {\n    kind: InternalError<T, C>,\n}\n\nimpl<T, C> Display for GdbStubError<T, C>\nwhere\n    C: Display,\n    T: Display,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        use self::InternalError::*;\n        const CONTEXT: &str = \"See the `GdbStubError` docs for more details\";\n        match &self.kind {\n            Connection(e, ConnectionErrorKind::Init) => write!(f, \"Connection Error while initializing the session: {}\", e),\n            Connection(e, ConnectionErrorKind::Read) => write!(f, \"Connection Error while reading request: {}\", e),\n            Connection(e, ConnectionErrorKind::Write) => write!(f, \"Connection Error while writing response: {}\", e),\n            ClientSentNack => write!(f, \"Client nack'd the last packet, but `gdbstub` doesn't implement re-transmission.\"),\n            PacketBufferOverflow => write!(f, \"Received an oversized packet (did not fit in provided packet buffer)\"),\n            PacketParse(e) => write!(f, \"Failed to parse packet into a valid command: {:?}\", e),\n            PacketUnexpected => write!(f, \"Client sent an unexpected packet. This should never happen! Please re-run with `log` trace-level logging enabled and file an issue at https://github.com/daniel5151/gdbstub/issues\"),\n            TargetMismatch => write!(f, \"Received a packet with too much data for the given target\"),\n            TargetError(e) => write!(f, \"Target threw a fatal error: {}\", e),\n            UnsupportedStopReason => write!(f, \"{} {}\", unsupported_stop_reason!(), CONTEXT),\n            UnexpectedStepPacket => write!(f, \"{} {}\", unexpected_step_packet!(), CONTEXT),\n\n            ImplicitSwBreakpoints => write!(f, \"Warning: The target has not opted into using implicit software breakpoints. See `Target::guard_rail_implicit_sw_breakpoints` for more information\"),\n            MissingCurrentActivePidImpl => write!(f, \"GDB client attempted to attach to a new process, but the target has not implemented support for `ExtendedMode::support_current_active_pid`\"),\n            TracepointFeatureUnimplemented(feat) => write!(f, \"GDB client sent us a tracepoint packet using feature {}, but `gdbstub` doesn't implement it. If this is something you require, please file an issue at https://github.com/daniel5151/gdbstub/issues\", *feat as char),\n            TracepointUnsupportedSourceEnumeration => write!(f, \"The target doesn't support the gdbstub TracepointSource extension, but attempted to transition to enumerating tracepoint sources\"),\n            MissingMultiThreadSchedulerLocking => write!(f, \"GDB requested Scheduler Locking, but the Target does not implement the `MultiThreadSchedulerLocking` IDET\"),\n            MissingToRawId => write!(f, \"A RegId was used with an API that requires raw register IDs to be available (e.g. `report_stop_with_regs`) but returned `None` from `to_raw_id()`\"),\n\n            NonFatalError(_) => write!(f, \"Internal non-fatal error. You should never see this! Please file an issue if you do!\"),\n        }\n    }\n}\n\n#[cfg(any(feature = \"std\", feature = \"core_error\"))]\nimpl<T, C> CoreError for GdbStubError<T, C>\nwhere\n    C: Debug + Display,\n    T: Debug + Display,\n{\n}\n\nimpl<T, C> GdbStubError<T, C> {\n    /// Check if the error was due to a target error.\n    pub fn is_target_error(&self) -> bool {\n        matches!(self.kind, InternalError::TargetError(..))\n    }\n\n    /// If the error was due to a target error, return the concrete error type.\n    pub fn into_target_error(self) -> Option<T> {\n        match self.kind {\n            InternalError::TargetError(e) => Some(e),\n            _ => None,\n        }\n    }\n\n    /// Check if the error was due to a connection error.\n    pub fn is_connection_error(&self) -> bool {\n        matches!(self.kind, InternalError::Connection(..))\n    }\n\n    /// If the error was due to a connection error, return the concrete error\n    /// type.\n    pub fn into_connection_error(self) -> Option<(C, ConnectionErrorKind)> {\n        match self.kind {\n            InternalError::Connection(e, kind) => Some((e, kind)),\n            _ => None,\n        }\n    }\n}\n\nimpl<T, C> From<InternalError<T, C>> for GdbStubError<T, C> {\n    fn from(kind: InternalError<T, C>) -> Self {\n        GdbStubError { kind }\n    }\n}\n\nimpl<A, T, C> From<CapacityError<A>> for GdbStubError<T, C> {\n    fn from(_: CapacityError<A>) -> Self {\n        InternalError::PacketBufferOverflow.into()\n    }\n}\n"
  },
  {
    "path": "src/stub/mod.rs",
    "content": "//! The core [`GdbStub`] type, used to drive a GDB debugging session for a\n//! particular [`Target`] over a given [`Connection`].\n\npub use builder::GdbStubBuilder;\npub use builder::GdbStubBuilderError;\npub use core_impl::DisconnectReason;\npub use error::GdbStubError;\npub use stop_reason::BaseStopReason;\npub use stop_reason::IntoStopReason;\npub use stop_reason::MultiThreadStopReason;\npub use stop_reason::SingleThreadStopReason;\n\nmod builder;\nmod core_impl;\nmod error;\nmod stop_reason;\n\npub mod state_machine;\n\nuse self::error::InternalError;\nuse crate::conn::Connection;\nuse crate::conn::ConnectionExt;\nuse crate::target::Target;\nuse managed::ManagedSlice;\n\n/// Types and traits related to the [`GdbStub::run_blocking`] interface.\npub mod run_blocking {\n    use super::*;\n    use crate::conn::ConnectionExt;\n\n    /// A set of user-provided methods required to run a GDB debugging session\n    /// using the [`GdbStub::run_blocking`] method.\n    ///\n    /// Reminder: to use `gdbstub` in a non-blocking manner (e.g: via\n    /// async/await, unix polling, from an interrupt handler, etc...) you will\n    /// need to interface with the\n    /// [`GdbStubStateMachine`](state_machine::GdbStubStateMachine) API\n    /// directly.\n    pub trait BlockingEventLoop {\n        /// The Target being driven.\n        type Target: Target;\n        /// Connection being used to drive the target.\n        type Connection: ConnectionExt;\n\n        /// Which variant of the `StopReason` type should be used. Single\n        /// threaded targets should use [`SingleThreadStopReason`], whereas\n        /// multi threaded targets should use [`MultiThreadStopReason`].\n        ///\n        /// [`SingleThreadStopReason`]: crate::stub::SingleThreadStopReason\n        /// [`MultiThreadStopReason`]: crate::stub::MultiThreadStopReason\n        type StopReason: IntoStopReason<Self::Target>;\n\n        /// Invoked immediately after the target's `resume` method has been\n        /// called. The implementation should block until either the target\n        /// reports a stop reason, or if new data was sent over the connection.\n        ///\n        /// The specific mechanism to \"select\" between these two events is\n        /// implementation specific. Some examples might include: `epoll`,\n        /// `select!` across multiple event channels, periodic polling, etc...\n        fn wait_for_stop_reason(\n            target: &mut Self::Target,\n            conn: &mut Self::Connection,\n        ) -> Result<\n            Event<Self::StopReason>,\n            WaitForStopReasonError<\n                <Self::Target as Target>::Error,\n                <Self::Connection as Connection>::Error,\n            >,\n        >;\n\n        /// Invoked when the GDB client sends a Ctrl-C interrupt.\n        ///\n        /// Depending on how the target is implemented, it may or may not make\n        /// sense to immediately return a stop reason as part of handling the\n        /// Ctrl-C interrupt. e.g: in some cases, it may be better to send the\n        /// target a signal upon receiving a Ctrl-C interrupt _without_\n        /// immediately sending a stop reason, and instead deferring the stop\n        /// reason to some later point in the target's execution.\n        ///\n        /// _Suggestion_: If you're unsure which stop reason to report,\n        /// [`BaseStopReason::Signal(Signal::SIGINT)`] is a sensible default.\n        ///\n        /// [`BaseStopReason::Signal(Signal::SIGINT)`]:\n        /// crate::stub::BaseStopReason::Signal\n        fn on_interrupt(\n            target: &mut Self::Target,\n        ) -> Result<Option<Self::StopReason>, <Self::Target as Target>::Error>;\n    }\n\n    /// Returned by the `wait_for_stop_reason` closure in\n    /// [`GdbStub::run_blocking`]\n    pub enum Event<StopReason> {\n        /// GDB Client sent data while the target was running.\n        IncomingData(u8),\n        /// The target has stopped.\n        TargetStopped(StopReason),\n    }\n\n    /// Error value returned by the `wait_for_stop_reason` closure in\n    /// [`GdbStub::run_blocking`]\n    pub enum WaitForStopReasonError<T, C> {\n        /// A fatal target error has occurred.\n        Target(T),\n        /// A fatal connection error has occurred.\n        Connection(C),\n    }\n}\n\n/// Debug a [`Target`] using the GDB Remote Serial Protocol over a given\n/// [`Connection`].\npub struct GdbStub<'a, T: Target, C: Connection> {\n    conn: C,\n    packet_buffer: ManagedSlice<'a, u8>,\n    inner: core_impl::GdbStubImpl<T, C>,\n}\n\nimpl<'a, T: Target, C: Connection> GdbStub<'a, T, C> {\n    /// Create a [`GdbStubBuilder`] using the provided Connection.\n    pub fn builder(conn: C) -> GdbStubBuilder<'a, T, C> {\n        GdbStubBuilder::new(conn)\n    }\n\n    /// Create a new `GdbStub` using the provided connection.\n    ///\n    /// _Note:_ `new` is only available when the `alloc` feature is enabled, as\n    /// it will use a dynamically allocated `Vec` as a packet buffer.\n    ///\n    /// For fine-grained control over various `GdbStub` options, including the\n    /// ability to specify a fixed-size buffer, use the [`GdbStub::builder`]\n    /// method instead.\n    #[cfg(feature = \"alloc\")]\n    pub fn new(conn: C) -> GdbStub<'a, T, C> {\n        GdbStubBuilder::new(conn).build().unwrap()\n    }\n\n    /// (Quickstart) Start a GDB remote debugging session using a blocking event\n    /// loop.\n    ///\n    /// This method provides a quick and easy way to get up and running with\n    /// `gdbstub` without directly having to immediately interface with the\n    /// lower-level [state-machine](state_machine::GdbStubStateMachine)\n    /// based interface.\n    ///\n    /// Instead, an implementation simply needs to provide a implementation of\n    /// [`run_blocking::BlockingEventLoop`], which is a simplified set\n    /// of methods describing how to drive the target.\n    ///\n    /// `GdbStub::run_blocking` returns once the GDB client closes the debugging\n    /// session, or if the target triggers a disconnect.\n    ///\n    /// Note that this implementation is **blocking**, which many not be\n    /// preferred (or suitable) in all cases. To use `gdbstub` in a non-blocking\n    /// manner (e.g: via async/await, unix polling, from an interrupt handler,\n    /// etc...) you will need to interface with the underlying\n    /// [`GdbStubStateMachine`](state_machine::GdbStubStateMachine) API\n    /// directly.\n    pub fn run_blocking<E>(\n        self,\n        target: &mut T,\n    ) -> Result<DisconnectReason, GdbStubError<T::Error, C::Error>>\n    where\n        C: ConnectionExt,\n        E: run_blocking::BlockingEventLoop<Target = T, Connection = C>,\n    {\n        let mut gdb = self.run_state_machine(target)?;\n        loop {\n            gdb = match gdb {\n                state_machine::GdbStubStateMachine::Idle(mut gdb) => {\n                    // needs more data, so perform a blocking read on the connection\n                    let byte = gdb.borrow_conn().read().map_err(InternalError::conn_read)?;\n                    gdb.incoming_data(target, byte)?\n                }\n\n                state_machine::GdbStubStateMachine::Disconnected(gdb) => {\n                    // run_blocking keeps things simple, and doesn't expose a way to re-use the\n                    // state machine\n                    break Ok(gdb.get_reason());\n                }\n\n                state_machine::GdbStubStateMachine::CtrlCInterrupt(gdb) => {\n                    // defer to the implementation on how it wants to handle the interrupt\n                    let stop_reason =\n                        E::on_interrupt(target).map_err(InternalError::TargetError)?;\n                    gdb.interrupt_handled(target, stop_reason)?\n                }\n\n                state_machine::GdbStubStateMachine::Running(mut gdb) => {\n                    use run_blocking::Event as BlockingEventLoopEvent;\n                    use run_blocking::WaitForStopReasonError;\n\n                    // block waiting for the target to return a stop reason\n                    let event = E::wait_for_stop_reason(target, gdb.borrow_conn());\n                    match event {\n                        Ok(BlockingEventLoopEvent::TargetStopped(stop_reason)) => {\n                            gdb.report_stop(target, stop_reason)?\n                        }\n\n                        Ok(BlockingEventLoopEvent::IncomingData(byte)) => {\n                            gdb.incoming_data(target, byte)?\n                        }\n\n                        Err(WaitForStopReasonError::Target(e)) => {\n                            break Err(InternalError::TargetError(e).into());\n                        }\n                        Err(WaitForStopReasonError::Connection(e)) => {\n                            break Err(InternalError::conn_read(e).into());\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    /// Starts a GDB remote debugging session, converting this instance of\n    /// `GdbStub` into a\n    /// [`GdbStubStateMachine`](state_machine::GdbStubStateMachine) that is\n    /// ready to receive data.\n    pub fn run_state_machine(\n        mut self,\n        target: &mut T,\n    ) -> Result<state_machine::GdbStubStateMachine<'a, T, C>, GdbStubError<T::Error, C::Error>>\n    {\n        // Check if the target hasn't explicitly opted into implicit sw breakpoints\n        {\n            let support_software_breakpoints = target\n                .support_breakpoints()\n                .map(|ops| ops.support_sw_breakpoint().is_some())\n                .unwrap_or(false);\n\n            if !support_software_breakpoints && !target.guard_rail_implicit_sw_breakpoints() {\n                return Err(InternalError::ImplicitSwBreakpoints.into());\n            }\n        }\n\n        // Perform any connection initialization\n        {\n            self.conn\n                .on_session_start()\n                .map_err(InternalError::conn_init)?;\n        }\n\n        Ok(state_machine::GdbStubStateMachineInner::from_plain_gdbstub(self).into())\n    }\n}\n"
  },
  {
    "path": "src/stub/state_machine.rs",
    "content": "//! Low-level state-machine interface that underpins [`GdbStub`].\n//\n// TODO: write some proper documentation + examples of how to interface with\n// this API.\n//!\n//! # Hey, what gives? Where are all the docs!?\n//!\n//! Yep, sorry about that!\n//!\n//! `gdbstub` 0.6 turned out ot be a pretty massive release, and documenting\n//! everything has proven to be a somewhat gargantuan task that's kept delaying\n//! the release data further and further back...\n//!\n//! To avoid blocking the release any further, I've decided to leave this bit of\n//! the API sparsely documented.\n//!\n//! If you're interested in using this API directly (e.g: to integrate `gdbstub`\n//! into a `no_std` project, or to use `gdbstub` in a non-blocking manner\n//! alongside `async/await` / a project specific event loop), your best bet\n//! would be to review the following bits of code to get a feel for the API:\n//!\n//! - The implementation of [`GdbStub::run_blocking`]\n//! - Implementations of [`BlockingEventLoop`] used alongside\n//!   `GdbStub::run_blocking` (e.g: the in-tree `armv4t` / `armv4t_multicore`\n//!   examples)\n//! - Real-world projects using the API (see the repo's README.md)\n//!\n//! If you have any questions, feel free to open a discussion thread over at the\n//! [`gdbstub` GitHub repo](https://github.com/daniel5151/gdbstub/).\n//!\n//! [`BlockingEventLoop`]: super::run_blocking::BlockingEventLoop\n//! [`GdbStub::run_blocking`]: super::GdbStub::run_blocking\n\nuse super::core_impl::FinishExecStatus;\nuse super::core_impl::GdbStubImpl;\nuse super::core_impl::State;\nuse super::DisconnectReason;\nuse super::GdbStub;\nuse crate::arch::Arch;\nuse crate::arch::RegId;\nuse crate::conn::Connection;\nuse crate::protocol::recv_packet::RecvPacketStateMachine;\nuse crate::protocol::Packet;\nuse crate::protocol::ResponseWriter;\nuse crate::stub::error::GdbStubError;\nuse crate::stub::error::InternalError;\nuse crate::stub::stop_reason::IntoStopReason;\nuse crate::stub::BaseStopReason;\nuse crate::target::Target;\nuse managed::ManagedSlice;\n\n/// State-machine interface to `GdbStub`.\n///\n/// See the [module level documentation](self) for more details.\npub enum GdbStubStateMachine<'a, T, C>\nwhere\n    T: Target,\n    C: Connection,\n{\n    /// The target is completely stopped, and the GDB stub is waiting for\n    /// additional input.\n    Idle(GdbStubStateMachineInner<'a, state::Idle<T>, T, C>),\n    /// The target is currently running, and the GDB client is waiting for\n    /// the target to report a stop reason.\n    ///\n    /// Note that the client may still send packets to the target\n    /// (e.g: to trigger a Ctrl-C interrupt).\n    Running(GdbStubStateMachineInner<'a, state::Running, T, C>),\n    /// The GDB client has sent a Ctrl-C interrupt to the target.\n    CtrlCInterrupt(GdbStubStateMachineInner<'a, state::CtrlCInterrupt, T, C>),\n    /// The GDB client has disconnected.\n    Disconnected(GdbStubStateMachineInner<'a, state::Disconnected, T, C>),\n}\n\n/// State machine typestates.\n///\n/// The types in this module are used to parameterize instances of\n/// [`GdbStubStateMachineInner`], thereby enforcing that certain API methods\n/// can only be called while the stub is in a certain state.\n// As an internal implementation detail, they _also_ carry state-specific\n// payloads, which are used when transitioning between states.\npub mod state {\n    use super::*;\n    use crate::stub::stop_reason::MultiThreadStopReason;\n\n    // used internally when logging state transitions\n    pub(crate) const MODULE_PATH: &str = concat!(module_path!(), \"::\");\n\n    /// Typestate corresponding to the \"Idle\" state.\n    #[non_exhaustive]\n    pub struct Idle<T: Target> {\n        pub(crate) deferred_ctrlc_stop_reason:\n            Option<MultiThreadStopReason<<<T as Target>::Arch as Arch>::Usize>>,\n    }\n\n    /// Typestate corresponding to the \"Running\" state.\n    #[non_exhaustive]\n    pub struct Running {}\n\n    /// Typestate corresponding to the \"CtrlCInterrupt\" state.\n    #[non_exhaustive]\n    pub struct CtrlCInterrupt {\n        pub(crate) from_idle: bool,\n    }\n\n    /// Typestate corresponding to the \"Disconnected\" state.\n    #[non_exhaustive]\n    pub struct Disconnected {\n        pub(crate) reason: DisconnectReason,\n    }\n}\n\n/// Internal helper macro to convert between a particular inner state into\n/// its corresponding `GdbStubStateMachine` variant.\nmacro_rules! impl_from_inner {\n        ($state:ident $($tt:tt)*) => {\n            impl<'a, T, C> From<GdbStubStateMachineInner<'a, state::$state $($tt)*, T, C>>\n                for GdbStubStateMachine<'a, T, C>\n            where\n                T: Target,\n                C: Connection,\n            {\n                fn from(inner: GdbStubStateMachineInner<'a, state::$state $($tt)*, T, C>) -> Self {\n                    GdbStubStateMachine::$state(inner)\n                }\n            }\n        };\n    }\n\nimpl_from_inner!(Idle<T>);\nimpl_from_inner!(Running);\nimpl_from_inner!(CtrlCInterrupt);\nimpl_from_inner!(Disconnected);\n\n/// Internal helper trait to cut down on boilerplate required to transition\n/// between states.\ntrait Transition<'a, T, C>\nwhere\n    T: Target,\n    C: Connection,\n{\n    /// Transition between different state machine states\n    fn transition<S2>(self, state: S2) -> GdbStubStateMachineInner<'a, S2, T, C>;\n}\n\nimpl<'a, S1, T, C> Transition<'a, T, C> for GdbStubStateMachineInner<'a, S1, T, C>\nwhere\n    T: Target,\n    C: Connection,\n{\n    #[inline(always)]\n    fn transition<S2>(self, state: S2) -> GdbStubStateMachineInner<'a, S2, T, C> {\n        if log::log_enabled!(log::Level::Trace) {\n            let s1 = core::any::type_name::<S1>();\n            let s2 = core::any::type_name::<S2>();\n            log::trace!(\n                \"transition: {:?} --> {:?}\",\n                s1.strip_prefix(state::MODULE_PATH).unwrap_or(s1),\n                s2.strip_prefix(state::MODULE_PATH).unwrap_or(s2)\n            );\n        }\n        GdbStubStateMachineInner { i: self.i, state }\n    }\n}\n\n// split off `GdbStubStateMachineInner`'s non state-dependant data into separate\n// struct for code bloat optimization (i.e: `transition` will generate better\n// code when the struct is cleaved this way).\nstruct GdbStubStateMachineReallyInner<'a, T: Target, C: Connection> {\n    conn: C,\n    packet_buffer: ManagedSlice<'a, u8>,\n    recv_packet: RecvPacketStateMachine,\n    inner: GdbStubImpl<T, C>,\n}\n\n/// Core state machine implementation that is parameterized by various\n/// [states](state). Can be converted back into the appropriate\n/// [`GdbStubStateMachine`] variant via [`Into::into`].\npub struct GdbStubStateMachineInner<'a, S, T: Target, C: Connection> {\n    i: GdbStubStateMachineReallyInner<'a, T, C>,\n    state: S,\n}\n\n/// Methods which can be called regardless of the current state.\nimpl<S, T: Target, C: Connection> GdbStubStateMachineInner<'_, S, T, C> {\n    /// Return a mutable reference to the underlying connection.\n    pub fn borrow_conn(&mut self) -> &mut C {\n        &mut self.i.conn\n    }\n}\n\n/// Methods which can only be called from the [`GdbStubStateMachine::Idle`]\n/// state.\nimpl<'a, T: Target, C: Connection> GdbStubStateMachineInner<'a, state::Idle<T>, T, C> {\n    /// Internal entrypoint into the state machine.\n    pub(crate) fn from_plain_gdbstub(\n        stub: GdbStub<'a, T, C>,\n    ) -> GdbStubStateMachineInner<'a, state::Idle<T>, T, C> {\n        GdbStubStateMachineInner {\n            i: GdbStubStateMachineReallyInner {\n                conn: stub.conn,\n                packet_buffer: stub.packet_buffer,\n                recv_packet: RecvPacketStateMachine::new(),\n                inner: stub.inner,\n            },\n            state: state::Idle {\n                deferred_ctrlc_stop_reason: None,\n            },\n        }\n    }\n\n    /// Pass a byte to the GDB stub.\n    pub fn incoming_data(\n        mut self,\n        target: &mut T,\n        byte: u8,\n    ) -> Result<GdbStubStateMachine<'a, T, C>, GdbStubError<T::Error, C::Error>> {\n        let packet_buffer = match self.i.recv_packet.pump(&mut self.i.packet_buffer, byte)? {\n            Some(buf) => buf,\n            None => return Ok(self.into()),\n        };\n\n        let packet = Packet::from_buf(target, packet_buffer).map_err(InternalError::PacketParse)?;\n        let state = self\n            .i\n            .inner\n            .handle_packet(target, &mut self.i.conn, packet)?;\n        Ok(match state {\n            State::Pump => self.into(),\n            State::Disconnect(reason) => self.transition(state::Disconnected { reason }).into(),\n            State::DeferredStopReason => {\n                match self.state.deferred_ctrlc_stop_reason {\n                    // if we were interrupted while idle, immediately report the deferred stop\n                    // reason after transitioning into the running state\n                    Some(reason) => {\n                        return self\n                            .transition(state::Running {})\n                            .report_stop(target, reason)\n                    }\n                    // otherwise, just transition into the running state as usual\n                    None => self.transition(state::Running {}).into(),\n                }\n            }\n            State::CtrlCInterrupt => self\n                .transition(state::CtrlCInterrupt { from_idle: true })\n                .into(),\n        })\n    }\n}\n\n/// Methods which can only be called from the\n/// [`GdbStubStateMachine::Running`] state.\nimpl<'a, T: Target, C: Connection> GdbStubStateMachineInner<'a, state::Running, T, C> {\n    /// Report a target stop reason back to GDB.\n    pub fn report_stop(\n        self,\n        target: &mut T,\n        reason: impl IntoStopReason<T>,\n    ) -> Result<GdbStubStateMachine<'a, T, C>, GdbStubError<T::Error, C::Error>> {\n        self.report_stop_impl(target, reason, None)\n    }\n\n    /// Report a target stop reason back to GDB, including expedited register\n    /// values in the stop reply T-packet.\n    ///\n    /// **Note:** In order to use this method, the Target's [`Arch`]\n    /// implementation MUST implement a valid [`RegId::to_raw_id`]\n    /// implementation. If the method is unimplemented, `gdbstub` will report an\n    /// error.\n    ///\n    /// The iterator yields `(register_number, value_bytes)` pairs that are\n    /// written as expedited registers in the T-packet. Values should be in\n    /// target byte order (typically little-endian).\n    ///\n    /// This may be useful to use, rather than [`Self::report_stop`], when we\n    /// want to provide register values immediately to, for example, avoid a\n    /// round-trip, or work around a quirk/bug in a debugger that does not\n    /// otherwise request new register values.\n    ///\n    /// [`RegId::to_raw_id`]: crate::arch::RegId::to_raw_id\n    pub fn report_stop_with_regs(\n        self,\n        target: &mut T,\n        reason: impl IntoStopReason<T>,\n        // FUTURE: (breaking) explore adding a `RegIdWithVal` construct, in\n        // order to tighten up this typing even further?\n        regs: &mut dyn Iterator<Item = (<<T as Target>::Arch as Arch>::RegId, &[u8])>,\n    ) -> Result<GdbStubStateMachine<'a, T, C>, GdbStubError<T::Error, C::Error>> {\n        self.report_stop_impl(target, reason, Some(regs))\n    }\n\n    /// Shared implementation for the `report_stop`/`report_stop_with_regs` API.\n    /// Takes an `Option` around the `&mut dyn Iterator` to avoid making a\n    /// dynamic vtable dispatch in the common `report_stop` case.\n    fn report_stop_impl(\n        mut self,\n        target: &mut T,\n        reason: impl IntoStopReason<T>,\n        regs: Option<&mut dyn Iterator<Item = (<<T as Target>::Arch as Arch>::RegId, &[u8])>>,\n    ) -> Result<GdbStubStateMachine<'a, T, C>, GdbStubError<T::Error, C::Error>> {\n        let reason: BaseStopReason<_, _> = reason.into();\n        let mut res = ResponseWriter::new(&mut self.i.conn, target.use_rle());\n        let event = self.i.inner.finish_exec(&mut res, target, reason)?;\n\n        if let Some(regs) = regs {\n            if reason.is_t_packet() {\n                for (reg_id, value) in regs {\n                    let reg = reg_id.to_raw_id().ok_or(InternalError::MissingToRawId)?;\n                    res.write_num(reg).map_err(InternalError::from)?;\n                    res.write_str(\":\").map_err(InternalError::from)?;\n                    res.write_hex_buf(value).map_err(InternalError::from)?;\n                    res.write_str(\";\").map_err(InternalError::from)?;\n                }\n            }\n        }\n\n        res.flush().map_err(InternalError::from)?;\n\n        Ok(match event {\n            FinishExecStatus::Handled => self\n                .transition(state::Idle {\n                    deferred_ctrlc_stop_reason: None,\n                })\n                .into(),\n            FinishExecStatus::Disconnect(reason) => {\n                self.transition(state::Disconnected { reason }).into()\n            }\n        })\n    }\n\n    /// Pass a byte to the GDB stub.\n    pub fn incoming_data(\n        mut self,\n        target: &mut T,\n        byte: u8,\n    ) -> Result<GdbStubStateMachine<'a, T, C>, GdbStubError<T::Error, C::Error>> {\n        let packet_buffer = match self.i.recv_packet.pump(&mut self.i.packet_buffer, byte)? {\n            Some(buf) => buf,\n            None => return Ok(self.into()),\n        };\n\n        let packet = Packet::from_buf(target, packet_buffer).map_err(InternalError::PacketParse)?;\n        let state = self\n            .i\n            .inner\n            .handle_packet(target, &mut self.i.conn, packet)?;\n        Ok(match state {\n            State::Pump => self.transition(state::Running {}).into(),\n            State::Disconnect(reason) => self.transition(state::Disconnected { reason }).into(),\n            State::DeferredStopReason => self.transition(state::Running {}).into(),\n            State::CtrlCInterrupt => self\n                .transition(state::CtrlCInterrupt { from_idle: false })\n                .into(),\n        })\n    }\n}\n\n/// Methods which can only be called from the\n/// [`GdbStubStateMachine::CtrlCInterrupt`] state.\nimpl<'a, T: Target, C: Connection> GdbStubStateMachineInner<'a, state::CtrlCInterrupt, T, C> {\n    /// Acknowledge the Ctrl-C interrupt.\n    ///\n    /// Passing `None` as a stop reason will return the state machine to\n    /// whatever state it was in pre-interruption, without immediately returning\n    /// a stop reason.\n    ///\n    /// Depending on how the target is implemented, it may or may not make sense\n    /// to immediately return a stop reason as part of handling the Ctrl-C\n    /// interrupt. e.g: in some cases, it may be better to send the target a\n    /// signal upon receiving a Ctrl-C interrupt _without_ immediately sending a\n    /// stop reason, and instead deferring the stop reason to some later point\n    /// in the target's execution.\n    ///\n    /// Some notes on handling Ctrl-C interrupts:\n    ///\n    /// - Stubs are not required to recognize these interrupt mechanisms, and\n    ///   the precise meaning associated with receipt of the interrupt is\n    ///   implementation defined.\n    /// - If the target supports debugging of multiple threads and/or processes,\n    ///   it should attempt to interrupt all currently-executing threads and\n    ///   processes.\n    /// - If the stub is successful at interrupting the running program, it\n    ///   should send one of the stop reply packets (see Stop Reply Packets) to\n    ///   GDB as a result of successfully stopping the program\n    pub fn interrupt_handled(\n        self,\n        target: &mut T,\n        stop_reason: Option<impl IntoStopReason<T>>,\n    ) -> Result<GdbStubStateMachine<'a, T, C>, GdbStubError<T::Error, C::Error>> {\n        if self.state.from_idle {\n            // target is stopped - we cannot report the stop reason yet\n            Ok(self\n                .transition(state::Idle {\n                    deferred_ctrlc_stop_reason: stop_reason.map(Into::into),\n                })\n                .into())\n        } else {\n            // target is running - we can immediately report the stop reason\n            let gdb = self.transition(state::Running {});\n            match stop_reason {\n                Some(reason) => gdb.report_stop(target, reason),\n                None => Ok(gdb.into()),\n            }\n        }\n    }\n}\n\n/// Methods which can only be called from the\n/// [`GdbStubStateMachine::Disconnected`] state.\nimpl<'a, T: Target, C: Connection> GdbStubStateMachineInner<'a, state::Disconnected, T, C> {\n    /// Inspect why the GDB client disconnected.\n    pub fn get_reason(&self) -> DisconnectReason {\n        self.state.reason\n    }\n\n    /// Reuse the existing state machine instance, reentering the idle loop.\n    pub fn return_to_idle(self) -> GdbStubStateMachine<'a, T, C> {\n        self.transition(state::Idle {\n            deferred_ctrlc_stop_reason: None,\n        })\n        .into()\n    }\n}\n"
  },
  {
    "path": "src/stub/stop_reason.rs",
    "content": "//! Stop reasons reported back to the GDB client.\n\nuse crate::arch::Arch;\nuse crate::common::Signal;\nuse crate::common::Tid;\nuse crate::target::ext::base::reverse_exec::ReplayLogPosition;\nuse crate::target::ext::breakpoints::WatchKind;\nuse crate::target::ext::catch_syscalls::CatchSyscallPosition;\nuse crate::target::Target;\n\n/// Describes why a thread stopped.\n///\n/// Single threaded targets should set `Tid` to `()`, whereas multi threaded\n/// targets should set `Tid` to [`Tid`]. To make things easier, it is\n/// recommended to use the [`SingleThreadStopReason`] and\n/// [`MultiThreadStopReason`] when possible.\n///\n///\n///\n/// Targets MUST only respond with stop reasons that correspond to IDETs that\n/// target has implemented. Not doing so will result in a runtime error.\n///\n/// e.g: A target which has not implemented the [`HwBreakpoint`] IDET must not\n/// return a `HwBreak` stop reason. While this is not enforced at compile time,\n/// doing so will result in a runtime `UnsupportedStopReason` error.\n///\n/// [`HwBreakpoint`]: crate::target::ext::breakpoints::HwBreakpoint\n#[derive(Clone, Copy, Debug, PartialEq, Eq)]\n#[non_exhaustive]\npub enum BaseStopReason<Tid, U> {\n    /// Completed the single-step request.\n    DoneStep,\n    /// The process exited with the specified exit status.\n    Exited(u8),\n    /// The process terminated with the specified signal number.\n    Terminated(Signal),\n    /// The program received a signal.\n    Signal(Signal),\n    /// A specific thread received a signal.\n    SignalWithThread {\n        /// Tid of the associated thread\n        tid: Tid,\n        /// The signal\n        signal: Signal,\n    },\n    /// A thread hit a software breakpoint (e.g. due to a trap instruction).\n    ///\n    /// Requires: [`SwBreakpoint`].\n    ///\n    /// NOTE: This does not necessarily have to be a breakpoint configured by\n    /// the client/user of the current GDB session.\n    ///\n    /// [`SwBreakpoint`]: crate::target::ext::breakpoints::SwBreakpoint\n    SwBreak(Tid),\n    /// A thread hit a hardware breakpoint.\n    ///\n    /// Requires: [`HwBreakpoint`].\n    ///\n    /// [`HwBreakpoint`]: crate::target::ext::breakpoints::HwBreakpoint\n    HwBreak(Tid),\n    /// A thread hit a watchpoint.\n    ///\n    /// Requires: [`HwWatchpoint`].\n    ///\n    /// [`HwWatchpoint`]: crate::target::ext::breakpoints::HwWatchpoint\n    Watch {\n        /// Tid of the associated thread\n        tid: Tid,\n        /// Kind of watchpoint that was hit\n        kind: WatchKind,\n        /// Address of watched memory\n        addr: U,\n    },\n    /// The program has reached the end of the logged replay events.\n    ///\n    /// Requires: [`ReverseCont`] or [`ReverseStep`].\n    ///\n    /// This is used for GDB's reverse execution. When playing back a recording,\n    /// you may hit the end of the buffer of recorded events, and as such no\n    /// further execution can be done. This stop reason tells GDB that this has\n    /// occurred.\n    ///\n    /// [`ReverseCont`]: crate::target::ext::base::reverse_exec::ReverseCont\n    /// [`ReverseStep`]: crate::target::ext::base::reverse_exec::ReverseStep\n    ReplayLog {\n        /// (optional) Tid of the associated thread.\n        tid: Option<Tid>,\n        /// The point reached in a replay log (i.e: beginning vs. end).\n        pos: ReplayLogPosition,\n    },\n    /// The program has reached a syscall entry or return location.\n    ///\n    /// Requires: [`CatchSyscalls`].\n    ///\n    /// [`CatchSyscalls`]: crate::target::ext::catch_syscalls::CatchSyscalls\n    CatchSyscall {\n        /// (optional) Tid of the associated thread.\n        tid: Option<Tid>,\n        /// The syscall number.\n        number: U,\n        /// The location the event occurred at.\n        position: CatchSyscallPosition,\n    },\n    /// A thread hit a specific library event.\n    ///\n    /// This stop reason indicates that loaded libraries have changed. The\n    /// debugger should fetch a new list of loaded libraries.\n    Library(Tid),\n    /// A thread created a new process via fork.\n    ///\n    /// This indicates that a fork system call was executed, creating a new\n    /// child process.\n    Fork {\n        /// Tid of the thread that called fork\n        cur_tid: Tid,\n        /// Tid of the new child process\n        new_tid: core::num::NonZeroUsize,\n    },\n    /// A thread created a new process via vfork.\n    ///\n    /// Similar to Fork, but the parent process is suspended until the child\n    /// calls exec or exits, as the parent and child temporarily share the\n    /// same address space.\n    VFork {\n        /// Tid of the thread that called vfork\n        cur_tid: Tid,\n        /// Tid of the new child process\n        new_tid: core::num::NonZeroUsize,\n    },\n    /// A vfork child process has completed its operation.\n    ///\n    /// This indicates that a child process created by vfork has either called\n    /// exec or terminated, so the address spaces of parent and child are no\n    /// longer shared.\n    VForkDone(Tid),\n}\n\nimpl<Tid, U> BaseStopReason<Tid, U> {\n    /// Does this stop reason respond with a `T` packet?\n    pub(crate) fn is_t_packet(&self) -> bool {\n        match self {\n            Self::SignalWithThread { .. }\n            | Self::SwBreak(_)\n            | Self::HwBreak(_)\n            | Self::Watch { .. }\n            | Self::ReplayLog { .. }\n            | Self::CatchSyscall { .. }\n            | Self::Library(_)\n            | Self::Fork { .. }\n            | Self::VFork { .. }\n            | Self::VForkDone(_) => true,\n            Self::DoneStep | Self::Signal(_) | Self::Exited(_) | Self::Terminated(_) => false,\n        }\n    }\n}\n\n/// A stop reason for a single threaded target.\n///\n/// Threads are identified using the unit type `()` (as there is only a single\n/// possible thread-id).\npub type SingleThreadStopReason<U> = BaseStopReason<(), U>;\n\n/// A stop reason for a multi threaded target.\n///\n/// Threads are identified using a [`Tid`].\npub type MultiThreadStopReason<U> = BaseStopReason<Tid, U>;\n\nimpl<U> From<BaseStopReason<(), U>> for BaseStopReason<Tid, U> {\n    fn from(st_stop_reason: BaseStopReason<(), U>) -> BaseStopReason<Tid, U> {\n        match st_stop_reason {\n            BaseStopReason::DoneStep => BaseStopReason::DoneStep,\n            BaseStopReason::Exited(code) => BaseStopReason::Exited(code),\n            BaseStopReason::Terminated(sig) => BaseStopReason::Terminated(sig),\n            BaseStopReason::SignalWithThread { signal, .. } => BaseStopReason::SignalWithThread {\n                tid: crate::SINGLE_THREAD_TID,\n                signal,\n            },\n            BaseStopReason::SwBreak(_) => BaseStopReason::SwBreak(crate::SINGLE_THREAD_TID),\n            BaseStopReason::HwBreak(_) => BaseStopReason::HwBreak(crate::SINGLE_THREAD_TID),\n            BaseStopReason::Watch { kind, addr, .. } => BaseStopReason::Watch {\n                tid: crate::SINGLE_THREAD_TID,\n                kind,\n                addr,\n            },\n            BaseStopReason::Signal(sig) => BaseStopReason::Signal(sig),\n            BaseStopReason::ReplayLog { pos, .. } => BaseStopReason::ReplayLog { tid: None, pos },\n            BaseStopReason::CatchSyscall {\n                number, position, ..\n            } => BaseStopReason::CatchSyscall {\n                tid: None,\n                number,\n                position,\n            },\n            BaseStopReason::Library(_) => BaseStopReason::Library(crate::SINGLE_THREAD_TID),\n            BaseStopReason::Fork { new_tid, .. } => BaseStopReason::Fork {\n                cur_tid: crate::SINGLE_THREAD_TID,\n                new_tid,\n            },\n            BaseStopReason::VFork { new_tid, .. } => BaseStopReason::VFork {\n                cur_tid: crate::SINGLE_THREAD_TID,\n                new_tid,\n            },\n            BaseStopReason::VForkDone(_) => BaseStopReason::VForkDone(crate::SINGLE_THREAD_TID),\n        }\n    }\n}\n\nmod private {\n    pub trait Sealed {}\n\n    impl<U> Sealed for super::SingleThreadStopReason<U> {}\n    impl<U> Sealed for super::MultiThreadStopReason<U> {}\n}\n\n/// A marker trait implemented by [`SingleThreadStopReason`] and\n/// [`MultiThreadStopReason`].\npub trait IntoStopReason<T: Target>:\n    private::Sealed + Into<MultiThreadStopReason<<<T as Target>::Arch as Arch>::Usize>>\n{\n}\n\nimpl<T: Target> IntoStopReason<T> for SingleThreadStopReason<<<T as Target>::Arch as Arch>::Usize> {}\nimpl<T: Target> IntoStopReason<T> for MultiThreadStopReason<<<T as Target>::Arch as Arch>::Usize> {}\n"
  },
  {
    "path": "src/target/ext/auxv.rs",
    "content": "//! Access the target’s auxiliary vector.\nuse crate::target::Target;\nuse crate::target::TargetResult;\n\n/// Target Extension - Access the target’s auxiliary vector.\npub trait Auxv: Target {\n    /// Get auxiliary vector from the target.\n    ///\n    /// Return the number of bytes written into `buf` (which may be less than\n    /// `length`).\n    ///\n    /// If `offset` is greater than the length of the underlying data, return\n    /// `Ok(0)`.\n    fn get_auxv(&self, offset: u64, length: usize, buf: &mut [u8]) -> TargetResult<usize, Self>;\n}\n\ndefine_ext!(AuxvOps, Auxv);\n"
  },
  {
    "path": "src/target/ext/base/mod.rs",
    "content": "//! Base operations required to debug most targets (e.g: read/write\n//! memory/registers, step/resume, etc...)\n//!\n//! It is **highly recommended** that single threaded targets implement the\n//! simplified `singlethread` API, as `gdbstub` includes optimized\n//! implementations of certain internal routines when operating in single\n//! threaded mode.\n\nuse crate::arch::Arch;\n\npub mod multithread;\npub mod reverse_exec;\npub mod single_register_access;\npub mod singlethread;\n\n/// Base required operations for single/multi threaded targets.\npub enum BaseOps<'a, A, E> {\n    /// Single-threaded target\n    SingleThread(&'a mut dyn singlethread::SingleThreadBase<Arch = A, Error = E>),\n    /// Multi-threaded target\n    MultiThread(&'a mut dyn multithread::MultiThreadBase<Arch = A, Error = E>),\n}\n\npub(crate) enum ResumeOps<'a, A, E> {\n    /// Single-threaded target\n    SingleThread(&'a mut dyn singlethread::SingleThreadResume<Arch = A, Error = E>),\n    /// Multi-threaded target\n    MultiThread(&'a mut dyn multithread::MultiThreadResume<Arch = A, Error = E>),\n}\n\nimpl<'a, A: Arch, E> BaseOps<'a, A, E> {\n    #[inline(always)]\n    pub(crate) fn resume_ops(self) -> Option<ResumeOps<'a, A, E>> {\n        let ret = match self {\n            BaseOps::SingleThread(ops) => ResumeOps::SingleThread(ops.support_resume()?),\n            BaseOps::MultiThread(ops) => ResumeOps::MultiThread(ops.support_resume()?),\n        };\n        Some(ret)\n    }\n}\n"
  },
  {
    "path": "src/target/ext/base/multithread.rs",
    "content": "//! Base debugging operations for multi threaded targets.\n\nuse crate::arch::Arch;\nuse crate::common::Signal;\nuse crate::common::Tid;\nuse crate::target::Target;\nuse crate::target::TargetResult;\n\n/// Base required debugging operations for multi threaded targets.\npub trait MultiThreadBase: Target {\n    /// Read the target's registers.\n    ///\n    /// If the registers could not be accessed, an appropriate non-fatal error\n    /// should be returned.\n    fn read_registers(\n        &mut self,\n        regs: &mut <Self::Arch as Arch>::Registers,\n        tid: Tid,\n    ) -> TargetResult<(), Self>;\n\n    /// Write the target's registers.\n    ///\n    /// If the registers could not be accessed, an appropriate non-fatal error\n    /// should be returned.\n    fn write_registers(\n        &mut self,\n        regs: &<Self::Arch as Arch>::Registers,\n        tid: Tid,\n    ) -> TargetResult<(), Self>;\n\n    /// Support for single-register access.\n    /// See [`SingleRegisterAccess`] for more details.\n    ///\n    /// While this is an optional feature, it is **highly recommended** to\n    /// implement it when possible, as it can significantly improve performance\n    /// on certain architectures.\n    ///\n    /// [`SingleRegisterAccess`]:\n    /// super::single_register_access::SingleRegisterAccess\n    #[inline(always)]\n    fn support_single_register_access(\n        &mut self,\n    ) -> Option<super::single_register_access::SingleRegisterAccessOps<'_, Tid, Self>> {\n        None\n    }\n\n    /// Read bytes from the specified address range and return the number of\n    /// bytes that were read.\n    ///\n    /// Implementations may return a number `n` that is less than `data.len()`\n    /// to indicate that memory starting at `start_addr + n` cannot be\n    /// accessed.\n    ///\n    /// Implemenations may also return an appropriate non-fatal error if the\n    /// requested address range could not be accessed (e.g: due to MMU\n    /// protection, unhanded page fault, etc...).\n    ///\n    /// Implementations must guarantee that the returned number is less than or\n    /// equal `data.len()`.\n    fn read_addrs(\n        &mut self,\n        start_addr: <Self::Arch as Arch>::Usize,\n        data: &mut [u8],\n        tid: Tid,\n    ) -> TargetResult<usize, Self>;\n\n    /// Write bytes to the specified address range.\n    ///\n    /// If the requested address range could not be accessed (e.g: due to\n    /// MMU protection, unhanded page fault, etc...), an appropriate non-fatal\n    /// error should be returned.\n    fn write_addrs(\n        &mut self,\n        start_addr: <Self::Arch as Arch>::Usize,\n        data: &[u8],\n        tid: Tid,\n    ) -> TargetResult<(), Self>;\n\n    /// List all currently active threads.\n    ///\n    /// See [the section above](#bare-metal-targets) on implementing\n    /// thread-related methods on bare-metal (threadless) targets.\n    ///\n    /// _Note_: Implementors should mark this method as `#[inline(always)]`, as\n    /// this will result in better codegen (namely, by sidestepping any of the\n    /// `dyn FnMut` closure machinery).\n    fn list_active_threads(\n        &mut self,\n        thread_is_active: &mut dyn FnMut(Tid),\n    ) -> Result<(), Self::Error>;\n\n    /// Check if the specified thread is alive.\n    ///\n    /// As a convenience, this method provides a default implementation which\n    /// uses `list_active_threads` to do a linear-search through all active\n    /// threads. On thread-heavy systems, it may be more efficient\n    /// to override this method with a more direct query.\n    #[allow(clippy::wrong_self_convention)] // requires breaking change to fix\n    fn is_thread_alive(&mut self, tid: Tid) -> Result<bool, Self::Error> {\n        let mut found = false;\n        self.list_active_threads(&mut |active_tid| {\n            if tid == active_tid {\n                found = true;\n            }\n        })?;\n        Ok(found)\n    }\n\n    /// Support for resuming the target (e.g: via `continue` or `step`)\n    #[inline(always)]\n    fn support_resume(&mut self) -> Option<MultiThreadResumeOps<'_, Self>> {\n        None\n    }\n\n    /// Support for providing thread extra information.\n    #[inline(always)]\n    fn support_thread_extra_info(\n        &mut self,\n    ) -> Option<crate::target::ext::thread_extra_info::ThreadExtraInfoOps<'_, Self>> {\n        None\n    }\n}\n\n/// Target extension - support for resuming multi threaded targets.\npub trait MultiThreadResume: Target {\n    /// Resume execution on the target.\n    ///\n    /// Prior to calling `resume`, `gdbstub` will call `clear_resume_actions`,\n    /// followed by zero or more calls to the `set_resume_action_XXX` methods,\n    /// specifying any thread-specific resume actions.\n    ///\n    /// Upon returning from the `resume` method, the target being debugged\n    /// should be configured to run according to whatever resume actions the\n    /// GDB client had specified using any of the `set_resume_action_XXX`\n    /// methods.\n    ///\n    /// # Default Resume Behavior\n    ///\n    /// By default, any thread that wasn't explicitly resumed by a\n    /// `set_resume_action_XXX` method should be resumed as though it was\n    /// resumed with `set_resume_action_continue`.\n    ///\n    /// **However**, if [`support_scheduler_locking`] is implemented and\n    /// [`set_resume_action_scheduler_lock`] has been called for the current\n    /// resume cycle, this default changes: **unmentioned threads must remain\n    /// stopped.**\n    ///\n    /// [`support_scheduler_locking`]: Self::support_scheduler_locking\n    /// [`set_resume_action_scheduler_lock`]: MultiThreadSchedulerLocking::set_resume_action_scheduler_lock\n    ///\n    /// # Protocol Extensions\n    ///\n    /// A basic target implementation only needs to implement support for\n    /// `set_resume_action_continue`, with all other resume actions requiring\n    /// their corresponding protocol extension to be implemented:\n    ///\n    /// Action                      | Protocol Extension\n    /// ----------------------------|------------------------------\n    /// Optimized [Single Stepping] | See [`support_single_step()`]\n    /// Optimized [Range Stepping]  | See [`support_range_step()`]\n    /// [Scheduler Locking]         | See [`support_scheduler_locking()`]\n    /// \"Stop\"                      | Used in \"Non-Stop\" mode \\*\n    ///\n    /// \\* \"Non-Stop\" mode is currently unimplemented in `gdbstub`\n    ///\n    /// [Single stepping]: https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#index-stepi\n    /// [Range Stepping]: https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#range-stepping\n    /// [Scheduler Locking]: https://sourceware.org/gdb/current/onlinedocs/gdb#index-scheduler-locking-mode\n    /// [`support_single_step()`]: Self::support_single_step\n    /// [`support_range_step()`]: Self::support_range_step\n    /// [`support_scheduler_locking()`]: Self::support_scheduler_locking\n    ///\n    /// # Additional Considerations\n    ///\n    /// ### Adjusting PC after a breakpoint is hit\n    ///\n    /// The [GDB remote serial protocol documentation](https://sourceware.org/gdb/current/onlinedocs/gdb/Stop-Reply-Packets.html#swbreak-stop-reason)\n    /// notes the following:\n    ///\n    /// > On some architectures, such as x86, at the architecture level, when a\n    /// > breakpoint instruction executes the program counter points at the\n    /// > breakpoint address plus an offset. On such targets, the stub is\n    /// > responsible for adjusting the PC to point back at the breakpoint\n    /// > address.\n    ///\n    /// Omitting PC adjustment may result in unexpected execution flow and/or\n    /// breakpoints not appearing to work correctly.\n    ///\n    /// ### Bare-Metal Targets\n    ///\n    /// On bare-metal targets (such as microcontrollers or emulators), it's\n    /// common to treat individual _CPU cores_ as a separate \"threads\". e.g:\n    /// in a dual-core system, [CPU0, CPU1] might be mapped to [TID1, TID2]\n    /// (note that TIDs cannot be zero).\n    ///\n    /// In this case, the `Tid` argument of `read/write_addrs` becomes quite\n    /// relevant, as different cores may have different memory maps.\n    fn resume(&mut self) -> Result<(), Self::Error>;\n\n    /// Clear all previously set resume actions.\n    fn clear_resume_actions(&mut self) -> Result<(), Self::Error>;\n\n    /// Continue the specified thread.\n    ///\n    /// See the [`resume`](Self::resume) docs for information on when this is\n    /// called.\n    ///\n    /// The GDB client may also include a `signal` which should be passed to the\n    /// target.\n    fn set_resume_action_continue(\n        &mut self,\n        tid: Tid,\n        signal: Option<Signal>,\n    ) -> Result<(), Self::Error>;\n\n    /// Support for optimized [single stepping].\n    ///\n    /// [single stepping]: https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#index-stepi\n    #[inline(always)]\n    fn support_single_step(&mut self) -> Option<MultiThreadSingleStepOps<'_, Self>> {\n        None\n    }\n\n    /// Support for optimized [range stepping].\n    ///\n    /// [range stepping]: https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#range-stepping\n    #[inline(always)]\n    fn support_range_step(&mut self) -> Option<MultiThreadRangeSteppingOps<'_, Self>> {\n        None\n    }\n\n    /// Support for [reverse stepping] a target.\n    ///\n    /// [reverse stepping]: https://sourceware.org/gdb/current/onlinedocs/gdb/Reverse-Execution.html\n    #[inline(always)]\n    fn support_reverse_step(\n        &mut self,\n    ) -> Option<super::reverse_exec::ReverseStepOps<'_, Tid, Self>> {\n        None\n    }\n\n    /// Support for [reverse continuing] a target.\n    ///\n    /// [reverse continuing]: https://sourceware.org/gdb/current/onlinedocs/gdb/Reverse-Execution.html\n    #[inline(always)]\n    fn support_reverse_cont(\n        &mut self,\n    ) -> Option<super::reverse_exec::ReverseContOps<'_, Tid, Self>> {\n        None\n    }\n\n    /// Support for [scheduler locking].\n    ///\n    /// [scheduler locking]: https://sourceware.org/gdb/current/onlinedocs/gdb#index-scheduler-locking-mode\n    #[inline(always)]\n    fn support_scheduler_locking(&mut self) -> Option<MultiThreadSchedulerLockingOps<'_, Self>> {\n        None\n    }\n}\n\ndefine_ext!(MultiThreadResumeOps, MultiThreadResume);\n\n/// Target Extension - Optimized single stepping for multi threaded targets.\n/// See [`MultiThreadResume::support_single_step`].\npub trait MultiThreadSingleStep: Target + MultiThreadResume {\n    /// [Single step] the specified target thread.\n    ///\n    /// Single stepping will step the target a single \"step\" - typically a\n    /// single instruction.\n    ///\n    /// The GDB client may also include a `signal` which should be passed to the\n    /// target.\n    ///\n    /// If your target does not support signals (e.g: the target is a bare-metal\n    /// microcontroller / emulator), the recommended behavior is to return a\n    /// target-specific fatal error\n    ///\n    /// [Single step]: https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#index-stepi\n    fn set_resume_action_step(\n        &mut self,\n        tid: Tid,\n        signal: Option<Signal>,\n    ) -> Result<(), Self::Error>;\n}\n\ndefine_ext!(MultiThreadSingleStepOps, MultiThreadSingleStep);\n\n/// Target Extension - Optimized range stepping for multi threaded targets.\n/// See [`MultiThreadResume::support_range_step`].\npub trait MultiThreadRangeStepping: Target + MultiThreadResume {\n    /// [Range step] the specified target thread.\n    ///\n    /// Range Stepping will step the target once, and keep stepping the target\n    /// as long as execution remains between the specified start (inclusive)\n    /// and end (exclusive) addresses, or another stop condition is met\n    /// (e.g: a breakpoint it hit).\n    ///\n    /// If the range is empty (`start` == `end`), then the action becomes\n    /// equivalent to the ‘s’ action. In other words, single-step once, and\n    /// report the stop (even if the stepped instruction jumps to start).\n    ///\n    /// _Note:_ A stop reply may be sent at any point even if the PC is still\n    /// within the stepping range; for example, it is valid to implement range\n    /// stepping in a degenerate way as a single instruction step operation.\n    ///\n    /// [Range step]: https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#range-stepping\n    fn set_resume_action_range_step(\n        &mut self,\n        tid: Tid,\n        start: <Self::Arch as Arch>::Usize,\n        end: <Self::Arch as Arch>::Usize,\n    ) -> Result<(), Self::Error>;\n}\n\ndefine_ext!(MultiThreadRangeSteppingOps, MultiThreadRangeStepping);\n\n/// Target Extension - support for GDB's \"Scheduler Locking\" mode.\n/// See [`MultiThreadResume::support_scheduler_locking`].\npub trait MultiThreadSchedulerLocking: Target + MultiThreadResume {\n    /// Configure the target to enable \"Scheduler Locking\" for the upcoming\n    /// resume.\n    ///\n    /// This method is invoked when the GDB client expects only a specific set\n    /// of threads to run, while all other threads remain frozen. This behavior\n    /// is typically toggled in GDB using the `set scheduler-locking on`\n    /// command.\n    ///\n    /// When this method is called, the implementation must ensure that any\n    /// threads not explicitly resumed via previous `set_resume_action_...`\n    /// calls **remain stopped**.\n    ///\n    /// This prevents any \"implicit continue\" behavior for unmentioned threads,\n    /// satisfying GDB's expectation that only the designated threads will\n    /// advance during the next resume.\n    fn set_resume_action_scheduler_lock(&mut self) -> Result<(), Self::Error>;\n}\n\ndefine_ext!(MultiThreadSchedulerLockingOps, MultiThreadSchedulerLocking);\n"
  },
  {
    "path": "src/target/ext/base/reverse_exec.rs",
    "content": "//! Support for reverse debugging targets.\n\nuse crate::target::Target;\n\n/// Target Extension - Reverse continue for targets.\npub trait ReverseCont<Tid>: Target\nwhere\n    Tid: crate::is_valid_tid::IsValidTid,\n{\n    /// [Reverse continue] the target.\n    ///\n    /// Reverse continue allows the target to run backwards until it reaches the\n    /// end of the replay log.\n    ///\n    /// [Reverse continue]: https://sourceware.org/gdb/current/onlinedocs/gdb/Reverse-Execution.html\n    fn reverse_cont(&mut self) -> Result<(), Self::Error>;\n}\n\n/// See [`ReverseCont`]\npub type ReverseContOps<'a, Tid, T> =\n    &'a mut dyn ReverseCont<Tid, Arch = <T as Target>::Arch, Error = <T as Target>::Error>;\n\n/// Target Extension - Reverse stepping for targets.\npub trait ReverseStep<Tid>: Target\nwhere\n    Tid: crate::is_valid_tid::IsValidTid,\n{\n    /// [Reverse step] the specified `Tid`.\n    ///\n    /// On single threaded targets, `tid` is set to `()` and can be ignored.\n    ///\n    /// Reverse stepping allows the target to run backwards by one \"step\" -\n    /// typically a single instruction.\n    ///\n    /// [Reverse step]: https://sourceware.org/gdb/current/onlinedocs/gdb/Reverse-Execution.html\n    fn reverse_step(&mut self, tid: Tid) -> Result<(), Self::Error>;\n}\n\n/// See [`ReverseStep`]\npub type ReverseStepOps<'a, Tid, T> =\n    &'a mut dyn ReverseStep<Tid, Arch = <T as Target>::Arch, Error = <T as Target>::Error>;\n\n/// Describes the point reached in a replay log (used alongside\n/// [`BaseStopReason::ReplayLog`](crate::stub::BaseStopReason::ReplayLog))\n#[derive(Clone, Copy, Debug, PartialEq, Eq)]\npub enum ReplayLogPosition {\n    /// Reached the beginning of the replay log.\n    Begin,\n    /// Reached the end of the replay log.\n    End,\n}\n"
  },
  {
    "path": "src/target/ext/base/single_register_access.rs",
    "content": "//! Support for single-register read/write access.\n\nuse crate::arch::Arch;\nuse crate::target::Target;\nuse crate::target::TargetResult;\n\n/// Target Extension - Support for single-register access.\n///\n/// While this is an optional feature, it is **highly recommended** to\n/// implement it when possible, as it can significantly improve performance\n/// on certain architectures.\n///\n/// If this extension is not implemented, the GDB client will fall-back to\n/// accessing _all_ registers, even in cases where it only requires knowing a\n/// single register's value.\n///\n/// Moreover, certain architectures have registers that are not accessible as\n/// part of the default default register file used by the `read/write_registers`\n/// methods, and can only be accessed via this extension (e.g: the RISC-V\n/// Control and Status registers).\npub trait SingleRegisterAccess<Tid>: Target\nwhere\n    Tid: crate::is_valid_tid::IsValidTid,\n{\n    /// Read to a single register on the target.\n    ///\n    /// The `tid` field identifies which thread the value should be read from.\n    /// On single threaded targets, `tid` is set to `()` and can be ignored.\n    ///\n    /// Implementations should write the value of the register using target's\n    /// native byte order in the buffer `buf`.\n    ///\n    /// Return the number of bytes written into `buf` or `0` if the register is\n    /// valid but unavailable.\n    ///\n    /// If the requested register could not be accessed, an appropriate\n    /// non-fatal error should be returned.\n    fn read_register(\n        &mut self,\n        tid: Tid,\n        reg_id: <Self::Arch as Arch>::RegId,\n        buf: &mut [u8],\n    ) -> TargetResult<usize, Self>;\n\n    /// Write from a single register on the target.\n    ///\n    /// The `tid` field identifies which thread the value should be written to.\n    /// On single threaded targets, `tid` is set to `()` and can be ignored.\n    ///\n    /// The `val` buffer contains the new value of the register in the target's\n    /// native byte order. It is guaranteed to be the exact length as the target\n    /// register.\n    ///\n    /// If the requested register could not be accessed, an appropriate\n    /// non-fatal error should be returned.\n    fn write_register(\n        &mut self,\n        tid: Tid,\n        reg_id: <Self::Arch as Arch>::RegId,\n        val: &[u8],\n    ) -> TargetResult<(), Self>;\n}\n\n/// See [`SingleRegisterAccess`]\npub type SingleRegisterAccessOps<'a, Tid, T> =\n    &'a mut dyn SingleRegisterAccess<Tid, Arch = <T as Target>::Arch, Error = <T as Target>::Error>;\n"
  },
  {
    "path": "src/target/ext/base/singlethread.rs",
    "content": "//! Base debugging operations for single threaded targets.\n\nuse crate::arch::Arch;\nuse crate::common::Signal;\nuse crate::target::Target;\nuse crate::target::TargetResult;\n\n/// Base required debugging operations for single threaded targets.\npub trait SingleThreadBase: Target {\n    /// Read the target's registers.\n    fn read_registers(\n        &mut self,\n        regs: &mut <Self::Arch as Arch>::Registers,\n    ) -> TargetResult<(), Self>;\n\n    /// Write the target's registers.\n    fn write_registers(&mut self, regs: &<Self::Arch as Arch>::Registers)\n        -> TargetResult<(), Self>;\n\n    /// Support for single-register access.\n    /// See [`SingleRegisterAccess`] for more details.\n    ///\n    /// While this is an optional feature, it is **highly recommended** to\n    /// implement it when possible, as it can significantly improve performance\n    /// on certain architectures.\n    ///\n    /// [`SingleRegisterAccess`]:\n    /// super::single_register_access::SingleRegisterAccess\n    #[inline(always)]\n    fn support_single_register_access(\n        &mut self,\n    ) -> Option<super::single_register_access::SingleRegisterAccessOps<'_, (), Self>> {\n        None\n    }\n\n    /// Read bytes from the specified address range and return the number of\n    /// bytes that were read.\n    ///\n    /// Implementations may return a number `n` that is less than `data.len()`\n    /// to indicate that memory starting at `start_addr + n` cannot be\n    /// accessed.\n    ///\n    /// Implemenations may also return an appropriate non-fatal error if the\n    /// requested address range could not be accessed (e.g: due to MMU\n    /// protection, unhanded page fault, etc...).\n    ///\n    /// Implementations must guarantee that the returned number is less than or\n    /// equal `data.len()`.\n    fn read_addrs(\n        &mut self,\n        start_addr: <Self::Arch as Arch>::Usize,\n        data: &mut [u8],\n    ) -> TargetResult<usize, Self>;\n\n    /// Write bytes to the specified address range.\n    ///\n    /// If the requested address range could not be accessed (e.g: due to\n    /// MMU protection, unhanded page fault, etc...), an appropriate\n    /// non-fatal error should be returned.\n    fn write_addrs(\n        &mut self,\n        start_addr: <Self::Arch as Arch>::Usize,\n        data: &[u8],\n    ) -> TargetResult<(), Self>;\n\n    /// Support for resuming the target (e.g: via `continue` or `step`)\n    #[inline(always)]\n    fn support_resume(&mut self) -> Option<SingleThreadResumeOps<'_, Self>> {\n        None\n    }\n}\n\n/// Target extension - support for resuming single threaded targets.\npub trait SingleThreadResume: Target {\n    /// Resume execution on the target.\n    ///\n    /// The GDB client may also include a `signal` which should be passed to the\n    /// target.\n    ///\n    /// # Additional Considerations\n    ///\n    /// ### Adjusting PC after a breakpoint is hit\n    ///\n    /// The [GDB remote serial protocol documentation](https://sourceware.org/gdb/current/onlinedocs/gdb/Stop-Reply-Packets.html#swbreak-stop-reason)\n    /// notes the following:\n    ///\n    /// > On some architectures, such as x86, at the architecture level, when a\n    /// > breakpoint instruction executes the program counter points at the\n    /// > breakpoint address plus an offset. On such targets, the stub is\n    /// > responsible for adjusting the PC to point back at the breakpoint\n    /// > address.\n    ///\n    /// Omitting PC adjustment may result in unexpected execution flow and/or\n    /// breakpoints not appearing to work correctly.\n    fn resume(&mut self, signal: Option<Signal>) -> Result<(), Self::Error>;\n\n    /// Support for optimized [single stepping].\n    ///\n    /// [single stepping]: https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#index-stepi\n    #[inline(always)]\n    fn support_single_step(&mut self) -> Option<SingleThreadSingleStepOps<'_, Self>> {\n        None\n    }\n\n    /// Support for optimized [range stepping].\n    ///\n    /// [range stepping]: https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#range-stepping\n    #[inline(always)]\n    fn support_range_step(&mut self) -> Option<SingleThreadRangeSteppingOps<'_, Self>> {\n        None\n    }\n\n    /// Support for [reverse stepping] a target.\n    ///\n    /// [reverse stepping]: https://sourceware.org/gdb/current/onlinedocs/gdb/Reverse-Execution.html\n    #[inline(always)]\n    fn support_reverse_step(\n        &mut self,\n    ) -> Option<super::reverse_exec::ReverseStepOps<'_, (), Self>> {\n        None\n    }\n\n    /// Support for [reverse continuing] a target.\n    ///\n    /// [reverse continuing]: https://sourceware.org/gdb/current/onlinedocs/gdb/Reverse-Execution.html\n    #[inline(always)]\n    fn support_reverse_cont(\n        &mut self,\n    ) -> Option<super::reverse_exec::ReverseContOps<'_, (), Self>> {\n        None\n    }\n}\n\ndefine_ext!(SingleThreadResumeOps, SingleThreadResume);\n\n/// Target Extension - Optimized single stepping for single threaded targets.\n/// See [`SingleThreadResume::support_single_step`].\npub trait SingleThreadSingleStep: Target + SingleThreadResume {\n    /// [Single step] the target.\n    ///\n    /// Single stepping will step the target a single \"step\" - typically a\n    /// single instruction.\n    /// The GDB client may also include a `signal` which should be passed to the\n    /// target.\n    ///\n    /// [Single step]: https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#index-stepi\n    fn step(&mut self, signal: Option<Signal>) -> Result<(), Self::Error>;\n}\n\ndefine_ext!(SingleThreadSingleStepOps, SingleThreadSingleStep);\n\n/// Target Extension - Optimized range stepping for single threaded targets.\n/// See [`SingleThreadResume::support_range_step`].\npub trait SingleThreadRangeStepping: Target + SingleThreadResume {\n    /// [Range step] the target.\n    ///\n    /// Range Stepping will step the target once, and keep stepping the target\n    /// as long as execution remains between the specified start (inclusive)\n    /// and end (exclusive) addresses, or another stop condition is met\n    /// (e.g: a breakpoint it hit).\n    ///\n    /// If the range is empty (`start` == `end`), then the action becomes\n    /// equivalent to the ‘s’ action. In other words, single-step once, and\n    /// report the stop (even if the stepped instruction jumps to start).\n    ///\n    /// _Note:_ A stop reply may be sent at any point even if the PC is still\n    /// within the stepping range; for example, it is valid to implement range\n    /// stepping in a degenerate way as a single instruction step operation.\n    ///\n    /// [Range step]: https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#range-stepping\n    fn resume_range_step(\n        &mut self,\n        start: <Self::Arch as Arch>::Usize,\n        end: <Self::Arch as Arch>::Usize,\n    ) -> Result<(), Self::Error>;\n}\n\ndefine_ext!(SingleThreadRangeSteppingOps, SingleThreadRangeStepping);\n"
  },
  {
    "path": "src/target/ext/breakpoints.rs",
    "content": "//! Add/Remove various kinds of breakpoints.\n\nuse crate::arch::Arch;\nuse crate::target::Target;\nuse crate::target::TargetResult;\n\n/// Target Extension - Set/Remove Breakpoints.\npub trait Breakpoints: Target {\n    /// Support for setting / removing software breakpoints.\n    #[inline(always)]\n    fn support_sw_breakpoint(&mut self) -> Option<SwBreakpointOps<'_, Self>> {\n        None\n    }\n\n    /// Support for setting / removing hardware breakpoints.\n    #[inline(always)]\n    fn support_hw_breakpoint(&mut self) -> Option<HwBreakpointOps<'_, Self>> {\n        None\n    }\n\n    /// Support for setting / removing hardware watchpoints.\n    #[inline(always)]\n    fn support_hw_watchpoint(&mut self) -> Option<HwWatchpointOps<'_, Self>> {\n        None\n    }\n}\n\ndefine_ext!(BreakpointsOps, Breakpoints);\n\n/// Nested Target Extension - Set/Remove Software Breakpoints.\n///\n/// See [this stackoverflow discussion](https://stackoverflow.com/questions/8878716/what-is-the-difference-between-hardware-and-software-breakpoints)\n/// about the differences between hardware and software breakpoints.\n///\n/// _Recommendation:_ If you're implementing `Target` for an emulator that's\n/// using an _interpreted_ CPU (as opposed to a JIT), the simplest way to\n/// implement \"software\" breakpoints would be to check the `PC` value after each\n/// CPU cycle, ignoring the specified breakpoint `kind` entirely.\npub trait SwBreakpoint: Target + Breakpoints {\n    /// Add a new software breakpoint.\n    ///\n    /// Return `Ok(false)` if the operation could not be completed.\n    fn add_sw_breakpoint(\n        &mut self,\n        addr: <Self::Arch as Arch>::Usize,\n        kind: <Self::Arch as Arch>::BreakpointKind,\n    ) -> TargetResult<bool, Self>;\n\n    /// Remove an existing software breakpoint.\n    ///\n    /// Return `Ok(false)` if the operation could not be completed.\n    fn remove_sw_breakpoint(\n        &mut self,\n        addr: <Self::Arch as Arch>::Usize,\n        kind: <Self::Arch as Arch>::BreakpointKind,\n    ) -> TargetResult<bool, Self>;\n}\n\ndefine_ext!(SwBreakpointOps, SwBreakpoint);\n\n/// Nested Target Extension - Set/Remove Hardware Breakpoints.\n///\n/// See [this stackoverflow discussion](https://stackoverflow.com/questions/8878716/what-is-the-difference-between-hardware-and-software-breakpoints)\n/// about the differences between hardware and software breakpoints.\n///\n/// _Recommendation:_ If you're implementing `Target` for an emulator that's\n/// using an _interpreted_ CPU (as opposed to a JIT), there shouldn't be any\n/// reason to implement this extension (as software breakpoints are likely to be\n/// just-as-fast).\npub trait HwBreakpoint: Target + Breakpoints {\n    /// Add a new hardware breakpoint.\n    ///\n    /// Return `Ok(false)` if the operation could not be completed.\n    fn add_hw_breakpoint(\n        &mut self,\n        addr: <Self::Arch as Arch>::Usize,\n        kind: <Self::Arch as Arch>::BreakpointKind,\n    ) -> TargetResult<bool, Self>;\n\n    /// Remove an existing hardware breakpoint.\n    ///\n    /// Return `Ok(false)` if the operation could not be completed.\n    fn remove_hw_breakpoint(\n        &mut self,\n        addr: <Self::Arch as Arch>::Usize,\n        kind: <Self::Arch as Arch>::BreakpointKind,\n    ) -> TargetResult<bool, Self>;\n}\n\ndefine_ext!(HwBreakpointOps, HwBreakpoint);\n\n/// The kind of watchpoint that should be set/removed.\n#[derive(Clone, Copy, Debug, PartialEq, Eq)]\npub enum WatchKind {\n    /// Fire when the memory location is written to.\n    Write,\n    /// Fire when the memory location is read from.\n    Read,\n    /// Fire when the memory location is written to and/or read from.\n    ReadWrite,\n}\n\n/// Nested Target Extension - Set/Remove Hardware Watchpoints.\n///\n/// See the [GDB documentation](https://sourceware.org/gdb/current/onlinedocs/gdb/Set-Watchpoints.html)\n/// regarding watchpoints for how they're supposed to work.\n///\n/// _Note:_ If this extension isn't implemented, GDB will default to using\n/// _software watchpoints_, which tend to be excruciatingly slow (as hey are\n/// implemented by single-stepping the system, and reading the watched memory\n/// location after each step).\npub trait HwWatchpoint: Target + Breakpoints {\n    /// Add a new hardware watchpoint.\n    /// The number of bytes to watch is specified by `len`.\n    ///\n    /// Return `Ok(false)` if the operation could not be completed.\n    fn add_hw_watchpoint(\n        &mut self,\n        addr: <Self::Arch as Arch>::Usize,\n        len: <Self::Arch as Arch>::Usize,\n        kind: WatchKind,\n    ) -> TargetResult<bool, Self>;\n\n    /// Remove an existing hardware watchpoint.\n    /// The number of bytes to watch is specified by `len`.\n    ///\n    /// Return `Ok(false)` if the operation could not be completed.\n    fn remove_hw_watchpoint(\n        &mut self,\n        addr: <Self::Arch as Arch>::Usize,\n        len: <Self::Arch as Arch>::Usize,\n        kind: WatchKind,\n    ) -> TargetResult<bool, Self>;\n}\n\ndefine_ext!(HwWatchpointOps, HwWatchpoint);\n"
  },
  {
    "path": "src/target/ext/catch_syscalls.rs",
    "content": "//! Enable or disable catching syscalls from the inferior process.\n\nuse crate::arch::Arch;\nuse crate::target::Target;\nuse crate::target::TargetResult;\n\n/// Target Extension - Enable and disable catching syscalls from the inferior\n/// process.\n///\n/// Implementing this extension allows the target to support the `catch syscall`\n/// GDB client command. See [GDB documentation](https://sourceware.org/gdb/onlinedocs/gdb/Set-Catchpoints.html)\n/// for further details.\npub trait CatchSyscalls: Target {\n    /// Enables catching syscalls from the inferior process.\n    ///\n    /// If `filter` is `None`, then all syscalls should be reported to GDB. If a\n    /// filter is provided, only the syscalls listed in the filter should be\n    /// reported to GDB.\n    ///\n    /// Note: filters are not combined, subsequent calls this method should\n    /// replace any existing syscall filtering.\n    fn enable_catch_syscalls(\n        &mut self,\n        filter: Option<SyscallNumbers<'_, <Self::Arch as Arch>::Usize>>,\n    ) -> TargetResult<(), Self>;\n\n    /// Disables catching syscalls from the inferior process.\n    fn disable_catch_syscalls(&mut self) -> TargetResult<(), Self>;\n}\n\ndefine_ext!(CatchSyscallsOps, CatchSyscalls);\n\n/// Describes where the syscall catchpoint was triggered at.\n#[derive(Clone, Copy, Debug, PartialEq, Eq)]\npub enum CatchSyscallPosition {\n    /// Reached the entry location of the syscall.\n    Entry,\n    /// Reached the return location of the syscall.\n    Return,\n}\n\n/// Iterator of syscall numbers that should be reported to GDB.\npub struct SyscallNumbers<'a, U> {\n    pub(crate) inner: &'a mut dyn Iterator<Item = U>,\n}\n\nimpl<U> Iterator for SyscallNumbers<'_, U> {\n    type Item = U;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.inner.next()\n    }\n}\n"
  },
  {
    "path": "src/target/ext/exec_file.rs",
    "content": "//! Provide exec-file path for the target.\nuse crate::common::Pid;\nuse crate::target::Target;\nuse crate::target::TargetResult;\n\n/// Target Extension - Provide current exec-file.\n///\n/// NOTE: this extension is primarily intended to be used alongside the [`Host\n/// I/O Extensions`](crate::target::ext::host_io), which enables the GDB client\n/// to read the executable file directly from the target\npub trait ExecFile: Target {\n    /// Get full absolute path of the file that was executed to create\n    /// process `pid` running on the remote system.\n    ///\n    /// If `pid` is `None`, return the filename corresponding to the\n    /// currently executing process.\n    ///\n    /// Return the number of bytes written into `buf` (which may be less than\n    /// `length`).\n    ///\n    /// If `offset` is greater than the length of the underlying data, return\n    /// `Ok(0)`.\n    fn get_exec_file(\n        &self,\n        pid: Option<Pid>,\n        offset: u64,\n        length: usize,\n        buf: &mut [u8],\n    ) -> TargetResult<usize, Self>;\n}\n\ndefine_ext!(ExecFileOps, ExecFile);\n"
  },
  {
    "path": "src/target/ext/extended_mode.rs",
    "content": "//! Enables [Extended Mode](https://sourceware.org/gdb/current/onlinedocs/gdb/Connecting.html)\n//! functionality when connecting using `target extended-remote`, such as\n//! spawning new processes and/or attaching to existing processes.\n\nuse crate::common::*;\nuse crate::target::Target;\nuse crate::target::TargetResult;\n\n/// Returned from `ExtendedMode::kill`\n///\n/// Retuning `ShouldTerminate::Yes` will cause the `GdbStub` to immediately\n/// shut down and return a `DisconnectReason::Kill`. Returning\n/// `ShouldTerminate::No` will keep the `GdbStub` running and listening for\n/// further run/attach requests.\npub enum ShouldTerminate {\n    /// Terminate GdbStub\n    Yes,\n    /// Don't Terminate GdbStub\n    No,\n}\n\nimpl ShouldTerminate {\n    /// Convert `ShouldTerminate::Yes` into `true`, and `ShouldTerminate::No`\n    /// into `false`\n    pub fn into_bool(self) -> bool {\n        match self {\n            ShouldTerminate::Yes => true,\n            ShouldTerminate::No => false,\n        }\n    }\n}\n\n/// Describes how the target attached to a process.\npub enum AttachKind {\n    /// It attached to an existing process.\n    Attach,\n    /// It spawned a new process.\n    Run,\n}\n\nimpl AttachKind {\n    pub(crate) fn was_attached(self) -> bool {\n        match self {\n            AttachKind::Attach => true,\n            AttachKind::Run => false,\n        }\n    }\n}\n\n/// Target Extension - Support\n/// [Extended Mode](https://sourceware.org/gdb/current/onlinedocs/gdb/Connecting.html) functionality.\n///\n/// # Extended Mode for Single/Multi Threaded Targets\n///\n/// While extended-mode is primarily intended to be implemented by targets which\n/// support debugging multiple processes, there's no reason why a basic\n/// single/multi-threaded target can't implement these extensions as well.\n///\n/// For example, instead of \"spawning\" a process, the `run` command could be\n/// used to reset the execution state instead (e.g: resetting an emulator).\npub trait ExtendedMode: Target {\n    /// Spawn and attach to the program `filename`, passing it the provided\n    /// `args` on its command line.\n    ///\n    /// The program is created in the stopped state.\n    ///\n    /// If no filename is provided, the stub may use a default program (e.g. the\n    /// last program run), or a non fatal error should be returned.\n    ///\n    /// `filename` and `args` are not guaranteed to be valid UTF-8, and are\n    /// passed as raw byte arrays. If the filenames/arguments could not be\n    /// converted into an appropriate representation, a non fatal error should\n    /// be returned.\n    ///\n    /// _Note:_ This method's implementation should handle any additional\n    /// configuration options set via the various `ConfigureXXX` extensions to\n    /// `ExtendedMode`. e.g: if the [`ConfigureEnv`](trait.ConfigureEnv.html)\n    /// extension is implemented and enabled, this method should set the spawned\n    /// processes' environment variables accordingly.\n    fn run(&mut self, filename: Option<&[u8]>, args: Args<'_, '_>) -> TargetResult<Pid, Self>;\n\n    /// Attach to a new process with the specified PID.\n    ///\n    /// Targets that wish to use `attach` are required to implement\n    /// [`CurrentActivePid`] (via `support_current_active_pid`), as the default\n    /// `gdbstub` behavior of always reporting a Pid of `1` will cause issues\n    /// when attaching to new processes.\n    ///\n    /// _Note:_ In the next API-breaking release of `gdbstub`, this coupling\n    /// will become a compile-time checked invariant.\n    ///\n    /// In all-stop mode, all threads in the attached process are stopped; in\n    /// non-stop mode, it may be attached without being stopped (if that is\n    /// supported by the target).\n    fn attach(&mut self, pid: Pid) -> TargetResult<(), Self>;\n\n    /// Query if specified PID was spawned by the target (via `run`), or if the\n    /// target attached to an existing process (via `attach`).\n    ///\n    /// If the PID doesn't correspond to a process the target has run or\n    /// attached to, a non fatal error should be returned.\n    fn query_if_attached(&mut self, pid: Pid) -> TargetResult<AttachKind, Self>;\n\n    /// Called when the GDB client sends a Kill request.\n    ///\n    /// If the PID doesn't correspond to a process the target has run or\n    /// attached to, a non fatal error should be returned.\n    ///\n    /// GDB may or may not specify a specific PID to kill. When no PID is\n    /// specified, the target is free to decide what to do (e.g: kill the\n    /// last-used pid, terminate the connection, etc...).\n    ///\n    /// If `ShouldTerminate::Yes` is returned, `GdbStub` will immediately stop\n    /// and return a `DisconnectReason::Kill`. Otherwise, the connection will\n    /// remain open, and `GdbStub` will continue listening for run/attach\n    /// requests.\n    fn kill(&mut self, pid: Option<Pid>) -> TargetResult<ShouldTerminate, Self>;\n\n    /// Restart the program being debugged.\n    ///\n    /// The GDB docs don't do a good job describing what a \"restart\" operation\n    /// entails. For reference, the official `gdbserver` seems to kill all\n    /// inferior processes, and then re-run whatever program was provided on the\n    /// command line (if one was provided).\n    ///\n    /// _Author's Note:_ Based on my current (as of Sept 2020) understanding of\n    /// the GDB client;s source code, it seems that the \"R\" packet is _never_\n    /// sent so-long as the target implements the \"vRun\" packet (which\n    /// corresponds to this trait's `run` method). As such, while `gdbstub`\n    /// exposes this functionality, and \"requires\" an implementation, unless\n    /// you're running a fairly old version of GDB, it should be fine to\n    /// simply stub it out -- e.g: using the `unimplemented!()` macro /\n    /// returning a fatal error.\n    fn restart(&mut self) -> Result<(), Self::Error>;\n\n    /// (optional) Invoked when GDB client switches to extended mode.\n    ///\n    /// The default implementation is a no-op.\n    ///\n    /// Target implementations can override this implementation if they need to\n    /// perform any operations once extended mode is activated.\n    fn on_start(&mut self) -> Result<(), Self::Error> {\n        Ok(())\n    }\n\n    /// Support for enabling / disabling ASLR for spawned processes.\n    #[inline(always)]\n    fn support_configure_aslr(&mut self) -> Option<ConfigureAslrOps<'_, Self>> {\n        None\n    }\n\n    /// Support for setting / removing / resetting environment variables for\n    /// spawned processes.\n    #[inline(always)]\n    fn support_configure_env(&mut self) -> Option<ConfigureEnvOps<'_, Self>> {\n        None\n    }\n\n    /// Support for configuring if spawned processes should be spawned using a\n    /// shell.\n    #[inline(always)]\n    fn support_configure_startup_shell(&mut self) -> Option<ConfigureStartupShellOps<'_, Self>> {\n        None\n    }\n\n    /// Support for configuring the working directory for spawned processes.\n    #[inline(always)]\n    fn support_configure_working_dir(&mut self) -> Option<ConfigureWorkingDirOps<'_, Self>> {\n        None\n    }\n\n    /// Support for reporting the current active Pid. Must be implemented in\n    /// order to use `attach`.\n    #[inline(always)]\n    fn support_current_active_pid(&mut self) -> Option<CurrentActivePidOps<'_, Self>> {\n        None\n    }\n}\n\ndefine_ext!(ExtendedModeOps, ExtendedMode);\n\n/// Iterator of `args` passed to a spawned process (used in\n/// `ExtendedMode::run`)\npub struct Args<'a, 'args> {\n    inner: &'a mut dyn Iterator<Item = &'args [u8]>,\n}\n\nimpl core::fmt::Debug for Args<'_, '_> {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        write!(f, \"Args {{ .. }}\")\n    }\n}\n\nimpl<'a, 'b> Args<'a, 'b> {\n    pub(crate) fn new(inner: &'a mut dyn Iterator<Item = &'b [u8]>) -> Args<'a, 'b> {\n        Args { inner }\n    }\n}\n\nimpl<'args> Iterator for Args<'_, 'args> {\n    type Item = &'args [u8];\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.inner.next()\n    }\n}\n\n/// Nested Target Extension - Enable/Disable ASLR for spawned processes (for a\n/// more consistent debugging experience).\n///\n/// Corresponds to GDB's [`set disable-randomization`](https://sourceware.org/gdb/onlinedocs/gdb/Starting.html) command.\npub trait ConfigureAslr: ExtendedMode {\n    /// Enable/Disable ASLR for spawned processes.\n    fn cfg_aslr(&mut self, enabled: bool) -> TargetResult<(), Self>;\n}\n\ndefine_ext!(ConfigureAslrOps, ConfigureAslr);\n\n/// Nested Target Extension - Set/Remove/Reset the Environment variables for\n/// spawned processes.\n///\n/// Corresponds to GDB's [`set environment`](https://sourceware.org/gdb/onlinedocs/gdb/Environment.html#set-environment) cmd.\n///\n/// _Note:_ Environment variables are not guaranteed to be UTF-8, and are passed\n/// as raw byte arrays. If the provided keys/values could not be converted into\n/// an appropriate representation, a non fatal error should be returned.\npub trait ConfigureEnv: ExtendedMode {\n    /// Set an environment variable.\n    fn set_env(&mut self, key: &[u8], val: Option<&[u8]>) -> TargetResult<(), Self>;\n\n    /// Remove an environment variable.\n    fn remove_env(&mut self, key: &[u8]) -> TargetResult<(), Self>;\n\n    /// Reset all environment variables to their initial state (i.e: undo all\n    /// previous `set/remove_env` calls).\n    fn reset_env(&mut self) -> TargetResult<(), Self>;\n}\n\ndefine_ext!(ConfigureEnvOps, ConfigureEnv);\n\n/// Nested Target Extension - Configure if spawned processes should be spawned\n/// using a shell.\n///\n/// Corresponds to GDB's [`set startup-with-shell`](https://sourceware.org/gdb/onlinedocs/gdb/Starting.html) command.\npub trait ConfigureStartupShell: ExtendedMode {\n    /// Configure if spawned processes should be spawned using a shell.\n    ///\n    /// On UNIX-like targets, it is possible to start the inferior using a shell\n    /// program. This is the default behavior on both `GDB` and `gdbserver`.\n    fn cfg_startup_with_shell(&mut self, enabled: bool) -> TargetResult<(), Self>;\n}\n\ndefine_ext!(ConfigureStartupShellOps, ConfigureStartupShell);\n\n/// Nested Target Extension - Configure the working directory for spawned\n/// processes.\n///\n/// Corresponds to GDB's [`set cwd` and `cd`](https://sourceware.org/gdb/onlinedocs/gdb/Working-Directory.html) commands.\npub trait ConfigureWorkingDir: ExtendedMode {\n    /// Set the working directory for spawned processes.\n    ///\n    /// If no directory is provided, the stub should reset the value to it's\n    /// original value.\n    ///\n    /// The path is not guaranteed to be valid UTF-8, and is passed as a raw\n    /// byte array. If the path could not be converted into an appropriate\n    /// representation, a non fatal error should be returned.\n    fn cfg_working_dir(&mut self, dir: Option<&[u8]>) -> TargetResult<(), Self>;\n}\n\ndefine_ext!(ConfigureWorkingDirOps, ConfigureWorkingDir);\n\n/// Nested Target extension - Return the current active Pid.\npub trait CurrentActivePid: ExtendedMode {\n    /// Report the current active Pid.\n    ///\n    /// When implementing gdbstub on a platform that supports multiple\n    /// processes, the active PID needs to match the attached process. Failing\n    /// to do so will cause GDB to fail to attach to the target process.\n    ///\n    /// This should reflect the currently-debugged process which should be\n    /// updated when switching processes after calling\n    /// [`attach()`](ExtendedMode::attach).\n    ///\n    /// _Note:_ `gdbstub` doesn't yet support debugging multiple processes\n    /// _simultaneously_. If this is a feature you're interested in, please\n    /// leave a comment on this [tracking\n    /// issue](https://github.com/daniel5151/gdbstub/issues/124).\n    fn current_active_pid(&mut self) -> Result<Pid, Self::Error>;\n}\n\ndefine_ext!(CurrentActivePidOps, CurrentActivePid);\n"
  },
  {
    "path": "src/target/ext/flash.rs",
    "content": "//! Provide flash operations on the target.\nuse crate::arch::Arch;\nuse crate::target::Target;\nuse crate::target::TargetResult;\n\n/// Flash memory operations.\n/// It's necessary to implement this extension to support GDB `load` command.\n///\n/// Typically, a GDB `load` command sequence starts by issuing a `flash_erase`\n/// command, followed by multiple `flash_write` commands (typically one for each\n/// loadable ELF section), and ends with a `flash_done` command.\n///\n/// The regions containing the addresses to be flashed must be specified as\n/// \"flash\" regions in the memory map xml, returned by\n/// [MemoryMap::memory_map_xml][crate::target::ext::memory_map::MemoryMap::memory_map_xml].\npub trait Flash: Target {\n    /// Erase `length` bytes of the target's flash memory starting from\n    /// `start_addr`.\n    ///\n    /// GDB ensures `start_addr` and `length` are aligned to flash memory\n    /// block boundaries as defined by the memory map xml.\n    fn flash_erase(\n        &mut self,\n        start_addr: <Self::Arch as Arch>::Usize,\n        length: <Self::Arch as Arch>::Usize,\n    ) -> TargetResult<(), Self>;\n\n    /// Write bytes to the target's flash memory.\n    ///\n    /// GDB guarantees that the memory ranges specified by `flash_write`\n    /// commands sent before a `flash_done` do not overlap and appear in\n    /// order of increasing addresses.\n    ///\n    /// See [GDB Documentation] for more details.\n    ///\n    /// [GDB Documentation]: https://sourceware.org/gdb/current/onlinedocs/gdb.html/Packets.html\n    fn flash_write(\n        &mut self,\n        start_addr: <Self::Arch as Arch>::Usize,\n        data: &[u8],\n    ) -> TargetResult<(), Self>;\n\n    /// Indicate to the target that flash programming is finished.\n    ///\n    /// By GDB documentation, you can batch flash erase and write operations\n    /// until this is called.\n    fn flash_done(&mut self) -> TargetResult<(), Self>;\n}\n\ndefine_ext!(FlashOps, Flash);\n"
  },
  {
    "path": "src/target/ext/host_info.rs",
    "content": "//! (LLDB extension) Provide host information to the debugger.\n//!\n//! This allows for reporting key-value metadata, for example the target triple,\n//! endianness, and pointer size.\n//!\n//! This corresponds to the `qHostInfo` command in the LLDB extensions.\n\nuse crate::common::Endianness;\nuse crate::target::Target;\n\n/// A response key-value pair to a [HostInfo::host_info] query.\n///\n/// A response consists of a list of key-value pairs, each of which is\n/// represented by one instance of this enum.\n///\n/// The allowed responses are documented in the [LLDB extension documentation].\n/// Not all supported responses are currently represented in this enum. If you\n/// need another one, please feel free to send a PR!\n///\n/// [LLDB extension documentation]:\n///     https://lldb.llvm.org/resources/lldbplatformpackets.html\n#[derive(Clone, Copy)]\n#[non_exhaustive]\npub enum HostInfoResponse<'a> {\n    /// The target triple for the debuggee, as a string.\n    Triple(&'a str),\n    /// The target endianness.\n    Endianness(Endianness),\n    /// The pointer size.\n    PointerSize(usize),\n}\n\n/// (LLDB extension) Target Extension - Provide host information.\npub trait HostInfo: Target {\n    /// Write a response to a host-info query.\n    ///\n    /// Call `write_item` with each `HostInfoResponse` you wish to send.\n    fn host_info(\n        &self,\n        write_item: &mut dyn FnMut(&HostInfoResponse<'_>),\n    ) -> Result<(), Self::Error>;\n}\n\ndefine_ext!(HostInfoOps, HostInfo);\n"
  },
  {
    "path": "src/target/ext/host_io.rs",
    "content": "//! Provide Host I/O operations for the target.\nuse crate::arch::Arch;\nuse crate::target::Target;\nuse bitflags::bitflags;\n\n/// Host flags for opening files.\n///\n/// Extracted from the GDB documentation at\n/// [Open Flags](https://sourceware.org/gdb/current/onlinedocs/gdb/Open-Flags.html#Open-Flags),\n/// and the LLDB source code at\n/// [`lldb/include/lldb/Host/File.h`](https://github.com/llvm/llvm-project/blob/ec642ceebc1aacc8b16249df7734b8cf90ae2963/lldb/include/lldb/Host/File.h#L47-L66)\n#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]\n#[repr(transparent)]\npub struct HostIoOpenFlags(u32);\n\nbitflags! {\n    impl HostIoOpenFlags: u32 {\n        /// A read-only file.\n        const O_RDONLY = 0x0;\n        /// A write-only file.\n        const O_WRONLY = 0x1;\n        /// A read-write file.\n        const O_RDWR = 0x2;\n        /// Append to an existing file.\n        const O_APPEND = 0x8;\n        /// Create a non-existent file.\n        const O_CREAT = 0x200;\n        /// Truncate an existing file.\n        const O_TRUNC = 0x400;\n        /// Exclusive access.\n        const O_EXCL = 0x800;\n\n        /// LLDB extension: Do not block.\n        const O_NONBLOCK = 1 << 28;\n        /// LLDB extension: Do not follow symlinks.\n        const O_DONT_FOLLOW_SYMLINKS = 1 << 29;\n        /// LLDB extension: Close the file when executing a new process.\n        const O_CLOSE_ON_EXEC = 1 << 30;\n        /// LLDB extension: Invalid value.\n        const O_INVALID = 1 << 31;\n    }\n}\n\n/// Host file permissions.\n///\n/// Extracted from the GDB documentation at\n/// [mode_t Values](https://sourceware.org/gdb/current/onlinedocs/gdb/mode_005ft-Values.html#mode_005ft-Values)\n#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]\n#[repr(transparent)]\npub struct HostIoOpenMode(u32);\n\nbitflags! {\n    impl HostIoOpenMode: u32 {\n        /// A regular file.\n        const S_IFREG = 0o100000;\n        /// A directory.\n        const S_IFDIR = 0o40000;\n        /// User read permissions.\n        const S_IRUSR = 0o400;\n        /// User write permissions.\n        const S_IWUSR = 0o200;\n        /// User execute permissions.\n        const S_IXUSR = 0o100;\n        /// Group read permissions.\n        const S_IRGRP = 0o40;\n        /// Group write permissions\n        const S_IWGRP = 0o20;\n        /// Group execute permissions.\n        const S_IXGRP = 0o10;\n        /// World read permissions.\n        const S_IROTH = 0o4;\n        /// World write permissions\n        const S_IWOTH = 0o2;\n        /// World execute permissions.\n        const S_IXOTH = 0o1;\n    }\n}\n\n/// Data returned by a host fstat request.\n///\n/// Extracted from the GDB documentation at\n/// [struct stat](https://sourceware.org/gdb/current/onlinedocs/gdb/struct-stat.html#struct-stat)\n#[derive(Debug)]\npub struct HostIoStat {\n    /// The device.\n    pub st_dev: u32,\n    /// The inode.\n    pub st_ino: u32,\n    /// Protection bits.\n    pub st_mode: HostIoOpenMode,\n    /// The number of hard links.\n    pub st_nlink: u32,\n    /// The user id of the owner.\n    pub st_uid: u32,\n    /// The group id of the owner.\n    pub st_gid: u32,\n    /// The device type, if an inode device.\n    pub st_rdev: u32,\n    /// The size of the file in bytes.\n    pub st_size: u64,\n    /// The blocksize for the filesystem.\n    pub st_blksize: u64,\n    /// The number of blocks allocated.\n    pub st_blocks: u64,\n    /// The last time the file was accessed, in seconds since the epoch.\n    pub st_atime: u32,\n    /// The last time the file was modified, in seconds since the epoch.\n    pub st_mtime: u32,\n    /// The last time the file was changed, in seconds since the epoch.\n    pub st_ctime: u32,\n}\n\n/// Select the filesystem vFile operations will operate on. Used by vFile setfs\n/// command.\n#[derive(Debug)]\npub enum FsKind {\n    /// Select the filesystem as seen by the remote stub.\n    Stub,\n    /// Select the filesystem as seen by process pid.\n    Pid(crate::common::Pid),\n}\n\n/// Errno values for Host I/O operations.\n///\n/// Extracted from the GDB documentation at\n/// <https://sourceware.org/gdb/onlinedocs/gdb/Errno-Values.html>\n#[derive(Debug)]\npub enum HostIoErrno {\n    /// Operation not permitted (POSIX.1-2001).\n    EPERM = 1,\n    /// No such file or directory (POSIX.1-2001).\n    ///\n    /// Typically, this error results when a specified pathname does not exist,\n    /// or one of the components in the directory prefix of a pathname does not\n    /// exist, or the specified pathname is a dangling symbolic link.\n    ENOENT = 2,\n    /// Interrupted function call (POSIX.1-2001); see signal(7).\n    EINTR = 4,\n    /// Input/output error (POSIX.1-2001).\n    EIO = 5,\n    /// Bad file descriptor (POSIX.1-2001).\n    EBADF = 9,\n    /// Permission denied (POSIX.1-2001).\n    EACCES = 13,\n    /// Bad address (POSIX.1-2001).\n    EFAULT = 14,\n    /// Device or resource busy (POSIX.1-2001).\n    EBUSY = 16,\n    /// File exists (POSIX.1-2001).\n    EEXIST = 17,\n    /// No such device (POSIX.1-2001).\n    ENODEV = 19,\n    /// Not a directory (POSIX.1-2001).\n    ENOTDIR = 20,\n    /// Is a directory (POSIX.1-2001).\n    EISDIR = 21,\n    /// Invalid argument (POSIX.1-2001).\n    EINVAL = 22,\n    /// Too many open files in system (POSIX.1-2001). On Linux, this is probably\n    /// a result of encountering the /proc/sys/fs/file-max limit (see proc(5)).\n    ENFILE = 23,\n    /// Too many open files (POSIX.1-2001). Commonly caused by exceeding the\n    /// RLIMIT_NOFILE resource limit described in getrlimit(2).\n    EMFILE = 24,\n    /// File too large (POSIX.1-2001).\n    EFBIG = 27,\n    /// No space left on device (POSIX.1-2001).\n    ENOSPC = 28,\n    /// Invalid seek (POSIX.1-2001).\n    ESPIPE = 29,\n    /// Read-only filesystem (POSIX.1-2001).\n    EROFS = 30,\n    /// Function not implemented (POSIX.1-2001).\n    ENOSYS = 88,\n    /// Filename too long (POSIX.1-2001).\n    ENAMETOOLONG = 91,\n    /// Unknown errno - there may not be a GDB mapping for this value\n    EUNKNOWN = 9999,\n}\n\n/// The error type for Host I/O operations.\npub enum HostIoError<E> {\n    /// An operation-specific non-fatal error code.\n    ///\n    /// See [`HostIoErrno`] for more details.\n    Errno(HostIoErrno),\n    /// A target-specific fatal error.\n    ///\n    /// **WARNING:** Returning this error will immediately halt the target's\n    /// execution and return a [`GdbStubError`](crate::stub::GdbStubError)!\n    ///\n    /// Note that returning this error will _not_ notify the GDB client that the\n    /// debugging session has been terminated, making it possible to resume\n    /// execution after resolving the error and/or setting up a post-mortem\n    /// debugging environment.\n    Fatal(E),\n}\n\n/// When the `std` feature is enabled, `HostIoError` implements\n/// `From<std::io::Error>`, mapping [`std::io::ErrorKind`] to the appropriate\n/// [`HostIoErrno`] when possible, and falling back to [`HostIoErrno::EUNKNOWN`]\n/// when no mapping exists.\n#[cfg(feature = \"std\")]\nimpl<E> From<std::io::Error> for HostIoError<E> {\n    fn from(e: std::io::Error) -> HostIoError<E> {\n        use std::io::ErrorKind::*;\n        let errno = match e.kind() {\n            PermissionDenied => HostIoErrno::EPERM,\n            NotFound => HostIoErrno::ENOENT,\n            Interrupted => HostIoErrno::EINTR,\n            AlreadyExists => HostIoErrno::EEXIST,\n            InvalidInput => HostIoErrno::EINVAL,\n            _ => HostIoErrno::EUNKNOWN,\n        };\n        HostIoError::Errno(errno)\n    }\n}\n\n/// A specialized `Result` type for Host I/O operations. Supports reporting\n/// non-fatal errors back to the GDB client.\n///\n/// See [`HostIoError`] for more details.\npub type HostIoResult<T, Tgt> = Result<T, HostIoError<<Tgt as Target>::Error>>;\n\n/// Target Extension - Perform I/O operations on host\npub trait HostIo: Target {\n    /// Support `open` operation.\n    #[inline(always)]\n    fn support_open(&mut self) -> Option<HostIoOpenOps<'_, Self>> {\n        None\n    }\n\n    /// Support `close` operation.\n    #[inline(always)]\n    fn support_close(&mut self) -> Option<HostIoCloseOps<'_, Self>> {\n        None\n    }\n\n    /// Support `pread` operation.\n    #[inline(always)]\n    fn support_pread(&mut self) -> Option<HostIoPreadOps<'_, Self>> {\n        None\n    }\n\n    /// Support `pwrite` operation.\n    #[inline(always)]\n    fn support_pwrite(&mut self) -> Option<HostIoPwriteOps<'_, Self>> {\n        None\n    }\n\n    /// Support `fstat` operation.\n    #[inline(always)]\n    fn support_fstat(&mut self) -> Option<HostIoFstatOps<'_, Self>> {\n        None\n    }\n\n    /// Support `unlink` operation.\n    #[inline(always)]\n    fn support_unlink(&mut self) -> Option<HostIoUnlinkOps<'_, Self>> {\n        None\n    }\n\n    /// Support `readlink` operation.\n    #[inline(always)]\n    fn support_readlink(&mut self) -> Option<HostIoReadlinkOps<'_, Self>> {\n        None\n    }\n\n    /// Support `setfs` operation.\n    #[inline(always)]\n    fn support_setfs(&mut self) -> Option<HostIoSetfsOps<'_, Self>> {\n        None\n    }\n}\n\ndefine_ext!(HostIoOps, HostIo);\n\n/// Nested Target Extension - Host I/O open operation.\npub trait HostIoOpen: HostIo {\n    /// Open a file at `filename` and return a file descriptor for it, or return\n    /// [`HostIoError::Errno`] if an error occurs.\n    ///\n    /// `flags` are the flags used when opening the file (see\n    /// [`HostIoOpenFlags`]), and `mode` is the mode used if the file is\n    /// created (see [`HostIoOpenMode`]).\n    fn open(\n        &mut self,\n        filename: &[u8],\n        flags: HostIoOpenFlags,\n        mode: HostIoOpenMode,\n    ) -> HostIoResult<u32, Self>;\n}\n\ndefine_ext!(HostIoOpenOps, HostIoOpen);\n\n/// Nested Target Extension - Host I/O close operation.\npub trait HostIoClose: HostIo {\n    /// Close the open file corresponding to `fd`.\n    fn close(&mut self, fd: u32) -> HostIoResult<(), Self>;\n}\n\ndefine_ext!(HostIoCloseOps, HostIoClose);\n\n/// Nested Target Extension - Host I/O pread operation.\npub trait HostIoPread: HostIo {\n    /// Read data from the open file corresponding to `fd`.\n    ///\n    /// Up to `count` bytes will be read from the file, starting at `offset`\n    /// relative to the start of the file.\n    ///\n    /// Return the number of bytes written into `buf` (which may be less than\n    /// `count`).\n    ///\n    /// If `offset` is greater than the length of the underlying data, return\n    /// `Ok(0)`.\n    fn pread(\n        &mut self,\n        fd: u32,\n        count: usize,\n        offset: u64,\n        buf: &mut [u8],\n    ) -> HostIoResult<usize, Self>;\n}\n\ndefine_ext!(HostIoPreadOps, HostIoPread);\n\n/// Nested Target Extension - Host I/O pwrite operation.\npub trait HostIoPwrite: HostIo {\n    /// Write `data` to the open file corresponding to `fd`.\n    ///\n    /// Start the write at `offset` from the start of the file.\n    ///\n    /// Return the number of bytes written, which may be shorter\n    /// than the length of data, or [`HostIoError::Errno`] if an error occurred.\n    fn pwrite(\n        &mut self,\n        fd: u32,\n        offset: <Self::Arch as Arch>::Usize,\n        data: &[u8],\n    ) -> HostIoResult<<Self::Arch as Arch>::Usize, Self>;\n}\n\ndefine_ext!(HostIoPwriteOps, HostIoPwrite);\n\n/// Nested Target Extension - Host I/O fstat operation.\npub trait HostIoFstat: HostIo {\n    /// Get information about the open file corresponding to `fd`.\n    ///\n    /// On success return a [`HostIoStat`] struct.\n    /// Return [`HostIoError::Errno`] if an error occurs.\n    fn fstat(&mut self, fd: u32) -> HostIoResult<HostIoStat, Self>;\n}\n\ndefine_ext!(HostIoFstatOps, HostIoFstat);\n\n/// Nested Target Extension - Host I/O unlink operation.\npub trait HostIoUnlink: HostIo {\n    /// Delete the file at `filename` on the target.\n    fn unlink(&mut self, filename: &[u8]) -> HostIoResult<(), Self>;\n}\n\ndefine_ext!(HostIoUnlinkOps, HostIoUnlink);\n\n/// Nested Target Extension - Host I/O readlink operation.\npub trait HostIoReadlink: HostIo {\n    /// Read value of symbolic link `filename` on the target.\n    ///\n    /// Return the number of bytes written into `buf`.\n    ///\n    /// Unlike most other Host IO handlers, if the resolved file path exceeds\n    /// the length of the provided `buf`, the target should NOT return a\n    /// partial response, and MUST return a `Err(HostIoErrno::ENAMETOOLONG)`.\n    fn readlink(&mut self, filename: &[u8], buf: &mut [u8]) -> HostIoResult<usize, Self>;\n}\n\ndefine_ext!(HostIoReadlinkOps, HostIoReadlink);\n\n/// Nested Target Extension - Host I/O setfs operation.\npub trait HostIoSetfs: HostIo {\n    /// Select the filesystem on which vFile operations with filename arguments\n    /// will operate. This is required for GDB to be able to access files on\n    /// remote targets where the remote stub does not share a common filesystem\n    /// with the inferior(s).\n    ///\n    /// See [`FsKind`] for the meaning of `fs`.\n    ///\n    /// If setfs indicates success, the selected filesystem remains selected\n    /// until the next successful setfs operation.\n    fn setfs(&mut self, fs: FsKind) -> HostIoResult<(), Self>;\n}\n\ndefine_ext!(HostIoSetfsOps, HostIoSetfs);\n"
  },
  {
    "path": "src/target/ext/libraries.rs",
    "content": "//! Report information about the loaded shared libraries for targets where there\n//! are possibly multiple files to be debugged mapped into the same address\n//! space.\n\nuse crate::target::Target;\nuse crate::target::TargetResult;\n\n/// Target Extension - List an SVR4 (System-V/Unix) target's libraries.\npub trait LibrariesSvr4: Target {\n    /// Get library list XML for this target.\n    ///\n    /// See the [GDB Documentation] for a description of the format.\n    ///\n    /// [GDB Documentation]: https://sourceware.org/gdb/current/onlinedocs/gdb.html/Library-List-Format-for-SVR4-Targets.html\n    ///\n    /// Return the number of bytes written into `buf` (which may be less than\n    /// `length`).\n    ///\n    /// If `offset` is greater than the length of the underlying data, return\n    /// `Ok(0)`.\n    fn get_libraries_svr4(\n        &self,\n        offset: u64,\n        length: usize,\n        buf: &mut [u8],\n    ) -> TargetResult<usize, Self>;\n}\n\ndefine_ext!(LibrariesSvr4Ops, LibrariesSvr4);\n\n/// Target Extension - List a target's libraries (Windows/generic format).\n///\n/// This is used for targets where library offsets are maintained externally\n/// (e.g., Windows PE targets). Unlike SVR4 format, this uses a simpler XML\n/// structure with segment addresses.\npub trait Libraries: Target {\n    /// Get library list XML for this target.\n    ///\n    /// The expected XML format is:\n    /// ```xml\n    /// <library-list version=\"1.0\">\n    /// <library name=\"C:\\Windows\\notepad.exe\"><segment address=\"0x00401000\"/></library>\n    /// <library name=\"C:\\Windows\\SYSTEM32\\ntdll.dll\"><segment address=\"0x774d1000\"/></library>\n    /// <library name=\"C:\\Windows\\system32\\kernel32.dll\"><segment address=\"0x772b1000\"/></library>\n    /// <library name=\"C:\\Windows\\system32\\KernelBase.dll\"><segment address=\"0x7fefd701000\"/></library>\n    /// </library-list>\n    /// ```\n    ///\n    /// Note that on Windows, the `address` is not the image base, but the\n    /// address of the first section. See the [GDB Documentation] for more\n    /// details.\n    ///\n    /// [GDB Documentation]: https://sourceware.org/gdb/current/onlinedocs/gdb.html/Library-List-Format.html\n    ///\n    /// Return the number of bytes written into `buf` (which may be less than\n    /// `length`).\n    ///\n    /// If `offset` is greater than the length of the underlying data, return\n    /// `Ok(0)`.\n    fn get_libraries(\n        &self,\n        offset: u64,\n        length: usize,\n        buf: &mut [u8],\n    ) -> TargetResult<usize, Self>;\n}\n\ndefine_ext!(LibrariesOps, Libraries);\n"
  },
  {
    "path": "src/target/ext/lldb_register_info_override.rs",
    "content": "//! (LLDB extension) Override the register info specified by `Target::Arch`.\n\nuse crate::arch::lldb::Register;\nuse crate::target::Target;\n\n/// This type serves as a \"proof of callback\", ensuring that either\n/// `reg_info.done()` or `reg_info.write()` have been called from within the\n/// `register_info` function. The only way to obtain a valid instance of this\n/// type is by invoking one of those two methods.\npub struct CallbackToken<'a>(pub(crate) core::marker::PhantomData<&'a *mut ()>);\n\n/// `register_info` callbacks\npub struct Callback<'a> {\n    pub(crate) cb: &'a mut dyn FnMut(Option<Register<'_>>),\n    pub(crate) token: CallbackToken<'a>,\n}\n\nimpl<'a> Callback<'a> {\n    /// The `qRegisterInfo` query shall be concluded.\n    #[inline(always)]\n    pub fn done(self) -> CallbackToken<'a> {\n        (self.cb)(None);\n        self.token\n    }\n\n    /// Write the register info of a single register.\n    #[inline(always)]\n    pub fn write(self, reg: Register<'_>) -> CallbackToken<'a> {\n        (self.cb)(Some(reg));\n        self.token\n    }\n}\n\n/// Target Extension - Override the target register info specified by\n/// `Target::Arch`.\n///\n/// _Note:_ Unless you're working with a particularly dynamic,\n/// runtime-configurable target, it's unlikely that you'll need to implement\n/// this extension.\npub trait LldbRegisterInfoOverride: Target {\n    /// Invoke `reg_info.write(reg)` where `reg` is a [`Register`] struct to\n    /// write information of a single register or `reg_info.done()` if you want\n    /// to end the `qRegisterInfo` packet exchange.\n    fn lldb_register_info<'a>(\n        &mut self,\n        reg_id: usize,\n        reg_info: Callback<'a>,\n    ) -> Result<CallbackToken<'a>, Self::Error>;\n}\n\ndefine_ext!(LldbRegisterInfoOverrideOps, LldbRegisterInfoOverride);\n"
  },
  {
    "path": "src/target/ext/memory_map.rs",
    "content": "//! Provide a memory map for the target.\nuse crate::target::Target;\nuse crate::target::TargetResult;\n\n/// Target Extension - Read the target's memory map.\npub trait MemoryMap: Target {\n    /// Get memory map XML file from the target.\n    ///\n    /// See the [GDB Documentation] for a description of the format.\n    ///\n    /// [GDB Documentation]: https://sourceware.org/gdb/onlinedocs/gdb/Memory-Map-Format.html\n    ///\n    /// Return the number of bytes written into `buf` (which may be less than\n    /// `length`).\n    ///\n    /// If `offset` is greater than the length of the underlying data, return\n    /// `Ok(0)`.\n    fn memory_map_xml(\n        &self,\n        offset: u64,\n        length: usize,\n        buf: &mut [u8],\n    ) -> TargetResult<usize, Self>;\n}\n\ndefine_ext!(MemoryMapOps, MemoryMap);\n"
  },
  {
    "path": "src/target/ext/mod.rs",
    "content": "//! Extensions to [`Target`](super::Target) which add support for various\n//! subsets of the GDB Remote Serial Protocol.\n//!\n//! ### Note: Missing Protocol Extensions\n//!\n//! `gdbstub`'s development is guided by the needs of its contributors, with new\n//! features being added on an \"as-needed\" basis.\n//!\n//! If there's a GDB protocol extensions you're interested in that hasn't been\n//! implemented in `gdbstub` yet, (e.g: remote filesystem access, tracepoint\n//! support, etc...), consider opening an issue / filing a PR on the\n//! [`gdbstub` GitHub repo](https://github.com/daniel5151/gdbstub/).\n//!\n//! Check out the [GDB Remote Configuration Docs](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Configuration.html)\n//! for a table of GDB commands + their corresponding Remote Serial Protocol\n//! packets.\n//!\n//! ## How Protocol Extensions Work - Inlineable Dyn Extension Traits (IDETs)\n//!\n//! The GDB protocol is massive, and contains all sorts of optional\n//! functionality. In the early versions of `gdbstub`, the `Target` trait\n//! directly implemented a method for _every single protocol extension_. If this\n//! trend continued, there would've been literally _hundreds_ of associated\n//! methods - of which only a small subset were ever used at once!\n//!\n//! Aside from the cognitive complexity of having so many methods on a single\n//! trait, this approach had numerous other drawbacks as well:\n//!\n//!  - Implementations that did not implement all available protocol extensions\n//!    still had to \"pay\" for the unused packet parsing/handler code, resulting\n//!    in substantial code bloat, even on `no_std` platforms.\n//!  - `GdbStub`'s internal implementation needed to include a large number of\n//!    _runtime_ checks to deal with incorrectly implemented `Target`s.\n//!      - No way to enforce \"mutually-dependent\" trait methods at compile-time.\n//!          - e.g: When implementing hardware breakpoint extensions, targets\n//!            _must_ implement both the `add_breakpoint` and\n//!            `remove_breakpoints` methods.\n//!      - No way to enforce \"mutually-exclusive\" trait methods at compile-time.\n//!          - e.g: The `resume` method for single-threaded targets has a much\n//!            simpler API than for multi-threaded targets, but it would be\n//!            incorrect for a target to implement both.\n//!\n//! At first blush, it seems the the solution to all these issues is obvious:\n//! simply tie each protocol extension to a `cargo` feature! And yes, while this\n//! would indeed work, there would be several serious ergonomic drawbacks:\n//!\n//! - There would be _hundreds_ of individual feature flags that would need to\n//!   be toggled by end users.\n//! - It would be functionally impossible to _test_ all permutations of\n//!   enabled/disabled cargo features.\n//! - A single binary would need to rely on some [non-trivial `cargo`-fu](https://github.com/rust-lang/cargo/issues/674)\n//!   in order to have multiple `Target` implementations in a single binary.\n//!\n//! After much experimentation and iteration, `gdbstub` ended up taking a\n//! radically different approach to implementing and enumerating available\n//! features, using a technique called **Inlineable Dyn Extension Traits**.\n//!\n//! > _Author's note:_ As far as I can tell, this isn't a very well-known trick,\n//! > or at the very least, I've personally never encountered any library that\n//! > uses this sort of API. As such, I've decided to be a bit cheeky and give\n//! > it a name! At some point, I'm hoping to write a standalone blog post which\n//! > further explores this technique, comparing it to other/existing\n//! > approaches, and diving into details of the how the compiler optimizes this\n//! > sort of code. In fact, I've already got a [very rough github repo](https://github.com/daniel5151/optional-trait-methods)\n//! > with some of my findings.\n//!\n//! So, what are \"Inlineable Dyn Extension Traits\"? Well, let's break it down:\n//!\n//! - **Extension Traits** - A common [Rust convention](https://rust-lang.github.io/rfcs/0445-extension-trait-conventions.html#what-is-an-extension-trait)\n//!   to extend the functionality of a Trait, _without_ modifying the original\n//!   trait.\n//! - **Dyn** - Alludes to the use of Dynamic Dispatch via [Trait Objects](https://doc.rust-lang.org/book/ch17-02-trait-objects.html).\n//! - **Inlineable** - Alludes to the fact that this approach can be easily\n//!   inlined, making it a truly zero-cost abstraction.\n//!\n//! In a nutshell, Inlineable Dyn Extension Traits (or IDETs) are an abuse of\n//! the Rust trait system + modern compiler optimizations to emulate zero-cost,\n//! runtime-enumerable optional trait methods!\n//!\n//! #### Technical overview\n//!\n//! The basic principles behind Inlineable Dyn Extension Traits are best\n//! explained though example:\n//!\n//! Lets say we want to add an optional protocol extension described by an\n//! `ProtocolExt` trait to a base `Protocol` trait. How would we do that using\n//! IDETs?\n//!\n//! - (library) Define a `trait ProtocolExt: Protocol { ... }` which includes\n//!   all the methods required by the protocol extension:\n//!    - _Note:_ Making `ProtocolExt` a subtrait of `Protocol` is not strictly\n//!      required, but it does enable transparently using `Protocol`'s\n//!      associated types as part of `ProtocolExt`'s method definitions.\n//!\n//! ```rust,ignore\n//! /// `foo` and `bar` are mutually-dependent methods.\n//! trait ProtocolExt: Protocol {\n//!     fn foo(&self);\n//!     // can use associated types in method signature!\n//!     fn bar(&mut self) -> Result<(), Self::Error>;\n//! }\n//! ```\n//!\n//! - (library) \"Associate\" the `ProtocolExt` extension trait to the original\n//!   `Protocol` trait by adding a new `Protocol` method that \"downcasts\" `self`\n//!   into a `&mut dyn ProtocolExt`.\n//!\n//! ```rust,ignore\n//! trait Protocol {\n//!     // ... other methods ...\n//!\n//!     // Optional extension\n//!     #[inline(always)]\n//!     fn support_protocol_ext(&mut self) -> Option<ProtocolExtOps<Self>> {\n//!         // disabled by default\n//!         None\n//!     }\n//!\n//!     // Mutually-exclusive extensions\n//!     fn get_ext_a_or_b(&mut self) -> EitherOrExt<Self::Arch, Self::Error>;\n//! }\n//!\n//! // Using a typedef for readability\n//! type ProtocolExtOps<T> =\n//!     &'a mut dyn ProtocolExt<Arch = <T as Protocol>::Arch, Error = <T as Protocol>::Error>;\n//!\n//! enum EitherOrExt<A, E> {\n//!     ProtocolExtA(&'a mut dyn ProtocolExtA<Arch = A, Error = E>),\n//!     ProtocolExtB(&'a mut dyn ProtocolExtB<Arch = A, Error = E>),\n//! }\n//! ```\n//!\n//! - (user) Implements the `ProtocolExt` extension for their target (just like\n//!   a normal trait).\n//!\n//! ```rust,ignore\n//! impl ProtocolExt for MyTarget {\n//!     fn foo(&self) { ... }\n//!     fn bar(&mut self) -> Result<(), Self::Error> { ... }\n//! }\n//! ```\n//!\n//! - (user) Implements the base `Protocol` trait, overriding the\n//!   `support_protocol_ext` method to return `Some(self)`, which will\n//!   effectively \"enable\" the extension.\n//!\n//! ```rust,ignore\n//! impl Protocol for MyTarget {\n//!     // Optional extension\n//!     #[inline(always)]\n//!     fn support_protocol_ext(&mut self) -> Option<ProtocolExtOps<Self>> {\n//!         Some(self) // will not compile unless `MyTarget` also implements `ProtocolExt`\n//!     }\n//!\n//!     // Mutually-exclusive extensions\n//!     #[inline(always)]\n//!     fn get_ext_a_or_b(&mut self) -> EitherOrExt<Self::Arch, Self::Error> {\n//!         EitherOrExt::ProtocolExtA(self)\n//!     }\n//! }\n//! ```\n//!\n//! > Please note the use of `#[inline(always)]` when enabling IDET methods.\n//! > While LLVM is usually smart enough to inline single-level IDETs (such as\n//! > in the example above), nested IDETs will often require a bit of \"help\"\n//! > from the `inline` directive to be correctly optimized.\n//!\n//! Now, here's where IDETs really shine: If the user didn't implement\n//! `ProtocolExt`, but _did_ try to enable the feature by overriding\n//! `support_protocol_ext` to return `Some(self)`, they'll get a compile-time\n//! error that looks something like this:\n//!\n//! ```text\n//! error[E0277]: the trait bound `MyTarget: ProtocolExt` is not satisfied\n//!   --> path/to/implementation.rs:44:14\n//!    |\n//! 44 |         Some(self)\n//!    |              ^^^^ the trait `ProtocolExt` is not implemented for `MyTarget`\n//!    |\n//!    = note: required for the cast to the object type `dyn ProtocolExt<Arch = ..., Error = ...>`\n//! ```\n//!\n//! The Rust compiler is preventing you from enabling a feature you haven't\n//! implemented _at compile time!_\n//!\n//! - (library) Is able to _query_ whether or not an extension is available,\n//!   _without_ having to actually invoke any method on the target!\n//!\n//! ```rust,ignore\n//! fn execute_protocol(mut target: impl Target) {\n//!     match target.support_protocol_ext() {\n//!         Some(ops) => ops.foo(),\n//!         None => { /* fallback when not enabled */ }\n//!     }\n//! }\n//! ```\n//!\n//! This is already pretty cool, but what's _even cooler_ is that if you take a\n//! look at the generated assembly of a monomorphized `execute_protocol` method\n//! (e.g: using godbolt.org), you'll find that the compiler is able to\n//! efficiently inline and devirtualize _all_ the calls to\n//! `support_protocol_ext` method, which in-turn allows the dead-code-eliminator\n//! to work its magic, and remove the unused branches from the generated code!\n//! i.e: If a target implemention didn't implement the `ProtocolExt` extension,\n//! then that `match` statement in `execute_protocol` would simply turn into a\n//! noop!\n//!\n//! If IDETs are something you're interested in, consider checking out\n//! [daniel5151/optional-trait-methods](https://github.com/daniel5151/optional-trait-methods)\n//! for some sample code that shows off the power of IDETs. It's not\n//! particularly polished, but it does includes code snippets which can be\n//! pasted into godbolt.org directly to confirm the optimizations described\n//! above, and a brief writeup which compares / contrasts alternatives to IDETs.\n//!\n//! Long story short: Optimizing compilers really are magic!\n//!\n//! #### Summary: The Benefits of IDETs\n//!\n//! IDETs solve the numerous issues and shortcomings that arise from the\n//! traditional single trait + \"optional\" methods approach:\n//!\n//! - **Compile-time enforcement of mutually-dependent methods**\n//!    - By grouping mutually-dependent methods behind a single extension trait\n//!      and marking them all as required methods, the Rust compiler is able to\n//!      catch missing mutually-dependent methods at compile time, with no need\n//!      for any runtime checks!\n//! - **Compile-time enforcement of mutually-exclusive methods**\n//!    - By grouping mutually-exclusive methods behind two extension traits, and\n//!      wrapping those in an `enum`, the API is able to document\n//!      mutually-exclusive functions _at the type-level_, in-turn enabling the\n//!      library to omit any runtime checks!\n//!    - _Note:_ Strictly speaking, this isn't really compile time\n//!      \"enforcement\", as there's nothing stopping an \"adversarial\"\n//!      implementation from implementing both sets of methods, and then\n//!      \"flipping\" between the two at runtime. Nonetheless, it serves as a good\n//!      guardrail.\n//! - **Enforce dead-code-elimination _without_ `cargo` feature flags**\n//!     - This is a really awesome trick: by wrapping code in an `if\n//!       target.support_protocol_ext().is_some()` block, it's possible to\n//!       specify _arbitrary_ blocks of code to be feature-dependent!\n//!     - This is used to great effect in `gdbstub` to optimize-out any packet\n//!       parsing / handler code for unimplemented protocol extensions.\n\nmacro_rules! doc_comment {\n    ($x:expr, $($tt:tt)*) => {\n        #[doc = $x]\n        $($tt)*\n    };\n}\n\nmacro_rules! define_ext {\n    ($extname:ident, $exttrait:ident) => {\n        doc_comment! {\n            concat!(\"See [`\", stringify!($exttrait), \"`](trait.\", stringify!($exttrait), \".html).\"),\n            pub type $extname<'a, T> =\n                &'a mut dyn $exttrait<Arch = <T as Target>::Arch, Error = <T as Target>::Error>;\n        }\n    };\n}\n\npub mod auxv;\npub mod base;\npub mod breakpoints;\npub mod catch_syscalls;\npub mod exec_file;\npub mod extended_mode;\npub mod flash;\npub mod host_info;\npub mod host_io;\npub mod libraries;\npub mod lldb_register_info_override;\npub mod memory_map;\npub mod monitor_cmd;\npub mod process_info;\npub mod section_offsets;\npub mod target_description_xml_override;\npub mod thread_extra_info;\npub mod tracepoints;\npub mod wasm;\n"
  },
  {
    "path": "src/target/ext/monitor_cmd.rs",
    "content": "//! Create custom target-specific debugging commands accessible via GDB's\n//! `monitor` command!\n\npub use crate::output;\npub use crate::outputln;\npub use crate::protocol::ConsoleOutput;\n\nuse crate::target::Target;\n\n/// Target Extension - Handle custom GDB `monitor` commands.\npub trait MonitorCmd: Target {\n    /// Handle custom commands sent using the `monitor` command.\n    ///\n    /// The GDB remote serial protocol includes a built-in mechanism to send\n    /// arbitrary commands to the remote stub: the `monitor` command. For\n    /// example, running `monitor dbg` from the GDB client will invoke\n    /// `handle_monitor_cmd` with `cmd = b\"dbg\"`.\n    ///\n    /// Commands are _not_ guaranteed to be valid UTF-8, hence the use of\n    /// `&[u8]` as opposed to `&str`.\n    ///\n    /// Intermediate console output can be written back to the GDB client using\n    /// the provided `ConsoleOutput` object + the\n    /// [`gdbstub::output!`](macro.output.html) macro.\n    ///\n    /// _Note:_ The maximum length of incoming commands is limited by the size\n    /// of the packet buffer provided to the [`GdbStub`](struct.GdbStub.html).\n    /// Specifically, commands can only be up to `(buf.len() - 10) / 2` bytes.\n    fn handle_monitor_cmd(&mut self, cmd: &[u8], out: ConsoleOutput<'_>)\n        -> Result<(), Self::Error>;\n}\n\ndefine_ext!(MonitorCmdOps, MonitorCmd);\n"
  },
  {
    "path": "src/target/ext/process_info.rs",
    "content": "//! (LLDB extension) Provide process information to the debugger.\n//!\n//! This allows for reporting key-value metadata, for example the current PID,\n//! target triple, endianness, and pointer size.\n//!\n//! This corresponds to the `qHostInfo` command in the LLDB extensions.\n\nuse crate::common::Endianness;\nuse crate::common::Pid;\nuse crate::target::Target;\n\n/// A response key-value pair to a [ProcessInfo::process_info] query.\n///\n/// A response consists of a list of key-value pairs, each of which is\n/// represented by one instance of this enum.\n///\n/// The allowed responses are documented in the [LLDB extension documentation].\n/// Not all supported responses are currently represented in this enum. If you\n/// need another one, please feel free to send a PR!\n///\n/// [LLDB extension documentation]:\n///     https://lldb.llvm.org/resources/lldbplatformpackets.html\n#[derive(Clone, Copy)]\n#[non_exhaustive]\npub enum ProcessInfoResponse<'a> {\n    /// The current process PID.\n    Pid(Pid),\n    /// The target triple for the debuggee, as a string.\n    Triple(&'a str),\n    /// The target endianness.\n    Endianness(Endianness),\n    /// The pointer size.\n    PointerSize(usize),\n}\n\n/// (LLDB extension) Target Extension - Provide process information.\npub trait ProcessInfo: Target {\n    /// Write the response to process-info query.\n    ///\n    /// Call `write_item` with each `InfoResponse` you wish to send.\n    fn process_info(\n        &self,\n        write_item: &mut dyn FnMut(&ProcessInfoResponse<'_>),\n    ) -> Result<(), Self::Error>;\n}\n\ndefine_ext!(ProcessInfoOps, ProcessInfo);\n"
  },
  {
    "path": "src/target/ext/section_offsets.rs",
    "content": "//! Get section/segment relocation offsets from the target.\n//!\n//! For some targets, sections may be relocated from their base address. As\n//! a result, the stub may need to tell GDB the final section addresses\n//! to ensure that debug symbols are resolved correctly after relocation.\n//!\n//! _Note:_ This extension corresponds to the `qOffsets` command, which is\n//! limited to reporting the offsets for code, data and bss, and is\n//! generally considered a legacy feature.\n//!\n//! For System-V architectures GDB may use the `qXfer:libraries-svr4:read`\n//! command to try to learn about loaded libraries and this can be implemented\n//! with the [`LibrariesSvr4`\n//! trait](crate::target::ext::libraries::LibrariesSvr4). Note that not all\n//! targets may query this and it may not be applicable in all situations\n//! either.\n//!\n//! For targets where library offsets are maintained externally (e.g. Windows)\n//! you should consider implementing the more flexible `qXfer:library:read`.\n//! See issue [#20](https://github.com/daniel5151/gdbstub/issues/20) for more\n//! info.\n//!\n//! For System-V architectures GDB is capable of extracting library offsets\n//! from memory if it knows the base address of the dynamic linker. The base\n//! address can be specified by either implementing this command or by including\n//! a `AT_BASE` entry in the response to the more modern `qXfer:auxv:read`\n//! command. See issue [#20](https://github.com/daniel5151/gdbstub/issues/20)\n//! for more info.\n\nuse crate::arch::Arch;\nuse crate::target::Target;\n\n/// Describes the offset the target loaded the image sections at, so the target\n/// can notify GDB that it needs to adjust the addresses of symbols.\n///\n/// GDB supports either section offsets, or segment addresses.\npub enum Offsets<U> {\n    /// Section offsets relative to their base addresses.\n    Sections {\n        /// The offset of the `.text` section.\n        text: U,\n        /// The offset of the `.data` section.\n        data: U,\n        /// The offset of the `.bss` section.\n        ///\n        /// _Note:_ GDB expects that `bss` is either `None` or equal to `data`.\n        bss: Option<U>,\n    },\n\n    /// Absolute addresses of the first two segments.\n    ///\n    /// _Note:_ any extra segments will kept at fixed offsets relative to the\n    /// last relocated segment.\n    Segments {\n        /// The absolute address of the first segment which conventionally\n        /// contains program code.\n        text_seg: U,\n        /// The absolute address of the second segment which conventionally\n        /// contains modifiable data.\n        data_seg: Option<U>,\n    },\n}\n\n/// Target Extension - Get section/segment relocation offsets from the target.\n///\n/// Corresponds to the `qOffset` command. See the [section_offset module\n/// documentation](index.html).\npub trait SectionOffsets: Target {\n    /// Return the target's current section (or segment) offsets.\n    fn get_section_offsets(&mut self) -> Result<Offsets<<Self::Arch as Arch>::Usize>, Self::Error>;\n}\n\ndefine_ext!(SectionOffsetsOps, SectionOffsets);\n"
  },
  {
    "path": "src/target/ext/target_description_xml_override.rs",
    "content": "//! Override the target description XML specified by `Target::Arch`.\nuse crate::target::Target;\nuse crate::target::TargetResult;\n\n/// Target Extension - Override the target description XML specified by\n/// `Target::Arch`.\n///\n/// _Note:_ Unless you're working with a particularly dynamic,\n/// runtime-configurable target, it's unlikely that you'll need to implement\n/// this extension.\npub trait TargetDescriptionXmlOverride: Target {\n    /// Read a target's description XML file at the specified `annex`.\n    ///\n    /// The \"root\" `annex` will always be `b\"target.xml\"`, though advanced\n    /// targets may choose to split `target.xml` into multiple files via the\n    /// the `<xi:include href=\"other_file.xml\"/>` XML tag. If the GDB client\n    /// encounter any such tags, it will re-invoke this handler with `annex`\n    /// specified to point to `b\"other_file.xml\"`.\n    ///\n    /// Refer to the\n    /// [target_description_xml](crate::arch::Arch::target_description_xml)\n    /// docs for more info.\n    ///\n    /// Return the number of bytes written into `buf` (which may be less than\n    /// `length`).\n    ///\n    /// If `offset` is greater than the length of the underlying data, return\n    /// `Ok(0)`.\n    fn target_description_xml(\n        &self,\n        annex: &[u8],\n        offset: u64,\n        length: usize,\n        buf: &mut [u8],\n    ) -> TargetResult<usize, Self>;\n}\n\ndefine_ext!(\n    TargetDescriptionXmlOverrideOps,\n    TargetDescriptionXmlOverride\n);\n"
  },
  {
    "path": "src/target/ext/thread_extra_info.rs",
    "content": "//! Provide extra information for a thread\nuse crate::common::Tid;\nuse crate::target::Target;\n\n/// Target Extension - Provide extra information for a thread\npub trait ThreadExtraInfo: Target {\n    /// Provide extra information about a thread\n    ///\n    /// GDB queries for extra information for a thread as part of the\n    /// `info threads` command.  This function will be called once\n    /// for each active thread.\n    ///\n    /// A string can be copied into `buf` that will then be displayed\n    /// to the client.  The string is displayed as `(value)`, such as:\n    ///\n    /// `Thread 1.1 (value)`\n    ///\n    /// Return the number of bytes written into `buf`.\n    fn thread_extra_info(&self, tid: Tid, buf: &mut [u8]) -> Result<usize, Self::Error>;\n}\n\ndefine_ext!(ThreadExtraInfoOps, ThreadExtraInfo);\n"
  },
  {
    "path": "src/target/ext/tracepoints.rs",
    "content": "//! Support for\n//! [Tracepoint](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Tracepoints.html)\n//! extensions.\n//!\n//! ## Implementation Status\n//!\n//! Most fundamental tracepoint operations are supported, but there quite a few\n//! packets / APIs that are not yet implemented, such as:\n//!\n//! - Fast Tracepoints\n//! - Tracepoint Conditions\n//! - Trace State Variables\n//!\n//! If you are interested in extending this API to support these additional\n//! features, please consider opening an Issue / PR on the `gdbstub` GitHub\n//! repo.\n\nuse crate::target::Arch;\nuse crate::target::Target;\nuse crate::target::TargetResult;\n#[cfg(feature = \"alloc\")]\nuse alloc::borrow::ToOwned;\nuse managed::ManagedSlice;\n\n/// A tracepoint, identified by a unique number.\n#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]\npub struct Tracepoint(pub usize);\n\n/// A state variable, identified by a unique number.\n#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]\npub struct StateVariable(usize);\n\n/// Describes a new tracepoint. GDB may ask for the state of current\n/// tracepoints, which are described with this same structure.\n#[derive(Debug, Clone)]\npub struct NewTracepoint<U> {\n    /// The tracepoint number\n    pub number: Tracepoint,\n    /// If the tracepoint is enabled or not\n    pub enabled: bool,\n    /// The address the tracepoint is set at.\n    pub addr: U,\n    /// The tracepoint's step count\n    pub step_count: u64,\n    /// The tracepoint's pass count.\n    pub pass_count: u64,\n}\n\n/// Describes how to collect information for a trace frame when the tracepoint\n/// it is attached to is hit. A tracepoint may have more than one action\n/// attached.\n#[derive(Debug)]\npub enum TracepointAction<'a, U> {\n    /// Collect registers.\n    Registers {\n        /// A bitmask of which registers should be collected. The least\n        /// significant bit is numberered zero. Note that the mask may\n        /// be larger than the word length.\n        mask: ManagedSlice<'a, u8>,\n    },\n    /// Collect memory.`len` bytes of memory starting at the address in register\n    /// number `basereg`, plus `offset`. If `basereg` is None, then treat it\n    /// as a fixed address.\n    Memory {\n        /// If `Some`, then calculate the address of memory to collect relative\n        /// to the value of this register number. If `None` then memory\n        /// should be collected from a fixed address.\n        basereg: Option<u64>,\n        /// The offset used to calculate the address to collect memory from.\n        offset: U,\n        /// How many bytes of memory to collect.\n        length: u64,\n    },\n    /// Collect data according to an agent bytecode program.\n    Expression {\n        /// The GDB agent bytecode program to evaluate.\n        expr: ManagedSlice<'a, u8>,\n    },\n}\n\n/// What type of information a tracepoint source item is about.\n#[derive(Debug, Clone, Copy)]\npub enum TracepointSourceType {\n    /// Describes the location the tracepoint is at.\n    At,\n    /// Describes the conditional expression for a tracepoint.\n    Cond,\n    /// Describes the action command that should be executed when a tracepoint\n    /// is hit.\n    Cmd,\n}\n\n/// Source string fragment for a tracepoint. A tracepoint may have more than one\n/// source string, such as being describes by one source string for the location\n/// and another for the actions, or by GDB splitting a larger source string\n/// into multiple fragments. GDB may ask for the source of current tracepoints,\n/// which are described by this same structure.\n#[derive(Debug)]\npub struct SourceTracepoint<'a, U> {\n    /// The tracepoint that the source string is specifying.\n    pub number: Tracepoint,\n    /// The PC address of the tracepoint that the source string is specifying.\n    pub addr: U,\n    /// What type of information for this tracepoint the string fragment is\n    /// about.\n    pub kind: TracepointSourceType,\n    /// The offset in bytes within the overall source string this fragment is\n    /// within.\n    pub start: u32,\n    /// The total length of the overall source string this fragment is within.\n    pub slen: u32,\n    /// The data for this source string fragment.\n    pub bytes: ManagedSlice<'a, u8>,\n}\n\n#[cfg(feature = \"alloc\")]\nimpl<U: Copy> SourceTracepoint<'_, U> {\n    /// Allocate an owned copy of this structure.\n    pub fn get_owned<'b>(&self) -> SourceTracepoint<'b, U> {\n        SourceTracepoint {\n            number: self.number,\n            addr: self.addr,\n            kind: self.kind,\n            start: self.start,\n            slen: self.slen,\n            bytes: ManagedSlice::Owned(self.bytes.to_owned()),\n        }\n    }\n}\n\n#[cfg(feature = \"alloc\")]\nimpl<U: Copy> TracepointAction<'_, U> {\n    /// Allocate an owned copy of this structure.\n    pub fn get_owned<'b>(&self) -> TracepointAction<'b, U> {\n        use core::ops::Deref;\n        match self {\n            TracepointAction::Registers { mask } => TracepointAction::Registers {\n                mask: ManagedSlice::Owned(mask.deref().into()),\n            },\n            TracepointAction::Memory {\n                basereg,\n                offset,\n                length,\n            } => TracepointAction::Memory {\n                basereg: *basereg,\n                offset: *offset,\n                length: *length,\n            },\n            TracepointAction::Expression { expr } => TracepointAction::Expression {\n                expr: ManagedSlice::Owned(expr.deref().into()),\n            },\n        }\n    }\n}\n\n/// The running state of a trace experiment.\n#[derive(Debug)]\npub enum ExperimentStatus<'a> {\n    /// The experiment is currently running\n    Running,\n    /// The experiment is not currently running, with no more information given\n    /// as to why.\n    NotRunning,\n    /// No trace has been ran yet.\n    NotRun,\n    /// The trace was stopped by the user. May contain an optional user-supplied\n    /// stop reason.\n    Stop(Option<&'a [u8]>),\n    /// The trace stopped because the buffer is full.\n    Full,\n    /// The trace stopped because GDB disconnect from the target.\n    Disconnected,\n    /// The trace stopped because the specified tracepoint exceeded its pass\n    /// count.\n    PassCount(Tracepoint),\n    /// The trace stopped because the specified tracepoint had an error.\n    Error(&'a [u8], Tracepoint),\n    /// The trace stopped for some other reason.\n    Unknown,\n}\n\n/// An explanation of some detail of the currently running trace experiment.\n#[derive(Debug)]\npub enum ExperimentExplanation<'a> {\n    /// The number of trace frames in the buffer.\n    Frames(usize),\n    /// The total number of trace frames created during the run. This may be\n    /// larger than the trace frame count, if the buffer is circular.\n    Created(usize),\n    /// The total size of the trace buffer, in bytes.\n    Size(usize),\n    /// The number of bytes still unused in the buffer.\n    Free(usize),\n    /// The value of the circular trace buffer flag. True means the trace buffer\n    /// is circular and old trace frames will be discarded if necessary to\n    /// make room, false means that the trace buffer is linear and may fill\n    /// up.\n    Circular(bool),\n    /// The value of the disconnected tracing flag. True means that tracing will\n    /// continue after GDB disconnects, false means that the trace run will\n    /// stop.\n    DisconnectedTracing(bool),\n\n    /// Report a raw string as a trace status explanation.\n    Other(&'a str),\n}\n\n/// Shape of the trace buffer\n#[derive(Debug)]\npub enum BufferShape {\n    /// A circular trace buffer\n    Circular,\n    /// A linear trace buffer\n    Linear,\n}\n\n/// Configuration for the trace buffer.\n#[derive(Debug)]\npub enum TraceBufferConfig {\n    /// Set the buffer's shape.\n    Shape(BufferShape),\n    /// Set the buffer's size in bytes. If None, the target should use whatever\n    /// size it prefers.\n    Size(Option<u64>),\n}\n\n/// Request to select a new frame from the trace buffer.\n#[derive(Debug)]\npub enum FrameRequest<U> {\n    /// Select the specified tracepoint frame in the buffer.\n    Select(u64),\n    /// Select a tracepoint frame that has a specified PC after the currently\n    /// selected frame.\n    AtPC(U),\n    /// Select a tracepoint frame that hit a specified tracepoint after the\n    /// currently selected frame.\n    Hit(Tracepoint),\n    /// Select a tramepoint frame that has a PC between a start (inclusive) and\n    /// end (inclusive).\n    Between(U, U),\n    /// Select a tracepoint frame that has a PC outside the range of addresses\n    /// (exclusive).\n    Outside(U, U),\n}\n\n/// Describes a detail of a frame from the trace buffer\n#[derive(Debug)]\npub enum FrameDescription {\n    /// The frame is at the specified index in the trace buffer\n    FrameNumber(u64),\n    /// The frame is a hit of the specified tracepoint\n    Hit(Tracepoint),\n}\n\n/// The state of a tracepoint.\n#[derive(Debug)]\npub struct TracepointStatus {\n    /// The number of times a tracepoint has been hit in a trace run.\n    pub hit_count: u64,\n    /// The number of bytes the tracepoint accounts for in the trace buffer.\n    pub bytes_used: u64,\n}\n\n#[derive(Debug)]\npub(crate) enum TracepointEnumerateCursor<U> {\n    New { tp: Tracepoint, addr: U },\n    Action { tp: Tracepoint, addr: U, step: u64 },\n    Source { tp: Tracepoint, addr: U, step: u64 },\n}\n\n/// The current state of enumerating tracepoints. gdbstub uses it as an opaque\n/// bookkeeping record for what information has already been reported when GDB\n/// downloads tracepoints on attachment.\n#[derive(Debug, Default)]\npub struct TracepointEnumerateState<U> {\n    pub(crate) cursor: Option<TracepointEnumerateCursor<U>>,\n}\n\n/// How to transition the [`TracepointEnumerateState`] state machine after\n/// reporting an item for tracepoint enumeration.\n#[derive(Debug)]\npub enum TracepointEnumerateStep<U> {\n    /// The current tracepoint that is being enumerated has more actions.\n    ///\n    /// Increments the step counter if the state machine was already\n    /// enumerating actions, otherwise it is reset to 0 and GDB will start\n    /// enumerating actions.\n    Action,\n    /// The current tracepoint that is being enumerated has more source strings.\n    ///\n    /// Increments the step counter if the state machine was already\n    /// enumerating sources strings, otherwise it is reset to 0 and GDB will\n    /// start enumerating source strings.\n    ///\n    /// Targets should only return this transition if they implement\n    /// [`Tracepoints::support_tracepoint_source`], or else it indicates an\n    /// error and the state machine iteration will stop.\n    Source,\n    /// The current tracepoint is done being enumerated, and GDB should next\n    /// enumerate a different one.\n    Next {\n        /// The next tracepoint to move to.\n        tp: Tracepoint,\n        /// The PC of the next tracepoint.\n        addr: U,\n    },\n    /// All tracepoints have been enumerated, and the state machine is done.\n    Done,\n}\n\n/// Target Extension - Provide tracepoints.\npub trait Tracepoints: Target {\n    /// Clear any saved tracepoints and empty the trace frame buffer.\n    fn tracepoints_init(&mut self) -> TargetResult<(), Self>;\n\n    /// Begin creating a new tracepoint according to the description `tdp`.\n    fn tracepoint_create_begin(\n        &mut self,\n        tdp: NewTracepoint<<Self::Arch as Arch>::Usize>,\n    ) -> TargetResult<(), Self>;\n    /// Configure an existing tracepoint, appending an additional action to its\n    /// definition.\n    ///\n    /// This method will only ever be called in-between\n    /// [`Tracepoints::tracepoint_create_begin`] and\n    /// [`Tracepoints::tracepoint_create_complete`] invocations for a new\n    /// tracepoint.\n    fn tracepoint_create_continue(\n        &mut self,\n        tp: Tracepoint,\n        action: &TracepointAction<'_, <Self::Arch as Arch>::Usize>,\n    ) -> TargetResult<(), Self>;\n    /// Complete the creation of a tracepoint. All of its actions are expected\n    /// to have been received.\n    ///\n    /// This method will only ever be called after all of the\n    /// [`Tracepoints::tracepoint_create_begin`] and\n    /// [`Tracepoints::tracepoint_create_continue`] invocations for a new\n    /// tracepoint.\n    fn tracepoint_create_complete(&mut self, tp: Tracepoint) -> TargetResult<(), Self>;\n    /// Request the status of tracepoint `tp` at address `addr`.\n    ///\n    /// Returns a [`TracepointStatus`] with the requested information.\n    fn tracepoint_status(\n        &self,\n        tp: Tracepoint,\n        addr: <Self::Arch as Arch>::Usize,\n    ) -> TargetResult<TracepointStatus, Self>;\n\n    /// Return the stub's tracepoint enumeration state. gdbstub internally\n    /// uses this state to support GDB downloading tracepoints on attachment,\n    /// but requires the target implementation to provide storage for it.\n    ///\n    /// The state instance that this returns should be the same across multiple\n    /// calls and unmodified, or else gdbstub will be unable to transition the\n    /// state machine during enumeration correctly.\n    ///\n    /// For the average trait implementations, this will look like:\n    ///\n    /// ```rust,ignore\n    /// struct MyTarget {\n    ///    tracepoint_enumerate_state: TracepointEnumerateState,\n    ///    ...\n    /// }\n    ///\n    /// impl MyTarget {\n    ///    fn new() -> Self {\n    ///        MyTarget {\n    ///            tracepoint_enumerate_state: TracepointEnumerateState::default(),\n    ///            ...\n    ///        }\n    ///    }\n    /// }\n    ///\n    /// impl Tracepoints for MyTarget {\n    ///    fn tracepoint_enumerate_state(\n    ///        &mut self,\n    ///    ) -> &mut TracepointEnumerateState<<Self::Arch as Arch>::Usize> {\n    ///        &mut self.tracepoint_enumerate_state\n    ///    }\n    /// }\n    /// ```\n    fn tracepoint_enumerate_state(\n        &mut self,\n    ) -> &mut TracepointEnumerateState<<Self::Arch as Arch>::Usize>;\n\n    /// Begin enumerating a new tracepoint. If `tp` is None, then the first\n    /// tracepoint recorded should be reported via `f`, otherwise the requested\n    /// tracepoint should be.\n    ///\n    /// After reporting a tracepoint, [`TracepointEnumerateStep`] describes what\n    /// information is still available. Unlike tracepoint *creation*, which is\n    /// driven by GDB, for *enumeration* it's the responsibility of the trait\n    /// implementation to correctly sequence the state transitions so that\n    /// GDB is able to enumerate all of the information for the tracepoints the\n    /// implementation has saved via the various `tracepoint_enumerate_*`\n    /// methods.\n    ///\n    /// For the average implementation, it should report the requested\n    /// tracepoint, and then return\n    /// [`TracepointEnumerateStep::Action`] to transition to reporting\n    /// actions for the tracepoint. If the trait implements\n    /// [`TracepointSource`], it can instead return\n    /// [`TracepointEnumerateStep::Source`] to begin reporting source items\n    /// instead.\n    fn tracepoint_enumerate_start(\n        &mut self,\n        tp: Option<Tracepoint>,\n        f: &mut dyn FnMut(&NewTracepoint<<Self::Arch as Arch>::Usize>),\n    ) -> TargetResult<TracepointEnumerateStep<<Self::Arch as Arch>::Usize>, Self>;\n    /// Enumerate an action attached to a tracepoint. `step` is which action\n    /// item is being asked for, so that the implementation can respond with\n    /// multiple items across multiple function calls. Each action should be\n    /// reported via `f`.\n    ///\n    /// After reporting a tracepoint action, [`TracepointEnumerateStep`]\n    /// describes what information will next be enumerated: this may be\n    /// [`TracepointEnumerateStep::Action`] if there are more actions that\n    /// still need to be reported, for example.\n    fn tracepoint_enumerate_action(\n        &mut self,\n        tp: Tracepoint,\n        step: u64,\n        f: &mut dyn FnMut(&TracepointAction<'_, <Self::Arch as Arch>::Usize>),\n    ) -> TargetResult<TracepointEnumerateStep<<Self::Arch as Arch>::Usize>, Self>;\n\n    /// Reconfigure the trace buffer to include or modify an attribute.\n    fn trace_buffer_configure(&mut self, config: TraceBufferConfig) -> TargetResult<(), Self>;\n\n    /// Read up to `len` bytes from the trace buffer, starting at `offset`.\n    /// The trace buffer is treated as a contiguous collection of traceframes,\n    /// as per [GDB's trace file format](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Trace-File-Format.html).\n    /// The function `f` should be called to report as many bytes from\n    /// the trace buffer that were requested as possible.\n    fn trace_buffer_request(\n        &mut self,\n        offset: u64,\n        len: usize,\n        f: &mut dyn FnMut(&mut [u8]),\n    ) -> TargetResult<(), Self>;\n\n    /// Return the status of the current trace experiment.\n    fn trace_experiment_status(\n        &self,\n        report: &mut dyn FnMut(ExperimentStatus<'_>),\n    ) -> TargetResult<(), Self>;\n    /// List any statistical information for the current trace experiment, by\n    /// calling `report` with each [`ExperimentExplanation`] item.\n    fn trace_experiment_info(\n        &self,\n        report: &mut dyn FnMut(ExperimentExplanation<'_>),\n    ) -> TargetResult<(), Self>;\n    /// Start a new trace experiment.\n    fn trace_experiment_start(&mut self) -> TargetResult<(), Self>;\n    /// Stop the currently running trace experiment.\n    fn trace_experiment_stop(&mut self) -> TargetResult<(), Self>;\n\n    /// Select a new frame in the trace buffer. The target should attempt to\n    /// fulfill the request according to the [`FrameRequest`]. If it's\n    /// successful it should call `report` with a series of calls describing\n    /// the found frame, and then record it as the currently selected frame.\n    /// Future register and memory requests should be fulfilled from the\n    /// currently selected frame.\n    fn select_frame(\n        &mut self,\n        frame: FrameRequest<<Self::Arch as Arch>::Usize>,\n        report: &mut dyn FnMut(FrameDescription),\n    ) -> TargetResult<(), Self>;\n\n    /// Support for setting and enumerating the source strings for tracepoint\n    /// actions.\n    ///\n    /// The GDB client will attempt to download tracepoints when it attaches to\n    /// the stub, which will trigger the\n    /// `Tracepoints::tracepoint_enumerate_*` state machine enumeration\n    /// codepaths. GDB depends on accurately enumerating source strings for\n    /// tracepoints, or else for agent bytecode programs (which are most\n    /// non-trivial `collect` actions) it won't be able to parse them and\n    /// throw away the actions attached to the tracepoint. [`TracepointSource`]\n    /// allows for recording and then reporting action source\n    /// strings for targets that want to fully support GDB tracepoint\n    /// downloading.\n    #[inline(always)]\n    fn support_tracepoint_source(&mut self) -> Option<TracepointSourceOps<'_, Self>> {\n        None\n    }\n}\n\n/// Target Extension - Support setting and enumerating source strings for\n/// tracepoint actions.\n///\n/// GDB requires source strings to be accurately reported back to it when it\n/// attaches to a target in order to download tracepoints, or else it will\n/// locally not be able to parse them and throw away the attached actions.\n///\n/// Downloading tracepoints is only triggered for new GDB clients attaching to a\n/// stub that already has tracepoints loaded, however. An example use case would\n/// be one GDB client attaching, creating tracepoints, disconnecting, and then a\n/// new GDB client starting and connecting to the stub to download the loaded\n/// tracepoints. If supporting that behavior is unimportant and you only need to\n/// work with a single GDB session, it is safe to not implement this extension.\npub trait TracepointSource: Tracepoints {\n    /// Configure an existing tracepoint, appending a new source string\n    /// fragment.\n    fn tracepoint_attach_source(\n        &mut self,\n        src: SourceTracepoint<'_, <Self::Arch as Arch>::Usize>,\n    ) -> TargetResult<(), Self>;\n\n    /// Enumerate the source strings that describe a tracepoint. `step` is which\n    /// source string is being asked for, so that the implementation can\n    /// respond with multiple items across multiple function calls. Each\n    /// source string should be reported via `f`.\n    ///\n    /// After reporting a tracepoint source string, [`TracepointEnumerateStep`]\n    /// describes what source string will next be enumerated.\n    fn tracepoint_enumerate_source(\n        &mut self,\n        tp: Tracepoint,\n        step: u64,\n        f: &mut dyn FnMut(&SourceTracepoint<'_, <Self::Arch as Arch>::Usize>),\n    ) -> TargetResult<TracepointEnumerateStep<<Self::Arch as Arch>::Usize>, Self>;\n}\n\ndefine_ext!(TracepointsOps, Tracepoints);\ndefine_ext!(TracepointSourceOps, TracepointSource);\n"
  },
  {
    "path": "src/target/ext/wasm.rs",
    "content": "//! (LLDB extension) Provide Wasm-specific actions for the target.\n//!\n//! ### Address Encoding\n//!\n//! LLDB's Wasm extensions to the GDB RSP use a specific encoding for addresses,\n//! both for commands in this extension trait, as well as for commands in the\n//! base protocol (e.g. for reading and writing memory and setting breakpoints).\n//!\n//! The need for this scheme arises from the fact that Wasm is natively\n//! \"multimemory\": there can be many code modules, and many linear memories, and\n//! each is a native entity (rather than mapped into a larger single address\n//! space) in the VM definition. The LLDB GDB RSP extensions map these native\n//! entities into an address space where the upper 32 bits encode the index of a\n//! particular Wasm code module or linear (data) memory and the lower 32 bits\n//! encode an offset.\n//!\n//! See the [LLDB source code] (particularly `WasmAddressType` and\n//! `wasm_addr_t`) for a description of the encoding of the PC values.\n//!\n//! [LLDB source code]:\n//!     https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/Process/wasm/ProcessWasm.h\n//!\n//! An implementation of this address encoding/decoding can be found in the\n//! `gdbstub_arch` crate in `gdbstub_arch::wasm::addr`.\n\nuse crate::common::Tid;\nuse crate::target::Target;\n\n/// (LLDB extension) Target Extension - perform Wasm-specific actions.\npub trait Wasm: Target {\n    /// Get the Wasm call stack for a given thread.\n    ///\n    /// The addresses provided for the PC at each frame should be encoded as per\n    /// the [Wasm address encoding].\n    ///\n    /// To avoid allocation, the call stack PCs should be returned to the caller\n    /// by calling the given callback, in order from innermost (most recently\n    /// called) frame to outermost.\n    ///\n    /// [Wasm address encoding]: `self#Address_Encoding`\n    fn wasm_call_stack(&self, tid: Tid, next_pc: &mut dyn FnMut(u64)) -> Result<(), Self::Error>;\n\n    /// Get the Wasm local for a given thread, frame index, and local index.\n    ///\n    /// The Wasm local's value should be placed into `buf`, and the length\n    /// should be returned. If the Wasm local or frame does not exist, this\n    /// method should return `0`.\n    ///\n    /// `buf` will be long enough to allow for the largest possible supported\n    /// Wasm value (i.e., at least a `v128` SIMD value). Values should be\n    /// encoded in little-endian format with their native length (e.g., 4 bytes\n    /// for a Wasm `i32` or `f32` type, or 8 bytes for a Wasm `i64` or `f64`\n    /// type).\n    fn read_wasm_local(\n        &self,\n        tid: Tid,\n        frame: usize,\n        local: usize,\n        buf: &mut [u8],\n    ) -> Result<usize, Self::Error>;\n\n    /// Get the Wasm operand-stack value for a given thread, frame index, and\n    /// stack index. Top-of-stack is index 0, and values below that have\n    /// incrementing indices.\n    ///\n    /// The Wasm operand's value should be placed into `buf`, and the length\n    /// should be returned. If the Wasm local or frame does not exist, this\n    /// method should return `0`.\n    ///\n    /// `buf` will be long enough to allow for the largest possible supported\n    /// Wasm value (i.e., at least a `v128` SIMD value). Values should be\n    /// encoded in little-endian format with their native length (e.g., 4 bytes\n    /// for a Wasm `i32` or `f32` type, or 8 bytes for a Wasm `i64` or `f64`\n    /// type).\n    fn read_wasm_stack(\n        &self,\n        tid: Tid,\n        frame: usize,\n        index: usize,\n        buf: &mut [u8],\n    ) -> Result<usize, Self::Error>;\n\n    /// Get the Wasm global value for a given thread, frame, and global index.\n    /// The global index is relative to the module whose function corresponds to\n    /// that frame.\n    ///\n    /// The Wasm global's value should be placed into `buf`, and the length\n    /// should be returned. If the Wasm local or frame does not exist, this\n    /// method should return `0`.\n    ///\n    /// `buf` will be long enough to allow for the largest possible supported\n    /// Wasm value (i.e., at least a `v128` SIMD value). Values should be\n    /// encoded in little-endian format with their native length (e.g., 4 bytes\n    /// for a Wasm `i32` or `f32` type, or 8 bytes for a Wasm `i64` or `f64`\n    /// type).\n    fn read_wasm_global(\n        &self,\n        tid: Tid,\n        frame: usize,\n        global: usize,\n        buf: &mut [u8],\n    ) -> Result<usize, Self::Error>;\n}\n\ndefine_ext!(WasmOps, Wasm);\n"
  },
  {
    "path": "src/target/mod.rs",
    "content": "//! The core [`Target`] trait, and all its various protocol extension traits.\n//!\n//! The [`Target`] trait describes how to control and modify a system's\n//! execution state during a GDB debugging session, and serves as the\n//! primary bridge between `gdbstub`'s generic protocol implementation and a\n//! target's project/platform-specific code.\n//!\n//! **`Target` is the most important trait in `gdbstub`, and must be implemented\n//! by all consumers of the library!**\n//!\n//! # Implementing `Target`\n//!\n//! `gdbstub` uses a technique called [\"Inlineable Dyn Extension Traits\"](ext)\n//! (IDETs) to expose an ergonomic and extensible interface to the GDB protocol.\n//! It's not a very common pattern, and can seem a little \"weird\" at first\n//! glance, but IDETs are actually very straightforward to use!\n//!\n//! **TL;DR:** Whenever you see a method that returns something that looks like\n//! `Option<ProtocolExtOps>`, you can enable that protocol extension by\n//! implementing the `ProtocolExt` type on your target, and overriding the\n//! `Option<ProtocolExtOps>` method to return `Some(self)`.\n//!\n//! Please refer to the [documentation in the `ext` module](ext) for more\n//! information on IDETs, including a more in-depth explanation of how they\n//! work, and how `Target` leverages them to provide fine grained control over\n//! enabled protocol features.\n//!\n//! ## Associated Types\n//!\n//! - The [`Target::Arch`](trait.Target.html#associatedtype.Arch) associated\n//!   type encodes information about the target's architecture, such as its\n//!   pointer size, register layout, etc... `gdbstub` comes with several\n//!   built-in architecture definitions, which can be found under the\n//!   [`arch`](../arch/index.html) module.\n//!\n//! - The [`Target::Error`](trait.Target.html#associatedtype.Error) associated\n//!   type allows implementors to plumb-through their own project-specific fatal\n//!   error type into the `Target` trait. This is a big-boost to library\n//!   ergonomics, as it enables consumers of `gdbstub` to preserve\n//!   target-specific context while using `gdbstub`, without having to do any\n//!   \"error-stashing\".\n//!\n//! For example: consider an emulated target where certain devices might return\n//! a `MyEmuError::ContractViolation` error whenever they're accessed\n//! \"improperly\" (e.g: setting registers in the wrong order). By setting `type\n//! Error = MyEmuError`, the method signature of the `Target`'s `resume` method\n//! becomes `fn resume(&mut self, ...) -> Result<_, MyEmuError>`, which makes it\n//! possible to preserve the target-specific error while using `gdbstub`!\n//!\n//! ## Required Methods (Base Protocol)\n//!\n//! A minimal `Target` implementation only needs to implement a single method:\n//! [`Target::base_ops`](trait.Target.html#tymethod.base_ops). This method is\n//! used to select which set of [`base`](crate::target::ext::base)\n//! debugging operations will be used to control the target. These are\n//! fundamental operations such as reading/writing memory, etc...\n//!\n//! All other methods are entirely optional! Check out the\n//! [`ext`](ext#modules) module for a full list of currently supported protocol\n//! extensions.\n//!\n//! ## Optional Protocol Extensions\n//!\n//! The GDB protocol is _massive_, and there are plenty of optional protocol\n//! extensions that targets can implement to enhance the base debugging\n//! experience.\n//!\n//! These protocol extensions range from relatively mundane things such as\n//! setting/removing breakpoints or reading/writing individual registers, but\n//! also include fancy things such as support for time travel debugging, running\n//! shell commands remotely, or even performing file IO on the target!\n//!\n//! `gdbstub` uses a somewhat unique approach to exposing these many features,\n//! called **Inlinable Dyn Extension Traits (IDETs)**. While this might sound a\n//! bit daunting, the API is actually quite straightforward, and described in\n//! great detail under the [`ext` module's documentation](ext).\n//!\n//! After getting the base protocol up and running, do take a moment to skim\n//! through and familiarize yourself with the [many different protocol\n//! extensions](ext# modules) that `gdbstub` implements. There are some really\n//! nifty ones that you might not even realize you need!\n//!\n//! As a suggestion on where to start, consider implementing some of the\n//! breakpoint related extensions under\n//! [`breakpoints`](crate::target::ext::breakpoints). While setting/removing\n//! breakpoints is technically an \"optional\" part of the GDB protocol, I'm sure\n//! you'd be hard pressed to find a debugger that doesn't support breakpoints.\n//!\n//! ### Note: Missing Protocol Extensions\n//!\n//! `gdbstub`'s development is guided by the needs of its contributors, with\n//! new features being added on an \"as-needed\" basis.\n//!\n//! If there's a GDB protocol extensions you're interested in that hasn't been\n//! implemented in `gdbstub` yet, (e.g: remote filesystem access, tracepoint\n//! support, etc...), consider opening an issue / filing a PR on the\n//! [`gdbstub` GitHub repo](https://github.com/daniel5151/gdbstub/).\n//!\n//! Check out the [GDB Remote Configuration Docs](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Configuration.html)\n//! for a table of GDB commands + their corresponding Remote Serial Protocol\n//! packets.\n//!\n//! ### Example: A fairly minimal Single Threaded `Target`\n//!\n//! This example includes a handful of required and optional target features,\n//! and shows off the basics of how to work with IDETs.\n//!\n//! ```rust\n//! use gdbstub::common::Signal;\n//! use gdbstub::target::{Target, TargetResult};\n//! use gdbstub::target::ext::base::BaseOps;\n//! use gdbstub::target::ext::base::singlethread::{\n//!     SingleThreadResumeOps, SingleThreadSingleStepOps\n//! };\n//! use gdbstub::target::ext::base::singlethread::{\n//!     SingleThreadBase, SingleThreadResume, SingleThreadSingleStep\n//! };\n//! use gdbstub::target::ext::breakpoints::{Breakpoints, SwBreakpoint};\n//! use gdbstub::target::ext::breakpoints::{BreakpointsOps, SwBreakpointOps};\n//!\n//! struct MyTarget;\n//!\n//! impl Target for MyTarget {\n//!     type Error = ();\n//!     type Arch = gdbstub_arch::arm::Armv4t; // as an example\n//!\n//!     #[inline(always)]\n//!     fn base_ops(&mut self) -> BaseOps<Self::Arch, Self::Error> {\n//!         BaseOps::SingleThread(self)\n//!     }\n//!\n//!     // opt-in to support for setting/removing breakpoints\n//!     #[inline(always)]\n//!     fn support_breakpoints(&mut self) -> Option<BreakpointsOps<Self>> {\n//!         Some(self)\n//!     }\n//! }\n//!\n//! impl SingleThreadBase for MyTarget {\n//!     fn read_registers(\n//!         &mut self,\n//!         regs: &mut gdbstub_arch::arm::reg::ArmCoreRegs,\n//!     ) -> TargetResult<(), Self> { todo!() }\n//!\n//!     fn write_registers(\n//!         &mut self,\n//!         regs: &gdbstub_arch::arm::reg::ArmCoreRegs\n//!     ) -> TargetResult<(), Self> { todo!() }\n//!\n//!     fn read_addrs(\n//!         &mut self,\n//!         start_addr: u32,\n//!         data: &mut [u8],\n//!     ) -> TargetResult<usize, Self> { todo!() }\n//!\n//!     fn write_addrs(\n//!         &mut self,\n//!         start_addr: u32,\n//!         data: &[u8],\n//!     ) -> TargetResult<(), Self> { todo!() }\n//!\n//!     // most targets will want to support at resumption as well...\n//!\n//!     #[inline(always)]\n//!     fn support_resume(&mut self) -> Option<SingleThreadResumeOps<Self>> {\n//!         Some(self)\n//!     }\n//! }\n//!\n//! impl SingleThreadResume for MyTarget {\n//!     fn resume(\n//!         &mut self,\n//!         signal: Option<Signal>,\n//!     ) -> Result<(), Self::Error> { todo!() }\n//!\n//!     // ...and if the target supports resumption, it'll likely want to support\n//!     // single-step resume as well\n//!\n//!     #[inline(always)]\n//!     fn support_single_step(\n//!         &mut self\n//!     ) -> Option<SingleThreadSingleStepOps<'_, Self>> {\n//!         Some(self)\n//!     }\n//! }\n//!\n//! impl SingleThreadSingleStep for MyTarget {\n//!     fn step(\n//!         &mut self,\n//!         signal: Option<Signal>,\n//!     ) -> Result<(), Self::Error> { todo!() }\n//! }\n//!\n//! impl Breakpoints for MyTarget {\n//!     // there are several kinds of breakpoints - this target uses software breakpoints\n//!     #[inline(always)]\n//!     fn support_sw_breakpoint(&mut self) -> Option<SwBreakpointOps<Self>> {\n//!         Some(self)\n//!     }\n//! }\n//!\n//! impl SwBreakpoint for MyTarget {\n//!     fn add_sw_breakpoint(\n//!         &mut self,\n//!         addr: u32,\n//!         kind: gdbstub_arch::arm::ArmBreakpointKind,\n//!     ) -> TargetResult<bool, Self> { todo!() }\n//!\n//!     fn remove_sw_breakpoint(\n//!         &mut self,\n//!         addr: u32,\n//!         kind: gdbstub_arch::arm::ArmBreakpointKind,\n//!     ) -> TargetResult<bool, Self> { todo!() }\n//! }\n//! ```\n//!\n//! ## A note on error handling\n//!\n//! As you explore the various protocol extension traits, you'll often find that\n//! functions don't return a typical [`Result<T, Self::Error>`],\n//! and will instead return a [`TargetResult<T, Self>`].\n//!\n//! At first glance this might look a bit strange, since it looks like the `Err`\n//! variant of `TargetResult` is `Self` instead of `Self::Error`!\n//!\n//! Thankfully, there's a good reason for why that's the case. In a nutshell,\n//! `TargetResult` wraps a typical `Result<T, Self::Error>` with a few\n//! additional error types which can be reported back to the GDB client via the\n//! GDB RSP.\n//!\n//! For example, if the GDB client tried to read memory from invalid memory,\n//! instead of immediately terminating the entire debugging session, it's\n//! possible to simply return a `Err(TargetError::Errno(14)) // EFAULT`, which\n//! will notify the GDB client that the operation has failed.\n//!\n//! See the [`TargetError`] docs for more details.\n//!\n//! ## A note on all the `<Self::Arch as Arch>::` syntax\n//!\n//! As you explore `Target` and its many extension traits, you'll enounter\n//! many method signatures that use this pretty gnarly bit of Rust type syntax.\n//!\n//! If [rust-lang/rust#38078](https://github.com/rust-lang/rust/issues/38078)\n//! gets fixed, then types like `<Self::Arch as Arch>::Foo` could be simplified\n//! to just `Self::Arch::Foo`, but until then, the much more explicit\n//! [fully qualified syntax](https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#fully-qualified-syntax-for-disambiguation-calling-methods-with-the-same-name)\n//! must be used instead.\n//!\n//! To improve the readability and maintainability of your own implementation,\n//! it'd be best to swap out the fully qualified syntax with whatever concrete\n//! type is being used. e.g: on a 32-bit target, instead of cluttering up a\n//! method implementation with a parameter passed as `(addr: <Self::Arch as\n//! Arch>::Usize)`, just write `(addr: u32)` directly.\nuse crate::arch::Arch;\n\npub mod ext;\n\n/// The error type for various methods on `Target` and its assorted associated\n/// extension traits.\n///\n/// # Error Handling over the GDB Remote Serial Protocol\n///\n/// The GDB Remote Serial Protocol has less-than-stellar support for error\n/// handling, typically taking the form of a single-byte\n/// [`errno`-style error codes](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/constants/errnos.md).\n/// Moreover, often times the GDB client will simply _ignore_ the specific error\n/// code returned by the stub, and print a generic failure message instead.\n///\n/// As such, while it's certainly better to use appropriate error codes when\n/// possible (e.g: returning a `EFAULT` (14) when reading from invalid memory),\n/// it's often fine to simply return the more general `TargetError::NonFatal`\n/// instead, and avoid the headache of picking a \"descriptive\" error code. Under\n/// the good, `TargetError::NonFatal` is sent to the GDB client as a generic\n/// `EREMOTEIO` (121) error.\n///\n/// # `From` and `Into` implementations\n///\n/// - `From<()>` -> `TargetError::NonFatal`\n/// - `From<io::Error>` -> `TargetError::Io(io::Error)` (requires `std` feature)\n///\n/// When using a custom target-specific fatal error type, users are encouraged\n/// to write the following impl to simplify error handling in `Target` methods:\n///\n/// ```rust\n/// use gdbstub::target::TargetError;\n///\n/// /// Target-specific Fatal Error\n/// enum MyTargetFatalError {\n///     // ...\n/// }\n///\n/// impl From<MyTargetFatalError> for TargetError<MyTargetFatalError> {\n///     fn from(e: MyTargetFatalError) -> Self {\n///         TargetError::Fatal(e)\n///     }\n/// }\n/// ```\n///\n/// Unfortunately, a blanket impl such as `impl<T: Target> From<T::Error> for\n/// TargetError<T::Error>` isn't possible, as it could result in impl conflicts.\n/// For example, if a Target decided to use `()` as its fatal error type, then\n/// there would be conflict with the existing `From<()>` impl.\n#[non_exhaustive]\npub enum TargetError<E> {\n    /// A non-specific, non-fatal error has occurred.\n    NonFatal,\n    /// Non-fatal I/O Error. Only available when the `std` feature is enabled.\n    ///\n    /// At the moment, this is just shorthand for\n    /// `TargetError::NonFatal(e.raw_os_err().unwrap_or(121))`. Error code `121`\n    /// corresponds to `EREMOTEIO`.\n    ///\n    /// In the future, `gdbstub` may add support for the \"QEnableErrorStrings\"\n    /// LLDB protocol extension, which would allow sending additional error\n    /// context (in the form of an ASCII string) when an I/O error occurs. If\n    /// this is something you're interested in, consider opening a PR!\n    #[cfg(feature = \"std\")]\n    Io(std::io::Error),\n    /// An operation-specific non-fatal error code.\n    Errno(u8),\n    /// A target-specific fatal error.\n    ///\n    /// **WARNING:** Returning this error will immediately terminate the GDB\n    /// debugging session, and return a\n    /// [`GdbStubError`](crate::stub::GdbStubError)!\n    Fatal(E),\n}\n\n/// Converts a `()` into a `TargetError::NonFatal`.\nimpl<E> From<()> for TargetError<E> {\n    fn from(_: ()) -> TargetError<E> {\n        TargetError::NonFatal\n    }\n}\n\n/// Converts a `std::io::Error` into a `TargetError::Io`.\n#[cfg(feature = \"std\")]\nimpl<E> From<std::io::Error> for TargetError<E> {\n    fn from(e: std::io::Error) -> TargetError<E> {\n        TargetError::Io(e)\n    }\n}\n\n/// A specialized `Result` type for `Target` operations. Supports reporting\n/// non-fatal errors back to the GDB client.\n///\n/// See [`TargetError`] for more details.\n///\n/// _Note:_ While it's typically parameterized as `TargetResult<T, Self>`, the\n/// error value is in-fact `TargetError<Self::Error>` (not `Self`).\npub type TargetResult<T, Tgt> = Result<T, TargetError<<Tgt as Target>::Error>>;\n\n/// Describes the architecture and capabilities of a target which can be\n/// debugged by [`GdbStub`](../struct.GdbStub.html).\n///\n/// The [`Target`](trait.Target.html) trait describes how to control and modify\n/// a system's execution state during a GDB debugging session, and serves as the\n/// primary bridge between `gdbstub`'s generic protocol implementation and a\n/// target's project/platform-specific code.\n///\n/// **`Target` is the most important trait in `gdbstub`, and must be implemented\n/// by anyone who uses the library!**\n///\n/// Please refer to the the documentation in the [`target` module](self)\n/// for more information on how to implement and work with `Target` and its\n/// various extension traits.\npub trait Target {\n    /// The target's architecture.\n    type Arch: Arch;\n\n    /// A target-specific **fatal** error.\n    type Error;\n\n    /// Base operations such as reading/writing from memory/registers,\n    /// stopping/resuming the target, etc....\n    ///\n    /// For example, on a single-threaded target:\n    ///\n    /// ```rust\n    /// use gdbstub::target::Target;\n    /// use gdbstub::target::ext::base::BaseOps;\n    /// use gdbstub::target::ext::base::singlethread::SingleThreadBase;\n    /// # use gdbstub::target::TargetResult;\n    /// # struct MyTarget;\n    ///\n    /// impl Target for MyTarget {\n    ///     // ...\n    ///     # type Arch = gdbstub_arch::arm::Armv4t;\n    ///     # type Error = ();\n    ///\n    ///     fn base_ops(&mut self) -> BaseOps<Self::Arch, Self::Error> {\n    ///         BaseOps::SingleThread(self)\n    ///     }\n    /// }\n    ///\n    /// // ...and then implement the associated base IDET\n    /// impl SingleThreadBase for MyTarget {\n    ///     // ...\n    /// #   fn read_registers(\n    /// #       &mut self,\n    /// #       regs: &mut gdbstub_arch::arm::reg::ArmCoreRegs,\n    /// #   ) -> TargetResult<(), Self> { todo!() }\n    /// #\n    /// #   fn write_registers(\n    /// #       &mut self,\n    /// #       regs: &gdbstub_arch::arm::reg::ArmCoreRegs\n    /// #   ) -> TargetResult<(), Self> { todo!() }\n    /// #\n    /// #   fn read_addrs(\n    /// #       &mut self,\n    /// #       start_addr: u32,\n    /// #       data: &mut [u8],\n    /// #   ) -> TargetResult<usize, Self> { todo!() }\n    /// #\n    /// #   fn write_addrs(\n    /// #       &mut self,\n    /// #       start_addr: u32,\n    /// #       data: &[u8],\n    /// #   ) -> TargetResult<(), Self> { todo!() }\n    /// }\n    /// ```\n    fn base_ops(&mut self) -> ext::base::BaseOps<'_, Self::Arch, Self::Error>;\n\n    /// If the target supports resumption, but hasn't implemented explicit\n    /// support for software breakpoints (via\n    /// [`SwBreakpoints`](ext::breakpoints::SwBreakpoint)), notify the user\n    /// that the GDB client may set \"implicit\" software breakpoints by\n    /// rewriting the target's instruction stream.\n    ///\n    /// Targets that wish to use the GDB client's implicit software breakpoint\n    /// handler must explicitly **opt-in** to this somewhat surprising GDB\n    /// feature by overriding this method to return `true`.\n    ///\n    /// # Context\n    ///\n    /// An \"implicit\" software breakpoint is set by the GDB client by manually\n    /// writing a software breakpoint instruction into target memory via the\n    /// target's `write_addrs` implementation. i.e: the GDB client will\n    /// overwrite the target's instruction stream with a software breakpoint\n    /// instruction, with the expectation that the target has a implemented a\n    /// breakpoint exception handler.\n    ///\n    /// # Implications\n    ///\n    /// While this is a reasonable (and useful!) bit of behavior when targeting\n    /// many classes of remote stub (e.g: bare-metal, separate process), there\n    /// are many `gdbstub` implementations that do _not_ implement \"software\n    /// breakpoints\" by naively rewriting the target's instruction stream.\n    ///\n    /// - e.g: a `gdbstub` implemented in an emulator is unlikely to implement\n    ///   \"software breakpoints\" by hooking into the emulated hardware's\n    ///   breakpoint handler, and would likely implement \"breakpoints\" by\n    ///   maintaining a list of addresses to stop at as part of its core\n    ///   interpreter loop.\n    /// - e.g: a `gdbstub` implemented in a hypervisor would require special\n    ///   coordination with the guest kernel to support software breakpoints, as\n    ///   there would need to be some way to distinguish between \"in-guest\"\n    ///   debugging, and \"hypervisor\" debugging.\n    ///\n    /// As such, `gdbstub` includes this `guard_rail_implicit_sw_breakpoints`\n    /// method.\n    ///\n    /// As the name suggests, this method acts as a \"guard rail\" that\n    /// warns users from accidentally opting into this \"implicit\" breakpoint\n    /// functionality, and being exceptionally confused as to why their\n    /// target is acting weird.\n    ///\n    /// If `gdbstub` detects that the target has not implemented a software\n    /// breakpoint handler, it will check if\n    /// `guard_rail_implicit_sw_breakpoints()` has been enabled, and if it\n    /// has not, it will trigger a runtime error that points the user at this\n    /// very documentation.\n    ///\n    /// # A note on breakpoints\n    ///\n    /// Aside from setting breakpoints at the explicit behest of the user (e.g:\n    /// when setting breakpoints via the `b` command in GDB), the GDB client may\n    /// also set/remove _temporary breakpoints_ as part of other commands.\n    ///\n    /// e.g: On targets without native support for hardware single-stepping,\n    /// calling `stepi` in GDB will result in the GDB client setting a temporary\n    /// breakpoint on the next instruction + resuming via `continue` instead.\n    #[inline(always)]\n    fn guard_rail_implicit_sw_breakpoints(&self) -> bool {\n        false\n    }\n\n    /// Enable/disable support for activating \"no ack mode\".\n    ///\n    /// By default, this method returns `true`.\n    ///\n    /// _Author's note:_ Unless you're using `gdbstub` with a truly unreliable\n    /// transport line (e.g: a noisy serial connection), it's best to support\n    /// \"no ack mode\", as it can substantially improve debugging latency.\n    ///\n    /// **Warning:** `gdbstub` doesn't currently implement all necessary\n    /// features for running correctly over a unreliable transport! See issue\n    /// [\\#137](https://github.com/daniel5151/gdbstub/issues/137) for details.\n    ///\n    /// # What is \"No Ack Mode\"?\n    ///\n    /// From the [GDB RSP docs](https://sourceware.org/gdb/onlinedocs/gdb/Packet-Acknowledgment.html#Packet-Acknowledgment):\n    ///\n    /// > By default, when either the host or the target machine receives a\n    /// > packet, the first response expected is an acknowledgment: either '+'\n    /// > (to indicate the package was received correctly) or '-' (to request\n    /// > retransmission). This mechanism allows the GDB remote protocol to\n    /// > operate over unreliable transport mechanisms, such as a serial line.\n    /// >\n    /// > In cases where the transport mechanism is itself reliable (such as a\n    /// > pipe or TCP connection), the '+'/'-' acknowledgments are redundant. It\n    /// > may be desirable to disable them in that case to reduce communication\n    /// > overhead, or for other reasons. This can be accomplished by means of\n    /// > the 'QStartNoAckMode' packet\n    #[inline(always)]\n    fn use_no_ack_mode(&self) -> bool {\n        true\n    }\n\n    /// Enable/disable using the more efficient `X` packet to write to target\n    /// memory (as opposed to the basic `M` packet).\n    ///\n    /// By default, this method returns `true`.\n    ///\n    /// _Author's note:_ Unless you're _really_ trying to squeeze `gdbstub` onto\n    /// a particularly resource-constrained platform, you may as well leave this\n    /// optimization enabled.\n    #[inline(always)]\n    fn use_x_upcase_packet(&self) -> bool {\n        true\n    }\n\n    /// Enable/disable using the more efficient `x` packet to read to target\n    /// memory (as opposed to the basic `m` packet).\n    ///\n    /// **By default, this method returns `false`.**\n    ///\n    /// This packet is disabled by default in order to maximize out-of-the-box\n    /// compatibility between `gdbstub` and all released GDB and LLDB versions.\n    /// For more context, see the discussion at\n    /// [daniel5151/gdbstub#163](https://github.com/daniel5151/gdbstub/issues/163#issuecomment-4049691552).\n    ///\n    /// `gdbstub` implements the `x` packet according to the GDB RSP spec, and\n    /// as such, enabling this packet will break compatibility with older LLDB\n    /// version.\n    ///\n    /// _Author's note:_ If you are _certain_ that your target will only even be\n    /// debugged used alongside a sufficiently recent GDB / LLDB version (i.e:\n    /// those released sometime after ~early 2026), you can set this to `true`\n    /// for improved performance. That said, unless you're planning to fetch\n    /// a _lot_ of memory data from your `Target`, you may as well leave\n    /// this optimization disabled, and guarantee client compatibility.\n    #[inline(always)]\n    fn use_x_lowcase_packet(&self) -> bool {\n        false\n    }\n\n    /// Whether `gdbstub` should provide a \"stub\" `resume` implementation on\n    /// targets without support for resumption.\n    ///\n    /// At the time of writing, the mainline GDB client does not gracefully\n    /// handle targets that do not support support resumption, and will hang\n    /// indefinitely if a user inadvertently attempts to `continue` or `step`\n    /// such a target.\n    ///\n    /// To make the `gdbstub` user experience a bit better, the library includes\n    /// bit of \"stub\" code to gracefully handle these cases.\n    ///\n    /// If a user attempts to resume a target that hasn't implemented support\n    /// for resumption, `gdbstub` will write a brief message back to the GDB\n    /// client console, and will immediately return a \"stopped with TRAP\" stop\n    /// reason.\n    ///\n    /// This method controls whether or not this bt of behavior is enabled.\n    ///\n    /// _Author's note:_ Unless you're _really_ trying to squeeze `gdbstub` onto\n    /// a particularly resource-constrained platform, you may as well leave this\n    /// enabled. The resulting stub code is entirely optimized out on targets\n    /// that implement support for resumption.\n    #[inline(always)]\n    fn use_resume_stub(&self) -> bool {\n        true\n    }\n\n    /// Enable/Disable the use of run-length encoding on outgoing packets.\n    ///\n    /// This is enabled by default, as RLE can save substantial amounts of\n    /// bandwidth down the wire.\n    ///\n    /// _Author's note:_ There are essentially no reasons to disable RLE, unless\n    /// you happen to be using a custom GDB client that doesn't support RLE.\n    #[inline(always)]\n    fn use_rle(&self) -> bool {\n        true\n    }\n\n    /// Whether to send a target description XML to the client.\n    ///\n    /// Setting this to `false` will override both\n    /// [`Target::support_target_description_xml_override`] and the associated\n    /// [`Arch::target_description_xml`].\n    ///\n    /// _Author's note:_ Having the GDB client autodetect your target's\n    /// architecture and register set is really useful, so unless you're\n    /// _really_ trying to squeeze `gdbstub` onto a particularly\n    /// resource-constrained platform, you may as well leave this enabled.\n    #[inline(always)]\n    fn use_target_description_xml(&self) -> bool {\n        true\n    }\n\n    /// (LLDB extension) Whether to send register information to the client.\n    ///\n    /// Setting this to `false` will override both\n    /// [`Target::support_lldb_register_info_override`] and the associated\n    /// [`Arch::lldb_register_info`].\n    ///\n    /// _Author's note:_ Having the LLDB client autodetect your target's\n    /// register set is really useful, so unless you're _really_ trying to\n    /// squeeze `gdbstub` onto a particularly resource-constrained platform, you\n    /// may as well leave this enabled.\n    #[inline(always)]\n    fn use_lldb_register_info(&self) -> bool {\n        true\n    }\n\n    /// Enable support for [`BaseStopReason::Fork`].\n    ///\n    /// By default, this method returns `true`.\n    ///\n    /// _Author's note:_ Unless you're _really_ trying to squeeze `gdbstub` onto\n    /// a particularly resource-constrained platform (and looking to save ~100\n    /// bytes), you may as well leave this enabled.\n    ///\n    /// [`BaseStopReason::Fork`]: crate::stub::BaseStopReason::Fork\n    #[inline(always)]\n    fn use_fork_stop_reason(&self) -> bool {\n        true\n    }\n\n    /// Enable support for [`BaseStopReason::VFork`].\n    ///\n    /// By default, this method returns `true`.\n    ///\n    /// _Author's note:_ Unless you're _really_ trying to squeeze `gdbstub` onto\n    /// a particularly resource-constrained platform (and looking to save ~100\n    /// bytes), you may as well leave this enabled.\n    ///\n    /// [`BaseStopReason::VFork`]: crate::stub::BaseStopReason::VFork\n    #[inline(always)]\n    fn use_vfork_stop_reason(&self) -> bool {\n        true\n    }\n\n    /// Enable support for [`BaseStopReason::VForkDone`].\n    ///\n    /// By default, this method returns `true`.\n    ///\n    /// _Author's note:_ Unless you're _really_ trying to squeeze `gdbstub` onto\n    /// a particularly resource-constrained platform (and looking to save ~100\n    /// bytes), you may as well leave this enabled.\n    ///\n    /// [`BaseStopReason::VForkDone`]: crate::stub::BaseStopReason::VForkDone\n    #[inline(always)]\n    fn use_vforkdone_stop_reason(&self) -> bool {\n        true\n    }\n\n    /// Support for setting / removing breakpoints.\n    #[inline(always)]\n    fn support_breakpoints(&mut self) -> Option<ext::breakpoints::BreakpointsOps<'_, Self>> {\n        None\n    }\n\n    /// Support for handling custom GDB `monitor` commands.\n    #[inline(always)]\n    fn support_monitor_cmd(&mut self) -> Option<ext::monitor_cmd::MonitorCmdOps<'_, Self>> {\n        None\n    }\n\n    /// Support for Extended Mode operations.\n    #[inline(always)]\n    fn support_extended_mode(&mut self) -> Option<ext::extended_mode::ExtendedModeOps<'_, Self>> {\n        None\n    }\n\n    /// Support for handling requests to get the target's current section (or\n    /// segment) offsets.\n    #[inline(always)]\n    fn support_section_offsets(\n        &mut self,\n    ) -> Option<ext::section_offsets::SectionOffsetsOps<'_, Self>> {\n        None\n    }\n\n    /// Support for setting / removing tracepoints.\n    #[inline(always)]\n    fn support_tracepoints(&mut self) -> Option<ext::tracepoints::TracepointsOps<'_, Self>> {\n        None\n    }\n\n    /// Support for overriding the target description XML specified by\n    /// `Target::Arch`.\n    #[inline(always)]\n    fn support_target_description_xml_override(\n        &mut self,\n    ) -> Option<ext::target_description_xml_override::TargetDescriptionXmlOverrideOps<'_, Self>>\n    {\n        None\n    }\n\n    /// (LLDB extension) Support for overriding the register info specified by\n    /// `Target::Arch`.\n    #[inline(always)]\n    fn support_lldb_register_info_override(\n        &mut self,\n    ) -> Option<ext::lldb_register_info_override::LldbRegisterInfoOverrideOps<'_, Self>> {\n        None\n    }\n\n    /// Support for reading the target's memory map.\n    #[inline(always)]\n    fn support_memory_map(&mut self) -> Option<ext::memory_map::MemoryMapOps<'_, Self>> {\n        None\n    }\n\n    /// Support for flash memory operations.\n    #[inline(always)]\n    fn support_flash_operations(&mut self) -> Option<ext::flash::FlashOps<'_, Self>> {\n        None\n    }\n\n    /// Support for setting / removing syscall catchpoints.\n    #[inline(always)]\n    fn support_catch_syscalls(\n        &mut self,\n    ) -> Option<ext::catch_syscalls::CatchSyscallsOps<'_, Self>> {\n        None\n    }\n\n    /// Support for Host I/O operations.\n    #[inline(always)]\n    fn support_host_io(&mut self) -> Option<ext::host_io::HostIoOps<'_, Self>> {\n        None\n    }\n\n    /// Support for reading the current exec-file.\n    #[inline(always)]\n    fn support_exec_file(&mut self) -> Option<ext::exec_file::ExecFileOps<'_, Self>> {\n        None\n    }\n\n    /// Support for reading the target's Auxillary Vector.\n    #[inline(always)]\n    fn support_auxv(&mut self) -> Option<ext::auxv::AuxvOps<'_, Self>> {\n        None\n    }\n\n    /// Support for reading a list of libraries for SVR4 (System-V/Unix)\n    /// platforms.\n    #[inline(always)]\n    fn support_libraries_svr4(&mut self) -> Option<ext::libraries::LibrariesSvr4Ops<'_, Self>> {\n        None\n    }\n\n    /// Support for reading a list of libraries (Windows/generic format).\n    ///\n    /// This is used for targets where library offsets are maintained externally\n    /// (e.g., Windows PE targets).\n    #[inline(always)]\n    fn support_libraries(&mut self) -> Option<ext::libraries::LibrariesOps<'_, Self>> {\n        None\n    }\n\n    /// (LLDB extension) Support for reporting host information.\n    #[inline(always)]\n    fn support_host_info(&mut self) -> Option<ext::host_info::HostInfoOps<'_, Self>> {\n        None\n    }\n\n    /// (LLDB extension) Support for reporting process information.\n    #[inline(always)]\n    fn support_process_info(&mut self) -> Option<ext::process_info::ProcessInfoOps<'_, Self>> {\n        None\n    }\n\n    /// (LLDB extension) Support for WebAssembly (Wasm)-specific commands.\n    #[inline(always)]\n    fn support_wasm(&mut self) -> Option<ext::wasm::WasmOps<'_, Self>> {\n        None\n    }\n}\n\nmacro_rules! __delegate {\n    (fn $op:ident(&mut $this:ident) $($sig:tt)*) => {\n        fn $op(&mut $this) $($sig)* {\n            (**$this).$op()\n        }\n    };\n\n    (fn $op:ident(&$this:ident) $($sig:tt)*) => {\n        fn $op(&$this) $($sig)* {\n            (**$this).$op()\n        }\n    }\n}\n\nmacro_rules! __delegate_support {\n    ($ext:ident, $extpath:ident) => {\n        pastey::paste! {\n            __delegate!(fn [<support_ $ext>](&mut self) -> Option<ext::$extpath::[<$ext:camel Ops>]<'_, Self>>);\n        }\n    };\n\n    ($ext:ident) => {\n        __delegate_support!($ext, $ext);\n    };\n}\n\nmacro_rules! impl_dyn_target {\n    ($type:ty) => {\n        impl<A, E> Target for $type\n        where\n            A: Arch,\n        {\n            type Arch = A;\n            type Error = E;\n\n            __delegate!(fn base_ops(&mut self) -> ext::base::BaseOps<'_, Self::Arch, Self::Error>);\n\n            __delegate!(fn guard_rail_implicit_sw_breakpoints(&self) -> bool);\n\n            __delegate!(fn use_fork_stop_reason(&self) -> bool);\n            __delegate!(fn use_lldb_register_info(&self) -> bool);\n            __delegate!(fn use_no_ack_mode(&self) -> bool);\n            __delegate!(fn use_resume_stub(&self) -> bool);\n            __delegate!(fn use_rle(&self) -> bool);\n            __delegate!(fn use_target_description_xml(&self) -> bool);\n            __delegate!(fn use_vfork_stop_reason(&self) -> bool);\n            __delegate!(fn use_vforkdone_stop_reason(&self) -> bool);\n            __delegate!(fn use_x_lowcase_packet(&self) -> bool);\n            __delegate!(fn use_x_upcase_packet(&self) -> bool);\n\n            // TODO: (breaking) fix inconsistencies in `support_` naming\n            __delegate_support!(auxv);\n            __delegate_support!(breakpoints);\n            __delegate_support!(catch_syscalls);\n            __delegate_support!(exec_file);\n            __delegate_support!(extended_mode);\n            __delegate!(fn support_flash_operations(&mut self) -> Option<ext::flash::FlashOps<'_, Self>>);\n            __delegate_support!(host_info);\n            __delegate_support!(host_io);\n            __delegate_support!(libraries);\n            __delegate!(fn support_libraries_svr4(&mut self) -> Option<ext::libraries::LibrariesSvr4Ops<'_, Self>>);\n            __delegate_support!(lldb_register_info_override);\n            __delegate_support!(memory_map);\n            __delegate_support!(monitor_cmd);\n            __delegate_support!(process_info);\n            __delegate_support!(section_offsets);\n            __delegate_support!(target_description_xml_override);\n            __delegate_support!(tracepoints);\n            __delegate_support!(wasm);\n        }\n    };\n}\n\nimpl_dyn_target!(&mut dyn Target<Arch = A, Error = E>);\n#[cfg(feature = \"alloc\")]\nimpl_dyn_target!(alloc::boxed::Box<dyn Target<Arch = A, Error = E>>);\n"
  },
  {
    "path": "src/util/dead_code_marker.rs",
    "content": "/// NOTE: We don't have a proper black box in stable Rust. This is\n/// a workaround implementation, that may have a too big performance overhead,\n/// depending on operation, or it may fail to properly avoid having code\n/// optimized out. It is good enough that it is used by default.\n///\n/// A function that is opaque to the optimizer, to allow benchmarks to\n/// pretend to use outputs to assist in avoiding dead-code\n/// elimination.\n// copied from https://docs.rs/bencher/0.1.5/src/bencher/lib.rs.html#590-596\n#[cfg(feature = \"__dead_code_marker\")]\npub fn black_box<T>(dummy: T) -> T {\n    unsafe {\n        let ret = core::ptr::read_volatile(&dummy);\n        core::mem::forget(dummy);\n        ret\n    }\n}\n\n/// If the block of code which contains this macro doesn't get dead code\n/// eliminated, this macro ensures that the resulting binary contains a\n/// easy-to-find static string with the format `\"<$feature,$ctx>\"`.\n///\n/// In `gdbstub`, this macro makes it easy to see if the Rust compiler was able\n/// to dead-code-eliminate the packet parsing / handling code associated with\n/// unimplemented protocol extensions.\n///\n/// e.g: if the target didn't implement the `MonitorCmd` extension, then running\n/// the unix command `strings <finalbinary> | grep \"<qRcmd,\"` should return no\n/// results.\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __dead_code_marker {\n    ($feature:literal, $ctx:literal) => {\n        #[cfg(feature = \"__dead_code_marker\")]\n        $crate::util::dead_code_marker::black_box(concat!(\"<\", $feature, \",\", $ctx, \">\"));\n    };\n}\n"
  },
  {
    "path": "src/util/managed_vec.rs",
    "content": "use managed::ManagedSlice;\n\n/// Error value indicating insufficient capacity.\n#[derive(Debug, Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]\npub struct CapacityError<Element>(pub Element);\n\n/// Wraps a ManagedSlice in a vec-like interface.\npub struct ManagedVec<'a, 'b, T> {\n    buf: &'b mut ManagedSlice<'a, T>,\n    len: usize,\n}\n\nimpl<'a, 'b, T> ManagedVec<'a, 'b, T> {\n    pub fn new_with_idx(buf: &'b mut ManagedSlice<'a, T>, len: usize) -> Self {\n        ManagedVec { buf, len }\n    }\n\n    pub fn push(&mut self, value: T) -> Result<(), CapacityError<T>> {\n        if self.len < self.buf.len() {\n            self.buf[self.len] = value;\n            self.len += 1;\n            Ok(())\n        } else {\n            match &mut self.buf {\n                ManagedSlice::Borrowed(_) => Err(CapacityError(value)),\n                #[cfg(feature = \"alloc\")]\n                ManagedSlice::Owned(buf) => {\n                    buf.push(value);\n                    Ok(())\n                }\n            }\n        }\n    }\n\n    #[cfg(feature = \"trace-pkt\")]\n    pub fn as_slice<'c: 'b>(&'c self) -> &'b [T] {\n        &self.buf[..self.len]\n    }\n}\n"
  },
  {
    "path": "src/util/mod.rs",
    "content": "//! Private utility types used internally within `gdbstub`.\n//!\n//! These are all bits of functionality that _could_ exist as their own crates /\n//! libraries, and do not rely on any `gdbstub` specific infrastructure.\n\npub mod managed_vec;\n\npub(crate) mod dead_code_marker;\n"
  }
]