blob: ee61ecd58b4b1bd0ca3acf04a5fe0a8ebefd88fa [file] [log] [blame]
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +00001// 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
10namespace zucchini {
11namespace dex {
12// Contains types that models DEX executable format data structures.
13// See https://source.android.com/devices/tech/dalvik/dex-format
14
ckitagawa1269b5c2021-09-07 21:12:21 +000015// The supported versions are 035, 037, 038, and 039.
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +000016
17enum class FormatId : uint8_t {
18 b, // 22b.
ckitagawa26518ff2021-09-03 15:48:28 +000019 c, // 21c, 22c, 31c, 35c, 3rc, 45cc, 4rcc.
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +000020 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
29struct 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)
35 : 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
50constexpr 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
ckitagawa26518ff2021-09-03 15:48:28 +0000113 {0xFA, 4, FormatId::c},
114 {0xFB, 4, FormatId::c},
115 {0xFC, 3, FormatId::c},
116 {0xFD, 3, FormatId::c},
ckitagawa1269b5c2021-09-07 21:12:21 +0000117 {0xFE, 2, FormatId::c},
118 {0xFF, 2, FormatId::c},
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +0000119};
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.
125struct 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.
152struct StringIdItem {
153 uint32_t string_data_off;
154};
155
156// type_id_item: Type identifiers list.
157struct TypeIdItem {
158 uint32_t descriptor_idx;
159};
160
161// proto_id_item: Method prototype identifiers list.
162struct 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.
169struct 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.
176struct 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.
183struct 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
ckitagawa26518ff2021-09-03 15:48:28 +0000194// call_site_id_item: Call site identifiers list.
195struct CallSiteIdItem {
196 uint32_t call_site_off;
197};
198
199// method_handle_type: Determines the behavior of the MethodHandleItem.
200enum 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.
217struct 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
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +0000224// code_item: Header of a code item.
225struct 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
ckitagawa26518ff2021-09-03 15:48:28 +0000235// 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
237constexpr uint32_t kMaxItemListSize = 21;
238
239constexpr uint16_t kTypeHeaderItem = 0x0000;
240constexpr uint16_t kTypeStringIdItem = 0x0001;
241constexpr uint16_t kTypeTypeIdItem = 0x0002;
242constexpr uint16_t kTypeProtoIdItem = 0x0003;
243constexpr uint16_t kTypeFieldIdItem = 0x0004;
244constexpr uint16_t kTypeMethodIdItem = 0x0005;
245constexpr uint16_t kTypeClassDefItem = 0x0006;
246constexpr uint16_t kTypeCallSiteIdItem = 0x0007;
247constexpr uint16_t kTypeMethodHandleItem = 0x0008;
248constexpr uint16_t kTypeMapList = 0x1000;
249constexpr uint16_t kTypeTypeList = 0x1001;
250constexpr uint16_t kTypeAnnotationSetRefList = 0x1002;
251constexpr uint16_t kTypeAnnotationSetItem = 0x1003;
252constexpr uint16_t kTypeClassDataItem = 0x2000;
253constexpr uint16_t kTypeCodeItem = 0x2001;
254constexpr uint16_t kTypeStringDataItem = 0x2002;
255constexpr uint16_t kTypeDebugInfoItem = 0x2003;
256constexpr uint16_t kTypeAnnotationItem = 0x2004;
257constexpr uint16_t kTypeEncodedArrayItem = 0x2005;
258constexpr uint16_t kTypeAnnotationsDirectoryItem = 0x2006;
259constexpr uint16_t kTypeHiddenApiClassDataItem = 0xF000;
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +0000260
261// map_item
262struct MapItem {
263 uint16_t type;
264 uint16_t unused;
265 uint32_t size;
266 uint32_t offset;
267};
268
269// map_list
270struct MapList {
271 uint32_t size;
272 MapItem list[kMaxItemListSize];
273};
274
275// type_item
276struct TypeItem {
277 uint16_t type_idx;
278};
279
280// annotation_set_ref_item
281struct AnnotationSetRefItem {
282 uint32_t annotations_off;
283};
284
285// annotation_off_item
286struct AnnotationOffItem {
287 uint32_t annotation_off;
288};
289
Calder Kitagawa1b257092018-06-12 14:37:39 +0000290// field_annotation
291struct FieldAnnotation {
292 uint32_t field_idx;
293 uint32_t annotations_off;
294};
295
296// method_annotation
297struct MethodAnnotation {
298 uint32_t method_idx;
299 uint32_t annotations_off;
300};
301
302// parameter_annotation
303struct ParameterAnnotation {
304 uint32_t method_idx;
305 uint32_t annotations_off;
306};
307
308// annotations_directory_item
309struct 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
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +0000320// try_item
321struct TryItem {
322 uint32_t start_addr;
323 uint16_t insn_count;
324 uint16_t handler_off;
325};
326
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +0000327#pragma pack(pop)
328
329} // namespace dex
330} // namespace zucchini
331
332#endif // COMPONENTS_ZUCCHINI_TYPE_DEX_H_