1 /*
2  * Copyright (c) 2003, 2018, 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 #include <stdio.h>
25 #include <string.h>
26 #include "jvmti.h"
27 #include "agent_common.h"
28 #include "JVMTITools.h"
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 #ifndef JNI_ENV_ARG
35 
36 #ifdef __cplusplus
37 #define JNI_ENV_ARG(x, y) y
38 #define JNI_ENV_PTR(x) x
39 #else
40 #define JNI_ENV_ARG(x,y) x, y
41 #define JNI_ENV_PTR(x) (*x)
42 #endif
43 
44 #endif
45 
46 #define PASSED 0
47 #define STATUS_FAILED 2
48 
49 static jvmtiEnv *jvmti = NULL;
50 static jint result = PASSED;
51 static jboolean printdump = JNI_FALSE;
52 
53 #ifdef STATIC_BUILD
Agent_OnLoad_methloc002(JavaVM * jvm,char * options,void * reserved)54 JNIEXPORT jint JNICALL Agent_OnLoad_methloc002(JavaVM *jvm, char *options, void *reserved) {
55     return Agent_Initialize(jvm, options, reserved);
56 }
Agent_OnAttach_methloc002(JavaVM * jvm,char * options,void * reserved)57 JNIEXPORT jint JNICALL Agent_OnAttach_methloc002(JavaVM *jvm, char *options, void *reserved) {
58     return Agent_Initialize(jvm, options, reserved);
59 }
JNI_OnLoad_methloc002(JavaVM * jvm,char * options,void * reserved)60 JNIEXPORT jint JNI_OnLoad_methloc002(JavaVM *jvm, char *options, void *reserved) {
61     return JNI_VERSION_1_8;
62 }
63 #endif
Agent_Initialize(JavaVM * jvm,char * options,void * reserved)64 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
65     jint res;
66 
67     if (options != NULL && strcmp(options, "printdump") == 0) {
68         printdump = JNI_TRUE;
69     }
70 
71     res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti),
72         JVMTI_VERSION_1_1);
73     if (res != JNI_OK || jvmti == NULL) {
74         printf("Wrong result of a valid call to GetEnv!\n");
75         return JNI_ERR;
76     }
77 
78     return JNI_OK;
79 }
80 
81 JNIEXPORT jint JNICALL
Java_nsk_jvmti_GetMethodLocation_methloc002_check(JNIEnv * env,jclass cls)82 Java_nsk_jvmti_GetMethodLocation_methloc002_check(JNIEnv *env, jclass cls) {
83     jvmtiError err;
84     jmethodID mid;
85     jlocation startLocation;
86     jlocation endLocation;
87 
88     if (jvmti == NULL) {
89         printf("JVMTI client was not properly loaded!\n");
90         return STATUS_FAILED;
91     }
92 
93     mid = JNI_ENV_PTR(env)->GetMethodID(JNI_ENV_ARG(env, cls), "<init>", "()V");
94     if (mid == NULL) {
95         printf("Cannot get method ID for \"<init>\"!\n");
96         return STATUS_FAILED;
97     }
98 
99     if (printdump == JNI_TRUE) {
100         printf(">>> invalid method check ...\n");
101     }
102     err = (*jvmti)->GetMethodLocation(jvmti, NULL, &startLocation, &endLocation);
103     if (err != JVMTI_ERROR_INVALID_METHODID) {
104         printf("Error expected: JVMTI_ERROR_INVALID_METHODID,\n");
105         printf("\tactual: %s (%d)\n", TranslateError(err), err);
106         result = STATUS_FAILED;
107     }
108 
109     if (printdump == JNI_TRUE) {
110         printf(">>> (startLocationPtr) null pointer check ...\n");
111     }
112     err = (*jvmti)->GetMethodLocation(jvmti, mid, NULL, &endLocation);
113     if (err != JVMTI_ERROR_NULL_POINTER) {
114         printf("(startLocationPtr) error expected: JVMTI_ERROR_NULL_POINTER,\n");
115         printf("\tactual: %s (%d)\n", TranslateError(err), err);
116         result = STATUS_FAILED;
117     }
118 
119     if (printdump == JNI_TRUE) {
120         printf(">>> (endLocationPtr) null pointer check ...\n");
121     }
122     err = (*jvmti)->GetMethodLocation(jvmti, mid, &startLocation, NULL);
123     if (err != JVMTI_ERROR_NULL_POINTER) {
124         printf("(endLocationPtr) error expected: JVMTI_ERROR_NULL_POINTER,\n");
125         printf("\tactual: %s (%d)\n", TranslateError(err), err);
126         result = STATUS_FAILED;
127     }
128 
129     mid = JNI_ENV_PTR(env)->GetStaticMethodID(JNI_ENV_ARG(env, cls),
130         "check", "()I");
131     if (mid == NULL) {
132         printf("Cannot get method ID for \"check\"!\n");
133         return STATUS_FAILED;
134     }
135 
136     if (printdump == JNI_TRUE) {
137         printf(">>> native method check ...\n");
138     }
139     err = (*jvmti)->GetMethodLocation(jvmti, mid, &startLocation, &endLocation);
140     if (err != JVMTI_ERROR_NATIVE_METHOD) {
141         printf("Error expected: JVMTI_ERROR_NATIVE_METHOD,\n");
142         printf("\tactual: %s (%d)\n", TranslateError(err), err);
143         result = STATUS_FAILED;
144     }
145 
146     if (printdump == JNI_TRUE) {
147         printf(">>> ... done\n");
148     }
149 
150     return result;
151 }
152 
153 #ifdef __cplusplus
154 }
155 #endif
156