Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/transport/shmem/shmemBack.c
38813 views
1
/*
2
* Copyright (c) 1999, 2008, 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
#include <string.h>
26
27
#include "jdwpTransport.h"
28
#include "shmemBase.h"
29
#include "sysShmem.h"
30
#include "sys.h"
31
32
/*
33
* The Shared Memory Transport Library.
34
*
35
* This module is an implementation of the Java Debug Wire Protocol Transport
36
* Service Provider Interface - see src/share/javavm/export/jdwpTransport.h.
37
*/
38
39
static SharedMemoryTransport *transport = NULL; /* maximum of 1 transport */
40
static SharedMemoryConnection *connection = NULL; /* maximum of 1 connection */
41
static jdwpTransportCallback *callbacks;
42
static jboolean initialized;
43
static struct jdwpTransportNativeInterface_ interface;
44
static jdwpTransportEnv single_env = (jdwpTransportEnv)&interface;
45
46
/*
47
* Thread-local index to the per-thread error message
48
*/
49
static int tlsIndex;
50
51
/*
52
* Return an error and record the error message associated with
53
* the error. Note the if (1==1) { } usage here is to avoid
54
* compilers complaining that a statement isn't reached which
55
* will arise if the semicolon (;) appears after the macro,
56
*/
57
#define RETURN_ERROR(err, msg) \
58
if (1==1) { \
59
setLastError(err, msg); \
60
return err; \
61
}
62
63
/*
64
* Return an I/O error and record the error message.
65
*/
66
#define RETURN_IO_ERROR(msg) RETURN_ERROR(JDWPTRANSPORT_ERROR_IO_ERROR, msg);
67
68
69
/*
70
* Set the error message for this thread. If the error is an I/O
71
* error then augment the supplied error message with the textual
72
* representation of the I/O error.
73
*/
74
static void
75
setLastError(int err, char *newmsg) {
76
char buf[255];
77
char *msg;
78
79
/* get any I/O first in case any system calls override errno */
80
if (err == JDWPTRANSPORT_ERROR_IO_ERROR) {
81
if (shmemBase_getlasterror(buf, sizeof(buf)) != SYS_OK) {
82
buf[0] = '\0';
83
}
84
}
85
86
/* free any current error */
87
msg = (char *)sysTlsGet(tlsIndex);
88
if (msg != NULL) {
89
(*callbacks->free)(msg);
90
}
91
92
/*
93
* For I/O errors append the I/O error message with to the
94
* supplied message. For all other errors just use the supplied
95
* message.
96
*/
97
if (err == JDWPTRANSPORT_ERROR_IO_ERROR) {
98
char *join_str = ": ";
99
int msg_len = (int)strlen(newmsg) + (int)strlen(join_str) +
100
(int)strlen(buf) + 3;
101
msg = (*callbacks->alloc)(msg_len);
102
if (msg != NULL) {
103
strcpy(msg, newmsg);
104
strcat(msg, join_str);
105
strcat(msg, buf);
106
}
107
} else {
108
msg = (*callbacks->alloc)((int)strlen(newmsg)+1);
109
if (msg != NULL) {
110
strcpy(msg, newmsg);
111
}
112
}
113
114
/* Put a pointer to the message in TLS */
115
sysTlsPut(tlsIndex, msg);
116
}
117
118
static jdwpTransportError
119
handshake()
120
{
121
char *hello = "JDWP-Handshake";
122
unsigned int i;
123
124
for (i=0; i<strlen(hello); i++) {
125
jbyte b;
126
int rv = shmemBase_receiveByte(connection, &b);
127
if (rv != 0) {
128
RETURN_IO_ERROR("receive failed during handshake");
129
}
130
if ((char)b != hello[i]) {
131
RETURN_IO_ERROR("handshake failed - debugger sent unexpected message");
132
}
133
}
134
135
for (i=0; i<strlen(hello); i++) {
136
int rv = shmemBase_sendByte(connection, (jbyte)hello[i]);
137
if (rv != 0) {
138
RETURN_IO_ERROR("write failed during handshake");
139
}
140
}
141
142
return JDWPTRANSPORT_ERROR_NONE;
143
}
144
145
146
/*
147
* Return the capabilities of the shared memory transport. The shared
148
* memory transport supports both the attach and accept timeouts but
149
* doesn't support a handshake timeout.
150
*/
151
static jdwpTransportError JNICALL
152
shmemGetCapabilities(jdwpTransportEnv* env, JDWPTransportCapabilities *capabilitiesPtr)
153
{
154
JDWPTransportCapabilities result;
155
156
memset(&result, 0, sizeof(result));
157
result.can_timeout_attach = JNI_TRUE;
158
result.can_timeout_accept = JNI_TRUE;
159
result.can_timeout_handshake = JNI_FALSE;
160
161
*capabilitiesPtr = result;
162
163
return JDWPTRANSPORT_ERROR_NONE;
164
}
165
166
167
static jdwpTransportError JNICALL
168
shmemStartListening(jdwpTransportEnv* env, const char *address, char **actualAddress)
169
{
170
jint rc;
171
172
if (connection != NULL || transport != NULL) {
173
RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_STATE, "already connected or already listening");
174
}
175
176
rc = shmemBase_listen(address, &transport);
177
178
/*
179
* If a name was selected by the function above, find it and return
180
* it in place of the original arg.
181
*/
182
if (rc == SYS_OK) {
183
char *name;
184
char *name2;
185
rc = shmemBase_name(transport, &name);
186
if (rc == SYS_OK) {
187
name2 = (callbacks->alloc)((int)strlen(name) + 1);
188
if (name2 == NULL) {
189
RETURN_ERROR(JDWPTRANSPORT_ERROR_OUT_OF_MEMORY, "out of memory");
190
} else {
191
strcpy(name2, name);
192
*actualAddress = name2;
193
}
194
}
195
} else {
196
RETURN_IO_ERROR("failed to create shared memory listener");
197
}
198
return JDWPTRANSPORT_ERROR_NONE;
199
}
200
201
static jdwpTransportError JNICALL
202
shmemAccept(jdwpTransportEnv* env, jlong acceptTimeout, jlong handshakeTimeout)
203
{
204
jint rc;
205
206
if (connection != NULL) {
207
RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_STATE, "already connected");
208
}
209
if (transport == NULL) {
210
RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_STATE, "transport not listening");
211
}
212
213
rc = shmemBase_accept(transport, (long)acceptTimeout, &connection);
214
if (rc != SYS_OK) {
215
if (rc == SYS_TIMEOUT) {
216
RETURN_ERROR(JDWPTRANSPORT_ERROR_TIMEOUT, "Timed out waiting for connection");
217
} else {
218
RETURN_IO_ERROR("failed to accept shared memory connection");
219
}
220
}
221
222
rc = handshake();
223
if (rc != JDWPTRANSPORT_ERROR_NONE) {
224
shmemBase_closeConnection(connection);
225
connection = NULL;
226
}
227
return rc;
228
}
229
230
static jdwpTransportError JNICALL
231
shmemStopListening(jdwpTransportEnv* env)
232
{
233
if (transport != NULL) {
234
shmemBase_closeTransport(transport);
235
transport = NULL;
236
}
237
return JDWPTRANSPORT_ERROR_NONE;
238
}
239
240
static jdwpTransportError JNICALL
241
shmemAttach(jdwpTransportEnv* env, const char *address, jlong attachTimeout, jlong handshakeTimeout)
242
{
243
jint rc;
244
245
if (connection != NULL) {
246
RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_STATE, "already connected");
247
}
248
rc = shmemBase_attach(address, (long)attachTimeout, &connection);
249
if (rc != SYS_OK) {
250
if (rc == SYS_NOMEM) {
251
RETURN_ERROR(JDWPTRANSPORT_ERROR_OUT_OF_MEMORY, "out of memory");
252
}
253
if (rc == SYS_TIMEOUT) {
254
RETURN_ERROR(JDWPTRANSPORT_ERROR_TIMEOUT, "Timed out waiting to attach");
255
}
256
RETURN_IO_ERROR("failed to attach to shared memory connection");
257
}
258
259
rc = handshake();
260
if (rc != JDWPTRANSPORT_ERROR_NONE) {
261
shmemBase_closeConnection(connection);
262
connection = NULL;
263
}
264
return rc;
265
}
266
267
static jdwpTransportError JNICALL
268
shmemWritePacket(jdwpTransportEnv* env, const jdwpPacket *packet)
269
{
270
if (packet == NULL) {
271
RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "packet is null");
272
}
273
if (packet->type.cmd.len < 11) {
274
RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "invalid length");
275
}
276
if (connection == NULL) {
277
RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_STATE, "not connected");
278
}
279
if (shmemBase_sendPacket(connection, packet) == SYS_OK) {
280
return JDWPTRANSPORT_ERROR_NONE;
281
} else {
282
RETURN_IO_ERROR("write packet failed");
283
}
284
}
285
286
static jdwpTransportError JNICALL
287
shmemReadPacket(jdwpTransportEnv* env, jdwpPacket *packet)
288
{
289
if (packet == NULL) {
290
RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "packet is null");
291
}
292
if (connection == NULL) {
293
RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_STATE, "not connected");
294
}
295
if (shmemBase_receivePacket(connection, packet) == SYS_OK) {
296
return JDWPTRANSPORT_ERROR_NONE;
297
} else {
298
RETURN_IO_ERROR("receive packet failed");
299
}
300
}
301
302
static jboolean JNICALL
303
shmemIsOpen(jdwpTransportEnv* env)
304
{
305
if (connection != NULL) {
306
return JNI_TRUE;
307
} else {
308
return JNI_FALSE;
309
}
310
}
311
312
static jdwpTransportError JNICALL
313
shmemClose(jdwpTransportEnv* env)
314
{
315
SharedMemoryConnection* current_connection = connection;
316
if (current_connection != NULL) {
317
connection = NULL;
318
shmemBase_closeConnection(current_connection);
319
}
320
return JDWPTRANSPORT_ERROR_NONE;
321
}
322
323
/*
324
* Return the error message for this thread.
325
*/
326
static jdwpTransportError JNICALL
327
shmemGetLastError(jdwpTransportEnv* env, char **msgP)
328
{
329
char *msg = (char *)sysTlsGet(tlsIndex);
330
if (msg == NULL) {
331
return JDWPTRANSPORT_ERROR_MSG_NOT_AVAILABLE;
332
}
333
*msgP = (*callbacks->alloc)((int)strlen(msg)+1);
334
if (*msgP == NULL) {
335
return JDWPTRANSPORT_ERROR_OUT_OF_MEMORY;
336
}
337
strcpy(*msgP, msg);
338
return JDWPTRANSPORT_ERROR_NONE;
339
}
340
341
JNIEXPORT jint JNICALL
342
jdwpTransport_OnLoad(JavaVM *vm, jdwpTransportCallback* cbTablePtr,
343
jint version, jdwpTransportEnv** result)
344
{
345
if (version != JDWPTRANSPORT_VERSION_1_0) {
346
return JNI_EVERSION;
347
}
348
if (initialized) {
349
/*
350
* This library doesn't support multiple environments (yet)
351
*/
352
return JNI_EEXIST;
353
}
354
initialized = JNI_TRUE;
355
356
/* initialize base shared memory system */
357
(void) shmemBase_initialize(vm, cbTablePtr);
358
359
/* save callbacks */
360
callbacks = cbTablePtr;
361
362
/* initialize interface table */
363
interface.GetCapabilities = &shmemGetCapabilities;
364
interface.Attach = &shmemAttach;
365
interface.StartListening = &shmemStartListening;
366
interface.StopListening = &shmemStopListening;
367
interface.Accept = &shmemAccept;
368
interface.IsOpen = &shmemIsOpen;
369
interface.Close = &shmemClose;
370
interface.ReadPacket = &shmemReadPacket;
371
interface.WritePacket = &shmemWritePacket;
372
interface.GetLastError = &shmemGetLastError;
373
*result = &single_env;
374
375
/* initialized TLS */
376
tlsIndex = sysTlsAlloc();
377
378
return JNI_OK;
379
}
380
381