podman

Форк
0
649 строк · 10.6 Кб
1
// Copyright 2014 The Go Authors.  All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4

5
// Package x86asm implements decoding of x86 machine code.
6
package x86asm
7

8
import (
9
	"bytes"
10
	"fmt"
11
)
12

13
// An Inst is a single instruction.
14
type Inst struct {
15
	Prefix   Prefixes // Prefixes applied to the instruction.
16
	Op       Op       // Opcode mnemonic
17
	Opcode   uint32   // Encoded opcode bits, left aligned (first byte is Opcode>>24, etc)
18
	Args     Args     // Instruction arguments, in Intel order
19
	Mode     int      // processor mode in bits: 16, 32, or 64
20
	AddrSize int      // address size in bits: 16, 32, or 64
21
	DataSize int      // operand size in bits: 16, 32, or 64
22
	MemBytes int      // size of memory argument in bytes: 1, 2, 4, 8, 16, and so on.
23
	Len      int      // length of encoded instruction in bytes
24
	PCRel    int      // length of PC-relative address in instruction encoding
25
	PCRelOff int      // index of start of PC-relative address in instruction encoding
26
}
27

28
// Prefixes is an array of prefixes associated with a single instruction.
29
// The prefixes are listed in the same order as found in the instruction:
30
// each prefix byte corresponds to one slot in the array. The first zero
31
// in the array marks the end of the prefixes.
32
type Prefixes [14]Prefix
33

34
// A Prefix represents an Intel instruction prefix.
35
// The low 8 bits are the actual prefix byte encoding,
36
// and the top 8 bits contain distinguishing bits and metadata.
37
type Prefix uint16
38

39
const (
40
	// Metadata about the role of a prefix in an instruction.
41
	PrefixImplicit Prefix = 0x8000 // prefix is implied by instruction text
42
	PrefixIgnored  Prefix = 0x4000 // prefix is ignored: either irrelevant or overridden by a later prefix
43
	PrefixInvalid  Prefix = 0x2000 // prefix makes entire instruction invalid (bad LOCK)
44

45
	// Memory segment overrides.
46
	PrefixES Prefix = 0x26 // ES segment override
47
	PrefixCS Prefix = 0x2E // CS segment override
48
	PrefixSS Prefix = 0x36 // SS segment override
49
	PrefixDS Prefix = 0x3E // DS segment override
50
	PrefixFS Prefix = 0x64 // FS segment override
51
	PrefixGS Prefix = 0x65 // GS segment override
52

53
	// Branch prediction.
54
	PrefixPN Prefix = 0x12E // predict not taken (conditional branch only)
55
	PrefixPT Prefix = 0x13E // predict taken (conditional branch only)
56

57
	// Size attributes.
58
	PrefixDataSize Prefix = 0x66 // operand size override
59
	PrefixData16   Prefix = 0x166
60
	PrefixData32   Prefix = 0x266
61
	PrefixAddrSize Prefix = 0x67 // address size override
62
	PrefixAddr16   Prefix = 0x167
63
	PrefixAddr32   Prefix = 0x267
64

65
	// One of a kind.
66
	PrefixLOCK     Prefix = 0xF0 // lock
67
	PrefixREPN     Prefix = 0xF2 // repeat not zero
68
	PrefixXACQUIRE Prefix = 0x1F2
69
	PrefixBND      Prefix = 0x2F2
70
	PrefixREP      Prefix = 0xF3 // repeat
71
	PrefixXRELEASE Prefix = 0x1F3
72

73
	// The REX prefixes must be in the range [PrefixREX, PrefixREX+0x10).
74
	// the other bits are set or not according to the intended use.
75
	PrefixREX       Prefix = 0x40 // REX 64-bit extension prefix
76
	PrefixREXW      Prefix = 0x08 // extension bit W (64-bit instruction width)
77
	PrefixREXR      Prefix = 0x04 // extension bit R (r field in modrm)
78
	PrefixREXX      Prefix = 0x02 // extension bit X (index field in sib)
79
	PrefixREXB      Prefix = 0x01 // extension bit B (r/m field in modrm or base field in sib)
80
	PrefixVEX2Bytes Prefix = 0xC5 // Short form of vex prefix
81
	PrefixVEX3Bytes Prefix = 0xC4 // Long form of vex prefix
82
)
83

84
// IsREX reports whether p is a REX prefix byte.
85
func (p Prefix) IsREX() bool {
86
	return p&0xF0 == PrefixREX
87
}
88

89
func (p Prefix) IsVEX() bool {
90
	return p&0xFF == PrefixVEX2Bytes || p&0xFF == PrefixVEX3Bytes
91
}
92

