--- ./qtwebkit/Source/JavaScriptCore/heap/MachineStackMarker.cpp.orig Thu Sep 11 12:48:22 2014 +++ ./qtwebkit/Source/JavaScriptCore/heap/MachineStackMarker.cpp Sun Oct 19 04:57:32 2014 @@ -46,10 +46,12 @@ #elif OS(UNIX) #include +#if !OS(SOLARIS) #include - +#endif #if OS(SOLARIS) #include +#include #else #include #endif @@ -169,7 +171,7 @@ static inline bool equalThread(const PlatformThread& first, const PlatformThread& second) { -#if OS(DARWIN) || OS(WINDOWS) +#if OS(DARWIN) || OS(WINDOWS) || OS(SOLARIS) return first == second; #elif USE(PTHREADS) return !!pthread_equal(first, second); @@ -311,6 +313,8 @@ typedef CONTEXT PlatformThreadRegisters; #elif OS(QNX) typedef struct _debug_thread_info PlatformThreadRegisters; +#elif OS(SOLARIS) +typedef stack_t PlatformThreadRegisters; #elif USE(PTHREADS) typedef pthread_attr_t PlatformThreadRegisters; #else @@ -317,6 +321,92 @@ #error Need a thread register struct for this platform #endif +#if OS(SOLARIS) + +typedef int (*int_fn)(thread_t, int*, unsigned *, stack_t*, gregset_t); +static int_fn _thread_getstate = NULL; +static void *_main_stack_base = NULL; + +static void * resolve_symbol(const char* name) { + void *addr = dlsym(RTLD_DEFAULT, name); + if(addr == NULL) { + // RTLD_DEFAULT was not defined on some early versions of 2.5.1 + addr = dlsym(RTLD_NEXT, name); + } + if(addr == NULL) { + perror(dlerror()); + } + return addr; +} + +static int +get_stack_other(thread_t t, stack_t *st) { + int flag, res; + gregset_t regs; + + if (_thread_getstate == NULL) { + /* not in the API, but also not hidden so: get a reference on the-fly */ + void *fn = resolve_symbol("thr_getstate"); + _thread_getstate = (int_fn) ((uintptr_t)(fn)); + } + /* this does a thrp_stksegment for the given thread, if it could find it */ + res = _thread_getstate(t, &flag, NULL, st, regs); + if (res == ESRCH) { + /* thread not found */ + return 1; + } + return 0; +} + +static int +get_stack_current(stack_t *st) { + int res = 0; + int is_main = thr_main(); + if (is_main < 0) { + /* thread not initialized */ + return 1; + } + if (is_main) { + struct rlimit limits; + if (_main_stack_base == NULL) { + res = thr_stksegment(st); + _main_stack_base = st->ss_sp; + } + st->ss_sp = _main_stack_base; + getrlimit(RLIMIT_STACK, &limits); + st->ss_size = (size_t)limits.rlim_cur; + } else { + res = thr_stksegment(st); + } + return res; +} + +/* NOTE: + st.ss_sp is the high address of the stack (stktop) aka Thread.stackBase aka + StackBounds.m_origin . Allocation goes downto the end of the stack (stk) + aka StackBounds.m_bound, which is (st.ss_sp - st.ss_size)! + pthread_attr_getstackaddr(...) in turn returns the end of the stack! +*/ +static int +get_stack(thread_t t, stack_t *st) { + int ret; + pthread_t me = pthread_self(); + if (me != t) { + ret = get_stack_other(t, st); + } else { + ret = get_stack_current(st); + } + if (ret) { + st->ss_sp = NULL; + st->ss_size = 0; + } else { + // adjust to return StackBounds.m_bound + st->ss_sp -= st->ss_size; + } + return ret; +} +#endif + static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs) { #if OS(DARWIN) @@ -369,16 +459,20 @@ } close(fd); return sizeof(struct _debug_thread_info); +# elif OS(SOLARIS) + if (get_stack(platformThread, ®s)) { + // should we issue a warning ? + } + return sizeof(stack_t); #elif USE(PTHREADS) pthread_attr_init(®s); -#if HAVE(PTHREAD_NP_H) || OS(NETBSD) +# if HAVE(PTHREAD_NP_H) || OS(NETBSD) // e.g. on FreeBSD 5.4, neundorf@kde.org pthread_attr_get_np(platformThread, ®s); -#else +# else // FIXME: this function is non-portable; other POSIX systems may have different np alternatives pthread_getattr_np(platformThread, ®s); -#endif - return 0; +# endif #else #error Need a way to get thread registers on this platform #endif @@ -416,7 +510,7 @@ #endif // __DARWIN_UNIX03 -// end OS(DARWIN) +// end DARWIN #elif OS(WINDOWS) #if CPU(ARM) @@ -430,10 +524,11 @@ #else #error Unknown Architecture #endif - +// end WINDOWS #elif OS(QNX) return reinterpret_cast((uintptr_t) regs.sp); - +#elif OS(SOLARIS) + return reinterpret_cast((uintptr_t) regs.ss_sp); #elif USE(PTHREADS) void* stackBase = 0; size_t stackSize = 0; @@ -448,7 +543,7 @@ static void freePlatformThreadRegisters(PlatformThreadRegisters& regs) { -#if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN) && !OS(QNX) +#if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN) && !OS(QNX) && !OS(SOLARIS) pthread_attr_destroy(®s); #else UNUSED_PARAM(regs);