Skip to content

Commit 62fda26

Browse files
committed
nostd version of C API
1 parent e8ae32f commit 62fda26

File tree

1 file changed

+79
-23
lines changed

1 file changed

+79
-23
lines changed

rustc-demangle-capi/src/lib.rs

Lines changed: 79 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,29 @@
1+
#![no_std]
2+
#![feature(lang_items, core_intrinsics)]
3+
4+
#[cfg(test)]
5+
#[macro_use]
6+
extern crate std;
7+
18
extern crate rustc_demangle;
29

3-
use std::os::raw::{c_char,c_int};
4-
use std::io::Write;
10+
use core::fmt::Write;
11+
12+
struct WriteAdaptor<'a> {
13+
inner: &'a mut [u8]
14+
}
15+
16+
impl<'a> core::fmt::Write for WriteAdaptor<'a> {
17+
fn write_str(&mut self, s: &str) -> core::fmt::Result {
18+
if s.len() > self.inner.len() {
19+
return Err(core::fmt::Error);
20+
}
21+
let (left,right) = core::mem::replace(self, WriteAdaptor { inner: &mut [] }).inner.split_at_mut(s.len());
22+
left.copy_from_slice(s.as_bytes());
23+
*self = WriteAdaptor { inner: right };
24+
Ok(())
25+
}
26+
}
527

