| 1 | /* |
| 2 | * Copyright (c) 2002, 2013, 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. Oracle designates this |
| 8 | * particular file as subject to the "Classpath" exception as provided |
| 9 | * by Oracle in the LICENSE file that accompanied this code. |
| 10 | * |
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 14 | * version 2 for more details (a copy is included in the LICENSE file that |
| 15 | * accompanied this code). |
| 16 | * |
| 17 | * You should have received a copy of the GNU General Public License version |
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| 20 | * |
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| 22 | * or visit www.oracle.com if you need additional information or have any |
| 23 | * questions. |
| 24 | */ |
| 25 | |
| 26 | // -*- C++ -*- |
| 27 | // Small program for unpacking specially compressed Java packages. |
| 28 | // John R. Rose |
| 29 | |
| 30 | #include <sys/types.h> |
| 31 | |
| 32 | #include <stdio.h> |
| 33 | #include <string.h> |
| 34 | #include <stdlib.h> |
| 35 | #include <stdarg.h> |
| 36 | |
| 37 | #include "defines.h" |
| 38 | #include "bytes.h" |
| 39 | #include "utils.h" |
| 40 | #include "coding.h" |
| 41 | #include "bands.h" |
| 42 | |
| 43 | #include "constants.h" |
| 44 | #include "unpack.h" |
| 45 | |
| 46 | inline void band::abort(const char* msg) { u->abort(msg); } |
| 47 | inline bool band::aborting() { return u->aborting(); } |
| 48 | |
| 49 | void band::readData(int expectedLength) { |
| 50 | CHECK; |
| 51 | assert(expectedLength >= 0); |
| 52 | assert(vs[0].cmk == cmk_ERROR); |
| 53 | if (expectedLength != 0) { |
| 54 | assert(length == 0); |
| 55 | length = expectedLength; |
| 56 | } |
| 57 | if (length == 0) { |
| 58 | assert((rplimit = cm.vs0.rp = u->rp) != null); |
| 59 | return; |
| 60 | } |
| 61 | assert(length > 0); |
| 62 | |
| 63 | bool is_BYTE1 = (defc->spec == BYTE1_spec); |
| 64 | |
| 65 | if (is_BYTE1) { |
| 66 | // No possibility of coding change. Sizing is exact. |
| 67 | u->ensure_input(length); |
| 68 | } else { |
| 69 | // Make a conservatively generous estimate of band size in bytes. |
| 70 | // Assume B == 5 everywhere. |
| 71 | // Assume awkward pop with all {U} values (2*5 per value) |
| 72 | jlong generous = (jlong) length * (B_MAX*3+1) + C_SLOP; |
| 73 | u->ensure_input(generous); |
| 74 | } |
| 75 | |
| 76 | // Read one value to see what it might be. |
| 77 | int XB = _meta_default; |
| 78 | int cp1 = 0, cp2 = 0; |
| 79 | if (!is_BYTE1) { |
| 80 | // must be a variable-length coding |
| 81 | assert(defc->B() > 1 && defc->L() > 0); |
| 82 | // must have already read from previous band: |
| 83 | assert(bn >= BAND_LIMIT || bn <= 0 |
| 84 | || bn == e_cp_Utf8_big_chars |
| 85 | || endsWith(name, "_lo" ) // preceded by _hi conditional band |
| 86 | || bn == e_file_options // preceded by conditional band |
| 87 | || u->rp == u->all_bands[bn-1].maxRP() |
| 88 | || u->all_bands[bn-1].defc == null); |
| 89 | |
| 90 | value_stream xvs; |
| 91 | coding* valc = defc; |
| 92 | if (valc->D() != 0) { |
| 93 | valc = coding::findBySpec(defc->B(), defc->H(), defc->S()); |
| 94 | assert(!valc->isMalloc); |
| 95 | } |
| 96 | xvs.init(u->rp, u->rplimit, valc); |
| 97 | CHECK; |
| 98 | int X = xvs.getInt(); |
| 99 | if (valc->S() != 0) { |
| 100 | assert(valc->min <= -256); |
| 101 | XB = -1-X; |
| 102 | } else { |
| 103 | int L = valc->L(); |
| 104 | assert(valc->max >= L+255); |
| 105 | XB = X-L; |
| 106 | } |
| 107 | if (0 <= XB && XB < 256) { |
| 108 | // Skip over the escape value. |
| 109 | u->rp = xvs.rp; |
| 110 | cp1 = 1; |
| 111 | } else { |
| 112 | // No, it's still default. |
| 113 | XB = _meta_default; |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | if (XB <= _meta_canon_max) { |
| 118 | byte XB_byte = (byte) XB; |
| 119 | byte* XB_ptr = &XB_byte; |
| 120 | cm.init(u->rp, u->rplimit, XB_ptr, 0, defc, length, null); |
| 121 | CHECK; |
| 122 | } else { |
| 123 | NOT_PRODUCT(byte* meta_rp0 = u->meta_rp); |
| 124 | assert(u->meta_rp != null); |
| 125 | // Scribble the initial byte onto the band. |
| 126 | byte* save_meta_rp = --u->meta_rp; |
| 127 | byte save_meta_xb = (*save_meta_rp); |
| 128 | (*save_meta_rp) = (byte) XB; |
| 129 | cm.init(u->rp, u->rplimit, u->meta_rp, 0, defc, length, null); |
| 130 | (*save_meta_rp) = save_meta_xb; // put it back, just to be tidy |
| 131 | NOT_PRODUCT(cp2 = (int)(u->meta_rp - meta_rp0)); |
| 132 | } |
| 133 | rplimit = u->rp; |
| 134 | |
| 135 | rewind(); |
| 136 | |
| 137 | #ifndef PRODUCT |
| 138 | PRINTCR((3,"readFrom %s at %p [%d values, %d bytes, cp=%d/%d]" , |
| 139 | (name?name:"(band)" ), minRP(), length, size(), cp1, cp2)); |
| 140 | if (u->verbose_bands || u->verbose >= 4) dump(); |
| 141 | |
| 142 | if (ix != null && u->verbose != 0 && length > 0) { |
| 143 | // Check referential integrity early, for easier debugging. |
| 144 | band saved = (*this); // save state |
| 145 | for (int i = 0; i < length; i++) { |
| 146 | int n = vs[0].getInt() - nullOK; |
| 147 | entry *ref = ix->get(n); |
| 148 | assert(ref != null || n == -1); |
| 149 | } |
| 150 | (*this) = saved; |
| 151 | } |
| 152 | #endif |
| 153 | } |
| 154 | |
| 155 | #ifndef PRODUCT |
| 156 | void band::dump() { |
| 157 | band saved = (*this); // save state |
| 158 | const char* b_name = name; |
| 159 | char b_name_buf[100]; |
| 160 | if (b_name == null) { |
| 161 | char* bp = &b_name_buf[0]; |
| 162 | b_name = bp; |
| 163 | sprintf(bp, "#%d/%d" , bn, le_kind); bp += strlen(bp); |
| 164 | if (le_bci != 0) { sprintf(bp, "/bci%d" , le_bci); bp += strlen(bp); } |
| 165 | if (le_back != 0) { sprintf(bp, "/back%d" , le_back); bp += strlen(bp); } |
| 166 | if (le_len != 0) { sprintf(bp, "/len%d" , le_len); bp += strlen(bp); } |
| 167 | } |
| 168 | fprintf(u->errstrm, "band %s[%d]%s" , b_name, length, (length==0?"\n" :" {" )); |
| 169 | if (length > 0) { |
| 170 | for (int i = 0; i < length; i++) { |
| 171 | const char* eol = (length > 10 && i % 10 == 0) ? "\n" : " " ; |
| 172 | fprintf(u->errstrm, "%s%d" , eol, vs[0].getInt()); |
| 173 | } |
| 174 | fprintf(u->errstrm, " }\n" ); |
| 175 | } |
| 176 | (*this) = saved; |
| 177 | } |
| 178 | #endif |
| 179 | |
| 180 | void band::setIndex(cpindex* ix_) { |
| 181 | assert(ix_ == null || ixTag == ix_->ixTag); |
| 182 | ix = ix_; |
| 183 | } |
| 184 | void band::setIndexByTag(byte tag) { |
| 185 | setIndex(u->cp.getIndex(tag)); |
| 186 | } |
| 187 | |
| 188 | entry* band::getRefCommon(cpindex* ix_, bool nullOKwithCaller) { |
| 189 | CHECK_0; |
| 190 | if (ix_ == NULL) { |
| 191 | abort("no index" ); |
| 192 | return NULL; |
| 193 | } |
| 194 | assert(ix_->ixTag == ixTag |
| 195 | || ((ixTag == CONSTANT_All || |
| 196 | ixTag == CONSTANT_LoadableValue || |
| 197 | ixTag == CONSTANT_AnyMember) |
| 198 | || (ixTag == CONSTANT_FieldSpecific && |
| 199 | ix_->ixTag >= CONSTANT_Integer && |
| 200 | ix_->ixTag <= CONSTANT_String)) |
| 201 | ); |
| 202 | int n = vs[0].getInt() - nullOK; |
| 203 | // Note: band-local nullOK means null encodes as 0. |
| 204 | // But nullOKwithCaller means caller is willing to tolerate a null. |
| 205 | entry *ref = ix_->get(n); |
| 206 | if (ref == null && !(nullOKwithCaller && n == -1)) |
| 207 | abort(n == -1 ? "null ref" : "bad ref" ); |
| 208 | return ref; |
| 209 | } |
| 210 | |
| 211 | jlong band::getLong(band& lo_band, bool have_hi) { |
| 212 | band& hi_band = (*this); |
| 213 | assert(lo_band.bn == hi_band.bn + 1); |
| 214 | uint lo = lo_band.getInt(); |
| 215 | if (!have_hi) { |
| 216 | assert(hi_band.length == 0); |
| 217 | return makeLong(0, lo); |
| 218 | } |
| 219 | uint hi = hi_band.getInt(); |
| 220 | return makeLong(hi, lo); |
| 221 | } |
| 222 | |
| 223 | int band::getIntTotal() { |
| 224 | CHECK_0; |
| 225 | if (length == 0) return 0; |
| 226 | if (total_memo > 0) return total_memo-1; |
| 227 | int total = getInt(); |
| 228 | // overflow checks require that none of the addends are <0, |
| 229 | // and that the partial sums never overflow (wrap negative) |
| 230 | if (total < 0) { |
| 231 | abort("overflow detected" ); |
| 232 | return 0; |
| 233 | } |
| 234 | for (int k = length-1; k > 0; k--) { |
| 235 | int prev_total = total; |
| 236 | total += vs[0].getInt(); |
| 237 | if (total < prev_total) { |
| 238 | abort("overflow detected" ); |
| 239 | return 0; |
| 240 | } |
| 241 | } |
| 242 | rewind(); |
| 243 | total_memo = total+1; |
| 244 | return total; |
| 245 | } |
| 246 | |
| 247 | int band::getIntCount(int tag) { |
| 248 | CHECK_0; |
| 249 | if (length == 0) return 0; |
| 250 | if (tag >= HIST0_MIN && tag <= HIST0_MAX) { |
| 251 | if (hist0 == null) { |
| 252 | // Lazily calculate an approximate histogram. |
| 253 | hist0 = U_NEW(int, (HIST0_MAX - HIST0_MIN)+1); |
| 254 | CHECK_0; |
| 255 | for (int k = length; k > 0; k--) { |
| 256 | int x = vs[0].getInt(); |
| 257 | if (x >= HIST0_MIN && x <= HIST0_MAX) |
| 258 | hist0[x - HIST0_MIN] += 1; |
| 259 | } |
| 260 | rewind(); |
| 261 | } |
| 262 | return hist0[tag - HIST0_MIN]; |
| 263 | } |
| 264 | int total = 0; |
| 265 | for (int k = length; k > 0; k--) { |
| 266 | total += (vs[0].getInt() == tag) ? 1 : 0; |
| 267 | } |
| 268 | rewind(); |
| 269 | return total; |
| 270 | } |
| 271 | |
| 272 | #define INDEX_INIT(tag, nullOK, subindex) \ |
| 273 | ((tag) + (subindex)*SUBINDEX_BIT + (nullOK)*256) |
| 274 | |
| 275 | #define INDEX(tag) INDEX_INIT(tag, 0, 0) |
| 276 | #define NULL_OR_INDEX(tag) INDEX_INIT(tag, 1, 0) |
| 277 | #define SUB_INDEX(tag) INDEX_INIT(tag, 0, 1) |
| 278 | #define NO_INDEX 0 |
| 279 | |
| 280 | struct band_init { |
| 281 | int bn; |
| 282 | const char* name; |
| 283 | int defc; |
| 284 | int index; |
| 285 | }; |
| 286 | |
| 287 | #define BAND_INIT(name, cspec, ix) \ |
| 288 | { e_##name, #name, /*debug only*/ \ |
| 289 | cspec, ix } |
| 290 | |
| 291 | const band_init all_band_inits[BAND_LIMIT+1] = { |
| 292 | //BAND_INIT(archive_magic, BYTE1_spec, 0), |
| 293 | //BAND_INIT(archive_header, UNSIGNED5_spec, 0), |
| 294 | //BAND_INIT(band_headers, BYTE1_spec, 0), |
| 295 | BAND_INIT(cp_Utf8_prefix, DELTA5_spec, 0), |
| 296 | BAND_INIT(cp_Utf8_suffix, UNSIGNED5_spec, 0), |
| 297 | BAND_INIT(cp_Utf8_chars, CHAR3_spec, 0), |
| 298 | BAND_INIT(cp_Utf8_big_suffix, DELTA5_spec, 0), |
| 299 | BAND_INIT(cp_Utf8_big_chars, DELTA5_spec, 0), |
| 300 | BAND_INIT(cp_Int, UDELTA5_spec, 0), |
| 301 | BAND_INIT(cp_Float, UDELTA5_spec, 0), |
| 302 | BAND_INIT(cp_Long_hi, UDELTA5_spec, 0), |
| 303 | BAND_INIT(cp_Long_lo, DELTA5_spec, 0), |
| 304 | BAND_INIT(cp_Double_hi, UDELTA5_spec, 0), |
| 305 | BAND_INIT(cp_Double_lo, DELTA5_spec, 0), |
| 306 | BAND_INIT(cp_String, UDELTA5_spec, INDEX(CONSTANT_Utf8)), |
| 307 | BAND_INIT(cp_Class, UDELTA5_spec, INDEX(CONSTANT_Utf8)), |
| 308 | BAND_INIT(cp_Signature_form, DELTA5_spec, INDEX(CONSTANT_Utf8)), |
| 309 | BAND_INIT(cp_Signature_classes, UDELTA5_spec, INDEX(CONSTANT_Class)), |
| 310 | BAND_INIT(cp_Descr_name, DELTA5_spec, INDEX(CONSTANT_Utf8)), |
| 311 | BAND_INIT(cp_Descr_type, UDELTA5_spec, INDEX(CONSTANT_Signature)), |
| 312 | BAND_INIT(cp_Field_class, DELTA5_spec, INDEX(CONSTANT_Class)), |
| 313 | BAND_INIT(cp_Field_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)), |
| 314 | BAND_INIT(cp_Method_class, DELTA5_spec, INDEX(CONSTANT_Class)), |
| 315 | BAND_INIT(cp_Method_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)), |
| 316 | BAND_INIT(cp_Imethod_class, DELTA5_spec, INDEX(CONSTANT_Class)), |
| 317 | BAND_INIT(cp_Imethod_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)), |
| 318 | BAND_INIT(cp_MethodHandle_refkind, DELTA5_spec, 0), |
| 319 | BAND_INIT(cp_MethodHandle_member, UDELTA5_spec, INDEX(CONSTANT_AnyMember)), |
| 320 | BAND_INIT(cp_MethodType, UDELTA5_spec, INDEX(CONSTANT_Signature)), |
| 321 | BAND_INIT(cp_BootstrapMethod_ref, DELTA5_spec, INDEX(CONSTANT_MethodHandle)), |
| 322 | BAND_INIT(cp_BootstrapMethod_arg_count, UDELTA5_spec, 0), |
| 323 | BAND_INIT(cp_BootstrapMethod_arg, DELTA5_spec, INDEX(CONSTANT_LoadableValue)), |
| 324 | BAND_INIT(cp_InvokeDynamic_spec, DELTA5_spec, INDEX(CONSTANT_BootstrapMethod)), |
| 325 | BAND_INIT(cp_InvokeDynamic_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)), |
| 326 | BAND_INIT(attr_definition_headers, BYTE1_spec, 0), |
| 327 | BAND_INIT(attr_definition_name, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)), |
| 328 | BAND_INIT(attr_definition_layout, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)), |
| 329 | BAND_INIT(ic_this_class, UDELTA5_spec, INDEX(CONSTANT_Class)), |
| 330 | BAND_INIT(ic_flags, UNSIGNED5_spec, 0), |
| 331 | BAND_INIT(ic_outer_class, DELTA5_spec, NULL_OR_INDEX(CONSTANT_Class)), |
| 332 | BAND_INIT(ic_name, DELTA5_spec, NULL_OR_INDEX(CONSTANT_Utf8)), |
| 333 | BAND_INIT(class_this, DELTA5_spec, INDEX(CONSTANT_Class)), |
| 334 | BAND_INIT(class_super, DELTA5_spec, INDEX(CONSTANT_Class)), |
| 335 | BAND_INIT(class_interface_count, DELTA5_spec, 0), |
| 336 | BAND_INIT(class_interface, DELTA5_spec, INDEX(CONSTANT_Class)), |
| 337 | BAND_INIT(class_field_count, DELTA5_spec, 0), |
| 338 | BAND_INIT(class_method_count, DELTA5_spec, 0), |
| 339 | BAND_INIT(field_descr, DELTA5_spec, INDEX(CONSTANT_NameandType)), |
| 340 | BAND_INIT(field_flags_hi, UNSIGNED5_spec, 0), |
| 341 | BAND_INIT(field_flags_lo, UNSIGNED5_spec, 0), |
| 342 | BAND_INIT(field_attr_count, UNSIGNED5_spec, 0), |
| 343 | BAND_INIT(field_attr_indexes, UNSIGNED5_spec, 0), |
| 344 | BAND_INIT(field_attr_calls, UNSIGNED5_spec, 0), |
| 345 | BAND_INIT(field_ConstantValue_KQ, UNSIGNED5_spec, INDEX(CONSTANT_FieldSpecific)), |
| 346 | BAND_INIT(field_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)), |
| 347 | BAND_INIT(field_metadata_bands, -1, -1), |
| 348 | BAND_INIT(field_attr_bands, -1, -1), |
| 349 | BAND_INIT(method_descr, MDELTA5_spec, INDEX(CONSTANT_NameandType)), |
| 350 | BAND_INIT(method_flags_hi, UNSIGNED5_spec, 0), |
| 351 | BAND_INIT(method_flags_lo, UNSIGNED5_spec, 0), |
| 352 | BAND_INIT(method_attr_count, UNSIGNED5_spec, 0), |
| 353 | BAND_INIT(method_attr_indexes, UNSIGNED5_spec, 0), |
| 354 | BAND_INIT(method_attr_calls, UNSIGNED5_spec, 0), |
| 355 | BAND_INIT(method_Exceptions_N, UNSIGNED5_spec, 0), |
| 356 | BAND_INIT(method_Exceptions_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)), |
| 357 | BAND_INIT(method_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)), |
| 358 | BAND_INIT(method_metadata_bands, -1, -1), |
| 359 | BAND_INIT(method_MethodParameters_NB, BYTE1_spec, 0), |
| 360 | BAND_INIT(method_MethodParameters_name_RUN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Utf8)), |
| 361 | BAND_INIT(method_MethodParameters_flag_FH, UNSIGNED5_spec, 0), |
| 362 | BAND_INIT(method_attr_bands, -1, -1), |
| 363 | BAND_INIT(class_flags_hi, UNSIGNED5_spec, 0), |
| 364 | BAND_INIT(class_flags_lo, UNSIGNED5_spec, 0), |
| 365 | BAND_INIT(class_attr_count, UNSIGNED5_spec, 0), |
| 366 | BAND_INIT(class_attr_indexes, UNSIGNED5_spec, 0), |
| 367 | BAND_INIT(class_attr_calls, UNSIGNED5_spec, 0), |
| 368 | BAND_INIT(class_SourceFile_RUN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Utf8)), |
| 369 | BAND_INIT(class_EnclosingMethod_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)), |
| 370 | BAND_INIT(class_EnclosingMethod_RDN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_NameandType)), |
| 371 | BAND_INIT(class_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)), |
| 372 | BAND_INIT(class_metadata_bands, -1, -1), |
| 373 | BAND_INIT(class_InnerClasses_N, UNSIGNED5_spec, 0), |
| 374 | BAND_INIT(class_InnerClasses_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)), |
| 375 | BAND_INIT(class_InnerClasses_F, UNSIGNED5_spec, 0), |
| 376 | BAND_INIT(class_InnerClasses_outer_RCN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Class)), |
| 377 | BAND_INIT(class_InnerClasses_name_RUN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Utf8)), |
| 378 | BAND_INIT(class_ClassFile_version_minor_H, UNSIGNED5_spec, 0), |
| 379 | BAND_INIT(class_ClassFile_version_major_H, UNSIGNED5_spec, 0), |
| 380 | BAND_INIT(class_attr_bands, -1, -1), |
| 381 | BAND_INIT(code_headers, BYTE1_spec, 0), |
| 382 | BAND_INIT(code_max_stack, UNSIGNED5_spec, 0), |
| 383 | BAND_INIT(code_max_na_locals, UNSIGNED5_spec, 0), |
| 384 | BAND_INIT(code_handler_count, UNSIGNED5_spec, 0), |
| 385 | BAND_INIT(code_handler_start_P, BCI5_spec, 0), |
| 386 | BAND_INIT(code_handler_end_PO, BRANCH5_spec, 0), |
| 387 | BAND_INIT(code_handler_catch_PO, BRANCH5_spec, 0), |
| 388 | BAND_INIT(code_handler_class_RCN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Class)), |
| 389 | BAND_INIT(code_flags_hi, UNSIGNED5_spec, 0), |
| 390 | BAND_INIT(code_flags_lo, UNSIGNED5_spec, 0), |
| 391 | BAND_INIT(code_attr_count, UNSIGNED5_spec, 0), |
| 392 | BAND_INIT(code_attr_indexes, UNSIGNED5_spec, 0), |
| 393 | BAND_INIT(code_attr_calls, UNSIGNED5_spec, 0), |
| 394 | BAND_INIT(code_StackMapTable_N, UNSIGNED5_spec, 0), |
| 395 | BAND_INIT(code_StackMapTable_frame_T, BYTE1_spec, 0), |
| 396 | BAND_INIT(code_StackMapTable_local_N, UNSIGNED5_spec, 0), |
| 397 | BAND_INIT(code_StackMapTable_stack_N, UNSIGNED5_spec, 0), |
| 398 | BAND_INIT(code_StackMapTable_offset, UNSIGNED5_spec, 0), |
| 399 | BAND_INIT(code_StackMapTable_T, BYTE1_spec, 0), |
| 400 | BAND_INIT(code_StackMapTable_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)), |
| 401 | BAND_INIT(code_StackMapTable_P, BCI5_spec, 0), |
| 402 | BAND_INIT(code_LineNumberTable_N, UNSIGNED5_spec, 0), |
| 403 | BAND_INIT(code_LineNumberTable_bci_P, BCI5_spec, 0), |
| 404 | BAND_INIT(code_LineNumberTable_line, UNSIGNED5_spec, 0), |
| 405 | BAND_INIT(code_LocalVariableTable_N, UNSIGNED5_spec, 0), |
| 406 | BAND_INIT(code_LocalVariableTable_bci_P, BCI5_spec, 0), |
| 407 | BAND_INIT(code_LocalVariableTable_span_O, BRANCH5_spec, 0), |
| 408 | BAND_INIT(code_LocalVariableTable_name_RU, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)), |
| 409 | BAND_INIT(code_LocalVariableTable_type_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)), |
| 410 | BAND_INIT(code_LocalVariableTable_slot, UNSIGNED5_spec, 0), |
| 411 | BAND_INIT(code_LocalVariableTypeTable_N, UNSIGNED5_spec, 0), |
| 412 | BAND_INIT(code_LocalVariableTypeTable_bci_P, BCI5_spec, 0), |
| 413 | BAND_INIT(code_LocalVariableTypeTable_span_O, BRANCH5_spec, 0), |
| 414 | BAND_INIT(code_LocalVariableTypeTable_name_RU, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)), |
| 415 | BAND_INIT(code_LocalVariableTypeTable_type_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)), |
| 416 | BAND_INIT(code_LocalVariableTypeTable_slot, UNSIGNED5_spec, 0), |
| 417 | BAND_INIT(code_attr_bands, -1, -1), |
| 418 | BAND_INIT(bc_codes, BYTE1_spec, 0), |
| 419 | BAND_INIT(bc_case_count, UNSIGNED5_spec, 0), |
| 420 | BAND_INIT(bc_case_value, DELTA5_spec, 0), |
| 421 | BAND_INIT(bc_byte, BYTE1_spec, 0), |
| 422 | BAND_INIT(bc_short, DELTA5_spec, 0), |
| 423 | BAND_INIT(bc_local, UNSIGNED5_spec, 0), |
| 424 | BAND_INIT(bc_label, BRANCH5_spec, 0), |
| 425 | BAND_INIT(bc_intref, DELTA5_spec, INDEX(CONSTANT_Integer)), |
| 426 | BAND_INIT(bc_floatref, DELTA5_spec, INDEX(CONSTANT_Float)), |
| 427 | BAND_INIT(bc_longref, DELTA5_spec, INDEX(CONSTANT_Long)), |
| 428 | BAND_INIT(bc_doubleref, DELTA5_spec, INDEX(CONSTANT_Double)), |
| 429 | BAND_INIT(bc_stringref, DELTA5_spec, INDEX(CONSTANT_String)), |
| 430 | BAND_INIT(bc_loadablevalueref, DELTA5_spec, INDEX(CONSTANT_LoadableValue)), |
| 431 | BAND_INIT(bc_classref, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Class)), |
| 432 | BAND_INIT(bc_fieldref, DELTA5_spec, INDEX(CONSTANT_Fieldref)), |
| 433 | BAND_INIT(bc_methodref, UNSIGNED5_spec, INDEX(CONSTANT_Methodref)), |
| 434 | BAND_INIT(bc_imethodref, DELTA5_spec, INDEX(CONSTANT_InterfaceMethodref)), |
| 435 | BAND_INIT(bc_indyref, DELTA5_spec, INDEX(CONSTANT_InvokeDynamic)), |
| 436 | BAND_INIT(bc_thisfield, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Fieldref)), |
| 437 | BAND_INIT(bc_superfield, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Fieldref)), |
| 438 | BAND_INIT(bc_thismethod, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Methodref)), |
| 439 | BAND_INIT(bc_supermethod, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Methodref)), |
| 440 | BAND_INIT(bc_initref, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Methodref)), |
| 441 | BAND_INIT(bc_escref, UNSIGNED5_spec, INDEX(CONSTANT_All)), |
| 442 | BAND_INIT(bc_escrefsize, UNSIGNED5_spec, 0), |
| 443 | BAND_INIT(bc_escsize, UNSIGNED5_spec, 0), |
| 444 | BAND_INIT(bc_escbyte, BYTE1_spec, 0), |
| 445 | BAND_INIT(file_name, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)), |
| 446 | BAND_INIT(file_size_hi, UNSIGNED5_spec, 0), |
| 447 | BAND_INIT(file_size_lo, UNSIGNED5_spec, 0), |
| 448 | BAND_INIT(file_modtime, DELTA5_spec, 0), |
| 449 | BAND_INIT(file_options, UNSIGNED5_spec, 0), |
| 450 | //BAND_INIT(file_bits, BYTE1_spec, 0), |
| 451 | { 0, NULL, 0, 0 } |
| 452 | }; |
| 453 | |
| 454 | band* band::makeBands(unpacker* u) { |
| 455 | band* tmp_all_bands = U_NEW(band, BAND_LIMIT); |
| 456 | for (int i = 0; i < BAND_LIMIT; i++) { |
| 457 | assert((byte*)&all_band_inits[i+1] |
| 458 | < (byte*)all_band_inits+sizeof(all_band_inits)); |
| 459 | const band_init& bi = all_band_inits[i]; |
| 460 | band& b = tmp_all_bands[i]; |
| 461 | coding* defc = coding::findBySpec(bi.defc); |
| 462 | assert((defc == null) == (bi.defc == -1)); // no garbage, please |
| 463 | assert(defc == null || !defc->isMalloc); |
| 464 | assert(bi.bn == i); // band array consistent w/ band enum |
| 465 | b.init(u, i, defc); |
| 466 | if (bi.index > 0) { |
| 467 | b.nullOK = ((bi.index >> 8) & 1); |
| 468 | b.ixTag = (bi.index & 0xFF); |
| 469 | } |
| 470 | #ifndef PRODUCT |
| 471 | b.name = bi.name; |
| 472 | #endif |
| 473 | } |
| 474 | return tmp_all_bands; |
| 475 | } |
| 476 | |
| 477 | void band::initIndexes(unpacker* u) { |
| 478 | band* tmp_all_bands = u->all_bands; |
| 479 | for (int i = 0; i < BAND_LIMIT; i++) { |
| 480 | band* scan = &tmp_all_bands[i]; |
| 481 | uint tag = scan->ixTag; // Cf. #define INDEX(tag) above |
| 482 | if (tag != 0 && tag != CONSTANT_FieldSpecific && (tag & SUBINDEX_BIT) == 0) { |
| 483 | scan->setIndex(u->cp.getIndex(tag)); |
| 484 | } |
| 485 | } |
| 486 | } |
| 487 | |