Platform.java revision 2764:e2a74fa085ea
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.io.File;
27import java.io.IOException;
28import java.io.RandomAccessFile;
29import java.util.regex.Pattern;
30
31public class Platform {
32    public  static final String vmName      = System.getProperty("java.vm.name");
33    public  static final String vmInfo      = System.getProperty("java.vm.info");
34    private static final String osVersion   = System.getProperty("os.version");
35    private static       int osVersionMajor = -1;
36    private static       int osVersionMinor = -1;
37    private static final String osName      = System.getProperty("os.name");
38    private static final String dataModel   = System.getProperty("sun.arch.data.model");
39    private static final String vmVersion   = System.getProperty("java.vm.version");
40    private static final String jdkDebug    = System.getProperty("jdk.debug");
41    private static final String osArch      = System.getProperty("os.arch");
42    private static final String userName    = System.getProperty("user.name");
43    private static final String compiler    = System.getProperty("sun.management.compiler");
44
45    public static boolean isClient() {
46        return vmName.endsWith(" Client VM");
47    }
48
49    public static boolean isServer() {
50        return vmName.endsWith(" Server VM");
51    }
52
53    public static boolean isGraal() {
54        return vmName.endsWith(" Graal VM");
55    }
56
57    public static boolean isZero() {
58        return vmName.endsWith(" Zero VM");
59    }
60
61    public static boolean isMinimal() {
62        return vmName.endsWith(" Minimal VM");
63    }
64
65    public static boolean isEmbedded() {
66        return vmName.contains("Embedded");
67    }
68
69    public static boolean isEmulatedClient() {
70        return vmInfo.contains(" emulated-client");
71    }
72
73    public static boolean isTieredSupported() {
74        return compiler.contains("Tiered Compilers");
75    }
76
77    public static boolean isInt() {
78        return vmInfo.contains("interpreted");
79    }
80
81    public static boolean isMixed() {
82        return vmInfo.contains("mixed");
83    }
84
85    public static boolean isComp() {
86        return vmInfo.contains("compiled");
87    }
88
89    public static boolean is32bit() {
90        return dataModel.equals("32");
91    }
92
93    public static boolean is64bit() {
94        return dataModel.equals("64");
95    }
96
97    public static boolean isAix() {
98        return isOs("aix");
99    }
100
101    public static boolean isLinux() {
102        return isOs("linux");
103    }
104
105    public static boolean isOSX() {
106        return isOs("mac");
107    }
108
109    public static boolean isSolaris() {
110        return isOs("sunos");
111    }
112
113    public static boolean isWindows() {
114        return isOs("win");
115    }
116
117    private static boolean isOs(String osname) {
118        return osName.toLowerCase().startsWith(osname.toLowerCase());
119    }
120
121    public static String getOsName() {
122        return osName;
123    }
124
125    // Os version support.
126    private static void init_version() {
127        try {
128            final String[] tokens = osVersion.split("\\.");
129            if (tokens.length > 0) {
130                osVersionMajor = Integer.parseInt(tokens[0]);
131                if (tokens.length > 1) {
132                    osVersionMinor = Integer.parseInt(tokens[1]);
133                }
134            }
135        } catch (NumberFormatException e) {
136            osVersionMajor = osVersionMinor = 0;
137        }
138    }
139
140    // Returns major version number from os.version system property.
141    // E.g. 5 on Solaris 10 and 3 on SLES 11.3 (for the linux kernel version).
142    public static int getOsVersionMajor() {
143        if (osVersionMajor == -1) init_version();
144        return osVersionMajor;
145    }
146
147    // Returns minor version number from os.version system property.
148    // E.g. 10 on Solaris 10 and 0 on SLES 11.3 (for the linux kernel version).
149    public static int getOsVersionMinor() {
150        if (osVersionMinor == -1) init_version();
151        return osVersionMinor;
152    }
153
154    public static boolean isDebugBuild() {
155        return (jdkDebug.toLowerCase().contains("debug"));
156    }
157
158    public static boolean isSlowDebugBuild() {
159        return (jdkDebug.toLowerCase().equals("slowdebug"));
160    }
161
162    public static boolean isFastDebugBuild() {
163        return (jdkDebug.toLowerCase().equals("fastdebug"));
164    }
165
166    public static String getVMVersion() {
167        return vmVersion;
168    }
169
170    public static boolean isAArch64() {
171        return isArch("aarch64");
172    }
173
174    public static boolean isARM() {
175        return isArch("arm.*");
176    }
177
178    public static boolean isPPC() {
179        return isArch("ppc.*");
180    }
181
182    // Returns true for IBM z System running linux.
183    public static boolean isS390x() {
184        return isArch("s390.*") || isArch("s/390.*") || isArch("zArch_64");
185    }
186
187    // Returns true for sparc and sparcv9.
188    public static boolean isSparc() {
189        return isArch("sparc.*");
190    }
191
192    public static boolean isX64() {
193        // On OSX it's 'x86_64' and on other (Linux, Windows and Solaris) platforms it's 'amd64'
194        return isArch("(amd64)|(x86_64)");
195    }
196
197    public static boolean isX86() {
198        // On Linux it's 'i386', Windows 'x86' without '_64' suffix.
199        return isArch("(i386)|(x86(?!_64))");
200    }
201
202    public static String getOsArch() {
203        return osArch;
204    }
205
206    /**
207     * Return a boolean for whether we expect to be able to attach
208     * the SA to our own processes on this system.
209     */
210    public static boolean shouldSAAttach() throws IOException {
211        if (isAix()) {
212            return false; // SA not implemented.
213        } else if (isLinux()) {
214            if (isS390x()) {
215                return false; // SA not implemented.
216            }
217            return canPtraceAttachLinux();
218        } else if (isOSX()) {
219            return canAttachOSX();
220        } else {
221            // Other platforms expected to work:
222            return true;
223        }
224    }
225
226    /**
227     * On Linux, first check the SELinux boolean "deny_ptrace" and return false
228     * as we expect to be denied if that is "1".  Then expect permission to attach
229     * if we are root, so return true.  Then return false for an expected denial
230     * if "ptrace_scope" is 1, and true otherwise.
231     */
232    private static boolean canPtraceAttachLinux() throws IOException {
233        // SELinux deny_ptrace:
234        File deny_ptrace = new File("/sys/fs/selinux/booleans/deny_ptrace");
235        if (deny_ptrace.exists()) {
236            try (RandomAccessFile file = new RandomAccessFile(deny_ptrace, "r")) {
237                if (file.readByte() != '0') {
238                    return false;
239                }
240            }
241        }
242
243        // YAMA enhanced security ptrace_scope:
244        // 0 - a process can PTRACE_ATTACH to any other process running under the same uid
245        // 1 - restricted ptrace: a process must be a children of the inferior or user is root
246        // 2 - only processes with CAP_SYS_PTRACE may use ptrace or user is root
247        // 3 - no attach: no processes may use ptrace with PTRACE_ATTACH
248        File ptrace_scope = new File("/proc/sys/kernel/yama/ptrace_scope");
249        if (ptrace_scope.exists()) {
250            try (RandomAccessFile file = new RandomAccessFile(ptrace_scope, "r")) {
251                byte yama_scope = file.readByte();
252                if (yama_scope == '3') {
253                    return false;
254                }
255
256                if (!userName.equals("root") && yama_scope != '0') {
257                    return false;
258                }
259            }
260        }
261        // Otherwise expect to be permitted:
262        return true;
263    }
264
265    /**
266     * On OSX, expect permission to attach only if we are root.
267     */
268    private static boolean canAttachOSX() {
269        return userName.equals("root");
270    }
271
272    private static boolean isArch(String archnameRE) {
273        return Pattern.compile(archnameRE, Pattern.CASE_INSENSITIVE)
274                      .matcher(osArch)
275                      .matches();
276    }
277
278    /**
279     * Returns file extension of shared library, e.g. "so" on linux, "dll" on windows.
280     * @return file extension
281     */
282    public static String sharedLibraryExt() {
283        if (isWindows()) {
284            return "dll";
285        } else if (isOSX()) {
286            return "dylib";
287        } else {
288            return "so";
289        }
290    }
291}
292