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 }