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