1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 et sw=4 tw=80:
3 : */
4 : /* ***** BEGIN LICENSE BLOCK *****
5 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 : *
7 : * The contents of this file are subject to the Mozilla Public License Version
8 : * 1.1 (the "License"); you may not use this file except in compliance with
9 : * the License. You may obtain a copy of the License at
10 : * http://www.mozilla.org/MPL/
11 : *
12 : * Software distributed under the License is distributed on an "AS IS" basis,
13 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 : * for the specific language governing rights and limitations under the
15 : * License.
16 : *
17 : * The Original Code is Mozilla code.
18 : *
19 : * The Initial Developer of the Original Code is the Mozilla Corporation.
20 : * Portions created by the Initial Developer are Copyright (C) 2009
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include <stdlib.h>
40 : #include "jstypes.h"
41 : #include "jsnativestack.h"
42 :
43 : #ifdef XP_WIN
44 : # include "jswin.h"
45 :
46 : #elif defined(XP_OS2)
47 : # define INCL_DOSPROCESS
48 : # include <os2.h>
49 :
50 : #elif defined(XP_MACOSX) || defined(DARWIN) || defined(XP_UNIX)
51 : # include <pthread.h>
52 :
53 : # if defined(__FreeBSD__) || defined(__OpenBSD__)
54 : # include <pthread_np.h>
55 : # endif
56 :
57 : #else
58 : # error "Unsupported platform"
59 :
60 : #endif
61 :
62 : namespace js {
63 :
64 : #if defined(XP_WIN)
65 :
66 : void *
67 : GetNativeStackBaseImpl()
68 : {
69 : # if defined(_M_IX86) && defined(_MSC_VER)
70 : /*
71 : * offset 0x18 from the FS segment register gives a pointer to
72 : * the thread information block for the current thread
73 : */
74 : NT_TIB* pTib;
75 : __asm {
76 : MOV EAX, FS:[18h]
77 : MOV pTib, EAX
78 : }
79 : return static_cast<void*>(pTib->StackBase);
80 :
81 : # elif defined(_M_X64)
82 : PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb());
83 : return reinterpret_cast<void*>(pTib->StackBase);
84 :
85 : # elif defined(_WIN32) && defined(__GNUC__)
86 : NT_TIB* pTib;
87 : asm ("movl %%fs:0x18, %0\n" : "=r" (pTib));
88 : return static_cast<void*>(pTib->StackBase);
89 :
90 : # endif
91 : }
92 :
93 : #elif defined(SOLARIS)
94 :
95 : #include <ucontext.h>
96 :
97 : JS_STATIC_ASSERT(JS_STACK_GROWTH_DIRECTION < 0);
98 :
99 : void *
100 : GetNativeStackBaseImpl()
101 : {
102 : stack_t st;
103 : stack_getbounds(&st);
104 : return static_cast<char*>(st.ss_sp) + st.ss_size;
105 : }
106 :
107 : #elif defined(AIX)
108 :
109 : #include <ucontext.h>
110 :
111 : JS_STATIC_ASSERT(JS_STACK_GROWTH_DIRECTION < 0);
112 :
113 : void *
114 : GetNativeStackBaseImpl()
115 : {
116 : ucontext_t context;
117 : getcontext(&context);
118 : return static_cast<char*>(context.uc_stack.ss_sp) +
119 : context.uc_stack.ss_size;
120 : }
121 :
122 : #elif defined(XP_OS2)
123 :
124 : void *
125 : GetNativeStackBaseImpl()
126 : {
127 : PTIB ptib;
128 : PPIB ppib;
129 :
130 : DosGetInfoBlocks(&ptib, &ppib);
131 : return ptib->tib_pstacklimit;
132 : }
133 :
134 : #else /* XP_UNIX */
135 :
136 : void *
137 19916 : GetNativeStackBaseImpl()
138 : {
139 19916 : pthread_t thread = pthread_self();
140 : # if defined(XP_MACOSX) || defined(DARWIN)
141 : return pthread_get_stackaddr_np(thread);
142 :
143 : # else
144 : pthread_attr_t sattr;
145 19916 : pthread_attr_init(&sattr);
146 : # if defined(__OpenBSD__)
147 : stack_t ss;
148 : # elif defined(PTHREAD_NP_H) || defined(_PTHREAD_NP_H_) || defined(NETBSD)
149 : /* e.g. on FreeBSD 4.8 or newer, neundorf@kde.org */
150 : pthread_attr_get_np(thread, &sattr);
151 : # else
152 : /*
153 : * FIXME: this function is non-portable;
154 : * other POSIX systems may have different np alternatives
155 : */
156 19916 : pthread_getattr_np(thread, &sattr);
157 : # endif
158 :
159 19916 : void *stackBase = 0;
160 19916 : size_t stackSize = 0;
161 : # ifdef DEBUG
162 : int rc =
163 : # endif
164 : # if defined(__OpenBSD__)
165 : pthread_stackseg_np(pthread_self(), &ss);
166 : stackBase = (void*)((size_t) ss.ss_sp - ss.ss_size);
167 : stackSize = ss.ss_size;
168 : # else
169 19916 : pthread_attr_getstack(&sattr, &stackBase, &stackSize);
170 : # endif
171 19916 : JS_ASSERT(!rc);
172 19916 : JS_ASSERT(stackBase);
173 19916 : pthread_attr_destroy(&sattr);
174 :
175 : # if JS_STACK_GROWTH_DIRECTION > 0
176 : return stackBase;
177 : # else
178 19916 : return static_cast<char*>(stackBase) + stackSize;
179 : # endif
180 : # endif
181 : }
182 :
183 : #endif /* !XP_WIN */
184 :
185 : } /* namespace js */
|