Source file src/cmd/link/internal/sym/symbol.go
1
2
3
4
5 package sym
6
7 import (
8 "cmd/internal/obj"
9 "cmd/internal/objabi"
10 "cmd/internal/sys"
11 "debug/elf"
12 "fmt"
13 "log"
14 )
15
16
17 type Symbol struct {
18 Name string
19 Type SymKind
20 Version int16
21 Attr Attribute
22 Dynid int32
23 Align int32
24 Elfsym int32
25 LocalElfsym int32
26 Value int64
27 Size int64
28 Sub *Symbol
29 Outer *Symbol
30 Gotype *Symbol
31 File string
32 auxinfo *AuxSymbol
33 Sect *Section
34 FuncInfo *FuncInfo
35 Lib *Library
36
37 P []byte
38 R []Reloc
39 }
40
41
42 type AuxSymbol struct {
43 extname string
44 dynimplib string
45 dynimpvers string
46 localentry uint8
47 plt int32
48 got int32
49
50
51
52 elftype elf.SymType
53 }
54
55 const (
56 SymVerABI0 = 0
57 SymVerABIInternal = 1
58 SymVerStatic = 10
59 )
60
61 func ABIToVersion(abi obj.ABI) int {
62 switch abi {
63 case obj.ABI0:
64 return SymVerABI0
65 case obj.ABIInternal:
66 return SymVerABIInternal
67 }
68 return -1
69 }
70
71 func VersionToABI(v int) (obj.ABI, bool) {
72 switch v {
73 case SymVerABI0:
74 return obj.ABI0, true
75 case SymVerABIInternal:
76 return obj.ABIInternal, true
77 }
78 return ^obj.ABI(0), false
79 }
80
81 func (s *Symbol) String() string {
82 if s.Version == 0 {
83 return s.Name
84 }
85 return fmt.Sprintf("%s<%d>", s.Name, s.Version)
86 }
87
88 func (s *Symbol) IsFileLocal() bool {
89 return s.Version >= SymVerStatic
90 }
91
92 func (s *Symbol) ElfsymForReloc() int32 {
93
94
95 if s.LocalElfsym != 0 {
96 return s.LocalElfsym
97 } else {
98 return s.Elfsym
99 }
100 }
101
102 func (s *Symbol) Len() int64 {
103 return s.Size
104 }
105
106 func (s *Symbol) Grow(siz int64) {
107 if int64(int(siz)) != siz {
108 log.Fatalf("symgrow size %d too long", siz)
109 }
110 if int64(len(s.P)) >= siz {
111 return
112 }
113 if cap(s.P) < int(siz) {
114 p := make([]byte, 2*(siz+1))
115 s.P = append(p[:0], s.P...)
116 }
117 s.P = s.P[:siz]
118 }
119
120 func (s *Symbol) AddBytes(bytes []byte) int64 {
121 if s.Type == 0 {
122 s.Type = SDATA
123 }
124 s.Attr |= AttrReachable
125 s.P = append(s.P, bytes...)
126 s.Size = int64(len(s.P))
127
128 return s.Size
129 }
130
131 func (s *Symbol) AddUint8(v uint8) int64 {
132 off := s.Size
133 if s.Type == 0 {
134 s.Type = SDATA
135 }
136 s.Attr |= AttrReachable
137 s.Size++
138 s.P = append(s.P, v)
139
140 return off
141 }
142
143 func (s *Symbol) AddUint16(arch *sys.Arch, v uint16) int64 {
144 return s.AddUintXX(arch, uint64(v), 2)
145 }
146
147 func (s *Symbol) AddUint32(arch *sys.Arch, v uint32) int64 {
148 return s.AddUintXX(arch, uint64(v), 4)
149 }
150
151 func (s *Symbol) AddUint64(arch *sys.Arch, v uint64) int64 {
152 return s.AddUintXX(arch, v, 8)
153 }
154
155 func (s *Symbol) AddUint(arch *sys.Arch, v uint64) int64 {
156 return s.AddUintXX(arch, v, arch.PtrSize)
157 }
158
159 func (s *Symbol) SetUint8(arch *sys.Arch, r int64, v uint8) int64 {
160 return s.setUintXX(arch, r, uint64(v), 1)
161 }
162
163 func (s *Symbol) SetUint16(arch *sys.Arch, r int64, v uint16) int64 {
164 return s.setUintXX(arch, r, uint64(v), 2)
165 }
166
167 func (s *Symbol) SetUint32(arch *sys.Arch, r int64, v uint32) int64 {
168 return s.setUintXX(arch, r, uint64(v), 4)
169 }
170
171 func (s *Symbol) SetUint(arch *sys.Arch, r int64, v uint64) int64 {
172 return s.setUintXX(arch, r, v, int64(arch.PtrSize))
173 }
174
175 func (s *Symbol) addAddrPlus(arch *sys.Arch, t *Symbol, add int64, typ objabi.RelocType) int64 {
176 if s.Type == 0 {
177 s.Type = SDATA
178 }
179 s.Attr |= AttrReachable
180 i := s.Size
181 s.Size += int64(arch.PtrSize)
182 s.Grow(s.Size)
183 r := s.AddRel()
184 r.Sym = t
185 r.Off = int32(i)
186 r.Siz = uint8(arch.PtrSize)
187 r.Type = typ
188 r.Add = add
189 return i + int64(r.Siz)
190 }
191
192 func (s *Symbol) AddAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
193 return s.addAddrPlus(arch, t, add, objabi.R_ADDR)
194 }
195
196 func (s *Symbol) AddCURelativeAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
197 return s.addAddrPlus(arch, t, add, objabi.R_ADDRCUOFF)
198 }
199
200 func (s *Symbol) AddPCRelPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
201 if s.Type == 0 {
202 s.Type = SDATA
203 }
204 s.Attr |= AttrReachable
205 i := s.Size
206 s.Size += 4
207 s.Grow(s.Size)
208 r := s.AddRel()
209 r.Sym = t
210 r.Off = int32(i)
211 r.Add = add
212 r.Type = objabi.R_PCREL
213 r.Siz = 4
214 if arch.Family == sys.S390X || arch.Family == sys.PPC64 {
215 r.InitExt()
216 }
217 if arch.Family == sys.S390X {
218 r.Variant = RV_390_DBL
219 }
220 return i + int64(r.Siz)
221 }
222
223 func (s *Symbol) AddAddr(arch *sys.Arch, t *Symbol) int64 {
224 return s.AddAddrPlus(arch, t, 0)
225 }
226
227 func (s *Symbol) SetAddrPlus(arch *sys.Arch, off int64, t *Symbol, add int64) int64 {
228 if s.Type == 0 {
229 s.Type = SDATA
230 }
231 s.Attr |= AttrReachable
232 if off+int64(arch.PtrSize) > s.Size {
233 s.Size = off + int64(arch.PtrSize)
234 s.Grow(s.Size)
235 }
236
237 r := s.AddRel()
238 r.Sym = t
239 r.Off = int32(off)
240 r.Siz = uint8(arch.PtrSize)
241 r.Type = objabi.R_ADDR
242 r.Add = add
243 return off + int64(r.Siz)
244 }
245
246 func (s *Symbol) SetAddr(arch *sys.Arch, off int64, t *Symbol) int64 {
247 return s.SetAddrPlus(arch, off, t, 0)
248 }
249
250 func (s *Symbol) AddSize(arch *sys.Arch, t *Symbol) int64 {
251 if s.Type == 0 {
252 s.Type = SDATA
253 }
254 s.Attr |= AttrReachable
255 i := s.Size
256 s.Size += int64(arch.PtrSize)
257 s.Grow(s.Size)
258 r := s.AddRel()
259 r.Sym = t
260 r.Off = int32(i)
261 r.Siz = uint8(arch.PtrSize)
262 r.Type = objabi.R_SIZE
263 return i + int64(r.Siz)
264 }
265
266 func (s *Symbol) AddAddrPlus4(t *Symbol, add int64) int64 {
267 if s.Type == 0 {
268 s.Type = SDATA
269 }
270 s.Attr |= AttrReachable
271 i := s.Size
272 s.Size += 4
273 s.Grow(s.Size)
274 r := s.AddRel()
275 r.Sym = t
276 r.Off = int32(i)
277 r.Siz = 4
278 r.Type = objabi.R_ADDR
279 r.Add = add
280 return i + int64(r.Siz)
281 }
282
283 func (s *Symbol) AddRel() *Reloc {
284 s.R = append(s.R, Reloc{})
285 return &s.R[len(s.R)-1]
286 }
287
288 func (s *Symbol) AddUintXX(arch *sys.Arch, v uint64, wid int) int64 {
289 off := s.Size
290 s.setUintXX(arch, off, v, int64(wid))
291 return off
292 }
293
294 func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64 {
295 if s.Type == 0 {
296 s.Type = SDATA
297 }
298 s.Attr |= AttrReachable
299 if s.Size < off+wid {
300 s.Size = off + wid
301 s.Grow(s.Size)
302 }
303
304 switch wid {
305 case 1:
306 s.P[off] = uint8(v)
307 case 2:
308 arch.ByteOrder.PutUint16(s.P[off:], uint16(v))
309 case 4:
310 arch.ByteOrder.PutUint32(s.P[off:], uint32(v))
311 case 8:
312 arch.ByteOrder.PutUint64(s.P[off:], v)
313 }
314
315 return off + wid
316 }
317
318 func (s *Symbol) makeAuxInfo() {
319 if s.auxinfo == nil {
320 s.auxinfo = &AuxSymbol{extname: s.Name, plt: -1, got: -1}
321 }
322 }
323
324 func (s *Symbol) Extname() string {
325 if s.auxinfo == nil {
326 return s.Name
327 }
328 return s.auxinfo.extname
329 }
330
331 func (s *Symbol) SetExtname(n string) {
332 if s.auxinfo == nil {
333 if s.Name == n {
334 return
335 }
336 s.makeAuxInfo()
337 }
338 s.auxinfo.extname = n
339 }
340
341 func (s *Symbol) Dynimplib() string {
342 if s.auxinfo == nil {
343 return ""
344 }
345 return s.auxinfo.dynimplib
346 }
347
348 func (s *Symbol) Dynimpvers() string {
349 if s.auxinfo == nil {
350 return ""
351 }
352 return s.auxinfo.dynimpvers
353 }
354
355 func (s *Symbol) SetDynimplib(lib string) {
356 if s.auxinfo == nil {
357 s.makeAuxInfo()
358 }
359 s.auxinfo.dynimplib = lib
360 }
361
362 func (s *Symbol) SetDynimpvers(vers string) {
363 if s.auxinfo == nil {
364 s.makeAuxInfo()
365 }
366 s.auxinfo.dynimpvers = vers
367 }
368
369 func (s *Symbol) ResetDyninfo() {
370 if s.auxinfo != nil {
371 s.auxinfo.dynimplib = ""
372 s.auxinfo.dynimpvers = ""
373 }
374 }
375
376 func (s *Symbol) Localentry() uint8 {
377 if s.auxinfo == nil {
378 return 0
379 }
380 return s.auxinfo.localentry
381 }
382
383 func (s *Symbol) SetLocalentry(val uint8) {
384 if s.auxinfo == nil {
385 if val != 0 {
386 return
387 }
388 s.makeAuxInfo()
389 }
390 s.auxinfo.localentry = val
391 }
392
393 func (s *Symbol) Plt() int32 {
394 if s.auxinfo == nil {
395 return -1
396 }
397 return s.auxinfo.plt
398 }
399
400 func (s *Symbol) SetPlt(val int32) {
401 if s.auxinfo == nil {
402 if val == -1 {
403 return
404 }
405 s.makeAuxInfo()
406 }
407 s.auxinfo.plt = val
408 }
409
410 func (s *Symbol) Got() int32 {
411 if s.auxinfo == nil {
412 return -1
413 }
414 return s.auxinfo.got
415 }
416
417 func (s *Symbol) SetGot(val int32) {
418 if s.auxinfo == nil {
419 if val == -1 {
420 return
421 }
422 s.makeAuxInfo()
423 }
424 s.auxinfo.got = val
425 }
426
427 func (s *Symbol) ElfType() elf.SymType {
428 if s.auxinfo == nil {
429 return elf.STT_NOTYPE
430 }
431 return s.auxinfo.elftype
432 }
433
434 func (s *Symbol) SetElfType(val elf.SymType) {
435 if s.auxinfo == nil {
436 if val == elf.STT_NOTYPE {
437 return
438 }
439 s.makeAuxInfo()
440 }
441 s.auxinfo.elftype = val
442 }
443
444
445
446 func SortSub(l *Symbol) *Symbol {
447 if l == nil || l.Sub == nil {
448 return l
449 }
450
451 l1 := l
452 l2 := l
453 for {
454 l2 = l2.Sub
455 if l2 == nil {
456 break
457 }
458 l2 = l2.Sub
459 if l2 == nil {
460 break
461 }
462 l1 = l1.Sub
463 }
464
465 l2 = l1.Sub
466 l1.Sub = nil
467 l1 = SortSub(l)
468 l2 = SortSub(l2)
469
470
471 if l1.Value < l2.Value {
472 l = l1
473 l1 = l1.Sub
474 } else {
475 l = l2
476 l2 = l2.Sub
477 }
478
479 le := l
480
481 for {
482 if l1 == nil {
483 for l2 != nil {
484 le.Sub = l2
485 le = l2
486 l2 = l2.Sub
487 }
488
489 le.Sub = nil
490 break
491 }
492
493 if l2 == nil {
494 for l1 != nil {
495 le.Sub = l1
496 le = l1
497 l1 = l1.Sub
498 }
499
500 break
501 }
502
503 if l1.Value < l2.Value {
504 le.Sub = l1
505 le = l1
506 l1 = l1.Sub
507 } else {
508 le.Sub = l2
509 le = l2
510 l2 = l2.Sub
511 }
512 }
513
514 le.Sub = nil
515 return l
516 }
517
518 type FuncInfo struct {
519 Args int32
520 Locals int32
521 Autom []Auto
522 Pcsp Pcdata
523 Pcfile Pcdata
524 Pcline Pcdata
525 Pcinline Pcdata
526 Pcdata []Pcdata
527 Funcdata []*Symbol
528 Funcdataoff []int64
529 File []*Symbol
530 InlTree []InlinedCall
531 }
532
533
534 type InlinedCall struct {
535 Parent int32
536 File *Symbol
537 Line int32
538 Func *Symbol
539 ParentPC int32
540 }
541
542 type Pcdata struct {
543 P []byte
544 }
545
546 type Auto struct {
547 Asym *Symbol
548 Gotype *Symbol
549 Aoffset int32
550 Name int16
551 }
552
View as plain text