11use crate :: {
2- ckb_constants:: { self as consts, CellField , HeaderField , InputField , Source } ,
2+ ckb_constants:: { self as consts, CellField , HeaderField , InputField , Place , Source } ,
33 error:: SysError ,
44 syscalls:: internal:: SpawnArgs ,
55} ;
@@ -242,8 +242,8 @@ pub trait SyscallImpls {
242242 & self ,
243243 index : usize ,
244244 source : Source ,
245- place : usize ,
246- bounds : usize ,
245+ place : Place ,
246+ bounds : Bounds ,
247247 argv : & [ & CStr ] ,
248248 ) -> Result < ( ) , Error > {
249249 let argv_ptr: alloc:: vec:: Vec < * const i8 > =
@@ -253,7 +253,7 @@ pub trait SyscallImpls {
253253 index as u64 ,
254254 source as u64 ,
255255 place as u64 ,
256- bounds as u64 ,
256+ bounds. into ( ) ,
257257 argv. len ( ) as u64 ,
258258 argv_ptr. as_ptr ( ) as u64 ,
259259 consts:: SYS_EXEC ,
@@ -265,8 +265,8 @@ pub trait SyscallImpls {
265265 & self ,
266266 index : usize ,
267267 source : Source ,
268- place : usize ,
269- bounds : usize ,
268+ place : Place ,
269+ bounds : Bounds ,
270270 argv : & [ & CStr ] ,
271271 inherited_fds : & [ u64 ] ,
272272 ) -> Result < u64 , Error > {
@@ -288,7 +288,7 @@ pub trait SyscallImpls {
288288 index as u64 ,
289289 source as u64 ,
290290 place as u64 ,
291- bounds as u64 ,
291+ bounds. into ( ) ,
292292 & mut spgs as * mut _ as u64 ,
293293 0 ,
294294 consts:: SYS_SPAWN ,
@@ -474,13 +474,17 @@ pub fn syscall_to_impls<S: SyscallImpls + ?Sized>(
474474 consts:: SYS_EXEC => {
475475 let source: Source = a1. try_into ( ) . expect ( "parse source" ) ;
476476 let argv = build_argv ( a4, a5 as * const * const i8 ) ;
477- match impls. exec ( a0 as usize , source, a2 as usize , a3 as usize , & argv) {
477+ let place = a2. try_into ( ) . expect ( "parse place" ) ;
478+ let bounds = a3. into ( ) ;
479+ match impls. exec ( a0 as usize , source, place, bounds, & argv) {
478480 Ok ( ( ) ) => 0 ,
479481 Err ( e) => e. into ( ) ,
480482 }
481483 }
482484 consts:: SYS_SPAWN => {
483485 let source: Source = a1. try_into ( ) . expect ( "parse source" ) ;
486+ let place = a2. try_into ( ) . expect ( "parse place" ) ;
487+ let bounds = a3. into ( ) ;
484488 let spgs_addr = a4 as * mut SpawnArgs ;
485489 let spgs: & mut SpawnArgs = unsafe { & mut * spgs_addr } ;
486490
@@ -495,7 +499,7 @@ pub fn syscall_to_impls<S: SyscallImpls + ?Sized>(
495499 fds. push ( fd) ;
496500 fd_ptr = unsafe { fd_ptr. offset ( 1 ) } ;
497501 }
498- match impls. spawn ( a0 as usize , source, a2 as usize , a3 as usize , & argv, & fds) {
502+ match impls. spawn ( a0 as usize , source, place , bounds , & argv, & fds) {
499503 Ok ( process_id) => {
500504 unsafe { spgs. process_id . write ( process_id) } ;
501505 0
@@ -609,6 +613,49 @@ where
609613 }
610614}
611615
616+ /// Bounds for exec / spawn syscalls
617+ #[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
618+ pub struct Bounds {
619+ offset : u32 ,
620+ length : u32 ,
621+ }
622+
623+ impl Bounds {
624+ pub fn new_till_end ( offset : u32 ) -> Self {
625+ Self { offset, length : 0 }
626+ }
627+
628+ pub fn new ( offset : u32 , length : u32 ) -> Self {
629+ Self { offset, length }
630+ }
631+
632+ pub fn offset ( & self ) -> u32 {
633+ self . offset
634+ }
635+
636+ /// Only returns length when user provides a length. In case user uses
637+ /// 0 to denote reading to the end, this method returns None.
638+ pub fn length ( & self ) -> Option < u32 > {
639+ if self . length == 0 {
640+ None
641+ } else {
642+ Some ( self . length )
643+ }
644+ }
645+ }
646+
647+ impl From < Bounds > for u64 {
648+ fn from ( bounds : Bounds ) -> u64 {
649+ ( ( bounds. offset as u64 ) << 32 ) | ( bounds. length as u64 )
650+ }
651+ }
652+
653+ impl From < u64 > for Bounds {
654+ fn from ( val : u64 ) -> Bounds {
655+ Bounds :: new ( ( val >> 32 ) as u32 , val as u32 )
656+ }
657+ }
658+
612659/// Error defined here differs from SysError: it only captures true CKB
613660/// errors. It is not considered an error when a partial loading function
614661/// reads part, but not all of the data.
0 commit comments