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