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