forked from go-delve/delve
-
Notifications
You must be signed in to change notification settings - Fork 0
/
disasm.go
67 lines (59 loc) · 1.78 KB
/
disasm.go
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
package proc
type AsmInstruction struct {
Loc Location
DestLoc *Location
Bytes []byte
Breakpoint bool
AtPC bool
Inst *ArchInst
}
type AssemblyFlavour int
const (
GNUFlavour = AssemblyFlavour(iota)
IntelFlavour
)
// Disassemble disassembles target memory between startPC and endPC
// If currentGoroutine is set and thread is stopped at a CALL instruction Disassemble will evaluate the argument of the CALL instruction using the thread's registers
// Be aware that the Bytes field of each returned instruction is a slice of a larger array of size endPC - startPC
func (thread *Thread) Disassemble(startPC, endPC uint64, currentGoroutine bool) ([]AsmInstruction, error) {
if thread.dbp.exited {
return nil, &ProcessExitedError{}
}
mem, err := thread.readMemory(uintptr(startPC), int(endPC-startPC))
if err != nil {
return nil, err
}
r := make([]AsmInstruction, 0, len(mem)/15)
pc := startPC
var curpc uint64
var regs Registers
if currentGoroutine {
regs, _ = thread.Registers(false)
if regs != nil {
curpc = regs.PC()
}
}
for len(mem) > 0 {
bp, atbp := thread.dbp.Breakpoints[pc]
if atbp {
for i := range bp.OriginalData {
mem[i] = bp.OriginalData[i]
}
}
file, line, fn := thread.dbp.PCToLine(pc)
loc := Location{PC: pc, File: file, Line: line, Fn: fn}
inst, err := asmDecode(mem, pc)
if err == nil {
atpc := currentGoroutine && (curpc == pc)
destloc := thread.resolveCallArg(inst, atpc, regs)
r = append(r, AsmInstruction{Loc: loc, DestLoc: destloc, Bytes: mem[:inst.Len], Breakpoint: atbp, AtPC: atpc, Inst: inst})
pc += uint64(inst.Size())
mem = mem[inst.Size():]
} else {
r = append(r, AsmInstruction{Loc: loc, Bytes: mem[:1], Breakpoint: atbp, Inst: nil})
pc++
mem = mem[1:]
}
}
return r, nil
}