00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #include "arch.h"
00063 ARCH_COPYRIGHT_APACHE(classfile, c, "$URL: https://svn.apache.org/path/name/classfile.c $ $Id: classfile.c 0 09/28/2005 dlydick $");
00064
00065
00066 #include <fcntl.h>
00067 #include <stdlib.h>
00068 #include <string.h>
00069 #include <unistd.h>
00070 #include <sys/stat.h>
00071
00072 #include "jvmcfg.h"
00073 #include "cfmacros.h"
00074 #include "classfile.h"
00075 #include "classpath.h"
00076 #include "exit.h"
00077 #include "jvm.h"
00078 #include "native.h"
00079 #include "util.h"
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 ClassFile *classfile_allocate_primative(jvm_basetype basetype)
00122 {
00123
00124
00125
00126
00127
00128 ClassFile *pcfs = HEAP_GET_DATA(sizeof(ClassFile), rtrue);
00129
00130
00131 pcfs->magic = CLASSFILE_MAGIC;
00132
00133 pcfs->major_version = VERSION_MAJOR_JDK2;
00134 pcfs->minor_version = VERSION_MINOR_DEFAULT;
00135
00136 pcfs->constant_pool_count = 3;
00137 pcfs->constant_pool = HEAP_GET_DATA(pcfs->constant_pool_count *
00138 sizeof(cp_info_dup *), rfalse);
00139
00140
00141
00142
00143
00144
00145 pcfs->constant_pool[0] = (cp_info_dup *) rnull;
00146
00147
00148
00149 pcfs->constant_pool[1] = HEAP_GET_DATA(sizeof(cp_info_dup) +
00150 sizeof(CONSTANT_Utf8_info) -
00151 sizeof(cp_info), rtrue);
00152 CONSTANT_Utf8_info *putf =PTR_THIS_CP_Utf8(pcfs->constant_pool[1]);
00153 putf->tag = CONSTANT_Utf8;
00154 putf->length = sizeof(u1);
00155 putf->bytes[0] = basetype;
00156
00157
00158 pcfs->constant_pool[2] = HEAP_GET_DATA(sizeof(cp_info_dup) +
00159 sizeof(CONSTANT_Class_info) -
00160 sizeof(cp_info), rfalse);
00161 CONSTANT_Class_info *pci =PTR_THIS_CP_Class(pcfs->constant_pool[2]);
00162 pci->tag = CONSTANT_Class;
00163 pci->name_index = 1;
00164
00165
00166 pcfs->access_flags = ACC_SYNTHETIC;
00167 pcfs->this_class = 2;
00168
00169
00170
00171 pcfs->super_class = 0;
00172
00173 pcfs->interfaces_count = 0;
00174 pcfs->interfaces = (u2 *) rnull;
00175
00176 pcfs->fields_count = 0;
00177 pcfs->fields = (field_info **) rnull;
00178
00179 pcfs->methods_count = 0;
00180 pcfs->methods = (method_info **) rnull;
00181
00182 pcfs->attributes_count = 0;
00183 pcfs->attributes = (attribute_info_dup **) rnull;
00184
00185 return(pcfs);
00186
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 #define ALLOC_CP_INFO(spec_typedef, binding_struct) \
00216 misc_adj = sizeof(u1) * CP_INFO_NUM_EMPTIES; \
00217 \
00218 cf_item_size = sizeof(spec_typedef)-sizeof(struct binding_struct); \
00219 pcpd = HEAP_GET_METHOD(misc_adj + sizeof(spec_typedef), rfalse); \
00220 memcpy(((rbyte *) pcpd) + misc_adj,pcpbytes,cf_item_size); \
00221 \
00222 pcpd->empty[0] = FILL_INFO_DUP0; \
00223 pcpd->empty[1] = FILL_INFO_DUP1; \
00224 pcpd->empty[2] = FILL_INFO_DUP2;
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 #define ALLOC_CF_ITEM(spec_typedef, pbytes, pcfsi, binding_struct) \
00252 cf_item_size = sizeof(spec_typedef) - \
00253 sizeof(struct binding_struct) - \
00254 sizeof(attribute_info_dup **); \
00255 pcfsi = HEAP_GET_METHOD(sizeof(spec_typedef), rfalse); \
00256 memcpy(((rbyte *) pcfsi),pbytes,cf_item_size);
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 #define CPTYPEIDX_RANGE_CHECK(type, pcfs, cpidx, msg) \
00290 LOAD_SYSCALL_FAILURE(( \
00291 ((((type *) &pcpd->cp)->cpidx) >= \
00292 pcfs->constant_pool_count)), \
00293 msg, \
00294 rnull, \
00295 rnull);
00296
00297
00298
00299
00300
00301
00302 #define CPIDX_RANGE_CHECK(pcfs, cpidx, msg) \
00303 LOAD_SYSCALL_FAILURE(( \
00304 (cpidx >= pcfs->constant_pool_count)), \
00305 msg, \
00306 rnull, \
00307 rnull);
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 ClassFile *classfile_loadclassdata(u1 *pclassfile_image)
00345 {
00346 rint misc_adj;
00347
00348
00349 u2 tmplenutf;
00350
00351
00352 #ifdef CONFIG_LITTLE_ENDIAN
00353 u2 *pcpu2;
00354 u4 *pcpu4;
00355 #endif
00356
00357
00358 u2 *pu2;
00359 u4 *pu4;
00360
00361
00362
00363
00364
00365 u1 *pcfd = (u1 *) pclassfile_image;
00366
00367
00368
00369
00370
00371 ClassFile *pcfs = (ClassFile *) HEAP_GET_METHOD(sizeof(ClassFile),
00372 rtrue);
00373
00374
00375
00376
00377
00378
00379 pcfs->this_class = jvm_class_index_null;
00380
00381
00382
00383
00384 MAKE_PU4(pu4, pcfd);
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 pcfs->magic = GETRI4(pu4);
00399
00400
00401
00402
00403
00404 MACHINE_JINT_SWAP(pcfs->magic);
00405
00406 sysDbgMsg(DMLNORM,
00407 "classfile_loadclassdata",
00408 "magic=%08x",
00409 pcfs->magic);
00410
00411
00412
00413
00414 LOAD_SYSCALL_FAILURE((CLASSFILE_MAGIC != pcfs->magic),
00415 "magic",
00416 rnull,
00417 rnull);
00418
00419
00420 pu4++;
00421
00422
00423
00424
00425
00426 MAKE_PU2(pu2, pu4);
00427
00428 pcfs->minor_version = GETRS2(pu2);
00429
00430 MACHINE_JSHORT_SWAP(pcfs->minor_version);
00431
00432
00433
00434 sysDbgMsg(DMLNORM,
00435 "classfile_loadclassdata",
00436 "minor=%d",
00437 pcfs->minor_version);
00438
00439 pu2++;
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 pcfs->major_version = GETRS2(pu2++);
00450
00451 MACHINE_JSHORT_SWAP(pcfs->major_version);
00452
00453 sysDbgMsg(DMLNORM,
00454 "classfile_loadclassdata",
00455 "major=%d",
00456 pcfs->major_version);
00457
00458
00459 LOAD_SYSCALL_FAILURE(((pcfs->major_version < VERSION_MAJOR_LOW) ||
00460 (pcfs->major_version > VERSION_MAJOR_HIGH)),
00461 "major",
00462 rnull,
00463 rnull);
00464
00465 LOAD_SYSCALL_FAILURE(((pcfs->major_version == VERSION_MAJOR_LOW)
00466
00467
00468 ),
00469 "low minor",
00470 rnull,
00471 rnull);
00472
00473 LOAD_SYSCALL_FAILURE(((pcfs->major_version == VERSION_MAJOR_HIGH) &&
00474 (pcfs->minor_version > VERSION_MINOR_HIGH)),
00475 "high minor",
00476 rnull,
00477 rnull);
00478
00479
00480
00481
00482
00483
00484
00485 pcfs->constant_pool_count = GETRS2(pu2++);
00486
00487 MACHINE_JSHORT_SWAP(pcfs->constant_pool_count);
00488
00489 sysDbgMsg(DMLNORM,
00490 "classfile_loadclassdata",
00491 "cp count=%d",
00492 pcfs->constant_pool_count);
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 jvm_constant_pool_index cpidx;
00503 rint cf_item_size;
00504 jbyte *pcpbytes = (jbyte *) pu2;
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 pcfs->constant_pool = HEAP_GET_METHOD(pcfs->constant_pool_count *
00519 sizeof(cp_info_dup *),
00520 rfalse);
00521
00522
00523
00524
00525
00526 pcfs->constant_pool[CONSTANT_CP_DEFAULT_INDEX] =
00527 (cp_info_dup *) rnull;
00528
00529
00530
00531
00532
00533 for (cpidx = CONSTANT_CP_START_INDEX;
00534 cpidx < pcfs->constant_pool_count + CONSTANT_CP_START_INDEX -1;
00535 cpidx++)
00536 {
00537 cp_info_dup *pcpd;
00538
00539 pu2 = (u2 *) pcpbytes;
00540
00541
00542
00543
00544
00545 switch (((cp_info *) pcpbytes)->tag)
00546 {
00547 case CONSTANT_Class:
00548 ALLOC_CP_INFO(CONSTANT_Class_info,
00549 LOCAL_Class_binding);
00550
00551 CP_ITEM_SWAP_U2(CONSTANT_Class_info, name_index);
00552
00553 CPTYPEIDX_RANGE_CHECK(CONSTANT_Class_info,
00554 pcfs,
00555 name_index,
00556 "CP name index");
00557
00558
00559 PTR_THIS_CP_Class(pcpd)->LOCAL_Class_binding.clsidxJVM =
00560 jvm_class_index_null;
00561
00562 break;
00563
00564 case CONSTANT_Fieldref:
00565 ALLOC_CP_INFO(CONSTANT_Fieldref_info,
00566 LOCAL_Fieldref_binding);
00567
00568 CP_ITEM_SWAP_U2(CONSTANT_Fieldref_info,class_index);
00569
00570 CP_ITEM_SWAP_U2(CONSTANT_Fieldref_info,
00571 name_and_type_index);
00572
00573 CPTYPEIDX_RANGE_CHECK(CONSTANT_Fieldref_info,
00574 pcfs,
00575 class_index,
00576 "CP class index");
00577
00578
00579 PTR_THIS_CP_Fieldref(pcpd)
00580 ->LOCAL_Fieldref_binding.clsidxJVM =
00581 jvm_class_index_null;
00582
00583 PTR_THIS_CP_Fieldref(pcpd)
00584 ->LOCAL_Fieldref_binding.fluidxJVM =
00585 jvm_field_index_bad;
00586
00587 PTR_THIS_CP_Fieldref(pcpd)
00588 ->LOCAL_Fieldref_binding.oiflagJVM =
00589 rneither_true_nor_false;
00590
00591 PTR_THIS_CP_Fieldref(pcpd)
00592 ->LOCAL_Fieldref_binding.jvaluetypeJVM =
00593 LOCAL_BASETYPE_ERROR;
00594
00595 break;
00596
00597 case CONSTANT_Methodref:
00598 ALLOC_CP_INFO(CONSTANT_Methodref_info,
00599 LOCAL_Methodref_binding);
00600
00601 CP_ITEM_SWAP_U2(CONSTANT_Methodref_info, class_index);
00602
00603 CP_ITEM_SWAP_U2(CONSTANT_Methodref_info,
00604 name_and_type_index);
00605
00606 CPTYPEIDX_RANGE_CHECK(CONSTANT_Methodref_info,
00607 pcfs,
00608 class_index,
00609 "CP method class index");
00610
00611 CPTYPEIDX_RANGE_CHECK(CONSTANT_Methodref_info,
00612 pcfs,
00613 name_and_type_index,
00614 "CP method name and type index");
00615
00616
00617 PTR_THIS_CP_Methodref(pcpd)
00618 ->LOCAL_Methodref_binding.clsidxJVM =
00619 jvm_class_index_null;
00620
00621 PTR_THIS_CP_Methodref(pcpd)
00622 ->LOCAL_Methodref_binding.mthidxJVM =
00623 jvm_method_index_bad;
00624
00625 PTR_THIS_CP_Methodref(pcpd)
00626 ->LOCAL_Methodref_binding.codeatridxJVM =
00627 jvm_attribute_index_bad;
00628
00629 PTR_THIS_CP_Methodref(pcpd)
00630 ->LOCAL_Methodref_binding.excpatridxJVM =
00631 jvm_attribute_index_bad;
00632
00633 PTR_THIS_CP_Methodref(pcpd)
00634 ->LOCAL_Methodref_binding.nmordJVM =
00635 jvm_native_method_ordinal_null;
00636
00637 break;
00638
00639 case CONSTANT_InterfaceMethodref:
00640 ALLOC_CP_INFO(CONSTANT_InterfaceMethodref_info,
00641 LOCAL_InterfaceMethodref_binding);
00642
00643 CP_ITEM_SWAP_U2(CONSTANT_InterfaceMethodref_info,
00644 class_index);
00645
00646 CP_ITEM_SWAP_U2(CONSTANT_InterfaceMethodref_info,
00647 name_and_type_index);
00648
00649 CPTYPEIDX_RANGE_CHECK(CONSTANT_InterfaceMethodref_info,
00650 pcfs,
00651 class_index,
00652 "CP interface method class index");
00653
00654 CPTYPEIDX_RANGE_CHECK(CONSTANT_InterfaceMethodref_info,
00655 pcfs,
00656 name_and_type_index,
00657 "CP interface method name and type index");
00658
00659
00660 PTR_THIS_CP_InterfaceMethodref(pcpd)
00661 ->LOCAL_InterfaceMethodref_binding.clsidxJVM =
00662 jvm_class_index_null;
00663
00664 PTR_THIS_CP_InterfaceMethodref(pcpd)
00665 ->LOCAL_InterfaceMethodref_binding.mthidxJVM =
00666 jvm_method_index_bad;
00667
00668 PTR_THIS_CP_InterfaceMethodref(pcpd)
00669 ->LOCAL_InterfaceMethodref_binding.codeatridxJVM =
00670 jvm_attribute_index_bad;
00671
00672 PTR_THIS_CP_InterfaceMethodref(pcpd)
00673 ->LOCAL_InterfaceMethodref_binding.excpatridxJVM =
00674 jvm_attribute_index_bad;
00675
00676 PTR_THIS_CP_InterfaceMethodref(pcpd)
00677 ->LOCAL_InterfaceMethodref_binding.nmordJVM =
00678 jvm_native_method_ordinal_null;
00679
00680 break;
00681
00682 case CONSTANT_String:
00683 ALLOC_CP_INFO(CONSTANT_String_info,
00684 LOCAL_String_binding);
00685
00686 CP_ITEM_SWAP_U2(CONSTANT_String_info, string_index);
00687
00688 CPTYPEIDX_RANGE_CHECK(CONSTANT_String_info,
00689 pcfs,
00690 string_index,
00691 "CP string index");
00692 break;
00693
00694 case CONSTANT_Integer:
00695 ALLOC_CP_INFO(CONSTANT_Integer_info,
00696 LOCAL_Integer_binding);
00697
00698 CP_ITEM_SWAP_U4(CONSTANT_Integer_info, bytes);
00699
00700 break;
00701
00702 case CONSTANT_Float:
00703 ALLOC_CP_INFO(CONSTANT_Float_info,
00704 LOCAL_Float_binding);
00705
00706 CP_ITEM_SWAP_U4(CONSTANT_Float_info, bytes);
00707
00708 break;
00709
00710 case CONSTANT_Long:
00711 ALLOC_CP_INFO(CONSTANT_Long_info,
00712 LOCAL_Long_binding);
00713
00714 CP_ITEM_SWAP_U4(CONSTANT_Long_info, high_bytes);
00715
00716 CP_ITEM_SWAP_U4(CONSTANT_Long_info, low_bytes);
00717
00718
00719
00720
00721
00722
00723
00724
00725 pcfs->constant_pool[cpidx] = pcpd;
00726 cpidx++;
00727
00728 break;
00729
00730 case CONSTANT_Double:
00731 ALLOC_CP_INFO(CONSTANT_Double_info,
00732 LOCAL_Double_binding);
00733
00734 CP_ITEM_SWAP_U4(CONSTANT_Double_info, high_bytes);
00735
00736 CP_ITEM_SWAP_U4(CONSTANT_Double_info, low_bytes);
00737
00738
00739
00740
00741
00742
00743
00744
00745 pcfs->constant_pool[cpidx] = pcpd;
00746 cpidx++;
00747
00748 break;
00749
00750 case CONSTANT_NameAndType:
00751 ALLOC_CP_INFO(CONSTANT_NameAndType_info,
00752 LOCAL_NameAndType_binding);
00753 CP_ITEM_SWAP_U2(CONSTANT_NameAndType_info, name_index);
00754 CP_ITEM_SWAP_U2(CONSTANT_NameAndType_info,
00755 descriptor_index);
00756 CPTYPEIDX_RANGE_CHECK(CONSTANT_NameAndType_info,
00757 pcfs,
00758 name_index,
00759 "CP name and type name index");
00760 CPTYPEIDX_RANGE_CHECK(CONSTANT_NameAndType_info,
00761 pcfs,
00762 descriptor_index,
00763 "CP name and type descriptor index");
00764
00765
00766
00767
00768 break;
00769
00770 case CONSTANT_Utf8:
00771
00772 tmplenutf = ((CONSTANT_Utf8_info *) pcpbytes)->length;
00773 MACHINE_JSHORT_SWAP(tmplenutf);
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 cf_item_size = sizeof(CONSTANT_Utf8_info) -
00788 sizeof(struct LOCAL_Utf8_binding) -
00789 sizeof(u1);
00790
00791
00792 pcpd = HEAP_GET_METHOD(sizeof(u1) * CP_INFO_NUM_EMPTIES+
00793 tmplenutf + cf_item_size,
00794 rfalse);
00795
00796
00797 memcpy(((rbyte *)pcpd) +
00798 sizeof(u1) * CP_INFO_NUM_EMPTIES,
00799 pcpbytes,
00800 cf_item_size);
00801 pcpd->empty[0] = FILL_INFO_DUP0;
00802 pcpd->empty[1] = FILL_INFO_DUP1;
00803 pcpd->empty[2] = FILL_INFO_DUP2;
00804
00805
00806
00807
00808
00809
00810 CP_ITEM_SWAP_U2(CONSTANT_Utf8_info, length);
00811
00812
00813 memcpy(PTR_THIS_CP_Utf8(pcpd)->bytes,
00814 ((CONSTANT_Utf8_info *) pcpbytes)->bytes,
00815 tmplenutf);
00816
00817
00818
00819
00820 cf_item_size += tmplenutf;
00821
00822
00823
00824
00825
00826 break;
00827
00828 default:
00829
00830
00831
00832
00833
00834 HEAP_FREE_METHOD(pcfs);
00835
00836 GENERIC_FAILURE1_PTR(rtrue,
00837 DMLNORM,
00838 "classfile_loadclassdata",
00839 "Invalid CP tag %d",
00840 (((cp_info *) pcpbytes)->tag),
00841 ClassFile,
00842 rnull,
00843 rnull);
00844
00845 }
00846
00847
00848 pcfs->constant_pool[cpidx] = pcpd;
00849
00850
00851 pcpbytes += cf_item_size;
00852
00853 }
00854
00855
00856
00857
00858
00859
00860
00861 MAKE_PU2(pu2, pcpbytes);
00862
00863 pcfs->access_flags = GETRS2(pu2++);
00864
00865
00866
00867
00868 pcfs->access_flags &= (ACC_PUBLIC | ACC_FINAL | ACC_SUPER |
00869 ACC_INTERFACE | ACC_ABSTRACT | ACC_SYNTHETIC | ACC_ANNOTATION |
00870 ACC_ENUM);
00871
00872 MACHINE_JSHORT_SWAP(pcfs->access_flags);
00873
00874
00875
00876 sysDbgMsg(DMLNORM,
00877 "classfile_loadclassdata",
00878 "access %04x",
00879 pcfs->access_flags);
00880
00881
00882
00883
00884
00885 pcfs->this_class = GETRS2(pu2++);
00886
00887 MACHINE_JSHORT_SWAP(pcfs->this_class);
00888
00889
00890
00891
00892 CPIDX_RANGE_CHECK(pcfs, pcfs->this_class, "this class");
00893
00894 cfmsgs_typemsg("this", pcfs, pcfs->this_class);
00895
00896 cfmsgs_show_constant_pool(pcfs);
00897
00898
00899
00900
00901
00902 pcfs->super_class = GETRS2(pu2++);
00903
00904 MACHINE_JSHORT_SWAP(pcfs->super_class);
00905
00906
00907
00908 cfmsgs_typemsg("super", pcfs, pcfs->super_class);
00909
00910
00911
00912
00913 pcfs->interfaces_count = GETRS2(pu2++);
00914
00915 MACHINE_JSHORT_SWAP(pcfs->interfaces_count);
00916
00917 sysDbgMsg(DMLNORM,
00918 "classfile_loadclassdata",
00919 "intfc count=%d",
00920 pcfs->interfaces_count);
00921
00922
00923
00924
00925
00926 if (0 == pcfs->interfaces_count)
00927 {
00928
00929 pcfs->interfaces = (u2 *) rnull;
00930 }
00931 else
00932 {
00933
00934
00935
00936
00937 pcfs->interfaces = HEAP_GET_METHOD(pcfs->interfaces_count *
00938 sizeof(u2 *),
00939 rfalse);
00940
00941
00942
00943
00944
00945 jvm_interface_index ifidx;
00946 for (ifidx = 0; ifidx < pcfs->interfaces_count; ifidx++)
00947 {
00948
00949 jvm_interface_index cfifidx = GETRS2(pu2++);
00950
00951
00952 CPIDX_RANGE_CHECK(pcfs,
00953 cfifidx,
00954 "interface index");
00955
00956
00957
00958
00959
00960
00961 if (CONSTANT_Class != CP_TAG(pcfs, cfifidx))
00962 {
00963 HEAP_FREE_METHOD(pcfs->interfaces);
00964
00965
00966
00967 HEAP_FREE_METHOD(pcfs);
00968 }
00969
00970 GENERIC_FAILURE1_PTR((CONSTANT_Class !=
00971 CP_TAG(pcfs,cfifidx)),
00972 DMLNORM,
00973 "classfile_loadclassdata",
00974 "Invalid interface tag %d",
00975 CP_TAG(pcfs, cfifidx),
00976 ClassFile,
00977 rnull,
00978 rnull);
00979
00980
00981 pcfs->interfaces[ifidx] = cfifidx;
00982
00983 cfmsgs_typemsg("intfc", pcfs, cfifidx);
00984
00985 }
00986
00987
00988
00989
00990
00991
00992
00993
00994 }
00995
00996
00997
00998
00999
01000 pcfs->fields_count = GETRS2(pu2++);
01001
01002 MACHINE_JSHORT_SWAP(pcfs->fields_count);
01003
01004
01005
01006 sysDbgMsg(DMLNORM,
01007 "classfile_loadclassdata",
01008 "flds count=%d",
01009 pcfs->fields_count);
01010
01011
01012
01013
01014
01015 jbyte *pfbytes = (jbyte *) pu2;
01016
01017 if (0 == pcfs->fields_count)
01018 {
01019
01020 pcfs->fields = (field_info **) rnull;
01021 }
01022 else
01023 {
01024 jvm_field_index fldidx;
01025
01026
01027
01028
01029
01030 pcfs->fields = HEAP_GET_METHOD(pcfs->fields_count *
01031 sizeof(field_info *),
01032 rtrue);
01033
01034
01035
01036
01037
01038
01039 for (fldidx = 0; fldidx < pcfs->fields_count; fldidx++)
01040 {
01041
01042 ALLOC_CF_ITEM(field_info,
01043 pfbytes,
01044 pcfs->fields[fldidx],
01045 LOCAL_field_binding);
01046
01047 MACHINE_JSHORT_SWAP(pcfs->fields[fldidx]->access_flags);
01048 MACHINE_JSHORT_SWAP(pcfs->fields[fldidx]->name_index);
01049 MACHINE_JSHORT_SWAP(pcfs->fields[fldidx]->descriptor_index);
01050 MACHINE_JSHORT_SWAP(pcfs->fields[fldidx]->attributes_count);
01051
01052
01053 pcfs->fields[fldidx]->access_flags &=
01054 (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED |
01055 ACC_STATIC | ACC_FINAL | ACC_VOLATILE | ACC_TRANSIENT |
01056 ACC_SYNTHETIC | ACC_ENUM);
01057
01058
01059 CPIDX_RANGE_CHECK(pcfs,
01060 pcfs->fields[fldidx]->name_index,
01061 "field name index");
01062 CPIDX_RANGE_CHECK(pcfs,
01063 pcfs->fields[fldidx]->descriptor_index,
01064 "field descriptor index");
01065
01066 cfmsgs_typemsg("fld name",
01067 pcfs,
01068 pcfs->fields[fldidx]->name_index);
01069 cfmsgs_typemsg("fld desc",
01070 pcfs,
01071 pcfs->fields[fldidx]->descriptor_index);
01072
01073
01074 pfbytes = (jbyte *) &((method_info *) pfbytes)->attributes;
01075
01076
01077
01078
01079
01080
01081 if (0 == pcfs->fields[fldidx]->attributes_count)
01082 {
01083
01084 pcfs->fields[fldidx]->attributes =
01085 (attribute_info_dup **) rnull;
01086 }
01087 else
01088 {
01089 pcfs->fields[fldidx]->attributes =
01090 HEAP_GET_METHOD(
01091 pcfs->fields[fldidx]->attributes_count *
01092 sizeof(attribute_info *),
01093 rtrue);
01094
01095
01096
01097
01098 jvm_attribute_index atridx;
01099 for (atridx = 0;
01100 atridx < pcfs->fields[fldidx]->attributes_count;
01101 atridx++)
01102 {
01103
01104
01105
01106
01107
01108
01109 pfbytes =
01110 cfattrib_loadattribute(
01111 pcfs,
01112 &pcfs->fields[fldidx]->attributes[atridx],
01113 (attribute_info *) pfbytes);
01114
01115 LOAD_SYSCALL_FAILURE((rnull == pfbytes),
01116 "load field attribute",
01117 rnull,
01118 rnull);
01119
01120 }
01121
01122 }
01123
01124
01125 pcfs->fields[fldidx]->LOCAL_field_binding.fluidxJVM =
01126 jvm_field_index_bad;
01127
01128 }
01129
01130 }
01131
01132
01133
01134
01135
01136
01137
01138 MAKE_PU2(pu2, pfbytes);
01139
01140
01141 MACHINE_JSHORT_SWAP(pu2);
01142 pcfs->methods_count = GETRS2(pu2++);
01143
01144 sysDbgMsg(DMLNORM,
01145 "classfile_loadclassdata",
01146 "meth count=%d",
01147 pcfs->methods_count);
01148
01149
01150
01151
01152 jbyte *pmbytes = (jbyte *) pu2;
01153
01154 if (0 == pcfs->methods_count)
01155 {
01156
01157 pcfs->methods = (method_info **) rnull;
01158 }
01159 else
01160 {
01161 jvm_method_index mthidx;
01162
01163
01164
01165
01166
01167 pcfs->methods = HEAP_GET_METHOD(pcfs->methods_count *
01168 sizeof(method_info *),
01169 rtrue);
01170
01171
01172
01173
01174
01175 for (mthidx = 0; mthidx < pcfs->methods_count; mthidx++)
01176 {
01177
01178 ALLOC_CF_ITEM(method_info,
01179 pmbytes,
01180 pcfs->methods[mthidx],
01181 LOCAL_method_binding);
01182
01183 MACHINE_JSHORT_SWAP(pcfs->methods[mthidx]->access_flags);
01184 MACHINE_JSHORT_SWAP(pcfs->methods[mthidx]->name_index);
01185 MACHINE_JSHORT_SWAP(pcfs->methods[mthidx]->descriptor_index);
01186 MACHINE_JSHORT_SWAP(pcfs->methods[mthidx]->attributes_count);
01187
01188
01189 pcfs->methods[mthidx]->access_flags &=
01190 (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED |
01191 ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
01192 ACC_BRIDGE | ACC_VARARGS | ACC_NATIVE| ACC_ABSTRACT |
01193 ACC_STRICT | ACC_SYNTHETIC);
01194
01195
01196 CPIDX_RANGE_CHECK(pcfs,
01197 pcfs->methods[mthidx]->name_index,
01198 "method name index");
01199 CPIDX_RANGE_CHECK(pcfs,
01200 pcfs->methods[mthidx]->descriptor_index,
01201 "method descriptor index");
01202
01203 cfmsgs_typemsg("meth name",
01204 pcfs,
01205 pcfs->methods[mthidx]->name_index);
01206 cfmsgs_typemsg("meth desc",
01207 pcfs,
01208 pcfs->methods[mthidx]->descriptor_index);
01209
01210
01211
01212 pmbytes = (jbyte *) &((method_info *) pmbytes)->attributes;
01213
01214
01215
01216
01217
01218
01219
01220 pcfs->methods[mthidx]
01221 ->LOCAL_method_binding.codeatridxJVM =
01222 jvm_attribute_index_bad;
01223
01224 pcfs->methods[mthidx]
01225 ->LOCAL_method_binding.excpatridxJVM =
01226 jvm_attribute_index_bad;
01227
01228 pcfs->methods[mthidx]
01229 ->LOCAL_method_binding.nmordJVM =
01230 jvm_native_method_ordinal_null;
01231
01232
01233
01234
01235
01236
01237 if (0 == pcfs->methods[mthidx]->attributes_count)
01238 {
01239
01240 pcfs->methods[mthidx]->attributes =
01241 (attribute_info_dup **) rnull;
01242 }
01243 else
01244 {
01245
01246
01247
01248 pcfs->methods[mthidx]->attributes =
01249 HEAP_GET_METHOD(
01250 pcfs->methods[mthidx]->attributes_count *
01251 sizeof(attribute_info_dup *),
01252 rtrue);
01253
01254
01255
01256
01257 jvm_attribute_index atridx;
01258 for (atridx = 0;
01259 atridx < pcfs->methods[mthidx]->attributes_count;
01260 atridx++)
01261 {
01262
01263
01264
01265
01266
01267
01268 pmbytes =
01269 cfattrib_loadattribute(
01270 pcfs,
01271 &pcfs->methods[mthidx]->attributes[atridx],
01272 (attribute_info *) pmbytes);
01273
01274 LOAD_SYSCALL_FAILURE((rnull == pmbytes),
01275 "verify member attribute",
01276 rnull,
01277 rnull);
01278
01279
01280
01281
01282
01283 switch (cfattrib_atr2enum(pcfs,
01284 pcfs->methods[mthidx]->attributes[atridx]
01285 ->ai.attribute_name_index))
01286 {
01287 case LOCAL_CODE_ATTRIBUTE:
01288 pcfs
01289 ->methods[mthidx]
01290 ->LOCAL_method_binding.codeatridxJVM =
01291 atridx;
01292 break;
01293
01294 case LOCAL_EXCEPTIONS_ATTRIBUTE:
01295
01296 pcfs
01297 ->methods[mthidx]
01298 ->LOCAL_method_binding.excpatridxJVM =
01299 atridx;
01300 break;
01301
01302
01303 case LOCAL_UNKNOWN_ATTRIBUTE:
01304 case LOCAL_CONSTANTVALUE_ATTRIBUTE:
01305 case LOCAL_INNERCLASSES_ATTRIBUTE:
01306 case LOCAL_ENCLOSINGMETHOD_ATTRIBUTE:
01307 case LOCAL_SYNTHETIC_ATTRIBUTE:
01308 case LOCAL_SIGNATURE_ATTRIBUTE:
01309 case LOCAL_SOURCEFILE_ATTRIBUTE:
01310 case LOCAL_LINENUMBERTABLE_ATTRIBUTE:
01311 case LOCAL_LOCALVARIABLETABLE_ATTRIBUTE:
01312 case LOCAL_LOCALVARIABLETYPETABLE_ATTRIBUTE:
01313 case LOCAL_DEPRECATED_ATTRIBUTE:
01314 case LOCAL_RUNTIMEVISIBLEANNOTATIONS_ATTRIBUTE:
01315 case
01316 LOCAL_RUNTIMEINVISIBLEANNOTATIONS_ATTRIBUTE:
01317 case
01318 LOCAL_RUNTIMEVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE:
01319 case
01320 LOCAL_RUNTIMEINVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE:
01321 case LOCAL_ANNOTATIONDEFAULT_ATTRIBUTE:
01322 break;
01323 }
01324
01325 }
01326
01327 }
01328
01329 }
01330
01331 }
01332
01333
01334
01335
01336
01337
01338 MAKE_PU2(pu2, pmbytes);
01339
01340
01341 MACHINE_JSHORT_SWAP(pu2);
01342 pcfs->attributes_count = GETRS2(pu2++);
01343
01344 sysDbgMsg(DMLNORM,
01345 "classfile_loadclassdata",
01346 "att cnt=%d",
01347 pcfs->attributes_count);
01348
01349
01350
01351
01352
01353 if (0 == pcfs->attributes_count)
01354 {
01355
01356 pcfs->attributes = (attribute_info_dup **) rnull;
01357 }
01358 else
01359 {
01360
01361
01362
01363
01364 pcfs->attributes = HEAP_GET_METHOD(pcfs->attributes_count *
01365 sizeof(attribute_info *),
01366 rtrue);
01367
01368
01369
01370
01371 jvm_attribute_index atridx;
01372 jbyte *pcbytes = (jbyte *) pu2;
01373
01374 for (atridx = 0; atridx < pcfs->attributes_count; atridx++)
01375 {
01376
01377
01378
01379
01380
01381
01382 pcbytes =
01383 cfattrib_loadattribute(
01384 pcfs,
01385 &pcfs->attributes[atridx],
01386 (attribute_info *) pcbytes);
01387
01388 LOAD_SYSCALL_FAILURE((rnull == pcbytes),
01389 "verify file attribute",
01390 rnull,
01391 rnull);
01392
01393 }
01394
01395 }
01396
01397
01398
01399
01400
01401
01402 return(pcfs);
01403
01404 }
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418 rvoid classfile_unloadclassdata(ClassFile *pcfs)
01419 {
01420 if (rnull == pcfs)
01421 {
01422 return;
01423 }
01424
01425 jvm_constant_pool_index cpidx;
01426 jvm_field_index fldidx;
01427 jvm_method_index mthidx;
01428 jvm_attribute_index atridx;
01429
01430
01431
01432
01433
01434
01435
01436
01437 if ((0 < pcfs->attributes_count) && (rnull != pcfs->attributes))
01438 {
01439 for (atridx = pcfs->attributes_count - 1;
01440 atridx != JVMCFG_BAD_ATTRIBUTE;
01441 atridx--)
01442 {
01443
01444
01445
01446
01447 if (rnull == pcfs->attributes[atridx])
01448 {
01449 continue;
01450 }
01451
01452 cfattrib_unloadattribute(pcfs, pcfs->attributes[atridx]);
01453 }
01454 }
01455
01456
01457 if ((0 < pcfs->methods_count) && (rnull != pcfs->methods))
01458 {
01459 for (mthidx = pcfs->methods_count - 1;
01460 mthidx != JVMCFG_BAD_METHOD;
01461 mthidx--)
01462 {
01463
01464
01465
01466
01467 if (rnull == pcfs->methods[mthidx])
01468 {
01469 continue;
01470 }
01471
01472 if (0 < pcfs->methods[mthidx]->attributes_count)
01473 {
01474 for (atridx = pcfs->methods[mthidx]->attributes_count-1;
01475
01476 atridx != JVMCFG_BAD_ATTRIBUTE;
01477 atridx--)
01478 {
01479
01480
01481
01482
01483 if (rnull ==
01484 pcfs->methods[mthidx]->attributes[atridx])
01485 {
01486 continue;
01487 }
01488
01489 cfattrib_unloadattribute(pcfs,
01490 pcfs->methods[mthidx]->attributes[atridx]);
01491 }
01492 }
01493
01494 HEAP_FREE_METHOD(pcfs->methods[mthidx]->attributes);
01495 HEAP_FREE_METHOD(pcfs->methods[mthidx]);
01496 }
01497 }
01498
01499
01500 if ((0 < pcfs->fields_count) && (rnull != pcfs->fields))
01501 {
01502 for (fldidx = pcfs->fields_count - 1;
01503 fldidx != JVMCFG_BAD_FIELD;
01504 fldidx--)
01505 {
01506
01507
01508
01509
01510 if (rnull == pcfs->fields[fldidx])
01511 {
01512 continue;
01513 }
01514
01515 if (0 < pcfs->fields[fldidx]->attributes_count)
01516 {
01517 for (atridx = pcfs->fields[fldidx]->attributes_count -1;
01518
01519 atridx != JVMCFG_BAD_ATTRIBUTE;
01520 atridx--)
01521 {
01522
01523
01524
01525
01526 if (rnull ==
01527 pcfs->fields[fldidx]->attributes[atridx])
01528 {
01529 continue;
01530 }
01531
01532 cfattrib_unloadattribute(pcfs,
01533 pcfs->fields[fldidx]->attributes[atridx]);
01534 }
01535 }
01536
01537 HEAP_FREE_METHOD(pcfs->fields[fldidx]->attributes);
01538 HEAP_FREE_METHOD(pcfs->fields[fldidx]);
01539 }
01540 }
01541
01542
01543 if ((0 < pcfs->constant_pool_count)&&(rnull != pcfs->constant_pool))
01544 {
01545 for (cpidx = pcfs->constant_pool_count - 1;
01546 cpidx > CONSTANT_CP_DEFAULT_INDEX;
01547 cpidx--)
01548 {
01549
01550
01551
01552
01553 if (rnull == pcfs->constant_pool[cpidx])
01554 {
01555 continue;
01556 }
01557
01558 HEAP_FREE_METHOD(pcfs->constant_pool[cpidx]);
01559 }
01560 }
01561
01562 HEAP_FREE_METHOD(pcfs->constant_pool);
01563 HEAP_FREE_METHOD(pcfs);
01564
01565 return;
01566
01567 }
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590 #define READ_SYSCALL_FAILURE(expr, msg) \
01591 GENERIC_FAILURE_PTR((expr), \
01592 DMLMIN, \
01593 "classfile_readclassfile", \
01594 msg, \
01595 rvoid, \
01596 rnull, \
01597 rnull)
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624 u1 *classfile_readclassfile(rchar *filename)
01625 {
01626 off_t filesize = 0;
01627
01628 struct stat statbfr;
01629
01630 rvoid *pclassfile_image;
01631
01632 int fd;
01633
01634
01635
01636
01637 int rc = stat(filename, &statbfr);
01638 READ_SYSCALL_FAILURE(0 > rc, "statbfr");
01639
01640
01641
01642
01643
01644
01645 pclassfile_image = (rvoid *) HEAP_GET_DATA(statbfr.st_size, rfalse);
01646
01647
01648 fd = open(filename, O_RDONLY);
01649 READ_SYSCALL_FAILURE(0 > fd, "file open");
01650
01651
01652 filesize = read(fd, pclassfile_image, statbfr.st_size);
01653 READ_SYSCALL_FAILURE(0 > filesize, "file read");
01654
01655 close(fd);
01656
01657
01658 GENERIC_FAILURE_PTR((filesize != statbfr.st_size),
01659 DMLNORM,
01660 "classfile_readclassfile",
01661 "Incomplete file read",
01662 rvoid,
01663 pclassfile_image,
01664 rnull);
01665
01666
01667 return(pclassfile_image);
01668
01669 }
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683 u1 *classfile_readjarfile(rchar *filename)
01684 {
01685 struct stat statbfr;
01686
01687 rchar *jarparm = HEAP_GET_DATA(JVMCFG_SCRIPT_MAX, rfalse);
01688
01689 rchar *pwd = HEAP_GET_DATA(JVMCFG_SCRIPT_MAX, rfalse);
01690
01691 rchar *jarscript = HEAP_GET_DATA(JVMCFG_SCRIPT_MAX, rfalse);
01692
01693
01694
01695
01696
01697
01698
01699
01700 if (JVMCFG_PATHNAME_DELIMITER_CHAR == filename[0])
01701 {
01702 strcpy(jarparm, filename);
01703 }
01704 else
01705 {
01706
01707
01708
01709
01710 getwd(pwd);
01711
01712 sprintfLocal(jarparm,
01713 "%s%c%s",
01714 pwd,
01715 JVMCFG_PATHNAME_DELIMITER_CHAR,
01716 filename);
01717 }
01718
01719
01720
01721
01722
01723
01724
01725 sprintfLocal(jarscript,
01726 JVMCFG_JARFILE_MANIFEST_EXTRACT_SCRIPT,
01727 tmparea_get(),
01728 pjvm->java_home,
01729 jarparm);
01730
01731 int rc = system(jarscript);
01732
01733 if (0 != rc)
01734 {
01735 sysErrMsg("classfile_readjarfile",
01736 "Cannot extract data from JAR file %s",
01737 jarparm);
01738 exit_jvm(EXIT_CLASSPATH_JAR);
01739
01740 }
01741
01742
01743 sprintfLocal(jarscript,
01744 "%s%c%s",
01745 tmparea_get(),
01746 JVMCFG_PATHNAME_DELIMITER_CHAR,
01747 JVMCFG_JARFILE_MANIFEST_FILENAME);
01748
01749 rc = stat(jarscript, &statbfr);
01750
01751
01752
01753 rchar *mnfstartclass = manifest_get_main(jarscript);
01754
01755 if (rnull == mnfstartclass)
01756 {
01757 sysErrMsg("classfile_readjarfile",
01758 "Cannot locate start class in JAR file %s",
01759 jarparm);
01760 exit_jvm(EXIT_CLASSPATH_JAR);
01761
01762 }
01763
01764
01765 rchar *start_class_tmpfile = pwd;
01766
01767
01768 sprintfLocal(start_class_tmpfile,
01769 "%s%c",
01770 tmparea_get(),
01771 JVMCFG_PATHNAME_DELIMITER_CHAR);
01772
01773 int dirlen = strlen(start_class_tmpfile);
01774 strcat(pwd, mnfstartclass);
01775
01776 (rvoid) classpath_external2internal_classname_inplace(&pwd[dirlen]);
01777
01778 int alllen = strlen(start_class_tmpfile);
01779 start_class_tmpfile[alllen] = JVMCFG_EXTENSION_DELIMITER_CHAR;
01780 start_class_tmpfile[alllen + 1] = '\0';
01781 strcat(pwd, CLASSFILE_EXTENSION_DEFAULT);
01782
01783 rc = stat(start_class_tmpfile, &statbfr);
01784
01785
01786 if (0 != rc)
01787 {
01788 sysErrMsg("classfile_readjarfile",
01789 "Cannot locate start class '%s' in manifest for JAR file %s",
01790 mnfstartclass,
01791 jarparm);
01792
01793 HEAP_FREE_DATA(mnfstartclass);
01794 HEAP_FREE_DATA(jarparm);
01795 HEAP_FREE_DATA(start_class_tmpfile);
01796 HEAP_FREE_DATA(jarscript);
01797
01798 exit_jvm(EXIT_CLASSPATH_JAR);
01799 }
01800
01801
01802 HEAP_FREE_DATA(jarparm);
01803 HEAP_FREE_DATA(mnfstartclass);
01804 HEAP_FREE_DATA(jarscript);
01805
01806
01807
01808
01809
01810
01811 rvoid *pvrc = classfile_readclassfile(start_class_tmpfile);
01812
01813 HEAP_FREE_DATA(start_class_tmpfile);
01814
01815 return(pvrc);
01816
01817 }
01818
01819
01820
01821
01822
01823