Skip to content

Commit 0d551ae

Browse files
aero_proc::syscall: fix const array parsing
* The current code parsed the array by parsing it as a slice and then getting a reference `N` elements which does *not* make it an array (it will still be a slice). * Update the macro to use `validate_array_mut` to validate and construct the array. * Remove the length param from ArgType::Array since the `validate_array_mut` method takes the length as a const generic param which means that the compiler can automagically get us the length :^) * Remove all of the useless diagnostic since now we automagically get the array length. Signed-off-by: Andy-Python-Programmer <[email protected]>
1 parent e81305c commit 0d551ae

File tree

4 files changed

+20
-63
lines changed

4 files changed

+20
-63
lines changed

src/aero_kernel/src/syscall/fs.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,7 @@ pub fn seek(fd: usize, offset: usize, whence: usize) -> Result<usize, AeroSyscal
238238
}
239239

240240
#[aero_proc::syscall]
241-
pub fn pipe(fds: &mut [usize], flags: usize) -> Result<usize, AeroSyscallError> {
242-
assert!(fds.len() == 2);
243-
241+
pub fn pipe(fds: &mut [usize; 2], flags: usize) -> Result<usize, AeroSyscallError> {
244242
let flags = OpenFlags::from_bits(flags).ok_or(AeroSyscallError::EINVAL)?;
245243
let pipe = Pipe::new();
246244

src/aero_kernel/src/syscall/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ pub fn generic_do_syscall(
194194
SYS_IOCTL => fs::ioctl(b, c, d),
195195
SYS_SEEK => fs::seek(b, c, d),
196196
SYS_ACCESS => fs::access(b, c, d, e, f),
197-
SYS_PIPE => fs::pipe(b, 2, c), // TODO: We shouldn't have to pass 2 here.
197+
SYS_PIPE => fs::pipe(b, c),
198198
SYS_UNLINK => fs::unlink(b, c, d, e),
199199
SYS_DUP => fs::dup(b, c),
200200
SYS_DUP2 => fs::dup2(b, c, d),

src/aero_kernel/src/utils/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ pub fn validate_str(ptr: *const u8, len: usize) -> Option<&'static str> {
6868
}
6969
}
7070

71+
pub fn validate_array_mut<T, const COUNT: usize>(ptr: *mut T) -> Option<&'static mut [T; COUNT]> {
72+
// We use the `validate_slice_mut` function to validate if it safe to read `COUNT` amount
73+
// of memory from `ptr`. Then we convert the slice to an array.
74+
let slice = validate_slice_mut::<T>(ptr, COUNT);
75+
// SAFETY: We know that `slice` is a valid slice of `COUNT` elements.
76+
slice.map(|e| unsafe { &mut *(e.as_ptr() as *mut [T; COUNT]) })
77+
}
78+
7179
pub macro intel_asm($($code:expr,)+) {
7280
core::arch::global_asm!(concat!($($code),+,));
7381
}

src/aero_proc/src/lib.rs

Lines changed: 10 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
use proc_macro::{Diagnostic, Level, TokenStream};
44
use proc_macro2::{Ident, Span};
55
use quote::quote;
6-
use syn::{punctuated::Punctuated, spanned::Spanned, Expr, FnArg, Lit, Pat, Type};
6+
use syn::{punctuated::Punctuated, spanned::Spanned, Expr, FnArg, Pat, Type};
77

88
enum ArgType {
9-
Array(bool, usize),
10-
Slice(bool),
11-
Pointer(bool),
12-
Reference(bool),
9+
Array(bool), // mutable?
10+
Slice(bool), // mutable?
11+
Pointer(bool), // mutable?
12+
Reference(bool), // mutable?
1313
String,
1414
Path,
1515
}
@@ -82,48 +82,7 @@ pub fn syscall(_: TokenStream, item: TokenStream) -> TokenStream {
8282
fn determine_arg_type(typ: &Type) -> Option<ArgType> {
8383
match typ {
8484
Type::Reference(typ) => match typ.elem.as_ref() {
85-
Type::Array(array) => match &array.len {
86-
Expr::Lit(lit) => match &lit.lit {
87-
Lit::Int(lit) => match lit.base10_parse() {
88-
Ok(len) => Some(ArgType::Array(typ.mutability.is_some(), len)),
89-
Err(err) => {
90-
Diagnostic::spanned(
91-
lit.span().unwrap(),
92-
Level::Error,
93-
&format!("failed to parse array length: {}", err),
94-
)
95-
.emit();
96-
97-
// If we can't parse the array length, we just give it an arbitrary length.
98-
// This is probably not the best way to do this, but it won't cause any
99-
// further errors to be emitted.
100-
Some(ArgType::Array(typ.mutability.is_some(), 0))
101-
}
102-
},
103-
_ => {
104-
Diagnostic::spanned(
105-
lit.span().unwrap(),
106-
Level::Error,
107-
"array length must be a constant integer",
108-
)
109-
.emit();
110-
111-
// Same as above.
112-
Some(ArgType::Array(typ.mutability.is_some(), 0))
113-
}
114-
},
115-
_ => {
116-
Diagnostic::spanned(
117-
array.span().unwrap(),
118-
Level::Error,
119-
"array length must be a constant integer",
120-
)
121-
.emit();
122-
123-
// Same as above.
124-
Some(ArgType::Array(typ.mutability.is_some(), 0))
125-
}
126-
},
85+
Type::Array(_) => Some(ArgType::Array(typ.mutability.is_some())),
12786
Type::Slice(_) => Some(ArgType::Slice(typ.mutability.is_some())),
12887
Type::Path(path) => {
12988
if path.path.segments.last().unwrap().ident == "str" {
@@ -161,7 +120,7 @@ fn process_args(args: &Punctuated<FnArg, syn::Token![,]>) -> Vec<FnArg> {
161120
result.push(syn::parse_quote!(#data: usize));
162121
result.push(syn::parse_quote!(#len: usize));
163122
}
164-
Some(ArgType::Array(_, _)) => {
123+
Some(ArgType::Array(_)) => {
165124
let data = Ident::new(&format!("{}_data", ident), Span::call_site());
166125

167126
result.push(syn::parse_quote!(#data: usize));
@@ -225,21 +184,13 @@ fn process_call_args(args: &Punctuated<FnArg, syn::Token![,]>) -> Vec<Expr> {
225184

226185
result.push(slice_expr);
227186
}
228-
ArgType::Array(is_mut, length) => {
187+
ArgType::Array(is_mut) => {
229188
let array_expr: Expr = if is_mut {
230189
syn::parse_quote! {
231-
{
232-
let slice = crate::utils::validate_slice_mut(#data_ident as *mut _, #length).ok_or(AeroSyscallError::EINVAL)?;
233-
&mut slice[0..#length]
234-
}
190+
crate::utils::validate_array_mut(#data_ident as *mut _).ok_or(AeroSyscallError::EINVAL)?
235191
}
236192
} else {
237-
syn::parse_quote! {
238-
{
239-
let slice = crate::utils::validate_slice(#data_ident as *const _, #length).ok_or(AeroSyscallError::EINVAL)?;
240-
&slice[0..#length]
241-
}
242-
}
193+
unimplemented!()
243194
};
244195

245196
result.push(array_expr);

0 commit comments

Comments
 (0)