
* proc: refactor BinaryInfo part of proc.Process to own type The data structures and associated code used by proc.Process to implement target.BinaryInfo will also be useful to support a backend for examining core dumps, split this part of proc.Process to a different type. * proc: compile support for all executable formats unconditionally So far we only compiled in support for loading the executable format supported by the host operating system. Once support for core files is introduced it is however useful to support loading in all executable formats, there is no reason why it shouldn't be possible to examine a linux coredump on windows, or viceversa. * proc: bugfix: do not resume threads on detach if killing * Replace BinaryInfo interface with BinInfo() method returning proc.BinaryInfo
68 lines
1.8 KiB
Go
68 lines
1.8 KiB
Go
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.bi.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
|
|
}
|