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 }