static boolean cs_valid_pointer_p(struct call_frame *pointer) { struct thread *thread=arch_os_get_current_thread(); return (((char *) thread->control_stack_start <= (char *) pointer) && ((char *) pointer < (char *) access_control_stack_pointer(thread))); }
static void catchers_cmd(char **ptr) { struct catch_block *catch; struct thread *thread=arch_os_get_current_thread(); catch = (struct catch_block *)SymbolValue(CURRENT_CATCH_BLOCK,thread);
static void print_context_cmd(char **ptr) { int free_ici; struct thread *thread=arch_os_get_current_thread(); free_ici = fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX,thread)); if (more_p(ptr)) { int index; index = parse_number(ptr); if ((index >= 0) && (index < free_ici)) { printf("There are %d interrupt contexts.\n", free_ici); printf("printing context %d\n", index); print_context(thread->interrupt_contexts[index]); } else { printf("There aren't that many/few contexts.\n"); printf("There are %d interrupt contexts.\n", free_ici); } } else { if (free_ici == 0) printf("There are no interrupt contexts!\n"); else { printf("There are %d interrupt contexts.\n", free_ici); printf("printing context %d\n", free_ici - 1); print_context(thread->interrupt_contexts[free_ici - 1]); } } }
lispobj funcall0(lispobj function) { lispobj **stack_pointer = &access_control_stack_pointer(arch_os_get_current_thread()); lispobj *args = *stack_pointer; return safe_call_into_lisp(function, args, 0); }
static void call_info_from_lisp_state(struct call_info *info) { info->frame = (struct call_frame *)access_control_frame_pointer(arch_os_get_current_thread()); info->interrupted = 0; info->code = NULL; info->lra = 0; info->pc = 0; previous_info(info); }
void detach_os_thread(init_thread_data *scribble) { struct thread *th = arch_os_get_current_thread(); odxprint(misc, "detach_os_thread: detaching"); undo_init_new_thread(th, scribble); odxprint(misc, "deattach_os_thread: detached"); pthread_setspecific(lisp_thread, (void *)0); thread_sigmask(SIG_SETMASK, &scribble->oldset, 0); }
lispobj funcall1(lispobj function, lispobj arg0) { lispobj **stack_pointer = &access_control_stack_pointer(arch_os_get_current_thread()); lispobj *args = *stack_pointer; *stack_pointer += 1; args[0] = arg0; return safe_call_into_lisp(function, args, 1); }
lispobj funcall3(lispobj function, lispobj arg0, lispobj arg1, lispobj arg2) { lispobj **stack_pointer = &access_control_stack_pointer(arch_os_get_current_thread()); lispobj *args = *stack_pointer; *stack_pointer += 3; args[0] = arg0; args[1] = arg1; args[2] = arg2; return safe_call_into_lisp(function, args, 3); }
void vodxprint_fun(const char *fmt, va_list args) { #ifdef LISP_FEATURE_WIN32 DWORD lastError = GetLastError(); #endif int original_errno = errno; QSHOW_BLOCK; char buf[1024]; int n = 0; #ifdef LISP_FEATURE_SB_THREAD struct thread *arch_os_get_current_thread(void); struct thread *self = arch_os_get_current_thread(); void *pth = self ? (void *) self->os_thread : 0; snprintf(buf, sizeof(buf), "[%p/%p] ", self, pth); n = strlen(buf); #endif vsnprintf(buf + n, sizeof(buf) - n - 1, fmt, args); /* buf is now zero-terminated (even in case of overflow). * Our caller took care of the newline (if any) through `fmt'. */ /* A sufficiently POSIXy implementation of stdio will provide * per-FILE locking, as defined in the spec for flockfile. At least * glibc complies with this. Hence we do not need to perform * locking ourselves here. (Should it turn out, of course, that * other libraries opt for speed rather than safety, we need to * revisit this decision.) */ fputs(buf, stderr); #ifdef LISP_FEATURE_WIN32 /* stdio's stderr is line-bufferred, i.e. \n ought to flush it. * Unfortunately, MinGW does not behave the way I would expect it * to. Let's be safe: */ fflush(stderr); #endif QSHOW_UNBLOCK; #ifdef LISP_FEATURE_WIN32 SetLastError(lastError); #endif errno = original_errno; }
static void regs_cmd(char **ptr) { struct thread *thread=arch_os_get_current_thread(); printf("CSP\t=\t%p ", access_control_stack_pointer(thread)); #if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) printf("CFP\t=\t%p ", access_control_frame_pointer(thread)); #endif #ifdef reg_BSP printf("BSP\t=\t%p\n", get_binding_stack_pointer(thread)); #else /* printf("BSP\t=\t0x%08lx\n", (unsigned long)SymbolValue(BINDING_STACK_POINTER)); */ printf("\n"); #endif #ifdef LISP_FEATURE_GENCGC /* printf("DYNAMIC\t=\t0x%08lx\n", DYNAMIC_SPACE_START); */ #else printf("STATIC\t=\t%p ", SymbolValue(STATIC_SPACE_FREE_POINTER, thread)); printf("RDONLY\t=\t0x%08lx ", (unsigned long)SymbolValue(READ_ONLY_SPACE_FREE_POINTER, thread)); printf("DYNAMIC\t=\t0x%08lx\n", (unsigned long)current_dynamic_space); #endif #ifdef reg_ALLOC printf("ALLOC\t=\t0x%08lx\n", (unsigned long)dynamic_space_free_pointer); #else printf("ALLOC\t=\t0x%08lx\n", (unsigned long)SymbolValue(ALLOCATION_POINTER, thread)); #endif #ifndef LISP_FEATURE_GENCGC printf("TRIGGER\t=\t0x%08lx\n", (unsigned long)current_auto_gc_trigger); #endif }
void sigtrap_handler(int signal, siginfo_t *info, os_context_t *context) { unsigned int trap; if (single_stepping) { restore_breakpoint_from_single_step(context); return; } /* This is just for info in case the monitor wants to print an * approximation. */ access_control_stack_pointer(arch_os_get_current_thread()) = (lispobj *)*os_context_sp_addr(context); /* On entry %eip points just after the INT3 byte and aims at the * 'kind' value (eg trap_Cerror). For error-trap and Cerror-trap a * number of bytes will follow, the first is the length of the byte * arguments to follow. */ trap = *(unsigned char *)(*os_context_pc_addr(context)); handle_trap(context, trap); }
callback_wrapper_trampoline( #if !(defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)) /* On the x86oid backends, the assembly wrapper happens to not pass * in ENTER_ALIEN_CALLBACK explicitly for safepoints. However, the * platforms with precise GC are tricky enough already, and I want * to minimize the read-time conditionals. For those platforms, I'm * only replacing funcall3 with callback_wrapper_trampoline while * keeping the arguments unchanged. --DFL */ lispobj __attribute__((__unused__)) fun, #endif lispobj arg0, lispobj arg1, lispobj arg2) { #if defined(LISP_FEATURE_WIN32) pthread_np_notice_thread(); #endif struct thread* th = arch_os_get_current_thread(); if (!th) { /* callback invoked in non-lisp thread */ init_thread_data scribble; attach_os_thread(&scribble); funcall3(StaticSymbolFunction(ENTER_FOREIGN_CALLBACK), arg0,arg1,arg2); detach_os_thread(&scribble); return; } #ifdef LISP_FEATURE_WIN32 /* arg2 is the pointer to a return value, which sits on the stack */ th->carried_base_pointer = (os_context_register_t) *(((void**)arg2)-1); #endif #ifdef LISP_FEATURE_SB_SAFEPOINT WITH_GC_AT_SAFEPOINTS_ONLY()
void arch_clear_pseudo_atomic_interrupted(os_context_t *context) { struct thread *thread = arch_os_get_current_thread(); clear_pseudo_atomic_interrupted(thread); }
boolean arch_pseudo_atomic_atomic(os_context_t *context) { return get_pseudo_atomic_atomic(arch_os_get_current_thread()); }