< prev index next >
src/share/vm/classfile/stackMapTableFormat.hpp
Print this page
rev 4136 : 7116786: RFE: Detailed information on VerifyErrors
Summary: Provide additional detail in VerifyError messages
Reviewed-by: sspitsyn, acorn
rev 4137 : 8159511: Stack map validation
Reviewed-by: acorn, mschoene
Contributed-by: harold.seigel@oracle.com
*** 1,7 ****
/*
! * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 133,143 ****
(address)this < end &&
(bci_addr() + sizeof(u2) <= end ||
!is_object() && !is_uninitialized()));
}
- #ifdef ASSERT
void print_on(outputStream* st) {
switch (tag()) {
case ITEM_Top: st->print("Top"); break;
case ITEM_Integer: st->print("Integer"); break;
case ITEM_Float: st->print("Float"); break;
--- 133,142 ----
*** 152,169 ****
st->print("Object[#%d]", cpool_index()); break;
default:
assert(false, "Bad verification_type_info");
}
}
- #endif
};
#define FOR_EACH_STACKMAP_FRAME_TYPE(macro, arg1, arg2) \
macro(same_frame, arg1, arg2) \
macro(same_frame_extended, arg1, arg2) \
! macro(same_frame_1_stack_item_frame, arg1, arg2) \
! macro(same_frame_1_stack_item_extended, arg1, arg2) \
macro(chop_frame, arg1, arg2) \
macro(append_frame, arg1, arg2) \
macro(full_frame, arg1, arg2)
#define SM_FORWARD_DECL(type, arg1, arg2) class type;
--- 151,167 ----
st->print("Object[#%d]", cpool_index()); break;
default:
assert(false, "Bad verification_type_info");
}
}
};
#define FOR_EACH_STACKMAP_FRAME_TYPE(macro, arg1, arg2) \
macro(same_frame, arg1, arg2) \
macro(same_frame_extended, arg1, arg2) \
! macro(same_locals_1_stack_item_frame, arg1, arg2) \
! macro(same_locals_1_stack_item_extended, arg1, arg2) \
macro(chop_frame, arg1, arg2) \
macro(append_frame, arg1, arg2) \
macro(full_frame, arg1, arg2)
#define SM_FORWARD_DECL(type, arg1, arg2) class type;
*** 201,213 ****
// This method must be used when reading unverified data in order to ensure
// that we don't read past a particular memory limit. It returns false
// if any part of the data structure is outside the specified memory bounds.
inline bool verify(address start, address end) const;
! #ifdef ASSERT
! inline void print_on(outputStream* st) const;
! #endif
// Create as_xxx and is_xxx methods for the subtypes
#define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \
inline stackmap_frame_type* as_##stackmap_frame_type() const; \
bool is_##stackmap_frame_type() { \
--- 199,211 ----
// This method must be used when reading unverified data in order to ensure
// that we don't read past a particular memory limit. It returns false
// if any part of the data structure is outside the specified memory bounds.
inline bool verify(address start, address end) const;
!
! inline void print_on(outputStream* st, int current_offset) const;
! inline void print_truncated(outputStream* st, int current_offset) const;
// Create as_xxx and is_xxx methods for the subtypes
#define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \
inline stackmap_frame_type* as_##stackmap_frame_type() const; \
bool is_##stackmap_frame_type() { \
*** 261,275 ****
bool verify_subtype(address start, address end) const {
return true;
}
! #ifdef ASSERT
! void print_on(outputStream* st) const {
! st->print("same_frame(%d)", offset_delta());
}
- #endif
};
class same_frame_extended : public stack_map_frame {
private:
enum { _frame_id = 251 };
--- 259,275 ----
bool verify_subtype(address start, address end) const {
return true;
}
! void print_on(outputStream* st, int current_offset = -1) const {
! st->print("same_frame(@%d)", offset_delta() + current_offset);
! }
!
! void print_truncated(outputStream* st, int current_offset = -1) const {
! print_on(st, current_offset);
}
};
class same_frame_extended : public stack_map_frame {
private:
enum { _frame_id = 251 };
*** 309,326 ****
bool verify_subtype(address start, address end) const {
return frame_type_addr() + size() <= end;
}
! #ifdef ASSERT
! void print_on(outputStream* st) const {
! st->print("same_frame_extended(%d)", offset_delta());
}
- #endif
};
! class same_frame_1_stack_item_frame : public stack_map_frame {
private:
address type_addr() const { return frame_type_addr() + sizeof(u1); }
static int frame_type_to_offset_delta(u1 frame_type) {
return frame_type - 63; }
--- 309,328 ----
bool verify_subtype(address start, address end) const {
return frame_type_addr() + size() <= end;
}
! void print_on(outputStream* st, int current_offset = -1) const {
! st->print("same_frame_extended(@%d)", offset_delta() + current_offset);
! }
!
! void print_truncated(outputStream* st, int current_offset = -1) const {
! print_on(st, current_offset);
}
};
! class same_locals_1_stack_item_frame : public stack_map_frame {
private:
address type_addr() const { return frame_type_addr() + sizeof(u1); }
static int frame_type_to_offset_delta(u1 frame_type) {
return frame_type - 63; }
*** 330,347 ****
public:
static bool is_frame_type(u1 tag) {
return tag >= 64 && tag < 128;
}
! static same_frame_1_stack_item_frame* at(address addr) {
assert(is_frame_type(*addr), "Wrong frame id");
! return (same_frame_1_stack_item_frame*)addr;
}
! static same_frame_1_stack_item_frame* create_at(
address addr, int offset_delta, verification_type_info* vti) {
! same_frame_1_stack_item_frame* sm = (same_frame_1_stack_item_frame*)addr;
sm->set_offset_delta(offset_delta);
if (vti != NULL) {
sm->set_type(vti);
}
return sm;
--- 332,349 ----
public:
static bool is_frame_type(u1 tag) {
return tag >= 64 && tag < 128;
}
! static same_locals_1_stack_item_frame* at(address addr) {
assert(is_frame_type(*addr), "Wrong frame id");
! return (same_locals_1_stack_item_frame*)addr;
}
! static same_locals_1_stack_item_frame* create_at(
address addr, int offset_delta, verification_type_info* vti) {
! same_locals_1_stack_item_frame* sm = (same_locals_1_stack_item_frame*)addr;
sm->set_offset_delta(offset_delta);
if (vti != NULL) {
sm->set_type(vti);
}
return sm;
*** 380,399 ****
bool verify_subtype(address start, address end) const {
return types()->verify(start, end);
}
! #ifdef ASSERT
! void print_on(outputStream* st) const {
! st->print("same_frame_1_stack_item_frame(%d,", offset_delta());
types()->print_on(st);
st->print(")");
}
! #endif
};
! class same_frame_1_stack_item_extended : public stack_map_frame {
private:
address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
address type_addr() const { return offset_delta_addr() + sizeof(u2); }
enum { _frame_id = 247 };
--- 382,405 ----
bool verify_subtype(address start, address end) const {
return types()->verify(start, end);
}
! void print_on(outputStream* st, int current_offset = -1) const {
! st->print("same_locals_1_stack_item_frame(@%d,",
! offset_delta() + current_offset);
types()->print_on(st);
st->print(")");
}
!
! void print_truncated(outputStream* st, int current_offset = -1) const {
! st->print("same_locals_1_stack_item_frame(@%d), output truncated, Stackmap exceeds table size.",
! offset_delta() + current_offset);
! }
};
! class same_locals_1_stack_item_extended : public stack_map_frame {
private:
address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
address type_addr() const { return offset_delta_addr() + sizeof(u2); }
enum { _frame_id = 247 };
*** 401,419 ****
public:
static bool is_frame_type(u1 tag) {
return tag == _frame_id;
}
! static same_frame_1_stack_item_extended* at(address addr) {
assert(is_frame_type(*addr), "Wrong frame id");
! return (same_frame_1_stack_item_extended*)addr;
}
! static same_frame_1_stack_item_extended* create_at(
address addr, int offset_delta, verification_type_info* vti) {
! same_frame_1_stack_item_extended* sm =
! (same_frame_1_stack_item_extended*)addr;
sm->set_frame_type(_frame_id);
sm->set_offset_delta(offset_delta);
if (vti != NULL) {
sm->set_type(vti);
}
--- 407,425 ----
public:
static bool is_frame_type(u1 tag) {
return tag == _frame_id;
}
! static same_locals_1_stack_item_extended* at(address addr) {
assert(is_frame_type(*addr), "Wrong frame id");
! return (same_locals_1_stack_item_extended*)addr;
}
! static same_locals_1_stack_item_extended* create_at(
address addr, int offset_delta, verification_type_info* vti) {
! same_locals_1_stack_item_extended* sm =
! (same_locals_1_stack_item_extended*)addr;
sm->set_frame_type(_frame_id);
sm->set_offset_delta(offset_delta);
if (vti != NULL) {
sm->set_type(vti);
}
*** 446,462 ****
bool verify_subtype(address start, address end) const {
return type_addr() < end && types()->verify(start, end);
}
! #ifdef ASSERT
! void print_on(outputStream* st) const {
! st->print("same_frame_1_stack_item_extended(%d,", offset_delta());
types()->print_on(st);
st->print(")");
}
! #endif
};
class chop_frame : public stack_map_frame {
private:
address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
--- 452,472 ----
bool verify_subtype(address start, address end) const {
return type_addr() < end && types()->verify(start, end);
}
! void print_on(outputStream* st, int current_offset = -1) const {
! st->print("same_locals_1_stack_item_extended(@%d,",
! offset_delta() + current_offset);
types()->print_on(st);
st->print(")");
}
!
! void print_truncated(outputStream* st, int current_offset = -1) const {
! st->print("same_locals_1_stack_item_extended(@%d), output truncated, Stackmap exceeds table size.",
! offset_delta() + current_offset);
! }
};
class chop_frame : public stack_map_frame {
private:
address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
*** 515,529 ****
bool verify_subtype(address start, address end) const {
return frame_type_addr() + size() <= end;
}
! #ifdef ASSERT
! void print_on(outputStream* st) const {
! st->print("chop_frame(%d,%d)", offset_delta(), chops());
}
- #endif
};
class append_frame : public stack_map_frame {
private:
address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
--- 525,541 ----
bool verify_subtype(address start, address end) const {
return frame_type_addr() + size() <= end;
}
! void print_on(outputStream* st, int current_offset = -1) const {
! st->print("chop_frame(@%d,%d)", offset_delta() + current_offset, chops());
! }
!
! void print_truncated(outputStream* st, int current_offset = -1) const {
! print_on(st, current_offset);
}
};
class append_frame : public stack_map_frame {
private:
address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
*** 616,639 ****
}
}
return false;
}
! #ifdef ASSERT
! void print_on(outputStream* st) const {
! st->print("append_frame(%d,", offset_delta());
verification_type_info* vti = types();
for (int i = 0; i < number_of_types(); ++i) {
vti->print_on(st);
if (i != number_of_types() - 1) {
st->print(",");
}
vti = vti->next();
}
st->print(")");
}
! #endif
};
class full_frame : public stack_map_frame {
private:
address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
--- 628,654 ----
}
}
return false;
}
! void print_on(outputStream* st, int current_offset = -1) const {
! st->print("append_frame(@%d,", offset_delta() + current_offset);
verification_type_info* vti = types();
for (int i = 0; i < number_of_types(); ++i) {
vti->print_on(st);
if (i != number_of_types() - 1) {
st->print(",");
}
vti = vti->next();
}
st->print(")");
}
!
! void print_truncated(outputStream* st, int current_offset = -1) const {
! st->print("append_frame(@%d), output truncated, Stackmap exceeds table size.",
! offset_delta() + current_offset);
! }
};
class full_frame : public stack_map_frame {
private:
address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
*** 772,784 ****
vti = vti->next();
}
return true;
}
! #ifdef ASSERT
! void print_on(outputStream* st) const {
! st->print("full_frame(%d,{", offset_delta());
verification_type_info* vti = locals();
for (int i = 0; i < num_locals(); ++i) {
vti->print_on(st);
if (i != num_locals() - 1) {
st->print(",");
--- 787,798 ----
vti = vti->next();
}
return true;
}
! void print_on(outputStream* st, int current_offset = -1) const {
! st->print("full_frame(@%d,{", offset_delta() + current_offset);
verification_type_info* vti = locals();
for (int i = 0; i < num_locals(); ++i) {
vti->print_on(st);
if (i != num_locals() - 1) {
st->print(",");
*** 796,806 ****
}
vti = vti->next();
}
st->print("})");
}
! #endif
};
#define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
stack_frame_type* item_##stack_frame_type = as_##stack_frame_type(); \
if (item_##stack_frame_type != NULL) { \
--- 810,824 ----
}
vti = vti->next();
}
st->print("})");
}
!
! void print_truncated(outputStream* st, int current_offset = -1) const {
! st->print("full_frame(@%d), output truncated, Stackmap exceeds table size.",
! offset_delta() + current_offset);
! }
};
#define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
stack_frame_type* item_##stack_frame_type = as_##stack_frame_type(); \
if (item_##stack_frame_type != NULL) { \
*** 850,864 ****
VIRTUAL_DISPATCH, verify_subtype, (start, end));
}
return false;
}
! #ifdef ASSERT
! void stack_map_frame::print_on(outputStream* st) const {
! FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st));
}
- #endif
#undef VIRTUAL_DISPATCH
#undef VOID_VIRTUAL_DISPATCH
#define AS_SUBTYPE_DEF(stack_frame_type, arg1, arg2) \
--- 868,884 ----
VIRTUAL_DISPATCH, verify_subtype, (start, end));
}
return false;
}
! void stack_map_frame::print_on(outputStream* st, int offs = -1) const {
! FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st, offs));
! }
!
! void stack_map_frame::print_truncated(outputStream* st, int offs = -1) const {
! FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_truncated, (st, offs));
}
#undef VIRTUAL_DISPATCH
#undef VOID_VIRTUAL_DISPATCH
#define AS_SUBTYPE_DEF(stack_frame_type, arg1, arg2) \
*** 871,890 ****
}
FOR_EACH_STACKMAP_FRAME_TYPE(AS_SUBTYPE_DEF, x, x)
#undef AS_SUBTYPE_DEF
class stack_map_table_attribute {
private:
address name_index_addr() const {
return (address)this; }
address attribute_length_addr() const {
return name_index_addr() + sizeof(u2); }
! address number_of_entries_addr() const {
return attribute_length_addr() + sizeof(u4); }
- address entries_addr() const {
- return number_of_entries_addr() + sizeof(u2); }
protected:
// No constructors - should be 'private', but GCC issues a warning if it is
stack_map_table_attribute() {}
stack_map_table_attribute(const stack_map_table_attribute&) {}
--- 891,940 ----
}
FOR_EACH_STACKMAP_FRAME_TYPE(AS_SUBTYPE_DEF, x, x)
#undef AS_SUBTYPE_DEF
+ class stack_map_table {
+ private:
+ address number_of_entries_addr() const {
+ return (address)this;
+ }
+ address entries_addr() const {
+ return number_of_entries_addr() + sizeof(u2);
+ }
+
+ protected:
+ // No constructors - should be 'private', but GCC issues a warning if it is
+ stack_map_table() {}
+ stack_map_table(const stack_map_table&) {}
+
+ public:
+
+ static stack_map_table* at(address addr) {
+ return (stack_map_table*)addr;
+ }
+
+ u2 number_of_entries() const {
+ return Bytes::get_Java_u2(number_of_entries_addr());
+ }
+ stack_map_frame* entries() const {
+ return stack_map_frame::at(entries_addr());
+ }
+
+ void set_number_of_entries(u2 num) {
+ Bytes::put_Java_u2(number_of_entries_addr(), num);
+ }
+ };
+
class stack_map_table_attribute {
private:
address name_index_addr() const {
return (address)this; }
address attribute_length_addr() const {
return name_index_addr() + sizeof(u2); }
! address stack_map_table_addr() const {
return attribute_length_addr() + sizeof(u4); }
protected:
// No constructors - should be 'private', but GCC issues a warning if it is
stack_map_table_attribute() {}
stack_map_table_attribute(const stack_map_table_attribute&) {}
*** 897,923 ****
u2 name_index() const {
return Bytes::get_Java_u2(name_index_addr()); }
u4 attribute_length() const {
return Bytes::get_Java_u4(attribute_length_addr()); }
! u2 number_of_entries() const {
! return Bytes::get_Java_u2(number_of_entries_addr()); }
! stack_map_frame* entries() const {
! return stack_map_frame::at(entries_addr());
! }
!
! static size_t header_size() {
! return sizeof(u2) + sizeof(u4);
}
void set_name_index(u2 idx) {
Bytes::put_Java_u2(name_index_addr(), idx);
}
void set_attribute_length(u4 len) {
Bytes::put_Java_u4(attribute_length_addr(), len);
}
- void set_number_of_entries(u2 num) {
- Bytes::put_Java_u2(number_of_entries_addr(), num);
- }
};
#endif // SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP
--- 947,966 ----
u2 name_index() const {
return Bytes::get_Java_u2(name_index_addr()); }
u4 attribute_length() const {
return Bytes::get_Java_u4(attribute_length_addr()); }
! stack_map_table* table() const {
! return stack_map_table::at(stack_map_table_addr());
}
void set_name_index(u2 idx) {
Bytes::put_Java_u2(name_index_addr(), idx);
}
void set_attribute_length(u4 len) {
Bytes::put_Java_u4(attribute_length_addr(), len);
}
};
+ #undef FOR_EACH_STACKMAP_FRAME_TYPE
+
#endif // SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP
< prev index next >