forked from go-delve/delve
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
*: FreeBSD initial support (go-delve#1480)
* FreeBSD initial support * first code review fixes * regs slice upd * execPtraceFunc wrap * disabled concurrency tests fixed kill() issue * disabled concurrency tests fixed kill() issue * cleanup vendor related code * cleanup ptrace calls * vendoring latest changes * Revert "vendoring latest changes" This reverts commit 833cb87 * vendoring latest changes * requested changes
- Loading branch information
1 parent
1df718f
commit d428d64
Showing
24 changed files
with
1,352 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Installation on FreeBSD | ||
|
||
Please use the following steps to build and install Delve on FreeBSD. | ||
|
||
There are two ways to install on FreeBSD. First is the standard `go get` method: | ||
|
||
``` | ||
go get -u github.com/go-delve/delve/cmd/dlv | ||
``` | ||
|
||
Alternatively make sure $GOPATH is set (e.g. as `~/.go`) and: | ||
|
||
``` | ||
$ git clone https://github.com/go-delve/delve.git $GOPATH/src/github.com/go-delve/delve | ||
$ cd $GOPATH/src/github.com/go-delve/delve | ||
$ gmake install | ||
``` | ||
|
||
Note: If you are using Go 1.5 you must set `GO15VENDOREXPERIMENT=1` before continuing. The `GO15VENDOREXPERIMENT` env var simply opts into the [Go 1.5 Vendor Experiment](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo/). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,333 @@ | ||
package fbsdutil | ||
|
||
import ( | ||
"golang.org/x/arch/x86/x86asm" | ||
|
||
"github.com/go-delve/delve/pkg/proc" | ||
"github.com/go-delve/delve/pkg/proc/linutil" | ||
) | ||
|
||
// AMD64Registers implements the proc.Registers interface for the native/freebsd | ||
// backend and core/freebsd backends, on AMD64. | ||
type AMD64Registers struct { | ||
Regs *AMD64PtraceRegs | ||
Fpregs []proc.Register | ||
Fpregset *AMD64Xstate | ||
Fsbase uint64 | ||
} | ||
|
||
// AMD64PtraceRegs is the struct used by the freebsd kernel to return the | ||
// general purpose registers for AMD64 CPUs. | ||
// source: sys/x86/include/reg.h | ||
type AMD64PtraceRegs struct { | ||
R15 int64 | ||
R14 int64 | ||
R13 int64 | ||
R12 int64 | ||
R11 int64 | ||
R10 int64 | ||
R9 int64 | ||
R8 int64 | ||
Rdi int64 | ||
Rsi int64 | ||
Rbp int64 | ||
Rbx int64 | ||
Rdx int64 | ||
Rcx int64 | ||
Rax int64 | ||
Trapno uint32 | ||
Fs uint16 | ||
Gs uint16 | ||
Err uint32 | ||
Es uint16 | ||
Ds uint16 | ||
Rip int64 | ||
Cs int64 | ||
Rflags int64 | ||
Rsp int64 | ||
Ss int64 | ||
} | ||
|
||
// Slice returns the registers as a list of (name, value) pairs. | ||
func (r *AMD64Registers) Slice(floatingPoint bool) []proc.Register { | ||
var regs64 = []struct { | ||
k string | ||
v int64 | ||
}{ | ||
{"R15", r.Regs.R15}, | ||
{"R14", r.Regs.R14}, | ||
{"R13", r.Regs.R13}, | ||
{"R12", r.Regs.R12}, | ||
{"R11", r.Regs.R11}, | ||
{"R10", r.Regs.R10}, | ||
{"R9", r.Regs.R9}, | ||
{"R8", r.Regs.R8}, | ||
{"Rdi", r.Regs.Rdi}, | ||
{"Rsi", r.Regs.Rsi}, | ||
{"Rbp", r.Regs.Rbp}, | ||
{"Rbx", r.Regs.Rbx}, | ||
{"Rdx", r.Regs.Rdx}, | ||
{"Rcx", r.Regs.Rcx}, | ||
{"Rax", r.Regs.Rax}, | ||
{"Rip", r.Regs.Rip}, | ||
{"Cs", r.Regs.Cs}, | ||
{"Rflags", r.Regs.Rflags}, | ||
{"Rsp", r.Regs.Rsp}, | ||
{"Ss", r.Regs.Ss}, | ||
} | ||
var regs32 = []struct { | ||
k string | ||
v uint32 | ||
}{ | ||
{"Trapno", r.Regs.Trapno}, | ||
{"Err", r.Regs.Err}, | ||
} | ||
var regs16 = []struct { | ||
k string | ||
v uint16 | ||
}{ | ||
{"Fs", r.Regs.Fs}, | ||
{"Gs", r.Regs.Gs}, | ||
{"Es", r.Regs.Es}, | ||
{"Ds", r.Regs.Ds}, | ||
} | ||
out := make([]proc.Register, 0, | ||
len(regs64)+ | ||
len(regs32)+ | ||
len(regs16)+ | ||
1+ // for Rflags | ||
len(r.Fpregs)) | ||
for _, reg := range regs64 { | ||
// FreeBSD defines the registers as signed, but Linux defines | ||
// them as unsigned. Of course, a register doesn't really have | ||
// a concept of signedness. Cast to what Delve expects. | ||
out = proc.AppendQwordReg(out, reg.k, uint64(reg.v)) | ||
} | ||
for _, reg := range regs32 { | ||
out = proc.AppendDwordReg(out, reg.k, reg.v) | ||
} | ||
for _, reg := range regs16 { | ||
out = proc.AppendWordReg(out, reg.k, reg.v) | ||
} | ||
// x86 called this register "Eflags". amd64 extended it and renamed it | ||
// "Rflags", but Linux still uses the old name. | ||
out = proc.AppendEflagReg(out, "Rflags", uint64(r.Regs.Rflags)) | ||
if floatingPoint { | ||
out = append(out, r.Fpregs...) | ||
} | ||
return out | ||
} | ||
|
||
// PC returns the value of RIP register. | ||
func (r *AMD64Registers) PC() uint64 { | ||
return uint64(r.Regs.Rip) | ||
} | ||
|
||
// SP returns the value of RSP register. | ||
func (r *AMD64Registers) SP() uint64 { | ||
return uint64(r.Regs.Rsp) | ||
} | ||
|
||
func (r *AMD64Registers) BP() uint64 { | ||
return uint64(r.Regs.Rbp) | ||
} | ||
|
||
// CX returns the value of RCX register. | ||
func (r *AMD64Registers) CX() uint64 { | ||
return uint64(r.Regs.Rcx) | ||
} | ||
|
||
// TLS returns the address of the thread local storage memory segment. | ||
func (r *AMD64Registers) TLS() uint64 { | ||
return r.Fsbase | ||
} | ||
|
||
// GAddr returns the address of the G variable if it is known, 0 and false | ||
// otherwise. | ||
func (r *AMD64Registers) GAddr() (uint64, bool) { | ||
return 0, false | ||
} | ||
|
||
// Get returns the value of the n-th register (in x86asm order). | ||
func (r *AMD64Registers) Get(n int) (uint64, error) { | ||
reg := x86asm.Reg(n) | ||
const ( | ||
mask8 = 0x000000ff | ||
mask16 = 0x0000ffff | ||
mask32 = 0xffffffff | ||
) | ||
|
||
switch reg { | ||
// 8-bit | ||
case x86asm.AL: | ||
return uint64(r.Regs.Rax) & mask8, nil | ||
case x86asm.CL: | ||
return uint64(r.Regs.Rcx) & mask8, nil | ||
case x86asm.DL: | ||
return uint64(r.Regs.Rdx) & mask8, nil | ||
case x86asm.BL: | ||
return uint64(r.Regs.Rbx) & mask8, nil | ||
case x86asm.AH: | ||
return (uint64(r.Regs.Rax) >> 8) & mask8, nil | ||
case x86asm.CH: | ||
return (uint64(r.Regs.Rcx) >> 8) & mask8, nil | ||
case x86asm.DH: | ||
return (uint64(r.Regs.Rdx) >> 8) & mask8, nil | ||
case x86asm.BH: | ||
return (uint64(r.Regs.Rbx) >> 8) & mask8, nil | ||
case x86asm.SPB: | ||
return uint64(r.Regs.Rsp) & mask8, nil | ||
case x86asm.BPB: | ||
return uint64(r.Regs.Rbp) & mask8, nil | ||
case x86asm.SIB: | ||
return uint64(r.Regs.Rsi) & mask8, nil | ||
case x86asm.DIB: | ||
return uint64(r.Regs.Rdi) & mask8, nil | ||
case x86asm.R8B: | ||
return uint64(r.Regs.R8) & mask8, nil | ||
case x86asm.R9B: | ||
return uint64(r.Regs.R9) & mask8, nil | ||
case x86asm.R10B: | ||
return uint64(r.Regs.R10) & mask8, nil | ||
case x86asm.R11B: | ||
return uint64(r.Regs.R11) & mask8, nil | ||
case x86asm.R12B: | ||
return uint64(r.Regs.R12) & mask8, nil | ||
case x86asm.R13B: | ||
return uint64(r.Regs.R13) & mask8, nil | ||
case x86asm.R14B: | ||
return uint64(r.Regs.R14) & mask8, nil | ||
case x86asm.R15B: | ||
return uint64(r.Regs.R15) & mask8, nil | ||
|
||
// 16-bit | ||
case x86asm.AX: | ||
return uint64(r.Regs.Rax) & mask16, nil | ||
case x86asm.CX: | ||
return uint64(r.Regs.Rcx) & mask16, nil | ||
case x86asm.DX: | ||
return uint64(r.Regs.Rdx) & mask16, nil | ||
case x86asm.BX: | ||
return uint64(r.Regs.Rbx) & mask16, nil | ||
case x86asm.SP: | ||
return uint64(r.Regs.Rsp) & mask16, nil | ||
case x86asm.BP: | ||
return uint64(r.Regs.Rbp) & mask16, nil | ||
case x86asm.SI: | ||
return uint64(r.Regs.Rsi) & mask16, nil | ||
case x86asm.DI: | ||
return uint64(r.Regs.Rdi) & mask16, nil | ||
case x86asm.R8W: | ||
return uint64(r.Regs.R8) & mask16, nil | ||
case x86asm.R9W: | ||
return uint64(r.Regs.R9) & mask16, nil | ||
case x86asm.R10W: | ||
return uint64(r.Regs.R10) & mask16, nil | ||
case x86asm.R11W: | ||
return uint64(r.Regs.R11) & mask16, nil | ||
case x86asm.R12W: | ||
return uint64(r.Regs.R12) & mask16, nil | ||
case x86asm.R13W: | ||
return uint64(r.Regs.R13) & mask16, nil | ||
case x86asm.R14W: | ||
return uint64(r.Regs.R14) & mask16, nil | ||
case x86asm.R15W: | ||
return uint64(r.Regs.R15) & mask16, nil | ||
|
||
// 32-bit | ||
case x86asm.EAX: | ||
return uint64(r.Regs.Rax) & mask32, nil | ||
case x86asm.ECX: | ||
return uint64(r.Regs.Rcx) & mask32, nil | ||
case x86asm.EDX: | ||
return uint64(r.Regs.Rdx) & mask32, nil | ||
case x86asm.EBX: | ||
return uint64(r.Regs.Rbx) & mask32, nil | ||
case x86asm.ESP: | ||
return uint64(r.Regs.Rsp) & mask32, nil | ||
case x86asm.EBP: | ||
return uint64(r.Regs.Rbp) & mask32, nil | ||
case x86asm.ESI: | ||
return uint64(r.Regs.Rsi) & mask32, nil | ||
case x86asm.EDI: | ||
return uint64(r.Regs.Rdi) & mask32, nil | ||
case x86asm.R8L: | ||
return uint64(r.Regs.R8) & mask32, nil | ||
case x86asm.R9L: | ||
return uint64(r.Regs.R9) & mask32, nil | ||
case x86asm.R10L: | ||
return uint64(r.Regs.R10) & mask32, nil | ||
case x86asm.R11L: | ||
return uint64(r.Regs.R11) & mask32, nil | ||
case x86asm.R12L: | ||
return uint64(r.Regs.R12) & mask32, nil | ||
case x86asm.R13L: | ||
return uint64(r.Regs.R13) & mask32, nil | ||
case x86asm.R14L: | ||
return uint64(r.Regs.R14) & mask32, nil | ||
case x86asm.R15L: | ||
return uint64(r.Regs.R15) & mask32, nil | ||
|
||
// 64-bit | ||
case x86asm.RAX: | ||
return uint64(r.Regs.Rax), nil | ||
case x86asm.RCX: | ||
return uint64(r.Regs.Rcx), nil | ||
case x86asm.RDX: | ||
return uint64(r.Regs.Rdx), nil | ||
case x86asm.RBX: | ||
return uint64(r.Regs.Rbx), nil | ||
case x86asm.RSP: | ||
return uint64(r.Regs.Rsp), nil | ||
case x86asm.RBP: | ||
return uint64(r.Regs.Rbp), nil | ||
case x86asm.RSI: | ||
return uint64(r.Regs.Rsi), nil | ||
case x86asm.RDI: | ||
return uint64(r.Regs.Rdi), nil | ||
case x86asm.R8: | ||
return uint64(r.Regs.R8), nil | ||
case x86asm.R9: | ||
return uint64(r.Regs.R9), nil | ||
case x86asm.R10: | ||
return uint64(r.Regs.R10), nil | ||
case x86asm.R11: | ||
return uint64(r.Regs.R11), nil | ||
case x86asm.R12: | ||
return uint64(r.Regs.R12), nil | ||
case x86asm.R13: | ||
return uint64(r.Regs.R13), nil | ||
case x86asm.R14: | ||
return uint64(r.Regs.R14), nil | ||
case x86asm.R15: | ||
return uint64(r.Regs.R15), nil | ||
} | ||
|
||
return 0, proc.ErrUnknownRegister | ||
} | ||
|
||
// Copy returns a copy of these registers that is guarenteed not to change. | ||
func (r *AMD64Registers) Copy() proc.Registers { | ||
var rr AMD64Registers | ||
rr.Regs = &AMD64PtraceRegs{} | ||
rr.Fpregset = &AMD64Xstate{} | ||
*(rr.Regs) = *(r.Regs) | ||
if r.Fpregset != nil { | ||
*(rr.Fpregset) = *(r.Fpregset) | ||
} | ||
if r.Fpregs != nil { | ||
rr.Fpregs = make([]proc.Register, len(r.Fpregs)) | ||
copy(rr.Fpregs, r.Fpregs) | ||
} | ||
return &rr | ||
} | ||
|
||
type AMD64Xstate linutil.AMD64Xstate | ||
|
||
func AMD64XstateRead(xstateargs []byte, readLegacy bool, regset *AMD64Xstate) error { | ||
return linutil.AMD64XstateRead(xstateargs, readLegacy, (*linutil.AMD64Xstate)(regset)) | ||
} | ||
|
||
func (xsave *AMD64Xstate) Decode() (regs []proc.Register) { | ||
return (*linutil.AMD64Xstate).Decode((*linutil.AMD64Xstate)(xsave)) | ||
} |
Oops, something went wrong.