use crate::dex::insn::DexInsn;
use crate::impls::jvms::r::U32BasedSize;
use crate::StrRef;
use java_asm_macro::ReadFrom;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct DexFile {
pub header: Header,
pub string_ids: Vec<StringId>,
pub type_ids: Vec<TypeId>,
pub proto_ids: Vec<ProtoId>,
pub field_ids: Vec<FieldId>,
pub method_ids: Vec<MethodId>,
pub class_defs: Vec<ClassDef>,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
#[align(4)]
pub struct Header {
pub magic: [u8; 8],
pub checksum: DUInt,
pub signature: [u8; 20],
pub file_size: DUInt,
pub header_size: DUInt,
pub endian_tag: DUInt,
pub link_size: DUInt,
pub link_off: DUInt,
pub map_off: DUInt,
pub string_ids_size: U32BasedSize,
pub string_ids_off: DUInt,
pub type_ids_size: U32BasedSize,
pub type_ids_off: DUInt,
pub proto_ids_size: U32BasedSize,
pub proto_ids_off: DUInt,
pub field_ids_size: U32BasedSize,
pub field_ids_off: DUInt,
pub method_ids_size: U32BasedSize,
pub method_ids_off: DUInt,
pub class_defs_size: U32BasedSize,
pub class_defs_off: DUInt,
pub data_size: U32BasedSize,
pub data_off: DUInt,
}
impl Header {
pub const LITTLE_ENDIAN_TAG: u32 = 0x12345678;
pub const BIG_ENDIAN_TAG: u32 = 0x78563412;
}
#[derive(Clone, Debug, Eq, PartialEq, ReadFrom, Default)]
#[align(4)]
pub struct MapList {
pub size: U32BasedSize,
#[index(size)]
pub items: Vec<MapItem>,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
pub struct MapItem {
pub type_value: DUShort,
pub unused: DUShort, pub size: U32BasedSize,
pub offset: DUInt, }
#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
#[align(4)]
pub struct StringId {
pub string_data_off: DUInt,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct StringData {
pub utf16_size: DULeb128,
pub str_ref: StrRef,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
#[align(4)]
pub struct TypeId {
pub descriptor_idx: U32BasedSize, }
#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
#[align(4)]
pub struct ProtoId {
pub shorty_idx: U32BasedSize, pub return_type_idx: U32BasedSize, pub parameters_off: DUInt,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
#[align(4)]
pub struct FieldId {
pub class_idx: DUShort, pub type_idx: DUShort, pub name_idx: U32BasedSize, }
#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
#[align(4)]
pub struct MethodId {
pub class_idx: DUShort, pub proto_idx: DUShort, pub name_idx: U32BasedSize, }
#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
#[align(4)]
pub struct ClassDef {
pub class_idx: U32BasedSize,
pub access_flags: DUInt,
pub superclass_idx: U32BasedSize,
pub interfaces_off: DUInt,
pub source_file_idx: U32BasedSize,
pub annotations_off: DUInt,
pub class_data_off: DUInt,
pub static_values_off: DUInt,
}
#[derive(Clone, Debug, Eq, PartialEq, ReadFrom)]
pub struct ClassDataItem {
pub static_fields_size: DULeb128,
pub instance_fields_size: DULeb128,
pub direct_methods_size: DULeb128,
pub virtual_methods_size: DULeb128,
#[index(static_fields_size)]
pub static_fields: Vec<EncodedField>,
#[index(instance_fields_size)]
pub instance_fields: Vec<EncodedField>,
#[index(direct_methods_size)]
pub direct_methods: Vec<EncodedMethod>,
#[index(virtual_methods_size)]
pub virtual_methods: Vec<EncodedMethod>,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
pub struct EncodedField {
pub field_idx_diff: DULeb128,
pub access_flags: DULeb128,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
pub struct EncodedMethod {
pub method_idx_diff: DULeb128,
pub access_flags: DULeb128,
pub code_off: DULeb128,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct CodeItem {
pub registers_size: DUShort,
pub ins_size: DUShort,
pub outs_size: DUShort,
pub tries_size: DUShort,
pub debug_info_off: DUInt,
pub insn_container: InsnContainer,
pub tries: Vec<TryItem>,
pub handlers: EncodedCatchHandlerList,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct DebugInfoItem {
pub line_start: DULeb128,
pub parameter_names: Vec<DULeb128P1>,
pub records: Vec<(DUInt, DUInt, DULeb128P1)>,
pub local_vars: Vec<LocalVar>,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct LocalVar {
pub register: DULeb128,
pub name_idx: DULeb128P1,
pub type_idx: DULeb128P1,
pub sig_idx: DULeb128P1,
pub start_addr: Option<DUInt>,
pub end_addr: Option<DUInt>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct InsnContainer {
pub insns_size: DUInt,
pub insns: Vec<DexInsn>,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
pub struct TryItem {
pub start_addr: DUInt,
pub insn_count: DUShort,
pub handler_off: DUShort,
}
#[derive(Clone, Debug, Eq, PartialEq, ReadFrom, Default)]
pub struct EncodedCatchHandlerList {
pub size: DULeb128,
#[index(size)]
pub list: Vec<EncodedCatchHandler>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct EncodedCatchHandler {
pub size: DSleb128,
pub handlers: Vec<EncodedTypeAddrPair>,
pub catch_all_addr: Option<DULeb128>,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
pub struct EncodedTypeAddrPair {
pub type_idx: DULeb128,
pub addr: DULeb128,
}
#[derive(Clone, Debug, Eq, PartialEq, ReadFrom)]
#[align(4)]
pub struct TypeList {
pub size: U32BasedSize,
#[index(size)]
pub type_id_indices: Vec<DUShort>, }
#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
#[align(4)]
pub struct CallSiteId {
pub call_site_off: DUInt,
}
pub type CallSiteItem = EncodedArray;
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum EncodedValue {
Byte(DByte),
Short(DShort),
Char(DUShort),
Int(DInt),
Long(DLong),
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,
Boolean(bool),
}
#[derive(Clone, Debug, Eq, PartialEq, ReadFrom)]
pub struct EncodedArray {
pub size: DULeb128,
#[index(size)]
pub values: Vec<EncodedValue>,
}
#[derive(Clone, Debug, Eq, PartialEq, ReadFrom)]
pub struct EncodedAnnotation {
pub type_idx: DULeb128, pub size: DULeb128, #[index(size)]
pub elements: Vec<EncodedAnnotationAttribute>,
}
#[derive(Clone, Debug, Eq, PartialEq, ReadFrom)]
pub struct EncodedAnnotationAttribute {
pub name_idx: DULeb128, pub value: EncodedValue,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, ReadFrom)]
#[align(4)]
pub struct MethodHandle {
pub method_handle_type: DUShort,
pub unused_stub_0: DUShort, pub field_or_method_id: DUShort,
pub unused_stub_1: DUShort, }
pub type DByte = i8;
pub type DUByte = u8;
pub type DShort = i16;
pub type DUShort = u16;
pub type DInt = i32;
pub type DUInt = u32;
pub type DLong = i64;
pub type DULong = u64;
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, Hash)]
pub struct DSleb128(pub(crate) u32);
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, Hash)]
pub struct DULeb128(pub(crate) u32);
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, Hash)]
pub struct DULeb128P1(pub(crate) u32);
pub const NO_INDEX: u32 = 0xFFFFFFFF;
impl DSleb128 {
#[inline]
pub const fn value(&self) -> i32 {
self.0 as i32
}
}
impl DULeb128 {
#[inline]
pub const fn value(&self) -> u32 {
self.0
}
}
impl Into<usize> for DULeb128 {
fn into(self) -> usize {
self.value() as usize
}
}
impl DULeb128P1 {
pub const ZERO: DULeb128P1 = DULeb128P1(0);
#[inline]
pub const fn value(&self) -> Option<u32> {
let internal = self.0;
if internal == 0 {
None
} else {
Some(internal - 1)
}
}
}