2015-06-12 19:49:23 +00:00
|
|
|
package proc
|
2015-04-29 17:07:27 +00:00
|
|
|
|
2016-01-10 08:57:52 +00:00
|
|
|
// Arch defines an interface for representing a
|
|
|
|
// CPU architecture.
|
2015-04-29 17:07:27 +00:00
|
|
|
type Arch interface {
|
2015-07-28 05:33:07 +00:00
|
|
|
SetGStructOffset(ver GoVersion, iscgo bool)
|
2015-04-29 17:07:27 +00:00
|
|
|
PtrSize() int
|
|
|
|
BreakpointInstruction() []byte
|
|
|
|
BreakpointSize() int
|
2015-07-28 05:33:07 +00:00
|
|
|
GStructOffset() uint64
|
2015-04-29 17:07:27 +00:00
|
|
|
}
|
|
|
|
|
2016-01-10 11:47:54 +00:00
|
|
|
// AMD64 represents the AMD64 CPU architecture.
|
2015-04-29 17:07:27 +00:00
|
|
|
type AMD64 struct {
|
2015-06-17 18:09:55 +00:00
|
|
|
ptrSize int
|
|
|
|
breakInstruction []byte
|
|
|
|
breakInstructionLen int
|
2015-07-28 05:33:07 +00:00
|
|
|
gStructOffset uint64
|
2015-06-17 18:09:55 +00:00
|
|
|
hardwareBreakpointUsage []bool
|
2017-04-06 18:14:01 +00:00
|
|
|
goos string
|
2015-04-29 17:07:27 +00:00
|
|
|
}
|
|
|
|
|
2016-01-10 08:57:52 +00:00
|
|
|
// AMD64Arch returns an initialized AMD64
|
|
|
|
// struct.
|
2017-04-06 18:14:01 +00:00
|
|
|
func AMD64Arch(goos string) *AMD64 {
|
2015-07-23 17:08:28 +00:00
|
|
|
var breakInstr = []byte{0xCC}
|
|
|
|
|
|
|
|
return &AMD64{
|
|
|
|
ptrSize: 8,
|
|
|
|
breakInstruction: breakInstr,
|
|
|
|
breakInstructionLen: len(breakInstr),
|
|
|
|
hardwareBreakpointUsage: make([]bool, 4),
|
2017-04-06 18:14:01 +00:00
|
|
|
goos: goos,
|
2015-07-23 17:08:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-10 08:57:52 +00:00
|
|
|
// SetGStructOffset sets the offset of the G struct on the AMD64
|
2016-07-08 05:57:40 +00:00
|
|
|
// arch struct. The offset is dependent on the Go compiler Version
|
2016-01-10 08:57:52 +00:00
|
|
|
// and whether or not the target program was externally linked.
|
2015-07-28 05:33:07 +00:00
|
|
|
func (a *AMD64) SetGStructOffset(ver GoVersion, isextld bool) {
|
2017-04-06 18:14:01 +00:00
|
|
|
switch a.goos {
|
2015-06-11 20:17:56 +00:00
|
|
|
case "darwin":
|
2015-07-28 05:33:07 +00:00
|
|
|
a.gStructOffset = 0x8a0
|
2015-06-11 20:17:56 +00:00
|
|
|
case "linux":
|
2015-07-28 05:33:07 +00:00
|
|
|
a.gStructOffset = 0xfffffffffffffff0
|
2015-08-11 13:37:27 +00:00
|
|
|
if isextld || ver.AfterOrEqual(GoVersion{1, 5, -1, 2, 0}) || ver.IsDevel() {
|
2015-07-28 23:56:55 +00:00
|
|
|
a.gStructOffset += 8
|
|
|
|
}
|
2016-01-15 05:26:54 +00:00
|
|
|
case "windows":
|
2016-01-24 16:30:23 +00:00
|
|
|
// Use ArbitraryUserPointer (0x28) as pointer to pointer
|
2016-01-15 05:26:54 +00:00
|
|
|
// to G struct per:
|
|
|
|
// https://golang.org/src/runtime/cgo/gcc_windows_amd64.c
|
|
|
|
a.gStructOffset = 0x28
|
2015-07-28 05:33:07 +00:00
|
|
|
}
|
2015-04-29 17:07:27 +00:00
|
|
|
}
|
|
|
|
|
2016-01-10 08:57:52 +00:00
|
|
|
// PtrSize returns the size of a pointer
|
|
|
|
// on this architecture.
|
2015-04-29 17:07:27 +00:00
|
|
|
func (a *AMD64) PtrSize() int {
|
|
|
|
return a.ptrSize
|
|
|
|
}
|
|
|
|
|
2016-01-10 08:57:52 +00:00
|
|
|
// BreakpointInstruction returns the Breakpoint
|
|
|
|
// instruction for this architecture.
|
2015-04-29 17:07:27 +00:00
|
|
|
func (a *AMD64) BreakpointInstruction() []byte {
|
|
|
|
return a.breakInstruction
|
|
|
|
}
|
|
|
|
|
2016-01-10 08:57:52 +00:00
|
|
|
// BreakpointSize returns the size of the
|
|
|
|
// breakpoint instruction on this architecture.
|
2015-04-29 17:07:27 +00:00
|
|
|
func (a *AMD64) BreakpointSize() int {
|
|
|
|
return a.breakInstructionLen
|
|
|
|
}
|
2015-06-11 20:17:56 +00:00
|
|
|
|
2016-01-10 08:57:52 +00:00
|
|
|
// GStructOffset returns the offset of the G
|
|
|
|
// struct in thread local storage.
|
2015-07-28 05:33:07 +00:00
|
|
|
func (a *AMD64) GStructOffset() uint64 {
|
|
|
|
return a.gStructOffset
|
2015-06-11 20:17:56 +00:00
|
|
|
}
|