/*
 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
 *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include "config.h"
#include "StackBounds.h"

#if OS(DARWIN)

#include <mach/task.h>
#include <mach/thread_act.h>
#include <pthread.h>

#elif OS(WINDOWS)

#include <windows.h>

#elif OS(SOLARIS)

#include <thread.h>

#elif OS(QNX)

#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/procfs.h>

#elif OS(STARBOARD)

#include "starboard/memory.h"

#elif OS(UNIX)

#include <pthread.h>
#if HAVE(PTHREAD_NP_H)
#include <pthread_np.h>
#endif

#endif

namespace WTF {

// Bug 26276 - Need a mechanism to determine stack extent
//
// These platforms should now be working correctly:
//     DARWIN, QNX, UNIX
// These platforms are not:
//     WINDOWS, SOLARIS, OPENBSD, WINCE
//
// FIXME: remove this! - this code unsafely guesses at stack sizes!
#if OS(WINDOWS) || OS(SOLARIS) || OS(OPENBSD)
// Based on the current limit used by the JSC parser, guess the stack size.
static const ptrdiff_t estimatedStackSize = 128 * sizeof(void*) * 1024;
// This method assumes the stack is growing downwards.
static void* estimateStackBound(void* origin)
{
    return static_cast<char*>(origin) - estimatedStackSize;
}
#endif

#if OS(DARWIN)

void StackBounds::initialize()
{
    pthread_t thread = pthread_self();
    m_origin = pthread_get_stackaddr_np(thread);
    m_bound = static_cast<char*>(m_origin) - pthread_get_stacksize_np(thread);
}

#elif OS(QNX)

void StackBounds::initialize()
{
    void* stackBase = 0;
    size_t stackSize = 0;

    struct _debug_thread_info threadInfo;
    memset(&threadInfo, 0, sizeof(threadInfo));
    threadInfo.tid = pthread_self();
    int fd = open("/proc/self", O_RDONLY);
    if (fd == -1) {
        LOG_ERROR("Unable to open /proc/self (errno: %d)", errno);
        CRASH();
    }
    devctl(fd, DCMD_PROC_TIDSTATUS, &threadInfo, sizeof(threadInfo), 0);
    close(fd);
    stackBase = reinterpret_cast<void*>(threadInfo.stkbase);
    stackSize = threadInfo.stksize;
    ASSERT(stackBase);

    m_bound = static_cast<char*>(stackBase) + 0x1000; // 4kb guard page
    m_origin = static_cast<char*>(stackBase) + stackSize;
}

#elif OS(SOLARIS)

void StackBounds::initialize()
{
    stack_t s;
    thr_stksegment(&s);
    m_origin = s.ss_sp;
    m_bound = estimateStackBound(m_origin);
}

#elif OS(OPENBSD)

void StackBounds::initialize()
{
    pthread_t thread = pthread_self();
    stack_t stack;
    pthread_stackseg_np(thread, &stack);
    m_origin = stack.ss_sp;
    m_bound = estimateStackBound(m_origin);
}

#elif OS(STARBOARD)

void StackBounds::initialize()
{
    SbMemoryGetStackBounds(&m_origin, &m_bound);
}

#elif defined(__LB_SHELL__)

// defined in the platform library

#elif OS(UNIX)

void StackBounds::initialize()
{
    void* stackBase = 0;
    size_t stackSize = 0;

    pthread_t thread = pthread_self();
    pthread_attr_t sattr;
    pthread_attr_init(&sattr);
#if HAVE(PTHREAD_NP_H) || OS(NETBSD)
    // e.g. on FreeBSD 5.4, neundorf@kde.org
    pthread_attr_get_np(thread, &sattr);
#else
    // FIXME: this function is non-portable; other POSIX systems may have different np alternatives
    pthread_getattr_np(thread, &sattr);
#endif
    int rc = pthread_attr_getstack(&sattr, &stackBase, &stackSize);
    (void)rc; // FIXME: Deal with error code somehow? Seems fatal.
    ASSERT(stackBase);
    pthread_attr_destroy(&sattr);
    m_bound = stackBase;
    m_origin = static_cast<char*>(stackBase) + stackSize;
}

#elif OS(WINCE)

static bool detectGrowingDownward(void* previousFrame)
{
    // Find the address of this stack frame by taking the address of a local variable.
    int thisFrame;
    return previousFrame > &thisFrame;
}

static inline bool isPageWritable(void* page)
{
    MEMORY_BASIC_INFORMATION memoryInformation;
    DWORD result = VirtualQuery(page, &memoryInformation, sizeof(memoryInformation));

    // return false on error, including ptr outside memory
    if (result != sizeof(memoryInformation))
        return false;

    DWORD protect = memoryInformation.Protect & ~(PAGE_GUARD | PAGE_NOCACHE);
    return protect == PAGE_READWRITE
        || protect == PAGE_WRITECOPY
        || protect == PAGE_EXECUTE_READWRITE
        || protect == PAGE_EXECUTE_WRITECOPY;
}

static inline void* getLowerStackBound(char* currentPage, DWORD pageSize)
{
    while (currentPage > 0) {
        // check for underflow
        if (currentPage >= reinterpret_cast<char*>(pageSize))
            currentPage -= pageSize;
        else
            currentPage = 0;

        if (!isPageWritable(currentPage))
            return currentPage + pageSize;
    }

    return 0;
}

static inline void* getUpperStackBound(char* currentPage, DWORD pageSize)
{
    do {
        // guaranteed to complete because isPageWritable returns false at end of memory
        currentPage += pageSize;
    } while (isPageWritable(currentPage));

    return currentPage - pageSize;
}

void StackBounds::initialize()
{
    // find the address of this stack frame by taking the address of a local variable
    void* thisFrame = &thisFrame;
    bool isGrowingDownward = detectGrowingDownward(thisFrame);

    SYSTEM_INFO systemInfo;
    GetSystemInfo(&systemInfo);
    DWORD pageSize = systemInfo.dwPageSize;

    // scan all of memory starting from this frame, and return the last writeable page found
    char* currentPage = reinterpret_cast<char*>(reinterpret_cast<DWORD>(thisFrame) & ~(pageSize - 1));
    void* lowerStackBound = getLowerStackBound(currentPage, pageSize);
    void* upperStackBound = getUpperStackBound(currentPage, pageSize);

    m_origin = isGrowingDownward ? upperStackBound : lowerStackBound;
    m_bound = isGrowingDownward ? lowerStackBound : upperStackBound;
}

#elif OS(WINDOWS)

void StackBounds::initialize()
{
#if CPU(X86) && COMPILER(MSVC)
    // offset 0x18 from the FS segment register gives a pointer to
    // the thread information block for the current thread
    NT_TIB* pTib;
    __asm {
        MOV EAX, FS:[18h]
        MOV pTib, EAX
    }
    m_origin = static_cast<void*>(pTib->StackBase);
#elif CPU(X86) && COMPILER(GCC)
    // offset 0x18 from the FS segment register gives a pointer to
    // the thread information block for the current thread
    NT_TIB* pTib;
    asm ( "movl %%fs:0x18, %0\n"
          : "=r" (pTib)
        );
    m_origin = static_cast<void*>(pTib->StackBase);
#elif CPU(X86_64)
    PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb());
    m_origin = reinterpret_cast<void*>(pTib->StackBase);
#else
#error Need a way to get the stack bounds on this platform (Windows)
#endif
    // Looks like we should be able to get pTib->StackLimit
    m_bound = estimateStackBound(m_origin);
}

#else
#error Need a way to get the stack bounds on this platform
#endif

} // namespace WTF
