Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/transport/shmem/shmemBack.c
38813 views
/*1* Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24#include <string.h>2526#include "jdwpTransport.h"27#include "shmemBase.h"28#include "sysShmem.h"29#include "sys.h"3031/*32* The Shared Memory Transport Library.33*34* This module is an implementation of the Java Debug Wire Protocol Transport35* Service Provider Interface - see src/share/javavm/export/jdwpTransport.h.36*/3738static SharedMemoryTransport *transport = NULL; /* maximum of 1 transport */39static SharedMemoryConnection *connection = NULL; /* maximum of 1 connection */40static jdwpTransportCallback *callbacks;41static jboolean initialized;42static struct jdwpTransportNativeInterface_ interface;43static jdwpTransportEnv single_env = (jdwpTransportEnv)&interface;4445/*46* Thread-local index to the per-thread error message47*/48static int tlsIndex;4950/*51* Return an error and record the error message associated with52* the error. Note the if (1==1) { } usage here is to avoid53* compilers complaining that a statement isn't reached which54* will arise if the semicolon (;) appears after the macro,55*/56#define RETURN_ERROR(err, msg) \57if (1==1) { \58setLastError(err, msg); \59return err; \60}6162/*63* Return an I/O error and record the error message.64*/65#define RETURN_IO_ERROR(msg) RETURN_ERROR(JDWPTRANSPORT_ERROR_IO_ERROR, msg);666768/*69* Set the error message for this thread. If the error is an I/O70* error then augment the supplied error message with the textual71* representation of the I/O error.72*/73static void74setLastError(int err, char *newmsg) {75char buf[255];76char *msg;7778/* get any I/O first in case any system calls override errno */79if (err == JDWPTRANSPORT_ERROR_IO_ERROR) {80if (shmemBase_getlasterror(buf, sizeof(buf)) != SYS_OK) {81buf[0] = '\0';82}83}8485/* free any current error */86msg = (char *)sysTlsGet(tlsIndex);87if (msg != NULL) {88(*callbacks->free)(msg);89}9091/*92* For I/O errors append the I/O error message with to the93* supplied message. For all other errors just use the supplied94* message.95*/96if (err == JDWPTRANSPORT_ERROR_IO_ERROR) {97char *join_str = ": ";98int msg_len = (int)strlen(newmsg) + (int)strlen(join_str) +99(int)strlen(buf) + 3;100msg = (*callbacks->alloc)(msg_len);101if (msg != NULL) {102strcpy(msg, newmsg);103strcat(msg, join_str);104strcat(msg, buf);105}106} else {107msg = (*callbacks->alloc)((int)strlen(newmsg)+1);108if (msg != NULL) {109strcpy(msg, newmsg);110}111}112113/* Put a pointer to the message in TLS */114sysTlsPut(tlsIndex, msg);115}116117static jdwpTransportError118handshake()119{120char *hello = "JDWP-Handshake";121unsigned int i;122123for (i=0; i<strlen(hello); i++) {124jbyte b;125int rv = shmemBase_receiveByte(connection, &b);126if (rv != 0) {127RETURN_IO_ERROR("receive failed during handshake");128}129if ((char)b != hello[i]) {130RETURN_IO_ERROR("handshake failed - debugger sent unexpected message");131}132}133134for (i=0; i<strlen(hello); i++) {135int rv = shmemBase_sendByte(connection, (jbyte)hello[i]);136if (rv != 0) {137RETURN_IO_ERROR("write failed during handshake");138}139}140141return JDWPTRANSPORT_ERROR_NONE;142}143144145/*146* Return the capabilities of the shared memory transport. The shared147* memory transport supports both the attach and accept timeouts but148* doesn't support a handshake timeout.149*/150static jdwpTransportError JNICALL151shmemGetCapabilities(jdwpTransportEnv* env, JDWPTransportCapabilities *capabilitiesPtr)152{153JDWPTransportCapabilities result;154155memset(&result, 0, sizeof(result));156result.can_timeout_attach = JNI_TRUE;157result.can_timeout_accept = JNI_TRUE;158result.can_timeout_handshake = JNI_FALSE;159160*capabilitiesPtr = result;161162return JDWPTRANSPORT_ERROR_NONE;163}164165166static jdwpTransportError JNICALL167shmemStartListening(jdwpTransportEnv* env, const char *address, char **actualAddress)168{169jint rc;170171if (connection != NULL || transport != NULL) {172RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_STATE, "already connected or already listening");173}174175rc = shmemBase_listen(address, &transport);176177/*178* If a name was selected by the function above, find it and return179* it in place of the original arg.180*/181if (rc == SYS_OK) {182char *name;183char *name2;184rc = shmemBase_name(transport, &name);185if (rc == SYS_OK) {186name2 = (callbacks->alloc)((int)strlen(name) + 1);187if (name2 == NULL) {188RETURN_ERROR(JDWPTRANSPORT_ERROR_OUT_OF_MEMORY, "out of memory");189} else {190strcpy(name2, name);191*actualAddress = name2;192}193}194} else {195RETURN_IO_ERROR("failed to create shared memory listener");196}197return JDWPTRANSPORT_ERROR_NONE;198}199200static jdwpTransportError JNICALL201shmemAccept(jdwpTransportEnv* env, jlong acceptTimeout, jlong handshakeTimeout)202{203jint rc;204205if (connection != NULL) {206RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_STATE, "already connected");207}208if (transport == NULL) {209RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_STATE, "transport not listening");210}211212rc = shmemBase_accept(transport, (long)acceptTimeout, &connection);213if (rc != SYS_OK) {214if (rc == SYS_TIMEOUT) {215RETURN_ERROR(JDWPTRANSPORT_ERROR_TIMEOUT, "Timed out waiting for connection");216} else {217RETURN_IO_ERROR("failed to accept shared memory connection");218}219}220221rc = handshake();222if (rc != JDWPTRANSPORT_ERROR_NONE) {223shmemBase_closeConnection(connection);224connection = NULL;225}226return rc;227}228229static jdwpTransportError JNICALL230shmemStopListening(jdwpTransportEnv* env)231{232if (transport != NULL) {233shmemBase_closeTransport(transport);234transport = NULL;235}236return JDWPTRANSPORT_ERROR_NONE;237}238239static jdwpTransportError JNICALL240shmemAttach(jdwpTransportEnv* env, const char *address, jlong attachTimeout, jlong handshakeTimeout)241{242jint rc;243244if (connection != NULL) {245RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_STATE, "already connected");246}247rc = shmemBase_attach(address, (long)attachTimeout, &connection);248if (rc != SYS_OK) {249if (rc == SYS_NOMEM) {250RETURN_ERROR(JDWPTRANSPORT_ERROR_OUT_OF_MEMORY, "out of memory");251}252if (rc == SYS_TIMEOUT) {253RETURN_ERROR(JDWPTRANSPORT_ERROR_TIMEOUT, "Timed out waiting to attach");254}255RETURN_IO_ERROR("failed to attach to shared memory connection");256}257258rc = handshake();259if (rc != JDWPTRANSPORT_ERROR_NONE) {260shmemBase_closeConnection(connection);261connection = NULL;262}263return rc;264}265266static jdwpTransportError JNICALL267shmemWritePacket(jdwpTransportEnv* env, const jdwpPacket *packet)268{269if (packet == NULL) {270RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "packet is null");271}272if (packet->type.cmd.len < 11) {273RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "invalid length");274}275if (connection == NULL) {276RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_STATE, "not connected");277}278if (shmemBase_sendPacket(connection, packet) == SYS_OK) {279return JDWPTRANSPORT_ERROR_NONE;280} else {281RETURN_IO_ERROR("write packet failed");282}283}284285static jdwpTransportError JNICALL286shmemReadPacket(jdwpTransportEnv* env, jdwpPacket *packet)287{288if (packet == NULL) {289RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "packet is null");290}291if (connection == NULL) {292RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_STATE, "not connected");293}294if (shmemBase_receivePacket(connection, packet) == SYS_OK) {295return JDWPTRANSPORT_ERROR_NONE;296} else {297RETURN_IO_ERROR("receive packet failed");298}299}300301static jboolean JNICALL302shmemIsOpen(jdwpTransportEnv* env)303{304if (connection != NULL) {305return JNI_TRUE;306} else {307return JNI_FALSE;308}309}310311static jdwpTransportError JNICALL312shmemClose(jdwpTransportEnv* env)313{314SharedMemoryConnection* current_connection = connection;315if (current_connection != NULL) {316connection = NULL;317shmemBase_closeConnection(current_connection);318}319return JDWPTRANSPORT_ERROR_NONE;320}321322/*323* Return the error message for this thread.324*/325static jdwpTransportError JNICALL326shmemGetLastError(jdwpTransportEnv* env, char **msgP)327{328char *msg = (char *)sysTlsGet(tlsIndex);329if (msg == NULL) {330return JDWPTRANSPORT_ERROR_MSG_NOT_AVAILABLE;331}332*msgP = (*callbacks->alloc)((int)strlen(msg)+1);333if (*msgP == NULL) {334return JDWPTRANSPORT_ERROR_OUT_OF_MEMORY;335}336strcpy(*msgP, msg);337return JDWPTRANSPORT_ERROR_NONE;338}339340JNIEXPORT jint JNICALL341jdwpTransport_OnLoad(JavaVM *vm, jdwpTransportCallback* cbTablePtr,342jint version, jdwpTransportEnv** result)343{344if (version != JDWPTRANSPORT_VERSION_1_0) {345return JNI_EVERSION;346}347if (initialized) {348/*349* This library doesn't support multiple environments (yet)350*/351return JNI_EEXIST;352}353initialized = JNI_TRUE;354355/* initialize base shared memory system */356(void) shmemBase_initialize(vm, cbTablePtr);357358/* save callbacks */359callbacks = cbTablePtr;360361/* initialize interface table */362interface.GetCapabilities = &shmemGetCapabilities;363interface.Attach = &shmemAttach;364interface.StartListening = &shmemStartListening;365interface.StopListening = &shmemStopListening;366interface.Accept = &shmemAccept;367interface.IsOpen = &shmemIsOpen;368interface.Close = &shmemClose;369interface.ReadPacket = &shmemReadPacket;370interface.WritePacket = &shmemWritePacket;371interface.GetLastError = &shmemGetLastError;372*result = &single_env;373374/* initialized TLS */375tlsIndex = sysTlsAlloc();376377return JNI_OK;378}379380381