Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include "symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include "demangle-java.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 	MODE_PREFIX = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 	MODE_CLASS  = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 	MODE_FUNC   = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	MODE_TYPE   = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	MODE_CTYPE  = 4, /* class arg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define BASE_ENT(c, n)	[c - 'A']=n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) static const char *base_types['Z' - 'A' + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	BASE_ENT('B', "byte" ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	BASE_ENT('C', "char" ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	BASE_ENT('D', "double" ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	BASE_ENT('F', "float" ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	BASE_ENT('I', "int" ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	BASE_ENT('J', "long" ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	BASE_ENT('S', "short" ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	BASE_ENT('Z', "boolean" ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * demangle Java symbol between str and end positions and stores
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * up to maxlen characters into buf. The parser starts in mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * Use MODE_PREFIX to process entire prototype till end position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * Use MODE_TYPE to process return type if str starts on return type char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  *  Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *	success: buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  *	error  : NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) __demangle_java_sym(const char *str, const char *end, char *buf, int maxlen, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	int rlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	int array = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	int narg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	const char *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	if (!end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		end = str + strlen(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	for (q = str; q != end; q++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		if (rlen == (maxlen - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		switch (*q) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		case 'L':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			if (mode == MODE_PREFIX || mode == MODE_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 				if (mode == MODE_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 					if (narg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 						rlen += scnprintf(buf + rlen, maxlen - rlen, ", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 					narg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 				if (mode == MODE_PREFIX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 					mode = MODE_CLASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 					mode = MODE_CTYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 				buf[rlen++] = *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		case 'B':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		case 'C':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		case 'D':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		case 'F':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		case 'I':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		case 'J':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		case 'S':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		case 'Z':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			if (mode == MODE_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 				if (narg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 					rlen += scnprintf(buf + rlen, maxlen - rlen, ", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 				rlen += scnprintf(buf + rlen, maxlen - rlen, "%s", base_types[*q - 'A']);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 				while (array--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 					rlen += scnprintf(buf + rlen, maxlen - rlen, "[]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 				array = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 				narg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 				buf[rlen++] = *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		case 'V':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			if (mode == MODE_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 				rlen += scnprintf(buf + rlen, maxlen - rlen, "void");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 				while (array--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 					rlen += scnprintf(buf + rlen, maxlen - rlen, "[]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 				array = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 				buf[rlen++] = *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		case '[':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			if (mode != MODE_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			array++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		case '(':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			if (mode != MODE_FUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			buf[rlen++] = *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			mode = MODE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		case ')':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			if (mode != MODE_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			buf[rlen++] = *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			narg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		case ';':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			if (mode != MODE_CLASS && mode != MODE_CTYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			/* safe because at least one other char to process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 			if (isalpha(*(q + 1)) && mode == MODE_CLASS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 				rlen += scnprintf(buf + rlen, maxlen - rlen, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			if (mode == MODE_CLASS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 				mode = MODE_FUNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			else if (mode == MODE_CTYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 				mode = MODE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		case '/':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 			if (mode != MODE_CLASS && mode != MODE_CTYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			rlen += scnprintf(buf + rlen, maxlen - rlen, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		default :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			buf[rlen++] = *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	buf[rlen] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * Demangle Java function signature (openJDK, not GCJ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  * input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  * 	str: string to parse. String is not modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  *    flags: comobination of JAVA_DEMANGLE_* flags to modify demangling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  * return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  *	if input can be demangled, then a newly allocated string is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  *	if input cannot be demangled, then NULL is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  * Note: caller is responsible for freeing demangled string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) java_demangle_sym(const char *str, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	char *buf, *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	size_t len, l1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	/* find start of retunr type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	p = strrchr(str, ')');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	 * expansion factor estimated to 3x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	len = strlen(str) * 3 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	buf = malloc(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	buf[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	if (!(flags & JAVA_DEMANGLE_NORET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		 * get return type first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		ptr = __demangle_java_sym(p + 1, NULL, buf, len, MODE_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		if (!ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		/* add space between return type and function prototype */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		l1 = strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		buf[l1++] = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	/* process function up to return type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	ptr = __demangle_java_sym(str, p + 1, buf + l1, len - l1, MODE_PREFIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	if (!ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }