comparison src/share/vm/interpreter/bytecodes.cpp @ 413:c7ec737733a6

6756528: Bytecodes::special_length_at reads past end of code buffer Summary: Add end-of-buffer indicator for paths used by the verifier Reviewed-by: acorn, coleenp
author kamg
date Thu, 30 Oct 2008 15:48:59 -0400
parents a61af66fc99e
children ad8c8ca4ab0f
comparison
equal deleted inserted replaced
410:8fb16f199266 413:c7ec737733a6
52 Bytecodes::Code Bytecodes::non_breakpoint_code_at(address bcp, methodOop method) { 52 Bytecodes::Code Bytecodes::non_breakpoint_code_at(address bcp, methodOop method) {
53 if (method == NULL) method = methodOopDesc::method_from_bcp(bcp); 53 if (method == NULL) method = methodOopDesc::method_from_bcp(bcp);
54 return method->orig_bytecode_at(method->bci_from(bcp)); 54 return method->orig_bytecode_at(method->bci_from(bcp));
55 } 55 }
56 56
57 int Bytecodes::special_length_at(address bcp) { 57 int Bytecodes::special_length_at(address bcp, address end) {
58 Code code = code_at(bcp); 58 Code code = code_at(bcp);
59 switch (code) { 59 switch (code) {
60 case _wide: 60 case _wide:
61 if (end != NULL && bcp + 1 >= end) {
62 return -1; // don't read past end of code buffer
63 }
61 return wide_length_for(cast(*(bcp + 1))); 64 return wide_length_for(cast(*(bcp + 1)));
62 case _tableswitch: 65 case _tableswitch:
63 { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize); 66 { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
67 if (end != NULL && aligned_bcp + 3*jintSize >= end) {
68 return -1; // don't read past end of code buffer
69 }
64 jlong lo = (jint)Bytes::get_Java_u4(aligned_bcp + 1*jintSize); 70 jlong lo = (jint)Bytes::get_Java_u4(aligned_bcp + 1*jintSize);
65 jlong hi = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize); 71 jlong hi = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
66 jlong len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize; 72 jlong len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize;
67 // only return len if it can be represented as a positive int; 73 // only return len if it can be represented as a positive int;
68 // return -1 otherwise 74 // return -1 otherwise
71 77
72 case _lookupswitch: // fall through 78 case _lookupswitch: // fall through
73 case _fast_binaryswitch: // fall through 79 case _fast_binaryswitch: // fall through
74 case _fast_linearswitch: 80 case _fast_linearswitch:
75 { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize); 81 { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
82 if (end != NULL && aligned_bcp + 2*jintSize >= end) {
83 return -1; // don't read past end of code buffer
84 }
76 jlong npairs = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize); 85 jlong npairs = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
77 jlong len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize; 86 jlong len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize;
78 // only return len if it can be represented as a positive int; 87 // only return len if it can be represented as a positive int;
79 // return -1 otherwise 88 // return -1 otherwise
80 return (len > 0 && len == (int)len) ? len : -1; 89 return (len > 0 && len == (int)len) ? len : -1;
88 // the RawByteCodeStream, which wants to see the actual bytecode 97 // the RawByteCodeStream, which wants to see the actual bytecode
89 // values (including breakpoint). RawByteCodeStream is used by the 98 // values (including breakpoint). RawByteCodeStream is used by the
90 // verifier when reading in bytecode to verify. Other mechanisms that 99 // verifier when reading in bytecode to verify. Other mechanisms that
91 // run at runtime (such as generateOopMaps) need to iterate over the code 100 // run at runtime (such as generateOopMaps) need to iterate over the code
92 // and don't expect to see breakpoints: they want to see the instruction 101 // and don't expect to see breakpoints: they want to see the instruction
93 // which was replaces so that they can get the correct length and find 102 // which was replaced so that they can get the correct length and find
94 // the next bytecode. 103 // the next bytecode.
95 int Bytecodes::raw_special_length_at(address bcp) { 104 //
105 // 'end' indicates the end of the code buffer, which we should not try to read
106 // past.
107 int Bytecodes::raw_special_length_at(address bcp, address end) {
96 Code code = code_or_bp_at(bcp); 108 Code code = code_or_bp_at(bcp);
97 if (code == _breakpoint) { 109 if (code == _breakpoint) {
98 return 1; 110 return 1;
99 } else { 111 } else {
100 return special_length_at(bcp); 112 return special_length_at(bcp, end);
101 } 113 }
102 } 114 }
103 115
104 116
105 117