// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package ogle import ( "debug/proc"; "math"; ) type Arch interface { // ToWord converts an array of up to 8 bytes in memory order // to a word. ToWord(data []byte) proc.Word; // FromWord converts a word to an array of up to 8 bytes in // memory order. FromWord(v proc.Word, out []byte); // ToFloat32 converts a word to a float. The order of this // word will be the order returned by ToWord on the memory // representation of a float, and thus may require reversing. ToFloat32(bits uint32) float32; // FromFloat32 converts a float to a word. This should return // a word that can be passed to FromWord to get the memory // representation of a float on this architecture. FromFloat32(f float32) uint32; // ToFloat64 is to float64 as ToFloat32 is to float32. ToFloat64(bits uint64) float64; // FromFloat64 is to float64 as FromFloat32 is to float32. FromFloat64(f float64) uint64; // IntSize returns the number of bytes in an 'int'. IntSize() int; // PtrSize returns the number of bytes in a 'uintptr'. PtrSize() int; // FloatSize returns the number of bytes in a 'float'. FloatSize() int; // Align rounds offset up to the appropriate offset for a // basic type with the given width. Align(offset, width int) int; // G returns the current G pointer. G(regs proc.Regs) proc.Word; // ClosureSize returns the number of bytes expected by // ParseClosure. ClosureSize() int; // ParseClosure takes ClosureSize bytes read from a return PC // in a remote process, determines if the code is a closure, // and returns the frame size of the closure if it is. ParseClosure(data []byte) (frame int, ok bool); } type ArchLSB struct{} func (ArchLSB) ToWord(data []byte) proc.Word { var v proc.Word; for i, b := range data { v |= proc.Word(b) << (uint(i) * 8) } return v; } func (ArchLSB) FromWord(v proc.Word, out []byte) { for i := range out { out[i] = byte(v); v >>= 8; } } func (ArchLSB) ToFloat32(bits uint32) float32 { // TODO(austin) Do these definitions depend on my current // architecture? return math.Float32frombits(bits) } func (ArchLSB) FromFloat32(f float32) uint32 { return math.Float32bits(f) } func (ArchLSB) ToFloat64(bits uint64) float64 { return math.Float64frombits(bits) } func (ArchLSB) FromFloat64(f float64) uint64 { return math.Float64bits(f) } type ArchAlignedMultiple struct{} func (ArchAlignedMultiple) Align(offset, width int) int { return ((offset - 1) | (width - 1)) + 1 } type amd64 struct { ArchLSB; ArchAlignedMultiple; gReg int; } func (a *amd64) IntSize() int { return 4 } func (a *amd64) PtrSize() int { return 8 } func (a *amd64) FloatSize() int { return 4 } func (a *amd64) G(regs proc.Regs) proc.Word { // See src/pkg/runtime/mkasmh if a.gReg == -1 { ns := regs.Names(); for i, n := range ns { if n == "r15" { a.gReg = i; break; } } } return regs.Get(a.gReg); } func (a *amd64) ClosureSize() int { return 8 } func (a *amd64) ParseClosure(data []byte) (int, bool) { if data[0] == 0x48 && data[1] == 0x81 && data[2] == 0xc4 && data[7] == 0xc3 { return int(a.ToWord(data[3:7]) + 8), true } return 0, false; } var Amd64 = &amd64{gReg: -1}