From fce95f58dc360dbf6799f298b97a3f80303fae57 Mon Sep 17 00:00:00 2001 From: tompro Date: Sun, 18 Feb 2024 15:55:04 +0100 Subject: [PATCH 01/25] initial --- src/kernel/src/rtld/mod.rs | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/kernel/src/rtld/mod.rs b/src/kernel/src/rtld/mod.rs index 9ed800cc5..9095b1419 100644 --- a/src/kernel/src/rtld/mod.rs +++ b/src/kernel/src/rtld/mod.rs @@ -148,6 +148,7 @@ impl RuntimeLinker { sys.register(591, &ld, Self::sys_dynlib_dlsym); sys.register(592, &ld, Self::sys_dynlib_get_list); + sys.register(608, &ld, Self::sys_dynlib_get_info); sys.register(594, &ld, Self::sys_dynlib_load_prx); sys.register(596, &ld, Self::sys_dynlib_do_copy_relocations); sys.register(598, &ld, Self::sys_dynlib_get_proc_param); @@ -449,6 +450,25 @@ impl RuntimeLinker { Ok(SysOut::ZERO) } + fn sys_dynlib_get_info(self: &Arc, i: &SysIn) -> Result { + let arg1: usize = i.args[1].into(); + let info: *mut DynlibInfo = i.args[2].into(); + + if self.app.file_info().is_none() { + return Err(SysErr::Raw(EPERM)); + } + + if unsafe { (*info).size } != size_of::() { + return Err(SysErr::Raw(EINVAL)); + } + + let info = unsafe { &mut *info }; + + *info = unsafe { zeroed() }; + + todo!() + } + fn sys_dynlib_load_prx(self: &Arc, i: &SysIn) -> Result { // Check if application is a dynamic SELF. let td = VThread::current().unwrap(); @@ -887,9 +907,8 @@ impl RuntimeLinker { } // Check buffer size. - let size: usize = unsafe { (*info).size.try_into().unwrap() }; - if size != size_of::() { + if unsafe { (*info).size } != size_of::() { return Err(SysErr::Raw(EINVAL)); } @@ -1026,9 +1045,16 @@ impl RuntimeLinker { } } +#[repr(C)] +struct DynlibInfo { + size: usize, +} + +const _: () = assert!(size_of::() == 0x160); + #[repr(C)] struct DynlibInfoEx { - size: u64, + size: usize, name: [u8; 256], handle: u32, tlsindex: u32, @@ -1056,6 +1082,8 @@ struct DynlibInfoEx { refcount: u32, } +const _: () = assert!(size_of::() == 0x1a8); + /// Contains how TLS was allocated so far. #[derive(Debug)] pub struct TlsAlloc { From b9bef9a0af8c39a3d4d7437debf8117105fbeed2 Mon Sep 17 00:00:00 2001 From: tompro Date: Sun, 18 Feb 2024 20:19:56 +0100 Subject: [PATCH 02/25] initial implementation of sys_dynlib_get_info --- src/elf/src/info.rs | 12 +++++- src/kernel/src/rtld/mem.rs | 4 +- src/kernel/src/rtld/mod.rs | 78 ++++++++++++++++++++++++++++------- src/kernel/src/rtld/module.rs | 13 +++--- 4 files changed, 83 insertions(+), 24 deletions(-) diff --git a/src/elf/src/info.rs b/src/elf/src/info.rs index b677bc7e9..66e64af2d 100644 --- a/src/elf/src/info.rs +++ b/src/elf/src/info.rs @@ -279,7 +279,7 @@ impl FileInfo { let id = LE::read_u16(&data[6..]); // Lookup name. - let name = match self.read_str(name.try_into().unwrap()) { + let name = match self.read_str(name as usize) { Ok(v) => v.to_owned(), Err(e) => return Err(ReadModuleError::InvalidNameOffset(name, e)), }; @@ -316,7 +316,9 @@ impl FileInfo { }; // Get Rust string. - std::str::from_utf8(raw).map_err(|_| StringTableError::NotUtf8) + let string = std::str::from_utf8(raw)?; + + Ok(string) } } @@ -419,3 +421,9 @@ pub enum StringTableError { #[error("the offset is not a UTF-8 string")] NotUtf8, } + +impl From for StringTableError { + fn from(_: std::str::Utf8Error) -> Self { + Self::NotUtf8 + } +} diff --git a/src/kernel/src/rtld/mem.rs b/src/kernel/src/rtld/mem.rs index a294835e4..740ad7d30 100644 --- a/src/kernel/src/rtld/mem.rs +++ b/src/kernel/src/rtld/mem.rs @@ -59,10 +59,8 @@ impl Memory { } } ProgramType::PT_SCE_RELRO => { - if relro.is_some() { + if relro.replace(segments.len()).is_some() { return Err(MapError::MultipleRelroProgram); - } else { - relro = Some(segments.len()); } } _ => continue, diff --git a/src/kernel/src/rtld/mod.rs b/src/kernel/src/rtld/mod.rs index 9095b1419..da3c57842 100644 --- a/src/kernel/src/rtld/mod.rs +++ b/src/kernel/src/rtld/mod.rs @@ -451,22 +451,60 @@ impl RuntimeLinker { } fn sys_dynlib_get_info(self: &Arc, i: &SysIn) -> Result { - let arg1: usize = i.args[1].into(); - let info: *mut DynlibInfo = i.args[2].into(); + let handle: u32 = i.args[0].try_into().unwrap(); + let info = { + let info: *mut DynlibInfo = i.args[2].into(); + + unsafe { &mut *info } + }; if self.app.file_info().is_none() { return Err(SysErr::Raw(EPERM)); } - if unsafe { (*info).size } != size_of::() { + if info.size != size_of::() { return Err(SysErr::Raw(EINVAL)); } - let info = unsafe { &mut *info }; + *info = self.dynlib_get_info(handle, true)?; - *info = unsafe { zeroed() }; + Ok(SysOut::ZERO) + } + + fn dynlib_get_info(&self, handle: u32, unk: bool) -> Result { + let mut info: DynlibInfo = unsafe { zeroed() }; + + let modules = self.list.read(); + + let md = modules + .iter() + .find(|m| m.id() == handle) + .ok_or(SysErr::Raw(ESRCH))?; + + if unk && todo!() { + return Err(SysErr::Raw(EPERM)); + } + + let name = md.path().file_name().unwrap(); + + let mem = md.memory(); + let addr = mem.addr(); + + info.name[..name.len()].copy_from_slice(name.as_bytes()); + info.name[0xff] = 0; + info.segment_count = 2; + info.mapbase = mem.base(); + info.textsize = mem.text_segment().len().try_into().unwrap(); + info.unk1 = 5; + info.database = addr + mem.data_segment().start(); + info.datasize = mem.data_segment().len().try_into().unwrap(); + info.unk2 = 3; + + //TODO: set unk4 and segment_count + + info.fingerprint = md.fingerprint(); - todo!() + Ok(info) } fn sys_dynlib_load_prx(self: &Arc, i: &SysIn) -> Result { @@ -914,10 +952,10 @@ impl RuntimeLinker { // Lookup the module. let modules = self.list.read(); - let md = match modules.iter().find(|m| m.id() == handle) { - Some(v) => v, - None => return Err(SysErr::Raw(ESRCH)), - }; + let md = modules + .iter() + .find(|m| m.id() == handle) + .ok_or(SysErr::Raw(ESRCH))?; // Fill the info. let info = unsafe { &mut *info }; @@ -932,7 +970,7 @@ impl RuntimeLinker { info.database = addr + mem.data_segment().start(); info.datasize = mem.data_segment().len().try_into().unwrap(); info.unk4 = 3; - info.unk6 = 2; + info.segment_count = 2; info.refcount = Arc::strong_count(md).try_into().unwrap(); // Copy module name. @@ -1048,6 +1086,18 @@ impl RuntimeLinker { #[repr(C)] struct DynlibInfo { size: usize, + name: [u8; 256], + mapbase: usize, + textsize: u32, + unk1: u32, // always 5 + database: usize, + datasize: u32, + unk2: u32, // always 3 + unk3: [u8; 0xc], // always zeroes + unk4: u32, + unk5: [u8; 0x10], // always zeroes + segment_count: u32, // always 2 + fingerprint: [u8; 0x14], } const _: () = assert!(size_of::() == 0x160); @@ -1076,9 +1126,9 @@ struct DynlibInfoEx { unk3: u32, // Always 5. database: usize, datasize: u32, - unk4: u32, // Always 3. - unk5: [u8; 0x20], // Always zeroes. - unk6: u32, // Always 2. + unk4: u32, // Always 3. + unk5: [u8; 0x20], // Always zeroes. + segment_count: u32, // Always 2. refcount: u32, } diff --git a/src/kernel/src/rtld/module.rs b/src/kernel/src/rtld/module.rs index 82bf99260..1cc2377f3 100644 --- a/src/kernel/src/rtld/module.rs +++ b/src/kernel/src/rtld/module.rs @@ -39,6 +39,7 @@ pub struct Module { needed: Vec, modules: Vec, libraries: Vec, + fingerprint: [u8; 20], memory: Memory, relocated: Gutex>>>, file_info: Option, @@ -179,6 +180,7 @@ impl Module { needed: Vec::new(), modules: Vec::new(), libraries: Vec::new(), + fingerprint: [0; 20], memory, relocated: gg.spawn(Vec::new()), file_info: None, @@ -191,11 +193,7 @@ impl Module { if let Some(info) = file_info { module.digest_dynamic(base, &info)?; - module.relocated = gg.spawn( - std::iter::repeat_with(|| None) - .take(info.reloc_count() + info.plt_count()) - .collect(), - ); + module.relocated = gg.spawn(Vec::default()); module.file_info = Some(info); } @@ -282,6 +280,10 @@ impl Module { self.libraries.as_ref() } + pub fn fingerprint(&self) -> [u8; 20] { + self.fingerprint + } + pub fn memory(&self) -> &Memory { &self.memory } @@ -569,6 +571,7 @@ impl Module { DynamicTag::DT_SONAME => self.digest_soname(info, i, value)?, DynamicTag::DT_TEXTREL => *self.flags.get_mut() |= ModuleFlags::TEXT_REL, DynamicTag::DT_FLAGS => self.digest_flags(value)?, + DynamicTag::DT_SCE_FINGERPRINT => todo!(), DynamicTag::DT_SCE_MODULE_INFO | DynamicTag::DT_SCE_NEEDED_MODULE => { self.digest_module_info(info, i, value)?; } From de5cf92225902b45914d8d18c2a0bee31c96f110 Mon Sep 17 00:00:00 2001 From: tompro Date: Wed, 21 Feb 2024 20:15:18 +0100 Subject: [PATCH 03/25] fix syscall number --- src/kernel/src/rtld/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/src/rtld/mod.rs b/src/kernel/src/rtld/mod.rs index 75f2cffc4..5c995b409 100644 --- a/src/kernel/src/rtld/mod.rs +++ b/src/kernel/src/rtld/mod.rs @@ -149,7 +149,7 @@ impl RuntimeLinker { sys.register(591, &ld, Self::sys_dynlib_dlsym); sys.register(592, &ld, Self::sys_dynlib_get_list); - sys.register(608, &ld, Self::sys_dynlib_get_info); + sys.register(593, &ld, Self::sys_dynlib_get_info); sys.register(594, &ld, Self::sys_dynlib_load_prx); sys.register(596, &ld, Self::sys_dynlib_do_copy_relocations); sys.register(598, &ld, Self::sys_dynlib_get_proc_param); From 5836df8f3ed854eec8ebfa9bcda42a3506321a9a Mon Sep 17 00:00:00 2001 From: tompro Date: Fri, 23 Feb 2024 14:55:16 +0100 Subject: [PATCH 04/25] fingerprint --- src/elf/src/info.rs | 9 +++++++++ src/kernel/src/rtld/module.rs | 20 ++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/elf/src/info.rs b/src/elf/src/info.rs index 66e64af2d..8cb0a2074 100644 --- a/src/elf/src/info.rs +++ b/src/elf/src/info.rs @@ -301,6 +301,15 @@ impl FileInfo { Ok(LibraryInfo::new(id, name, LibraryFlags::empty())) } + pub fn read_fingerprint(&self, offset: usize) -> [u8; 20] { + let offset = offset + self.dynoff; + + let mut fingerprint = [0u8; 20]; + fingerprint.copy_from_slice(&self.data[offset..(offset + 20)]); + + fingerprint + } + pub fn read_str(&self, offset: usize) -> Result<&str, StringTableError> { // Get raw string. let tab = &self.data[self.strtab..(self.strtab + self.strsz)]; diff --git a/src/kernel/src/rtld/module.rs b/src/kernel/src/rtld/module.rs index 1cc2377f3..d73392a4e 100644 --- a/src/kernel/src/rtld/module.rs +++ b/src/kernel/src/rtld/module.rs @@ -193,7 +193,11 @@ impl Module { if let Some(info) = file_info { module.digest_dynamic(base, &info)?; - module.relocated = gg.spawn(Vec::default()); + module.relocated = gg.spawn( + std::iter::repeat_with(|| None) + .take(info.reloc_count() + info.plt_count()) + .collect(), + ); module.file_info = Some(info); } @@ -542,6 +546,8 @@ impl Module { /// See `digest_dynamic` on the PS4 for a reference. fn digest_dynamic(&mut self, base: usize, info: &FileInfo) -> Result<(), MapError> { // TODO: Implement the remaining tags. + let mut fingerprint_offset = None; + for (i, (tag, value)) in info.dynamic().enumerate() { match tag { DynamicTag::DT_NULL => break, @@ -571,7 +577,9 @@ impl Module { DynamicTag::DT_SONAME => self.digest_soname(info, i, value)?, DynamicTag::DT_TEXTREL => *self.flags.get_mut() |= ModuleFlags::TEXT_REL, DynamicTag::DT_FLAGS => self.digest_flags(value)?, - DynamicTag::DT_SCE_FINGERPRINT => todo!(), + DynamicTag::DT_SCE_FINGERPRINT => { + fingerprint_offset = Some(u64::from_le_bytes(value) as usize) + } DynamicTag::DT_SCE_MODULE_INFO | DynamicTag::DT_SCE_NEEDED_MODULE => { self.digest_module_info(info, i, value)?; } @@ -582,6 +590,8 @@ impl Module { } } + self.digest_fingerprint(info, fingerprint_offset.unwrap_or(0)); + Ok(()) } @@ -638,6 +648,12 @@ impl Module { Ok(()) } + fn digest_fingerprint(&mut self, info: &FileInfo, offset: usize) { + let fingerprint = info.read_fingerprint(offset); + + self.fingerprint = fingerprint; + } + fn digest_module_info( &mut self, info: &FileInfo, From 95085f1cd92f0ee1933e4b34c19352dd7cc2d9da Mon Sep 17 00:00:00 2001 From: tompro Date: Sat, 24 Feb 2024 17:20:50 +0100 Subject: [PATCH 05/25] segment info --- src/elf/src/lib.rs | 4 ++ src/kernel/src/rtld/mem.rs | 8 ++- src/kernel/src/rtld/mod.rs | 100 ++++++++++++++++++++++--------------- 3 files changed, 70 insertions(+), 42 deletions(-) diff --git a/src/elf/src/lib.rs b/src/elf/src/lib.rs index 675afc903..f64061cde 100644 --- a/src/elf/src/lib.rs +++ b/src/elf/src/lib.rs @@ -336,6 +336,10 @@ impl Elf { self.programs.as_slice() } + pub fn relro(&self) -> Option { + self.relro + } + pub fn dynamic(&self) -> Option { self.dynamic } diff --git a/src/kernel/src/rtld/mem.rs b/src/kernel/src/rtld/mem.rs index 740ad7d30..b85f9053b 100644 --- a/src/kernel/src/rtld/mem.rs +++ b/src/kernel/src/rtld/mem.rs @@ -18,6 +18,7 @@ pub struct Memory { base: usize, text: usize, data: usize, + relro: Option, obcode: usize, obcode_sealed: Gutex, obdata: usize, @@ -128,7 +129,7 @@ impl Memory { len += segment.len; segments.push(segment); - // Create workspace for our data. We cannot mix this the code because the executable-space + // Create workspace for our data. We cannot mix this with the code because the executable-space // protection on some system don't allow execution on writable page. let obdata = segments.len(); let segment = MemorySegment { @@ -176,6 +177,7 @@ impl Memory { base, text, data, + relro, obcode, obcode_sealed: gg.spawn(0), obdata, @@ -208,6 +210,10 @@ impl Memory { &self.segments[self.data] } + pub fn relro_segment(&self) -> Option<&MemorySegment> { + self.relro.as_ref().map(|i| &self.segments[*i]) + } + /// # Safety /// Some part of the returned slice may not readable. pub unsafe fn as_bytes(&self) -> &[u8] { diff --git a/src/kernel/src/rtld/mod.rs b/src/kernel/src/rtld/mod.rs index 256fe4b2a..6783b39ed 100644 --- a/src/kernel/src/rtld/mod.rs +++ b/src/kernel/src/rtld/mod.rs @@ -452,9 +452,9 @@ impl RuntimeLinker { fn sys_dynlib_get_info(self: &Arc, _: &VThread, i: &SysIn) -> Result { let handle: u32 = i.args[0].try_into().unwrap(); let info = { - let info: *mut DynlibInfo = i.args[2].into(); + let info_out: *mut DynlibInfo = i.args[2].into(); - unsafe { &mut *info } + unsafe { &mut *info_out } }; if self.app.file_info().is_none() { @@ -492,17 +492,37 @@ impl RuntimeLinker { info.name[..name.len()].copy_from_slice(name.as_bytes()); info.name[0xff] = 0; info.segment_count = 2; - info.mapbase = mem.base(); - info.textsize = mem.text_segment().len().try_into().unwrap(); - info.unk1 = 5; - info.database = addr + mem.data_segment().start(); - info.datasize = mem.data_segment().len().try_into().unwrap(); - info.unk2 = 3; - //TODO: set unk4 and segment_count + info.text_segment.addr = mem.base(); + info.text_segment.size = mem.text_segment().len().try_into().unwrap(); + info.text_segment.prot = 5; + + info.data_segment.addr = addr + mem.data_segment().start(); + info.data_segment.size = mem.data_segment().len().try_into().unwrap(); + info.data_segment.prot = 3; + + if let Some(seg) = mem.relro_segment() { + info.relro_segment.addr = addr + seg.start(); + info.relro_segment.size = seg.len().try_into().unwrap(); + info.relro_segment.prot = 1; + + info.segment_count += 1; + }; info.fingerprint = md.fingerprint(); + let mut e = info!(); + + writeln!( + e, + "Retrieved info for module {} (ID = {}).", + md.path(), + handle + ) + .unwrap(); + + writeln!(e, "{:#?}", info).unwrap(); + Ok(info) } @@ -972,6 +992,7 @@ impl RuntimeLinker { // Lookup the module. let modules = self.list.read(); + let md = modules .iter() .find(|m| m.id() == handle) @@ -984,12 +1005,15 @@ impl RuntimeLinker { *info = unsafe { zeroed() }; info.handle = md.id(); - info.mapbase = addr + mem.base(); - info.textsize = mem.text_segment().len().try_into().unwrap(); - info.unk3 = 5; - info.database = addr + mem.data_segment().start(); - info.datasize = mem.data_segment().len().try_into().unwrap(); - info.unk4 = 3; + + info.text_segment.addr = addr + mem.base(); + info.text_segment.size = mem.text_segment().len().try_into().unwrap(); + info.text_segment.prot = 5; + + info.data_segment.addr = addr + mem.data_segment().start(); + info.data_segment.size = mem.data_segment().len().try_into().unwrap(); + info.data_segment.prot = 3; + info.segment_count = 2; info.refcount = Arc::strong_count(md).try_into().unwrap(); @@ -1056,16 +1080,8 @@ impl RuntimeLinker { handle ) .unwrap(); - writeln!(e, "mapbase : {:#x}", info.mapbase).unwrap(); - writeln!(e, "textsize : {:#x}", info.textsize).unwrap(); - writeln!(e, "database : {:#x}", info.database).unwrap(); - writeln!(e, "datasize : {:#x}", info.datasize).unwrap(); - writeln!(e, "tlsindex : {}", info.tlsindex).unwrap(); - writeln!(e, "tlsinit : {:#x}", info.tlsinit).unwrap(); - writeln!(e, "tlsoffset : {:#x}", info.tlsoffset).unwrap(); - writeln!(e, "init : {:#x}", info.init).unwrap(); - writeln!(e, "fini : {:#x}", info.fini).unwrap(); - writeln!(e, "eh_frame_hdr: {:#x}", info.eh_frame_hdr).unwrap(); + + writeln!(e, "{:#?}", info).unwrap(); print(e); @@ -1107,25 +1123,30 @@ impl RuntimeLinker { } } +#[derive(Debug)] +#[repr(C)] +struct SegmentInfo { + addr: usize, + size: u32, + prot: u32, +} + +#[derive(Debug)] #[repr(C)] struct DynlibInfo { size: usize, name: [u8; 256], - mapbase: usize, - textsize: u32, - unk1: u32, // always 5 - database: usize, - datasize: u32, - unk2: u32, // always 3 - unk3: [u8; 0xc], // always zeroes - unk4: u32, - unk5: [u8; 0x10], // always zeroes + text_segment: SegmentInfo, + data_segment: SegmentInfo, + relro_segment: SegmentInfo, + unk_segment: SegmentInfo, segment_count: u32, // always 2 fingerprint: [u8; 0x14], } const _: () = assert!(size_of::() == 0x160); +#[derive(Debug)] #[repr(C)] struct DynlibInfoEx { size: usize, @@ -1145,13 +1166,10 @@ struct DynlibInfoEx { eh_frame: usize, eh_frame_hdr_size: u32, eh_frame_size: u32, - mapbase: usize, - textsize: u32, - unk3: u32, // Always 5. - database: usize, - datasize: u32, - unk4: u32, // Always 3. - unk5: [u8; 0x20], // Always zeroes. + text_segment: SegmentInfo, + data_segment: SegmentInfo, + relro_segment: SegmentInfo, + unk_segment: SegmentInfo, segment_count: u32, // Always 2. refcount: u32, } From ca212b3d8e5404c8e47563078fbd85be09eb7501 Mon Sep 17 00:00:00 2001 From: tompro Date: Sat, 24 Feb 2024 17:22:29 +0100 Subject: [PATCH 06/25] nfnrg --- src/kernel/src/rtld/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/src/rtld/mod.rs b/src/kernel/src/rtld/mod.rs index 6783b39ed..25a46caaf 100644 --- a/src/kernel/src/rtld/mod.rs +++ b/src/kernel/src/rtld/mod.rs @@ -1140,7 +1140,7 @@ struct DynlibInfo { data_segment: SegmentInfo, relro_segment: SegmentInfo, unk_segment: SegmentInfo, - segment_count: u32, // always 2 + segment_count: u32, fingerprint: [u8; 0x14], } From f5a8611bce99a3d67f1d6aad09becadf2514a360 Mon Sep 17 00:00:00 2001 From: tompro Date: Tue, 19 Mar 2024 14:48:50 +0100 Subject: [PATCH 07/25] fix --- src/kernel/src/rtld/mod.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/kernel/src/rtld/mod.rs b/src/kernel/src/rtld/mod.rs index a8bb56ebd..c71be84c4 100644 --- a/src/kernel/src/rtld/mod.rs +++ b/src/kernel/src/rtld/mod.rs @@ -465,7 +465,7 @@ impl RuntimeLinker { Ok(SysOut::ZERO) } - fn sys_dynlib_get_info(self: &Arc, _: &VThread, i: &SysIn) -> Result { + fn sys_dynlib_get_info(self: &Arc, td: &VThread, i: &SysIn) -> Result { let handle: u32 = i.args[0].try_into().unwrap(); let info = { let info_out: *mut DynlibInfo = i.args[2].into(); @@ -473,7 +473,9 @@ impl RuntimeLinker { unsafe { &mut *info_out } }; - if self.app.file_info().is_none() { + let bin = td.proc().bin(); + + if bin.as_ref().map(|bin| bin.app().file_info()).is_none() { return Err(SysErr::Raw(EPERM)); } From 881f22c39d4e5e10aa6e64cc8280925d92ae42f9 Mon Sep 17 00:00:00 2001 From: tompro Date: Tue, 19 Mar 2024 14:49:12 +0100 Subject: [PATCH 08/25] add syscall back --- src/kernel/src/rtld/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kernel/src/rtld/mod.rs b/src/kernel/src/rtld/mod.rs index c71be84c4..b7e9fed19 100644 --- a/src/kernel/src/rtld/mod.rs +++ b/src/kernel/src/rtld/mod.rs @@ -79,6 +79,7 @@ impl RuntimeLinker { sys.register(591, &ld, Self::sys_dynlib_dlsym); sys.register(592, &ld, Self::sys_dynlib_get_list); + sys.register(593, &ld, Self::sys_dynlib_get_info); sys.register(594, &ld, Self::sys_dynlib_load_prx); sys.register(596, &ld, Self::sys_dynlib_do_copy_relocations); sys.register(598, &ld, Self::sys_dynlib_get_proc_param); From 0ee03e9092b6fc8aaa211a0fc645b48ff810d00e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Tue, 2 Apr 2024 22:19:46 +0200 Subject: [PATCH 09/25] fix --- src/kernel/src/rtld/mod.rs | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/kernel/src/rtld/mod.rs b/src/kernel/src/rtld/mod.rs index c6453221e..505e5ca1c 100644 --- a/src/kernel/src/rtld/mod.rs +++ b/src/kernel/src/rtld/mod.rs @@ -461,26 +461,31 @@ impl RuntimeLinker { let bin = td.proc().bin(); - if bin.as_ref().map(|bin| bin.app().file_info()).is_none() { - return Err(SysErr::Raw(EPERM)); - } + let bin = match bin.as_ref() { + Some(bin) if bin.app().file_info().is_some() => bin, + _ => return Err(SysErr::Raw(EPERM)), + }; if info.size != size_of::() { return Err(SysErr::Raw(EINVAL)); } - *info = self.dynlib_get_info(handle, true)?; + *info = self.dynlib_get_info(handle, true, bin)?; Ok(SysOut::ZERO) } - fn dynlib_get_info(&self, handle: u32, unk: bool) -> Result { + fn dynlib_get_info( + &self, + handle: u32, + unk: bool, + bin: &Binaries, + ) -> Result { let mut info: DynlibInfo = unsafe { zeroed() }; - let modules = self.list.read(); + let mut modules = bin.list(); let md = modules - .iter() .find(|m| m.id() == handle) .ok_or(SysErr::Raw(ESRCH))?; @@ -525,10 +530,14 @@ impl RuntimeLinker { ) .unwrap(); - writeln!(e, "{:#?}", info).unwrap(); + writeln!(e, "mapbase : {:#x}", info.text_segment.addr).unwrap(); + writeln!(e, "textsize: {:#x}", info.text_segment.size).unwrap(); + writeln!(e, "database: {:#x}", info.data_segment.addr).unwrap(); + writeln!(e, "datasize: {:#x}", info.data_segment.size).unwrap(); + + print(e); Ok(info) - } fn sys_dynlib_load_prx(self: &Arc, td: &VThread, i: &SysIn) -> Result { @@ -1071,7 +1080,16 @@ impl RuntimeLinker { ) .unwrap(); - writeln!(e, "{:#?}", info).unwrap(); + writeln!(e, "mapbase : {:#x}", info.text_segment.addr).unwrap(); + writeln!(e, "textsize : {:#x}", info.text_segment.size).unwrap(); + writeln!(e, "database : {:#x}", info.data_segment.addr).unwrap(); + writeln!(e, "datasize : {:#x}", info.data_segment.size).unwrap(); + writeln!(e, "tlsindex : {}", info.tlsindex).unwrap(); + writeln!(e, "tlsinit : {:#x}", info.tlsinit).unwrap(); + writeln!(e, "tlsoffset : {:#x}", info.tlsoffset).unwrap(); + writeln!(e, "init : {:#x}", info.init).unwrap(); + writeln!(e, "fini : {:#x}", info.fini).unwrap(); + writeln!(e, "eh_frame_hdr: {:#x}", info.eh_frame_hdr).unwrap(); print(e); From 6a974e7e11863b80cbe93ed9a1d07b3afbffc0d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Tue, 2 Apr 2024 23:14:47 +0200 Subject: [PATCH 10/25] comment --- src/kernel/src/rtld/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/src/rtld/mod.rs b/src/kernel/src/rtld/mod.rs index 505e5ca1c..4b09551b9 100644 --- a/src/kernel/src/rtld/mod.rs +++ b/src/kernel/src/rtld/mod.rs @@ -1074,7 +1074,7 @@ impl RuntimeLinker { writeln!( e, - "Retrieved info for module {} (ID = {}).", + "Retrieved info_ex for module {} (ID = {}).", md.path(), handle ) From d37ae51cfa0b3dfbd6f4c1fade97101189e4adb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Wed, 3 Apr 2024 00:40:07 +0200 Subject: [PATCH 11/25] fix + log --- src/kernel/src/rtld/mod.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/kernel/src/rtld/mod.rs b/src/kernel/src/rtld/mod.rs index 4b09551b9..c2ef5fc25 100644 --- a/src/kernel/src/rtld/mod.rs +++ b/src/kernel/src/rtld/mod.rs @@ -454,11 +454,13 @@ impl RuntimeLinker { fn sys_dynlib_get_info(self: &Arc, td: &VThread, i: &SysIn) -> Result { let handle: u32 = i.args[0].try_into().unwrap(); let info = { - let info_out: *mut DynlibInfo = i.args[2].into(); + let info_out: *mut DynlibInfo = i.args[1].into(); unsafe { &mut *info_out } }; + info!("Getting info for module id = {}.", handle); + let bin = td.proc().bin(); let bin = match bin.as_ref() { @@ -470,7 +472,7 @@ impl RuntimeLinker { return Err(SysErr::Raw(EINVAL)); } - *info = self.dynlib_get_info(handle, true, bin)?; + *info = self.dynlib_get_info(handle, bin, true)?; Ok(SysOut::ZERO) } @@ -478,8 +480,8 @@ impl RuntimeLinker { fn dynlib_get_info( &self, handle: u32, - unk: bool, bin: &Binaries, + unk: bool, ) -> Result { let mut info: DynlibInfo = unsafe { zeroed() }; @@ -977,6 +979,8 @@ impl RuntimeLinker { let flags: u32 = i.args[1].try_into().unwrap(); let info: *mut DynlibInfoEx = i.args[2].into(); + info!("Getting info_ex for module id = {}.", handle); + // Check if application is dynamic linking. let bin = td.proc().bin(); let bin = bin.as_ref().ok_or(SysErr::Raw(EPERM))?; From 2560c555235f88e4a4af7dbc1effa3a588d7a50d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Wed, 3 Apr 2024 01:21:59 +0200 Subject: [PATCH 12/25] Finalize --- src/kernel/src/rtld/mod.rs | 16 ++++++++-------- src/kernel/src/rtld/module.rs | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/kernel/src/rtld/mod.rs b/src/kernel/src/rtld/mod.rs index c2ef5fc25..fd924f702 100644 --- a/src/kernel/src/rtld/mod.rs +++ b/src/kernel/src/rtld/mod.rs @@ -129,7 +129,7 @@ impl RuntimeLinker { ) .map_err(ExecError::MapFailed)?; - *app.flags_mut() |= ModuleFlags::MAIN_PROG; + *app.flags_mut() |= ModuleFlags::MAINPROG; self.ee .setup_module(&mut app) @@ -270,7 +270,7 @@ impl RuntimeLinker { // TODO: Check the call to sceSblAuthMgrIsLoadable in the self_load_shared_object on the PS4 // to see how it is return the value. if name != "libc.sprx" && name != "libSceFios2.sprx" { - *md.flags_mut() |= ModuleFlags::UNK1; + *md.flags_mut() |= ModuleFlags::IS_SYSTEM; } if let Err(e) = self.ee.setup_module(&mut md) { @@ -335,7 +335,7 @@ impl RuntimeLinker { // Resolve. let dags = md.dag_static(); - let sym = if md.flags().intersects(ModuleFlags::MAIN_PROG) { + let sym = if md.flags().intersects(ModuleFlags::MAINPROG) { todo!("do_dlsym on MAIN_PROG"); } else { resolver.resolve_from_list( @@ -481,7 +481,7 @@ impl RuntimeLinker { &self, handle: u32, bin: &Binaries, - unk: bool, + no_system: bool, ) -> Result { let mut info: DynlibInfo = unsafe { zeroed() }; @@ -491,7 +491,7 @@ impl RuntimeLinker { .find(|m| m.id() == handle) .ok_or(SysErr::Raw(ESRCH))?; - if unk && todo!() { + if no_system && md.flags().intersects(ModuleFlags::IS_SYSTEM) { return Err(SysErr::Raw(EPERM)); } @@ -1021,7 +1021,7 @@ impl RuntimeLinker { info.refcount = *md.ref_count(); // Copy module name. - if flags & 2 == 0 || !md.flags().contains(ModuleFlags::UNK1) { + if flags & 2 == 0 || !md.flags().contains(ModuleFlags::IS_SYSTEM) { let name = md.path().file_name().unwrap(); info.name[..name.len()].copy_from_slice(name.as_bytes()); @@ -1032,13 +1032,13 @@ impl RuntimeLinker { // Let's keep the same behavior as the PS4 for now. info.tlsindex = if flags & 1 != 0 { let flags = md.flags(); - let mut upper = if flags.contains(ModuleFlags::UNK1) { + let mut upper = if flags.contains(ModuleFlags::IS_SYSTEM) { 1 } else { 0 }; - if flags.contains(ModuleFlags::MAIN_PROG) { + if flags.contains(ModuleFlags::MAINPROG) { upper += 2; } diff --git a/src/kernel/src/rtld/module.rs b/src/kernel/src/rtld/module.rs index 1aeb040cd..08f3f46aa 100644 --- a/src/kernel/src/rtld/module.rs +++ b/src/kernel/src/rtld/module.rs @@ -758,14 +758,14 @@ bitflags! { /// Flags for [`Module`]. #[derive(Debug, Clone, Copy, PartialEq)] pub struct ModuleFlags: u16 { - const MAIN_PROG = 0x0001; + const MAINPROG = 0x0001; const TEXT_REL = 0x0002; const JMPSLOTS_DONE = 0x0004; // TODO: This seems incorrect. const TLS_DONE = 0x0008; const INIT_SCANNED = 0x0010; const ON_FINI_LIST = 0x0020; const DAG_INITED = 0x0040; - const UNK1 = 0x0100; // TODO: Rename this. + const IS_SYSTEM = 0x0100; // TODO: Rename this. const UNK2 = 0x0200; // TODO: Rename this. const UNK3 = 0x0400; // TODO: Rename this. const UNK4 = 0x0800; // TODO: It seems like this is actually JMPSLOTS_DONE. From 0577b4d49b5697cdaebc5425d52df0a2b54fc13d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Thu, 4 Apr 2024 14:03:17 +0200 Subject: [PATCH 13/25] Implement get proc type info checks --- src/kernel/src/budget/mod.rs | 10 +++++++++ src/kernel/src/process/mod.rs | 2 +- src/kernel/src/ucred/auth.rs | 24 ++++++++++---------- src/kernel/src/ucred/mod.rs | 41 +++++++++++++++++++++++++++++------ 4 files changed, 58 insertions(+), 19 deletions(-) diff --git a/src/kernel/src/budget/mod.rs b/src/kernel/src/budget/mod.rs index 924755333..449f17fb4 100644 --- a/src/kernel/src/budget/mod.rs +++ b/src/kernel/src/budget/mod.rs @@ -90,3 +90,13 @@ pub enum ProcType { MiniApp, System, // TODO: Verify this. } + +impl Into for ProcType { + fn into(self) -> u32 { + match self { + ProcType::BigApp => 0, + ProcType::MiniApp => 1, + ProcType::System => 2, + } + } +} diff --git a/src/kernel/src/process/mod.rs b/src/kernel/src/process/mod.rs index cb172d505..2b4b12be5 100644 --- a/src/kernel/src/process/mod.rs +++ b/src/kernel/src/process/mod.rs @@ -783,7 +783,7 @@ impl VProc { ProcTypeInfo { len: size_of::(), - ty: self.budget_ptype as u32, + ty: self.budget_ptype.into(), flags, } } diff --git a/src/kernel/src/ucred/auth.rs b/src/kernel/src/ucred/auth.rs index 4fb7c525f..b757986ce 100644 --- a/src/kernel/src/ucred/auth.rs +++ b/src/kernel/src/ucred/auth.rs @@ -72,7 +72,7 @@ impl AuthPaid { /// A wrapper type for `caps` field of [`AuthInfo`]. #[repr(transparent)] #[derive(Debug, Clone)] -pub struct AuthCaps([u64; 4]); +pub struct AuthCaps(pub(super) [u64; 4]); impl AuthCaps { pub fn new(raw: [u64; 4]) -> Self { @@ -87,14 +87,6 @@ impl AuthCaps { (self.0[0] & 0x2000000000000000) != 0 } - pub fn is_jit_compiler_process(&self) -> bool { - todo!() - } - - pub fn is_jit_application_process(&self) -> bool { - todo!() - } - pub fn has_use_video_service_capability(&self) -> bool { self.0[0] >> 0x39 & 1 != 0 } @@ -126,11 +118,21 @@ impl AuthAttrs { } pub fn has_sce_program_attribute(&self) -> bool { - todo!() + (self.0[0] & 0x80000000) != 0 } pub fn is_debuggable_process(&self) -> bool { - todo!() + if self.0[0] & 0x1000000 == 0 { + if self.0[0] & 0x2000000 != 0 { + true + } else if todo!() { + true + } else { + todo!() + } + } else { + todo!() + } } pub fn is_unk1(&self) -> bool { diff --git a/src/kernel/src/ucred/mod.rs b/src/kernel/src/ucred/mod.rs index ac81a087c..026286362 100644 --- a/src/kernel/src/ucred/mod.rs +++ b/src/kernel/src/ucred/mod.rs @@ -59,8 +59,8 @@ impl Ucred { pub fn is_unknown1(&self) -> bool { // TODO: Refactor this for readability. - let id = self.auth.paid.get().wrapping_add(0xc7ffffffeffffffc); - (id < 0xf) && ((0x6001 >> (id & 0x3f) & 1) != 0) + let val = self.auth.paid.get().wrapping_add(0xc7ffffffeffffffc); + (val < 0xf) && ((0x6001 >> (val & 0x3f) & 1) != 0) } pub fn is_unknown2(&self) -> bool { @@ -77,12 +77,36 @@ impl Ucred { /// See `sceSblACMgrIsJitCompilerProcess` on the PS4 for a reference. pub fn is_jit_compiler_process(&self) -> bool { - self.auth.caps.is_jit_compiler_process() + let val = self.auth.caps.0[1]; + + if val >> 0x3e & 1 == 0 { + if val >> 0x38 & 1 != 0 && !todo!() { + true + } else if (self.auth.paid.get() >> 56) == 0x31 && !todo!() { + true + } else { + false + } + } else { + true + } } - /// See `sceSblACMgrIsJitCompilerProcess` on the PS4 for a reference. + /// See `sceSblACMgrIsJitApplicationProcess` on the PS4 for a reference. pub fn is_jit_application_process(&self) -> bool { - self.auth.caps.is_jit_application_process() + let val = self.auth.caps.0[1]; + + if val >> 0x3d & 1 == 0 { + if val >> 0x38 & 1 != 0 && !todo!() { + true + } else if (self.auth.paid.get() >> 56) == 0x31 && !todo!() { + true + } else { + false + } + } else { + true + } } /// See `sceSblACMgrIsVideoplayerProcess` on the PS4 for a reference. @@ -97,14 +121,17 @@ impl Ucred { /// See `sceSblACMgrIsWebcoreProcess` on the PS4 for a reference. pub fn is_webcore_process(&self) -> bool { - todo!() + let val = self.auth.paid.get().wrapping_add(0xc7ffffffeffffffd); + + (val < 0x11) && (0x1d003 >> (val & 0x3f) & 1 != 0) } + /// See `sceSblACMgrHasSceProgramAttribute` on the PS4 for a reference. pub fn has_sce_program_attribute(&self) -> bool { self.auth.attrs.has_sce_program_attribute() } - /// See `sceSblACMgrHasSceProgramAttribute` on the PS4 for a reference. + /// See `sceSblACMgrIsDebuggableProcess` on the PS4 for a reference. pub fn is_debuggable_process(&self) -> bool { self.auth.attrs.is_debuggable_process() } From 0b96ac3e007c0f563059ab253c7ad52534b84fdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Thu, 4 Apr 2024 14:13:12 +0200 Subject: [PATCH 14/25] remove copy and clone from privilege --- src/kernel/src/ucred/privilege.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/src/ucred/privilege.rs b/src/kernel/src/ucred/privilege.rs index 06e1cbc17..c5841651c 100644 --- a/src/kernel/src/ucred/privilege.rs +++ b/src/kernel/src/ucred/privilege.rs @@ -35,7 +35,7 @@ privileges! { /// See https://github.com/freebsd/freebsd-src/blob/release/9.1.0/sys/sys/priv.h for standard /// FreeBSD privileges. #[repr(i32)] - #[derive(Clone, Copy, PartialEq, Eq)] + #[derive(PartialEq, Eq)] pub enum Privilege { /// Exceed system open files limit. #[allow(unused)] From 529865e38a03a1f309979b03519a229e2e943111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Thu, 4 Apr 2024 14:13:37 +0200 Subject: [PATCH 15/25] add unused --- src/kernel/src/ucred/privilege.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kernel/src/ucred/privilege.rs b/src/kernel/src/ucred/privilege.rs index c5841651c..5916aad42 100644 --- a/src/kernel/src/ucred/privilege.rs +++ b/src/kernel/src/ucred/privilege.rs @@ -57,6 +57,7 @@ privileges! { /// Currently unknown. SCE683 = 683, /// Currently unknown. + #[allow(unused)] SCE685 = 685, /// Currently unknown. SCE686 = 686, From 6de4dd789cb76af4a36e6ba3dd3178caf77521ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Fri, 5 Apr 2024 13:47:31 +0200 Subject: [PATCH 16/25] checks fix --- src/kernel/src/regmgr/mod.rs | 2 +- src/kernel/src/ucred/auth.rs | 5 ++--- src/kernel/src/ucred/mod.rs | 4 ++-- src/kernel/src/vm/mod.rs | 8 ++++---- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/kernel/src/regmgr/mod.rs b/src/kernel/src/regmgr/mod.rs index 4679837d4..ad2a95a93 100644 --- a/src/kernel/src/regmgr/mod.rs +++ b/src/kernel/src/regmgr/mod.rs @@ -132,7 +132,7 @@ impl RegMgr { // Lookup the entry. let key = RegKey::new(key); let entry = self.lookup(key).ok_or(RegError::NotFound(key))?; - let web = if cred.is_webcore_process() || cred.is_diskplayerui_process() { + let web = if cred.is_libkernel_web() || cred.is_webprocess_webapp_or_webmas() { 1 } else { 0 diff --git a/src/kernel/src/ucred/auth.rs b/src/kernel/src/ucred/auth.rs index b757986ce..f47b4c918 100644 --- a/src/kernel/src/ucred/auth.rs +++ b/src/kernel/src/ucred/auth.rs @@ -125,10 +125,9 @@ impl AuthAttrs { if self.0[0] & 0x1000000 == 0 { if self.0[0] & 0x2000000 != 0 { true - } else if todo!() { - true } else { - todo!() + // TODO: properly implement this branch. + false } } else { todo!() diff --git a/src/kernel/src/ucred/mod.rs b/src/kernel/src/ucred/mod.rs index 026286362..343cbb012 100644 --- a/src/kernel/src/ucred/mod.rs +++ b/src/kernel/src/ucred/mod.rs @@ -57,13 +57,13 @@ impl Ucred { self.groups[1..].binary_search(&gid).is_ok() } - pub fn is_unknown1(&self) -> bool { + pub fn is_libkernel_web(&self) -> bool { // TODO: Refactor this for readability. let val = self.auth.paid.get().wrapping_add(0xc7ffffffeffffffc); (val < 0xf) && ((0x6001 >> (val & 0x3f) & 1) != 0) } - pub fn is_unknown2(&self) -> bool { + pub fn is_webprocess_webapp_or_webmas(&self) -> bool { matches!( self.auth.paid.get(), 0x380000001000000f | 0x3800000010000013 diff --git a/src/kernel/src/vm/mod.rs b/src/kernel/src/vm/mod.rs index 3e0508d1a..a160ef5bb 100644 --- a/src/kernel/src/vm/mod.rs +++ b/src/kernel/src/vm/mod.rs @@ -295,11 +295,11 @@ impl Vm { } /// See `vm_map_set_name` on the PS4 for a reference. - pub fn mname>( + pub fn mname( &self, addr: *mut u8, len: usize, - name: N, + name: impl AsRef, ) -> Result<(), MemoryUpdateError> { let name = name.as_ref(); let sname = CString::new(name); @@ -310,7 +310,7 @@ impl Vm { |i| i.name != name, |i| { if let Ok(name) = &sname { - i.storage.set_name(i.addr, i.len, name).ok(); + let _ = i.storage.set_name(i.addr, i.len, name); } i.name = name.to_owned(); @@ -510,7 +510,7 @@ impl Vm { // Set storage name if supported. if let Ok(name) = CString::new(name.as_str()) { - storage.set_name(addr, len, &name).ok(); + let _ = storage.set_name(addr, len, &name); } Ok(Alloc { From d43495afb7de5f6e8ed4d302cad9e5e64bcf5ecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Fri, 5 Apr 2024 13:54:34 +0200 Subject: [PATCH 17/25] blockpool_open --- src/kernel/src/dev/dmem.rs | 2 +- src/kernel/src/dmem/blockpool.rs | 6 ++++++ src/kernel/src/dmem/mod.rs | 32 ++++++++++++++++++-------------- src/kernel/src/fs/file.rs | 2 +- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/kernel/src/dev/dmem.rs b/src/kernel/src/dev/dmem.rs index 95caf5dd0..a227dd622 100644 --- a/src/kernel/src/dev/dmem.rs +++ b/src/kernel/src/dev/dmem.rs @@ -54,7 +54,7 @@ impl TryInto for usize { impl DeviceDriver for Dmem { fn ioctl( &self, - dev: &Arc, + _: &Arc, cmd: IoCmd, td: Option<&VThread>, ) -> Result<(), Box> { diff --git a/src/kernel/src/dmem/blockpool.rs b/src/kernel/src/dmem/blockpool.rs index 9de601fe1..53b8f5bfe 100644 --- a/src/kernel/src/dmem/blockpool.rs +++ b/src/kernel/src/dmem/blockpool.rs @@ -6,6 +6,12 @@ use std::sync::Arc; #[derive(Debug)] pub struct BlockPool {} +impl BlockPool { + pub fn new() -> Arc { + Arc::new(Self {}) + } +} + impl FileBackend for BlockPool { #[allow(unused_variables)] // TODO: remove when implementing fn ioctl( diff --git a/src/kernel/src/dmem/mod.rs b/src/kernel/src/dmem/mod.rs index 5ddd3e815..b26afc621 100644 --- a/src/kernel/src/dmem/mod.rs +++ b/src/kernel/src/dmem/mod.rs @@ -1,14 +1,15 @@ -use thiserror::Error; - use crate::dev::{Dmem, DmemContainer}; use crate::errno::EINVAL; -use crate::fs::{make_dev, CharacterDevice, DriverFlags, Fs, MakeDevError, MakeDevFlags, Mode}; +use crate::fs::{ + make_dev, CharacterDevice, DriverFlags, Fs, MakeDevError, MakeDevFlags, Mode, VFile, VFileType, +}; use crate::info; -use crate::process::{VProc, VThread}; +use crate::process::VThread; use crate::syscalls::{SysErr, SysIn, SysOut, Syscalls}; -use crate::ucred::{Gid, Privilege, Uid}; +use crate::ucred::{Gid, Uid}; use std::ops::Index; use std::sync::Arc; +use thiserror::Error; pub use self::blockpool::*; @@ -112,24 +113,31 @@ impl DmemManager { fn sys_dmem_container(self: &Arc, td: &VThread, i: &SysIn) -> Result { let dmem_id: i32 = i.args[0].try_into().unwrap(); - let mut dmem_container = td.proc().dmem_container_mut(); - let old_dmem_container = *dmem_container; + let dmem_container = td.proc().dmem_container_mut(); + let current_container = *dmem_container; if dmem_id != -1 { todo!() } - Ok(old_dmem_container.into()) + Ok(current_container.into()) } - fn sys_blockpool_open(self: &Arc, _td: &VThread, i: &SysIn) -> Result { + fn sys_blockpool_open(self: &Arc, td: &VThread, i: &SysIn) -> Result { let flags: u32 = i.args[0].try_into().unwrap(); if flags & 0xffafffff != 0 { return Err(SysErr::Raw(EINVAL)); } - todo!("sys_blockpool_open on new FS") + let bp = BlockPool::new(); + + let fd = td + .proc() + .files() + .alloc(Arc::new(VFile::new(VFileType::Blockpool(bp)))); + + Ok(fd.into()) } fn sys_blockpool_map(self: &Arc, _: &VThread, i: &SysIn) -> Result { @@ -158,10 +166,6 @@ impl DmemManager { fn sys_blockpool_move(self: &Arc, _: &VThread, _i: &SysIn) -> Result { todo!() } - - fn get_dmem_device<'a>(self: &'a Arc, dmem: DmemContainer) -> &'a DmemDevice { - self.index(dmem) - } } impl Index for DmemManager { diff --git a/src/kernel/src/fs/file.rs b/src/kernel/src/fs/file.rs index 9eb82052c..60c4f4098 100644 --- a/src/kernel/src/fs/file.rs +++ b/src/kernel/src/fs/file.rs @@ -24,7 +24,7 @@ pub struct VFile { } impl VFile { - pub(super) fn new(ty: VFileType) -> Self { + pub fn new(ty: VFileType) -> Self { let gg = GutexGroup::new(); Self { From 712c4e6cc2970bd96c8539618b375c9278c4b46a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Fri, 5 Apr 2024 13:58:00 +0200 Subject: [PATCH 18/25] rename dmem10 ioctl --- src/kernel/src/dev/dmem.rs | 2 +- src/kernel/src/fs/ioctl.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kernel/src/dev/dmem.rs b/src/kernel/src/dev/dmem.rs index a227dd622..21a5b9c69 100644 --- a/src/kernel/src/dev/dmem.rs +++ b/src/kernel/src/dev/dmem.rs @@ -76,7 +76,7 @@ impl DeviceDriver for Dmem { } match cmd { - IoCmd::DMEM10(size) => *size = self.total_size, + IoCmd::DMEMTOTAL(size) => *size = self.total_size, IoCmd::DMEMGETPRT(_prt) => todo!(), IoCmd::DMEMGETAVAIL(_avail) => todo!(), IoCmd::DMEMALLOC(_alloc) => todo!(), diff --git a/src/kernel/src/fs/ioctl.rs b/src/kernel/src/fs/ioctl.rs index dbabdef1a..57fd72b71 100644 --- a/src/kernel/src/fs/ioctl.rs +++ b/src/kernel/src/fs/ioctl.rs @@ -112,7 +112,7 @@ commands! { DIPSWCHECK2(&mut i32) = 0x40048806, /// Get total size? - DMEM10(&mut usize) = 0x4008800a, + DMEMTOTAL(&mut usize) = 0x4008800a, /// Get PRT aperture DMEMGETPRT(&mut PrtAperture) = 0xC018800C, /// Get available memory size From b38a82566ec17fc971b49f2a320fddb5097f7740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Fri, 5 Apr 2024 14:02:07 +0200 Subject: [PATCH 19/25] improve log --- src/kernel/src/dev/dmem.rs | 4 +++- src/kernel/src/fs/mod.rs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/kernel/src/dev/dmem.rs b/src/kernel/src/dev/dmem.rs index 21a5b9c69..78e2a07de 100644 --- a/src/kernel/src/dev/dmem.rs +++ b/src/kernel/src/dev/dmem.rs @@ -78,7 +78,9 @@ impl DeviceDriver for Dmem { match cmd { IoCmd::DMEMTOTAL(size) => *size = self.total_size, IoCmd::DMEMGETPRT(_prt) => todo!(), - IoCmd::DMEMGETAVAIL(_avail) => todo!(), + IoCmd::DMEMGETAVAIL(avail) => { + avail.start_or_phys_out = self.total_size; + } IoCmd::DMEMALLOC(_alloc) => todo!(), IoCmd::DMEMQUERY(_query) => todo!(), _ => todo!(), diff --git a/src/kernel/src/fs/mod.rs b/src/kernel/src/fs/mod.rs index c5747ae20..a2534722e 100644 --- a/src/kernel/src/fs/mod.rs +++ b/src/kernel/src/fs/mod.rs @@ -443,7 +443,7 @@ impl Fs { // Our IoCmd contains both the command and the argument (if there is one). let cmd = IoCmd::try_from_raw_parts(i.args[1].into(), i.args[2].into())?; - info!("Executing ioctl({cmd:?}) on file descriptor {fd}."); + info!("Executing ioctl {cmd:?} on file descriptor {fd}."); self.ioctl(fd, cmd, td)?; From 97ae9b5f3ddc928b3c115bee9429e3284abc08fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Fri, 5 Apr 2024 14:02:46 +0200 Subject: [PATCH 20/25] revert back to todo --- src/kernel/src/dev/dmem.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/kernel/src/dev/dmem.rs b/src/kernel/src/dev/dmem.rs index 78e2a07de..1c6e42bc2 100644 --- a/src/kernel/src/dev/dmem.rs +++ b/src/kernel/src/dev/dmem.rs @@ -78,9 +78,7 @@ impl DeviceDriver for Dmem { match cmd { IoCmd::DMEMTOTAL(size) => *size = self.total_size, IoCmd::DMEMGETPRT(_prt) => todo!(), - IoCmd::DMEMGETAVAIL(avail) => { - avail.start_or_phys_out = self.total_size; - } + IoCmd::DMEMGETAVAIL(avail) => todo!(), IoCmd::DMEMALLOC(_alloc) => todo!(), IoCmd::DMEMQUERY(_query) => todo!(), _ => todo!(), From 514eac59bf42d3b5b78c4a363c9eaa4777f57085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Fri, 5 Apr 2024 14:03:02 +0200 Subject: [PATCH 21/25] add comment --- src/kernel/src/dev/dmem.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kernel/src/dev/dmem.rs b/src/kernel/src/dev/dmem.rs index 1c6e42bc2..2b55f9bb8 100644 --- a/src/kernel/src/dev/dmem.rs +++ b/src/kernel/src/dev/dmem.rs @@ -76,6 +76,7 @@ impl DeviceDriver for Dmem { } match cmd { + // TODO: properly implement this IoCmd::DMEMTOTAL(size) => *size = self.total_size, IoCmd::DMEMGETPRT(_prt) => todo!(), IoCmd::DMEMGETAVAIL(avail) => todo!(), From ecc8606c05024843c7c44c785c8144a346bf9917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Fri, 5 Apr 2024 14:05:41 +0200 Subject: [PATCH 22/25] remove unused --- src/kernel/src/dev/dmem.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/kernel/src/dev/dmem.rs b/src/kernel/src/dev/dmem.rs index 2b55f9bb8..6270b5398 100644 --- a/src/kernel/src/dev/dmem.rs +++ b/src/kernel/src/dev/dmem.rs @@ -43,14 +43,6 @@ impl TryInto for i32 { } } -impl TryInto for usize { - type Error = SysErr; - - fn try_into(self) -> Result { - (self as i32).try_into() - } -} - impl DeviceDriver for Dmem { fn ioctl( &self, @@ -79,7 +71,7 @@ impl DeviceDriver for Dmem { // TODO: properly implement this IoCmd::DMEMTOTAL(size) => *size = self.total_size, IoCmd::DMEMGETPRT(_prt) => todo!(), - IoCmd::DMEMGETAVAIL(avail) => todo!(), + IoCmd::DMEMGETAVAIL(_avail) => todo!(), IoCmd::DMEMALLOC(_alloc) => todo!(), IoCmd::DMEMQUERY(_query) => todo!(), _ => todo!(), From ba86702340071b865c22338f96c8de37002e413f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Fri, 5 Apr 2024 22:02:04 +0200 Subject: [PATCH 23/25] rename flags --- src/kernel/src/rtld/module.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/kernel/src/rtld/module.rs b/src/kernel/src/rtld/module.rs index 08f3f46aa..c17f7ff5a 100644 --- a/src/kernel/src/rtld/module.rs +++ b/src/kernel/src/rtld/module.rs @@ -174,7 +174,7 @@ impl Module { proc_param, mod_param, sdk_ver, - flags: gg.spawn(ModuleFlags::UNK2), + flags: gg.spawn(ModuleFlags::IS_NEW), names, dag_static: gg.spawn(Vec::new()), dag_dynamic: gg.spawn(Vec::new()), @@ -760,16 +760,15 @@ bitflags! { pub struct ModuleFlags: u16 { const MAINPROG = 0x0001; const TEXT_REL = 0x0002; - const JMPSLOTS_DONE = 0x0004; // TODO: This seems incorrect. const TLS_DONE = 0x0008; const INIT_SCANNED = 0x0010; const ON_FINI_LIST = 0x0020; const DAG_INITED = 0x0040; - const IS_SYSTEM = 0x0100; // TODO: Rename this. - const UNK2 = 0x0200; // TODO: Rename this. - const UNK3 = 0x0400; // TODO: Rename this. - const UNK4 = 0x0800; // TODO: It seems like this is actually JMPSLOTS_DONE. - const UNK5 = 0x1000; // TODO: Rename this. + const IS_SYSTEM = 0x0100; + const IS_NEW = 0x0200; + const LIBC_FIOS = 0x0400; + const JMPSLOTS_DONE = 0x0800; + const NOT_GET_PROC = 0x1000; } } From 9813b46aaed4607cfd18856812b336f2332f3768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Fri, 5 Apr 2024 22:33:53 +0200 Subject: [PATCH 24/25] fix flags --- src/kernel/src/rtld/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kernel/src/rtld/mod.rs b/src/kernel/src/rtld/mod.rs index fd924f702..ce1eaf89f 100644 --- a/src/kernel/src/rtld/mod.rs +++ b/src/kernel/src/rtld/mod.rs @@ -790,7 +790,7 @@ impl RuntimeLinker { self.relocate_rela(md, mem.as_mut(), &mut relocated, resolver)?; - if !md.flags().contains(ModuleFlags::UNK4) { + if !md.flags().contains(ModuleFlags::JMPSLOTS_DONE) { self.relocate_plt(md, mem.as_mut(), &mut relocated, resolver)?; } @@ -1059,7 +1059,7 @@ impl RuntimeLinker { info.tlsoffset = (*md.tls_offset()).try_into().unwrap(); // Initialization and finalization functions. - if !md.flags().contains(ModuleFlags::UNK5) { + if !md.flags().contains(ModuleFlags::NOT_GET_PROC) { info.init = md.init().map(|v| addr + v).unwrap_or(0); info.fini = md.fini().map(|v| addr + v).unwrap_or(0); } From 904f975545a84268f1e725e1fb1150f2f54efc98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Proch=C3=A1zka?= Date: Fri, 5 Apr 2024 22:38:19 +0200 Subject: [PATCH 25/25] fix main --- src/kernel/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kernel/src/main.rs b/src/kernel/src/main.rs index 8c37651ad..96b9e0180 100644 --- a/src/kernel/src/main.rs +++ b/src/kernel/src/main.rs @@ -434,7 +434,7 @@ fn run() -> Result<(), KernelError> { .load(path, flags, false, true, &main) .map_err(|e| KernelError::FailedToLoadLibkernel(e.into()))?; - libkernel.flags_mut().remove(ModuleFlags::UNK2); + libkernel.flags_mut().remove(ModuleFlags::IS_NEW); libkernel.print(info!()); ld.set_kernel(libkernel); @@ -448,7 +448,7 @@ fn run() -> Result<(), KernelError> { .load(path, flags, false, true, &main) .map_err(|e| KernelError::FailedToLoadLibSceLibcInternal(e.into()))?; - libc.flags_mut().remove(ModuleFlags::UNK2); + libc.flags_mut().remove(ModuleFlags::IS_NEW); libc.print(info!()); drop(libc);