• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_ZUCCHINI_TYPE_DEX_H_
6 #define COMPONENTS_ZUCCHINI_TYPE_DEX_H_
7 
8 #include <stdint.h>
9 
10 namespace zucchini {
11 namespace dex {
12 // Contains types that models DEX executable format data structures.
13 // See https://source.android.com/devices/tech/dalvik/dex-format
14 
15 // The supported versions are 035, 037, 038, and 039.
16 
17 enum class FormatId : uint8_t {
18   b,  // 22b.
19   c,  // 21c, 22c, 31c, 35c, 3rc, 45cc, 4rcc.
20   h,  // 21h.
21   i,  // 31i.
22   l,  // 51l.
23   n,  // 11n.
24   s,  // 21s, 22s.
25   t,  // 10t, 20t, 21t, 22t, 30t, 31t.
26   x,  // 10x, 11x, 12x, 22x, 23x, 32x.
27 };
28 
29 struct Instruction {
30   Instruction() = default;
31   constexpr Instruction(uint8_t opcode_in,
32                         uint8_t layout_in,
33                         FormatId format_in,
34                         uint8_t variant_in = 1)
opcodeInstruction35       : opcode(opcode_in),
36         layout(layout_in),
37         format(format_in),
38         variant(variant_in) {}
39 
40   // The opcode that identifies the instruction.
41   uint8_t opcode;
42   // Number of uint16_t units for the instruction.
43   uint8_t layout;
44   // Identifier that groups similar instructions, as quick filter.
45   FormatId format;
46   // Number of successive opcodes that have the same format.
47   uint8_t variant = 1;
48 };
49 
50 constexpr Instruction kByteCode[] = {
51     {0x00, 1, FormatId::x},
52     {0x01, 1, FormatId::x},
53     {0x02, 2, FormatId::x},
54     {0x03, 3, FormatId::x},
55     {0x04, 1, FormatId::x},
56     {0x05, 2, FormatId::x},
57     {0x06, 3, FormatId::x},
58     {0x07, 1, FormatId::x},
59     {0x08, 2, FormatId::x},
60     {0x09, 3, FormatId::x},
61     {0x0A, 1, FormatId::x},
62     {0x0B, 1, FormatId::x},
63     {0x0C, 1, FormatId::x},
64     {0x0D, 1, FormatId::x},
65     {0x0E, 1, FormatId::x},
66     {0x0F, 1, FormatId::x},
67     {0x10, 1, FormatId::x},
68     {0x11, 1, FormatId::x},
69     {0x12, 1, FormatId::n},
70     {0x13, 2, FormatId::s},
71     {0x14, 3, FormatId::i},
72     {0x15, 2, FormatId::h},
73     {0x16, 2, FormatId::s},
74     {0x17, 3, FormatId::i},
75     {0x18, 5, FormatId::l},
76     {0x19, 2, FormatId::h},
77     {0x1A, 2, FormatId::c},
78     {0x1B, 3, FormatId::c},
79     {0x1C, 2, FormatId::c},
80     {0x1D, 1, FormatId::x},
81     {0x1E, 1, FormatId::x},
82     {0x1F, 2, FormatId::c},
83     {0x20, 2, FormatId::c},
84     {0x21, 1, FormatId::x},
85     {0x22, 2, FormatId::c},
86     {0x23, 2, FormatId::c},
87     {0x24, 3, FormatId::c},
88     {0x25, 3, FormatId::c},
89     {0x26, 3, FormatId::t},
90     {0x27, 1, FormatId::x},
91     {0x28, 1, FormatId::t},
92     {0x29, 2, FormatId::t},
93     {0x2A, 3, FormatId::t},
94     {0x2B, 3, FormatId::t},
95     {0x2C, 3, FormatId::t},
96     {0x2D, 2, FormatId::x, 5},
97     {0x32, 2, FormatId::t, 6},
98     {0x38, 2, FormatId::t, 6},
99     // {0x3E, 1, FormatId::x, 6}, unused
100     {0x44, 2, FormatId::x, 14},
101     {0x52, 2, FormatId::c, 14},
102     {0x60, 2, FormatId::c, 14},
103     {0x6E, 3, FormatId::c, 5},
104     // {0x73, 1, FormatId::x}, unused
105     {0x74, 3, FormatId::c, 5},
106     // {0x79, 1, FormatId::x, 2}, unused
107     {0x7B, 1, FormatId::x, 21},
108     {0x90, 2, FormatId::x, 32},
109     {0xB0, 1, FormatId::x, 32},
110     {0xD0, 2, FormatId::s, 8},
111     {0xD8, 2, FormatId::b, 11},
112     // {0xE3, 1, FormatId::x, 29}, unused
113     {0xFA, 4, FormatId::c},
114     {0xFB, 4, FormatId::c},
115     {0xFC, 3, FormatId::c},
116     {0xFD, 3, FormatId::c},
117     {0xFE, 2, FormatId::c},
118     {0xFF, 2, FormatId::c},
119 };
120 
121 // Supported by MSVC, g++, and clang++. Ensures no gaps in packing.
122 #pragma pack(push, 1)
123 
124 // header_item: Appears in the header section.
125 struct HeaderItem {
126   uint8_t magic[8];
127   uint32_t checksum;
128   uint8_t signature[20];
129   uint32_t file_size;
130   uint32_t header_size;
131   uint32_t endian_tag;
132   uint32_t link_size;
133   uint32_t link_off;
134   uint32_t map_off;
135   uint32_t string_ids_size;
136   uint32_t string_ids_off;
137   uint32_t type_ids_size;
138   uint32_t type_ids_off;
139   uint32_t proto_ids_size;
140   uint32_t proto_ids_off;
141   uint32_t field_ids_size;
142   uint32_t field_ids_off;
143   uint32_t method_ids_size;
144   uint32_t method_ids_off;
145   uint32_t class_defs_size;
146   uint32_t class_defs_off;
147   uint32_t data_size;
148   uint32_t data_off;
149 };
150 
151 // string_id_item: String identifiers list.
152 struct StringIdItem {
153   uint32_t string_data_off;
154 };
155 
156 // type_id_item: Type identifiers list.
157 struct TypeIdItem {
158   uint32_t descriptor_idx;
159 };
160 
161 // proto_id_item: Method prototype identifiers list.
162 struct ProtoIdItem {
163   uint32_t shorty_idx;
164   uint32_t return_type_idx;
165   uint32_t parameters_off;
166 };
167 
168 // field_id_item: Field identifiers list.
169 struct FieldIdItem {
170   uint16_t class_idx;
171   uint16_t type_idx;
172   uint32_t name_idx;
173 };
174 
175 // method_id_item: Method identifiers list.
176 struct MethodIdItem {
177   uint16_t class_idx;
178   uint16_t proto_idx;
179   uint32_t name_idx;
180 };
181 
182 // class_def_item: Class definitions list.
183 struct ClassDefItem {
184   uint32_t class_idx;
185   uint32_t access_flags;
186   uint32_t superclass_idx;
187   uint32_t interfaces_off;
188   uint32_t source_file_idx;
189   uint32_t annotations_off;
190   uint32_t class_data_off;
191   uint32_t static_values_off;
192 };
193 
194 // call_site_id_item: Call site identifiers list.
195 struct CallSiteIdItem {
196   uint32_t call_site_off;
197 };
198 
199 // method_handle_type: Determines the behavior of the MethodHandleItem.
200 enum class MethodHandleType : uint16_t {
201   // FieldId
202   kStaticPut = 0x00,
203   kStaticGet = 0x01,
204   kInstancePut = 0x02,
205   kInstanceGet = 0x03,
206   // MethodId
207   kInvokeStatic = 0x04,
208   kInvokeInstance = 0x05,
209   kInvokeConstructor = 0x06,
210   kInvokeDirect = 0x07,
211   kInvokeInterface = 0x08,
212   // Sentinel. If new types are added put them before this and increment.
213   kMaxMethodHandleType = 0x09
214 };
215 
216 // method_handle_item: Method handles referred within the Dex file.
217 struct MethodHandleItem {
218   uint16_t method_handle_type;
219   uint16_t unused_1;
220   uint16_t field_or_method_id;
221   uint16_t unused_2;
222 };
223 
224 // code_item: Header of a code item.
225 struct CodeItem {
226   uint16_t registers_size;
227   uint16_t ins_size;
228   uint16_t outs_size;
229   uint16_t tries_size;
230   uint32_t debug_info_off;
231   uint32_t insns_size;
232   // Variable length data follow for complete code item.
233 };
234 
235 // Number of valid type codes for map_item elements in map_list.
236 // See: https://source.android.com/devices/tech/dalvik/dex-format#type-codes
237 constexpr uint32_t kMaxItemListSize = 21;
238 
239 constexpr uint16_t kTypeHeaderItem = 0x0000;
240 constexpr uint16_t kTypeStringIdItem = 0x0001;
241 constexpr uint16_t kTypeTypeIdItem = 0x0002;
242 constexpr uint16_t kTypeProtoIdItem = 0x0003;
243 constexpr uint16_t kTypeFieldIdItem = 0x0004;
244 constexpr uint16_t kTypeMethodIdItem = 0x0005;
245 constexpr uint16_t kTypeClassDefItem = 0x0006;
246 constexpr uint16_t kTypeCallSiteIdItem = 0x0007;
247 constexpr uint16_t kTypeMethodHandleItem = 0x0008;
248 constexpr uint16_t kTypeMapList = 0x1000;
249 constexpr uint16_t kTypeTypeList = 0x1001;
250 constexpr uint16_t kTypeAnnotationSetRefList = 0x1002;
251 constexpr uint16_t kTypeAnnotationSetItem = 0x1003;
252 constexpr uint16_t kTypeClassDataItem = 0x2000;
253 constexpr uint16_t kTypeCodeItem = 0x2001;
254 constexpr uint16_t kTypeStringDataItem = 0x2002;
255 constexpr uint16_t kTypeDebugInfoItem = 0x2003;
256 constexpr uint16_t kTypeAnnotationItem = 0x2004;
257 constexpr uint16_t kTypeEncodedArrayItem = 0x2005;
258 constexpr uint16_t kTypeAnnotationsDirectoryItem = 0x2006;
259 constexpr uint16_t kTypeHiddenApiClassDataItem = 0xF000;
260 
261 // map_item
262 struct MapItem {
263   uint16_t type;
264   uint16_t unused;
265   uint32_t size;
266   uint32_t offset;
267 };
268 
269 // map_list
270 struct MapList {
271   uint32_t size;
272   MapItem list[kMaxItemListSize];
273 };
274 
275 // type_item
276 struct TypeItem {
277   uint16_t type_idx;
278 };
279 
280 // annotation_set_ref_item
281 struct AnnotationSetRefItem {
282   uint32_t annotations_off;
283 };
284 
285 // annotation_off_item
286 struct AnnotationOffItem {
287   uint32_t annotation_off;
288 };
289 
290 // field_annotation
291 struct FieldAnnotation {
292   uint32_t field_idx;
293   uint32_t annotations_off;
294 };
295 
296 // method_annotation
297 struct MethodAnnotation {
298   uint32_t method_idx;
299   uint32_t annotations_off;
300 };
301 
302 // parameter_annotation
303 struct ParameterAnnotation {
304   uint32_t method_idx;
305   uint32_t annotations_off;
306 };
307 
308 // annotations_directory_item
309 struct AnnotationsDirectoryItem {
310   uint32_t class_annotations_off;
311   uint32_t fields_size;
312   uint32_t annotated_methods_size;
313   uint32_t annotated_parameters_size;
314   // FieldAnnotation field_annotations[fields_size];
315   // MethodAnnotation method_annotations[annotated_methods_size];
316   // ParameterAnnotation parameter_annotations[annotated_parameters_size];
317   // All *Annotation are 8 bytes each.
318 };
319 
320 // try_item
321 struct TryItem {
322   uint32_t start_addr;
323   uint16_t insn_count;
324   uint16_t handler_off;
325 };
326 
327 #pragma pack(pop)
328 
329 }  // namespace dex
330 }  // namespace zucchini
331 
332 #endif  // COMPONENTS_ZUCCHINI_TYPE_DEX_H_
333