summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Clements <aclements@csail.mit.edu>2009-08-28 18:04:18 -0700
committerAustin Clements <aclements@csail.mit.edu>2009-08-28 18:04:18 -0700
commitfa5035fb94d4a07e1f46d7c53be6ea928e4b5038 (patch)
tree10c138e7b0df84a244b910b234295d8ca2510591
parent4332a2efb4a28985c5b5bc08971f80b4e6e623fc (diff)
downloadgolang-fa5035fb94d4a07e1f46d7c53be6ea928e4b5038.tar.gz
Debugger's remote runtime definitions.
R=rsc APPROVED=rsc DELTA=237 (237 added, 0 deleted, 0 changed) OCL=33966 CL=34065
-rw-r--r--usr/austin/ogle/rruntime.go241
1 files changed, 241 insertions, 0 deletions
diff --git a/usr/austin/ogle/rruntime.go b/usr/austin/ogle/rruntime.go
new file mode 100644
index 000000000..685cc95a7
--- /dev/null
+++ b/usr/austin/ogle/rruntime.go
@@ -0,0 +1,241 @@
+// 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 (
+ "eval";
+ "ptrace";
+ "reflect";
+)
+
+// This file contains remote runtime definitions. Using reflection,
+// we convert all of these to interpreter types and layout their
+// remote representations using the architecture rules.
+//
+// We could get most of these definitions from our own runtime
+// package; however, some of them differ in convenient ways, some of
+// them are not defined or exported by the runtime, and having our own
+// definitions makes it easy to support multiple remote runtime
+// versions. This may turn out to be overkill.
+//
+// All of these structures are prefixed with rt1 to indicate the
+// runtime version and to mark them as types used only as templates
+// for remote types.
+
+/*
+ * Runtime data headers
+ *
+ * See $GOROOT/src/pkg/runtime/runtime.h
+ */
+
+type rt1String struct {
+ str uintptr;
+ len int;
+}
+
+type rt1Slice struct {
+ array uintptr;
+ len int;
+ cap int;
+}
+
+type rt1Eface struct {
+ typ uintptr;
+ ptr uintptr;
+}
+
+/*
+ * Runtime type structures
+ *
+ * See $GOROOT/src/pkg/runtime/type.h and $GOROOT/src/pkg/runtime/type.go
+ */
+
+type rt1UncommonType struct {
+ name *string;
+ pkgPath *string;
+ //methods []method;
+}
+
+type rt1CommonType struct {
+ size uintptr;
+ hash uint32;
+ alg, align, fieldAlign uint8;
+ string *string;
+ uncommonType *rt1UncommonType;
+}
+
+type rt1Type struct {
+ // While Type is technically an Eface, treating the
+ // discriminator as an opaque pointer and taking advantage of
+ // the commonType prologue on all Type's makes type parsing
+ // much simpler.
+ typ uintptr;
+ ptr *rt1CommonType;
+}
+
+type rt1StructField struct {
+ name *string;
+ pkgPath *string;
+ typ *rt1Type;
+ tag *string;
+ offset uintptr;
+}
+
+type rt1StructType struct {
+ rt1CommonType;
+ fields []rt1StructField;
+}
+
+type rt1PtrType struct {
+ rt1CommonType;
+ elem *rt1Type;
+}
+
+type rt1SliceType struct {
+ rt1CommonType;
+ elem *rt1Type;
+}
+
+type rt1ArrayType struct {
+ rt1CommonType;
+ elem *rt1Type;
+ len uintptr;
+}
+
+/*
+ * Runtime scheduler structures
+ *
+ * See $GOROOT/src/pkg/runtime/runtime.h
+ */
+
+type rt1Stktop struct {
+ stackguard uintptr;
+ stackbase *rt1Stktop;
+ gobuf rt1Gobuf;
+}
+
+type rt1Gobuf struct {
+ sp uintptr;
+ pc uintptr;
+ g *rt1G;
+}
+
+type rt1G struct {
+ stackguard uintptr;
+ stackbase *rt1Stktop;
+}
+
+// runtimeIndexes stores the indexes of fields in the runtime
+// structures. It is filled in using reflection, so the name of the
+// fields must match the names of the remoteType's in runtimeValues
+// exactly and the names of the index fields must be the capitalized
+// version of the names of the fields in the runtime structures above.
+type runtimeIndexes struct {
+ String struct {
+ Str, Len int;
+ };
+ Slice struct {
+ Array, Len, Cap int;
+ };
+ Eface struct {
+ Typ, Ptr int;
+ };
+
+ UncommonType struct {
+ Name, PkgPath int;
+ };
+ CommonType struct {
+ Size, Hash, Alg, Align, FieldAlign, String, UncommonType int;
+ };
+ Type struct {
+ Typ, Ptr int;
+ };
+ StructField struct {
+ Name, PkgPath, Typ, Tag, Offset int;
+ };
+ StructType struct {
+ Fields int;
+ };
+ PtrType struct {
+ Elem int;
+ };
+ SliceType struct {
+ Elem int;
+ };
+ ArrayType struct {
+ Elem, Len int;
+ };
+
+ Stktop struct {
+ Stackguard, Stackbase, Gobuf int;
+ };
+ Gobuf struct {
+ Sp, Pc, G int;
+ };
+ G struct {
+ Stackguard, Stackbase int;
+ };
+}
+
+// runtimeValues stores the types and values that correspond to those
+// in the remote runtime package.
+type runtimeValues struct {
+ // Runtime data headers
+ String, Slice, Eface *remoteType;
+ // Runtime type structures
+ Type, CommonType, UncommonType, StructField, StructType, PtrType,
+ ArrayType, SliceType *remoteType;
+ // Runtime scheduler structures
+ Stktop, Gobuf, G *remoteType;
+ // Addresses of *runtime.XType types. These are the
+ // discriminators on the runtime.Type interface. We use local
+ // reflection to fill these in from the remote symbol table,
+ // so the names must match the runtime names.
+ PBoolType,
+ PUint8Type, PUint16Type, PUint32Type, PUint64Type, PUintType, PUintptrType,
+ PInt8Type, PInt16Type, PInt32Type, PInt64Type, PIntType,
+ PFloat32Type, PFloat64Type, PFloatType,
+ PArrayType, PStringType, PStructType, PPtrType, PFuncType,
+ PInterfaceType, PSliceType, PMapType, PChanType,
+ PDotDotDotType, PUnsafePointerType ptrace.Word;
+}
+
+// fillRuntimeIndexes fills a runtimeIndexes structure will the field
+// indexes gathered from the remoteTypes recorded in a runtimeValues
+// structure.
+func fillRuntimeIndexes(runtime *runtimeValues, out *runtimeIndexes) {
+ outv := reflect.Indirect(reflect.NewValue(out)).(*reflect.StructValue);
+ outt := outv.Type().(*reflect.StructType);
+ runtimev := reflect.Indirect(reflect.NewValue(runtime)).(*reflect.StructValue);
+
+ // out contains fields corresponding to each runtime type
+ for i := 0; i < outt.NumField(); i++ {
+ // Find the interpreter type for this runtime type
+ name := outt.Field(i).Name;
+ et := runtimev.FieldByName(name).Interface().(*remoteType).Type.(*eval.StructType);
+
+ // Get the field indexes of the interpreter struct type
+ indexes := make(map[string] int, len(et.Elems));
+ for j, f := range et.Elems {
+ if f.Anonymous {
+ continue;
+ }
+ name := f.Name;
+ if name[0] >= 'a' && name[0] <= 'z' {
+ name = string(name[0] + 'A' - 'a') + name[1:len(name)];
+ }
+ indexes[name] = j;
+ }
+
+ // Fill this field of out
+ outStructv := outv.Field(i).(*reflect.StructValue);
+ outStructt := outStructv.Type().(*reflect.StructType);
+ for j := 0; j < outStructt.NumField(); j++ {
+ f := outStructv.Field(j).(*reflect.IntValue);
+ name := outStructt.Field(j).Name;
+ f.Set(indexes[name]);
+ }
+ }
+}