github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/cmd/internal/ld/decodesym.go (about) 1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ld 6 7 import "cmd/internal/obj" 8 9 // Decoding the type.* symbols. This has to be in sync with 10 // ../../runtime/type.go, or more specifically, with what 11 // ../gc/reflect.c stuffs in these. 12 13 func decode_reloc(s *LSym, off int32) *Reloc { 14 for i := 0; i < len(s.R); i++ { 15 if s.R[i].Off == off { 16 return &s.R[i:][0] 17 } 18 } 19 return nil 20 } 21 22 func decode_reloc_sym(s *LSym, off int32) *LSym { 23 r := decode_reloc(s, off) 24 if r == nil { 25 return nil 26 } 27 return r.Sym 28 } 29 30 func decode_inuxi(p []byte, sz int) uint64 { 31 switch sz { 32 case 2: 33 return uint64(Ctxt.Arch.ByteOrder.Uint16(p)) 34 case 4: 35 return uint64(Ctxt.Arch.ByteOrder.Uint32(p)) 36 case 8: 37 return Ctxt.Arch.ByteOrder.Uint64(p) 38 } 39 Diag("dwarf: decode inuxi %d", sz) 40 Errorexit() 41 return 0 42 } 43 44 func commonsize() int { 45 return 8*Thearch.Ptrsize + 8 46 } 47 48 // Type.commonType.kind 49 func decodetype_kind(s *LSym) uint8 { 50 return uint8(s.P[1*Thearch.Ptrsize+7] & obj.KindMask) // 0x13 / 0x1f 51 } 52 53 // Type.commonType.kind 54 func decodetype_noptr(s *LSym) uint8 { 55 return uint8(s.P[1*Thearch.Ptrsize+7] & obj.KindNoPointers) // 0x13 / 0x1f 56 } 57 58 // Type.commonType.kind 59 func decodetype_usegcprog(s *LSym) uint8 { 60 return uint8(s.P[1*Thearch.Ptrsize+7] & obj.KindGCProg) // 0x13 / 0x1f 61 } 62 63 // Type.commonType.size 64 func decodetype_size(s *LSym) int64 { 65 return int64(decode_inuxi(s.P, Thearch.Ptrsize)) // 0x8 / 0x10 66 } 67 68 // Type.commonType.gc 69 func decodetype_gcprog(s *LSym) *LSym { 70 return decode_reloc_sym(s, 1*int32(Thearch.Ptrsize)+8+2*int32(Thearch.Ptrsize)) 71 } 72 73 func decodetype_gcmask(s *LSym) []byte { 74 mask := decode_reloc_sym(s, 1*int32(Thearch.Ptrsize)+8+1*int32(Thearch.Ptrsize)) 75 return mask.P 76 } 77 78 // Type.ArrayType.elem and Type.SliceType.Elem 79 func decodetype_arrayelem(s *LSym) *LSym { 80 return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30 81 } 82 83 func decodetype_arraylen(s *LSym) int64 { 84 return int64(decode_inuxi(s.P[commonsize()+2*Thearch.Ptrsize:], Thearch.Ptrsize)) 85 } 86 87 // Type.PtrType.elem 88 func decodetype_ptrelem(s *LSym) *LSym { 89 return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30 90 } 91 92 // Type.MapType.key, elem 93 func decodetype_mapkey(s *LSym) *LSym { 94 return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30 95 } 96 97 func decodetype_mapvalue(s *LSym) *LSym { 98 return decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)) // 0x20 / 0x38 99 } 100 101 // Type.ChanType.elem 102 func decodetype_chanelem(s *LSym) *LSym { 103 return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30 104 } 105 106 // Type.FuncType.dotdotdot 107 func decodetype_funcdotdotdot(s *LSym) int { 108 return int(s.P[commonsize()]) 109 } 110 111 // Type.FuncType.in.length 112 func decodetype_funcincount(s *LSym) int { 113 return int(decode_inuxi(s.P[commonsize()+2*Thearch.Ptrsize:], Thearch.Intsize)) 114 } 115 116 func decodetype_funcoutcount(s *LSym) int { 117 return int(decode_inuxi(s.P[commonsize()+3*Thearch.Ptrsize+2*Thearch.Intsize:], Thearch.Intsize)) 118 } 119 120 func decodetype_funcintype(s *LSym, i int) *LSym { 121 r := decode_reloc(s, int32(commonsize())+int32(Thearch.Ptrsize)) 122 if r == nil { 123 return nil 124 } 125 return decode_reloc_sym(r.Sym, int32(r.Add+int64(int32(i)*int32(Thearch.Ptrsize)))) 126 } 127 128 func decodetype_funcouttype(s *LSym, i int) *LSym { 129 r := decode_reloc(s, int32(commonsize())+2*int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize)) 130 if r == nil { 131 return nil 132 } 133 return decode_reloc_sym(r.Sym, int32(r.Add+int64(int32(i)*int32(Thearch.Ptrsize)))) 134 } 135 136 // Type.StructType.fields.Slice::length 137 func decodetype_structfieldcount(s *LSym) int { 138 return int(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize:], Thearch.Intsize)) 139 } 140 141 func structfieldsize() int { 142 return 5 * Thearch.Ptrsize 143 } 144 145 // Type.StructType.fields[]-> name, typ and offset. 146 func decodetype_structfieldname(s *LSym, i int) string { 147 // go.string."foo" 0x28 / 0x40 148 s = decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize)+int32(i)*int32(structfieldsize())) 149 150 if s == nil { // embedded structs have a nil name. 151 return "" 152 } 153 r := decode_reloc(s, 0) // s has a pointer to the string data at offset 0 154 if r == nil { // shouldn't happen. 155 return "" 156 } 157 return cstring(r.Sym.P[r.Add:]) 158 } 159 160 func decodetype_structfieldtype(s *LSym, i int) *LSym { 161 return decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize)+int32(i)*int32(structfieldsize())+2*int32(Thearch.Ptrsize)) 162 } 163 164 func decodetype_structfieldoffs(s *LSym, i int) int64 { 165 return int64(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize+2*Thearch.Intsize+i*structfieldsize()+4*Thearch.Ptrsize:], Thearch.Intsize)) 166 } 167 168 // InterfaceType.methods.length 169 func decodetype_ifacemethodcount(s *LSym) int64 { 170 return int64(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize:], Thearch.Intsize)) 171 }