xref: /onnv-gate/usr/src/lib/libdtrace_jni/common/dtj_util.h (revision 6136:b1f0a0698377)
11449Stomee /*
21449Stomee  * CDDL HEADER START
31449Stomee  *
41449Stomee  * The contents of this file are subject to the terms of the
51449Stomee  * Common Development and Distribution License (the "License").
61449Stomee  * You may not use this file except in compliance with the License.
71449Stomee  *
81449Stomee  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91449Stomee  * or http://www.opensolaris.org/os/licensing.
101449Stomee  * See the License for the specific language governing permissions
111449Stomee  * and limitations under the License.
121449Stomee  *
131449Stomee  * When distributing Covered Code, include this CDDL HEADER in each
141449Stomee  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151449Stomee  * If applicable, add the following below this CDDL HEADER, with the
161449Stomee  * fields enclosed by brackets "[]" replaced with your own identifying
171449Stomee  * information: Portions Copyright [yyyy] [name of copyright owner]
181449Stomee  *
191449Stomee  * CDDL HEADER END
201449Stomee  */
211449Stomee 
221449Stomee /*
23*6136Stomee  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
241449Stomee  * Use is subject to license terms.
251449Stomee  */
261449Stomee 
271449Stomee #ifndef	_DTJ_UTIL_H
281449Stomee #define	_DTJ_UTIL_H
291449Stomee 
301449Stomee #pragma ident	"%Z%%M%	%I%	%E% SMI"
311449Stomee 
321449Stomee #include <jni.h>
331449Stomee #include <libuutil.h>
341449Stomee 
351449Stomee #ifdef	__cplusplus
361449Stomee extern "C" {
371449Stomee #endif
381449Stomee 
391449Stomee /*
401449Stomee  * dtj_util.h separates functionality that is generally useful from
411449Stomee  * that which is specific to the Java DTrace API.  If moved to a separate
421449Stomee  * library, this functionality could be shared by other JNI wrappers.
431449Stomee  */
441449Stomee 
451449Stomee #ifdef JNI_VERSION_1_4
461449Stomee #define	JNI_VERSION JNI_VERSION_1_4
471449Stomee #else
481449Stomee #define	JNI_VERSION JNI_VERSION_1_2
491449Stomee #endif
501449Stomee 
511449Stomee #define	CONSTRUCTOR "<init>"
521449Stomee #define	DTJ_MSG_SIZE 1024
531449Stomee #define	DTJ_INVALID_PTR ((void *)-1)
541449Stomee #define	DTJ_INVALID_STR ((const char *)-1)
551449Stomee 
561449Stomee #define	WRAP_EXCEPTION(JENV)	dtj_wrap_exception((JENV), __FILE__, __LINE__)
571449Stomee 
581449Stomee extern boolean_t g_dtj_util_debug;
591449Stomee 
601449Stomee typedef enum dtj_status {
611449Stomee 	DTJ_OK = JNI_OK,
621449Stomee 	DTJ_ERR = JNI_ERR
631449Stomee } dtj_status_t;
641449Stomee 
651449Stomee typedef enum dtj_type {
661449Stomee 	JCLASS,
671449Stomee 	JMETHOD,
681449Stomee 	JMETHOD_STATIC,
691449Stomee 	JFIELD,
701449Stomee 	JFIELD_STATIC,
711449Stomee 	DTJ_TYPE_END = -1
721449Stomee } dtj_type_t;
731449Stomee 
741449Stomee /*
751449Stomee  * Convenient description format for java classes, methods, and fields.  The
761449Stomee  * java_class_t, java_method_t, and java_field_t structures derived from these
771449Stomee  * descriptions are used to create a table of usable JNI jclass, jmethodID, and
781449Stomee  * jfieldID instances.
791449Stomee  */
801449Stomee typedef struct dtj_table_entry {
811449Stomee 	dtj_type_t djte_type;	/* JNI type */
821449Stomee 	void *djte_addr;	/* jclass, jmethodID, or jfieldID address */
831449Stomee 	char *djte_name;	/* symbol name declared in Java */
841449Stomee 	char *djte_desc;	/* JNI descriptor (string format) */
851449Stomee } dtj_table_entry_t;
861449Stomee 
871449Stomee typedef struct dtj_java_class {
881449Stomee 	jclass *djc_ptr;	/* address in user-defined structure */
891449Stomee 	char *djc_name;		/* fully qualified '/' delimited class name */
901449Stomee 	uu_list_t *djc_methods;	/* element type (java_method_t *) */
911449Stomee 	uu_list_t *djc_fields;	/* element type (java_field_t *) */
921449Stomee 	uu_list_node_t djc_node;
931449Stomee } dtj_java_class_t;
941449Stomee 
951449Stomee typedef struct dtj_java_method {
961449Stomee 	jmethodID *djm_ptr;	/* address in user-defined structure */
971449Stomee 	char *djm_name;		/* method name in java source file */
981449Stomee 	char *djm_signature;	/* javap -s method signature string */
991449Stomee 	boolean_t djm_static;	/* flag indicating static qualifier */
1001449Stomee 	uu_list_node_t djm_node;
1011449Stomee } dtj_java_method_t;
1021449Stomee 
1031449Stomee typedef struct dtj_java_field {
1041449Stomee 	jfieldID *djf_ptr;	/* address in user-defined structure */
1051449Stomee 	char *djf_name;		/* field name in java source file */
1061449Stomee 	char *djf_type;		/* javap -s field type string */
1071449Stomee 	boolean_t djf_static;	/* flag indicating static qualifier */
1081449Stomee 	uu_list_node_t djf_node;
1091449Stomee } dtj_java_field_t;
1101449Stomee 
1111449Stomee /*
1121449Stomee  * Table of cached jclass, jmethodID, and jfieldID values usable across multiple
1131449Stomee  * native method calls and multiple threads.
1141449Stomee  *
1151449Stomee  * Suffix conventions:
1161449Stomee  *   jc  java class
1171449Stomee  *   jm  java method
1181449Stomee  *   jsm java static method
1191449Stomee  *   jf  java field
1201449Stomee  *   jsf java static field
1211449Stomee  */
1221449Stomee 
1231449Stomee /* NativeException */
1241449Stomee extern jclass g_nx_jc;
1251449Stomee extern jmethodID g_nxinit_jm;
1261449Stomee 
1271449Stomee /* java.io.Serializable */
1281449Stomee extern jclass g_serial_jc;
1291449Stomee 
1301449Stomee /* java.lang.Number */
1311449Stomee extern jclass g_number_jc;
1321449Stomee extern jmethodID g_shortval_jm;
1331449Stomee extern jmethodID g_intval_jm;
1341449Stomee extern jmethodID g_longval_jm;
1351449Stomee 
1361449Stomee /* java.lang.Byte */
1371449Stomee extern jclass g_byte_jc;
1381449Stomee extern jmethodID g_byteinit_jm;
1391449Stomee 
1401449Stomee /* java.lang.Character */
1411449Stomee extern jclass g_char_jc;
1421449Stomee extern jmethodID g_charinit_jm;
1431449Stomee extern jmethodID g_charval_jm;
1441449Stomee 
1451449Stomee /* java.lang.Short */
1461449Stomee extern jclass g_short_jc;
1471449Stomee extern jmethodID g_shortinit_jm;
1481449Stomee 
1491449Stomee /* java.lang.Integer */
1501449Stomee extern jclass g_int_jc;
1511449Stomee extern jmethodID g_intinit_jm;
1521449Stomee 
1531449Stomee /* java.lang.Long */
1541449Stomee extern jclass g_long_jc;
1551449Stomee extern jmethodID g_longinit_jm;
1561449Stomee 
157*6136Stomee /* java.math.BigInteger */
158*6136Stomee extern jclass g_bigint_jc;
159*6136Stomee extern jmethodID g_bigint_val_jsm;
160*6136Stomee extern jmethodID g_bigint_div_jm;
161*6136Stomee extern jmethodID g_bigint_shl_jm;
162*6136Stomee extern jmethodID g_bigint_or_jm;
163*6136Stomee extern jmethodID g_bigint_setbit_jm;
164*6136Stomee 
1651449Stomee /* java.lang.String */
1661449Stomee extern jclass g_string_jc;
1671449Stomee extern jmethodID g_strinit_bytes_jm;
1681449Stomee extern jmethodID g_strbytes_jm;
1691449Stomee extern jmethodID g_trim_jm;
1701449Stomee 
1711449Stomee /* java.lang.StringBuffer */
1721449Stomee extern jclass g_buf_jc;
1731449Stomee extern jmethodID g_bufinit_jm;
1741449Stomee extern jmethodID g_buf_append_char_jm;
1751449Stomee extern jmethodID g_buf_append_int_jm;
1761449Stomee extern jmethodID g_buf_append_long_jm;
1771449Stomee extern jmethodID g_buf_append_str_jm;
1781449Stomee extern jmethodID g_buf_append_obj_jm;
1791449Stomee extern jmethodID g_buflen_jm;
1801449Stomee extern jmethodID g_bufsetlen_jm;
1811449Stomee 
1821449Stomee /* java.lang.Object */
1831449Stomee extern jclass g_object_jc;
1841449Stomee extern jmethodID g_tostring_jm;
1851449Stomee extern jmethodID g_equals_jm;
1861449Stomee 
1871449Stomee /* java.lang.Enum */
1881449Stomee extern jclass g_enum_jc;
1891449Stomee extern jmethodID g_enumname_jm;
1901449Stomee 
1911449Stomee /* List */
1921449Stomee extern jclass g_list_jc;
1931449Stomee extern jmethodID g_listclear_jm;
1941449Stomee extern jmethodID g_listadd_jm;
1951449Stomee extern jmethodID g_listget_jm;
1961449Stomee extern jmethodID g_listsize_jm;
1971449Stomee 
1981449Stomee /*
1991449Stomee  * Populates the common java class references and associated method and field
2001449Stomee  * IDs declared in this file (above) using the dtj_cache_jni_classes() method.
2011449Stomee  */
2021449Stomee extern dtj_status_t dtj_load_common(JNIEnv *);
2031449Stomee 
2041449Stomee /*
2051449Stomee  * Populates the user-declared java class references and associated method and
2061449Stomee  * field IDs described in the given table.  Because the class references are
2071449Stomee  * created as global JNI references, the method and field IDs remain valid
2081449Stomee  * across multiple native method calls and across multiple threads.
2091449Stomee  *
2101449Stomee  * This function assumes that the given table of java class, method, and field
2111449Stomee  * descriptions is terminated by an entry with DTJ_TYPE_END, and that the
2121449Stomee  * method and field descriptions immediately follow the description of their
2131449Stomee  * containing class.
2141449Stomee  *
2151449Stomee  * Throws NoClassDefFoundError, NoSuchMethodError, or NoSuchFieldError if any
2161449Stomee  * dtj_table_entry_t in common_jni_table.c is incorrect.
2171449Stomee  */
2181449Stomee extern dtj_status_t dtj_cache_jni_classes(JNIEnv *, const dtj_table_entry_t *);
2191449Stomee 
2201449Stomee /* Common utilities */
2211449Stomee 
2221449Stomee /*
2231449Stomee  * The following functions each create a pending Java Error or Exception:
2241449Stomee  *
2251449Stomee  * OutOfMemoryError
2261449Stomee  * NullPointerException
2271449Stomee  * IllegalArgumentException
2281449Stomee  * IllegalStateException
2291449Stomee  * NoSuchElementException
2301449Stomee  * ClassCastException
2311449Stomee  * AssertionError
232*6136Stomee  * org.opensolaris.os.dtrace.ResourceLimitException
2331449Stomee  *
2341449Stomee  * Control should be returned to Java immediately afterwards.
2351449Stomee  */
2361449Stomee extern void dtj_throw_out_of_memory(JNIEnv *, const char *, ...);
2371449Stomee extern void dtj_throw_null_pointer(JNIEnv *, const char *, ...);
2381449Stomee extern void dtj_throw_illegal_argument(JNIEnv *, const char *, ...);
2391449Stomee extern void dtj_throw_illegal_state(JNIEnv *, const char *, ...);
2401449Stomee extern void dtj_throw_no_such_element(JNIEnv *, const char *, ...);
2411449Stomee extern void dtj_throw_class_cast(JNIEnv *, const char *, ...);
2421449Stomee extern void dtj_throw_assertion(JNIEnv *, const char *, ...);
2431449Stomee extern void dtj_throw_resource_limit(JNIEnv *, const char *, ...);
2441449Stomee 
2451449Stomee /*
2461449Stomee  * Attaches native filename and line number to the currently pending java
2471449Stomee  * exception, since that information is not present in the exception stack
2481449Stomee  * trace.
2491449Stomee  */
2501449Stomee extern void dtj_wrap_exception(JNIEnv *, const char *, int);
2511449Stomee 
2521449Stomee /*
2531449Stomee  * Calls the toString() method of the given object and prints the value to
2541449Stomee  * stdout (useful for debugging).  If an exception is thrown in this function,
2551449Stomee  * it is described on stdout and cleared.  It's guaranteed that no exception is
2561449Stomee  * pending when this function returns.
2571449Stomee  */
2581449Stomee extern void dtj_print_object(JNIEnv *jenv, jobject obj);
2591449Stomee 
2601449Stomee /*
261*6136Stomee  * Gets a java.math.BigInteger representing a 64-bit unsigned integer.
262*6136Stomee  */
263*6136Stomee extern jobject dtj_uint64(JNIEnv *jenv, uint64_t);
264*6136Stomee 
265*6136Stomee /*
266*6136Stomee  * Gets a java.math.BigInteger representing a 128-bit integer given as 64 high
267*6136Stomee  * bits (1st arg) and 64 low bits (2nd arg).
268*6136Stomee  */
269*6136Stomee extern jobject dtj_int128(JNIEnv *jenv, uint64_t, uint64_t);
270*6136Stomee 
271*6136Stomee /*
2721449Stomee  * Gets a formatted String (local reference) from a format and a variable
2731449Stomee  * argument list of placeholder values.  Returns NULL if OutOfMemoryError is
2741449Stomee  * thrown.
2751449Stomee  */
2761449Stomee extern jstring dtj_format_string(JNIEnv *jenv, const char *fmt, ...);
2771449Stomee 
2781449Stomee /*
2791449Stomee  * Internationalization support.  These functions taken (not verbatim) from
2801449Stomee  * Section 8.2 of The Java Native Interface by Sheng Liang, The Java Series.
2811449Stomee  * Use these functions for locale-specific strings such as file names.
2821449Stomee  */
2831449Stomee extern jstring dtj_NewStringNative(JNIEnv *jenv, const char *str);
2841449Stomee extern char *dtj_GetStringNativeChars(JNIEnv *jenv, jstring jstr);
2851449Stomee extern void dtj_ReleaseStringNativeChars(JNIEnv *jenv, jstring jstr,
2861449Stomee     const char *str);
2871449Stomee 
2881449Stomee /*
2891449Stomee  * Converts the args array of main(String[] args) in Java into a native
2901449Stomee  * dynamically allocated array of strings.  The returned array must be
2911449Stomee  * deallocated by calling free_argv().  A java exception is pending if this
2921449Stomee  * function returns NULL (in that case, any allocations made up to the point of
2931449Stomee  * failure in get_argv() are automatically freed).
2941449Stomee  *
2951449Stomee  * Returns a NULL-terminated array that works with functions that expect a
2961449Stomee  * terminating NULL rather than relying on an element count.  The argc parameter
2971449Stomee  * is also overwritten with the number of returned array elements (not including
2981449Stomee  * the terminating NULL).
2991449Stomee  */
3001449Stomee extern char **dtj_get_argv(JNIEnv *jenv, jobjectArray args, int *argc);
3011449Stomee /*
3021449Stomee  * Tokenizes a command string to create a native dynamically allocated array of
3031449Stomee  * strings.  The first element of the returned array is assumed to be the name
3041449Stomee  * of the command, and subsequent elements are arguments to that command.
3051449Stomee  * Otherwise behaves exactly like get_argv() above, including requiring a
3061449Stomee  * subsequent call to free_argv() on the returned array.
3071449Stomee  * Throws NullPointerException if cmd is NULL.
3081449Stomee  * Throws IllegalArgumentException if cmd is empty.
3091449Stomee  */
3101449Stomee extern char **dtj_make_argv(JNIEnv *jenv, jstring cmd, int *argc);
3111449Stomee extern void dtj_free_argv(char **argv);
3121449Stomee 
3131449Stomee 
3141449Stomee /* Wrappers for uu_list_t */
3151449Stomee 
3161449Stomee /*
3171449Stomee  * List element destructor.
3181449Stomee  * params: node pointer, user arg (may be NULL)
3191449Stomee  */
3201449Stomee typedef void dtj_value_destroy_f(void *, void *);
3211449Stomee 
3221449Stomee /*
3231449Stomee  * uu_list_t generic entry type for pointers compared by pointer value, similar
3241449Stomee  * to Java's default Object.equals() implementation (referenced objects are
3251449Stomee  * equal only if they have the same address in memory).  Used with
3261449Stomee  * pointer_list_entry_cmp.
3271449Stomee  */
3281449Stomee typedef struct dtj_pointer_list_entry {
3291449Stomee 	void *dple_ptr;
3301449Stomee 	uu_list_node_t dple_node;
3311449Stomee } dtj_pointer_list_entry_t;
3321449Stomee 
3331449Stomee typedef struct dtj_string_list_entry {
3341449Stomee 	char *dsle_value;
3351449Stomee 	uu_list_node_t dsle_node;
3361449Stomee } dtj_string_list_entry_t;
3371449Stomee 
3381449Stomee /* Comparison functions, uu_compare_fn_t signature */
3391449Stomee extern int dtj_pointer_list_entry_cmp(const void *, const void *, void *);
3401449Stomee extern int dtj_string_list_entry_cmp(const void *, const void *, void *);
3411449Stomee 
3421449Stomee /* Constructors */
3431449Stomee extern uu_list_t *dtj_pointer_list_create(void);
3441449Stomee extern dtj_pointer_list_entry_t *dtj_pointer_list_entry_create(void *);
3451449Stomee extern uu_list_t *dtj_string_list_create(void);
3461449Stomee extern dtj_string_list_entry_t *dtj_string_list_entry_create(const char *);
3471449Stomee 
3481449Stomee /* Destructors */
3491449Stomee extern void dtj_pointer_list_entry_destroy(void *, dtj_value_destroy_f *,
3501449Stomee     void *);
3511449Stomee extern void dtj_string_list_entry_destroy(void *, void *);
3521449Stomee /*
3531449Stomee  * Convenience function destroys a uu_list_t and its values.
3541449Stomee  *
3551449Stomee  * param list: list to be destroyed, call is a no-op if list is NULL
3561449Stomee  * param value_destroy: optional destructor; if non-NULL, it is called on each
3571449Stomee  *	list value
3581449Stomee  * param arg: user argument to the optional destructor
3591449Stomee  */
3601449Stomee extern void dtj_list_destroy(uu_list_t *, dtj_value_destroy_f *, void *);
3611449Stomee extern void dtj_pointer_list_destroy(uu_list_t *, dtj_value_destroy_f *,
3621449Stomee     void *);
3631449Stomee extern void dtj_string_list_destroy(uu_list_t *);
3641449Stomee 
3651449Stomee /*
3661449Stomee  * Convenience functions clear a uu_list_t without destroying it.  Destroys all
3671449Stomee  * list elements and leaves the list empty.  The *_list_destroy() functions
3681449Stomee  * implicitly clear the list before destroying it.
3691449Stomee  */
3701449Stomee extern void dtj_list_clear(uu_list_t *, dtj_value_destroy_f *, void *);
3711449Stomee extern void dtj_pointer_list_clear(uu_list_t *, dtj_value_destroy_f *,
3721449Stomee     void *);
3731449Stomee extern void dtj_string_list_clear(uu_list_t *);
3741449Stomee 
3751449Stomee extern boolean_t dtj_list_empty(uu_list_t *);
3761449Stomee /* Return B_TRUE if successful, B_FALSE otherwise */
3771449Stomee extern boolean_t dtj_list_add(uu_list_t *, void *);
3781449Stomee extern boolean_t dtj_pointer_list_add(uu_list_t *, void *);
3791449Stomee extern boolean_t dtj_string_list_add(uu_list_t *, const char *);
3801449Stomee /* Return INVALID_PTR if list is empty (NULL is a valid list element) */
3811449Stomee extern void * dtj_pointer_list_first(uu_list_t *);
3821449Stomee extern void * dtj_pointer_list_last(uu_list_t *);
3831449Stomee /* Return INVALID_STR if list is empty (NULL is a valid list element) */
3841449Stomee extern const char *dtj_string_list_first(uu_list_t *);
3851449Stomee extern const char *dtj_string_list_last(uu_list_t *);
3861449Stomee /* Return INVALID_PTR at end of list (NULL is a valid list element) */
3871449Stomee extern void *dtj_pointer_list_walk_next(uu_list_walk_t *);
3881449Stomee /* Return INVALID_STR at end of list (NULL is a valid list element) */
3891449Stomee extern const char *dtj_string_list_walk_next(uu_list_walk_t *);
3901449Stomee 
3911449Stomee #ifdef	__cplusplus
3921449Stomee }
3931449Stomee #endif
3941449Stomee 
3951449Stomee #endif	/* _DTJ_UTIL_H */
396