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