mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-23 01:30:29 +08:00
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
This commit is contained in:
parent
9026e8d4d5
commit
a022cd5969
@ -1,3 +1,20 @@
|
||||
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:
|
||||
|
@ -101,13 +101,17 @@ struct _Jv_ClassReader
|
||||
|
||||
// the class to define (see java-interp.h)
|
||||
jclass def;
|
||||
|
||||
|
||||
// the classes associated interpreter data.
|
||||
_Jv_InterpClass *def_interp;
|
||||
|
||||
// The name we found.
|
||||
_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 */
|
||||
inline void check (int num)
|
||||
{
|
||||
@ -233,6 +237,8 @@ struct _Jv_ClassReader
|
||||
bytes = (unsigned char*) (elements (data)+offset);
|
||||
len = length;
|
||||
pos = 0;
|
||||
is_15 = false;
|
||||
|
||||
def = klass;
|
||||
found_name = name_result;
|
||||
|
||||
@ -302,19 +308,32 @@ _Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length,
|
||||
|
||||
/** 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
|
||||
_Jv_ClassReader::parse ()
|
||||
{
|
||||
int magic = read4 ();
|
||||
|
||||
/* FIXME: Decide which range of version numbers to allow */
|
||||
|
||||
/* int minor_version = */ read2u ();
|
||||
/* int major_verson = */ read2u ();
|
||||
|
||||
if (magic != (int) 0xCAFEBABE)
|
||||
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 ();
|
||||
|
||||
read_constpool ();
|
||||
@ -1318,6 +1337,7 @@ void _Jv_ClassReader::handleCodeAttribute
|
||||
method->max_locals = max_locals;
|
||||
method->code_length = code_length;
|
||||
method->exc_count = exc_table_length;
|
||||
method->is_15 = is_15;
|
||||
method->defining_class = def;
|
||||
method->self = &def->methods[method_index];
|
||||
method->prepared = NULL;
|
||||
|
@ -137,6 +137,7 @@ class _Jv_InterpMethod : public _Jv_MethodBase
|
||||
int code_length;
|
||||
|
||||
_Jv_ushort exc_count;
|
||||
bool is_15;
|
||||
|
||||
// Length of the line_table - when this is zero then line_table is NULL.
|
||||
int line_table_len;
|
||||
@ -218,7 +219,8 @@ _Jv_GetFirstMethod (_Jv_InterpClass *klass)
|
||||
return klass->interpreted_methods;
|
||||
}
|
||||
|
||||
struct _Jv_ResolvedMethod {
|
||||
struct _Jv_ResolvedMethod
|
||||
{
|
||||
jint stack_item_count;
|
||||
jint vtable_index;
|
||||
jclass klass;
|
||||
|
@ -507,7 +507,16 @@ _Jv_InterpMethod::compile (const void * const *insn_targets)
|
||||
{
|
||||
int index = get1u (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;
|
||||
|
||||
@ -537,7 +546,16 @@ _Jv_InterpMethod::compile (const void * const *insn_targets)
|
||||
{
|
||||
int index = get2u (pc);
|
||||
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;
|
||||
|
||||
@ -1017,7 +1035,11 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth)
|
||||
INSN_LABEL(ifnonnull),
|
||||
INSN_LABEL(goto_w),
|
||||
INSN_LABEL(jsr_w),
|
||||
#ifdef DIRECT_THREADED
|
||||
INSN_LABEL (ldc_class)
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
};
|
||||
|
||||
pc_t pc;
|
||||
@ -1058,8 +1080,16 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth)
|
||||
#define GET2S() (pc += 2, get2s (pc- 2))
|
||||
#define GET1U() get1u (pc++)
|
||||
#define GET2U() (pc += 2, get2u (pc - 2))
|
||||
#define AVAL1U() ({ int index = get1u (pc++); pool_data[index].o; })
|
||||
#define AVAL2U() ({ int index = get2u (pc); pc += 2; pool_data[index].o; })
|
||||
// Note that these could be more efficient when not handling 'ldc
|
||||
// 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 SKIP_GOTO pc += 2
|
||||
#define GOTO_VAL() pc - 1 + get2s (pc)
|
||||
@ -1320,6 +1350,19 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth)
|
||||
PUSHA ((jobject) AVAL2U ());
|
||||
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:
|
||||
{
|
||||
void *where = AVAL2UP ();
|
||||
|
@ -1950,13 +1950,16 @@ private:
|
||||
{
|
||||
check_pool_index (index);
|
||||
_Jv_Constants *pool = ¤t_class->constants;
|
||||
if (pool->tags[index] == JV_CONSTANT_ResolvedString
|
||||
|| pool->tags[index] == JV_CONSTANT_String)
|
||||
int tag = pool->tags[index];
|
||||
if (tag == JV_CONSTANT_ResolvedString || tag == JV_CONSTANT_String)
|
||||
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);
|
||||
else if (pool->tags[index] == JV_CONSTANT_Float)
|
||||
else if (tag == JV_CONSTANT_Float)
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user