[kaffe] CVS kaffe (robilad): small warning fixlet

Kaffe CVS cvs-commits at kaffe.org
Tue Apr 11 17:09:42 PDT 2006


PatchSet 7218 
Date: 2006/04/11 23:59:52
Author: robilad
Branch: HEAD
Tag: (none) 
Log:
small warning fixlet

2006-04-12  Dalibor Topic  <robilad at kaffe.org>

* kaffe/xprof/mangle.c (mangleClassType):
Added missing cast to ptrdiff_t to fix compiler warning.

Members: 
	ChangeLog:1.4724->1.4725 
	kaffe/xprof/mangle.c:INITIAL->1.9 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.4724 kaffe/ChangeLog:1.4725
--- kaffe/ChangeLog:1.4724	Thu Apr  6 03:29:45 2006
+++ kaffe/ChangeLog	Tue Apr 11 23:59:52 2006
@@ -1,3 +1,8 @@
+2006-04-12  Dalibor Topic  <robilad at kaffe.org>
+
+	* kaffe/xprof/mangle.c (mangleClassType): 
+	Added missing cast to ptrdiff_t to fix compiler warning.
+
 2006-04-06  Dalibor Topic  <robilad at kaffe.org>
 
 	* kaffe/kaffevm/readClass.c (readSignatureAttribute): 
