Executes the command.
(self)
| 106 | |
| 107 | /// Executes the command. |
| 108 | pub fn execute(self) -> Result<()> { |
| 109 | // Setup stdout handling color options. Also build some variables used |
| 110 | // below to configure colors of certain items. |
| 111 | let mut choice = self.color; |
| 112 | if choice == ColorChoice::Auto && !std::io::stdout().is_terminal() { |
| 113 | choice = ColorChoice::Never; |
| 114 | } |
| 115 | let mut stdout = StandardStream::stdout(choice); |
| 116 | |
| 117 | let mut color_address = ColorSpec::new(); |
| 118 | color_address.set_bold(true).set_fg(Some(Color::Yellow)); |
| 119 | let mut color_bytes = ColorSpec::new(); |
| 120 | color_bytes.set_fg(Some(Color::Magenta)); |
| 121 | |
| 122 | let bytes = self.read_cwasm()?; |
| 123 | |
| 124 | // Double-check this is a `*.cwasm` |
| 125 | if Engine::detect_precompiled(&bytes).is_none() { |
| 126 | bail!("not a `*.cwasm` file from wasmtime: {:?}", self.cwasm); |
| 127 | } |
| 128 | |
| 129 | // Parse the input as an ELF file, extract the `.text` section. |
| 130 | let elf = ElfFile64::<Endianness>::parse(&bytes)?; |
| 131 | let text = elf |
| 132 | .section_by_name(".text") |
| 133 | .context("missing .text section")?; |
| 134 | let text = text.data()?; |
| 135 | |
| 136 | let frame_table_descriptors = elf |
| 137 | .section_by_name(obj::ELF_WASMTIME_FRAMES) |
| 138 | .and_then(|section| section.data().ok()) |
| 139 | .and_then(|bytes| FrameTable::parse(bytes, text).ok()); |
| 140 | |
| 141 | let mut breakpoints = frame_table_descriptors |
| 142 | .iter() |
| 143 | .flat_map(|ftd| ftd.breakpoint_patches()) |
| 144 | .map(|(wasm_pc, patch)| (wasm_pc, patch.offset, SmallVec::from(patch.enable))) |
| 145 | .collect::<Vec<_>>(); |
| 146 | breakpoints.sort_by_key(|(_wasm_pc, native_offset, _patch)| *native_offset); |
| 147 | let breakpoints: Box<dyn Iterator<Item = _>> = Box::new(breakpoints.into_iter()); |
| 148 | let breakpoints = breakpoints.peekable(); |
| 149 | |
| 150 | // Build the helper that'll get used to attach decorations/annotations |
| 151 | // to various instructions. |
| 152 | let mut decorator = Decorator { |
| 153 | addrmap: elf |
| 154 | .section_by_name(obj::ELF_WASMTIME_ADDRMAP) |
| 155 | .and_then(|section| section.data().ok()) |
| 156 | .and_then(|bytes| wasmtime_environ::iterate_address_map(bytes)) |
| 157 | .map(|i| (Box::new(i) as Box<dyn Iterator<Item = _>>).peekable()), |
| 158 | traps: elf |
| 159 | .section_by_name(obj::ELF_WASMTIME_TRAPS) |
| 160 | .and_then(|section| section.data().ok()) |
| 161 | .and_then(|bytes| wasmtime_environ::iterate_traps(bytes)) |
| 162 | .map(|i| (Box::new(i) as Box<dyn Iterator<Item = _>>).peekable()), |
| 163 | stack_maps: elf |
| 164 | .section_by_name(obj::ELF_WASMTIME_STACK_MAP) |
| 165 | .and_then(|section| section.data().ok()) |
nothing calls this directly
no test coverage detected