| | |
| | |
| | |
| |
|
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | package goobj |
| |
|
| | import ( |
| | "cmd/internal/bio" |
| | "encoding/binary" |
| | "errors" |
| | "fmt" |
| | "unsafe" |
| | ) |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | const stringRefSize = 8 |
| |
|
| | type FingerprintType [8]byte |
| |
|
| | func (fp FingerprintType) IsZero() bool { return fp == FingerprintType{} } |
| |
|
| | |
| | const ( |
| | PkgIdxNone = (1<<31 - 1) - iota |
| | PkgIdxHashed64 |
| | PkgIdxHashed |
| | PkgIdxBuiltin |
| | PkgIdxSelf |
| | PkgIdxSpecial = PkgIdxSelf |
| | PkgIdxInvalid = 0 |
| | |
| | ) |
| |
|
| | |
| | const ( |
| | BlkAutolib = iota |
| | BlkPkgIdx |
| | BlkFile |
| | BlkSymdef |
| | BlkHashed64def |
| | BlkHasheddef |
| | BlkNonpkgdef |
| | BlkNonpkgref |
| | BlkRefFlags |
| | BlkHash64 |
| | BlkHash |
| | BlkRelocIdx |
| | BlkAuxIdx |
| | BlkDataIdx |
| | BlkReloc |
| | BlkAux |
| | BlkData |
| | BlkRefName |
| | BlkEnd |
| | NBlk |
| | ) |
| |
|
| | |
| | |
| | type Header struct { |
| | Magic string |
| | Fingerprint FingerprintType |
| | Flags uint32 |
| | Offsets [NBlk]uint32 |
| | } |
| |
|
| | const Magic = "\x00go120ld" |
| |
|
| | func (h *Header) Write(w *Writer) { |
| | w.RawString(h.Magic) |
| | w.Bytes(h.Fingerprint[:]) |
| | w.Uint32(h.Flags) |
| | for _, x := range h.Offsets { |
| | w.Uint32(x) |
| | } |
| | } |
| |
|
| | func (h *Header) Read(r *Reader) error { |
| | b := r.BytesAt(0, len(Magic)) |
| | h.Magic = string(b) |
| | if h.Magic != Magic { |
| | return errors.New("wrong magic, not a Go object file") |
| | } |
| | off := uint32(len(h.Magic)) |
| | copy(h.Fingerprint[:], r.BytesAt(off, len(h.Fingerprint))) |
| | off += 8 |
| | h.Flags = r.uint32At(off) |
| | off += 4 |
| | for i := range h.Offsets { |
| | h.Offsets[i] = r.uint32At(off) |
| | off += 4 |
| | } |
| | return nil |
| | } |
| |
|
| | func (h *Header) Size() int { |
| | return len(h.Magic) + len(h.Fingerprint) + 4 + 4*len(h.Offsets) |
| | } |
| |
|
| | |
| | type ImportedPkg struct { |
| | Pkg string |
| | Fingerprint FingerprintType |
| | } |
| |
|
| | const importedPkgSize = stringRefSize + 8 |
| |
|
| | func (p *ImportedPkg) Write(w *Writer) { |
| | w.StringRef(p.Pkg) |
| | w.Bytes(p.Fingerprint[:]) |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | type Sym [SymSize]byte |
| |
|
| | const SymSize = stringRefSize + 2 + 1 + 1 + 1 + 4 + 4 |
| |
|
| | const SymABIstatic = ^uint16(0) |
| |
|
| | const ( |
| | ObjFlagShared = 1 << iota |
| | _ |
| | ObjFlagFromAssembly |
| | ObjFlagUnlinkable |
| | ObjFlagStd |
| | ) |
| |
|
| | |
| | const ( |
| | SymFlagDupok = 1 << iota |
| | SymFlagLocal |
| | SymFlagTypelink |
| | SymFlagLeaf |
| | SymFlagNoSplit |
| | SymFlagReflectMethod |
| | SymFlagGoType |
| | ) |
| |
|
| | |
| | const ( |
| | SymFlagUsedInIface = 1 << iota |
| | SymFlagItab |
| | SymFlagDict |
| | SymFlagPkgInit |
| | SymFlagLinkname |
| | SymFlagABIWrapper |
| | SymFlagWasmExport |
| | ) |
| |
|
| | |
| | func (s *Sym) NameLen(r *Reader) int { |
| | return int(binary.LittleEndian.Uint32(s[:])) |
| | } |
| |
|
| | func (s *Sym) Name(r *Reader) string { |
| | len := binary.LittleEndian.Uint32(s[:]) |
| | off := binary.LittleEndian.Uint32(s[4:]) |
| | return r.StringAt(off, len) |
| | } |
| |
|
| | func (s *Sym) ABI() uint16 { return binary.LittleEndian.Uint16(s[8:]) } |
| | func (s *Sym) Type() uint8 { return s[10] } |
| | func (s *Sym) Flag() uint8 { return s[11] } |
| | func (s *Sym) Flag2() uint8 { return s[12] } |
| | func (s *Sym) Siz() uint32 { return binary.LittleEndian.Uint32(s[13:]) } |
| | func (s *Sym) Align() uint32 { return binary.LittleEndian.Uint32(s[17:]) } |
| |
|
| | func (s *Sym) Dupok() bool { return s.Flag()&SymFlagDupok != 0 } |
| | func (s *Sym) Local() bool { return s.Flag()&SymFlagLocal != 0 } |
| | func (s *Sym) Typelink() bool { return s.Flag()&SymFlagTypelink != 0 } |
| | func (s *Sym) Leaf() bool { return s.Flag()&SymFlagLeaf != 0 } |
| | func (s *Sym) NoSplit() bool { return s.Flag()&SymFlagNoSplit != 0 } |
| | func (s *Sym) ReflectMethod() bool { return s.Flag()&SymFlagReflectMethod != 0 } |
| | func (s *Sym) IsGoType() bool { return s.Flag()&SymFlagGoType != 0 } |
| | func (s *Sym) UsedInIface() bool { return s.Flag2()&SymFlagUsedInIface != 0 } |
| | func (s *Sym) IsItab() bool { return s.Flag2()&SymFlagItab != 0 } |
| | func (s *Sym) IsDict() bool { return s.Flag2()&SymFlagDict != 0 } |
| | func (s *Sym) IsPkgInit() bool { return s.Flag2()&SymFlagPkgInit != 0 } |
| | func (s *Sym) IsLinkname() bool { return s.Flag2()&SymFlagLinkname != 0 } |
| | func (s *Sym) ABIWrapper() bool { return s.Flag2()&SymFlagABIWrapper != 0 } |
| | func (s *Sym) WasmExport() bool { return s.Flag2()&SymFlagWasmExport != 0 } |
| |
|
| | func (s *Sym) SetName(x string, w *Writer) { |
| | binary.LittleEndian.PutUint32(s[:], uint32(len(x))) |
| | binary.LittleEndian.PutUint32(s[4:], w.stringOff(x)) |
| | } |
| |
|
| | func (s *Sym) SetABI(x uint16) { binary.LittleEndian.PutUint16(s[8:], x) } |
| | func (s *Sym) SetType(x uint8) { s[10] = x } |
| | func (s *Sym) SetFlag(x uint8) { s[11] = x } |
| | func (s *Sym) SetFlag2(x uint8) { s[12] = x } |
| | func (s *Sym) SetSiz(x uint32) { binary.LittleEndian.PutUint32(s[13:], x) } |
| | func (s *Sym) SetAlign(x uint32) { binary.LittleEndian.PutUint32(s[17:], x) } |
| |
|
| | func (s *Sym) Write(w *Writer) { w.Bytes(s[:]) } |
| |
|
| | |
| | func (s *Sym) fromBytes(b []byte) { copy(s[:], b) } |
| |
|
| | |
| | type SymRef struct { |
| | PkgIdx uint32 |
| | SymIdx uint32 |
| | } |
| |
|
| | func (s SymRef) IsZero() bool { return s == SymRef{} } |
| |
|
| | |
| | type Hash64Type [Hash64Size]byte |
| |
|
| | const Hash64Size = 8 |
| |
|
| | |
| | type HashType [HashSize]byte |
| |
|
| | const HashSize = 16 |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | type Reloc [RelocSize]byte |
| |
|
| | const RelocSize = 4 + 1 + 2 + 8 + 8 |
| |
|
| | func (r *Reloc) Off() int32 { return int32(binary.LittleEndian.Uint32(r[:])) } |
| | func (r *Reloc) Siz() uint8 { return r[4] } |
| | func (r *Reloc) Type() uint16 { return binary.LittleEndian.Uint16(r[5:]) } |
| | func (r *Reloc) Add() int64 { return int64(binary.LittleEndian.Uint64(r[7:])) } |
| | func (r *Reloc) Sym() SymRef { |
| | return SymRef{binary.LittleEndian.Uint32(r[15:]), binary.LittleEndian.Uint32(r[19:])} |
| | } |
| |
|
| | func (r *Reloc) SetOff(x int32) { binary.LittleEndian.PutUint32(r[:], uint32(x)) } |
| | func (r *Reloc) SetSiz(x uint8) { r[4] = x } |
| | func (r *Reloc) SetType(x uint16) { binary.LittleEndian.PutUint16(r[5:], x) } |
| | func (r *Reloc) SetAdd(x int64) { binary.LittleEndian.PutUint64(r[7:], uint64(x)) } |
| | func (r *Reloc) SetSym(x SymRef) { |
| | binary.LittleEndian.PutUint32(r[15:], x.PkgIdx) |
| | binary.LittleEndian.PutUint32(r[19:], x.SymIdx) |
| | } |
| |
|
| | func (r *Reloc) Set(off int32, size uint8, typ uint16, add int64, sym SymRef) { |
| | r.SetOff(off) |
| | r.SetSiz(size) |
| | r.SetType(typ) |
| | r.SetAdd(add) |
| | r.SetSym(sym) |
| | } |
| |
|
| | func (r *Reloc) Write(w *Writer) { w.Bytes(r[:]) } |
| |
|
| | |
| | func (r *Reloc) fromBytes(b []byte) { copy(r[:], b) } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | type Aux [AuxSize]byte |
| |
|
| | const AuxSize = 1 + 8 |
| |
|
| | |
| | const ( |
| | AuxGotype = iota |
| | AuxFuncInfo |
| | AuxFuncdata |
| | AuxDwarfInfo |
| | AuxDwarfLoc |
| | AuxDwarfRanges |
| | AuxDwarfLines |
| | AuxPcsp |
| | AuxPcfile |
| | AuxPcline |
| | AuxPcinline |
| | AuxPcdata |
| | AuxWasmImport |
| | AuxWasmType |
| | AuxSehUnwindInfo |
| | ) |
| |
|
| | func (a *Aux) Type() uint8 { return a[0] } |
| | func (a *Aux) Sym() SymRef { |
| | return SymRef{binary.LittleEndian.Uint32(a[1:]), binary.LittleEndian.Uint32(a[5:])} |
| | } |
| |
|
| | func (a *Aux) SetType(x uint8) { a[0] = x } |
| | func (a *Aux) SetSym(x SymRef) { |
| | binary.LittleEndian.PutUint32(a[1:], x.PkgIdx) |
| | binary.LittleEndian.PutUint32(a[5:], x.SymIdx) |
| | } |
| |
|
| | func (a *Aux) Write(w *Writer) { w.Bytes(a[:]) } |
| |
|
| | |
| | func (a *Aux) fromBytes(b []byte) { copy(a[:], b) } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | type RefFlags [RefFlagsSize]byte |
| |
|
| | const RefFlagsSize = 8 + 1 + 1 |
| |
|
| | func (r *RefFlags) Sym() SymRef { |
| | return SymRef{binary.LittleEndian.Uint32(r[:]), binary.LittleEndian.Uint32(r[4:])} |
| | } |
| | func (r *RefFlags) Flag() uint8 { return r[8] } |
| | func (r *RefFlags) Flag2() uint8 { return r[9] } |
| |
|
| | func (r *RefFlags) SetSym(x SymRef) { |
| | binary.LittleEndian.PutUint32(r[:], x.PkgIdx) |
| | binary.LittleEndian.PutUint32(r[4:], x.SymIdx) |
| | } |
| | func (r *RefFlags) SetFlag(x uint8) { r[8] = x } |
| | func (r *RefFlags) SetFlag2(x uint8) { r[9] = x } |
| |
|
| | func (r *RefFlags) Write(w *Writer) { w.Bytes(r[:]) } |
| |
|
| | |
| | |
| | |
| | const huge = (1<<31 - 1) / RelocSize |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | type RefName [RefNameSize]byte |
| |
|
| | const RefNameSize = 8 + stringRefSize |
| |
|
| | func (n *RefName) Sym() SymRef { |
| | return SymRef{binary.LittleEndian.Uint32(n[:]), binary.LittleEndian.Uint32(n[4:])} |
| | } |
| | func (n *RefName) Name(r *Reader) string { |
| | len := binary.LittleEndian.Uint32(n[8:]) |
| | off := binary.LittleEndian.Uint32(n[12:]) |
| | return r.StringAt(off, len) |
| | } |
| |
|
| | func (n *RefName) SetSym(x SymRef) { |
| | binary.LittleEndian.PutUint32(n[:], x.PkgIdx) |
| | binary.LittleEndian.PutUint32(n[4:], x.SymIdx) |
| | } |
| | func (n *RefName) SetName(x string, w *Writer) { |
| | binary.LittleEndian.PutUint32(n[8:], uint32(len(x))) |
| | binary.LittleEndian.PutUint32(n[12:], w.stringOff(x)) |
| | } |
| |
|
| | func (n *RefName) Write(w *Writer) { w.Bytes(n[:]) } |
| |
|
| | type Writer struct { |
| | wr *bio.Writer |
| | stringMap map[string]uint32 |
| | off uint32 |
| |
|
| | b [8]byte |
| | } |
| |
|
| | func NewWriter(wr *bio.Writer) *Writer { |
| | return &Writer{wr: wr, stringMap: make(map[string]uint32)} |
| | } |
| |
|
| | func (w *Writer) AddString(s string) { |
| | if _, ok := w.stringMap[s]; ok { |
| | return |
| | } |
| | w.stringMap[s] = w.off |
| | w.RawString(s) |
| | } |
| |
|
| | func (w *Writer) stringOff(s string) uint32 { |
| | off, ok := w.stringMap[s] |
| | if !ok { |
| | panic(fmt.Sprintf("writeStringRef: string not added: %q", s)) |
| | } |
| | return off |
| | } |
| |
|
| | func (w *Writer) StringRef(s string) { |
| | w.Uint32(uint32(len(s))) |
| | w.Uint32(w.stringOff(s)) |
| | } |
| |
|
| | func (w *Writer) RawString(s string) { |
| | w.wr.WriteString(s) |
| | w.off += uint32(len(s)) |
| | } |
| |
|
| | func (w *Writer) Bytes(s []byte) { |
| | w.wr.Write(s) |
| | w.off += uint32(len(s)) |
| | } |
| |
|
| | func (w *Writer) Uint64(x uint64) { |
| | binary.LittleEndian.PutUint64(w.b[:], x) |
| | w.wr.Write(w.b[:]) |
| | w.off += 8 |
| | } |
| |
|
| | func (w *Writer) Uint32(x uint32) { |
| | binary.LittleEndian.PutUint32(w.b[:4], x) |
| | w.wr.Write(w.b[:4]) |
| | w.off += 4 |
| | } |
| |
|
| | func (w *Writer) Uint16(x uint16) { |
| | binary.LittleEndian.PutUint16(w.b[:2], x) |
| | w.wr.Write(w.b[:2]) |
| | w.off += 2 |
| | } |
| |
|
| | func (w *Writer) Uint8(x uint8) { |
| | w.wr.WriteByte(x) |
| | w.off++ |
| | } |
| |
|
| | func (w *Writer) Offset() uint32 { |
| | return w.off |
| | } |
| |
|
| | type Reader struct { |
| | b []byte |
| | readonly bool |
| |
|
| | start uint32 |
| | h Header |
| | } |
| |
|
| | func NewReaderFromBytes(b []byte, readonly bool) *Reader { |
| | r := &Reader{b: b, readonly: readonly, start: 0} |
| | err := r.h.Read(r) |
| | if err != nil { |
| | return nil |
| | } |
| | return r |
| | } |
| |
|
| | func (r *Reader) BytesAt(off uint32, len int) []byte { |
| | if len == 0 { |
| | return nil |
| | } |
| | end := int(off) + len |
| | return r.b[int(off):end:end] |
| | } |
| |
|
| | func (r *Reader) uint64At(off uint32) uint64 { |
| | b := r.BytesAt(off, 8) |
| | return binary.LittleEndian.Uint64(b) |
| | } |
| |
|
| | func (r *Reader) uint32At(off uint32) uint32 { |
| | b := r.BytesAt(off, 4) |
| | return binary.LittleEndian.Uint32(b) |
| | } |
| |
|
| | func (r *Reader) StringAt(off uint32, len uint32) string { |
| | b := r.b[off : off+len] |
| | if r.readonly { |
| | return toString(b) |
| | } |
| | return string(b) |
| | } |
| |
|
| | func toString(b []byte) string { |
| | if len(b) == 0 { |
| | return "" |
| | } |
| | return unsafe.String(&b[0], len(b)) |
| | } |
| |
|
| | func (r *Reader) StringRef(off uint32) string { |
| | l := r.uint32At(off) |
| | return r.StringAt(r.uint32At(off+4), l) |
| | } |
| |
|
| | func (r *Reader) Fingerprint() FingerprintType { |
| | return r.h.Fingerprint |
| | } |
| |
|
| | func (r *Reader) Autolib() []ImportedPkg { |
| | n := (r.h.Offsets[BlkAutolib+1] - r.h.Offsets[BlkAutolib]) / importedPkgSize |
| | s := make([]ImportedPkg, n) |
| | off := r.h.Offsets[BlkAutolib] |
| | for i := range s { |
| | s[i].Pkg = r.StringRef(off) |
| | copy(s[i].Fingerprint[:], r.BytesAt(off+stringRefSize, len(s[i].Fingerprint))) |
| | off += importedPkgSize |
| | } |
| | return s |
| | } |
| |
|
| | func (r *Reader) Pkglist() []string { |
| | n := (r.h.Offsets[BlkPkgIdx+1] - r.h.Offsets[BlkPkgIdx]) / stringRefSize |
| | s := make([]string, n) |
| | off := r.h.Offsets[BlkPkgIdx] |
| | for i := range s { |
| | s[i] = r.StringRef(off) |
| | off += stringRefSize |
| | } |
| | return s |
| | } |
| |
|
| | func (r *Reader) NPkg() int { |
| | return int(r.h.Offsets[BlkPkgIdx+1]-r.h.Offsets[BlkPkgIdx]) / stringRefSize |
| | } |
| |
|
| | func (r *Reader) Pkg(i int) string { |
| | off := r.h.Offsets[BlkPkgIdx] + uint32(i)*stringRefSize |
| | return r.StringRef(off) |
| | } |
| |
|
| | func (r *Reader) NFile() int { |
| | return int(r.h.Offsets[BlkFile+1]-r.h.Offsets[BlkFile]) / stringRefSize |
| | } |
| |
|
| | func (r *Reader) File(i int) string { |
| | off := r.h.Offsets[BlkFile] + uint32(i)*stringRefSize |
| | return r.StringRef(off) |
| | } |
| |
|
| | func (r *Reader) NSym() int { |
| | return int(r.h.Offsets[BlkSymdef+1]-r.h.Offsets[BlkSymdef]) / SymSize |
| | } |
| |
|
| | func (r *Reader) NHashed64def() int { |
| | return int(r.h.Offsets[BlkHashed64def+1]-r.h.Offsets[BlkHashed64def]) / SymSize |
| | } |
| |
|
| | func (r *Reader) NHasheddef() int { |
| | return int(r.h.Offsets[BlkHasheddef+1]-r.h.Offsets[BlkHasheddef]) / SymSize |
| | } |
| |
|
| | func (r *Reader) NNonpkgdef() int { |
| | return int(r.h.Offsets[BlkNonpkgdef+1]-r.h.Offsets[BlkNonpkgdef]) / SymSize |
| | } |
| |
|
| | func (r *Reader) NNonpkgref() int { |
| | return int(r.h.Offsets[BlkNonpkgref+1]-r.h.Offsets[BlkNonpkgref]) / SymSize |
| | } |
| |
|
| | |
| | func (r *Reader) SymOff(i uint32) uint32 { |
| | return r.h.Offsets[BlkSymdef] + i*SymSize |
| | } |
| |
|
| | |
| | func (r *Reader) Sym(i uint32) *Sym { |
| | off := r.SymOff(i) |
| | return (*Sym)(unsafe.Pointer(&r.b[off])) |
| | } |
| |
|
| | |
| | func (r *Reader) NRefFlags() int { |
| | return int(r.h.Offsets[BlkRefFlags+1]-r.h.Offsets[BlkRefFlags]) / RefFlagsSize |
| | } |
| |
|
| | |
| | |
| | func (r *Reader) RefFlags(i int) *RefFlags { |
| | off := r.h.Offsets[BlkRefFlags] + uint32(i*RefFlagsSize) |
| | return (*RefFlags)(unsafe.Pointer(&r.b[off])) |
| | } |
| |
|
| | |
| | |
| | |
| | func (r *Reader) Hash64(i uint32) uint64 { |
| | off := r.h.Offsets[BlkHash64] + i*Hash64Size |
| | return r.uint64At(off) |
| | } |
| |
|
| | |
| | |
| | |
| | func (r *Reader) Hash(i uint32) *HashType { |
| | off := r.h.Offsets[BlkHash] + i*HashSize |
| | return (*HashType)(unsafe.Pointer(&r.b[off])) |
| | } |
| |
|
| | |
| | func (r *Reader) NReloc(i uint32) int { |
| | relocIdxOff := r.h.Offsets[BlkRelocIdx] + i*4 |
| | return int(r.uint32At(relocIdxOff+4) - r.uint32At(relocIdxOff)) |
| | } |
| |
|
| | |
| | func (r *Reader) RelocOff(i uint32, j int) uint32 { |
| | relocIdxOff := r.h.Offsets[BlkRelocIdx] + i*4 |
| | relocIdx := r.uint32At(relocIdxOff) |
| | return r.h.Offsets[BlkReloc] + (relocIdx+uint32(j))*uint32(RelocSize) |
| | } |
| |
|
| | |
| | func (r *Reader) Reloc(i uint32, j int) *Reloc { |
| | off := r.RelocOff(i, j) |
| | return (*Reloc)(unsafe.Pointer(&r.b[off])) |
| | } |
| |
|
| | |
| | func (r *Reader) Relocs(i uint32) []Reloc { |
| | off := r.RelocOff(i, 0) |
| | n := r.NReloc(i) |
| | return (*[huge]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n] |
| | } |
| |
|
| | |
| | func (r *Reader) NAux(i uint32) int { |
| | auxIdxOff := r.h.Offsets[BlkAuxIdx] + i*4 |
| | return int(r.uint32At(auxIdxOff+4) - r.uint32At(auxIdxOff)) |
| | } |
| |
|
| | |
| | func (r *Reader) AuxOff(i uint32, j int) uint32 { |
| | auxIdxOff := r.h.Offsets[BlkAuxIdx] + i*4 |
| | auxIdx := r.uint32At(auxIdxOff) |
| | return r.h.Offsets[BlkAux] + (auxIdx+uint32(j))*uint32(AuxSize) |
| | } |
| |
|
| | |
| | func (r *Reader) Aux(i uint32, j int) *Aux { |
| | off := r.AuxOff(i, j) |
| | return (*Aux)(unsafe.Pointer(&r.b[off])) |
| | } |
| |
|
| | |
| | func (r *Reader) Auxs(i uint32) []Aux { |
| | off := r.AuxOff(i, 0) |
| | n := r.NAux(i) |
| | return (*[huge]Aux)(unsafe.Pointer(&r.b[off]))[:n:n] |
| | } |
| |
|
| | |
| | func (r *Reader) DataOff(i uint32) uint32 { |
| | dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4 |
| | return r.h.Offsets[BlkData] + r.uint32At(dataIdxOff) |
| | } |
| |
|
| | |
| | func (r *Reader) DataSize(i uint32) int { |
| | dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4 |
| | return int(r.uint32At(dataIdxOff+4) - r.uint32At(dataIdxOff)) |
| | } |
| |
|
| | |
| | func (r *Reader) Data(i uint32) []byte { |
| | dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4 |
| | base := r.h.Offsets[BlkData] |
| | off := r.uint32At(dataIdxOff) |
| | end := r.uint32At(dataIdxOff + 4) |
| | return r.BytesAt(base+off, int(end-off)) |
| | } |
| |
|
| | |
| | func (r *Reader) DataString(i uint32) string { |
| | dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4 |
| | base := r.h.Offsets[BlkData] |
| | off := r.uint32At(dataIdxOff) |
| | end := r.uint32At(dataIdxOff + 4) |
| | return r.StringAt(base+off, end-off) |
| | } |
| |
|
| | |
| | func (r *Reader) NRefName() int { |
| | return int(r.h.Offsets[BlkRefName+1]-r.h.Offsets[BlkRefName]) / RefNameSize |
| | } |
| |
|
| | |
| | |
| | func (r *Reader) RefName(i int) *RefName { |
| | off := r.h.Offsets[BlkRefName] + uint32(i*RefNameSize) |
| | return (*RefName)(unsafe.Pointer(&r.b[off])) |
| | } |
| |
|
| | |
| | func (r *Reader) ReadOnly() bool { |
| | return r.readonly |
| | } |
| |
|
| | |
| | func (r *Reader) Flags() uint32 { |
| | return r.h.Flags |
| | } |
| |
|
| | func (r *Reader) Shared() bool { return r.Flags()&ObjFlagShared != 0 } |
| | func (r *Reader) FromAssembly() bool { return r.Flags()&ObjFlagFromAssembly != 0 } |
| | func (r *Reader) Unlinkable() bool { return r.Flags()&ObjFlagUnlinkable != 0 } |
| | func (r *Reader) Std() bool { return r.Flags()&ObjFlagStd != 0 } |
| |
|