Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/os/windows/vm/decoder_windows.cpp
32285 views
1
/*
2
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#include "precompiled.hpp"
26
#include "prims/jvm.h"
27
#include "runtime/arguments.hpp"
28
#include "decoder_windows.hpp"
29
30
WindowsDecoder::WindowsDecoder() {
31
_dbghelp_handle = NULL;
32
_can_decode_in_vm = false;
33
_pfnSymGetSymFromAddr64 = NULL;
34
_pfnUndecorateSymbolName = NULL;
35
#ifdef AMD64
36
_pfnStackWalk64 = NULL;
37
_pfnSymFunctionTableAccess64 = NULL;
38
_pfnSymGetModuleBase64 = NULL;
39
#endif
40
_decoder_status = no_error;
41
initialize();
42
}
43
44
void WindowsDecoder::initialize() {
45
if (!has_error() && _dbghelp_handle == NULL) {
46
HMODULE handle = ::LoadLibrary("dbghelp.dll");
47
if (!handle) {
48
_decoder_status = helper_not_found;
49
return;
50
}
51
52
_dbghelp_handle = handle;
53
54
pfn_SymSetOptions _pfnSymSetOptions = (pfn_SymSetOptions)::GetProcAddress(handle, "SymSetOptions");
55
pfn_SymInitialize _pfnSymInitialize = (pfn_SymInitialize)::GetProcAddress(handle, "SymInitialize");
56
_pfnSymGetSymFromAddr64 = (pfn_SymGetSymFromAddr64)::GetProcAddress(handle, "SymGetSymFromAddr64");
57
_pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)::GetProcAddress(handle, "UnDecorateSymbolName");
58
59
if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) {
60
uninitialize();
61
_decoder_status = helper_func_error;
62
return;
63
}
64
65
#ifdef AMD64
66
_pfnStackWalk64 = (pfn_StackWalk64)::GetProcAddress(handle, "StackWalk64");
67
_pfnSymFunctionTableAccess64 = (pfn_SymFunctionTableAccess64)::GetProcAddress(handle, "SymFunctionTableAccess64");
68
_pfnSymGetModuleBase64 = (pfn_SymGetModuleBase64)::GetProcAddress(handle, "SymGetModuleBase64");
69
if (_pfnStackWalk64 == NULL || _pfnSymFunctionTableAccess64 == NULL || _pfnSymGetModuleBase64 == NULL) {
70
// We can't call StackWalk64 to walk the stack, but we are still
71
// able to decode the symbols. Let's limp on.
72
_pfnStackWalk64 = NULL;
73
_pfnSymFunctionTableAccess64 = NULL;
74
_pfnSymGetModuleBase64 = NULL;
75
}
76
#endif
77
78
HANDLE hProcess = ::GetCurrentProcess();
79
_pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS);
80
if (!_pfnSymInitialize(hProcess, NULL, TRUE)) {
81
_pfnSymGetSymFromAddr64 = NULL;
82
_pfnUndecorateSymbolName = NULL;
83
::FreeLibrary(handle);
84
_dbghelp_handle = NULL;
85
_decoder_status = helper_init_error;
86
return;
87
}
88
89
// set pdb search paths
90
pfn_SymSetSearchPath _pfn_SymSetSearchPath =
91
(pfn_SymSetSearchPath)::GetProcAddress(handle, "SymSetSearchPath");
92
pfn_SymGetSearchPath _pfn_SymGetSearchPath =
93
(pfn_SymGetSearchPath)::GetProcAddress(handle, "SymGetSearchPath");
94
if (_pfn_SymSetSearchPath != NULL && _pfn_SymGetSearchPath != NULL) {
95
char paths[MAX_PATH];
96
int len = sizeof(paths);
97
if (!_pfn_SymGetSearchPath(hProcess, paths, len)) {
98
paths[0] = '\0';
99
} else {
100
// available spaces in path buffer
101
len -= (int)strlen(paths);
102
}
103
104
char tmp_path[MAX_PATH];
105
DWORD dwSize;
106
HMODULE hJVM = ::GetModuleHandle("jvm.dll");
107
tmp_path[0] = '\0';
108
// append the path where jvm.dll is located
109
if (hJVM != NULL && (dwSize = ::GetModuleFileName(hJVM, tmp_path, sizeof(tmp_path))) > 0) {
110
while (dwSize > 0 && tmp_path[dwSize] != '\\') {
111
dwSize --;
112
}
113
114
tmp_path[dwSize] = '\0';
115
116
if (dwSize > 0 && len > (int)dwSize + 1) {
117
strncat(paths, os::path_separator(), 1);
118
strncat(paths, tmp_path, dwSize);
119
len -= dwSize + 1;
120
}
121
}
122
123
// append $JRE/bin. Arguments::get_java_home actually returns $JRE
124
// path
125
char *p = Arguments::get_java_home();
126
assert(p != NULL, "empty java home");
127
size_t java_home_len = strlen(p);
128
if (len > (int)java_home_len + 5) {
129
strncat(paths, os::path_separator(), 1);
130
strncat(paths, p, java_home_len);
131
strncat(paths, "\\bin", 4);
132
len -= (int)(java_home_len + 5);
133
}
134
135
// append $JDK/bin path if it exists
136
assert(java_home_len < MAX_PATH, "Invalid path length");
137
// assume $JRE is under $JDK, construct $JDK/bin path and
138
// see if it exists or not
139
if (strncmp(&p[java_home_len - 3], "jre", 3) == 0) {
140
strncpy(tmp_path, p, java_home_len - 3);
141
tmp_path[java_home_len - 3] = '\0';
142
strncat(tmp_path, "bin", 3);
143
144
// if the directory exists
145
DWORD dwAttrib = GetFileAttributes(tmp_path);
146
if (dwAttrib != INVALID_FILE_ATTRIBUTES &&
147
(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) {
148
// tmp_path should have the same length as java_home_len, since we only
149
// replaced 'jre' with 'bin'
150
if (len > (int)java_home_len + 1) {
151
strncat(paths, os::path_separator(), 1);
152
strncat(paths, tmp_path, java_home_len);
153
}
154
}
155
}
156
157
_pfn_SymSetSearchPath(hProcess, paths);
158
}
159
160
// find out if jvm.dll contains private symbols, by decoding
161
// current function and comparing the result
162
address addr = (address)Decoder::demangle;
163
char buf[MAX_PATH];
164
if (decode(addr, buf, sizeof(buf), NULL)) {
165
_can_decode_in_vm = !strcmp(buf, "Decoder::demangle");
166
}
167
}
168
}
169
170
void WindowsDecoder::uninitialize() {
171
_pfnSymGetSymFromAddr64 = NULL;
172
_pfnUndecorateSymbolName = NULL;
173
#ifdef AMD64
174
_pfnStackWalk64 = NULL;
175
_pfnSymFunctionTableAccess64 = NULL;
176
_pfnSymGetModuleBase64 = NULL;
177
#endif
178
if (_dbghelp_handle != NULL) {
179
::FreeLibrary(_dbghelp_handle);
180
}
181
_dbghelp_handle = NULL;
182
}
183
184
bool WindowsDecoder::can_decode_C_frame_in_vm() const {
185
return (!has_error() && _can_decode_in_vm);
186
}
187
188
189
bool WindowsDecoder::decode(address addr, char *buf, int buflen, int* offset, const char* modulepath) {
190
if (_pfnSymGetSymFromAddr64 != NULL) {
191
PIMAGEHLP_SYMBOL64 pSymbol;
192
char symbolInfo[MAX_PATH + sizeof(IMAGEHLP_SYMBOL64)];
193
pSymbol = (PIMAGEHLP_SYMBOL64)symbolInfo;
194
pSymbol->MaxNameLength = MAX_PATH;
195
pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
196
DWORD64 displacement;
197
if (_pfnSymGetSymFromAddr64(::GetCurrentProcess(), (DWORD64)addr, &displacement, pSymbol)) {
198
if (buf != NULL) {
199
if (demangle(pSymbol->Name, buf, buflen)) {
200
jio_snprintf(buf, buflen, "%s", pSymbol->Name);
201
}
202
}
203
if(offset != NULL) *offset = (int)displacement;
204
return true;
205
}
206
}
207
if (buf != NULL && buflen > 0) buf[0] = '\0';
208
if (offset != NULL) *offset = -1;
209
return false;
210
}
211
212
bool WindowsDecoder::demangle(const char* symbol, char *buf, int buflen) {
213
return _pfnUndecorateSymbolName != NULL &&
214
_pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE);
215
}
216
217
#ifdef AMD64
218
BOOL WindowsDbgHelp::StackWalk64(DWORD MachineType,
219
HANDLE hProcess,
220
HANDLE hThread,
221
LPSTACKFRAME64 StackFrame,
222
PVOID ContextRecord,
223
PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
224
PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
225
PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
226
PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress) {
227
DecoderLocker locker;
228
WindowsDecoder* wd = (WindowsDecoder*)locker.decoder();
229
230
if (!wd->has_error() && wd->_pfnStackWalk64) {
231
return wd->_pfnStackWalk64(MachineType,
232
hProcess,
233
hThread,
234
StackFrame,
235
ContextRecord,
236
ReadMemoryRoutine,
237
FunctionTableAccessRoutine,
238
GetModuleBaseRoutine,
239
TranslateAddress);
240
} else {
241
return false;
242
}
243
}
244
245
PVOID WindowsDbgHelp::SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase) {
246
DecoderLocker locker;
247
WindowsDecoder* wd = (WindowsDecoder*)locker.decoder();
248
249
if (!wd->has_error() && wd->_pfnSymFunctionTableAccess64) {
250
return wd->_pfnSymFunctionTableAccess64(hProcess, AddrBase);
251
} else {
252
return NULL;
253
}
254
}
255
256
pfn_SymFunctionTableAccess64 WindowsDbgHelp::pfnSymFunctionTableAccess64() {
257
DecoderLocker locker;
258
WindowsDecoder* wd = (WindowsDecoder*)locker.decoder();
259
260
if (!wd->has_error()) {
261
return wd->_pfnSymFunctionTableAccess64;
262
} else {
263
return NULL;
264
}
265
}
266
267
pfn_SymGetModuleBase64 WindowsDbgHelp::pfnSymGetModuleBase64() {
268
DecoderLocker locker;
269
WindowsDecoder* wd = (WindowsDecoder*)locker.decoder();
270
271
if (!wd->has_error()) {
272
return wd->_pfnSymGetModuleBase64;
273
} else {
274
return NULL;
275
}
276
}
277
278
#endif // AMD64
279
280