@@ -5492,82 +5492,164 @@ impl Cage {
54925492 shmid
54935493 }
54945494
5495- //------------------SHMAT SYSCALL------------------
5496-
5495+ /// ### Description
5496+ ///
5497+ /// The `shmat_syscall` maps the shared memory segment associated with the
5498+ /// shared memory identifer onto the address space of the calling Cage
5499+ /// object. The address to which the segment is mapped is given by the
5500+ /// `shmaddr` parameter of this function.
5501+ ///
5502+ /// ### Arguments
5503+ ///
5504+ /// `shmid` : identifier of the memory segment to be mapped
5505+ /// `shmaddr` : Address in the address space of the calling Cage where the
5506+ /// segment is to be mapped `shmflag` : Flag which indicates if the
5507+ /// memory segment to be mapped is readonly or not
5508+ ///
5509+ /// ### Returns
5510+ ///
5511+ /// Returns the address at which the memory segment has been mapped into
5512+ ///
5513+ /// ### Errors
5514+ ///
5515+ /// * `EINVAL` : If the shmid passed as an argument is an invalid identifier
5516+ ///
5517+ /// ### Panics
5518+ ///
5519+ /// Currently there are no scenarios where the function panics
5520+ ///
5521+ /// For more information - refer the documentation at [https://man7.org/linux/man-pages/man3/shmat.3p.html]
54975522 pub fn shmat_syscall ( & self , shmid : i32 , shmaddr : * mut u8 , shmflg : i32 ) -> i32 {
5523+ // Get shm table
54985524 let metadata = & SHM_METADATA ;
54995525 let prot: i32 ;
5526+ // Check if the shmid passed points to a valid table entry
55005527 if let Some ( mut segment) = metadata. shmtable . get_mut ( & shmid) {
5528+ // Check if the readonly flag is set or not
55015529 if 0 != ( shmflg & SHM_RDONLY ) {
55025530 prot = PROT_READ ;
55035531 } else {
55045532 prot = PROT_READ | PROT_WRITE ;
55055533 }
5534+ // Aquire a mutex lock on the reverse memory mappings
55065535 let mut rev_shm = self . rev_shm . lock ( ) ;
5536+ // Push a reverse mapping of shmaddr -> shmid the processes's reverse mapping
5537+ // table
55075538 rev_shm. push ( ( shmaddr as u32 , shmid) ) ;
55085539 drop ( rev_shm) ;
55095540
5510- // update semaphores
5541+ // Clone semaphores that the memory segment holds into the current calling
5542+ // process
55115543 if !segment. semaphor_offsets . is_empty ( ) {
5512- // lets just look at the first cage in the set, since we only need to grab the
5513- // ref from one
5544+ // Since all processes that share this segment hold all the semaphores - we only
5545+ // need to grab them from one cage
55145546 if let Some ( cageid) = segment
55155547 . attached_cages
55165548 . clone ( )
55175549 . into_read_only ( )
55185550 . keys ( )
55195551 . next ( )
55205552 {
5553+ // Get the first cage associated with the memory segment
55215554 let cage2 = interface:: cagetable_getref ( * cageid) ;
5555+ // Get the reverse memory mappings
55225556 let cage2_rev_shm = cage2. rev_shm . lock ( ) ;
5523- let addrs = Self :: rev_shm_find_addrs_by_shmid ( & cage2_rev_shm, shmid) ; // find all the addresses assoc. with shmid
5557+ // Find all addresses associated with the shmid of the memory segment
5558+ let addrs = Self :: rev_shm_find_addrs_by_shmid ( & cage2_rev_shm, shmid) ;
5559+ // Add each semaphore at its appropriate offset - only need to index the first
5560+ // address Since semaphores are consistent across all cages
5561+ // and all addresses within the cages
55245562 for offset in segment. semaphor_offsets . iter ( ) {
5525- let sementry = cage2. sem_table . get ( & ( addrs[ 0 ] + * offset) ) . unwrap ( ) . clone ( ) ; //add semaphors into semtable at addr + offsets
5563+ let sementry = cage2. sem_table . get ( & ( addrs[ 0 ] + * offset) ) . unwrap ( ) . clone ( ) ;
55265564 self . sem_table . insert ( shmaddr as u32 + * offset, sementry) ;
55275565 }
55285566 }
55295567 }
55305568
5569+ // Map the shared segment onto the current cage using `map_shm` function
55315570 segment. map_shm ( shmaddr, prot, self . cageid )
55325571 } else {
55335572 syscall_error ( Errno :: EINVAL , "shmat" , "Invalid shmid value" )
55345573 }
55355574 }
55365575
5537- //------------------SHMDT SYSCALL------------------
5538-
5576+ ///------------------SHMDT SYSCALL------------------
5577+ /// ### Description
5578+ ///
5579+ /// This syscall can be viewed as a reversal of the `shmat_syscall`
5580+ /// 'shmat_syscall` attaches a particular memory shared memory segment to a
5581+ /// `shmaddr` passed as an argument
5582+ /// `shmdt` unmaps the shared memory segment that is currently mapped at the
5583+ /// address specified by the `shmaddr` argument.
5584+ ///
5585+ /// ### Arguments
5586+ ///
5587+ /// `shmaddr` : The address within the address space of the calling Cage to
5588+ /// unmap
5589+ ///
5590+ /// ### Returns
5591+ ///
5592+ /// Returns the id of the memory segment that has been unmapped
5593+ ///
5594+ /// ### Errors
5595+ ///
5596+ /// This function can result in the following errors
5597+ ///
5598+ /// * EINVAL : If there is no memory segment with the address specified
5599+ ///
5600+ ///
5601+ /// ### Panics
5602+ ///
5603+ /// This function panics if there is no memory segment associated with the specified `shmaddr`
5604+ ///
5605+ /// For more information please refer - [https://man7.org/linux/man-pages/man3/shmdt.3p.html]
55395606 pub fn shmdt_syscall ( & self , shmaddr : * mut u8 ) -> i32 {
55405607 let metadata = & SHM_METADATA ;
55415608 let mut rm = false ;
5609+ // Acquire the lock of the reverse memory mappings of the Cage object
55425610 let mut rev_shm = self . rev_shm . lock ( ) ;
5611+ // This function returns the index where the pair of (shmaddr, shmid) is stored
5612+ // within the vector That holds these mappings
55435613 let rev_shm_index = Self :: rev_shm_find_index_by_addr ( & rev_shm, shmaddr as u32 ) ;
55445614
5615+ // Check if the index is valid
55455616 if let Some ( index) = rev_shm_index {
5617+ // Get the second element of the (shmaddr,shmid) pair which gives us the id of
5618+ // the memory segment
55465619 let shmid = rev_shm[ index] . 1 ;
5620+ // Get the memory segment from the shmtable which corresponds to the shmid
5621+ // extracted above
55475622 match metadata. shmtable . entry ( shmid) {
5623+ // If the memory segment is occupied
55485624 interface:: RustHashEntry :: Occupied ( mut occupied) => {
5625+ // Get the mutex for the memory segment
55495626 let segment = occupied. get_mut ( ) ;
5550-
5551- // update semaphores
5627+ // Loop through each semaphore that the segment hold and remove it from the semaphore table
55525628 for offset in segment. semaphor_offsets . iter ( ) {
55535629 self . sem_table . remove ( & ( shmaddr as u32 + * offset) ) ;
55545630 }
5555-
5631+ // Use the unmap helper function to unmap the shmaddr from the current cage object
55565632 segment. unmap_shm ( shmaddr, self . cageid ) ;
55575633
5634+ // Check if segment has been removed previously by the `shmctl_syscall`
5635+ // and that the number of processess attached to the segment are zero
55585636 if segment. rmid && segment. shminfo . shm_nattch == 0 {
55595637 rm = true ;
55605638 }
5639+
5640+ // Remove the reverse mapping from the mappings of the current cage object
55615641 rev_shm. swap_remove ( index) ;
55625642
5643+ // If segment has been removed previously
5644+ // and has no processess attached to it
5645+ // we delete the memory segment from the shmtable
55635646 if rm {
55645647 let key = segment. key ;
55655648 occupied. remove_entry ( ) ;
55665649 metadata. shmkeyidtable . remove ( & key) ;
55675650 }
5568-
5569- return shmid; //NaCl relies on this non-posix behavior of
5570- // returning the shmid on success
5651+
5652+ return shmid;
55715653 }
55725654 interface:: RustHashEntry :: Vacant ( _) => {
55735655 panic ! ( "Inode not created for some reason" ) ;
0 commit comments