Apply this Render Layer to the lines produced by a LinearViewObject for rendering in Linear View.
(
&self,
object: &mut LinearViewObject,
_prev_object: Option<&mut LinearViewObject>,
_next_object: Option<&mut LinearViewObject>,
lines: Vec<LinearDisassemblyLi
| 97 | |
| 98 | /// Apply this Render Layer to the lines produced by a LinearViewObject for rendering in Linear View. |
| 99 | fn apply_to_linear_object( |
| 100 | &self, |
| 101 | object: &mut LinearViewObject, |
| 102 | _prev_object: Option<&mut LinearViewObject>, |
| 103 | _next_object: Option<&mut LinearViewObject>, |
| 104 | lines: Vec<LinearDisassemblyLine>, |
| 105 | ) -> Vec<LinearDisassemblyLine> { |
| 106 | let text_to_lines = |
| 107 | |function: &Function, block: &BasicBlock<NativeBlock>, text: DisassemblyTextLine| { |
| 108 | LinearDisassemblyLine { |
| 109 | ty: LinearDisassemblyLineType::CodeDisassemblyLineType, |
| 110 | function: Some(function.to_owned()), |
| 111 | basic_block: Some(block.to_owned()), |
| 112 | contents: text, |
| 113 | } |
| 114 | }; |
| 115 | |
| 116 | // Hack: HLIL bodies don't have basic blocks. |
| 117 | let obj_ident = object.identifier(); |
| 118 | if !lines.is_empty() |
| 119 | && (obj_ident.name.starts_with("HLIL") || obj_ident.name.starts_with("Language")) |
| 120 | { |
| 121 | // Apply to HLIL body. |
| 122 | let function = lines[0] |
| 123 | .function |
| 124 | .to_owned() |
| 125 | .expect("HLIL body has no function"); |
| 126 | return self.apply_to_hlil_body(&function, lines); |
| 127 | } |
| 128 | |
| 129 | // Collect the "line blocks". |
| 130 | // Line blocks are contiguous lines with the same backing basic block (or lack thereof). |
| 131 | // Line blocks also group by line type. |
| 132 | let mut line_blocks: Vec<Vec<LinearDisassemblyLine>> = Vec::new(); |
| 133 | for line in lines { |
| 134 | let Some(last_block) = line_blocks.last_mut() else { |
| 135 | // No last block, create the first block. |
| 136 | line_blocks.push(vec![line]); |
| 137 | continue; |
| 138 | }; |
| 139 | |
| 140 | let Some(last_line) = last_block.last() else { |
| 141 | // No last line, create the first line. |
| 142 | last_block.push(line); |
| 143 | continue; |
| 144 | }; |
| 145 | |
| 146 | // TODO: If we want to allow a block with multiple line types we need to specifically check |
| 147 | // TODO: If the last line type was Code, if it is and the last line is not we make a new block. |
| 148 | if last_line.basic_block == line.basic_block && last_line.ty == line.ty { |
| 149 | // Same basic block and line type, this is a part of the same line block. |
| 150 | last_block.push(line); |
| 151 | } else { |
| 152 | // Not the same line block, create a new block. |
| 153 | line_blocks.push(vec![line]); |
| 154 | } |
| 155 | } |
| 156 |
no test coverage detected