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