Platform.java revision 2252:01852aa3235d
1/*
2 * Copyright (c) 2013, 2016, 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
24package jdk.test.lib;
25
26import java.util.regex.Pattern;
27
28public class Platform {
29    public  static final String vmName      = System.getProperty("java.vm.name");
30    public  static final String vmInfo      = System.getProperty("java.vm.info");
31    private static final String osName      = System.getProperty("os.name");
32    private static final String dataModel   = System.getProperty("sun.arch.data.model");
33    private static final String vmVersion   = System.getProperty("java.vm.version");
34    private static final String jdkDebug    = System.getProperty("jdk.debug");
35    private static final String osArch      = System.getProperty("os.arch");
36    private static final String userName    = System.getProperty("user.name");
37    private static final String compiler    = System.getProperty("sun.management.compiler");
38
39    public static boolean isClient() {
40        return vmName.endsWith(" Client VM");
41    }
42
43    public static boolean isServer() {
44        return vmName.endsWith(" Server VM");
45    }
46
47    public static boolean isGraal() {
48        return vmName.endsWith(" Graal VM");
49    }
50
51    public static boolean isZero() {
52        return vmName.endsWith(" Zero VM");
53    }
54
55    public static boolean isMinimal() {
56        return vmName.endsWith(" Minimal VM");
57    }
58
59    public static boolean isEmbedded() {
60        return vmName.contains("Embedded");
61    }
62
63    public static boolean isTieredSupported() {
64        return compiler.contains("Tiered Compilers");
65    }
66
67    public static boolean isInt() {
68        return vmInfo.contains("interpreted");
69    }
70
71    public static boolean isMixed() {
72        return vmInfo.contains("mixed");
73    }
74
75    public static boolean isComp() {
76        return vmInfo.contains("compiled");
77    }
78
79    public static boolean is32bit() {
80        return dataModel.equals("32");
81    }
82
83    public static boolean is64bit() {
84        return dataModel.equals("64");
85    }
86
87    public static boolean isAix() {
88        return isOs("aix");
89    }
90
91    public static boolean isLinux() {
92        return isOs("linux");
93    }
94
95    public static boolean isOSX() {
96        return isOs("mac");
97    }
98
99    public static boolean isSolaris() {
100        return isOs("sunos");
101    }
102
103    public static boolean isWindows() {
104        return isOs("win");
105    }
106
107    private static boolean isOs(String osname) {
108        return osName.toLowerCase().startsWith(osname.toLowerCase());
109    }
110
111    public static String getOsName() {
112        return osName;
113    }
114
115    public static boolean isDebugBuild() {
116        return (jdkDebug.toLowerCase().contains("debug"));
117    }
118
119    public static boolean isSlowDebugBuild() {
120        return (jdkDebug.toLowerCase().equals("slowdebug"));
121    }
122
123    public static boolean isFastDebugBuild() {
124        return (jdkDebug.toLowerCase().equals("fastdebug"));
125    }
126
127    public static String getVMVersion() {
128        return vmVersion;
129    }
130
131    // Returns true for sparc and sparcv9.
132    public static boolean isSparc() {
133        return isArch("sparc.*");
134    }
135
136    public static boolean isARM() {
137        return isArch("arm.*");
138    }
139
140    public static boolean isPPC() {
141        return isArch("ppc.*");
142    }
143
144    public static boolean isX86() {
145        // On Linux it's 'i386', Windows 'x86' without '_64' suffix.
146        return isArch("(i386)|(x86(?!_64))");
147    }
148
149    public static boolean isX64() {
150        // On OSX it's 'x86_64' and on other (Linux, Windows and Solaris) platforms it's 'amd64'
151        return isArch("(amd64)|(x86_64)");
152    }
153
154    public static boolean isAArch64() {
155        return isArch("aarch64");
156    }
157
158    public static String getOsArch() {
159        return osArch;
160    }
161
162    /**
163     * Return a boolean for whether we expect to be able to attach
164     * the SA to our own processes on this system.
165     */
166    public static boolean shouldSAAttach() throws Exception {
167
168        if (isAix()) {
169            return false;   // SA not implemented.
170        } else if (isLinux()) {
171            return canPtraceAttachLinux();
172        } else if (isOSX()) {
173            return canAttachOSX();
174        } else {
175            // Other platforms expected to work:
176            return true;
177        }
178    }
179
180    /**
181     * On Linux, first check the SELinux boolean "deny_ptrace" and return false
182     * as we expect to be denied if that is "1".  Then expect permission to attach
183     * if we are root, so return true.  Then return false for an expected denial
184     * if "ptrace_scope" is 1, and true otherwise.
185     */
186    public static boolean canPtraceAttachLinux() throws Exception {
187
188        // SELinux deny_ptrace:
189        String deny_ptrace = Utils.fileAsString("/sys/fs/selinux/booleans/deny_ptrace");
190        if (deny_ptrace != null && deny_ptrace.contains("1")) {
191            // ptrace will be denied:
192            return false;
193        }
194
195        // YAMA enhanced security ptrace_scope:
196        // 0 - a process can PTRACE_ATTACH to any other process running under the same uid
197        // 1 - restricted ptrace: a process must be a children of the inferior or user is root
198        // 2 - only processes with CAP_SYS_PTRACE may use ptrace or user is root
199        // 3 - no attach: no processes may use ptrace with PTRACE_ATTACH
200        String ptrace_scope = Utils.fileAsString("/proc/sys/kernel/yama/ptrace_scope");
201        if (ptrace_scope != null) {
202            if (ptrace_scope.startsWith("3")) {
203                return false;
204            }
205            if (!userName.equals("root") && !ptrace_scope.startsWith("0")) {
206                // ptrace will be denied:
207                return false;
208            }
209        }
210        // Otherwise expect to be permitted:
211        return true;
212    }
213
214    /**
215     * On OSX, expect permission to attach only if we are root.
216     */
217    public static boolean canAttachOSX() throws Exception {
218        return userName.equals("root");
219    }
220
221    private static boolean isArch(String archnameRE) {
222        return Pattern.compile(archnameRE, Pattern.CASE_INSENSITIVE)
223                      .matcher(osArch)
224                      .matches();
225    }
226}
227