Commit a022cd59 by Tom Tromey Committed by Tom Tromey

re PR libgcj/16032 (libgcj should reject class files with incorrect version numbers)

	PR libgcj/16032:
	* interpret.cc (AVAL1U): Resolve pool entry when not direct
	threaded.
	(AVAL2U): Likewise.
	(compile): Handle 'ldc class' specially.
	(_Jv_InterpMethod::run): Added special 'ldc class' instruction.
	* verify.cc (check_constant): Handle 'ldc class' for 1.5 classes.
	* defineclass.cc (handleCodeAttribute): Set new field.
	(MAJOR_1_1, MINOR_1_1, MAJOR_1_2, MINOR_1_2, MAJOR_1_3, MINOR_1_3,
	MAJOR_1_4, MINOR_1_4, MAJOR_1_5, MINOR_1_5): New defines.
	(parse): Check version numbers.
	(_Jv_ClassReader::is_15): New field.
	(_Jv_ClassReader): Initialize it.
	* include/java-interp.h (_Jv_InterpMethod::is_15): New field.

From-SVN: r104325
parent 9026e8d4
2005-09-15 Tom Tromey <tromey@redhat.com> 2005-09-15 Tom Tromey <tromey@redhat.com>
PR libgcj/16032:
* interpret.cc (AVAL1U): Resolve pool entry when not direct
threaded.
(AVAL2U): Likewise.
(compile): Handle 'ldc class' specially.
(_Jv_InterpMethod::run): Added special 'ldc class' instruction.
* verify.cc (check_constant): Handle 'ldc class' for 1.5 classes.
* defineclass.cc (handleCodeAttribute): Set new field.
(MAJOR_1_1, MINOR_1_1, MAJOR_1_2, MINOR_1_2, MAJOR_1_3, MINOR_1_3,
MAJOR_1_4, MINOR_1_4, MAJOR_1_5, MINOR_1_5): New defines.
(parse): Check version numbers.
(_Jv_ClassReader::is_15): New field.
(_Jv_ClassReader): Initialize it.
* include/java-interp.h (_Jv_InterpMethod::is_15): New field.
2005-09-15 Tom Tromey <tromey@redhat.com>
For PR libgcj/23288: For PR libgcj/23288:
* java/net/URLClassLoader.java (definePackage): Correctly order * java/net/URLClassLoader.java (definePackage): Correctly order
arguments to definePackage. Look up per-entry Attributes. arguments to definePackage. Look up per-entry Attributes.
......
...@@ -101,13 +101,17 @@ struct _Jv_ClassReader ...@@ -101,13 +101,17 @@ struct _Jv_ClassReader
// the class to define (see java-interp.h) // the class to define (see java-interp.h)
jclass def; jclass def;
// the classes associated interpreter data. // the classes associated interpreter data.
_Jv_InterpClass *def_interp; _Jv_InterpClass *def_interp;
// The name we found. // The name we found.
_Jv_Utf8Const **found_name; _Jv_Utf8Const **found_name;
// True if this is a 1.5 class file.
bool is_15;
/* check that the given number of input bytes are available */ /* check that the given number of input bytes are available */
inline void check (int num) inline void check (int num)
{ {
...@@ -233,6 +237,8 @@ struct _Jv_ClassReader ...@@ -233,6 +237,8 @@ struct _Jv_ClassReader
bytes = (unsigned char*) (elements (data)+offset); bytes = (unsigned char*) (elements (data)+offset);
len = length; len = length;
pos = 0; pos = 0;
is_15 = false;
def = klass; def = klass;
found_name = name_result; found_name = name_result;
...@@ -302,19 +308,32 @@ _Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length, ...@@ -302,19 +308,32 @@ _Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length,
/** This section defines the parsing/scanning of the class data */ /** This section defines the parsing/scanning of the class data */
// Major and minor version numbers for various releases.
#define MAJOR_1_1 45
#define MINOR_1_1 3
#define MAJOR_1_2 46
#define MINOR_1_2 0
#define MAJOR_1_3 47
#define MINOR_1_3 0
#define MAJOR_1_4 48
#define MINOR_1_4 0
#define MAJOR_1_5 49
#define MINOR_1_5 0
void void
_Jv_ClassReader::parse () _Jv_ClassReader::parse ()
{ {
int magic = read4 (); int magic = read4 ();
/* FIXME: Decide which range of version numbers to allow */
/* int minor_version = */ read2u ();
/* int major_verson = */ read2u ();
if (magic != (int) 0xCAFEBABE) if (magic != (int) 0xCAFEBABE)
throw_class_format_error ("bad magic number"); throw_class_format_error ("bad magic number");
int minor_version = read2u ();
int major_version = read2u ();
if (major_version < MAJOR_1_1 || major_version > MAJOR_1_5
|| (major_version == MAJOR_1_5 && minor_version > MINOR_1_5))
throw_class_format_error ("unrecognized class file version");
is_15 = (major_version == MAJOR_1_5);
pool_count = read2u (); pool_count = read2u ();
read_constpool (); read_constpool ();
...@@ -1318,6 +1337,7 @@ void _Jv_ClassReader::handleCodeAttribute ...@@ -1318,6 +1337,7 @@ void _Jv_ClassReader::handleCodeAttribute
method->max_locals = max_locals; method->max_locals = max_locals;
method->code_length = code_length; method->code_length = code_length;
method->exc_count = exc_table_length; method->exc_count = exc_table_length;
method->is_15 = is_15;
method->defining_class = def; method->defining_class = def;
method->self = &def->methods[method_index]; method->self = &def->methods[method_index];
method->prepared = NULL; method->prepared = NULL;
......
...@@ -137,6 +137,7 @@ class _Jv_InterpMethod : public _Jv_MethodBase ...@@ -137,6 +137,7 @@ class _Jv_InterpMethod : public _Jv_MethodBase
int code_length; int code_length;
_Jv_ushort exc_count; _Jv_ushort exc_count;
bool is_15;
// Length of the line_table - when this is zero then line_table is NULL. // Length of the line_table - when this is zero then line_table is NULL.
int line_table_len; int line_table_len;
...@@ -218,7 +219,8 @@ _Jv_GetFirstMethod (_Jv_InterpClass *klass) ...@@ -218,7 +219,8 @@ _Jv_GetFirstMethod (_Jv_InterpClass *klass)
return klass->interpreted_methods; return klass->interpreted_methods;
} }
struct _Jv_ResolvedMethod { struct _Jv_ResolvedMethod
{
jint stack_item_count; jint stack_item_count;
jint vtable_index; jint vtable_index;
jclass klass; jclass klass;
......
...@@ -507,7 +507,16 @@ _Jv_InterpMethod::compile (const void * const *insn_targets) ...@@ -507,7 +507,16 @@ _Jv_InterpMethod::compile (const void * const *insn_targets)
{ {
int index = get1u (pc); int index = get1u (pc);
++pc; ++pc;
SET_DATUM (pool_data[index].o); // For an unresolved class we want to delay resolution
// until execution.
if (defining_class->constants.tags[index] == JV_CONSTANT_Class)
{
--next;
SET_INSN (insn_targets[int (op_jsr_w) + 1]);
SET_INT (index);
}
else
SET_DATUM (pool_data[index].o);
} }
break; break;
...@@ -537,7 +546,16 @@ _Jv_InterpMethod::compile (const void * const *insn_targets) ...@@ -537,7 +546,16 @@ _Jv_InterpMethod::compile (const void * const *insn_targets)
{ {
int index = get2u (pc); int index = get2u (pc);
pc += 2; pc += 2;
SET_DATUM (pool_data[index].o); // For an unresolved class we want to delay resolution
// until execution.
if (defining_class->constants.tags[index] == JV_CONSTANT_Class)
{
--next;
SET_INSN (insn_targets[int (op_jsr_w) + 1]);
SET_INT (index);
}
else
SET_DATUM (pool_data[index].o);
} }
break; break;
...@@ -1017,7 +1035,11 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth) ...@@ -1017,7 +1035,11 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth)
INSN_LABEL(ifnonnull), INSN_LABEL(ifnonnull),
INSN_LABEL(goto_w), INSN_LABEL(goto_w),
INSN_LABEL(jsr_w), INSN_LABEL(jsr_w),
#ifdef DIRECT_THREADED
INSN_LABEL (ldc_class)
#else
0 0
#endif
}; };
pc_t pc; pc_t pc;
...@@ -1058,8 +1080,16 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth) ...@@ -1058,8 +1080,16 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth)
#define GET2S() (pc += 2, get2s (pc- 2)) #define GET2S() (pc += 2, get2s (pc- 2))
#define GET1U() get1u (pc++) #define GET1U() get1u (pc++)
#define GET2U() (pc += 2, get2u (pc - 2)) #define GET2U() (pc += 2, get2u (pc - 2))
#define AVAL1U() ({ int index = get1u (pc++); pool_data[index].o; }) // Note that these could be more efficient when not handling 'ldc
#define AVAL2U() ({ int index = get2u (pc); pc += 2; pool_data[index].o; }) // class'.
#define AVAL1U() \
({ int index = get1u (pc++); \
resolve_pool_entry (meth->defining_class, index).o; })
#define AVAL2U() \
({ int index = get2u (pc); pc += 2; \
resolve_pool_entry (meth->defining_class, index).o; })
// Note that we don't need to resolve the pool entry here as class
// constants are never wide.
#define AVAL2UP() ({ int index = get2u (pc); pc += 2; &pool_data[index]; }) #define AVAL2UP() ({ int index = get2u (pc); pc += 2; &pool_data[index]; })
#define SKIP_GOTO pc += 2 #define SKIP_GOTO pc += 2
#define GOTO_VAL() pc - 1 + get2s (pc) #define GOTO_VAL() pc - 1 + get2s (pc)
...@@ -1320,6 +1350,19 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth) ...@@ -1320,6 +1350,19 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth)
PUSHA ((jobject) AVAL2U ()); PUSHA ((jobject) AVAL2U ());
NEXT_INSN; NEXT_INSN;
#ifdef DIRECT_THREADED
// For direct threaded we have a separate 'ldc class' operation.
insn_ldc_class:
{
// We could rewrite the instruction at this point.
int index = INTVAL ();
jobject k = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
index)).o;
PUSHA (k);
}
NEXT_INSN;
#endif /* DIRECT_THREADED */
insn_ldc2_w: insn_ldc2_w:
{ {
void *where = AVAL2UP (); void *where = AVAL2UP ();
......
...@@ -1950,13 +1950,16 @@ private: ...@@ -1950,13 +1950,16 @@ private:
{ {
check_pool_index (index); check_pool_index (index);
_Jv_Constants *pool = &current_class->constants; _Jv_Constants *pool = &current_class->constants;
if (pool->tags[index] == JV_CONSTANT_ResolvedString int tag = pool->tags[index];
|| pool->tags[index] == JV_CONSTANT_String) if (tag == JV_CONSTANT_ResolvedString || tag == JV_CONSTANT_String)
return type (&java::lang::String::class$, this); return type (&java::lang::String::class$, this);
else if (pool->tags[index] == JV_CONSTANT_Integer) else if (tag == JV_CONSTANT_Integer)
return type (int_type); return type (int_type);
else if (pool->tags[index] == JV_CONSTANT_Float) else if (tag == JV_CONSTANT_Float)
return type (float_type); return type (float_type);
else if (current_method->is_15
&& (tag == JV_CONSTANT_ResolvedClass || tag == JV_CONSTANT_Class))
return type (&java::lang::Class::class$, this);
verify_fail ("String, int, or float constant expected", start_PC); verify_fail ("String, int, or float constant expected", start_PC);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment