Файловый менеджер - Редактировать - /var/www/html/goobj.zip
Ðазад
PK ! �!p�^ ^ objfile.gonu �[��� // 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 ( "cmd/internal/bio" "encoding/binary" "errors" "fmt" "unsafe" ) // New object file format. // // Header struct { // Magic [...]byte // "\x00go120ld" // 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 uint16 // Add int64 // Sym symRef // } // // Aux [...]struct { // Type uint8 // Sym symRef // } // // Data [...]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 naturally 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 PkgIdxSpecial = PkgIdxSelf // Indices above it has special meanings 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 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 = "\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) } // 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 _ // was ObjFlagNeedNameExpansion ObjFlagFromAssembly // object is from asm src, not go ObjFlagUnlinkable // unlinkable package (linker will emit an error) ) // Sym.Flag const ( SymFlagDupok = 1 << iota SymFlagLocal SymFlagTypelink SymFlagLeaf SymFlagNoSplit SymFlagReflectMethod SymFlagGoType ) // Sym.Flag2 const ( SymFlagUsedInIface = 1 << iota SymFlagItab SymFlagDict SymFlagPkgInit ) // 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) 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) 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 } func (s SymRef) IsZero() bool { return s == SymRef{} } // Hash64 type Hash64Type [Hash64Size]byte const Hash64Size = 8 // Hash type HashType [HashSize]byte const HashSize = 16 // truncated SHA256 // Relocation. // // Serialized format: // // Reloc struct { // Off int32 // Siz uint8 // Type uint16 // Add int64 // Sym SymRef // } 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[:]) } // 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 AuxPcsp AuxPcfile AuxPcline AuxPcinline AuxPcdata AuxWasmImport 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[:]) } // 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[:]) } // Used to construct an artificially large array type when reading an // item from the object file relocs section or aux sym section (needs // to work on 32-bit as well as 64-bit). See issue 41621. const huge = (1<<31 - 1) / RelocSize // 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 b [8]byte // scratch space for writing bytes } 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 // mmapped bytes, if not nil readonly bool // whether b is backed with read-only memory start uint32 h Header // keep block offsets } 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) 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 "" } 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 } // 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 (*[huge]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 (*[huge]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)) } // DataString returns the i-th symbol's data as a string. 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) } // 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) FromAssembly() bool { return r.Flags()&ObjFlagFromAssembly != 0 } func (r *Reader) Unlinkable() bool { return r.Flags()&ObjFlagUnlinkable != 0 } PK ! 2�� I I builtinlist.gonu �[��� // Code generated by mkbuiltin.go. DO NOT EDIT. package goobj var builtins = [...]struct { name string abi int }{ {"runtime.newobject", 1}, {"runtime.mallocgc", 1}, {"runtime.panicdivide", 1}, {"runtime.panicshift", 1}, {"runtime.panicmakeslicelen", 1}, {"runtime.panicmakeslicecap", 1}, {"runtime.throwinit", 1}, {"runtime.panicwrap", 1}, {"runtime.gopanic", 1}, {"runtime.gorecover", 1}, {"runtime.goschedguarded", 1}, {"runtime.goPanicIndex", 1}, {"runtime.goPanicIndexU", 1}, {"runtime.goPanicSliceAlen", 1}, {"runtime.goPanicSliceAlenU", 1}, {"runtime.goPanicSliceAcap", 1}, {"runtime.goPanicSliceAcapU", 1}, {"runtime.goPanicSliceB", 1}, {"runtime.goPanicSliceBU", 1}, {"runtime.goPanicSlice3Alen", 1}, {"runtime.goPanicSlice3AlenU", 1}, {"runtime.goPanicSlice3Acap", 1}, {"runtime.goPanicSlice3AcapU", 1}, {"runtime.goPanicSlice3B", 1}, {"runtime.goPanicSlice3BU", 1}, {"runtime.goPanicSlice3C", 1}, {"runtime.goPanicSlice3CU", 1}, {"runtime.goPanicSliceConvert", 1}, {"runtime.printbool", 1}, {"runtime.printfloat", 1}, {"runtime.printint", 1}, {"runtime.printhex", 1}, {"runtime.printuint", 1}, {"runtime.printcomplex", 1}, {"runtime.printstring", 1}, {"runtime.printpointer", 1}, {"runtime.printuintptr", 1}, {"runtime.printiface", 1}, {"runtime.printeface", 1}, {"runtime.printslice", 1}, {"runtime.printnl", 1}, {"runtime.printsp", 1}, {"runtime.printlock", 1}, {"runtime.printunlock", 1}, {"runtime.concatstring2", 1}, {"runtime.concatstring3", 1}, {"runtime.concatstring4", 1}, {"runtime.concatstring5", 1}, {"runtime.concatstrings", 1}, {"runtime.cmpstring", 1}, {"runtime.intstring", 1}, {"runtime.slicebytetostring", 1}, {"runtime.slicebytetostringtmp", 1}, {"runtime.slicerunetostring", 1}, {"runtime.stringtoslicebyte", 1}, {"runtime.stringtoslicerune", 1}, {"runtime.slicecopy", 1}, {"runtime.decoderune", 1}, {"runtime.countrunes", 1}, {"runtime.convT", 1}, {"runtime.convTnoptr", 1}, {"runtime.convT16", 1}, {"runtime.convT32", 1}, {"runtime.convT64", 1}, {"runtime.convTstring", 1}, {"runtime.convTslice", 1}, {"runtime.assertE2I", 1}, {"runtime.assertE2I2", 1}, {"runtime.panicdottypeE", 1}, {"runtime.panicdottypeI", 1}, {"runtime.panicnildottype", 1}, {"runtime.typeAssert", 1}, {"runtime.interfaceSwitch", 1}, {"runtime.ifaceeq", 1}, {"runtime.efaceeq", 1}, {"runtime.panicrangeexit", 1}, {"runtime.deferrangefunc", 1}, {"runtime.rand32", 1}, {"runtime.makemap64", 1}, {"runtime.makemap", 1}, {"runtime.makemap_small", 1}, {"runtime.mapaccess1", 1}, {"runtime.mapaccess1_fast32", 1}, {"runtime.mapaccess1_fast64", 1}, {"runtime.mapaccess1_faststr", 1}, {"runtime.mapaccess1_fat", 1}, {"runtime.mapaccess2", 1}, {"runtime.mapaccess2_fast32", 1}, {"runtime.mapaccess2_fast64", 1}, {"runtime.mapaccess2_faststr", 1}, {"runtime.mapaccess2_fat", 1}, {"runtime.mapassign", 1}, {"runtime.mapassign_fast32", 1}, {"runtime.mapassign_fast32ptr", 1}, {"runtime.mapassign_fast64", 1}, {"runtime.mapassign_fast64ptr", 1}, {"runtime.mapassign_faststr", 1}, {"runtime.mapiterinit", 1}, {"runtime.mapdelete", 1}, {"runtime.mapdelete_fast32", 1}, {"runtime.mapdelete_fast64", 1}, {"runtime.mapdelete_faststr", 1}, {"runtime.mapiternext", 1}, {"runtime.mapclear", 1}, {"runtime.makechan64", 1}, {"runtime.makechan", 1}, {"runtime.chanrecv1", 1}, {"runtime.chanrecv2", 1}, {"runtime.chansend1", 1}, {"runtime.closechan", 1}, {"runtime.writeBarrier", 0}, {"runtime.typedmemmove", 1}, {"runtime.typedmemclr", 1}, {"runtime.typedslicecopy", 1}, {"runtime.selectnbsend", 1}, {"runtime.selectnbrecv", 1}, {"runtime.selectsetpc", 1}, {"runtime.selectgo", 1}, {"runtime.block", 1}, {"runtime.makeslice", 1}, {"runtime.makeslice64", 1}, {"runtime.makeslicecopy", 1}, {"runtime.growslice", 1}, {"runtime.unsafeslicecheckptr", 1}, {"runtime.panicunsafeslicelen", 1}, {"runtime.panicunsafeslicenilptr", 1}, {"runtime.unsafestringcheckptr", 1}, {"runtime.panicunsafestringlen", 1}, {"runtime.panicunsafestringnilptr", 1}, {"runtime.memmove", 1}, {"runtime.memclrNoHeapPointers", 1}, {"runtime.memclrHasPointers", 1}, {"runtime.memequal", 1}, {"runtime.memequal0", 1}, {"runtime.memequal8", 1}, {"runtime.memequal16", 1}, {"runtime.memequal32", 1}, {"runtime.memequal64", 1}, {"runtime.memequal128", 1}, {"runtime.f32equal", 1}, {"runtime.f64equal", 1}, {"runtime.c64equal", 1}, {"runtime.c128equal", 1}, {"runtime.strequal", 1}, {"runtime.interequal", 1}, {"runtime.nilinterequal", 1}, {"runtime.memhash", 1}, {"runtime.memhash0", 1}, {"runtime.memhash8", 1}, {"runtime.memhash16", 1}, {"runtime.memhash32", 1}, {"runtime.memhash64", 1}, {"runtime.memhash128", 1}, {"runtime.f32hash", 1}, {"runtime.f64hash", 1}, {"runtime.c64hash", 1}, {"runtime.c128hash", 1}, {"runtime.strhash", 1}, {"runtime.interhash", 1}, {"runtime.nilinterhash", 1}, {"runtime.int64div", 1}, {"runtime.uint64div", 1}, {"runtime.int64mod", 1}, {"runtime.uint64mod", 1}, {"runtime.float64toint64", 1}, {"runtime.float64touint64", 1}, {"runtime.float64touint32", 1}, {"runtime.int64tofloat64", 1}, {"runtime.int64tofloat32", 1}, {"runtime.uint64tofloat64", 1}, {"runtime.uint64tofloat32", 1}, {"runtime.uint32tofloat64", 1}, {"runtime.complex128div", 1}, {"runtime.getcallerpc", 1}, {"runtime.getcallersp", 1}, {"runtime.racefuncenter", 1}, {"runtime.racefuncexit", 1}, {"runtime.raceread", 1}, {"runtime.racewrite", 1}, {"runtime.racereadrange", 1}, {"runtime.racewriterange", 1}, {"runtime.msanread", 1}, {"runtime.msanwrite", 1}, {"runtime.msanmove", 1}, {"runtime.asanread", 1}, {"runtime.asanwrite", 1}, {"runtime.checkptrAlignment", 1}, {"runtime.checkptrArithmetic", 1}, {"runtime.libfuzzerTraceCmp1", 1}, {"runtime.libfuzzerTraceCmp2", 1}, {"runtime.libfuzzerTraceCmp4", 1}, {"runtime.libfuzzerTraceCmp8", 1}, {"runtime.libfuzzerTraceConstCmp1", 1}, {"runtime.libfuzzerTraceConstCmp2", 1}, {"runtime.libfuzzerTraceConstCmp4", 1}, {"runtime.libfuzzerTraceConstCmp8", 1}, {"runtime.libfuzzerHookStrCmp", 1}, {"runtime.libfuzzerHookEqualFold", 1}, {"runtime.addCovMeta", 1}, {"runtime.x86HasPOPCNT", 0}, {"runtime.x86HasSSE41", 0}, {"runtime.x86HasFMA", 0}, {"runtime.armHasVFPv4", 0}, {"runtime.arm64HasATOMICS", 0}, {"runtime.asanregisterglobals", 1}, {"runtime.deferproc", 1}, {"runtime.deferprocStack", 1}, {"runtime.deferreturn", 1}, {"runtime.newproc", 1}, {"runtime.panicoverflow", 1}, {"runtime.sigpanic", 1}, {"runtime.gcWriteBarrier", 1}, {"runtime.duffzero", 1}, {"runtime.duffcopy", 1}, {"runtime.morestack", 0}, {"runtime.morestackc", 0}, {"runtime.morestack_noctxt", 0}, {"type:int8", 0}, {"type:*int8", 0}, {"type:uint8", 0}, {"type:*uint8", 0}, {"type:int16", 0}, {"type:*int16", 0}, {"type:uint16", 0}, {"type:*uint16", 0}, {"type:int32", 0}, {"type:*int32", 0}, {"type:uint32", 0}, {"type:*uint32", 0}, {"type:int64", 0}, {"type:*int64", 0}, {"type:uint64", 0}, {"type:*uint64", 0}, {"type:float32", 0}, {"type:*float32", 0}, {"type:float64", 0}, {"type:*float64", 0}, {"type:complex64", 0}, {"type:*complex64", 0}, {"type:complex128", 0}, {"type:*complex128", 0}, {"type:unsafe.Pointer", 0}, {"type:*unsafe.Pointer", 0}, {"type:uintptr", 0}, {"type:*uintptr", 0}, {"type:bool", 0}, {"type:*bool", 0}, {"type:string", 0}, {"type:*string", 0}, {"type:error", 0}, {"type:*error", 0}, {"type:func(error) string", 0}, {"type:*func(error) string", 0}, } PK ! 4U�\ \ builtin.gonu �[��� // 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. package goobj import "internal/buildcfg" // Builtin (compiler-generated) function references appear // frequently. We assign special indices for them, so they // don't need to be referenced by name. // NBuiltin returns the number of listed builtin // symbols. func NBuiltin() int { return len(builtins) } // BuiltinName returns the name and ABI of the i-th // builtin symbol. func BuiltinName(i int) (string, int) { return builtins[i].name, builtins[i].abi } // BuiltinIdx returns the index of the builtin with the // given name and abi, or -1 if it is not a builtin. func BuiltinIdx(name string, abi int) int { i, ok := builtinMap[name] if !ok { return -1 } if buildcfg.Experiment.RegabiWrappers && builtins[i].abi != abi { return -1 } return i } //go:generate go run mkbuiltin.go var builtinMap map[string]int func init() { builtinMap = make(map[string]int, len(builtins)) for i, b := range builtins { builtinMap[b.name] = i } } PK ! �39b b funcinfo.gonu �[��� // 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. package goobj import ( "bytes" "encoding/binary" "internal/abi" ) // CUFileIndex is used to index the filenames that are stored in the // per-package/per-CU FileList. type CUFileIndex uint32 // FuncInfo is serialized as a symbol (aux symbol). The symbol data is // the binary encoding of the struct below. type FuncInfo struct { Args uint32 Locals uint32 FuncID abi.FuncID FuncFlag abi.FuncFlag StartLine int32 File []CUFileIndex InlTree []InlTreeNode } func (a *FuncInfo) Write(w *bytes.Buffer) { writeUint8 := func(x uint8) { w.WriteByte(x) } var b [4]byte writeUint32 := func(x uint32) { binary.LittleEndian.PutUint32(b[:], x) w.Write(b[:]) } writeUint32(a.Args) writeUint32(a.Locals) writeUint8(uint8(a.FuncID)) writeUint8(uint8(a.FuncFlag)) writeUint8(0) // pad to uint32 boundary writeUint8(0) writeUint32(uint32(a.StartLine)) writeUint32(uint32(len(a.File))) for _, f := range a.File { writeUint32(uint32(f)) } writeUint32(uint32(len(a.InlTree))) for i := range a.InlTree { a.InlTree[i].Write(w) } } // FuncInfoLengths is a cache containing a roadmap of offsets and // lengths for things within a serialized FuncInfo. Each length field // stores the number of items (e.g. files, inltree nodes, etc), and the // corresponding "off" field stores the byte offset of the start of // the items in question. type FuncInfoLengths struct { NumFile uint32 FileOff uint32 NumInlTree uint32 InlTreeOff uint32 Initialized bool } func (*FuncInfo) ReadFuncInfoLengths(b []byte) FuncInfoLengths { var result FuncInfoLengths // Offset to the number of the file table. This value is determined by counting // the number of bytes until we write funcdataoff to the file. const numfileOff = 16 result.NumFile = binary.LittleEndian.Uint32(b[numfileOff:]) result.FileOff = numfileOff + 4 numinltreeOff := result.FileOff + 4*result.NumFile result.NumInlTree = binary.LittleEndian.Uint32(b[numinltreeOff:]) result.InlTreeOff = numinltreeOff + 4 result.Initialized = true return result } func (*FuncInfo) ReadArgs(b []byte) uint32 { return binary.LittleEndian.Uint32(b) } func (*FuncInfo) ReadLocals(b []byte) uint32 { return binary.LittleEndian.Uint32(b[4:]) } func (*FuncInfo) ReadFuncID(b []byte) abi.FuncID { return abi.FuncID(b[8]) } func (*FuncInfo) ReadFuncFlag(b []byte) abi.FuncFlag { return abi.FuncFlag(b[9]) } func (*FuncInfo) ReadStartLine(b []byte) int32 { return int32(binary.LittleEndian.Uint32(b[12:])) } func (*FuncInfo) ReadFile(b []byte, filesoff uint32, k uint32) CUFileIndex { return CUFileIndex(binary.LittleEndian.Uint32(b[filesoff+4*k:])) } func (*FuncInfo) ReadInlTree(b []byte, inltreeoff uint32, k uint32) InlTreeNode { const inlTreeNodeSize = 4 * 6 var result InlTreeNode result.Read(b[inltreeoff+k*inlTreeNodeSize:]) return result } // InlTreeNode is the serialized form of FileInfo.InlTree. type InlTreeNode struct { Parent int32 File CUFileIndex Line int32 Func SymRef ParentPC int32 } func (inl *InlTreeNode) Write(w *bytes.Buffer) { var b [4]byte writeUint32 := func(x uint32) { binary.LittleEndian.PutUint32(b[:], x) w.Write(b[:]) } writeUint32(uint32(inl.Parent)) writeUint32(uint32(inl.File)) writeUint32(uint32(inl.Line)) writeUint32(inl.Func.PkgIdx) writeUint32(inl.Func.SymIdx) writeUint32(uint32(inl.ParentPC)) } // Read an InlTreeNode from b, return the remaining bytes. func (inl *InlTreeNode) Read(b []byte) []byte { readUint32 := func() uint32 { x := binary.LittleEndian.Uint32(b) b = b[4:] return x } inl.Parent = int32(readUint32()) inl.File = CUFileIndex(readUint32()) inl.Line = int32(readUint32()) inl.Func = SymRef{readUint32(), readUint32()} inl.ParentPC = int32(readUint32()) return b } PK ! v��� � objfile_test.gonu �[��� // Copyright 2020 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. package goobj import ( "bufio" "bytes" "fmt" "internal/buildcfg" "internal/testenv" "os" "testing" "cmd/internal/bio" "cmd/internal/objabi" ) func dummyWriter(buf *bytes.Buffer) *Writer { wr := &bio.Writer{Writer: bufio.NewWriter(buf)} // hacky: no file, so cannot seek return NewWriter(wr) } func TestReadWrite(t *testing.T) { // Test that we get the same data in a write-read roundtrip. // Write a symbol, a relocation, and an aux info. var buf bytes.Buffer w := dummyWriter(&buf) var s Sym s.SetABI(1) s.SetType(uint8(objabi.STEXT)) s.SetFlag(0x12) s.SetSiz(12345) s.SetAlign(8) s.Write(w) var r Reloc r.SetOff(12) r.SetSiz(4) r.SetType(uint16(objabi.R_ADDR)) r.SetAdd(54321) r.SetSym(SymRef{11, 22}) r.Write(w) var a Aux a.SetType(AuxFuncInfo) a.SetSym(SymRef{33, 44}) a.Write(w) w.wr.Flush() // Read them back and check. b := buf.Bytes() var s2 Sym s2.fromBytes(b) if s2.ABI() != 1 || s2.Type() != uint8(objabi.STEXT) || s2.Flag() != 0x12 || s2.Siz() != 12345 || s2.Align() != 8 { t.Errorf("read Sym2 mismatch: got %v %v %v %v %v", s2.ABI(), s2.Type(), s2.Flag(), s2.Siz(), s2.Align()) } b = b[SymSize:] var r2 Reloc r2.fromBytes(b) if r2.Off() != 12 || r2.Siz() != 4 || r2.Type() != uint16(objabi.R_ADDR) || r2.Add() != 54321 || r2.Sym() != (SymRef{11, 22}) { t.Errorf("read Reloc2 mismatch: got %v %v %v %v %v", r2.Off(), r2.Siz(), r2.Type(), r2.Add(), r2.Sym()) } b = b[RelocSize:] var a2 Aux a2.fromBytes(b) if a2.Type() != AuxFuncInfo || a2.Sym() != (SymRef{33, 44}) { t.Errorf("read Aux2 mismatch: got %v %v", a2.Type(), a2.Sym()) } } var issue41621prolog = ` package main var lines = []string{ ` var issue41621epilog = ` } func getLines() []string { return lines } func main() { println(getLines()) } ` func TestIssue41621LargeNumberOfRelocations(t *testing.T) { if testing.Short() || (buildcfg.GOARCH != "amd64") { t.Skipf("Skipping large number of relocations test in short mode or on %s", buildcfg.GOARCH) } testenv.MustHaveGoBuild(t) tmpdir, err := os.MkdirTemp("", "lotsofrelocs") if err != nil { t.Fatalf("can't create temp directory: %v\n", err) } defer os.RemoveAll(tmpdir) // Emit testcase. var w bytes.Buffer fmt.Fprintf(&w, issue41621prolog) for i := 0; i < 1048576+13; i++ { fmt.Fprintf(&w, "\t\"%d\",\n", i) } fmt.Fprintf(&w, issue41621epilog) err = os.WriteFile(tmpdir+"/large.go", w.Bytes(), 0666) if err != nil { t.Fatalf("can't write output: %v\n", err) } // Emit go.mod w.Reset() fmt.Fprintf(&w, "module issue41621\n\ngo 1.12\n") err = os.WriteFile(tmpdir+"/go.mod", w.Bytes(), 0666) if err != nil { t.Fatalf("can't write output: %v\n", err) } w.Reset() // Build. cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", "large") cmd.Dir = tmpdir out, err := cmd.CombinedOutput() if err != nil { t.Fatalf("Build failed: %v, output: %s", err, out) } } PK ! �5�f f mkbuiltin.gonu �[��� // 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. //go:build ignore // Generate builtinlist.go from cmd/compile/internal/typecheck/builtin/runtime.go. package main import ( "bytes" "flag" "fmt" "go/ast" "go/format" "go/parser" "go/token" "io" "log" "os" "path/filepath" "strings" ) var stdout = flag.Bool("stdout", false, "write to stdout instead of builtinlist.go") func main() { flag.Parse() var b bytes.Buffer fmt.Fprintln(&b, "// Code generated by mkbuiltin.go. DO NOT EDIT.") fmt.Fprintln(&b) fmt.Fprintln(&b, "package goobj") mkbuiltin(&b) out, err := format.Source(b.Bytes()) if err != nil { log.Fatal(err) } if *stdout { _, err = os.Stdout.Write(out) } else { err = os.WriteFile("builtinlist.go", out, 0666) } if err != nil { log.Fatal(err) } } func mkbuiltin(w io.Writer) { pkg := "runtime" fset := token.NewFileSet() path := filepath.Join("..", "..", "compile", "internal", "typecheck", "_builtin", "runtime.go") f, err := parser.ParseFile(fset, path, nil, 0) if err != nil { log.Fatal(err) } decls := make(map[string]bool) fmt.Fprintf(w, "var builtins = [...]struct{ name string; abi int }{\n") for _, decl := range f.Decls { switch decl := decl.(type) { case *ast.FuncDecl: if decl.Recv != nil { log.Fatal("methods unsupported") } if decl.Body != nil { log.Fatal("unexpected function body") } declName := pkg + "." + decl.Name.Name decls[declName] = true fmt.Fprintf(w, "{%q, 1},\n", declName) // functions are ABIInternal (1) case *ast.GenDecl: if decl.Tok == token.IMPORT { continue } if decl.Tok != token.VAR { log.Fatal("unhandled declaration kind", decl.Tok) } for _, spec := range decl.Specs { spec := spec.(*ast.ValueSpec) if len(spec.Values) != 0 { log.Fatal("unexpected values") } for _, name := range spec.Names { declName := pkg + "." + name.Name decls[declName] = true fmt.Fprintf(w, "{%q, 0},\n", declName) // variables are ABI0 } } default: log.Fatal("unhandled decl type", decl) } } // The list above only contains ones that are used by the frontend. // The backend may create more references of builtin functions. // We also want to include predefined types. // Add them. extras := append(fextras[:], enumerateBasicTypes()...) for _, b := range extras { prefix := "" if !strings.HasPrefix(b.name, "type:") { prefix = pkg + "." } name := prefix + b.name if decls[name] { log.Fatalf("%q already added -- mkbuiltin.go out of sync?", name) } fmt.Fprintf(w, "{%q, %d},\n", name, b.abi) } fmt.Fprintln(w, "}") } // enumerateBasicTypes returns the symbol names for basic types that are // defined in the runtime and referenced in other packages. // Needs to be kept in sync with reflect.go:WriteBasicTypes() and // reflect.go:writeType() in the compiler. func enumerateBasicTypes() []extra { names := [...]string{ "int8", "uint8", "int16", "uint16", "int32", "uint32", "int64", "uint64", "float32", "float64", "complex64", "complex128", "unsafe.Pointer", "uintptr", "bool", "string", "error", "func(error) string"} result := []extra{} for _, n := range names { result = append(result, extra{"type:" + n, 0}) result = append(result, extra{"type:*" + n, 0}) } return result } type extra struct { name string abi int } var fextras = [...]extra{ // compiler frontend inserted calls (sysfunc) {"deferproc", 1}, {"deferprocStack", 1}, {"deferreturn", 1}, {"newproc", 1}, {"panicoverflow", 1}, {"sigpanic", 1}, // compiler backend inserted calls {"gcWriteBarrier", 1}, {"duffzero", 1}, {"duffcopy", 1}, // assembler backend inserted calls {"morestack", 0}, // asm function, ABI0 {"morestackc", 0}, // asm function, ABI0 {"morestack_noctxt", 0}, // asm function, ABI0 } PK ! �!p�^ ^ objfile.gonu �[��� PK ! 2�� I I F^ builtinlist.gonu �[��� PK ! 4U�\ \ �{ builtin.gonu �[��� PK ! �39b b c� funcinfo.gonu �[��� PK ! v��� � � objfile_test.gonu �[��� PK ! �5�f f 9� mkbuiltin.gonu �[��� PK � ۫
| ver. 1.1 | |
.
| PHP 8.4.18 | Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтраницы: 0 |
proxy
|
phpinfo
|
ÐаÑтройка