📄 classread.cc
字号:
clazz->aoffset = offset; count = clazz->attribs_count = READ2(); if (count) { clazz->attribs = ht_malloc(count*sizeof (*(clazz->attribs))); if (!clazz->attribs) { return NULL; } for (int i=0; i<(int)count; i++) { clazz->attribs[i] = attribute_read (htio, clazz); if (!clazz->attribs[i]) { return NULL; } } } else { clazz->attribs = 0; } return shared;}void class_unread(ht_class_shared_data *shared){ u1 tag; classfile *clazz = shared->file; if (!clazz) return; for (uint i = 1; i < clazz->cpool_count; i++) { tag = clazz->cpool[i]->tag; if (tag == CONSTANT_Utf8) { free(clazz->cpool[i]->value.string); } free(clazz->cpool[i]); if (tag == CONSTANT_Long || tag == CONSTANT_Double) { i++; } } if (clazz->cpool_count) free(clazz->cpool); free(clazz->interfaces); for (uint i=0; i < clazz->fields_count; i++) { for (uint j=0; j < clazz->fields[i]->attribs_count; j++) { free(clazz->fields[i]->attribs[j]); } if (clazz->fields[i]->attribs_count) free(clazz->fields[i]->attribs); free(clazz->fields[i]); } if (clazz->fields_count) free(clazz->fields); for (uint i=0; i < clazz->methods_count; i++) { for (uint j=0; j<clazz->methods[i]->attribs_count; j++) { free (clazz->methods[i]->attribs[j]); } if (clazz->methods[i]->attribs_count) free(clazz->methods[i]->attribs); free(clazz->methods[i]); } if (clazz->methods_count) free(clazz->methods); for (uint i=0; i < clazz->attribs_count; i++) { free(clazz->attribs[i]); } if (clazz->attribs_count) { free(clazz->attribs); } if (shared->valid) { shared->valid->done(); delete shared->valid; }/* if (shared->initialized) { shared->initialized->done(); delete shared->initialized; }*/ delete shared->methods; free(shared->file); free(shared);}int java_demangle_type(char *result, const char **type);int java_demangle_generic(char *result, const char **type){#if 0 (Ljava/util/List<+Ljava/lang/Float;>;)V (Ljava/util/List<*>;)V (Ljava/util/Map<Ljava/lang/Integer;+Ljava/lang/Integer;>;)V <S:Ljava/lang/Object;>(Ljava/util/Map<Ljava/lang/Integer;+TS;>;)V <S:Ljava/lang/Object;B:Ljava/lang/Object;>(Ljava/util/Map<TS;TB;>;)V <S:Ljava/lang/Object;B:TS;>(Ljava/util/Map<TS;TB;>;)V <T:Ljava/lang/Object;:Ljava/util/List;>(Ljava/util/List<TT;>;)V#endif char *old = result; *result++ = '<'; (*type)++; goto first; do { *result++ = ','; *result++ = ' '; first: switch (**type) { case 0: *result = 0; return result-old; case '*': (*type)++; *result++ = '?'; break; case '+': case '-': result += sprintf(result, "? %s ", **type=='+' ? "extends": "super"); (*type)++; // fall through default: result += java_demangle_type(result, type); } } while (**type != '>'); (*type)++; *result++ = '>'; *result = 0; return result - old;}#define STRIP_PATHint java_demangle_template(char *result, const char **type){ char *old = result; *result++ = '<'; (*type)++; goto first; do { *result++ = ','; *result++ = ' '; first: if (*type == 0) { *result = 0; return result - old; } do { *result++ = **type; (*type)++; } while (**type != ':' && **type != 0); result += sprintf(result, " extends "); goto first2; do { *result++ = ' '; *result++ = '&'; *result++ = ' '; first2: if (*type == 0) { *result = 0; return result - old; } (*type)++; result += java_demangle_type(result, type); } while (**type == ':'); } while (**type != '>'); *result++ = '>'; (*type)++; return result - old;}int java_demangle_type(char *result, const char **type){ switch (*(*type)++) { case 0: *result = 0; (*type)--; return 0; case '[': { char temp[300]; java_demangle_type(temp, type); return sprintf(result, "%s[]", temp); } case 'B': return sprintf(result, "byte"); case 'C': return sprintf(result, "char"); case 'D': return sprintf(result, "double"); case 'F': return sprintf(result, "float"); case 'I': return sprintf(result, "int"); case 'J': return sprintf(result, "long"); case 'T': case 'L': { char *oldresult = result; while (**type != ';' && **type != '<' && **type != 0) { *result = **type;#ifdef STRIP_PATH if (*result == '/') result = oldresult; else#endif result++; (*type)++; } if (**type == '<') { result += java_demangle_generic(result, type); } (*type)++; *result = 0; return result-oldresult; } case 'S': return sprintf(result, "short"); case 'V': return sprintf(result, "void"); case 'Z': return sprintf(result, "boolean"); default: return sprintf(result, "%c", *(*type-1)); }}char *java_demangle_flags(char *result, int flags){ if (flags & jACC_PUBLIC) result += sprintf(result, "public "); if (flags & jACC_PRIVATE) result += sprintf(result, "private "); if (flags & jACC_PROTECTED) result += sprintf(result, "protected "); if (flags & jACC_STATIC) result += sprintf(result, "static "); if (flags & jACC_FINAL) result += sprintf(result, "final "); if (flags & jACC_SUPER) result += sprintf(result, "super "); if (flags & jACC_SYNCHRONIZED) result += sprintf(result, "synchronized "); if (flags & jACC_VOLATILE) result += sprintf(result, "volatile "); if (flags & jACC_TRANSIENT) result += sprintf(result, "transient "); if (flags & jACC_NATIVE) result += sprintf(result, "native "); if (flags & jACC_INTERFACE) result += sprintf(result, "interface "); if (flags & jACC_ABSTRACT) result += sprintf(result, "abstract "); if (flags & jACC_STRICT) result += sprintf(result, "strict "); return result;}static const char *java_strip_path(const char *name){#ifdef STRIP_PATH const char *nname = strrchr(name, '/'); return nname?(nname+1):name;#else return name;#endif}void java_demangle(char *result, const char *classname, const char *name, const char *type, int flags){ result = java_demangle_flags(result, flags); name = java_strip_path(name); classname = java_strip_path(classname); strcpy(result, name); const char *ret = strchr(type, ')'); if (!ret) return; if (*type == '<') { result += java_demangle_template(result, &type); *result++ = ' '; *result = 0; } if (*type != '(') return; ret++; result += java_demangle_type(result, &ret); if (strcmp(name, "<init>")==0) { name = classname; } result += sprintf(result, " %s::%s(", classname, name); type++; while (*type != ')') { result += java_demangle_type(result, &type); if (*type != ')') { result += sprintf(result, ", "); } } result += sprintf(result, ")");}void java_demangle_field(char *result, const char *name, const char *type, int flags){ result = java_demangle_flags(result, flags); result += java_demangle_type(result, &type); *result++ = ' '; strcpy(result, name);}int token_translate(char *buf, int maxlen, uint32 token, ht_class_shared_data *shared){ classfile *clazz = shared->file; char tag[20]; char data[1024]; char classname[1024]; char name[1024]; char type[1024]; strcpy(tag, "?"); strcpy(data, "?"); strcpy(classname, "?"); strcpy(name, "?"); strcpy(type, "?"); if (token < clazz->cpool_count) switch (clazz->cpool[token]->tag) { case CONSTANT_Class: { strcpy(tag, "Class"); const char *cl = get_class_name(NULL, clazz, token); if (cl[0] == '[') { java_demangle_type(data, &cl); } else { strcpy(data, java_strip_path(cl)); } break; } case CONSTANT_Double: strcpy(tag, "Double"); sprintf(data, "double (%f)", clazz->cpool[token]->value.dval); break; case CONSTANT_Float: strcpy(tag, "Float"); sprintf(data, "float (%f)", clazz->cpool[token]->value.fval); break; case CONSTANT_Integer: strcpy(tag, "Int"); ht_snprintf(data, sizeof data, "int (%d)", clazz->cpool[token]->value.ival); break; case CONSTANT_Long: { strcpy(tag, "Long"); uint64 v = (uint64(clazz->cpool[token]->value.llval[0]) << 32) | clazz->cpool[token]->value.llval[1]; ht_snprintf(data, sizeof data, "long (%qd)", v); break; } case CONSTANT_String: { strcpy(tag, "String"); char *d = data; *d++ = '\"'; // FIXME: add "..." on too long strings d += escape_special_str(d, 256, get_string(NULL, clazz, clazz->cpool[token]->value.llval[0]), "\"", false); *d++ = '\"'; *d = 0; break; } case CONSTANT_Fieldref: { strcpy(tag, "Field"); get_name_and_type(NULL, clazz, clazz->cpool[token]->value.llval[1], name, type); char dtype[1024]; const char *ttype=type; java_demangle_type(dtype, &ttype); ht_snprintf(data, sizeof data, "%s %s", dtype, name); break; } case CONSTANT_Methodref: strcpy(tag, "Method"); strcpy(classname, get_class_name(NULL, clazz, clazz->cpool[token]->value.llval[0])); get_name_and_type(NULL, clazz, clazz->cpool[token]->value.llval[1], name, type); java_demangle(data, classname, name, type, 0); break; case CONSTANT_InterfaceMethodref: strcpy(tag, "InterfaceMethod"); strcpy(classname, get_class_name(NULL, clazz, clazz->cpool[token]->value.llval[0])); get_name_and_type(NULL, clazz, clazz->cpool[token]->value.llval[1], name, type); java_demangle(data, classname, name, type, 0); break; }// return ht_snprintf(buf, maxlen, "<%s %s>", tag, data); return ht_snprintf(buf, maxlen, "<%s>", data);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -