panda/plugins/
proc_start_linux.rs1use crate::plugin_import;
7use std::os::raw::c_int;
8
9use crate::sys::{target_ulong, CPUState, TranslationBlock};
10
11plugin_import! {
12 static PROC_START_LINUX: ProcStartLinux = extern "proc_start_linux" {
13 callbacks {
14 fn on_rec_auxv(cpu: &mut CPUState, tb: &mut TranslationBlock, auxv: &AuxvValues);
15 }
16 };
17}
18
19pub const MAX_PATH_LEN: u32 = 256;
20pub const MAX_NUM_ARGS: u32 = 10;
21pub const MAX_NUM_ENV: u32 = 20;
22
23#[repr(C)]
30#[derive(Clone)]
31pub struct AuxvValues {
32 pub argc: c_int,
33 pub argv_ptr_ptr: target_ulong,
34 pub arg_ptr: [target_ulong; 10usize],
35 pub argv: [[u8; 256usize]; 10usize],
36 pub envc: c_int,
37 pub env_ptr_ptr: target_ulong,
38 pub env_ptr: [target_ulong; 20usize],
39 pub envp: [[u8; 256usize]; 20usize],
40 pub execfn_ptr: target_ulong,
41 pub execfn: [u8; 256usize],
42 pub phdr: target_ulong,
43 pub entry: target_ulong,
44 pub ehdr: target_ulong,
45 pub hwcap: target_ulong,
46 pub hwcap2: target_ulong,
47 pub pagesz: target_ulong,
48 pub clktck: target_ulong,
49 pub phent: target_ulong,
50 pub phnum: target_ulong,
51 pub base: target_ulong,
52 pub flags: target_ulong,
53 pub uid: target_ulong,
54 pub euid: target_ulong,
55 pub gid: target_ulong,
56 pub egid: target_ulong,
57 pub secure: bool,
58 pub random: target_ulong,
59 pub platform: target_ulong,
60 pub program_header: target_ulong,
61}
62
63impl AuxvValues {
64 pub fn argv(&self) -> Vec<String> {
65 self.argv[..self.argc as usize]
66 .iter()
67 .map(|arg| {
68 String::from_utf8_lossy(&arg[..arg.iter().position(|x| *x == 0).unwrap()])
69 .into_owned()
70 })
71 .collect()
72 }
73
74 pub fn envp(&self) -> Vec<String> {
75 self.envp[..self.envc as usize]
76 .iter()
77 .map(|env| {
78 String::from_utf8_lossy(&env[..env.iter().position(|x| *x == 0).unwrap()])
79 .into_owned()
80 })
81 .collect()
82 }
83
84 pub fn execfn(&self) -> String {
85 let execfn = &self.execfn;
86 String::from_utf8_lossy(&execfn[..execfn.iter().position(|x| *x == 0).unwrap()])
87 .into_owned()
88 }
89}
90
91use std::fmt;
92
93struct HexDebug<D: fmt::Debug>(D);
94
95impl<D: fmt::Debug> fmt::Debug for HexDebug<D> {
96 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97 write!(f, "{:#x?}", self.0)
98 }
99}
100
101impl fmt::Debug for AuxvValues {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 f.debug_struct("AuxvValues")
104 .field("argc", &self.argc)
105 .field("argv_ptr_ptr", &HexDebug(self.argv_ptr_ptr))
106 .field("arg_ptr", &HexDebug(&self.arg_ptr[..self.argc as usize]))
107 .field("argv", &self.argv())
108 .field("envc", &self.envc)
109 .field("env_ptr_ptr", &HexDebug(self.env_ptr_ptr))
110 .field("env_ptr", &HexDebug(&self.env_ptr[..self.envc as usize]))
111 .field("envp", &self.envp())
112 .field("execfn_ptr", &HexDebug(self.execfn_ptr))
113 .field("execfn", &self.execfn())
114 .field("phdr", &HexDebug(self.phdr))
115 .field("entry", &HexDebug(self.entry))
116 .field("ehdr", &HexDebug(self.ehdr))
117 .field("hwcap", &self.hwcap)
118 .field("hwcap2", &self.hwcap2)
119 .field("pagesz", &HexDebug(self.pagesz))
120 .field("clktck", &self.clktck)
121 .field("phent", &self.phent)
122 .field("phnum", &self.phnum)
123 .field("base", &HexDebug(self.base))
124 .field("flags", &self.flags)
125 .field("uid", &self.uid)
126 .field("euid", &self.euid)
127 .field("gid", &self.gid)
128 .field("egid", &self.egid)
129 .field("secure", &self.secure)
130 .field("random", &HexDebug(self.random))
131 .field("platform", &HexDebug(self.platform))
132 .field("program_header", &HexDebug(self.program_header))
133 .finish()
134 }
135}