Mercurial > hg > truffle
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 |