1 /*
  2  * Copyright (c) 2001, 2022, 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 package nsk.share.jdi;
 25 
 26 import nsk.share.*;
 27 import nsk.share.jpda.*;
 28 
 29 import com.sun.jdi.VirtualMachine;
 30 
 31 /**
 32  * Parser for JDI test's specific command-line arguments.
 33  * <p>
 34  * <code>ArgumentHandler</code> handles JDI test's specific
 35  * arguments related to launching debugee VM using JDI features
 36  * in addition to general arguments recognized by
 37  * <code>DebugeeArgumentHandler</code> and <code>ArgumentParser</code>.
 38  * <p>
 39  * Following is the list of specific options recognized by
 40  * <code>AgrumentHandler</code>:
 41  * <ul>
 42  * <li> <code>-connector=[launching|attaching|listening|default]</code> -
 43  *   JDI connector type
 44  * <li> <code>-transport=[socket|shmem|default]</code> -
 45  *   JDWP transport kind
 46  * <li> <code>-jdi.trace=[none|all|events|sends|receives|reftypes|objrefs]</code> -
 47  *   JDI trace mode for debugee VM
 48  * </ul>
 49  * <p>
 50  * See also list of arguments recognized by the base <code>DebugeeArgumentHandler</code>
 51  * and <code>ArgumentParser</code> classes.
 52  * <p>
 53  * See also description of <code>ArgumentParser</code> how to work with
 54  * command line arguments and options.
 55  *
 56  * @see ArgumentParser
 57  * @see DebugeeArgumentHandler
 58  */
 59 public class ArgumentHandler extends DebugeeArgumentHandler {
 60 
 61     static private String JDI_CONNECTOR_NAME_PREFIX = "com.sun.jdi.";
 62 
 63     /**
 64      * Keep a copy of raw command-line arguments and parse them;
 65      * but throw an exception on parsing error.
 66      *
 67      * @param  args  Array of the raw command-line arguments.
 68      *
 69      * @throws  NullPointerException  If <code>args==null</code>.
 70      * @throws  IllegalArgumentException  If Binder or Log options
 71      *                                    are set incorrectly.
 72      *
 73      * @see #setRawArguments(String[])
 74      */
 75     public ArgumentHandler(String args[]) {
 76         super(args);
 77 //        parseArguments();
 78     }
 79 
 80     /**
 81      * Overriden method returns transport type for JDWP connection, specified by
 82      * <code>-transport</code> command line option, or <i>"default"</i> value
 83      * by default.
 84      *
 85      * @see #getTransportName()
 86      * @see #isSocketTransport()
 87      * @see #isShmemTransport()
 88      * @see #isDefaultTransport()
 89      * @see #setRawArguments(String[])
 90      */
 91     public String getTransportType() {
 92         return options.getProperty("transport", "default");
 93     }
 94 
 95     /**
 96      * Overriden method returns <i>true</i> if <code>socket</code> transport
 97      * is used either as specified or as a platform default transport.
 98      *
 99      * @see #getTransportType()
100      */
101     public boolean isSocketTransport() {
102         String transport = getTransportType();
103         if (transport.equals("socket"))
104             return true;
105         if (transport.equals("shmem"))
106             return false;
107         if (transport.equals("default")) {
108             String arch = getArch();
109             if (arch == null)
110                 if (System.getProperty("os.arch").equals("windows-i586"))
111                     return false;
112                 else
113                     return true;
114             else if (arch.equals("windows-i586"))
115                 return false;
116             else
117                 return true;
118         }
119         throw new TestBug("Bad value of argument transport: " + transport);
120     }
121 
122     /**
123      * Overriden method returns <i>true</i> if <code>shmem</code> transport is used
124      * either as specified or as a platform default transport.
125      *
126      * @see #getTransportType()
127      */
128     public boolean isShmemTransport() {
129         return ! isSocketTransport();
130     }
131 
132     /**
133      * Overriden method returns <i>true</i> if transport type is <code>default</code>.
134      *
135      * @see #getTransportType()
136      */
137     public boolean isDefaultTransport() {
138         String transport = getTransportType();
139         return transport.equals("default");
140     }
141 
142     /**
143      * Overriden methos returns JDI connector type, specified by
144      * <code>-connector</code>. or <i>"default"</i> value by default.
145      *
146      * @see #getConnectorName()
147      * @see #isLaunchingConnector()
148      * @see #isAttachingConnector()
149      * @see #isListeningConnector()
150      * @see #isDefaultConnector()
151      * @see #setRawArguments(String[])
152      */
153     public String getConnectorType() {
154         return options.getProperty("connector", "default");
155     }
156 
157     /**
158      * Overriden method returns full connector name corresponding to
159      * the used connector and transport types.
160      *
161      * @see #getConnectorType()
162      * @see #getTransportType()
163      */
164     public String getConnectorName() {
165         if (isLaunchingConnector()) {
166             if (isRawLaunchingConnector())
167                 return JDI_CONNECTOR_NAME_PREFIX + "RawCommandLineLaunch";
168             return JDI_CONNECTOR_NAME_PREFIX + "CommandLineLaunch";
169         }
170         if (isAttachingConnector()) {
171             if (isSocketTransport())
172                 return JDI_CONNECTOR_NAME_PREFIX + "SocketAttach";
173             if (isShmemTransport())
174                 return JDI_CONNECTOR_NAME_PREFIX + "SharedMemoryAttach";
175             return JDI_CONNECTOR_NAME_PREFIX + "SocketAttach";
176         }
177         if (isListeningConnector()) {
178             if (isSocketTransport())
179                 return JDI_CONNECTOR_NAME_PREFIX + "SocketListen";
180             if (isShmemTransport())
181                 return JDI_CONNECTOR_NAME_PREFIX + "SharedMemoryListen";
182             return JDI_CONNECTOR_NAME_PREFIX + "SocketListen";
183         }
184         throw new Failure("Unable to find full name of connector \"" + getConnectorType()
185                         + "\" for transport \"" + getTransportType() + "\"");
186     }
187 
188     /**
189      * Overriden method returns <i>true</i> if connector type is <code>default</code>.
190      *
191      * @see #getConnectorType()
192      */
193     public boolean isDefaultConnector() {
194         return getConnectorType().equals("default");
195     }
196 
197     /**
198      * Return <i>true</i> if connector type is <code>launching</code>
199      * <code>rawlaunching<code> or <code>default</code>.
200      *
201      * @see #getConnectorType()
202      */
203     public boolean isLaunchingConnector() {
204         return getConnectorType().equals("launching")
205                 || getConnectorType().equals("rawlaunching")
206                 || getConnectorType().equals("default");
207     }
208 
209     /**
210      * Return <i>true</i> if connector type is <code>rawlaunching</code>.
211      *
212      * @see #getConnectorType()
213      */
214     public boolean isRawLaunchingConnector() {
215         return getConnectorType().equals("rawlaunching");
216     }
217 
218     /**
219      * Return string representation of debug trace mode, specified by
220      * <code>-jdi.trace</code> command line option, or <i>"none"</i>
221      * value by default.
222      * <p>
223      * Possible values for this option are the same as symbolic constants names
224      * in <code>com.sun.jdi.VirtualMachine</code> interface:
225      * <br>&nbsp;&nbsp;<code>"all"</code>, or
226      * <br>&nbsp;&nbsp;<code>"events"</code>, or
227      * <br>&nbsp;&nbsp;<code>"none"</code>, or
228      * <br>&nbsp;&nbsp;<code>"objrefs"</code>, or
229      * <br>&nbsp;&nbsp;<code>"receives"</code>, or
230      * <br>&nbsp;&nbsp;<code>"reftypes"</code>, or
231      * <br>&nbsp;&nbsp;<code>"sends"</code>.
232      *
233      * @see #getTraceMode()
234      * @see #setRawArguments(String[])
235      */
236     public String getTraceModeString() {
237         return options.getProperty("jdi.trace", "none");
238     }
239 
240     /**
241      * Return integer code corresponding to debug trace mode, specified by
242      * <code>-jdi.trace</code> command line option, or <i>VirtualMachine.TRACE_NONE</i>
243      * value by default.
244      * <p>
245      * Possible values are the same as symbolic constant values
246      * in <code>com.sun.jdi.VirtualMachine</code> interface:
247      * <ul>
248      *   <li><code>VirtualMachine.TRACE_ALL</code>
249      *   <li><code>VirtualMachine.TRACE_EVENTS</code>
250      *   <li><code>VirtualMachine.TRACE_NONE</code>
251      *   <li><code>VirtualMachine.TRACE_OBJREFS</code>
252      *   <li><code>VirtualMachine.TRACE_RECEIVES</code>
253      *   <li><code>VirtualMachine.TRACE_REFTYPES</code>
254      *   <li><code>VirtualMachine.TRACE_SENDS</code>
255      * </ul>
256      *
257      * @see #getTraceModeString()
258      * @see #setRawArguments(String[])
259      */
260     public int getTraceMode() {
261         String val = getTraceModeString();
262         if (val == null)
263             return VirtualMachine.TRACE_NONE;
264         if (val.equals("none"))
265             return VirtualMachine.TRACE_NONE;
266         if (val.equals("all"))
267             return VirtualMachine.TRACE_ALL;
268         if (val.equals("events"))
269             return VirtualMachine.TRACE_EVENTS;
270         if (val.equals("objrefs"))
271             return VirtualMachine.TRACE_OBJREFS;
272         if (val.equals("receives"))
273             return VirtualMachine.TRACE_RECEIVES;
274         if (val.equals("reftypes"))
275             return VirtualMachine.TRACE_REFTYPES;
276         if (val.equals("sends"))
277             return VirtualMachine.TRACE_SENDS;
278         throw new TestBug("Unknown JDI trace mode string: " + val);
279     }
280 
281     // delay between connection attempts, used in connectors tests
282     public int getConnectionDelay() {
283         String value = options.getProperty("connectionDelay", "4000");
284         try {
285             return Integer.parseInt(value);
286         } catch (NumberFormatException e) {
287             throw new TestBug("Not integer value of \"connectionDelay\" argument: " + value);
288         }
289     }
290 
291 
292     /**
293      * Return <i>true</i> if the test should pass in any case i.e.
294      * an entity specified by the arguments <code>entry[]</code> is
295      * not implemented on the tested platform. Name of the tested
296      * platform is resolved from the "<code>-arch</code>" option.
297      *
298      * @param  entry   Array with the arguments which are specifing
299      * the entity.
300      *
301      * @throws Oddity  If test parameter<code>-arch</code>
302      *                 has not been set.
303      *
304      * @see #setRawArguments(String[])
305      */
306     public boolean shouldPass(String entry[]) {
307         String arch;
308         boolean found = false;
309 
310         if ((arch=getArch()) == null)
311             throw new Oddity("Test parameter -arch should be set");
312 
313         for (int i=0; i < CheckedFeatures.notImplemented.length; i++) {
314             if (CheckedFeatures.notImplemented[i][0].equals(arch) &&
315                 CheckedFeatures.notImplemented[i].length == (entry.length+1)) {
316                 for (int j=1; j < (entry.length+1); j++) {
317                     if (CheckedFeatures.notImplemented[i][j].equals(entry[j-1]))
318                         found = true;
319                     else {
320                         found = false;
321                         break;
322                     }
323                 }
324                 if (found) return true; // the entry[] is not implemented
325             }
326         }
327 
328         return false; // the entry[] is implemented
329     }
330 
331     /**
332      * Return <i>true</i> if the test should pass in any case i.e.
333      * an entity specified by the argument <code>entry</code> is
334      * not implemented on the tested platform. Name of the tested
335      * platform is resolved from the "<code>-arch</code>" option.
336      *
337      * @param  entry   String with the argument which is specifing
338      * the entity.
339      *
340      * @throws Oddity  If test parameter<code>-arch</code>
341      *                 has not been set.
342      *
343      * @see #setRawArguments(String[])
344      */
345     public boolean shouldPass(String entry) {
346         return (shouldPass(new String[] {entry}));
347     }
348 
349     /**
350      * Return <i>true</i> if the test should pass in any case i.e.
351      * an entity specified by the arguments <code>entry1</code> and
352      * <code>entry2</code> is not implemented on the tested platform.
353      * The entry is considered to be not implemented if exact entry
354      *  "entry1, entry2" or its main entry "entry1" is not implemented.
355      *
356      * Name of the tested platform is resolved from the "<code>-arch</code>"
357      * option.
358      *
359      * @param  entry1   String with the argument 1 which is specifing
360      * the entity.
361      *
362      * @param  entry2   String with the argument 2 which is specifing
363      * the entity.
364      *
365      * @throws Oddity  If test parameter<code>-arch</code>
366      *                 has not been set.
367      *
368      * @see #setRawArguments(String[])
369      */
370     public boolean shouldPass(String entry1, String entry2) {
371         return ( shouldPass(new String[] {entry1, entry2}) ||
372                  shouldPass(new String[] {entry1})  );
373     }
374 
375     /**
376      * Check if an option is admissible and has proper value.
377      * This method is invoked by <code>parseArguments()</code>
378      *
379      * @param option option name
380      * @param value string representation of value (could be an empty string)
381      *              null if this option has no value
382      * @return <i>true</i> if option is admissible and has proper value
383      *         <i>false</i> if otion is not admissible
384      *
385      * @throws <i>BadOption</i> if option has illegal value
386      *
387      * @see #parseArguments()
388      */
389     protected boolean checkOption(String option, String value) {
390 
391         // check options with enumerated values
392 
393         if (option.equals("connectionDelay")) {
394             try {
395                 int number = Integer.parseInt(value);
396                 if (number <= 0) {
397                     throw new BadOption(option + ": must be a positive integer");
398                 }
399             } catch (NumberFormatException e) {
400                 throw new BadOption(option + ": must be an integer");
401             }
402 
403             return true;
404         }
405 
406         if (option.equals("connector")) {
407             if ((!value.equals("launching"))
408                 && (!value.equals("rawlaunching"))
409                 && (!value.equals("attaching"))
410                 && (!value.equals("listening"))
411                 && (!value.equals("default"))) {
412                 throw new BadOption(option + ": value must be one of: "
413                                            + "launching, attaching, listening, default");
414             }
415             return true;
416         }
417 
418         if (option.equals("transport")) {
419             if ((!value.equals("socket"))
420                 && (!value.equals("shmem"))
421                 && (!value.equals("default"))) {
422                 throw new BadOption(option + ": must be one of: "
423                                            + "socket, shmem, default");
424             }
425             return true;
426         }
427 
428         if (option.equals("jdi.trace")) {
429             if ((!value.equals("all"))
430                 && (!value.equals("none"))
431                 && (!value.equals("events"))
432                 && (!value.equals("receives"))
433                 && (!value.equals("sends"))
434                 && (!value.equals("reftypes"))
435                 && (!value.equals("objrefs"))) {
436                 throw new BadOption(option + ": value must be one of: "
437                                            + "none, all, events, receives, sends, reftypes, objrefs");
438             }
439             return true;
440         }
441 
442         return super.checkOption(option, value);
443     }
444 
445     /**
446      * Check options against inconcistence.
447      * This method is invoked by <code>parseArguments()</code>
448      *
449      * @see #parseArguments()
450      */
451     protected void checkOptions() {
452 /*
453         if (isTransportAddressDynamic() &&
454                 (!isDefaultConnector() && isRawLaunchingConnector())) {
455             throw new BadOption("-transport.address=dynamic should NOT be used with"
456                                 + " -connector=rawlaunching");
457         }
458  */
459 
460         if (! isLaunchedLocally() && ! isDefaultDebugeeSuspendMode()) {
461             throw new BadOption("inconsistent options: "
462                                 + "-debugee.launch=" + getLaunchMode()
463                                 + " and -debugee.suspend=" + getDebugeeSuspendMode());
464         }
465 
466         if (! isLaunchedLocally() && isLaunchingConnector()) {
467             throw new BadOption("inconsistent options: "
468                                 + "-debugee.launch=" + getLaunchMode()
469                                 + " and -connector=" + getConnectorType());
470         }
471 
472         if (isLaunchingConnector() && ! isDefaultTransport()) {
473             throw new BadOption("inconsistent options: "
474                                 + "-connector=" + getConnectorType()
475                                 + " and -transport=" + getTransportType());
476         }
477 
478         if (! isLaunchingConnector() && isDefaultTransport()) {
479             throw new BadOption("inconsistent options: "
480                                 + "-connector=" + getConnectorType()
481                                 + " and -transport=" + getTransportType());
482         }
483 
484         if (! isDefaultJVMDIStrictMode()) {
485             throw new BadOption("unsupported options: "
486                                 + "jvmdi.strict: non default JVMDI strict mode is not supported now" + getJVMDIStrictMode());
487         }
488 
489 /*
490         if (! isLaunchedLocally() && ! isDefaultJVMDIStrictMode()) {
491             throw new BadOption("inconsistent options: "
492                                 + "-launch.mode=" + getLaunchMode()
493                                 + " and -jvmdi.strict=" + getJVMDIStrictMode());
494         }
495  */
496 
497         super.checkOptions();
498     }
499 }
500 
501 /**
502  * This is an auxiliary class intended for <code>ArgumentHandler</code>.
503  * The following information is used by the <code>ArgumentHandler</code>
504  * for resolving features (i.e., JDI connectors and transport names)
505  * which are not implemented on given platform (the first column).
506  * This list is actual for JDK 1.3.x, 1.4.x, 1.5.0, 1.6.0.
507  *
508  * @see ArgumentHandler
509  */
510 class CheckedFeatures {
511 
512     static final String[][] notImplemented = {
513 
514             // attaching connectors
515         /*
516          * From docs/technotes/guides/jpda/conninv.html:
517          * "
518          *  This connector can be used by a debugger application to attach to
519          *  a currently running target VM through the shared memory transport. It is
520          *  available only on the Microsoft Windows platform.
521          *  "
522          */
523         {"linux-i586",      "com.sun.jdi.SharedMemoryAttach"},
524         {"linux-ia64",      "com.sun.jdi.SharedMemoryAttach"},
525         {"linux-amd64",     "com.sun.jdi.SharedMemoryAttach"},
526         {"linux-x64",       "com.sun.jdi.SharedMemoryAttach"},
527         {"linux-aarch64",   "com.sun.jdi.SharedMemoryAttach"},
528         {"linux-arm",       "com.sun.jdi.SharedMemoryAttach"},
529         {"linux-ppc64",     "com.sun.jdi.SharedMemoryAttach"},
530         {"linux-ppc64le",   "com.sun.jdi.SharedMemoryAttach"},
531         {"linux-s390x",     "com.sun.jdi.SharedMemoryAttach"},
532         {"linux-riscv64",   "com.sun.jdi.SharedMemoryAttach"},
533         {"macosx-amd64",    "com.sun.jdi.SharedMemoryAttach"},
534         {"mac-x64",         "com.sun.jdi.SharedMemoryAttach"},
535         {"macosx-aarch64",  "com.sun.jdi.SharedMemoryAttach"},
536         {"mac-aarch64",     "com.sun.jdi.SharedMemoryAttach"},
537         {"aix-ppc64",       "com.sun.jdi.SharedMemoryAttach"},
538 
539             // listening connectors
540         /*
541          * From docs/technotes/guides/jpda/conninv.html:
542          * "
543          *  This connector can be used by a debugger application to accept a
544          *  connection from  a separately invoked target VM through the shared memory
545          *  transport.
546          *  It is available only on the Microsoft Windows platform.
547          *  "
548          */
549         {"linux-i586",      "com.sun.jdi.SharedMemoryListen"},
550         {"linux-ia64",      "com.sun.jdi.SharedMemoryListen"},
551         {"linux-amd64",     "com.sun.jdi.SharedMemoryListen"},
552         {"linux-x64",       "com.sun.jdi.SharedMemoryListen"},
553         {"linux-aarch64",   "com.sun.jdi.SharedMemoryListen"},
554         {"linux-arm",       "com.sun.jdi.SharedMemoryListen"},
555         {"linux-ppc64",     "com.sun.jdi.SharedMemoryListen"},
556         {"linux-ppc64le",   "com.sun.jdi.SharedMemoryListen"},
557         {"linux-s390x",     "com.sun.jdi.SharedMemoryListen"},
558         {"linux-riscv64",   "com.sun.jdi.SharedMemoryListen"},
559         {"macosx-amd64",    "com.sun.jdi.SharedMemoryListen"},
560         {"mac-x64",         "com.sun.jdi.SharedMemoryListen"},
561         {"macosx-aarch64",  "com.sun.jdi.SharedMemoryListen"},
562         {"mac-aarch64",     "com.sun.jdi.SharedMemoryListen"},
563         {"aix-ppc64",       "com.sun.jdi.SharedMemoryListen"},
564 
565             // launching connectors
566         /*
567          * From docs/technotes/guides/jpda/conninv.html:
568          * "
569          *  Sun Command Line Launching Connector
570          *  This connector can be used by a debugger application to launch a
571          *  Sun VM or any other VM which supports the same invocation options with
572          *  respect to debugging. The details of launching the VM and specifying the
573          *  necessary debug options are handled by the connector. The underlying
574          *  transport used by this connector depends on the platform. On Microsoft
575          *  Windows, the shared memory transport is used. On Linux the socket transport is used.
576          * "
577          */
578         {"linux-i586",      "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
579         {"linux-i586",      "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
580 
581         {"linux-ia64",      "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
582         {"linux-ia64",      "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
583 
584         {"linux-amd64",     "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
585         {"linux-amd64",     "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
586 
587         {"linux-x64",       "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
588         {"linux-x64",       "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
589 
590         {"linux-aarch64",   "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
591         {"linux-aarch64",   "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
592 
593         {"linux-arm",       "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
594         {"linux-arm",       "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
595 
596         {"linux-ppc64",     "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
597         {"linux-ppc64",     "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
598 
599         {"linux-ppc64le",   "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
600         {"linux-ppc64le",   "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
601 
602         {"linux-s390x",     "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
603         {"linux-s390x",     "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
604 
605         {"linux-riscv64",   "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
606         {"linux-riscv64",   "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
607 
608         {"windows-i586",    "com.sun.jdi.CommandLineLaunch", "dt_socket"},
609         {"windows-i586",    "com.sun.jdi.RawCommandLineLaunch", "dt_socket"},
610 
611         {"windows-ia64",    "com.sun.jdi.CommandLineLaunch", "dt_socket"},
612         {"windows-ia64",    "com.sun.jdi.RawCommandLineLaunch", "dt_socket"},
613 
614         {"windows-amd64",   "com.sun.jdi.CommandLineLaunch", "dt_socket"},
615         {"windows-amd64",   "com.sun.jdi.RawCommandLineLaunch", "dt_socket"},
616 
617         {"windows-x64",     "com.sun.jdi.CommandLineLaunch", "dt_socket"},
618         {"windows-x64",     "com.sun.jdi.RawCommandLineLaunch", "dt_socket"},
619 
620         {"macosx-amd64",     "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
621         {"macosx-amd64",     "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
622 
623         {"mac-x64",          "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
624         {"mac-x64",          "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
625 
626         {"macosx-aarch64",   "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
627         {"macosx-aarch64",   "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
628 
629         {"mac-aarch64",      "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
630         {"mac-aarch64",      "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
631 
632         {"aix-ppc64",       "com.sun.jdi.CommandLineLaunch", "dt_shmem"},
633         {"aix-ppc64",       "com.sun.jdi.RawCommandLineLaunch", "dt_shmem"},
634 
635         // shared memory transport is implemented only on windows platform
636         {"linux-i586",      "dt_shmem"},
637         {"linux-ia64",      "dt_shmem"},
638         {"linux-amd64",     "dt_shmem"},
639         {"linux-x64",       "dt_shmem"},
640         {"linux-aarch64",   "dt_shmem"},
641         {"linux-arm",       "dt_shmem"},
642         {"linux-ppc64",     "dt_shmem"},
643         {"linux-ppc64le",   "dt_shmem"},
644         {"linux-s390x",     "dt_shmem"},
645         {"linux-riscv64",   "dt_shmem"},
646         {"macosx-amd64",    "dt_shmem"},
647         {"mac-x64",         "dt_shmem"},
648         {"macosx-aarch64",  "dt_shmem"},
649         {"mac-aarch64",     "dt_shmem"},
650         {"aix-ppc64",       "dt_shmem"},
651     };
652 }