diff --git a/androscalpel/src/dex_writer.rs b/androscalpel/src/dex_writer.rs index 7402361..e3e9ae9 100644 --- a/androscalpel/src/dex_writer.rs +++ b/androscalpel/src/dex_writer.rs @@ -445,7 +445,18 @@ impl DexWriter { } Instruction::ConstString { .. } => { let size = ins - .get_raw_ins(Some(&self.strings), None, None, None, None, None) + .get_raw_ins( + Some(&self.strings), + None, + None, + None, + None, + None, + None, + None, + None, + None, + ) .with_context(|| format!("In code of {}", method_id.__repr__()))? .size() / 2; @@ -470,7 +481,18 @@ impl DexWriter { } Instruction::ConstString { .. } => { addr += ins - .get_raw_ins(Some(&self.strings), None, None, None, None, None)? + .get_raw_ins( + Some(&self.strings), + None, + None, + None, + None, + None, + None, + None, + None, + None, + )? .size() / 2; // should not fail after @@ -492,7 +514,7 @@ impl DexWriter { } // Serialize instructions let mut tries = vec![]; - let mut handlers = EncodedCatchHandlerList { list: vec![] }; + let mut encoded_handlers = EncodedCatchHandlerList { list: vec![] }; let mut handler_off = 0; let mut insns = vec![]; let mut payloads = vec![]; @@ -517,15 +539,27 @@ impl DexWriter { // https://cs.android.com/android/platform/superproject/main/+/main:art/runtime/verifier/method_verifier.cc;drc=e8c3e7be783937a340cd4f3280b69962d6f1ea0c;l=1347 // The ART check if the array data table is 4 bytes aligned (= 2 ins alligned) // TODO: check how it is donne in android and other dex generation code. - let nop = (Instruction::Nop {}) - .get_raw_ins(None, None, None, None, None, None)?; + let nop = (Instruction::Nop {}).get_raw_ins( + None, None, None, None, None, None, None, None, None, None, + )?; payload_addr += nop.size() / 2; payloads.push(nop); } let data_offset = payload_addr as i32 - addr as i32; payload_addr += payload.size() / 2; payloads.push(payload); - let ins = ins.get_raw_ins(None, None, None, None, None, Some(data_offset))?; + let ins = ins.get_raw_ins( + None, + None, + None, + None, + None, + None, + None, + None, + None, + Some(data_offset), + )?; addr += ins.size() / 2; insns.push(ins); } @@ -533,6 +567,10 @@ impl DexWriter { let goto_size = goto_sizes[goto_idx]; goto_idx += 1; let ins = ins.get_raw_ins( + None, + None, + None, + None, None, None, None, @@ -570,158 +608,74 @@ impl DexWriter { // https://cs.android.com/android/platform/superproject/main/+/main:art/runtime/verifier/method_verifier.cc;drc=e8c3e7be783937a340cd4f3280b69962d6f1ea0c;l=1464 // The ART check if the switch table is 4 bytes aligned (= 2 ins alligned) // TODO: check how it is donne in android and other dex generation code. - let nop = (Instruction::Nop {}) - .get_raw_ins(None, None, None, None, None, None)?; + let nop = (Instruction::Nop {}).get_raw_ins( + None, None, None, None, None, None, None, None, None, None, + )?; payload_addr += nop.size() / 2; payloads.push(nop); } let data_offset = payload_addr as i32 - addr as i32; payload_addr += payload.size() / 2; payloads.push(payload); - let ins = ins.get_raw_ins(None, None, None, None, None, Some(data_offset))?; + let ins = ins.get_raw_ins( + None, + None, + None, + None, + None, + None, + None, + None, + None, + Some(data_offset), + )?; addr += ins.size() / 2; insns.push(ins); } - Instruction::InvokeVirtual(ins) => { - let meth = &ins.method; - let meth_idx = self.method_ids.get(meth).ok_or(anyhow!( - "Method {} (method of class {}, found in code of {}) not found in dex builder", - meth.__repr__(), - meth.class_.__repr__(), - method_id.__repr__() - ))?; - debug_assert!( - *meth_idx <= u16::MAX as usize, - "methode id too big for invoke instruction" - ); - let meth_idx = *meth_idx as u16; - let ins = ins.get_raw_ins(meth_idx); - addr += ins.size() / 2; - insns.push(ins); - } - Instruction::InvokeSuper(ins) => { - let meth = &ins.method; - let meth_idx = self.method_ids.get(meth).ok_or(anyhow!( - "Method {} (method of class {}, found in code of {}) not found in dex builder", - meth.__repr__(), - meth.class_.__repr__(), - method_id.__repr__() - ))?; - debug_assert!( - *meth_idx <= u16::MAX as usize, - "methode id too big for invoke instruction" - ); - let meth_idx = *meth_idx as u16; - let ins = ins.get_raw_ins(meth_idx); - addr += ins.size() / 2; - insns.push(ins); - } - Instruction::InvokeDirect(ins) => { - let meth = &ins.method; - let meth_idx = self.method_ids.get(meth).ok_or(anyhow!( - "Method {} (method of class {}, found in code of {}) not found in dex builder", - meth.__repr__(), - meth.class_.__repr__(), - method_id.__repr__() - ))?; - debug_assert!( - *meth_idx <= u16::MAX as usize, - "methode id too big for invoke instruction" - ); - let meth_idx = *meth_idx as u16; - let ins = ins.get_raw_ins(meth_idx); - addr += ins.size() / 2; - insns.push(ins); - } - Instruction::InvokeStatic(ins) => { - let meth = &ins.method; - let meth_idx = self.method_ids.get(meth).ok_or(anyhow!( - "Method {} (method of class {}, found in code of {}) not found in dex builder", - meth.__repr__(), - meth.class_.__repr__(), - method_id.__repr__() - ))?; - debug_assert!( - *meth_idx <= u16::MAX as usize, - "methode id too big for invoke instruction" - ); - let meth_idx = *meth_idx as u16; - let ins = ins.get_raw_ins(meth_idx); - addr += ins.size() / 2; - insns.push(ins); - } - Instruction::InvokeInterface(ins) => { - let meth = &ins.method; - let meth_idx = self.method_ids.get(meth).ok_or(anyhow!( - "Method {} (method of class {}, found in code of {}) not found in dex builder", - meth.__repr__(), - meth.class_.__repr__(), - method_id.__repr__() - ))?; - debug_assert!( - *meth_idx <= u16::MAX as usize, - "methode id too big for invoke instruction" - ); - let meth_idx = *meth_idx as u16; - let ins = ins.get_raw_ins(meth_idx); - addr += ins.size() / 2; - insns.push(ins); - } - Instruction::InvokePolymorphic(ins) => { - let meth = &ins.method; - let meth_idx = self.method_ids.get(meth).ok_or(anyhow!( - "Method {} (method of class {}, found in code of {}) not found in dex builder", - meth.__repr__(), - meth.class_.__repr__(), - method_id.__repr__() - ))?; - let proto_idx = self.proto_ids.get(&ins.proto).ok_or(anyhow!( - "Prototype {} (found in code of {}) not found in dex builder", - ins.proto.__repr__(), - method_id.__repr__() - ))?; - debug_assert!( - *meth_idx <= u16::MAX as usize, - "methode id too big for invoke instruction" - ); - debug_assert!( - *proto_idx <= u16::MAX as usize, - "proto id too big for invoke instruction" - ); - let meth_idx = *meth_idx as u16; - let proto_idx = *proto_idx as u16; - let ins = ins.get_raw_ins(meth_idx, proto_idx); - addr += ins.size() / 2; - insns.push(ins); - } - Instruction::InvokeCustom(ins) => { + Instruction::InvokeCustom { call_site, .. } => { let call_site_idx = self.call_site_ids.len(); - self.insert_call_site_item(&ins.call_site)?; - let ins = ins.get_raw_ins(call_site_idx); + self.insert_call_site_item(&call_site)?; + let ins = ins.get_raw_ins( + None, + None, + None, + None, + None, + Some(call_site_idx), + None, + None, + None, + None, + )?; addr += ins.size() / 2; insns.push(ins); } - Instruction::ConstMethodHandle(ins) => { + Instruction::ConstMethodHandle { handle, .. } => { let method_handle_idx = self.method_handles.len(); - self.insert_method_handle(&ins.handle)?; - let ins = ins.get_raw_ins(method_handle_idx); + self.insert_method_handle(&handle)?; + let ins = ins.get_raw_ins( + None, + None, + None, + None, + None, + None, + Some(method_handle_idx), + None, + None, + None, + )?; addr += ins.size() / 2; insns.push(ins); } - Instruction::ConstMethodType(ins) => { - let proto_idx = self.proto_ids.get(&ins.proto).ok_or(anyhow!( - "Prototype {} (found in code of {}) not found in dex builder", - ins.proto.__repr__(), - method_id.__repr__() - ))?; - let ins = ins.get_raw_ins(*proto_idx); - addr += ins.size() / 2; - insns.push(ins); - } - Instruction::Try(try_) => { - let end_block_addr = *label_addrs.get(&try_.end_label).ok_or(anyhow!( + Instruction::Try { + end_label, + handlers, + default_handler, + } => { + let end_block_addr = *label_addrs.get(end_label).ok_or(anyhow!( "Label {} not found in code of {}, but found try with this label", - &try_.end_label, + end_label, method_id.__repr__() ))?; if end_block_addr < addr { @@ -741,7 +695,7 @@ impl DexWriter { handlers: vec![], catch_all_addr: None, }; - for (ty, label) in &try_.handlers { + for (ty, label) in handlers { let type_idx = Uleb128(*self.type_ids.get(ty).ok_or(anyhow!( "Could not found type {} captured by a try block in {}\ in the dex builder", @@ -751,7 +705,7 @@ impl DexWriter { let addr = Uleb128(*label_addrs.get(label).ok_or(anyhow!( "Label {} not found in code of {}, but found try \ with this label as catch for type {}", - &try_.end_label, + end_label, method_id.__repr__(), ty.__repr__(), ))? as u32); @@ -759,17 +713,17 @@ impl DexWriter { .handlers .push(EncodedTypeAddrPair { type_idx, addr }); } - if let Some(ref label) = try_.default_handler { + if let Some(ref label) = default_handler { let catch_all_addr = *label_addrs.get(label).ok_or(anyhow!( "Label {} not found in code of {}, but found try \ with this label as catch all", - &try_.end_label, + end_label, method_id.__repr__() ))?; catches.catch_all_addr = Some(Uleb128(catch_all_addr as u32)); } handler_off += catches.size(); - handlers.list.push(catches); + encoded_handlers.list.push(catches); } Instruction::Label { .. } => (), _ => { @@ -778,6 +732,10 @@ impl DexWriter { Some(&self.strings), Some(&self.type_ids), Some(&self.field_ids), + Some(&self.method_ids), + Some(&self.proto_ids), + None, + None, Some((addr, &label_addrs)), None, None, @@ -796,14 +754,15 @@ impl DexWriter { } if addr % 2 != 0 { // make sure the payload section is 4 bytes aligned - let nop = (Instruction::Nop {}).get_raw_ins(None, None, None, None, None, None)?; + let nop = (Instruction::Nop {}) + .get_raw_ins(None, None, None, None, None, None, None, None, None, None)?; //addr += nop.size() / 2; insns.push(nop); } insns.extend(payloads); for try_ in &mut tries { - try_.handler_off += handlers.size_field().size() as u16; + try_.handler_off += encoded_handlers.size_field().size() as u16; } let debug_info_off = if code.debug_info.1.is_empty() && code.parameter_names.is_none() { diff --git a/androscalpel/src/instructions.rs b/androscalpel/src/instructions.rs index ee76295..0a2dd71 100644 --- a/androscalpel/src/instructions.rs +++ b/androscalpel/src/instructions.rs @@ -1965,6 +1965,79 @@ macro_rules! raw_ins_sget_put { }}; } +macro_rules! raw_ins_invoke { + ($ins_op_35c:tt, $ins_op_3rc:tt, $method_ids:ident, $meth:ident, $args:ident) => {{ + let meth_idx = $method_ids.get($meth).ok_or(anyhow!( + "Method {} (method of class {}) not found in dex builder", + $meth.__repr__(), + $meth.class_.__repr__(), + ))?; + debug_assert!( + *meth_idx <= u16::MAX as usize, + "methode id too big for invoke instruction" + ); + let meth_idx = *meth_idx as u16; + let mut last = None; + let mut first = None; + let mut consec = true; + let mut four_bites = true; + let len = $args.len(); + for r in $args.iter().cloned() { + if first.is_none() { + first = Some(r); + } + if let Some(last) = last { + if r != last + 1 { + consec = false; + } + } + if r & 0b1111_0000 != 0 { + four_bites = false; + } + last = Some(r); + } + if four_bites && len <= 5 { + let mut regs = vec![]; + for reg in $args.iter().cloned() { + regs.push(reg); + } + while regs.len() != 5 { + regs.push(0); + } + let [vc, vd, ve, vf, vg]: [u8; 5] = regs + .into_iter() + .map(|r| r as u8) + .collect::>() + .try_into() + .ok() + .unwrap(); + let a = $args.len() as u8; + Ok(InsFormat::Format35C { + op: $ins_op_35c, + a, + vc, + ve, + vd, + vf, + vg, + b: meth_idx, + }) + } else if consec && len <= 255 { + let a = $args.len() as u8; + let vc = if let Some(vc) = first { vc } else { 0 }; + Ok(InsFormat::Format3RC { + op: $ins_op_3rc, + a, + vc, + b: meth_idx, + }) + } else { + // Not supposed to happend with a sanitized invoke + Err(anyhow!("Invalid Invoke instruction")) + } + }}; +} + #[pymethods] impl Instruction { pub fn __eq__(&self, other: &Self) -> bool { @@ -3987,6 +4060,50 @@ impl Instruction { /// - `IPutByte` /// - `IPutChar` /// - `IPutShort` + /// - `SGet` + /// - `SGetWide` + /// - `SGetObject` + /// - `SGetBoolean` + /// - `SGetByte` + /// - `SGetChar` + /// - `SGetShort` + /// - `SPut` + /// - `SPutWide` + /// - `SPutObject` + /// - `SPutBoolean` + /// - `SPutByte` + /// - `SPutChar` + /// - `SPutShort` + /// + /// # Variants that require `method_ids` + /// + /// `method_ids` is a lookup table that associate its idx to a method. + /// + /// - `InvokeVirtual` + /// - `InvokeSuper` + /// - `InvokeDirect` + /// - `InvokeStatic` + /// - `InvokeInterface` + /// - `InvokePolymorphic` + /// + /// # Variants that require `proto_ids` + /// + /// `proto_ids` is a lookup table that associate its idx to a method type. + /// + /// - `InvokePolymorphic` + /// - `ConstMethodType` + /// + /// # Variants that require `call_site_idx` + /// + /// `call_site_idx` is the idx of the call site used by the instruction + /// + /// - `InvokeCustom` + /// + /// # Variants that require `method_handle_idx` + /// + /// `method_handle_idx` is the idx of the method handle used by the instruction + /// + /// - `ConstMethodHandle` /// /// # Variants that require `data_offset` /// @@ -4023,36 +4140,18 @@ impl Instruction { /// /// # Variants that do not implement this method: /// - /// - `SGet` - /// - `SGetWide` - /// - `SGetObject` - /// - `SGetBoolean` - /// - `SGetByte` - /// - `SGetChar` - /// - `SGetShort` - /// - `SPut` - /// - `SPutWide` - /// - `SPutObject` - /// - `SPutBoolean` - /// - `SPutByte` - /// - `SPutChar` - /// - `SPutShort` - /// - `InvokeVirtual` - /// - `InvokeSuper` - /// - `InvokeDirect` - /// - `InvokeStatic` - /// - `InvokeInterface` - /// - `InvokePolymorphic` - /// - `InvokeCustom` - /// - `ConstMethodHandle` - /// - `ConstMethodType` /// - `Try` /// - `Label` + /// pub fn get_raw_ins( &self, strings: Option<&HashMap>, type_ids: Option<&HashMap>, field_ids: Option<&HashMap>, + method_ids: Option<&HashMap>, + proto_ids: Option<&HashMap>, + call_site_idx: Option, + method_handle_idx: Option, jump_data: Option<(usize, &HashMap)>, goto_size: Option, data_offset: Option, @@ -4062,6 +4161,10 @@ impl Instruction { strings, type_ids, field_ids, + method_ids, + proto_ids, + call_site_idx, + method_handle_idx, jump_data, goto_size, data_offset, @@ -4071,6 +4174,10 @@ impl Instruction { None, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4082,6 +4189,10 @@ impl Instruction { Some(strings), _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4108,6 +4219,10 @@ impl Instruction { _strings, None, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4119,6 +4234,10 @@ impl Instruction { _strings, Some(types), _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4135,6 +4254,10 @@ impl Instruction { _strings, None, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4146,6 +4269,10 @@ impl Instruction { _strings, Some(types), _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4162,6 +4289,10 @@ impl Instruction { _strings, None, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4173,6 +4304,10 @@ impl Instruction { _strings, Some(types), _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4190,6 +4325,10 @@ impl Instruction { _strings, None, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4201,6 +4340,10 @@ impl Instruction { _strings, Some(types), _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4217,6 +4360,10 @@ impl Instruction { _strings, None, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4228,6 +4375,10 @@ impl Instruction { _strings, Some(types), _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4245,6 +4396,10 @@ impl Instruction { _strings, None, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4256,6 +4411,10 @@ impl Instruction { _strings, Some(types), _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4330,6 +4489,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, None, @@ -4342,6 +4505,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, Some(data_offset), @@ -4350,19 +4517,45 @@ impl Instruction { va: *arr, b: data_offset, }), - (Self::Goto { .. }, _strings, _types, _fields, None, _goto_size, _data_offset) => Err( - anyhow!("Cannot get the size of a goto without knowing the branch offset"), - ), - (Self::Goto { .. }, _strings, _types, _fields, _jump_data, None, _data_offset) => { - Err(anyhow!( - "Cannot get the size of a goto without knowing the size of the instruction" - )) - } + ( + Self::Goto { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + None, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the size of a goto without knowing the branch offset" + )), + ( + Self::Goto { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + _jump_data, + None, + _data_offset, + ) => Err(anyhow!( + "Cannot get the size of a goto without knowing the size of the instruction" + )), ( Self::Goto { label }, _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, Some((addr, label_addrs)), Some(goto_size), _data_offset, @@ -4393,17 +4586,31 @@ impl Instruction { Err(anyhow!("Invalid goto_size and/or data_offset value")) } } - (Self::Switch { .. }, _strings, _types, _fields, _jump_data, _goto_size, None) => { - Err(anyhow!( - "Cannot get the raw instruction of a switch without knowing the offset \ + ( + Self::Switch { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + None, + ) => Err(anyhow!( + "Cannot get the raw instruction of a switch without knowing the offset \ to the packed/sparse-switch-payload" - )) - } + )), ( Self::Switch { reg, .. }, _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, Some(data_offset), @@ -4412,83 +4619,207 @@ impl Instruction { va: *reg, b: data_offset, }), - (Self::IfEq { .. }, _strings, _types, _fields, None, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a if-eq without knowing \ + ( + Self::IfEq { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + None, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a if-eq without knowing \ the offset to the branch" - )) - } - (Self::IfNe { .. }, _strings, _types, _fields, None, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a if-ne without knowing \ + )), + ( + Self::IfNe { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + None, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a if-ne without knowing \ the offset to the branch" - )) - } - (Self::IfLt { .. }, _strings, _types, _fields, None, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a if-lt without knowing \ + )), + ( + Self::IfLt { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + None, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a if-lt without knowing \ the offset to the branch" - )) - } - (Self::IfGe { .. }, _strings, _types, _fields, None, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a if-ge without knowing \ + )), + ( + Self::IfGe { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + None, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a if-ge without knowing \ the offset to the branch" - )) - } - (Self::IfGt { .. }, _strings, _types, _fields, None, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a if-gt without knowing \ + )), + ( + Self::IfGt { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + None, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a if-gt without knowing \ the offset to the branch" - )) - } - (Self::IfLe { .. }, _strings, _types, _fields, None, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a if-le without knowing \ + )), + ( + Self::IfLe { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + None, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a if-le without knowing \ the offset to the branch" - )) - } - (Self::IfEqZ { .. }, _strings, _types, _fields, None, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a if-eqz without knowing \ + )), + ( + Self::IfEqZ { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + None, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a if-eqz without knowing \ the offset to the branch" - )) - } - (Self::IfNeZ { .. }, _strings, _types, _fields, None, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a if-nez without knowing \ + )), + ( + Self::IfNeZ { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + None, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a if-nez without knowing \ the offset to the branch" - )) - } - (Self::IfLtZ { .. }, _strings, _types, _fields, None, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a if-ltz without knowing \ + )), + ( + Self::IfLtZ { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + None, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a if-ltz without knowing \ the offset to the branch" - )) - } - (Self::IfGeZ { .. }, _strings, _types, _fields, None, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a if-gez without knowing \ + )), + ( + Self::IfGeZ { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + None, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a if-gez without knowing \ the offset to the branch" - )) - } - (Self::IfGtZ { .. }, _strings, _types, _fields, None, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a if-gtz without knowing \ + )), + ( + Self::IfGtZ { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + None, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a if-gtz without knowing \ the offset to the branch" - )) - } - (Self::IfLeZ { .. }, _strings, _types, _fields, None, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a if-lez without knowing \ + )), + ( + Self::IfLeZ { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + None, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a if-lez without knowing \ the offset to the branch" - )) - } + )), ( Self::IfEq { a, b, label }, _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, Some((addr, label_addrs)), _goto_size, _data_offset, @@ -4498,6 +4829,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, Some((addr, label_addrs)), _goto_size, _data_offset, @@ -4507,6 +4842,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, Some((addr, label_addrs)), _goto_size, _data_offset, @@ -4516,6 +4855,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, Some((addr, label_addrs)), _goto_size, _data_offset, @@ -4525,6 +4868,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, Some((addr, label_addrs)), _goto_size, _data_offset, @@ -4534,6 +4881,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, Some((addr, label_addrs)), _goto_size, _data_offset, @@ -4543,6 +4894,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, Some((addr, label_addrs)), _goto_size, _data_offset, @@ -4552,6 +4907,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, Some((addr, label_addrs)), _goto_size, _data_offset, @@ -4561,6 +4920,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, Some((addr, label_addrs)), _goto_size, _data_offset, @@ -4570,6 +4933,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, Some((addr, label_addrs)), _goto_size, _data_offset, @@ -4579,6 +4946,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, Some((addr, label_addrs)), _goto_size, _data_offset, @@ -4588,20 +4959,38 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, Some((addr, label_addrs)), _goto_size, _data_offset, ) => raw_ins_ifz!(0x3b, label_addrs, label, addr, a), - (Self::IGet { .. }, _strings, _types, None, _jump_data, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a iget without knowing the field idx" - )) - } + ( + Self::IGet { .. }, + _strings, + _types, + None, + _methods, + _protos, + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a iget without knowing the field idx" + )), ( Self::IGetWide { .. }, _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4613,6 +5002,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4624,6 +5017,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4635,6 +5032,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4646,6 +5047,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4657,22 +5062,40 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, ) => Err(anyhow!( "Cannot get the raw instruction of a iget-short without knowing the field idx" )), - (Self::IPut { .. }, _strings, _types, None, _jump_data, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a iput without knowing the field idx" - )) - } + ( + Self::IPut { .. }, + _strings, + _types, + None, + _methods, + _protos, + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a iput without knowing the field idx" + )), ( Self::IPutWide { .. }, _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4684,6 +5107,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4695,6 +5122,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4706,6 +5137,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4717,6 +5152,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4728,6 +5167,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4739,6 +5182,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4748,6 +5195,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4757,6 +5208,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4766,6 +5221,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4775,6 +5234,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4784,6 +5247,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4793,6 +5260,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4802,6 +5273,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4811,6 +5286,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4820,6 +5299,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4829,6 +5312,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4838,6 +5325,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4847,6 +5338,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4856,20 +5351,38 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, ) => raw_ins_iget_put!(0x5f, fields, field, from, obj), - (Self::SGet { .. }, _strings, _types, None, _jump_data, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a sget without knowing the field idx" - )) - } + ( + Self::SGet { .. }, + _strings, + _types, + None, + _methods, + _protos, + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a sget without knowing the field idx" + )), ( Self::SGetWide { .. }, _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4881,6 +5394,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4892,6 +5409,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4903,6 +5424,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4914,6 +5439,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4925,22 +5454,40 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, ) => Err(anyhow!( "Cannot get the raw instruction of a sget-short without knowing the field idx" )), - (Self::SPut { .. }, _strings, _types, None, _jump_data, _goto_size, _data_offset) => { - Err(anyhow!( - "Cannot get the raw instruction of a sput without knowing the field idx" - )) - } + ( + Self::SPut { .. }, + _strings, + _types, + None, + _methods, + _protos, + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a sput without knowing the field idx" + )), ( Self::SPutWide { .. }, _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4952,6 +5499,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4963,6 +5514,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4974,6 +5529,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4985,6 +5544,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -4996,6 +5559,10 @@ impl Instruction { _strings, _types, None, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5007,6 +5574,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5016,6 +5587,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5025,6 +5600,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5034,6 +5613,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5043,6 +5626,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5052,6 +5639,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5061,6 +5652,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5070,6 +5665,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5079,6 +5678,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5088,6 +5691,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5097,6 +5704,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5106,6 +5717,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5115,6 +5730,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5124,6 +5743,10 @@ impl Instruction { _strings, _types, Some(fields), + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5133,6 +5756,10 @@ impl Instruction { _strings, _types, _fields, + None, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5145,6 +5772,10 @@ impl Instruction { _strings, _types, _fields, + None, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5157,6 +5788,10 @@ impl Instruction { _strings, _types, _fields, + None, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5169,6 +5804,10 @@ impl Instruction { _strings, _types, _fields, + None, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5181,6 +5820,10 @@ impl Instruction { _strings, _types, _fields, + None, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5188,23 +5831,209 @@ impl Instruction { "Cannot get the raw instruction of a invoke-interface without knowing \ the method idx" )), + ( + Self::InvokeVirtual { args, method }, + _strings, + _types, + _fields, + Some(methods), + _protos, + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => raw_ins_invoke!(0x6e, 0x74, methods, method, args), + ( + Self::InvokeSuper { args, method }, + _strings, + _types, + _fields, + Some(methods), + _protos, + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => raw_ins_invoke!(0x6f, 0x75, methods, method, args), + ( + Self::InvokeDirect { args, method }, + _strings, + _types, + _fields, + Some(methods), + _protos, + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => raw_ins_invoke!(0x70, 0x76, methods, method, args), + ( + Self::InvokeStatic { args, method }, + _strings, + _types, + _fields, + Some(methods), + _protos, + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => raw_ins_invoke!(0x71, 0x77, methods, method, args), + ( + Self::InvokeInterface { args, method }, + _strings, + _types, + _fields, + Some(methods), + _protos, + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => raw_ins_invoke!(0x72, 0x78, methods, method, args), ( Self::InvokePolymorphic { .. }, _strings, _types, _fields, + None, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, ) => Err(anyhow!( "Cannot get the raw instruction of a invoke-polymorphic without knowing \ - the method idx and proto idx" + the method idx" )), + ( + Self::InvokePolymorphic { .. }, + _strings, + _types, + _fields, + _methods, + None, + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Cannot get the raw instruction of a invoke-polymorphic without knowing \ + the proto idx" + )), + ( + Self::InvokePolymorphic { + args, + method, + proto, + }, + _strings, + _types, + _fields, + Some(methods), + Some(protos), + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => { + let meth_idx = methods.get(method).ok_or(anyhow!( + "Method {} (method of class {}) not found in dex builder", + method.__repr__(), + method.class_.__repr__(), + ))?; + let proto_idx = protos.get(proto).ok_or(anyhow!( + "Prototype {} not found in dex builder", + proto.__repr__(), + ))?; + debug_assert!( + *meth_idx <= u16::MAX as usize, + "methode id too big for invoke instruction" + ); + debug_assert!( + *proto_idx <= u16::MAX as usize, + "proto id too big for invoke instruction" + ); + let meth_idx = *meth_idx as u16; + let proto_idx = *proto_idx as u16; + let mut last = None; + let mut first = None; + let mut consec = true; + let mut four_bites = true; + let len = args.len(); + for r in args.iter().cloned() { + if first.is_none() { + first = Some(r); + } + if let Some(last) = last { + if r != last + 1 { + consec = false; + } + } + if r & 0b1111_0000 != 0 { + four_bites = false; + } + last = Some(r); + } + if four_bites && len <= 5 { + let mut regs = vec![]; + for reg in args.iter().cloned() { + regs.push(reg); + } + while regs.len() != 5 { + regs.push(0); + } + let [vc, vd, ve, vf, vg]: [u8; 5] = regs + .into_iter() + .map(|r| r as u8) + .collect::>() + .try_into() + .ok() + .unwrap(); + let a = args.len() as u8; + Ok(InsFormat::Format45CC { + op: 0xfa, + a, + vc, + ve, + vd, + vf, + vg, + b: meth_idx, + h: proto_idx, + }) + } else if consec && len <= 255 { + let a = args.len() as u8; + let vc = if let Some(vc) = first { vc } else { 0 }; + Ok(InsFormat::Format4RCC { + op: 0xfb, + a, + vc, + b: meth_idx, + h: proto_idx, + }) + } else { + // Not supposed to happend with a sanitized invoke + bail!("Invalid Invoke instruction {self:?}") + } + } ( Self::InvokeCustom { .. }, _strings, _types, _fields, + _methods, + _protos, + None, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5212,11 +6041,87 @@ impl Instruction { "Cannot get the raw instruction of a invoke-custom without knowing the \ call site idx" )), + ( + Self::InvokeCustom { args, .. }, + _strings, + _types, + _fields, + _methods, + _protos, + Some(call_site_idx), + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => { + let mut last = None; + let mut first = None; + let mut consec = true; + let mut four_bites = true; + let len = args.len(); + for r in args.iter().cloned() { + if first.is_none() { + first = Some(r); + } + if let Some(last) = last { + if r != last + 1 { + consec = false; + } + } + if r & 0b1111_0000 != 0 { + four_bites = false; + } + last = Some(r); + } + if four_bites && len <= 5 { + let mut regs = vec![]; + for reg in args.iter().cloned() { + regs.push(reg); + } + while regs.len() != 5 { + regs.push(0); + } + let [vc, vd, ve, vf, vg]: [u8; 5] = regs + .into_iter() + .map(|r| r as u8) + .collect::>() + .try_into() + .ok() + .unwrap(); + let a = args.len() as u8; + Ok(InsFormat::Format35C { + op: 0xfc, + a, + vc, + ve, + vd, + vf, + vg, + b: call_site_idx as u16, + }) + } else if consec && len <= 255 { + let a = args.len() as u8; + let vc = if let Some(vc) = first { vc } else { 0 }; + Ok(InsFormat::Format3RC { + op: 0xfd, + a, + vc, + b: call_site_idx as u16, + }) + } else { + // Not supposed to happend with a sanitized invoke + bail!("Invalid Invoke instruction {self:?}") + } + } ( Self::ConstMethodHandle { .. }, _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + None, _jump_data, _goto_size, _data_offset, @@ -5224,11 +6129,32 @@ impl Instruction { "Cannot get the raw instruction of a const-method-handle \ without knowing the method handle idx" )), + ( + Self::ConstMethodHandle { to, .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + Some(handle_idx), + _jump_data, + _goto_size, + _data_offset, + ) => Ok(InsFormat::Format21C { + op: 0xfe, + va: *to, + b: handle_idx as u16, + }), ( Self::ConstMethodType { .. }, _strings, _types, _fields, + _methods, + None, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5236,28 +6162,79 @@ impl Instruction { "Cannot get the raw instruction of a const-method-type \ without knowing the proto idx" )), - (Self::Try { .. }, _strings, _types, _fields, _jump_data, _goto_size, _data_offset) => { - Err(anyhow!( - "Try instruction cannot be converted to raw instruction" - )) + ( + Self::ConstMethodType { to, proto }, + _strings, + _types, + _fields, + _methods, + Some(protos), + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => { + let proto_idx = protos.get(proto).ok_or(anyhow!( + "Prototype {} not found in dex builder", + proto.__repr__(), + ))?; + Ok(InsFormat::Format21C { + op: 0xff, + va: *to, + b: *proto_idx as u16, + }) } + ( + Self::Try { .. }, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => Err(anyhow!( + "Try instruction cannot be converted to raw instruction" + )), ( Self::Label { .. }, _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, ) => Err(anyhow!("Label cannot be converted to raw instruction")), - (Self::Nop {}, _strings, _types, _fields, _jump_data, _goto_size, _data_offset) => { - Ok(InsFormat::Format10X { op: 0x00 }) - } + ( + Self::Nop {}, + _strings, + _types, + _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, + _jump_data, + _goto_size, + _data_offset, + ) => Ok(InsFormat::Format10X { op: 0x00 }), ( Self::Move { from, to }, _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5283,6 +6260,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5308,6 +6289,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5333,6 +6318,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5342,6 +6331,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5351,6 +6344,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5360,6 +6357,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5369,6 +6370,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5378,6 +6383,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5387,6 +6396,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5396,6 +6409,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5405,6 +6422,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5435,6 +6456,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5465,6 +6490,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5474,6 +6503,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5483,6 +6516,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5496,6 +6533,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5505,6 +6546,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5519,6 +6564,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5533,6 +6582,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5547,6 +6600,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5561,6 +6618,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5575,6 +6636,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5589,6 +6654,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5603,6 +6672,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5617,6 +6690,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5631,6 +6708,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5645,6 +6726,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5659,6 +6744,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5673,6 +6762,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5687,6 +6780,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5701,6 +6798,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5715,6 +6816,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5729,6 +6834,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5743,6 +6852,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5757,6 +6870,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -5766,313 +6883,15 @@ impl Instruction { vb: *arr, vc: *idx, }), - /* needs meth_idx - (Self::InvokeVirtual { args, method }, _strings, _types,_fields, _jump_data, _goto_size, _data_offset) => { - let mut last = None; - let mut first = None; - let mut consec = true; - let mut four_bites = true; - let len = args.len(); - for r in args.iter().cloned() { - if first.is_none() { - first = Some(r); - } - if let Some(last) = last { - if r != last + 1 { - consec = false; - } - } - if r & 0b1111_0000 != 0 { - four_bites = false; - } - last = Some(r); - } - if four_bites && len <= 5 { - let mut regs = vec![]; - for reg in args.iter().cloned() { - regs.push(reg); - } - while regs.len() != 5 { - regs.push(0); - } - let [vc, vd, ve, vf, vg]: [u8; 5] = regs - .into_iter() - .map(|r| r as u8) - .collect::>() - .try_into() - .ok() - .unwrap(); - let a = args.len() as u8; - Ok(InsFormat::Format35C { - op: 0x6e, - a, - vc, - ve, - vd, - vf, - vg, - b: meth_idx, - }) - } else if consec && len <= 255 { - let a = args.len() as u8; - let vc = if let Some(vc) = first { vc } else { 0 }; - Ok(InsFormat::Format3RC { - op: 0x74, - a, - vc, - b: meth_idx, - }) - } else { - // Not supposed to happend with a sanitized invoke - panic!("Invalid Invoke instruction {self:?}") - } - } - (Self::InvokeSuper { args, method }, _strings, _types,_fields, _jump_data, _goto_size, _data_offset) => { - let mut last = None; - let mut first = None; - let mut consec = true; - let mut four_bites = true; - let len = args.len(); - for r in args.iter().cloned() { - if first.is_none() { - first = Some(r); - } - if let Some(last) = last { - if r != last + 1 { - consec = false; - } - } - if r & 0b1111_0000 != 0 { - four_bites = false; - } - last = Some(r); - } - if four_bites && len <= 5 { - let mut regs = vec![]; - for reg in args.iter().cloned() { - regs.push(reg); - } - while regs.len() != 5 { - regs.push(0); - } - let [vc, vd, ve, vf, vg]: [u8; 5] = regs - .into_iter() - .map(|r| r as u8) - .collect::>() - .try_into() - .ok() - .unwrap(); - let a = args.len() as u8; - Ok(InsFormat::Format35C { - op: 0x6f, - a, - vc, - ve, - vd, - vf, - vg, - b: meth_idx, - }) - } else if consec && len <= 255 { - let a = args.len() as u8; - let vc = if let Some(vc) = first { vc } else { 0 }; - Ok(InsFormat::Format3RC { - op: 0x75, - a, - vc, - b: meth_idx, - }) - } else { - // Not supposed to happend with a sanitized invoke - panic!("Invalid Invoke instruction {self:?}") - } - } - (Self::InvokeDirect { args, method }, _strings, _types,_fields, _jump_data, _goto_size, _data_offset) => { - let mut last = None; - let mut first = None; - let mut consec = true; - let mut four_bites = true; - let len = args.len(); - for r in args.iter().cloned() { - if first.is_none() { - first = Some(r); - } - if let Some(last) = last { - if r != last + 1 { - consec = false; - } - } - if r & 0b1111_0000 != 0 { - four_bites = false; - } - last = Some(r); - } - if four_bites && len <= 5 { - let mut regs = vec![]; - for reg in args.iter().cloned() { - regs.push(reg); - } - while regs.len() != 5 { - regs.push(0); - } - let [vc, vd, ve, vf, vg]: [u8; 5] = regs - .into_iter() - .map(|r| r as u8) - .collect::>() - .try_into() - .ok() - .unwrap(); - let a = args.len() as u8; - Ok(InsFormat::Format35C { - op: 0x70, - a, - vc, - ve, - vd, - vf, - vg, - b: meth_idx, - }) - } else if consec && len <= 255 { - let a = args.len() as u8; - let vc = if let Some(vc) = first { vc } else { 0 }; - Ok(InsFormat::Format3RC { - op: 0x76, - a, - vc, - b: meth_idx, - }) - } else { - // Not supposed to happend with a sanitized invoke - panic!("Invalid Invoke instruction {self:?}") - } - } - (Self::InvokeStatic { args, method }, _strings, _types,_fields, _jump_data, _goto_size, _data_offset) => { - let mut last = None; - let mut first = None; - let mut consec = true; - let mut four_bites = true; - let len = args.len(); - for r in args.iter().cloned() { - if first.is_none() { - first = Some(r); - } - if let Some(last) = last { - if r != last + 1 { - consec = false; - } - } - if r & 0b1111_0000 != 0 { - four_bites = false; - } - last = Some(r); - } - if four_bites && len <= 5 { - let mut regs = vec![]; - for reg in args.iter().cloned() { - regs.push(reg); - } - while regs.len() != 5 { - regs.push(0); - } - let [vc, vd, ve, vf, vg]: [u8; 5] = regs - .into_iter() - .map(|r| r as u8) - .collect::>() - .try_into() - .ok() - .unwrap(); - let a = args.len() as u8; - Ok(InsFormat::Format35C { - op: 0x71, - a, - vc, - ve, - vd, - vf, - vg, - b: meth_idx, - }) - } else if consec && len <= 255 { - let a = args.len() as u8; - let vc = if let Some(vc) = first { vc } else { 0 }; - Ok(InsFormat::Format3RC { - op: 0x77, - a, - vc, - b: meth_idx, - }) - } else { - // Not supposed to happend with a sanitized invoke - panic!("Invalid Invoke instruction {self:?}") - } - } - (Self::InvokeInterface { args, method }, _strings, _types,_fields, _jump_data, _goto_size, _data_offset) => { - let mut last = None; - let mut first = None; - let mut consec = true; - let mut four_bites = true; - let len = args.len(); - for r in args.iter().cloned() { - if first.is_none() { - first = Some(r); - } - if let Some(last) = last { - if r != last + 1 { - consec = false; - } - } - if r & 0b1111_0000 != 0 { - four_bites = false; - } - last = Some(r); - } - if four_bites && len <= 5 { - let mut regs = vec![]; - for reg in args.iter().cloned() { - regs.push(reg); - } - while regs.len() != 5 { - regs.push(0); - } - let [vc, vd, ve, vf, vg]: [u8; 5] = regs - .into_iter() - .map(|r| r as u8) - .collect::>() - .try_into() - .ok() - .unwrap(); - let a = args.len() as u8; - Ok(InsFormat::Format35C { - op: 0x72, - a, - vc, - ve, - vd, - vf, - vg, - b: meth_idx, - }) - } else if consec && len <= 255 { - let a = args.len() as u8; - let vc = if let Some(vc) = first { vc } else { 0 }; - Ok(InsFormat::Format3RC { - op: 0x78, - a, - vc, - b: meth_idx, - }) - } else { - // Not supposed to happend with a sanitized invoke - panic!("Invalid Invoke instruction {self:?}") - } - } - */ ( Self::NegInt { dest, val }, _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6086,6 +6905,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6099,6 +6922,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6112,6 +6939,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6125,6 +6956,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6138,6 +6973,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6151,6 +6990,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6164,6 +7007,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6177,6 +7024,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6190,6 +7041,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6203,6 +7058,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6216,6 +7075,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6229,6 +7092,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6242,6 +7109,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6255,6 +7126,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6268,6 +7143,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6281,6 +7160,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6294,6 +7177,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6307,6 +7194,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6320,6 +7211,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6333,6 +7228,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6346,6 +7245,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6360,6 +7263,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6374,6 +7281,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6388,6 +7299,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6402,6 +7317,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6416,6 +7335,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6430,6 +7353,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6444,6 +7371,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6458,6 +7389,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6472,6 +7407,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6486,6 +7425,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6500,6 +7443,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6514,6 +7461,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6528,6 +7479,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6542,6 +7497,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6556,6 +7515,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6570,6 +7533,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6584,6 +7551,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6598,6 +7569,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6612,6 +7587,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6626,6 +7605,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6640,6 +7623,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6654,6 +7641,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6668,6 +7659,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6682,6 +7677,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6696,6 +7695,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6710,6 +7713,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6724,6 +7731,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6738,6 +7749,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6752,6 +7767,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6766,6 +7785,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6780,6 +7803,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6794,6 +7821,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6807,6 +7838,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6820,6 +7855,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6833,6 +7872,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6846,6 +7889,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6859,6 +7906,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6872,6 +7923,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6885,6 +7940,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6898,6 +7957,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6911,6 +7974,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6924,6 +7991,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6937,6 +8008,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6950,6 +8025,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6963,6 +8042,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6976,6 +8059,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -6989,6 +8076,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7002,6 +8093,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7015,6 +8110,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7028,6 +8127,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7041,6 +8144,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7054,6 +8161,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7067,6 +8178,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7080,6 +8195,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7093,6 +8212,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7106,6 +8229,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7119,6 +8246,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7132,6 +8263,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7145,6 +8280,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7158,6 +8297,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7171,6 +8314,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7184,6 +8331,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7197,6 +8348,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7210,6 +8365,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7255,6 +8414,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7300,6 +8463,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7345,6 +8512,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7390,6 +8561,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7435,6 +8610,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7480,6 +8659,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7525,6 +8708,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7570,6 +8757,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7584,6 +8775,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7598,6 +8793,10 @@ impl Instruction { _strings, _types, _fields, + _methods, + _protos, + _call_site_idx, + _handle_idx, _jump_data, _goto_size, _data_offset, @@ -7606,146 +8805,7 @@ impl Instruction { va: *dest, vb: *b, c: *lit, - }), /* needs method_idx and proto_idx - (Self::InvokePolymorphic { args, method, proto }, _strings, _types,_fields, _jump_data, _goto_size, _data_offset) => { - let mut last = None; - let mut first = None; - let mut consec = true; - let mut four_bites = true; - let len = args.len(); - for r in args.iter().cloned() { - if first.is_none() { - first = Some(r); - } - if let Some(last) = last { - if r != last + 1 { - consec = false; - } - } - if r & 0b1111_0000 != 0 { - four_bites = false; - } - last = Some(r); - } - if four_bites && len <= 5 { - let mut regs = vec![]; - for reg in args.iter().cloned() { - regs.push(reg); - } - while regs.len() != 5 { - regs.push(0); - } - let [vc, vd, ve, vf, vg]: [u8; 5] = regs - .into_iter() - .map(|r| r as u8) - .collect::>() - .try_into() - .ok() - .unwrap(); - let a = args.len() as u8; - Ok(InsFormat::Format45CC { - op: 0xfa, - a, - vc, - ve, - vd, - vf, - vg, - b: meth_idx, - h: proto_idx, - }) - } else if consec && len <= 255 { - let a = args.len() as u8; - let vc = if let Some(vc) = first { vc } else { 0 }; - Ok(InsFormat::Format4RCC { - op: 0xfb, - a, - vc, - b: meth_idx, - h: proto_idx, - }) - } else { - // Not supposed to happend with a sanitized invoke - panic!("Invalid Invoke instruction {self:?}") - } - } - */ - /* needs call_site_idx - (Self::InvokeCustom { args, call_site }, _strings, _types,_fields, _jump_data, _goto_size, _data_offset) => { - let mut last = None; - let mut first = None; - let mut consec = true; - let mut four_bites = true; - let len = args.len(); - for r in args.iter().cloned() { - if first.is_none() { - first = Some(r); - } - if let Some(last) = last { - if r != last + 1 { - consec = false; - } - } - if r & 0b1111_0000 != 0 { - four_bites = false; - } - last = Some(r); - } - if four_bites && len <= 5 { - let mut regs = vec![]; - for reg in args.iter().cloned() { - regs.push(reg); - } - while regs.len() != 5 { - regs.push(0); - } - let [vc, vd, ve, vf, vg]: [u8; 5] = regs - .into_iter() - .map(|r| r as u8) - .collect::>() - .try_into() - .ok() - .unwrap(); - let a = args.len() as u8; - Ok(InsFormat::Format35C { - op: 0xfc, - a, - vc, - ve, - vd, - vf, - vg, - b: call_site_idx as u16, - }) - } else if consec && len <= 255 { - let a = args.len() as u8; - let vc = if let Some(vc) = first { vc } else { 0 }; - Ok(InsFormat::Format3RC { - op: 0xfd, - a, - vc, - b: call_site_idx as u16, - }) - } else { - // Not supposed to happend with a sanitized invoke - panic!("Invalid Invoke instruction {self:?}") - } - } - */ - /* needs method_handle_idx - (Self::ConstMethodHandle {to, handle}, _strings, _types,_fields, _jump_data, _goto_size, _data_offset) => Ok(InsFormat::Format21C { - op: 0xfe, - va: *to, - b: method_handle_idx as u16, - }), - */ - /* needs proto_idx - (Self::ConstMethodType {to, proto}, _strings, _types,_fields, _jump_data, _goto_size, _data_offset) => Ok(InsFormat::Format21C { - op: 0xff, - va: *to, - b: proto_idx as u16, - }), - */ + }), } }