@@ -294,16 +294,6 @@ def init_objc(self, module: Module):
294294 if not self .emu .find_module ("libobjc.A.dylib" ):
295295 return
296296
297- initialized = self .emu .find_symbol ("__ZZ10_objc_initE11initialized" )
298- if not self .emu .read_u8 (initialized .address ):
299- # As the initialization timing before program execution
300- self ._init_magic_vars ()
301- self ._init_program_vars ()
302- self ._init_dyld_vars ()
303- self ._init_lib_system_kernel ()
304- self ._init_lib_system_pthread ()
305- self ._init_objc_vars ()
306-
307297 text_segment = module .binary .get_segment ("__TEXT" )
308298
309299 mach_header_ptr = module .base - module .image_base + text_segment .virtual_address
@@ -319,8 +309,6 @@ def init_objc(self, module: Module):
319309 self .emu .call_symbol ("_load_images" , 0 , mach_header_ptr )
320310 except EmulatorCrashed :
321311 self .emu .logger .warning ("Initialize Objective-C failed." )
322- finally :
323- module .binary = None
324312
325313 def search_module_binary (self , module_name : str ) -> str :
326314 """Search system module binary in rootfs directory.
@@ -365,10 +353,25 @@ def resolve_modules(self, module_names: List[str]):
365353 # Fixup must be executed before initializing Objective-C.
366354 fixup .install (module )
367355
368- # TODO: `__pthread_init` in `libsystem_pthread.dylib`
356+ self . _after_module_loaded ( module_name )
369357
370358 self .init_objc (module )
371359
360+ module .binary = None
361+
362+ def _after_module_loaded (self , module_name : str ):
363+ """Perform initialization after module loaded."""
364+ if module_name == "libsystem_kernel.dylib" :
365+ self ._init_lib_system_kernel ()
366+ elif module_name == "libsystem_c.dylib" :
367+ self ._init_program_vars ()
368+ elif module_name == "libdyld.dylib" :
369+ self ._init_dyld_vars ()
370+ elif module_name == "libsystem_pthread.dylib" :
371+ self ._init_lib_system_pthread ()
372+ elif module_name == "libobjc.A.dylib" :
373+ self ._init_objc_vars ()
374+
372375 def _enable_objc (self ):
373376 """Enable Objective-C support."""
374377 self .resolve_modules (OBJC_DEPENDENCIES )
@@ -488,6 +491,37 @@ def fix_method_signature_rom_table(self):
488491 self .emu .write_pointer (offset + 8 , str_ptr )
489492 self .emu .write_u64 (offset + 16 , item [2 ])
490493
494+ def _fd_open (self , fd : int , mode : str , unbuffered : bool = False ) -> int :
495+ mode_p = self .emu .create_string (mode )
496+
497+ try :
498+ fp = self .emu .call_symbol ("_fdopen" , fd , mode_p )
499+ flags = self .emu .read_u32 (fp + 16 )
500+
501+ if unbuffered :
502+ flags |= 0x2
503+
504+ self .emu .write_u32 (fp + 16 , flags )
505+ return fp
506+ finally :
507+ self .emu .free (mode_p )
508+
509+ def _setup_standard_io (self ):
510+ """Setup standard IO: `stdin`, `stdout`, `stderr`."""
511+ stdin_p = self .emu .find_symbol ("___stdinp" )
512+ stdout_p = self .emu .find_symbol ("___stdoutp" )
513+ stderr_p = self .emu .find_symbol ("___stderrp" )
514+
515+ if isinstance (self .file_system .stdin_fd , int ):
516+ stdin_fp = self ._fd_open (self .file_system .stdin_fd , "r" )
517+ self .emu .write_pointer (stdin_p .address , stdin_fp )
518+
519+ stdout_fp = self ._fd_open (self .file_system .stdout_fd , "w" , unbuffered = True )
520+ self .emu .write_pointer (stdout_p .address , stdout_fp )
521+
522+ stderr_fp = self ._fd_open (self .file_system .stderr_fd , "w" , unbuffered = True )
523+ self .emu .write_pointer (stderr_p .address , stderr_fp )
524+
491525 def initialize (self ):
492526 """Initialize environment."""
493527 self ._setup_hooks ()
@@ -497,8 +531,12 @@ def initialize(self):
497531 self ._setup_symbolic_links ()
498532 self ._setup_bundle_dir ()
499533
534+ self ._init_magic_vars ()
535+
500536 if self .emu .enable_objc :
501537 self ._enable_objc ()
502538
503539 if self .emu .enable_ui_kit :
504540 self ._enable_ui_kit ()
541+
542+ self ._setup_standard_io ()
0 commit comments