Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/classfile/verifier.hpp
32285 views
1
/*
2
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#ifndef SHARE_VM_CLASSFILE_VERIFIER_HPP
26
#define SHARE_VM_CLASSFILE_VERIFIER_HPP
27
28
#include "classfile/verificationType.hpp"
29
#include "memory/gcLocker.hpp"
30
#include "oops/klass.hpp"
31
#include "oops/method.hpp"
32
#include "runtime/handles.hpp"
33
#include "utilities/growableArray.hpp"
34
#include "utilities/exceptions.hpp"
35
36
// The verifier class
37
class Verifier : AllStatic {
38
public:
39
enum {
40
STRICTER_ACCESS_CTRL_CHECK_VERSION = 49,
41
STACKMAP_ATTRIBUTE_MAJOR_VERSION = 50,
42
INVOKEDYNAMIC_MAJOR_VERSION = 51,
43
NO_RELAX_ACCESS_CTRL_CHECK_VERSION = 52
44
};
45
typedef enum { ThrowException, NoException } Mode;
46
47
/**
48
* Verify the bytecodes for a class. If 'throw_exception' is true
49
* then the appropriate VerifyError or ClassFormatError will be thrown.
50
* Otherwise, no exception is thrown and the return indicates the
51
* error.
52
*/
53
static bool verify(instanceKlassHandle klass, Mode mode, bool should_verify_class, TRAPS);
54
55
// Return false if the class is loaded by the bootstrap loader,
56
// or if defineClass was called requesting skipping verification
57
// -Xverify:all/none override this value
58
static bool should_verify_for(oop class_loader, bool should_verify_class);
59
60
// Relax certain access checks to enable some broken 1.1 apps to run on 1.2.
61
static bool relax_access_for(oop class_loader);
62
63
private:
64
static bool is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class);
65
static Symbol* inference_verify(
66
instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS);
67
};
68
69
class RawBytecodeStream;
70
class StackMapFrame;
71
class StackMapTable;
72
73
// Summary of verifier's memory usage:
74
// StackMapTable is stack allocated.
75
// StackMapFrame are resource allocated. There is only one ResourceMark
76
// for each class verification, which is created at the top level.
77
// There is one mutable StackMapFrame (current_frame) which is updated
78
// by abstract bytecode interpretation. frame_in_exception_handler() returns
79
// a frame that has a mutable one-item stack (ready for pushing the
80
// catch type exception object). All the other StackMapFrame's
81
// are immutable (including their locals and stack arrays) after
82
// their constructions.
83
// locals/stack arrays in StackMapFrame are resource allocated.
84
// locals/stack arrays can be shared between StackMapFrame's, except
85
// the mutable StackMapFrame (current_frame).
86
87
// These macros are used similarly to CHECK macros but also check
88
// the status of the verifier and return if that has an error.
89
#define CHECK_VERIFY(verifier) \
90
CHECK); if ((verifier)->has_error()) return; ((void)0
91
#define CHECK_VERIFY_(verifier, result) \
92
CHECK_(result)); if ((verifier)->has_error()) return (result); ((void)0
93
94
class TypeOrigin VALUE_OBJ_CLASS_SPEC {
95
private:
96
typedef enum {
97
CF_LOCALS, // Comes from the current frame locals
98
CF_STACK, // Comes from the current frame expression stack
99
SM_LOCALS, // Comes from stackmap locals
100
SM_STACK, // Comes from stackmap expression stack
101
CONST_POOL, // Comes from the constant pool
102
SIG, // Comes from method signature
103
IMPLICIT, // Comes implicitly from code or context
104
BAD_INDEX, // No type, but the index is bad
105
FRAME_ONLY, // No type, context just contains the frame
106
NONE
107
} Origin;
108
109
Origin _origin;
110
u2 _index; // local, stack, or constant pool index
111
StackMapFrame* _frame; // source frame if CF or SM
112
VerificationType _type; // The actual type
113
114
TypeOrigin(
115
Origin origin, u2 index, StackMapFrame* frame, VerificationType type)
116
: _origin(origin), _index(index), _frame(frame), _type(type) {}
117
118
public:
119
TypeOrigin() : _origin(NONE), _index(0), _frame(NULL) {}
120
121
static TypeOrigin null();
122
static TypeOrigin local(u2 index, StackMapFrame* frame);
123
static TypeOrigin stack(u2 index, StackMapFrame* frame);
124
static TypeOrigin sm_local(u2 index, StackMapFrame* frame);
125
static TypeOrigin sm_stack(u2 index, StackMapFrame* frame);
126
static TypeOrigin cp(u2 index, VerificationType vt);
127
static TypeOrigin signature(VerificationType vt);
128
static TypeOrigin bad_index(u2 index);
129
static TypeOrigin implicit(VerificationType t);
130
static TypeOrigin frame(StackMapFrame* frame);
131
132
void reset_frame();
133
void details(outputStream* ss) const;
134
void print_frame(outputStream* ss) const;
135
const StackMapFrame* frame() const { return _frame; }
136
bool is_valid() const { return _origin != NONE; }
137
u2 index() const { return _index; }
138
139
#ifdef ASSERT
140
void print_on(outputStream* str) const;
141
#endif
142
};
143
144
class ErrorContext VALUE_OBJ_CLASS_SPEC {
145
private:
146
typedef enum {
147
INVALID_BYTECODE, // There was a problem with the bytecode
148
WRONG_TYPE, // Type value was not as expected
149
FLAGS_MISMATCH, // Frame flags are not assignable
150
BAD_CP_INDEX, // Invalid constant pool index
151
BAD_LOCAL_INDEX, // Invalid local index
152
LOCALS_SIZE_MISMATCH, // Frames have differing local counts
153
STACK_SIZE_MISMATCH, // Frames have different stack sizes
154
STACK_OVERFLOW, // Attempt to push onto a full expression stack
155
STACK_UNDERFLOW, // Attempt to pop and empty expression stack
156
MISSING_STACKMAP, // No stackmap for this location and there should be
157
BAD_STACKMAP, // Format error in stackmap
158
NO_FAULT, // No error
159
UNKNOWN
160
} FaultType;
161
162
int _bci;
163
FaultType _fault;
164
TypeOrigin _type;
165
TypeOrigin _expected;
166
167
ErrorContext(int bci, FaultType fault) :
168
_bci(bci), _fault(fault) {}
169
ErrorContext(int bci, FaultType fault, TypeOrigin type) :
170
_bci(bci), _fault(fault), _type(type) {}
171
ErrorContext(int bci, FaultType fault, TypeOrigin type, TypeOrigin exp) :
172
_bci(bci), _fault(fault), _type(type), _expected(exp) {}
173
174
public:
175
ErrorContext() : _bci(-1), _fault(NO_FAULT) {}
176
177
static ErrorContext bad_code(u2 bci) {
178
return ErrorContext(bci, INVALID_BYTECODE);
179
}
180
static ErrorContext bad_type(u2 bci, TypeOrigin type) {
181
return ErrorContext(bci, WRONG_TYPE, type);
182
}
183
static ErrorContext bad_type(u2 bci, TypeOrigin type, TypeOrigin exp) {
184
return ErrorContext(bci, WRONG_TYPE, type, exp);
185
}
186
static ErrorContext bad_flags(u2 bci, StackMapFrame* frame) {
187
return ErrorContext(bci, FLAGS_MISMATCH, TypeOrigin::frame(frame));
188
}
189
static ErrorContext bad_flags(u2 bci, StackMapFrame* cur, StackMapFrame* sm) {
190
return ErrorContext(bci, FLAGS_MISMATCH,
191
TypeOrigin::frame(cur), TypeOrigin::frame(sm));
192
}
193
static ErrorContext bad_cp_index(u2 bci, u2 index) {
194
return ErrorContext(bci, BAD_CP_INDEX, TypeOrigin::bad_index(index));
195
}
196
static ErrorContext bad_local_index(u2 bci, u2 index) {
197
return ErrorContext(bci, BAD_LOCAL_INDEX, TypeOrigin::bad_index(index));
198
}
199
static ErrorContext locals_size_mismatch(
200
u2 bci, StackMapFrame* frame0, StackMapFrame* frame1) {
201
return ErrorContext(bci, LOCALS_SIZE_MISMATCH,
202
TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
203
}
204
static ErrorContext stack_size_mismatch(
205
u2 bci, StackMapFrame* frame0, StackMapFrame* frame1) {
206
return ErrorContext(bci, STACK_SIZE_MISMATCH,
207
TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
208
}
209
static ErrorContext stack_overflow(u2 bci, StackMapFrame* frame) {
210
return ErrorContext(bci, STACK_OVERFLOW, TypeOrigin::frame(frame));
211
}
212
static ErrorContext stack_underflow(u2 bci, StackMapFrame* frame) {
213
return ErrorContext(bci, STACK_UNDERFLOW, TypeOrigin::frame(frame));
214
}
215
static ErrorContext missing_stackmap(u2 bci) {
216
return ErrorContext(bci, MISSING_STACKMAP);
217
}
218
static ErrorContext bad_stackmap(int index, StackMapFrame* frame) {
219
return ErrorContext(0, BAD_STACKMAP, TypeOrigin::frame(frame));
220
}
221
222
bool is_valid() const { return _fault != NO_FAULT; }
223
int bci() const { return _bci; }
224
225
void reset_frames() {
226
_type.reset_frame();
227
_expected.reset_frame();
228
}
229
230
void details(outputStream* ss, const Method* method) const;
231
232
#ifdef ASSERT
233
void print_on(outputStream* str) const {
234
str->print("error_context(%d, %d,", _bci, _fault);
235
_type.print_on(str);
236
str->print(",");
237
_expected.print_on(str);
238
str->print(")");
239
}
240
#endif
241
242
private:
243
void location_details(outputStream* ss, const Method* method) const;
244
void reason_details(outputStream* ss) const;
245
void frame_details(outputStream* ss) const;
246
void bytecode_details(outputStream* ss, const Method* method) const;
247
void handler_details(outputStream* ss, const Method* method) const;
248
void stackmap_details(outputStream* ss, const Method* method) const;
249
};
250
251
// A new instance of this class is created for each class being verified
252
class ClassVerifier : public StackObj {
253
private:
254
Thread* _thread;
255
GrowableArray<Symbol*>* _symbols; // keep a list of symbols created
256
257
Symbol* _exception_type;
258
char* _message;
259
260
ErrorContext _error_context; // contains information about an error
261
262
void verify_method(methodHandle method, TRAPS);
263
char* generate_code_data(methodHandle m, u4 code_length, TRAPS);
264
void verify_exception_handler_table(u4 code_length, char* code_data,
265
int& min, int& max, TRAPS);
266
void verify_local_variable_table(u4 code_length, char* code_data, TRAPS);
267
268
VerificationType cp_ref_index_to_type(
269
int index, constantPoolHandle cp, TRAPS) {
270
return cp_index_to_type(cp->klass_ref_index_at(index), cp, THREAD);
271
}
272
273
bool is_protected_access(
274
instanceKlassHandle this_class, Klass* target_class,
275
Symbol* field_name, Symbol* field_sig, bool is_method);
276
277
void verify_cp_index(u2 bci, constantPoolHandle cp, int index, TRAPS);
278
void verify_cp_type(u2 bci, int index, constantPoolHandle cp,
279
unsigned int types, TRAPS);
280
void verify_cp_class_type(u2 bci, int index, constantPoolHandle cp, TRAPS);
281
282
u2 verify_stackmap_table(
283
u2 stackmap_index, u2 bci, StackMapFrame* current_frame,
284
StackMapTable* stackmap_table, bool no_control_flow, TRAPS);
285
286
void verify_exception_handler_targets(
287
u2 bci, bool this_uninit, StackMapFrame* current_frame,
288
StackMapTable* stackmap_table, TRAPS);
289
290
void verify_ldc(
291
int opcode, u2 index, StackMapFrame *current_frame,
292
constantPoolHandle cp, u2 bci, TRAPS);
293
294
void verify_switch(
295
RawBytecodeStream* bcs, u4 code_length, char* code_data,
296
StackMapFrame* current_frame, StackMapTable* stackmap_table, TRAPS);
297
298
void verify_field_instructions(
299
RawBytecodeStream* bcs, StackMapFrame* current_frame,
300
constantPoolHandle cp, TRAPS);
301
302
void verify_invoke_init(
303
RawBytecodeStream* bcs, u2 ref_index, VerificationType ref_class_type,
304
StackMapFrame* current_frame, u4 code_length, bool in_try_block,
305
bool* this_uninit, constantPoolHandle cp, StackMapTable* stackmap_table,
306
TRAPS);
307
308
// Used by ends_in_athrow() to push all handlers that contain bci onto the
309
// handler_stack, if the handler has not already been pushed on the stack.
310
void push_handlers(ExceptionTable* exhandlers,
311
GrowableArray<u4>* handler_list,
312
GrowableArray<u4>* handler_stack,
313
u4 bci);
314
315
// Returns true if all paths starting with start_bc_offset end in athrow
316
// bytecode or loop.
317
bool ends_in_athrow(u4 start_bc_offset);
318
319
void verify_invoke_instructions(
320
RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
321
bool in_try_block, bool* this_uninit, VerificationType return_type,
322
constantPoolHandle cp, StackMapTable* stackmap_table, TRAPS);
323
324
VerificationType get_newarray_type(u2 index, u2 bci, TRAPS);
325
void verify_anewarray(u2 bci, u2 index, constantPoolHandle cp,
326
StackMapFrame* current_frame, TRAPS);
327
void verify_return_value(
328
VerificationType return_type, VerificationType type, u2 offset,
329
StackMapFrame* current_frame, TRAPS);
330
331
void verify_iload (u2 index, StackMapFrame* current_frame, TRAPS);
332
void verify_lload (u2 index, StackMapFrame* current_frame, TRAPS);
333
void verify_fload (u2 index, StackMapFrame* current_frame, TRAPS);
334
void verify_dload (u2 index, StackMapFrame* current_frame, TRAPS);
335
void verify_aload (u2 index, StackMapFrame* current_frame, TRAPS);
336
void verify_istore(u2 index, StackMapFrame* current_frame, TRAPS);
337
void verify_lstore(u2 index, StackMapFrame* current_frame, TRAPS);
338
void verify_fstore(u2 index, StackMapFrame* current_frame, TRAPS);
339
void verify_dstore(u2 index, StackMapFrame* current_frame, TRAPS);
340
void verify_astore(u2 index, StackMapFrame* current_frame, TRAPS);
341
void verify_iinc (u2 index, StackMapFrame* current_frame, TRAPS);
342
343
bool name_in_supers(Symbol* ref_name, instanceKlassHandle current);
344
345
VerificationType object_type() const;
346
347
instanceKlassHandle _klass; // the class being verified
348
methodHandle _method; // current method being verified
349
VerificationType _this_type; // the verification type of the current class
350
351
// Some recursive calls from the verifier to the name resolver
352
// can cause the current class to be re-verified and rewritten.
353
// If this happens, the original verification should not continue,
354
// because constant pool indexes will have changed.
355
// The rewriter is preceded by the verifier. If the verifier throws
356
// an error, rewriting is prevented. Also, rewriting always precedes
357
// bytecode execution or compilation. Thus, is_rewritten implies
358
// that a class has been verified and prepared for execution.
359
bool was_recursively_verified() { return _klass->is_rewritten(); }
360
361
bool is_same_or_direct_interface(instanceKlassHandle klass,
362
VerificationType klass_type, VerificationType ref_class_type);
363
364
public:
365
enum {
366
BYTECODE_OFFSET = 1,
367
NEW_OFFSET = 2
368
};
369
370
// constructor
371
ClassVerifier(instanceKlassHandle klass, TRAPS);
372
373
// destructor
374
~ClassVerifier();
375
376
Thread* thread() { return _thread; }
377
methodHandle method() { return _method; }
378
instanceKlassHandle current_class() const { return _klass; }
379
VerificationType current_type() const { return _this_type; }
380
381
// Verifies the class. If a verify or class file format error occurs,
382
// the '_exception_name' symbols will set to the exception name and
383
// the message_buffer will be filled in with the exception message.
384
void verify_class(TRAPS);
385
386
// Return status modes
387
Symbol* result() const { return _exception_type; }
388
bool has_error() const { return result() != NULL; }
389
char* exception_message() {
390
stringStream ss;
391
ss.print("%s", _message);
392
_error_context.details(&ss, _method());
393
return ss.as_string();
394
}
395
396
// Called when verify or class format errors are encountered.
397
// May throw an exception based upon the mode.
398
void verify_error(ErrorContext ctx, const char* fmt, ...) ATTRIBUTE_PRINTF(3, 4);
399
void class_format_error(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3);
400
401
Klass* load_class(Symbol* name, TRAPS);
402
403
int change_sig_to_verificationType(
404
SignatureStream* sig_type, VerificationType* inference_type, TRAPS);
405
406
VerificationType cp_index_to_type(int index, constantPoolHandle cp, TRAPS) {
407
return VerificationType::reference_type(cp->klass_name_at(index));
408
}
409
410
// Keep a list of temporary symbols created during verification because
411
// their reference counts need to be decrememented when the verifier object
412
// goes out of scope. Since these symbols escape the scope in which they're
413
// created, we can't use a TempNewSymbol.
414
Symbol* create_temporary_symbol(
415
const Symbol* s, int begin, int end, TRAPS);
416
Symbol* create_temporary_symbol(const char *s, int length, TRAPS);
417
418
TypeOrigin ref_ctx(const char* str, TRAPS);
419
420
};
421
422
inline int ClassVerifier::change_sig_to_verificationType(
423
SignatureStream* sig_type, VerificationType* inference_type, TRAPS) {
424
BasicType bt = sig_type->type();
425
switch (bt) {
426
case T_OBJECT:
427
case T_ARRAY:
428
{
429
Symbol* name = sig_type->as_symbol(CHECK_0);
430
// Create another symbol to save as signature stream unreferences
431
// this symbol.
432
Symbol* name_copy =
433
create_temporary_symbol(name, 0, name->utf8_length(), CHECK_0);
434
assert(name_copy == name, "symbols don't match");
435
*inference_type =
436
VerificationType::reference_type(name_copy);
437
return 1;
438
}
439
case T_LONG:
440
*inference_type = VerificationType::long_type();
441
*++inference_type = VerificationType::long2_type();
442
return 2;
443
case T_DOUBLE:
444
*inference_type = VerificationType::double_type();
445
*++inference_type = VerificationType::double2_type();
446
return 2;
447
case T_INT:
448
case T_BOOLEAN:
449
case T_BYTE:
450
case T_CHAR:
451
case T_SHORT:
452
*inference_type = VerificationType::integer_type();
453
return 1;
454
case T_FLOAT:
455
*inference_type = VerificationType::float_type();
456
return 1;
457
default:
458
ShouldNotReachHere();
459
return 1;
460
}
461
}
462
463
#endif // SHARE_VM_CLASSFILE_VERIFIER_HPP
464
465