aboutsummaryrefslogtreecommitdiff
path: root/CHANGELOG
blob: 14a43fae600915a4a6a68061894916ecb7d234dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
## 1.0.0
* `avx512` support
* `avx2` support
* `avx` support
* real-mode (x86_16) support
* ffi-friendly packaging of decoders for 16-bit, 32-bit, and multi-arch uses
* added `Instruction::mem_size()` to query the size of an instruction's memory access
* `xacquire`/`xrelease` support
* `AMD` `sev_snp` support
* `pconfig`/Total Memory Encryption support
* `Intel` `keylocker` support
* removed `MOVSX_b`, `MOVSX_w`, `MOVZX_b`, and `MOVZX_w` - these differentiations are now described by `mem_size` and the `MOVSX`/`MOVZX` opcodes generally
* `PartialEq` impl for `Instruction` and all contained structures
* expose more details of an instruction's prefixes, and which prefixes are actually present on the instruction

## 0.2.2
* fix rendering error in `ShowContextual` impl with `&[Option<String>]` overrides
  - would in some circumstances incorrectly print stale data if an `Instruction` was reused for decoding.
    no impact on logical correctness, but certainly made for awkward disassembly in some cases.

## 0.2.1
* update `yaxpeax-arch` dep to 0.0.5
  - no external-facing changes for this, but `yaxpeax-arch 0.0.5` uses `crossterm` for cross-platform terminal coloring
* clean up a few warnings that made it into 0.2.0?

## 0.2.0
### features!
* fuzz against mishegos and fix many bugs that made obvious
  - duplicate and redundant f2, f3, and 66 prefixes on 0f-type opcodes are now
    handled "right", assuming xed as a source of truth. almost all of these cases
    are undefined by the intel and AMD manuals, but it seems unlikely that
    capstone is correct with respect to cpu interpretation while xed is
    incorrect.
* public `enum`s are now `#[non_exhaustive]`. these are `Operand`, `Opcode`, and `DecodeError`.
  - `Operand` is not expected to vary, but might.
  - `Opcode` will grow new variants for every extension.
  - `DecodeError` will probably not change, but no guarantees.
* add a notion of display styles for instructions, see `Instruction::display_with`. currently there are two styles:
  - `DisplayStyle::Intel` produces intel-like syntax for instructions
  - `DisplayStyle::C` produces C pseudocode-ish syntax for instructions
    - as an example, `xor eax, [rax]` is rendered as `eax ^= [rax]`.
  - `DisplayStyle::Att` is one potential future style, but not yet implemented
* `fmt`-related code and the `display` module are now optional on the `fmt` feature
  - this is to support minimal builds for decoders in non-formatting circumstances. `yaxpeax-x86` long mode is still 65kb there.
* improved packaging of ffi-friendly bindings in `ffi/`
  - architectures have standalone libraries for each of `long_mode`, `protected_mode`, and `real_mode` (last still to be implemented)
  - improved `ffi/` build instructions to describe how to build minimal-size `.so` and `.a` archives for linking
* `ffi/multiarch` is intended to be a single package for all architectures, but currently does not fulfil this role

### decode fixes
* segment prefixes (`cs`, `ds`, `ss`, `es`) are now properly ignored in long mode
* `lock xchg` now decodes correctly (operands were in reversed order and so memory "destinations" were treated as memory sources)
* some missing sse instructions are now supported (`blendps`, `blendpd`, `pclmulqdq`)
* some missing avx instructions are now supported (`vorpd`, `vorps`, `vandpd`, `vandps`, `vandnpd`, `vandnps`, `vpmaxuw`)
* prefetch instructions with register operand are interpreted as `nop`, not `#UD`
* `mov` to control or debug registers that are statically known to `#UD` now produce `DecodeError::InvalidOperand`
* `salc` is now rejected. it was accepted on a whim, and i am fickle.
  - realistically, this should be behind a decoder flag and accepted by
    default, but this makes fuzzing somewhat easier and isn't an instruction
    you'd expect to see in a modern x86 binary. see the summary at the end of
    this section for some thoughts on decoder flags...

