1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use alloc::vec::Vec;
use core::{slice, str};
use lazy_static::lazy_static;
use log::info;
extern "C" {
fn _bin_count();
fn _bin_address();
fn _bin_name();
}
lazy_static! {
static ref BIN_NAME_LIST: Vec<&'static str> = {
let mut bin_name_list = Vec::new();
let mut bin_name_pointer = _bin_name as usize as *const u8;
let bin_count = get_bin_count();
unsafe {
for _ in 0..bin_count {
let mut bin_name_length = 0;
while bin_name_pointer.add(bin_name_length).read_volatile() != b'\0' {
bin_name_length += 1;
}
let bin_name_slice = slice::from_raw_parts(bin_name_pointer, bin_name_length);
bin_name_list.push(str::from_utf8(bin_name_slice).unwrap());
bin_name_pointer = bin_name_pointer.add(bin_name_length).add(1);
}
}
bin_name_list
};
}
pub fn get_bin_count() -> usize {
unsafe { (_bin_count as *const usize).read_volatile() }
}
pub fn get_bin(name: &str) -> Option<&'static [u8]> {
let bin_count = get_bin_count();
(0..bin_count)
.find(|&bin_index| BIN_NAME_LIST[bin_index] == name)
.map(get_bin_data)
}
pub fn get_bin_data(bin_index: usize) -> &'static [u8] {
let bin_address_pointer = _bin_address as *const usize;
unsafe {
let bin_address_start = bin_address_pointer.add(bin_index * 2).read_volatile();
let bin_address_end = bin_address_pointer.add(bin_index * 2 + 1).read_volatile();
slice::from_raw_parts(
bin_address_start as *const u8,
bin_address_end - bin_address_start,
)
}
}
pub fn print_bin_name() {
let bin_count = get_bin_count();
let mut bin_name_list = Vec::new();
for bin_index in 0..bin_count {
let bin_name = BIN_NAME_LIST[bin_index];
if bin_name == "init" {
continue;
}
bin_name_list.push(bin_name);
}
info!("built-in binaries: {}", bin_name_list.join(", "));
}