2016-02-06 06:00:48 +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
)
2017-04-13 23:19:57 +00:00
func ( dbp * Process ) Disassemble ( g * G , startPC , endPC uint64 ) ( [ ] AsmInstruction , error ) {
if g == nil {
regs , _ := dbp . currentThread . Registers ( false )
return Disassemble ( dbp . currentThread , regs , dbp . breakpoints , & dbp . bi , startPC , endPC )
}
var regs Registers
thread := dbp . currentThread
if g . thread != nil {
thread = g . thread
regs , _ = g . thread . Registers ( false )
}
return Disassemble ( thread , regs , dbp . breakpoints , & dbp . bi , startPC , endPC )
}
2016-02-06 06:00:48 +00:00
// 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
2017-04-13 23:19:57 +00:00
func Disassemble ( memrw memoryReadWriter , regs Registers , breakpoints map [ uint64 ] * Breakpoint , bi * BinaryInfo , startPC , endPC uint64 ) ( [ ] AsmInstruction , error ) {
mem , err := memrw . readMemory ( uintptr ( startPC ) , int ( endPC - startPC ) )
2016-02-06 06:00:48 +00:00
if err != nil {
return nil , err
}
r := make ( [ ] AsmInstruction , 0 , len ( mem ) / 15 )
pc := startPC
var curpc uint64
2017-04-13 23:19:57 +00:00
if regs != nil {
curpc = regs . PC ( )
2016-02-06 06:00:48 +00:00
}
for len ( mem ) > 0 {
2017-04-13 23:19:57 +00:00
bp , atbp := breakpoints [ pc ]
2016-02-06 06:00:48 +00:00
if atbp {
for i := range bp . OriginalData {
mem [ i ] = bp . OriginalData [ i ]
}
}
2017-04-13 23:19:57 +00:00
file , line , fn := bi . PCToLine ( pc )
2016-02-06 06:00:48 +00:00
loc := Location { PC : pc , File : file , Line : line , Fn : fn }
inst , err := asmDecode ( mem , pc )
if err == nil {
2017-04-13 23:19:57 +00:00
atpc := ( regs != nil ) && ( curpc == pc )
destloc := resolveCallArg ( inst , atpc , regs , memrw , bi )
2016-02-06 06:00:48 +00:00
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
}