Skip to content

Commit 4c023aa

Browse files
syscall: make use of the #[syscall] proc macro to generate the syslog
* Make use of the `#[syscall]` proc macro to generate the syscall log for that syscall. * Pass `no_return` to the macro if the syscall never returns (`#[syscall(no_return)]`) TODO: We may want to automagically detect this case by checking the return type of the function. Which is'nt that stright-forward since type information is not avaliable to proc macros (if you see how they work) This patch makes the syslogs more readable and significantly helps in debugging a syscall :). Signed-off-by: Andy-Python-Programmer <[email protected]>
1 parent 38618f5 commit 4c023aa

File tree

7 files changed

+171
-45
lines changed

7 files changed

+171
-45
lines changed

aero.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ def run_in_emulator(args, iso_path):
524524

525525
qemu_args = ['-cdrom', iso_path,
526526
'-M', 'q35',
527-
'-m', '1G',
527+
'-m', '5G',
528528
'-smp', '5',
529529
'-serial', 'stdio']
530530

src/aero_kernel/src/syscall/mod.rs

Lines changed: 65 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,70 @@ pub fn exec_args_from_slice(args: usize, size: usize) -> ExecArgs {
155155
ExecArgs { inner: result }
156156
}
157157

158+
#[cfg(feature = "syslog")]
159+
pub(super) struct SysLog {
160+
name: &'static str,
161+
/// The result of the syscall.
162+
result: Option<Result<usize, SyscallError>>,
163+
/// The formatted argument values.
164+
args: Vec<String>,
165+
}
166+
167+
#[cfg(feature = "syslog")]
168+
impl SysLog {
169+
pub fn new(name: &'static str) -> Self {
170+
Self {
171+
name,
172+
result: None,
173+
args: Vec::new(),
174+
}
175+
}
176+
177+
pub fn add_argument<T>(mut self, value: T) -> Self
178+
where
179+
T: core::fmt::Display,
180+
{
181+
self.args.push(alloc::format!("{value}"));
182+
self
183+
}
184+
185+
pub fn add_argument_dbg<T>(mut self, value: T) -> Self
186+
where
187+
T: core::fmt::Debug,
188+
{
189+
self.args.push(alloc::format!("{value:?}"));
190+
self
191+
}
192+
193+
pub fn set_result(mut self, result: Result<usize, SyscallError>) -> Self {
194+
self.result = Some(result);
195+
self
196+
}
197+
198+
pub fn flush(self) {
199+
let mut result = String::new();
200+
201+
if self.result.map(|e| e.is_ok()).unwrap_or_default() {
202+
result.push_str("\x1b[1;32m");
203+
} else {
204+
result.push_str("\x1b[1;31m");
205+
}
206+
207+
result.push_str(alloc::format!("{}\x1b[0m(", self.name).as_str());
208+
209+
for (i, e) in self.args.iter().enumerate() {
210+
if i != 0 {
211+
result.push_str(", ");
212+
}
213+
214+
result.push_str(e);
215+
}
216+
217+
result.push_str(alloc::format!(") = {:?}", self.result.unwrap()).as_str());
218+
log::trace!("{result}");
219+
}
220+
}
221+
158222
pub fn generic_do_syscall(
159223
a: usize,
160224
b: usize,
@@ -241,40 +305,5 @@ pub fn generic_do_syscall(
241305
}
242306
};
243307

244-
let result_usize = aero_syscall::syscall_result_as_usize(result);
245-
246-
#[cfg(feature = "syslog")]
247-
{
248-
let name = aero_syscall::syscall_as_str(a);
249-
let mut result_v = String::new();
250-
251-
if result.is_ok() {
252-
result_v.push_str("\x1b[1;32m");
253-
} else {
254-
result_v.push_str("\x1b[1;31m");
255-
}
256-
257-
result_v.push_str(name);
258-
result_v.push_str("\x1b[0m");
259-
260-
result_v.push_str("(");
261-
262-
for (i, arg) in [b, c, d, e, f, g].iter().enumerate() {
263-
if i != 0 {
264-
result_v.push_str(", ");
265-
}
266-
267-
let hex_arg = alloc::format!("{:#x}", *arg);
268-
result_v.push_str(&hex_arg);
269-
}
270-
271-
result_v.push_str(") = ");
272-
273-
let result_str = alloc::format!("{:?}", result);
274-
result_v.push_str(&result_str);
275-
276-
log::trace!("{}", result_v);
277-
}
278-
279-
result_usize
308+
aero_syscall::syscall_result_as_usize(result)
280309
}

src/aero_kernel/src/syscall/process.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ fn hostname() -> &'static Mutex<String> {
3737
HOSTNAME.call_once(|| Mutex::new(String::from("aero")))
3838
}
3939

