1
+ #![ no_std]
2
+ #![ feature( lang_items, core_intrinsics) ]
3
+
4
+ #[ cfg( test) ]
5
+ #[ macro_use]
6
+ extern crate std;
7
+
1
8
extern crate rustc_demangle;
2
9
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
+ }
5
27
6
28
/// C-style interface for demangling.
7
29
/// Demangles symbol given in `mangled` argument into `out` buffer
@@ -11,16 +33,23 @@ use std::io::Write;
11
33
/// Returns 0 if `mangled` is not Rust symbol or if `out` buffer is too small
12
34
/// Returns 1 otherwise
13
35
#[ 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) ;
16
44
if mangled_str. is_err ( ) {
17
45
return 0 ;
18
46
}
19
47
let mangled_str = mangled_str. unwrap ( ) ;
20
48
match rustc_demangle:: try_demangle ( mangled_str) {
21
49
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) {
24
53
Ok ( _) => { return 1 } ,
25
54
Err ( _) => { return 0 }
26
55
}
@@ -31,13 +60,13 @@ pub unsafe extern fn rustc_demangle(mangled: *const c_char, out: *mut c_char, ou
31
60
32
61
#[ cfg( test) ]
33
62
mod tests {
34
- use std:: os:: raw:: c_char;
35
63
use std;
64
+
36
65
#[ test]
37
66
fn demangle_c_str_large ( ) {
38
67
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 ) } ;
41
70
assert_eq ! ( res, 1 ) ;
42
71
let out_str = std:: str:: from_utf8 ( & out_buf[ ..5 ] ) . unwrap ( ) ;
43
72
assert_eq ! ( out_str, "test\0 " ) ;
@@ -46,8 +75,8 @@ mod tests {
46
75
#[ test]
47
76
fn demangle_c_str_exact ( ) {
48
77
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 ) } ;
51
80
assert_eq ! ( res, 1 ) ;
52
81
let out_str = std:: str:: from_utf8 ( & out_buf) . unwrap ( ) ;
53
82
assert_eq ! ( out_str, "test\0 ***" ) ;
@@ -56,8 +85,8 @@ mod tests {
56
85
#[ test]
57
86
fn demangle_c_str_small ( ) {
58
87
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 ) } ;
61
90
assert_eq ! ( res, 0 ) ;
62
91
let out_str = std:: str:: from_utf8 ( & out_buf[ 4 ..] ) . unwrap ( ) ;
63
92
assert_eq ! ( out_str, "****" ) ;
@@ -66,8 +95,8 @@ mod tests {
66
95
#[ test]
67
96
fn demangle_c_str_smaller ( ) {
68
97
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 ) } ;
71
100
assert_eq ! ( res, 0 ) ;
72
101
let out_str = std:: str:: from_utf8 ( & out_buf[ 3 ..] ) . unwrap ( ) ;
73
102
assert_eq ! ( out_str, "*****" ) ;
@@ -76,8 +105,8 @@ mod tests {
76
105
#[ test]
77
106
fn demangle_c_str_zero ( ) {
78
107
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 ) } ;
81
110
assert_eq ! ( res, 0 ) ;
82
111
let out_str = std:: str:: from_utf8 ( & out_buf) . unwrap ( ) ;
83
112
assert_eq ! ( out_str, "********" ) ;
@@ -86,24 +115,51 @@ mod tests {
86
115
#[ test]
87
116
fn demangle_c_str_not_rust_symbol ( ) {
88
117
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 ) } ;
91
120
assert_eq ! ( res, 0 ) ;
92
121
}
93
122
94
123
#[ test]
95
124
fn demangle_c_str_null ( ) {
96
125
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 ) } ;
99
128
assert_eq ! ( res, 0 ) ;
100
129
}
101
130
102
131
#[ test]
103
132
fn demangle_c_str_invalid_utf8 ( ) {
104
133
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 ) } ;
107
136
assert_eq ! ( res, 0 ) ;
108
137
}
109
138
}
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