93
func (p Prefix) String() string {
94
	p &^= PrefixImplicit | PrefixIgnored | PrefixInvalid
95
	if s := prefixNames[p]; s != "" {
96
		return s
97
	}
98

99
	if p.IsREX() {
100
		s := "REX."
101
		if p&PrefixREXW != 0 {
102
			s += "W"
103
		}
104
		if p&PrefixREXR != 0 {
105
			s += "R"
106
		}
107
		if p&PrefixREXX != 0 {
108
			s += "X"
109
		}
110
		if p&PrefixREXB != 0 {
111
			s += "B"
112
		}
113
		return s
114
	}
115

116
	return fmt.Sprintf("Prefix(%#x)", int(p))
117
}
118

119
// An Op is an x86 opcode.
120
type Op uint32
121

122
func (op Op) String() string {
123
	i := int(op)
124
	if i < 0 || i >= len(opNames) || opNames[i] == "" {
125
		return fmt.Sprintf("Op(%d)", i)
126
	}
127
	return opNames[i]
128
}
129

130
// An Args holds the instruction arguments.
131
// If an instruction has fewer than 4 arguments,
132
// the final elements in the array are nil.
133
type Args [4]Arg
134

135
// An Arg is a single instruction argument,
136
// one of these types: Reg, Mem, Imm, Rel.
137
type Arg interface {
138
	String() string
139
	isArg()
140
}
141

142
// Note that the implements of Arg that follow are all sized
143
// so that on a 64-bit machine the data can be inlined in
144
// the interface value instead of requiring an allocation.
145

146
// A Reg is a single register.
147
// The zero Reg value has no name but indicates “no register.”
148
type Reg uint8
149

150
const (
151
	_ Reg = iota
152

153
	// 8-bit
154
	AL
155
	CL
156
	DL
157
	BL
158
	AH
159
	CH
160
	DH
161
	BH
162
	SPB
163
	BPB
164
	SIB
165
	DIB
166
	R8B
167
	R9B
168
	R10B
169
	R11B
170
	R12B
171
	R13B
172
	R14B
173
	R15B
174

175
	// 16-bit
176
	AX
177
	CX
178
	DX
179
	BX
180
	SP
181
	BP
182
	SI
183
	DI
184
	R8W
185
	R9W
186
	R10W
187
	R11W
188
	R12W
189
	R13W
190
	R14W
191
	R15W
192

193
	// 32-bit
194
	EAX
195
	ECX
196
	EDX
197
	EBX
198
	ESP
199
	EBP
200
	ESI
201
	EDI
202
	R8L
203
	R9L
204
	R10L
205
	R11L
206
	R12L
207
	R13L
208
	R14L
209
	R15L
210

211
	// 64-bit
212
	RAX
213
	RCX
214
	RDX
215
	RBX
216
	RSP
217
	RBP
218
	RSI
219
	RDI
220
	R8
221
	R9
222
	R10
223
	R11
224
	R12
225
	R13
226
	R14
227
	R15
228

229
	// Instruction pointer.
230
	IP  // 16-bit
231
	EIP // 32-bit
232
	RIP // 64-bit
233

234
	// 387 floating point registers.
235
	F0
236
	F1
237
	F2
238
	F3
239
	F4
240
	F5
241
	F6
242
	F7
243

244
	// MMX registers.
245
	M0
246
	M1
247
	M2
248
	M3
249
	M4
250
	M5
251
	M6
252
	M7
253

254
	// XMM registers.
255
	X0
256
	X1
257
	X2
258
	X3
259
	X4
260
	X5
261
	X6
262
	X7
263
	X8
264
	X9
265
	X10
266
	X11
267
	X12
268
	X13
269
	X14
270
	X15
271

272
	// Segment registers.
273
	ES
274
	CS
275
	SS
276
	DS
277
	FS
278
	GS
279

280
	// System registers.
281
	GDTR
282
	IDTR
283
	LDTR
284
	MSW
285
	TASK
286

287
	// Control registers.
288
	CR0
289
	CR1
290
	CR2
291
	CR3
292
	CR4
293
	CR5
294
	CR6
295
	CR7
296
	CR8
297
	CR9
298
	CR10
299
	CR11
300
	CR12
301
	CR13
302
	CR14
303
	CR15
304

305
	// Debug registers.
306
	DR0
307
	DR1
308
	DR2
309
	DR3
310
	DR4
311
	DR5
312
	DR6
313
	DR7
314
	DR8
315
	DR9
316
	DR10
317
	DR11
318
	DR12
319
	DR13
320
	DR14
321
	DR15
322

323
	// Task registers.
324
	TR0
325
	TR1
326
	TR2
327
	TR3
328
	TR4
329
	TR5
330
	TR6
331
	TR7
332
)
333

334
const regMax = TR7
335

336
func (Reg) isArg() {}
337

338
func (r Reg) String() string {
339
	i := int(r)
340
	if i < 0 || i >= len(regNames) || regNames[i] == "" {
341
		return fmt.Sprintf("Reg(%d)", i)
342
	}
343
	return regNames[i]
344
}
345

