]> git.lizzy.rs Git - rust.git/blob - library/panic_abort/src/android.rs
Rollup merge of #100804 - GuillaumeGomez:search-results-color-ayu, r=notriddle
[rust.git] / library / panic_abort / src / android.rs
1 use alloc::string::String;
2 use core::mem::transmute;
3 use core::panic::BoxMeUp;
4 use core::ptr::copy_nonoverlapping;
5
6 const ANDROID_SET_ABORT_MESSAGE: &[u8] = b"android_set_abort_message\0";
7 type SetAbortMessageType = unsafe extern "C" fn(*const libc::c_char) -> ();
8
9 // Forward the abort message to libc's android_set_abort_message. We try our best to populate the
10 // message but as this function may already be called as part of a failed allocation, it might not be
11 // possible to do so.
12 //
13 // Some methods of core are on purpose avoided (such as try_reserve) as these rely on the correct
14 // resolution of rust_eh_personality which is loosely defined in panic_abort.
15 //
16 // Weakly resolve the symbol for android_set_abort_message. This function is only available
17 // for API >= 21.
18 pub(crate) unsafe fn android_set_abort_message(payload: *mut &mut dyn BoxMeUp) {
19     let func_addr =
20         libc::dlsym(libc::RTLD_DEFAULT, ANDROID_SET_ABORT_MESSAGE.as_ptr() as *const libc::c_char)
21             as usize;
22     if func_addr == 0 {
23         return;
24     }
25
26     let payload = (*payload).get();
27     let msg = match payload.downcast_ref::<&'static str>() {
28         Some(msg) => msg.as_bytes(),
29         None => match payload.downcast_ref::<String>() {
30             Some(msg) => msg.as_bytes(),
31             None => &[],
32         },
33     };
34     if msg.is_empty() {
35         return;
36     }
37
38     // Allocate a new buffer to append the null byte.
39     let size = msg.len() + 1usize;
40     let buf = libc::malloc(size) as *mut libc::c_char;
41     if buf.is_null() {
42         return; // allocation failure
43     }
44     copy_nonoverlapping(msg.as_ptr(), buf as *mut u8, msg.len());
45     buf.add(msg.len()).write(0);
46
47     let func = transmute::<usize, SetAbortMessageType>(func_addr);
48     func(buf);
49 }