├── .gitignore ├── crates ├── capi │ ├── LICENSE-MIT │ ├── LICENSE-APACHE │ ├── Cargo.toml │ ├── include │ │ └── rustc_demangle.h │ ├── CHANGELOG.md │ └── src │ │ └── lib.rs └── native-c │ ├── build.rs │ ├── Cargo.toml │ ├── README │ ├── include │ └── demangle.h │ └── src │ └── lib.rs ├── fuzz ├── .gitignore ├── Cargo.toml └── fuzz_targets │ ├── demangle.rs │ └── native_c.rs ├── .github ├── dependabot.yml └── workflows │ ├── release.yml │ └── main.yml ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-MIT ├── README.md ├── LICENSE-APACHE └── src ├── legacy.rs ├── lib.rs ├── v0-large-test-symbols └── early-recursion-limit └── v0.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /crates/capi/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /crates/capi/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /fuzz/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | target 3 | corpus 4 | artifacts 5 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "08:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /crates/native-c/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | cc::Build::new() 3 | .file("src/demangle.c") 4 | .include("include") 5 | .compile("demangle_native_c"); 6 | println!("cargo::rerun-if-changed=src/demangle.c"); 7 | println!("cargo::rerun-if-changed=include/demangle.h"); 8 | } 9 | -------------------------------------------------------------------------------- /crates/native-c/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustc-demangle-native-c" 3 | version = "0.1.0" 4 | authors = ["automatically generated"] 5 | description = """ 6 | Native C version of the rustc_demangle crate 7 | """ 8 | license = "MIT/Apache-2.0" 9 | repository = "https://github.com/rust-lang/rustc-demangle" 10 | publish = false 11 | 12 | [lib] 13 | name = "rustc_demangle_native_c" 14 | 15 | [build-dependencies] 16 | cc = "1" 17 | -------------------------------------------------------------------------------- /crates/capi/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustc-demangle-capi" 3 | version = "0.1.2" 4 | authors = ["Torste Aikio "] 5 | description = """ 6 | C API for the `rustc-demangle` crate 7 | """ 8 | license = "MIT/Apache-2.0" 9 | repository = "https://github.com/alexcrichton/rustc-demangle" 10 | 11 | [lib] 12 | name = "rustc_demangle" 13 | crate-type = ["staticlib", "cdylib"] 14 | 15 | [dependencies] 16 | rustc-demangle = { version = "0.1.26", path = "../.." } 17 | -------------------------------------------------------------------------------- /crates/capi/include/rustc_demangle.h: -------------------------------------------------------------------------------- 1 | #ifndef RUST_DEMANGLE_H_ 2 | #define RUST_DEMANGLE_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | // Demangles symbol given in `mangled` argument into `out` buffer 9 | // 10 | // Returns 0 if `mangled` is not Rust symbol or if `out` buffer is too small 11 | // Returns 1 otherwise 12 | int rustc_demangle(const char *mangled, char *out, size_t out_size); 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | 18 | #endif // RUSTC_DEMANGLE_H_ 19 | -------------------------------------------------------------------------------- /crates/capi/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | ## [0.1.2](https://github.com/rust-lang/rustc-demangle/compare/rustc-demangle-capi-v0.1.1...rustc-demangle-capi-v0.1.2) - 2025-07-16 11 | 12 | ### Other 13 | 14 | - updated the following local packages: rustc-demangle 15 | -------------------------------------------------------------------------------- /fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustc-demangle-fuzz" 3 | version = "0.0.0" 4 | authors = ["Automatically generated"] 5 | publish = false 6 | edition = "2021" 7 | 8 | [package.metadata] 9 | cargo-fuzz = true 10 | 11 | [dependencies] 12 | libfuzzer-sys = "0.4" 13 | rustc-demangle = { path = '..', features = ["std"] } 14 | rustc-demangle-native-c = { path = '../crates/native-c' } 15 | 16 | [[bin]] 17 | name = "demangle" 18 | path = "fuzz_targets/demangle.rs" 19 | test = false 20 | doc = false 21 | 22 | [[bin]] 23 | name = "native_c" 24 | path = "fuzz_targets/native_c.rs" 25 | test = false 26 | doc = false 27 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | ## [0.1.26](https://github.com/rust-lang/rustc-demangle/compare/rustc-demangle-v0.1.25...rustc-demangle-v0.1.26) - 2025-07-16 11 | 12 | ### Other 13 | 14 | - Add new v0 demangling tags for pattern types 15 | - Do not publish the `native-c` crate 16 | - Use release-plz for releases 17 | - Add a CI workflow to publish new releases after a tag is pushed 18 | -------------------------------------------------------------------------------- /fuzz/fuzz_targets/demangle.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | use libfuzzer_sys::fuzz_target; 3 | use std::fmt::Write; 4 | 5 | fuzz_target!(|data: &str| { 6 | let mut s = String::new(); 7 | let sym = rustc_demangle::demangle(data); 8 | drop(write!(s, "{}", sym)); 9 | s.truncate(0); 10 | 11 | if let Ok(sym) = rustc_demangle::try_demangle(data) { 12 | drop(write!(s, "{}", sym)); 13 | } 14 | 15 | let mut output = Vec::new(); 16 | drop(rustc_demangle::demangle_stream( 17 | &mut s.as_bytes(), 18 | &mut output, 19 | true, 20 | )); 21 | output.clear(); 22 | drop(rustc_demangle::demangle_stream( 23 | &mut s.as_bytes(), 24 | &mut output, 25 | false, 26 | )); 27 | }); 28 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release-plz 2 | 3 | permissions: 4 | pull-requests: write 5 | contents: write 6 | 7 | on: 8 | push: 9 | branches: 10 | - main 11 | 12 | jobs: 13 | release-plz: 14 | name: Release-plz 15 | runs-on: ubuntu-24.04 16 | steps: 17 | - name: Checkout repository 18 | uses: actions/checkout@v4 19 | with: 20 | fetch-depth: 0 21 | - name: Install Rust (rustup) 22 | run: rustup update nightly --no-self-update && rustup default nightly 23 | - name: Run release-plz 24 | uses: MarcoIeni/release-plz-action@v0.5 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} 28 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustc-demangle" 3 | version = "0.1.26" 4 | authors = ["Alex Crichton "] 5 | license = "MIT/Apache-2.0" 6 | readme = "README.md" 7 | repository = "https://github.com/rust-lang/rustc-demangle" 8 | homepage = "https://github.com/rust-lang/rustc-demangle" 9 | documentation = "https://docs.rs/rustc-demangle" 10 | description = """ 11 | Rust compiler symbol demangling. 12 | """ 13 | 14 | [workspace] 15 | members = ["crates/capi", "fuzz"] 16 | 17 | [dependencies] 18 | core = { version = '1.0.0', optional = true, package = 'rustc-std-workspace-core' } 19 | 20 | [features] 21 | rustc-dep-of-std = ['core'] 22 | std = [] 23 | # Deprecated: `compiler_builtins` used to be a dependency and was enabled by 24 | # some downstream users, but it is no longer needed. This feature should be 25 | # removed in a future release. 26 | compiler_builtins = [] 27 | 28 | [profile.release] 29 | #lto = true 30 | 31 | [package.metadata.docs.rs] 32 | features = ["std"] 33 | rustdoc-args = ["--cfg", "docsrs"] 34 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Alex Crichton 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /crates/native-c/README: -------------------------------------------------------------------------------- 1 | A portable native C demangler, which should mostly have byte-for-byte identical outputs to the Rust one, including in error cases. 2 | 3 | This code is intended to be safe to run on untrusted inputs and has been fuzzed, but only it's author has tried to find security issues in it so a security review is probably wise before using it as a serious security barrier. 4 | 5 | The only difference is that since it's hard to include up-to-date unicode tables in portable C code, strings in constants (do you know that feature exists?) have all non-ASCII characters escaped (as `\u{ABCD}`) rather than having only non-printable characters escaped. Unicode in identifiers is still translated as-is, allowing non-printable characters just like rustc. If you care, the code intentionally includes `unicode_isprint` and `unicode_isgraphemextend` that can be replaced with actual Unicode tables. 6 | 7 | This has a Cargo.toml to make it easy to test, but people whose build systems can use Rust are expected to use the `rustc-demangle-capi` crate which uses the Rust `rustc-demangle` implementation instead. Since the crate is intended only for users with weird build systems, there is no build system provided. 8 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | test: 6 | name: Test 7 | runs-on: ubuntu-latest 8 | strategy: 9 | matrix: 10 | rust: [stable, beta, nightly] 11 | steps: 12 | - uses: actions/checkout@v2 13 | - name: Install Rust 14 | run: rustup update ${{ matrix.rust }} && rustup default ${{ matrix.rust }} 15 | - run: cargo build --all 16 | - run: cargo test --all 17 | - run: cd crates/native-c && cargo test --all 18 | - run: cargo build --features std 19 | 20 | fuzz_targets: 21 | name: Fuzz Targets 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v2 25 | # Note that building with fuzzers requires nightly since it uses unstable 26 | # flags to rustc. 27 | - run: rustup update nightly && rustup default nightly 28 | - run: cargo install cargo-fuzz --vers "^0.11" 29 | - run: cargo fuzz build --dev 30 | 31 | rustfmt: 32 | name: Rustfmt 33 | runs-on: ubuntu-latest 34 | steps: 35 | - uses: actions/checkout@v2 36 | - name: Install Rust 37 | run: rustup update stable && rustup default stable && rustup component add rustfmt 38 | - run: cargo fmt -- --check 39 | 40 | publish_docs: 41 | name: Publish Documentation 42 | runs-on: ubuntu-latest 43 | steps: 44 | - uses: actions/checkout@v2 45 | - name: Install Rust 46 | run: rustup update stable && rustup default stable 47 | - name: Build documentation 48 | run: cargo doc --no-deps 49 | - name: Publish documentation 50 | run: | 51 | cd target/doc 52 | git init 53 | git add . 54 | git -c user.name='ci' -c user.email='ci' commit -m init 55 | git push -f -q https://git:${{ secrets.github_token }}@github.com/${{ github.repository }} HEAD:gh-pages 56 | if: github.event_name == 'push' && github.event.ref == 'refs/heads/main' 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rustc-demangle 2 | 3 | Demangling for Rust symbols, written in Rust. 4 | 5 | [Documentation](https://docs.rs/rustc-demangle) 6 | 7 | ## Usage 8 | 9 | You can add this as a dependency via your `Cargo.toml` 10 | 11 | ```toml 12 | [dependencies] 13 | rustc-demangle = "0.1" 14 | ``` 15 | 16 | and then be sure to check out the [crate 17 | documentation](https://docs.rs/rustc-demangle) for usage. 18 | 19 | ## Usage from non-Rust languages 20 | 21 | You can also use this crate from other languages via the C API wrapper in the 22 | `crates/capi` directory. This can be build with: 23 | 24 | ```sh 25 | $ cargo build -p rustc-demangle-capi --release 26 | ``` 27 | 28 | You'll then find `target/release/librustc_demangle.a` and 29 | `target/release/librustc_demangle.so` (or a different name depending on your 30 | platform). These objects implement the interface specified in 31 | `crates/capi/include/rustc_demangle.h`. 32 | 33 | If your build system does not support Rust, there is also a mostly-identical 34 | C version in the `crates/native-c` which you can use via copy-paste or as 35 | a git submodule. Read `crates/native-c/README.md` for more details. It is 36 | likely to be less supported than the Rust version, so it is better to use 37 | the Rust version if your build system supports it. 38 | 39 | Both the Rust and C versions don't require memory allocation or any other 40 | operating-system support. 41 | 42 | # License 43 | 44 | This project is licensed under either of 45 | 46 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or 47 | http://www.apache.org/licenses/LICENSE-2.0) 48 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or 49 | http://opensource.org/licenses/MIT) 50 | 51 | at your option. 52 | 53 | ### Contribution 54 | 55 | Unless you explicitly state otherwise, any contribution intentionally submitted 56 | for inclusion in rustc-demangle you, as defined in the Apache-2.0 license, shall 57 | be dual licensed as above, without any additional terms or conditions. 58 | -------------------------------------------------------------------------------- /crates/native-c/include/demangle.h: -------------------------------------------------------------------------------- 1 | #ifndef _H_DEMANGLE_V0_H 2 | #define _H_DEMANGLE_V0_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | #if defined(__GNUC__) || defined(__clang__) 11 | #define DEMANGLE_NODISCARD __attribute__((warn_unused_result)) 12 | #else 13 | #define DEMANGLE_NODISCARD 14 | #endif 15 | 16 | typedef enum { 17 | OverflowOk, 18 | OverflowOverflow 19 | } overflow_status; 20 | 21 | enum demangle_style { 22 | DemangleStyleUnknown = 0, 23 | DemangleStyleLegacy, 24 | DemangleStyleV0, 25 | }; 26 | 27 | // Not using a union here to make the struct easier to copy-paste if needed. 28 | struct demangle { 29 | enum demangle_style style; 30 | // points to the "mangled" part of the name, 31 | // not including `ZN` or `R` prefixes. 32 | const char *mangled; 33 | size_t mangled_len; 34 | // In DemangleStyleLegacy, is the number of path elements 35 | size_t elements; 36 | // while it's called "original", it will not contain `.llvm.9D1C9369@@16` suffixes 37 | // that are to be ignored. 38 | const char *original; 39 | size_t original_len; 40 | // Contains the part after the mangled name that is to be outputted, 41 | // which can be `.exit.i.i` suffixes LLVM sometimes adds. 42 | const char *suffix; 43 | size_t suffix_len; 44 | }; 45 | 46 | // if the length of the output buffer is less than `output_len-OVERFLOW_MARGIN`, 47 | // the demangler will return `OverflowOverflow` even if there is no overflow. 48 | #define OVERFLOW_MARGIN 4 49 | 50 | /// Demangle a C string that refers to a Rust symbol and put the demangle intermediate result in `res`. 51 | /// Beware that `res` contains references into `s`. If `s` is modified (or free'd) before calling 52 | /// `rust_demangle_display_demangle` behavior is undefined. 53 | /// 54 | /// Use `rust_demangle_display_demangle` to convert it to an actual string. 55 | void rust_demangle_demangle(const char *s, struct demangle *res); 56 | 57 | /// Write the string in a `struct demangle` into a buffer. 58 | /// 59 | /// Return `OverflowOk` if the output buffer was sufficiently big, `OverflowOverflow` if it wasn't. 60 | /// This function is `O(n)` in the length of the input + *output* [$], but the demangled output of demangling a symbol can 61 | /// be exponentially[$$] large, therefore it is recommended to have a sane bound (`rust-demangle` 62 | /// uses 1,000,000 bytes) on `len`. 63 | /// 64 | /// `alternate`, if true, uses the less verbose alternate formatting (Rust `{:#}`) is used, which does not show 65 | /// symbol hashes and types of constant ints. 66 | /// 67 | /// [$] It's `O(n * MAX_DEPTH)`, but `MAX_DEPTH` is a constant 300 and therefore it's `O(n)` 68 | /// [$$] Technically, bounded by `O(n^MAX_DEPTH)`, but this is practically exponential. 69 | DEMANGLE_NODISCARD overflow_status rust_demangle_display_demangle(struct demangle const *res, char *out, size_t len, bool alternate); 70 | 71 | /// Returns true if `res` refers to a known valid Rust demangling style, false if it's an unknown style. 72 | bool rust_demangle_is_known(struct demangle *res); 73 | 74 | #undef DEMANGLE_NODISCARD 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /crates/capi/src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate rustc_demangle; 2 | 3 | use std::io::Write; 4 | use std::os::raw::{c_char, c_int}; 5 | 6 | /// C-style interface for demangling. 7 | /// Demangles symbol given in `mangled` argument into `out` buffer 8 | /// 9 | /// Unsafe as it handles buffers by raw pointers. 10 | /// 11 | /// Returns 0 if `mangled` is not Rust symbol or if `out` buffer is too small 12 | /// Returns 1 otherwise 13 | #[no_mangle] 14 | pub unsafe extern "C" fn rustc_demangle( 15 | mangled: *const c_char, 16 | out: *mut c_char, 17 | out_size: usize, 18 | ) -> c_int { 19 | let mangled_str = match std::ffi::CStr::from_ptr(mangled).to_str() { 20 | Ok(s) => s, 21 | Err(_) => return 0, 22 | }; 23 | match rustc_demangle::try_demangle(mangled_str) { 24 | Ok(demangle) => { 25 | let mut out_slice = std::slice::from_raw_parts_mut(out as *mut u8, out_size); 26 | match write!(out_slice, "{:#}\0", demangle) { 27 | Ok(_) => return 1, 28 | Err(_) => return 0, 29 | } 30 | } 31 | Err(_) => return 0, 32 | } 33 | } 34 | 35 | #[cfg(test)] 36 | mod tests { 37 | use std; 38 | use std::os::raw::c_char; 39 | #[test] 40 | fn demangle_c_str_large() { 41 | let mangled = "_ZN4testE\0"; 42 | let mut out_buf: Vec = vec![42; 8]; 43 | let res = unsafe { 44 | super::rustc_demangle( 45 | mangled.as_ptr() as *const c_char, 46 | out_buf.as_mut_ptr() as *mut c_char, 47 | 8, 48 | ) 49 | }; 50 | assert_eq!(res, 1); 51 | let out_str = std::str::from_utf8(&out_buf[..5]).unwrap(); 52 | assert_eq!(out_str, "test\0"); 53 | } 54 | 55 | #[test] 56 | fn demangle_c_str_exact() { 57 | let mangled = "_ZN4testE\0"; 58 | let mut out_buf: Vec = vec![42; 8]; 59 | let res = unsafe { 60 | super::rustc_demangle( 61 | mangled.as_ptr() as *const c_char, 62 | out_buf.as_mut_ptr() as *mut c_char, 63 | 5, 64 | ) 65 | }; 66 | assert_eq!(res, 1); 67 | let out_str = std::str::from_utf8(&out_buf).unwrap(); 68 | assert_eq!(out_str, "test\0***"); 69 | } 70 | 71 | #[test] 72 | fn demangle_c_str_small() { 73 | let mangled = "_ZN4testE\0"; 74 | let mut out_buf: Vec = vec![42; 8]; 75 | let res = unsafe { 76 | super::rustc_demangle( 77 | mangled.as_ptr() as *const c_char, 78 | out_buf.as_mut_ptr() as *mut c_char, 79 | 4, 80 | ) 81 | }; 82 | assert_eq!(res, 0); 83 | let out_str = std::str::from_utf8(&out_buf[4..]).unwrap(); 84 | assert_eq!(out_str, "****"); 85 | } 86 | 87 | #[test] 88 | fn demangle_c_str_smaller() { 89 | let mangled = "_ZN4testE\0"; 90 | let mut out_buf: Vec = vec![42; 8]; 91 | let res = unsafe { 92 | super::rustc_demangle( 93 | mangled.as_ptr() as *const c_char, 94 | out_buf.as_mut_ptr() as *mut c_char, 95 | 3, 96 | ) 97 | }; 98 | assert_eq!(res, 0); 99 | let out_str = std::str::from_utf8(&out_buf[3..]).unwrap(); 100 | assert_eq!(out_str, "*****"); 101 | } 102 | 103 | #[test] 104 | fn demangle_c_str_zero() { 105 | let mangled = "_ZN4testE\0"; 106 | let mut out_buf: Vec = vec![42; 8]; 107 | let res = unsafe { 108 | super::rustc_demangle( 109 | mangled.as_ptr() as *const c_char, 110 | out_buf.as_mut_ptr() as *mut c_char, 111 | 0, 112 | ) 113 | }; 114 | assert_eq!(res, 0); 115 | let out_str = std::str::from_utf8(&out_buf).unwrap(); 116 | assert_eq!(out_str, "********"); 117 | } 118 | 119 | #[test] 120 | fn demangle_c_str_not_rust_symbol() { 121 | let mangled = "la la la\0"; 122 | let mut out_buf: Vec = vec![42; 8]; 123 | let res = unsafe { 124 | super::rustc_demangle( 125 | mangled.as_ptr() as *const c_char, 126 | out_buf.as_mut_ptr() as *mut c_char, 127 | 8, 128 | ) 129 | }; 130 | assert_eq!(res, 0); 131 | } 132 | 133 | #[test] 134 | fn demangle_c_str_null() { 135 | let mangled = "\0"; 136 | let mut out_buf: Vec = vec![42; 8]; 137 | let res = unsafe { 138 | super::rustc_demangle( 139 | mangled.as_ptr() as *const c_char, 140 | out_buf.as_mut_ptr() as *mut c_char, 141 | 8, 142 | ) 143 | }; 144 | assert_eq!(res, 0); 145 | } 146 | 147 | #[test] 148 | fn demangle_c_str_invalid_utf8() { 149 | let mangled = [116, 101, 115, 116, 165, 0]; 150 | let mut out_buf: Vec = vec![42; 8]; 151 | let res = unsafe { 152 | super::rustc_demangle( 153 | mangled.as_ptr() as *const c_char, 154 | out_buf.as_mut_ptr() as *mut c_char, 155 | 8, 156 | ) 157 | }; 158 | assert_eq!(res, 0); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /crates/native-c/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::{c_char, c_int}; 2 | 3 | /// struct demangle 4 | #[repr(C)] 5 | #[derive(Copy, Clone)] 6 | pub struct CDemangle { 7 | style: c_int, 8 | mangled: *const c_char, 9 | mangled_len: usize, 10 | elements: usize, 11 | // 32 12 | original: *const c_char, 13 | original_len: usize, 14 | suffix: *const c_char, 15 | suffix_len: usize, 16 | } 17 | 18 | impl CDemangle { 19 | /// Create an empty `struct demangle` 20 | pub fn zero() -> Self { 21 | Self { 22 | style: 0, 23 | mangled: core::ptr::null(), 24 | mangled_len: 0, 25 | elements: 0, 26 | original: core::ptr::null(), 27 | original_len: 0, 28 | suffix: core::ptr::null(), 29 | suffix_len: 0, 30 | } 31 | } 32 | } 33 | 34 | extern "C" { 35 | /// call rust_demangle_demangle 36 | pub fn rust_demangle_demangle(s: *const c_char, res: *mut CDemangle); 37 | /// call rust_demangle_display_demangle 38 | pub fn rust_demangle_display_demangle( 39 | res: *const CDemangle, 40 | out: *mut c_char, 41 | len: usize, 42 | alternate: bool, 43 | ) -> c_int; 44 | } 45 | 46 | #[test] 47 | fn smoke_test() { 48 | fn test_single(input: &str, expected: &str, alternate: bool) { 49 | use std::ffi::{CStr, CString}; 50 | 51 | let mut buf = [0u8; 4096]; 52 | unsafe { 53 | let mut demangle = CDemangle::zero(); 54 | let cs = CString::new(input).unwrap(); 55 | for output_len in 0..4096 { 56 | rust_demangle_demangle(cs.as_ptr(), &mut demangle); 57 | if rust_demangle_display_demangle( 58 | &demangle, 59 | buf.as_mut_ptr().cast(), 60 | output_len, 61 | alternate, 62 | ) != 0 63 | { 64 | continue; // buffer is not big enough 65 | } 66 | let output = CStr::from_bytes_until_nul(&buf[..]) 67 | .expect("nul") 68 | .to_str() 69 | .expect("utf-8"); 70 | assert_eq!(output, expected); 71 | // test overflow margin 72 | assert_eq!(output_len, output.len() + 4); 73 | return; 74 | } 75 | panic!("overflow"); 76 | } 77 | } 78 | for (input, normal, alternate) in [ 79 | // test empty string 80 | ("", "", ""), 81 | // just a path 82 | ("_RNvC6_123foo3bar", "123foo::bar", "123foo::bar"), 83 | // more complex paths 84 | ("_RNCNCNgCs6DXkGYLi8lr_2cc5spawn00B5_", "cc[4d6468d6c9fd4bb3]::spawn::{closure#0}::{closure#0}", "cc::spawn::{closure#0}::{closure#0}"), 85 | ("_RINbNbCskIICzLVDPPb_5alloc5alloc8box_freeDINbNiB4_5boxed5FnBoxuEp6OutputuEL_ECs1iopQbuBiw2_3std", "alloc[f15a878b47eb696b]::alloc::box_free::>", "alloc::alloc::box_free::>"), 86 | ("_RMC0INtC8arrayvec8ArrayVechKj7b_E", ">", ">"), 87 | // punycode 88 | ("_RNqCs4fqI2P2rA04_11utf8_identsu30____7hkackfecea1cbdathfdh9hlq6y", "utf8_idents[317d481089b8c8fe]::საჭმელად_გემრიელი_სადილი", "utf8_idents::საჭმელად_გემრიელი_სადილი"), 89 | // string with non-utf8 characters 90 | ("_RIC0Kef09f908af09fa688f09fa686f09f90ae20c2a720f09f90b6f09f9192e29895f09f94a520c2a720f09fa7a1f09f929bf09f929af09f9299f09f929c_E", 91 | "::<{*\"\\u{1f40a}\\u{1f988}\\u{1f986}\\u{1f42e} \\u{a7} \\u{1f436}\\u{1f452}\\u{2615}\\u{1f525} \\u{a7} \\u{1f9e1}\\u{1f49b}\\u{1f49a}\\u{1f499}\\u{1f49c}\"}>", 92 | "::<{*\"\\u{1f40a}\\u{1f988}\\u{1f986}\\u{1f42e} \\u{a7} \\u{1f436}\\u{1f452}\\u{2615}\\u{1f525} \\u{a7} \\u{1f9e1}\\u{1f49b}\\u{1f49a}\\u{1f499}\\u{1f49c}\"}>" 93 | ), 94 | // invalid syntax via backref 95 | ("_RNvNvB0_1x1y", "{invalid syntax}::x::y", "{invalid syntax}::x::y"), 96 | // overflow via backref 97 | ("_RNvNvB1_1x1y", 98 | "{recursion limit reached}::?::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::y", 99 | "{recursion limit reached}::?::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::x::y", 100 | ), 101 | // native 102 | ("_ZN9backtrace3foo17hbb467fcdaea5d79bE.llvm.A5310EB9", "backtrace::foo::hbb467fcdaea5d79b", "backtrace::foo"), 103 | // LLVM suffix 104 | ("_RNvC6_123foo3bar.llvm.A5310EB9", "123foo::bar", "123foo::bar"), 105 | ("_ZN9backtrace3foo17hbb467fcdaea5d79bE.llvm.A5310EB9", "backtrace::foo::hbb467fcdaea5d79b", "backtrace::foo"), 106 | // other suffix 107 | ("_RNvC6_123foo3bar.i", "123foo::bar.i", "123foo::bar.i"), 108 | ("_ZN9backtrace3foo17hbb467fcdaea5d79bE.i", "backtrace::foo::hbb467fcdaea5d79b.i", "backtrace::foo.i"), 109 | ] { 110 | test_single(input, normal, false); 111 | test_single(input, alternate, true); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /fuzz/fuzz_targets/native_c.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | 3 | use std::ffi::{CStr, CString}; 4 | use std::fmt::Write; 5 | 6 | use libfuzzer_sys::fuzz_target; 7 | 8 | #[derive(Debug)] 9 | enum State<'a> { 10 | Ok(&'a str), 11 | Overflow, 12 | } 13 | 14 | pub struct FormatBuf<'a> { 15 | buf: &'a mut String, 16 | max_len: usize, 17 | } 18 | 19 | impl<'a> Write for FormatBuf<'a> { 20 | fn write_str(&mut self, s: &str) -> Result<(), std::fmt::Error> { 21 | if self.buf.len() + s.len() > self.max_len { 22 | return Err(std::fmt::Error); 23 | } 24 | self.buf.push_str(s); 25 | Ok(()) 26 | } 27 | } 28 | 29 | fn asciify(x: &str) -> String { 30 | let mut result = String::with_capacity(x.len() * 4); 31 | for ch in x.chars() { 32 | if ch.is_ascii() { 33 | result.push(ch); 34 | } else { 35 | write!(&mut result, "\\u{{{:x}}}", ch as u32).ok(); 36 | } 37 | } 38 | result 39 | } 40 | 41 | fn fuzz(data: &[u8], alternate: bool) { 42 | let mut str_buf = String::with_capacity(16384); 43 | let mut buf = [0u8; 4096]; 44 | let mut demangle = rustc_demangle_native_c::CDemangle::zero(); 45 | // We want to allow for easy overflow checking. The C output 46 | // can be longer than the Rust output by a factor of up to *7/2, 47 | // since e.g. an 'α' (U+03b1) in a constant string will be encoded 48 | // as [b'\xce' b'\xb1'] in the C output (2 bytes) but as 49 | // [b'\\' b'u' b'{' b'3' b'b' b'1' '}'] (7 bytes). The 50 | // other factors are smaller than that (4 hex digits = 3 utf-8 bytes, 51 | // leading to a lower expansion factor of *8/3, and so on). 52 | // 53 | // Also, to make the fuzzer more easily encounter overflow conditions 54 | // in the C code, and since for most outputs the output lengths is the 55 | // same, starting with a similar output length makes it easier. 56 | let starting_buf_len = buf.len() / 4; 57 | let state; 58 | if let Ok(s) = std::str::from_utf8(data) { 59 | if let Ok(cs) = CString::new(data) { 60 | unsafe { 61 | rustc_demangle_native_c::rust_demangle_demangle(cs.as_ptr(), &mut demangle); 62 | match rustc_demangle_native_c::rust_demangle_display_demangle( 63 | &demangle, 64 | buf.as_mut_ptr().cast(), 65 | starting_buf_len, 66 | alternate, 67 | ) { 68 | 0 => { 69 | state = State::Ok( 70 | CStr::from_bytes_until_nul(&buf[..]) 71 | .expect("nul") 72 | .to_str() 73 | .expect("utf-8"), 74 | ); 75 | } 76 | _ => { 77 | state = State::Overflow; 78 | } 79 | }; 80 | } 81 | let rdemangle = rustc_demangle::demangle(s); 82 | match state { 83 | State::Overflow => { 84 | str_buf.clear(); 85 | let fmt_buf = &mut FormatBuf { 86 | buf: &mut str_buf, 87 | max_len: starting_buf_len - 4, 88 | }; 89 | let rust_overflowed = if alternate { 90 | write!(fmt_buf, "{:#}", rdemangle) 91 | } else { 92 | write!(fmt_buf, "{}", rdemangle) 93 | }; 94 | if rust_overflowed.is_err() { 95 | return; // rust overflowed as well, OK 96 | } 97 | // call C again with larger buffer. If it fits in an 1020-byte Rust buffer, it will fit in a 4096-byte C buffer 98 | let c_demangled = unsafe { 99 | match rustc_demangle_native_c::rust_demangle_display_demangle( 100 | &demangle, 101 | buf.as_mut_ptr().cast(), 102 | buf.len(), 103 | alternate, 104 | ) { 105 | 0 => CStr::from_bytes_until_nul(&buf[..]) 106 | .expect("nul") 107 | .to_str() 108 | .expect("utf-8"), 109 | _ => { 110 | panic!("overflow again"); 111 | } 112 | } 113 | }; 114 | assert_eq!(asciify(&str_buf), asciify(c_demangled)); 115 | if c_demangled.len() < starting_buf_len - 3 { 116 | panic!( 117 | "spurious overflow {} {:?} {:?} {:?} {}", 118 | c_demangled.len(), 119 | alternate, 120 | asciify(&str_buf), 121 | asciify(c_demangled), 122 | starting_buf_len 123 | ) 124 | } 125 | } 126 | State::Ok(demangled) => { 127 | let fmt_buf = &mut FormatBuf { 128 | buf: &mut str_buf, 129 | max_len: starting_buf_len - 4, 130 | }; 131 | let rust_overflowed = if alternate { 132 | write!(fmt_buf, "{:#}", rdemangle) 133 | } else { 134 | write!(fmt_buf, "{}", rdemangle) 135 | }; 136 | if rust_overflowed.is_err() { 137 | panic!("rust overflowed 1020 but C output is <1024"); 138 | } 139 | assert_eq!( 140 | (alternate, asciify(&str_buf)), 141 | (alternate, asciify(demangled)) 142 | ); 143 | } 144 | } 145 | } 146 | } 147 | } 148 | 149 | fuzz_target!(|data: &[u8]| { 150 | // fuzz both normal and alternate modes. 151 | fuzz(data, false); 152 | fuzz(data, true); 153 | }); 154 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/legacy.rs: -------------------------------------------------------------------------------- 1 | use core::char; 2 | use core::fmt; 3 | 4 | /// Representation of a demangled symbol name. 5 | pub struct Demangle<'a> { 6 | inner: &'a str, 7 | /// The number of ::-separated elements in the original name. 8 | elements: usize, 9 | } 10 | 11 | /// De-mangles a Rust symbol into a more readable version 12 | /// 13 | /// All Rust symbols by default are mangled as they contain characters that 14 | /// cannot be represented in all object files. The mangling mechanism is similar 15 | /// to C++'s, but Rust has a few specifics to handle items like lifetimes in 16 | /// symbols. 17 | /// 18 | /// This function will take a **mangled** symbol and return a value. When printed, 19 | /// the de-mangled version will be written. If the symbol does not look like 20 | /// a mangled symbol, the original value will be written instead. 21 | /// 22 | /// # Examples 23 | /// 24 | /// ``` 25 | /// use rustc_demangle::demangle; 26 | /// 27 | /// assert_eq!(demangle("_ZN4testE").to_string(), "test"); 28 | /// assert_eq!(demangle("_ZN3foo3barE").to_string(), "foo::bar"); 29 | /// assert_eq!(demangle("foo").to_string(), "foo"); 30 | /// ``` 31 | 32 | // All Rust symbols are in theory lists of "::"-separated identifiers. Some 33 | // assemblers, however, can't handle these characters in symbol names. To get 34 | // around this, we use C++-style mangling. The mangling method is: 35 | // 36 | // 1. Prefix the symbol with "_ZN" 37 | // 2. For each element of the path, emit the length plus the element 38 | // 3. End the path with "E" 39 | // 40 | // For example, "_ZN4testE" => "test" and "_ZN3foo3barE" => "foo::bar". 41 | // 42 | // We're the ones printing our backtraces, so we can't rely on anything else to 43 | // demangle our symbols. It's *much* nicer to look at demangled symbols, so 44 | // this function is implemented to give us nice pretty output. 45 | // 46 | // Note that this demangler isn't quite as fancy as it could be. We have lots 47 | // of other information in our symbols like hashes, version, type information, 48 | // etc. Additionally, this doesn't handle glue symbols at all. 49 | pub fn demangle(s: &str) -> Result<(Demangle, &str), ()> { 50 | // First validate the symbol. If it doesn't look like anything we're 51 | // expecting, we just print it literally. Note that we must handle non-Rust 52 | // symbols because we could have any function in the backtrace. 53 | let inner = if s.starts_with("_ZN") { 54 | &s[3..] 55 | } else if s.starts_with("ZN") { 56 | // On Windows, dbghelp strips leading underscores, so we accept "ZN...E" 57 | // form too. 58 | &s[2..] 59 | } else if s.starts_with("__ZN") { 60 | // On OSX, symbols are prefixed with an extra _ 61 | &s[4..] 62 | } else { 63 | return Err(()); 64 | }; 65 | 66 | // only work with ascii text 67 | if inner.bytes().any(|c| c & 0x80 != 0) { 68 | return Err(()); 69 | } 70 | 71 | let mut elements = 0; 72 | let mut chars = inner.chars(); 73 | let mut c = chars.next().ok_or(())?; 74 | while c != 'E' { 75 | // Decode an identifier element's length. 76 | if !c.is_digit(10) { 77 | return Err(()); 78 | } 79 | let mut len = 0usize; 80 | while let Some(d) = c.to_digit(10) { 81 | len = len 82 | .checked_mul(10) 83 | .and_then(|len| len.checked_add(d as usize)) 84 | .ok_or(())?; 85 | c = chars.next().ok_or(())?; 86 | } 87 | 88 | // `c` already contains the first character of this identifier, skip it and 89 | // all the other characters of this identifier, to reach the next element. 90 | for _ in 0..len { 91 | c = chars.next().ok_or(())?; 92 | } 93 | 94 | elements += 1; 95 | } 96 | 97 | Ok((Demangle { inner, elements }, chars.as_str())) 98 | } 99 | 100 | // Rust hashes are hex digits with an `h` prepended. 101 | fn is_rust_hash(s: &str) -> bool { 102 | s.starts_with('h') && s[1..].chars().all(|c| c.is_digit(16)) 103 | } 104 | 105 | impl<'a> fmt::Display for Demangle<'a> { 106 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 107 | // Alright, let's do this. 108 | let mut inner = self.inner; 109 | for element in 0..self.elements { 110 | let mut rest = inner; 111 | while rest.chars().next().unwrap().is_digit(10) { 112 | rest = &rest[1..]; 113 | } 114 | let i: usize = inner[..(inner.len() - rest.len())].parse().unwrap(); 115 | inner = &rest[i..]; 116 | rest = &rest[..i]; 117 | // Skip printing the hash if alternate formatting 118 | // was requested. 119 | if f.alternate() && element + 1 == self.elements && is_rust_hash(&rest) { 120 | break; 121 | } 122 | if element != 0 { 123 | f.write_str("::")?; 124 | } 125 | if rest.starts_with("_$") { 126 | rest = &rest[1..]; 127 | } 128 | loop { 129 | if rest.starts_with('.') { 130 | if let Some('.') = rest[1..].chars().next() { 131 | f.write_str("::")?; 132 | rest = &rest[2..]; 133 | } else { 134 | f.write_str(".")?; 135 | rest = &rest[1..]; 136 | } 137 | } else if rest.starts_with('$') { 138 | let (escape, after_escape) = if let Some(end) = rest[1..].find('$') { 139 | (&rest[1..=end], &rest[end + 2..]) 140 | } else { 141 | break; 142 | }; 143 | 144 | // see src/librustc_codegen_utils/symbol_names/legacy.rs for these mappings 145 | let unescaped = match escape { 146 | "SP" => "@", 147 | "BP" => "*", 148 | "RF" => "&", 149 | "LT" => "<", 150 | "GT" => ">", 151 | "LP" => "(", 152 | "RP" => ")", 153 | "C" => ",", 154 | 155 | _ => { 156 | if escape.starts_with('u') { 157 | let digits = &escape[1..]; 158 | let all_lower_hex = digits.chars().all(|c| match c { 159 | '0'..='9' | 'a'..='f' => true, 160 | _ => false, 161 | }); 162 | let c = u32::from_str_radix(digits, 16) 163 | .ok() 164 | .and_then(char::from_u32); 165 | if let (true, Some(c)) = (all_lower_hex, c) { 166 | // FIXME(eddyb) do we need to filter out control codepoints? 167 | if !c.is_control() { 168 | c.fmt(f)?; 169 | rest = after_escape; 170 | continue; 171 | } 172 | } 173 | } 174 | break; 175 | } 176 | }; 177 | f.write_str(unescaped)?; 178 | rest = after_escape; 179 | } else if let Some(i) = rest.find(|c| c == '$' || c == '.') { 180 | f.write_str(&rest[..i])?; 181 | rest = &rest[i..]; 182 | } else { 183 | break; 184 | } 185 | } 186 | f.write_str(rest)?; 187 | } 188 | 189 | Ok(()) 190 | } 191 | } 192 | 193 | #[cfg(test)] 194 | mod tests { 195 | use std::prelude::v1::*; 196 | 197 | macro_rules! t { 198 | ($a:expr, $b:expr) => { 199 | assert!(ok($a, $b)) 200 | }; 201 | } 202 | 203 | macro_rules! t_err { 204 | ($a:expr) => { 205 | assert!(ok_err($a)) 206 | }; 207 | } 208 | 209 | macro_rules! t_nohash { 210 | ($a:expr, $b:expr) => {{ 211 | assert_eq!(format!("{:#}", ::demangle($a)), $b); 212 | }}; 213 | } 214 | 215 | fn ok(sym: &str, expected: &str) -> bool { 216 | match ::try_demangle(sym) { 217 | Ok(s) => { 218 | if s.to_string() == expected { 219 | true 220 | } else { 221 | println!("\n{}\n!=\n{}\n", s, expected); 222 | false 223 | } 224 | } 225 | Err(_) => { 226 | println!("error demangling"); 227 | false 228 | } 229 | } 230 | } 231 | 232 | fn ok_err(sym: &str) -> bool { 233 | match ::try_demangle(sym) { 234 | Ok(_) => { 235 | println!("succeeded in demangling"); 236 | false 237 | } 238 | Err(_) => ::demangle(sym).to_string() == sym, 239 | } 240 | } 241 | 242 | #[test] 243 | fn demangle() { 244 | t_err!("test"); 245 | t!("_ZN4testE", "test"); 246 | t_err!("_ZN4test"); 247 | t!("_ZN4test1a2bcE", "test::a::bc"); 248 | } 249 | 250 | #[test] 251 | fn demangle_dollars() { 252 | t!("_ZN4$RP$E", ")"); 253 | t!("_ZN8$RF$testE", "&test"); 254 | t!("_ZN8$BP$test4foobE", "*test::foob"); 255 | t!("_ZN9$u20$test4foobE", " test::foob"); 256 | t!("_ZN35Bar$LT$$u5b$u32$u3b$$u20$4$u5d$$GT$E", "Bar<[u32; 4]>"); 257 | } 258 | 259 | #[test] 260 | fn demangle_many_dollars() { 261 | t!("_ZN13test$u20$test4foobE", "test test::foob"); 262 | t!("_ZN12test$BP$test4foobE", "test*test::foob"); 263 | } 264 | 265 | #[test] 266 | fn demangle_osx() { 267 | t!( 268 | "__ZN5alloc9allocator6Layout9for_value17h02a996811f781011E", 269 | "alloc::allocator::Layout::for_value::h02a996811f781011" 270 | ); 271 | t!("__ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap18_MSG_FILE_LINE_COL17haf7cb8d5824ee659E", ">::unwrap::_MSG_FILE_LINE_COL::haf7cb8d5824ee659"); 272 | t!("__ZN4core5slice89_$LT$impl$u20$core..iter..traits..IntoIterator$u20$for$u20$$RF$$u27$a$u20$$u5b$T$u5d$$GT$9into_iter17h450e234d27262170E", "core::slice::::into_iter::h450e234d27262170"); 273 | } 274 | 275 | #[test] 276 | fn demangle_windows() { 277 | t!("ZN4testE", "test"); 278 | t!("ZN13test$u20$test4foobE", "test test::foob"); 279 | t!("ZN12test$RF$test4foobE", "test&test::foob"); 280 | } 281 | 282 | #[test] 283 | fn demangle_elements_beginning_with_underscore() { 284 | t!("_ZN13_$LT$test$GT$E", ""); 285 | t!("_ZN28_$u7b$$u7b$closure$u7d$$u7d$E", "{{closure}}"); 286 | t!("_ZN15__STATIC_FMTSTRE", "__STATIC_FMTSTR"); 287 | } 288 | 289 | #[test] 290 | fn demangle_trait_impls() { 291 | t!( 292 | "_ZN71_$LT$Test$u20$$u2b$$u20$$u27$static$u20$as$u20$foo..Bar$LT$Test$GT$$GT$3barE", 293 | ">::bar" 294 | ); 295 | } 296 | 297 | #[test] 298 | fn demangle_without_hash() { 299 | let s = "_ZN3foo17h05af221e174051e9E"; 300 | t!(s, "foo::h05af221e174051e9"); 301 | t_nohash!(s, "foo"); 302 | } 303 | 304 | #[test] 305 | fn demangle_without_hash_edgecases() { 306 | // One element, no hash. 307 | t_nohash!("_ZN3fooE", "foo"); 308 | // Two elements, no hash. 309 | t_nohash!("_ZN3foo3barE", "foo::bar"); 310 | // Longer-than-normal hash. 311 | t_nohash!("_ZN3foo20h05af221e174051e9abcE", "foo"); 312 | // Shorter-than-normal hash. 313 | t_nohash!("_ZN3foo5h05afE", "foo"); 314 | // Valid hash, but not at the end. 315 | t_nohash!("_ZN17h05af221e174051e93fooE", "h05af221e174051e9::foo"); 316 | // Not a valid hash, missing the 'h'. 317 | t_nohash!("_ZN3foo16ffaf221e174051e9E", "foo::ffaf221e174051e9"); 318 | // Not a valid hash, has a non-hex-digit. 319 | t_nohash!("_ZN3foo17hg5af221e174051e9E", "foo::hg5af221e174051e9"); 320 | } 321 | 322 | #[test] 323 | fn demangle_thinlto() { 324 | // One element, no hash. 325 | t!("_ZN3fooE.llvm.9D1C9369", "foo"); 326 | t!("_ZN3fooE.llvm.9D1C9369@@16", "foo"); 327 | t_nohash!( 328 | "_ZN9backtrace3foo17hbb467fcdaea5d79bE.llvm.A5310EB9", 329 | "backtrace::foo" 330 | ); 331 | } 332 | 333 | #[test] 334 | fn demangle_llvm_ir_branch_labels() { 335 | t!("_ZN4core5slice77_$LT$impl$u20$core..ops..index..IndexMut$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$9index_mut17haf9727c2edfbc47bE.exit.i.i", "core::slice:: for [T]>::index_mut::haf9727c2edfbc47b.exit.i.i"); 336 | t_nohash!("_ZN4core5slice77_$LT$impl$u20$core..ops..index..IndexMut$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$9index_mut17haf9727c2edfbc47bE.exit.i.i", "core::slice:: for [T]>::index_mut.exit.i.i"); 337 | } 338 | 339 | #[test] 340 | fn demangle_ignores_suffix_that_doesnt_look_like_a_symbol() { 341 | t_err!("_ZN3fooE.llvm moocow"); 342 | } 343 | 344 | #[test] 345 | fn dont_panic() { 346 | ::demangle("_ZN2222222222222222222222EE").to_string(); 347 | ::demangle("_ZN5*70527e27.ll34csaғE").to_string(); 348 | ::demangle("_ZN5*70527a54.ll34_$b.1E").to_string(); 349 | ::demangle( 350 | "\ 351 | _ZN5~saäb4e\n\ 352 | 2734cOsbE\n\ 353 | 5usage20h)3\0\0\0\0\0\0\07e2734cOsbE\ 354 | ", 355 | ) 356 | .to_string(); 357 | } 358 | 359 | #[test] 360 | fn invalid_no_chop() { 361 | t_err!("_ZNfooE"); 362 | } 363 | 364 | #[test] 365 | fn handle_assoc_types() { 366 | t!("_ZN151_$LT$alloc..boxed..Box$LT$alloc..boxed..FnBox$LT$A$C$$u20$Output$u3d$R$GT$$u20$$u2b$$u20$$u27$a$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$9call_once17h69e8f44b3723e1caE", " + 'a> as core::ops::function::FnOnce>::call_once::h69e8f44b3723e1ca"); 367 | } 368 | 369 | #[test] 370 | fn handle_bang() { 371 | t!( 372 | "_ZN88_$LT$core..result..Result$LT$$u21$$C$$u20$E$GT$$u20$as$u20$std..process..Termination$GT$6report17hfc41d0da4a40b3e8E", 373 | " as std::process::Termination>::report::hfc41d0da4a40b3e8" 374 | ); 375 | } 376 | 377 | #[test] 378 | fn demangle_utf8_idents() { 379 | t_nohash!( 380 | "_ZN11utf8_idents157_$u10e1$$u10d0$$u10ed$$u10db$$u10d4$$u10da$$u10d0$$u10d3$_$u10d2$$u10d4$$u10db$$u10e0$$u10d8$$u10d4$$u10da$$u10d8$_$u10e1$$u10d0$$u10d3$$u10d8$$u10da$$u10d8$17h21634fd5714000aaE", 381 | "utf8_idents::საჭმელად_გემრიელი_სადილი" 382 | ); 383 | } 384 | 385 | #[test] 386 | fn demangle_issue_60925() { 387 | t_nohash!( 388 | "_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h059a991a004536adE", 389 | "issue_60925::foo::Foo::foo" 390 | ); 391 | } 392 | } 393 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Demangle Rust compiler symbol names. 2 | //! 3 | //! This crate provides a `demangle` function which will return a `Demangle` 4 | //! sentinel value that can be used to learn about the demangled version of a 5 | //! symbol name. The demangled representation will be the same as the original 6 | //! if it doesn't look like a mangled symbol name. 7 | //! 8 | //! `Demangle` can be formatted with the `Display` trait. The alternate 9 | //! modifier (`#`) can be used to format the symbol name without the 10 | //! trailing hash value. 11 | //! 12 | //! # Examples 13 | //! 14 | //! ``` 15 | //! use rustc_demangle::demangle; 16 | //! 17 | //! assert_eq!(demangle("_ZN4testE").to_string(), "test"); 18 | //! assert_eq!(demangle("_ZN3foo3barE").to_string(), "foo::bar"); 19 | //! assert_eq!(demangle("foo").to_string(), "foo"); 20 | //! // With hash 21 | //! assert_eq!(format!("{}", demangle("_ZN3foo17h05af221e174051e9E")), "foo::h05af221e174051e9"); 22 | //! // Without hash 23 | //! assert_eq!(format!("{:#}", demangle("_ZN3foo17h05af221e174051e9E")), "foo"); 24 | //! ``` 25 | 26 | #![no_std] 27 | #![deny(missing_docs)] 28 | #![cfg_attr(docsrs, feature(doc_cfg))] 29 | 30 | #[cfg(any(test, feature = "std"))] 31 | #[macro_use] 32 | extern crate std; 33 | 34 | // HACK(eddyb) helper macros for tests. 35 | #[cfg(test)] 36 | macro_rules! assert_contains { 37 | ($s:expr, $needle:expr) => {{ 38 | let (s, needle) = ($s, $needle); 39 | assert!( 40 | s.contains(needle), 41 | "{:?} should've contained {:?}", 42 | s, 43 | needle 44 | ); 45 | }}; 46 | } 47 | #[cfg(test)] 48 | macro_rules! assert_ends_with { 49 | ($s:expr, $suffix:expr) => {{ 50 | let (s, suffix) = ($s, $suffix); 51 | assert!( 52 | s.ends_with(suffix), 53 | "{:?} should've ended in {:?}", 54 | s, 55 | suffix 56 | ); 57 | }}; 58 | } 59 | 60 | mod legacy; 61 | mod v0; 62 | 63 | use core::fmt::{self, Write as _}; 64 | 65 | /// Representation of a demangled symbol name. 66 | pub struct Demangle<'a> { 67 | style: Option>, 68 | original: &'a str, 69 | suffix: &'a str, 70 | } 71 | 72 | enum DemangleStyle<'a> { 73 | Legacy(legacy::Demangle<'a>), 74 | V0(v0::Demangle<'a>), 75 | } 76 | 77 | /// De-mangles a Rust symbol into a more readable version 78 | /// 79 | /// This function will take a **mangled** symbol and return a value. When printed, 80 | /// the de-mangled version will be written. If the symbol does not look like 81 | /// a mangled symbol, the original value will be written instead. 82 | /// 83 | /// # Examples 84 | /// 85 | /// ``` 86 | /// use rustc_demangle::demangle; 87 | /// 88 | /// assert_eq!(demangle("_ZN4testE").to_string(), "test"); 89 | /// assert_eq!(demangle("_ZN3foo3barE").to_string(), "foo::bar"); 90 | /// assert_eq!(demangle("foo").to_string(), "foo"); 91 | /// ``` 92 | pub fn demangle(mut s: &str) -> Demangle { 93 | // During ThinLTO LLVM may import and rename internal symbols, so strip out 94 | // those endings first as they're one of the last manglings applied to symbol 95 | // names. 96 | let llvm = ".llvm."; 97 | if let Some(i) = s.find(llvm) { 98 | let candidate = &s[i + llvm.len()..]; 99 | let all_hex = candidate.chars().all(|c| match c { 100 | 'A'..='F' | '0'..='9' | '@' => true, 101 | _ => false, 102 | }); 103 | 104 | if all_hex { 105 | s = &s[..i]; 106 | } 107 | } 108 | 109 | let mut suffix = ""; 110 | let mut style = match legacy::demangle(s) { 111 | Ok((d, s)) => { 112 | suffix = s; 113 | Some(DemangleStyle::Legacy(d)) 114 | } 115 | Err(()) => match v0::demangle(s) { 116 | Ok((d, s)) => { 117 | suffix = s; 118 | Some(DemangleStyle::V0(d)) 119 | } 120 | // FIXME(eddyb) would it make sense to treat an unknown-validity 121 | // symbol (e.g. one that errored with `RecursedTooDeep`) as 122 | // v0-mangled, and have the error show up in the demangling? 123 | // (that error already gets past this initial check, and therefore 124 | // will show up in the demangling, if hidden behind a backref) 125 | Err(v0::ParseError::Invalid) | Err(v0::ParseError::RecursedTooDeep) => None, 126 | }, 127 | }; 128 | 129 | // Output like LLVM IR adds extra period-delimited words. See if 130 | // we are in that case and save the trailing words if so. 131 | if !suffix.is_empty() { 132 | if suffix.starts_with('.') && is_symbol_like(suffix) { 133 | // Keep the suffix. 134 | } else { 135 | // Reset the suffix and invalidate the demangling. 136 | suffix = ""; 137 | style = None; 138 | } 139 | } 140 | 141 | Demangle { 142 | style, 143 | original: s, 144 | suffix, 145 | } 146 | } 147 | 148 | #[cfg(feature = "std")] 149 | fn demangle_line( 150 | line: &str, 151 | output: &mut impl std::io::Write, 152 | include_hash: bool, 153 | ) -> std::io::Result<()> { 154 | let mut head = 0; 155 | while head < line.len() { 156 | // Move to the next potential match 157 | let next_head = match (line[head..].find("_ZN"), line[head..].find("_R")) { 158 | (Some(idx), None) | (None, Some(idx)) => head + idx, 159 | (Some(idx1), Some(idx2)) => head + idx1.min(idx2), 160 | (None, None) => { 161 | // No more matches... 162 | line.len() 163 | } 164 | }; 165 | output.write_all(line[head..next_head].as_bytes())?; 166 | head = next_head; 167 | // Find the non-matching character. 168 | // 169 | // If we do not find a character, then until the end of the line is the 170 | // thing to demangle. 171 | let match_end = line[head..] 172 | .find(|ch: char| !(ch == '$' || ch == '.' || ch == '_' || ch.is_ascii_alphanumeric())) 173 | .map(|idx| head + idx) 174 | .unwrap_or(line.len()); 175 | 176 | let mangled = &line[head..match_end]; 177 | head = head + mangled.len(); 178 | if let Ok(demangled) = try_demangle(mangled) { 179 | if include_hash { 180 | write!(output, "{}", demangled)?; 181 | } else { 182 | write!(output, "{:#}", demangled)?; 183 | } 184 | } else { 185 | output.write_all(mangled.as_bytes())?; 186 | } 187 | } 188 | Ok(()) 189 | } 190 | 191 | /// Process a stream of data from `input` into the provided `output`, demangling any symbols found 192 | /// within. 193 | /// 194 | /// Note that the underlying implementation will perform many relatively small writes to the 195 | /// output. If the output is expensive to write to (e.g., requires syscalls), consider using 196 | /// `std::io::BufWriter`. 197 | #[cfg(feature = "std")] 198 | #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 199 | pub fn demangle_stream( 200 | input: &mut R, 201 | output: &mut W, 202 | include_hash: bool, 203 | ) -> std::io::Result<()> { 204 | let mut buf = std::string::String::new(); 205 | // We read in lines to reduce the memory usage at any time. 206 | // 207 | // demangle_line is also more efficient with relatively small buffers as it will copy around 208 | // trailing data during demangling. In the future we might directly stream to the output but at 209 | // least right now that seems to be less efficient. 210 | while input.read_line(&mut buf)? > 0 { 211 | demangle_line(&buf, output, include_hash)?; 212 | buf.clear(); 213 | } 214 | Ok(()) 215 | } 216 | 217 | /// Error returned from the `try_demangle` function below when demangling fails. 218 | #[derive(Debug, Clone)] 219 | pub struct TryDemangleError { 220 | _priv: (), 221 | } 222 | 223 | /// The same as `demangle`, except return an `Err` if the string does not appear 224 | /// to be a Rust symbol, rather than "demangling" the given string as a no-op. 225 | /// 226 | /// ``` 227 | /// extern crate rustc_demangle; 228 | /// 229 | /// let not_a_rust_symbol = "la la la"; 230 | /// 231 | /// // The `try_demangle` function will reject strings which are not Rust symbols. 232 | /// assert!(rustc_demangle::try_demangle(not_a_rust_symbol).is_err()); 233 | /// 234 | /// // While `demangle` will just pass the non-symbol through as a no-op. 235 | /// assert_eq!(rustc_demangle::demangle(not_a_rust_symbol).as_str(), not_a_rust_symbol); 236 | /// ``` 237 | pub fn try_demangle(s: &str) -> Result { 238 | let sym = demangle(s); 239 | if sym.style.is_some() { 240 | Ok(sym) 241 | } else { 242 | Err(TryDemangleError { _priv: () }) 243 | } 244 | } 245 | 246 | impl<'a> Demangle<'a> { 247 | /// Returns the underlying string that's being demangled. 248 | pub fn as_str(&self) -> &'a str { 249 | self.original 250 | } 251 | } 252 | 253 | fn is_symbol_like(s: &str) -> bool { 254 | s.chars().all(|c| { 255 | // Once `char::is_ascii_punctuation` and `char::is_ascii_alphanumeric` 256 | // have been stable for long enough, use those instead for clarity 257 | is_ascii_alphanumeric(c) || is_ascii_punctuation(c) 258 | }) 259 | } 260 | 261 | // Copied from the documentation of `char::is_ascii_alphanumeric` 262 | fn is_ascii_alphanumeric(c: char) -> bool { 263 | match c { 264 | '\u{0041}'..='\u{005A}' | '\u{0061}'..='\u{007A}' | '\u{0030}'..='\u{0039}' => true, 265 | _ => false, 266 | } 267 | } 268 | 269 | // Copied from the documentation of `char::is_ascii_punctuation` 270 | fn is_ascii_punctuation(c: char) -> bool { 271 | match c { 272 | '\u{0021}'..='\u{002F}' 273 | | '\u{003A}'..='\u{0040}' 274 | | '\u{005B}'..='\u{0060}' 275 | | '\u{007B}'..='\u{007E}' => true, 276 | _ => false, 277 | } 278 | } 279 | 280 | impl<'a> fmt::Display for DemangleStyle<'a> { 281 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 282 | match *self { 283 | DemangleStyle::Legacy(ref d) => fmt::Display::fmt(d, f), 284 | DemangleStyle::V0(ref d) => fmt::Display::fmt(d, f), 285 | } 286 | } 287 | } 288 | 289 | // Maximum size of the symbol that we'll print. 290 | const MAX_SIZE: usize = 1_000_000; 291 | 292 | #[derive(Copy, Clone, Debug)] 293 | struct SizeLimitExhausted; 294 | 295 | struct SizeLimitedFmtAdapter { 296 | remaining: Result, 297 | inner: F, 298 | } 299 | 300 | impl fmt::Write for SizeLimitedFmtAdapter { 301 | fn write_str(&mut self, s: &str) -> fmt::Result { 302 | self.remaining = self 303 | .remaining 304 | .and_then(|r| r.checked_sub(s.len()).ok_or(SizeLimitExhausted)); 305 | 306 | match self.remaining { 307 | Ok(_) => self.inner.write_str(s), 308 | Err(SizeLimitExhausted) => Err(fmt::Error), 309 | } 310 | } 311 | } 312 | 313 | impl<'a> fmt::Display for Demangle<'a> { 314 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 315 | match self.style { 316 | None => f.write_str(self.original)?, 317 | Some(ref d) => { 318 | let alternate = f.alternate(); 319 | let mut size_limited_fmt = SizeLimitedFmtAdapter { 320 | remaining: Ok(MAX_SIZE), 321 | inner: &mut *f, 322 | }; 323 | let fmt_result = if alternate { 324 | write!(size_limited_fmt, "{:#}", d) 325 | } else { 326 | write!(size_limited_fmt, "{}", d) 327 | }; 328 | let size_limit_result = size_limited_fmt.remaining.map(|_| ()); 329 | 330 | // Translate a `fmt::Error` generated by `SizeLimitedFmtAdapter` 331 | // into an error message, instead of propagating it upwards 332 | // (which could cause panicking from inside e.g. `std::io::print`). 333 | match (fmt_result, size_limit_result) { 334 | (Err(_), Err(SizeLimitExhausted)) => f.write_str("{size limit reached}")?, 335 | 336 | _ => { 337 | fmt_result?; 338 | size_limit_result 339 | .expect("`fmt::Error` from `SizeLimitedFmtAdapter` was discarded"); 340 | } 341 | } 342 | } 343 | } 344 | f.write_str(self.suffix) 345 | } 346 | } 347 | 348 | impl<'a> fmt::Debug for Demangle<'a> { 349 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 350 | fmt::Display::fmt(self, f) 351 | } 352 | } 353 | 354 | #[cfg(test)] 355 | mod tests { 356 | use std::prelude::v1::*; 357 | 358 | macro_rules! t { 359 | ($a:expr, $b:expr) => { 360 | assert!(ok($a, $b)) 361 | }; 362 | } 363 | 364 | macro_rules! t_err { 365 | ($a:expr) => { 366 | assert!(ok_err($a)) 367 | }; 368 | } 369 | 370 | macro_rules! t_nohash { 371 | ($a:expr, $b:expr) => {{ 372 | assert_eq!(format!("{:#}", super::demangle($a)), $b); 373 | }}; 374 | } 375 | 376 | fn ok(sym: &str, expected: &str) -> bool { 377 | match super::try_demangle(sym) { 378 | Ok(s) => { 379 | if s.to_string() == expected { 380 | true 381 | } else { 382 | println!("\n{}\n!=\n{}\n", s, expected); 383 | false 384 | } 385 | } 386 | Err(_) => { 387 | println!("error demangling"); 388 | false 389 | } 390 | } 391 | } 392 | 393 | fn ok_err(sym: &str) -> bool { 394 | match super::try_demangle(sym) { 395 | Ok(_) => { 396 | println!("succeeded in demangling"); 397 | false 398 | } 399 | Err(_) => super::demangle(sym).to_string() == sym, 400 | } 401 | } 402 | 403 | #[test] 404 | fn demangle() { 405 | t_err!("test"); 406 | t!("_ZN4testE", "test"); 407 | t_err!("_ZN4test"); 408 | t!("_ZN4test1a2bcE", "test::a::bc"); 409 | } 410 | 411 | #[test] 412 | fn demangle_dollars() { 413 | t!("_ZN4$RP$E", ")"); 414 | t!("_ZN8$RF$testE", "&test"); 415 | t!("_ZN8$BP$test4foobE", "*test::foob"); 416 | t!("_ZN9$u20$test4foobE", " test::foob"); 417 | t!("_ZN35Bar$LT$$u5b$u32$u3b$$u20$4$u5d$$GT$E", "Bar<[u32; 4]>"); 418 | } 419 | 420 | #[test] 421 | fn demangle_many_dollars() { 422 | t!("_ZN13test$u20$test4foobE", "test test::foob"); 423 | t!("_ZN12test$BP$test4foobE", "test*test::foob"); 424 | } 425 | 426 | #[test] 427 | fn demangle_osx() { 428 | t!( 429 | "__ZN5alloc9allocator6Layout9for_value17h02a996811f781011E", 430 | "alloc::allocator::Layout::for_value::h02a996811f781011" 431 | ); 432 | t!("__ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap18_MSG_FILE_LINE_COL17haf7cb8d5824ee659E", ">::unwrap::_MSG_FILE_LINE_COL::haf7cb8d5824ee659"); 433 | t!("__ZN4core5slice89_$LT$impl$u20$core..iter..traits..IntoIterator$u20$for$u20$$RF$$u27$a$u20$$u5b$T$u5d$$GT$9into_iter17h450e234d27262170E", "core::slice::::into_iter::h450e234d27262170"); 434 | } 435 | 436 | #[test] 437 | fn demangle_windows() { 438 | t!("ZN4testE", "test"); 439 | t!("ZN13test$u20$test4foobE", "test test::foob"); 440 | t!("ZN12test$RF$test4foobE", "test&test::foob"); 441 | } 442 | 443 | #[test] 444 | fn demangle_elements_beginning_with_underscore() { 445 | t!("_ZN13_$LT$test$GT$E", ""); 446 | t!("_ZN28_$u7b$$u7b$closure$u7d$$u7d$E", "{{closure}}"); 447 | t!("_ZN15__STATIC_FMTSTRE", "__STATIC_FMTSTR"); 448 | } 449 | 450 | #[test] 451 | fn demangle_trait_impls() { 452 | t!( 453 | "_ZN71_$LT$Test$u20$$u2b$$u20$$u27$static$u20$as$u20$foo..Bar$LT$Test$GT$$GT$3barE", 454 | ">::bar" 455 | ); 456 | } 457 | 458 | #[test] 459 | fn demangle_without_hash() { 460 | let s = "_ZN3foo17h05af221e174051e9E"; 461 | t!(s, "foo::h05af221e174051e9"); 462 | t_nohash!(s, "foo"); 463 | } 464 | 465 | #[test] 466 | fn demangle_without_hash_edgecases() { 467 | // One element, no hash. 468 | t_nohash!("_ZN3fooE", "foo"); 469 | // Two elements, no hash. 470 | t_nohash!("_ZN3foo3barE", "foo::bar"); 471 | // Longer-than-normal hash. 472 | t_nohash!("_ZN3foo20h05af221e174051e9abcE", "foo"); 473 | // Shorter-than-normal hash. 474 | t_nohash!("_ZN3foo5h05afE", "foo"); 475 | // Valid hash, but not at the end. 476 | t_nohash!("_ZN17h05af221e174051e93fooE", "h05af221e174051e9::foo"); 477 | // Not a valid hash, missing the 'h'. 478 | t_nohash!("_ZN3foo16ffaf221e174051e9E", "foo::ffaf221e174051e9"); 479 | // Not a valid hash, has a non-hex-digit. 480 | t_nohash!("_ZN3foo17hg5af221e174051e9E", "foo::hg5af221e174051e9"); 481 | } 482 | 483 | #[test] 484 | fn demangle_thinlto() { 485 | // One element, no hash. 486 | t!("_ZN3fooE.llvm.9D1C9369", "foo"); 487 | t!("_ZN3fooE.llvm.9D1C9369@@16", "foo"); 488 | t_nohash!( 489 | "_ZN9backtrace3foo17hbb467fcdaea5d79bE.llvm.A5310EB9", 490 | "backtrace::foo" 491 | ); 492 | } 493 | 494 | #[test] 495 | fn demangle_llvm_ir_branch_labels() { 496 | t!("_ZN4core5slice77_$LT$impl$u20$core..ops..index..IndexMut$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$9index_mut17haf9727c2edfbc47bE.exit.i.i", "core::slice:: for [T]>::index_mut::haf9727c2edfbc47b.exit.i.i"); 497 | t_nohash!("_ZN4core5slice77_$LT$impl$u20$core..ops..index..IndexMut$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$9index_mut17haf9727c2edfbc47bE.exit.i.i", "core::slice:: for [T]>::index_mut.exit.i.i"); 498 | } 499 | 500 | #[test] 501 | fn demangle_ignores_suffix_that_doesnt_look_like_a_symbol() { 502 | t_err!("_ZN3fooE.llvm moocow"); 503 | } 504 | 505 | #[test] 506 | fn dont_panic() { 507 | super::demangle("_ZN2222222222222222222222EE").to_string(); 508 | super::demangle("_ZN5*70527e27.ll34csaғE").to_string(); 509 | super::demangle("_ZN5*70527a54.ll34_$b.1E").to_string(); 510 | super::demangle( 511 | "\ 512 | _ZN5~saäb4e\n\ 513 | 2734cOsbE\n\ 514 | 5usage20h)3\0\0\0\0\0\0\07e2734cOsbE\ 515 | ", 516 | ) 517 | .to_string(); 518 | } 519 | 520 | #[test] 521 | fn invalid_no_chop() { 522 | t_err!("_ZNfooE"); 523 | } 524 | 525 | #[test] 526 | fn handle_assoc_types() { 527 | t!("_ZN151_$LT$alloc..boxed..Box$LT$alloc..boxed..FnBox$LT$A$C$$u20$Output$u3d$R$GT$$u20$$u2b$$u20$$u27$a$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$9call_once17h69e8f44b3723e1caE", " + 'a> as core::ops::function::FnOnce>::call_once::h69e8f44b3723e1ca"); 528 | } 529 | 530 | #[test] 531 | fn handle_bang() { 532 | t!( 533 | "_ZN88_$LT$core..result..Result$LT$$u21$$C$$u20$E$GT$$u20$as$u20$std..process..Termination$GT$6report17hfc41d0da4a40b3e8E", 534 | " as std::process::Termination>::report::hfc41d0da4a40b3e8" 535 | ); 536 | } 537 | 538 | #[test] 539 | fn limit_recursion() { 540 | assert_contains!( 541 | super::demangle("_RNvB_1a").to_string(), 542 | "{recursion limit reached}" 543 | ); 544 | assert_contains!( 545 | super::demangle("_RMC0RB2_").to_string(), 546 | "{recursion limit reached}" 547 | ); 548 | } 549 | 550 | #[test] 551 | fn limit_output() { 552 | assert_ends_with!( 553 | super::demangle("RYFG_FGyyEvRYFF_EvRYFFEvERLB_B_B_ERLRjB_B_B_").to_string(), 554 | "{size limit reached}" 555 | ); 556 | // NOTE(eddyb) somewhat reduced version of the above, effectively 557 | // ` fn()>` with a larger number of lifetimes in `...`. 558 | assert_ends_with!( 559 | super::demangle("_RMC0FGZZZ_Eu").to_string(), 560 | "{size limit reached}" 561 | ); 562 | } 563 | 564 | #[cfg(feature = "std")] 565 | fn demangle_str(input: &str) -> String { 566 | let mut output = Vec::new(); 567 | super::demangle_line(input, &mut output, false); 568 | String::from_utf8(output).unwrap() 569 | } 570 | 571 | #[test] 572 | #[cfg(feature = "std")] 573 | fn find_multiple() { 574 | assert_eq!( 575 | demangle_str("_ZN3fooE.llvm moocow _ZN3fooE.llvm"), 576 | "foo.llvm moocow foo.llvm" 577 | ); 578 | } 579 | 580 | #[test] 581 | #[cfg(feature = "std")] 582 | fn interleaved_new_legacy() { 583 | assert_eq!( 584 | demangle_str("_ZN3fooE.llvm moocow _RNvMNtNtNtNtCs8a2262Dv4r_3mio3sys4unix8selector5epollNtB2_8Selector6select _ZN3fooE.llvm"), 585 | "foo.llvm moocow ::select foo.llvm" 586 | ); 587 | } 588 | } 589 | -------------------------------------------------------------------------------- /src/v0-large-test-symbols/early-recursion-limit: -------------------------------------------------------------------------------- 1 | # NOTE: empty lines, and lines starting with `#`, are ignored. 2 | 3 | # Large test symbols for `v0::test::demangling_limits`, that specifically cause 4 | # a `RecursedTooDeep` error from `v0::demangle`'s shallow traversal (sanity check) 5 | # of the mangled symbol, i.e. before any printing coudl be attempted. 6 | 7 | RICu4$TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOSOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTxxxxxRICu4,-xOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTxxxxxRICu4,-xOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTxxxxxRICu4,-xOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTxxxxxRICu4,-xOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTxxxxxRICu4,-xOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTxxxxxRICu4,-xOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTxxxxxRICu4,-xOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTxxxxxRICu4,-xOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTYTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTxxxxxRICu4,-xOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTxxxxxRICu4,-xOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTxxxxxRICu5,-xOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTxxxxxRICu3.,-xOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOxxxRICu4,-xxxxffff..ffffffffffffffffffffffffffffffffffffffffffffffffffffffffxxxxxxxxxxxxxxxxxxxRaRBRaR>R>xxxu2IC,-xxxxxxRIC4xxxOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTxxxxxRICu4.,-xOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOTTTOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOxxxRICu4,-xxxxffff..ffffffffffffffffffffffffffffffffffffffffffffffffffffffffxxxxxxxxxxxxxxxxxxxRaRBRaR>R>xxxu2IC,-xxxxxxRIC4xxx..K..xRBRaR>RICu6$-RBKIQARICu6$-RBKIQAA........TvvKKKKKKKKKxxxxxxxxxxxxxxxBKIQARICu6$-RBKIQAA...._.xxx 8 | RIYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRYYYYYYYYYXB_RXB_lYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRYYYYYYYYYXB_RXB_lYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRYFhhhhYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYNYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRYYYYYYYYYXB_RXB_lYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRYYYYYYYYYXB_RXB_lYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYNYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRYYYYYYYYYXB_RXB_lYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRYYYYYYYYYXB_RXB_lYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRYFhhhhYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYNYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRYYYYYYYYYXB_RXB_lYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRYYYYYYYYYXB_RXB_lYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRYYYYYYYYYXB_RXB_lYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYMYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRXB_RXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYIBRIIRIIBRCIByEEj_ByEEj_EEj 9 | RYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRSSSSSSSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSYYYYYYYYYYYYRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSYYYYSSSSSSSSSSSSSSSSSYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRSSSSSSSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYSSSSRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRSSSSSSSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRSSSSSSSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRSSSSSSSRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRSSSSSSSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSYYYYYYYYYYYYRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRSSSSSSSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRSSSSSSSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRSSSSSSSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRSSSSSSSRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRSSSSSSSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRSSSSSSSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRSSSSSSSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRSSSSSSSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYyYYYbYYYYYYYYYYYYYYRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRYYYYYYYYYYYYYmYYYYYYYYYYYYYYYYYYYYYRCu3YYYYYYYYYYYPYYYYYYbYYYYYYYYYRYYYYYYYYYYYYYYYYYYSSSSSSSSSSSS 10 | RYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYyYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYR; 11 | -------------------------------------------------------------------------------- /src/v0.rs: -------------------------------------------------------------------------------- 1 | use core::convert::TryFrom; 2 | use core::{char, fmt, iter, mem, str}; 3 | 4 | #[allow(unused_macros)] 5 | macro_rules! write { 6 | ($($ignored:tt)*) => { 7 | compile_error!( 8 | "use `self.print(value)` or `fmt::Trait::fmt(&value, self.out)`, \ 9 | instead of `write!(self.out, \"{...}\", value)`" 10 | ) 11 | }; 12 | } 13 | 14 | // Maximum recursion depth when parsing symbols before we just bail out saying 15 | // "this symbol is invalid" 16 | const MAX_DEPTH: u32 = 500; 17 | 18 | /// Representation of a demangled symbol name. 19 | pub struct Demangle<'a> { 20 | inner: &'a str, 21 | } 22 | 23 | #[derive(PartialEq, Eq, Debug)] 24 | pub enum ParseError { 25 | /// Symbol doesn't match the expected `v0` grammar. 26 | Invalid, 27 | 28 | /// Parsing the symbol crossed the recursion limit (see `MAX_DEPTH`). 29 | RecursedTooDeep, 30 | } 31 | 32 | /// De-mangles a Rust symbol into a more readable version 33 | /// 34 | /// This function will take a **mangled** symbol and return a value. When printed, 35 | /// the de-mangled version will be written. If the symbol does not look like 36 | /// a mangled symbol, the original value will be written instead. 37 | pub fn demangle(s: &str) -> Result<(Demangle, &str), ParseError> { 38 | // First validate the symbol. If it doesn't look like anything we're 39 | // expecting, we just print it literally. Note that we must handle non-Rust 40 | // symbols because we could have any function in the backtrace. 41 | let inner; 42 | if s.len() > 2 && s.starts_with("_R") { 43 | inner = &s[2..]; 44 | } else if s.len() > 1 && s.starts_with('R') { 45 | // On Windows, dbghelp strips leading underscores, so we accept "R..." 46 | // form too. 47 | inner = &s[1..]; 48 | } else if s.len() > 3 && s.starts_with("__R") { 49 | // On OSX, symbols are prefixed with an extra _ 50 | inner = &s[3..]; 51 | } else { 52 | return Err(ParseError::Invalid); 53 | } 54 | 55 | // Paths always start with uppercase characters. 56 | match inner.as_bytes()[0] { 57 | b'A'..=b'Z' => {} 58 | _ => return Err(ParseError::Invalid), 59 | } 60 | 61 | // only work with ascii text 62 | if inner.bytes().any(|c| c & 0x80 != 0) { 63 | return Err(ParseError::Invalid); 64 | } 65 | 66 | // Verify that the symbol is indeed a valid path. 67 | let try_parse_path = |parser| { 68 | let mut dummy_printer = Printer { 69 | parser: Ok(parser), 70 | out: None, 71 | bound_lifetime_depth: 0, 72 | }; 73 | dummy_printer 74 | .print_path(false) 75 | .expect("`fmt::Error`s should be impossible without a `fmt::Formatter`"); 76 | dummy_printer.parser 77 | }; 78 | let mut parser = Parser { 79 | sym: inner, 80 | next: 0, 81 | depth: 0, 82 | }; 83 | parser = try_parse_path(parser)?; 84 | 85 | // Instantiating crate (paths always start with uppercase characters). 86 | if let Some(&(b'A'..=b'Z')) = parser.sym.as_bytes().get(parser.next) { 87 | parser = try_parse_path(parser)?; 88 | } 89 | 90 | Ok((Demangle { inner }, &parser.sym[parser.next..])) 91 | } 92 | 93 | impl<'s> fmt::Display for Demangle<'s> { 94 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 95 | let mut printer = Printer { 96 | parser: Ok(Parser { 97 | sym: self.inner, 98 | next: 0, 99 | depth: 0, 100 | }), 101 | out: Some(f), 102 | bound_lifetime_depth: 0, 103 | }; 104 | printer.print_path(true) 105 | } 106 | } 107 | 108 | struct Ident<'s> { 109 | /// ASCII part of the identifier. 110 | ascii: &'s str, 111 | /// Punycode insertion codes for Unicode codepoints, if any. 112 | punycode: &'s str, 113 | } 114 | 115 | const SMALL_PUNYCODE_LEN: usize = 128; 116 | 117 | impl<'s> Ident<'s> { 118 | /// Attempt to decode punycode on the stack (allocation-free), 119 | /// and pass the char slice to the closure, if successful. 120 | /// This supports up to `SMALL_PUNYCODE_LEN` characters. 121 | fn try_small_punycode_decode R, R>(&self, f: F) -> Option { 122 | let mut out = ['\0'; SMALL_PUNYCODE_LEN]; 123 | let mut out_len = 0; 124 | let r = self.punycode_decode(|i, c| { 125 | // Check there's space left for another character. 126 | out.get(out_len).ok_or(())?; 127 | 128 | // Move the characters after the insert position. 129 | let mut j = out_len; 130 | out_len += 1; 131 | 132 | while j > i { 133 | out[j] = out[j - 1]; 134 | j -= 1; 135 | } 136 | 137 | // Insert the new character. 138 | out[i] = c; 139 | 140 | Ok(()) 141 | }); 142 | if r.is_ok() { 143 | Some(f(&out[..out_len])) 144 | } else { 145 | None 146 | } 147 | } 148 | 149 | /// Decode punycode as insertion positions and characters 150 | /// and pass them to the closure, which can return `Err(())` 151 | /// to stop the decoding process. 152 | fn punycode_decode Result<(), ()>>( 153 | &self, 154 | mut insert: F, 155 | ) -> Result<(), ()> { 156 | let mut punycode_bytes = self.punycode.bytes().peekable(); 157 | if punycode_bytes.peek().is_none() { 158 | return Err(()); 159 | } 160 | 161 | let mut len = 0; 162 | 163 | // Populate initial output from ASCII fragment. 164 | for c in self.ascii.chars() { 165 | insert(len, c)?; 166 | len += 1; 167 | } 168 | 169 | // Punycode parameters and initial state. 170 | let base = 36; 171 | let t_min = 1; 172 | let t_max = 26; 173 | let skew = 38; 174 | let mut damp = 700; 175 | let mut bias = 72; 176 | let mut i: usize = 0; 177 | let mut n: usize = 0x80; 178 | 179 | loop { 180 | // Read one delta value. 181 | let mut delta: usize = 0; 182 | let mut w = 1; 183 | let mut k: usize = 0; 184 | loop { 185 | use core::cmp::{max, min}; 186 | 187 | k += base; 188 | let t = min(max(k.saturating_sub(bias), t_min), t_max); 189 | 190 | let d = match punycode_bytes.next() { 191 | Some(d @ b'a'..=b'z') => d - b'a', 192 | Some(d @ b'0'..=b'9') => 26 + (d - b'0'), 193 | _ => return Err(()), 194 | }; 195 | let d = d as usize; 196 | delta = delta.checked_add(d.checked_mul(w).ok_or(())?).ok_or(())?; 197 | if d < t { 198 | break; 199 | } 200 | w = w.checked_mul(base - t).ok_or(())?; 201 | } 202 | 203 | // Compute the new insert position and character. 204 | len += 1; 205 | i = i.checked_add(delta).ok_or(())?; 206 | n = n.checked_add(i / len).ok_or(())?; 207 | i %= len; 208 | 209 | let n_u32 = n as u32; 210 | let c = if n_u32 as usize == n { 211 | char::from_u32(n_u32).ok_or(())? 212 | } else { 213 | return Err(()); 214 | }; 215 | 216 | // Insert the new character and increment the insert position. 217 | insert(i, c)?; 218 | i += 1; 219 | 220 | // If there are no more deltas, decoding is complete. 221 | if punycode_bytes.peek().is_none() { 222 | return Ok(()); 223 | } 224 | 225 | // Perform bias adaptation. 226 | delta /= damp; 227 | damp = 2; 228 | 229 | delta += delta / len; 230 | let mut k = 0; 231 | while delta > ((base - t_min) * t_max) / 2 { 232 | delta /= base - t_min; 233 | k += base; 234 | } 235 | bias = k + ((base - t_min + 1) * delta) / (delta + skew); 236 | } 237 | } 238 | } 239 | 240 | impl<'s> fmt::Display for Ident<'s> { 241 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 242 | self.try_small_punycode_decode(|chars| { 243 | for &c in chars { 244 | c.fmt(f)?; 245 | } 246 | Ok(()) 247 | }) 248 | .unwrap_or_else(|| { 249 | if !self.punycode.is_empty() { 250 | f.write_str("punycode{")?; 251 | 252 | // Reconstruct a standard Punycode encoding, 253 | // by using `-` as the separator. 254 | if !self.ascii.is_empty() { 255 | f.write_str(self.ascii)?; 256 | f.write_str("-")?; 257 | } 258 | f.write_str(self.punycode)?; 259 | 260 | f.write_str("}") 261 | } else { 262 | f.write_str(self.ascii) 263 | } 264 | }) 265 | } 266 | } 267 | 268 | /// Sequence of lowercase hexadecimal nibbles (`0-9a-f`), used by leaf consts. 269 | struct HexNibbles<'s> { 270 | nibbles: &'s str, 271 | } 272 | 273 | impl<'s> HexNibbles<'s> { 274 | /// Decode an integer value (with the "most significant nibble" first), 275 | /// returning `None` if it can't fit in an `u64`. 276 | // FIXME(eddyb) should this "just" use `u128` instead? 277 | fn try_parse_uint(&self) -> Option { 278 | let nibbles = self.nibbles.trim_start_matches("0"); 279 | 280 | if nibbles.len() > 16 { 281 | return None; 282 | } 283 | 284 | let mut v = 0; 285 | for nibble in nibbles.chars() { 286 | v = (v << 4) | (nibble.to_digit(16).unwrap() as u64); 287 | } 288 | Some(v) 289 | } 290 | 291 | /// Decode a UTF-8 byte sequence (with each byte using a pair of nibbles) 292 | /// into individual `char`s, returning `None` for invalid UTF-8. 293 | fn try_parse_str_chars(&self) -> Option + 's> { 294 | if self.nibbles.len() % 2 != 0 { 295 | return None; 296 | } 297 | 298 | // FIXME(eddyb) use `array_chunks` instead, when that becomes stable. 299 | let mut bytes = self 300 | .nibbles 301 | .as_bytes() 302 | .chunks_exact(2) 303 | .map(|slice| match slice { 304 | [a, b] => [a, b], 305 | _ => unreachable!(), 306 | }) 307 | .map(|[&hi, &lo]| { 308 | let half = |nibble: u8| (nibble as char).to_digit(16).unwrap() as u8; 309 | (half(hi) << 4) | half(lo) 310 | }); 311 | 312 | let chars = iter::from_fn(move || { 313 | // As long as there are any bytes left, there's at least one more 314 | // UTF-8-encoded `char` to decode (or the possibility of error). 315 | bytes.next().map(|first_byte| -> Result { 316 | // FIXME(eddyb) this `enum` and `fn` should be somewhere in `core`. 317 | enum Utf8FirstByteError { 318 | ContinuationByte, 319 | TooLong, 320 | } 321 | fn utf8_len_from_first_byte(byte: u8) -> Result { 322 | match byte { 323 | 0x00..=0x7f => Ok(1), 324 | 0x80..=0xbf => Err(Utf8FirstByteError::ContinuationByte), 325 | 0xc0..=0xdf => Ok(2), 326 | 0xe0..=0xef => Ok(3), 327 | 0xf0..=0xf7 => Ok(4), 328 | 0xf8..=0xff => Err(Utf8FirstByteError::TooLong), 329 | } 330 | } 331 | 332 | // Collect the appropriate amount of bytes (up to 4), according 333 | // to the UTF-8 length implied by the first byte. 334 | let utf8_len = utf8_len_from_first_byte(first_byte).map_err(|_| ())?; 335 | let utf8 = &mut [first_byte, 0, 0, 0][..utf8_len]; 336 | for i in 1..utf8_len { 337 | utf8[i] = bytes.next().ok_or(())?; 338 | } 339 | 340 | // Fully validate the UTF-8 sequence. 341 | let s = str::from_utf8(utf8).map_err(|_| ())?; 342 | 343 | // Since we included exactly one UTF-8 sequence, and validation 344 | // succeeded, `str::chars` should return exactly one `char`. 345 | let mut chars = s.chars(); 346 | match (chars.next(), chars.next()) { 347 | (Some(c), None) => Ok(c), 348 | _ => unreachable!( 349 | "str::from_utf8({:?}) = {:?} was expected to have 1 char, \ 350 | but {} chars were found", 351 | utf8, 352 | s, 353 | s.chars().count() 354 | ), 355 | } 356 | }) 357 | }); 358 | 359 | // HACK(eddyb) doing a separate validation iteration like this might be 360 | // wasteful, but it's easier to avoid starting to print a string literal 361 | // in the first place, than to abort it mid-string. 362 | if chars.clone().any(|r| r.is_err()) { 363 | None 364 | } else { 365 | Some(chars.map(Result::unwrap)) 366 | } 367 | } 368 | } 369 | 370 | fn basic_type(tag: u8) -> Option<&'static str> { 371 | Some(match tag { 372 | b'b' => "bool", 373 | b'c' => "char", 374 | b'e' => "str", 375 | b'u' => "()", 376 | b'a' => "i8", 377 | b's' => "i16", 378 | b'l' => "i32", 379 | b'x' => "i64", 380 | b'n' => "i128", 381 | b'i' => "isize", 382 | b'h' => "u8", 383 | b't' => "u16", 384 | b'm' => "u32", 385 | b'y' => "u64", 386 | b'o' => "u128", 387 | b'j' => "usize", 388 | b'f' => "f32", 389 | b'd' => "f64", 390 | b'z' => "!", 391 | b'p' => "_", 392 | b'v' => "...", 393 | 394 | _ => return None, 395 | }) 396 | } 397 | 398 | struct Parser<'s> { 399 | sym: &'s str, 400 | next: usize, 401 | depth: u32, 402 | } 403 | 404 | impl<'s> Parser<'s> { 405 | fn push_depth(&mut self) -> Result<(), ParseError> { 406 | self.depth += 1; 407 | if self.depth > MAX_DEPTH { 408 | Err(ParseError::RecursedTooDeep) 409 | } else { 410 | Ok(()) 411 | } 412 | } 413 | 414 | fn pop_depth(&mut self) { 415 | self.depth -= 1; 416 | } 417 | 418 | fn peek(&self) -> Option { 419 | self.sym.as_bytes().get(self.next).cloned() 420 | } 421 | 422 | fn eat(&mut self, b: u8) -> bool { 423 | if self.peek() == Some(b) { 424 | self.next += 1; 425 | true 426 | } else { 427 | false 428 | } 429 | } 430 | 431 | fn next(&mut self) -> Result { 432 | let b = self.peek().ok_or(ParseError::Invalid)?; 433 | self.next += 1; 434 | Ok(b) 435 | } 436 | 437 | fn hex_nibbles(&mut self) -> Result, ParseError> { 438 | let start = self.next; 439 | loop { 440 | match self.next()? { 441 | b'0'..=b'9' | b'a'..=b'f' => {} 442 | b'_' => break, 443 | _ => return Err(ParseError::Invalid), 444 | } 445 | } 446 | Ok(HexNibbles { 447 | nibbles: &self.sym[start..self.next - 1], 448 | }) 449 | } 450 | 451 | fn digit_10(&mut self) -> Result { 452 | let d = match self.peek() { 453 | Some(d @ b'0'..=b'9') => d - b'0', 454 | _ => return Err(ParseError::Invalid), 455 | }; 456 | self.next += 1; 457 | Ok(d) 458 | } 459 | 460 | fn digit_62(&mut self) -> Result { 461 | let d = match self.peek() { 462 | Some(d @ b'0'..=b'9') => d - b'0', 463 | Some(d @ b'a'..=b'z') => 10 + (d - b'a'), 464 | Some(d @ b'A'..=b'Z') => 10 + 26 + (d - b'A'), 465 | _ => return Err(ParseError::Invalid), 466 | }; 467 | self.next += 1; 468 | Ok(d) 469 | } 470 | 471 | fn integer_62(&mut self) -> Result { 472 | if self.eat(b'_') { 473 | return Ok(0); 474 | } 475 | 476 | let mut x: u64 = 0; 477 | while !self.eat(b'_') { 478 | let d = self.digit_62()? as u64; 479 | x = x.checked_mul(62).ok_or(ParseError::Invalid)?; 480 | x = x.checked_add(d).ok_or(ParseError::Invalid)?; 481 | } 482 | x.checked_add(1).ok_or(ParseError::Invalid) 483 | } 484 | 485 | fn opt_integer_62(&mut self, tag: u8) -> Result { 486 | if !self.eat(tag) { 487 | return Ok(0); 488 | } 489 | self.integer_62()?.checked_add(1).ok_or(ParseError::Invalid) 490 | } 491 | 492 | fn disambiguator(&mut self) -> Result { 493 | self.opt_integer_62(b's') 494 | } 495 | 496 | fn namespace(&mut self) -> Result, ParseError> { 497 | match self.next()? { 498 | // Special namespaces, like closures and shims. 499 | ns @ b'A'..=b'Z' => Ok(Some(ns as char)), 500 | 501 | // Implementation-specific/unspecified namespaces. 502 | b'a'..=b'z' => Ok(None), 503 | 504 | _ => Err(ParseError::Invalid), 505 | } 506 | } 507 | 508 | fn backref(&mut self) -> Result, ParseError> { 509 | let s_start = self.next - 1; 510 | let i = self.integer_62()?; 511 | if i >= s_start as u64 { 512 | return Err(ParseError::Invalid); 513 | } 514 | let mut new_parser = Parser { 515 | sym: self.sym, 516 | next: i as usize, 517 | depth: self.depth, 518 | }; 519 | new_parser.push_depth()?; 520 | Ok(new_parser) 521 | } 522 | 523 | fn ident(&mut self) -> Result, ParseError> { 524 | let is_punycode = self.eat(b'u'); 525 | let mut len = self.digit_10()? as usize; 526 | if len != 0 { 527 | while let Ok(d) = self.digit_10() { 528 | len = len.checked_mul(10).ok_or(ParseError::Invalid)?; 529 | len = len.checked_add(d as usize).ok_or(ParseError::Invalid)?; 530 | } 531 | } 532 | 533 | // Skip past the optional `_` separator. 534 | self.eat(b'_'); 535 | 536 | let start = self.next; 537 | self.next = self.next.checked_add(len).ok_or(ParseError::Invalid)?; 538 | if self.next > self.sym.len() { 539 | return Err(ParseError::Invalid); 540 | } 541 | 542 | let ident = &self.sym[start..self.next]; 543 | 544 | if is_punycode { 545 | let ident = match ident.bytes().rposition(|b| b == b'_') { 546 | Some(i) => Ident { 547 | ascii: &ident[..i], 548 | punycode: &ident[i + 1..], 549 | }, 550 | None => Ident { 551 | ascii: "", 552 | punycode: ident, 553 | }, 554 | }; 555 | if ident.punycode.is_empty() { 556 | return Err(ParseError::Invalid); 557 | } 558 | Ok(ident) 559 | } else { 560 | Ok(Ident { 561 | ascii: ident, 562 | punycode: "", 563 | }) 564 | } 565 | } 566 | } 567 | 568 | struct Printer<'a, 'b: 'a, 's> { 569 | /// The input parser to demangle from, or `Err` if any (parse) error was 570 | /// encountered (in order to disallow further likely-incorrect demangling). 571 | /// 572 | /// See also the documentation on the `invalid!` and `parse!` macros below. 573 | parser: Result, ParseError>, 574 | 575 | /// The output formatter to demangle to, or `None` while skipping printing. 576 | out: Option<&'a mut fmt::Formatter<'b>>, 577 | 578 | /// Cumulative number of lifetimes bound by `for<...>` binders ('G'), 579 | /// anywhere "around" the current entity (e.g. type) being demangled. 580 | /// This value is not tracked while skipping printing, as it'd be unused. 581 | /// 582 | /// See also the documentation on the `Printer::in_binder` method. 583 | bound_lifetime_depth: u32, 584 | } 585 | 586 | impl ParseError { 587 | /// Snippet to print when the error is initially encountered. 588 | fn message(&self) -> &str { 589 | match self { 590 | ParseError::Invalid => "{invalid syntax}", 591 | ParseError::RecursedTooDeep => "{recursion limit reached}", 592 | } 593 | } 594 | } 595 | 596 | /// Mark the parser as errored (with `ParseError::Invalid`), print the 597 | /// appropriate message (see `ParseError::message`) and return early. 598 | macro_rules! invalid { 599 | ($printer:ident) => {{ 600 | let err = ParseError::Invalid; 601 | $printer.print(err.message())?; 602 | $printer.parser = Err(err); 603 | return Ok(()); 604 | }}; 605 | } 606 | 607 | /// Call a parser method (if the parser hasn't errored yet), 608 | /// and mark the parser as errored if it returns `Err`. 609 | /// 610 | /// If the parser errored, before or now, this returns early, 611 | /// from the current function, after printing either: 612 | /// * for a new error, the appropriate message (see `ParseError::message`) 613 | /// * for an earlier error, only `?` - this allows callers to keep printing 614 | /// the approximate syntax of the path/type/const, despite having errors, 615 | /// e.g. `Vec<[(A, ?); ?]>` instead of `Vec<[(A, ?` 616 | macro_rules! parse { 617 | ($printer:ident, $method:ident $(($($arg:expr),*))*) => { 618 | match $printer.parser { 619 | Ok(ref mut parser) => match parser.$method($($($arg),*)*) { 620 | Ok(x) => x, 621 | Err(err) => { 622 | $printer.print(err.message())?; 623 | $printer.parser = Err(err); 624 | return Ok(()); 625 | } 626 | } 627 | Err(_) => return $printer.print("?"), 628 | } 629 | }; 630 | } 631 | 632 | impl<'a, 'b, 's> Printer<'a, 'b, 's> { 633 | /// Eat the given character from the parser, 634 | /// returning `false` if the parser errored. 635 | fn eat(&mut self, b: u8) -> bool { 636 | self.parser.as_mut().map(|p| p.eat(b)) == Ok(true) 637 | } 638 | 639 | /// Skip printing (i.e. `self.out` will be `None`) for the duration of the 640 | /// given closure. This should not change parsing behavior, only disable the 641 | /// output, but there may be optimizations (such as not traversing backrefs). 642 | fn skipping_printing(&mut self, f: F) 643 | where 644 | F: FnOnce(&mut Self) -> fmt::Result, 645 | { 646 | let orig_out = self.out.take(); 647 | f(self).expect("`fmt::Error`s should be impossible without a `fmt::Formatter`"); 648 | self.out = orig_out; 649 | } 650 | 651 | /// Print the target of a backref, using the given closure. 652 | /// When printing is being skipped, the backref will only be parsed, 653 | /// ignoring the backref's target completely. 654 | fn print_backref(&mut self, f: F) -> fmt::Result 655 | where 656 | F: FnOnce(&mut Self) -> fmt::Result, 657 | { 658 | let backref_parser = parse!(self, backref); 659 | 660 | if self.out.is_none() { 661 | return Ok(()); 662 | } 663 | 664 | let orig_parser = mem::replace(&mut self.parser, Ok(backref_parser)); 665 | let r = f(self); 666 | self.parser = orig_parser; 667 | r 668 | } 669 | 670 | fn pop_depth(&mut self) { 671 | if let Ok(ref mut parser) = self.parser { 672 | parser.pop_depth(); 673 | } 674 | } 675 | 676 | /// Output the given value to `self.out` (using `fmt::Display` formatting), 677 | /// if printing isn't being skipped. 678 | fn print(&mut self, x: impl fmt::Display) -> fmt::Result { 679 | if let Some(out) = &mut self.out { 680 | fmt::Display::fmt(&x, out)?; 681 | } 682 | Ok(()) 683 | } 684 | 685 | /// Output the given `char`s (escaped using `char::escape_debug`), with the 686 | /// whole sequence wrapped in quotes, for either a `char` or `&str` literal, 687 | /// if printing isn't being skipped. 688 | fn print_quoted_escaped_chars( 689 | &mut self, 690 | quote: char, 691 | chars: impl Iterator, 692 | ) -> fmt::Result { 693 | if let Some(out) = &mut self.out { 694 | use core::fmt::Write; 695 | 696 | out.write_char(quote)?; 697 | for c in chars { 698 | // Special-case not escaping a single/double quote, when 699 | // inside the opposite kind of quote. 700 | if matches!((quote, c), ('\'', '"') | ('"', '\'')) { 701 | out.write_char(c)?; 702 | continue; 703 | } 704 | 705 | for escaped in c.escape_debug() { 706 | out.write_char(escaped)?; 707 | } 708 | } 709 | out.write_char(quote)?; 710 | } 711 | Ok(()) 712 | } 713 | 714 | /// Print the lifetime according to the previously decoded index. 715 | /// An index of `0` always refers to `'_`, but starting with `1`, 716 | /// indices refer to late-bound lifetimes introduced by a binder. 717 | fn print_lifetime_from_index(&mut self, lt: u64) -> fmt::Result { 718 | // Bound lifetimes aren't tracked when skipping printing. 719 | if self.out.is_none() { 720 | return Ok(()); 721 | } 722 | 723 | self.print("'")?; 724 | if lt == 0 { 725 | return self.print("_"); 726 | } 727 | match (self.bound_lifetime_depth as u64).checked_sub(lt) { 728 | Some(depth) => { 729 | // Try to print lifetimes alphabetically first. 730 | if depth < 26 { 731 | let c = (b'a' + depth as u8) as char; 732 | self.print(c) 733 | } else { 734 | // Use `'_123` after running out of letters. 735 | self.print("_")?; 736 | self.print(depth) 737 | } 738 | } 739 | None => invalid!(self), 740 | } 741 | } 742 | 743 | /// Optionally enter a binder ('G') for late-bound lifetimes, 744 | /// printing e.g. `for<'a, 'b> ` before calling the closure, 745 | /// and make those lifetimes visible to it (via depth level). 746 | fn in_binder(&mut self, f: F) -> fmt::Result 747 | where 748 | F: FnOnce(&mut Self) -> fmt::Result, 749 | { 750 | let bound_lifetimes = parse!(self, opt_integer_62(b'G')); 751 | 752 | // Don't track bound lifetimes when skipping printing. 753 | if self.out.is_none() { 754 | return f(self); 755 | } 756 | 757 | if bound_lifetimes > 0 { 758 | self.print("for<")?; 759 | for i in 0..bound_lifetimes { 760 | if i > 0 { 761 | self.print(", ")?; 762 | } 763 | self.bound_lifetime_depth += 1; 764 | self.print_lifetime_from_index(1)?; 765 | } 766 | self.print("> ")?; 767 | } 768 | 769 | let r = f(self); 770 | 771 | // Restore `bound_lifetime_depth` to the previous value. 772 | self.bound_lifetime_depth -= bound_lifetimes as u32; 773 | 774 | r 775 | } 776 | 777 | /// Print list elements using the given closure and separator, 778 | /// until the end of the list ('E') is found, or the parser errors. 779 | /// Returns the number of elements printed. 780 | fn print_sep_list(&mut self, f: F, sep: &str) -> Result 781 | where 782 | F: Fn(&mut Self) -> fmt::Result, 783 | { 784 | let mut i = 0; 785 | while self.parser.is_ok() && !self.eat(b'E') { 786 | if i > 0 { 787 | self.print(sep)?; 788 | } 789 | f(self)?; 790 | i += 1; 791 | } 792 | Ok(i) 793 | } 794 | 795 | fn print_path(&mut self, in_value: bool) -> fmt::Result { 796 | parse!(self, push_depth); 797 | 798 | let tag = parse!(self, next); 799 | match tag { 800 | b'C' => { 801 | let dis = parse!(self, disambiguator); 802 | let name = parse!(self, ident); 803 | 804 | self.print(name)?; 805 | if let Some(out) = &mut self.out { 806 | if !out.alternate() && dis != 0 { 807 | out.write_str("[")?; 808 | fmt::LowerHex::fmt(&dis, out)?; 809 | out.write_str("]")?; 810 | } 811 | } 812 | } 813 | b'N' => { 814 | let ns = parse!(self, namespace); 815 | 816 | self.print_path(in_value)?; 817 | 818 | // HACK(eddyb) if the parser is already marked as having errored, 819 | // `parse!` below will print a `?` without its preceding `::` 820 | // (because printing the `::` is skipped in certain conditions, 821 | // i.e. a lowercase namespace with an empty identifier), 822 | // so in order to get `::?`, the `::` has to be printed here. 823 | if self.parser.is_err() { 824 | self.print("::")?; 825 | } 826 | 827 | let dis = parse!(self, disambiguator); 828 | let name = parse!(self, ident); 829 | 830 | match ns { 831 | // Special namespaces, like closures and shims. 832 | Some(ns) => { 833 | self.print("::{")?; 834 | match ns { 835 | 'C' => self.print("closure")?, 836 | 'S' => self.print("shim")?, 837 | _ => self.print(ns)?, 838 | } 839 | if !name.ascii.is_empty() || !name.punycode.is_empty() { 840 | self.print(":")?; 841 | self.print(name)?; 842 | } 843 | self.print("#")?; 844 | self.print(dis)?; 845 | self.print("}")?; 846 | } 847 | 848 | // Implementation-specific/unspecified namespaces. 849 | None => { 850 | if !name.ascii.is_empty() || !name.punycode.is_empty() { 851 | self.print("::")?; 852 | self.print(name)?; 853 | } 854 | } 855 | } 856 | } 857 | b'M' | b'X' | b'Y' => { 858 | if tag != b'Y' { 859 | // Ignore the `impl`'s own path. 860 | parse!(self, disambiguator); 861 | self.skipping_printing(|this| this.print_path(false)); 862 | } 863 | 864 | self.print("<")?; 865 | self.print_type()?; 866 | if tag != b'M' { 867 | self.print(" as ")?; 868 | self.print_path(false)?; 869 | } 870 | self.print(">")?; 871 | } 872 | b'I' => { 873 | self.print_path(in_value)?; 874 | if in_value { 875 | self.print("::")?; 876 | } 877 | self.print("<")?; 878 | self.print_sep_list(Self::print_generic_arg, ", ")?; 879 | self.print(">")?; 880 | } 881 | b'B' => { 882 | self.print_backref(|this| this.print_path(in_value))?; 883 | } 884 | _ => invalid!(self), 885 | } 886 | 887 | self.pop_depth(); 888 | Ok(()) 889 | } 890 | 891 | fn print_generic_arg(&mut self) -> fmt::Result { 892 | if self.eat(b'L') { 893 | let lt = parse!(self, integer_62); 894 | self.print_lifetime_from_index(lt) 895 | } else if self.eat(b'K') { 896 | self.print_const(false) 897 | } else { 898 | self.print_type() 899 | } 900 | } 901 | 902 | fn print_type(&mut self) -> fmt::Result { 903 | let tag = parse!(self, next); 904 | 905 | if let Some(ty) = basic_type(tag) { 906 | return self.print(ty); 907 | } 908 | 909 | parse!(self, push_depth); 910 | 911 | match tag { 912 | b'R' | b'Q' => { 913 | self.print("&")?; 914 | if self.eat(b'L') { 915 | let lt = parse!(self, integer_62); 916 | if lt != 0 { 917 | self.print_lifetime_from_index(lt)?; 918 | self.print(" ")?; 919 | } 920 | } 921 | if tag != b'R' { 922 | self.print("mut ")?; 923 | } 924 | self.print_type()?; 925 | } 926 | 927 | b'P' | b'O' => { 928 | self.print("*")?; 929 | if tag != b'P' { 930 | self.print("mut ")?; 931 | } else { 932 | self.print("const ")?; 933 | } 934 | self.print_type()?; 935 | } 936 | 937 | b'A' | b'S' => { 938 | self.print("[")?; 939 | self.print_type()?; 940 | if tag == b'A' { 941 | self.print("; ")?; 942 | self.print_const(true)?; 943 | } 944 | self.print("]")?; 945 | } 946 | b'T' => { 947 | self.print("(")?; 948 | let count = self.print_sep_list(Self::print_type, ", ")?; 949 | if count == 1 { 950 | self.print(",")?; 951 | } 952 | self.print(")")?; 953 | } 954 | b'F' => self.in_binder(|this| { 955 | let is_unsafe = this.eat(b'U'); 956 | let abi = if this.eat(b'K') { 957 | if this.eat(b'C') { 958 | Some("C") 959 | } else { 960 | let abi = parse!(this, ident); 961 | if abi.ascii.is_empty() || !abi.punycode.is_empty() { 962 | invalid!(this); 963 | } 964 | Some(abi.ascii) 965 | } 966 | } else { 967 | None 968 | }; 969 | 970 | if is_unsafe { 971 | this.print("unsafe ")?; 972 | } 973 | 974 | if let Some(abi) = abi { 975 | this.print("extern \"")?; 976 | 977 | // If the ABI had any `-`, they were replaced with `_`, 978 | // so the parts between `_` have to be re-joined with `-`. 979 | let mut parts = abi.split('_'); 980 | this.print(parts.next().unwrap())?; 981 | for part in parts { 982 | this.print("-")?; 983 | this.print(part)?; 984 | } 985 | 986 | this.print("\" ")?; 987 | } 988 | 989 | this.print("fn(")?; 990 | this.print_sep_list(Self::print_type, ", ")?; 991 | this.print(")")?; 992 | 993 | if this.eat(b'u') { 994 | // Skip printing the return type if it's 'u', i.e. `()`. 995 | } else { 996 | this.print(" -> ")?; 997 | this.print_type()?; 998 | } 999 | 1000 | Ok(()) 1001 | })?, 1002 | b'D' => { 1003 | self.print("dyn ")?; 1004 | self.in_binder(|this| { 1005 | this.print_sep_list(Self::print_dyn_trait, " + ")?; 1006 | Ok(()) 1007 | })?; 1008 | 1009 | if !self.eat(b'L') { 1010 | invalid!(self); 1011 | } 1012 | let lt = parse!(self, integer_62); 1013 | if lt != 0 { 1014 | self.print(" + ")?; 1015 | self.print_lifetime_from_index(lt)?; 1016 | } 1017 | } 1018 | b'B' => { 1019 | self.print_backref(Self::print_type)?; 1020 | } 1021 | b'W' => { 1022 | self.print_type()?; 1023 | self.print(" is ")?; 1024 | self.print_pat()?; 1025 | } 1026 | _ => { 1027 | // Go back to the tag, so `print_path` also sees it. 1028 | let _ = self.parser.as_mut().map(|p| p.next -= 1); 1029 | self.print_path(false)?; 1030 | } 1031 | } 1032 | 1033 | self.pop_depth(); 1034 | Ok(()) 1035 | } 1036 | 1037 | /// A trait in a trait object may have some "existential projections" 1038 | /// (i.e. associated type bindings) after it, which should be printed 1039 | /// in the `<...>` of the trait, e.g. `dyn Trait`. 1040 | /// To this end, this method will keep the `<...>` of an 'I' path 1041 | /// open, by omitting the `>`, and return `Ok(true)` in that case. 1042 | fn print_path_maybe_open_generics(&mut self) -> Result { 1043 | if self.eat(b'B') { 1044 | // NOTE(eddyb) the closure may not run if printing is being skipped, 1045 | // but in that case the returned boolean doesn't matter. 1046 | let mut open = false; 1047 | self.print_backref(|this| { 1048 | open = this.print_path_maybe_open_generics()?; 1049 | Ok(()) 1050 | })?; 1051 | Ok(open) 1052 | } else if self.eat(b'I') { 1053 | self.print_path(false)?; 1054 | self.print("<")?; 1055 | self.print_sep_list(Self::print_generic_arg, ", ")?; 1056 | Ok(true) 1057 | } else { 1058 | self.print_path(false)?; 1059 | Ok(false) 1060 | } 1061 | } 1062 | 1063 | fn print_dyn_trait(&mut self) -> fmt::Result { 1064 | let mut open = self.print_path_maybe_open_generics()?; 1065 | 1066 | while self.eat(b'p') { 1067 | if !open { 1068 | self.print("<")?; 1069 | open = true; 1070 | } else { 1071 | self.print(", ")?; 1072 | } 1073 | 1074 | let name = parse!(self, ident); 1075 | self.print(name)?; 1076 | self.print(" = ")?; 1077 | self.print_type()?; 1078 | } 1079 | 1080 | if open { 1081 | self.print(">")?; 1082 | } 1083 | 1084 | Ok(()) 1085 | } 1086 | 1087 | fn print_pat(&mut self) -> fmt::Result { 1088 | let tag = parse!(self, next); 1089 | 1090 | match tag { 1091 | b'R' => { 1092 | self.print_const(false)?; 1093 | self.print("..=")?; 1094 | self.print_const(false)?; 1095 | } 1096 | b'O' => { 1097 | parse!(self, push_depth); 1098 | self.print_pat()?; 1099 | while !self.eat(b'E') { 1100 | // May have reached the end of the string, 1101 | // avoid going into an endless loop. 1102 | if self.parser.is_err() { 1103 | invalid!(self) 1104 | } 1105 | self.print(" | ")?; 1106 | self.print_pat()?; 1107 | } 1108 | self.pop_depth(); 1109 | } 1110 | b'N' => self.print("!null")?, 1111 | _ => invalid!(self), 1112 | } 1113 | 1114 | Ok(()) 1115 | } 1116 | 1117 | fn print_const(&mut self, in_value: bool) -> fmt::Result { 1118 | let tag = parse!(self, next); 1119 | 1120 | parse!(self, push_depth); 1121 | 1122 | // Only literals (and the names of `const` generic parameters, but they 1123 | // don't get mangled at all), can appear in generic argument position 1124 | // without any disambiguation, all other expressions require braces. 1125 | // To avoid duplicating the mapping between `tag` and what syntax gets 1126 | // used (especially any special-casing), every case that needs braces 1127 | // has to call `open_brace(self)?` (and the closing brace is automatic). 1128 | let mut opened_brace = false; 1129 | let mut open_brace_if_outside_expr = |this: &mut Self| { 1130 | // If this expression is nested in another, braces aren't required. 1131 | if in_value { 1132 | return Ok(()); 1133 | } 1134 | 1135 | opened_brace = true; 1136 | this.print("{") 1137 | }; 1138 | 1139 | match tag { 1140 | b'p' => self.print("_")?, 1141 | 1142 | // Primitive leaves with hex-encoded values (see `basic_type`). 1143 | b'h' | b't' | b'm' | b'y' | b'o' | b'j' => self.print_const_uint(tag)?, 1144 | b'a' | b's' | b'l' | b'x' | b'n' | b'i' => { 1145 | if self.eat(b'n') { 1146 | self.print("-")?; 1147 | } 1148 | 1149 | self.print_const_uint(tag)?; 1150 | } 1151 | b'b' => match parse!(self, hex_nibbles).try_parse_uint() { 1152 | Some(0) => self.print("false")?, 1153 | Some(1) => self.print("true")?, 1154 | _ => invalid!(self), 1155 | }, 1156 | b'c' => { 1157 | let valid_char = parse!(self, hex_nibbles) 1158 | .try_parse_uint() 1159 | .and_then(|v| u32::try_from(v).ok()) 1160 | .and_then(char::from_u32); 1161 | match valid_char { 1162 | Some(c) => self.print_quoted_escaped_chars('\'', iter::once(c))?, 1163 | None => invalid!(self), 1164 | } 1165 | } 1166 | b'e' => { 1167 | // NOTE(eddyb) a string literal `"..."` has type `&str`, so 1168 | // to get back the type `str`, `*"..."` syntax is needed 1169 | // (even if that may not be valid in Rust itself). 1170 | open_brace_if_outside_expr(self)?; 1171 | self.print("*")?; 1172 | 1173 | self.print_const_str_literal()?; 1174 | } 1175 | 1176 | b'R' | b'Q' => { 1177 | // NOTE(eddyb) this prints `"..."` instead of `&*"..."`, which 1178 | // is what `Re..._` would imply (see comment for `str` above). 1179 | if tag == b'R' && self.eat(b'e') { 1180 | self.print_const_str_literal()?; 1181 | } else { 1182 | open_brace_if_outside_expr(self)?; 1183 | self.print("&")?; 1184 | if tag != b'R' { 1185 | self.print("mut ")?; 1186 | } 1187 | self.print_const(true)?; 1188 | } 1189 | } 1190 | b'A' => { 1191 | open_brace_if_outside_expr(self)?; 1192 | self.print("[")?; 1193 | self.print_sep_list(|this| this.print_const(true), ", ")?; 1194 | self.print("]")?; 1195 | } 1196 | b'T' => { 1197 | open_brace_if_outside_expr(self)?; 1198 | self.print("(")?; 1199 | let count = self.print_sep_list(|this| this.print_const(true), ", ")?; 1200 | if count == 1 { 1201 | self.print(",")?; 1202 | } 1203 | self.print(")")?; 1204 | } 1205 | b'V' => { 1206 | open_brace_if_outside_expr(self)?; 1207 | self.print_path(true)?; 1208 | match parse!(self, next) { 1209 | b'U' => {} 1210 | b'T' => { 1211 | self.print("(")?; 1212 | self.print_sep_list(|this| this.print_const(true), ", ")?; 1213 | self.print(")")?; 1214 | } 1215 | b'S' => { 1216 | self.print(" { ")?; 1217 | self.print_sep_list( 1218 | |this| { 1219 | parse!(this, disambiguator); 1220 | let name = parse!(this, ident); 1221 | this.print(name)?; 1222 | this.print(": ")?; 1223 | this.print_const(true) 1224 | }, 1225 | ", ", 1226 | )?; 1227 | self.print(" }")?; 1228 | } 1229 | _ => invalid!(self), 1230 | } 1231 | } 1232 | b'B' => { 1233 | self.print_backref(|this| this.print_const(in_value))?; 1234 | } 1235 | _ => invalid!(self), 1236 | } 1237 | 1238 | if opened_brace { 1239 | self.print("}")?; 1240 | } 1241 | 1242 | self.pop_depth(); 1243 | Ok(()) 1244 | } 1245 | 1246 | fn print_const_uint(&mut self, ty_tag: u8) -> fmt::Result { 1247 | let hex = parse!(self, hex_nibbles); 1248 | 1249 | match hex.try_parse_uint() { 1250 | Some(v) => self.print(v)?, 1251 | 1252 | // Print anything that doesn't fit in `u64` verbatim. 1253 | None => { 1254 | self.print("0x")?; 1255 | self.print(hex.nibbles)?; 1256 | } 1257 | } 1258 | 1259 | if let Some(out) = &mut self.out { 1260 | if !out.alternate() { 1261 | let ty = basic_type(ty_tag).unwrap(); 1262 | self.print(ty)?; 1263 | } 1264 | } 1265 | 1266 | Ok(()) 1267 | } 1268 | 1269 | fn print_const_str_literal(&mut self) -> fmt::Result { 1270 | match parse!(self, hex_nibbles).try_parse_str_chars() { 1271 | Some(chars) => self.print_quoted_escaped_chars('"', chars), 1272 | None => invalid!(self), 1273 | } 1274 | } 1275 | } 1276 | 1277 | #[cfg(test)] 1278 | mod tests { 1279 | use std::prelude::v1::*; 1280 | 1281 | macro_rules! t { 1282 | ($a:expr, $b:expr) => {{ 1283 | assert_eq!(format!("{}", ::demangle($a)), $b); 1284 | }}; 1285 | } 1286 | macro_rules! t_nohash { 1287 | ($a:expr, $b:expr) => {{ 1288 | assert_eq!(format!("{:#}", ::demangle($a)), $b); 1289 | }}; 1290 | } 1291 | macro_rules! t_nohash_type { 1292 | ($a:expr, $b:expr) => { 1293 | t_nohash!(concat!("_RMC0", $a), concat!("<", $b, ">")) 1294 | }; 1295 | } 1296 | macro_rules! t_const { 1297 | ($mangled:expr, $value:expr) => { 1298 | t_nohash!( 1299 | concat!("_RIC0K", $mangled, "E"), 1300 | concat!("::<", $value, ">") 1301 | ) 1302 | }; 1303 | } 1304 | macro_rules! t_const_suffixed { 1305 | ($mangled:expr, $value:expr, $value_ty_suffix:expr) => {{ 1306 | t_const!($mangled, $value); 1307 | t!( 1308 | concat!("_RIC0K", $mangled, "E"), 1309 | concat!("::<", $value, $value_ty_suffix, ">") 1310 | ); 1311 | }}; 1312 | } 1313 | 1314 | #[test] 1315 | fn demangle_crate_with_leading_digit() { 1316 | t_nohash!("_RNvC6_123foo3bar", "123foo::bar"); 1317 | } 1318 | 1319 | #[test] 1320 | fn demangle_crate_with_zero_disambiguator() { 1321 | t!("_RC4f128", "f128"); 1322 | t_nohash!("_RC4f128", "f128"); 1323 | } 1324 | 1325 | #[test] 1326 | fn demangle_utf8_idents() { 1327 | t_nohash!( 1328 | "_RNqCs4fqI2P2rA04_11utf8_identsu30____7hkackfecea1cbdathfdh9hlq6y", 1329 | "utf8_idents::საჭმელად_გემრიელი_სადილი" 1330 | ); 1331 | } 1332 | 1333 | #[test] 1334 | fn demangle_closure() { 1335 | t_nohash!( 1336 | "_RNCNCNgCs6DXkGYLi8lr_2cc5spawn00B5_", 1337 | "cc::spawn::{closure#0}::{closure#0}" 1338 | ); 1339 | t_nohash!( 1340 | "_RNCINkXs25_NgCsbmNqQUJIY6D_4core5sliceINyB9_4IterhENuNgNoBb_4iter8iterator8Iterator9rpositionNCNgNpB9_6memchr7memrchrs_0E0Bb_", 1341 | " as core::iter::iterator::Iterator>::rposition::::{closure#0}" 1342 | ); 1343 | } 1344 | 1345 | #[test] 1346 | fn demangle_dyn_trait() { 1347 | t_nohash!( 1348 | "_RINbNbCskIICzLVDPPb_5alloc5alloc8box_freeDINbNiB4_5boxed5FnBoxuEp6OutputuEL_ECs1iopQbuBiw2_3std", 1349 | "alloc::alloc::box_free::>" 1350 | ); 1351 | } 1352 | 1353 | #[test] 1354 | fn demangle_pat_ty() { 1355 | t_nohash_type!("WmRm1_m9_", "u32 is 1..=9"); 1356 | t_nohash_type!("WmORm1_m2_Rm5_m6_E", "u32 is 1..=2 | 5..=6"); 1357 | assert!(::v0::demangle("_RMC0WmORm1_m2_Rm5_m6_").is_err()); 1358 | } 1359 | 1360 | #[test] 1361 | fn demangle_const_generics_preview() { 1362 | // NOTE(eddyb) this was hand-written, before rustc had working 1363 | // const generics support (but the mangling format did include them). 1364 | t_nohash_type!( 1365 | "INtC8arrayvec8ArrayVechKj7b_E", 1366 | "arrayvec::ArrayVec" 1367 | ); 1368 | t_const_suffixed!("j7b_", "123", "usize"); 1369 | } 1370 | 1371 | #[test] 1372 | fn demangle_min_const_generics() { 1373 | t_const!("p", "_"); 1374 | t_const_suffixed!("hb_", "11", "u8"); 1375 | t_const_suffixed!("off00ff00ff00ff00ff_", "0xff00ff00ff00ff00ff", "u128"); 1376 | t_const_suffixed!("s98_", "152", "i16"); 1377 | t_const_suffixed!("anb_", "-11", "i8"); 1378 | t_const!("b0_", "false"); 1379 | t_const!("b1_", "true"); 1380 | t_const!("c76_", "'v'"); 1381 | t_const!("c22_", r#"'"'"#); 1382 | t_const!("ca_", "'\\n'"); 1383 | t_const!("c2202_", "'∂'"); 1384 | } 1385 | 1386 | #[test] 1387 | fn demangle_const_str() { 1388 | t_const!("e616263_", "{*\"abc\"}"); 1389 | t_const!("e27_", r#"{*"'"}"#); 1390 | t_const!("e090a_", "{*\"\\t\\n\"}"); 1391 | t_const!("ee28882c3bc_", "{*\"∂ü\"}"); 1392 | t_const!( 1393 | "ee183a1e18390e183ade1839be18394e1839ae18390e183935fe18392e18394e1839b\ 1394 | e183a0e18398e18394e1839ae183985fe183a1e18390e18393e18398e1839ae18398_", 1395 | "{*\"საჭმელად_გემრიელი_სადილი\"}" 1396 | ); 1397 | t_const!( 1398 | "ef09f908af09fa688f09fa686f09f90ae20c2a720f09f90b6f09f9192e298\ 1399 | 95f09f94a520c2a720f09fa7a1f09f929bf09f929af09f9299f09f929c_", 1400 | "{*\"🐊🦈🦆🐮 § 🐶👒☕🔥 § 🧡💛💚💙💜\"}" 1401 | ); 1402 | } 1403 | 1404 | // NOTE(eddyb) this uses the same strings as `demangle_const_str` and should 1405 | // be kept in sync with it - while a macro could be used to generate both 1406 | // `str` and `&str` tests, from a single list of strings, this seems clearer. 1407 | #[test] 1408 | fn demangle_const_ref_str() { 1409 | t_const!("Re616263_", "\"abc\""); 1410 | t_const!("Re27_", r#""'""#); 1411 | t_const!("Re090a_", "\"\\t\\n\""); 1412 | t_const!("Ree28882c3bc_", "\"∂ü\""); 1413 | t_const!( 1414 | "Ree183a1e18390e183ade1839be18394e1839ae18390e183935fe18392e18394e1839b\ 1415 | e183a0e18398e18394e1839ae183985fe183a1e18390e18393e18398e1839ae18398_", 1416 | "\"საჭმელად_გემრიელი_სადილი\"" 1417 | ); 1418 | t_const!( 1419 | "Ref09f908af09fa688f09fa686f09f90ae20c2a720f09f90b6f09f9192e298\ 1420 | 95f09f94a520c2a720f09fa7a1f09f929bf09f929af09f9299f09f929c_", 1421 | "\"🐊🦈🦆🐮 § 🐶👒☕🔥 § 🧡💛💚💙💜\"" 1422 | ); 1423 | } 1424 | 1425 | #[test] 1426 | fn demangle_const_ref() { 1427 | t_const!("Rp", "{&_}"); 1428 | t_const!("Rh7b_", "{&123}"); 1429 | t_const!("Rb0_", "{&false}"); 1430 | t_const!("Rc58_", "{&'X'}"); 1431 | t_const!("RRRh0_", "{&&&0}"); 1432 | t_const!("RRRe_", "{&&\"\"}"); 1433 | t_const!("QAE", "{&mut []}"); 1434 | } 1435 | 1436 | #[test] 1437 | fn demangle_const_array() { 1438 | t_const!("AE", "{[]}"); 1439 | t_const!("Aj0_E", "{[0]}"); 1440 | t_const!("Ah1_h2_h3_E", "{[1, 2, 3]}"); 1441 | t_const!("ARe61_Re62_Re63_E", "{[\"a\", \"b\", \"c\"]}"); 1442 | t_const!("AAh1_h2_EAh3_h4_EE", "{[[1, 2], [3, 4]]}"); 1443 | } 1444 | 1445 | #[test] 1446 | fn demangle_const_tuple() { 1447 | t_const!("TE", "{()}"); 1448 | t_const!("Tj0_E", "{(0,)}"); 1449 | t_const!("Th1_b0_E", "{(1, false)}"); 1450 | t_const!( 1451 | "TRe616263_c78_RAh1_h2_h3_EE", 1452 | "{(\"abc\", 'x', &[1, 2, 3])}" 1453 | ); 1454 | } 1455 | 1456 | #[test] 1457 | fn demangle_const_adt() { 1458 | t_const!( 1459 | "VNvINtNtC4core6option6OptionjE4NoneU", 1460 | "{core::option::Option::::None}" 1461 | ); 1462 | t_const!( 1463 | "VNvINtNtC4core6option6OptionjE4SomeTj0_E", 1464 | "{core::option::Option::::Some(0)}" 1465 | ); 1466 | t_const!( 1467 | "VNtC3foo3BarS1sRe616263_2chc78_5sliceRAh1_h2_h3_EE", 1468 | "{foo::Bar { s: \"abc\", ch: 'x', slice: &[1, 2, 3] }}" 1469 | ); 1470 | } 1471 | 1472 | #[test] 1473 | fn demangle_exponential_explosion() { 1474 | // NOTE(eddyb) because of the prefix added by `t_nohash_type!` is 1475 | // 3 bytes long, `B2_` refers to the start of the type, not `B_`. 1476 | // 6 backrefs (`B8_E` through `B3_E`) result in 2^6 = 64 copies of `_`. 1477 | // Also, because the `p` (`_`) type is after all of the starts of the 1478 | // backrefs, it can be replaced with any other type, independently. 1479 | t_nohash_type!( 1480 | concat!("TTTTTT", "p", "B8_E", "B7_E", "B6_E", "B5_E", "B4_E", "B3_E"), 1481 | "((((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _)))), \ 1482 | ((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _))))), \ 1483 | (((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _)))), \ 1484 | ((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _))))))" 1485 | ); 1486 | } 1487 | 1488 | #[test] 1489 | fn demangle_thinlto() { 1490 | t_nohash!("_RC3foo.llvm.9D1C9369", "foo"); 1491 | t_nohash!("_RC3foo.llvm.9D1C9369@@16", "foo"); 1492 | t_nohash!("_RNvC9backtrace3foo.llvm.A5310EB9", "backtrace::foo"); 1493 | } 1494 | 1495 | #[test] 1496 | fn demangle_extra_suffix() { 1497 | // From alexcrichton/rustc-demangle#27: 1498 | t_nohash!( 1499 | "_RNvNtNtNtNtCs92dm3009vxr_4rand4rngs7adapter9reseeding4fork23FORK_HANDLER_REGISTERED.0.0", 1500 | "rand::rngs::adapter::reseeding::fork::FORK_HANDLER_REGISTERED.0.0" 1501 | ); 1502 | } 1503 | 1504 | #[test] 1505 | fn demangling_limits() { 1506 | // Stress tests found via fuzzing. 1507 | 1508 | for sym in include_str!("v0-large-test-symbols/early-recursion-limit") 1509 | .lines() 1510 | .filter(|line| !line.is_empty() && !line.starts_with('#')) 1511 | { 1512 | assert_eq!( 1513 | super::demangle(sym).map(|_| ()), 1514 | Err(super::ParseError::RecursedTooDeep) 1515 | ); 1516 | } 1517 | 1518 | assert_contains!( 1519 | ::demangle( 1520 | "RIC20tRYIMYNRYFG05_EB5_B_B6_RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR\ 1521 | RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRB_E", 1522 | ) 1523 | .to_string(), 1524 | "{recursion limit reached}" 1525 | ); 1526 | } 1527 | 1528 | #[test] 1529 | fn recursion_limit_leaks() { 1530 | // NOTE(eddyb) this test checks that both paths and types support the 1531 | // recursion limit correctly, i.e. matching `push_depth` and `pop_depth`, 1532 | // and don't leak "recursion levels" and trip the limit. 1533 | // The test inputs are generated on the fly, using a repeated pattern, 1534 | // as hardcoding the actual strings would be too verbose. 1535 | // Also, `MAX_DEPTH` can be directly used, instead of assuming its value. 1536 | for &(sym_leaf, expected_leaf) in &[("p", "_"), ("Rp", "&_"), ("C1x", "x")] { 1537 | let mut sym = format!("_RIC0p"); 1538 | let mut expected = format!("::<_"); 1539 | for _ in 0..(super::MAX_DEPTH * 2) { 1540 | sym.push_str(sym_leaf); 1541 | expected.push_str(", "); 1542 | expected.push_str(expected_leaf); 1543 | } 1544 | sym.push('E'); 1545 | expected.push('>'); 1546 | 1547 | t_nohash!(&sym, expected); 1548 | } 1549 | } 1550 | 1551 | #[test] 1552 | fn recursion_limit_backref_free_bypass() { 1553 | // NOTE(eddyb) this test checks that long symbols cannot bypass the 1554 | // recursion limit by not using backrefs, and cause a stack overflow. 1555 | 1556 | // This value was chosen to be high enough that stack overflows were 1557 | // observed even with `cargo test --release`. 1558 | let depth = 100_000; 1559 | 1560 | // In order to hide the long mangling from the initial "shallow" parse, 1561 | // it's nested in an identifier (crate name), preceding its use. 1562 | let mut sym = format!("_RIC{}", depth); 1563 | let backref_start = sym.len() - 2; 1564 | for _ in 0..depth { 1565 | sym.push('R'); 1566 | } 1567 | 1568 | // Write a backref to just after the length of the identifier. 1569 | sym.push('B'); 1570 | sym.push(char::from_digit((backref_start - 1) as u32, 36).unwrap()); 1571 | sym.push('_'); 1572 | 1573 | // Close the `I` at the start. 1574 | sym.push('E'); 1575 | 1576 | assert_contains!(::demangle(&sym).to_string(), "{recursion limit reached}"); 1577 | } 1578 | } 1579 | --------------------------------------------------------------------------------