1f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch/* 2f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 4f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * 5f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * This library is free software; you can redistribute it and/or 6f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * modify it under the terms of the GNU Lesser General Public 7f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * License as published by the Free Software Foundation; either 8f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * version 2 of the License, or (at your option) any later version. 9f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * 10f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * This library is distributed in the hope that it will be useful, 11f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * but WITHOUT ANY WARRANTY; without even the implied warranty of 12f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * Lesser General Public License for more details. 14f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * 15f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * You should have received a copy of the GNU Lesser General Public 16f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * License along with this library; if not, write to the Free Software 17f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * 19f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch */ 20f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 21f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "config.h" 22f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "StackBounds.h" 23f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 24f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if OS(DARWIN) 25f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 26f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <mach/task.h> 27f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <mach/thread_act.h> 28f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <pthread.h> 29f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 30f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#elif OS(WINDOWS) 31f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 32f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <windows.h> 33f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 34f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#elif OS(HAIKU) 35f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 36f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <OS.h> 37f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 38f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#elif OS(SOLARIS) 39f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 40f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <thread.h> 41f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 42f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#elif OS(QNX) 43f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 44f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <fcntl.h> 45f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <sys/procfs.h> 46f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <stdio.h> 47f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <errno.h> 48f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 49f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#elif OS(UNIX) 50f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 51f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <pthread.h> 52f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if HAVE(PTHREAD_NP_H) 53f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <pthread_np.h> 54f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif 55f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 56f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif 57f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 58f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochnamespace WTF { 59f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 60f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch// Bug 26276 - Need a mechanism to determine stack extent 61f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch// 62f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch// These platforms should now be working correctly: 63ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch// DARWIN, QNX, UNIX, SYMBIAN 64f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch// These platforms are not: 65ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch// WINDOWS, SOLARIS, OPENBSD, HAIKU, WINCE 66f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch// 67f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch// FIXME: remove this! - this code unsafely guesses at stack sizes! 68ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#if OS(WINDOWS) || OS(SOLARIS) || OS(OPENBSD) || OS(HAIKU) 69f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch// Based on the current limit used by the JSC parser, guess the stack size. 70f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic const ptrdiff_t estimatedStackSize = 128 * sizeof(void*) * 1024; 71f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch// This method assumes the stack is growing downwards. 72f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic void* estimateStackBound(void* origin) 73f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 74f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return static_cast<char*>(origin) - estimatedStackSize; 75f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 76f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif 77f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 78f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if OS(DARWIN) 79f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 80f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid StackBounds::initialize() 81f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 82f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch pthread_t thread = pthread_self(); 83f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_origin = pthread_get_stackaddr_np(thread); 84f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_bound = static_cast<char*>(m_origin) - pthread_get_stacksize_np(thread); 85f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 86f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 87f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#elif OS(QNX) 88f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 89f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid StackBounds::initialize() 90f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 91f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch void* stackBase = 0; 92f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch size_t stackSize = 0; 93f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch pthread_t thread = pthread_self(); 94f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 95f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch struct _debug_thread_info threadInfo; 96f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch memset(&threadInfo, 0, sizeof(threadInfo)); 97f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch threadInfo.tid = pthread_self(); 98f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int fd = open("/proc/self", O_RDONLY); 99f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (fd == -1) { 100f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch LOG_ERROR("Unable to open /proc/self (errno: %d)", errno); 101f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch CRASH(); 102f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 103f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch devctl(fd, DCMD_PROC_TIDSTATUS, &threadInfo, sizeof(threadInfo), 0); 104f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch close(fd); 105f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch stackBase = reinterpret_cast<void*>(threadInfo.stkbase); 106f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch stackSize = threadInfo.stksize; 107f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch ASSERT(stackBase); 108f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 109f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_bound = stackBase; 110f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_origin = static_cast<char*>(stackBase) + stackSize; 111f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 112f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 113f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#elif OS(SOLARIS) 114f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 115f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid StackBounds::initialize() 116f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 117f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch stack_t s; 118f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch thr_stksegment(&s); 119f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_origin = s.ss_sp; 120f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_bound = estimateStackBound(m_origin); 121f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 122f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 123f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#elif OS(OPENBSD) 124f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 125f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid StackBounds::initialize() 126f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 127f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch pthread_t thread = pthread_self(); 128f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch stack_t stack; 129f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch pthread_stackseg_np(thread, &stack); 130f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_origin = stack.ss_sp; 131f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_bound = estimateStackBound(m_origin); 132f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 133f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 134f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#elif OS(SYMBIAN) 135f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 136f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid StackBounds::initialize() 137f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 138f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch TThreadStackInfo info; 139f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch RThread thread; 140f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch thread.StackInfo(info); 141f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_origin = (void*)info.iBase; 142ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch m_bound = (void*)info.iLimit; 143f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 144f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 145f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#elif OS(HAIKU) 146f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 147f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid StackBounds::initialize() 148f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 149f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch thread_info threadInfo; 150f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch get_thread_info(find_thread(NULL), &threadInfo); 151f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_origin = threadInfo.stack_end; 152f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_bound = estimateStackBound(m_origin); 153f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 154f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 155f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#elif OS(UNIX) 156f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 157f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid StackBounds::initialize() 158f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 159f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch void* stackBase = 0; 160f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch size_t stackSize = 0; 161f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 162f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch pthread_t thread = pthread_self(); 163f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch pthread_attr_t sattr; 164f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch pthread_attr_init(&sattr); 165f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if HAVE(PTHREAD_NP_H) || OS(NETBSD) 166f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // e.g. on FreeBSD 5.4, neundorf@kde.org 167f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch pthread_attr_get_np(thread, &sattr); 168f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#else 169f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // FIXME: this function is non-portable; other POSIX systems may have different np alternatives 170f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch pthread_getattr_np(thread, &sattr); 171f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif 172f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int rc = pthread_attr_getstack(&sattr, &stackBase, &stackSize); 173f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch (void)rc; // FIXME: Deal with error code somehow? Seems fatal. 174f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch ASSERT(stackBase); 175f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch pthread_attr_destroy(&sattr); 176f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_bound = stackBase; 177f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_origin = static_cast<char*>(stackBase) + stackSize; 178f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 179f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 180f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#elif OS(WINCE) 181f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 182cad810f21b803229eb11403f9209855525a25d57Steve Blockstatic bool detectGrowingDownward(void* previousFrame) 183cad810f21b803229eb11403f9209855525a25d57Steve Block{ 184cad810f21b803229eb11403f9209855525a25d57Steve Block // Find the address of this stack frame by taking the address of a local variable. 185cad810f21b803229eb11403f9209855525a25d57Steve Block int thisFrame; 186cad810f21b803229eb11403f9209855525a25d57Steve Block return previousFrame > &thisFrame; 187cad810f21b803229eb11403f9209855525a25d57Steve Block} 188f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 189cad810f21b803229eb11403f9209855525a25d57Steve Blockstatic inline bool isPageWritable(void* page) 190f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 191f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch MEMORY_BASIC_INFORMATION memoryInformation; 192f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch DWORD result = VirtualQuery(page, &memoryInformation, sizeof(memoryInformation)); 193f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 194f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // return false on error, including ptr outside memory 195f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (result != sizeof(memoryInformation)) 196f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return false; 197f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 198f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch DWORD protect = memoryInformation.Protect & ~(PAGE_GUARD | PAGE_NOCACHE); 199f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return protect == PAGE_READWRITE 200f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch || protect == PAGE_WRITECOPY 201f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch || protect == PAGE_EXECUTE_READWRITE 202f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch || protect == PAGE_EXECUTE_WRITECOPY; 203f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 204f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 205cad810f21b803229eb11403f9209855525a25d57Steve Blockstatic inline void* getLowerStackBound(char* currentPage, DWORD pageSize) 206cad810f21b803229eb11403f9209855525a25d57Steve Block{ 207cad810f21b803229eb11403f9209855525a25d57Steve Block while (currentPage > 0) { 208cad810f21b803229eb11403f9209855525a25d57Steve Block // check for underflow 209cad810f21b803229eb11403f9209855525a25d57Steve Block if (currentPage >= reinterpret_cast<char*>(pageSize)) 210cad810f21b803229eb11403f9209855525a25d57Steve Block currentPage -= pageSize; 211cad810f21b803229eb11403f9209855525a25d57Steve Block else 212cad810f21b803229eb11403f9209855525a25d57Steve Block currentPage = 0; 213cad810f21b803229eb11403f9209855525a25d57Steve Block 214cad810f21b803229eb11403f9209855525a25d57Steve Block if (!isPageWritable(currentPage)) 215cad810f21b803229eb11403f9209855525a25d57Steve Block return currentPage + pageSize; 216cad810f21b803229eb11403f9209855525a25d57Steve Block } 217cad810f21b803229eb11403f9209855525a25d57Steve Block 218cad810f21b803229eb11403f9209855525a25d57Steve Block return 0; 219cad810f21b803229eb11403f9209855525a25d57Steve Block} 220cad810f21b803229eb11403f9209855525a25d57Steve Block 221cad810f21b803229eb11403f9209855525a25d57Steve Blockstatic inline void* getUpperStackBound(char* currentPage, DWORD pageSize) 222cad810f21b803229eb11403f9209855525a25d57Steve Block{ 223cad810f21b803229eb11403f9209855525a25d57Steve Block do { 224cad810f21b803229eb11403f9209855525a25d57Steve Block // guaranteed to complete because isPageWritable returns false at end of memory 225cad810f21b803229eb11403f9209855525a25d57Steve Block currentPage += pageSize; 226cad810f21b803229eb11403f9209855525a25d57Steve Block } while (isPageWritable(currentPage)); 227cad810f21b803229eb11403f9209855525a25d57Steve Block 228cad810f21b803229eb11403f9209855525a25d57Steve Block return currentPage - pageSize; 229cad810f21b803229eb11403f9209855525a25d57Steve Block} 230cad810f21b803229eb11403f9209855525a25d57Steve Block 231cad810f21b803229eb11403f9209855525a25d57Steve Blockvoid StackBounds::initialize() 232f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 233f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // find the address of this stack frame by taking the address of a local variable 234f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch void* thisFrame = &thisFrame; 235cad810f21b803229eb11403f9209855525a25d57Steve Block bool isGrowingDownward = detectGrowingDownward(thisFrame); 236f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 237f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch SYSTEM_INFO systemInfo; 238f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch GetSystemInfo(&systemInfo); 239f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch DWORD pageSize = systemInfo.dwPageSize; 240f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 241f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // scan all of memory starting from this frame, and return the last writeable page found 242cad810f21b803229eb11403f9209855525a25d57Steve Block char* currentPage = reinterpret_cast<char*>(reinterpret_cast<DWORD>(thisFrame) & ~(pageSize - 1)); 243cad810f21b803229eb11403f9209855525a25d57Steve Block void* lowerStackBound = getLowerStackBound(currentPage, pageSize); 244cad810f21b803229eb11403f9209855525a25d57Steve Block void* upperStackBound = getUpperStackBound(currentPage, pageSize); 245cad810f21b803229eb11403f9209855525a25d57Steve Block 246cad810f21b803229eb11403f9209855525a25d57Steve Block m_origin = isGrowingDownward ? upperStackBound : lowerStackBound; 247cad810f21b803229eb11403f9209855525a25d57Steve Block m_bound = isGrowingDownward ? lowerStackBound : upperStackBound; 248f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 249f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 25065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif OS(WINDOWS) 251cad810f21b803229eb11403f9209855525a25d57Steve Block 252f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid StackBounds::initialize() 253f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 25465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if CPU(X86) && COMPILER(MSVC) 25565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // offset 0x18 from the FS segment register gives a pointer to 25665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // the thread information block for the current thread 257cad810f21b803229eb11403f9209855525a25d57Steve Block NT_TIB* pTib; 258cad810f21b803229eb11403f9209855525a25d57Steve Block __asm { 259cad810f21b803229eb11403f9209855525a25d57Steve Block MOV EAX, FS:[18h] 260cad810f21b803229eb11403f9209855525a25d57Steve Block MOV pTib, EAX 261cad810f21b803229eb11403f9209855525a25d57Steve Block } 26265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch m_origin = static_cast<void*>(pTib->StackBase); 26365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(X86) && COMPILER(GCC) 26465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // offset 0x18 from the FS segment register gives a pointer to 26565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // the thread information block for the current thread 26665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch NT_TIB* pTib; 267cad810f21b803229eb11403f9209855525a25d57Steve Block asm ( "movl %%fs:0x18, %0\n" 268cad810f21b803229eb11403f9209855525a25d57Steve Block : "=r" (pTib) 269cad810f21b803229eb11403f9209855525a25d57Steve Block ); 270cad810f21b803229eb11403f9209855525a25d57Steve Block m_origin = static_cast<void*>(pTib->StackBase); 271cad810f21b803229eb11403f9209855525a25d57Steve Block#elif CPU(X86_64) 272cad810f21b803229eb11403f9209855525a25d57Steve Block PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb()); 273cad810f21b803229eb11403f9209855525a25d57Steve Block m_origin = reinterpret_cast<void*>(pTib->StackBase); 27465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else 27565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#error Need a way to get the stack bounds on this platform (Windows) 276cad810f21b803229eb11403f9209855525a25d57Steve Block#endif 27765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Looks like we should be able to get pTib->StackLimit 27865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch m_bound = estimateStackBound(m_origin); 279f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 280f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 281f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#else 28265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#error Need a way to get the stack bounds on this platform 283f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif 284f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 285f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} // namespace WTF 286