346
// A Mem is a memory reference.
347
// The general form is Segment:[Base+Scale*Index+Disp].
348
type Mem struct {
349
	Segment Reg
350
	Base    Reg
351
	Scale   uint8
352
	Index   Reg
353
	Disp    int64
354
}
355

356
func (Mem) isArg() {}
357

358
func (m Mem) String() string {
359
	var base, plus, scale, index, disp string
360

361
	if m.Base != 0 {
362
		base = m.Base.String()
363
	}
364
	if m.Scale != 0 {
365
		if m.Base != 0 {
366
			plus = "+"
367
		}
368
		if m.Scale > 1 {
369
			scale = fmt.Sprintf("%d*", m.Scale)
370
		}
371
		index = m.Index.String()
372
	}
373
	if m.Disp != 0 || m.Base == 0 && m.Scale == 0 {
374
		disp = fmt.Sprintf("%+#x", m.Disp)
375
	}
376
	return "[" + base + plus + scale + index + disp + "]"
377
}
378

379
// A Rel is an offset relative to the current instruction pointer.
380
type Rel int32
381

382
func (Rel) isArg() {}
383

384
func (r Rel) String() string {
385
	return fmt.Sprintf(".%+d", r)
386
}
387

388
// An Imm is an integer constant.
389
type Imm int64
390

391
func (Imm) isArg() {}
392

393
func (i Imm) String() string {
394
	return fmt.Sprintf("%#x", int64(i))
395
}
396

397
func (i Inst) String() string {
398
	var buf bytes.Buffer
399
	for _, p := range i.Prefix {
400
		if p == 0 {
401
			break
402
		}
403
		if p&PrefixImplicit != 0 {
404
			continue
405
		}
406
		fmt.Fprintf(&buf, "%v ", p)
407
	}
408
	fmt.Fprintf(&buf, "%v", i.Op)
409
	sep := " "
410
	for _, v := range i.Args {
411
		if v == nil {
412
			break
413
		}
414
		fmt.Fprintf(&buf, "%s%v", sep, v)
415
		sep = ", "
416
	}
417
	return buf.String()
418
}
419

420
func isReg(a Arg) bool {
421
	_, ok := a.(Reg)
422
	return ok
423
}
424

425
func isSegReg(a Arg) bool {
426
	r, ok := a.(Reg)
427
	return ok && ES <= r && r <= GS
428
}
429

430
func isMem(a Arg) bool {
431
	_, ok := a.(Mem)
432
	return ok
433
}
434

435
func isImm(a Arg) bool {
436
	_, ok := a.(Imm)
437
	return ok
438
}
439

440
func regBytes(a Arg) int {
441
	r, ok := a.(Reg)
442
	if !ok {
443
		return 0
444
	}
445
	if AL <= r && r <= R15B {
446
		return 1
447
	}
448
	if AX <= r && r <= R15W {
449
		return 2
450
	}
451
	if EAX <= r && r <= R15L {
452
		return 4
453
	}
454
	if RAX <= r && r <= R15 {
455
		return 8
456
	}
457
	return 0
458
}
459

460
func isSegment(p Prefix) bool {
461
	switch p {
462
	case PrefixCS, PrefixDS, PrefixES, PrefixFS, PrefixGS, PrefixSS:
463
		return true
464
	}
465
	return false
466
}
467

468
// The Op definitions and string list are in tables.go.
469

470
var prefixNames = map[Prefix]string{
471
	PrefixCS:       "CS",
472
	PrefixDS:       "DS",
473
	PrefixES:       "ES",
474
	PrefixFS:       "FS",
475
	PrefixGS:       "GS",
476
	PrefixSS:       "SS",
477
	PrefixLOCK:     "LOCK",
478
	PrefixREP:      "REP",
479
	PrefixREPN:     "REPN",
480
	PrefixAddrSize: "ADDRSIZE",
481
	PrefixDataSize: "DATASIZE",
482
	PrefixAddr16:   "ADDR16",
483
	PrefixData16:   "DATA16",
484
	PrefixAddr32:   "ADDR32",
485
	PrefixData32:   "DATA32",
486
	PrefixBND:      "BND",
487
	PrefixXACQUIRE: "XACQUIRE",
488
	PrefixXRELEASE: "XRELEASE",
489
	PrefixREX:      "REX",
490
	PrefixPT:       "PT",
491
	PrefixPN:       "PN",
492
}
493

