📄 gcj-class.cc
字号:
/* * gcj-class.cc * * Copyright (c) 1996, 1997, 1998, 1999 * Transvirtual Technologies, Inc. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. * * Written by Godmar Back <gback@cs.utah.edu> */#include "config.h"#include "debug.h"#include "config-std.h"#include "gcj.h"#if defined(HAVE_GCJ_SUPPORT) && defined(TRANSLATOR) && defined(JIT3)#define private public#include <java/lang/Object.h>#include <java/lang/Class.h>#include <java/lang/reflect/Method.h>#include <java/lang/reflect/Modifier.h>#include <gcj/field.h>#include <gcj/method.h>static java::lang::Class *preCList;static char *findPrimitiveClass(void *symbol);/* * Repeat those from libjava/include/java-cpool.h */#define JV_CONSTANT_Undefined (0L)#define JV_CONSTANT_Utf8 (1L)#define JV_CONSTANT_Unicode (2L)#define JV_CONSTANT_Integer (3L)#define JV_CONSTANT_Float (4L)#define JV_CONSTANT_Long (5L)#define JV_CONSTANT_Double (6L)#define JV_CONSTANT_Class (7L)#define JV_CONSTANT_String (8L)#define JV_CONSTANT_Fieldref (9L)#define JV_CONSTANT_Methodref (10L)#define JV_CONSTANT_InterfaceMethodref (11L)#define JV_CONSTANT_NameAndType (12L)#define JV_CONSTANT_ResolvedFlag (16L)#define JV_CONSTANT_ResolvedString (16L | 8L)#define JV_CONSTANT_ResolvedClass (16L | 7L)#include <dlfcn.h>#include <string.h>#include <assert.h>fixup_table_t *fixupTable;/* tell gcj where the static field has been allocated */void *fixup_table_t::getStaticFieldAddr(const char *clazz, const char *name){ fixup_table_t *f = this;DBG(GCJ, if (0) { dprintf("%s: looking for static %s. %s\n", __FUNCTION__, clazz, name); } ) while (f->symbol) { /* use strstr because we want to find java/lang/String in * Ljava/lang/String; */ if (f->type == STATICFIELD && strstr(f->data1, clazz) && !strcmp(name, f->data2)) {DBG(GCJ, dprintf("%s: static field %s.%s at %p\n", __FUNCTION__, clazz, name, f->symbol); ) return (f->symbol); } f++; } return (0);}char* fixup_table_t::findClass(void *symbol){ fixup_table_t *f = this; while (f->symbol) { if (f->symbol == symbol && f->type == CLASS) { return (f->data1); } f++; } return (0);}extern "C" void *gcj_fixup_trampoline(void **psymbol){DBG(GCJ, dprintf("%s (%p)\n", __FUNCTION__, psymbol); ) fixup_table_t *entry = fixupTable; while (entry->symbol) { if (entry->symbol == *psymbol) { break; } entry++; } assert(entry->symbol); void *ncode; const char *classname = entry->data1; const char *mname = entry->data2; const char *msig = entry->data3; assert(entry->type == fixup_table_t::METHODREF);DBG(GCJ, dprintf("%s: %s.%s.%s\n", __FUNCTION__, classname, mname, msig); ) ncode = kenvTranslateMethod(classname, mname, msig); /* Atomic write. */ *psymbol = ncode;DBG(GCJ, dprintf("%s: patch %p with %p\n", __FUNCTION__, psymbol, ncode); ) return (ncode);}void fixup_table_t::dump(){ fixup_table_t *f = this; while (f->symbol) { fprintf(stderr, "%13s @%p, d1=%s, d2=%s, d3=%s\n", f->type == CLASS ? "CLASS" : f->type == STATICFIELD ? "STATICFIELD" : f->type == METHODREF ? "METHOD" : f->type == VTABLE ? "VTABLE" : "???", f->symbol, f->data1, f->data2, f->data3); f++; }}extern "C" void *gcjGetFieldAddr(const char *clazz, const char *name){ if (fixupTable) { return (fixupTable->getStaticFieldAddr(clazz, name)); } else { return (0); }}extern "C" char *gcjFindUnresolvedClassByAddress(void *symbol){ assert (fixupTable); char *name = fixupTable->findClass(symbol); if (name == 0) { name = findPrimitiveClass(symbol); } return (name);}/* * Load any shared objects in the class path. */extern "C" voidgcjLoadSharedObject(char* sofile){#if LIBTOOL_CRAP_THAT_DOESNT_REALLY_WORK /* I would like to use loadNativeLibrary here. * Problem is that this function returns success * even if there is no success. But what can you expect from * libtool? */ char errmsg[256]; if (loadNativeLibrary(entry->path, errmsg, 255) != 1) { fprintf(stderr, "Failed to load `%s'\nError: `%s'\n", sofile, errmsg); } else {DBG(GCJ, dprintf("%s: Loaded `%s'\n", __FUNCTION__, sofile); ) }#else char buf[1024]; // XXX /* We load a fixup .so module first in order to avoid undefined * symbols when loading the actual library. Use "make_fixup X" * to create the _fixup_X.so shared module */ strcpy(buf, "_fixup_"); strcat(buf, sofile); blockAsyncSignals(); void *h = dlopen(buf, RTLD_GLOBAL); if (h == 0) { fprintf(stderr, "Failed to load fixup `%s'\n" "Error: `%s'\n", buf, dlerror()); } fixupTable = (fixup_table_t*)dlsym(h, "_gcjSymbols"); if (fixupTable == 0) { fprintf(stderr, "Failed to find gcj symbols\nError: `%s'\n", dlerror()); }DBG(GCJ, dprintf("---------------------------------------------------------\n"); dprintf("Dumping fixup symbol table for module %s\n", sofile); fixupTable->dump(); dprintf("-------end of table for %s---\n", sofile); ) h = dlopen(sofile, RTLD_GLOBAL); unblockAsyncSignals(); if (h == 0) { fprintf(stderr, "Failed to load `%s'\nError: `%s'\n", sofile, dlerror()); } else {DBG(GCJ, dprintf("%s: Loaded `%s'\n", __FUNCTION__, sofile); ) }#endif}static voiddumpMethod(_Jv_Method *meth){ fprintf(stderr," Method @%p ", meth); fprintf(stderr,"name=`%s', sig=`%s', flags=0x%x ", meth->name->data, meth->signature->data, meth->accflags); fprintf(stderr,"ncode=%p\n", meth->ncode);}static voiddumpField(_Jv_Field *fld){ fprintf(stderr," Field @%p ", fld); fprintf(stderr,"name=`%s', flags=0x%x\n", fld->name->data, fld->flags);}static const char *poolTag2Name(int i){#define C(x) if (i == x) { return #x + sizeof "JV_CONSTANT"; } C(JV_CONSTANT_String); C(JV_CONSTANT_Undefined); C(JV_CONSTANT_Utf8); C(JV_CONSTANT_Unicode); C(JV_CONSTANT_Integer); C(JV_CONSTANT_Float); C(JV_CONSTANT_Long); C(JV_CONSTANT_Double); C(JV_CONSTANT_Class); C(JV_CONSTANT_String); C(JV_CONSTANT_Fieldref); C(JV_CONSTANT_Methodref); C(JV_CONSTANT_InterfaceMethodref); C(JV_CONSTANT_NameAndType); return "UNKNOWN";}static voiddumpClass(java::lang::Class *clazz){ fprintf(stderr,"Class `%s'@%p\n", clazz->name->data, clazz); fprintf(stderr," accflags=0x%x ", clazz->accflags); fprintf(stderr," superclass=@%p\n", clazz->superclass);#define PFIELD(x) fprintf(stderr," "#x"= %d ", (int)clazz->x) PFIELD(size_in_bytes); PFIELD(vtable_method_count); PFIELD(method_count); fprintf(stderr, "\n"); PFIELD(field_count); PFIELD(static_field_count); PFIELD(state); fprintf(stderr, "\n"); PFIELD(interface_count); for (int i = 0; i < clazz->interface_count; i++) { fprintf(stderr, " %p", clazz->interfaces[i]); } fprintf(stderr, "\n"); for (int i = 0; i < clazz->method_count; i++) { dumpMethod(clazz->methods + i); } for (int i = 0; i < clazz->field_count; i++) { dumpField(clazz->fields + i); } _Jv_Constants& pool = clazz->constants; for (int i = 1; i < pool.size; i++) { fprintf(stderr, " CPool[%d].%s = ", i, poolTag2Name(pool.tags[i])); switch (pool.tags[i]) { case JV_CONSTANT_String: case JV_CONSTANT_Class: { fprintf(stderr, "`%s'\n", pool.data[i].utf8->data); break; } default: /* else just print the pointer value for now */ fprintf(stderr, "%p (?)\n", pool.data[i].utf8); break; } }}/* * Register a pre-built class. */extern "C" void_Jv_RegisterClass(java::lang::Class* clazz){DBG(GCJ, dumpClass(clazz); ) /* use next field provided by libgcj definition */ clazz->next = preCList; preCList = clazz;}static voidfillInClassInfo(neutralClassInfo *info, java::lang::Class *clazz){ info->gcjClass = clazz; info->name = clazz->name->data; info->vtable = clazz->vtable; info->superclass = clazz->superclass; info->methodCount = clazz->method_count; info->accflags = clazz->accflags; info->fieldCount = clazz->field_count; info->vTableCount = clazz->vtable_method_count; info->interfaceCount = clazz->interface_count; info->interfaces = (void**)clazz->interfaces;}static voidfillInMethodInfo(neutralMethodInfo *info, struct _Jv_Method *meth){ info->name = meth->name->data; info->signature = meth->signature->data; info->accflags = meth->accflags; info->ncode = meth->ncode;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -