blob: 4f4f01390d7ebb7ba7257d7da714f4e7063997fb [file] [log] [blame]
Andreas Gampe1bdaf732017-01-09 19:21:06 -08001/* Copyright (C) 2017 The Android Open Source Project
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This file implements interfaces from the file jvmti.h. This implementation
5 * is licensed under the same terms as the file jvmti.h. The
6 * copyright and license information for the file jvmti.h follows.
7 *
8 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10 *
11 * This code is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 only, as
13 * published by the Free Software Foundation. Oracle designates this
14 * particular file as subject to the "Classpath" exception as provided
15 * by Oracle in the LICENSE file that accompanied this code.
16 *
17 * This code is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * version 2 for more details (a copy is included in the LICENSE file that
21 * accompanied this code).
22 *
23 * You should have received a copy of the GNU General Public License version
24 * 2 along with this work; if not, write to the Free Software Foundation,
25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26 *
27 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28 * or visit www.oracle.com if you need additional information or have any
29 * questions.
30 */
31
32#include "ti_properties.h"
33
34#include <string.h>
35#include <vector>
36
37#include "art_jvmti.h"
38#include "runtime.h"
39
40namespace openjdkjvmti {
41
42// Hardcoded properties. Tests ensure that these are consistent with libcore's view, as seen
43// in System.java and AndroidHardcodedSystemProperties.java.
44static constexpr const char* kProperties[][2] = {
45 // Recommended by the spec.
46 { "java.vm.vendor", "The Android Project" },
47 { "java.vm.version", "2.1.0" }, // This is Runtime::GetVersion().
48 { "java.vm.name", "Dalvik" },
49 // Android does not provide java.vm.info.
50 //
51 // These are other values provided by AndroidHardcodedSystemProperties.
52 { "java.class.version", "50.0" },
53 { "java.version", "0" },
54 { "java.compiler", "" },
55 { "java.ext.dirs", "" },
56
57 { "java.specification.name", "Dalvik Core Library" },
58 { "java.specification.vendor", "The Android Project" },
59 { "java.specification.version", "0.9" },
60
61 { "java.vendor", "The Android Project" },
62 { "java.vendor.url", "http://www.android.com/" },
63 { "java.vm.name", "Dalvik" },
64 { "java.vm.specification.name", "Dalvik Virtual Machine Specification" },
65 { "java.vm.specification.vendor", "The Android Project" },
66 { "java.vm.specification.version", "0.9" },
67 { "java.vm.vendor", "The Android Project" },
68
69 { "java.vm.vendor.url", "http://www.android.com/" },
70
71 { "java.net.preferIPv6Addresses", "false" },
72
73 { "file.encoding", "UTF-8" },
74
75 { "file.separator", "/" },
76 { "line.separator", "\n" },
77 { "path.separator", ":" },
78
79 { "os.name", "Linux" },
80};
81static constexpr size_t kPropertiesSize = arraysize(kProperties);
82static constexpr const char* kPropertyLibraryPath = "java.library.path";
83static constexpr const char* kPropertyClassPath = "java.class.path";
84
Andreas Gampe1bdaf732017-01-09 19:21:06 -080085jvmtiError PropertiesUtil::GetSystemProperties(jvmtiEnv* env,
86 jint* count_ptr,
87 char*** property_ptr) {
88 if (count_ptr == nullptr || property_ptr == nullptr) {
89 return ERR(NULL_POINTER);
90 }
Andreas Gampe54711412017-02-21 12:41:43 -080091 jvmtiError array_alloc_result;
92 JvmtiUniquePtr<char*[]> array_data_ptr = AllocJvmtiUniquePtr<char*[]>(env,
93 kPropertiesSize + 2,
94 &array_alloc_result);
95 if (array_data_ptr == nullptr) {
Andreas Gampe1bdaf732017-01-09 19:21:06 -080096 return array_alloc_result;
97 }
Andreas Gampe1bdaf732017-01-09 19:21:06 -080098
Andreas Gampe54711412017-02-21 12:41:43 -080099 std::vector<JvmtiUniquePtr<char[]>> property_copies;
Andreas Gampe1bdaf732017-01-09 19:21:06 -0800100
101 {
Andreas Gampe54711412017-02-21 12:41:43 -0800102 jvmtiError libpath_result;
103 JvmtiUniquePtr<char[]> libpath_data = CopyString(env, kPropertyLibraryPath, &libpath_result);
104 if (libpath_data == nullptr) {
Andreas Gampe1bdaf732017-01-09 19:21:06 -0800105 return libpath_result;
106 }
Andreas Gampe54711412017-02-21 12:41:43 -0800107 array_data_ptr.get()[0] = libpath_data.get();
108 property_copies.push_back(std::move(libpath_data));
Andreas Gampe1bdaf732017-01-09 19:21:06 -0800109 }
110
111 {
Andreas Gampe54711412017-02-21 12:41:43 -0800112 jvmtiError classpath_result;
113 JvmtiUniquePtr<char[]> classpath_data = CopyString(env, kPropertyClassPath, &classpath_result);
114 if (classpath_data == nullptr) {
Andreas Gampe1bdaf732017-01-09 19:21:06 -0800115 return classpath_result;
116 }
Andreas Gampe54711412017-02-21 12:41:43 -0800117 array_data_ptr.get()[1] = classpath_data.get();
118 property_copies.push_back(std::move(classpath_data));
Andreas Gampe1bdaf732017-01-09 19:21:06 -0800119 }
120
121 for (size_t i = 0; i != kPropertiesSize; ++i) {
Andreas Gampe54711412017-02-21 12:41:43 -0800122 jvmtiError data_result;
123 JvmtiUniquePtr<char[]> data = CopyString(env, kProperties[i][0], &data_result);
124 if (data == nullptr) {
Andreas Gampe1bdaf732017-01-09 19:21:06 -0800125 return data_result;
126 }
Andreas Gampe54711412017-02-21 12:41:43 -0800127 array_data_ptr.get()[i + 2] = data.get();
128 property_copies.push_back(std::move(data));
Andreas Gampe1bdaf732017-01-09 19:21:06 -0800129 }
130
131 // Everything is OK, release the data.
Andreas Gampe54711412017-02-21 12:41:43 -0800132 *count_ptr = kPropertiesSize + 2;
133 *property_ptr = array_data_ptr.release();
Andreas Gampe1bdaf732017-01-09 19:21:06 -0800134 for (auto& uptr : property_copies) {
135 uptr.release();
136 }
137
Andreas Gampe1bdaf732017-01-09 19:21:06 -0800138 return ERR(NONE);
139}
140
Andreas Gampe54711412017-02-21 12:41:43 -0800141static jvmtiError Copy(jvmtiEnv* env, const char* in, char** out) {
142 jvmtiError result;
143 JvmtiUniquePtr<char[]> data = CopyString(env, in, &result);
144 *out = data.release();
145 return result;
146}
147
Andreas Gampe1bdaf732017-01-09 19:21:06 -0800148jvmtiError PropertiesUtil::GetSystemProperty(jvmtiEnv* env,
149 const char* property,
150 char** value_ptr) {
151 if (property == nullptr || value_ptr == nullptr) {
152 return ERR(NULL_POINTER);
153 }
154
155 if (strcmp(property, kPropertyLibraryPath) == 0) {
156 // TODO: In the live phase, we should probably compare to System.getProperty. java.library.path
157 // may not be set initially, and is then freely modifiable.
158 const std::vector<std::string>& runtime_props = art::Runtime::Current()->GetProperties();
159 for (const std::string& prop_assignment : runtime_props) {
160 size_t assign_pos = prop_assignment.find('=');
161 if (assign_pos != std::string::npos && assign_pos > 0) {
162 if (prop_assignment.substr(0, assign_pos) == kPropertyLibraryPath) {
163 return Copy(env, prop_assignment.substr(assign_pos + 1).c_str(), value_ptr);
164 }
165 }
166 }
167 return ERR(NOT_AVAILABLE);
168 }
169
170 if (strcmp(property, kPropertyClassPath) == 0) {
171 return Copy(env, art::Runtime::Current()->GetClassPathString().c_str(), value_ptr);
172 }
173
174 for (size_t i = 0; i != kPropertiesSize; ++i) {
175 if (strcmp(property, kProperties[i][0]) == 0) {
176 return Copy(env, kProperties[i][1], value_ptr);
177 }
178 }
179
180 return ERR(NOT_AVAILABLE);
181}
182
183jvmtiError PropertiesUtil::SetSystemProperty(jvmtiEnv* env ATTRIBUTE_UNUSED,
184 const char* property ATTRIBUTE_UNUSED,
185 const char* value ATTRIBUTE_UNUSED) {
186 // We do not allow manipulation of any property here.
187 return ERR(NOT_AVAILABLE);
188}
189
190} // namespace openjdkjvmti