40-
#[syscall]
41-
pub fn exit(status: usize) -> ! {
40+
#[syscall(no_return)]
41+
pub fn exit(status: usize) -> Result<usize, SyscallError> {
4242
#[cfg(all(test, feature = "ci"))]
4343
crate::emu::exit_qemu(crate::emu::ExitStatus::Success);
4444

@@ -113,7 +113,7 @@ pub fn kill(pid: usize, signal: usize) -> Result<usize, SyscallError> {
113113
}
114114
}
115115

116-
#[syscall]
116+
#[syscall(no_return)]
117117
pub fn exec(
118118
path: &Path,
119119
args: usize,
@@ -328,8 +328,8 @@ pub fn sigaction(
328328
Ok(0)
329329
}
330330

331-
#[syscall]
332-
pub fn shutdown() -> ! {
331+
#[syscall(no_return)]
332+
pub fn shutdown() -> Result<usize, SyscallError> {
333333
fs::cache::dcache().log();
334334

335335
fs::cache::clear_inode_cache();

src/aero_proc/src/syscall.rs

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use quote::quote;
2424

2525
use syn::punctuated::Punctuated;
2626
use syn::spanned::Spanned;
27-
use syn::{Expr, FnArg, Pat, Type};
27+
use syn::{Expr, FnArg, NestedMeta, Pat, Type};
2828

2929
enum ArgType {
3030
Array(bool), // mutable?
@@ -35,7 +35,40 @@ enum ArgType {
3535
Path,
3636
}
3737

38-
pub fn parse(_: TokenStream, item: TokenStream) -> TokenStream {
38+
#[derive(Default)]
39+
struct Config {
40+
no_return: bool,
41+
}
42+
43+
// TODO: determine if no_return by checking the return type of the syscall function;
44+
// if its the never type <!>.
45+
fn parse_attribute_args(args: Vec<NestedMeta>) -> Config {
46+
let mut config = Config::default();
47+
48+
for attribute in args {
49+
match attribute {
50+
NestedMeta::Meta(meta) => match meta {
51+
syn::Meta::Path(path) => {
52+
if let Some(ident) = path.get_ident() {
53+
match ident.to_string().as_str() {
54+
"no_return" => config.no_return = true,
55+
_ => emit_error!(ident.span(), "unknown attribute"),
56+
}
57+
}
58+
}
59+
_ => emit_error!(meta.span(), "unknown attribute"),
60+
},
61+
NestedMeta::Lit(e) => emit_error!(e.span(), "unknown attribute"),
62+
}
63+
}
64+
65+
config
66+
}
67+
68+
pub fn parse(attr: TokenStream, item: TokenStream) -> TokenStream {
69+
let attr = syn::parse_macro_input!(attr as syn::AttributeArgs);
70+
let config = parse_attribute_args(attr);
71+
3972
let parsed_fn = syn::parse_macro_input!(item as syn::ItemFn);
4073
let signature = &parsed_fn.sig;
4174

@@ -75,10 +108,61 @@ pub fn parse(_: TokenStream, item: TokenStream) -> TokenStream {
75108
let ret = &signature.output;
76109
let body = &parsed_fn.block;
77110

111+
let syslog_args = orig_args
112+
.iter()
113+
.map(|e| match e {
114+
FnArg::Typed(typed) => match typed.pat.as_ref() {
115+
Pat::Ident(pat) => {
116+
let ident = &pat.ident;
117+
let typ = determine_arg_type(&typed.ty);
118+
119+
if let Some(typ) = typ {
120+
match typ {
121+
ArgType::Array(_) => quote::quote!(.add_argument("<array>")),
122+
ArgType::Slice(_) => quote::quote!(.add_argument("<slice>")),
123+
124+
ArgType::Pointer(_) => {
125+
quote::quote!(.add_argument(alloc::format!("*{:#x}", #ident as usize)))
126+
}
127+
128+
ArgType::Reference(_) => {
129+
quote::quote!(.add_argument(alloc::format!("&{:#x}", #ident as *const _ as usize)))
130+
},
131+
132+
ArgType::String | ArgType::Path => quote::quote!(.add_argument_dbg(#ident)),
133+
}
134+
} else {
135+
quote::quote!(.add_argument(#ident))
136+
}
137+
}
138+
_ => unreachable!(),
139+
},
140+
_ => unreachable!(),
141+
})
142+
.collect::<Vec<_>>();
143+
144+
let syslog = quote::quote! {
145+
#[cfg(feature = "syslog")]
146+
crate::syscall::SysLog::new(stringify!(#name))
147+
#(#syslog_args)*
148+
.set_result(result)
149+
.flush();
150+
};
151+
152+
let compiled_body = if config.no_return {
153+
quote::quote! { #body }
154+
} else {
155+
quote::quote! {
156+
let result = #body;
157+
#syslog
158+
result
159+
}
160+
};
161+
78162
let result = quote! {
79163
#(#attrs)* #vis fn #name(#(#processed_args),*) #ret {
80164
#(#attrs)* fn inner_syscall(#orig_args) #ret {
81-
#body
165+
#compiled_body
82166
}
83167

84168
inner_syscall(#(#call_args),*)

src/aero_syscall/src/consts.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,16 @@ pub struct EPollEvent {
155155
pub data: EPollData,
156156
}
157157

158+
impl core::fmt::Debug for EPollEvent {
159+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
160+
f.debug_struct("EPollEvent")
161+
.field("events", &self.events)
162+
.finish()
163+
}
164+
}
165+
158166
// structures for the poll API:
167+
#[derive(Debug)]
159168
pub struct PollFd {
160169
pub fd: i32,
161170
pub events: PollEventFlags,

src/aero_syscall/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ pub struct SysDirEntry {
255255
pub name: [u8; 0],
256256
}
257257

258+
#[derive(Debug)]
258259
#[repr(C)]
259260
pub struct Utsname {
260261
pub name: [u8; 65],
@@ -421,6 +422,7 @@ pub struct Termios {
421422
pub const AT_FDCWD: isize = -100;
422423

423424
#[repr(C)]
425+
#[derive(Debug)]
424426
pub struct SysInfo {
425427
/// Seconds since boot
426428
pub uptime: i64,

src/aero_syscall/src/socket.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// sysdeps/aero/include/abi-bits/socket.h
2+
#[derive(Debug)]
23
#[repr(C)]
34
pub struct MessageHeader {
45
name: *const u8,
@@ -14,6 +15,7 @@ pub struct MessageHeader {
1415
}
1516

1617
// options/posix/include/bits/posix/iovec.h
18+
#[derive(Debug)]
1719
#[repr(C)]
1820
pub struct IoVec {
1921
base: *mut u8,

0 commit comments

Comments
 (0)