From e8ae32f2b44d7dfe73480467578597373c6de0c0 Mon Sep 17 00:00:00 2001 From: Torste Aikio Date: Sun, 8 Apr 2018 15:36:26 +0300 Subject: [PATCH 1/8] std based C API --- Cargo.toml | 4 + rustc-demangle-capi/Cargo.toml | 11 ++ rustc-demangle-capi/include/rustc_demangle.h | 18 +++ rustc-demangle-capi/src/lib.rs | 109 +++++++++++++++++++ 4 files changed, 142 insertions(+) create mode 100644 rustc-demangle-capi/Cargo.toml create mode 100644 rustc-demangle-capi/include/rustc_demangle.h create mode 100644 rustc-demangle-capi/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 91da30c..4869f31 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,7 @@ documentation = "http://alexcrichton.com/rustc-demangle" description = """ Rust compiler symbol demangling. """ + +[workspace] +members = ["rustc-demangle-capi"] + diff --git a/rustc-demangle-capi/Cargo.toml b/rustc-demangle-capi/Cargo.toml new file mode 100644 index 0000000..dcf9f98 --- /dev/null +++ b/rustc-demangle-capi/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "rustc-demangle-capi" +version = "0.1.0" +authors = ["Torste Aikio "] + +[lib] +name = "rustc_demangle" +crate-type = ["staticlib", "cdylib"] + +[dependencies] +rustc-demangle = { version = "*", path = ".." } diff --git a/rustc-demangle-capi/include/rustc_demangle.h b/rustc-demangle-capi/include/rustc_demangle.h new file mode 100644 index 0000000..61c4aa1 --- /dev/null +++ b/rustc-demangle-capi/include/rustc_demangle.h @@ -0,0 +1,18 @@ +#ifndef RUST_DEMANGLE_H_ +#define RUST_DEMANGLE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// Demangles symbol given in `mangled` argument into `out` buffer +// +// Returns 0 if `mangled` is not Rust symbol or if `out` buffer is too small +// Returns 1 otherwise +int rustc_demangle(const char *mangled, char *out, size_t out_size); + +#ifdef __cplusplus +} +#endif + +#endif // RUSTC_DEMANGLE_H_ diff --git a/rustc-demangle-capi/src/lib.rs b/rustc-demangle-capi/src/lib.rs new file mode 100644 index 0000000..0df6569 --- /dev/null +++ b/rustc-demangle-capi/src/lib.rs @@ -0,0 +1,109 @@ +extern crate rustc_demangle; + +use std::os::raw::{c_char,c_int}; +use std::io::Write; + +/// C-style interface for demangling. +/// Demangles symbol given in `mangled` argument into `out` buffer +/// +/// Unsafe as it handles buffers by raw pointers. +/// +/// Returns 0 if `mangled` is not Rust symbol or if `out` buffer is too small +/// Returns 1 otherwise +#[no_mangle] +pub unsafe extern fn rustc_demangle(mangled: *const c_char, out: *mut c_char, out_size: usize) -> c_int { + let mangled_str = std::ffi::CStr::from_ptr(mangled).to_str(); + if mangled_str.is_err() { + return 0; + } + let mangled_str = mangled_str.unwrap(); + match rustc_demangle::try_demangle(mangled_str) { + Ok(demangle) => { + let mut out_slice = std::slice::from_raw_parts_mut(out as *mut u8, out_size); + match write!(out_slice, "{:#}\0", demangle) { + Ok(_) => { return 1 }, + Err(_) => { return 0 } + } + }, + Err(_) => { return 0 } + } +} + +#[cfg(test)] +mod tests { + use std::os::raw::c_char; + use std; + #[test] + fn demangle_c_str_large() { + let mangled = "_ZN4testE\0"; + let mut out_buf: Vec = vec![42;8]; + let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 8) }; + assert_eq!(res, 1); + let out_str = std::str::from_utf8(&out_buf[..5]).unwrap(); + assert_eq!(out_str, "test\0"); + } + + #[test] + fn demangle_c_str_exact() { + let mangled = "_ZN4testE\0"; + let mut out_buf: Vec = vec![42;8]; + let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 5) }; + assert_eq!(res, 1); + let out_str = std::str::from_utf8(&out_buf).unwrap(); + assert_eq!(out_str, "test\0***"); + } + + #[test] + fn demangle_c_str_small() { + let mangled = "_ZN4testE\0"; + let mut out_buf: Vec = vec![42;8]; + let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 4) }; + assert_eq!(res, 0); + let out_str = std::str::from_utf8(&out_buf[4..]).unwrap(); + assert_eq!(out_str, "****"); + } + + #[test] + fn demangle_c_str_smaller() { + let mangled = "_ZN4testE\0"; + let mut out_buf: Vec = vec![42;8]; + let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 3) }; + assert_eq!(res, 0); + let out_str = std::str::from_utf8(&out_buf[3..]).unwrap(); + assert_eq!(out_str, "*****"); + } + + #[test] + fn demangle_c_str_zero() { + let mangled = "_ZN4testE\0"; + let mut out_buf: Vec = vec![42;8]; + let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 0) }; + assert_eq!(res, 0); + let out_str = std::str::from_utf8(&out_buf).unwrap(); + assert_eq!(out_str, "********"); + } + + #[test] + fn demangle_c_str_not_rust_symbol() { + let mangled = "la la la\0"; + let mut out_buf: Vec = vec![42;8]; + let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 8) }; + assert_eq!(res, 0); + } + + #[test] + fn demangle_c_str_null() { + let mangled = "\0"; + let mut out_buf: Vec = vec![42;8]; + let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 8) }; + assert_eq!(res, 0); + } + + #[test] + fn demangle_c_str_invalid_utf8() { + let mangled = [116, 101, 115, 116, 165, 0]; + let mut out_buf: Vec = vec![42;8]; + let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 8) }; + assert_eq!(res, 0); + } +} From a2da0df4c67495ac16f8c02366b595202a103ce1 Mon Sep 17 00:00:00 2001 From: Torste Aikio Date: Sun, 8 Apr 2018 16:16:49 +0300 Subject: [PATCH 2/8] Build and test C API with Travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 15ec25e..d4396f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,8 +7,8 @@ sudo: false before_script: - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH script: - - cargo build - - cargo test + - cargo build --all + - cargo test --all - cargo doc after_success: - travis-cargo --only nightly doc-upload From 2495462acc0c5c45d378778555769998e7c998e1 Mon Sep 17 00:00:00 2001 From: Torste Aikio Date: Sun, 8 Apr 2018 21:44:02 +0300 Subject: [PATCH 3/8] Use full lto for release profile --- Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 4869f31..864a547 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,7 @@ Rust compiler symbol demangling. [workspace] members = ["rustc-demangle-capi"] +[profile.release] +lto = true +codegen-units = 1 +incremental = false From 256d83b183c3dc206d3ced105e62b6da0618dfae Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 9 Dec 2019 10:05:31 -0800 Subject: [PATCH 4/8] Add CI for GitHub Actions --- .github/workflows/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c242c5b..61465ce 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,8 @@ jobs: - uses: actions/checkout@master - name: Install Rust run: rustup update ${{ matrix.rust }} && rustup default ${{ matrix.rust }} - - run: cargo test + - run: cargo build --all + - run: cargo test --all rustfmt: name: Rustfmt From 295c176173d0bc57ab997188de7bf5b0e9f21b72 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 9 Dec 2019 10:06:16 -0800 Subject: [PATCH 5/8] Move demangle crate to a `crates` directory --- Cargo.toml | 2 +- {rustc-demangle-capi => crates/capi}/Cargo.toml | 2 +- {rustc-demangle-capi => crates/capi}/include/rustc_demangle.h | 0 {rustc-demangle-capi => crates/capi}/src/lib.rs | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename {rustc-demangle-capi => crates/capi}/Cargo.toml (76%) rename {rustc-demangle-capi => crates/capi}/include/rustc_demangle.h (100%) rename {rustc-demangle-capi => crates/capi}/src/lib.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index d0a0320..0701278 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ Rust compiler symbol demangling. """ [workspace] -members = ["rustc-demangle-capi"] +members = ["crates/capi"] [dependencies] core = { version = '1.0.0', optional = true, package = 'rustc-std-workspace-core' } diff --git a/rustc-demangle-capi/Cargo.toml b/crates/capi/Cargo.toml similarity index 76% rename from rustc-demangle-capi/Cargo.toml rename to crates/capi/Cargo.toml index dcf9f98..0f1fb07 100644 --- a/rustc-demangle-capi/Cargo.toml +++ b/crates/capi/Cargo.toml @@ -8,4 +8,4 @@ name = "rustc_demangle" crate-type = ["staticlib", "cdylib"] [dependencies] -rustc-demangle = { version = "*", path = ".." } +rustc-demangle = { version = "0.1.16", path = "../.." } diff --git a/rustc-demangle-capi/include/rustc_demangle.h b/crates/capi/include/rustc_demangle.h similarity index 100% rename from rustc-demangle-capi/include/rustc_demangle.h rename to crates/capi/include/rustc_demangle.h diff --git a/rustc-demangle-capi/src/lib.rs b/crates/capi/src/lib.rs similarity index 100% rename from rustc-demangle-capi/src/lib.rs rename to crates/capi/src/lib.rs From ed911699b199c7c32a634cea5a958474a316313f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 9 Dec 2019 10:06:36 -0800 Subject: [PATCH 6/8] Run rustfmt --- crates/capi/src/lib.rs | 98 ++++++++++++++++++++++++++++++++---------- 1 file changed, 75 insertions(+), 23 deletions(-) diff --git a/crates/capi/src/lib.rs b/crates/capi/src/lib.rs index 0df6569..9adfb83 100644 --- a/crates/capi/src/lib.rs +++ b/crates/capi/src/lib.rs @@ -1,7 +1,7 @@ extern crate rustc_demangle; -use std::os::raw::{c_char,c_int}; use std::io::Write; +use std::os::raw::{c_char, c_int}; /// C-style interface for demangling. /// Demangles symbol given in `mangled` argument into `out` buffer @@ -11,7 +11,11 @@ use std::io::Write; /// Returns 0 if `mangled` is not Rust symbol or if `out` buffer is too small /// Returns 1 otherwise #[no_mangle] -pub unsafe extern fn rustc_demangle(mangled: *const c_char, out: *mut c_char, out_size: usize) -> c_int { +pub unsafe extern "C" fn rustc_demangle( + mangled: *const c_char, + out: *mut c_char, + out_size: usize, +) -> c_int { let mangled_str = std::ffi::CStr::from_ptr(mangled).to_str(); if mangled_str.is_err() { return 0; @@ -21,23 +25,29 @@ pub unsafe extern fn rustc_demangle(mangled: *const c_char, out: *mut c_char, ou Ok(demangle) => { let mut out_slice = std::slice::from_raw_parts_mut(out as *mut u8, out_size); match write!(out_slice, "{:#}\0", demangle) { - Ok(_) => { return 1 }, - Err(_) => { return 0 } + Ok(_) => return 1, + Err(_) => return 0, } - }, - Err(_) => { return 0 } + } + Err(_) => return 0, } } #[cfg(test)] mod tests { - use std::os::raw::c_char; use std; + use std::os::raw::c_char; #[test] fn demangle_c_str_large() { let mangled = "_ZN4testE\0"; - let mut out_buf: Vec = vec![42;8]; - let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 8) }; + let mut out_buf: Vec = vec![42; 8]; + let res = unsafe { + super::rustc_demangle( + mangled.as_ptr() as *const c_char, + out_buf.as_mut_ptr() as *mut c_char, + 8, + ) + }; assert_eq!(res, 1); let out_str = std::str::from_utf8(&out_buf[..5]).unwrap(); assert_eq!(out_str, "test\0"); @@ -46,8 +56,14 @@ mod tests { #[test] fn demangle_c_str_exact() { let mangled = "_ZN4testE\0"; - let mut out_buf: Vec = vec![42;8]; - let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 5) }; + let mut out_buf: Vec = vec![42; 8]; + let res = unsafe { + super::rustc_demangle( + mangled.as_ptr() as *const c_char, + out_buf.as_mut_ptr() as *mut c_char, + 5, + ) + }; assert_eq!(res, 1); let out_str = std::str::from_utf8(&out_buf).unwrap(); assert_eq!(out_str, "test\0***"); @@ -56,8 +72,14 @@ mod tests { #[test] fn demangle_c_str_small() { let mangled = "_ZN4testE\0"; - let mut out_buf: Vec = vec![42;8]; - let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 4) }; + let mut out_buf: Vec = vec![42; 8]; + let res = unsafe { + super::rustc_demangle( + mangled.as_ptr() as *const c_char, + out_buf.as_mut_ptr() as *mut c_char, + 4, + ) + }; assert_eq!(res, 0); let out_str = std::str::from_utf8(&out_buf[4..]).unwrap(); assert_eq!(out_str, "****"); @@ -66,8 +88,14 @@ mod tests { #[test] fn demangle_c_str_smaller() { let mangled = "_ZN4testE\0"; - let mut out_buf: Vec = vec![42;8]; - let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 3) }; + let mut out_buf: Vec = vec![42; 8]; + let res = unsafe { + super::rustc_demangle( + mangled.as_ptr() as *const c_char, + out_buf.as_mut_ptr() as *mut c_char, + 3, + ) + }; assert_eq!(res, 0); let out_str = std::str::from_utf8(&out_buf[3..]).unwrap(); assert_eq!(out_str, "*****"); @@ -76,8 +104,14 @@ mod tests { #[test] fn demangle_c_str_zero() { let mangled = "_ZN4testE\0"; - let mut out_buf: Vec = vec![42;8]; - let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 0) }; + let mut out_buf: Vec = vec![42; 8]; + let res = unsafe { + super::rustc_demangle( + mangled.as_ptr() as *const c_char, + out_buf.as_mut_ptr() as *mut c_char, + 0, + ) + }; assert_eq!(res, 0); let out_str = std::str::from_utf8(&out_buf).unwrap(); assert_eq!(out_str, "********"); @@ -86,24 +120,42 @@ mod tests { #[test] fn demangle_c_str_not_rust_symbol() { let mangled = "la la la\0"; - let mut out_buf: Vec = vec![42;8]; - let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 8) }; + let mut out_buf: Vec = vec![42; 8]; + let res = unsafe { + super::rustc_demangle( + mangled.as_ptr() as *const c_char, + out_buf.as_mut_ptr() as *mut c_char, + 8, + ) + }; assert_eq!(res, 0); } #[test] fn demangle_c_str_null() { let mangled = "\0"; - let mut out_buf: Vec = vec![42;8]; - let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 8) }; + let mut out_buf: Vec = vec![42; 8]; + let res = unsafe { + super::rustc_demangle( + mangled.as_ptr() as *const c_char, + out_buf.as_mut_ptr() as *mut c_char, + 8, + ) + }; assert_eq!(res, 0); } #[test] fn demangle_c_str_invalid_utf8() { let mangled = [116, 101, 115, 116, 165, 0]; - let mut out_buf: Vec = vec![42;8]; - let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 8) }; + let mut out_buf: Vec = vec![42; 8]; + let res = unsafe { + super::rustc_demangle( + mangled.as_ptr() as *const c_char, + out_buf.as_mut_ptr() as *mut c_char, + 8, + ) + }; assert_eq!(res, 0); } } From 3deb55d3c72c4adf7fb2fc2b612906258744678d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 9 Dec 2019 10:08:04 -0800 Subject: [PATCH 7/8] Use a `match` instead of `unwrap` --- crates/capi/src/lib.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/capi/src/lib.rs b/crates/capi/src/lib.rs index 9adfb83..42bb6e1 100644 --- a/crates/capi/src/lib.rs +++ b/crates/capi/src/lib.rs @@ -16,11 +16,10 @@ pub unsafe extern "C" fn rustc_demangle( out: *mut c_char, out_size: usize, ) -> c_int { - let mangled_str = std::ffi::CStr::from_ptr(mangled).to_str(); - if mangled_str.is_err() { - return 0; - } - let mangled_str = mangled_str.unwrap(); + let mangled_str = match std::ffi::CStr::from_ptr(mangled).to_str() { + Ok(s) => s, + Err(_) => return 0 + }; match rustc_demangle::try_demangle(mangled_str) { Ok(demangle) => { let mut out_slice = std::slice::from_raw_parts_mut(out as *mut u8, out_size); From 52ff4fac2a490eb576150b2d5b03715d5c1ed76b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 9 Dec 2019 10:09:56 -0800 Subject: [PATCH 8/8] Run rustfmt --- crates/capi/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/capi/src/lib.rs b/crates/capi/src/lib.rs index 42bb6e1..51e3103 100644 --- a/crates/capi/src/lib.rs +++ b/crates/capi/src/lib.rs @@ -18,7 +18,7 @@ pub unsafe extern "C" fn rustc_demangle( ) -> c_int { let mangled_str = match std::ffi::CStr::from_ptr(mangled).to_str() { Ok(s) => s, - Err(_) => return 0 + Err(_) => return 0, }; match rustc_demangle::try_demangle(mangled_str) { Ok(demangle) => {