2015-06-12 19:49:23 +00:00
package proc
2014-12-08 23:40:59 +00:00
import (
2016-03-18 08:32:17 +00:00
"errors"
2021-03-04 18:28:28 +00:00
"github.com/go-delve/delve/pkg/dwarf/op"
2014-12-08 23:40:59 +00:00
)
2017-04-21 07:50:38 +00:00
// Thread represents a thread.
type Thread interface {
2017-02-15 13:41:03 +00:00
Location ( ) ( * Location , error )
// Breakpoint will return the breakpoint that this thread is stopped at or
// nil if the thread is not stopped at any breakpoint.
2020-01-21 20:41:24 +00:00
Breakpoint ( ) * BreakpointState
2017-02-15 13:41:03 +00:00
ThreadID ( ) int
2018-08-03 15:17:01 +00:00
// Registers returns the CPU registers of this thread. The contents of the
// variable returned may or may not change to reflect the new CPU status
// when the thread is resumed or the registers are changed by calling
// SetPC/SetSP/etc.
// To insure that the the returned variable won't change call the Copy
// method of Registers.
2020-05-13 18:56:50 +00:00
Registers ( ) ( Registers , error )
2018-08-03 15:17:01 +00:00
2018-05-04 17:31:45 +00:00
// RestoreRegisters restores saved registers
2018-08-03 15:17:01 +00:00
RestoreRegisters ( Registers ) error
2017-02-15 13:41:03 +00:00
BinInfo ( ) * BinaryInfo
2020-11-09 19:28:40 +00:00
// ProcessMemory returns the process memory.
ProcessMemory ( ) MemoryReadWriter
2017-02-22 08:35:21 +00:00
StepInstruction ( ) error
2019-08-12 22:11:19 +00:00
// SetCurrentBreakpoint updates the current breakpoint of this thread, if adjustPC is true also checks for breakpoints that were just hit (this should only be passed true after a thread resume)
SetCurrentBreakpoint ( adjustPC bool ) error
2022-02-22 17:57:37 +00:00
// SoftExc returns true if this thread received a software exception during the last resume.
SoftExc ( ) bool
2018-05-11 12:51:15 +00:00
// Common returns the CommonThread structure for this thread
Common ( ) * CommonThread
2018-05-04 17:31:45 +00:00
2021-03-04 18:28:28 +00:00
// SetReg changes the value of the specified register. A minimal
// implementation of this interface can support just setting the PC
// register.
SetReg ( uint64 , * op . DwarfRegister ) error
2017-02-15 13:41:03 +00:00
}
2016-01-10 08:57:52 +00:00
// Location represents the location of a thread.
2015-06-18 03:01:31 +00:00
// Holds information on the current instruction
// address, the source file:line, and the function.
2015-05-27 17:16:45 +00:00
type Location struct {
PC uint64
File string
Line int
2017-09-01 13:30:45 +00:00
Fn * Function
2015-05-27 17:16:45 +00:00
}
2018-05-11 12:51:15 +00:00
// CommonThread contains fields used by this package, common to all
// implementations of the Thread interface.
type CommonThread struct {
2020-12-10 16:57:50 +00:00
CallReturn bool // returnValues are the return values of a call injection
2018-05-11 12:51:15 +00:00
returnValues [ ] * Variable
2020-03-10 19:48:46 +00:00
g * G // cached g for this thread
2018-05-11 12:51:15 +00:00
}
2018-08-31 18:08:18 +00:00
// ReturnValues reads the return values from the function executing on
// this thread using the provided LoadConfig.
2018-05-11 12:51:15 +00:00
func ( t * CommonThread ) ReturnValues ( cfg LoadConfig ) [ ] * Variable {
loadValues ( t . returnValues , cfg )
return t . returnValues
}
2017-05-16 18:23:33 +00:00
// topframe returns the two topmost frames of g, or thread if g is nil.
func topframe ( g * G , thread Thread ) ( Stackframe , Stackframe , error ) {
2016-04-11 11:50:01 +00:00
var frames [ ] Stackframe
2016-04-13 13:25:23 +00:00
var err error
2016-04-11 11:50:01 +00:00
2016-07-03 07:02:21 +00:00
if g == nil {
2017-05-16 18:23:33 +00:00
frames , err = ThreadStacktrace ( thread , 1 )
2016-04-11 11:50:01 +00:00
} else {
2019-09-25 17:21:20 +00:00
frames , err = g . Stacktrace ( 1 , StacktraceReadDefers )
2015-08-20 14:28:11 +00:00
}
2014-12-08 23:40:59 +00:00
if err != nil {
2017-05-16 18:23:33 +00:00
return Stackframe { } , Stackframe { } , err
2014-12-08 23:40:59 +00:00
}
2017-05-16 18:23:33 +00:00
switch len ( frames ) {
case 0 :
return Stackframe { } , Stackframe { } , errors . New ( "empty stack trace" )
case 1 :
return frames [ 0 ] , Stackframe { } , nil
default :
return frames [ 0 ] , frames [ 1 ] , nil
2016-04-13 13:25:23 +00:00
}
}
2021-03-04 18:28:28 +00:00
func setPC ( thread Thread , newPC uint64 ) error {
return thread . SetReg ( thread . BinInfo ( ) . Arch . PCRegNum , op . DwarfRegisterFromUint64 ( newPC ) )
}
func setSP ( thread Thread , newSP uint64 ) error {
return thread . SetReg ( thread . BinInfo ( ) . Arch . SPRegNum , op . DwarfRegisterFromUint64 ( newSP ) )
}
func setClosureReg ( thread Thread , newClosureReg uint64 ) error {
return thread . SetReg ( thread . BinInfo ( ) . Arch . ContextRegNum , op . DwarfRegisterFromUint64 ( newClosureReg ) )
}
2022-05-03 17:46:24 +00:00
func setLR ( thread Thread , newLR uint64 ) error {
return thread . SetReg ( thread . BinInfo ( ) . Arch . LRRegNum , op . DwarfRegisterFromUint64 ( newLR ) )
}