github.com/bgentry/go@v0.0.0-20150121062915-6cf5a733d54d/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  }