-
Notifications
You must be signed in to change notification settings - Fork 0
/
decodesym.go
183 lines (151 loc) · 5.16 KB
/
decodesym.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Do not edit. Bootstrap copy of /Users/rsc/g/go/src/cmd/internal/ld/decodesym.go
// 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.
package ld
import "rsc.io/tmp/bootstrap/internal/obj"
// Decoding the type.* symbols. This has to be in sync with
// ../../runtime/type.go, or more specifically, with what
// ../gc/reflect.c stuffs in these.
func decode_reloc(s *LSym, off int32) *Reloc {
for i := 0; i < len(s.R); i++ {
if s.R[i].Off == off {
return &s.R[i:][0]
}
}
return nil
}
func decode_reloc_sym(s *LSym, off int32) *LSym {
r := decode_reloc(s, off)
if r == nil {
return nil
}
return r.Sym
}
func decode_inuxi(p []byte, sz int) uint64 {
switch sz {
case 2:
return uint64(Ctxt.Arch.ByteOrder.Uint16(p))
case 4:
return uint64(Ctxt.Arch.ByteOrder.Uint32(p))
case 8:
return Ctxt.Arch.ByteOrder.Uint64(p)
default:
Exitf("dwarf: decode inuxi %d", sz)
panic("unreachable")
}
}
func commonsize() int {
return 8*Thearch.Ptrsize + 8
}
// Type.commonType.kind
func decodetype_kind(s *LSym) uint8 {
return uint8(s.P[1*Thearch.Ptrsize+7] & obj.KindMask) // 0x13 / 0x1f
}
// Type.commonType.kind
func decodetype_noptr(s *LSym) uint8 {
return uint8(s.P[1*Thearch.Ptrsize+7] & obj.KindNoPointers) // 0x13 / 0x1f
}
// Type.commonType.kind
func decodetype_usegcprog(s *LSym) uint8 {
return uint8(s.P[1*Thearch.Ptrsize+7] & obj.KindGCProg) // 0x13 / 0x1f
}
// Type.commonType.size
func decodetype_size(s *LSym) int64 {
return int64(decode_inuxi(s.P, Thearch.Ptrsize)) // 0x8 / 0x10
}
// Type.commonType.gc
func decodetype_gcprog(s *LSym) *LSym {
if s.Type == obj.SDYNIMPORT {
// The gcprog for "type.$name" is calle "type..gcprog.$name".
x := "type..gcprog." + s.Name[5:]
return Linklookup(Ctxt, x, 0)
}
return decode_reloc_sym(s, 1*int32(Thearch.Ptrsize)+8+2*int32(Thearch.Ptrsize))
}
func decodetype_gcmask(s *LSym) []byte {
if s.Type == obj.SDYNIMPORT {
// ldshlibsyms makes special efforts to read the value
// of gcmask for types defined in that shared library.
return s.gcmask
}
mask := decode_reloc_sym(s, 1*int32(Thearch.Ptrsize)+8+1*int32(Thearch.Ptrsize))
return mask.P
}
// Type.ArrayType.elem and Type.SliceType.Elem
func decodetype_arrayelem(s *LSym) *LSym {
return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30
}
func decodetype_arraylen(s *LSym) int64 {
return int64(decode_inuxi(s.P[commonsize()+2*Thearch.Ptrsize:], Thearch.Ptrsize))
}
// Type.PtrType.elem
func decodetype_ptrelem(s *LSym) *LSym {
return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30
}
// Type.MapType.key, elem
func decodetype_mapkey(s *LSym) *LSym {
return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30
}
func decodetype_mapvalue(s *LSym) *LSym {
return decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)) // 0x20 / 0x38
}
// Type.ChanType.elem
func decodetype_chanelem(s *LSym) *LSym {
return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30
}
// Type.FuncType.dotdotdot
func decodetype_funcdotdotdot(s *LSym) int {
return int(s.P[commonsize()])
}
// Type.FuncType.in.length
func decodetype_funcincount(s *LSym) int {
return int(decode_inuxi(s.P[commonsize()+2*Thearch.Ptrsize:], Thearch.Intsize))
}
func decodetype_funcoutcount(s *LSym) int {
return int(decode_inuxi(s.P[commonsize()+3*Thearch.Ptrsize+2*Thearch.Intsize:], Thearch.Intsize))
}
func decodetype_funcintype(s *LSym, i int) *LSym {
r := decode_reloc(s, int32(commonsize())+int32(Thearch.Ptrsize))
if r == nil {
return nil
}
return decode_reloc_sym(r.Sym, int32(r.Add+int64(int32(i)*int32(Thearch.Ptrsize))))
}
func decodetype_funcouttype(s *LSym, i int) *LSym {
r := decode_reloc(s, int32(commonsize())+2*int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize))
if r == nil {
return nil
}
return decode_reloc_sym(r.Sym, int32(r.Add+int64(int32(i)*int32(Thearch.Ptrsize))))
}
// Type.StructType.fields.Slice::length
func decodetype_structfieldcount(s *LSym) int {
return int(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize:], Thearch.Intsize))
}
func structfieldsize() int {
return 5 * Thearch.Ptrsize
}
// Type.StructType.fields[]-> name, typ and offset.
func decodetype_structfieldname(s *LSym, i int) string {
// go.string."foo" 0x28 / 0x40
s = decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize)+int32(i)*int32(structfieldsize()))
if s == nil { // embedded structs have a nil name.
return ""
}
r := decode_reloc(s, 0) // s has a pointer to the string data at offset 0
if r == nil { // shouldn't happen.
return ""
}
return cstring(r.Sym.P[r.Add:])
}
func decodetype_structfieldtype(s *LSym, i int) *LSym {
return decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize)+int32(i)*int32(structfieldsize())+2*int32(Thearch.Ptrsize))
}
func decodetype_structfieldoffs(s *LSym, i int) int64 {
return int64(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize+2*Thearch.Intsize+i*structfieldsize()+4*Thearch.Ptrsize:], Thearch.Intsize))
}
// InterfaceType.methods.length
func decodetype_ifacemethodcount(s *LSym) int64 {
return int64(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize:], Thearch.Intsize))
}