1 /* 2 * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of Oracle nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * This source code is provided to illustrate the usage of a given feature 34 * or technique and has been deliberately simplified. Additional steps 35 * required for a production-quality application, such as security checks, 36 * input validation and proper error handling, might not be present in 37 * this sample code. 38 */ 39 40 41 /* Class reader writer (java_crw_demo) for instrumenting bytecodes */ 42 43 /* 44 * As long as the callbacks allow for it and the class number is unique, 45 * this code is completely re-entrant and any number of classfile 46 * injections can happen at the same time. 47 * 48 * The current logic requires a unique number for this class instance 49 * or (jclass,jobject loader) pair, this is done via the ClassIndex 50 * in hprof, which is passed in as the 'unsigned cnum' to java_crw_demo(). 51 * It's up to the user of this interface if it wants to use this 52 * feature. 53 * 54 */ 55 56 #include <stdio.h> 57 #include <stdlib.h> 58 #include <string.h> 59 60 /* Get Java and class file and bytecode information. */ 61 62 #include <jni.h> 63 64 #include "classfile_constants.h" 65 66 67 /* Include our own interface for cross check */ 68 69 #include "java_crw_demo.h" 70 71 /* Macros over error functions to capture line numbers */ 72 73 #define CRW_FATAL(ci, message) fatal_error(ci, message, __FILE__, __LINE__) 74 75 #if defined(DEBUG) || !defined(NDEBUG) 76 77 #define CRW_ASSERT(ci, cond) \ 78 ((cond)?(void)0:assert_error(ci, #cond, __FILE__, __LINE__)) 79 80 #else 81 82 #define CRW_ASSERT(ci, cond) 83 84 #endif 85 86 #define CRW_ASSERT_MI(mi) CRW_ASSERT((mi)?(mi)->ci:NULL,(mi)!=NULL) 87 88 #define CRW_ASSERT_CI(ci) CRW_ASSERT(ci, ( (ci) != NULL && \ 89 (ci)->input_position <= (ci)->input_len && \ 90 (ci)->output_position <= (ci)->output_len) ) 91 92 #define BUFSIZE 256 93 94 #ifdef _WIN32 95 #define snprintf(buffer, count, format, ...) _snprintf_s(buffer, count, _TRUNCATE, format, ##__VA_ARGS__) 96 #endif 97 98 /* Typedefs for various integral numbers, just for code clarity */ 99 100 typedef unsigned ClassOpcode; /* One opcode */ 101 typedef unsigned char ByteCode; /* One byte from bytecodes */ 102 typedef int ByteOffset; /* Byte offset */ 103 typedef int ClassConstant; /* Constant pool kind */ 104 typedef long CrwPosition; /* Position in class image */ 105 typedef unsigned short CrwCpoolIndex; /* Index into constant pool */ 106 107 /* Misc support macros */ 108 109 /* Given the position of an opcode, find the next 4byte boundary position */ 110 #define NEXT_4BYTE_BOUNDARY(opcode_pos) (((opcode_pos)+4) & (~3)) 111 112 #define LARGEST_INJECTION (12*3) /* 3 injections at same site */ 113 #define MAXIMUM_NEW_CPOOL_ENTRIES 64 /* don't add more than 32 entries */ 114 115 /* Constant Pool Entry (internal table that mirrors pool in file image) */ 116 117 typedef struct { 118 const char * ptr; /* Pointer to any string */ 119 unsigned short len; /* Length of string */ 120 unsigned int index1; /* 1st 16 bit index or 32bit value. */ 121 unsigned int index2; /* 2nd 16 bit index or 32bit value. */ 122 ClassConstant tag; /* Tag or kind of entry. */ 123 } CrwConstantPoolEntry; 124 125 struct MethodImage; 126 127 /* Class file image storage structure */ 128 129 typedef struct CrwClassImage { 130 131 /* Unique class number for this class */ 132 unsigned number; 133 134 /* Name of class, given or gotten out of class image */ 135 const char * name; 136 137 /* Input and Output class images tracking */ 138 const unsigned char * input; 139 unsigned char * output; 140 CrwPosition input_len; 141 CrwPosition output_len; 142 CrwPosition input_position; 143 CrwPosition output_position; 144 145 /* Mirrored constant pool */ 146 CrwConstantPoolEntry * cpool; 147 CrwCpoolIndex cpool_max_elements; /* Max count */ 148 CrwCpoolIndex cpool_count_plus_one; 149 150 /* Input flags about class (e.g. is it a system class) */ 151 int system_class; 152 153 /* Class access flags gotten from file. */ 154 unsigned access_flags; 155 156 /* Names of classes and methods. */ 157 char* tclass_name; /* Name of class that has tracker methods. */ 158 char* tclass_sig; /* Signature of class */ 159 char* call_name; /* Method name to call at offset 0 */ 160 char* call_sig; /* Signature of this method */ 161 char* return_name; /* Method name to call before any return */ 162 char* return_sig; /* Signature of this method */ 163 char* obj_init_name; /* Method name to call in Object <init> */ 164 char* obj_init_sig; /* Signature of this method */ 165 char* newarray_name; /* Method name to call after newarray opcodes */ 166 char* newarray_sig; /* Signature of this method */ 167 168 /* Constant pool index values for new entries */ 169 CrwCpoolIndex tracker_class_index; 170 CrwCpoolIndex object_init_tracker_index; 171 CrwCpoolIndex newarray_tracker_index; 172 CrwCpoolIndex call_tracker_index; 173 CrwCpoolIndex return_tracker_index; 174 CrwCpoolIndex class_number_index; /* Class number in pool */ 175 176 /* Count of injections made into this class */ 177 int injection_count; 178 179 /* This class must be the java.lang.Object class */ 180 jboolean is_object_class; 181 182 /* This class must be the java.lang.Thread class */ 183 jboolean is_thread_class; 184 185 /* Callback functions */ 186 FatalErrorHandler fatal_error_handler; 187 MethodNumberRegister mnum_callback; 188 189 /* Table of method names and descr's */ 190 int method_count; 191 const char ** method_name; 192 const char ** method_descr; 193 struct MethodImage * current_mi; 194 195 } CrwClassImage; 196 197 /* Injection bytecodes (holds injected bytecodes for each code position) */ 198 199 typedef struct { 200 ByteCode * code; 201 ByteOffset len; 202 } Injection; 203 204 /* Method transformation data (allocated/freed as each method is processed) */ 205 206 typedef struct MethodImage { 207 208 /* Back reference to Class image data. */ 209 CrwClassImage * ci; 210 211 /* Unique method number for this class. */ 212 unsigned number; 213 214 /* Method name and descr */ 215 const char * name; 216 const char * descr; 217 218 /* Map of input bytecode offsets to output bytecode offsets */ 219 ByteOffset * map; 220 221 /* Bytecode injections for each input bytecode offset */ 222 Injection * injections; 223 224 /* Widening setting for each input bytecode offset */ 225 signed char * widening; 226 227 /* Length of original input bytecodes, and new bytecodes. */ 228 ByteOffset code_len; 229 ByteOffset new_code_len; 230 231 /* Location in input where bytecodes are located. */ 232 CrwPosition start_of_input_bytecodes; 233 234 /* Original max_stack and new max stack */ 235 unsigned max_stack; 236 unsigned new_max_stack; 237 238 jboolean object_init_method; 239 jboolean skip_call_return_sites; 240 241 /* Method access flags gotten from file. */ 242 unsigned access_flags; 243 244 } MethodImage; 245 246 /* ----------------------------------------------------------------- */ 247 /* General support functions (memory and error handling) */ 248 249 static void 250 fatal_error(CrwClassImage *ci, const char *message, const char *file, int line) 251 { 252 if ( ci != NULL && ci->fatal_error_handler != NULL ) { 253 (*ci->fatal_error_handler)(message, file, line); 254 } else { 255 /* Normal operation should NEVER reach here */ 256 /* NO CRW FATAL ERROR HANDLER! */ 257 (void)fprintf(stderr, "CRW: %s [%s:%d]\n", message, file, line); 258 abort(); 259 } 260 } 261 262 #if defined(DEBUG) || !defined(NDEBUG) 263 static void 264 assert_error(CrwClassImage *ci, const char *condition, 265 const char *file, int line) 266 { 267 char buf[512]; 268 MethodImage *mi; 269 ByteOffset byte_code_offset; 270 271 mi = ci->current_mi; 272 if ( mi != NULL ) { 273 byte_code_offset = (ByteOffset)(mi->ci->input_position - mi->start_of_input_bytecodes); 274 } else { 275 byte_code_offset=-1; 276 } 277 278 (void)sprintf(buf, 279 "CRW ASSERTION FAILURE: %s (%s:%s:%d)", 280 condition, 281 ci->name==NULL?"?":ci->name, 282 (mi==NULL||mi->name==NULL)?"?":mi->name, 283 byte_code_offset); 284 fatal_error(ci, buf, file, line); 285 } 286 #endif 287 288 static void * 289 allocate(CrwClassImage *ci, int nbytes) 290 { 291 void * ptr; 292 293 if ( nbytes <= 0 ) { 294 CRW_FATAL(ci, "Cannot allocate <= 0 bytes"); 295 } 296 ptr = malloc(nbytes); 297 if ( ptr == NULL ) { 298 CRW_FATAL(ci, "Ran out of malloc memory"); 299 } 300 return ptr; 301 } 302 303 static void * 304 reallocate(CrwClassImage *ci, void *optr, int nbytes) 305 { 306 void * ptr; 307 308 if ( optr == NULL ) { 309 CRW_FATAL(ci, "Cannot deallocate NULL"); 310 } 311 if ( nbytes <= 0 ) { 312 CRW_FATAL(ci, "Cannot reallocate <= 0 bytes"); 313 } 314 ptr = realloc(optr, nbytes); 315 if ( ptr == NULL ) { 316 CRW_FATAL(ci, "Ran out of malloc memory"); 317 } 318 return ptr; 319 } 320 321 static void * 322 allocate_clean(CrwClassImage *ci, int nbytes) 323 { 324 void * ptr; 325 326 if ( nbytes <= 0 ) { 327 CRW_FATAL(ci, "Cannot allocate <= 0 bytes"); 328 } 329 ptr = calloc(nbytes, 1); 330 if ( ptr == NULL ) { 331 CRW_FATAL(ci, "Ran out of malloc memory"); 332 } 333 return ptr; 334 } 335 336 static const char * 337 duplicate(CrwClassImage *ci, const char *str, int len) 338 { 339 char *copy; 340 341 copy = (char*)allocate(ci, len+1); 342 (void)memcpy(copy, str, len); 343 copy[len] = 0; 344 return (const char *)copy; 345 } 346 347 static void 348 deallocate(CrwClassImage *ci, void *ptr) 349 { 350 if ( ptr == NULL ) { 351 CRW_FATAL(ci, "Cannot deallocate NULL"); 352 } 353 (void)free(ptr); 354 } 355 356 /* ----------------------------------------------------------------- */ 357 /* Functions for reading/writing bytes to/from the class images */ 358 359 static unsigned 360 readU1(CrwClassImage *ci) 361 { 362 CRW_ASSERT_CI(ci); 363 return ((unsigned)(ci->input[ci->input_position++])) & 0xFF; 364 } 365 366 static unsigned 367 readU2(CrwClassImage *ci) 368 { 369 unsigned res; 370 371 res = readU1(ci); 372 return (res << 8) + readU1(ci); 373 } 374 375 static signed short 376 readS2(CrwClassImage *ci) 377 { 378 unsigned res; 379 380 res = readU1(ci); 381 return ((res << 8) + readU1(ci)) & 0xFFFF; 382 } 383 384 static unsigned 385 readU4(CrwClassImage *ci) 386 { 387 unsigned res; 388 389 res = readU2(ci); 390 return (res << 16) + readU2(ci); 391 } 392 393 static void 394 writeU1(CrwClassImage *ci, unsigned val) /* Only writes out lower 8 bits */ 395 { 396 CRW_ASSERT_CI(ci); 397 if ( ci->output != NULL ) { 398 ci->output[ci->output_position++] = val & 0xFF; 399 } 400 } 401 402 static void 403 writeU2(CrwClassImage *ci, unsigned val) 404 { 405 writeU1(ci, val >> 8); 406 writeU1(ci, val); 407 } 408 409 static void 410 writeU4(CrwClassImage *ci, unsigned val) 411 { 412 writeU2(ci, val >> 16); 413 writeU2(ci, val); 414 } 415 416 static unsigned 417 copyU1(CrwClassImage *ci) 418 { 419 unsigned value; 420 421 value = readU1(ci); 422 writeU1(ci, value); 423 return value; 424 } 425 426 static unsigned 427 copyU2(CrwClassImage *ci) 428 { 429 unsigned value; 430 431 value = readU2(ci); 432 writeU2(ci, value); 433 return value; 434 } 435 436 static unsigned 437 copyU4(CrwClassImage *ci) 438 { 439 unsigned value; 440 441 value = readU4(ci); 442 writeU4(ci, value); 443 return value; 444 } 445 446 static void 447 copy(CrwClassImage *ci, unsigned count) 448 { 449 CRW_ASSERT_CI(ci); 450 if ( ci->output != NULL ) { 451 (void)memcpy(ci->output+ci->output_position, 452 ci->input+ci->input_position, count); 453 ci->output_position += count; 454 } 455 ci->input_position += count; 456 CRW_ASSERT_CI(ci); 457 } 458 459 static void 460 skip(CrwClassImage *ci, unsigned count) 461 { 462 CRW_ASSERT_CI(ci); 463 ci->input_position += count; 464 } 465 466 static void 467 read_bytes(CrwClassImage *ci, void *bytes, unsigned count) 468 { 469 CRW_ASSERT_CI(ci); 470 CRW_ASSERT(ci, bytes!=NULL); 471 (void)memcpy(bytes, ci->input+ci->input_position, count); 472 ci->input_position += count; 473 } 474 475 static void 476 write_bytes(CrwClassImage *ci, void *bytes, unsigned count) 477 { 478 CRW_ASSERT_CI(ci); 479 CRW_ASSERT(ci, bytes!=NULL); 480 if ( ci->output != NULL ) { 481 (void)memcpy(ci->output+ci->output_position, bytes, count); 482 ci->output_position += count; 483 } 484 } 485 486 static void 487 random_writeU2(CrwClassImage *ci, CrwPosition pos, unsigned val) 488 { 489 CrwPosition save_position; 490 491 CRW_ASSERT_CI(ci); 492 save_position = ci->output_position; 493 ci->output_position = pos; 494 writeU2(ci, val); 495 ci->output_position = save_position; 496 } 497 498 static void 499 random_writeU4(CrwClassImage *ci, CrwPosition pos, unsigned val) 500 { 501 CrwPosition save_position; 502 503 CRW_ASSERT_CI(ci); 504 save_position = ci->output_position; 505 ci->output_position = pos; 506 writeU4(ci, val); 507 ci->output_position = save_position; 508 } 509 510 /* ----------------------------------------------------------------- */ 511 /* Constant Pool handling functions. */ 512 513 static void 514 fillin_cpool_entry(CrwClassImage *ci, CrwCpoolIndex i, 515 ClassConstant tag, 516 unsigned int index1, unsigned int index2, 517 const char *ptr, int len) 518 { 519 CRW_ASSERT_CI(ci); 520 CRW_ASSERT(ci, i > 0 && i < ci->cpool_count_plus_one); 521 ci->cpool[i].tag = tag; 522 ci->cpool[i].index1 = index1; 523 ci->cpool[i].index2 = index2; 524 ci->cpool[i].ptr = ptr; 525 ci->cpool[i].len = (unsigned short)len; 526 } 527 528 static CrwCpoolIndex 529 add_new_cpool_entry(CrwClassImage *ci, ClassConstant tag, 530 unsigned int index1, unsigned int index2, 531 const char *str, int len) 532 { 533 CrwCpoolIndex i; 534 char *utf8 = NULL; 535 536 CRW_ASSERT_CI(ci); 537 i = ci->cpool_count_plus_one++; 538 539 /* NOTE: This implementation does not automatically expand the 540 * constant pool table beyond the expected number needed 541 * to handle this particular CrwTrackerInterface injections. 542 * See MAXIMUM_NEW_CPOOL_ENTRIES 543 */ 544 CRW_ASSERT(ci, ci->cpool_count_plus_one < ci->cpool_max_elements ); 545 546 writeU1(ci, tag); 547 switch (tag) { 548 case JVM_CONSTANT_Class: 549 writeU2(ci, index1); 550 break; 551 case JVM_CONSTANT_String: 552 writeU2(ci, index1); 553 break; 554 case JVM_CONSTANT_Fieldref: 555 case JVM_CONSTANT_Methodref: 556 case JVM_CONSTANT_InterfaceMethodref: 557 case JVM_CONSTANT_Integer: 558 case JVM_CONSTANT_Float: 559 case JVM_CONSTANT_NameAndType: 560 writeU2(ci, index1); 561 writeU2(ci, index2); 562 break; 563 case JVM_CONSTANT_Long: 564 case JVM_CONSTANT_Double: 565 writeU4(ci, index1); 566 writeU4(ci, index2); 567 ci->cpool_count_plus_one++; 568 CRW_ASSERT(ci, ci->cpool_count_plus_one < ci->cpool_max_elements ); 569 break; 570 case JVM_CONSTANT_Utf8: 571 CRW_ASSERT(ci, len==(len & 0xFFFF)); 572 writeU2(ci, len); 573 write_bytes(ci, (void*)str, len); 574 utf8 = (char*)duplicate(ci, str, len); 575 break; 576 default: 577 CRW_FATAL(ci, "Unknown constant"); 578 break; 579 } 580 fillin_cpool_entry(ci, i, tag, index1, index2, (const char *)utf8, len); 581 CRW_ASSERT(ci, i > 0 && i < ci->cpool_count_plus_one); 582 return i; 583 } 584 585 static CrwCpoolIndex 586 add_new_class_cpool_entry(CrwClassImage *ci, const char *class_name) 587 { 588 CrwCpoolIndex name_index; 589 CrwCpoolIndex class_index; 590 int len; 591 592 CRW_ASSERT_CI(ci); 593 CRW_ASSERT(ci, class_name!=NULL); 594 595 len = (int)strlen(class_name); 596 name_index = add_new_cpool_entry(ci, JVM_CONSTANT_Utf8, len, 0, 597 class_name, len); 598 class_index = add_new_cpool_entry(ci, JVM_CONSTANT_Class, name_index, 0, 599 NULL, 0); 600 return class_index; 601 } 602 603 static CrwCpoolIndex 604 add_new_method_cpool_entry(CrwClassImage *ci, CrwCpoolIndex class_index, 605 const char *name, const char *descr) 606 { 607 CrwCpoolIndex name_index; 608 CrwCpoolIndex descr_index; 609 CrwCpoolIndex name_type_index; 610 int len; 611 612 CRW_ASSERT_CI(ci); 613 CRW_ASSERT(ci, name!=NULL); 614 CRW_ASSERT(ci, descr!=NULL); 615 len = (int)strlen(name); 616 name_index = 617 add_new_cpool_entry(ci, JVM_CONSTANT_Utf8, len, 0, name, len); 618 len = (int)strlen(descr); 619 descr_index = 620 add_new_cpool_entry(ci, JVM_CONSTANT_Utf8, len, 0, descr, len); 621 name_type_index = 622 add_new_cpool_entry(ci, JVM_CONSTANT_NameAndType, 623 name_index, descr_index, NULL, 0); 624 return add_new_cpool_entry(ci, JVM_CONSTANT_Methodref, 625 class_index, name_type_index, NULL, 0); 626 } 627 628 static CrwConstantPoolEntry 629 cpool_entry(CrwClassImage *ci, CrwCpoolIndex c_index) 630 { 631 CRW_ASSERT_CI(ci); 632 CRW_ASSERT(ci, c_index > 0 && c_index < ci->cpool_count_plus_one); 633 return ci->cpool[c_index]; 634 } 635 636 static void 637 cpool_setup(CrwClassImage *ci) 638 { 639 CrwCpoolIndex i; 640 CrwPosition cpool_output_position; 641 int count_plus_one; 642 643 CRW_ASSERT_CI(ci); 644 cpool_output_position = ci->output_position; 645 count_plus_one = copyU2(ci); 646 CRW_ASSERT(ci, count_plus_one>1); 647 ci->cpool_max_elements = count_plus_one+MAXIMUM_NEW_CPOOL_ENTRIES; 648 ci->cpool = (CrwConstantPoolEntry*)allocate_clean(ci, 649 (int)((ci->cpool_max_elements)*sizeof(CrwConstantPoolEntry))); 650 ci->cpool_count_plus_one = (CrwCpoolIndex)count_plus_one; 651 652 /* Index zero not in class file */ 653 for (i = 1; i < count_plus_one; ++i) { 654 CrwCpoolIndex ipos; 655 ClassConstant tag; 656 unsigned int index1; 657 unsigned int index2; 658 unsigned len; 659 char * utf8; 660 char message[BUFSIZE]; 661 662 ipos = i; 663 index1 = 0; 664 index2 = 0; 665 len = 0; 666 utf8 = NULL; 667 668 tag = copyU1(ci); 669 switch (tag) { 670 case JVM_CONSTANT_Class: 671 index1 = copyU2(ci); 672 break; 673 case JVM_CONSTANT_String: 674 index1 = copyU2(ci); 675 break; 676 case JVM_CONSTANT_Fieldref: 677 case JVM_CONSTANT_Methodref: 678 case JVM_CONSTANT_InterfaceMethodref: 679 case JVM_CONSTANT_Integer: 680 case JVM_CONSTANT_Float: 681 case JVM_CONSTANT_NameAndType: 682 index1 = copyU2(ci); 683 index2 = copyU2(ci); 684 break; 685 case JVM_CONSTANT_Long: 686 case JVM_CONSTANT_Double: 687 index1 = copyU4(ci); 688 index2 = copyU4(ci); 689 ++i; /* // these take two CP entries - duh! */ 690 break; 691 case JVM_CONSTANT_Utf8: 692 len = copyU2(ci); 693 index1 = (unsigned short)len; 694 utf8 = (char*)allocate(ci, len+1); 695 read_bytes(ci, (void*)utf8, len); 696 utf8[len] = 0; 697 write_bytes(ci, (void*)utf8, len); 698 break; 699 case JVM_CONSTANT_MethodType: 700 index1 = copyU2(ci); 701 break; 702 case JVM_CONSTANT_MethodHandle: 703 index1 = copyU1(ci); 704 index2 = copyU2(ci); 705 break; 706 case JVM_CONSTANT_InvokeDynamic: 707 index1 = copyU2(ci); 708 index2 = copyU2(ci); 709 break; 710 default: 711 snprintf(message, BUFSIZE, "Unknown tag: %d, at ipos %hu", tag, ipos); 712 CRW_FATAL(ci, message); 713 break; 714 } 715 fillin_cpool_entry(ci, ipos, tag, index1, index2, (const char *)utf8, len); 716 } 717 718 if (ci->call_name != NULL || ci->return_name != NULL) { 719 if ( ci->number != (ci->number & 0x7FFF) ) { 720 ci->class_number_index = 721 add_new_cpool_entry(ci, JVM_CONSTANT_Integer, 722 (ci->number>>16) & 0xFFFF, ci->number & 0xFFFF, NULL, 0); 723 } 724 } 725 726 if ( ci->tclass_name != NULL ) { 727 ci->tracker_class_index = 728 add_new_class_cpool_entry(ci, ci->tclass_name); 729 } 730 if (ci->obj_init_name != NULL) { 731 ci->object_init_tracker_index = add_new_method_cpool_entry(ci, 732 ci->tracker_class_index, 733 ci->obj_init_name, 734 ci->obj_init_sig); 735 } 736 if (ci->newarray_name != NULL) { 737 ci->newarray_tracker_index = add_new_method_cpool_entry(ci, 738 ci->tracker_class_index, 739 ci->newarray_name, 740 ci->newarray_sig); 741 } 742 if (ci->call_name != NULL) { 743 ci->call_tracker_index = add_new_method_cpool_entry(ci, 744 ci->tracker_class_index, 745 ci->call_name, 746 ci->call_sig); 747 } 748 if (ci->return_name != NULL) { 749 ci->return_tracker_index = add_new_method_cpool_entry(ci, 750 ci->tracker_class_index, 751 ci->return_name, 752 ci->return_sig); 753 } 754 755 random_writeU2(ci, cpool_output_position, ci->cpool_count_plus_one); 756 } 757 758 /* ----------------------------------------------------------------- */ 759 /* Functions that create the bytecodes to inject */ 760 761 static ByteOffset 762 push_pool_constant_bytecodes(ByteCode *bytecodes, CrwCpoolIndex index) 763 { 764 ByteOffset nbytes = 0; 765 766 if ( index == (index&0x7F) ) { 767 bytecodes[nbytes++] = (ByteCode)JVM_OPC_ldc; 768 } else { 769 bytecodes[nbytes++] = (ByteCode)JVM_OPC_ldc_w; 770 bytecodes[nbytes++] = (ByteCode)((index >> 8) & 0xFF); 771 } 772 bytecodes[nbytes++] = (ByteCode)(index & 0xFF); 773 return nbytes; 774 } 775 776 static ByteOffset 777 push_short_constant_bytecodes(ByteCode *bytecodes, unsigned number) 778 { 779 ByteOffset nbytes = 0; 780 781 if ( number <= 5 ) { 782 bytecodes[nbytes++] = (ByteCode)(JVM_OPC_iconst_0+number); 783 } else if ( number == (number&0x7F) ) { 784 bytecodes[nbytes++] = (ByteCode)JVM_OPC_bipush; 785 bytecodes[nbytes++] = (ByteCode)(number & 0xFF); 786 } else { 787 bytecodes[nbytes++] = (ByteCode)JVM_OPC_sipush; 788 bytecodes[nbytes++] = (ByteCode)((number >> 8) & 0xFF); 789 bytecodes[nbytes++] = (ByteCode)(number & 0xFF); 790 } 791 return nbytes; 792 } 793 794 static ByteOffset 795 injection_template(MethodImage *mi, ByteCode *bytecodes, ByteOffset max_nbytes, 796 CrwCpoolIndex method_index) 797 { 798 CrwClassImage * ci; 799 ByteOffset nbytes = 0; 800 unsigned max_stack; 801 int add_dup; 802 int add_aload; 803 int push_cnum; 804 int push_mnum; 805 806 ci = mi->ci; 807 808 CRW_ASSERT(ci, bytecodes!=NULL); 809 810 if ( method_index == 0 ) { 811 return 0; 812 } 813 814 if ( method_index == ci->newarray_tracker_index) { 815 max_stack = mi->max_stack + 1; 816 add_dup = JNI_TRUE; 817 add_aload = JNI_FALSE; 818 push_cnum = JNI_FALSE; 819 push_mnum = JNI_FALSE; 820 } else if ( method_index == ci->object_init_tracker_index) { 821 max_stack = mi->max_stack + 1; 822 add_dup = JNI_FALSE; 823 add_aload = JNI_TRUE; 824 push_cnum = JNI_FALSE; 825 push_mnum = JNI_FALSE; 826 } else { 827 max_stack = mi->max_stack + 2; 828 add_dup = JNI_FALSE; 829 add_aload = JNI_FALSE; 830 push_cnum = JNI_TRUE; 831 push_mnum = JNI_TRUE; 832 } 833 834 if ( add_dup ) { 835 bytecodes[nbytes++] = (ByteCode)JVM_OPC_dup; 836 } 837 if ( add_aload ) { 838 bytecodes[nbytes++] = (ByteCode)JVM_OPC_aload_0; 839 } 840 if ( push_cnum ) { 841 if ( ci->number == (ci->number & 0x7FFF) ) { 842 nbytes += push_short_constant_bytecodes(bytecodes+nbytes, 843 ci->number); 844 } else { 845 CRW_ASSERT(ci, ci->class_number_index!=0); 846 nbytes += push_pool_constant_bytecodes(bytecodes+nbytes, 847 ci->class_number_index); 848 } 849 } 850 if ( push_mnum ) { 851 nbytes += push_short_constant_bytecodes(bytecodes+nbytes, 852 mi->number); 853 } 854 bytecodes[nbytes++] = (ByteCode)JVM_OPC_invokestatic; 855 bytecodes[nbytes++] = (ByteCode)(method_index >> 8); 856 bytecodes[nbytes++] = (ByteCode)method_index; 857 bytecodes[nbytes] = 0; 858 CRW_ASSERT(ci, nbytes<max_nbytes); 859 860 /* Make sure the new max_stack is appropriate */ 861 if ( max_stack > mi->new_max_stack ) { 862 mi->new_max_stack = max_stack; 863 } 864 return nbytes; 865 } 866 867 /* Called to create injection code at entry to a method */ 868 static ByteOffset 869 entry_injection_code(MethodImage *mi, ByteCode *bytecodes, ByteOffset len) 870 { 871 CrwClassImage * ci; 872 ByteOffset nbytes = 0; 873 874 CRW_ASSERT_MI(mi); 875 876 ci = mi->ci; 877 878 if ( mi->object_init_method ) { 879 nbytes = injection_template(mi, 880 bytecodes, len, ci->object_init_tracker_index); 881 } 882 if ( !mi->skip_call_return_sites ) { 883 nbytes += injection_template(mi, 884 bytecodes+nbytes, len-nbytes, ci->call_tracker_index); 885 } 886 return nbytes; 887 } 888 889 /* Called to create injection code before an opcode */ 890 static ByteOffset 891 before_injection_code(MethodImage *mi, ClassOpcode opcode, 892 ByteCode *bytecodes, ByteOffset len) 893 { 894 ByteOffset nbytes = 0; 895 896 897 CRW_ASSERT_MI(mi); 898 switch ( opcode ) { 899 case JVM_OPC_return: 900 case JVM_OPC_ireturn: 901 case JVM_OPC_lreturn: 902 case JVM_OPC_freturn: 903 case JVM_OPC_dreturn: 904 case JVM_OPC_areturn: 905 if ( !mi->skip_call_return_sites ) { 906 nbytes = injection_template(mi, 907 bytecodes, len, mi->ci->return_tracker_index); 908 } 909 break; 910 default: 911 break; 912 } 913 return nbytes; 914 } 915 916 /* Called to create injection code after an opcode */ 917 static ByteOffset 918 after_injection_code(MethodImage *mi, ClassOpcode opcode, 919 ByteCode *bytecodes, ByteOffset len) 920 { 921 CrwClassImage* ci; 922 ByteOffset nbytes; 923 924 ci = mi->ci; 925 nbytes = 0; 926 927 CRW_ASSERT_MI(mi); 928 switch ( opcode ) { 929 case JVM_OPC_new: 930 /* Can't inject here cannot pass around uninitialized object */ 931 break; 932 case JVM_OPC_newarray: 933 case JVM_OPC_anewarray: 934 case JVM_OPC_multianewarray: 935 nbytes = injection_template(mi, 936 bytecodes, len, ci->newarray_tracker_index); 937 break; 938 default: 939 break; 940 } 941 return nbytes; 942 } 943 944 /* Actually inject the bytecodes */ 945 static void 946 inject_bytecodes(MethodImage *mi, ByteOffset at, 947 ByteCode *bytecodes, ByteOffset len) 948 { 949 Injection injection; 950 CrwClassImage *ci; 951 952 ci = mi->ci; 953 CRW_ASSERT_MI(mi); 954 CRW_ASSERT(ci, at <= mi->code_len); 955 956 injection = mi->injections[at]; 957 958 CRW_ASSERT(ci, len <= LARGEST_INJECTION/2); 959 CRW_ASSERT(ci, injection.len+len <= LARGEST_INJECTION); 960 961 /* Either start an injection area or concatenate to what is there */ 962 if ( injection.code == NULL ) { 963 CRW_ASSERT(ci, injection.len==0); 964 injection.code = (ByteCode *)allocate_clean(ci, LARGEST_INJECTION+1); 965 } 966 967 (void)memcpy(injection.code+injection.len, bytecodes, len); 968 injection.len += len; 969 injection.code[injection.len] = 0; 970 mi->injections[at] = injection; 971 ci->injection_count++; 972 } 973 974 /* ----------------------------------------------------------------- */ 975 /* Method handling functions */ 976 977 static MethodImage * 978 method_init(CrwClassImage *ci, unsigned mnum, ByteOffset code_len) 979 { 980 MethodImage * mi; 981 ByteOffset i; 982 983 mi = (MethodImage*)allocate_clean(ci, (int)sizeof(MethodImage)); 984 mi->ci = ci; 985 mi->name = ci->method_name[mnum]; 986 mi->descr = ci->method_descr[mnum]; 987 mi->code_len = code_len; 988 mi->map = (ByteOffset*)allocate_clean(ci, 989 (int)((code_len+1)*sizeof(ByteOffset))); 990 for(i=0; i<=code_len; i++) { 991 mi->map[i] = i; 992 } 993 mi->widening = (signed char*)allocate_clean(ci, code_len+1); 994 mi->injections = (Injection *)allocate_clean(ci, 995 (int)((code_len+1)*sizeof(Injection))); 996 mi->number = mnum; 997 ci->current_mi = mi; 998 return mi; 999 } 1000 1001 static void 1002 method_term(MethodImage *mi) 1003 { 1004 CrwClassImage *ci; 1005 1006 ci = mi->ci; 1007 CRW_ASSERT_MI(mi); 1008 if ( mi->map != NULL ) { 1009 deallocate(ci, (void*)mi->map); 1010 mi->map = NULL; 1011 } 1012 if ( mi->widening != NULL ) { 1013 deallocate(ci, (void*)mi->widening); 1014 mi->widening = NULL; 1015 } 1016 if ( mi->injections != NULL ) { 1017 ByteOffset i; 1018 for(i=0; i<= mi->code_len; i++) { 1019 if ( mi->injections[i].code != NULL ) { 1020 deallocate(ci, (void*)mi->injections[i].code); 1021 mi->injections[i].code = NULL; 1022 } 1023 } 1024 deallocate(ci, (void*)mi->injections); 1025 mi->injections = NULL; 1026 } 1027 ci->current_mi = NULL; 1028 deallocate(ci, (void*)mi); 1029 } 1030 1031 static ByteOffset 1032 input_code_offset(MethodImage *mi) 1033 { 1034 CRW_ASSERT_MI(mi); 1035 return (ByteOffset)(mi->ci->input_position - mi->start_of_input_bytecodes); 1036 } 1037 1038 static void 1039 rewind_to_beginning_of_input_bytecodes(MethodImage *mi) 1040 { 1041 CRW_ASSERT_MI(mi); 1042 mi->ci->input_position = mi->start_of_input_bytecodes; 1043 } 1044 1045 /* Starting at original byte position 'at', add 'offset' to it's new 1046 * location. This may be a negative value. 1047 * NOTE: That this map is not the new bytecode location of the opcode 1048 * but the new bytecode location that should be used when 1049 * a goto or jump instruction was targeting the old bytecode 1050 * location. 1051 */ 1052 static void 1053 adjust_map(MethodImage *mi, ByteOffset at, ByteOffset offset) 1054 { 1055 ByteOffset i; 1056 1057 CRW_ASSERT_MI(mi); 1058 for (i = at; i <= mi->code_len; ++i) { 1059 mi->map[i] += offset; 1060 } 1061 } 1062 1063 static void 1064 widen(MethodImage *mi, ByteOffset at, ByteOffset len) 1065 { 1066 int delta; 1067 1068 CRW_ASSERT(mi->ci, at <= mi->code_len); 1069 delta = len - mi->widening[at]; 1070 /* Adjust everything from the current input location by delta */ 1071 adjust_map(mi, input_code_offset(mi), delta); 1072 /* Mark at beginning of instruction */ 1073 mi->widening[at] = (signed char)len; 1074 } 1075 1076 static void 1077 verify_opc_wide(CrwClassImage *ci, ClassOpcode wopcode) 1078 { 1079 switch (wopcode) { 1080 case JVM_OPC_aload: case JVM_OPC_astore: 1081 case JVM_OPC_fload: case JVM_OPC_fstore: 1082 case JVM_OPC_iload: case JVM_OPC_istore: 1083 case JVM_OPC_lload: case JVM_OPC_lstore: 1084 case JVM_OPC_dload: case JVM_OPC_dstore: 1085 case JVM_OPC_ret: case JVM_OPC_iinc: 1086 break; 1087 default: 1088 CRW_FATAL(ci, "Invalid opcode supplied to wide opcode"); 1089 break; 1090 } 1091 } 1092 1093 static unsigned 1094 opcode_length(CrwClassImage *ci, ClassOpcode opcode) 1095 { 1096 /* Define array that holds length of an opcode */ 1097 static unsigned char _opcode_length[JVM_OPC_MAX+1] = 1098 JVM_OPCODE_LENGTH_INITIALIZER; 1099 1100 if ( opcode > JVM_OPC_MAX ) { 1101 CRW_FATAL(ci, "Invalid opcode supplied to opcode_length()"); 1102 } 1103 return _opcode_length[opcode]; 1104 } 1105 1106 /* Walk one instruction and inject instrumentation */ 1107 static void 1108 inject_for_opcode(MethodImage *mi) 1109 { 1110 CrwClassImage * ci; 1111 ClassOpcode opcode; 1112 int pos; 1113 1114 CRW_ASSERT_MI(mi); 1115 ci = mi->ci; 1116 pos = input_code_offset(mi); 1117 opcode = readU1(ci); 1118 1119 if (opcode == JVM_OPC_wide) { 1120 ClassOpcode wopcode; 1121 1122 wopcode = readU1(ci); 1123 /* lvIndex not used */ 1124 (void)readU2(ci); 1125 verify_opc_wide(ci, wopcode); 1126 if ( wopcode==JVM_OPC_iinc ) { 1127 (void)readU1(ci); 1128 (void)readU1(ci); 1129 } 1130 } else { 1131 1132 ByteCode bytecodes[LARGEST_INJECTION+1]; 1133 int header; 1134 int instr_len; 1135 int low; 1136 int high; 1137 int npairs; 1138 ByteOffset len; 1139 1140 /* Get bytecodes to inject before this opcode */ 1141 len = before_injection_code(mi, opcode, bytecodes, (int)sizeof(bytecodes)); 1142 if ( len > 0 ) { 1143 inject_bytecodes(mi, pos, bytecodes, len); 1144 /* Adjust map after processing this opcode */ 1145 } 1146 1147 /* Process this opcode */ 1148 switch (opcode) { 1149 case JVM_OPC_tableswitch: 1150 header = NEXT_4BYTE_BOUNDARY(pos); 1151 skip(ci, header - (pos+1)); 1152 (void)readU4(ci); 1153 low = readU4(ci); 1154 high = readU4(ci); 1155 skip(ci, (high+1-low) * 4); 1156 break; 1157 case JVM_OPC_lookupswitch: 1158 header = NEXT_4BYTE_BOUNDARY(pos); 1159 skip(ci, header - (pos+1)); 1160 (void)readU4(ci); 1161 npairs = readU4(ci); 1162 skip(ci, npairs * 8); 1163 break; 1164 default: 1165 instr_len = opcode_length(ci, opcode); 1166 skip(ci, instr_len-1); 1167 break; 1168 } 1169 1170 /* Get position after this opcode is processed */ 1171 pos = input_code_offset(mi); 1172 1173 /* Adjust for any before_injection_code() */ 1174 if ( len > 0 ) { 1175 /* Adjust everything past this opcode. 1176 * Why past it? Because we want any jumps to this bytecode loc 1177 * to go to the injected code, not where the opcode 1178 * was moved too. 1179 * Consider a 'return' opcode that is jumped too. 1180 * NOTE: This may not be correct in all cases, but will 1181 * when we are only dealing with non-variable opcodes 1182 * like the return opcodes. Be careful if the 1183 * before_injection_code() changes to include other 1184 * opcodes that have variable length. 1185 */ 1186 adjust_map(mi, pos, len); 1187 } 1188 1189 /* Get bytecodes to inject after this opcode */ 1190 len = after_injection_code(mi, opcode, bytecodes, (int)sizeof(bytecodes)); 1191 if ( len > 0 ) { 1192 inject_bytecodes(mi, pos, bytecodes, len); 1193 1194 /* Adjust for any after_injection_code() */ 1195 adjust_map(mi, pos, len); 1196 } 1197 1198 } 1199 } 1200 1201 /* Map original bytecode location to it's new location. (See adjust_map()). */ 1202 static ByteOffset 1203 method_code_map(MethodImage *mi, ByteOffset pos) 1204 { 1205 CRW_ASSERT_MI(mi); 1206 CRW_ASSERT(mi->ci, pos <= mi->code_len); 1207 return mi->map[pos]; 1208 } 1209 1210 static int 1211 adjust_instruction(MethodImage *mi) 1212 { 1213 CrwClassImage * ci; 1214 ClassOpcode opcode; 1215 int pos; 1216 int new_pos; 1217 1218 CRW_ASSERT_MI(mi); 1219 ci = mi->ci; 1220 pos = input_code_offset(mi); 1221 new_pos = method_code_map(mi,pos); 1222 1223 opcode = readU1(ci); 1224 1225 if (opcode == JVM_OPC_wide) { 1226 ClassOpcode wopcode; 1227 1228 wopcode = readU1(ci); 1229 /* lvIndex not used */ 1230 (void)readU2(ci); 1231 verify_opc_wide(ci, wopcode); 1232 if ( wopcode==JVM_OPC_iinc ) { 1233 (void)readU1(ci); 1234 (void)readU1(ci); 1235 } 1236 } else { 1237 1238 int widened; 1239 int header; 1240 int newHeader; 1241 int low; 1242 int high; 1243 int new_pad; 1244 int old_pad; 1245 int delta; 1246 int new_delta; 1247 int delta_pad; 1248 int npairs; 1249 int instr_len; 1250 1251 switch (opcode) { 1252 1253 case JVM_OPC_tableswitch: 1254 widened = mi->widening[pos]; 1255 header = NEXT_4BYTE_BOUNDARY(pos); 1256 newHeader = NEXT_4BYTE_BOUNDARY(new_pos); 1257 1258 skip(ci, header - (pos+1)); 1259 1260 delta = readU4(ci); 1261 low = readU4(ci); 1262 high = readU4(ci); 1263 skip(ci, (high+1-low) * 4); 1264 new_pad = newHeader - new_pos; 1265 old_pad = header - pos; 1266 delta_pad = new_pad - old_pad; 1267 if (widened != delta_pad) { 1268 widen(mi, pos, delta_pad); 1269 return 0; 1270 } 1271 break; 1272 1273 case JVM_OPC_lookupswitch: 1274 widened = mi->widening[pos]; 1275 header = NEXT_4BYTE_BOUNDARY(pos); 1276 newHeader = NEXT_4BYTE_BOUNDARY(new_pos); 1277 1278 skip(ci, header - (pos+1)); 1279 1280 delta = readU4(ci); 1281 npairs = readU4(ci); 1282 skip(ci, npairs * 8); 1283 new_pad = newHeader - new_pos; 1284 old_pad = header - pos; 1285 delta_pad = new_pad - old_pad; 1286 if (widened != delta_pad) { 1287 widen(mi, pos, delta_pad); 1288 return 0; 1289 } 1290 break; 1291 1292 case JVM_OPC_jsr: case JVM_OPC_goto: 1293 case JVM_OPC_ifeq: case JVM_OPC_ifge: case JVM_OPC_ifgt: 1294 case JVM_OPC_ifle: case JVM_OPC_iflt: case JVM_OPC_ifne: 1295 case JVM_OPC_if_icmpeq: case JVM_OPC_if_icmpne: case JVM_OPC_if_icmpge: 1296 case JVM_OPC_if_icmpgt: case JVM_OPC_if_icmple: case JVM_OPC_if_icmplt: 1297 case JVM_OPC_if_acmpeq: case JVM_OPC_if_acmpne: 1298 case JVM_OPC_ifnull: case JVM_OPC_ifnonnull: 1299 widened = mi->widening[pos]; 1300 delta = readS2(ci); 1301 if (widened == 0) { 1302 new_delta = method_code_map(mi,pos+delta) - new_pos; 1303 if ((new_delta < -32768) || (new_delta > 32767)) { 1304 switch (opcode) { 1305 case JVM_OPC_jsr: case JVM_OPC_goto: 1306 widen(mi, pos, 2); 1307 break; 1308 default: 1309 widen(mi, pos, 5); 1310 break; 1311 } 1312 return 0; 1313 } 1314 } 1315 break; 1316 1317 case JVM_OPC_jsr_w: 1318 case JVM_OPC_goto_w: 1319 (void)readU4(ci); 1320 break; 1321 1322 default: 1323 instr_len = opcode_length(ci, opcode); 1324 skip(ci, instr_len-1); 1325 break; 1326 } 1327 } 1328 return 1; 1329 } 1330 1331 static void 1332 write_instruction(MethodImage *mi) 1333 { 1334 CrwClassImage * ci; 1335 ClassOpcode opcode; 1336 ByteOffset new_code_len; 1337 int pos; 1338 int new_pos; 1339 1340 CRW_ASSERT_MI(mi); 1341 ci = mi->ci; 1342 pos = input_code_offset(mi); 1343 new_pos = method_code_map(mi,pos); 1344 new_code_len = mi->injections[pos].len; 1345 if (new_code_len > 0) { 1346 write_bytes(ci, (void*)mi->injections[pos].code, new_code_len); 1347 } 1348 1349 opcode = readU1(ci); 1350 if (opcode == JVM_OPC_wide) { 1351 ClassOpcode wopcode; 1352 1353 writeU1(ci, opcode); 1354 1355 wopcode = copyU1(ci); 1356 /* lvIndex not used */ 1357 (void)copyU2(ci); 1358 verify_opc_wide(ci, wopcode); 1359 if ( wopcode==JVM_OPC_iinc ) { 1360 (void)copyU1(ci); 1361 (void)copyU1(ci); 1362 } 1363 } else { 1364 1365 ClassOpcode new_opcode; 1366 int header; 1367 int newHeader; 1368 int low; 1369 int high; 1370 int i; 1371 int npairs; 1372 int widened; 1373 int instr_len; 1374 int delta; 1375 int new_delta; 1376 1377 switch (opcode) { 1378 1379 case JVM_OPC_tableswitch: 1380 header = NEXT_4BYTE_BOUNDARY(pos); 1381 newHeader = NEXT_4BYTE_BOUNDARY(new_pos); 1382 1383 skip(ci, header - (pos+1)); 1384 1385 delta = readU4(ci); 1386 new_delta = method_code_map(mi,pos+delta) - new_pos; 1387 low = readU4(ci); 1388 high = readU4(ci); 1389 1390 writeU1(ci, opcode); 1391 for (i = new_pos+1; i < newHeader; ++i) { 1392 writeU1(ci, 0); 1393 } 1394 writeU4(ci, new_delta); 1395 writeU4(ci, low); 1396 writeU4(ci, high); 1397 1398 for (i = low; i <= high; ++i) { 1399 delta = readU4(ci); 1400 new_delta = method_code_map(mi,pos+delta) - new_pos; 1401 writeU4(ci, new_delta); 1402 } 1403 break; 1404 1405 case JVM_OPC_lookupswitch: 1406 header = NEXT_4BYTE_BOUNDARY(pos); 1407 newHeader = NEXT_4BYTE_BOUNDARY(new_pos); 1408 1409 skip(ci, header - (pos+1)); 1410 1411 delta = readU4(ci); 1412 new_delta = method_code_map(mi,pos+delta) - new_pos; 1413 npairs = readU4(ci); 1414 writeU1(ci, opcode); 1415 for (i = new_pos+1; i < newHeader; ++i) { 1416 writeU1(ci, 0); 1417 } 1418 writeU4(ci, new_delta); 1419 writeU4(ci, npairs); 1420 for (i = 0; i< npairs; ++i) { 1421 unsigned match = readU4(ci); 1422 delta = readU4(ci); 1423 new_delta = method_code_map(mi,pos+delta) - new_pos; 1424 writeU4(ci, match); 1425 writeU4(ci, new_delta); 1426 } 1427 break; 1428 1429 case JVM_OPC_jsr: case JVM_OPC_goto: 1430 case JVM_OPC_ifeq: case JVM_OPC_ifge: case JVM_OPC_ifgt: 1431 case JVM_OPC_ifle: case JVM_OPC_iflt: case JVM_OPC_ifne: 1432 case JVM_OPC_if_icmpeq: case JVM_OPC_if_icmpne: case JVM_OPC_if_icmpge: 1433 case JVM_OPC_if_icmpgt: case JVM_OPC_if_icmple: case JVM_OPC_if_icmplt: 1434 case JVM_OPC_if_acmpeq: case JVM_OPC_if_acmpne: 1435 case JVM_OPC_ifnull: case JVM_OPC_ifnonnull: 1436 widened = mi->widening[pos]; 1437 delta = readS2(ci); 1438 new_delta = method_code_map(mi,pos+delta) - new_pos; 1439 new_opcode = opcode; 1440 if (widened == 0) { 1441 writeU1(ci, opcode); 1442 writeU2(ci, new_delta); 1443 } else if (widened == 2) { 1444 switch (opcode) { 1445 case JVM_OPC_jsr: 1446 new_opcode = JVM_OPC_jsr_w; 1447 break; 1448 case JVM_OPC_goto: 1449 new_opcode = JVM_OPC_goto_w; 1450 break; 1451 default: 1452 CRW_FATAL(ci, "unexpected opcode"); 1453 break; 1454 } 1455 writeU1(ci, new_opcode); 1456 writeU4(ci, new_delta); 1457 } else if (widened == 5) { 1458 switch (opcode) { 1459 case JVM_OPC_ifeq: 1460 new_opcode = JVM_OPC_ifne; 1461 break; 1462 case JVM_OPC_ifge: 1463 new_opcode = JVM_OPC_iflt; 1464 break; 1465 case JVM_OPC_ifgt: 1466 new_opcode = JVM_OPC_ifle; 1467 break; 1468 case JVM_OPC_ifle: 1469 new_opcode = JVM_OPC_ifgt; 1470 break; 1471 case JVM_OPC_iflt: 1472 new_opcode = JVM_OPC_ifge; 1473 break; 1474 case JVM_OPC_ifne: 1475 new_opcode = JVM_OPC_ifeq; 1476 break; 1477 case JVM_OPC_if_icmpeq: 1478 new_opcode = JVM_OPC_if_icmpne; 1479 break; 1480 case JVM_OPC_if_icmpne: 1481 new_opcode = JVM_OPC_if_icmpeq; 1482 break; 1483 case JVM_OPC_if_icmpge: 1484 new_opcode = JVM_OPC_if_icmplt; 1485 break; 1486 case JVM_OPC_if_icmpgt: 1487 new_opcode = JVM_OPC_if_icmple; 1488 break; 1489 case JVM_OPC_if_icmple: 1490 new_opcode = JVM_OPC_if_icmpgt; 1491 break; 1492 case JVM_OPC_if_icmplt: 1493 new_opcode = JVM_OPC_if_icmpge; 1494 break; 1495 case JVM_OPC_if_acmpeq: 1496 new_opcode = JVM_OPC_if_acmpne; 1497 break; 1498 case JVM_OPC_if_acmpne: 1499 new_opcode = JVM_OPC_if_acmpeq; 1500 break; 1501 case JVM_OPC_ifnull: 1502 new_opcode = JVM_OPC_ifnonnull; 1503 break; 1504 case JVM_OPC_ifnonnull: 1505 new_opcode = JVM_OPC_ifnull; 1506 break; 1507 default: 1508 CRW_FATAL(ci, "Unexpected opcode"); 1509 break; 1510 } 1511 writeU1(ci, new_opcode); /* write inverse branch */ 1512 writeU2(ci, 3 + 5); /* beyond if and goto_w */ 1513 writeU1(ci, JVM_OPC_goto_w); /* add a goto_w */ 1514 writeU4(ci, new_delta-3); /* write new and wide delta */ 1515 } else { 1516 CRW_FATAL(ci, "Unexpected widening"); 1517 } 1518 break; 1519 1520 case JVM_OPC_jsr_w: 1521 case JVM_OPC_goto_w: 1522 delta = readU4(ci); 1523 new_delta = method_code_map(mi,pos+delta) - new_pos; 1524 writeU1(ci, opcode); 1525 writeU4(ci, new_delta); 1526 break; 1527 1528 default: 1529 instr_len = opcode_length(ci, opcode); 1530 writeU1(ci, opcode); 1531 copy(ci, instr_len-1); 1532 break; 1533 } 1534 } 1535 } 1536 1537 static void 1538 method_inject_and_write_code(MethodImage *mi) 1539 { 1540 ByteCode bytecodes[LARGEST_INJECTION+1]; 1541 ByteOffset len; 1542 1543 CRW_ASSERT_MI(mi); 1544 1545 /* Do injections */ 1546 rewind_to_beginning_of_input_bytecodes(mi); 1547 len = entry_injection_code(mi, bytecodes, (int)sizeof(bytecodes)); 1548 if ( len > 0 ) { 1549 int pos; 1550 1551 pos = 0; 1552 inject_bytecodes(mi, pos, bytecodes, len); 1553 /* Adjust pos 0 to map to new pos 0, you never want to 1554 * jump into this entry code injection. So the new pos 0 1555 * will be past this entry_injection_code(). 1556 */ 1557 adjust_map(mi, pos, len); /* Inject before behavior */ 1558 } 1559 while (input_code_offset(mi) < mi->code_len) { 1560 inject_for_opcode(mi); 1561 } 1562 1563 /* Adjust instructions */ 1564 rewind_to_beginning_of_input_bytecodes(mi); 1565 while (input_code_offset(mi) < mi->code_len) { 1566 if (!adjust_instruction(mi)) { 1567 rewind_to_beginning_of_input_bytecodes(mi); 1568 } 1569 } 1570 1571 /* Write new instructions */ 1572 rewind_to_beginning_of_input_bytecodes(mi); 1573 while (input_code_offset(mi) < mi->code_len) { 1574 write_instruction(mi); 1575 } 1576 } 1577 1578 static void 1579 copy_attribute(CrwClassImage *ci) 1580 { 1581 int len; 1582 1583 (void)copyU2(ci); 1584 len = copyU4(ci); 1585 copy(ci, len); 1586 } 1587 1588 static void 1589 copy_attributes(CrwClassImage *ci) 1590 { 1591 unsigned i; 1592 unsigned count; 1593 1594 count = copyU2(ci); 1595 for (i = 0; i < count; ++i) { 1596 copy_attribute(ci); 1597 } 1598 } 1599 1600 static void 1601 copy_all_fields(CrwClassImage *ci) 1602 { 1603 unsigned i; 1604 unsigned count; 1605 1606 count = copyU2(ci); 1607 for (i = 0; i < count; ++i) { 1608 /* access, name, descriptor */ 1609 copy(ci, 6); 1610 copy_attributes(ci); 1611 } 1612 } 1613 1614 static void 1615 write_line_table(MethodImage *mi) 1616 { 1617 unsigned i; 1618 unsigned count; 1619 CrwClassImage * ci; 1620 1621 CRW_ASSERT_MI(mi); 1622 ci = mi->ci; 1623 (void)copyU4(ci); 1624 count = copyU2(ci); 1625 for(i=0; i<count; i++) { 1626 ByteOffset start_pc; 1627 ByteOffset new_start_pc; 1628 1629 start_pc = readU2(ci); 1630 1631 if ( start_pc == 0 ) { 1632 new_start_pc = 0; /* Don't skip entry injection code. */ 1633 } else { 1634 new_start_pc = method_code_map(mi, start_pc); 1635 } 1636 1637 writeU2(ci, new_start_pc); 1638 (void)copyU2(ci); 1639 } 1640 } 1641 1642 /* Used for LocalVariableTable and LocalVariableTypeTable attributes */ 1643 static void 1644 write_var_table(MethodImage *mi) 1645 { 1646 unsigned i; 1647 unsigned count; 1648 CrwClassImage * ci; 1649 1650 CRW_ASSERT_MI(mi); 1651 ci = mi->ci; 1652 (void)copyU4(ci); 1653 count = copyU2(ci); 1654 for(i=0; i<count; i++) { 1655 ByteOffset start_pc; 1656 ByteOffset new_start_pc; 1657 ByteOffset length; 1658 ByteOffset new_length; 1659 ByteOffset end_pc; 1660 ByteOffset new_end_pc; 1661 1662 start_pc = readU2(ci); 1663 length = readU2(ci); 1664 1665 if ( start_pc == 0 ) { 1666 new_start_pc = 0; /* Don't skip entry injection code. */ 1667 } else { 1668 new_start_pc = method_code_map(mi, start_pc); 1669 } 1670 end_pc = start_pc + length; 1671 new_end_pc = method_code_map(mi, end_pc); 1672 new_length = new_end_pc - new_start_pc; 1673 1674 writeU2(ci, new_start_pc); 1675 writeU2(ci, new_length); 1676 (void)copyU2(ci); 1677 (void)copyU2(ci); 1678 (void)copyU2(ci); 1679 } 1680 } 1681 1682 /* The uoffset field is u2 or u4 depending on the code_len. 1683 * Note that the code_len is likely changing, so be careful here. 1684 */ 1685 static unsigned 1686 readUoffset(MethodImage *mi) 1687 { 1688 if ( mi->code_len > 65535 ) { 1689 return readU4(mi->ci); 1690 } 1691 return readU2(mi->ci); 1692 } 1693 1694 static void 1695 writeUoffset(MethodImage *mi, unsigned val) 1696 { 1697 if ( mi->new_code_len > 65535 ) { 1698 writeU4(mi->ci, val); 1699 } 1700 writeU2(mi->ci, val); 1701 } 1702 1703 static unsigned 1704 copyUoffset(MethodImage *mi) 1705 { 1706 unsigned uoffset; 1707 1708 uoffset = readUoffset(mi); 1709 writeUoffset(mi, uoffset); 1710 return uoffset; 1711 } 1712 1713 /* Copy over verification_type_info structure */ 1714 static void 1715 copy_verification_types(MethodImage *mi, int ntypes) 1716 { 1717 /* If there were ntypes, we just copy that over, no changes */ 1718 if ( ntypes > 0 ) { 1719 int j; 1720 1721 for ( j = 0 ; j < ntypes ; j++ ) { 1722 unsigned tag; 1723 1724 tag = copyU1(mi->ci); 1725 switch ( tag ) { 1726 case JVM_ITEM_Object: 1727 (void)copyU2(mi->ci); /* Constant pool entry */ 1728 break; 1729 case JVM_ITEM_Uninitialized: 1730 /* Code offset for 'new' opcode is for this object */ 1731 writeUoffset(mi, method_code_map(mi, readUoffset(mi))); 1732 break; 1733 } 1734 } 1735 } 1736 } 1737 1738 /* Process the StackMapTable attribute. We didn't add any basic blocks 1739 * so the frame count remains the same but we may need to process the 1740 * frame types due to offset changes putting things out of range. 1741 */ 1742 static void 1743 write_stackmap_table(MethodImage *mi) 1744 { 1745 CrwClassImage *ci; 1746 CrwPosition save_position; 1747 ByteOffset last_pc; 1748 ByteOffset last_new_pc; 1749 unsigned i; 1750 unsigned attr_len; 1751 unsigned new_attr_len; 1752 unsigned count; 1753 unsigned delta_adj; 1754 1755 CRW_ASSERT_MI(mi); 1756 ci = mi->ci; 1757 1758 /* Save the position of the attribute length so we can fix it later */ 1759 save_position = ci->output_position; 1760 attr_len = copyU4(ci); 1761 count = copyUoffset(mi); /* uoffset: number_of_entries */ 1762 if ( count == 0 ) { 1763 CRW_ASSERT(ci, attr_len==2); 1764 return; 1765 } 1766 1767 /* Process entire stackmap */ 1768 last_pc = 0; 1769 last_new_pc = 0; 1770 delta_adj = 0; 1771 for ( i = 0 ; i < count ; i++ ) { 1772 ByteOffset new_pc=0; /* new pc in instrumented code */ 1773 unsigned ft; /* frame_type */ 1774 int delta=0; /* pc delta */ 1775 int new_delta=0; /* new pc delta */ 1776 1777 ft = readU1(ci); 1778 if ( ft <= 63 ) { 1779 /* Frame Type: same_frame ([0,63]) */ 1780 unsigned new_ft; /* new frame_type */ 1781 1782 delta = (delta_adj + ft); 1783 new_pc = method_code_map(mi, last_pc + delta); 1784 new_delta = new_pc - last_new_pc; 1785 new_ft = (new_delta - delta_adj); 1786 if ( new_ft > 63 ) { 1787 /* Change to same_frame_extended (251) */ 1788 new_ft = 251; 1789 writeU1(ci, new_ft); 1790 writeUoffset(mi, (new_delta - delta_adj)); 1791 } else { 1792 writeU1(ci, new_ft); 1793 } 1794 } else if ( ft >= 64 && ft <= 127 ) { 1795 /* Frame Type: same_locals_1_stack_item_frame ([64,127]) */ 1796 unsigned new_ft; /* new frame_type */ 1797 1798 delta = (delta_adj + ft - 64); 1799 new_pc = method_code_map(mi, last_pc + delta); 1800 new_delta = new_pc - last_new_pc; 1801 if ( (new_delta - delta_adj) > 63 ) { 1802 /* Change to same_locals_1_stack_item_frame_extended (247) */ 1803 new_ft = 247; 1804 writeU1(ci, new_ft); 1805 writeUoffset(mi, (new_delta - delta_adj)); 1806 } else { 1807 new_ft = (new_delta - delta_adj) + 64; 1808 writeU1(ci, new_ft); 1809 } 1810 copy_verification_types(mi, 1); 1811 } else if ( ft >= 128 && ft <= 246 ) { 1812 /* Frame Type: reserved_for_future_use ([128,246]) */ 1813 CRW_FATAL(ci, "Unknown frame type in StackMapTable attribute"); 1814 } else if ( ft == 247 ) { 1815 /* Frame Type: same_locals_1_stack_item_frame_extended (247) */ 1816 delta = (delta_adj + readUoffset(mi)); 1817 new_pc = method_code_map(mi, last_pc + delta); 1818 new_delta = new_pc - last_new_pc; 1819 writeU1(ci, ft); 1820 writeUoffset(mi, (new_delta - delta_adj)); 1821 copy_verification_types(mi, 1); 1822 } else if ( ft >= 248 && ft <= 250 ) { 1823 /* Frame Type: chop_frame ([248,250]) */ 1824 delta = (delta_adj + readUoffset(mi)); 1825 new_pc = method_code_map(mi, last_pc + delta); 1826 new_delta = new_pc - last_new_pc; 1827 writeU1(ci, ft); 1828 writeUoffset(mi, (new_delta - delta_adj)); 1829 } else if ( ft == 251 ) { 1830 /* Frame Type: same_frame_extended (251) */ 1831 delta = (delta_adj + readUoffset(mi)); 1832 new_pc = method_code_map(mi, last_pc + delta); 1833 new_delta = new_pc - last_new_pc; 1834 writeU1(ci, ft); 1835 writeUoffset(mi, (new_delta - delta_adj)); 1836 } else if ( ft >= 252 && ft <= 254 ) { 1837 /* Frame Type: append_frame ([252,254]) */ 1838 delta = (delta_adj + readUoffset(mi)); 1839 new_pc = method_code_map(mi, last_pc + delta); 1840 new_delta = new_pc - last_new_pc; 1841 writeU1(ci, ft); 1842 writeUoffset(mi, (new_delta - delta_adj)); 1843 copy_verification_types(mi, (ft - 251)); 1844 } else if ( ft == 255 ) { 1845 unsigned ntypes; 1846 1847 /* Frame Type: full_frame (255) */ 1848 delta = (delta_adj + readUoffset(mi)); 1849 new_pc = method_code_map(mi, last_pc + delta); 1850 new_delta = new_pc - last_new_pc; 1851 writeU1(ci, ft); 1852 writeUoffset(mi, (new_delta - delta_adj)); 1853 ntypes = copyU2(ci); /* ulocalvar */ 1854 copy_verification_types(mi, ntypes); 1855 ntypes = copyU2(ci); /* ustack */ 1856 copy_verification_types(mi, ntypes); 1857 } 1858 1859 /* Update last_pc and last_new_pc (save on calls to method_code_map) */ 1860 CRW_ASSERT(ci, delta >= 0); 1861 CRW_ASSERT(ci, new_delta >= 0); 1862 last_pc += delta; 1863 last_new_pc = new_pc; 1864 CRW_ASSERT(ci, last_pc <= mi->code_len); 1865 CRW_ASSERT(ci, last_new_pc <= mi->new_code_len); 1866 1867 /* Delta adjustment, all deltas are -1 now in attribute */ 1868 delta_adj = 1; 1869 } 1870 1871 /* Update the attribute length */ 1872 new_attr_len = ci->output_position - (save_position + 4); 1873 CRW_ASSERT(ci, new_attr_len >= attr_len); 1874 random_writeU4(ci, save_position, new_attr_len); 1875 } 1876 1877 /* Process the CLDC StackMap attribute. We didn't add any basic blocks 1878 * so the frame count remains the same but we may need to process the 1879 * frame types due to offset changes putting things out of range. 1880 */ 1881 static void 1882 write_cldc_stackmap_table(MethodImage *mi) 1883 { 1884 CrwClassImage *ci; 1885 CrwPosition save_position; 1886 unsigned i; 1887 unsigned attr_len; 1888 unsigned new_attr_len; 1889 unsigned count; 1890 1891 CRW_ASSERT_MI(mi); 1892 ci = mi->ci; 1893 1894 /* Save the position of the attribute length so we can fix it later */ 1895 save_position = ci->output_position; 1896 attr_len = copyU4(ci); 1897 count = copyUoffset(mi); /* uoffset: number_of_entries */ 1898 if ( count == 0 ) { 1899 CRW_ASSERT(ci, attr_len==2); 1900 return; 1901 } 1902 1903 /* Process entire stackmap */ 1904 for ( i = 0 ; i < count ; i++ ) { 1905 unsigned ntypes; 1906 1907 writeUoffset(mi, method_code_map(mi, readUoffset(mi))); 1908 ntypes = copyU2(ci); /* ulocalvar */ 1909 copy_verification_types(mi, ntypes); 1910 ntypes = copyU2(ci); /* ustack */ 1911 copy_verification_types(mi, ntypes); 1912 } 1913 1914 /* Update the attribute length */ 1915 new_attr_len = ci->output_position - (save_position + 4); 1916 CRW_ASSERT(ci, new_attr_len >= attr_len); 1917 random_writeU4(ci, save_position, new_attr_len); 1918 } 1919 1920 static void 1921 method_write_exception_table(MethodImage *mi) 1922 { 1923 unsigned i; 1924 unsigned count; 1925 CrwClassImage * ci; 1926 1927 CRW_ASSERT_MI(mi); 1928 ci = mi->ci; 1929 count = copyU2(ci); 1930 for(i=0; i<count; i++) { 1931 ByteOffset start_pc; 1932 ByteOffset new_start_pc; 1933 ByteOffset end_pc; 1934 ByteOffset new_end_pc; 1935 ByteOffset handler_pc; 1936 ByteOffset new_handler_pc; 1937 1938 start_pc = readU2(ci); 1939 end_pc = readU2(ci); 1940 handler_pc = readU2(ci); 1941 1942 new_start_pc = method_code_map(mi, start_pc); 1943 new_end_pc = method_code_map(mi, end_pc); 1944 new_handler_pc = method_code_map(mi, handler_pc); 1945 1946 writeU2(ci, new_start_pc); 1947 writeU2(ci, new_end_pc); 1948 writeU2(ci, new_handler_pc); 1949 (void)copyU2(ci); 1950 } 1951 } 1952 1953 static int 1954 attribute_match(CrwClassImage *ci, CrwCpoolIndex name_index, const char *name) 1955 { 1956 CrwConstantPoolEntry cs; 1957 int len; 1958 1959 CRW_ASSERT_CI(ci); 1960 CRW_ASSERT(ci, name!=NULL); 1961 len = (int)strlen(name); 1962 cs = cpool_entry(ci, name_index); 1963 if ( cs.len==len && strncmp(cs.ptr, name, len)==0) { 1964 return 1; 1965 } 1966 return 0; 1967 } 1968 1969 static void 1970 method_write_code_attribute(MethodImage *mi) 1971 { 1972 CrwClassImage * ci; 1973 CrwCpoolIndex name_index; 1974 1975 CRW_ASSERT_MI(mi); 1976 ci = mi->ci; 1977 name_index = copyU2(ci); 1978 if ( attribute_match(ci, name_index, "LineNumberTable") ) { 1979 write_line_table(mi); 1980 } else if ( attribute_match(ci, name_index, "LocalVariableTable") ) { 1981 write_var_table(mi); 1982 } else if ( attribute_match(ci, name_index, "LocalVariableTypeTable") ) { 1983 write_var_table(mi); /* Exact same format as the LocalVariableTable */ 1984 } else if ( attribute_match(ci, name_index, "StackMapTable") ) { 1985 write_stackmap_table(mi); 1986 } else if ( attribute_match(ci, name_index, "StackMap") ) { 1987 write_cldc_stackmap_table(mi); 1988 } else { 1989 unsigned len; 1990 len = copyU4(ci); 1991 copy(ci, len); 1992 } 1993 } 1994 1995 static int 1996 is_init_method(const char *name) 1997 { 1998 if ( name!=NULL && strcmp(name,"<init>")==0 ) { 1999 return JNI_TRUE; 2000 } 2001 return JNI_FALSE; 2002 } 2003 2004 static int 2005 is_clinit_method(const char *name) 2006 { 2007 if ( name!=NULL && strcmp(name,"<clinit>")==0 ) { 2008 return JNI_TRUE; 2009 } 2010 return JNI_FALSE; 2011 } 2012 2013 static int 2014 is_finalize_method(const char *name) 2015 { 2016 if ( name!=NULL && strcmp(name,"finalize")==0 ) { 2017 return JNI_TRUE; 2018 } 2019 return JNI_FALSE; 2020 } 2021 2022 static int 2023 skip_method(CrwClassImage *ci, const char *name, 2024 unsigned access_flags, ByteOffset code_len, 2025 int system_class, jboolean *pskip_call_return_sites) 2026 { 2027 *pskip_call_return_sites = JNI_FALSE; 2028 if ( system_class ) { 2029 if ( code_len == 1 && is_init_method(name) ) { 2030 return JNI_TRUE; 2031 } else if ( code_len == 1 && is_finalize_method(name) ) { 2032 return JNI_TRUE; 2033 } else if ( is_clinit_method(name) ) { 2034 return JNI_TRUE; 2035 } else if ( ci->is_thread_class && strcmp(name,"currentThread")==0 ) { 2036 return JNI_TRUE; 2037 } 2038 /* 2039 if ( access_flags & JVM_ACC_PRIVATE ) { 2040 *pskip_call_return_sites = JNI_TRUE; 2041 } 2042 */ 2043 } 2044 return JNI_FALSE; 2045 } 2046 2047 /* Process all code attributes */ 2048 static void 2049 method_write_bytecodes(CrwClassImage *ci, unsigned mnum, unsigned access_flags) 2050 { 2051 CrwPosition output_attr_len_position; 2052 CrwPosition output_max_stack_position; 2053 CrwPosition output_code_len_position; 2054 CrwPosition start_of_output_bytecodes; 2055 unsigned i; 2056 unsigned attr_len; 2057 unsigned max_stack; 2058 ByteOffset code_len; 2059 unsigned attr_count; 2060 unsigned new_attr_len; 2061 MethodImage * mi; 2062 jboolean object_init_method; 2063 jboolean skip_call_return_sites; 2064 2065 CRW_ASSERT_CI(ci); 2066 2067 /* Attribute Length */ 2068 output_attr_len_position = ci->output_position; 2069 attr_len = copyU4(ci); 2070 2071 /* Max Stack */ 2072 output_max_stack_position = ci->output_position; 2073 max_stack = copyU2(ci); 2074 2075 /* Max Locals */ 2076 (void)copyU2(ci); 2077 2078 /* Code Length */ 2079 output_code_len_position = ci->output_position; 2080 code_len = copyU4(ci); 2081 start_of_output_bytecodes = ci->output_position; 2082 2083 /* Some methods should not be instrumented */ 2084 object_init_method = JNI_FALSE; 2085 skip_call_return_sites = JNI_FALSE; 2086 if ( ci->is_object_class && 2087 is_init_method(ci->method_name[mnum]) && 2088 strcmp(ci->method_descr[mnum],"()V")==0 ) { 2089 object_init_method = JNI_TRUE; 2090 skip_call_return_sites = JNI_TRUE; 2091 } else if ( skip_method(ci, ci->method_name[mnum], access_flags, 2092 code_len, ci->system_class, &skip_call_return_sites) ) { 2093 /* Copy remainder minus already copied, the U2 max_stack, 2094 * U2 max_locals, and U4 code_length fields have already 2095 * been processed. 2096 */ 2097 copy(ci, attr_len - (2+2+4)); 2098 return; 2099 } 2100 2101 /* Start Injection */ 2102 mi = method_init(ci, mnum, code_len); 2103 mi->object_init_method = object_init_method; 2104 mi->access_flags = access_flags; 2105 mi->skip_call_return_sites = skip_call_return_sites; 2106 2107 /* Save the current position as the start of the input bytecodes */ 2108 mi->start_of_input_bytecodes = ci->input_position; 2109 2110 /* The max stack may increase */ 2111 mi->max_stack = max_stack; 2112 mi->new_max_stack = max_stack; 2113 2114 /* Adjust all code offsets */ 2115 method_inject_and_write_code(mi); 2116 2117 /* Fix up code length (save new_code_len for later attribute processing) */ 2118 mi->new_code_len = (int)(ci->output_position - start_of_output_bytecodes); 2119 random_writeU4(ci, output_code_len_position, mi->new_code_len); 2120 2121 /* Fixup max stack */ 2122 CRW_ASSERT(ci, mi->new_max_stack <= 0xFFFF); 2123 random_writeU2(ci, output_max_stack_position, mi->new_max_stack); 2124 2125 /* Copy exception table */ 2126 method_write_exception_table(mi); 2127 2128 /* Copy code attributes (needs mi->new_code_len) */ 2129 attr_count = copyU2(ci); 2130 for (i = 0; i < attr_count; ++i) { 2131 method_write_code_attribute(mi); 2132 } 2133 2134 /* Fix up attribute length */ 2135 new_attr_len = (int)(ci->output_position - (output_attr_len_position + 4)); 2136 random_writeU4(ci, output_attr_len_position, new_attr_len); 2137 2138 /* Free method data */ 2139 method_term(mi); 2140 mi = NULL; 2141 2142 } 2143 2144 static void 2145 method_write(CrwClassImage *ci, unsigned mnum) 2146 { 2147 unsigned i; 2148 unsigned access_flags; 2149 CrwCpoolIndex name_index; 2150 CrwCpoolIndex descr_index; 2151 unsigned attr_count; 2152 2153 access_flags = copyU2(ci); 2154 name_index = copyU2(ci); 2155 ci->method_name[mnum] = cpool_entry(ci, name_index).ptr; 2156 descr_index = copyU2(ci); 2157 ci->method_descr[mnum] = cpool_entry(ci, descr_index).ptr; 2158 attr_count = copyU2(ci); 2159 2160 for (i = 0; i < attr_count; ++i) { 2161 CrwCpoolIndex name_index; 2162 2163 name_index = copyU2(ci); 2164 if ( attribute_match(ci, name_index, "Code") ) { 2165 method_write_bytecodes(ci, mnum, access_flags); 2166 } else { 2167 unsigned len; 2168 len = copyU4(ci); 2169 copy(ci, len); 2170 } 2171 } 2172 } 2173 2174 static void 2175 method_write_all(CrwClassImage *ci) 2176 { 2177 unsigned i; 2178 unsigned count; 2179 2180 count = copyU2(ci); 2181 ci->method_count = count; 2182 if ( count > 0 ) { 2183 ci->method_name = (const char **)allocate_clean(ci, count*(int)sizeof(const char*)); 2184 ci->method_descr = (const char **)allocate_clean(ci, count*(int)sizeof(const char*)); 2185 } 2186 2187 for (i = 0; i < count; ++i) { 2188 method_write(ci, i); 2189 } 2190 2191 if ( ci->mnum_callback != NULL ) { 2192 (*(ci->mnum_callback))(ci->number, ci->method_name, ci->method_descr, 2193 count); 2194 } 2195 } 2196 2197 /* ------------------------------------------------------------------- */ 2198 /* Cleanup function. */ 2199 2200 static void 2201 cleanup(CrwClassImage *ci) 2202 { 2203 CRW_ASSERT_CI(ci); 2204 if ( ci->name != NULL ) { 2205 deallocate(ci, (void*)ci->name); 2206 ci->name = NULL; 2207 } 2208 if ( ci->method_name != NULL ) { 2209 deallocate(ci, (void*)ci->method_name); 2210 ci->method_name = NULL; 2211 } 2212 if ( ci->method_descr != NULL ) { 2213 deallocate(ci, (void*)ci->method_descr); 2214 ci->method_descr = NULL; 2215 } 2216 if ( ci->cpool != NULL ) { 2217 CrwCpoolIndex i; 2218 for(i=0; i<ci->cpool_count_plus_one; i++) { 2219 if ( ci->cpool[i].ptr != NULL ) { 2220 deallocate(ci, (void*)(ci->cpool[i].ptr)); 2221 ci->cpool[i].ptr = NULL; 2222 } 2223 } 2224 deallocate(ci, (void*)ci->cpool); 2225 ci->cpool = NULL; 2226 } 2227 } 2228 2229 static jboolean 2230 skip_class(unsigned access_flags) 2231 { 2232 if ( access_flags & JVM_ACC_INTERFACE ) { 2233 return JNI_TRUE; 2234 } 2235 return JNI_FALSE; 2236 } 2237 2238 static long 2239 inject_class(struct CrwClassImage *ci, 2240 int system_class, 2241 char* tclass_name, 2242 char* tclass_sig, 2243 char* call_name, 2244 char* call_sig, 2245 char* return_name, 2246 char* return_sig, 2247 char* obj_init_name, 2248 char* obj_init_sig, 2249 char* newarray_name, 2250 char* newarray_sig, 2251 unsigned char *buf, 2252 long buf_len) 2253 { 2254 CrwConstantPoolEntry cs; 2255 CrwCpoolIndex this_class; 2256 CrwCpoolIndex super_class; 2257 unsigned magic; 2258 unsigned classfileMajorVersion; 2259 unsigned classfileMinorVersion; 2260 unsigned interface_count; 2261 2262 CRW_ASSERT_CI(ci); 2263 CRW_ASSERT(ci, buf!=NULL); 2264 CRW_ASSERT(ci, buf_len!=0); 2265 2266 CRW_ASSERT(ci, strchr(tclass_name,'.')==NULL); /* internal qualified name */ 2267 2268 ci->injection_count = 0; 2269 ci->system_class = system_class; 2270 ci->tclass_name = tclass_name; 2271 ci->tclass_sig = tclass_sig; 2272 ci->call_name = call_name; 2273 ci->call_sig = call_sig; 2274 ci->return_name = return_name; 2275 ci->return_sig = return_sig; 2276 ci->obj_init_name = obj_init_name; 2277 ci->obj_init_sig = obj_init_sig; 2278 ci->newarray_name = newarray_name; 2279 ci->newarray_sig = newarray_sig; 2280 ci->output = buf; 2281 ci->output_len = buf_len; 2282 2283 magic = copyU4(ci); 2284 CRW_ASSERT(ci, magic==0xCAFEBABE); 2285 if ( magic != 0xCAFEBABE ) { 2286 return (long)0; 2287 } 2288 2289 /* minor version number not used */ 2290 classfileMinorVersion = copyU2(ci); 2291 /* major version number not used */ 2292 classfileMajorVersion = copyU2(ci); 2293 CRW_ASSERT(ci, (classfileMajorVersion <= JVM_CLASSFILE_MAJOR_VERSION) || 2294 ((classfileMajorVersion == JVM_CLASSFILE_MAJOR_VERSION) && 2295 (classfileMinorVersion <= JVM_CLASSFILE_MINOR_VERSION))); 2296 2297 cpool_setup(ci); 2298 2299 ci->access_flags = copyU2(ci); 2300 if ( skip_class(ci->access_flags) ) { 2301 return (long)0; 2302 } 2303 2304 this_class = copyU2(ci); 2305 2306 cs = cpool_entry(ci, (CrwCpoolIndex)(cpool_entry(ci, this_class).index1)); 2307 if ( ci->name == NULL ) { 2308 ci->name = duplicate(ci, cs.ptr, cs.len); 2309 CRW_ASSERT(ci, strchr(ci->name,'.')==NULL); /* internal qualified name */ 2310 } 2311 CRW_ASSERT(ci, (int)strlen(ci->name)==cs.len && strncmp(ci->name, cs.ptr, cs.len)==0); 2312 2313 super_class = copyU2(ci); 2314 if ( super_class == 0 ) { 2315 ci->is_object_class = JNI_TRUE; 2316 CRW_ASSERT(ci, strcmp(ci->name,"java/lang/Object")==0); 2317 } 2318 2319 interface_count = copyU2(ci); 2320 copy(ci, interface_count * 2); 2321 2322 copy_all_fields(ci); 2323 2324 method_write_all(ci); 2325 2326 if ( ci->injection_count == 0 ) { 2327 return (long)0; 2328 } 2329 2330 copy_attributes(ci); 2331 2332 return (long)ci->output_position; 2333 } 2334 2335 /* ------------------------------------------------------------------- */ 2336 /* Exported interfaces */ 2337 2338 JNIEXPORT void JNICALL 2339 java_crw_demo(unsigned class_number, 2340 const char *name, 2341 const unsigned char *file_image, 2342 long file_len, 2343 int system_class, 2344 char* tclass_name, /* Name of class that has tracker methods. */ 2345 char* tclass_sig, /* Signature of tclass */ 2346 char* call_name, /* Method name to call at offset 0 */ 2347 char* call_sig, /* Signature of this method */ 2348 char* return_name, /* Method name to call before any return */ 2349 char* return_sig, /* Signature of this method */ 2350 char* obj_init_name, /* Method name to call in Object <init> */ 2351 char* obj_init_sig, /* Signature of this method */ 2352 char* newarray_name, /* Method name to call after newarray opcodes */ 2353 char* newarray_sig, /* Signature of this method */ 2354 unsigned char **pnew_file_image, 2355 long *pnew_file_len, 2356 FatalErrorHandler fatal_error_handler, 2357 MethodNumberRegister mnum_callback) 2358 { 2359 CrwClassImage ci; 2360 long max_length; 2361 long new_length; 2362 void *new_image; 2363 int len; 2364 2365 /* Initial setup of the CrwClassImage structure */ 2366 (void)memset(&ci, 0, (int)sizeof(CrwClassImage)); 2367 ci.fatal_error_handler = fatal_error_handler; 2368 ci.mnum_callback = mnum_callback; 2369 2370 /* Do some interface error checks */ 2371 if ( pnew_file_image==NULL ) { 2372 CRW_FATAL(&ci, "pnew_file_image==NULL"); 2373 } 2374 if ( pnew_file_len==NULL ) { 2375 CRW_FATAL(&ci, "pnew_file_len==NULL"); 2376 } 2377 2378 /* No file length means do nothing */ 2379 *pnew_file_image = NULL; 2380 *pnew_file_len = 0; 2381 if ( file_len==0 ) { 2382 return; 2383 } 2384 2385 /* Do some more interface error checks */ 2386 if ( file_image == NULL ) { 2387 CRW_FATAL(&ci, "file_image == NULL"); 2388 } 2389 if ( file_len < 0 ) { 2390 CRW_FATAL(&ci, "file_len < 0"); 2391 } 2392 if ( system_class != 0 && system_class != 1 ) { 2393 CRW_FATAL(&ci, "system_class is not 0 or 1"); 2394 } 2395 if ( tclass_name == NULL ) { 2396 CRW_FATAL(&ci, "tclass_name == NULL"); 2397 } 2398 if ( tclass_sig == NULL || tclass_sig[0]!='L' ) { 2399 CRW_FATAL(&ci, "tclass_sig is not a valid class signature"); 2400 } 2401 len = (int)strlen(tclass_sig); 2402 if ( tclass_sig[len-1]!=';' ) { 2403 CRW_FATAL(&ci, "tclass_sig is not a valid class signature"); 2404 } 2405 if ( call_name != NULL ) { 2406 if ( call_sig == NULL || strcmp(call_sig, "(II)V") != 0 ) { 2407 CRW_FATAL(&ci, "call_sig is not (II)V"); 2408 } 2409 } 2410 if ( return_name != NULL ) { 2411 if ( return_sig == NULL || strcmp(return_sig, "(II)V") != 0 ) { 2412 CRW_FATAL(&ci, "return_sig is not (II)V"); 2413 } 2414 } 2415 if ( obj_init_name != NULL ) { 2416 if ( obj_init_sig == NULL || strcmp(obj_init_sig, "(Ljava/lang/Object;)V") != 0 ) { 2417 CRW_FATAL(&ci, "obj_init_sig is not (Ljava/lang/Object;)V"); 2418 } 2419 } 2420 if ( newarray_name != NULL ) { 2421 if ( newarray_sig == NULL || strcmp(newarray_sig, "(Ljava/lang/Object;)V") != 0 ) { 2422 CRW_FATAL(&ci, "newarray_sig is not (Ljava/lang/Object;)V"); 2423 } 2424 } 2425 2426 /* Finish setup the CrwClassImage structure */ 2427 ci.is_thread_class = JNI_FALSE; 2428 if ( name != NULL ) { 2429 CRW_ASSERT(&ci, strchr(name,'.')==NULL); /* internal qualified name */ 2430 2431 ci.name = duplicate(&ci, name, (int)strlen(name)); 2432 if ( strcmp(name, "java/lang/Thread")==0 ) { 2433 ci.is_thread_class = JNI_TRUE; 2434 } 2435 } 2436 ci.number = class_number; 2437 ci.input = file_image; 2438 ci.input_len = file_len; 2439 2440 /* Do the injection */ 2441 max_length = file_len*2 + 512; /* Twice as big + 512 */ 2442 new_image = allocate(&ci, (int)max_length); 2443 new_length = inject_class(&ci, 2444 system_class, 2445 tclass_name, 2446 tclass_sig, 2447 call_name, 2448 call_sig, 2449 return_name, 2450 return_sig, 2451 obj_init_name, 2452 obj_init_sig, 2453 newarray_name, 2454 newarray_sig, 2455 new_image, 2456 max_length); 2457 2458 /* Dispose or shrink the space to be returned. */ 2459 if ( new_length == 0 ) { 2460 deallocate(&ci, (void*)new_image); 2461 new_image = NULL; 2462 } else { 2463 new_image = (void*)reallocate(&ci, (void*)new_image, (int)new_length); 2464 } 2465 2466 /* Return the new class image */ 2467 *pnew_file_image = (unsigned char *)new_image; 2468 *pnew_file_len = (long)new_length; 2469 2470 /* Cleanup before we leave. */ 2471 cleanup(&ci); 2472 } 2473 2474 /* Return the classname for this class which is inside the classfile image. */ 2475 JNIEXPORT char * JNICALL 2476 java_crw_demo_classname(const unsigned char *file_image, long file_len, 2477 FatalErrorHandler fatal_error_handler) 2478 { 2479 CrwClassImage ci; 2480 CrwConstantPoolEntry cs; 2481 CrwCpoolIndex this_class; 2482 unsigned magic; 2483 char * name; 2484 2485 name = NULL; 2486 2487 if ( file_len==0 || file_image==NULL ) { 2488 return name; 2489 } 2490 2491 /* The only fields we need filled in are the image pointer and the error 2492 * handler. 2493 * By not adding an output buffer pointer, no output is created. 2494 */ 2495 (void)memset(&ci, 0, (int)sizeof(CrwClassImage)); 2496 ci.input = file_image; 2497 ci.input_len = file_len; 2498 ci.fatal_error_handler = fatal_error_handler; 2499 2500 /* Read out the bytes from the classfile image */ 2501 2502 magic = readU4(&ci); /* magic number */ 2503 CRW_ASSERT(&ci, magic==0xCAFEBABE); 2504 if ( magic != 0xCAFEBABE ) { 2505 return name; 2506 } 2507 (void)readU2(&ci); /* minor version number */ 2508 (void)readU2(&ci); /* major version number */ 2509 2510 /* Read in constant pool. Since no output setup, writes are NOP's */ 2511 cpool_setup(&ci); 2512 2513 (void)readU2(&ci); /* access flags */ 2514 this_class = readU2(&ci); /* 'this' class */ 2515 2516 /* Get 'this' constant pool entry */ 2517 cs = cpool_entry(&ci, (CrwCpoolIndex)(cpool_entry(&ci, this_class).index1)); 2518 2519 /* Duplicate the name */ 2520 name = (char *)duplicate(&ci, cs.ptr, cs.len); 2521 2522 /* Cleanup before we leave. */ 2523 cleanup(&ci); 2524 2525 /* Return malloc space */ 2526 return name; 2527 }