494
var regNames = [...]string{
495
	AL:   "AL",
496
	CL:   "CL",
497
	BL:   "BL",
498
	DL:   "DL",
499
	AH:   "AH",
500
	CH:   "CH",
501
	BH:   "BH",
502
	DH:   "DH",
503
	SPB:  "SPB",
504
	BPB:  "BPB",
505
	SIB:  "SIB",
506
	DIB:  "DIB",
507
	R8B:  "R8B",
508
	R9B:  "R9B",
509
	R10B: "R10B",
510
	R11B: "R11B",
511
	R12B: "R12B",
512
	R13B: "R13B",
513
	R14B: "R14B",
514
	R15B: "R15B",
515
	AX:   "AX",
516
	CX:   "CX",
517
	BX:   "BX",
518
	DX:   "DX",
519
	SP:   "SP",
520
	BP:   "BP",
521
	SI:   "SI",
522
	DI:   "DI",
523
	R8W:  "R8W",
524
	R9W:  "R9W",
525
	R10W: "R10W",
526
	R11W: "R11W",
527
	R12W: "R12W",
528
	R13W: "R13W",
529
	R14W: "R14W",
530
	R15W: "R15W",
531
	EAX:  "EAX",
532
	ECX:  "ECX",
533
	EDX:  "EDX",
534
	EBX:  "EBX",
535
	ESP:  "ESP",
536
	EBP:  "EBP",
537
	ESI:  "ESI",
538
	EDI:  "EDI",
539
	R8L:  "R8L",
540
	R9L:  "R9L",
541
	R10L: "R10L",
542
	R11L: "R11L",
543
	R12L: "R12L",
544
	R13L: "R13L",
545
	R14L: "R14L",
546
	R15L: "R15L",
547
	RAX:  "RAX",
548
	RCX:  "RCX",
549
	RDX:  "RDX",
550
	RBX:  "RBX",
551
	RSP:  "RSP",
552
	RBP:  "RBP",
553
	RSI:  "RSI",
554
	RDI:  "RDI",
555
	R8:   "R8",
556
	R9:   "R9",
557
	R10:  "R10",
558
	R11:  "R11",
559
	R12:  "R12",
560
	R13:  "R13",
561
	R14:  "R14",
562
	R15:  "R15",
563
	IP:   "IP",
564
	EIP:  "EIP",
565
	RIP:  "RIP",
566
	F0:   "F0",
567
	F1:   "F1",
568
	F2:   "F2",
569
	F3:   "F3",
570
	F4:   "F4",
571
	F5:   "F5",
572
	F6:   "F6",
573
	F7:   "F7",
574
	M0:   "M0",
575
	M1:   "M1",
576
	M2:   "M2",
577
	M3:   "M3",
578
	M4:   "M4",
579
	M5:   "M5",
580
	M6:   "M6",
581
	M7:   "M7",
582
	X0:   "X0",
583
	X1:   "X1",
584
	X2:   "X2",
585
	X3:   "X3",
586
	X4:   "X4",
587
	X5:   "X5",
588
	X6:   "X6",
589
	X7:   "X7",
590
	X8:   "X8",
591
	X9:   "X9",
592
	X10:  "X10",
593
	X11:  "X11",
594
	X12:  "X12",
595
	X13:  "X13",
596
	X14:  "X14",
597
	X15:  "X15",
598
	CS:   "CS",
599
	SS:   "SS",
600
	DS:   "DS",
601
	ES:   "ES",
602
	FS:   "FS",
603
	GS:   "GS",
604
	GDTR: "GDTR",
605
	IDTR: "IDTR",
606
	LDTR: "LDTR",
607
	MSW:  "MSW",
608
	TASK: "TASK",
609
	CR0:  "CR0",
610
	CR1:  "CR1",
611
	CR2:  "CR2",
612
	CR3:  "CR3",
613
	CR4:  "CR4",
614
	CR5:  "CR5",
615
	CR6:  "CR6",
616
	CR7:  "CR7",
617
	CR8:  "CR8",
618
	CR9:  "CR9",
619
	CR10: "CR10",
620
	CR11: "CR11",
621
	CR12: "CR12",
622
	CR13: "CR13",
623
	CR14: "CR14",
624
	CR15: "CR15",
625
	DR0:  "DR0",
626
	DR1:  "DR1",
627
	DR2:  "DR2",
628
	DR3:  "DR3",
629
	DR4:  "DR4",
630
	DR5:  "DR5",
631
	DR6:  "DR6",
632
	DR7:  "DR7",
633
	DR8:  "DR8",
634
	DR9:  "DR9",
635
	DR10: "DR10",
636
	DR11: "DR11",
637
	DR12: "DR12",
638
	DR13: "DR13",
639
	DR14: "DR14",
640
	DR15: "DR15",
641
	TR0:  "TR0",
642
	TR1:  "TR1",
643
	TR2:  "TR2",
644
	TR3:  "TR3",
645
	TR4:  "TR4",
646
	TR5:  "TR5",
647
	TR6:  "TR6",
648
	TR7:  "TR7",
649
}
650

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.