### new ISA extension support!
* 3dnow is 3d-supported-now
* `sse4a` is now supported
* `gfni` extensions are now supported
* `ptwrite` extensions are now supported
* `cet` (`c`ontrol-flow `e`nforcement `t`echnology) extensions are now supported
* `invpcid` extensions are now supported
* `tdx` extensions are now supported
* `waitpkg` extensions are now supported
* `uintr` extensions are now supported
* `tsxldtrk` extensions are now supported
* `ud0`, `ud1`, and `ud2` are now supported - `ud2e` which was never real, is actually `ud1`
* `movdir` extensions are now supported
* `key locker` extensions are now supported
* `enqcmd` extensions are now supported

### architecture support
* all above changes apply both to `long_mode` and `protected_mode`.
  `protected_mode` may accept some 64bit-only instructions incorrectly. beware.

### thoughts?
folks, i'm out of feature bits in `InstDecoder`. there are too dang many x86
extensions. in the happy case, rustc knows that the provided decoder always
compares equal to `InstDecoder::default()` so it can be made an arbitrarily
large byte array. but i continue to be in awe of how much they put in the
computer. as things stand, new extensions are not categorized into
`InstDecoder` flags, but since there is a way to implement additional bits
without causing overhead in the happy path, this feature will probably continue
being supported in the future.

### unsafe
there are still a handful of `unsafe {}` uses in `yaxpeax-x86` for performance
reasons. i tried removing arms in matches by making the last meaningful arm,
often something like:
```
8 => { /* handle 8-byte operand */ }
```
into a general catchall arm and deleting the `unreachable_unchecked`, like:
```
_ => { /* handle 8-byte operand */ }
```
but this also caused a ~5% regression in performance. this makes sense, since
`unreachable_unchecked` is stronger in saying that other values (`3`, `5`, `6`,
`7`, ...) will _not_ occur, but `_` doesn't disallow them and likely produces
jump tables for no good reason. maybe this can be solved some other way, one
day...

## 0.1.5
* fix several issues around 0f01* opcode decoding;
  - AMD-only `monitorx`, `mwaitx`, `clzero`, and `rdpru` are now supported
  - `swapgs` is invalid in non-64-bit modes
  - `rdpkru` and `wrpkru` were incorrectly decoded when modrm bits were not `11`
* small performance tweaks. read_imm_signed is now inline(always) and some
  pre-decode initialization is a bit better-packed
* `xchg {r,e,}ax, reg` was not supported! it's supported now.

## 0.1.4
* [long mode only]: fix decoding of rex-prefixed modrm+sib operands selecting index 0b100 and base 0b101
  - for memory operands with a base, index, and displacement either
    the wrong base would be selected (register number ignored, so only
    `*ax` or `r8*` would be reported), or yaxpeax-x86 would report a
    base register is present when it is not (`RegIndexBaseScaleDisp`
    when the operand is actually `RegScaleDisp`)

thank you to Evan Johnson for catching and reporting this bug!

## 0.1.3
* fix 0x80-opcode instructions not having an opcode
  - this meant that for example `lock xorb [rax], 0` would decode as invalid

## 0.1.2
* expose constructors for `RegSpec` in both `long_mode` and `protected_mode`
* expose a const `RegSpec::RIP`
  - most useful for matching `Operand::RegDisp(RegSpec::RIP, disp)` in patterns, really

## 0.1.1
* add `long_mode::register_class` and `protected_mode::register_class` where
  `RegisterClass` constants for each register class are defined.
  - without these, the only way to distinguish register classes would be string compares. bad. sorry!

## 0.1.0
* port `long_mode` improvements to `protected_mode` decoder
  - real mode will wait until another day
* support undocumented instruction `salc`
* fix segment registers being numbered wrong
  - this is relevant only for mov to/from segments
