Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qv4functiontable_win64.cpp
Go to the documentation of this file.
1// Copyright (C) 2018 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <assembler/MacroAssemblerCodeRef.h>
7
8#include <QtCore/qdebug.h>
9
10#include <qt_windows.h>
11
13
14namespace QV4 {
15
16enum UnwindOpcode: UINT8
17{
18 UWOP_PUSH_NONVOL = 0, /* info == register number */
19 UWOP_ALLOC_LARGE, /* no info, alloc size in next 2 slots */
20 UWOP_ALLOC_SMALL, /* info == size of allocation / 8 - 1 */
21 UWOP_SET_FPREG, /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */
22 UWOP_SAVE_NONVOL, /* info == register number, offset in next slot */
23 UWOP_SAVE_NONVOL_FAR, /* info == register number, offset in next 2 slots */
24 UWOP_SAVE_XMM128 = 8, /* info == XMM reg number, offset in next slot */
25 UWOP_SAVE_XMM128_FAR, /* info == XMM reg number, offset in next 2 slots */
26 UWOP_PUSH_MACHFRAME /* info == 0: no error-code, 1: error-code */
27};
28
29enum Register : UINT8
30{
31 RAX = 0,
39 NONE = 15
40};
41
52
54{
55 UINT8 Version : 3;
56 UINT8 Flags : 5;
59 UINT8 FrameRegister : 4;
62};
63
65{
66 RUNTIME_FUNCTION handler;
68};
69
70void generateFunctionTable(Function *, JSC::MacroAssemblerCodeRef *codeRef)
71{
73 codeRef->executableMemory()->exceptionHandlerStart());
74
75 record->info.Version = 1;
76 record->info.Flags = 0;
77 record->info.SizeOfProlog = 4;
78 record->info.CountOfUnwindCodes = 2;
79 record->info.FrameRegister = RBP;
80 record->info.FrameRegisterOffset = 0;
81
82 // Push frame pointer
83 record->info.UnwindCodes[1] = UnwindCode(1, UWOP_PUSH_NONVOL, RBP);
84 // Set frame pointer from stack pointer
85 record->info.UnwindCodes[0] = UnwindCode(4, UWOP_SET_FPREG, NONE);
86
87 const quintptr codeStart = quintptr(codeRef->code().executableAddress());
88 const quintptr codeSize = codeRef->size();
89
90 record->handler.BeginAddress = DWORD(codeStart - quintptr(record));
91 record->handler.EndAddress = DWORD(codeStart + codeSize - quintptr(record));
92 record->handler.UnwindData = offsetof(ExceptionHandlerRecord, info);
93
94 if (!RtlAddFunctionTable(&record->handler, 1, DWORD64(record))) {
95 const unsigned int errorCode = GetLastError();
96 qWarning() << "Failed to install win64 unwind hook. Error code:" << errorCode;
97 }
98}
99
100void destroyFunctionTable(Function *, JSC::MacroAssemblerCodeRef *codeRef)
101{
102 ExceptionHandlerRecord *record = reinterpret_cast<ExceptionHandlerRecord *>(
103 codeRef->executableMemory()->exceptionHandlerStart());
104 if (!RtlDeleteFunctionTable(&record->handler)) {
105 const unsigned int errorCode = GetLastError();
106 qWarning() << "Failed to remove win64 unwind hook. Error code:" << errorCode;
107 }
108}
109
111{
112 return sizeof(ExceptionHandlerRecord);
113}
114
115} // QV4
116
Combined button and popup list for selecting options.
size_t exceptionHandlerSize()
void generateFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef)
void destroyFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef)
#define qWarning
Definition qlogging.h:166
GLenum GLuint GLintptr offset
size_t quintptr
Definition qtypes.h:167
MyRecord record(int row) const
[0]
QHostInfo info
[0]
UnwindCode(UINT8 offset, UnwindOpcode operation, Register info)