mirror of https://github.com/golang/go.git
216 lines
3.9 KiB
C
216 lines
3.9 KiB
C
// Copyright 2012 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
#include "l.h"
|
|
#include "lib.h"
|
|
#include "../../pkg/runtime/typekind.h"
|
|
|
|
// Decoding the type.* symbols. This has to be in sync with
|
|
// ../../pkg/runtime/type.go, or more specificaly, with what
|
|
// ../gc/reflect.c stuffs in these.
|
|
|
|
static Reloc*
|
|
decode_reloc(LSym *s, int32 off)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < s->nr; i++)
|
|
if (s->r[i].off == off)
|
|
return s->r + i;
|
|
return nil;
|
|
}
|
|
|
|
static LSym*
|
|
decode_reloc_sym(LSym *s, int32 off)
|
|
{
|
|
Reloc *r;
|
|
|
|
r = decode_reloc(s,off);
|
|
if (r == nil)
|
|
return nil;
|
|
return r->sym;
|
|
}
|
|
|
|
static uvlong
|
|
decode_inuxi(uchar* p, int sz)
|
|
{
|
|
uint64 v;
|
|
uint32 l;
|
|
uchar *cast, *inuxi;
|
|
int i;
|
|
|
|
v = l = 0;
|
|
cast = nil;
|
|
inuxi = nil;
|
|
switch (sz) {
|
|
case 2:
|
|
cast = (uchar*)&l;
|
|
inuxi = inuxi2;
|
|
break;
|
|
case 4:
|
|
cast = (uchar*)&l;
|
|
inuxi = inuxi4;
|
|
break;
|
|
case 8:
|
|
cast = (uchar*)&v;
|
|
inuxi = inuxi8;
|
|
break;
|
|
default:
|
|
diag("dwarf: decode inuxi %d", sz);
|
|
errorexit();
|
|
}
|
|
for (i = 0; i < sz; i++)
|
|
cast[inuxi[i]] = p[i];
|
|
if (sz == 8)
|
|
return v;
|
|
return l;
|
|
}
|
|
|
|
// Type.commonType.kind
|
|
uint8
|
|
decodetype_kind(LSym *s)
|
|
{
|
|
return s->p[1*PtrSize + 7] & ~KindNoPointers; // 0x13 / 0x1f
|
|
}
|
|
|
|
// Type.commonType.size
|
|
vlong
|
|
decodetype_size(LSym *s)
|
|
{
|
|
return decode_inuxi(s->p, PtrSize); // 0x8 / 0x10
|
|
}
|
|
|
|
// Type.commonType.gc
|
|
LSym*
|
|
decodetype_gc(LSym *s)
|
|
{
|
|
return decode_reloc_sym(s, 1*PtrSize + 8 + 1*PtrSize);
|
|
}
|
|
|
|
// Type.ArrayType.elem and Type.SliceType.Elem
|
|
LSym*
|
|
decodetype_arrayelem(LSym *s)
|
|
{
|
|
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
|
|
}
|
|
|
|
vlong
|
|
decodetype_arraylen(LSym *s)
|
|
{
|
|
return decode_inuxi(s->p + CommonSize+PtrSize, PtrSize);
|
|
}
|
|
|
|
// Type.PtrType.elem
|
|
LSym*
|
|
decodetype_ptrelem(LSym *s)
|
|
{
|
|
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
|
|
}
|
|
|
|
// Type.MapType.key, elem
|
|
LSym*
|
|
decodetype_mapkey(LSym *s)
|
|
{
|
|
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
|
|
}
|
|
LSym*
|
|
decodetype_mapvalue(LSym *s)
|
|
{
|
|
return decode_reloc_sym(s, CommonSize+PtrSize); // 0x20 / 0x38
|
|
}
|
|
|
|
// Type.ChanType.elem
|
|
LSym*
|
|
decodetype_chanelem(LSym *s)
|
|
{
|
|
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
|
|
}
|
|
|
|
// Type.FuncType.dotdotdot
|
|
int
|
|
decodetype_funcdotdotdot(LSym *s)
|
|
{
|
|
return s->p[CommonSize];
|
|
}
|
|
|
|
// Type.FuncType.in.len
|
|
int
|
|
decodetype_funcincount(LSym *s)
|
|
{
|
|
return decode_inuxi(s->p + CommonSize+2*PtrSize, IntSize);
|
|
}
|
|
|
|
int
|
|
decodetype_funcoutcount(LSym *s)
|
|
{
|
|
return decode_inuxi(s->p + CommonSize+3*PtrSize + 2*IntSize, IntSize);
|
|
}
|
|
|
|
LSym*
|
|
decodetype_funcintype(LSym *s, int i)
|
|
{
|
|
Reloc *r;
|
|
|
|
r = decode_reloc(s, CommonSize + PtrSize);
|
|
if (r == nil)
|
|
return nil;
|
|
return decode_reloc_sym(r->sym, r->add + i * PtrSize);
|
|
}
|
|
|
|
LSym*
|
|
decodetype_funcouttype(LSym *s, int i)
|
|
{
|
|
Reloc *r;
|
|
|
|
r = decode_reloc(s, CommonSize + 2*PtrSize + 2*IntSize);
|
|
if (r == nil)
|
|
return nil;
|
|
return decode_reloc_sym(r->sym, r->add + i * PtrSize);
|
|
}
|
|
|
|
// Type.StructType.fields.Slice::len
|
|
int
|
|
decodetype_structfieldcount(LSym *s)
|
|
{
|
|
return decode_inuxi(s->p + CommonSize + PtrSize, IntSize);
|
|
}
|
|
|
|
enum {
|
|
StructFieldSize = 5*PtrSize
|
|
};
|
|
// Type.StructType.fields[]-> name, typ and offset.
|
|
char*
|
|
decodetype_structfieldname(LSym *s, int i)
|
|
{
|
|
Reloc *r;
|
|
|
|
// go.string."foo" 0x28 / 0x40
|
|
s = decode_reloc_sym(s, CommonSize + PtrSize + 2*IntSize + i*StructFieldSize);
|
|
if (s == nil) // embedded structs have a nil name.
|
|
return nil;
|
|
r = decode_reloc(s, 0); // s has a pointer to the string data at offset 0
|
|
if (r == nil) // shouldn't happen.
|
|
return nil;
|
|
return (char*) r->sym->p + r->add; // the c-string
|
|
}
|
|
|
|
LSym*
|
|
decodetype_structfieldtype(LSym *s, int i)
|
|
{
|
|
return decode_reloc_sym(s, CommonSize + PtrSize + 2*IntSize + i*StructFieldSize + 2*PtrSize);
|
|
}
|
|
|
|
vlong
|
|
decodetype_structfieldoffs(LSym *s, int i)
|
|
{
|
|
return decode_inuxi(s->p + CommonSize + PtrSize + 2*IntSize + i*StructFieldSize + 4*PtrSize, IntSize);
|
|
}
|
|
|
|
// InterfaceTYpe.methods.len
|
|
vlong
|
|
decodetype_ifacemethodcount(LSym *s)
|
|
{
|
|
return decode_inuxi(s->p + CommonSize + PtrSize, IntSize);
|
|
}
|