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