Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.jdi/share/native/libdt_shmem/SharedMemoryConnection.c
41149 views
1
/*
2
* Copyright (c) 1999, 2017, 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
#include <stdlib.h>
27
#include <stddef.h>
28
#include <jni.h>
29
#include "SharedMemory.h"
30
#include "com_sun_tools_jdi_SharedMemoryConnection.h"
31
#include "jdwpTransport.h"
32
#include "shmemBase.h"
33
#include "sys.h"
34
35
/*
36
* JNI interface to the shared memory transport. These JNI methods
37
* call the base shared memory support to do the real work.
38
*
39
* That is, this is the front-ends interface to our shared memory
40
* communication code.
41
*/
42
43
/*
44
* Cached architecture
45
*/
46
static int byte_ordering_known;
47
static int is_big_endian;
48
49
50
/*
51
* Returns 1 if big endian architecture
52
*/
53
static int isBigEndian() {
54
if (!byte_ordering_known) {
55
unsigned int i = 0xff000000;
56
if (((char *)(&i))[0] != 0) {
57
is_big_endian = 1;
58
} else {
59
is_big_endian = 0;
60
}
61
byte_ordering_known = 1;
62
}
63
return is_big_endian;
64
}
65
66
/*
67
* Convert to big endian
68
*/
69
static jint intToBigInt(jint i) {
70
unsigned int b[4];
71
if (isBigEndian()) {
72
return i;
73
}
74
b[0] = (i >> 24) & 0xff;
75
b[1] = (i >> 16) & 0xff;
76
b[2] = (i >> 8) & 0xff;
77
b[3] = i & 0xff;
78
79
/*
80
* It doesn't matter that jint is signed as we are or'ing
81
* and hence end up with the correct bits.
82
*/
83
return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
84
}
85
86
/*
87
* Convert unsigned short to big endian
88
*/
89
static unsigned short shortToBigShort(unsigned short s) {
90
unsigned int b[2];
91
if (isBigEndian()) {
92
return s;
93
}
94
b[0] = (s >> 8) & 0xff;
95
b[1] = s & 0xff;
96
return (b[1] << 8) + b[0];
97
}
98
99
/*
100
* Create a byte[] from a packet struct. All data in the byte array
101
* is JDWP packet suitable for wire transmission. That is, all fields,
102
* and data are in big-endian format as required by the JDWP
103
* specification.
104
*/
105
static jbyteArray
106
packetToByteArray(JNIEnv *env, jdwpPacket *str)
107
{
108
jbyteArray array;
109
jsize data_length;
110
jint total_length;
111
jint tmpInt;
112
113
total_length = str->type.cmd.len;
114
data_length = total_length - JDWP_HEADER_SIZE;
115
116
/* total packet length is header + data */
117
array = (*env)->NewByteArray(env, total_length);
118
if ((*env)->ExceptionOccurred(env)) {
119
return NULL;
120
}
121
122
/* First 4 bytes of packet are the length (in big endian format) */
123
tmpInt = intToBigInt((unsigned int)total_length);
124
(*env)->SetByteArrayRegion(env, array, 0, 4, (const jbyte *)&tmpInt);
125
126
/* Next 4 bytes are the id field */
127
tmpInt = intToBigInt(str->type.cmd.id);
128
(*env)->SetByteArrayRegion(env, array, 4, 4, (const jbyte *)&tmpInt);
129
130
/* next byte is the flags */
131
(*env)->SetByteArrayRegion(env, array, 8, 1, (const jbyte *)&(str->type.cmd.flags));
132
133
/* next two bytes are either the error code or the command set/command */
134
if (str->type.cmd.flags & JDWPTRANSPORT_FLAGS_REPLY) {
135
short s = shortToBigShort(str->type.reply.errorCode);
136
(*env)->SetByteArrayRegion(env, array, 9, 2, (const jbyte *)&(s));
137
} else {
138
(*env)->SetByteArrayRegion(env, array, 9, 1, (const jbyte *)&(str->type.cmd.cmdSet));
139
(*env)->SetByteArrayRegion(env, array, 10, 1, (const jbyte *)&(str->type.cmd.cmd));
140
}
141
142
/* finally the data */
143
144
if (data_length > 0) {
145
(*env)->SetByteArrayRegion(env, array, JDWP_HEADER_SIZE,
146
data_length, str->type.cmd.data);
147
if ((*env)->ExceptionOccurred(env)) {
148
return NULL;
149
}
150
}
151
152
return array;
153
}
154
155
/*
156
* Fill a packet struct from a byte array. The byte array is a
157
* JDWP packet suitable for wire transmission. That is, all fields,
158
* and data are in big-endian format as required by the JDWP
159
* specification. We thus need to convert the fields from big
160
* endian to the platform endian.
161
*
162
* The jbyteArray provided to this function is assumed to
163
* of a length than is equal or greater than the length of
164
* the JDWP packet that is contains.
165
*/
166
static void
167
byteArrayToPacket(JNIEnv *env, jbyteArray b, jdwpPacket *str)
168
{
169
jsize total_length, data_length;
170
jbyte *data;
171
unsigned char pktHeader[JDWP_HEADER_SIZE];
172
173
/*
174
* Get the packet header
175
*/
176
(*env)->GetByteArrayRegion(env, b, 0, sizeof(pktHeader), pktHeader);
177
if ((*env)->ExceptionOccurred(env)) {
178
/* b shorter than sizeof(pktHeader) */
179
return;
180
}
181
182
total_length = (int)pktHeader[3] | ((int)pktHeader[2] << 8) |
183
((int)pktHeader[1] << 16) | ((int)pktHeader[0] << 24);
184
185
if (total_length < sizeof(pktHeader)) {
186
throwException(env, "java/lang/IllegalArgumentException",
187
"JDWP header is incorrect");
188
return;
189
}
190
191
/*
192
* The id field is in big endian (also errorCode field in the case
193
* of reply packets).
194
*/
195
str->type.cmd.id = (int)pktHeader[7] | ((int)pktHeader[6] << 8) |
196
((int)pktHeader[5] << 16) | ((int)pktHeader[4] << 24);
197
198
str->type.cmd.flags = (jbyte)pktHeader[8];
199
200
if (str->type.cmd.flags & JDWPTRANSPORT_FLAGS_REPLY) {
201
str->type.reply.errorCode = (int)pktHeader[9] + ((int)pktHeader[10] << 8);
202
} else {
203
/* command packet */
204
str->type.cmd.cmdSet = (jbyte)pktHeader[9];
205
str->type.cmd.cmd = (jbyte)pktHeader[10];
206
}
207
208
/*
209
* The length of the JDWP packet is sizeof(pktHeader) + data
210
*/
211
data_length = total_length - sizeof(pktHeader);
212
213
if (data_length == 0) {
214
data = NULL;
215
} else {
216
data = malloc(data_length);
217
if (data == NULL) {
218
throwException(env, "java/lang/OutOfMemoryError",
219
"Unable to allocate command data buffer");
220
return;
221
}
222
223
(*env)->GetByteArrayRegion(env, b, sizeof(pktHeader), /*sizeof(CmdPacket)+4*/ data_length, data);
224
if ((*env)->ExceptionOccurred(env)) {
225
free(data);
226
return;
227
}
228
}
229
230
str->type.cmd.len = total_length;
231
str->type.cmd.data = data;
232
}
233
234
static void
235
freePacketData(jdwpPacket *packet)
236
{
237
if (packet->type.cmd.len > 0) {
238
free(packet->type.cmd.data);
239
}
240
}
241
242
/*
243
* Class: com_sun_tools_jdi_SharedMemoryConnection
244
* Method: close0
245
* Signature: (J)V
246
*/
247
JNIEXPORT void JNICALL Java_com_sun_tools_jdi_SharedMemoryConnection_close0
248
(JNIEnv *env, jobject thisObject, jlong id)
249
{
250
SharedMemoryConnection *connection = ID_TO_CONNECTION(id);
251
shmemBase_closeConnection(connection);
252
}
253
254
/*
255
* Class: com_sun_tools_jdi_SharedMemoryConnection
256
* Method: receiveByte0
257
* Signature: (J)B
258
*/
259
JNIEXPORT jbyte JNICALL Java_com_sun_tools_jdi_SharedMemoryConnection_receiveByte0
260
(JNIEnv *env, jobject thisObject, jlong id)
261
{
262
SharedMemoryConnection *connection = ID_TO_CONNECTION(id);
263
jbyte b = 0;
264
jint rc;
265
266
rc = shmemBase_receiveByte(connection, &b);
267
if (rc != SYS_OK) {
268
throwShmemException(env, "shmemBase_receiveByte failed", rc);
269
}
270
271
return b;
272
}
273
274
/*
275
* Class: com_sun_tools_jdi_SharedMemoryConnection
276
* Method: receivePacket0
277
* Signature: (JLcom/sun/tools/jdi/Packet;)V
278
*/
279
JNIEXPORT jbyteArray JNICALL Java_com_sun_tools_jdi_SharedMemoryConnection_receivePacket0
280
(JNIEnv *env, jobject thisObject, jlong id)
281
{
282
SharedMemoryConnection *connection = ID_TO_CONNECTION(id);
283
jdwpPacket packet;
284
jint rc;
285
286
rc = shmemBase_receivePacket(connection, &packet);
287
if (rc != SYS_OK) {
288
throwShmemException(env, "shmemBase_receivePacket failed", rc);
289
return NULL;
290
} else {
291
jbyteArray array = packetToByteArray(env, &packet);
292
293
/* Free the packet even if there was an exception above */
294
freePacketData(&packet);
295
return array;
296
}
297
}
298
299
/*
300
* Class: com_sun_tools_jdi_SharedMemoryConnection
301
* Method: sendByte0
302
* Signature: (JB)V
303
*/
304
JNIEXPORT void JNICALL Java_com_sun_tools_jdi_SharedMemoryConnection_sendByte0
305
(JNIEnv *env, jobject thisObject, jlong id, jbyte b)
306
{
307
SharedMemoryConnection *connection = ID_TO_CONNECTION(id);
308
jint rc;
309
310
rc = shmemBase_sendByte(connection, b);
311
if (rc != SYS_OK) {
312
throwShmemException(env, "shmemBase_sendByte failed", rc);
313
}
314
}
315
316
/*
317
* Class: com_sun_tools_jdi_SharedMemoryConnection
318
* Method: sendPacket0
319
* Signature: (JLcom/sun/tools/jdi/Packet;)V
320
*/
321
JNIEXPORT void JNICALL Java_com_sun_tools_jdi_SharedMemoryConnection_sendPacket0
322
(JNIEnv *env, jobject thisObject, jlong id, jbyteArray b)
323
{
324
SharedMemoryConnection *connection = ID_TO_CONNECTION(id);
325
jdwpPacket packet;
326
jint rc;
327
328
byteArrayToPacket(env, b, &packet);
329
if ((*env)->ExceptionOccurred(env)) {
330
return;
331
}
332
333
rc = shmemBase_sendPacket(connection, &packet);
334
if (rc != SYS_OK) {
335
throwShmemException(env, "shmemBase_sendPacket failed", rc);
336
}
337
freePacketData(&packet);
338
}
339
340