]> Cypherpunks repositories - gostls13.git/commitdiff
Debugger's remote runtime definitions.
authorAustin Clements <aclements@csail.mit.edu>
Sat, 29 Aug 2009 01:04:18 +0000 (18:04 -0700)
committerAustin Clements <aclements@csail.mit.edu>
Sat, 29 Aug 2009 01:04:18 +0000 (18:04 -0700)
R=rsc
APPROVED=rsc
DELTA=237  (237 added, 0 deleted, 0 changed)
OCL=33966
CL=34065

usr/austin/ogle/rruntime.go [new file with mode: 0644]

diff --git a/usr/austin/ogle/rruntime.go b/usr/austin/ogle/rruntime.go
new file mode 100644 (file)
index 0000000..685cc95
--- /dev/null
@@ -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]);
+               }
+       }
+}