1 /* 2 * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.openjdk.asmtools.jdis; 24 25 import static java.lang.String.format; 26 import static org.openjdk.asmtools.jasm.Tables.*; 27 import static org.openjdk.asmtools.jdis.TraceUtils.mapToHexString; 28 import static org.openjdk.asmtools.jdis.TraceUtils.traceln; 29 30 import java.io.DataInputStream; 31 import java.io.EOFException; 32 import java.io.IOException; 33 34 /** 35 * represents one entry of StackMap attribute 36 */ 37 class StackMapData { 38 static int prevFramePC = 0; 39 boolean isStackMapTable = false; 40 StackMapFrameType stackFrameType = null; 41 int start_pc; 42 int[] lockMap; 43 int[] stackMap; 44 45 public StackMapData(CodeData code, DataInputStream in) throws IOException { 46 start_pc = in.readUnsignedShort(); 47 lockMap = readMap(code, in); 48 stackMap = readMap(code, in); 49 traceln(2, format("stack_map_entry:pc=%d numloc=%s numstack=%s", 50 start_pc, mapToHexString(lockMap), mapToHexString(stackMap))); 51 } 52 53 public StackMapData(CodeData code, DataInputStream in, 54 boolean isStackMapTable) throws IOException { 55 this.isStackMapTable = isStackMapTable; 56 int ft_val = in.readUnsignedByte(); 57 StackMapFrameType frame_type = stackMapFrameType(ft_val); 58 int offset = 0; 59 switch (frame_type) { 60 case SAME_FRAME: 61 // type is same_frame; 62 offset = ft_val; 63 traceln(2, format("same_frame=%d", ft_val)); 64 break; 65 case SAME_FRAME_EX: 66 // type is same_frame_extended; 67 offset = in.readUnsignedShort(); 68 traceln(2, format("same_frame_extended=%d, offset=%d", ft_val, offset)); 69 break; 70 case SAME_LOCALS_1_STACK_ITEM_FRAME: 71 // type is same_locals_1_stack_item_frame 72 offset = ft_val - 64; 73 stackMap = readMapElements(code, in, 1); 74 traceln(2, format("same_locals_1_stack_item_frame=%d, offset=%d, numstack=%s", 75 ft_val, offset, mapToHexString(stackMap))); 76 break; 77 case SAME_LOCALS_1_STACK_ITEM_EXTENDED_FRAME: 78 // type is same_locals_1_stack_item_frame_extended 79 offset = in.readUnsignedShort(); 80 stackMap = readMapElements(code, in, 1); 81 traceln(2, format("same_locals_1_stack_item_frame_extended=%d, offset=%d, numstack=%s", 82 ft_val, offset, mapToHexString(stackMap))); 83 break; 84 case CHOP_1_FRAME: 85 case CHOP_2_FRAME: 86 case CHOP_3_FRAME: 87 // type is chop_frame 88 offset = in.readUnsignedShort(); 89 traceln(2, format("chop_frame=%d offset=%d", ft_val, offset)); 90 break; 91 case APPEND_FRAME: 92 // type is append_frame 93 offset = in.readUnsignedShort(); 94 lockMap = readMapElements(code, in, ft_val - 251); 95 traceln(2, format("append_frame=%d offset=%d numlock=%s", 96 ft_val, offset, mapToHexString(lockMap))); 97 break; 98 case FULL_FRAME: 99 // type is full_frame 100 offset = in.readUnsignedShort(); 101 lockMap = readMap(code, in); 102 stackMap = readMap(code, in); 103 traceln(2, format("full_frame=%d offset=%d numloc=%s numstack=%s", 104 ft_val, offset, mapToHexString(lockMap), mapToHexString(stackMap))); 105 break; 106 default: 107 TraceUtils.traceln("incorrect frame_type argument"); 108 109 } 110 stackFrameType = frame_type; 111 start_pc = prevFramePC == 0 ? offset : prevFramePC + offset + 1; 112 prevFramePC = start_pc; 113 } 114 115 private int[] readMap(CodeData code, DataInputStream in) throws IOException { 116 int num = in.readUnsignedShort(); 117 return readMapElements(code, in, num); 118 } 119 120 private int[] readMapElements(CodeData code, DataInputStream in, int num) throws IOException { 121 int[] map = new int[num]; 122 for (int k = 0; k < num; k++) { 123 int mt_val = 0; 124 try { 125 mt_val = in.readUnsignedByte(); 126 } catch (EOFException eofe) { 127 throw eofe; 128 } 129 StackMapType maptype = stackMapType(mt_val, null); 130 switch (maptype) { 131 case ITEM_Object: 132 mt_val = mt_val | (in.readUnsignedShort() << 8); 133 break; 134 case ITEM_NewObject: { 135 int pc = in.readUnsignedShort(); 136 code.get_iAtt(pc).referred = true; 137 mt_val = mt_val | (pc << 8); 138 break; 139 } 140 } 141 map[k] = mt_val; 142 } 143 return map; 144 } 145 146 }