628
/// C-style interface for demangling.
729
/// Demangles symbol given in `mangled` argument into `out` buffer
@@ -11,16 +33,23 @@ use std::io::Write;
1133
/// Returns 0 if `mangled` is not Rust symbol or if `out` buffer is too small
1234
/// Returns 1 otherwise
1335
#[no_mangle]
14-
pub unsafe extern fn rustc_demangle(mangled: *const c_char, out: *mut c_char, out_size: usize) -> c_int {
15-
let mangled_str = std::ffi::CStr::from_ptr(mangled).to_str();
36+
pub unsafe extern fn rustc_demangle(mangled: *const u8, out: *mut u8, out_size: usize) -> i64 {
37+
// homebrew version of strlen
38+
let mut mangled_len = 0;
39+
while *(mangled.add(mangled_len)) != 0 {
40+
mangled_len += 1;
41+
}
42+
let mangled_slice = core::slice::from_raw_parts(mangled, mangled_len);
43+
let mangled_str = core::str::from_utf8(mangled_slice);
1644
if mangled_str.is_err() {
1745
return 0;
1846
}
1947
let mangled_str = mangled_str.unwrap();
2048
match rustc_demangle::try_demangle(mangled_str) {
2149
Ok(demangle) => {
22-
let mut out_slice = std::slice::from_raw_parts_mut(out as *mut u8, out_size);
23-
match write!(out_slice, "{:#}\0", demangle) {
50+
let mut out_slice = core::slice::from_raw_parts_mut(out, out_size);
51+
let mut out_adaptor = WriteAdaptor { inner: out_slice };
52+
match write!(out_adaptor, "{:#}\0", demangle) {
2453
Ok(_) => { return 1 },
2554
Err(_) => { return 0 }
2655
}
@@ -31,13 +60,13 @@ pub unsafe extern fn rustc_demangle(mangled: *const c_char, out: *mut c_char, ou
3160

3261
#[cfg(test)]
3362
mod tests {
34-
use std::os::raw::c_char;
3563
use std;
64+
3665
#[test]
3766
fn demangle_c_str_large() {
3867
let mangled = "_ZN4testE\0";
39-
let mut out_buf: Vec<u8> = vec![42;8];
40-
let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 8) };
68+
let mut out_buf = vec![42;8];
69+
let res = unsafe { super::rustc_demangle(mangled.as_ptr(), out_buf.as_mut_ptr(), 8) };
4170
assert_eq!(res, 1);
4271
let out_str = std::str::from_utf8(&out_buf[..5]).unwrap();
4372
assert_eq!(out_str, "test\0");
@@ -46,8 +75,8 @@ mod tests {
4675
#[test]
4776
fn demangle_c_str_exact() {
4877
let mangled = "_ZN4testE\0";
49-
let mut out_buf: Vec<u8> = vec![42;8];
50-
let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 5) };
78+
let mut out_buf = vec![42;8];
79+
let res = unsafe { super::rustc_demangle(mangled.as_ptr(), out_buf.as_mut_ptr(), 5) };
5180
assert_eq!(res, 1);
5281
let out_str = std::str::from_utf8(&out_buf).unwrap();
5382
assert_eq!(out_str, "test\0***");
@@ -56,8 +85,8 @@ mod tests {
5685
#[test]
5786
fn demangle_c_str_small() {
5887
let mangled = "_ZN4testE\0";
59-
let mut out_buf: Vec<u8> = vec![42;8];
60-
let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 4) };
88+
let mut out_buf = vec![42;8];
89+
let res = unsafe { super::rustc_demangle(mangled.as_ptr(), out_buf.as_mut_ptr(), 4) };
6190
assert_eq!(res, 0);
6291
let out_str = std::str::from_utf8(&out_buf[4..]).unwrap();
6392
assert_eq!(out_str, "****");
@@ -66,8 +95,8 @@ mod tests {
6695
#[test]
6796
fn demangle_c_str_smaller() {
6897
let mangled = "_ZN4testE\0";
69-
let mut out_buf: Vec<u8> = vec![42;8];
70-
let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 3) };
98+
let mut out_buf = vec![42;8];
99+
let res = unsafe { super::rustc_demangle(mangled.as_ptr(), out_buf.as_mut_ptr(), 3) };
71100
assert_eq!(res, 0);
72101
let out_str = std::str::from_utf8(&out_buf[3..]).unwrap();
73102
assert_eq!(out_str, "*****");
@@ -76,8 +105,8 @@ mod tests {
76105
#[test]
77106
fn demangle_c_str_zero() {
78107
let mangled = "_ZN4testE\0";
79-
let mut out_buf: Vec<u8> = vec![42;8];
80-
let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 0) };
108+
let mut out_buf = vec![42;8];
109+
let res = unsafe { super::rustc_demangle(mangled.as_ptr(), out_buf.as_mut_ptr(), 0) };
81110
assert_eq!(res, 0);
82111
let out_str = std::str::from_utf8(&out_buf).unwrap();
83112
assert_eq!(out_str, "********");
@@ -86,24 +115,51 @@ mod tests {
86115
#[test]
87116
fn demangle_c_str_not_rust_symbol() {
88117
let mangled = "la la la\0";
89-
let mut out_buf: Vec<u8> = vec![42;8];
90-
let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 8) };
118+
let mut out_buf = vec![42;8];
119+
let res = unsafe { super::rustc_demangle(mangled.as_ptr(), out_buf.as_mut_ptr(), 8) };
91120
assert_eq!(res, 0);
92121
}
93122

94123
#[test]
95124
fn demangle_c_str_null() {
96125
let mangled = "\0";
97-
let mut out_buf: Vec<u8> = vec![42;8];
98-
let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 8) };
126+
let mut out_buf = vec![42;8];
127+
let res = unsafe { super::rustc_demangle(mangled.as_ptr(), out_buf.as_mut_ptr(), 8) };
99128
assert_eq!(res, 0);
100129
}
101130

102131
#[test]
103132
fn demangle_c_str_invalid_utf8() {
104133
let mangled = [116, 101, 115, 116, 165, 0];
105-
let mut out_buf: Vec<u8> = vec![42;8];
106-
let res = unsafe { super::rustc_demangle(mangled.as_ptr() as *const c_char, out_buf.as_mut_ptr() as *mut c_char, 8) };
134+
let mut out_buf = vec![42;8];
135+
let res = unsafe { super::rustc_demangle(mangled.as_ptr(), out_buf.as_mut_ptr(), 8) };
107136
assert_eq!(res, 0);
108137
}
109138
}
139+
140+
#[cfg(not(test))]
141+
pub mod nostd_boilerplate {
142+
use core;
143+
// These functions are used by the compiler, but not
144+
// for a bare-bones hello world. These are normally
145+
// provided by libstd.
146+
#[lang = "eh_personality"]
147+
#[no_mangle]
148+
pub extern fn rust_eh_personality() {
149+
}
150+
151+
// This function may be needed based on the compilation target.
152+
#[lang = "eh_unwind_resume"]
153+
#[no_mangle]
154+
pub extern fn rust_eh_unwind_resume() {
155+
}
156+
157+
#[lang = "panic_fmt"]
158+
#[no_mangle]
159+
pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
160+
_file: &'static str,
161+
_line: u32,
162+
_column: u32) -> ! {
163+
unsafe { core::intrinsics::abort() }
164+
}
165+
}

0 commit comments

Comments
 (0)