github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/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 "../../pkg/runtime/typekind.h" 8 9 // Decoding the type.* symbols. This has to be in sync with 10 // ../../pkg/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 7*PtrSize + 8; 74 } 75 76 // Type.commonType.kind 77 uint8 78 decodetype_kind(LSym *s) 79 { 80 return s->p[1*PtrSize + 7] & ~KindNoPointers; // 0x13 / 0x1f 81 } 82 83 // Type.commonType.size 84 vlong 85 decodetype_size(LSym *s) 86 { 87 return decode_inuxi(s->p, PtrSize); // 0x8 / 0x10 88 } 89 90 // Type.commonType.gc 91 LSym* 92 decodetype_gc(LSym *s) 93 { 94 return decode_reloc_sym(s, 1*PtrSize + 8 + 1*PtrSize); 95 } 96 97 // Type.ArrayType.elem and Type.SliceType.Elem 98 LSym* 99 decodetype_arrayelem(LSym *s) 100 { 101 return decode_reloc_sym(s, commonsize()); // 0x1c / 0x30 102 } 103 104 vlong 105 decodetype_arraylen(LSym *s) 106 { 107 return decode_inuxi(s->p + commonsize()+PtrSize, PtrSize); 108 } 109 110 // Type.PtrType.elem 111 LSym* 112 decodetype_ptrelem(LSym *s) 113 { 114 return decode_reloc_sym(s, commonsize()); // 0x1c / 0x30 115 } 116 117 // Type.MapType.key, elem 118 LSym* 119 decodetype_mapkey(LSym *s) 120 { 121 return decode_reloc_sym(s, commonsize()); // 0x1c / 0x30 122 } 123 LSym* 124 decodetype_mapvalue(LSym *s) 125 { 126 return decode_reloc_sym(s, commonsize()+PtrSize); // 0x20 / 0x38 127 } 128 129 // Type.ChanType.elem 130 LSym* 131 decodetype_chanelem(LSym *s) 132 { 133 return decode_reloc_sym(s, commonsize()); // 0x1c / 0x30 134 } 135 136 // Type.FuncType.dotdotdot 137 int 138 decodetype_funcdotdotdot(LSym *s) 139 { 140 return s->p[commonsize()]; 141 } 142 143 // Type.FuncType.in.len 144 int 145 decodetype_funcincount(LSym *s) 146 { 147 return decode_inuxi(s->p + commonsize()+2*PtrSize, IntSize); 148 } 149 150 int 151 decodetype_funcoutcount(LSym *s) 152 { 153 return decode_inuxi(s->p + commonsize()+3*PtrSize + 2*IntSize, IntSize); 154 } 155 156 LSym* 157 decodetype_funcintype(LSym *s, int i) 158 { 159 Reloc *r; 160 161 r = decode_reloc(s, commonsize() + PtrSize); 162 if (r == nil) 163 return nil; 164 return decode_reloc_sym(r->sym, r->add + i * PtrSize); 165 } 166 167 LSym* 168 decodetype_funcouttype(LSym *s, int i) 169 { 170 Reloc *r; 171 172 r = decode_reloc(s, commonsize() + 2*PtrSize + 2*IntSize); 173 if (r == nil) 174 return nil; 175 return decode_reloc_sym(r->sym, r->add + i * PtrSize); 176 } 177 178 // Type.StructType.fields.Slice::len 179 int 180 decodetype_structfieldcount(LSym *s) 181 { 182 return decode_inuxi(s->p + commonsize() + PtrSize, IntSize); 183 } 184 185 static int 186 structfieldsize(void) 187 { 188 return 5*PtrSize; 189 } 190 191 // Type.StructType.fields[]-> name, typ and offset. 192 char* 193 decodetype_structfieldname(LSym *s, int i) 194 { 195 Reloc *r; 196 197 // go.string."foo" 0x28 / 0x40 198 s = decode_reloc_sym(s, commonsize() + PtrSize + 2*IntSize + i*structfieldsize()); 199 if (s == nil) // embedded structs have a nil name. 200 return nil; 201 r = decode_reloc(s, 0); // s has a pointer to the string data at offset 0 202 if (r == nil) // shouldn't happen. 203 return nil; 204 return (char*) r->sym->p + r->add; // the c-string 205 } 206 207 LSym* 208 decodetype_structfieldtype(LSym *s, int i) 209 { 210 return decode_reloc_sym(s, commonsize() + PtrSize + 2*IntSize + i*structfieldsize() + 2*PtrSize); 211 } 212 213 vlong 214 decodetype_structfieldoffs(LSym *s, int i) 215 { 216 return decode_inuxi(s->p + commonsize() + PtrSize + 2*IntSize + i*structfieldsize() + 4*PtrSize, IntSize); 217 } 218 219 // InterfaceTYpe.methods.len 220 vlong 221 decodetype_ifacemethodcount(LSym *s) 222 { 223 return decode_inuxi(s->p + commonsize() + PtrSize, IntSize); 224 }