diff options
author | 2025-03-09 17:47:56 +0100 | |
---|---|---|
committer | 2025-03-10 01:59:49 +0100 | |
commit | 3ac1ee16f377d31a0fb80c8dae28b6239ac4229e (patch) | |
tree | f61faa581feaaeaba2542b9f2b8234a590684413 /vendor/github.com/twitchyliquid64/golang-asm/goobj/objfile.go | |
parent | [chore] update URLs to forked source (diff) | |
download | gotosocial-3ac1ee16f377d31a0fb80c8dae28b6239ac4229e.tar.xz |
[chore] remove vendor
Diffstat (limited to 'vendor/github.com/twitchyliquid64/golang-asm/goobj/objfile.go')
-rw-r--r-- | vendor/github.com/twitchyliquid64/golang-asm/goobj/objfile.go | 871 |
1 files changed, 0 insertions, 871 deletions
diff --git a/vendor/github.com/twitchyliquid64/golang-asm/goobj/objfile.go b/vendor/github.com/twitchyliquid64/golang-asm/goobj/objfile.go deleted file mode 100644 index 3303549aa..000000000 --- a/vendor/github.com/twitchyliquid64/golang-asm/goobj/objfile.go +++ /dev/null @@ -1,871 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This package defines the Go object file format, and provide "low-level" functions -// for reading and writing object files. - -// The object file is understood by the compiler, assembler, linker, and tools. They -// have "high level" code that operates on object files, handling application-specific -// logics, and use this package for the actual reading and writing. Specifically, the -// code below: -// -// - cmd/internal/obj/objfile.go (used by cmd/asm and cmd/compile) -// - cmd/internal/objfile/goobj.go (used cmd/nm, cmd/objdump) -// - cmd/link/internal/loader package (used by cmd/link) -// -// If the object file format changes, they may (or may not) need to change. - -package goobj - -import ( - "bytes" - "github.com/twitchyliquid64/golang-asm/bio" - "crypto/sha1" - "encoding/binary" - "errors" - "fmt" - "github.com/twitchyliquid64/golang-asm/unsafeheader" - "io" - "unsafe" -) - -// New object file format. -// -// Header struct { -// Magic [...]byte // "\x00go116ld" -// Fingerprint [8]byte -// Flags uint32 -// Offsets [...]uint32 // byte offset of each block below -// } -// -// Strings [...]struct { -// Data [...]byte -// } -// -// Autolib [...]struct { // imported packages (for file loading) -// Pkg string -// Fingerprint [8]byte -// } -// -// PkgIndex [...]string // referenced packages by index -// -// Files [...]string -// -// SymbolDefs [...]struct { -// Name string -// ABI uint16 -// Type uint8 -// Flag uint8 -// Flag2 uint8 -// Size uint32 -// } -// Hashed64Defs [...]struct { // short hashed (content-addressable) symbol definitions -// ... // same as SymbolDefs -// } -// HashedDefs [...]struct { // hashed (content-addressable) symbol definitions -// ... // same as SymbolDefs -// } -// NonPkgDefs [...]struct { // non-pkg symbol definitions -// ... // same as SymbolDefs -// } -// NonPkgRefs [...]struct { // non-pkg symbol references -// ... // same as SymbolDefs -// } -// -// RefFlags [...]struct { // referenced symbol flags -// Sym symRef -// Flag uint8 -// Flag2 uint8 -// } -// -// Hash64 [...][8]byte -// Hash [...][N]byte -// -// RelocIndex [...]uint32 // index to Relocs -// AuxIndex [...]uint32 // index to Aux -// DataIndex [...]uint32 // offset to Data -// -// Relocs [...]struct { -// Off int32 -// Size uint8 -// Type uint8 -// Add int64 -// Sym symRef -// } -// -// Aux [...]struct { -// Type uint8 -// Sym symRef -// } -// -// Data [...]byte -// Pcdata [...]byte -// -// // blocks only used by tools (objdump, nm) -// -// RefNames [...]struct { // referenced symbol names -// Sym symRef -// Name string -// // TODO: include ABI version as well? -// } -// -// string is encoded as is a uint32 length followed by a uint32 offset -// that points to the corresponding string bytes. -// -// symRef is struct { PkgIdx, SymIdx uint32 }. -// -// Slice type (e.g. []symRef) is encoded as a length prefix (uint32) -// followed by that number of elements. -// -// The types below correspond to the encoded data structure in the -// object file. - -// Symbol indexing. -// -// Each symbol is referenced with a pair of indices, { PkgIdx, SymIdx }, -// as the symRef struct above. -// -// PkgIdx is either a predeclared index (see PkgIdxNone below) or -// an index of an imported package. For the latter case, PkgIdx is the -// index of the package in the PkgIndex array. 0 is an invalid index. -// -// SymIdx is the index of the symbol in the given package. -// - If PkgIdx is PkgIdxSelf, SymIdx is the index of the symbol in the -// SymbolDefs array. -// - If PkgIdx is PkgIdxHashed64, SymIdx is the index of the symbol in the -// Hashed64Defs array. -// - If PkgIdx is PkgIdxHashed, SymIdx is the index of the symbol in the -// HashedDefs array. -// - If PkgIdx is PkgIdxNone, SymIdx is the index of the symbol in the -// NonPkgDefs array (could natually overflow to NonPkgRefs array). -// - Otherwise, SymIdx is the index of the symbol in some other package's -// SymbolDefs array. -// -// {0, 0} represents a nil symbol. Otherwise PkgIdx should not be 0. -// -// Hash contains the content hashes of content-addressable symbols, of -// which PkgIdx is PkgIdxHashed, in the same order of HashedDefs array. -// Hash64 is similar, for PkgIdxHashed64 symbols. -// -// RelocIndex, AuxIndex, and DataIndex contains indices/offsets to -// Relocs/Aux/Data blocks, one element per symbol, first for all the -// defined symbols, then all the defined hashed and non-package symbols, -// in the same order of SymbolDefs/Hashed64Defs/HashedDefs/NonPkgDefs -// arrays. For N total defined symbols, the array is of length N+1. The -// last element is the total number of relocations (aux symbols, data -// blocks, etc.). -// -// They can be accessed by index. For the i-th symbol, its relocations -// are the RelocIndex[i]-th (inclusive) to RelocIndex[i+1]-th (exclusive) -// elements in the Relocs array. Aux/Data are likewise. (The index is -// 0-based.) - -// Auxiliary symbols. -// -// Each symbol may (or may not) be associated with a number of auxiliary -// symbols. They are described in the Aux block. See Aux struct below. -// Currently a symbol's Gotype, FuncInfo, and associated DWARF symbols -// are auxiliary symbols. - -const stringRefSize = 8 // two uint32s - -type FingerprintType [8]byte - -func (fp FingerprintType) IsZero() bool { return fp == FingerprintType{} } - -// Package Index. -const ( - PkgIdxNone = (1<<31 - 1) - iota // Non-package symbols - PkgIdxHashed64 // Short hashed (content-addressable) symbols - PkgIdxHashed // Hashed (content-addressable) symbols - PkgIdxBuiltin // Predefined runtime symbols (ex: runtime.newobject) - PkgIdxSelf // Symbols defined in the current package - PkgIdxInvalid = 0 - // The index of other referenced packages starts from 1. -) - -// Blocks -const ( - BlkAutolib = iota - BlkPkgIdx - BlkFile - BlkSymdef - BlkHashed64def - BlkHasheddef - BlkNonpkgdef - BlkNonpkgref - BlkRefFlags - BlkHash64 - BlkHash - BlkRelocIdx - BlkAuxIdx - BlkDataIdx - BlkReloc - BlkAux - BlkData - BlkPcdata - BlkRefName - BlkEnd - NBlk -) - -// File header. -// TODO: probably no need to export this. -type Header struct { - Magic string - Fingerprint FingerprintType - Flags uint32 - Offsets [NBlk]uint32 -} - -const Magic = "\x00go116ld" - -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) + 4 + 4*len(h.Offsets) -} - -// Autolib -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[:]) -} - -// Symbol definition. -// -// Serialized format: -// Sym struct { -// Name string -// ABI uint16 -// Type uint8 -// Flag uint8 -// Flag2 uint8 -// Siz uint32 -// Align uint32 -// } -type Sym [SymSize]byte - -const SymSize = stringRefSize + 2 + 1 + 1 + 1 + 4 + 4 - -const SymABIstatic = ^uint16(0) - -const ( - ObjFlagShared = 1 << iota // this object is built with -shared - ObjFlagNeedNameExpansion // the linker needs to expand `"".` to package path in symbol names - ObjFlagFromAssembly // object is from asm src, not go -) - -// Sym.Flag -const ( - SymFlagDupok = 1 << iota - SymFlagLocal - SymFlagTypelink - SymFlagLeaf - SymFlagNoSplit - SymFlagReflectMethod - SymFlagGoType - SymFlagTopFrame -) - -// Sym.Flag2 -const ( - SymFlagUsedInIface = 1 << iota - SymFlagItab -) - -// Returns the length of the name of the symbol. -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) TopFrame() bool { return s.Flag()&SymFlagTopFrame != 0 } -func (s *Sym) UsedInIface() bool { return s.Flag2()&SymFlagUsedInIface != 0 } -func (s *Sym) IsItab() bool { return s.Flag2()&SymFlagItab != 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[:]) } - -// for testing -func (s *Sym) fromBytes(b []byte) { copy(s[:], b) } - -// Symbol reference. -type SymRef struct { - PkgIdx uint32 - SymIdx uint32 -} - -// Hash64 -type Hash64Type [Hash64Size]byte - -const Hash64Size = 8 - -// Hash -type HashType [HashSize]byte - -const HashSize = sha1.Size - -// Relocation. -// -// Serialized format: -// Reloc struct { -// Off int32 -// Siz uint8 -// Type uint8 -// Add int64 -// Sym SymRef -// } -type Reloc [RelocSize]byte - -const RelocSize = 4 + 1 + 1 + 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() uint8 { return r[5] } -func (r *Reloc) Add() int64 { return int64(binary.LittleEndian.Uint64(r[6:])) } -func (r *Reloc) Sym() SymRef { - return SymRef{binary.LittleEndian.Uint32(r[14:]), binary.LittleEndian.Uint32(r[18:])} -} - -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 uint8) { r[5] = x } -func (r *Reloc) SetAdd(x int64) { binary.LittleEndian.PutUint64(r[6:], uint64(x)) } -func (r *Reloc) SetSym(x SymRef) { - binary.LittleEndian.PutUint32(r[14:], x.PkgIdx) - binary.LittleEndian.PutUint32(r[18:], x.SymIdx) -} - -func (r *Reloc) Set(off int32, size uint8, typ uint8, 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[:]) } - -// for testing -func (r *Reloc) fromBytes(b []byte) { copy(r[:], b) } - -// Aux symbol info. -// -// Serialized format: -// Aux struct { -// Type uint8 -// Sym SymRef -// } -type Aux [AuxSize]byte - -const AuxSize = 1 + 8 - -// Aux Type -const ( - AuxGotype = iota - AuxFuncInfo - AuxFuncdata - AuxDwarfInfo - AuxDwarfLoc - AuxDwarfRanges - AuxDwarfLines - - // TODO: more. Pcdata? -) - -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[:]) } - -// for testing -func (a *Aux) fromBytes(b []byte) { copy(a[:], b) } - -// Referenced symbol flags. -// -// Serialized format: -// RefFlags struct { -// Sym symRef -// Flag uint8 -// Flag2 uint8 -// } -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[:]) } - -// Referenced symbol name. -// -// Serialized format: -// RefName struct { -// Sym symRef -// Name string -// } -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 // running offset -} - -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) { - var b [8]byte - binary.LittleEndian.PutUint64(b[:], x) - w.wr.Write(b[:]) - w.off += 8 -} - -func (w *Writer) Uint32(x uint32) { - var b [4]byte - binary.LittleEndian.PutUint32(b[:], x) - w.wr.Write(b[:]) - w.off += 4 -} - -func (w *Writer) Uint16(x uint16) { - var b [2]byte - binary.LittleEndian.PutUint16(b[:], x) - w.wr.Write(b[:]) - 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 // mmapped bytes, if not nil - readonly bool // whether b is backed with read-only memory - - rd io.ReaderAt - start uint32 - h Header // keep block offsets -} - -func NewReaderFromBytes(b []byte, readonly bool) *Reader { - r := &Reader{b: b, readonly: readonly, rd: bytes.NewReader(b), 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) int64At(off uint32) int64 { - return int64(r.uint64At(off)) -} - -func (r *Reader) uint32At(off uint32) uint32 { - b := r.BytesAt(off, 4) - return binary.LittleEndian.Uint32(b) -} - -func (r *Reader) int32At(off uint32) int32 { - return int32(r.uint32At(off)) -} - -func (r *Reader) uint16At(off uint32) uint16 { - b := r.BytesAt(off, 2) - return binary.LittleEndian.Uint16(b) -} - -func (r *Reader) uint8At(off uint32) uint8 { - b := r.BytesAt(off, 1) - return b[0] -} - -func (r *Reader) StringAt(off uint32, len uint32) string { - b := r.b[off : off+len] - if r.readonly { - return toString(b) // backed by RO memory, ok to make unsafe string - } - return string(b) -} - -func toString(b []byte) string { - if len(b) == 0 { - return "" - } - - var s string - hdr := (*unsafeheader.String)(unsafe.Pointer(&s)) - hdr.Data = unsafe.Pointer(&b[0]) - hdr.Len = len(b) - - return s -} - -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 -} - -// SymOff returns the offset of the i-th symbol. -func (r *Reader) SymOff(i uint32) uint32 { - return r.h.Offsets[BlkSymdef] + uint32(i*SymSize) -} - -// Sym returns a pointer to the i-th symbol. -func (r *Reader) Sym(i uint32) *Sym { - off := r.SymOff(i) - return (*Sym)(unsafe.Pointer(&r.b[off])) -} - -// NRefFlags returns the number of referenced symbol flags. -func (r *Reader) NRefFlags() int { - return int(r.h.Offsets[BlkRefFlags+1]-r.h.Offsets[BlkRefFlags]) / RefFlagsSize -} - -// RefFlags returns a pointer to the i-th referenced symbol flags. -// Note: here i is not a local symbol index, just a counter. -func (r *Reader) RefFlags(i int) *RefFlags { - off := r.h.Offsets[BlkRefFlags] + uint32(i*RefFlagsSize) - return (*RefFlags)(unsafe.Pointer(&r.b[off])) -} - -// Hash64 returns the i-th short hashed symbol's hash. -// Note: here i is the index of short hashed symbols, not all symbols -// (unlike other accessors). -func (r *Reader) Hash64(i uint32) uint64 { - off := r.h.Offsets[BlkHash64] + uint32(i*Hash64Size) - return r.uint64At(off) -} - -// Hash returns a pointer to the i-th hashed symbol's hash. -// Note: here i is the index of hashed symbols, not all symbols -// (unlike other accessors). -func (r *Reader) Hash(i uint32) *HashType { - off := r.h.Offsets[BlkHash] + uint32(i*HashSize) - return (*HashType)(unsafe.Pointer(&r.b[off])) -} - -// NReloc returns the number of relocations of the i-th symbol. -func (r *Reader) NReloc(i uint32) int { - relocIdxOff := r.h.Offsets[BlkRelocIdx] + uint32(i*4) - return int(r.uint32At(relocIdxOff+4) - r.uint32At(relocIdxOff)) -} - -// RelocOff returns the offset of the j-th relocation of the i-th symbol. -func (r *Reader) RelocOff(i uint32, j int) uint32 { - relocIdxOff := r.h.Offsets[BlkRelocIdx] + uint32(i*4) - relocIdx := r.uint32At(relocIdxOff) - return r.h.Offsets[BlkReloc] + (relocIdx+uint32(j))*uint32(RelocSize) -} - -// Reloc returns a pointer to the j-th relocation of the i-th symbol. -func (r *Reader) Reloc(i uint32, j int) *Reloc { - off := r.RelocOff(i, j) - return (*Reloc)(unsafe.Pointer(&r.b[off])) -} - -// Relocs returns a pointer to the relocations of the i-th symbol. -func (r *Reader) Relocs(i uint32) []Reloc { - off := r.RelocOff(i, 0) - n := r.NReloc(i) - return (*[1 << 20]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n] -} - -// NAux returns the number of aux symbols of the i-th symbol. -func (r *Reader) NAux(i uint32) int { - auxIdxOff := r.h.Offsets[BlkAuxIdx] + i*4 - return int(r.uint32At(auxIdxOff+4) - r.uint32At(auxIdxOff)) -} - -// AuxOff returns the offset of the j-th aux symbol of the i-th symbol. -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) -} - -// Aux returns a pointer to the j-th aux symbol of the i-th symbol. -func (r *Reader) Aux(i uint32, j int) *Aux { - off := r.AuxOff(i, j) - return (*Aux)(unsafe.Pointer(&r.b[off])) -} - -// Auxs returns the aux symbols of the i-th symbol. -func (r *Reader) Auxs(i uint32) []Aux { - off := r.AuxOff(i, 0) - n := r.NAux(i) - return (*[1 << 20]Aux)(unsafe.Pointer(&r.b[off]))[:n:n] -} - -// DataOff returns the offset of the i-th symbol's data. -func (r *Reader) DataOff(i uint32) uint32 { - dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4 - return r.h.Offsets[BlkData] + r.uint32At(dataIdxOff) -} - -// DataSize returns the size of the i-th symbol's data. -func (r *Reader) DataSize(i uint32) int { - dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4 - return int(r.uint32At(dataIdxOff+4) - r.uint32At(dataIdxOff)) -} - -// Data returns the i-th symbol's data. -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)) -} - -// AuxDataBase returns the base offset of the aux data block. -func (r *Reader) PcdataBase() uint32 { - return r.h.Offsets[BlkPcdata] -} - -// NRefName returns the number of referenced symbol names. -func (r *Reader) NRefName() int { - return int(r.h.Offsets[BlkRefName+1]-r.h.Offsets[BlkRefName]) / RefNameSize -} - -// RefName returns a pointer to the i-th referenced symbol name. -// Note: here i is not a local symbol index, just a counter. -func (r *Reader) RefName(i int) *RefName { - off := r.h.Offsets[BlkRefName] + uint32(i*RefNameSize) - return (*RefName)(unsafe.Pointer(&r.b[off])) -} - -// ReadOnly returns whether r.BytesAt returns read-only bytes. -func (r *Reader) ReadOnly() bool { - return r.readonly -} - -// Flags returns the flag bits read from the object file header. -func (r *Reader) Flags() uint32 { - return r.h.Flags -} - -func (r *Reader) Shared() bool { return r.Flags()&ObjFlagShared != 0 } -func (r *Reader) NeedNameExpansion() bool { return r.Flags()&ObjFlagNeedNameExpansion != 0 } -func (r *Reader) FromAssembly() bool { return r.Flags()&ObjFlagFromAssembly != 0 } |