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