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