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