diff --git a/mach_dep.c b/mach_dep.c index 343add383..99c01a5fa 100644 --- a/mach_dep.c +++ b/mach_dep.c @@ -32,69 +32,33 @@ # include # include -# define VA_SIZE 48 -# define E2K_PSHTP_SIZE 12 - -# if defined(__clang__) -# define VLIW_CMD_BRACES_PREFIX "%" /* a workaround for clang-9 */ -# else -# define VLIW_CMD_BRACES_PREFIX /* empty */ -# endif - -# define get_stack_index(ps_ptr) \ - do { \ - word psp_lo, psp_hi; \ - signed_word pshtp; \ - char tmp = 0, val; \ - \ - __asm__ __volatile__ ( \ - "1:\n\t" \ - "ldb %4, 0, %0, mas = 7\n\t" \ - "rrd %%pshtp, %1\n\t" \ - "rrd %%psp.lo, %2\n\t" \ - "rrd %%psp.hi, %3\n\t" \ - VLIW_CMD_BRACES_PREFIX "{\n\t" \ - " stb %4, 0, %0, mas = 2\n\t" \ - " rbranch 1b\n\t" \ - VLIW_CMD_BRACES_PREFIX "}" \ - : "=&r" (val), "=&r" (pshtp), \ - "=&r" (psp_lo), "=&r" (psp_hi) \ - : "r" (&tmp)); \ - *(ps_ptr) = (psp_lo & ((1UL<> (63-E2K_PSHTP_SIZE)); \ - } while (0) - GC_INNER size_t GC_get_procedure_stack(ptr_t buf, size_t buf_sz) { - word ps; - word new_sz = 0; + word new_sz; GC_ASSERT(0 == buf_sz || buf != NULL); for (;;) { - get_stack_index(&ps); - if (syscall(__NR_access_hw_stacks, E2K_READ_PROCEDURE_STACK, - &ps, buf, buf_sz, &new_sz) != -1) - break; - - if (ENOMEM == errno && (word)buf_sz < new_sz) { -# ifdef LOG_E2K_ALLOCS - if (buf_sz > 0) /* probably may happen */ - GC_log_printf("GC_get_procedure_stack():" - " buffer size/requested %lu/%lu bytes, GC #%lu\n", - (unsigned long)buf_sz, (unsigned long)new_sz, - (unsigned long)GC_gc_no); -# endif - return (size_t)new_sz; /* buffer not enough */ - } else if (errno != EAGAIN) { - ABORT_ARG1("Cannot read procedure stack", ": errno= %d", errno); + word stack_ofs; + + new_sz = 0; + if (syscall(__NR_access_hw_stacks, E2K_GET_PROCEDURE_STACK_SIZE, + NULL, NULL, 0, &new_sz) == -1) { + if (errno != EAGAIN) + ABORT_ARG1("Cannot get size of procedure stack", + ": errno= %d", errno); + continue; } + GC_ASSERT(new_sz > 0 && new_sz % sizeof(word) == 0); + if (new_sz > buf_sz) + break; + /* Immediately read the stack right after checking its size. */ + stack_ofs = 0; + if (syscall(__NR_access_hw_stacks, E2K_READ_PROCEDURE_STACK_EX, + &stack_ofs, buf, new_sz, NULL) != -1) + break; + if (errno != EAGAIN) + ABORT_ARG2("Cannot read procedure stack", + ": new_sz= %lu, errno= %d", (unsigned long)new_sz, errno); } - - if ((word)buf_sz < new_sz) - ABORT_ARG2("Buffer overflow while reading procedure stack", - ": buf_sz= %lu, new_sz= %lu", - (unsigned long)buf_sz, (unsigned long)new_sz); return (size_t)new_sz; } @@ -124,6 +88,7 @@ # ifdef THREADS GC_INNER size_t GC_alloc_and_get_procedure_stack(ptr_t *pbuf) { + /* TODO: support saving from non-zero ofs in stack */ ptr_t buf = NULL; size_t new_sz, buf_sz; @@ -142,9 +107,6 @@ return new_sz; } # endif /* THREADS */ - -# undef VLIW_CMD_BRACES_PREFIX -# undef get_stack_index #endif /* E2K */ #if defined(MACOS) && defined(__MWERKS__)