diff --git a/tritondse/process_state.py b/tritondse/process_state.py index 1ad3c31..3901342 100644 --- a/tritondse/process_state.py +++ b/tritondse/process_state.py @@ -193,7 +193,12 @@ def spawn_new_thread(self, new_pc: Addr, args: Addr) -> ThreadContext: thread.save(self.tt_ctx) # Concretize pc, bp, sp, and first (argument) - regs = [self.program_counter_register, self.stack_pointer_register, self.base_pointer_register, self._get_argument_register(0)] + regs = [ + self.program_counter_register, + self.stack_pointer_register, + self.base_pointer_register, + self._get_argument_register(0) + ] for reg in regs: if reg.getId() in thread.sregs: del thread.sregs[reg.getId()] @@ -201,8 +206,16 @@ def spawn_new_thread(self, new_pc: Addr, args: Addr) -> ThreadContext: thread.cregs[self.program_counter_register.getId()] = new_pc # set new pc thread.cregs[self._get_argument_register(0).getId()] = args # set args pointer stack = self.memory.map_from_name(self.STACK_SEG) - thread.cregs[self.base_pointer_register.getId()] = ((stack.start+stack.size) - ((1 << 28) * tid)) - thread.cregs[self.stack_pointer_register.getId()] = ((stack.start+stack.size) - ((1 << 28) * tid)) + stack_base_addr = ((stack.start + stack.size - self.ptr_size) - ((1 << 28) * tid)) + thread.cregs[self.base_pointer_register.getId()] = stack_base_addr + thread.cregs[self.stack_pointer_register.getId()] = stack_base_addr + + if self.architecture == Architecture.AARCH64: + thread.cregs[getattr(self.registers, 'x30').getId()] = 0xcafecafe + elif self.architecture == Architecture.ARM32: + thread.cregs[getattr(self.registers, 'r14').getId()] = 0xcafecafe + elif self.architecture in [Architecture.X86, Architecture.X86_64]: + self.memory.write_ptr(stack_base_addr, 0xcafecafe) # Add the thread in the pool of threads self._threads[tid] = thread diff --git a/tritondse/routines.py b/tritondse/routines.py index 07c3f30..9d3b0ea 100644 --- a/tritondse/routines.py +++ b/tritondse/routines.py @@ -1219,9 +1219,12 @@ def rtn_pthread_join(se: 'SymbolicExecutor', pstate: 'ProcessState'): arg0 = pstate.get_argument_value(0) arg1 = pstate.get_argument_value(1) - if arg0 in pstate.threads: + if arg0 in pstate._threads: + # This will change the state of the current thread from RUNNING to + # JOINING. Therefore, it will not run until the joining thread + # finishes. pstate.current_thread.join_thread(arg0) - logger.info(f"Thread id {pstate.current_thread.tid} joined thread id {arg0}") + logger.info(f"Thread id {pstate.current_thread.tid} is waiting thread id {arg0} to join") else: pstate.current_thread.cancel_join() logger.debug(f"Thread id {arg0} already destroyed") diff --git a/tritondse/symbolic_executor.py b/tritondse/symbolic_executor.py index 41cc242..7402aca 100644 --- a/tritondse/symbolic_executor.py +++ b/tritondse/symbolic_executor.py @@ -232,7 +232,9 @@ def __schedule_thread(self) -> None: if len(threads_list) == 1: # If there is only one thread no need to schedule another thread return - if self.pstate.current_thread.count > self.config.thread_scheduling: + if self.pstate.current_thread.count > self.config.thread_scheduling or \ + self.pstate.current_thread.is_waiting_to_join() or \ + not self.pstate.current_thread.is_running(): # Select the next thread to execute next_th = self._fetch_next_thread(threads_list) @@ -287,6 +289,17 @@ def step(self) -> bool: # Fetch program counter (of the thread selected), at this point the current thread should be running! self.current_pc = self.pstate.cpu.program_counter # should normally be already set but still. + if self.current_pc == 0xcafecafe: + logger.debug(f"Schedule thread ({self.pstate.current_thread.tid}) finished running") + self.pstate.current_thread.kill() + + # Check whether the main thread was waiting for the schedule thread to join. + if self.pstate._threads[0]._join_th_id == self.pstate.current_thread.tid: + logger.debug(f"Set main thread state to RUNNING") + self.pstate._threads[0]._join_th_id = None + self.pstate._threads[0].state = ThreadState.RUNNING + return True + if self.current_pc == self._run_to_target: # Hit the location we wanted to reach return False diff --git a/tritondse/thread_context.py b/tritondse/thread_context.py index 6fc480e..61837d4 100644 --- a/tritondse/thread_context.py +++ b/tritondse/thread_context.py @@ -5,6 +5,11 @@ # third-party imports from triton import TritonContext +# local imports +import tritondse.logging + +logger = tritondse.logging.get("thread_context") + @enum_tools.documentation.document_enum class ThreadState(Enum):