blob: 46b9e71b138e0ca07af72c20f77bf02f001102a6 [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
85static jvmtiError Copy(jvmtiEnv* env, const char* in, char** out) {
86 unsigned char* data = nullptr;
87 jvmtiError result = CopyString(env, in, &data);
88 *out = reinterpret_cast<char*>(data);
89 return result;
90}
91
92jvmtiError PropertiesUtil::GetSystemProperties(jvmtiEnv* env,
93 jint* count_ptr,
94 char*** property_ptr) {
95 if (count_ptr == nullptr || property_ptr == nullptr) {
96 return ERR(NULL_POINTER);
97 }
98 unsigned char* array_data;
99 jvmtiError array_alloc_result = env->Allocate((kPropertiesSize + 2) * sizeof(char*), &array_data);
100 if (array_alloc_result != ERR(NONE)) {
101 return array_alloc_result;
102 }
103 JvmtiUniquePtr array_data_ptr = MakeJvmtiUniquePtr(env, array_data);
104 char** array = reinterpret_cast<char**>(array_data);
105
106 std::vector<JvmtiUniquePtr> property_copies;
107
108 {
109 char* libpath_data;
110 jvmtiError libpath_result = Copy(env, kPropertyLibraryPath, &libpath_data);
111 if (libpath_result != ERR(NONE)) {
112 return libpath_result;
113 }
114 array[0] = libpath_data;
115 property_copies.push_back(MakeJvmtiUniquePtr(env, libpath_data));
116 }
117
118 {
119 char* classpath_data;
120 jvmtiError classpath_result = Copy(env, kPropertyClassPath, &classpath_data);
121 if (classpath_result != ERR(NONE)) {
122 return classpath_result;
123 }
124 array[1] = classpath_data;
125 property_copies.push_back(MakeJvmtiUniquePtr(env, classpath_data));
126 }
127
128 for (size_t i = 0; i != kPropertiesSize; ++i) {
129 char* data;
130 jvmtiError data_result = Copy(env, kProperties[i][0], &data);
131 if (data_result != ERR(NONE)) {
132 return data_result;
133 }
134 array[i + 2] = data;
135 property_copies.push_back(MakeJvmtiUniquePtr(env, data));
136 }
137
138 // Everything is OK, release the data.
139 array_data_ptr.release();
140 for (auto& uptr : property_copies) {
141 uptr.release();
142 }
143
144 *count_ptr = kPropertiesSize + 2;
145 *property_ptr = array;
146
147 return ERR(NONE);
148}
149
150jvmtiError PropertiesUtil::GetSystemProperty(jvmtiEnv* env,
151 const char* property,
152 char** value_ptr) {
153 if (property == nullptr || value_ptr == nullptr) {
154 return ERR(NULL_POINTER);
155 }
156
157 if (strcmp(property, kPropertyLibraryPath) == 0) {
158 // TODO: In the live phase, we should probably compare to System.getProperty. java.library.path
159 // may not be set initially, and is then freely modifiable.
160 const std::vector<std::string>& runtime_props = art::Runtime::Current()->GetProperties();
161 for (const std::string& prop_assignment : runtime_props) {
162 size_t assign_pos = prop_assignment.find('=');
163 if (assign_pos != std::string::npos && assign_pos > 0) {
164 if (prop_assignment.substr(0, assign_pos) == kPropertyLibraryPath) {
165 return Copy(env, prop_assignment.substr(assign_pos + 1).c_str(), value_ptr);
166 }
167 }
168 }
169 return ERR(NOT_AVAILABLE);
170 }
171
172 if (strcmp(property, kPropertyClassPath) == 0) {
173 return Copy(env, art::Runtime::Current()->GetClassPathString().c_str(), value_ptr);
174 }
175
176 for (size_t i = 0; i != kPropertiesSize; ++i) {
177 if (strcmp(property, kProperties[i][0]) == 0) {
178 return Copy(env, kProperties[i][1], value_ptr);
179 }
180 }
181
182 return ERR(NOT_AVAILABLE);
183}
184
185jvmtiError PropertiesUtil::SetSystemProperty(jvmtiEnv* env ATTRIBUTE_UNUSED,
186 const char* property ATTRIBUTE_UNUSED,
187 const char* value ATTRIBUTE_UNUSED) {
188 // We do not allow manipulation of any property here.
189 return ERR(NOT_AVAILABLE);
190}
191
192} // namespace openjdkjvmti