mirror of
				https://github.com/go-delve/delve.git
				synced 2025-11-04 06:32:16 +08:00 
			
		
		
		
	- Unlike FunctionEntryToFirstLine can skip the prologue on functions that are defined on a single line, either because they weren't formatted or because they were autogenerated - Can skip the prologue on most functions when setting a breakpoint with the filename:line syntax Fixes #396
		
			
				
	
	
		
			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()
 | 
						|
		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
 | 
						|
}
 |