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  }