blob: 95080b92dfebd00a2e4ea9d6ff1252e856b84f20 [file] [log] [blame]
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +00001/*
2 * Copyright (C) 2017 Yusuke Suzuki <utatane.tea@gmail.com>.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "GPRInfo.h"
29#include "LLIntPCRanges.h"
utatane.tea@gmail.comfb859e82017-04-12 16:59:26 +000030#include <wtf/PlatformRegisters.h>
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +000031#include <wtf/StdLibExtras.h>
32
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +000033namespace JSC {
34namespace MachineContext {
35
utatane.tea@gmail.comfb859e82017-04-12 16:59:26 +000036void* stackPointer(const PlatformRegisters&);
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +000037
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +000038#if OS(WINDOWS) || HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com8d18a132017-06-12 00:47:18 +000039void*& stackPointer(PlatformRegisters&);
utatane.tea@gmail.comfb859e82017-04-12 16:59:26 +000040void*& framePointer(PlatformRegisters&);
41void* framePointer(const PlatformRegisters&);
42void*& instructionPointer(PlatformRegisters&);
43void* instructionPointer(const PlatformRegisters&);
44template<size_t N> void*& argumentPointer(PlatformRegisters&);
45template<size_t N> void* argumentPointer(const PlatformRegisters&);
46#if ENABLE(JIT)
47void*& llintInstructionPointer(PlatformRegisters&);
48void* llintInstructionPointer(const PlatformRegisters&);
49#endif // ENABLE(JIT)
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +000050#if HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.comfb859e82017-04-12 16:59:26 +000051void*& stackPointer(mcontext_t&);
52void* stackPointer(const mcontext_t&);
53void*& framePointer(mcontext_t&);
54void* framePointer(const mcontext_t&);
55void*& instructionPointer(mcontext_t&);
56void* instructionPointer(const mcontext_t&);
57template<size_t N> void*& argumentPointer(mcontext_t&);
58template<size_t N> void* argumentPointer(const mcontext_t&);
59#if ENABLE(JIT)
60void*& llintInstructionPointer(mcontext_t&);
61void* llintInstructionPointer(const mcontext_t&);
62#endif // ENABLE(JIT)
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +000063#endif // HAVE(MACHINE_CONTEXT)
64#endif // OS(WINDOWS) || HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +000065
utatane.tea@gmail.com8d18a132017-06-12 00:47:18 +000066#if OS(WINDOWS) || HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +000067inline void*& stackPointer(PlatformRegisters& regs)
68{
69#if OS(DARWIN)
70#if __DARWIN_UNIX03
71
72#if CPU(X86)
73 return reinterpret_cast<void*&>(regs.__esp);
74#elif CPU(X86_64)
75 return reinterpret_cast<void*&>(regs.__rsp);
76#elif CPU(PPC) || CPU(PPC64)
77 return reinterpret_cast<void*&>(regs.__r1);
78#elif CPU(ARM_THUMB2) || CPU(ARM) || CPU(ARM64)
79 return reinterpret_cast<void*&>(regs.__sp);
80#else
81#error Unknown Architecture
82#endif
83
84#else // !__DARWIN_UNIX03
85
86#if CPU(X86)
87 return reinterpret_cast<void*&>(regs.esp);
88#elif CPU(X86_64)
89 return reinterpret_cast<void*&>(regs.rsp);
90#elif CPU(PPC) || CPU(PPC64)
91 return reinterpret_cast<void*&>(regs.r1);
92#else
93#error Unknown Architecture
94#endif
95
96#endif // __DARWIN_UNIX03
97
98#elif OS(WINDOWS)
99
100#if CPU(ARM)
101 return reinterpret_cast<void*&>((uintptr_t&) regs.Sp);
102#elif CPU(MIPS)
103 return reinterpret_cast<void*&>((uintptr_t&) regs.IntSp);
104#elif CPU(X86)
105 return reinterpret_cast<void*&>((uintptr_t&) regs.Esp);
106#elif CPU(X86_64)
107 return reinterpret_cast<void*&>((uintptr_t&) regs.Rsp);
108#else
109#error Unknown Architecture
110#endif
111
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000112#elif HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.comfb859e82017-04-12 16:59:26 +0000113 return stackPointer(regs.machineContext);
utatane.tea@gmail.comfb859e82017-04-12 16:59:26 +0000114#endif
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000115}
116
117inline void* stackPointer(const PlatformRegisters& regs)
118{
119 return stackPointer(const_cast<PlatformRegisters&>(regs));
120}
utatane.tea@gmail.com8d18a132017-06-12 00:47:18 +0000121#else // not OS(WINDOWS) || HAVE(MACHINE_CONTEXT)
122inline void* stackPointer(const PlatformRegisters& regs)
123{
124 return regs.stackPointer;
125}
126#endif // OS(WINDOWS) || HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000127
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000128#if HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000129inline void*& stackPointer(mcontext_t& machineContext)
130{
131#if OS(DARWIN)
132 return stackPointer(machineContext->__ss);
133#elif OS(FREEBSD)
134
135#if CPU(X86)
136 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_esp);
137#elif CPU(X86_64)
138 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_rsp);
139#elif CPU(ARM)
140 return reinterpret_cast<void*&>((uintptr_t&) machineContext.__gregs[_REG_SP]);
141#elif CPU(ARM64)
142 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_gpregs.gp_sp);
143#elif CPU(MIPS)
144 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_regs[29]);
145#else
146#error Unknown Architecture
147#endif
148
149#elif defined(__GLIBC__)
150
151#if CPU(X86)
152 return reinterpret_cast<void*&>((uintptr_t&) machineContext.gregs[REG_ESP]);
153#elif CPU(X86_64)
154 return reinterpret_cast<void*&>((uintptr_t&) machineContext.gregs[REG_RSP]);
155#elif CPU(ARM)
156 return reinterpret_cast<void*&>((uintptr_t&) machineContext.arm_sp);
157#elif CPU(ARM64)
158 return reinterpret_cast<void*&>((uintptr_t&) machineContext.sp);
159#elif CPU(MIPS)
160 return reinterpret_cast<void*&>((uintptr_t&) machineContext.gregs[29]);
161#else
162#error Unknown Architecture
163#endif
164#endif
165}
166
167inline void* stackPointer(const mcontext_t& machineContext)
168{
169 return stackPointer(const_cast<mcontext_t&>(machineContext));
170}
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000171#endif // HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000172
173
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000174#if OS(WINDOWS) || HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000175inline void*& framePointer(PlatformRegisters& regs)
176{
177#if OS(DARWIN)
178
179#if __DARWIN_UNIX03
180
181#if CPU(X86)
182 return reinterpret_cast<void*&>(regs.__ebp);
183#elif CPU(X86_64)
184 return reinterpret_cast<void*&>(regs.__rbp);
185#elif CPU(ARM_THUMB2)
186 return reinterpret_cast<void*&>(regs.__r[7]);
187#elif CPU(ARM)
188 return reinterpret_cast<void*&>(regs.__r[11]);
189#elif CPU(ARM64)
190 return reinterpret_cast<void*&>(regs.__x[29]);
191#else
192#error Unknown Architecture
193#endif
194
195#else // !__DARWIN_UNIX03
196
197#if CPU(X86)
198 return reinterpret_cast<void*&>(regs.esp);
199#elif CPU(X86_64)
200 return reinterpret_cast<void*&>(regs.rsp);
201#else
202#error Unknown Architecture
203#endif
204
205#endif // __DARWIN_UNIX03
206
207#elif OS(WINDOWS)
208
209#if CPU(ARM)
210 return reinterpret_cast<void*&>((uintptr_t&) regs.R11);
211#elif CPU(MIPS)
212#error Dont know what to do with mips. Do we even need this?
213#elif CPU(X86)
214 return reinterpret_cast<void*&>((uintptr_t&) regs.Ebp);
215#elif CPU(X86_64)
216 return reinterpret_cast<void*&>((uintptr_t&) regs.Rbp);
217#else
218#error Unknown Architecture
219#endif
220
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000221#elif HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.comfb859e82017-04-12 16:59:26 +0000222 return framePointer(regs.machineContext);
223#endif
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000224}
225
226inline void* framePointer(const PlatformRegisters& regs)
227{
228 return framePointer(const_cast<PlatformRegisters&>(regs));
229}
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000230#endif // OS(WINDOWS) || HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000231
232
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000233#if HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000234inline void*& framePointer(mcontext_t& machineContext)
235{
236#if OS(DARWIN)
237 return framePointer(machineContext->__ss);
238#elif OS(FREEBSD)
239
240#if CPU(X86)
241 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_ebp);
242#elif CPU(X86_64)
243 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_rbp);
244#elif CPU(ARM)
245 return reinterpret_cast<void*&>((uintptr_t&) machineContext.__gregs[_REG_FP]);
246#elif CPU(ARM64)
247 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_gpregs.gp_x[29]);
248#elif CPU(MIPS)
249 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_regs[30]);
250#else
251#error Unknown Architecture
252#endif
253
254#elif defined(__GLIBC__)
255
256// The following sequence depends on glibc's sys/ucontext.h.
257#if CPU(X86)
258 return reinterpret_cast<void*&>((uintptr_t&) machineContext.gregs[REG_EBP]);
259#elif CPU(X86_64)
260 return reinterpret_cast<void*&>((uintptr_t&) machineContext.gregs[REG_RBP]);
261#elif CPU(ARM)
262 return reinterpret_cast<void*&>((uintptr_t&) machineContext.arm_fp);
263#elif CPU(ARM64)
264 return reinterpret_cast<void*&>((uintptr_t&) machineContext.regs[29]);
265#elif CPU(MIPS)
266 return reinterpret_cast<void*&>((uintptr_t&) machineContext.gregs[30]);
267#else
268#error Unknown Architecture
269#endif
270
271#else
272#error Need a way to get the frame pointer for another thread on this platform
273#endif
274}
275
276inline void* framePointer(const mcontext_t& machineContext)
277{
278 return framePointer(const_cast<mcontext_t&>(machineContext));
279}
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000280#endif // HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000281
282
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000283#if OS(WINDOWS) || HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000284inline void*& instructionPointer(PlatformRegisters& regs)
285{
286#if OS(DARWIN)
287#if __DARWIN_UNIX03
288
289#if CPU(X86)
290 return reinterpret_cast<void*&>(regs.__eip);
291#elif CPU(X86_64)
292 return reinterpret_cast<void*&>(regs.__rip);
293#elif CPU(ARM_THUMB2) || CPU(ARM) || CPU(ARM64)
294 return reinterpret_cast<void*&>(regs.__pc);
295#else
296#error Unknown Architecture
297#endif
298
299#else // !__DARWIN_UNIX03
300#if CPU(X86)
301 return reinterpret_cast<void*&>(regs.eip);
302#elif CPU(X86_64)
303 return reinterpret_cast<void*&>(regs.rip);
304#else
305#error Unknown Architecture
306#endif
307
308#endif // __DARWIN_UNIX03
309
310#elif OS(WINDOWS)
311
312#if CPU(ARM)
313 return reinterpret_cast<void*&>((uintptr_t&) regs.Pc);
314#elif CPU(MIPS)
315#error Dont know what to do with mips. Do we even need this?
316#elif CPU(X86)
317 return reinterpret_cast<void*&>((uintptr_t&) regs.Eip);
318#elif CPU(X86_64)
319 return reinterpret_cast<void*&>((uintptr_t&) regs.Rip);
320#else
321#error Unknown Architecture
322#endif
323
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000324#elif HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.comfb859e82017-04-12 16:59:26 +0000325 return instructionPointer(regs.machineContext);
326#endif
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000327}
328
329inline void* instructionPointer(const PlatformRegisters& regs)
330{
331 return instructionPointer(const_cast<PlatformRegisters&>(regs));
332}
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000333#endif // OS(WINDOWS) || HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000334
335
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000336#if HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000337inline void*& instructionPointer(mcontext_t& machineContext)
338{
339#if OS(DARWIN)
340 return instructionPointer(machineContext->__ss);
341#elif OS(FREEBSD)
342
343#if CPU(X86)
344 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_eip);
345#elif CPU(X86_64)
346 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_rip);
347#elif CPU(ARM)
348 return reinterpret_cast<void*&>((uintptr_t&) machineContext.__gregs[_REG_PC]);
349#elif CPU(ARM64)
350 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_gpregs.gp_elr);
351#elif CPU(MIPS)
352 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_pc);
353#else
354#error Unknown Architecture
355#endif
356
357#elif defined(__GLIBC__)
358
359// The following sequence depends on glibc's sys/ucontext.h.
360#if CPU(X86)
361 return reinterpret_cast<void*&>((uintptr_t&) machineContext.gregs[REG_EIP]);
362#elif CPU(X86_64)
363 return reinterpret_cast<void*&>((uintptr_t&) machineContext.gregs[REG_RIP]);
364#elif CPU(ARM)
365 return reinterpret_cast<void*&>((uintptr_t&) machineContext.arm_pc);
366#elif CPU(ARM64)
367 return reinterpret_cast<void*&>((uintptr_t&) machineContext.pc);
368#elif CPU(MIPS)
369 return reinterpret_cast<void*&>((uintptr_t&) machineContext.pc);
370#else
371#error Unknown Architecture
372#endif
373
374#else
375#error Need a way to get the instruction pointer for another thread on this platform
376#endif
377}
378
379inline void* instructionPointer(const mcontext_t& machineContext)
380{
381 return instructionPointer(const_cast<mcontext_t&>(machineContext));
382}
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000383#endif // HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000384
385
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000386#if OS(WINDOWS) || HAVE(MACHINE_CONTEXT)
387#if HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.comfb859e82017-04-12 16:59:26 +0000388template<> void*& argumentPointer<1>(mcontext_t&);
389#endif
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000390
391template<>
392inline void*& argumentPointer<1>(PlatformRegisters& regs)
393{
394#if OS(DARWIN)
395#if __DARWIN_UNIX03
396
397#if CPU(X86)
398 return reinterpret_cast<void*&>(regs.__edx);
399#elif CPU(X86_64)
400 return reinterpret_cast<void*&>(regs.__rsi);
401#elif CPU(ARM_THUMB2) || CPU(ARM)
402 return reinterpret_cast<void*&>(regs.__r[1]);
403#elif CPU(ARM64)
404 return reinterpret_cast<void*&>(regs.__x[1]);
405#else
406#error Unknown Architecture
407#endif
408
409#else // !__DARWIN_UNIX03
410
411#if CPU(X86)
412 return reinterpret_cast<void*&>(regs.edx);
413#elif CPU(X86_64)
414 return reinterpret_cast<void*&>(regs.rsi);
415#else
416#error Unknown Architecture
417#endif
418
419#endif // __DARWIN_UNIX03
420
421#elif OS(WINDOWS)
422
423#if CPU(ARM)
424 return reinterpret_cast<void*&>((uintptr_t&) regs.R1);
425#elif CPU(MIPS)
426#error Dont know what to do with mips. Do we even need this?
427#elif CPU(X86)
428 return reinterpret_cast<void*&>((uintptr_t&) regs.Edx);
429#elif CPU(X86_64)
430 return reinterpret_cast<void*&>((uintptr_t&) regs.Rdx);
431#else
432#error Unknown Architecture
433#endif
434
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000435#elif HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.comfb859e82017-04-12 16:59:26 +0000436 return argumentPointer<1>(regs.machineContext);
437#endif
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000438}
439
440template<size_t N>
441inline void* argumentPointer(const PlatformRegisters& regs)
442{
443 return argumentPointer<N>(const_cast<PlatformRegisters&>(regs));
444}
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000445#endif // OS(WINDOWS) || HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000446
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000447#if HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000448template<>
449inline void*& argumentPointer<1>(mcontext_t& machineContext)
450{
451#if OS(DARWIN)
452 return argumentPointer<1>(machineContext->__ss);
453#elif OS(FREEBSD)
454
455#if CPU(X86)
456 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_edx);
457#elif CPU(X86_64)
458 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_rsi);
459#elif CPU(ARM)
460 return reinterpret_cast<void*&>((uintptr_t&) machineContext.__gregs[_REG_R1]);
461#elif CPU(ARM64)
462 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_gpregs.gp_x[1]);
463#elif CPU(MIPS)
464 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_regs[5]);
465#else
466#error Unknown Architecture
467#endif
468
469#elif defined(__GLIBC__)
470
471// The following sequence depends on glibc's sys/ucontext.h.
472#if CPU(X86)
473 return reinterpret_cast<void*&>((uintptr_t&) machineContext.gregs[REG_EDX]);
474#elif CPU(X86_64)
475 return reinterpret_cast<void*&>((uintptr_t&) machineContext.gregs[REG_RSI]);
476#elif CPU(ARM)
477 return reinterpret_cast<void*&>((uintptr_t&) machineContext.arm_r1);
478#elif CPU(ARM64)
479 return reinterpret_cast<void*&>((uintptr_t&) machineContext.regs[1]);
480#elif CPU(MIPS)
481 return reinterpret_cast<void*&>((uintptr_t&) machineContext.gregs[5]);
482#else
483#error Unknown Architecture
484#endif
485
486#else
487#error Need a way to get the frame pointer for another thread on this platform
488#endif
489}
490
491template<unsigned N>
492inline void* argumentPointer(const mcontext_t& machineContext)
493{
494 return argumentPointer<N>(const_cast<mcontext_t&>(machineContext));
495}
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000496#endif // HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000497
498#if ENABLE(JIT)
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000499#if OS(WINDOWS) || HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000500inline void*& llintInstructionPointer(PlatformRegisters& regs)
501{
502 // LLInt uses regT4 as PC.
503#if OS(DARWIN)
504#if __DARWIN_UNIX03
505
506#if CPU(X86)
507 static_assert(LLInt::LLIntPC == X86Registers::esi, "Wrong LLInt PC.");
508 return reinterpret_cast<void*&>(regs.__esi);
509#elif CPU(X86_64)
510 static_assert(LLInt::LLIntPC == X86Registers::r8, "Wrong LLInt PC.");
511 return reinterpret_cast<void*&>(regs.__r8);
512#elif CPU(ARM)
513 static_assert(LLInt::LLIntPC == ARMRegisters::r8, "Wrong LLInt PC.");
514 return reinterpret_cast<void*&>(regs.__r[8]);
515#elif CPU(ARM64)
516 static_assert(LLInt::LLIntPC == ARM64Registers::x4, "Wrong LLInt PC.");
517 return reinterpret_cast<void*&>(regs.__x[4]);
518#else
519#error Unknown Architecture
520#endif
521
522#else // !__DARWIN_UNIX03
523#if CPU(X86)
524 static_assert(LLInt::LLIntPC == X86Registers::esi, "Wrong LLInt PC.");
525 return reinterpret_cast<void*&>(regs.esi);
526#elif CPU(X86_64)
527 static_assert(LLInt::LLIntPC == X86Registers::r8, "Wrong LLInt PC.");
528 return reinterpret_cast<void*&>(regs.r8);
529#else
530#error Unknown Architecture
531#endif
532
533#endif // __DARWIN_UNIX03
534
535#elif OS(WINDOWS)
536
537#if CPU(ARM)
538 static_assert(LLInt::LLIntPC == ARMRegisters::r8, "Wrong LLInt PC.");
539 return reinterpret_cast<void*&>((uintptr_t&) regs.R8);
540#elif CPU(MIPS)
541#error Dont know what to do with mips. Do we even need this?
542#elif CPU(X86)
543 static_assert(LLInt::LLIntPC == X86Registers::esi, "Wrong LLInt PC.");
544 return reinterpret_cast<void*&>((uintptr_t&) regs.Esi);
545#elif CPU(X86_64)
546 static_assert(LLInt::LLIntPC == X86Registers::r10, "Wrong LLInt PC.");
547 return reinterpret_cast<void*&>((uintptr_t&) regs.R10);
548#else
549#error Unknown Architecture
550#endif
551
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000552#elif HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.comfb859e82017-04-12 16:59:26 +0000553 return llintInstructionPointer(regs.machineContext);
554#endif
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000555}
556
557inline void* llintInstructionPointer(const PlatformRegisters& regs)
558{
559 return llintInstructionPointer(const_cast<PlatformRegisters&>(regs));
560}
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000561#endif // OS(WINDOWS) || HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000562
563
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000564#if HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000565inline void*& llintInstructionPointer(mcontext_t& machineContext)
566{
567 // LLInt uses regT4 as PC.
568#if OS(DARWIN)
569 return llintInstructionPointer(machineContext->__ss);
570#elif OS(FREEBSD)
571
572#if CPU(X86)
573 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_esi);
574#elif CPU(X86_64)
575 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_r8);
576#elif CPU(ARM)
577 return reinterpret_cast<void*&>((uintptr_t&) machineContext.__gregs[_REG_R8]);
578#elif CPU(ARM64)
579 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_gpregs.gp_x[4]);
580#elif CPU(MIPS)
581 return reinterpret_cast<void*&>((uintptr_t&) machineContext.mc_regs[12]);
582#else
583#error Unknown Architecture
584#endif
585
586#elif defined(__GLIBC__)
587
588// The following sequence depends on glibc's sys/ucontext.h.
589#if CPU(X86)
590 return reinterpret_cast<void*&>((uintptr_t&) machineContext.gregs[REG_ESI]);
591#elif CPU(X86_64)
592 return reinterpret_cast<void*&>((uintptr_t&) machineContext.gregs[REG_R8]);
593#elif CPU(ARM)
594 return reinterpret_cast<void*&>((uintptr_t&) machineContext.arm_r8);
595#elif CPU(ARM64)
596 return reinterpret_cast<void*&>((uintptr_t&) machineContext.regs[4]);
597#elif CPU(MIPS)
598 return reinterpret_cast<void*&>((uintptr_t&) machineContext.gregs[12]);
599#else
600#error Unknown Architecture
601#endif
602
603#else
604#error Need a way to get the LLIntPC for another thread on this platform
605#endif
606}
607
608inline void* llintInstructionPointer(const mcontext_t& machineContext)
609{
610 return llintInstructionPointer(const_cast<mcontext_t&>(machineContext));
611}
utatane.tea@gmail.com96de3282017-04-12 17:19:57 +0000612#endif // HAVE(MACHINE_CONTEXT)
utatane.tea@gmail.com68a697f2017-03-14 07:33:08 +0000613#endif // ENABLE(JIT)
614
615}
616}