Skip to content

Commit b4523f1

Browse files
feat: fix mmap memes
* The end_address of a partial mapping needs to be set to the start address of the unmap range. * Similarly for unmap end, the end address needs to be set to the start address of the unmap range. Signed-off-by: Anhad Singh <[email protected]>
1 parent a62348f commit b4523f1

File tree

11 files changed

+743
-178
lines changed

11 files changed

+743
-178
lines changed

src/aero_kernel/src/fs/cache.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,14 @@ pub type DirCacheKey = (usize, String);
314314
pub type DirCache = Cache<DirCacheKey, DirEntry>;
315315
pub type DirCacheItem = CacheArc<CacheItem<DirCacheKey, DirEntry>>;
316316

317+
impl Debug for DirCacheItem {
318+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
319+
f.debug_tuple("DirCacheItem")
320+
.field(&self.absolute_path_str())
321+
.finish()
322+
}
323+
}
324+
317325
pub struct CachedINode(Arc<dyn INodeInterface>);
318326

319327
impl CachedINode {

src/aero_kernel/src/socket/unix.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,9 +410,9 @@ impl INodeInterface for UnixSocket {
410410
.sum::<usize>())
411411
}
412412

413-
fn send(&self, message_hdr: &mut MessageHeader, _flags: MessageFlags) -> fs::Result<usize> {
413+
fn send(&self, header: &mut MessageHeader, _flags: MessageFlags) -> fs::Result<usize> {
414414
// FIXME(andyython): figure out the message header stuff...
415-
let data = message_hdr
415+
let data = header
416416
.iovecs()
417417
.iter()
418418
.flat_map(|e| e.as_slice())

src/aero_kernel/src/syscall/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ pub fn generic_do_syscall(
252252
SYS_SOCK_SHUTDOWN => net::shutdown(b, c),
253253
SYS_GETPEERNAME => net::get_peername(b, c, d),
254254
SYS_GETSOCKNAME => net::get_sockname(b, c, d),
255+
SYS_SETSOCKOPT => net::setopt(a, b, c, d, e),
255256

256257
SYS_GETTIME => time::gettime(b, c),
257258
SYS_SLEEP => time::sleep(b),

src/aero_kernel/src/syscall/net.rs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use aero_syscall::netlink::sockaddr_nl;
2-
use aero_syscall::socket::{MessageFlags, MessageHeader};
2+
use aero_syscall::socket::{MessageFlags, MessageHeader, SocketOptionLevel};
33
use aero_syscall::*;
44
use alloc::sync::Arc;
55
use num_traits::cast::FromPrimitive;
@@ -20,6 +20,8 @@ use crate::socket::{SocketAddr, SocketAddrRef};
2020
use crate::userland::scheduler;
2121
use crate::userland::task::TaskId;
2222

23+
use super::FileDescriptor;
24+
2325
/// Creates a [`SocketAddr`] from the provided userland socket structure address. This
2426
/// is done by looking at the family field present in every socket address structure.
2527
fn socket_addr_from_addr<'sys>(address: VirtAddr) -> Result<SocketAddrRef<'sys>> {
@@ -76,6 +78,8 @@ pub fn accept(fd: usize, address: usize, length: usize) -> Result<usize> {
7678

7779
#[syscall]
7880
pub fn sock_send(fd: usize, header: &mut MessageHeader, flags: usize) -> Result<usize> {
81+
dbg!(header.control());
82+
7983
let flags = MessageFlags::from_bits(flags).ok_or(SyscallError::EINVAL)?;
8084

8185
let current_task = scheduler::get_scheduler().current_task();
@@ -100,17 +104,32 @@ pub fn sock_recv(sockfd: usize, header: &mut MessageHeader, flags: usize) -> Res
100104
Ok(socket.inode().recv(header, flags)?)
101105
}
102106

107+
#[syscall]
108+
pub fn setopt(fd: FileDescriptor, layer: usize, number: usize, buf: &[u8]) -> Result<usize> {
109+
let layer = SocketOptionLevel::from_usize(layer).ok_or(SyscallError::EINVAL)?;
110+
111+
match layer {
112+
SocketOptionLevel::Socket => {
113+
unimplemented!(
114+
"setsockopt(fd={:?}, layer={:?}, number={:?}, buf={:?})",
115+
fd,
116+
layer,
117+
number,
118+
buf
119+
)
120+
}
121+
122+
_ => todo!(),
123+
}
124+
125+
Ok(0)
126+
}
127+
103128
/// Marks the socket as a passive socket (i.e. as a socket that will be used to accept incoming
104129
/// connection requests).
105130
#[syscall]
106-
pub fn listen(fd: usize, backlog: usize) -> Result<usize> {
107-
let file = scheduler::get_scheduler()
108-
.current_task()
109-
.file_table
110-
.get_handle(fd)
111-
.ok_or(SyscallError::EINVAL)?;
112-
113-
file.inode().listen(backlog)?;
131+
pub fn listen(fd: FileDescriptor, backlog: usize) -> Result<usize> {
132+
fd.handle()?.inode().listen(backlog)?;
114133
Ok(0)
115134
}
116135

src/aero_kernel/src/unwind.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,13 @@ pub fn unwind_stack_trace() {
169169
}
170170
}
171171

172-
let thread = scheduler::current_thread();
173-
let tags = thread.mem_tags.lock();
174-
let mut tags = tags.iter().collect::<alloc::vec::Vec<_>>();
175-
tags.sort_by(|x, y| x.0.start.cmp(&y.0.start));
176-
for (x, s) in tags.iter() {
177-
log::trace!("{:#x}..{:#x} {s}", x.start, x.end);
178-
}
172+
// let thread = scheduler::current_thread();
173+
// let tags = thread.mem_tags.lock();
174+
// let mut tags = tags.iter().collect::<alloc::vec::Vec<_>>();
175+
// tags.sort_by(|x, y| x.0.start.cmp(&y.0.start));
176+
// for (x, s) in tags.iter() {
177+
// log::trace!("{:#x}..{:#x} {s}", x.start, x.end);
178+
// }
179179
}
180180

181181
#[cfg(feature = "ci")]

src/aero_kernel/src/userland/vm.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ pub struct LoadedBinary<'header> {
319319
pub envv: Option<ExecArgs>,
320320
}
321321

322-
#[derive(Clone)]
322+
#[derive(Debug, Clone)]
323323
pub struct MMapFile {
324324
offset: usize,
325325
file: DirCacheItem,
@@ -333,7 +333,7 @@ impl MMapFile {
333333
}
334334
}
335335

336-
#[derive(Clone)]
336+
#[derive(Debug, Clone)]
337337
struct Mapping {
338338
protection: MMapProt,
339339
flags: MMapFlags,
@@ -584,8 +584,7 @@ impl Mapping {
584584
refresh_flags: true,
585585
};
586586

587-
self.end_addr = end;
588-
587+
self.end_addr = start;
589588
Ok(UnmapResult::Partial(new_mapping))
590589
} else if start <= self.start_addr && end >= self.end_addr {
591590
// We are unmapping the whole region.
@@ -610,7 +609,7 @@ impl Mapping {
610609

611610
// Update the end address of the mapping since we have unmapped the
612611
// last chunk of the mapping.
613-
self.end_addr = end;
612+
self.end_addr = start;
614613
Ok(UnmapResult::End)
615614
}
616615
}

src/aero_syscall/src/consts.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ pub const SYS_SOCK_SHUTDOWN: usize = 75;
9999
pub const SYS_GETPEERNAME: usize = 76;
100100
pub const SYS_GETSOCKNAME: usize = 77;
101101
pub const SYS_DEBUG: usize = 78;
102+
pub const SYS_SETSOCKOPT: usize = 79;
103+
pub const SYS_GETSOCKOPT: usize = 80;
102104

103105
// constants for fcntl()'s command argument:
104106
pub const F_DUPFD: usize = 1;

src/aero_syscall/src/socket.rs

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,31 @@
1+
#![allow(non_camel_case_types)]
2+
13
use crate::SocketAddr;
24

5+
mod c {
6+
// This should be bindgened.
7+
pub type socklen_t = u32;
8+
9+
pub const SCM_RIGHTS: i32 = 1;
10+
pub const SCM_CREDENTIALS: i32 = 2;
11+
12+
pub const SOL_SOCKET: i32 = 1;
13+
pub const SOL_IPV6: i32 = 41;
14+
pub const SOL_PACKET: i32 = 263;
15+
pub const SOL_NETLINK: i32 = 270;
16+
}
17+
318
bitflags::bitflags! {
419
// mlibc/abis/mlibc/socket.h
520
pub struct MessageFlags: usize {
21+
/// Indicates that some control data was discarded due to lack of space in the
22+
/// buffer for ancillary data.
623
const CTRUNC = 0x1;
724
const DONTROUTE = 0x2;
825
const EOR = 0x4;
926
const OOB = 0x8;
27+
/// Requests not to send `SIGPIPE` on errors on stream oriented sockets when the
28+
/// other end breaks the connection. The `EPIPE` error is still returned.
1029
const NOSIGNAL = 0x10;
1130
const PEEK = 0x20;
1231
const TRUNC = 0x40;
@@ -29,13 +48,13 @@ pub struct MessageHeader {
2948
/// Pointer to the socket address structure.
3049
name: *mut u8,
3150
/// Size of the socket address structure.
32-
name_len: u32,
51+
name_len: c::socklen_t,
3352

3453
iovec: *mut IoVec, // todo: use Option<NonNull<IoVec>>
3554
iovec_len: i32, // todo: use ffi::c_int
3655

3756
control: *const u8,
38-
control_len: u32,
57+
control_len: c::socklen_t,
3958

4059
pub flags: i32, // todo: use ffi::c_int
4160
}
@@ -48,22 +67,21 @@ impl MessageHeader {
4867

4968
assert!(self.name_len >= core::mem::size_of::<T>() as u32);
5069

51-
// SAFETY: We know that the `name` pointer is valid and we have an exclusive reference to
52-
// it. The size of name is checked above with the size of `T` and `T` is a `SocketAddr` so,
53-
// its safe to create a mutable reference of `T` from the ptr.
5470
unsafe { Some(&mut *(self.name as *mut T)) }
5571
}
5672

5773
pub fn iovecs(&self) -> &[IoVec] {
58-
// SAFETY: We know that the `iovec` pointer is valid, initialized.
5974
unsafe { core::slice::from_raw_parts(self.iovec, self.iovec_len as usize) }
6075
}
6176

6277
pub fn iovecs_mut(&mut self) -> &mut [IoVec] {
63-
// SAFETY: We know that the `iovec` pointer is valid, initialized and we have exclusive
64-
// access so, its safe to construct a mutable slice from it.
6578
unsafe { core::slice::from_raw_parts_mut(self.iovec, self.iovec_len as usize) }
6679
}
80+
81+
pub fn control(&self) -> &[ControlMessage] {
82+
assert!(self.control_len == 0);
83+
&[]
84+
}
6785
}
6886

6987
// options/posix/include/bits/posix/iovec.h
@@ -91,3 +109,32 @@ impl IoVec {
91109
self.len
92110
}
93111
}
112+
113+
/// Control Message Header (`struct cmsghdr`).
114+
#[derive(Debug)]
115+
#[repr(C)]
116+
pub struct ControlMessage {
117+
/// Data byte count, including the header.
118+
pub cmsg_len: c::socklen_t,
119+
/// Originating protocol.
120+
pub cmsg_level: SocketOptionLevel,
121+
/// Protocol-specific type.
122+
pub cmsg_type: ControlMessageType,
123+
// followed by cmsg_data: [u8; cmsg_len - sizeof(struct cmsghdr)]
124+
}
125+
126+
#[derive(Debug, Copy, Clone, PartialEq)]
127+
#[repr(i32)]
128+
pub enum ControlMessageType {
129+
Rights = c::SCM_RIGHTS,
130+
Credentials = c::SCM_CREDENTIALS,
131+
}
132+
133+
#[derive(Debug, Copy, Clone, PartialEq, FromPrimitive)]
134+
#[repr(i32)]
135+
pub enum SocketOptionLevel {
136+
Socket = c::SOL_SOCKET,
137+
Ipv6 = c::SOL_IPV6,
138+
Packet = c::SOL_PACKET,
139+
Netlink = c::SOL_NETLINK,
140+
}

tools/mkimage.sh

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,27 @@
33
set -x -e
44

55
ANSI_CLEAR="\033[0m"
6-
ANSI_YELLOW="\033[1;34m"
6+
ANSI_RED="\033[1;31m"
7+
ANSI_BOLD="\033[1m"
78

89
function warn() {
9-
echo -e "${ANSI_YELLOW}$1${ANSI_CLEAR}"
10+
echo -e "${ANSI_RED}error${ANSI_CLEAR}: ${ANSI_BOLD}$1${ANSI_CLEAR}"
1011
}
1112

12-
# check if the pkg-build directory is not newer than the system-root
13-
if [[ ./sysroot/pkg-build -nt ./sysroot/system-root]]; then
14-
warn "mkimage: pkg-build is newer than system-root, run `xbstrap install --all`"
13+
function newest_file() {
14+
local latest file
15+
for file; do
16+
[[ $file && $file -nt $latest ]] || latest=$file
17+
done
18+
}
19+
20+
function has_newer_files_than() {
21+
[[ "$(newest_file "$1"/*)" -nt "$(newest_file "$2" "$2"/*)" ]]
22+
}
23+
24+
# check if the packages directory is not newer than the system-root
25+
if has_newer_files_than "./sysroot/packages" "./system/system-root"; then
26+
warn "\`./sysroot/packages\` is newer than \`./sysroot/system-root\`, run \`xbstrap install --all\`"
1527
exit 1
1628
fi
1729

0 commit comments

Comments
 (0)