===================================================================
Checking out kaffe/kaffe/xprof/mangle.c
RCS:  /home/cvs/kaffe/kaffe/kaffe/xprof/mangle.c,v
VERS: 1.9
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/kaffe/xprof/mangle.c	Wed Apr 12 00:09:42 2006
@@ -0,0 +1,830 @@
+/*
+ * mangle.c
+ * Routines for doing name mangling on Java types
+ *
+ * Copyright (c) 2000, 2004 University of Utah and the Flux Group.
+ * All rights reserved.
+ *
+ * This file is licensed under the terms of the GNU Public License.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * Contributed by the Flux Research Group, Department of Computer Science,
+ * University of Utah, http://www.cs.utah.edu/flux/
+ */
+
+#include "config.h"
+
+#if defined(KAFFE_XDEBUGGING) || defined(KAFFE_XPROFILER)
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "config.h"
+#include "kaffe/jmalloc.h"
+#include "stringSupport.h"
+#include "classMethod.h"
+#include "xprofiler.h"
+
+#include "mangle.h"
+
+#ifndef MANGLE_GCJ
+# ifdef HAVE_GCJ_SUPPORT
+#  define MANGLE_GCJ 1
+# else
+#  define MANGLE_GCJ 0
+# endif
+#endif
+
+/*
+ * GCJ name mangling can confuse older tools.  It would be nice to be
+ * able to dectect whether gcj-aware versions of gdb and gprof are
+ * present, but we are already doing the next-best thing:  detecting
+ * whether GCJ itself is present.
+ *
+ * Our simplified mangler differs from gcj in two respects:  First, it
+ * it treats outer class names (left of a $), as qualifiers.  And
+ * second, it does not use U to indicate a unicode name part.
+ * Instead, is always escapes underscores preceding hex digits.
+ */
+#if MANGLE_GCJ
+# define IS_SEP(c) ((c) == '/')
+# define NAME_SEPARATORS "/"
+
+  /* GCJ escapes out underscore iff this is a unicode word */
+  static inline int bad_underscore(const char *p, const char *end) { return 1; }
+#else
+# define IS_SEP(c) ((c) == '/' || (c) == '$')
+# define NAME_SEPARATORS "/$"
+
+  /* In kaffe, everything is potential unicode-mangled, but underscores
+   * are only escaped out if they precede hex digits or underscores.
+   */
+  static inline int bad_underscore(const char *p, const char *end)
+  {
+	int next = UTF8_GET(p, end);
+	return   ((next >= '0' && next <= '9')
+		  || (next >= 'a' && next <= 'f')
+		  || next == '_');
+  }
+#endif
+
+struct mangled_method *createMangledMethod(void)
+{
+	struct mangled_method *retval;
+
+	xProfilingOff();
+	if( (retval = (struct mangled_method *)
+	     KMALLOC(sizeof(struct mangled_method))) )
+	{
+		retval->mm_flags = 0;
+		retval->mm_method = 0;
+		retval->mm_class = 0;
+		retval->mm_args = 0;
+		retval->mm_nargs = 0;
+	}
+	xProfilingOn();
+	return( retval );
+}
+
+void deleteMangledMethod(struct mangled_method *mm)
+{
+	xProfilingOff();
+	if( mm )
+	{
+		int lpc;
+
+		KFREE(mm->mm_method);
+		KFREE(mm->mm_class);
+		for( lpc = 0; lpc < mm->mm_nargs; lpc++ )
+		{
+			KFREE(mm->mm_args[lpc]);
+		}
+		KFREE(mm->mm_args);
+		KFREE(mm);
+	}
+	xProfilingOn();
+}
+
+int mangleMethodName(struct mangled_method *mm, const char *name)
+{
+	int retval = 0;
+	size_t len, m_len;
+
+	/* Constructors are mangled as an empty string */
+	if( !strcmp(name, "<init>") )
+	{
+		name = "";
+	}
+	len = strlen(name);
+	if( (m_len = mangleLength(name, (int)len, 0, 0)) )
+	{
+		/*
+		 * A method name with special chars has the `U' placed at the
+		 * end
+		 */
+		mm->mm_flags |= MMF_UNICODE_METHOD;
+	}
+	else
+		m_len = len;
+	if( (mm->mm_method = (char *)KMALLOC(m_len + 1)) )
+	{
+		size_t res;
+
+		res = mangleString(mm->mm_method, name, len, m_len != len);
+		assert(res <= (m_len + 1));
+		retval = 1;
+	}
+	return( retval );
+}
+
+int mangleMethodClass(struct mangled_method *mm, void *cl, const char *name)
+{
+	int retval = 0;
+
+	/* Just mangle the type directly */
+	if( (mm->mm_class = mangleClassType(0, cl, name)) )
+	{
+		retval = 1;
+	}
+	return( retval );
+}
+
+int mangleMethodArgCount(struct mangled_method *mm, int count)
+{
+	int retval = 0;
+
+	if( !count ||
+	    (mm->mm_args = (char **)KMALLOC(sizeof(char *) * count)) )
+	{
+		mm->mm_nargs = count;
+		retval = 1;
+	}
+	return( retval );
+}
+
+/*
+ * Helper function that checks for duplicate parameter types.
+ */
+static int duplicateParameter(Method *meth, int curr_param)
+{
+	int lpc, retval = -1;
+	size_t curr_len;
+
+	/* Figure out the length of the curr_param type string */
+	if( curr_param == METHOD_PSIG(meth)->nargs )
+	{
+		/*
+		 * Its the last arg, an ')' and the return type follow, so we
+		 * use them to find the length
+		 */
+		curr_len = (METHOD_PSIG(meth)->ret_and_args[0] - 1) -
+			METHOD_PSIG(meth)->ret_and_args[curr_param];
+	}
+	else
+	{
+		curr_len = METHOD_PSIG(meth)->ret_and_args[curr_param] -
+			METHOD_PSIG(meth)->ret_and_args[curr_param + 1];
+	}
+	/*
+	 * Loop over the parameters searching for one that matches curr_param,
+	 * we start at 1 since 0 is the return type.
+	 */
+	for( lpc = 1; (lpc < curr_param) && (retval != -1); lpc++ )
+	{
+		size_t arg_len;
+
+		/* Figure out the length of the current parameter type */
+		if( lpc == METHOD_PSIG(meth)->nargs )
+		{
+			arg_len = (METHOD_PSIG(meth)->ret_and_args[0] - 1) -
+				METHOD_PSIG(meth)->ret_and_args[lpc];
+		}
+		else
+		{
+			arg_len = METHOD_PSIG(meth)->ret_and_args[lpc] -
+				METHOD_PSIG(meth)->ret_and_args[lpc + 1];
+		}
+		if( arg_len > 1 )
+		{
+			if( (strncmp(&METHOD_PSIG(meth)->signature->
+				     data[METHOD_PSIG(meth)->
+					 ret_and_args[curr_param]],
+				     &METHOD_PSIG(meth)->signature->
+				     data[METHOD_PSIG(meth)->ret_and_args[lpc]],
+				     arg_len) == 0) &&
+			    (curr_len == arg_len) )
+			{
+				retval = lpc;
+			}
+		}
+	}
+	return( retval );
+}
+
+int mangleMethodArgs(struct mangled_method *mm, Method *meth)
+{
+	int retval = 1, lpc, ref;
+
+	for( lpc = 1; lpc <= mm->mm_nargs; lpc++ )
+	{
+		if( (ref = duplicateParameter(meth, lpc)) >= 0 )
+		{
+			/*
+			 * Duplicate parameter, use `T' to back ref the
+			 * previous one
+			 */
+			if( (mm->mm_args[lpc - 1] = (char *)
+				     KMALLOC(5)) )
+			{
+				sprintf(mm->mm_args[lpc - 1],
+					"T%d%s",
+					ref,
+					(ref > 9) ? "_" : "");
+			}
+		}
+		else
+		{
+			/* Unique parameter, mangle the type */
+			mm->mm_args[lpc - 1] = mangleType(
+				0,
+				(char *)&METHOD_PSIG(meth)->signature->
+				data[METHOD_PSIG(meth)->ret_and_args[lpc]]);
+		}
+	}
+	return( retval );
+}
+
+int mangleMethod(struct mangled_method *mm, Method *meth)
+{
+	int retval = 0;
+
+	xProfilingOff();
+	/* Try to mangle everything provided by `meth' */
+	if( mangleMethodName(mm, (char *)meth->name->data) &&
+	    mangleMethodClass(mm,
+			      meth->class->loader,
+			      (char *)CLASS_CNAME(meth->class)) &&
+	    mangleMethodArgCount(mm, METHOD_PSIG(meth)->nargs) &&
+	    mangleMethodArgs(mm, meth) )
+	{
+		retval = 1;
+	}
+	xProfilingOn();
+	return( retval );
+}
+
+int printMangledMethod(struct mangled_method *mm, FILE *file)
+{
+	int retval = 0;
+
+	/* Atleast check for method and class */
+	if( mm &&
+	    mm->mm_method &&
+	    mm->mm_class )
+	{
+		int lpc;
+
+		retval = 1;
+		fprintf(file, "%s__%s", mm->mm_method, mm->mm_class);
+		for( lpc = 0; (lpc < mm->mm_nargs) && retval; lpc++ )
+		{
+			if( mm->mm_args[lpc] )
+				fprintf(file, "%s", mm->mm_args[lpc]);
+			else
+				retval = 0;
+		}
+		/*
+		 * If the method name has escapes we need to append the `U' to
+		 * the end
+		 */
+#if MANGLE_GCJ
+		if( mm->mm_flags & MMF_UNICODE_METHOD )
+			fprintf(file, "U");
+#endif
+		if( ferror(file) )
+			retval = 0;
+	}
+	return( retval );
+}
+
+/* Map of primitive Java types to the mangled types */
+static const char *primitive_type_map[] = {
+	"Z", "b",	/* boolean */
+	"C", "w",	/* wide char */
+	"V", "v",	/* void */
+	"B", "c",	/* byte */
+	"S", "s",	/* short */
+	"I", "i",	/* integer */
+	"J", "x",	/* long */
+	"F", "f",	/* float */
+	"D", "d",	/* double */
+	0
+};
+
+const char *manglePrimitiveType(char type)
+{
+	const char *retval = NULL;
+	int lpc;
+
+	for( lpc = 0; primitive_type_map[lpc] && !retval; lpc += 2 )
+	{
+		if( type == primitive_type_map[lpc][0] )
+			retval = primitive_type_map[lpc + 1];
+	}
+	return( retval );
+}
+
+char *mangleClassType(int prepend, void *cl, const char *name)
+{
+	int quals = 0, num_chars = 0, num_underscores = 0, need_escapes = 0;
+	int ch, error = 0;
+	size_t len, m_len = 0, total_len = 0;
+	char *retval = 0;
+	const char *curr, *end;
+
+	/* First we find the length of mangled string */
+	len = strlen(name);
+	curr = name;
+	end = name + len;
+	while( (curr < end) && !error )
+	{
+		ch = UTF8_GET(curr, end);
+		if( ch < 0 )
+		{
+			error = 1;
+		}
+		else if( ch == ';' )
+		{
+			/*
+			 * The given name was of the form Ljava/lang/Object;,
+			 * so the `;' marks the end instead of the given null
+			 */
+			end = curr - 1;
+			break;
+		}
+		else if( IS_SEP(ch) )
+		{
+			/*
+			 * Its a qualified name, record the current counts for
+			 * this name segment and increment the number of
+			 * qualifiers
+			 */
+			quals++;
+			m_len += 4 + (need_escapes ? 7 : 0) + num_chars +
+				4 * (need_escapes + num_underscores);
+			num_chars = 0;
+			need_escapes = 0;
+			num_underscores = 0;
+		}
+		else if( (ch >= '0') && (ch <= '9') )
+		{
+			/* If a number starts a name then we need an escape */
+			if( num_chars == 0 )
+				need_escapes++;
+		}
+		else if( ch == '_' && bad_underscore(curr, end))
+		{
+#if MANGLE_GCJ
+			num_underscores++;
+#else
+			need_escapes++;
+#endif
+		}
+		else if( ((ch < 'a') || (ch > 'z')) &&
+			 ((ch < 'A') || (ch > 'Z')) &&
+			 (ch != '_') )
+		{
+			/* Its a special char, we'll need an escape */
+			need_escapes++;
+		}
+		num_chars++;
+	}
+	/* Figure out the total length of the mangled name */
+	total_len = m_len + 4 + (need_escapes ? 7 : 0) +
+		(quals ? 7 : 0) + num_chars +
+		4 * (need_escapes + num_underscores);
+	/*
+	 * If the class uses a non-root classLoader we need to encode that in
+	 * the name, otherwise we can make duplicate names for the same class
+	 * that are loaded by different class loaders.
+	 */
+	if( cl )
+	{
+		total_len += (quals ? 0 : 7) +
+			2 + /* character count of `cl' + the number */
+			2 + /* 'cl' */
+			2 + /* '0x' */
+			(sizeof(void *) * 2); /* the number */
+		quals++;
+	}
+	if( !error && (retval = (char *)KMALLOC(prepend + total_len + 1)) )
+	{
+		char *dest;
+
+		/* Start after the prepended section */
+		dest = retval + prepend;
+		dest[0] = 0;
+		if( quals )
+		{
+			/*
+			 * Its a qualified name, print out how many qualifiers
+			 * there are before continuing
+			 */
+			quals++;
+			if( quals < 10 )
+				sprintf(dest, "Q%d", quals);
+			else
+				sprintf(dest, "Q_%d_", quals);
+			quals--;
+		}
+		dest += strlen(dest);
+		/* Encode the class loader, if there is one */
+		if( cl )
+		{
+			int cl_len;
+
+			sprintf(dest + 3, "l%p", cl);
+			cl_len = strlen(dest + 3) + 1;
+			sprintf(dest, "%d", cl_len);
+			dest[2] = 'c'; /* The previous sprintf overwrote it */
+			dest += cl_len + 2;
+			quals--;
+		}
+		curr = name;
+		while( curr < end )
+		{
+			if( (m_len = mangleLength(curr,
+						  quals ? -1 : end - curr,
+						  NAME_SEPARATORS,
+						  &len)) )
+			{
+#if MANGLE_GCJ
+				*dest = 'U';
+				dest++;
+#endif
+			}
+			else
+			{
+				m_len = len;
+			}
+			/* Write the length of the name */
+			sprintf(dest, "%d", m_len);
+			dest += strlen(dest);
+			/* Mangle the string */
+			mangleString(dest, curr, len, m_len != len);
+			/* Move on to the next name */
+			dest += strlen(dest);
+			curr += len + 1;
+			quals--;
+		}
+		assert((dest - retval) <= (ptrdiff_t)(prepend + total_len + 1));
+	}
+	return( retval );
+}
+
+char *mangleType(size_t prepend, const char *type)
+{
+	char *retval = 0;
+
+	switch(type[0])
+	{
+	case 'L':
+		/* Object reference */
+		if( (retval = mangleClassType((int)prepend + 1, 0, type + 1)) )
+			retval[prepend] = 'P';
+		break;
+	case '[':
+		/* Array type */
+		if( (retval = mangleType(prepend + 11, type + 1)) )
+			strncpy(&retval[prepend], "Pt6JArray1Z", 11);
+		break;
+	default:
+		/* Most likely a primitive */
+		{
+			const char *prim;
+
+			if( (prim = manglePrimitiveType(type[0])) )
+			{
+				if( (retval = (char *)KMALLOC(prepend + 2)) )
+				{
+					retval[prepend] = prim[0];
+					retval[prepend + 1] = 0;
+				}
+			}
+		}
+		break;
+	}
+	return( retval );
+}
+
+size_t mangleLength(const char *string, int len, const char *term, size_t *out_len)
+{
+	int num_chars = 0, need_escapes = 0, num_underscores = 0;
+	int retval = -1, error = 0;
+	const char *curr, *end;
+
+	curr = string;
+	if( len < 0 )
+		end = (char *)-1; /* ick */
+	else
+		end = string + len;
+	while( !error && ((len < 0) || (curr < end)) )
+	{
+		int ch = UTF8_GET(curr, end);
+
+		if( ch < 0 )
+		{
+			error = 1;
+			break;
+		}
+		else if( term )
+		{
+			int found_term = 0;
+			int lpc;
+
+			for( lpc = 0; term[lpc]; lpc++ )
+			{
+				if( term[lpc] == ch )
+					found_term = 1;
+			}
+			if( found_term )
+			{
+				/* Found the specified terminator */
+				break;
+			}
+		}
+		if( (ch >= '0') && (ch <= '9') )
+		{
+			/* If a number starts a name then we need an escape */
+			if( (curr - 1) == string)
+				need_escapes++;
+		}
+		else if( ch == '_' && bad_underscore(curr, end))
+		{
+#if MANGLE_GCJ
+			num_underscores++;
+#else
+			need_escapes++;
+#endif
+		}
+		else if( ((ch < 'a') || (ch > 'z')) &&
+			 ((ch < 'A') || (ch > 'Z')) &&
+			 (ch != '_') )
+		{
+			/* Special character, we'll need an escape */
+			need_escapes++;
+		}
+		num_chars++;
+	}
+	if( !error )
+	{
+		if( need_escapes )
+		{
+			retval = num_chars +
+				4 * (need_escapes + num_underscores);
+		}
+		else
+			retval = 0;
+		/* Write back the length */
+		if( out_len )
+			*out_len = num_chars;
+	}
+	return( retval );
+}
+
+size_t mangleString(char *dest, const char *src, size_t slen, int _unicode)
+{
+	int retval = 0, ch, error = 0, need_escape = 0;
+	char *start;
+	const char *curr, *end;
+
+	start = dest;
+	curr = src;
+	end = src + slen;
+	while( (curr < end) && !error )
+	{
+		ch = UTF8_GET(curr, end);
+
+		if( ch < 0 )
+		{
+			error = 1;
+		}
+		else if( (ch >= '0') && (ch <= '9') )
+		{
+			if( (curr - 1) == src )
+				need_escape = 1;
+			else
+				need_escape = 0;
+		}
+		else if( ch == '_' )
+		{
+			if( _unicode && bad_underscore(curr, end) )
+			{
+				need_escape = 1;
+			}
+		}
+		else if( ((ch < 'a') || (ch > 'z')) &&
+			 ((ch < 'A') || (ch > 'Z')) )
+		{
+			need_escape = 1;
+		}
+		else
+		{
+			need_escape = 0;
+		}
+		if( !error )
+		{
+			if( need_escape )
+			{
+				sprintf(dest, "_%04x", ch);
+				dest += 5;
+			}
+			else
+			{
+				*dest = ch;
+				dest++;
+			}
+		}
+	}
+	*dest = 0;
+	if( error )
+		retval = -1;
+	else
+		retval = dest - start + 1;
+	return( retval );
+}
+
+static int fputss(const char *str, size_t len, FILE *stream)
+{
+    size_t lpc;
+    int retval = 0;
+
+    for( lpc = 0; lpc < len; lpc++ )
+    {
+	putc(str[lpc], stream);
+    }
+    return( retval );
+}
+
+int vfmanglef(FILE *file, const char *format, va_list args)
+{
+    unsigned int sindex, eindex;
+    int retval = 0;
+
+    for( sindex = eindex = 0; format[eindex] != '\0'; eindex++ )
+    {
+	switch( format[eindex] )
+	{
+	case '%':
+	    {
+		int done = 0;
+
+		while( !done )
+		{
+		    eindex += 1;
+		    switch( format[eindex] )
+		    {
+		    case 'q': /* qualified string */
+			{
+			    const char *quals, *str;
+			    size_t offset = 0, len;
+			    void *ptr;
+			    
+			    quals = va_arg(args, const char *);
+			    str = va_arg(args, const char *);
+			    ptr = va_arg(args, void *);
+			    
+			    len = strlen(str);
+
+			    while( offset < len )
+			    {
+				char buffer[1 + 2 + sizeof(void *) * 2 + 1];
+				const char *sub_end;
+				size_t slen;
+
+				buffer[0] = '\0';
+				sub_end = strpbrk(&str[offset], quals);
+				if( sub_end == NULL )
+				{
+				    sub_end = &str[len];
+				    if( ptr != NULL )
+				    {
+					snprintf(buffer,
+						 sizeof(buffer),
+						 "_%p",
+						 ptr);
+				    }
+				}
+				slen = sub_end - &str[offset];
+				fprintf(file, "%d", slen + strlen(buffer));
+				fputss(&str[offset], slen, file);
+				fprintf(file, "%s", buffer);
+				offset += slen + 1;
+			    }
+			    done = 1;
+			}
+			break;
+		    case 't':
+			{
+			    const char *in, *out, *str;
+			    unsigned int lpc;
+
+			    in = va_arg(args, const char *);
+			    out = va_arg(args, const char *);
+			    str = va_arg(args, const char *);
+			    
+			    assert(strlen(in) == strlen(out));
+			    for( lpc = 0; str[lpc] != '\0'; lpc++ )
+			    {
+				const char *rep;
+
+				if( (rep = strchr(in, str[lpc])) != NULL )
+				{
+				    putc(out[rep - in], file);
+				}
+				else
+				{
+				    putc(str[lpc], file);
+				}
+			    }
+			    done = 1;
+			}
+			break;
+		    case 'c':
+			{
+				char c;
+
+				c = (char)va_arg(args, int);
+				fprintf(file, "%c", c);
+				done = 1;
+			}
+			break;
+		    case 'd':
+			{
+			    int i;
+
+			    i = va_arg(args, int);
+			    fprintf(file, "%d", i);
+			    done = 1;
+			}
+			break;
+		    case 'p':
+			{
+			    void *ptr;
+
+			    ptr = va_arg(args, void *);
+			    fprintf(file, "%p", ptr);
+			    done = 1;
+			}
+			break;
+		    case 's':
+			{
+			    const char *str;
+			    
+			    str = va_arg(args, const char *);
+
+			    fprintf(file, "%s", str);
+			    done = 1;
+			}
+			break;
+		    case 'S':
+			{
+			    const char *str;
+			    size_t len;
+			    
+			    str = va_arg(args, const char *);
+			    len = va_arg(args, size_t);
+
+			    fputss(str, len, file);
+			    done = 1;
+			}
+			break;
+		    default:
+			assert(0);
+			break;
+		    }
+		}
+	    }
+	    break;
+	default:
+	    putc(format[eindex], file);
+	    break;
+	}
+    }
+    return( retval );
+}
+
+int fmanglef(FILE *file, const char *format, ...)
+{
+    va_list args;
+    int retval;
+
+    va_start(args, format);
+    retval = vfmanglef(file, format, args);
+    va_end(args);
+    return( retval );
+}
+
+#endif /* defined(KAFFE_XDEBUGGING) || defined(KAFFE_XPROFILER) */




More information about the kaffe mailing list