| 96 | |
| 97 | impl Arch for ArchX86 { |
| 98 | fn scan_instructions_internal( |
| 99 | &self, |
| 100 | address: u64, |
| 101 | code: &[u8], |
| 102 | _section_index: usize, |
| 103 | relocations: &[Relocation], |
| 104 | _diff_config: &DiffObjConfig, |
| 105 | ) -> Result<Vec<InstructionRef>> { |
| 106 | let mut out = Vec::with_capacity(code.len() / 2); |
| 107 | let mut decoder = self.decoder(code, address); |
| 108 | let mut instruction = Instruction::default(); |
| 109 | let mut reloc_iter = relocations.iter().peekable(); |
| 110 | 'outer: while decoder.can_decode() { |
| 111 | let address = decoder.ip(); |
| 112 | while let Some(reloc) = reloc_iter.peek() { |
| 113 | match reloc.address.cmp(&address) { |
| 114 | Ordering::Less => { |
| 115 | reloc_iter.next(); |
| 116 | } |
| 117 | Ordering::Equal => { |
| 118 | // If the instruction starts at a relocation, it's inline data |
| 119 | let size = self.reloc_size(reloc.flags).with_context(|| { |
| 120 | format!("Unsupported inline x86 relocation {:?}", reloc.flags) |
| 121 | })?; |
| 122 | if decoder.set_position(decoder.position() + size).is_ok() { |
| 123 | decoder.set_ip(address + size as u64); |
| 124 | out.push(InstructionRef { |
| 125 | address, |
| 126 | size: size as u8, |
| 127 | opcode: OPCODE_DATA, |
| 128 | branch_dest: None, |
| 129 | }); |
| 130 | |
| 131 | reloc_iter.next(); |
| 132 | |
| 133 | // support .byte arrays after jump tables (they're typically known as indirect tables) |
| 134 | |
| 135 | let indirect_array_address = address.wrapping_add(size as u64); |
| 136 | let indirect_array_pos = decoder.position(); |
| 137 | |
| 138 | let max_size = code.len().saturating_sub(indirect_array_pos); |
| 139 | |
| 140 | let indirect_array_size = reloc_iter |
| 141 | .peek() |
| 142 | .map(|next_reloc| { |
| 143 | next_reloc.address.saturating_sub(indirect_array_address) |
| 144 | as usize |
| 145 | }) |
| 146 | .unwrap_or(max_size) |
| 147 | .min(max_size); |
| 148 | |
| 149 | if indirect_array_size > 0 { |
| 150 | for i in 0..indirect_array_size { |
| 151 | out.push(InstructionRef { |
| 152 | address: indirect_array_address + i as u64, |
| 153 | size: 1, |
| 154 | opcode: OPCODE_DATA, |
| 155 | branch_dest: None, |