proc/gdbserial: remove unnecessary conditional compilation (#2389)
Remove unnecessary conditionally compiled files introduced with the darwin/arm64 port.
This commit is contained in:
parent
c223ef656d
commit
7ace7a8e76
@ -138,8 +138,9 @@ var canUnmaskSignalsCached bool
|
|||||||
// gdbProcess implements proc.Process using a connection to a debugger stub
|
// gdbProcess implements proc.Process using a connection to a debugger stub
|
||||||
// that understands Gdb Remote Serial Protocol.
|
// that understands Gdb Remote Serial Protocol.
|
||||||
type gdbProcess struct {
|
type gdbProcess struct {
|
||||||
bi *proc.BinaryInfo
|
bi *proc.BinaryInfo
|
||||||
conn gdbConn
|
regnames *gdbRegnames
|
||||||
|
conn gdbConn
|
||||||
|
|
||||||
threads map[int]*gdbThread
|
threads map[int]*gdbThread
|
||||||
currentThread *gdbThread
|
currentThread *gdbThread
|
||||||
@ -157,6 +158,8 @@ type gdbProcess struct {
|
|||||||
|
|
||||||
loadGInstrAddr uint64 // address of the g loading instruction, zero if we couldn't allocate it
|
loadGInstrAddr uint64 // address of the g loading instruction, zero if we couldn't allocate it
|
||||||
|
|
||||||
|
breakpointKind int // breakpoint kind to pass to 'z' and 'Z' when creating software breakpoints
|
||||||
|
|
||||||
process *os.Process
|
process *os.Process
|
||||||
waitChan chan *os.ProcessState
|
waitChan chan *os.ProcessState
|
||||||
|
|
||||||
@ -196,6 +199,7 @@ type gdbRegisters struct {
|
|||||||
hasgaddr bool
|
hasgaddr bool
|
||||||
buf []byte
|
buf []byte
|
||||||
arch *proc.Arch
|
arch *proc.Arch
|
||||||
|
regnames *gdbRegnames
|
||||||
}
|
}
|
||||||
|
|
||||||
type gdbRegister struct {
|
type gdbRegister struct {
|
||||||
@ -203,6 +207,11 @@ type gdbRegister struct {
|
|||||||
regnum int
|
regnum int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gdbRegname records names of important CPU registers
|
||||||
|
type gdbRegnames struct {
|
||||||
|
PC, SP, BP, CX, FsBase string
|
||||||
|
}
|
||||||
|
|
||||||
// newProcess creates a new Process instance.
|
// newProcess creates a new Process instance.
|
||||||
// If process is not nil it is the stub's process and will be killed after
|
// If process is not nil it is the stub's process and will be killed after
|
||||||
// Detach.
|
// Detach.
|
||||||
@ -218,12 +227,37 @@ func newProcess(process *os.Process) *gdbProcess {
|
|||||||
},
|
},
|
||||||
threads: make(map[int]*gdbThread),
|
threads: make(map[int]*gdbThread),
|
||||||
bi: proc.NewBinaryInfo(runtime.GOOS, runtime.GOARCH),
|
bi: proc.NewBinaryInfo(runtime.GOOS, runtime.GOARCH),
|
||||||
|
regnames: new(gdbRegnames),
|
||||||
breakpoints: proc.NewBreakpointMap(),
|
breakpoints: proc.NewBreakpointMap(),
|
||||||
gcmdok: true,
|
gcmdok: true,
|
||||||
threadStopInfo: true,
|
threadStopInfo: true,
|
||||||
process: process,
|
process: process,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch p.bi.Arch.Name {
|
||||||
|
default:
|
||||||
|
fallthrough
|
||||||
|
case "amd64":
|
||||||
|
p.breakpointKind = 1
|
||||||
|
case "arm64":
|
||||||
|
p.breakpointKind = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
p.regnames.PC = registerName(p.bi.Arch, p.bi.Arch.PCRegNum)
|
||||||
|
p.regnames.SP = registerName(p.bi.Arch, p.bi.Arch.SPRegNum)
|
||||||
|
p.regnames.BP = registerName(p.bi.Arch, p.bi.Arch.BPRegNum)
|
||||||
|
|
||||||
|
switch p.bi.Arch.Name {
|
||||||
|
case "arm64":
|
||||||
|
p.regnames.BP = "fp"
|
||||||
|
p.regnames.CX = "x0"
|
||||||
|
case "amd64":
|
||||||
|
p.regnames.CX = "rcx"
|
||||||
|
p.regnames.FsBase = "fs_base"
|
||||||
|
default:
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
if process != nil {
|
if process != nil {
|
||||||
p.waitChan = make(chan *os.ProcessState)
|
p.waitChan = make(chan *os.ProcessState)
|
||||||
go func() {
|
go func() {
|
||||||
@ -282,7 +316,7 @@ func (p *gdbProcess) Dial(addr string, path string, pid int, debugInfoDirs []str
|
|||||||
func (p *gdbProcess) Connect(conn net.Conn, path string, pid int, debugInfoDirs []string, stopReason proc.StopReason) (*proc.Target, error) {
|
func (p *gdbProcess) Connect(conn net.Conn, path string, pid int, debugInfoDirs []string, stopReason proc.StopReason) (*proc.Target, error) {
|
||||||
p.conn.conn = conn
|
p.conn.conn = conn
|
||||||
p.conn.pid = pid
|
p.conn.pid = pid
|
||||||
err := p.conn.handshake()
|
err := p.conn.handshake(p.regnames)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1038,7 +1072,7 @@ func (p *gdbProcess) Restart(pos string) (proc.Thread, error) {
|
|||||||
p.clearThreadRegisters()
|
p.clearThreadRegisters()
|
||||||
|
|
||||||
for addr := range p.breakpoints.M {
|
for addr := range p.breakpoints.M {
|
||||||
p.conn.setBreakpoint(addr)
|
p.conn.setBreakpoint(addr, p.breakpointKind)
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.currentThread, p.setCurrentBreakpoints()
|
return p.currentThread, p.setCurrentBreakpoints()
|
||||||
@ -1175,11 +1209,11 @@ func (p *gdbProcess) FindBreakpoint(pc uint64) (*proc.Breakpoint, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *gdbProcess) WriteBreakpoint(bp *proc.Breakpoint) error {
|
func (p *gdbProcess) WriteBreakpoint(bp *proc.Breakpoint) error {
|
||||||
return p.conn.setBreakpoint(bp.Addr)
|
return p.conn.setBreakpoint(bp.Addr, p.breakpointKind)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *gdbProcess) EraseBreakpoint(bp *proc.Breakpoint) error {
|
func (p *gdbProcess) EraseBreakpoint(bp *proc.Breakpoint) error {
|
||||||
return p.conn.clearBreakpoint(bp.Addr)
|
return p.conn.clearBreakpoint(bp.Addr, p.breakpointKind)
|
||||||
}
|
}
|
||||||
|
|
||||||
type threadUpdater struct {
|
type threadUpdater struct {
|
||||||
@ -1350,7 +1384,7 @@ func (t *gdbThread) Location() (*proc.Location, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if pcreg, ok := regs.(*gdbRegisters).regs[regnamePC]; !ok {
|
if pcreg, ok := regs.(*gdbRegisters).regs[regs.(*gdbRegisters).regnames.PC]; !ok {
|
||||||
t.p.conn.log.Errorf("thread %d could not find RIP register", t.ID)
|
t.p.conn.log.Errorf("thread %d could not find RIP register", t.ID)
|
||||||
} else if len(pcreg.value) < t.p.bi.Arch.PtrSize() {
|
} else if len(pcreg.value) < t.p.bi.Arch.PtrSize() {
|
||||||
t.p.conn.log.Errorf("thread %d bad length for RIP register: %d", t.ID, len(pcreg.value))
|
t.p.conn.log.Errorf("thread %d bad length for RIP register: %d", t.ID, len(pcreg.value))
|
||||||
@ -1400,11 +1434,11 @@ func (t *gdbThread) Common() *proc.CommonThread {
|
|||||||
func (t *gdbThread) StepInstruction() error {
|
func (t *gdbThread) StepInstruction() error {
|
||||||
pc := t.regs.PC()
|
pc := t.regs.PC()
|
||||||
if _, atbp := t.p.breakpoints.M[pc]; atbp {
|
if _, atbp := t.p.breakpoints.M[pc]; atbp {
|
||||||
err := t.p.conn.clearBreakpoint(pc)
|
err := t.p.conn.clearBreakpoint(pc, t.p.breakpointKind)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer t.p.conn.setBreakpoint(pc)
|
defer t.p.conn.setBreakpoint(pc, t.p.breakpointKind)
|
||||||
}
|
}
|
||||||
// Reset thread registers so the next call to
|
// Reset thread registers so the next call to
|
||||||
// Thread.Registers will not be cached.
|
// Thread.Registers will not be cached.
|
||||||
@ -1490,8 +1524,9 @@ func (p *gdbProcess) DumpProcessNotes(notes []elfwriter.Note, threadDone func())
|
|||||||
return false, notes, nil
|
return false, notes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (regs *gdbRegisters) init(regsInfo []gdbRegisterInfo, arch *proc.Arch) {
|
func (regs *gdbRegisters) init(regsInfo []gdbRegisterInfo, arch *proc.Arch, regnames *gdbRegnames) {
|
||||||
regs.arch = arch
|
regs.arch = arch
|
||||||
|
regs.regnames = regnames
|
||||||
regs.regs = make(map[string]gdbRegister)
|
regs.regs = make(map[string]gdbRegister)
|
||||||
regs.regsInfo = regsInfo
|
regs.regsInfo = regsInfo
|
||||||
|
|
||||||
@ -1513,7 +1548,7 @@ func (regs *gdbRegisters) init(regsInfo []gdbRegisterInfo, arch *proc.Arch) {
|
|||||||
// the stub can allocate memory, or reloadGAtPC, if the stub can't.
|
// the stub can allocate memory, or reloadGAtPC, if the stub can't.
|
||||||
func (t *gdbThread) reloadRegisters() error {
|
func (t *gdbThread) reloadRegisters() error {
|
||||||
if t.regs.regs == nil {
|
if t.regs.regs == nil {
|
||||||
t.regs.init(t.p.conn.regsInfo, t.p.bi.Arch)
|
t.regs.init(t.p.conn.regsInfo, t.p.bi.Arch, t.p.regnames)
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.p.gcmdok {
|
if t.p.gcmdok {
|
||||||
@ -1535,7 +1570,7 @@ func (t *gdbThread) reloadRegisters() error {
|
|||||||
|
|
||||||
switch t.p.bi.GOOS {
|
switch t.p.bi.GOOS {
|
||||||
case "linux":
|
case "linux":
|
||||||
if reg, hasFsBase := t.regs.regs[regnameFsBase]; hasFsBase {
|
if reg, hasFsBase := t.regs.regs[t.p.regnames.FsBase]; hasFsBase {
|
||||||
t.regs.gaddr = 0
|
t.regs.gaddr = 0
|
||||||
t.regs.tls = binary.LittleEndian.Uint64(reg.value)
|
t.regs.tls = binary.LittleEndian.Uint64(reg.value)
|
||||||
t.regs.hasgaddr = false
|
t.regs.hasgaddr = false
|
||||||
@ -1622,11 +1657,11 @@ func (t *gdbThread) reloadGAtPC() error {
|
|||||||
// Additionally all breakpoints in [pc, pc+len(movinstr)] need to be removed
|
// Additionally all breakpoints in [pc, pc+len(movinstr)] need to be removed
|
||||||
for addr := range t.p.breakpoints.M {
|
for addr := range t.p.breakpoints.M {
|
||||||
if addr >= pc && addr <= pc+uint64(len(movinstr)) {
|
if addr >= pc && addr <= pc+uint64(len(movinstr)) {
|
||||||
err := t.p.conn.clearBreakpoint(addr)
|
err := t.p.conn.clearBreakpoint(addr, t.p.breakpointKind)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer t.p.conn.setBreakpoint(addr)
|
defer t.p.conn.setBreakpoint(addr, t.p.breakpointKind)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1648,7 +1683,7 @@ func (t *gdbThread) reloadGAtPC() error {
|
|||||||
}
|
}
|
||||||
t.regs.setPC(pc)
|
t.regs.setPC(pc)
|
||||||
t.regs.setCX(cx)
|
t.regs.setCX(cx)
|
||||||
err1 := t.writeSomeRegisters(regnamePC, regnameCX)
|
err1 := t.writeSomeRegisters(t.p.regnames.PC, t.p.regnames.CX)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = err1
|
err = err1
|
||||||
}
|
}
|
||||||
@ -1665,7 +1700,7 @@ func (t *gdbThread) reloadGAtPC() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := t.readSomeRegisters(regnamePC, regnameCX); err != nil {
|
if err := t.readSomeRegisters(t.p.regnames.PC, t.p.regnames.CX); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1692,7 +1727,7 @@ func (t *gdbThread) reloadGAlloc() error {
|
|||||||
pc := t.regs.PC()
|
pc := t.regs.PC()
|
||||||
|
|
||||||
t.regs.setPC(t.p.loadGInstrAddr)
|
t.regs.setPC(t.p.loadGInstrAddr)
|
||||||
if err := t.writeSomeRegisters(regnamePC); err != nil {
|
if err := t.writeSomeRegisters(t.p.regnames.PC); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1701,7 +1736,7 @@ func (t *gdbThread) reloadGAlloc() error {
|
|||||||
defer func() {
|
defer func() {
|
||||||
t.regs.setPC(pc)
|
t.regs.setPC(pc)
|
||||||
t.regs.setCX(cx)
|
t.regs.setCX(cx)
|
||||||
err1 := t.writeSomeRegisters(regnamePC, regnameCX)
|
err1 := t.writeSomeRegisters(t.p.regnames.PC, t.p.regnames.CX)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = err1
|
err = err1
|
||||||
}
|
}
|
||||||
@ -1718,7 +1753,7 @@ func (t *gdbThread) reloadGAlloc() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := t.readSomeRegisters(regnameCX); err != nil {
|
if err := t.readSomeRegisters(t.p.regnames.CX); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1761,27 +1796,27 @@ func (t *gdbThread) SetCurrentBreakpoint(adjustPC bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (regs *gdbRegisters) PC() uint64 {
|
func (regs *gdbRegisters) PC() uint64 {
|
||||||
return binary.LittleEndian.Uint64(regs.regs[regnamePC].value)
|
return binary.LittleEndian.Uint64(regs.regs[regs.regnames.PC].value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (regs *gdbRegisters) setPC(value uint64) {
|
func (regs *gdbRegisters) setPC(value uint64) {
|
||||||
binary.LittleEndian.PutUint64(regs.regs[regnamePC].value, value)
|
binary.LittleEndian.PutUint64(regs.regs[regs.regnames.PC].value, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (regs *gdbRegisters) SP() uint64 {
|
func (regs *gdbRegisters) SP() uint64 {
|
||||||
return binary.LittleEndian.Uint64(regs.regs[regnameSP].value)
|
return binary.LittleEndian.Uint64(regs.regs[regs.regnames.SP].value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (regs *gdbRegisters) BP() uint64 {
|
func (regs *gdbRegisters) BP() uint64 {
|
||||||
return binary.LittleEndian.Uint64(regs.regs[regnameBP].value)
|
return binary.LittleEndian.Uint64(regs.regs[regs.regnames.BP].value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (regs *gdbRegisters) CX() uint64 {
|
func (regs *gdbRegisters) CX() uint64 {
|
||||||
return binary.LittleEndian.Uint64(regs.regs[regnameCX].value)
|
return binary.LittleEndian.Uint64(regs.regs[regs.regnames.CX].value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (regs *gdbRegisters) setCX(value uint64) {
|
func (regs *gdbRegisters) setCX(value uint64) {
|
||||||
binary.LittleEndian.PutUint64(regs.regs[regnameCX].value, value)
|
binary.LittleEndian.PutUint64(regs.regs[regs.regnames.CX].value, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (regs *gdbRegisters) TLS() uint64 {
|
func (regs *gdbRegisters) TLS() uint64 {
|
||||||
@ -2180,14 +2215,13 @@ func (t *gdbThread) setPC(pc uint64) error {
|
|||||||
if t.p.gcmdok {
|
if t.p.gcmdok {
|
||||||
return t.p.conn.writeRegisters(t.strID, t.regs.buf)
|
return t.p.conn.writeRegisters(t.strID, t.regs.buf)
|
||||||
}
|
}
|
||||||
reg := t.regs.regs[regnamePC]
|
reg := t.regs.regs[t.regs.regnames.PC]
|
||||||
return t.p.conn.writeRegister(t.strID, reg.regnum, reg.value)
|
return t.p.conn.writeRegister(t.strID, reg.regnum, reg.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetReg will change the value of a list of registers
|
// SetReg will change the value of a list of registers
|
||||||
func (t *gdbThread) SetReg(regNum uint64, reg *op.DwarfRegister) error {
|
func (t *gdbThread) SetReg(regNum uint64, reg *op.DwarfRegister) error {
|
||||||
regName, _, _ := t.p.bi.Arch.DwarfRegisterToString(int(regNum), nil)
|
regName := registerName(t.p.bi.Arch, regNum)
|
||||||
regName = strings.ToLower(regName)
|
|
||||||
_, _ = t.Registers() // Registers must be loaded first
|
_, _ = t.Registers() // Registers must be loaded first
|
||||||
gdbreg, ok := t.regs.regs[regName]
|
gdbreg, ok := t.regs.regs[regName]
|
||||||
if !ok && strings.HasPrefix(regName, "xmm") {
|
if !ok && strings.HasPrefix(regName, "xmm") {
|
||||||
@ -2261,7 +2295,12 @@ func (regs *gdbRegisters) Slice(floatingPoint bool) ([]proc.Register, error) {
|
|||||||
|
|
||||||
func (regs *gdbRegisters) Copy() (proc.Registers, error) {
|
func (regs *gdbRegisters) Copy() (proc.Registers, error) {
|
||||||
savedRegs := &gdbRegisters{}
|
savedRegs := &gdbRegisters{}
|
||||||
savedRegs.init(regs.regsInfo, regs.arch)
|
savedRegs.init(regs.regsInfo, regs.arch, regs.regnames)
|
||||||
copy(savedRegs.buf, regs.buf)
|
copy(savedRegs.buf, regs.buf)
|
||||||
return savedRegs, nil
|
return savedRegs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func registerName(arch *proc.Arch, regNum uint64) string {
|
||||||
|
regName, _, _ := arch.DwarfRegisterToString(int(regNum), nil)
|
||||||
|
return strings.ToLower(regName)
|
||||||
|
}
|
||||||
|
|||||||
@ -94,7 +94,7 @@ const (
|
|||||||
qSupportedMultiprocess = "$qSupported:multiprocess+;swbreak+;hwbreak+;no-resumed+;xmlRegisters=i386"
|
qSupportedMultiprocess = "$qSupported:multiprocess+;swbreak+;hwbreak+;no-resumed+;xmlRegisters=i386"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (conn *gdbConn) handshake() error {
|
func (conn *gdbConn) handshake(regnames *gdbRegnames) error {
|
||||||
conn.ack = true
|
conn.ack = true
|
||||||
conn.packetSize = 256
|
conn.packetSize = 256
|
||||||
conn.rdr = bufio.NewReader(conn.conn)
|
conn.rdr = bufio.NewReader(conn.conn)
|
||||||
@ -140,15 +140,29 @@ func (conn *gdbConn) handshake() error {
|
|||||||
|
|
||||||
// Attempt to figure out the name of the processor register.
|
// Attempt to figure out the name of the processor register.
|
||||||
// We either need qXfer:features:read (gdbserver/rr) or qRegisterInfo (lldb)
|
// We either need qXfer:features:read (gdbserver/rr) or qRegisterInfo (lldb)
|
||||||
if err := conn.readRegisterInfo(); err != nil {
|
regFound := map[string]bool{
|
||||||
|
regnames.PC: false,
|
||||||
|
regnames.SP: false,
|
||||||
|
regnames.BP: false,
|
||||||
|
regnames.CX: false,
|
||||||
|
}
|
||||||
|
if err := conn.readRegisterInfo(regFound); err != nil {
|
||||||
if isProtocolErrorUnsupported(err) {
|
if isProtocolErrorUnsupported(err) {
|
||||||
if err := conn.readTargetXml(); err != nil {
|
if err := conn.readTargetXml(regFound); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for n := range regFound {
|
||||||
|
if n == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !regFound[n] {
|
||||||
|
return fmt.Errorf("could not find %s register", n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We either need:
|
// We either need:
|
||||||
// * QListThreadsInStopReply + qThreadStopInfo (i.e. lldb-server/debugserver),
|
// * QListThreadsInStopReply + qThreadStopInfo (i.e. lldb-server/debugserver),
|
||||||
@ -226,17 +240,24 @@ type gdbRegisterInfo struct {
|
|||||||
Group string `xml:"group,attr"`
|
Group string `xml:"group,attr"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setRegFound(regFound map[string]bool, name string) {
|
||||||
|
for n := range regFound {
|
||||||
|
if name == n {
|
||||||
|
regFound[n] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// readTargetXml reads target.xml file from stub using qXfer:features:read,
|
// readTargetXml reads target.xml file from stub using qXfer:features:read,
|
||||||
// then parses it requesting any additional files.
|
// then parses it requesting any additional files.
|
||||||
// The schema of target.xml is described by:
|
// The schema of target.xml is described by:
|
||||||
// https://github.com/bminor/binutils-gdb/blob/61baf725eca99af2569262d10aca03dcde2698f6/gdb/features/gdb-target.dtd
|
// https://github.com/bminor/binutils-gdb/blob/61baf725eca99af2569262d10aca03dcde2698f6/gdb/features/gdb-target.dtd
|
||||||
func (conn *gdbConn) readTargetXml() (err error) {
|
func (conn *gdbConn) readTargetXml(regFound map[string]bool) (err error) {
|
||||||
conn.regsInfo, err = conn.readAnnex("target.xml")
|
conn.regsInfo, err = conn.readAnnex("target.xml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var offset int
|
var offset int
|
||||||
var pcFound, cxFound, spFound bool
|
|
||||||
regnum := 0
|
regnum := 0
|
||||||
for i := range conn.regsInfo {
|
for i := range conn.regsInfo {
|
||||||
if conn.regsInfo[i].Regnum == 0 {
|
if conn.regsInfo[i].Regnum == 0 {
|
||||||
@ -246,25 +267,9 @@ func (conn *gdbConn) readTargetXml() (err error) {
|
|||||||
}
|
}
|
||||||
conn.regsInfo[i].Offset = offset
|
conn.regsInfo[i].Offset = offset
|
||||||
offset += conn.regsInfo[i].Bitsize / 8
|
offset += conn.regsInfo[i].Bitsize / 8
|
||||||
switch conn.regsInfo[i].Name {
|
|
||||||
case regnamePC:
|
|
||||||
pcFound = true
|
|
||||||
case regnameCX:
|
|
||||||
cxFound = true
|
|
||||||
case regnameSP:
|
|
||||||
spFound = true
|
|
||||||
}
|
|
||||||
regnum++
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pcFound {
|
setRegFound(regFound, conn.regsInfo[i].Name)
|
||||||
return errors.New("could not find RIP register")
|
regnum++
|
||||||
}
|
|
||||||
if !spFound {
|
|
||||||
return errors.New("could not find RSP register")
|
|
||||||
}
|
|
||||||
if !cxFound {
|
|
||||||
return errors.New("could not find RCX register")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -272,9 +277,8 @@ func (conn *gdbConn) readTargetXml() (err error) {
|
|||||||
|
|
||||||
// readRegisterInfo uses qRegisterInfo to read register information (used
|
// readRegisterInfo uses qRegisterInfo to read register information (used
|
||||||
// when qXfer:feature:read is not supported).
|
// when qXfer:feature:read is not supported).
|
||||||
func (conn *gdbConn) readRegisterInfo() (err error) {
|
func (conn *gdbConn) readRegisterInfo(regFound map[string]bool) (err error) {
|
||||||
regnum := 0
|
regnum := 0
|
||||||
var pcFound, cxFound, spFound bool
|
|
||||||
for {
|
for {
|
||||||
conn.outbuf.Reset()
|
conn.outbuf.Reset()
|
||||||
fmt.Fprintf(&conn.outbuf, "$qRegisterInfo%x", regnum)
|
fmt.Fprintf(&conn.outbuf, "$qRegisterInfo%x", regnum)
|
||||||
@ -327,30 +331,13 @@ func (conn *gdbConn) readRegisterInfo() (err error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
switch regname {
|
setRegFound(regFound, regname)
|
||||||
case regnamePC:
|
|
||||||
pcFound = true
|
|
||||||
case regnameCX:
|
|
||||||
cxFound = true
|
|
||||||
case regnameSP:
|
|
||||||
spFound = true
|
|
||||||
}
|
|
||||||
|
|
||||||
conn.regsInfo = append(conn.regsInfo, gdbRegisterInfo{Regnum: regnum, Name: regname, Bitsize: bitsize, Offset: offset})
|
conn.regsInfo = append(conn.regsInfo, gdbRegisterInfo{Regnum: regnum, Name: regname, Bitsize: bitsize, Offset: offset})
|
||||||
|
|
||||||
regnum++
|
regnum++
|
||||||
}
|
}
|
||||||
|
|
||||||
if !pcFound {
|
|
||||||
return errors.New("could not find RIP register")
|
|
||||||
}
|
|
||||||
if !spFound {
|
|
||||||
return errors.New("could not find RSP register")
|
|
||||||
}
|
|
||||||
if !cxFound {
|
|
||||||
return errors.New("could not find RCX register")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,17 +397,17 @@ func (conn *gdbConn) qXfer(kind, annex string, binary bool) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setBreakpoint executes a 'Z' (insert breakpoint) command of type '0' and kind '1' or '4'
|
// setBreakpoint executes a 'Z' (insert breakpoint) command of type '0' and kind '1' or '4'
|
||||||
func (conn *gdbConn) setBreakpoint(addr uint64) error {
|
func (conn *gdbConn) setBreakpoint(addr uint64, kind int) error {
|
||||||
conn.outbuf.Reset()
|
conn.outbuf.Reset()
|
||||||
fmt.Fprintf(&conn.outbuf, "$Z0,%x,%d", addr, breakpointKind)
|
fmt.Fprintf(&conn.outbuf, "$Z0,%x,%d", addr, kind)
|
||||||
_, err := conn.exec(conn.outbuf.Bytes(), "set breakpoint")
|
_, err := conn.exec(conn.outbuf.Bytes(), "set breakpoint")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// clearBreakpoint executes a 'z' (remove breakpoint) command of type '0' and kind '1' or '4'
|
// clearBreakpoint executes a 'z' (remove breakpoint) command of type '0' and kind '1' or '4'
|
||||||
func (conn *gdbConn) clearBreakpoint(addr uint64) error {
|
func (conn *gdbConn) clearBreakpoint(addr uint64, kind int) error {
|
||||||
conn.outbuf.Reset()
|
conn.outbuf.Reset()
|
||||||
fmt.Fprintf(&conn.outbuf, "$z0,%x,%d", addr, breakpointKind)
|
fmt.Fprintf(&conn.outbuf, "$z0,%x,%d", addr, kind)
|
||||||
_, err := conn.exec(conn.outbuf.Bytes(), "clear breakpoint")
|
_, err := conn.exec(conn.outbuf.Bytes(), "clear breakpoint")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
//+build 386
|
|
||||||
|
|
||||||
package gdbserial
|
|
||||||
|
|
||||||
const (
|
|
||||||
regnamePC = "rip"
|
|
||||||
regnameCX = "rcx"
|
|
||||||
regnameSP = "rsp"
|
|
||||||
regnameDX = "rdx"
|
|
||||||
regnameBP = "rbp"
|
|
||||||
regnameFsBase = "fs_base"
|
|
||||||
regnameGsBase = "gs_base"
|
|
||||||
|
|
||||||
breakpointKind = 1
|
|
||||||
)
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
//+build amd64
|
|
||||||
|
|
||||||
package gdbserial
|
|
||||||
|
|
||||||
const (
|
|
||||||
regnamePC = "rip"
|
|
||||||
regnameCX = "rcx"
|
|
||||||
regnameSP = "rsp"
|
|
||||||
regnameDX = "rdx"
|
|
||||||
regnameBP = "rbp"
|
|
||||||
regnameFsBase = "fs_base"
|
|
||||||
regnameGsBase = "gs_base"
|
|
||||||
|
|
||||||
breakpointKind = 1
|
|
||||||
)
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
//+build arm64
|
|
||||||
|
|
||||||
package gdbserial
|
|
||||||
|
|
||||||
const (
|
|
||||||
regnamePC = "pc"
|
|
||||||
regnameCX = "x0"
|
|
||||||
regnameSP = "sp"
|
|
||||||
regnameBP = "fp"
|
|
||||||
|
|
||||||
// not needed but needs to be declared
|
|
||||||
regnameFsBase = ""
|
|
||||||
regnameDX = ""
|
|
||||||
|
|
||||||
breakpointKind = 4
|
|
||||||
)
|
|
||||||
Loading…
Reference in New Issue
Block a user