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-02-15 13:41:03 +00:00
// Disassemble disassembles target memory between startPC and endPC, marking
// the current instruction being executed in goroutine g.
// 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-21 07:50:38 +00:00
func Disassemble ( dbp Process , g * G , startPC , endPC uint64 ) ( [ ] AsmInstruction , error ) {
2017-04-13 23:19:57 +00:00
if g == nil {
2017-02-15 13:41:03 +00:00
ct := dbp . CurrentThread ( )
regs , _ := ct . Registers ( false )
return disassemble ( ct , regs , dbp . Breakpoints ( ) , dbp . BinInfo ( ) , startPC , endPC )
2017-04-13 23:19:57 +00:00
}
var regs Registers
2017-04-21 06:55:53 +00:00
var mem MemoryReadWriter = dbp . CurrentThread ( )
if g . Thread != nil {
mem = g . Thread
regs , _ = g . Thread . Registers ( false )
2017-04-13 23:19:57 +00:00
}
2017-02-15 13:41:03 +00:00
return disassemble ( mem , regs , dbp . Breakpoints ( ) , dbp . BinInfo ( ) , startPC , endPC )
2017-04-13 23:19:57 +00:00
}
2017-04-21 06:55:53 +00:00
func disassemble ( memrw MemoryReadWriter , regs Registers , breakpoints map [ uint64 ] * Breakpoint , bi * BinaryInfo , startPC , endPC uint64 ) ( [ ] AsmInstruction , error ) {
2017-04-18 14:24:45 +00:00
mem := make ( [ ] byte , int ( endPC - startPC ) )
_ , err := memrw . ReadMemory ( mem , uintptr ( 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
}