1 /* 2 * Copyright (c) 1997, 2019, 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_CLASSFILE_CLASSFILESTREAM_HPP 26 #define SHARE_CLASSFILE_CLASSFILESTREAM_HPP 27 28 #include "memory/allocation.hpp" 29 #include "utilities/bytes.hpp" 30 #include "utilities/exceptions.hpp" 31 32 // Input stream for reading .class file 33 // 34 // The entire input stream is present in a buffer allocated by the caller. 35 // The caller is responsible for deallocating the buffer and for using 36 // ResourceMarks appropriately when constructing streams. 37 38 class ClassPathEntry; 39 40 class ClassFileStream: public ResourceObj { 41 private: 42 const u1* const _buffer_start; // Buffer bottom 43 const u1* const _buffer_end; // Buffer top (one past last element) 44 mutable const u1* _current; // Current buffer position 45 const char* const _source; // Source of stream (directory name, ZIP/JAR archive name) 46 bool _need_verify; // True if verification is on for the class file 47 bool _from_boot_loader_modules_image; // True if this was created by ClassPathImageEntry. 48 void truncated_file_error(TRAPS) const ; 49 50 protected: 51 const u1* clone_buffer() const; 52 const char* const clone_source() const; 53 54 public: 55 static const bool verify; 56 57 ClassFileStream(const u1* buffer, 58 int length, 59 const char* source, 60 bool verify_stream = verify, // to be verified by default 61 bool from_boot_loader_modules_image = false); 62 63 virtual const ClassFileStream* clone() const; 64 65 // Buffer access buffer() const66 const u1* buffer() const { return _buffer_start; } length() const67 int length() const { return _buffer_end - _buffer_start; } current() const68 const u1* current() const { return _current; } set_current(const u1 * pos) const69 void set_current(const u1* pos) const { 70 assert(pos >= _buffer_start && pos <= _buffer_end, "invariant"); 71 _current = pos; 72 } 73 74 // for relative positioning current_offset() const75 juint current_offset() const { 76 return (juint)(_current - _buffer_start); 77 } source() const78 const char* source() const { return _source; } need_verify() const79 bool need_verify() const { return _need_verify; } set_verify(bool flag)80 void set_verify(bool flag) { _need_verify = flag; } from_boot_loader_modules_image() const81 bool from_boot_loader_modules_image() const { return _from_boot_loader_modules_image; } 82 check_truncated_file(bool b,TRAPS) const83 void check_truncated_file(bool b, TRAPS) const { 84 if (b) { 85 truncated_file_error(THREAD); 86 } 87 } 88 guarantee_more(int size,TRAPS) const89 void guarantee_more(int size, TRAPS) const { 90 size_t remaining = (size_t)(_buffer_end - _current); 91 unsigned int usize = (unsigned int)size; 92 check_truncated_file(usize > remaining, CHECK); 93 } 94 95 // Read u1 from stream get_u1_fast() const96 u1 get_u1_fast() const { 97 return *_current++; 98 } get_u1(TRAPS) const99 u1 get_u1(TRAPS) const { 100 if (_need_verify) { 101 guarantee_more(1, CHECK_0); 102 } else { 103 assert(1 <= _buffer_end - _current, "buffer overflow"); 104 } 105 return get_u1_fast(); 106 } 107 108 // Read u2 from stream get_u2_fast() const109 u2 get_u2_fast() const { 110 u2 res = Bytes::get_Java_u2((address)_current); 111 _current += 2; 112 return res; 113 } get_u2(TRAPS) const114 u2 get_u2(TRAPS) const { 115 if (_need_verify) { 116 guarantee_more(2, CHECK_0); 117 } else { 118 assert(2 <= _buffer_end - _current, "buffer overflow"); 119 } 120 return get_u2_fast(); 121 } 122 123 // Read u4 from stream get_u4_fast() const124 u4 get_u4_fast() const { 125 u4 res = Bytes::get_Java_u4((address)_current); 126 _current += 4; 127 return res; 128 } 129 130 // Read u8 from stream get_u8_fast() const131 u8 get_u8_fast() const { 132 u8 res = Bytes::get_Java_u8((address)_current); 133 _current += 8; 134 return res; 135 } 136 137 // Skip length elements from stream skip_u1(int length,TRAPS) const138 void skip_u1(int length, TRAPS) const { 139 if (_need_verify) { 140 guarantee_more(length, CHECK); 141 } 142 skip_u1_fast(length); 143 } skip_u1_fast(int length) const144 void skip_u1_fast(int length) const { 145 _current += length; 146 } 147 skip_u2_fast(int length) const148 void skip_u2_fast(int length) const { 149 _current += 2 * length; 150 } 151 skip_u4_fast(int length) const152 void skip_u4_fast(int length) const { 153 _current += 4 * length; 154 } 155 156 // Tells whether eos is reached at_eos() const157 bool at_eos() const { return _current == _buffer_end; } 158 159 uint64_t compute_fingerprint() const; 160 }; 161 162 #endif // SHARE_CLASSFILE_CLASSFILESTREAM_HPP 163