MCPcopy Index your code
hub / github.com/encounter/objdiff / display_instruction

Method display_instruction

objdiff-core/src/arch/x86.rs:187–263  ·  view source on GitHub ↗
(
        &self,
        resolved: ResolvedInstructionRef,
        diff_config: &DiffObjConfig,
        cb: &mut dyn FnMut(InstructionPart) -> Result<()>,
    )

Source from the content-addressed store, hash-verified

185 }
186
187 fn display_instruction(
188 &self,
189 resolved: ResolvedInstructionRef,
190 diff_config: &DiffObjConfig,
191 cb: &mut dyn FnMut(InstructionPart) -> Result<()>,
192 ) -> Result<()> {
193 if resolved.ins_ref.opcode == OPCODE_DATA {
194 let (mnemonic, imm) = match resolved.ins_ref.size {
195 1 => (".byte", resolved.code[0] as u64),
196 2 => (".word", self.endianness.read_u16_bytes(resolved.code.try_into()?) as u64),
197 4 => (".dword", self.endianness.read_u32_bytes(resolved.code.try_into()?) as u64),
198 _ => bail!("Unsupported x86 inline data size {}", resolved.ins_ref.size),
199 };
200 cb(InstructionPart::opcode(mnemonic, OPCODE_DATA))?;
201 if resolved.relocation.is_some() {
202 cb(InstructionPart::reloc())?;
203 } else {
204 cb(InstructionPart::unsigned(imm))?;
205 }
206 return Ok(());
207 }
208
209 let mut decoder = self.decoder(resolved.code, resolved.ins_ref.address);
210 let mut formatter = self.formatter(diff_config);
211 let mut instruction = Instruction::default();
212 decoder.decode_out(&mut instruction);
213
214 // Determine where to insert relocation in instruction output.
215 // We replace the immediate or displacement with a placeholder value since the formatter
216 // doesn't provide enough information to know which number is the displacement inside a
217 // memory operand.
218 let mut reloc_replace = None;
219 if let Some(reloc) = resolved.relocation {
220 const PLACEHOLDER: u64 = 0x7BDE3E7D; // chosen by fair dice roll. guaranteed to be random.
221 let reloc_offset = reloc.relocation.address - resolved.ins_ref.address;
222 let reloc_size = self.reloc_size(reloc.relocation.flags).unwrap_or(usize::MAX);
223 let offsets = decoder.get_constant_offsets(&instruction);
224 if reloc_offset == offsets.displacement_offset() as u64
225 && reloc_size == offsets.displacement_size()
226 {
227 instruction.set_memory_displacement64(PLACEHOLDER);
228 // Formatter always writes the displacement as Int32
229 reloc_replace = Some((OpKind::Memory, 4, PLACEHOLDER));
230 } else if reloc_offset == offsets.immediate_offset() as u64
231 && reloc_size == offsets.immediate_size()
232 {
233 let is_branch = matches!(
234 instruction.op0_kind(),
235 OpKind::NearBranch16 | OpKind::NearBranch32 | OpKind::NearBranch64
236 );
237 let op_kind = if is_branch {
238 instruction.op0_kind()
239 } else {
240 match reloc_size {
241 2 => OpKind::Immediate16,
242 4 => OpKind::Immediate32,
243 8 => OpKind::Immediate64,
244 _ => OpKind::default(),

Calls 4

is_someMethod · 0.80
decoderMethod · 0.80
formatterMethod · 0.80
reloc_sizeMethod · 0.80