1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package goobj
20
21 import (
22 "cmd/internal/bio"
23 "encoding/binary"
24 "errors"
25 "fmt"
26 "unsafe"
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 const stringRefSize = 8
168
169 type FingerprintType [8]byte
170
171 func (fp FingerprintType) IsZero() bool { return fp == FingerprintType{} }
172
173
174 const (
175 PkgIdxNone = (1<<31 - 1) - iota
176 PkgIdxHashed64
177 PkgIdxHashed
178 PkgIdxBuiltin
179 PkgIdxSelf
180 PkgIdxSpecial = PkgIdxSelf
181 PkgIdxInvalid = 0
182
183 )
184
185
186 const (
187 BlkAutolib = iota
188 BlkPkgIdx
189 BlkFile
190 BlkSymdef
191 BlkHashed64def
192 BlkHasheddef
193 BlkNonpkgdef
194 BlkNonpkgref
195 BlkRefFlags
196 BlkHash64
197 BlkHash
198 BlkRelocIdx
199 BlkAuxIdx
200 BlkDataIdx
201 BlkReloc
202 BlkAux
203 BlkData
204 BlkRefName
205 BlkEnd
206 NBlk
207 )
208
209
210
211 type Header struct {
212 Magic string
213 Fingerprint FingerprintType
214 Flags uint32
215 Offsets [NBlk]uint32
216 }
217
218 const Magic = "\x00go120ld"
219
220 func (h *Header) Write(w *Writer) {
221 w.RawString(h.Magic)
222 w.Bytes(h.Fingerprint[:])
223 w.Uint32(h.Flags)
224 for _, x := range h.Offsets {
225 w.Uint32(x)
226 }
227 }
228
229 func (h *Header) Read(r *Reader) error {
230 b := r.BytesAt(0, len(Magic))
231 h.Magic = string(b)
232 if h.Magic != Magic {
233 return errors.New("wrong magic, not a Go object file")
234 }
235 off := uint32(len(h.Magic))
236 copy(h.Fingerprint[:], r.BytesAt(off, len(h.Fingerprint)))
237 off += 8
238 h.Flags = r.uint32At(off)
239 off += 4
240 for i := range h.Offsets {
241 h.Offsets[i] = r.uint32At(off)
242 off += 4
243 }
244 return nil
245 }
246
247 func (h *Header) Size() int {
248 return len(h.Magic) + len(h.Fingerprint) + 4 + 4*len(h.Offsets)
249 }
250
251
252 type ImportedPkg struct {
253 Pkg string
254 Fingerprint FingerprintType
255 }
256
257 const importedPkgSize = stringRefSize + 8
258
259 func (p *ImportedPkg) Write(w *Writer) {
260 w.StringRef(p.Pkg)
261 w.Bytes(p.Fingerprint[:])
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277 type Sym [SymSize]byte
278
279 const SymSize = stringRefSize + 2 + 1 + 1 + 1 + 4 + 4
280
281 const SymABIstatic = ^uint16(0)
282
283 const (
284 ObjFlagShared = 1 << iota
285 _
286 ObjFlagFromAssembly
287 ObjFlagUnlinkable
288 ObjFlagStd
289 )
290
291
292 const (
293 SymFlagDupok = 1 << iota
294 SymFlagLocal
295 SymFlagTypelink
296 SymFlagLeaf
297 SymFlagNoSplit
298 SymFlagReflectMethod
299 SymFlagGoType
300 SymFlagWeakDef
301 )
302
303
304 const (
305 SymFlagUsedInIface = 1 << iota
306 SymFlagItab
307 SymFlagDict
308 SymFlagPkgInit
309 SymFlagLinkname
310 SymFlagLinknameStd
311 SymFlagABIWrapper
312 SymFlagWasmExport
313 )
314
315
316 func (s *Sym) NameLen(r *Reader) int {
317 return int(binary.LittleEndian.Uint32(s[:]))
318 }
319
320 func (s *Sym) Name(r *Reader) string {
321 len := binary.LittleEndian.Uint32(s[:])
322 off := binary.LittleEndian.Uint32(s[4:])
323 return r.StringAt(off, len)
324 }
325
326 func (s *Sym) ABI() uint16 { return binary.LittleEndian.Uint16(s[8:]) }
327 func (s *Sym) Type() uint8 { return s[10] }
328 func (s *Sym) Flag() uint8 { return s[11] }
329 func (s *Sym) Flag2() uint8 { return s[12] }
330 func (s *Sym) Siz() uint32 { return binary.LittleEndian.Uint32(s[13:]) }
331 func (s *Sym) Align() uint32 { return binary.LittleEndian.Uint32(s[17:]) }
332
333 func (s *Sym) Dupok() bool { return s.Flag()&SymFlagDupok != 0 }
334 func (s *Sym) Local() bool { return s.Flag()&SymFlagLocal != 0 }
335 func (s *Sym) Typelink() bool { return s.Flag()&SymFlagTypelink != 0 }
336 func (s *Sym) Leaf() bool { return s.Flag()&SymFlagLeaf != 0 }
337 func (s *Sym) NoSplit() bool { return s.Flag()&SymFlagNoSplit != 0 }
338 func (s *Sym) ReflectMethod() bool { return s.Flag()&SymFlagReflectMethod != 0 }
339 func (s *Sym) IsGoType() bool { return s.Flag()&SymFlagGoType != 0 }
340 func (s *Sym) WeakDef() bool { return s.Flag()&SymFlagWeakDef != 0 }
341 func (s *Sym) UsedInIface() bool { return s.Flag2()&SymFlagUsedInIface != 0 }
342 func (s *Sym) IsItab() bool { return s.Flag2()&SymFlagItab != 0 }
343 func (s *Sym) IsDict() bool { return s.Flag2()&SymFlagDict != 0 }
344 func (s *Sym) IsPkgInit() bool { return s.Flag2()&SymFlagPkgInit != 0 }
345 func (s *Sym) IsLinkname() bool { return s.Flag2()&SymFlagLinkname != 0 }
346 func (s *Sym) IsLinknameStd() bool { return s.Flag2()&SymFlagLinknameStd != 0 }
347 func (s *Sym) ABIWrapper() bool { return s.Flag2()&SymFlagABIWrapper != 0 }
348 func (s *Sym) WasmExport() bool { return s.Flag2()&SymFlagWasmExport != 0 }
349
350 func (s *Sym) SetName(x string, w *Writer) {
351 binary.LittleEndian.PutUint32(s[:], uint32(len(x)))
352 binary.LittleEndian.PutUint32(s[4:], w.stringOff(x))
353 }
354
355 func (s *Sym) SetABI(x uint16) { binary.LittleEndian.PutUint16(s[8:], x) }
356 func (s *Sym) SetType(x uint8) { s[10] = x }
357 func (s *Sym) SetFlag(x uint8) { s[11] = x }
358 func (s *Sym) SetFlag2(x uint8) { s[12] = x }
359 func (s *Sym) SetSiz(x uint32) { binary.LittleEndian.PutUint32(s[13:], x) }
360 func (s *Sym) SetAlign(x uint32) { binary.LittleEndian.PutUint32(s[17:], x) }
361
362 func (s *Sym) Write(w *Writer) { w.Bytes(s[:]) }
363
364
365 func (s *Sym) fromBytes(b []byte) { copy(s[:], b) }
366
367
368 type SymRef struct {
369 PkgIdx uint32
370 SymIdx uint32
371 }
372
373 func (s SymRef) IsZero() bool { return s == SymRef{} }
374
375
376 type Hash64Type [Hash64Size]byte
377
378 const Hash64Size = 8
379
380
381 type HashType [HashSize]byte
382
383 const HashSize = 16
384
385
386
387
388
389
390
391
392
393
394
395
396 type Reloc [RelocSize]byte
397
398 const RelocSize = 4 + 1 + 2 + 8 + 8
399
400 func (r *Reloc) Off() int32 { return int32(binary.LittleEndian.Uint32(r[:])) }
401 func (r *Reloc) Siz() uint8 { return r[4] }
402 func (r *Reloc) Type() uint16 { return binary.LittleEndian.Uint16(r[5:]) }
403 func (r *Reloc) Add() int64 { return int64(binary.LittleEndian.Uint64(r[7:])) }
404 func (r *Reloc) Sym() SymRef {
405 return SymRef{binary.LittleEndian.Uint32(r[15:]), binary.LittleEndian.Uint32(r[19:])}
406 }
407
408 func (r *Reloc) SetOff(x int32) { binary.LittleEndian.PutUint32(r[:], uint32(x)) }
409 func (r *Reloc) SetSiz(x uint8) { r[4] = x }
410 func (r *Reloc) SetType(x uint16) { binary.LittleEndian.PutUint16(r[5:], x) }
411 func (r *Reloc) SetAdd(x int64) { binary.LittleEndian.PutUint64(r[7:], uint64(x)) }
412 func (r *Reloc) SetSym(x SymRef) {
413 binary.LittleEndian.PutUint32(r[15:], x.PkgIdx)
414 binary.LittleEndian.PutUint32(r[19:], x.SymIdx)
415 }
416
417 func (r *Reloc) Set(off int32, size uint8, typ uint16, add int64, sym SymRef) {
418 r.SetOff(off)
419 r.SetSiz(size)
420 r.SetType(typ)
421 r.SetAdd(add)
422 r.SetSym(sym)
423 }
424
425 func (r *Reloc) Write(w *Writer) { w.Bytes(r[:]) }
426
427
428 func (r *Reloc) fromBytes(b []byte) { copy(r[:], b) }
429
430
431
432
433
434
435
436
437
438 type Aux [AuxSize]byte
439
440 const AuxSize = 1 + 8
441
442
443 const (
444 AuxGotype = iota
445 AuxFuncInfo
446 AuxFuncdata
447 AuxDwarfInfo
448 AuxDwarfLoc
449 AuxDwarfRanges
450 AuxDwarfLines
451 AuxPcsp
452 AuxPcfile
453 AuxPcline
454 AuxPcinline
455 AuxPcdata
456 AuxWasmImport
457 AuxWasmType
458 AuxSehUnwindInfo
459 )
460
461 func (a *Aux) Type() uint8 { return a[0] }
462 func (a *Aux) Sym() SymRef {
463 return SymRef{binary.LittleEndian.Uint32(a[1:]), binary.LittleEndian.Uint32(a[5:])}
464 }
465
466 func (a *Aux) SetType(x uint8) { a[0] = x }
467 func (a *Aux) SetSym(x SymRef) {
468 binary.LittleEndian.PutUint32(a[1:], x.PkgIdx)
469 binary.LittleEndian.PutUint32(a[5:], x.SymIdx)
470 }
471
472 func (a *Aux) Write(w *Writer) { w.Bytes(a[:]) }
473
474
475 func (a *Aux) fromBytes(b []byte) { copy(a[:], b) }
476
477
478
479
480
481
482
483
484
485
486 type RefFlags [RefFlagsSize]byte
487
488 const RefFlagsSize = 8 + 1 + 1
489
490 func (r *RefFlags) Sym() SymRef {
491 return SymRef{binary.LittleEndian.Uint32(r[:]), binary.LittleEndian.Uint32(r[4:])}
492 }
493 func (r *RefFlags) Flag() uint8 { return r[8] }
494 func (r *RefFlags) Flag2() uint8 { return r[9] }
495
496 func (r *RefFlags) SetSym(x SymRef) {
497 binary.LittleEndian.PutUint32(r[:], x.PkgIdx)
498 binary.LittleEndian.PutUint32(r[4:], x.SymIdx)
499 }
500 func (r *RefFlags) SetFlag(x uint8) { r[8] = x }
501 func (r *RefFlags) SetFlag2(x uint8) { r[9] = x }
502
503 func (r *RefFlags) Write(w *Writer) { w.Bytes(r[:]) }
504
505
506
507
508 const huge = (1<<31 - 1) / RelocSize
509
510
511
512
513
514
515
516
517
518 type RefName [RefNameSize]byte
519
520 const RefNameSize = 8 + stringRefSize
521
522 func (n *RefName) Sym() SymRef {
523 return SymRef{binary.LittleEndian.Uint32(n[:]), binary.LittleEndian.Uint32(n[4:])}
524 }
525 func (n *RefName) Name(r *Reader) string {
526 len := binary.LittleEndian.Uint32(n[8:])
527 off := binary.LittleEndian.Uint32(n[12:])
528 return r.StringAt(off, len)
529 }
530
531 func (n *RefName) SetSym(x SymRef) {
532 binary.LittleEndian.PutUint32(n[:], x.PkgIdx)
533 binary.LittleEndian.PutUint32(n[4:], x.SymIdx)
534 }
535 func (n *RefName) SetName(x string, w *Writer) {
536 binary.LittleEndian.PutUint32(n[8:], uint32(len(x)))
537 binary.LittleEndian.PutUint32(n[12:], w.stringOff(x))
538 }
539
540 func (n *RefName) Write(w *Writer) { w.Bytes(n[:]) }
541
542 type Writer struct {
543 wr *bio.Writer
544 stringMap map[string]uint32
545 off uint32
546
547 b [8]byte
548 }
549
550 func NewWriter(wr *bio.Writer) *Writer {
551 return &Writer{wr: wr, stringMap: make(map[string]uint32)}
552 }
553
554 func (w *Writer) AddString(s string) {
555 if _, ok := w.stringMap[s]; ok {
556 return
557 }
558 w.stringMap[s] = w.off
559 w.RawString(s)
560 }
561
562 func (w *Writer) stringOff(s string) uint32 {
563 off, ok := w.stringMap[s]
564 if !ok {
565 panic(fmt.Sprintf("writeStringRef: string not added: %q", s))
566 }
567 return off
568 }
569
570 func (w *Writer) StringRef(s string) {
571 w.Uint32(uint32(len(s)))
572 w.Uint32(w.stringOff(s))
573 }
574
575 func (w *Writer) RawString(s string) {
576 w.wr.WriteString(s)
577 w.off += uint32(len(s))
578 }
579
580 func (w *Writer) Bytes(s []byte) {
581 w.wr.Write(s)
582 w.off += uint32(len(s))
583 }
584
585 func (w *Writer) Uint64(x uint64) {
586 binary.LittleEndian.PutUint64(w.b[:], x)
587 w.wr.Write(w.b[:])
588 w.off += 8
589 }
590
591 func (w *Writer) Uint32(x uint32) {
592 binary.LittleEndian.PutUint32(w.b[:4], x)
593 w.wr.Write(w.b[:4])
594 w.off += 4
595 }
596
597 func (w *Writer) Uint16(x uint16) {
598 binary.LittleEndian.PutUint16(w.b[:2], x)
599 w.wr.Write(w.b[:2])
600 w.off += 2
601 }
602
603 func (w *Writer) Uint8(x uint8) {
604 w.wr.WriteByte(x)
605 w.off++
606 }
607
608 func (w *Writer) Offset() uint32 {
609 return w.off
610 }
611
612 type Reader struct {
613 b []byte
614 readonly bool
615
616 start uint32
617 h Header
618 }
619
620 func NewReaderFromBytes(b []byte, readonly bool) *Reader {
621 r := &Reader{b: b, readonly: readonly, start: 0}
622 err := r.h.Read(r)
623 if err != nil {
624 return nil
625 }
626 return r
627 }
628
629 func (r *Reader) BytesAt(off uint32, len int) []byte {
630 if len == 0 {
631 return nil
632 }
633 end := int(off) + len
634 return r.b[int(off):end:end]
635 }
636
637 func (r *Reader) uint64At(off uint32) uint64 {
638 b := r.BytesAt(off, 8)
639 return binary.LittleEndian.Uint64(b)
640 }
641
642 func (r *Reader) uint32At(off uint32) uint32 {
643 b := r.BytesAt(off, 4)
644 return binary.LittleEndian.Uint32(b)
645 }
646
647 func (r *Reader) StringAt(off uint32, len uint32) string {
648 b := r.b[off : off+len]
649 if r.readonly {
650 return toString(b)
651 }
652 return string(b)
653 }
654
655 func toString(b []byte) string {
656 if len(b) == 0 {
657 return ""
658 }
659 return unsafe.String(&b[0], len(b))
660 }
661
662 func (r *Reader) StringRef(off uint32) string {
663 l := r.uint32At(off)
664 return r.StringAt(r.uint32At(off+4), l)
665 }
666
667 func (r *Reader) Fingerprint() FingerprintType {
668 return r.h.Fingerprint
669 }
670
671 func (r *Reader) Autolib() []ImportedPkg {
672 n := (r.h.Offsets[BlkAutolib+1] - r.h.Offsets[BlkAutolib]) / importedPkgSize
673 s := make([]ImportedPkg, n)
674 off := r.h.Offsets[BlkAutolib]
675 for i := range s {
676 s[i].Pkg = r.StringRef(off)
677 copy(s[i].Fingerprint[:], r.BytesAt(off+stringRefSize, len(s[i].Fingerprint)))
678 off += importedPkgSize
679 }
680 return s
681 }
682
683 func (r *Reader) Pkglist() []string {
684 n := (r.h.Offsets[BlkPkgIdx+1] - r.h.Offsets[BlkPkgIdx]) / stringRefSize
685 s := make([]string, n)
686 off := r.h.Offsets[BlkPkgIdx]
687 for i := range s {
688 s[i] = r.StringRef(off)
689 off += stringRefSize
690 }
691 return s
692 }
693
694 func (r *Reader) NPkg() int {
695 return int(r.h.Offsets[BlkPkgIdx+1]-r.h.Offsets[BlkPkgIdx]) / stringRefSize
696 }
697
698 func (r *Reader) Pkg(i int) string {
699 off := r.h.Offsets[BlkPkgIdx] + uint32(i)*stringRefSize
700 return r.StringRef(off)
701 }
702
703 func (r *Reader) NFile() int {
704 return int(r.h.Offsets[BlkFile+1]-r.h.Offsets[BlkFile]) / stringRefSize
705 }
706
707 func (r *Reader) File(i int) string {
708 off := r.h.Offsets[BlkFile] + uint32(i)*stringRefSize
709 return r.StringRef(off)
710 }
711
712 func (r *Reader) NSym() int {
713 return int(r.h.Offsets[BlkSymdef+1]-r.h.Offsets[BlkSymdef]) / SymSize
714 }
715
716 func (r *Reader) NHashed64def() int {
717 return int(r.h.Offsets[BlkHashed64def+1]-r.h.Offsets[BlkHashed64def]) / SymSize
718 }
719
720 func (r *Reader) NHasheddef() int {
721 return int(r.h.Offsets[BlkHasheddef+1]-r.h.Offsets[BlkHasheddef]) / SymSize
722 }
723
724 func (r *Reader) NNonpkgdef() int {
725 return int(r.h.Offsets[BlkNonpkgdef+1]-r.h.Offsets[BlkNonpkgdef]) / SymSize
726 }
727
728 func (r *Reader) NNonpkgref() int {
729 return int(r.h.Offsets[BlkNonpkgref+1]-r.h.Offsets[BlkNonpkgref]) / SymSize
730 }
731
732
733 func (r *Reader) SymOff(i uint32) uint32 {
734 return r.h.Offsets[BlkSymdef] + i*SymSize
735 }
736
737
738 func (r *Reader) Sym(i uint32) *Sym {
739 off := r.SymOff(i)
740 return (*Sym)(unsafe.Pointer(&r.b[off]))
741 }
742
743
744 func (r *Reader) NRefFlags() int {
745 return int(r.h.Offsets[BlkRefFlags+1]-r.h.Offsets[BlkRefFlags]) / RefFlagsSize
746 }
747
748
749
750 func (r *Reader) RefFlags(i int) *RefFlags {
751 off := r.h.Offsets[BlkRefFlags] + uint32(i*RefFlagsSize)
752 return (*RefFlags)(unsafe.Pointer(&r.b[off]))
753 }
754
755
756
757
758 func (r *Reader) Hash64(i uint32) uint64 {
759 off := r.h.Offsets[BlkHash64] + i*Hash64Size
760 return r.uint64At(off)
761 }
762
763
764
765
766 func (r *Reader) Hash(i uint32) *HashType {
767 off := r.h.Offsets[BlkHash] + i*HashSize
768 return (*HashType)(unsafe.Pointer(&r.b[off]))
769 }
770
771
772 func (r *Reader) NReloc(i uint32) int {
773 relocIdxOff := r.h.Offsets[BlkRelocIdx] + i*4
774 return int(r.uint32At(relocIdxOff+4) - r.uint32At(relocIdxOff))
775 }
776
777
778 func (r *Reader) RelocOff(i uint32, j int) uint32 {
779 relocIdxOff := r.h.Offsets[BlkRelocIdx] + i*4
780 relocIdx := r.uint32At(relocIdxOff)
781 return r.h.Offsets[BlkReloc] + (relocIdx+uint32(j))*uint32(RelocSize)
782 }
783
784
785 func (r *Reader) Reloc(i uint32, j int) *Reloc {
786 off := r.RelocOff(i, j)
787 return (*Reloc)(unsafe.Pointer(&r.b[off]))
788 }
789
790
791 func (r *Reader) Relocs(i uint32) []Reloc {
792 off := r.RelocOff(i, 0)
793 n := r.NReloc(i)
794 return (*[huge]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n]
795 }
796
797
798 func (r *Reader) NAux(i uint32) int {
799 auxIdxOff := r.h.Offsets[BlkAuxIdx] + i*4
800 return int(r.uint32At(auxIdxOff+4) - r.uint32At(auxIdxOff))
801 }
802
803
804 func (r *Reader) AuxOff(i uint32, j int) uint32 {
805 auxIdxOff := r.h.Offsets[BlkAuxIdx] + i*4
806 auxIdx := r.uint32At(auxIdxOff)
807 return r.h.Offsets[BlkAux] + (auxIdx+uint32(j))*uint32(AuxSize)
808 }
809
810
811 func (r *Reader) Aux(i uint32, j int) *Aux {
812 off := r.AuxOff(i, j)
813 return (*Aux)(unsafe.Pointer(&r.b[off]))
814 }
815
816
817 func (r *Reader) Auxs(i uint32) []Aux {
818 off := r.AuxOff(i, 0)
819 n := r.NAux(i)
820 return (*[huge]Aux)(unsafe.Pointer(&r.b[off]))[:n:n]
821 }
822
823
824 func (r *Reader) DataOff(i uint32) uint32 {
825 dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4
826 return r.h.Offsets[BlkData] + r.uint32At(dataIdxOff)
827 }
828
829
830 func (r *Reader) DataSize(i uint32) int {
831 dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4
832 return int(r.uint32At(dataIdxOff+4) - r.uint32At(dataIdxOff))
833 }
834
835
836 func (r *Reader) Data(i uint32) []byte {
837 dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4
838 base := r.h.Offsets[BlkData]
839 off := r.uint32At(dataIdxOff)
840 end := r.uint32At(dataIdxOff + 4)
841 return r.BytesAt(base+off, int(end-off))
842 }
843
844
845 func (r *Reader) DataString(i uint32) string {
846 dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4
847 base := r.h.Offsets[BlkData]
848 off := r.uint32At(dataIdxOff)
849 end := r.uint32At(dataIdxOff + 4)
850 return r.StringAt(base+off, end-off)
851 }
852
853
854 func (r *Reader) NRefName() int {
855 return int(r.h.Offsets[BlkRefName+1]-r.h.Offsets[BlkRefName]) / RefNameSize
856 }
857
858
859
860 func (r *Reader) RefName(i int) *RefName {
861 off := r.h.Offsets[BlkRefName] + uint32(i*RefNameSize)
862 return (*RefName)(unsafe.Pointer(&r.b[off]))
863 }
864
865
866 func (r *Reader) ReadOnly() bool {
867 return r.readonly
868 }
869
870
871 func (r *Reader) Flags() uint32 {
872 return r.h.Flags
873 }
874
875 func (r *Reader) Shared() bool { return r.Flags()&ObjFlagShared != 0 }
876 func (r *Reader) FromAssembly() bool { return r.Flags()&ObjFlagFromAssembly != 0 }
877 func (r *Reader) Unlinkable() bool { return r.Flags()&ObjFlagUnlinkable != 0 }
878 func (r *Reader) Std() bool { return r.Flags()&ObjFlagStd != 0 }
879
View as plain text