1use crate::dex::insn::DexInsn;
2use crate::impls::jvms::r::U32BasedSize;
3use crate::StrRef;
4use java_asm_macro::ReadFrom;
5
6#[derive(Clone, Debug, Eq, PartialEq)]
7pub struct DexFile {
8 pub header: Header,
9 pub string_ids: Vec<StringId>,
10 pub type_ids: Vec<TypeId>,
11 pub proto_ids: Vec<ProtoId>,
12 pub field_ids: Vec<FieldId>,
13 pub method_ids: Vec<MethodId>,
14 pub class_defs: Vec<ClassDef>,
15 }
23
24#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
25#[align(4)]
26pub struct Header {
27 pub magic: [u8; 8],
29 pub checksum: DUInt,
31 pub signature: [u8; 20],
33 pub file_size: DUInt,
35 pub header_size: DUInt,
37 pub endian_tag: DUInt,
39 pub link_size: DUInt,
41 pub link_off: DUInt,
43 pub map_off: DUInt,
45 pub string_ids_size: U32BasedSize,
47 pub string_ids_off: DUInt,
49 pub type_ids_size: U32BasedSize,
51 pub type_ids_off: DUInt,
52 pub proto_ids_size: U32BasedSize,
54 pub proto_ids_off: DUInt,
55 pub field_ids_size: U32BasedSize,
57 pub field_ids_off: DUInt,
58 pub method_ids_size: U32BasedSize,
59 pub method_ids_off: DUInt,
60 pub class_defs_size: U32BasedSize,
61 pub class_defs_off: DUInt,
62 pub data_size: U32BasedSize,
64 pub data_off: DUInt,
65}
66
67impl Header {
68 pub const LITTLE_ENDIAN_TAG: u32 = 0x12345678;
69 pub const BIG_ENDIAN_TAG: u32 = 0x78563412;
70}
71
72#[derive(Clone, Debug, Eq, PartialEq, ReadFrom, Default)]
73#[align(4)]
74pub struct MapList {
75 pub size: U32BasedSize,
76 #[index(size)]
77 pub items: Vec<MapItem>,
78}
79
80#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
81pub struct MapItem {
82 pub type_value: DUShort,
84 pub unused: DUShort, pub size: U32BasedSize,
87 pub offset: DUInt, }
89
90#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
91#[align(4)]
92pub struct StringId {
93 pub string_data_off: DUInt,
95}
96
97#[derive(Clone, Debug, Eq, PartialEq)]
98pub struct StringData {
99 pub utf16_size: DULeb128,
103 pub str_ref: StrRef,
105}
106
107#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
108#[align(4)]
109pub struct TypeId {
110 pub descriptor_idx: U32BasedSize, }
112
113#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
114#[align(4)]
115pub struct ProtoId {
116 pub shorty_idx: U32BasedSize, pub return_type_idx: U32BasedSize, pub parameters_off: DUInt,
120}
121
122#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
123#[align(4)]
124pub struct FieldId {
125 pub class_idx: DUShort, pub type_idx: DUShort, pub name_idx: U32BasedSize, }
129
130#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
131#[align(4)]
132pub struct MethodId {
133 pub class_idx: DUShort, pub proto_idx: DUShort, pub name_idx: U32BasedSize, }
137
138#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
139#[align(4)]
140pub struct ClassDef {
141 pub class_idx: U32BasedSize,
143 pub access_flags: DUInt,
145 pub superclass_idx: U32BasedSize,
147 pub interfaces_off: DUInt,
150 pub source_file_idx: U32BasedSize,
152 pub annotations_off: DUInt,
154 pub class_data_off: DUInt,
156 pub static_values_off: DUInt,
159}
160
161#[derive(Clone, Debug, Eq, PartialEq, ReadFrom)]
162pub struct ClassDataItem {
163 pub static_fields_size: DULeb128,
164 pub instance_fields_size: DULeb128,
165 pub direct_methods_size: DULeb128,
166 pub virtual_methods_size: DULeb128,
167 #[index(static_fields_size)]
168 pub static_fields: Vec<EncodedField>,
169 #[index(instance_fields_size)]
170 pub instance_fields: Vec<EncodedField>,
171 #[index(direct_methods_size)]
172 pub direct_methods: Vec<EncodedMethod>,
173 #[index(virtual_methods_size)]
174 pub virtual_methods: Vec<EncodedMethod>,
175}
176
177#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
178pub struct EncodedField {
179 pub field_idx_diff: DULeb128,
181 pub access_flags: DULeb128,
183}
184
185#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
186pub struct EncodedMethod {
187 pub method_idx_diff: DULeb128,
189 pub access_flags: DULeb128,
191 pub code_off: DULeb128,
194}
195
196#[derive(Clone, Debug, Eq, PartialEq)]
197pub struct CodeItem {
198 pub registers_size: DUShort,
199 pub ins_size: DUShort,
200 pub outs_size: DUShort,
201 pub tries_size: DUShort,
202 pub debug_info_off: DUInt,
203 pub insn_container: InsnContainer,
204 pub tries: Vec<TryItem>,
205 pub handlers: EncodedCatchHandlerList,
206}
207
208#[derive(Clone, Debug, Eq, PartialEq)]
209pub struct DebugInfoItem {
210 pub line_start: DULeb128,
211 pub parameter_names: Vec<DULeb128P1>,
213 pub records: Vec<(DUInt, DUInt, DULeb128P1)>,
215 pub local_vars: Vec<LocalVar>,
216}
217
218#[derive(Copy, Clone, Debug, Eq, PartialEq)]
219pub struct LocalVar {
220 pub register: DULeb128,
221 pub name_idx: DULeb128P1,
222 pub type_idx: DULeb128P1,
223 pub sig_idx: DULeb128P1,
224 pub start_addr: Option<DUInt>,
225 pub end_addr: Option<DUInt>,
226}
227
228#[derive(Clone, Debug, Eq, PartialEq)]
229pub struct InsnContainer {
230 pub insns_size: DUInt,
231 pub insns: Vec<DexInsn>,
232}
233
234#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
235pub struct TryItem {
236 pub start_addr: DUInt,
237 pub insn_count: DUShort,
239 pub handler_off: DUShort,
242}
243
244#[derive(Clone, Debug, Eq, PartialEq, ReadFrom, Default)]
245pub struct EncodedCatchHandlerList {
246 pub size: DULeb128,
247 #[index(size)]
248 pub list: Vec<EncodedCatchHandler>,
249}
250
251#[derive(Clone, Debug, Eq, PartialEq)]
252pub struct EncodedCatchHandler {
253 pub size: DSleb128,
254 pub handlers: Vec<EncodedTypeAddrPair>,
255 pub catch_all_addr: Option<DULeb128>,
256}
257
258#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
259pub struct EncodedTypeAddrPair {
260 pub type_idx: DULeb128,
261 pub addr: DULeb128,
262}
263
264#[derive(Clone, Debug, Eq, PartialEq, ReadFrom)]
265#[align(4)]
266pub struct TypeList {
267 pub size: U32BasedSize,
268 #[index(size)]
269 pub type_id_indices: Vec<DUShort>, }
271
272#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
273#[align(4)]
274pub struct CallSiteId {
275 pub call_site_off: DUInt,
277}
278
279pub type CallSiteItem = EncodedArray;
285
286#[derive(Clone, Debug, Eq, PartialEq)]
287pub enum EncodedValue {
288 Byte(DByte),
289 Short(DShort),
290 Char(DUShort),
291 Int(DInt),
292 Long(DLong),
293 Float([DUByte; 4]), Double([DUByte; 8]), MethodType(U32BasedSize), MethodHandle(U32BasedSize), String(U32BasedSize), Type(U32BasedSize), Field(U32BasedSize), Method(U32BasedSize), Enum(U32BasedSize), Array(EncodedArray), Annotation(EncodedAnnotation), Null,
305 Boolean(bool),
306}
307
308#[derive(Clone, Debug, Eq, PartialEq, ReadFrom)]
309pub struct EncodedArray {
310 pub size: DULeb128,
311 #[index(size)]
312 pub values: Vec<EncodedValue>,
313}
314
315#[derive(Clone, Debug, Eq, PartialEq, ReadFrom)]
316pub struct EncodedAnnotation {
317 pub type_idx: DULeb128, pub size: DULeb128, #[index(size)]
320 pub elements: Vec<EncodedAnnotationAttribute>,
321}
322
323#[derive(Clone, Debug, Eq, PartialEq, ReadFrom)]
324pub struct EncodedAnnotationAttribute {
325 pub name_idx: DULeb128, pub value: EncodedValue,
327}
328
329#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
330#[align(4)]
331pub struct MethodHandle {
332 pub method_handle_type: DUShort,
333 pub unused_stub_0: DUShort, pub field_or_method_id: DUShort,
335 pub unused_stub_1: DUShort, }
337
338pub type DByte = i8;
340pub type DUByte = u8;
341pub type DShort = i16;
342pub type DUShort = u16;
343pub type DInt = i32;
344pub type DUInt = u32;
345pub type DLong = i64;
346pub type DULong = u64;
347
348#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, Hash)]
349pub struct DSleb128(pub(crate) u32);
350#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, Hash)]
351pub struct DULeb128(pub(crate) u32);
352#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, Hash)]
353pub struct DULeb128P1(pub(crate) u32);
354
355pub const NO_INDEX: u32 = 0xFFFFFFFF;
356
357impl DSleb128 {
358 #[inline]
359 pub const fn value(&self) -> i32 {
360 self.0 as i32
361 }
362}
363
364impl DULeb128 {
365 #[inline]
366 pub const fn value(&self) -> u32 {
367 self.0
368 }
369}
370
371impl Into<usize> for DULeb128 {
372 fn into(self) -> usize {
373 self.value() as usize
374 }
375}
376
377impl DULeb128P1 {
378 pub const ZERO: DULeb128P1 = DULeb128P1(0);
379
380 #[inline]
382 pub const fn value(&self) -> Option<u32> {
383 let internal = self.0;
384 if internal == 0 {
385 None
386 } else {
387 Some(internal - 1)
388 }
389 }
390}