2017-03-19 22:45:54 +00:00
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 {
2017-03-26 14:55:28 +00:00
bp , atbp := thread . dbp . Breakpoints [ pc ]
2017-03-19 22:45:54 +00:00
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
}