github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/src/cmd/ld/decodesym.c (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 #include "l.h" 6 #include "lib.h" 7 #include "../../runtime/typekind.h" 8 9 // Decoding the type.* symbols. This has to be in sync with 10 // ../../runtime/type.go, or more specificaly, with what 11 // ../gc/reflect.c stuffs in these. 12 13 static Reloc* 14 decode_reloc(LSym *s, int32 off) 15 { 16 int i; 17 18 for (i = 0; i < s->nr; i++) 19 if (s->r[i].off == off) 20 return s->r + i; 21 return nil; 22 } 23 24 static LSym* 25 decode_reloc_sym(LSym *s, int32 off) 26 { 27 Reloc *r; 28 29 r = decode_reloc(s,off); 30 if (r == nil) 31 return nil; 32 return r->sym; 33 } 34 35 static uvlong 36 decode_inuxi(uchar* p, int sz) 37 { 38 uint64 v; 39 uint32 l; 40 uchar *cast, *inuxi; 41 int i; 42 43 v = l = 0; 44 cast = nil; 45 inuxi = nil; 46 switch (sz) { 47 case 2: 48 cast = (uchar*)&l; 49 inuxi = inuxi2; 50 break; 51 case 4: 52 cast = (uchar*)&l; 53 inuxi = inuxi4; 54 break; 55 case 8: 56 cast = (uchar*)&v; 57 inuxi = inuxi8; 58 break; 59 default: 60 diag("dwarf: decode inuxi %d", sz); 61 errorexit(); 62 } 63 for (i = 0; i < sz; i++) 64 cast[inuxi[i]] = p[i]; 65 if (sz == 8) 66 return v; 67 return l; 68 } 69 70 static int 71 commonsize(void) 72 { 73 return 8*PtrSize + 8; 74 } 75 76 // Type.commonType.kind 77 uint8 78 decodetype_kind(LSym *s) 79 { 80 return s->p[1*PtrSize + 7] & KindMask; // 0x13 / 0x1f 81 } 82 83 // Type.commonType.kind 84 uint8 85 decodetype_noptr(LSym *s) 86 { 87 return s->p[1*PtrSize + 7] & KindNoPointers; // 0x13 / 0x1f 88 } 89 90 // Type.commonType.kind 91 uint8 92 decodetype_usegcprog(LSym *s) 93 { 94 return s->p[1*PtrSize + 7] & KindGCProg; // 0x13 / 0x1f 95 } 96 97 // Type.commonType.size 98 vlong 99 decodetype_size(LSym *s) 100 { 101 return decode_inuxi(s->p, PtrSize); // 0x8 / 0x10 102 } 103 104 // Type.commonType.gc 105 LSym* 106 decodetype_gcprog(LSym *s) 107 { 108 return decode_reloc_sym(s, 1*PtrSize + 8 + 2*PtrSize); 109 } 110 111 uint8* 112 decodetype_gcmask(LSym *s) 113 { 114 LSym *mask; 115 116 mask = decode_reloc_sym(s, 1*PtrSize + 8 + 1*PtrSize); 117 return mask->p; 118 } 119 120 // Type.ArrayType.elem and Type.SliceType.Elem 121 LSym* 122 decodetype_arrayelem(LSym *s) 123 { 124 return decode_reloc_sym(s, commonsize()); // 0x1c / 0x30 125 } 126 127 vlong 128 decodetype_arraylen(LSym *s) 129 { 130 return decode_inuxi(s->p + commonsize()+2*PtrSize, PtrSize); 131 } 132 133 // Type.PtrType.elem 134 LSym* 135 decodetype_ptrelem(LSym *s) 136 { 137 return decode_reloc_sym(s, commonsize()); // 0x1c / 0x30 138 } 139 140 // Type.MapType.key, elem 141 LSym* 142 decodetype_mapkey(LSym *s) 143 { 144 return decode_reloc_sym(s, commonsize()); // 0x1c / 0x30 145 } 146 147 LSym* 148 decodetype_mapvalue(LSym *s) 149 { 150 return decode_reloc_sym(s, commonsize()+PtrSize); // 0x20 / 0x38 151 } 152 153 // Type.ChanType.elem 154 LSym* 155 decodetype_chanelem(LSym *s) 156 { 157 return decode_reloc_sym(s, commonsize()); // 0x1c / 0x30 158 } 159 160 // Type.FuncType.dotdotdot 161 int 162 decodetype_funcdotdotdot(LSym *s) 163 { 164 return s->p[commonsize()]; 165 } 166 167 // Type.FuncType.in.len 168 int 169 decodetype_funcincount(LSym *s) 170 { 171 return decode_inuxi(s->p + commonsize()+2*PtrSize, IntSize); 172 } 173 174 int 175 decodetype_funcoutcount(LSym *s) 176 { 177 return decode_inuxi(s->p + commonsize()+3*PtrSize + 2*IntSize, IntSize); 178 } 179 180 LSym* 181 decodetype_funcintype(LSym *s, int i) 182 { 183 Reloc *r; 184 185 r = decode_reloc(s, commonsize() + PtrSize); 186 if (r == nil) 187 return nil; 188 return decode_reloc_sym(r->sym, r->add + i * PtrSize); 189 } 190 191 LSym* 192 decodetype_funcouttype(LSym *s, int i) 193 { 194 Reloc *r; 195 196 r = decode_reloc(s, commonsize() + 2*PtrSize + 2*IntSize); 197 if (r == nil) 198 return nil; 199 return decode_reloc_sym(r->sym, r->add + i * PtrSize); 200 } 201 202 // Type.StructType.fields.Slice::len 203 int 204 decodetype_structfieldcount(LSym *s) 205 { 206 return decode_inuxi(s->p + commonsize() + PtrSize, IntSize); 207 } 208 209 static int 210 structfieldsize(void) 211 { 212 return 5*PtrSize; 213 } 214 215 // Type.StructType.fields[]-> name, typ and offset. 216 char* 217 decodetype_structfieldname(LSym *s, int i) 218 { 219 Reloc *r; 220 221 // go.string."foo" 0x28 / 0x40 222 s = decode_reloc_sym(s, commonsize() + PtrSize + 2*IntSize + i*structfieldsize()); 223 if (s == nil) // embedded structs have a nil name. 224 return nil; 225 r = decode_reloc(s, 0); // s has a pointer to the string data at offset 0 226 if (r == nil) // shouldn't happen. 227 return nil; 228 return (char*) r->sym->p + r->add; // the c-string 229 } 230 231 LSym* 232 decodetype_structfieldtype(LSym *s, int i) 233 { 234 return decode_reloc_sym(s, commonsize() + PtrSize + 2*IntSize + i*structfieldsize() + 2*PtrSize); 235 } 236 237 vlong 238 decodetype_structfieldoffs(LSym *s, int i) 239 { 240 return decode_inuxi(s->p + commonsize() + PtrSize + 2*IntSize + i*structfieldsize() + 4*PtrSize, IntSize); 241 } 242 243 // InterfaceTYpe.methods.len 244 vlong 245 decodetype_ifacemethodcount(LSym *s) 246 { 247 return decode_inuxi(s->p + commonsize() + PtrSize, IntSize); 248 }