* support x86_32 `push <segment>``/`pop <segment>`
* support x86_32 `pusha`/`popa`
* support x86_32 BCD instructions
  - for `aam`/`aad`, the undocumented `amx` and `adx` forms are used in all cases, including when the base is 10
* begin some proper documentation for public items

/!\ BREAKING CHANGES /!\
* `RegisterBank` is no longer public. `RegisterClass` should be a suitable
  replacement, accessible via `reg.class()`, with the register class name
  available by `reg.class().name`, and size available by `reg.class().width()`.
  `reg.width()` still works, and just forwards to `reg.class().width()`.
* the field `opcode` of `Instruction` is no longer public. it can now be accessed by `inst.opcode()`.

## 0.0.15

* the `x87` instruction set is now fully supported
  - textual disassembly differs slightly from other decoders in that
    yaxpeax-x86 does not prefer using `st` in place of `st(0)`
* do not decode `into` in 64-bit mode
* support `vmread`, `vmwrite`
* support `iret`/`iretd`/`iretq`
* support `enter`
* support `cmc` and `int1`
* support `loopz`, `loopnz`, `jecxz`
* support `maskmovq`, `movnti`, and `movntq`
  - this brings full support to non-vex-coded x86 instructions
* reject excessively-long instructions
* reject reg-reg encodings where instructions forbid those operands
* correctly handle `mov [0xoffset], ax` and `mov ax, [0xoffset]`
  - offset had been read with incorrect size
* `vpsrlw`, `vpermq`, `vpminsq`, `vpsrlq`, `vextractf128`, `vinserti128`
* reorganize likely decoding paths for a smidge more speed

## 0.0.14

* `netburst` supported `cmpxchg16b` from its first x86_64 incarnation. since no
uarch in `long_mode` had declared `cmpxchg16b` support, no uarch-specific Intel
decoder supported `cmpxchg16b`.

## 0.0.13

* the Intel microarchitecture is named `Penryn`, not `Peryn`.

## 0.0.12

* fix improper decode of `sib` memory operand when `rex.x` is set and index is `0b100`
  - functionally: instructions which should have had a memory operand like
    `[rax + r12 + disp]` were missing `r12`
* add instruction set extensions: `SHA`, `BMI1`, `BMI2`, `XSAVE`, `RDRAND`,
  `RDSEED`, `CMPXCHG{8,16}B` `ADX`, `SVM`, `MOVBE`, `PREFETCHW`, `TSX`, and
  `F16C`
* add `RDFSBASE`, `RDGSBASE`, `WRFSBASE`, `WRGSBASE`
* builders for per-uarch x86_64 instruction decoders, see `yaxpeax_x86::long_mode::uarch::{intel, amd}`
* builders for per-uarch x86_32 instruction decoders, see `yaxpeax_x86::protected_mode::uarch::{intel, amd}`

## 0.0.11

* fix mis-named 'cbd' instruction, which should be 'cwd'
* add `Operand::width` to query the width of an x86 access
  - this is wrong for many memory operands, which require deeper changes
* bump `yaxpeax-arch` to 0.0.4, which yields a breaking change in `Self::Unit` of `LengthedInstruction
* `Prefixes::rep` is now public, allowing users to query if a decoded instruction has a rep prefix

## 0.0.10

same as 0.0.9, but with a warning fixed.

## 0.0.9

added `protected_mode` for 32-bit instruction decoding. BCD instructions not yet supported.

## 0.0.8

same as 0.0.7, but with a readme in the crates.io page.

## 0.0.7

`sse` and `sse2` support are mostly complete.
`jmp reg` erroneously decoded to 32-bit registers without `rex.w`.
`callf` could erroneously decode as having a register operand.
more comprehensive, if yet insufficiently tested, avx decoding.
support `vmclear` and `vmxon`, vmx still incomplete.

## 0.0.6

addressing modes using a sib byte with displacement != 0 were wrongly reported as having no displacement.

## 0.0.5

history basically starts here.

* impl Ord and PartialOrd on RegSpec and RegisterBank
* `RegSpec::name` to get `&'static str` labels for registers
* support `in` and `out` instructions

## 0.0.4 - 0.0.2

seriously stop, just don't use these versions

just bumps to use newer `yaxpeax-arch` since this is all wildly unstable