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 }