#include #include #include #include "util.h" #include "debug.h" #include "symbol.h" #include "demangle-java.h" enum { MODE_PREFIX = 0, MODE_CLASS = 1, MODE_FUNC = 2, MODE_TYPE = 3, MODE_CTYPE = 3, /* class arg */ }; #define BASE_ENT(c, n) [c - 'A']=n static const char *base_types['Z' - 'A' + 1] = { BASE_ENT('B', "byte" ), BASE_ENT('C', "char" ), BASE_ENT('D', "double" ), BASE_ENT('F', "float" ), BASE_ENT('I', "int" ), BASE_ENT('J', "long" ), BASE_ENT('S', "short" ), BASE_ENT('Z', "bool" ), }; /* * demangle Java symbol between str and end positions and stores * up to maxlen characters into buf. The parser starts in mode. * * Use MODE_PREFIX to process entire prototype till end position * Use MODE_TYPE to process return type if str starts on return type char * * Return: * success: buf * error : NULL */ static char * __demangle_java_sym(const char *str, const char *end, char *buf, int maxlen, int mode) { int rlen = 0; int array = 0; int narg = 0; const char *q; if (!end) end = str + strlen(str); for (q = str; q != end; q++) { if (rlen == (maxlen - 1)) break; switch (*q) { case 'L': if (mode == MODE_PREFIX || mode == MODE_CTYPE) { if (mode == MODE_CTYPE) { if (narg) rlen += scnprintf(buf + rlen, maxlen - rlen, ", "); narg++; } rlen += scnprintf(buf + rlen, maxlen - rlen, "class "); if (mode == MODE_PREFIX) mode = MODE_CLASS; } else buf[rlen++] = *q; break; case 'B': case 'C': case 'D': case 'F': case 'I': case 'J': case 'S': case 'Z': if (mode == MODE_TYPE) { if (narg) rlen += scnprintf(buf + rlen, maxlen - rlen, ", "); rlen += scnprintf(buf + rlen, maxlen - rlen, "%s", base_types[*q - 'A']); while (array--) rlen += scnprintf(buf + rlen, maxlen - rlen, "[]"); array = 0; narg++; } else buf[rlen++] = *q; break; case 'V': if (mode == MODE_TYPE) { rlen += scnprintf(buf + rlen, maxlen - rlen, "void"); while (array--) rlen += scnprintf(buf + rlen, maxlen - rlen, "[]"); array = 0; } else buf[rlen++] = *q; break; case '[': if (mode != MODE_TYPE) goto error; array++; break; case '(': if (mode != MODE_FUNC) goto error; buf[rlen++] = *q; mode = MODE_TYPE; break; case ')': if (mode != MODE_TYPE) goto error; buf[rlen++] = *q; narg = 0; break; case ';': if (mode != MODE_CLASS && mode != MODE_CTYPE) goto error; /* safe because at least one other char to process */ if (isalpha(*(q + 1))) rlen += scnprintf(buf + rlen, maxlen - rlen, "."); if (mode == MODE_CLASS) mode = MODE_FUNC; else if (mode == MODE_CTYPE) mode = MODE_TYPE; break; case '/': if (mode != MODE_CLASS && mode != MODE_CTYPE) goto error; rlen += scnprintf(buf + rlen, maxlen - rlen, "."); break; default : buf[rlen++] = *q; } } buf[rlen] = '\0'; return buf; error: return NULL; } /* * Demangle Java function signature (openJDK, not GCJ) * input: * str: string to parse. String is not modified * flags: comobination of JAVA_DEMANGLE_* flags to modify demangling * return: * if input can be demangled, then a newly allocated string is returned. * if input cannot be demangled, then NULL is returned * * Note: caller is responsible for freeing demangled string */ char * java_demangle_sym(const char *str, int flags) { char *buf, *ptr; char *p; size_t len, l1 = 0; if (!str) return NULL; /* find start of retunr type */ p = strrchr(str, ')'); if (!p) return NULL; /* * expansion factor estimated to 3x */ len = strlen(str) * 3 + 1; buf = malloc(len); if (!buf) return NULL; buf[0] = '\0'; if (!(flags & JAVA_DEMANGLE_NORET)) { /* * get return type first */ ptr = __demangle_java_sym(p + 1, NULL, buf, len, MODE_TYPE); if (!ptr) goto error; /* add space between return type and function prototype */ l1 = strlen(buf); buf[l1++] = ' '; } /* process function up to return type */ ptr = __demangle_java_sym(str, p + 1, buf + l1, len - l1, MODE_PREFIX); if (!ptr) goto error; return buf; error: free(buf); return NULL; } /option>space:mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-02-06 15:11:04 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-02-06 15:11:04 -0800
commitf7d6040aa45df6ffd9e891114125dc919f18b96b (patch)
treeb20fed8e63bf327d6521923851a96ba080c48ce5 /drivers/usb/common/led.c
parent50dcb6cdb70281d76b28d1564f8e076bb08f2c60 (diff)
parentcbf304e420da96992eae50bb6d51035681340ab8 (diff)
Merge tag 'pm-4.10-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fixes from Rafael Wysocki: "These add a quirk to intel_pstate to work around a firmware setting that leads to frequency scaling issues (discovered recently) on some Intel Kaby Lake processors, fix up the recently added brcmstb-avs cpufreq driver and avoid false-positive warnings from the runtime PM framework triggered by recent changes in i915. Specifics: - Add an intel_pstate driver quirk to work around a firmware setting that leads to frequency scaling issues on desktop Intel Kaby Lake processors in some configurations if the hardware-managed P-states (HWP) feature is in use (Srinivas Pandruvada) - Fix up the recently added brcmstb-avs cpufreq driver: fix a bug related to system suspend and change the sysfs interface to match the user space expectations (Markus Mayer) - Modify the runtime PM framework to avoid false-positive warnings from the might_sleep_if() assertions in it (Rafael Wysocki)" * tag 'pm-4.10-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: PM / runtime: Avoid false-positive warnings from might_sleep_if() cpufreq: intel_pstate: Disable energy efficiency optimization cpufreq: brcmstb-avs-cpufreq: properly retrieve P-state upon suspend cpufreq: brcmstb-avs-cpufreq: extend sysfs entry brcm_avs_pmap
Diffstat (limited to 'drivers/usb/common/led.c')