mirror of
https://github.com/golang/go
synced 2024-10-14 03:43:28 +00:00
[dev.regabi] all: merge master into dev.regabi
The list of conflicted files for this merge is: src/cmd/compile/internal/gc/inl.go src/cmd/compile/internal/gc/order.go src/cmd/compile/internal/gc/ssa.go test/fixedbugs/issue20415.go test/fixedbugs/issue22822.go test/fixedbugs/issue28079b.go inl.go was updated for changes on dev.regabi: namely that OSELRECV has been removed, and that OSELRECV2 now only uses List, rather than both Left and List. order.go was updated IsAutoTmp is now a standalone function, rather than a method on Node. ssa.go was similarly updated for new APIs involving package ir. The tests are all merging upstream additions for gccgo error messages with changes to cmd/compile's error messages on the dev.regabi branch. Change-Id: Icaaf186d69da791b5994dbb6688ec989caabec42
This commit is contained in:
commit
ca8e17164e
481
api/go1.16.txt
Normal file
481
api/go1.16.txt
Normal file
|
@ -0,0 +1,481 @@
|
|||
pkg archive/zip, method (*ReadCloser) Open(string) (fs.File, error)
|
||||
pkg archive/zip, method (*Reader) Open(string) (fs.File, error)
|
||||
pkg crypto/x509, method (SystemRootsError) Unwrap() error
|
||||
pkg crypto/x509, type CertificateRequest struct, BasicConstraintsValid bool
|
||||
pkg crypto/x509, type CertificateRequest struct, ExtKeyUsage []ExtKeyUsage
|
||||
pkg crypto/x509, type CertificateRequest struct, IsCA bool
|
||||
pkg crypto/x509, type CertificateRequest struct, KeyUsage KeyUsage
|
||||
pkg crypto/x509, type CertificateRequest struct, MaxPathLen int
|
||||
pkg crypto/x509, type CertificateRequest struct, MaxPathLenZero bool
|
||||
pkg crypto/x509, type CertificateRequest struct, PolicyIdentifiers []asn1.ObjectIdentifier
|
||||
pkg crypto/x509, type CertificateRequest struct, SubjectKeyId []uint8
|
||||
pkg crypto/x509, type CertificateRequest struct, UnknownExtKeyUsage []asn1.ObjectIdentifier
|
||||
pkg debug/elf, const DT_ADDRRNGHI = 1879047935
|
||||
pkg debug/elf, const DT_ADDRRNGHI DynTag
|
||||
pkg debug/elf, const DT_ADDRRNGLO = 1879047680
|
||||
pkg debug/elf, const DT_ADDRRNGLO DynTag
|
||||
pkg debug/elf, const DT_AUDIT = 1879047932
|
||||
pkg debug/elf, const DT_AUDIT DynTag
|
||||
pkg debug/elf, const DT_AUXILIARY = 2147483645
|
||||
pkg debug/elf, const DT_AUXILIARY DynTag
|
||||
pkg debug/elf, const DT_CHECKSUM = 1879047672
|
||||
pkg debug/elf, const DT_CHECKSUM DynTag
|
||||
pkg debug/elf, const DT_CONFIG = 1879047930
|
||||
pkg debug/elf, const DT_CONFIG DynTag
|
||||
pkg debug/elf, const DT_DEPAUDIT = 1879047931
|
||||
pkg debug/elf, const DT_DEPAUDIT DynTag
|
||||
pkg debug/elf, const DT_FEATURE = 1879047676
|
||||
pkg debug/elf, const DT_FEATURE DynTag
|
||||
pkg debug/elf, const DT_FILTER = 2147483647
|
||||
pkg debug/elf, const DT_FILTER DynTag
|
||||
pkg debug/elf, const DT_FLAGS_1 = 1879048187
|
||||
pkg debug/elf, const DT_FLAGS_1 DynTag
|
||||
pkg debug/elf, const DT_GNU_CONFLICT = 1879047928
|
||||
pkg debug/elf, const DT_GNU_CONFLICT DynTag
|
||||
pkg debug/elf, const DT_GNU_CONFLICTSZ = 1879047670
|
||||
pkg debug/elf, const DT_GNU_CONFLICTSZ DynTag
|
||||
pkg debug/elf, const DT_GNU_HASH = 1879047925
|
||||
pkg debug/elf, const DT_GNU_HASH DynTag
|
||||
pkg debug/elf, const DT_GNU_LIBLIST = 1879047929
|
||||
pkg debug/elf, const DT_GNU_LIBLIST DynTag
|
||||
pkg debug/elf, const DT_GNU_LIBLISTSZ = 1879047671
|
||||
pkg debug/elf, const DT_GNU_LIBLISTSZ DynTag
|
||||
pkg debug/elf, const DT_GNU_PRELINKED = 1879047669
|
||||
pkg debug/elf, const DT_GNU_PRELINKED DynTag
|
||||
pkg debug/elf, const DT_MIPS_AUX_DYNAMIC = 1879048241
|
||||
pkg debug/elf, const DT_MIPS_AUX_DYNAMIC DynTag
|
||||
pkg debug/elf, const DT_MIPS_BASE_ADDRESS = 1879048198
|
||||
pkg debug/elf, const DT_MIPS_BASE_ADDRESS DynTag
|
||||
pkg debug/elf, const DT_MIPS_COMPACT_SIZE = 1879048239
|
||||
pkg debug/elf, const DT_MIPS_COMPACT_SIZE DynTag
|
||||
pkg debug/elf, const DT_MIPS_CONFLICT = 1879048200
|
||||
pkg debug/elf, const DT_MIPS_CONFLICT DynTag
|
||||
pkg debug/elf, const DT_MIPS_CONFLICTNO = 1879048203
|
||||
pkg debug/elf, const DT_MIPS_CONFLICTNO DynTag
|
||||
pkg debug/elf, const DT_MIPS_CXX_FLAGS = 1879048226
|
||||
pkg debug/elf, const DT_MIPS_CXX_FLAGS DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASS = 1879048215
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASS DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASSSYM = 1879048224
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASSSYM DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASSSYM_NO = 1879048225
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASSSYM_NO DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASS_NO = 1879048216
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASS_NO DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_INSTANCE = 1879048217
|
||||
pkg debug/elf, const DT_MIPS_DELTA_INSTANCE DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_INSTANCE_NO = 1879048218
|
||||
pkg debug/elf, const DT_MIPS_DELTA_INSTANCE_NO DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_RELOC = 1879048219
|
||||
pkg debug/elf, const DT_MIPS_DELTA_RELOC DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_RELOC_NO = 1879048220
|
||||
pkg debug/elf, const DT_MIPS_DELTA_RELOC_NO DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_SYM = 1879048221
|
||||
pkg debug/elf, const DT_MIPS_DELTA_SYM DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_SYM_NO = 1879048222
|
||||
pkg debug/elf, const DT_MIPS_DELTA_SYM_NO DynTag
|
||||
pkg debug/elf, const DT_MIPS_DYNSTR_ALIGN = 1879048235
|
||||
pkg debug/elf, const DT_MIPS_DYNSTR_ALIGN DynTag
|
||||
pkg debug/elf, const DT_MIPS_FLAGS = 1879048197
|
||||
pkg debug/elf, const DT_MIPS_FLAGS DynTag
|
||||
pkg debug/elf, const DT_MIPS_GOTSYM = 1879048211
|
||||
pkg debug/elf, const DT_MIPS_GOTSYM DynTag
|
||||
pkg debug/elf, const DT_MIPS_GP_VALUE = 1879048240
|
||||
pkg debug/elf, const DT_MIPS_GP_VALUE DynTag
|
||||
pkg debug/elf, const DT_MIPS_HIDDEN_GOTIDX = 1879048231
|
||||
pkg debug/elf, const DT_MIPS_HIDDEN_GOTIDX DynTag
|
||||
pkg debug/elf, const DT_MIPS_HIPAGENO = 1879048212
|
||||
pkg debug/elf, const DT_MIPS_HIPAGENO DynTag
|
||||
pkg debug/elf, const DT_MIPS_ICHECKSUM = 1879048195
|
||||
pkg debug/elf, const DT_MIPS_ICHECKSUM DynTag
|
||||
pkg debug/elf, const DT_MIPS_INTERFACE = 1879048234
|
||||
pkg debug/elf, const DT_MIPS_INTERFACE DynTag
|
||||
pkg debug/elf, const DT_MIPS_INTERFACE_SIZE = 1879048236
|
||||
pkg debug/elf, const DT_MIPS_INTERFACE_SIZE DynTag
|
||||
pkg debug/elf, const DT_MIPS_IVERSION = 1879048196
|
||||
pkg debug/elf, const DT_MIPS_IVERSION DynTag
|
||||
pkg debug/elf, const DT_MIPS_LIBLIST = 1879048201
|
||||
pkg debug/elf, const DT_MIPS_LIBLIST DynTag
|
||||
pkg debug/elf, const DT_MIPS_LIBLISTNO = 1879048208
|
||||
pkg debug/elf, const DT_MIPS_LIBLISTNO DynTag
|
||||
pkg debug/elf, const DT_MIPS_LOCALPAGE_GOTIDX = 1879048229
|
||||
pkg debug/elf, const DT_MIPS_LOCALPAGE_GOTIDX DynTag
|
||||
pkg debug/elf, const DT_MIPS_LOCAL_GOTIDX = 1879048230
|
||||
pkg debug/elf, const DT_MIPS_LOCAL_GOTIDX DynTag
|
||||
pkg debug/elf, const DT_MIPS_LOCAL_GOTNO = 1879048202
|
||||
pkg debug/elf, const DT_MIPS_LOCAL_GOTNO DynTag
|
||||
pkg debug/elf, const DT_MIPS_MSYM = 1879048199
|
||||
pkg debug/elf, const DT_MIPS_MSYM DynTag
|
||||
pkg debug/elf, const DT_MIPS_OPTIONS = 1879048233
|
||||
pkg debug/elf, const DT_MIPS_OPTIONS DynTag
|
||||
pkg debug/elf, const DT_MIPS_PERF_SUFFIX = 1879048238
|
||||
pkg debug/elf, const DT_MIPS_PERF_SUFFIX DynTag
|
||||
pkg debug/elf, const DT_MIPS_PIXIE_INIT = 1879048227
|
||||
pkg debug/elf, const DT_MIPS_PIXIE_INIT DynTag
|
||||
pkg debug/elf, const DT_MIPS_PLTGOT = 1879048242
|
||||
pkg debug/elf, const DT_MIPS_PLTGOT DynTag
|
||||
pkg debug/elf, const DT_MIPS_PROTECTED_GOTIDX = 1879048232
|
||||
pkg debug/elf, const DT_MIPS_PROTECTED_GOTIDX DynTag
|
||||
pkg debug/elf, const DT_MIPS_RLD_MAP = 1879048214
|
||||
pkg debug/elf, const DT_MIPS_RLD_MAP DynTag
|
||||
pkg debug/elf, const DT_MIPS_RLD_MAP_REL = 1879048245
|
||||
pkg debug/elf, const DT_MIPS_RLD_MAP_REL DynTag
|
||||
pkg debug/elf, const DT_MIPS_RLD_TEXT_RESOLVE_ADDR = 1879048237
|
||||
pkg debug/elf, const DT_MIPS_RLD_TEXT_RESOLVE_ADDR DynTag
|
||||
pkg debug/elf, const DT_MIPS_RLD_VERSION = 1879048193
|
||||
pkg debug/elf, const DT_MIPS_RLD_VERSION DynTag
|
||||
pkg debug/elf, const DT_MIPS_RWPLT = 1879048244
|
||||
pkg debug/elf, const DT_MIPS_RWPLT DynTag
|
||||
pkg debug/elf, const DT_MIPS_SYMBOL_LIB = 1879048228
|
||||
pkg debug/elf, const DT_MIPS_SYMBOL_LIB DynTag
|
||||
pkg debug/elf, const DT_MIPS_SYMTABNO = 1879048209
|
||||
pkg debug/elf, const DT_MIPS_SYMTABNO DynTag
|
||||
pkg debug/elf, const DT_MIPS_TIME_STAMP = 1879048194
|
||||
pkg debug/elf, const DT_MIPS_TIME_STAMP DynTag
|
||||
pkg debug/elf, const DT_MIPS_UNREFEXTNO = 1879048210
|
||||
pkg debug/elf, const DT_MIPS_UNREFEXTNO DynTag
|
||||
pkg debug/elf, const DT_MOVEENT = 1879047674
|
||||
pkg debug/elf, const DT_MOVEENT DynTag
|
||||
pkg debug/elf, const DT_MOVESZ = 1879047675
|
||||
pkg debug/elf, const DT_MOVESZ DynTag
|
||||
pkg debug/elf, const DT_MOVETAB = 1879047934
|
||||
pkg debug/elf, const DT_MOVETAB DynTag
|
||||
pkg debug/elf, const DT_PLTPAD = 1879047933
|
||||
pkg debug/elf, const DT_PLTPAD DynTag
|
||||
pkg debug/elf, const DT_PLTPADSZ = 1879047673
|
||||
pkg debug/elf, const DT_PLTPADSZ DynTag
|
||||
pkg debug/elf, const DT_POSFLAG_1 = 1879047677
|
||||
pkg debug/elf, const DT_POSFLAG_1 DynTag
|
||||
pkg debug/elf, const DT_PPC64_GLINK = 1879048192
|
||||
pkg debug/elf, const DT_PPC64_GLINK DynTag
|
||||
pkg debug/elf, const DT_PPC64_OPD = 1879048193
|
||||
pkg debug/elf, const DT_PPC64_OPD DynTag
|
||||
pkg debug/elf, const DT_PPC64_OPDSZ = 1879048194
|
||||
pkg debug/elf, const DT_PPC64_OPDSZ DynTag
|
||||
pkg debug/elf, const DT_PPC64_OPT = 1879048195
|
||||
pkg debug/elf, const DT_PPC64_OPT DynTag
|
||||
pkg debug/elf, const DT_PPC_GOT = 1879048192
|
||||
pkg debug/elf, const DT_PPC_GOT DynTag
|
||||
pkg debug/elf, const DT_PPC_OPT = 1879048193
|
||||
pkg debug/elf, const DT_PPC_OPT DynTag
|
||||
pkg debug/elf, const DT_RELACOUNT = 1879048185
|
||||
pkg debug/elf, const DT_RELACOUNT DynTag
|
||||
pkg debug/elf, const DT_RELCOUNT = 1879048186
|
||||
pkg debug/elf, const DT_RELCOUNT DynTag
|
||||
pkg debug/elf, const DT_SPARC_REGISTER = 1879048193
|
||||
pkg debug/elf, const DT_SPARC_REGISTER DynTag
|
||||
pkg debug/elf, const DT_SYMINENT = 1879047679
|
||||
pkg debug/elf, const DT_SYMINENT DynTag
|
||||
pkg debug/elf, const DT_SYMINFO = 1879047935
|
||||
pkg debug/elf, const DT_SYMINFO DynTag
|
||||
pkg debug/elf, const DT_SYMINSZ = 1879047678
|
||||
pkg debug/elf, const DT_SYMINSZ DynTag
|
||||
pkg debug/elf, const DT_SYMTAB_SHNDX = 34
|
||||
pkg debug/elf, const DT_SYMTAB_SHNDX DynTag
|
||||
pkg debug/elf, const DT_TLSDESC_GOT = 1879047927
|
||||
pkg debug/elf, const DT_TLSDESC_GOT DynTag
|
||||
pkg debug/elf, const DT_TLSDESC_PLT = 1879047926
|
||||
pkg debug/elf, const DT_TLSDESC_PLT DynTag
|
||||
pkg debug/elf, const DT_USED = 2147483646
|
||||
pkg debug/elf, const DT_USED DynTag
|
||||
pkg debug/elf, const DT_VALRNGHI = 1879047679
|
||||
pkg debug/elf, const DT_VALRNGHI DynTag
|
||||
pkg debug/elf, const DT_VALRNGLO = 1879047424
|
||||
pkg debug/elf, const DT_VALRNGLO DynTag
|
||||
pkg debug/elf, const DT_VERDEF = 1879048188
|
||||
pkg debug/elf, const DT_VERDEF DynTag
|
||||
pkg debug/elf, const DT_VERDEFNUM = 1879048189
|
||||
pkg debug/elf, const DT_VERDEFNUM DynTag
|
||||
pkg debug/elf, const PT_AARCH64_ARCHEXT = 1879048192
|
||||
pkg debug/elf, const PT_AARCH64_ARCHEXT ProgType
|
||||
pkg debug/elf, const PT_AARCH64_UNWIND = 1879048193
|
||||
pkg debug/elf, const PT_AARCH64_UNWIND ProgType
|
||||
pkg debug/elf, const PT_ARM_ARCHEXT = 1879048192
|
||||
pkg debug/elf, const PT_ARM_ARCHEXT ProgType
|
||||
pkg debug/elf, const PT_ARM_EXIDX = 1879048193
|
||||
pkg debug/elf, const PT_ARM_EXIDX ProgType
|
||||
pkg debug/elf, const PT_GNU_EH_FRAME = 1685382480
|
||||
pkg debug/elf, const PT_GNU_EH_FRAME ProgType
|
||||
pkg debug/elf, const PT_GNU_MBIND_HI = 1685386580
|
||||
pkg debug/elf, const PT_GNU_MBIND_HI ProgType
|
||||
pkg debug/elf, const PT_GNU_MBIND_LO = 1685382485
|
||||
pkg debug/elf, const PT_GNU_MBIND_LO ProgType
|
||||
pkg debug/elf, const PT_GNU_PROPERTY = 1685382483
|
||||
pkg debug/elf, const PT_GNU_PROPERTY ProgType
|
||||
pkg debug/elf, const PT_GNU_RELRO = 1685382482
|
||||
pkg debug/elf, const PT_GNU_RELRO ProgType
|
||||
pkg debug/elf, const PT_GNU_STACK = 1685382481
|
||||
pkg debug/elf, const PT_GNU_STACK ProgType
|
||||
pkg debug/elf, const PT_MIPS_ABIFLAGS = 1879048195
|
||||
pkg debug/elf, const PT_MIPS_ABIFLAGS ProgType
|
||||
pkg debug/elf, const PT_MIPS_OPTIONS = 1879048194
|
||||
pkg debug/elf, const PT_MIPS_OPTIONS ProgType
|
||||
pkg debug/elf, const PT_MIPS_REGINFO = 1879048192
|
||||
pkg debug/elf, const PT_MIPS_REGINFO ProgType
|
||||
pkg debug/elf, const PT_MIPS_RTPROC = 1879048193
|
||||
pkg debug/elf, const PT_MIPS_RTPROC ProgType
|
||||
pkg debug/elf, const PT_OPENBSD_BOOTDATA = 1705253862
|
||||
pkg debug/elf, const PT_OPENBSD_BOOTDATA ProgType
|
||||
pkg debug/elf, const PT_OPENBSD_RANDOMIZE = 1705237478
|
||||
pkg debug/elf, const PT_OPENBSD_RANDOMIZE ProgType
|
||||
pkg debug/elf, const PT_OPENBSD_WXNEEDED = 1705237479
|
||||
pkg debug/elf, const PT_OPENBSD_WXNEEDED ProgType
|
||||
pkg debug/elf, const PT_PAX_FLAGS = 1694766464
|
||||
pkg debug/elf, const PT_PAX_FLAGS ProgType
|
||||
pkg debug/elf, const PT_S390_PGSTE = 1879048192
|
||||
pkg debug/elf, const PT_S390_PGSTE ProgType
|
||||
pkg debug/elf, const PT_SUNWSTACK = 1879048187
|
||||
pkg debug/elf, const PT_SUNWSTACK ProgType
|
||||
pkg debug/elf, const PT_SUNW_EH_FRAME = 1685382480
|
||||
pkg debug/elf, const PT_SUNW_EH_FRAME ProgType
|
||||
pkg embed, method (FS) Open(string) (fs.File, error)
|
||||
pkg embed, method (FS) ReadDir(string) ([]fs.DirEntry, error)
|
||||
pkg embed, method (FS) ReadFile(string) ([]uint8, error)
|
||||
pkg embed, type FS struct
|
||||
pkg flag, func Func(string, string, func(string) error)
|
||||
pkg flag, method (*FlagSet) Func(string, string, func(string) error)
|
||||
pkg go/build, type Package struct, EmbedPatterns []string
|
||||
pkg go/build, type Package struct, IgnoredOtherFiles []string
|
||||
pkg go/build, type Package struct, TestEmbedPatterns []string
|
||||
pkg go/build, type Package struct, XTestEmbedPatterns []string
|
||||
pkg html/template, func ParseFS(fs.FS, ...string) (*Template, error)
|
||||
pkg html/template, method (*Template) ParseFS(fs.FS, ...string) (*Template, error)
|
||||
pkg io, func NopCloser(Reader) ReadCloser
|
||||
pkg io, func ReadAll(Reader) ([]uint8, error)
|
||||
pkg io, type ReadSeekCloser interface { Close, Read, Seek }
|
||||
pkg io, type ReadSeekCloser interface, Close() error
|
||||
pkg io, type ReadSeekCloser interface, Read([]uint8) (int, error)
|
||||
pkg io, type ReadSeekCloser interface, Seek(int64, int) (int64, error)
|
||||
pkg io, var Discard Writer
|
||||
pkg io/fs, const ModeAppend = 1073741824
|
||||
pkg io/fs, const ModeAppend FileMode
|
||||
pkg io/fs, const ModeCharDevice = 2097152
|
||||
pkg io/fs, const ModeCharDevice FileMode
|
||||
pkg io/fs, const ModeDevice = 67108864
|
||||
pkg io/fs, const ModeDevice FileMode
|
||||
pkg io/fs, const ModeDir = 2147483648
|
||||
pkg io/fs, const ModeDir FileMode
|
||||
pkg io/fs, const ModeExclusive = 536870912
|
||||
pkg io/fs, const ModeExclusive FileMode
|
||||
pkg io/fs, const ModeIrregular = 524288
|
||||
pkg io/fs, const ModeIrregular FileMode
|
||||
pkg io/fs, const ModeNamedPipe = 33554432
|
||||
pkg io/fs, const ModeNamedPipe FileMode
|
||||
pkg io/fs, const ModePerm = 511
|
||||
pkg io/fs, const ModePerm FileMode
|
||||
pkg io/fs, const ModeSetgid = 4194304
|
||||
pkg io/fs, const ModeSetgid FileMode
|
||||
pkg io/fs, const ModeSetuid = 8388608
|
||||
pkg io/fs, const ModeSetuid FileMode
|
||||
pkg io/fs, const ModeSocket = 16777216
|
||||
pkg io/fs, const ModeSocket FileMode
|
||||
pkg io/fs, const ModeSticky = 1048576
|
||||
pkg io/fs, const ModeSticky FileMode
|
||||
pkg io/fs, const ModeSymlink = 134217728
|
||||
pkg io/fs, const ModeSymlink FileMode
|
||||
pkg io/fs, const ModeTemporary = 268435456
|
||||
pkg io/fs, const ModeTemporary FileMode
|
||||
pkg io/fs, const ModeType = 2401763328
|
||||
pkg io/fs, const ModeType FileMode
|
||||
pkg io/fs, func Glob(FS, string) ([]string, error)
|
||||
pkg io/fs, func ReadDir(FS, string) ([]DirEntry, error)
|
||||
pkg io/fs, func ReadFile(FS, string) ([]uint8, error)
|
||||
pkg io/fs, func Stat(FS, string) (FileInfo, error)
|
||||
pkg io/fs, func Sub(FS, string) (FS, error)
|
||||
pkg io/fs, func ValidPath(string) bool
|
||||
pkg io/fs, func WalkDir(FS, string, WalkDirFunc) error
|
||||
pkg io/fs, method (*PathError) Error() string
|
||||
pkg io/fs, method (*PathError) Timeout() bool
|
||||
pkg io/fs, method (*PathError) Unwrap() error
|
||||
pkg io/fs, method (FileMode) IsDir() bool
|
||||
pkg io/fs, method (FileMode) IsRegular() bool
|
||||
pkg io/fs, method (FileMode) Perm() FileMode
|
||||
pkg io/fs, method (FileMode) String() string
|
||||
pkg io/fs, method (FileMode) Type() FileMode
|
||||
pkg io/fs, type DirEntry interface { Info, IsDir, Name, Type }
|
||||
pkg io/fs, type DirEntry interface, Info() (FileInfo, error)
|
||||
pkg io/fs, type DirEntry interface, IsDir() bool
|
||||
pkg io/fs, type DirEntry interface, Name() string
|
||||
pkg io/fs, type DirEntry interface, Type() FileMode
|
||||
pkg io/fs, type FS interface { Open }
|
||||
pkg io/fs, type FS interface, Open(string) (File, error)
|
||||
pkg io/fs, type File interface { Close, Read, Stat }
|
||||
pkg io/fs, type File interface, Close() error
|
||||
pkg io/fs, type File interface, Read([]uint8) (int, error)
|
||||
pkg io/fs, type File interface, Stat() (FileInfo, error)
|
||||
pkg io/fs, type FileInfo interface { IsDir, ModTime, Mode, Name, Size, Sys }
|
||||
pkg io/fs, type FileInfo interface, IsDir() bool
|
||||
pkg io/fs, type FileInfo interface, ModTime() time.Time
|
||||
pkg io/fs, type FileInfo interface, Mode() FileMode
|
||||
pkg io/fs, type FileInfo interface, Name() string
|
||||
pkg io/fs, type FileInfo interface, Size() int64
|
||||
pkg io/fs, type FileInfo interface, Sys() interface{}
|
||||
pkg io/fs, type FileMode uint32
|
||||
pkg io/fs, type GlobFS interface { Glob, Open }
|
||||
pkg io/fs, type GlobFS interface, Glob(string) ([]string, error)
|
||||
pkg io/fs, type GlobFS interface, Open(string) (File, error)
|
||||
pkg io/fs, type PathError struct
|
||||
pkg io/fs, type PathError struct, Err error
|
||||
pkg io/fs, type PathError struct, Op string
|
||||
pkg io/fs, type PathError struct, Path string
|
||||
pkg io/fs, type ReadDirFS interface { Open, ReadDir }
|
||||
pkg io/fs, type ReadDirFS interface, Open(string) (File, error)
|
||||
pkg io/fs, type ReadDirFS interface, ReadDir(string) ([]DirEntry, error)
|
||||
pkg io/fs, type ReadDirFile interface { Close, Read, ReadDir, Stat }
|
||||
pkg io/fs, type ReadDirFile interface, Close() error
|
||||
pkg io/fs, type ReadDirFile interface, Read([]uint8) (int, error)
|
||||
pkg io/fs, type ReadDirFile interface, ReadDir(int) ([]DirEntry, error)
|
||||
pkg io/fs, type ReadDirFile interface, Stat() (FileInfo, error)
|
||||
pkg io/fs, type ReadFileFS interface { Open, ReadFile }
|
||||
pkg io/fs, type ReadFileFS interface, Open(string) (File, error)
|
||||
pkg io/fs, type ReadFileFS interface, ReadFile(string) ([]uint8, error)
|
||||
pkg io/fs, type StatFS interface { Open, Stat }
|
||||
pkg io/fs, type StatFS interface, Open(string) (File, error)
|
||||
pkg io/fs, type StatFS interface, Stat(string) (FileInfo, error)
|
||||
pkg io/fs, type SubFS interface { Open, Sub }
|
||||
pkg io/fs, type SubFS interface, Open(string) (File, error)
|
||||
pkg io/fs, type SubFS interface, Sub(string) (FS, error)
|
||||
pkg io/fs, type WalkDirFunc func(string, DirEntry, error) error
|
||||
pkg io/fs, var ErrClosed error
|
||||
pkg io/fs, var ErrExist error
|
||||
pkg io/fs, var ErrInvalid error
|
||||
pkg io/fs, var ErrNotExist error
|
||||
pkg io/fs, var ErrPermission error
|
||||
pkg io/fs, var SkipDir error
|
||||
pkg log, func Default() *Logger
|
||||
pkg net, var ErrClosed error
|
||||
pkg net/http, func FS(fs.FS) FileSystem
|
||||
pkg net/http, type Transport struct, GetProxyConnectHeader func(context.Context, *url.URL, string) (Header, error)
|
||||
pkg os, const ModeAppend fs.FileMode
|
||||
pkg os, const ModeCharDevice fs.FileMode
|
||||
pkg os, const ModeDevice fs.FileMode
|
||||
pkg os, const ModeDir fs.FileMode
|
||||
pkg os, const ModeExclusive fs.FileMode
|
||||
pkg os, const ModeIrregular fs.FileMode
|
||||
pkg os, const ModeNamedPipe fs.FileMode
|
||||
pkg os, const ModePerm fs.FileMode
|
||||
pkg os, const ModeSetgid fs.FileMode
|
||||
pkg os, const ModeSetuid fs.FileMode
|
||||
pkg os, const ModeSocket fs.FileMode
|
||||
pkg os, const ModeSticky fs.FileMode
|
||||
pkg os, const ModeSymlink fs.FileMode
|
||||
pkg os, const ModeTemporary fs.FileMode
|
||||
pkg os, const ModeType fs.FileMode
|
||||
pkg os, func Chmod(string, fs.FileMode) error
|
||||
pkg os, func CreateTemp(string, string) (*File, error)
|
||||
pkg os, func DirFS(string) fs.FS
|
||||
pkg os, func Lstat(string) (fs.FileInfo, error)
|
||||
pkg os, func Mkdir(string, fs.FileMode) error
|
||||
pkg os, func MkdirAll(string, fs.FileMode) error
|
||||
pkg os, func MkdirTemp(string, string) (string, error)
|
||||
pkg os, func OpenFile(string, int, fs.FileMode) (*File, error)
|
||||
pkg os, func ReadDir(string) ([]fs.DirEntry, error)
|
||||
pkg os, func ReadFile(string) ([]uint8, error)
|
||||
pkg os, func SameFile(fs.FileInfo, fs.FileInfo) bool
|
||||
pkg os, func Stat(string) (fs.FileInfo, error)
|
||||
pkg os, func WriteFile(string, []uint8, fs.FileMode) error
|
||||
pkg os, method (*File) Chmod(fs.FileMode) error
|
||||
pkg os, method (*File) ReadDir(int) ([]fs.DirEntry, error)
|
||||
pkg os, method (*File) Readdir(int) ([]fs.FileInfo, error)
|
||||
pkg os, method (*File) Stat() (fs.FileInfo, error)
|
||||
pkg os, type DirEntry = fs.DirEntry
|
||||
pkg os, type FileInfo = fs.FileInfo
|
||||
pkg os, type FileMode = fs.FileMode
|
||||
pkg os, type PathError = fs.PathError
|
||||
pkg os, var ErrProcessDone error
|
||||
pkg os/signal, func NotifyContext(context.Context, ...os.Signal) (context.Context, context.CancelFunc)
|
||||
pkg path/filepath, func WalkDir(string, fs.WalkDirFunc) error
|
||||
pkg runtime/metrics, const KindBad = 0
|
||||
pkg runtime/metrics, const KindBad ValueKind
|
||||
pkg runtime/metrics, const KindFloat64 = 2
|
||||
pkg runtime/metrics, const KindFloat64 ValueKind
|
||||
pkg runtime/metrics, const KindFloat64Histogram = 3
|
||||
pkg runtime/metrics, const KindFloat64Histogram ValueKind
|
||||
pkg runtime/metrics, const KindUint64 = 1
|
||||
pkg runtime/metrics, const KindUint64 ValueKind
|
||||
pkg runtime/metrics, func All() []Description
|
||||
pkg runtime/metrics, func Read([]Sample)
|
||||
pkg runtime/metrics, method (Value) Float64() float64
|
||||
pkg runtime/metrics, method (Value) Float64Histogram() *Float64Histogram
|
||||
pkg runtime/metrics, method (Value) Kind() ValueKind
|
||||
pkg runtime/metrics, method (Value) Uint64() uint64
|
||||
pkg runtime/metrics, type Description struct
|
||||
pkg runtime/metrics, type Description struct, Cumulative bool
|
||||
pkg runtime/metrics, type Description struct, Description string
|
||||
pkg runtime/metrics, type Description struct, Kind ValueKind
|
||||
pkg runtime/metrics, type Description struct, Name string
|
||||
pkg runtime/metrics, type Description struct, StopTheWorld bool
|
||||
pkg runtime/metrics, type Float64Histogram struct
|
||||
pkg runtime/metrics, type Float64Histogram struct, Buckets []float64
|
||||
pkg runtime/metrics, type Float64Histogram struct, Counts []uint64
|
||||
pkg runtime/metrics, type Sample struct
|
||||
pkg runtime/metrics, type Sample struct, Name string
|
||||
pkg runtime/metrics, type Sample struct, Value Value
|
||||
pkg runtime/metrics, type Value struct
|
||||
pkg runtime/metrics, type ValueKind int
|
||||
pkg syscall (linux-386), func AllThreadsSyscall(uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-386), func AllThreadsSyscall6(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-386), func Setegid(int) error
|
||||
pkg syscall (linux-386), func Seteuid(int) error
|
||||
pkg syscall (linux-386-cgo), func AllThreadsSyscall(uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-386-cgo), func AllThreadsSyscall6(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-386-cgo), func Setegid(int) error
|
||||
pkg syscall (linux-386-cgo), func Seteuid(int) error
|
||||
pkg syscall (linux-amd64), func AllThreadsSyscall(uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-amd64), func AllThreadsSyscall6(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-amd64), func Setegid(int) error
|
||||
pkg syscall (linux-amd64), func Seteuid(int) error
|
||||
pkg syscall (linux-amd64-cgo), func AllThreadsSyscall(uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-amd64-cgo), func AllThreadsSyscall6(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-amd64-cgo), func Setegid(int) error
|
||||
pkg syscall (linux-amd64-cgo), func Seteuid(int) error
|
||||
pkg syscall (linux-arm), func AllThreadsSyscall(uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-arm), func AllThreadsSyscall6(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-arm), func Setegid(int) error
|
||||
pkg syscall (linux-arm), func Seteuid(int) error
|
||||
pkg syscall (linux-arm-cgo), func AllThreadsSyscall(uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-arm-cgo), func AllThreadsSyscall6(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-arm-cgo), func Setegid(int) error
|
||||
pkg syscall (linux-arm-cgo), func Seteuid(int) error
|
||||
pkg syscall (windows-386), func RtlGenRandom(*uint8, uint32) error
|
||||
pkg syscall (windows-386), method (*DLLError) Unwrap() error
|
||||
pkg syscall (windows-386), type SysProcAttr struct, NoInheritHandles bool
|
||||
pkg syscall (windows-amd64), func RtlGenRandom(*uint8, uint32) error
|
||||
pkg syscall (windows-amd64), method (*DLLError) Unwrap() error
|
||||
pkg syscall (windows-amd64), type SysProcAttr struct, NoInheritHandles bool
|
||||
pkg testing/fstest, func TestFS(fs.FS, ...string) error
|
||||
pkg testing/fstest, method (MapFS) Glob(string) ([]string, error)
|
||||
pkg testing/fstest, method (MapFS) Open(string) (fs.File, error)
|
||||
pkg testing/fstest, method (MapFS) ReadDir(string) ([]fs.DirEntry, error)
|
||||
pkg testing/fstest, method (MapFS) ReadFile(string) ([]uint8, error)
|
||||
pkg testing/fstest, method (MapFS) Stat(string) (fs.FileInfo, error)
|
||||
pkg testing/fstest, method (MapFS) Sub(string) (fs.FS, error)
|
||||
pkg testing/fstest, type MapFS map[string]*MapFile
|
||||
pkg testing/fstest, type MapFile struct
|
||||
pkg testing/fstest, type MapFile struct, Data []uint8
|
||||
pkg testing/fstest, type MapFile struct, ModTime time.Time
|
||||
pkg testing/fstest, type MapFile struct, Mode fs.FileMode
|
||||
pkg testing/fstest, type MapFile struct, Sys interface{}
|
||||
pkg testing/iotest, func ErrReader(error) io.Reader
|
||||
pkg testing/iotest, func TestReader(io.Reader, []uint8) error
|
||||
pkg text/template, func ParseFS(fs.FS, ...string) (*Template, error)
|
||||
pkg text/template, method (*Template) ParseFS(fs.FS, ...string) (*Template, error)
|
||||
pkg text/template/parse, const NodeComment = 20
|
||||
pkg text/template/parse, const NodeComment NodeType
|
||||
pkg text/template/parse, const ParseComments = 1
|
||||
pkg text/template/parse, const ParseComments Mode
|
||||
pkg text/template/parse, method (*CommentNode) Copy() Node
|
||||
pkg text/template/parse, method (*CommentNode) String() string
|
||||
pkg text/template/parse, method (CommentNode) Position() Pos
|
||||
pkg text/template/parse, method (CommentNode) Type() NodeType
|
||||
pkg text/template/parse, type CommentNode struct
|
||||
pkg text/template/parse, type CommentNode struct, Text string
|
||||
pkg text/template/parse, type CommentNode struct, embedded NodeType
|
||||
pkg text/template/parse, type CommentNode struct, embedded Pos
|
||||
pkg text/template/parse, type Mode uint
|
||||
pkg text/template/parse, type Tree struct, Mode Mode
|
||||
pkg unicode, const Version = "13.0.0"
|
||||
pkg unicode, var Chorasmian *RangeTable
|
||||
pkg unicode, var Dives_Akuru *RangeTable
|
||||
pkg unicode, var Khitan_Small_Script *RangeTable
|
||||
pkg unicode, var Yezidi *RangeTable
|
452
api/next.txt
452
api/next.txt
|
@ -1,452 +0,0 @@
|
|||
pkg archive/zip, method (*ReadCloser) Open(string) (fs.File, error)
|
||||
pkg archive/zip, method (*Reader) Open(string) (fs.File, error)
|
||||
pkg debug/elf, const DT_ADDRRNGHI = 1879047935
|
||||
pkg debug/elf, const DT_ADDRRNGHI DynTag
|
||||
pkg debug/elf, const DT_ADDRRNGLO = 1879047680
|
||||
pkg debug/elf, const DT_ADDRRNGLO DynTag
|
||||
pkg debug/elf, const DT_AUDIT = 1879047932
|
||||
pkg debug/elf, const DT_AUDIT DynTag
|
||||
pkg debug/elf, const DT_AUXILIARY = 2147483645
|
||||
pkg debug/elf, const DT_AUXILIARY DynTag
|
||||
pkg debug/elf, const DT_CHECKSUM = 1879047672
|
||||
pkg debug/elf, const DT_CHECKSUM DynTag
|
||||
pkg debug/elf, const DT_CONFIG = 1879047930
|
||||
pkg debug/elf, const DT_CONFIG DynTag
|
||||
pkg debug/elf, const DT_DEPAUDIT = 1879047931
|
||||
pkg debug/elf, const DT_DEPAUDIT DynTag
|
||||
pkg debug/elf, const DT_FEATURE = 1879047676
|
||||
pkg debug/elf, const DT_FEATURE DynTag
|
||||
pkg debug/elf, const DT_FILTER = 2147483647
|
||||
pkg debug/elf, const DT_FILTER DynTag
|
||||
pkg debug/elf, const DT_FLAGS_1 = 1879048187
|
||||
pkg debug/elf, const DT_FLAGS_1 DynTag
|
||||
pkg debug/elf, const DT_GNU_CONFLICT = 1879047928
|
||||
pkg debug/elf, const DT_GNU_CONFLICT DynTag
|
||||
pkg debug/elf, const DT_GNU_CONFLICTSZ = 1879047670
|
||||
pkg debug/elf, const DT_GNU_CONFLICTSZ DynTag
|
||||
pkg debug/elf, const DT_GNU_HASH = 1879047925
|
||||
pkg debug/elf, const DT_GNU_HASH DynTag
|
||||
pkg debug/elf, const DT_GNU_LIBLIST = 1879047929
|
||||
pkg debug/elf, const DT_GNU_LIBLIST DynTag
|
||||
pkg debug/elf, const DT_GNU_LIBLISTSZ = 1879047671
|
||||
pkg debug/elf, const DT_GNU_LIBLISTSZ DynTag
|
||||
pkg debug/elf, const DT_GNU_PRELINKED = 1879047669
|
||||
pkg debug/elf, const DT_GNU_PRELINKED DynTag
|
||||
pkg debug/elf, const DT_MIPS_AUX_DYNAMIC = 1879048241
|
||||
pkg debug/elf, const DT_MIPS_AUX_DYNAMIC DynTag
|
||||
pkg debug/elf, const DT_MIPS_BASE_ADDRESS = 1879048198
|
||||
pkg debug/elf, const DT_MIPS_BASE_ADDRESS DynTag
|
||||
pkg debug/elf, const DT_MIPS_COMPACT_SIZE = 1879048239
|
||||
pkg debug/elf, const DT_MIPS_COMPACT_SIZE DynTag
|
||||
pkg debug/elf, const DT_MIPS_CONFLICT = 1879048200
|
||||
pkg debug/elf, const DT_MIPS_CONFLICT DynTag
|
||||
pkg debug/elf, const DT_MIPS_CONFLICTNO = 1879048203
|
||||
pkg debug/elf, const DT_MIPS_CONFLICTNO DynTag
|
||||
pkg debug/elf, const DT_MIPS_CXX_FLAGS = 1879048226
|
||||
pkg debug/elf, const DT_MIPS_CXX_FLAGS DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASS = 1879048215
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASS DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASSSYM = 1879048224
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASSSYM DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASSSYM_NO = 1879048225
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASSSYM_NO DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASS_NO = 1879048216
|
||||
pkg debug/elf, const DT_MIPS_DELTA_CLASS_NO DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_INSTANCE = 1879048217
|
||||
pkg debug/elf, const DT_MIPS_DELTA_INSTANCE DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_INSTANCE_NO = 1879048218
|
||||
pkg debug/elf, const DT_MIPS_DELTA_INSTANCE_NO DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_RELOC = 1879048219
|
||||
pkg debug/elf, const DT_MIPS_DELTA_RELOC DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_RELOC_NO = 1879048220
|
||||
pkg debug/elf, const DT_MIPS_DELTA_RELOC_NO DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_SYM = 1879048221
|
||||
pkg debug/elf, const DT_MIPS_DELTA_SYM DynTag
|
||||
pkg debug/elf, const DT_MIPS_DELTA_SYM_NO = 1879048222
|
||||
pkg debug/elf, const DT_MIPS_DELTA_SYM_NO DynTag
|
||||
pkg debug/elf, const DT_MIPS_DYNSTR_ALIGN = 1879048235
|
||||
pkg debug/elf, const DT_MIPS_DYNSTR_ALIGN DynTag
|
||||
pkg debug/elf, const DT_MIPS_FLAGS = 1879048197
|
||||
pkg debug/elf, const DT_MIPS_FLAGS DynTag
|
||||
pkg debug/elf, const DT_MIPS_GOTSYM = 1879048211
|
||||
pkg debug/elf, const DT_MIPS_GOTSYM DynTag
|
||||
pkg debug/elf, const DT_MIPS_GP_VALUE = 1879048240
|
||||
pkg debug/elf, const DT_MIPS_GP_VALUE DynTag
|
||||
pkg debug/elf, const DT_MIPS_HIDDEN_GOTIDX = 1879048231
|
||||
pkg debug/elf, const DT_MIPS_HIDDEN_GOTIDX DynTag
|
||||
pkg debug/elf, const DT_MIPS_HIPAGENO = 1879048212
|
||||
pkg debug/elf, const DT_MIPS_HIPAGENO DynTag
|
||||
pkg debug/elf, const DT_MIPS_ICHECKSUM = 1879048195
|
||||
pkg debug/elf, const DT_MIPS_ICHECKSUM DynTag
|
||||
pkg debug/elf, const DT_MIPS_INTERFACE = 1879048234
|
||||
pkg debug/elf, const DT_MIPS_INTERFACE DynTag
|
||||
pkg debug/elf, const DT_MIPS_INTERFACE_SIZE = 1879048236
|
||||
pkg debug/elf, const DT_MIPS_INTERFACE_SIZE DynTag
|
||||
pkg debug/elf, const DT_MIPS_IVERSION = 1879048196
|
||||
pkg debug/elf, const DT_MIPS_IVERSION DynTag
|
||||
pkg debug/elf, const DT_MIPS_LIBLIST = 1879048201
|
||||
pkg debug/elf, const DT_MIPS_LIBLIST DynTag
|
||||
pkg debug/elf, const DT_MIPS_LIBLISTNO = 1879048208
|
||||
pkg debug/elf, const DT_MIPS_LIBLISTNO DynTag
|
||||
pkg debug/elf, const DT_MIPS_LOCALPAGE_GOTIDX = 1879048229
|
||||
pkg debug/elf, const DT_MIPS_LOCALPAGE_GOTIDX DynTag
|
||||
pkg debug/elf, const DT_MIPS_LOCAL_GOTIDX = 1879048230
|
||||
pkg debug/elf, const DT_MIPS_LOCAL_GOTIDX DynTag
|
||||
pkg debug/elf, const DT_MIPS_LOCAL_GOTNO = 1879048202
|
||||
pkg debug/elf, const DT_MIPS_LOCAL_GOTNO DynTag
|
||||
pkg debug/elf, const DT_MIPS_MSYM = 1879048199
|
||||
pkg debug/elf, const DT_MIPS_MSYM DynTag
|
||||
pkg debug/elf, const DT_MIPS_OPTIONS = 1879048233
|
||||
pkg debug/elf, const DT_MIPS_OPTIONS DynTag
|
||||
pkg debug/elf, const DT_MIPS_PERF_SUFFIX = 1879048238
|
||||
pkg debug/elf, const DT_MIPS_PERF_SUFFIX DynTag
|
||||
pkg debug/elf, const DT_MIPS_PIXIE_INIT = 1879048227
|
||||
pkg debug/elf, const DT_MIPS_PIXIE_INIT DynTag
|
||||
pkg debug/elf, const DT_MIPS_PLTGOT = 1879048242
|
||||
pkg debug/elf, const DT_MIPS_PLTGOT DynTag
|
||||
pkg debug/elf, const DT_MIPS_PROTECTED_GOTIDX = 1879048232
|
||||
pkg debug/elf, const DT_MIPS_PROTECTED_GOTIDX DynTag
|
||||
pkg debug/elf, const DT_MIPS_RLD_MAP = 1879048214
|
||||
pkg debug/elf, const DT_MIPS_RLD_MAP DynTag
|
||||
pkg debug/elf, const DT_MIPS_RLD_MAP_REL = 1879048245
|
||||
pkg debug/elf, const DT_MIPS_RLD_MAP_REL DynTag
|
||||
pkg debug/elf, const DT_MIPS_RLD_TEXT_RESOLVE_ADDR = 1879048237
|
||||
pkg debug/elf, const DT_MIPS_RLD_TEXT_RESOLVE_ADDR DynTag
|
||||
pkg debug/elf, const DT_MIPS_RLD_VERSION = 1879048193
|
||||
pkg debug/elf, const DT_MIPS_RLD_VERSION DynTag
|
||||
pkg debug/elf, const DT_MIPS_RWPLT = 1879048244
|
||||
pkg debug/elf, const DT_MIPS_RWPLT DynTag
|
||||
pkg debug/elf, const DT_MIPS_SYMBOL_LIB = 1879048228
|
||||
pkg debug/elf, const DT_MIPS_SYMBOL_LIB DynTag
|
||||
pkg debug/elf, const DT_MIPS_SYMTABNO = 1879048209
|
||||
pkg debug/elf, const DT_MIPS_SYMTABNO DynTag
|
||||
pkg debug/elf, const DT_MIPS_TIME_STAMP = 1879048194
|
||||
pkg debug/elf, const DT_MIPS_TIME_STAMP DynTag
|
||||
pkg debug/elf, const DT_MIPS_UNREFEXTNO = 1879048210
|
||||
pkg debug/elf, const DT_MIPS_UNREFEXTNO DynTag
|
||||
pkg debug/elf, const DT_MOVEENT = 1879047674
|
||||
pkg debug/elf, const DT_MOVEENT DynTag
|
||||
pkg debug/elf, const DT_MOVESZ = 1879047675
|
||||
pkg debug/elf, const DT_MOVESZ DynTag
|
||||
pkg debug/elf, const DT_MOVETAB = 1879047934
|
||||
pkg debug/elf, const DT_MOVETAB DynTag
|
||||
pkg debug/elf, const DT_PLTPAD = 1879047933
|
||||
pkg debug/elf, const DT_PLTPAD DynTag
|
||||
pkg debug/elf, const DT_PLTPADSZ = 1879047673
|
||||
pkg debug/elf, const DT_PLTPADSZ DynTag
|
||||
pkg debug/elf, const DT_POSFLAG_1 = 1879047677
|
||||
pkg debug/elf, const DT_POSFLAG_1 DynTag
|
||||
pkg debug/elf, const DT_PPC64_GLINK = 1879048192
|
||||
pkg debug/elf, const DT_PPC64_GLINK DynTag
|
||||
pkg debug/elf, const DT_PPC64_OPD = 1879048193
|
||||
pkg debug/elf, const DT_PPC64_OPD DynTag
|
||||
pkg debug/elf, const DT_PPC64_OPDSZ = 1879048194
|
||||
pkg debug/elf, const DT_PPC64_OPDSZ DynTag
|
||||
pkg debug/elf, const DT_PPC64_OPT = 1879048195
|
||||
pkg debug/elf, const DT_PPC64_OPT DynTag
|
||||
pkg debug/elf, const DT_PPC_GOT = 1879048192
|
||||
pkg debug/elf, const DT_PPC_GOT DynTag
|
||||
pkg debug/elf, const DT_PPC_OPT = 1879048193
|
||||
pkg debug/elf, const DT_PPC_OPT DynTag
|
||||
pkg debug/elf, const DT_RELACOUNT = 1879048185
|
||||
pkg debug/elf, const DT_RELACOUNT DynTag
|
||||
pkg debug/elf, const DT_RELCOUNT = 1879048186
|
||||
pkg debug/elf, const DT_RELCOUNT DynTag
|
||||
pkg debug/elf, const DT_SPARC_REGISTER = 1879048193
|
||||
pkg debug/elf, const DT_SPARC_REGISTER DynTag
|
||||
pkg debug/elf, const DT_SYMINENT = 1879047679
|
||||
pkg debug/elf, const DT_SYMINENT DynTag
|
||||
pkg debug/elf, const DT_SYMINFO = 1879047935
|
||||
pkg debug/elf, const DT_SYMINFO DynTag
|
||||
pkg debug/elf, const DT_SYMINSZ = 1879047678
|
||||
pkg debug/elf, const DT_SYMINSZ DynTag
|
||||
pkg debug/elf, const DT_SYMTAB_SHNDX = 34
|
||||
pkg debug/elf, const DT_SYMTAB_SHNDX DynTag
|
||||
pkg debug/elf, const DT_TLSDESC_GOT = 1879047927
|
||||
pkg debug/elf, const DT_TLSDESC_GOT DynTag
|
||||
pkg debug/elf, const DT_TLSDESC_PLT = 1879047926
|
||||
pkg debug/elf, const DT_TLSDESC_PLT DynTag
|
||||
pkg debug/elf, const DT_USED = 2147483646
|
||||
pkg debug/elf, const DT_USED DynTag
|
||||
pkg debug/elf, const DT_VALRNGHI = 1879047679
|
||||
pkg debug/elf, const DT_VALRNGHI DynTag
|
||||
pkg debug/elf, const DT_VALRNGLO = 1879047424
|
||||
pkg debug/elf, const DT_VALRNGLO DynTag
|
||||
pkg debug/elf, const DT_VERDEF = 1879048188
|
||||
pkg debug/elf, const DT_VERDEF DynTag
|
||||
pkg debug/elf, const DT_VERDEFNUM = 1879048189
|
||||
pkg debug/elf, const DT_VERDEFNUM DynTag
|
||||
pkg debug/elf, const PT_AARCH64_ARCHEXT = 1879048192
|
||||
pkg debug/elf, const PT_AARCH64_ARCHEXT ProgType
|
||||
pkg debug/elf, const PT_AARCH64_UNWIND = 1879048193
|
||||
pkg debug/elf, const PT_AARCH64_UNWIND ProgType
|
||||
pkg debug/elf, const PT_ARM_ARCHEXT = 1879048192
|
||||
pkg debug/elf, const PT_ARM_ARCHEXT ProgType
|
||||
pkg debug/elf, const PT_ARM_EXIDX = 1879048193
|
||||
pkg debug/elf, const PT_ARM_EXIDX ProgType
|
||||
pkg debug/elf, const PT_GNU_EH_FRAME = 1685382480
|
||||
pkg debug/elf, const PT_GNU_EH_FRAME ProgType
|
||||
pkg debug/elf, const PT_GNU_MBIND_HI = 1685386580
|
||||
pkg debug/elf, const PT_GNU_MBIND_HI ProgType
|
||||
pkg debug/elf, const PT_GNU_MBIND_LO = 1685382485
|
||||
pkg debug/elf, const PT_GNU_MBIND_LO ProgType
|
||||
pkg debug/elf, const PT_GNU_PROPERTY = 1685382483
|
||||
pkg debug/elf, const PT_GNU_PROPERTY ProgType
|
||||
pkg debug/elf, const PT_GNU_RELRO = 1685382482
|
||||
pkg debug/elf, const PT_GNU_RELRO ProgType
|
||||
pkg debug/elf, const PT_GNU_STACK = 1685382481
|
||||
pkg debug/elf, const PT_GNU_STACK ProgType
|
||||
pkg debug/elf, const PT_MIPS_ABIFLAGS = 1879048195
|
||||
pkg debug/elf, const PT_MIPS_ABIFLAGS ProgType
|
||||
pkg debug/elf, const PT_MIPS_OPTIONS = 1879048194
|
||||
pkg debug/elf, const PT_MIPS_OPTIONS ProgType
|
||||
pkg debug/elf, const PT_MIPS_REGINFO = 1879048192
|
||||
pkg debug/elf, const PT_MIPS_REGINFO ProgType
|
||||
pkg debug/elf, const PT_MIPS_RTPROC = 1879048193
|
||||
pkg debug/elf, const PT_MIPS_RTPROC ProgType
|
||||
pkg debug/elf, const PT_OPENBSD_BOOTDATA = 1705253862
|
||||
pkg debug/elf, const PT_OPENBSD_BOOTDATA ProgType
|
||||
pkg debug/elf, const PT_OPENBSD_RANDOMIZE = 1705237478
|
||||
pkg debug/elf, const PT_OPENBSD_RANDOMIZE ProgType
|
||||
pkg debug/elf, const PT_OPENBSD_WXNEEDED = 1705237479
|
||||
pkg debug/elf, const PT_OPENBSD_WXNEEDED ProgType
|
||||
pkg debug/elf, const PT_PAX_FLAGS = 1694766464
|
||||
pkg debug/elf, const PT_PAX_FLAGS ProgType
|
||||
pkg debug/elf, const PT_S390_PGSTE = 1879048192
|
||||
pkg debug/elf, const PT_S390_PGSTE ProgType
|
||||
pkg debug/elf, const PT_SUNWSTACK = 1879048187
|
||||
pkg debug/elf, const PT_SUNWSTACK ProgType
|
||||
pkg debug/elf, const PT_SUNW_EH_FRAME = 1685382480
|
||||
pkg debug/elf, const PT_SUNW_EH_FRAME ProgType
|
||||
pkg embed, method (FS) Open(string) (fs.File, error)
|
||||
pkg embed, method (FS) ReadDir(string) ([]fs.DirEntry, error)
|
||||
pkg embed, method (FS) ReadFile(string) ([]uint8, error)
|
||||
pkg embed, type FS struct
|
||||
pkg flag, func Func(string, string, func(string) error)
|
||||
pkg flag, method (*FlagSet) Func(string, string, func(string) error)
|
||||
pkg go/build, type Package struct, EmbedPatterns []string
|
||||
pkg go/build, type Package struct, IgnoredOtherFiles []string
|
||||
pkg go/build, type Package struct, TestEmbedPatterns []string
|
||||
pkg go/build, type Package struct, XTestEmbedPatterns []string
|
||||
pkg html/template, func ParseFS(fs.FS, ...string) (*Template, error)
|
||||
pkg html/template, method (*Template) ParseFS(fs.FS, ...string) (*Template, error)
|
||||
pkg io, func NopCloser(Reader) ReadCloser
|
||||
pkg io, func ReadAll(Reader) ([]uint8, error)
|
||||
pkg io, type ReadSeekCloser interface { Close, Read, Seek }
|
||||
pkg io, type ReadSeekCloser interface, Close() error
|
||||
pkg io, type ReadSeekCloser interface, Read([]uint8) (int, error)
|
||||
pkg io, type ReadSeekCloser interface, Seek(int64, int) (int64, error)
|
||||
pkg io, var Discard Writer
|
||||
pkg io/fs, const ModeAppend = 1073741824
|
||||
pkg io/fs, const ModeAppend FileMode
|
||||
pkg io/fs, const ModeCharDevice = 2097152
|
||||
pkg io/fs, const ModeCharDevice FileMode
|
||||
pkg io/fs, const ModeDevice = 67108864
|
||||
pkg io/fs, const ModeDevice FileMode
|
||||
pkg io/fs, const ModeDir = 2147483648
|
||||
pkg io/fs, const ModeDir FileMode
|
||||
pkg io/fs, const ModeExclusive = 536870912
|
||||
pkg io/fs, const ModeExclusive FileMode
|
||||
pkg io/fs, const ModeIrregular = 524288
|
||||
pkg io/fs, const ModeIrregular FileMode
|
||||
pkg io/fs, const ModeNamedPipe = 33554432
|
||||
pkg io/fs, const ModeNamedPipe FileMode
|
||||
pkg io/fs, const ModePerm = 511
|
||||
pkg io/fs, const ModePerm FileMode
|
||||
pkg io/fs, const ModeSetgid = 4194304
|
||||
pkg io/fs, const ModeSetgid FileMode
|
||||
pkg io/fs, const ModeSetuid = 8388608
|
||||
pkg io/fs, const ModeSetuid FileMode
|
||||
pkg io/fs, const ModeSocket = 16777216
|
||||
pkg io/fs, const ModeSocket FileMode
|
||||
pkg io/fs, const ModeSticky = 1048576
|
||||
pkg io/fs, const ModeSticky FileMode
|
||||
pkg io/fs, const ModeSymlink = 134217728
|
||||
pkg io/fs, const ModeSymlink FileMode
|
||||
pkg io/fs, const ModeTemporary = 268435456
|
||||
pkg io/fs, const ModeTemporary FileMode
|
||||
pkg io/fs, const ModeType = 2401763328
|
||||
pkg io/fs, const ModeType FileMode
|
||||
pkg io/fs, func Glob(FS, string) ([]string, error)
|
||||
pkg io/fs, func ReadDir(FS, string) ([]DirEntry, error)
|
||||
pkg io/fs, func ReadFile(FS, string) ([]uint8, error)
|
||||
pkg io/fs, func Stat(FS, string) (FileInfo, error)
|
||||
pkg io/fs, func ValidPath(string) bool
|
||||
pkg io/fs, method (*PathError) Error() string
|
||||
pkg io/fs, method (*PathError) Timeout() bool
|
||||
pkg io/fs, method (*PathError) Unwrap() error
|
||||
pkg io/fs, method (FileMode) IsDir() bool
|
||||
pkg io/fs, method (FileMode) IsRegular() bool
|
||||
pkg io/fs, method (FileMode) Perm() FileMode
|
||||
pkg io/fs, method (FileMode) String() string
|
||||
pkg io/fs, method (FileMode) Type() FileMode
|
||||
pkg io/fs, type DirEntry interface { Info, IsDir, Name, Type }
|
||||
pkg io/fs, type DirEntry interface, Info() (FileInfo, error)
|
||||
pkg io/fs, type DirEntry interface, IsDir() bool
|
||||
pkg io/fs, type DirEntry interface, Name() string
|
||||
pkg io/fs, type DirEntry interface, Type() FileMode
|
||||
pkg io/fs, type FS interface { Open }
|
||||
pkg io/fs, type FS interface, Open(string) (File, error)
|
||||
pkg io/fs, type File interface { Close, Read, Stat }
|
||||
pkg io/fs, type File interface, Close() error
|
||||
pkg io/fs, type File interface, Read([]uint8) (int, error)
|
||||
pkg io/fs, type File interface, Stat() (FileInfo, error)
|
||||
pkg io/fs, type FileInfo interface { IsDir, ModTime, Mode, Name, Size, Sys }
|
||||
pkg io/fs, type FileInfo interface, IsDir() bool
|
||||
pkg io/fs, type FileInfo interface, ModTime() time.Time
|
||||
pkg io/fs, type FileInfo interface, Mode() FileMode
|
||||
pkg io/fs, type FileInfo interface, Name() string
|
||||
pkg io/fs, type FileInfo interface, Size() int64
|
||||
pkg io/fs, type FileInfo interface, Sys() interface{}
|
||||
pkg io/fs, type FileMode uint32
|
||||
pkg io/fs, type GlobFS interface { Glob, Open }
|
||||
pkg io/fs, type GlobFS interface, Glob(string) ([]string, error)
|
||||
pkg io/fs, type GlobFS interface, Open(string) (File, error)
|
||||
pkg io/fs, type PathError struct
|
||||
pkg io/fs, type PathError struct, Err error
|
||||
pkg io/fs, type PathError struct, Op string
|
||||
pkg io/fs, type PathError struct, Path string
|
||||
pkg io/fs, type ReadDirFS interface { Open, ReadDir }
|
||||
pkg io/fs, type ReadDirFS interface, Open(string) (File, error)
|
||||
pkg io/fs, type ReadDirFS interface, ReadDir(string) ([]DirEntry, error)
|
||||
pkg io/fs, type ReadDirFile interface { Close, Read, ReadDir, Stat }
|
||||
pkg io/fs, type ReadDirFile interface, Close() error
|
||||
pkg io/fs, type ReadDirFile interface, Read([]uint8) (int, error)
|
||||
pkg io/fs, type ReadDirFile interface, ReadDir(int) ([]DirEntry, error)
|
||||
pkg io/fs, type ReadDirFile interface, Stat() (FileInfo, error)
|
||||
pkg io/fs, type ReadFileFS interface { Open, ReadFile }
|
||||
pkg io/fs, type ReadFileFS interface, Open(string) (File, error)
|
||||
pkg io/fs, type ReadFileFS interface, ReadFile(string) ([]uint8, error)
|
||||
pkg io/fs, type StatFS interface { Open, Stat }
|
||||
pkg io/fs, type StatFS interface, Open(string) (File, error)
|
||||
pkg io/fs, type StatFS interface, Stat(string) (FileInfo, error)
|
||||
pkg io/fs, var ErrClosed error
|
||||
pkg io/fs, var ErrExist error
|
||||
pkg io/fs, var ErrInvalid error
|
||||
pkg io/fs, var ErrNotExist error
|
||||
pkg io/fs, var ErrPermission error
|
||||
pkg log, func Default() *Logger
|
||||
pkg net, var ErrClosed error
|
||||
pkg net/http, func FS(fs.FS) FileSystem
|
||||
pkg net/http, type Transport struct, GetProxyConnectHeader func(context.Context, *url.URL, string) (Header, error)
|
||||
pkg os, const ModeAppend fs.FileMode
|
||||
pkg os, const ModeCharDevice fs.FileMode
|
||||
pkg os, const ModeDevice fs.FileMode
|
||||
pkg os, const ModeDir fs.FileMode
|
||||
pkg os, const ModeExclusive fs.FileMode
|
||||
pkg os, const ModeIrregular fs.FileMode
|
||||
pkg os, const ModeNamedPipe fs.FileMode
|
||||
pkg os, const ModePerm fs.FileMode
|
||||
pkg os, const ModeSetgid fs.FileMode
|
||||
pkg os, const ModeSetuid fs.FileMode
|
||||
pkg os, const ModeSocket fs.FileMode
|
||||
pkg os, const ModeSticky fs.FileMode
|
||||
pkg os, const ModeSymlink fs.FileMode
|
||||
pkg os, const ModeTemporary fs.FileMode
|
||||
pkg os, const ModeType fs.FileMode
|
||||
pkg os, func Chmod(string, fs.FileMode) error
|
||||
pkg os, func DirFS(string) fs.FS
|
||||
pkg os, func Lstat(string) (fs.FileInfo, error)
|
||||
pkg os, func Mkdir(string, fs.FileMode) error
|
||||
pkg os, func MkdirAll(string, fs.FileMode) error
|
||||
pkg os, func OpenFile(string, int, fs.FileMode) (*File, error)
|
||||
pkg os, func SameFile(fs.FileInfo, fs.FileInfo) bool
|
||||
pkg os, func Stat(string) (fs.FileInfo, error)
|
||||
pkg os, method (*File) Chmod(fs.FileMode) error
|
||||
pkg os, method (*File) ReadDir(int) ([]fs.DirEntry, error)
|
||||
pkg os, method (*File) Readdir(int) ([]fs.FileInfo, error)
|
||||
pkg os, method (*File) Stat() (fs.FileInfo, error)
|
||||
pkg os, type DirEntry = fs.DirEntry
|
||||
pkg os, type FileInfo = fs.FileInfo
|
||||
pkg os, type FileMode = fs.FileMode
|
||||
pkg os, type PathError = fs.PathError
|
||||
pkg os/signal, func NotifyContext(context.Context, ...os.Signal) (context.Context, context.CancelFunc)
|
||||
pkg runtime/metrics, const KindBad = 0
|
||||
pkg runtime/metrics, const KindBad ValueKind
|
||||
pkg runtime/metrics, const KindFloat64 = 2
|
||||
pkg runtime/metrics, const KindFloat64 ValueKind
|
||||
pkg runtime/metrics, const KindFloat64Histogram = 3
|
||||
pkg runtime/metrics, const KindFloat64Histogram ValueKind
|
||||
pkg runtime/metrics, const KindUint64 = 1
|
||||
pkg runtime/metrics, const KindUint64 ValueKind
|
||||
pkg runtime/metrics, func All() []Description
|
||||
pkg runtime/metrics, func Read([]Sample)
|
||||
pkg runtime/metrics, method (Value) Float64() float64
|
||||
pkg runtime/metrics, method (Value) Float64Histogram() *Float64Histogram
|
||||
pkg runtime/metrics, method (Value) Kind() ValueKind
|
||||
pkg runtime/metrics, method (Value) Uint64() uint64
|
||||
pkg runtime/metrics, type Description struct
|
||||
pkg runtime/metrics, type Description struct, Cumulative bool
|
||||
pkg runtime/metrics, type Description struct, Description string
|
||||
pkg runtime/metrics, type Description struct, Kind ValueKind
|
||||
pkg runtime/metrics, type Description struct, Name string
|
||||
pkg runtime/metrics, type Description struct, StopTheWorld bool
|
||||
pkg runtime/metrics, type Float64Histogram struct
|
||||
pkg runtime/metrics, type Float64Histogram struct, Buckets []float64
|
||||
pkg runtime/metrics, type Float64Histogram struct, Counts []uint64
|
||||
pkg runtime/metrics, type Sample struct
|
||||
pkg runtime/metrics, type Sample struct, Name string
|
||||
pkg runtime/metrics, type Sample struct, Value Value
|
||||
pkg runtime/metrics, type Value struct
|
||||
pkg runtime/metrics, type ValueKind int
|
||||
pkg syscall (linux-386), func AllThreadsSyscall(uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-386), func AllThreadsSyscall6(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-386), func Setegid(int) error
|
||||
pkg syscall (linux-386), func Seteuid(int) error
|
||||
pkg syscall (linux-386-cgo), func AllThreadsSyscall(uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-386-cgo), func AllThreadsSyscall6(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-386-cgo), func Setegid(int) error
|
||||
pkg syscall (linux-386-cgo), func Seteuid(int) error
|
||||
pkg syscall (linux-amd64), func AllThreadsSyscall(uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-amd64), func AllThreadsSyscall6(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-amd64), func Setegid(int) error
|
||||
pkg syscall (linux-amd64), func Seteuid(int) error
|
||||
pkg syscall (linux-amd64-cgo), func AllThreadsSyscall(uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-amd64-cgo), func AllThreadsSyscall6(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-amd64-cgo), func Setegid(int) error
|
||||
pkg syscall (linux-amd64-cgo), func Seteuid(int) error
|
||||
pkg syscall (linux-arm), func AllThreadsSyscall(uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-arm), func AllThreadsSyscall6(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-arm), func Setegid(int) error
|
||||
pkg syscall (linux-arm), func Seteuid(int) error
|
||||
pkg syscall (linux-arm-cgo), func AllThreadsSyscall(uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-arm-cgo), func AllThreadsSyscall6(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-arm-cgo), func Setegid(int) error
|
||||
pkg syscall (linux-arm-cgo), func Seteuid(int) error
|
||||
pkg syscall (windows-386), func RtlGenRandom(*uint8, uint32) error
|
||||
pkg syscall (windows-amd64), func RtlGenRandom(*uint8, uint32) error
|
||||
pkg testing/fstest, func TestFS(fs.FS, ...string) error
|
||||
pkg testing/fstest, method (MapFS) Glob(string) ([]string, error)
|
||||
pkg testing/fstest, method (MapFS) Open(string) (fs.File, error)
|
||||
pkg testing/fstest, method (MapFS) ReadDir(string) ([]fs.DirEntry, error)
|
||||
pkg testing/fstest, method (MapFS) ReadFile(string) ([]uint8, error)
|
||||
pkg testing/fstest, method (MapFS) Stat(string) (fs.FileInfo, error)
|
||||
pkg testing/fstest, type MapFS map[string]*MapFile
|
||||
pkg testing/fstest, type MapFile struct
|
||||
pkg testing/fstest, type MapFile struct, Data []uint8
|
||||
pkg testing/fstest, type MapFile struct, ModTime time.Time
|
||||
pkg testing/fstest, type MapFile struct, Mode fs.FileMode
|
||||
pkg testing/fstest, type MapFile struct, Sys interface{}
|
||||
pkg testing/iotest, func ErrReader(error) io.Reader
|
||||
pkg testing/iotest, func TestReader(io.Reader, []uint8) error
|
||||
pkg text/template, func ParseFS(fs.FS, ...string) (*Template, error)
|
||||
pkg text/template, method (*Template) ParseFS(fs.FS, ...string) (*Template, error)
|
||||
pkg text/template/parse, const NodeComment = 20
|
||||
pkg text/template/parse, const NodeComment NodeType
|
||||
pkg text/template/parse, const ParseComments = 1
|
||||
pkg text/template/parse, const ParseComments Mode
|
||||
pkg text/template/parse, method (*CommentNode) Copy() Node
|
||||
pkg text/template/parse, method (*CommentNode) String() string
|
||||
pkg text/template/parse, method (CommentNode) Position() Pos
|
||||
pkg text/template/parse, method (CommentNode) Type() NodeType
|
||||
pkg text/template/parse, type CommentNode struct
|
||||
pkg text/template/parse, type CommentNode struct, Text string
|
||||
pkg text/template/parse, type CommentNode struct, embedded NodeType
|
||||
pkg text/template/parse, type CommentNode struct, embedded Pos
|
||||
pkg text/template/parse, type Mode uint
|
||||
pkg text/template/parse, type Tree struct, Mode Mode
|
||||
pkg unicode, const Version = "13.0.0"
|
||||
pkg unicode, var Chorasmian *RangeTable
|
||||
pkg unicode, var Dives_Akuru *RangeTable
|
||||
pkg unicode, var Khitan_Small_Script *RangeTable
|
||||
pkg unicode, var Yezidi *RangeTable
|
|
@ -397,6 +397,19 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
documentation</a> for more information.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 250940 -->
|
||||
In Go 1.15.3 and later, cgo will not permit Go code to allocate an
|
||||
undefined struct type (a C struct defined as just <code>struct
|
||||
S;</code> or similar) on the stack or heap.
|
||||
Go code will only be permitted to use pointers to those types.
|
||||
Allocating an instance of such a struct and passing a pointer, or a
|
||||
full struct value, to C code was always unsafe and unlikely to work
|
||||
correctly; it is now forbidden.
|
||||
The fix is to either rewrite the Go code to use only pointers, or to
|
||||
ensure that the Go code sees the full definition of the struct by
|
||||
including the appropriate C header file.
|
||||
</p>
|
||||
|
||||
<h3 id="commonname">X.509 CommonName deprecation</h3>
|
||||
|
||||
<p><!-- CL 231379 -->
|
||||
|
|
129
doc/go1.16.html
129
doc/go1.16.html
|
@ -99,10 +99,6 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
|
||||
<h2 id="tools">Tools</h2>
|
||||
|
||||
<p>
|
||||
TODO
|
||||
</p>
|
||||
|
||||
<h3 id="go-command">Go command</h3>
|
||||
|
||||
<h4 id="modules">Modules</h4>
|
||||
|
@ -275,6 +271,20 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
but without the extra step.
|
||||
</p>
|
||||
|
||||
<h4 id="overlay-flag">The <code>-overlay</code> flag</h4>
|
||||
|
||||
<p><!-- golang.org/issue/39958 -->
|
||||
The <code>-overlay</code> flag specifies a JSON configuration file containing
|
||||
a set of file path replacements. The <code>-overlay</code> flag may be used
|
||||
with all build commands and <code>go</code> <code>mod</code> subcommands.
|
||||
It is primarily intended to be used by editor tooling such as gopls to
|
||||
understand the effects of unsaved changes to source files. The config file
|
||||
maps actual file paths to replacement file paths and the <code>go</code>
|
||||
command and its builds will run as if the actual file paths exist with the
|
||||
contents given by the replacement file paths, or don't exist if the replacement
|
||||
file paths are empty.
|
||||
</p>
|
||||
|
||||
<h3 id="cgo">Cgo</h3>
|
||||
|
||||
<p><!-- CL 252378 -->
|
||||
|
@ -287,12 +297,55 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
|
||||
<h3 id="vet">Vet</h3>
|
||||
|
||||
<p>
|
||||
TODO
|
||||
<h4 id="vet-string-int">New warning for invalid testing.T use in
|
||||
goroutines</h4>
|
||||
|
||||
<!-- CL 235677: https://golang.org/cl/235677: cmd/vet: bring in pass to catch invalid uses of testing.T in goroutines -->
|
||||
<p><!-- CL 235677 -->
|
||||
The vet tool now warns about invalid calls to the <code>testing.T</code>
|
||||
method <code>Fatal</code> from within a goroutine created during the test.
|
||||
This also warns on calls to <code>Fatalf</code>, <code>FailNow</code>, and
|
||||
<code>Skip{,f,Now}</code> methods on <code>testing.T</code> tests or
|
||||
<code>testing.B</code> benchmarks.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Calls to these methods stop the execution of the created goroutine and not
|
||||
the <code>Test*</code> or <code>Benchmark*</code> function. So these are
|
||||
<a href="/pkg/testing/#T.FailNow">required</a> to be called by the goroutine
|
||||
running the test or benchmark function. For example:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
func TestFoo(t *testing.T) {
|
||||
go func() {
|
||||
if condition() {
|
||||
t.Fatal("oops") // This exits the inner func instead of TestFoo.
|
||||
}
|
||||
...
|
||||
}()
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Code calling <code>t.Fatal</code> (or a similar method) from a created
|
||||
goroutine should be rewritten to signal the test failure using
|
||||
<code>t.Error</code> and exit the goroutine early using an alternative
|
||||
method, such as using a <code>return</code> statement. The previous example
|
||||
could be rewritten as:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
func TestFoo(t *testing.T) {
|
||||
go func() {
|
||||
if condition() {
|
||||
t.Error("oops")
|
||||
return
|
||||
}
|
||||
...
|
||||
}()
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p><!-- CL 248686, CL 276372 -->
|
||||
The vet tool now warns about amd64 assembly that clobbers the BP
|
||||
register (the frame pointer) without saving and restoring it,
|
||||
|
@ -326,7 +379,7 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
summarizing its execution time and memory allocation. This trace can
|
||||
be used to find bottlenecks or regressions in Go startup
|
||||
performance.
|
||||
The <a href="/pkg/runtime/#hdr-Environment_Variables"><code>GODEBUG</code><
|
||||
The <a href="/pkg/runtime/#hdr-Environment_Variables"><code>GODEBUG</code>
|
||||
documentation</a> describes the format.
|
||||
</p>
|
||||
|
||||
|
@ -408,7 +461,7 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
|
||||
<p>
|
||||
On the producer side of the interface,
|
||||
the new <a href="/pkg/embed/#FS">embed.FS</code></a> type
|
||||
the new <a href="/pkg/embed/#FS"><code>embed.FS</code></a> type
|
||||
implements <code>fs.FS</code>, as does
|
||||
<a href="/pkg/archive/zip/#Reader"><code>zip.Reader</code></a>.
|
||||
The new <a href="/pkg/os/#DirFS"><code>os.DirFS</code></a> function
|
||||
|
@ -438,10 +491,10 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
implementations.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
TODO: when the "Minor changes to the library" section is close to completion,
|
||||
decide if any changes are worth factoring out and highlighting in "Core library"
|
||||
</p>
|
||||
<!-- okay-after-beta1
|
||||
TODO: decide if any additional changes are worth factoring out from
|
||||
"Minor changes to the library" and highlighting in "Core library"
|
||||
-->
|
||||
|
||||
<h3 id="minor_library_changes">Minor changes to the library</h3>
|
||||
|
||||
|
@ -451,10 +504,6 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
in mind.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
TODO: complete this section, resolve TODOs below, add missing entries
|
||||
</p>
|
||||
|
||||
<dl id="crypto/dsa"><dt><a href="/pkg/crypto/dsa/">crypto/dsa</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 257939 -->
|
||||
|
@ -490,16 +539,6 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
indefinitely.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 246338 -->
|
||||
The new <a href="/pkg/crypto/tls#Conn.HandshakeContext"><code>Conn.HandshakeContext</code></a>
|
||||
method allows cancellation of an in-progress handshake. The provided
|
||||
context is accessible through the new
|
||||
<a href="/pkg/crypto/tls#ClientHelloInfo.Context"><code>ClientHelloInfo.Context</code></a>
|
||||
and <a href="/pkg/crypto/tls#CertificateRequestInfo.Context">
|
||||
<code>CertificateRequestInfo.Context</code></a> methods. Canceling the
|
||||
context after the handshake has finished has no effect.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 239748 -->
|
||||
Clients now return a handshake error if the server selects
|
||||
<a href="/pkg/crypto/tls/#ConnectionState.NegotiatedProtocol">
|
||||
|
@ -672,8 +711,8 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
<p><!-- CL 250357 -->
|
||||
The case of I/O on a closed network connection, or I/O on a network
|
||||
connection that is closed before any of the I/O completes, can now
|
||||
be detected using the new <a href="/pkg/net/#ErrClosed">ErrClosed</a> error.
|
||||
A typical use would be <code>errors.Is(err, net.ErrClosed)</code>.
|
||||
be detected using the new <a href="/pkg/net/#ErrClosed"><code>ErrClosed</code></a>
|
||||
error. A typical use would be <code>errors.Is(err, net.ErrClosed)</code>.
|
||||
In earlier releases the only way to reliably detect this case was to
|
||||
match the string returned by the <code>Error</code> method
|
||||
with <code>"use of closed network connection"</code>.
|
||||
|
@ -722,13 +761,6 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
generating a SameSite key without a value.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 246338 -->
|
||||
The <a href="/pkg/net/http/"><code>net/http</code></a> package now passes the
|
||||
<a href="/pkg/net/http/#Request.Context"><code>Request</code> context</a> to
|
||||
<a href="/pkg/crypto/tls#Conn.HandshakeContext"><code>tls.Conn.HandshakeContext</code></a>
|
||||
when performing TLS handshakes.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 250039 -->
|
||||
The <a href="/pkg/net/http/#Client">Client</a> now sends
|
||||
an explicit <code>Content-Length:</code> <code>0</code>
|
||||
|
@ -737,9 +769,10 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
</p>
|
||||
|
||||
<p><!-- CL 249440 -->
|
||||
The <a href="/pkg/net/http/#ProxyFromEnvironment">ProxyFromEnvironment</a> function
|
||||
no longer returns the setting of the <code>HTTP_PROXY</code> environment
|
||||
variable for <code>https://</code> URLs when <code>HTTPS_PROXY</code> is unset.
|
||||
The <a href="/pkg/net/http/#ProxyFromEnvironment"><code>ProxyFromEnvironment</code></a>
|
||||
function no longer returns the setting of the <code>HTTP_PROXY</code>
|
||||
environment variable for <code>https://</code> URLs when
|
||||
<code>HTTPS_PROXY</code> is unset.
|
||||
</p>
|
||||
</dd>
|
||||
</dl><!-- net/http -->
|
||||
|
@ -747,7 +780,7 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
<dl id="net/http/httputil"><dt><a href="/pkg/net/http/httputil/">net/http/httputil</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 260637 -->
|
||||
The <a href="/pkg/net/http/httputil/#ReverseProxy">ReverseProxy</a>
|
||||
<a href="/pkg/net/http/httputil/#ReverseProxy"><code>ReverseProxy</code></a>
|
||||
now flushes buffered data more aggressively when proxying
|
||||
streamed responses with unknown body lengths.
|
||||
</p>
|
||||
|
@ -790,9 +823,9 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
<dl id="path"><dt><a href="/pkg/path/">path</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 264397, golang.org/issues/28614 -->
|
||||
The <code>Match</code> and <code>Glob</code> functions now
|
||||
return an error if the unmatched part of the pattern has a
|
||||
syntax error. Previously, the functions returned early on a failed
|
||||
The <a href="/pkg/path/#Match"><code>Match</code></a> function now
|
||||
returns an error if the unmatched part of the pattern has a
|
||||
syntax error. Previously, the function returned early on a failed
|
||||
match, and thus did not report any later syntax error in the
|
||||
pattern.
|
||||
</p>
|
||||
|
@ -802,7 +835,8 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
<dl id="path/filepath"><dt><a href="/pkg/path/filepath/">path/filepath</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 264397, golang.org/issues/28614 -->
|
||||
The <code>Match</code> and <code>Glob</code> functions now
|
||||
The <a href="/pkg/path/filepath#Match"><code>Match</code></a> and
|
||||
<a href="/pkg/path/filepath#Glob"><code>Glob</code></a> functions now
|
||||
return an error if the unmatched part of the pattern has a
|
||||
syntax error. Previously, the functions returned early on a failed
|
||||
match, and thus did not report any later syntax error in the
|
||||
|
@ -814,9 +848,10 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
<dl id="reflect"><dt><a href="/pkg/reflect/">reflect</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 248341, golang.org/issues/40281 -->
|
||||
<code>StructTag</code> now allows multiple space-separated keys
|
||||
in key:value pairs, as in <code>`json xml:"field1"`</code>
|
||||
(equivalent to <code>`json:"field1" xml:"field1"`</code>).
|
||||
<a href="/pkg/reflect/#StructTag"><code>StructTag</code></a>
|
||||
now allows multiple space-separated keys in key:value pairs,
|
||||
as in <code>`json xml:"field1"`</code> (equivalent to
|
||||
<code>`json:"field1" xml:"field1"`</code>).
|
||||
</p>
|
||||
</dd>
|
||||
</dl><!-- reflect -->
|
||||
|
|
|
@ -119,11 +119,26 @@ The Go toolchain is written in Go. To build it, you need a Go compiler installed
|
|||
The scripts that do the initial build of the tools look for a "go" command
|
||||
in <code>$PATH</code>, so as long as you have Go installed in your
|
||||
system and configured in your <code>$PATH</code>, you are ready to build Go
|
||||
from source.
|
||||
from source.
|
||||
Or if you prefer you can set <code>$GOROOT_BOOTSTRAP</code> to the
|
||||
root of a Go installation to use to build the new Go toolchain;
|
||||
<code>$GOROOT_BOOTSTRAP/bin/go</code> should be the go command to use.</p>
|
||||
|
||||
<p>
|
||||
There are four possible ways to obtain a bootstrap toolchain:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Download a recent binary release of Go.
|
||||
<li>Cross-compile a toolchain using a system with a working Go installation.
|
||||
<li>Use gccgo.
|
||||
<li>Compile a toolchain from Go 1.4, the last Go release with a compiler written in C.
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
These approaches are detailed below.
|
||||
</p>
|
||||
|
||||
<h3 id="bootstrapFromBinaryRelease">Bootstrap toolchain from binary release</h3>
|
||||
|
||||
<p>
|
||||
|
@ -132,30 +147,6 @@ To use a binary release as a bootstrap toolchain, see
|
|||
packaged Go distribution.
|
||||
</p>
|
||||
|
||||
<h3 id="bootstrapFromSource">Bootstrap toolchain from source</h3>
|
||||
|
||||
<p>
|
||||
To build a bootstrap toolchain from source, use
|
||||
either the git branch <code>release-branch.go1.4</code> or
|
||||
<a href="https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz">go1.4-bootstrap-20171003.tar.gz</a>,
|
||||
which contains the Go 1.4 source code plus accumulated fixes
|
||||
to keep the tools running on newer operating systems.
|
||||
(Go 1.4 was the last distribution in which the toolchain was written in C.)
|
||||
After unpacking the Go 1.4 source, <code>cd</code> to
|
||||
the <code>src</code> subdirectory, set <code>CGO_ENABLED=0</code> in
|
||||
the environment, and run <code>make.bash</code> (or,
|
||||
on Windows, <code>make.bat</code>).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Once the Go 1.4 source has been unpacked into your GOROOT_BOOTSTRAP directory,
|
||||
you must keep this git clone instance checked out to branch
|
||||
<code>release-branch.go1.4</code>. Specifically, do not attempt to reuse
|
||||
this git clone in the later step named "Fetch the repository." The go1.4
|
||||
bootstrap toolchain <b>must be able</b> to properly traverse the go1.4 sources
|
||||
that it assumes are present under this repository root.
|
||||
</p>
|
||||
|
||||
<h3 id="bootstrapFromCrosscompiledSource">Bootstrap toolchain from cross-compiled source</h3>
|
||||
|
||||
<p>
|
||||
|
@ -194,6 +185,36 @@ $ sudo update-alternatives --set go /usr/bin/go-5
|
|||
$ GOROOT_BOOTSTRAP=/usr ./make.bash
|
||||
</pre>
|
||||
|
||||
<h3 id="bootstrapFromSource">Bootstrap toolchain from C source code</h3>
|
||||
|
||||
<p>
|
||||
To build a bootstrap toolchain from C source code, use
|
||||
either the git branch <code>release-branch.go1.4</code> or
|
||||
<a href="https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz">go1.4-bootstrap-20171003.tar.gz</a>,
|
||||
which contains the Go 1.4 source code plus accumulated fixes
|
||||
to keep the tools running on newer operating systems.
|
||||
(Go 1.4 was the last distribution in which the toolchain was written in C.)
|
||||
After unpacking the Go 1.4 source, <code>cd</code> to
|
||||
the <code>src</code> subdirectory, set <code>CGO_ENABLED=0</code> in
|
||||
the environment, and run <code>make.bash</code> (or,
|
||||
on Windows, <code>make.bat</code>).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Once the Go 1.4 source has been unpacked into your GOROOT_BOOTSTRAP directory,
|
||||
you must keep this git clone instance checked out to branch
|
||||
<code>release-branch.go1.4</code>. Specifically, do not attempt to reuse
|
||||
this git clone in the later step named "Fetch the repository." The go1.4
|
||||
bootstrap toolchain <b>must be able</b> to properly traverse the go1.4 sources
|
||||
that it assumes are present under this repository root.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Note that Go 1.4 does not run on all systems that later versions of Go do.
|
||||
In particular, Go 1.4 does not support current versions of macOS.
|
||||
On such systems, the bootstrap toolchain must be obtained using one of the other methods.
|
||||
</p>
|
||||
|
||||
<h2 id="git">Install Git, if needed</h2>
|
||||
|
||||
<p>
|
||||
|
|
|
@ -20,6 +20,7 @@ var (
|
|||
TrimPath = flag.String("trimpath", "", "remove prefix from recorded source file paths")
|
||||
Shared = flag.Bool("shared", false, "generate code that can be linked into a shared library")
|
||||
Dynlink = flag.Bool("dynlink", false, "support references to Go symbols defined in other shared libraries")
|
||||
Linkshared = flag.Bool("linkshared", false, "generate code that will be linked against Go shared libraries")
|
||||
AllErrors = flag.Bool("e", false, "no limit on number of errors reported")
|
||||
SymABIs = flag.Bool("gensymabis", false, "write symbol ABI information to output file, don't assemble")
|
||||
Importpath = flag.String("p", "", "set expected package import to path")
|
||||
|
|
|
@ -37,6 +37,7 @@ func main() {
|
|||
ctxt := obj.Linknew(architecture.LinkArch)
|
||||
ctxt.Debugasm = flags.PrintOut
|
||||
ctxt.Flag_dynlink = *flags.Dynlink
|
||||
ctxt.Flag_linkshared = *flags.Linkshared
|
||||
ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
|
||||
ctxt.IsAsm = true
|
||||
ctxt.Pkgpath = *flags.Importpath
|
||||
|
|
|
@ -740,7 +740,7 @@ func reassigned(name *ir.Name) bool {
|
|||
if n.Left() == name && n != name.Defn {
|
||||
return true
|
||||
}
|
||||
case ir.OAS2, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2DOTTYPE:
|
||||
case ir.OAS2, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2DOTTYPE, ir.OAS2RECV, ir.OSELRECV2:
|
||||
for _, p := range n.List().Slice() {
|
||||
if p == name && n != name.Defn {
|
||||
return true
|
||||
|
|
|
@ -894,7 +894,7 @@ func (o *Order) stmt(n ir.Node) {
|
|||
// case x, ok = <-c
|
||||
recv := r.Rlist().First().(*ir.UnaryExpr)
|
||||
recv.SetLeft(o.expr(recv.Left(), nil))
|
||||
if recv.Left().Op() != ir.ONAME {
|
||||
if !ir.IsAutoTmp(recv.Left()) {
|
||||
recv.SetLeft(o.copyExpr(recv.Left()))
|
||||
}
|
||||
r := r.(*ir.AssignListStmt)
|
||||
|
|
|
@ -6003,7 +6003,7 @@ func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res, resok *ssa.Val
|
|||
// Load type out of itab, build interface with existing idata.
|
||||
off := s.newValue1I(ssa.OpOffPtr, byteptr, int64(Widthptr), itab)
|
||||
typ := s.load(byteptr, off)
|
||||
idata := s.newValue1(ssa.OpIData, n.Type(), iface)
|
||||
idata := s.newValue1(ssa.OpIData, byteptr, iface)
|
||||
res = s.newValue2(ssa.OpIMake, n.Type(), typ, idata)
|
||||
return
|
||||
}
|
||||
|
@ -6025,7 +6025,7 @@ func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res, resok *ssa.Val
|
|||
bOk.AddEdgeTo(bEnd)
|
||||
bFail.AddEdgeTo(bEnd)
|
||||
s.startBlock(bEnd)
|
||||
idata := s.newValue1(ssa.OpIData, n.Type(), iface)
|
||||
idata := s.newValue1(ssa.OpIData, byteptr, iface)
|
||||
res = s.newValue2(ssa.OpIMake, n.Type(), s.variable(typVar, byteptr), idata)
|
||||
resok = cond
|
||||
delete(s.vars, typVar)
|
||||
|
|
|
@ -147,6 +147,11 @@ func checkFunc(f *Func) {
|
|||
canHaveAuxInt = true
|
||||
case auxInt128:
|
||||
// AuxInt must be zero, so leave canHaveAuxInt set to false.
|
||||
case auxUInt8:
|
||||
if v.AuxInt != int64(uint8(v.AuxInt)) {
|
||||
f.Fatalf("bad uint8 AuxInt value for %v", v)
|
||||
}
|
||||
canHaveAuxInt = true
|
||||
case auxFloat32:
|
||||
canHaveAuxInt = true
|
||||
if math.IsNaN(v.AuxFloat()) {
|
||||
|
|
|
@ -196,9 +196,6 @@ func expandCalls(f *Func) {
|
|||
}
|
||||
if leaf.Op == OpIData {
|
||||
leafType = removeTrivialWrapperTypes(leaf.Type)
|
||||
if leafType.IsEmptyInterface() {
|
||||
leafType = typ.BytePtr
|
||||
}
|
||||
}
|
||||
aux := selector.Aux
|
||||
auxInt := selector.AuxInt + offset
|
||||
|
@ -247,12 +244,9 @@ func expandCalls(f *Func) {
|
|||
// i.e., the struct select is generated and remains in because it is not applied to an actual structure.
|
||||
// The OpLoad was created to load the single field of the IData
|
||||
// This case removes that StructSelect.
|
||||
if leafType != selector.Type && !selector.Type.IsEmptyInterface() { // empty interface for #42727
|
||||
if leafType != selector.Type {
|
||||
f.Fatalf("Unexpected Load as selector, leaf=%s, selector=%s\n", leaf.LongString(), selector.LongString())
|
||||
}
|
||||
if selector.Type.IsEmptyInterface() {
|
||||
selector.Type = typ.BytePtr
|
||||
}
|
||||
leaf.copyOf(selector)
|
||||
for _, s := range namedSelects[selector] {
|
||||
locs = append(locs, f.Names[s.locIndex])
|
||||
|
|
|
@ -663,8 +663,8 @@
|
|||
((OR|XOR)W x (MOVDconst [c])) => ((OR|XOR)Wconst [int32(c)] x)
|
||||
|
||||
// Constant shifts.
|
||||
(S(LD|RD|RAD) x (MOVDconst [c])) => (S(LD|RD|RAD)const x [int8(c&63)])
|
||||
(S(LW|RW|RAW) x (MOVDconst [c])) && c&32 == 0 => (S(LW|RW|RAW)const x [int8(c&31)])
|
||||
(S(LD|RD|RAD) x (MOVDconst [c])) => (S(LD|RD|RAD)const x [uint8(c&63)])
|
||||
(S(LW|RW|RAW) x (MOVDconst [c])) && c&32 == 0 => (S(LW|RW|RAW)const x [uint8(c&31)])
|
||||
(S(LW|RW) _ (MOVDconst [c])) && c&32 != 0 => (MOVDconst [0])
|
||||
(SRAW x (MOVDconst [c])) && c&32 != 0 => (SRAWconst x [31])
|
||||
|
||||
|
@ -685,8 +685,8 @@
|
|||
(SRAW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRAW x y)
|
||||
|
||||
// Match rotate by constant.
|
||||
(RLLG x (MOVDconst [c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, int8(c&63))})
|
||||
(RLL x (MOVDconst [c])) => (RLLconst x [int8(c&31)])
|
||||
(RLLG x (MOVDconst [c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, uint8(c&63))})
|
||||
(RLL x (MOVDconst [c])) => (RLLconst x [uint8(c&31)])
|
||||
|
||||
// Match rotate by constant pattern.
|
||||
((ADD|OR|XOR) (SLDconst x [c]) (SRDconst x [64-c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, c)})
|
||||
|
@ -705,10 +705,10 @@
|
|||
(CMP(W|WU) (MOVDconst [c]) x) => (InvertFlags (CMP(W|WU)const x [int32(c)]))
|
||||
|
||||
// Match (x >> c) << d to 'rotate then insert selected bits [into zero]'.
|
||||
(SLDconst (SRDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(max8(0, c-d), 63-d, (d-c)&63)})
|
||||
(SLDconst (SRDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(uint8(max8(0, int8(c-d))), 63-d, uint8(int8(d-c)&63))})
|
||||
|
||||
// Match (x << c) >> d to 'rotate then insert selected bits [into zero]'.
|
||||
(SRDconst (SLDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(d, min8(63, 63-c+d), (c-d)&63)})
|
||||
(SRDconst (SLDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(d, uint8(min8(63, int8(63-c+d))), uint8(int8(c-d)&63))})
|
||||
|
||||
// Absorb input zero extension into 'rotate then insert selected bits [into zero]'.
|
||||
(RISBGZ (MOVWZreg x) {r}) && r.InMerge(0xffffffff) != nil => (RISBGZ x {*r.InMerge(0xffffffff)})
|
||||
|
@ -818,18 +818,18 @@
|
|||
|
||||
// c = 2ˣ + 2ʸ => c - 2ˣ = 2ʸ
|
||||
(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(c&(c-1))
|
||||
=> ((ADD|ADDW) (SL(D|W)const <t> x [int8(log32(c&(c-1)))])
|
||||
(SL(D|W)const <t> x [int8(log32(c&^(c-1)))]))
|
||||
=> ((ADD|ADDW) (SL(D|W)const <t> x [uint8(log32(c&(c-1)))])
|
||||
(SL(D|W)const <t> x [uint8(log32(c&^(c-1)))]))
|
||||
|
||||
// c = 2ʸ - 2ˣ => c + 2ˣ = 2ʸ
|
||||
(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(c+(c&^(c-1)))
|
||||
=> ((SUB|SUBW) (SL(D|W)const <t> x [int8(log32(c+(c&^(c-1))))])
|
||||
(SL(D|W)const <t> x [int8(log32(c&^(c-1)))]))
|
||||
=> ((SUB|SUBW) (SL(D|W)const <t> x [uint8(log32(c+(c&^(c-1))))])
|
||||
(SL(D|W)const <t> x [uint8(log32(c&^(c-1)))]))
|
||||
|
||||
// c = 2ˣ - 2ʸ => -c + 2ˣ = 2ʸ
|
||||
(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(-c+(-c&^(-c-1)))
|
||||
=> ((SUB|SUBW) (SL(D|W)const <t> x [int8(log32(-c&^(-c-1)))])
|
||||
(SL(D|W)const <t> x [int8(log32(-c+(-c&^(-c-1))))]))
|
||||
=> ((SUB|SUBW) (SL(D|W)const <t> x [uint8(log32(-c&^(-c-1)))])
|
||||
(SL(D|W)const <t> x [uint8(log32(-c+(-c&^(-c-1))))]))
|
||||
|
||||
// Fold ADD into MOVDaddr. Odd offsets from SB shouldn't be folded (LARL can't handle them).
|
||||
(ADDconst [c] (MOVDaddr [d] {s} x:(SB))) && ((c+d)&1 == 0) && is32Bit(int64(c)+int64(d)) => (MOVDaddr [c+d] {s} x)
|
||||
|
|
|
@ -330,27 +330,27 @@ func init() {
|
|||
{name: "LTDBR", argLength: 1, reg: fp1flags, asm: "LTDBR", typ: "Flags"}, // arg0 compare to 0, f64
|
||||
{name: "LTEBR", argLength: 1, reg: fp1flags, asm: "LTEBR", typ: "Flags"}, // arg0 compare to 0, f32
|
||||
|
||||
{name: "SLD", argLength: 2, reg: sh21, asm: "SLD"}, // arg0 << arg1, shift amount is mod 64
|
||||
{name: "SLW", argLength: 2, reg: sh21, asm: "SLW"}, // arg0 << arg1, shift amount is mod 64
|
||||
{name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "Int8"}, // arg0 << auxint, shift amount 0-63
|
||||
{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "Int8"}, // arg0 << auxint, shift amount 0-31
|
||||
{name: "SLD", argLength: 2, reg: sh21, asm: "SLD"}, // arg0 << arg1, shift amount is mod 64
|
||||
{name: "SLW", argLength: 2, reg: sh21, asm: "SLW"}, // arg0 << arg1, shift amount is mod 64
|
||||
{name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "UInt8"}, // arg0 << auxint, shift amount 0-63
|
||||
{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "UInt8"}, // arg0 << auxint, shift amount 0-31
|
||||
|
||||
{name: "SRD", argLength: 2, reg: sh21, asm: "SRD"}, // unsigned arg0 >> arg1, shift amount is mod 64
|
||||
{name: "SRW", argLength: 2, reg: sh21, asm: "SRW"}, // unsigned uint32(arg0) >> arg1, shift amount is mod 64
|
||||
{name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "Int8"}, // unsigned arg0 >> auxint, shift amount 0-63
|
||||
{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "Int8"}, // unsigned uint32(arg0) >> auxint, shift amount 0-31
|
||||
{name: "SRD", argLength: 2, reg: sh21, asm: "SRD"}, // unsigned arg0 >> arg1, shift amount is mod 64
|
||||
{name: "SRW", argLength: 2, reg: sh21, asm: "SRW"}, // unsigned uint32(arg0) >> arg1, shift amount is mod 64
|
||||
{name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "UInt8"}, // unsigned arg0 >> auxint, shift amount 0-63
|
||||
{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "UInt8"}, // unsigned uint32(arg0) >> auxint, shift amount 0-31
|
||||
|
||||
// Arithmetic shifts clobber flags.
|
||||
{name: "SRAD", argLength: 2, reg: sh21, asm: "SRAD", clobberFlags: true}, // signed arg0 >> arg1, shift amount is mod 64
|
||||
{name: "SRAW", argLength: 2, reg: sh21, asm: "SRAW", clobberFlags: true}, // signed int32(arg0) >> arg1, shift amount is mod 64
|
||||
{name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "Int8", clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-63
|
||||
{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "Int8", clobberFlags: true}, // signed int32(arg0) >> auxint, shift amount 0-31
|
||||
{name: "SRAD", argLength: 2, reg: sh21, asm: "SRAD", clobberFlags: true}, // signed arg0 >> arg1, shift amount is mod 64
|
||||
{name: "SRAW", argLength: 2, reg: sh21, asm: "SRAW", clobberFlags: true}, // signed int32(arg0) >> arg1, shift amount is mod 64
|
||||
{name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "UInt8", clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-63
|
||||
{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "UInt8", clobberFlags: true}, // signed int32(arg0) >> auxint, shift amount 0-31
|
||||
|
||||
// Rotate instructions.
|
||||
// Note: no RLLGconst - use RISBGZ instead.
|
||||
{name: "RLLG", argLength: 2, reg: sh21, asm: "RLLG"}, // arg0 rotate left arg1, rotate amount 0-63
|
||||
{name: "RLL", argLength: 2, reg: sh21, asm: "RLL"}, // arg0 rotate left arg1, rotate amount 0-31
|
||||
{name: "RLLconst", argLength: 1, reg: gp11, asm: "RLL", aux: "Int8"}, // arg0 rotate left auxint, rotate amount 0-31
|
||||
{name: "RLLG", argLength: 2, reg: sh21, asm: "RLLG"}, // arg0 rotate left arg1, rotate amount 0-63
|
||||
{name: "RLL", argLength: 2, reg: sh21, asm: "RLL"}, // arg0 rotate left arg1, rotate amount 0-31
|
||||
{name: "RLLconst", argLength: 1, reg: gp11, asm: "RLL", aux: "UInt8"}, // arg0 rotate left auxint, rotate amount 0-31
|
||||
|
||||
// Rotate then (and|or|xor|insert) selected bits instructions.
|
||||
//
|
||||
|
|
|
@ -1395,7 +1395,7 @@ func parseValue(val string, arch arch, loc string) (op opData, oparch, typ, auxi
|
|||
|
||||
func opHasAuxInt(op opData) bool {
|
||||
switch op.aux {
|
||||
case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "Float32", "Float64",
|
||||
case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "UInt8", "Float32", "Float64",
|
||||
"SymOff", "CallOff", "SymValAndOff", "TypSize", "ARM64BitField", "FlagConstant", "CCop":
|
||||
return true
|
||||
}
|
||||
|
@ -1780,6 +1780,8 @@ func (op opData) auxIntType() string {
|
|||
return "int64"
|
||||
case "Int128":
|
||||
return "int128"
|
||||
case "UInt8":
|
||||
return "uint8"
|
||||
case "Float32":
|
||||
return "float32"
|
||||
case "Float64":
|
||||
|
|
|
@ -207,6 +207,7 @@ const (
|
|||
auxInt32 // auxInt is a 32-bit integer
|
||||
auxInt64 // auxInt is a 64-bit integer
|
||||
auxInt128 // auxInt represents a 128-bit integer. Always 0.
|
||||
auxUInt8 // auxInt is an 8-bit unsigned integer
|
||||
auxFloat32 // auxInt is a float32 (encoded with math.Float64bits)
|
||||
auxFloat64 // auxInt is a float64 (encoded with math.Float64bits)
|
||||
auxFlagConstant // auxInt is a flagConstant
|
||||
|
|
|
@ -30569,7 +30569,7 @@ var opcodeTable = [...]opInfo{
|
|||
},
|
||||
{
|
||||
name: "SLDconst",
|
||||
auxType: auxInt8,
|
||||
auxType: auxUInt8,
|
||||
argLen: 1,
|
||||
asm: s390x.ASLD,
|
||||
reg: regInfo{
|
||||
|
@ -30583,7 +30583,7 @@ var opcodeTable = [...]opInfo{
|
|||
},
|
||||
{
|
||||
name: "SLWconst",
|
||||
auxType: auxInt8,
|
||||
auxType: auxUInt8,
|
||||
argLen: 1,
|
||||
asm: s390x.ASLW,
|
||||
reg: regInfo{
|
||||
|
@ -30625,7 +30625,7 @@ var opcodeTable = [...]opInfo{
|
|||
},
|
||||
{
|
||||
name: "SRDconst",
|
||||
auxType: auxInt8,
|
||||
auxType: auxUInt8,
|
||||
argLen: 1,
|
||||
asm: s390x.ASRD,
|
||||
reg: regInfo{
|
||||
|
@ -30639,7 +30639,7 @@ var opcodeTable = [...]opInfo{
|
|||
},
|
||||
{
|
||||
name: "SRWconst",
|
||||
auxType: auxInt8,
|
||||
auxType: auxUInt8,
|
||||
argLen: 1,
|
||||
asm: s390x.ASRW,
|
||||
reg: regInfo{
|
||||
|
@ -30683,7 +30683,7 @@ var opcodeTable = [...]opInfo{
|
|||
},
|
||||
{
|
||||
name: "SRADconst",
|
||||
auxType: auxInt8,
|
||||
auxType: auxUInt8,
|
||||
argLen: 1,
|
||||
clobberFlags: true,
|
||||
asm: s390x.ASRAD,
|
||||
|
@ -30698,7 +30698,7 @@ var opcodeTable = [...]opInfo{
|
|||
},
|
||||
{
|
||||
name: "SRAWconst",
|
||||
auxType: auxInt8,
|
||||
auxType: auxUInt8,
|
||||
argLen: 1,
|
||||
clobberFlags: true,
|
||||
asm: s390x.ASRAW,
|
||||
|
@ -30741,7 +30741,7 @@ var opcodeTable = [...]opInfo{
|
|||
},
|
||||
{
|
||||
name: "RLLconst",
|
||||
auxType: auxInt8,
|
||||
auxType: auxUInt8,
|
||||
argLen: 1,
|
||||
asm: s390x.ARLL,
|
||||
reg: regInfo{
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,5 +8,5 @@ require (
|
|||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
|
||||
golang.org/x/mod v0.4.0
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
|
||||
golang.org/x/tools v0.0.0-20201208211828-de58e7c01d49
|
||||
golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11
|
||||
)
|
||||
|
|
|
@ -31,8 +31,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201208211828-de58e7c01d49 h1:K1QAOVIWIvmQ66F1Z3AEa9Wzp0bj+xU3YzLkvROk2Ds=
|
||||
golang.org/x/tools v0.0.0-20201208211828-de58e7c01d49/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11 h1:9j/upNXDRpADUw2RpUfJ7E7GHtfhDih62kX6JM8vs2c=
|
||||
golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
|
|
|
@ -164,6 +164,17 @@
|
|||
// directory, but it is not accessed. When -modfile is specified, an
|
||||
// alternate go.sum file is also used: its path is derived from the
|
||||
// -modfile flag by trimming the ".mod" extension and appending ".sum".
|
||||
// -overlay file
|
||||
// read a JSON config file that provides an overlay for build operations.
|
||||
// The file is a JSON struct with a single field, named 'Replace', that
|
||||
// maps each disk file path (a string) to its backing file path, so that
|
||||
// a build will run as if the disk file path exists with the contents
|
||||
// given by the backing file paths, or as if the disk file path does not
|
||||
// exist if its backing file path is empty. Support for the -overlay flag
|
||||
// has some limitations:importantly, cgo files included from outside the
|
||||
// include path must be in the same directory as the Go package they are
|
||||
// included from, and overlays will not appear when binaries and tests are
|
||||
// run through go run and go test respectively.
|
||||
// -pkgdir dir
|
||||
// install and load all packages from dir instead of the usual locations.
|
||||
// For example, when building with a non-standard configuration,
|
||||
|
|
|
@ -31,6 +31,7 @@ import (
|
|||
"cmd/go/internal/cache"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/robustio"
|
||||
"cmd/go/internal/work"
|
||||
"cmd/internal/sys"
|
||||
)
|
||||
|
||||
|
@ -1365,6 +1366,30 @@ func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
|
|||
tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`)
|
||||
}
|
||||
|
||||
func TestLdFlagsLongArgumentsIssue42295(t *testing.T) {
|
||||
// Test the extremely long command line arguments that contain '\n' characters
|
||||
// get encoded and passed correctly.
|
||||
skipIfGccgo(t, "gccgo does not support -ldflags -X")
|
||||
tooSlow(t)
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
tg.parallel()
|
||||
tg.tempFile("main.go", `package main
|
||||
var extern string
|
||||
func main() {
|
||||
print(extern)
|
||||
}`)
|
||||
testStr := "test test test test test \n\\ "
|
||||
var buf bytes.Buffer
|
||||
for buf.Len() < work.ArgLengthForResponseFile+1 {
|
||||
buf.WriteString(testStr)
|
||||
}
|
||||
tg.run("run", "-ldflags", fmt.Sprintf(`-X "main.extern=%s"`, buf.String()), tg.path("main.go"))
|
||||
if tg.stderr.String() != buf.String() {
|
||||
t.Errorf("strings differ")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) {
|
||||
skipIfGccgo(t, "gccgo has no standard packages")
|
||||
tooSlow(t)
|
||||
|
|
|
@ -33,8 +33,20 @@ See also: go fmt, go vet.
|
|||
}
|
||||
|
||||
func runFix(ctx context.Context, cmd *base.Command, args []string) {
|
||||
pkgs := load.PackagesAndErrors(ctx, args)
|
||||
w := 0
|
||||
for _, pkg := range pkgs {
|
||||
if pkg.Error != nil {
|
||||
base.Errorf("%v", pkg.Error)
|
||||
continue
|
||||
}
|
||||
pkgs[w] = pkg
|
||||
w++
|
||||
}
|
||||
pkgs = pkgs[:w]
|
||||
|
||||
printed := false
|
||||
for _, pkg := range load.Packages(ctx, args) {
|
||||
for _, pkg := range pkgs {
|
||||
if modload.Enabled() && pkg.Module != nil && !pkg.Module.Main {
|
||||
if !printed {
|
||||
fmt.Fprintf(os.Stderr, "go: not fixing packages in dependency modules\n")
|
||||
|
|
|
@ -180,13 +180,14 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
|
|||
// everything.
|
||||
load.ClearPackageCache()
|
||||
|
||||
pkgs := load.PackagesForBuild(ctx, args)
|
||||
pkgs := load.PackagesAndErrors(ctx, args)
|
||||
load.CheckPackageErrors(pkgs)
|
||||
|
||||
// Phase 3. Install.
|
||||
if *getD {
|
||||
// Download only.
|
||||
// Check delayed until now so that importPaths
|
||||
// and packagesForBuild have a chance to print errors.
|
||||
// Check delayed until now so that downloadPaths
|
||||
// and CheckPackageErrors have a chance to print errors.
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -471,11 +471,18 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
|
|||
}
|
||||
|
||||
load.IgnoreImports = *listFind
|
||||
var pkgs []*load.Package
|
||||
if *listE {
|
||||
pkgs = load.PackagesAndErrors(ctx, args)
|
||||
} else {
|
||||
pkgs = load.Packages(ctx, args)
|
||||
pkgs := load.PackagesAndErrors(ctx, args)
|
||||
if !*listE {
|
||||
w := 0
|
||||
for _, pkg := range pkgs {
|
||||
if pkg.Error != nil {
|
||||
base.Errorf("%v", pkg.Error)
|
||||
continue
|
||||
}
|
||||
pkgs[w] = pkg
|
||||
w++
|
||||
}
|
||||
pkgs = pkgs[:w]
|
||||
base.ExitIfErrors()
|
||||
}
|
||||
|
||||
|
|
|
@ -2314,30 +2314,14 @@ func LoadImportWithFlags(path, srcDir string, parent *Package, stk *ImportStack,
|
|||
// argument where needed.
|
||||
var ModResolveTests bool
|
||||
|
||||
// Packages returns the packages named by the
|
||||
// command line arguments 'args'. If a named package
|
||||
// cannot be loaded at all (for example, if the directory does not exist),
|
||||
// then packages prints an error and does not include that
|
||||
// package in the results. However, if errors occur trying
|
||||
// to load dependencies of a named package, the named
|
||||
// package is still returned, with p.Incomplete = true
|
||||
// and details in p.DepsErrors.
|
||||
func Packages(ctx context.Context, args []string) []*Package {
|
||||
var pkgs []*Package
|
||||
for _, pkg := range PackagesAndErrors(ctx, args) {
|
||||
if pkg.Error != nil {
|
||||
base.Errorf("%v", pkg.Error)
|
||||
continue
|
||||
}
|
||||
pkgs = append(pkgs, pkg)
|
||||
}
|
||||
return pkgs
|
||||
}
|
||||
|
||||
// PackagesAndErrors is like 'packages' but returns a
|
||||
// *Package for every argument, even the ones that
|
||||
// cannot be loaded at all.
|
||||
// The packages that fail to load will have p.Error != nil.
|
||||
// PackagesAndErrors returns the packages named by the command line arguments
|
||||
// 'patterns'. If a named package cannot be loaded, PackagesAndErrors returns
|
||||
// a *Package with the Error field describing the failure. If errors are found
|
||||
// loading imported packages, the DepsErrors field is set. The Incomplete field
|
||||
// may be set as well.
|
||||
//
|
||||
// To obtain a flat list of packages, use PackageList.
|
||||
// To report errors loading packages, use ReportPackageErrors.
|
||||
func PackagesAndErrors(ctx context.Context, patterns []string) []*Package {
|
||||
ctx, span := trace.StartSpan(ctx, "load.PackagesAndErrors")
|
||||
defer span.Done()
|
||||
|
@ -2427,20 +2411,9 @@ func PackagesAndErrors(ctx context.Context, patterns []string) []*Package {
|
|||
return pkgs
|
||||
}
|
||||
|
||||
func setToolFlags(pkgs ...*Package) {
|
||||
for _, p := range PackageList(pkgs) {
|
||||
p.Internal.Asmflags = BuildAsmflags.For(p)
|
||||
p.Internal.Gcflags = BuildGcflags.For(p)
|
||||
p.Internal.Ldflags = BuildLdflags.For(p)
|
||||
p.Internal.Gccgoflags = BuildGccgoflags.For(p)
|
||||
}
|
||||
}
|
||||
|
||||
// PackagesForBuild is like Packages but exits
|
||||
// if any of the packages or their dependencies have errors
|
||||
// (cannot be built).
|
||||
func PackagesForBuild(ctx context.Context, args []string) []*Package {
|
||||
pkgs := PackagesAndErrors(ctx, args)
|
||||
// CheckPackageErrors prints errors encountered loading pkgs and their
|
||||
// dependencies, then exits with a non-zero status if any errors were found.
|
||||
func CheckPackageErrors(pkgs []*Package) {
|
||||
printed := map[*PackageError]bool{}
|
||||
for _, pkg := range pkgs {
|
||||
if pkg.Error != nil {
|
||||
|
@ -2475,8 +2448,15 @@ func PackagesForBuild(ctx context.Context, args []string) []*Package {
|
|||
seen[pkg.ImportPath] = true
|
||||
}
|
||||
base.ExitIfErrors()
|
||||
}
|
||||
|
||||
return pkgs
|
||||
func setToolFlags(pkgs ...*Package) {
|
||||
for _, p := range PackageList(pkgs) {
|
||||
p.Internal.Asmflags = BuildAsmflags.For(p)
|
||||
p.Internal.Gcflags = BuildGcflags.For(p)
|
||||
p.Internal.Ldflags = BuildLdflags.For(p)
|
||||
p.Internal.Gccgoflags = BuildGccgoflags.For(p)
|
||||
}
|
||||
}
|
||||
|
||||
// GoFilesPackage creates a package for building a collection of Go files
|
||||
|
|
|
@ -434,11 +434,13 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
|
|||
// directory.
|
||||
if !*getD && len(pkgPatterns) > 0 {
|
||||
work.BuildInit()
|
||||
pkgs := load.PackagesForBuild(ctx, pkgPatterns)
|
||||
pkgs := load.PackagesAndErrors(ctx, pkgPatterns)
|
||||
load.CheckPackageErrors(pkgs)
|
||||
work.InstallPackages(ctx, pkgPatterns, pkgs)
|
||||
// TODO(#40276): After Go 1.16, print a deprecation notice when building
|
||||
// and installing main packages. 'go install pkg' or
|
||||
// 'go install pkg@version' should be used instead.
|
||||
// Give the specific argument to use if possible.
|
||||
}
|
||||
|
||||
if !modload.HasModRoot() {
|
||||
|
|
|
@ -595,7 +595,8 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
|
|||
work.VetFlags = testVet.flags
|
||||
work.VetExplicit = testVet.explicit
|
||||
|
||||
pkgs = load.PackagesForBuild(ctx, pkgArgs)
|
||||
pkgs = load.PackagesAndErrors(ctx, pkgArgs)
|
||||
load.CheckPackageErrors(pkgs)
|
||||
if len(pkgs) == 0 {
|
||||
base.Fatalf("no packages to test")
|
||||
}
|
||||
|
@ -678,7 +679,9 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
|
|||
sort.Strings(all)
|
||||
|
||||
a := &work.Action{Mode: "go test -i"}
|
||||
for _, p := range load.PackagesForBuild(ctx, all) {
|
||||
pkgs := load.PackagesAndErrors(ctx, all)
|
||||
load.CheckPackageErrors(pkgs)
|
||||
for _, p := range pkgs {
|
||||
if cfg.BuildToolchainName == "gccgo" && p.Standard {
|
||||
// gccgo's standard library packages
|
||||
// can not be reinstalled.
|
||||
|
|
|
@ -87,7 +87,8 @@ func runVet(ctx context.Context, cmd *base.Command, args []string) {
|
|||
}
|
||||
}
|
||||
|
||||
pkgs := load.PackagesForBuild(ctx, pkgArgs)
|
||||
pkgs := load.PackagesAndErrors(ctx, pkgArgs)
|
||||
load.CheckPackageErrors(pkgs)
|
||||
if len(pkgs) == 0 {
|
||||
base.Fatalf("no packages to vet")
|
||||
}
|
||||
|
|
|
@ -124,6 +124,17 @@ and test commands:
|
|||
directory, but it is not accessed. When -modfile is specified, an
|
||||
alternate go.sum file is also used: its path is derived from the
|
||||
-modfile flag by trimming the ".mod" extension and appending ".sum".
|
||||
-overlay file
|
||||
read a JSON config file that provides an overlay for build operations.
|
||||
The file is a JSON struct with a single field, named 'Replace', that
|
||||
maps each disk file path (a string) to its backing file path, so that
|
||||
a build will run as if the disk file path exists with the contents
|
||||
given by the backing file paths, or as if the disk file path does not
|
||||
exist if its backing file path is empty. Support for the -overlay flag
|
||||
has some limitations:importantly, cgo files included from outside the
|
||||
include path must be in the same directory as the Go package they are
|
||||
included from, and overlays will not appear when binaries and tests are
|
||||
run through go run and go test respectively.
|
||||
-pkgdir dir
|
||||
install and load all packages from dir instead of the usual locations.
|
||||
For example, when building with a non-standard configuration,
|
||||
|
@ -358,7 +369,8 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) {
|
|||
var b Builder
|
||||
b.Init()
|
||||
|
||||
pkgs := load.PackagesForBuild(ctx, args)
|
||||
pkgs := load.PackagesAndErrors(ctx, args)
|
||||
load.CheckPackageErrors(pkgs)
|
||||
|
||||
explicitO := len(cfg.BuildO) > 0
|
||||
|
||||
|
@ -388,7 +400,7 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) {
|
|||
fmt.Fprint(os.Stderr, "go build: -i flag is deprecated\n")
|
||||
}
|
||||
|
||||
pkgs = omitTestOnly(pkgsFilter(load.Packages(ctx, args)))
|
||||
pkgs = omitTestOnly(pkgsFilter(pkgs))
|
||||
|
||||
// Special case -o /dev/null by not writing at all.
|
||||
if cfg.BuildO == os.DevNull {
|
||||
|
@ -571,8 +583,32 @@ func runInstall(ctx context.Context, cmd *base.Command, args []string) {
|
|||
return
|
||||
}
|
||||
}
|
||||
|
||||
BuildInit()
|
||||
pkgs := load.PackagesForBuild(ctx, args)
|
||||
pkgs := load.PackagesAndErrors(ctx, args)
|
||||
if cfg.ModulesEnabled && !modload.HasModRoot() {
|
||||
haveErrors := false
|
||||
allMissingErrors := true
|
||||
for _, pkg := range pkgs {
|
||||
if pkg.Error == nil {
|
||||
continue
|
||||
}
|
||||
haveErrors = true
|
||||
if missingErr := (*modload.ImportMissingError)(nil); !errors.As(pkg.Error, &missingErr) {
|
||||
allMissingErrors = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if haveErrors && allMissingErrors {
|
||||
latestArgs := make([]string, len(args))
|
||||
for i := range args {
|
||||
latestArgs[i] = args[i] + "@latest"
|
||||
}
|
||||
hint := strings.Join(latestArgs, " ")
|
||||
base.Fatalf("go install: version is required when current directory is not in a module\n\tTry 'go install %s' to install the latest version", hint)
|
||||
}
|
||||
}
|
||||
load.CheckPackageErrors(pkgs)
|
||||
if cfg.BuildI {
|
||||
allGoroot := true
|
||||
for _, pkg := range pkgs {
|
||||
|
@ -585,6 +621,7 @@ func runInstall(ctx context.Context, cmd *base.Command, args []string) {
|
|||
fmt.Fprint(os.Stderr, "go install: -i flag is deprecated\n")
|
||||
}
|
||||
}
|
||||
|
||||
InstallPackages(ctx, args, pkgs)
|
||||
}
|
||||
|
||||
|
@ -802,7 +839,7 @@ func installOutsideModule(ctx context.Context, args []string) {
|
|||
|
||||
// Load packages for all arguments. Ignore non-main packages.
|
||||
// Print a warning if an argument contains "..." and matches no main packages.
|
||||
// PackagesForBuild already prints warnings for patterns that don't match any
|
||||
// PackagesAndErrors already prints warnings for patterns that don't match any
|
||||
// packages, so be careful not to double print.
|
||||
matchers := make([]func(string) bool, len(patterns))
|
||||
for i, p := range patterns {
|
||||
|
@ -813,7 +850,8 @@ func installOutsideModule(ctx context.Context, args []string) {
|
|||
|
||||
// TODO(golang.org/issue/40276): don't report errors loading non-main packages
|
||||
// matched by a pattern.
|
||||
pkgs := load.PackagesForBuild(ctx, patterns)
|
||||
pkgs := load.PackagesAndErrors(ctx, patterns)
|
||||
load.CheckPackageErrors(pkgs)
|
||||
mainPkgs := make([]*load.Package, 0, len(pkgs))
|
||||
mainCount := make([]int, len(patterns))
|
||||
nonMainCount := make([]int, len(patterns))
|
||||
|
|
|
@ -3236,7 +3236,7 @@ func passLongArgsInResponseFiles(cmd *exec.Cmd) (cleanup func()) {
|
|||
cleanup = func() { os.Remove(tf.Name()) }
|
||||
var buf bytes.Buffer
|
||||
for _, arg := range cmd.Args[1:] {
|
||||
fmt.Fprintf(&buf, "%s\n", arg)
|
||||
fmt.Fprintf(&buf, "%s\n", encodeArg(arg))
|
||||
}
|
||||
if _, err := tf.Write(buf.Bytes()); err != nil {
|
||||
tf.Close()
|
||||
|
@ -3251,6 +3251,12 @@ func passLongArgsInResponseFiles(cmd *exec.Cmd) (cleanup func()) {
|
|||
return cleanup
|
||||
}
|
||||
|
||||
// Windows has a limit of 32 KB arguments. To be conservative and not worry
|
||||
// about whether that includes spaces or not, just use 30 KB. Darwin's limit is
|
||||
// less clear. The OS claims 256KB, but we've seen failures with arglen as
|
||||
// small as 50KB.
|
||||
const ArgLengthForResponseFile = (30 << 10)
|
||||
|
||||
func useResponseFile(path string, argLen int) bool {
|
||||
// Unless the program uses objabi.Flagparse, which understands
|
||||
// response files, don't use response files.
|
||||
|
@ -3262,11 +3268,7 @@ func useResponseFile(path string, argLen int) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// Windows has a limit of 32 KB arguments. To be conservative and not
|
||||
// worry about whether that includes spaces or not, just use 30 KB.
|
||||
// Darwin's limit is less clear. The OS claims 256KB, but we've seen
|
||||
// failures with arglen as small as 50KB.
|
||||
if argLen > (30 << 10) {
|
||||
if argLen > ArgLengthForResponseFile {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -3279,3 +3281,25 @@ func useResponseFile(path string, argLen int) bool {
|
|||
|
||||
return false
|
||||
}
|
||||
|
||||
// encodeArg encodes an argument for response file writing.
|
||||
func encodeArg(arg string) string {
|
||||
// If there aren't any characters we need to reencode, fastpath out.
|
||||
if !strings.ContainsAny(arg, "\\\n") {
|
||||
return arg
|
||||
}
|
||||
var b strings.Builder
|
||||
for _, r := range arg {
|
||||
switch r {
|
||||
case '\\':
|
||||
b.WriteByte('\\')
|
||||
b.WriteByte('\\')
|
||||
case '\n':
|
||||
b.WriteByte('\\')
|
||||
b.WriteByte('n')
|
||||
default:
|
||||
b.WriteRune(r)
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
|
86
src/cmd/go/internal/work/exec_test.go
Normal file
86
src/cmd/go/internal/work/exec_test.go
Normal file
|
@ -0,0 +1,86 @@
|
|||
// Copyright 2011 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 work
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"cmd/internal/objabi"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func TestEncodeArgs(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
arg, want string
|
||||
}{
|
||||
{"", ""},
|
||||
{"hello", "hello"},
|
||||
{"hello\n", "hello\\n"},
|
||||
{"hello\\", "hello\\\\"},
|
||||
{"hello\nthere", "hello\\nthere"},
|
||||
{"\\\n", "\\\\\\n"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if got := encodeArg(test.arg); got != test.want {
|
||||
t.Errorf("encodeArg(%q) = %q, want %q", test.arg, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeDecode(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []string{
|
||||
"",
|
||||
"hello",
|
||||
"hello\\there",
|
||||
"hello\nthere",
|
||||
"hello 中国",
|
||||
"hello \n中\\国",
|
||||
}
|
||||
for _, arg := range tests {
|
||||
if got := objabi.DecodeArg(encodeArg(arg)); got != arg {
|
||||
t.Errorf("objabi.DecodeArg(encodeArg(%q)) = %q", arg, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeDecodeFuzz(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("fuzz test is slow")
|
||||
}
|
||||
t.Parallel()
|
||||
|
||||
nRunes := ArgLengthForResponseFile + 100
|
||||
rBuffer := make([]rune, nRunes)
|
||||
buf := bytes.NewBuffer([]byte(string(rBuffer)))
|
||||
|
||||
seed := time.Now().UnixNano()
|
||||
t.Logf("rand seed: %v", seed)
|
||||
rng := rand.New(rand.NewSource(seed))
|
||||
|
||||
for i := 0; i < 50; i++ {
|
||||
// Generate a random string of runes.
|
||||
buf.Reset()
|
||||
for buf.Len() < ArgLengthForResponseFile+1 {
|
||||
var r rune
|
||||
for {
|
||||
r = rune(rng.Intn(utf8.MaxRune + 1))
|
||||
if utf8.ValidRune(r) {
|
||||
break
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(buf, "%c", r)
|
||||
}
|
||||
arg := buf.String()
|
||||
|
||||
if got := objabi.DecodeArg(encodeArg(arg)); got != arg {
|
||||
t.Errorf("[%d] objabi.DecodeArg(encodeArg(%q)) = %q [seed: %v]", i, arg, got, seed)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -241,7 +241,8 @@ func buildModeInit() {
|
|||
if gccgo {
|
||||
codegenArg = "-fPIC"
|
||||
} else {
|
||||
forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1")
|
||||
forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1",
|
||||
"-linkshared")
|
||||
codegenArg = "-dynlink"
|
||||
forcedGcflags = append(forcedGcflags, "-linkshared")
|
||||
// TODO(mwhudson): remove -w when that gets fixed in linker.
|
||||
|
|
5
src/cmd/go/testdata/script/mod_outside.txt
vendored
5
src/cmd/go/testdata/script/mod_outside.txt
vendored
|
@ -189,13 +189,16 @@ exists $GOPATH/bin/printversion$GOEXE
|
|||
|
||||
# 'go install' should fail if a package argument must be resolved to a module.
|
||||
! go install example.com/printversion
|
||||
stderr 'no required module provides package example.com/printversion: working directory is not part of a module'
|
||||
stderr '^go install: version is required when current directory is not in a module\n\tTry ''go install example.com/printversion@latest'' to install the latest version$'
|
||||
|
||||
# 'go install' should fail if a source file imports a package that must be
|
||||
# resolved to a module.
|
||||
! go install ./needmod/needmod.go
|
||||
stderr 'needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: working directory is not part of a module'
|
||||
|
||||
# 'go install' should succeed with a package in GOROOT.
|
||||
go install cmd/addr2line
|
||||
! stderr .
|
||||
|
||||
# 'go run' with a verison should fail due to syntax.
|
||||
! go run example.com/printversion@v1.0.0
|
||||
|
|
|
@ -483,6 +483,11 @@ func (r *RefFlags) SetFlag2(x uint8) { r[9] = x }
|
|||
|
||||
func (r *RefFlags) Write(w *Writer) { w.Bytes(r[:]) }
|
||||
|
||||
// Used to construct an artifically 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:
|
||||
|
@ -792,7 +797,7 @@ func (r *Reader) Reloc(i uint32, j int) *Reloc {
|
|||
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]
|
||||
return (*[huge]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n]
|
||||
}
|
||||
|
||||
// NAux returns the number of aux symbols of the i-th symbol.
|
||||
|
@ -818,7 +823,7 @@ func (r *Reader) Aux(i uint32, j int) *Aux {
|
|||
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]
|
||||
return (*[huge]Aux)(unsafe.Pointer(&r.b[off]))[:n:n]
|
||||
}
|
||||
|
||||
// DataOff returns the offset of the i-th symbol's data.
|
||||
|
|
|
@ -28,9 +28,9 @@ import (
|
|||
// input left by. Note that this rotation is performed
|
||||
// before the masked region is used.
|
||||
type RotateParams struct {
|
||||
Start int8 // big-endian start bit index [0..63]
|
||||
End int8 // big-endian end bit index [0..63]
|
||||
Amount int8 // amount to rotate left
|
||||
Start uint8 // big-endian start bit index [0..63]
|
||||
End uint8 // big-endian end bit index [0..63]
|
||||
Amount uint8 // amount to rotate left
|
||||
}
|
||||
|
||||
// NewRotateParams creates a set of parameters representing a
|
||||
|
@ -39,7 +39,7 @@ type RotateParams struct {
|
|||
//
|
||||
// The start and end indexes and the rotation amount must all
|
||||
// be in the range 0-63 inclusive or this function will panic.
|
||||
func NewRotateParams(start, end, amount int8) RotateParams {
|
||||
func NewRotateParams(start, end, amount uint8) RotateParams {
|
||||
if start&^63 != 0 {
|
||||
panic("start out of bounds")
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ func NewRotateParams(start, end, amount int8) RotateParams {
|
|||
|
||||
// RotateLeft generates a new set of parameters with the rotation amount
|
||||
// increased by the given value. The selected bits are left unchanged.
|
||||
func (r RotateParams) RotateLeft(amount int8) RotateParams {
|
||||
func (r RotateParams) RotateLeft(amount uint8) RotateParams {
|
||||
r.Amount += amount
|
||||
r.Amount &= 63
|
||||
return r
|
||||
|
@ -100,8 +100,8 @@ func (r RotateParams) OutMerge(mask uint64) *RotateParams {
|
|||
}
|
||||
|
||||
// update start and end positions (rotation amount remains the same)
|
||||
r.Start = int8(o+z) & 63
|
||||
r.End = (r.Start + int8(l) - 1) & 63
|
||||
r.Start = uint8(o+z) & 63
|
||||
r.End = (r.Start + uint8(l) - 1) & 63
|
||||
return &r
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
func TestRotateParamsMask(t *testing.T) {
|
||||
tests := []struct {
|
||||
start, end, amount int8
|
||||
start, end, amount uint8
|
||||
inMask, outMask uint64
|
||||
}{
|
||||
// start before end, no rotation
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package objabi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -59,6 +60,9 @@ func expandArgs(in []string) (out []string) {
|
|||
log.Fatal(err)
|
||||
}
|
||||
args := strings.Split(strings.TrimSpace(strings.Replace(string(slurp), "\r", "", -1)), "\n")
|
||||
for i, arg := range args {
|
||||
args[i] = DecodeArg(arg)
|
||||
}
|
||||
out = append(out, expandArgs(args)...)
|
||||
} else if out != nil {
|
||||
out = append(out, s)
|
||||
|
@ -160,3 +164,38 @@ func (f fn1) Set(s string) error {
|
|||
}
|
||||
|
||||
func (f fn1) String() string { return "" }
|
||||
|
||||
// DecodeArg decodes an argument.
|
||||
//
|
||||
// This function is public for testing with the parallel encoder.
|
||||
func DecodeArg(arg string) string {
|
||||
// If no encoding, fastpath out.
|
||||
if !strings.ContainsAny(arg, "\\\n") {
|
||||
return arg
|
||||
}
|
||||
|
||||
// We can't use strings.Builder as this must work at bootstrap.
|
||||
var b bytes.Buffer
|
||||
var wasBS bool
|
||||
for _, r := range arg {
|
||||
if wasBS {
|
||||
switch r {
|
||||
case '\\':
|
||||
b.WriteByte('\\')
|
||||
case 'n':
|
||||
b.WriteByte('\n')
|
||||
default:
|
||||
// This shouldn't happen. The only backslashes that reach here
|
||||
// should encode '\n' and '\\' exclusively.
|
||||
panic("badly formatted input")
|
||||
}
|
||||
} else if r == '\\' {
|
||||
wasBS = true
|
||||
continue
|
||||
} else {
|
||||
b.WriteRune(r)
|
||||
}
|
||||
wasBS = false
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
|
26
src/cmd/internal/objabi/flag_test.go
Normal file
26
src/cmd/internal/objabi/flag_test.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
// 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 objabi
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestDecodeArg(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
arg, want string
|
||||
}{
|
||||
{"", ""},
|
||||
{"hello", "hello"},
|
||||
{"hello\\n", "hello\n"},
|
||||
{"hello\\nthere", "hello\nthere"},
|
||||
{"hello\\\\there", "hello\\there"},
|
||||
{"\\\\\\n", "\\\n"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if got := DecodeArg(test.arg); got != test.want {
|
||||
t.Errorf("decodoeArg(%q) = %q, want %q", test.arg, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@ import (
|
|||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"debug/elf"
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
|
@ -463,12 +464,29 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
|
|||
return true
|
||||
}
|
||||
|
||||
// sign-extends from 24-bit.
|
||||
func signext24(x int64) int64 { return x << 40 >> 40 }
|
||||
|
||||
func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, sectoff int64) bool {
|
||||
var v uint32
|
||||
|
||||
rs := r.Xsym
|
||||
rt := r.Type
|
||||
siz := r.Size
|
||||
xadd := r.Xadd
|
||||
|
||||
if xadd != signext24(xadd) {
|
||||
// If the relocation target would overflow the addend, then target
|
||||
// a linker-manufactured label symbol with a smaller addend instead.
|
||||
label := ldr.Lookup(machoLabelName(ldr, rs, xadd), ldr.SymVersion(rs))
|
||||
if label != 0 {
|
||||
xadd = ldr.SymValue(rs) + xadd - ldr.SymValue(label)
|
||||
rs = label
|
||||
}
|
||||
if xadd != signext24(xadd) {
|
||||
ldr.Errorf(s, "internal error: relocation addend overflow: %s+0x%x", ldr.SymName(rs), xadd)
|
||||
}
|
||||
}
|
||||
|
||||
if ldr.SymType(rs) == sym.SHOSTOBJ || rt == objabi.R_CALLARM64 || rt == objabi.R_ADDRARM64 || rt == objabi.R_ARM64_GOTPCREL {
|
||||
if ldr.SymDynid(rs) < 0 {
|
||||
|
@ -492,8 +510,8 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
|
|||
case objabi.R_ADDR:
|
||||
v |= ld.MACHO_ARM64_RELOC_UNSIGNED << 28
|
||||
case objabi.R_CALLARM64:
|
||||
if r.Xadd != 0 {
|
||||
ldr.Errorf(s, "ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", ldr.SymName(rs), r.Xadd)
|
||||
if xadd != 0 {
|
||||
ldr.Errorf(s, "ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", ldr.SymName(rs), xadd)
|
||||
}
|
||||
|
||||
v |= 1 << 24 // pc-relative bit
|
||||
|
@ -504,13 +522,13 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
|
|||
// if r.Xadd is non-zero, add two MACHO_ARM64_RELOC_ADDEND.
|
||||
if r.Xadd != 0 {
|
||||
out.Write32(uint32(sectoff + 4))
|
||||
out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
|
||||
out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(xadd&0xffffff))
|
||||
}
|
||||
out.Write32(uint32(sectoff + 4))
|
||||
out.Write32(v | (ld.MACHO_ARM64_RELOC_PAGEOFF12 << 28) | (2 << 25))
|
||||
if r.Xadd != 0 {
|
||||
out.Write32(uint32(sectoff))
|
||||
out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
|
||||
out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(xadd&0xffffff))
|
||||
}
|
||||
v |= 1 << 24 // pc-relative bit
|
||||
v |= ld.MACHO_ARM64_RELOC_PAGE21 << 28
|
||||
|
@ -520,13 +538,13 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
|
|||
// if r.Xadd is non-zero, add two MACHO_ARM64_RELOC_ADDEND.
|
||||
if r.Xadd != 0 {
|
||||
out.Write32(uint32(sectoff + 4))
|
||||
out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
|
||||
out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(xadd&0xffffff))
|
||||
}
|
||||
out.Write32(uint32(sectoff + 4))
|
||||
out.Write32(v | (ld.MACHO_ARM64_RELOC_GOT_LOAD_PAGEOFF12 << 28) | (2 << 25))
|
||||
if r.Xadd != 0 {
|
||||
out.Write32(uint32(sectoff))
|
||||
out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
|
||||
out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(xadd&0xffffff))
|
||||
}
|
||||
v |= 1 << 24 // pc-relative bit
|
||||
v |= ld.MACHO_ARM64_RELOC_GOT_LOAD_PAGE21 << 28
|
||||
|
@ -965,3 +983,66 @@ func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade
|
|||
ldr.Errorf(s, "addpltsym: unsupported binary format")
|
||||
}
|
||||
}
|
||||
|
||||
const machoRelocLimit = 1 << 23
|
||||
|
||||
func gensymlate(ctxt *ld.Link, ldr *loader.Loader) {
|
||||
// When external linking on darwin, Mach-O relocation has only signed 24-bit
|
||||
// addend. For large symbols, we generate "label" symbols in the middle, so
|
||||
// that relocations can target them with smaller addends.
|
||||
if !ctxt.IsDarwin() || !ctxt.IsExternal() {
|
||||
return
|
||||
}
|
||||
|
||||
big := false
|
||||
for _, seg := range ld.Segments {
|
||||
if seg.Length >= machoRelocLimit {
|
||||
big = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !big {
|
||||
return // skip work if nothing big
|
||||
}
|
||||
|
||||
// addLabelSyms adds "label" symbols at s+machoRelocLimit, s+2*machoRelocLimit, etc.
|
||||
addLabelSyms := func(s loader.Sym, sz int64) {
|
||||
v := ldr.SymValue(s)
|
||||
for off := int64(machoRelocLimit); off < sz; off += machoRelocLimit {
|
||||
p := ldr.LookupOrCreateSym(machoLabelName(ldr, s, off), ldr.SymVersion(s))
|
||||
ldr.SetAttrReachable(p, true)
|
||||
ldr.SetSymValue(p, v+off)
|
||||
ldr.SetSymSect(p, ldr.SymSect(s))
|
||||
ld.AddMachoSym(ldr, p)
|
||||
//fmt.Printf("gensymlate %s %x\n", ldr.SymName(p), ldr.SymValue(p))
|
||||
}
|
||||
}
|
||||
|
||||
for s, n := loader.Sym(1), loader.Sym(ldr.NSym()); s < n; s++ {
|
||||
if !ldr.AttrReachable(s) {
|
||||
continue
|
||||
}
|
||||
if ldr.SymType(s) == sym.STEXT {
|
||||
continue // we don't target the middle of a function
|
||||
}
|
||||
sz := ldr.SymSize(s)
|
||||
if sz <= machoRelocLimit {
|
||||
continue
|
||||
}
|
||||
addLabelSyms(s, sz)
|
||||
}
|
||||
|
||||
// Also for carrier symbols (for which SymSize is 0)
|
||||
for _, ss := range ld.CarrierSymByType {
|
||||
if ss.Sym != 0 && ss.Size > machoRelocLimit {
|
||||
addLabelSyms(ss.Sym, ss.Size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// machoLabelName returns the name of the "label" symbol used for a
|
||||
// relocation targetting s+off. The label symbols is used on darwin
|
||||
// when external linking, so that the addend fits in a Mach-O relocation.
|
||||
func machoLabelName(ldr *loader.Loader, s loader.Sym, off int64) string {
|
||||
return fmt.Sprintf("%s.%d", ldr.SymExtname(s), off/machoRelocLimit)
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
|||
ElfrelocSize: 24,
|
||||
Elfsetupplt: elfsetupplt,
|
||||
Gentext: gentext,
|
||||
GenSymsLate: gensymlate,
|
||||
Machoreloc1: machoreloc1,
|
||||
MachorelocSize: 8,
|
||||
|
||||
|
|
|
@ -1815,6 +1815,7 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
|
|||
for _, symn := range sym.ReadOnly {
|
||||
symnStartValue := state.datsize
|
||||
state.assignToSection(sect, symn, sym.SRODATA)
|
||||
setCarrierSize(symn, state.datsize-symnStartValue)
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
// Read-only symbols might be wrapped inside their outer
|
||||
// symbol.
|
||||
|
@ -1902,6 +1903,7 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
|
|||
}
|
||||
}
|
||||
state.assignToSection(sect, symn, sym.SRODATA)
|
||||
setCarrierSize(symn, state.datsize-symnStartValue)
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
// Read-only symbols might be wrapped inside their outer
|
||||
// symbol.
|
||||
|
@ -1949,6 +1951,7 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
|
|||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pctab", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.functab", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.epclntab", 0), sect)
|
||||
setCarrierSize(sym.SPCLNTAB, int64(sect.Length))
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
xcoffUpdateOuterSize(ctxt, int64(sect.Length), sym.SPCLNTAB)
|
||||
}
|
||||
|
|
|
@ -1458,7 +1458,7 @@ func (ctxt *Link) hostlink() {
|
|||
}
|
||||
|
||||
const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu"
|
||||
if ctxt.compressDWARF && linkerFlagSupported(argv[0], altLinker, compressDWARF) {
|
||||
if ctxt.compressDWARF && linkerFlagSupported(ctxt.Arch, argv[0], altLinker, compressDWARF) {
|
||||
argv = append(argv, compressDWARF)
|
||||
}
|
||||
|
||||
|
@ -1548,7 +1548,7 @@ func (ctxt *Link) hostlink() {
|
|||
if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared && !(ctxt.IsDarwin() && ctxt.IsARM64()) {
|
||||
// GCC uses -no-pie, clang uses -nopie.
|
||||
for _, nopie := range []string{"-no-pie", "-nopie"} {
|
||||
if linkerFlagSupported(argv[0], altLinker, nopie) {
|
||||
if linkerFlagSupported(ctxt.Arch, argv[0], altLinker, nopie) {
|
||||
argv = append(argv, nopie)
|
||||
break
|
||||
}
|
||||
|
@ -1560,10 +1560,22 @@ func (ctxt *Link) hostlink() {
|
|||
checkStatic(p)
|
||||
}
|
||||
if ctxt.HeadType == objabi.Hwindows {
|
||||
// Determine which linker we're using. Add in the extldflags in
|
||||
// case used has specified "-fuse-ld=...".
|
||||
cmd := exec.Command(*flagExtld, *flagExtldflags, "-Wl,--version")
|
||||
usingLLD := false
|
||||
if out, err := cmd.CombinedOutput(); err == nil {
|
||||
if bytes.Contains(out, []byte("LLD ")) {
|
||||
usingLLD = true
|
||||
}
|
||||
}
|
||||
|
||||
// use gcc linker script to work around gcc bug
|
||||
// (see https://golang.org/issue/20183 for details).
|
||||
p := writeGDBLinkerScript()
|
||||
argv = append(argv, "-Wl,-T,"+p)
|
||||
if !usingLLD {
|
||||
p := writeGDBLinkerScript()
|
||||
argv = append(argv, "-Wl,-T,"+p)
|
||||
}
|
||||
// libmingw32 and libmingwex have some inter-dependencies,
|
||||
// so must use linker groups.
|
||||
argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group")
|
||||
|
@ -1657,7 +1669,7 @@ func (ctxt *Link) hostlink() {
|
|||
|
||||
var createTrivialCOnce sync.Once
|
||||
|
||||
func linkerFlagSupported(linker, altLinker, flag string) bool {
|
||||
func linkerFlagSupported(arch *sys.Arch, linker, altLinker, flag string) bool {
|
||||
createTrivialCOnce.Do(func() {
|
||||
src := filepath.Join(*flagTmpdir, "trivial.c")
|
||||
if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
|
||||
|
@ -1691,7 +1703,7 @@ func linkerFlagSupported(linker, altLinker, flag string) bool {
|
|||
"-target",
|
||||
}
|
||||
|
||||
var flags []string
|
||||
flags := hostlinkArchArgs(arch)
|
||||
keep := false
|
||||
skip := false
|
||||
extldflags := strings.Fields(*flagExtldflags)
|
||||
|
@ -1801,7 +1813,7 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string,
|
|||
return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
|
||||
}
|
||||
|
||||
if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 {
|
||||
if /* x86 */ c1 == 0x4c && c2 == 0x01 || /* x86_64 */ c1 == 0x64 && c2 == 0x86 || /* armv7 */ c1 == 0xc4 && c2 == 0x01 {
|
||||
ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
|
||||
textp, rsrc, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
|
||||
if err != nil {
|
||||
|
|
|
@ -969,6 +969,15 @@ func machosymorder(ctxt *Link) {
|
|||
}
|
||||
}
|
||||
|
||||
// AddMachoSym adds s to Mach-O symbol table, used in GenSymLate.
|
||||
// Currently only used on ARM64 when external linking.
|
||||
func AddMachoSym(ldr *loader.Loader, s loader.Sym) {
|
||||
ldr.SetSymDynid(s, int32(nsortsym))
|
||||
sortsym = append(sortsym, s)
|
||||
nsortsym++
|
||||
nkind[symkind(ldr, s)]++
|
||||
}
|
||||
|
||||
// machoShouldExport reports whether a symbol needs to be exported.
|
||||
//
|
||||
// When dynamically linking, all non-local variables and plugin-exported
|
||||
|
@ -1474,6 +1483,17 @@ func machoCodeSign(ctxt *Link, fname string) error {
|
|||
// Skip.
|
||||
return nil
|
||||
}
|
||||
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sigOff+sigSz != fi.Size() {
|
||||
// We don't expect anything after the signature (this will invalidate
|
||||
// the signature anyway.)
|
||||
return fmt.Errorf("unexpected content after code signature")
|
||||
}
|
||||
|
||||
sz := codesign.Size(sigOff, "a.out")
|
||||
if sz != sigSz {
|
||||
// Update the load command,
|
||||
|
@ -1500,5 +1520,9 @@ func machoCodeSign(ctxt *Link, fname string) error {
|
|||
cs := make([]byte, sz)
|
||||
codesign.Sign(cs, f, "a.out", sigOff, int64(textSeg.Offset), int64(textSeg.Filesz), ctxt.IsExe() || ctxt.IsPIE())
|
||||
_, err = f.WriteAt(cs, sigOff)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = f.Truncate(sigOff + sz)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -859,6 +859,7 @@ func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab {
|
|||
state.carrier = ldr.LookupOrCreateSym("runtime.pclntab", 0)
|
||||
ldr.MakeSymbolUpdater(state.carrier).SetType(sym.SPCLNTAB)
|
||||
ldr.SetAttrReachable(state.carrier, true)
|
||||
setCarrierSym(sym.SPCLNTAB, state.carrier)
|
||||
|
||||
state.generatePCHeader(ctxt)
|
||||
nameOffsets := state.generateFuncnametab(ctxt, funcs)
|
||||
|
|
|
@ -1524,7 +1524,7 @@ func addpersrc(ctxt *Link) {
|
|||
data := ctxt.loader.Data(rsrcsym)
|
||||
size := len(data)
|
||||
h := pefile.addSection(".rsrc", size, size)
|
||||
h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA
|
||||
h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA
|
||||
h.checkOffset(ctxt.Out.Offset())
|
||||
|
||||
// relocation
|
||||
|
|
|
@ -483,6 +483,8 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
|
|||
symtype = s.Sym()
|
||||
symtyperel = s.Sym()
|
||||
}
|
||||
setCarrierSym(sym.STYPE, symtype)
|
||||
setCarrierSym(sym.STYPERELRO, symtyperel)
|
||||
}
|
||||
|
||||
groupSym := func(name string, t sym.SymKind) loader.Sym {
|
||||
|
@ -490,6 +492,7 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
|
|||
s.SetType(t)
|
||||
s.SetSize(0)
|
||||
s.SetLocal(true)
|
||||
setCarrierSym(t, s.Sym())
|
||||
return s.Sym()
|
||||
}
|
||||
var (
|
||||
|
@ -800,3 +803,23 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
|
|||
}
|
||||
return symGroupType
|
||||
}
|
||||
|
||||
// CarrierSymByType tracks carrier symbols and their sizes.
|
||||
var CarrierSymByType [sym.SXREF]struct {
|
||||
Sym loader.Sym
|
||||
Size int64
|
||||
}
|
||||
|
||||
func setCarrierSym(typ sym.SymKind, s loader.Sym) {
|
||||
if CarrierSymByType[typ].Sym != 0 {
|
||||
panic(fmt.Sprintf("carrier symbol for type %v already set", typ))
|
||||
}
|
||||
CarrierSymByType[typ].Sym = s
|
||||
}
|
||||
|
||||
func setCarrierSize(typ sym.SymKind, sz int64) {
|
||||
if CarrierSymByType[typ].Size != 0 {
|
||||
panic(fmt.Sprintf("carrier symbol size for type %v already set", typ))
|
||||
}
|
||||
CarrierSymByType[typ].Size = sz
|
||||
}
|
||||
|
|
|
@ -574,6 +574,7 @@ func xcoffUpdateOuterSize(ctxt *Link, size int64, stype sym.SymKind) {
|
|||
if size == 0 {
|
||||
return
|
||||
}
|
||||
// TODO: use CarrierSymByType
|
||||
|
||||
ldr := ctxt.loader
|
||||
switch stype {
|
||||
|
|
|
@ -969,6 +969,8 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
|
|||
case MIPS | uint32(elf.R_MIPS_HI16)<<16,
|
||||
MIPS | uint32(elf.R_MIPS_LO16)<<16,
|
||||
MIPS | uint32(elf.R_MIPS_GOT16)<<16,
|
||||
MIPS | uint32(elf.R_MIPS_GOT_HI16)<<16,
|
||||
MIPS | uint32(elf.R_MIPS_GOT_LO16)<<16,
|
||||
MIPS | uint32(elf.R_MIPS_GPREL16)<<16,
|
||||
MIPS | uint32(elf.R_MIPS_GOT_PAGE)<<16,
|
||||
MIPS | uint32(elf.R_MIPS_JALR)<<16,
|
||||
|
@ -976,6 +978,8 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
|
|||
MIPS64 | uint32(elf.R_MIPS_HI16)<<16,
|
||||
MIPS64 | uint32(elf.R_MIPS_LO16)<<16,
|
||||
MIPS64 | uint32(elf.R_MIPS_GOT16)<<16,
|
||||
MIPS64 | uint32(elf.R_MIPS_GOT_HI16)<<16,
|
||||
MIPS64 | uint32(elf.R_MIPS_GOT_LO16)<<16,
|
||||
MIPS64 | uint32(elf.R_MIPS_GPREL16)<<16,
|
||||
MIPS64 | uint32(elf.R_MIPS_GOT_PAGE)<<16,
|
||||
MIPS64 | uint32(elf.R_MIPS_JALR)<<16,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package loadpe
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"cmd/internal/bio"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
|
@ -308,7 +309,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
|
|||
|
||||
rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
|
||||
|
||||
case IMAGE_REL_ARM_ADDR32:
|
||||
case IMAGE_REL_ARM_ADDR32, IMAGE_REL_ARM_ADDR32NB:
|
||||
rType = objabi.R_ADDR
|
||||
|
||||
rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
|
||||
|
@ -359,6 +360,20 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
|
|||
if pesym.SectionNumber == IMAGE_SYM_DEBUG {
|
||||
continue
|
||||
}
|
||||
if pesym.SectionNumber == IMAGE_SYM_ABSOLUTE && bytes.Equal(pesym.Name[:], []byte("@feat.00")) {
|
||||
// Microsoft's linker looks at whether all input objects have an empty
|
||||
// section called @feat.00. If all of them do, then it enables SEH;
|
||||
// otherwise it doesn't enable that feature. So, since around the Windows
|
||||
// XP SP2 era, most tools that make PE objects just tack on that section,
|
||||
// so that it won't gimp Microsoft's linker logic. Go doesn't support SEH,
|
||||
// so in theory, none of this really matters to us. But actually, if the
|
||||
// linker tries to ingest an object with @feat.00 -- which are produced by
|
||||
// LLVM's resource compiler, for example -- it chokes because of the
|
||||
// IMAGE_SYM_ABSOLUTE section that it doesn't know how to deal with. Since
|
||||
// @feat.00 is just a marking anyway, skip IMAGE_SYM_ABSOLUTE sections that
|
||||
// are called @feat.00.
|
||||
continue
|
||||
}
|
||||
var sect *pe.Section
|
||||
if pesym.SectionNumber > 0 {
|
||||
sect = f.Sections[pesym.SectionNumber-1]
|
||||
|
|
|
@ -925,3 +925,57 @@ func TestIssue42396(t *testing.T) {
|
|||
t.Fatalf("error message incorrect: expected it to contain %q but instead got:\n%s\n", want, out)
|
||||
}
|
||||
}
|
||||
|
||||
const testLargeRelocSrc = `
|
||||
package main
|
||||
|
||||
var x = [1<<25]byte{1<<23: 23, 1<<24: 24}
|
||||
|
||||
func main() {
|
||||
check(x[1<<23-1], 0)
|
||||
check(x[1<<23], 23)
|
||||
check(x[1<<23+1], 0)
|
||||
check(x[1<<24-1], 0)
|
||||
check(x[1<<24], 24)
|
||||
check(x[1<<24+1], 0)
|
||||
}
|
||||
|
||||
func check(x, y byte) {
|
||||
if x != y {
|
||||
panic("FAIL")
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
func TestLargeReloc(t *testing.T) {
|
||||
// Test that large relocation addend is handled correctly.
|
||||
// In particular, on darwin/arm64 when external linking,
|
||||
// Mach-O relocation has only 24-bit addend. See issue #42738.
|
||||
testenv.MustHaveGoBuild(t)
|
||||
t.Parallel()
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "TestIssue42396")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
src := filepath.Join(tmpdir, "x.go")
|
||||
err = ioutil.WriteFile(src, []byte(testLargeRelocSrc), 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to write source file: %v", err)
|
||||
}
|
||||
cmd := exec.Command(testenv.GoToolPath(t), "run", src)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Errorf("build failed: %v. output:\n%s", err, out)
|
||||
}
|
||||
|
||||
if testenv.HasCGO() { // currently all targets that support cgo can external link
|
||||
cmd = exec.Command(testenv.GoToolPath(t), "run", "-ldflags=-linkmode=external", src)
|
||||
out, err = cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("build failed: %v. output:\n%s", err, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
98
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go
generated
vendored
98
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go
generated
vendored
|
@ -207,12 +207,12 @@ var (
|
|||
)
|
||||
|
||||
// validateStructTag parses the struct tag and returns an error if it is not
|
||||
// in the canonical format, which is a space-separated list of key:"value"
|
||||
// settings. The value may contain spaces.
|
||||
// in the canonical format, as defined by reflect.StructTag.
|
||||
func validateStructTag(tag string) error {
|
||||
// This code is based on the StructTag.Get code in package reflect.
|
||||
|
||||
n := 0
|
||||
var keys []string
|
||||
for ; tag != ""; n++ {
|
||||
if n > 0 && tag != "" && tag[0] != ' ' {
|
||||
// More restrictive than reflect, but catches likely mistakes
|
||||
|
@ -240,14 +240,27 @@ func validateStructTag(tag string) error {
|
|||
if i == 0 {
|
||||
return errTagKeySyntax
|
||||
}
|
||||
if i+1 >= len(tag) || tag[i] != ':' {
|
||||
if i+1 >= len(tag) || tag[i] < ' ' || tag[i] == 0x7f {
|
||||
return errTagSyntax
|
||||
}
|
||||
if tag[i+1] != '"' {
|
||||
key := tag[:i]
|
||||
keys = append(keys, key)
|
||||
tag = tag[i:]
|
||||
|
||||
// If we found a space char here - assume that we have a tag with
|
||||
// multiple keys.
|
||||
if tag[0] == ' ' {
|
||||
continue
|
||||
}
|
||||
|
||||
// Spaces were filtered above so we assume that here we have
|
||||
// only valid tag value started with `:"`.
|
||||
if tag[0] != ':' || tag[1] != '"' {
|
||||
return errTagValueSyntax
|
||||
}
|
||||
key := tag[:i]
|
||||
tag = tag[i+1:]
|
||||
|
||||
// Remove the colon leaving tag at the start of the quoted string.
|
||||
tag = tag[1:]
|
||||
|
||||
// Scan quoted string to find value.
|
||||
i = 1
|
||||
|
@ -263,51 +276,56 @@ func validateStructTag(tag string) error {
|
|||
qvalue := tag[:i+1]
|
||||
tag = tag[i+1:]
|
||||
|
||||
value, err := strconv.Unquote(qvalue)
|
||||
wholeValue, err := strconv.Unquote(qvalue)
|
||||
if err != nil {
|
||||
return errTagValueSyntax
|
||||
}
|
||||
|
||||
if !checkTagSpaces[key] {
|
||||
continue
|
||||
}
|
||||
|
||||
switch key {
|
||||
case "xml":
|
||||
// If the first or last character in the XML tag is a space, it is
|
||||
// suspicious.
|
||||
if strings.Trim(value, " ") != value {
|
||||
return errTagValueSpace
|
||||
}
|
||||
|
||||
// If there are multiple spaces, they are suspicious.
|
||||
if strings.Count(value, " ") > 1 {
|
||||
return errTagValueSpace
|
||||
}
|
||||
|
||||
// If there is no comma, skip the rest of the checks.
|
||||
comma := strings.IndexRune(value, ',')
|
||||
if comma < 0 {
|
||||
for _, key := range keys {
|
||||
if !checkTagSpaces[key] {
|
||||
continue
|
||||
}
|
||||
|
||||
// If the character before a comma is a space, this is suspicious.
|
||||
if comma > 0 && value[comma-1] == ' ' {
|
||||
value := wholeValue
|
||||
switch key {
|
||||
case "xml":
|
||||
// If the first or last character in the XML tag is a space, it is
|
||||
// suspicious.
|
||||
if strings.Trim(value, " ") != value {
|
||||
return errTagValueSpace
|
||||
}
|
||||
|
||||
// If there are multiple spaces, they are suspicious.
|
||||
if strings.Count(value, " ") > 1 {
|
||||
return errTagValueSpace
|
||||
}
|
||||
|
||||
// If there is no comma, skip the rest of the checks.
|
||||
comma := strings.IndexRune(value, ',')
|
||||
if comma < 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// If the character before a comma is a space, this is suspicious.
|
||||
if comma > 0 && value[comma-1] == ' ' {
|
||||
return errTagValueSpace
|
||||
}
|
||||
value = value[comma+1:]
|
||||
case "json":
|
||||
// JSON allows using spaces in the name, so skip it.
|
||||
comma := strings.IndexRune(value, ',')
|
||||
if comma < 0 {
|
||||
continue
|
||||
}
|
||||
value = value[comma+1:]
|
||||
}
|
||||
|
||||
if strings.IndexByte(value, ' ') >= 0 {
|
||||
return errTagValueSpace
|
||||
}
|
||||
value = value[comma+1:]
|
||||
case "json":
|
||||
// JSON allows using spaces in the name, so skip it.
|
||||
comma := strings.IndexRune(value, ',')
|
||||
if comma < 0 {
|
||||
continue
|
||||
}
|
||||
value = value[comma+1:]
|
||||
}
|
||||
|
||||
if strings.IndexByte(value, ' ') >= 0 {
|
||||
return errTagValueSpace
|
||||
}
|
||||
keys = keys[:0]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
2
src/cmd/vendor/modules.txt
vendored
2
src/cmd/vendor/modules.txt
vendored
|
@ -44,7 +44,7 @@ golang.org/x/mod/zip
|
|||
golang.org/x/sys/internal/unsafeheader
|
||||
golang.org/x/sys/unix
|
||||
golang.org/x/sys/windows
|
||||
# golang.org/x/tools v0.0.0-20201208211828-de58e7c01d49
|
||||
# golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11
|
||||
## explicit
|
||||
golang.org/x/tools/go/analysis
|
||||
golang.org/x/tools/go/analysis/internal/analysisflags
|
||||
|
|
|
@ -7,7 +7,6 @@ package tls
|
|||
import (
|
||||
"bytes"
|
||||
"container/list"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
|
@ -444,16 +443,6 @@ type ClientHelloInfo struct {
|
|||
// config is embedded by the GetCertificate or GetConfigForClient caller,
|
||||
// for use with SupportsCertificate.
|
||||
config *Config
|
||||
|
||||
// ctx is the context of the handshake that is in progress.
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// Context returns the context of the handshake that is in progress.
|
||||
// This context is a child of the context passed to HandshakeContext,
|
||||
// if any, and is canceled when the handshake concludes.
|
||||
func (c *ClientHelloInfo) Context() context.Context {
|
||||
return c.ctx
|
||||
}
|
||||
|
||||
// CertificateRequestInfo contains information from a server's
|
||||
|
@ -472,16 +461,6 @@ type CertificateRequestInfo struct {
|
|||
|
||||
// Version is the TLS version that was negotiated for this connection.
|
||||
Version uint16
|
||||
|
||||
// ctx is the context of the handshake that is in progress.
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// Context returns the context of the handshake that is in progress.
|
||||
// This context is a child of the context passed to HandshakeContext,
|
||||
// if any, and is canceled when the handshake concludes.
|
||||
func (c *CertificateRequestInfo) Context() context.Context {
|
||||
return c.ctx
|
||||
}
|
||||
|
||||
// RenegotiationSupport enumerates the different levels of support for TLS
|
||||
|
|
|
@ -8,7 +8,6 @@ package tls
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/cipher"
|
||||
"crypto/subtle"
|
||||
"crypto/x509"
|
||||
|
@ -28,7 +27,7 @@ type Conn struct {
|
|||
// constant
|
||||
conn net.Conn
|
||||
isClient bool
|
||||
handshakeFn func(context.Context) error // (*Conn).clientHandshake or serverHandshake
|
||||
handshakeFn func() error // (*Conn).clientHandshake or serverHandshake
|
||||
|
||||
// handshakeStatus is 1 if the connection is currently transferring
|
||||
// application data (i.e. is not currently processing a handshake).
|
||||
|
@ -1191,7 +1190,7 @@ func (c *Conn) handleRenegotiation() error {
|
|||
defer c.handshakeMutex.Unlock()
|
||||
|
||||
atomic.StoreUint32(&c.handshakeStatus, 0)
|
||||
if c.handshakeErr = c.clientHandshake(context.Background()); c.handshakeErr == nil {
|
||||
if c.handshakeErr = c.clientHandshake(); c.handshakeErr == nil {
|
||||
c.handshakes++
|
||||
}
|
||||
return c.handshakeErr
|
||||
|
@ -1374,61 +1373,8 @@ func (c *Conn) closeNotify() error {
|
|||
// first Read or Write will call it automatically.
|
||||
//
|
||||
// For control over canceling or setting a timeout on a handshake, use
|
||||
// HandshakeContext or the Dialer's DialContext method instead.
|
||||
// the Dialer's DialContext method.
|
||||
func (c *Conn) Handshake() error {
|
||||
return c.HandshakeContext(context.Background())
|
||||
}
|
||||
|
||||
// HandshakeContext runs the client or server handshake
|
||||
// protocol if it has not yet been run.
|
||||
//
|
||||
// The provided Context must be non-nil. If the context is canceled before
|
||||
// the handshake is complete, the handshake is interrupted and an error is returned.
|
||||
// Once the handshake has completed, cancellation of the context will not affect the
|
||||
// connection.
|
||||
//
|
||||
// Most uses of this package need not call HandshakeContext explicitly: the
|
||||
// first Read or Write will call it automatically.
|
||||
func (c *Conn) HandshakeContext(ctx context.Context) error {
|
||||
// Delegate to unexported method for named return
|
||||
// without confusing documented signature.
|
||||
return c.handshakeContext(ctx)
|
||||
}
|
||||
|
||||
func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
|
||||
handshakeCtx, cancel := context.WithCancel(ctx)
|
||||
// Note: defer this before starting the "interrupter" goroutine
|
||||
// so that we can tell the difference between the input being canceled and
|
||||
// this cancellation. In the former case, we need to close the connection.
|
||||
defer cancel()
|
||||
|
||||
// Start the "interrupter" goroutine, if this context might be canceled.
|
||||
// (The background context cannot).
|
||||
//
|
||||
// The interrupter goroutine waits for the input context to be done and
|
||||
// closes the connection if this happens before the function returns.
|
||||
if ctx.Done() != nil {
|
||||
done := make(chan struct{})
|
||||
interruptRes := make(chan error, 1)
|
||||
defer func() {
|
||||
close(done)
|
||||
if ctxErr := <-interruptRes; ctxErr != nil {
|
||||
// Return context error to user.
|
||||
ret = ctxErr
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
select {
|
||||
case <-handshakeCtx.Done():
|
||||
// Close the connection, discarding the error
|
||||
_ = c.conn.Close()
|
||||
interruptRes <- handshakeCtx.Err()
|
||||
case <-done:
|
||||
interruptRes <- nil
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
c.handshakeMutex.Lock()
|
||||
defer c.handshakeMutex.Unlock()
|
||||
|
||||
|
@ -1442,7 +1388,7 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
|
|||
c.in.Lock()
|
||||
defer c.in.Unlock()
|
||||
|
||||
c.handshakeErr = c.handshakeFn(handshakeCtx)
|
||||
c.handshakeErr = c.handshakeFn()
|
||||
if c.handshakeErr == nil {
|
||||
c.handshakes++
|
||||
} else {
|
||||
|
|
|
@ -6,7 +6,6 @@ package tls
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
|
@ -25,7 +24,6 @@ import (
|
|||
|
||||
type clientHandshakeState struct {
|
||||
c *Conn
|
||||
ctx context.Context
|
||||
serverHello *serverHelloMsg
|
||||
hello *clientHelloMsg
|
||||
suite *cipherSuite
|
||||
|
@ -136,7 +134,7 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
|
|||
return hello, params, nil
|
||||
}
|
||||
|
||||
func (c *Conn) clientHandshake(ctx context.Context) (err error) {
|
||||
func (c *Conn) clientHandshake() (err error) {
|
||||
if c.config == nil {
|
||||
c.config = defaultConfig()
|
||||
}
|
||||
|
@ -200,7 +198,6 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
|
|||
if c.vers == VersionTLS13 {
|
||||
hs := &clientHandshakeStateTLS13{
|
||||
c: c,
|
||||
ctx: ctx,
|
||||
serverHello: serverHello,
|
||||
hello: hello,
|
||||
ecdheParams: ecdheParams,
|
||||
|
@ -215,7 +212,6 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
|
|||
|
||||
hs := &clientHandshakeState{
|
||||
c: c,
|
||||
ctx: ctx,
|
||||
serverHello: serverHello,
|
||||
hello: hello,
|
||||
session: session,
|
||||
|
@ -544,7 +540,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
|
|||
certRequested = true
|
||||
hs.finishedHash.Write(certReq.marshal())
|
||||
|
||||
cri := certificateRequestInfoFromMsg(hs.ctx, c.vers, certReq)
|
||||
cri := certificateRequestInfoFromMsg(c.vers, certReq)
|
||||
if chainToSend, err = c.getClientCertificate(cri); err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
|
@ -884,11 +880,10 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
|
|||
|
||||
// certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS
|
||||
// <= 1.2 CertificateRequest, making an effort to fill in missing information.
|
||||
func certificateRequestInfoFromMsg(ctx context.Context, vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {
|
||||
func certificateRequestInfoFromMsg(vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {
|
||||
cri := &CertificateRequestInfo{
|
||||
AcceptableCAs: certReq.certificateAuthorities,
|
||||
Version: vers,
|
||||
ctx: ctx,
|
||||
}
|
||||
|
||||
var rsaAvail, ecAvail bool
|
||||
|
|
|
@ -6,7 +6,6 @@ package tls
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
|
@ -21,7 +20,6 @@ import (
|
|||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
@ -2513,37 +2511,3 @@ func testResumptionKeepsOCSPAndSCT(t *testing.T, ver uint16) {
|
|||
serverConfig.Certificates[0].SignedCertificateTimestamps, ccs.SignedCertificateTimestamps)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientHandshakeContextCancellation(t *testing.T) {
|
||||
c, s := localPipe(t)
|
||||
serverConfig := testConfig.Clone()
|
||||
serverErr := make(chan error, 1)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go func() {
|
||||
defer close(serverErr)
|
||||
defer s.Close()
|
||||
conn := Server(s, serverConfig)
|
||||
_, err := conn.readClientHello(ctx)
|
||||
cancel()
|
||||
serverErr <- err
|
||||
}()
|
||||
cli := Client(c, testConfig)
|
||||
err := cli.HandshakeContext(ctx)
|
||||
if err == nil {
|
||||
t.Fatal("Client handshake did not error when the context was canceled")
|
||||
}
|
||||
if err != context.Canceled {
|
||||
t.Errorf("Unexpected client handshake error: %v", err)
|
||||
}
|
||||
if err := <-serverErr; err != nil {
|
||||
t.Errorf("Unexpected server error: %v", err)
|
||||
}
|
||||
if runtime.GOARCH == "wasm" {
|
||||
t.Skip("conn.Close does not error as expected when called multiple times on WASM")
|
||||
}
|
||||
err = cli.Close()
|
||||
if err == nil {
|
||||
t.Error("Client connection was not closed when the context was canceled")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ package tls
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/hmac"
|
||||
"crypto/rsa"
|
||||
|
@ -18,7 +17,6 @@ import (
|
|||
|
||||
type clientHandshakeStateTLS13 struct {
|
||||
c *Conn
|
||||
ctx context.Context
|
||||
serverHello *serverHelloMsg
|
||||
hello *clientHelloMsg
|
||||
ecdheParams ecdheParameters
|
||||
|
@ -557,7 +555,6 @@ func (hs *clientHandshakeStateTLS13) sendClientCertificate() error {
|
|||
AcceptableCAs: hs.certReq.certificateAuthorities,
|
||||
SignatureSchemes: hs.certReq.supportedSignatureAlgorithms,
|
||||
Version: c.vers,
|
||||
ctx: hs.ctx,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
package tls
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
|
@ -24,7 +23,6 @@ import (
|
|||
// It's discarded once the handshake has completed.
|
||||
type serverHandshakeState struct {
|
||||
c *Conn
|
||||
ctx context.Context
|
||||
clientHello *clientHelloMsg
|
||||
hello *serverHelloMsg
|
||||
suite *cipherSuite
|
||||
|
@ -39,8 +37,8 @@ type serverHandshakeState struct {
|
|||
}
|
||||
|
||||
// serverHandshake performs a TLS handshake as a server.
|
||||
func (c *Conn) serverHandshake(ctx context.Context) error {
|
||||
clientHello, err := c.readClientHello(ctx)
|
||||
func (c *Conn) serverHandshake() error {
|
||||
clientHello, err := c.readClientHello()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -48,7 +46,6 @@ func (c *Conn) serverHandshake(ctx context.Context) error {
|
|||
if c.vers == VersionTLS13 {
|
||||
hs := serverHandshakeStateTLS13{
|
||||
c: c,
|
||||
ctx: ctx,
|
||||
clientHello: clientHello,
|
||||
}
|
||||
return hs.handshake()
|
||||
|
@ -56,7 +53,6 @@ func (c *Conn) serverHandshake(ctx context.Context) error {
|
|||
|
||||
hs := serverHandshakeState{
|
||||
c: c,
|
||||
ctx: ctx,
|
||||
clientHello: clientHello,
|
||||
}
|
||||
return hs.handshake()
|
||||
|
@ -128,7 +124,7 @@ func (hs *serverHandshakeState) handshake() error {
|
|||
}
|
||||
|
||||
// readClientHello reads a ClientHello message and selects the protocol version.
|
||||
func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) {
|
||||
func (c *Conn) readClientHello() (*clientHelloMsg, error) {
|
||||
msg, err := c.readHandshake()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -142,7 +138,7 @@ func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) {
|
|||
var configForClient *Config
|
||||
originalConfig := c.config
|
||||
if c.config.GetConfigForClient != nil {
|
||||
chi := clientHelloInfo(ctx, c, clientHello)
|
||||
chi := clientHelloInfo(c, clientHello)
|
||||
if configForClient, err = c.config.GetConfigForClient(chi); err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return nil, err
|
||||
|
@ -224,7 +220,7 @@ func (hs *serverHandshakeState) processClientHello() error {
|
|||
}
|
||||
}
|
||||
|
||||
hs.cert, err = c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
|
||||
hs.cert, err = c.config.getCertificate(clientHelloInfo(c, hs.clientHello))
|
||||
if err != nil {
|
||||
if err == errNoCertificates {
|
||||
c.sendAlert(alertUnrecognizedName)
|
||||
|
@ -832,7 +828,7 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo {
|
||||
func clientHelloInfo(c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo {
|
||||
supportedVersions := clientHello.supportedVersions
|
||||
if len(clientHello.supportedVersions) == 0 {
|
||||
supportedVersions = supportedVersionsFromMax(clientHello.vers)
|
||||
|
@ -848,6 +844,5 @@ func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg)
|
|||
SupportedVersions: supportedVersions,
|
||||
Conn: c.conn,
|
||||
config: c.config,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ package tls
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/elliptic"
|
||||
"crypto/x509"
|
||||
|
@ -18,7 +17,6 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -40,12 +38,10 @@ func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessa
|
|||
cli.writeRecord(recordTypeHandshake, m.marshal())
|
||||
c.Close()
|
||||
}()
|
||||
ctx := context.Background()
|
||||
conn := Server(s, serverConfig)
|
||||
ch, err := conn.readClientHello(ctx)
|
||||
ch, err := conn.readClientHello()
|
||||
hs := serverHandshakeState{
|
||||
c: conn,
|
||||
ctx: ctx,
|
||||
clientHello: ch,
|
||||
}
|
||||
if err == nil {
|
||||
|
@ -1425,11 +1421,9 @@ func TestSNIGivenOnFailure(t *testing.T) {
|
|||
c.Close()
|
||||
}()
|
||||
conn := Server(s, serverConfig)
|
||||
ctx := context.Background()
|
||||
ch, err := conn.readClientHello(ctx)
|
||||
ch, err := conn.readClientHello()
|
||||
hs := serverHandshakeState{
|
||||
c: conn,
|
||||
ctx: ctx,
|
||||
clientHello: ch,
|
||||
}
|
||||
if err == nil {
|
||||
|
@ -1683,46 +1677,6 @@ func TestMultipleCertificates(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestServerHandshakeContextCancellation(t *testing.T) {
|
||||
c, s := localPipe(t)
|
||||
clientConfig := testConfig.Clone()
|
||||
clientErr := make(chan error, 1)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go func() {
|
||||
defer close(clientErr)
|
||||
defer c.Close()
|
||||
clientHello := &clientHelloMsg{
|
||||
vers: VersionTLS10,
|
||||
random: make([]byte, 32),
|
||||
cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
|
||||
compressionMethods: []uint8{compressionNone},
|
||||
}
|
||||
cli := Client(c, clientConfig)
|
||||
_, err := cli.writeRecord(recordTypeHandshake, clientHello.marshal())
|
||||
cancel()
|
||||
clientErr <- err
|
||||
}()
|
||||
conn := Server(s, testConfig)
|
||||
err := conn.HandshakeContext(ctx)
|
||||
if err == nil {
|
||||
t.Fatal("Server handshake did not error when the context was canceled")
|
||||
}
|
||||
if err != context.Canceled {
|
||||
t.Errorf("Unexpected server handshake error: %v", err)
|
||||
}
|
||||
if err := <-clientErr; err != nil {
|
||||
t.Errorf("Unexpected client error: %v", err)
|
||||
}
|
||||
if runtime.GOARCH == "wasm" {
|
||||
t.Skip("conn.Close does not error as expected when called multiple times on WASM")
|
||||
}
|
||||
err = conn.Close()
|
||||
if err == nil {
|
||||
t.Error("Server connection was not closed when the context was canceled")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAESCipherReordering(t *testing.T) {
|
||||
currentAESSupport := hasAESGCMHardwareSupport
|
||||
defer func() { hasAESGCMHardwareSupport = currentAESSupport; initDefaultCipherSuites() }()
|
||||
|
|
|
@ -6,7 +6,6 @@ package tls
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/hmac"
|
||||
"crypto/rsa"
|
||||
|
@ -24,7 +23,6 @@ const maxClientPSKIdentities = 5
|
|||
|
||||
type serverHandshakeStateTLS13 struct {
|
||||
c *Conn
|
||||
ctx context.Context
|
||||
clientHello *clientHelloMsg
|
||||
hello *serverHelloMsg
|
||||
sentDummyCCS bool
|
||||
|
@ -376,7 +374,7 @@ func (hs *serverHandshakeStateTLS13) pickCertificate() error {
|
|||
return c.sendAlert(alertMissingExtension)
|
||||
}
|
||||
|
||||
certificate, err := c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
|
||||
certificate, err := c.config.getCertificate(clientHelloInfo(c, hs.clientHello))
|
||||
if err != nil {
|
||||
if err == errNoCertificates {
|
||||
c.sendAlert(alertUnrecognizedName)
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Server returns a new TLS server side connection
|
||||
|
@ -115,16 +116,28 @@ func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*
|
|||
}
|
||||
|
||||
func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
|
||||
if netDialer.Timeout != 0 {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithTimeout(ctx, netDialer.Timeout)
|
||||
defer cancel()
|
||||
}
|
||||
// We want the Timeout and Deadline values from dialer to cover the
|
||||
// whole process: TCP connection and TLS handshake. This means that we
|
||||
// also need to start our own timers now.
|
||||
timeout := netDialer.Timeout
|
||||
|
||||
if !netDialer.Deadline.IsZero() {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithDeadline(ctx, netDialer.Deadline)
|
||||
defer cancel()
|
||||
deadlineTimeout := time.Until(netDialer.Deadline)
|
||||
if timeout == 0 || deadlineTimeout < timeout {
|
||||
timeout = deadlineTimeout
|
||||
}
|
||||
}
|
||||
|
||||
// hsErrCh is non-nil if we might not wait for Handshake to complete.
|
||||
var hsErrCh chan error
|
||||
if timeout != 0 || ctx.Done() != nil {
|
||||
hsErrCh = make(chan error, 2)
|
||||
}
|
||||
if timeout != 0 {
|
||||
timer := time.AfterFunc(timeout, func() {
|
||||
hsErrCh <- timeoutError{}
|
||||
})
|
||||
defer timer.Stop()
|
||||
}
|
||||
|
||||
rawConn, err := netDialer.DialContext(ctx, network, addr)
|
||||
|
@ -151,10 +164,34 @@ func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, conf
|
|||
}
|
||||
|
||||
conn := Client(rawConn, config)
|
||||
if err := conn.HandshakeContext(ctx); err != nil {
|
||||
|
||||
if hsErrCh == nil {
|
||||
err = conn.Handshake()
|
||||
} else {
|
||||
go func() {
|
||||
hsErrCh <- conn.Handshake()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
err = ctx.Err()
|
||||
case err = <-hsErrCh:
|
||||
if err != nil {
|
||||
// If the error was due to the context
|
||||
// closing, prefer the context's error, rather
|
||||
// than some random network teardown error.
|
||||
if e := ctx.Err(); e != nil {
|
||||
err = e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
rawConn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1141,7 +1141,7 @@ func (db *DB) connectionOpener(ctx context.Context) {
|
|||
|
||||
// Open one new connection
|
||||
func (db *DB) openNewConnection(ctx context.Context) {
|
||||
// maybeOpenNewConnctions has already executed db.numOpen++ before it sent
|
||||
// maybeOpenNewConnections has already executed db.numOpen++ before it sent
|
||||
// on db.openerCh. This function must execute db.numOpen-- if the
|
||||
// connection fails or is closed before returning.
|
||||
ci, err := db.connector.Connect(ctx)
|
||||
|
|
|
@ -22,7 +22,12 @@ func TestDwarf5Ranges(t *testing.T) {
|
|||
if err := d.AddSection(".debug_rnglists", rngLists); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ret, err := d.dwarf5Ranges(nil, 0x5fbd, 0xc, [][2]uint64{})
|
||||
u := &unit{
|
||||
asize: 8,
|
||||
vers: 5,
|
||||
is64: true,
|
||||
}
|
||||
ret, err := d.dwarf5Ranges(u, nil, 0x5fbd, 0xc, [][2]uint64{})
|
||||
if err != nil {
|
||||
t.Fatalf("could not read rnglist: %v", err)
|
||||
}
|
||||
|
|
|
@ -423,6 +423,47 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
|
|||
Children: a.children,
|
||||
Field: make([]Field, len(a.field)),
|
||||
}
|
||||
|
||||
// If we are currently parsing the compilation unit,
|
||||
// we can't evaluate Addrx or Strx until we've seen the
|
||||
// relevant base entry.
|
||||
type delayed struct {
|
||||
idx int
|
||||
off uint64
|
||||
fmt format
|
||||
}
|
||||
var delay []delayed
|
||||
|
||||
resolveStrx := func(strBase, off uint64) string {
|
||||
off += strBase
|
||||
if uint64(int(off)) != off {
|
||||
b.error("DW_FORM_strx offset out of range")
|
||||
}
|
||||
|
||||
b1 := makeBuf(b.dwarf, b.format, "str_offsets", 0, b.dwarf.strOffsets)
|
||||
b1.skip(int(off))
|
||||
is64, _ := b.format.dwarf64()
|
||||
if is64 {
|
||||
off = b1.uint64()
|
||||
} else {
|
||||
off = uint64(b1.uint32())
|
||||
}
|
||||
if b1.err != nil {
|
||||
b.err = b1.err
|
||||
return ""
|
||||
}
|
||||
if uint64(int(off)) != off {
|
||||
b.error("DW_FORM_strx indirect offset out of range")
|
||||
}
|
||||
b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str)
|
||||
b1.skip(int(off))
|
||||
val := b1.string()
|
||||
if b1.err != nil {
|
||||
b.err = b1.err
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
for i := range e.Field {
|
||||
e.Field[i].Attr = a.field[i].attr
|
||||
e.Field[i].Class = a.field[i].class
|
||||
|
@ -467,10 +508,13 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
|
|||
var addrBase int64
|
||||
if cu != nil {
|
||||
addrBase, _ = cu.Val(AttrAddrBase).(int64)
|
||||
} else if a.tag == TagCompileUnit {
|
||||
delay = append(delay, delayed{i, off, formAddrx})
|
||||
break
|
||||
}
|
||||
|
||||
var err error
|
||||
val, err = b.dwarf.debugAddr(uint64(addrBase), off)
|
||||
val, err = b.dwarf.debugAddr(b.format, uint64(addrBase), off)
|
||||
if err != nil {
|
||||
if b.err == nil {
|
||||
b.err = err
|
||||
|
@ -611,38 +655,16 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
|
|||
// compilation unit. This won't work if the
|
||||
// program uses Reader.Seek to skip over the
|
||||
// unit. Not much we can do about that.
|
||||
var strBase int64
|
||||
if cu != nil {
|
||||
cuOff, ok := cu.Val(AttrStrOffsetsBase).(int64)
|
||||
if ok {
|
||||
off += uint64(cuOff)
|
||||
}
|
||||
strBase, _ = cu.Val(AttrStrOffsetsBase).(int64)
|
||||
} else if a.tag == TagCompileUnit {
|
||||
delay = append(delay, delayed{i, off, formStrx})
|
||||
break
|
||||
}
|
||||
|
||||
if uint64(int(off)) != off {
|
||||
b.error("DW_FORM_strx offset out of range")
|
||||
}
|
||||
val = resolveStrx(uint64(strBase), off)
|
||||
|
||||
b1 := makeBuf(b.dwarf, b.format, "str_offsets", 0, b.dwarf.strOffsets)
|
||||
b1.skip(int(off))
|
||||
if is64 {
|
||||
off = b1.uint64()
|
||||
} else {
|
||||
off = uint64(b1.uint32())
|
||||
}
|
||||
if b1.err != nil {
|
||||
b.err = b1.err
|
||||
return nil
|
||||
}
|
||||
if uint64(int(off)) != off {
|
||||
b.error("DW_FORM_strx indirect offset out of range")
|
||||
}
|
||||
b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str)
|
||||
b1.skip(int(off))
|
||||
val = b1.string()
|
||||
if b1.err != nil {
|
||||
b.err = b1.err
|
||||
return nil
|
||||
}
|
||||
case formStrpSup:
|
||||
is64, known := b.format.dwarf64()
|
||||
if !known {
|
||||
|
@ -689,11 +711,32 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
|
|||
case formRnglistx:
|
||||
val = b.uint()
|
||||
}
|
||||
|
||||
e.Field[i].Val = val
|
||||
}
|
||||
if b.err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, del := range delay {
|
||||
switch del.fmt {
|
||||
case formAddrx:
|
||||
addrBase, _ := e.Val(AttrAddrBase).(int64)
|
||||
val, err := b.dwarf.debugAddr(b.format, uint64(addrBase), del.off)
|
||||
if err != nil {
|
||||
b.err = err
|
||||
return nil
|
||||
}
|
||||
e.Field[del.idx].Val = val
|
||||
case formStrx:
|
||||
strBase, _ := e.Val(AttrStrOffsetsBase).(int64)
|
||||
e.Field[del.idx].Val = resolveStrx(uint64(strBase), del.off)
|
||||
if b.err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
|
@ -877,6 +920,7 @@ func (r *Reader) SeekPC(pc uint64) (*Entry, error) {
|
|||
r.err = nil
|
||||
r.lastChildren = false
|
||||
r.unit = unit
|
||||
r.cu = nil
|
||||
u := &r.d.unit[unit]
|
||||
r.b = makeBuf(r.d, u, "info", u.off, u.data)
|
||||
e, err := r.Next()
|
||||
|
@ -946,7 +990,7 @@ func (d *Data) Ranges(e *Entry) ([][2]uint64, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.dwarf5Ranges(cu, base, ranges, ret)
|
||||
return d.dwarf5Ranges(u, cu, base, ranges, ret)
|
||||
|
||||
case ClassRngList:
|
||||
// TODO: support DW_FORM_rnglistx
|
||||
|
@ -1023,13 +1067,13 @@ func (d *Data) dwarf2Ranges(u *unit, base uint64, ranges int64, ret [][2]uint64)
|
|||
|
||||
// dwarf5Ranges interpets a debug_rnglists sequence, see DWARFv5 section
|
||||
// 2.17.3 (page 53).
|
||||
func (d *Data) dwarf5Ranges(cu *Entry, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
|
||||
func (d *Data) dwarf5Ranges(u *unit, cu *Entry, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
|
||||
var addrBase int64
|
||||
if cu != nil {
|
||||
addrBase, _ = cu.Val(AttrAddrBase).(int64)
|
||||
}
|
||||
|
||||
buf := makeBuf(d, d.rngLists, "rnglists", 0, d.rngLists.data)
|
||||
buf := makeBuf(d, u, "rnglists", 0, d.rngLists)
|
||||
buf.skip(int(ranges))
|
||||
for {
|
||||
opcode := buf.uint8()
|
||||
|
@ -1043,7 +1087,7 @@ func (d *Data) dwarf5Ranges(cu *Entry, base uint64, ranges int64, ret [][2]uint6
|
|||
case rleBaseAddressx:
|
||||
baseIdx := buf.uint()
|
||||
var err error
|
||||
base, err = d.debugAddr(uint64(addrBase), baseIdx)
|
||||
base, err = d.debugAddr(u, uint64(addrBase), baseIdx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1052,11 +1096,11 @@ func (d *Data) dwarf5Ranges(cu *Entry, base uint64, ranges int64, ret [][2]uint6
|
|||
startIdx := buf.uint()
|
||||
endIdx := buf.uint()
|
||||
|
||||
start, err := d.debugAddr(uint64(addrBase), startIdx)
|
||||
start, err := d.debugAddr(u, uint64(addrBase), startIdx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
end, err := d.debugAddr(uint64(addrBase), endIdx)
|
||||
end, err := d.debugAddr(u, uint64(addrBase), endIdx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1065,7 +1109,7 @@ func (d *Data) dwarf5Ranges(cu *Entry, base uint64, ranges int64, ret [][2]uint6
|
|||
case rleStartxLength:
|
||||
startIdx := buf.uint()
|
||||
len := buf.uint()
|
||||
start, err := d.debugAddr(uint64(addrBase), startIdx)
|
||||
start, err := d.debugAddr(u, uint64(addrBase), startIdx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1093,19 +1137,18 @@ func (d *Data) dwarf5Ranges(cu *Entry, base uint64, ranges int64, ret [][2]uint6
|
|||
}
|
||||
|
||||
// debugAddr returns the address at idx in debug_addr
|
||||
func (d *Data) debugAddr(addrBase, idx uint64) (uint64, error) {
|
||||
off := idx*uint64(d.addr.addrsize()) + addrBase
|
||||
func (d *Data) debugAddr(format dataFormat, addrBase, idx uint64) (uint64, error) {
|
||||
off := idx*uint64(format.addrsize()) + addrBase
|
||||
|
||||
if uint64(int(off)) != off {
|
||||
return 0, errors.New("offset out of range")
|
||||
}
|
||||
|
||||
b := makeBuf(d, d.addr, "addr", 0, d.addr.data)
|
||||
b := makeBuf(d, format, "addr", 0, d.addr)
|
||||
b.skip(int(off))
|
||||
val := b.addr()
|
||||
if b.err != nil {
|
||||
return 0, b.err
|
||||
}
|
||||
|
||||
return val, nil
|
||||
}
|
||||
|
|
|
@ -55,6 +55,20 @@ func TestReaderSeek(t *testing.T) {
|
|||
{0x400611, nil},
|
||||
}
|
||||
testRanges(t, "testdata/line-gcc.elf", want)
|
||||
|
||||
want = []wantRange{
|
||||
{0x401122, [][2]uint64{{0x401122, 0x401166}}},
|
||||
{0x401165, [][2]uint64{{0x401122, 0x401166}}},
|
||||
{0x401166, [][2]uint64{{0x401166, 0x401179}}},
|
||||
}
|
||||
testRanges(t, "testdata/line-gcc-dwarf5.elf", want)
|
||||
|
||||
want = []wantRange{
|
||||
{0x401130, [][2]uint64{{0x401130, 0x40117e}}},
|
||||
{0x40117d, [][2]uint64{{0x401130, 0x40117e}}},
|
||||
{0x40117e, nil},
|
||||
}
|
||||
testRanges(t, "testdata/line-clang-dwarf5.elf", want)
|
||||
}
|
||||
|
||||
func TestRangesSection(t *testing.T) {
|
||||
|
@ -97,44 +111,72 @@ func testRanges(t *testing.T, name string, want []wantRange) {
|
|||
}
|
||||
|
||||
func TestReaderRanges(t *testing.T) {
|
||||
d := elfData(t, "testdata/line-gcc.elf")
|
||||
|
||||
subprograms := []struct {
|
||||
type subprograms []struct {
|
||||
name string
|
||||
ranges [][2]uint64
|
||||
}
|
||||
tests := []struct {
|
||||
filename string
|
||||
subprograms subprograms
|
||||
}{
|
||||
{"f1", [][2]uint64{{0x40059d, 0x4005e7}}},
|
||||
{"main", [][2]uint64{{0x4005e7, 0x400601}}},
|
||||
{"f2", [][2]uint64{{0x400601, 0x400611}}},
|
||||
{
|
||||
"testdata/line-gcc.elf",
|
||||
subprograms{
|
||||
{"f1", [][2]uint64{{0x40059d, 0x4005e7}}},
|
||||
{"main", [][2]uint64{{0x4005e7, 0x400601}}},
|
||||
{"f2", [][2]uint64{{0x400601, 0x400611}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
"testdata/line-gcc-dwarf5.elf",
|
||||
subprograms{
|
||||
{"main", [][2]uint64{{0x401147, 0x401166}}},
|
||||
{"f1", [][2]uint64{{0x401122, 0x401147}}},
|
||||
{"f2", [][2]uint64{{0x401166, 0x401179}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
"testdata/line-clang-dwarf5.elf",
|
||||
subprograms{
|
||||
{"main", [][2]uint64{{0x401130, 0x401144}}},
|
||||
{"f1", [][2]uint64{{0x401150, 0x40117e}}},
|
||||
{"f2", [][2]uint64{{0x401180, 0x401197}}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
r := d.Reader()
|
||||
i := 0
|
||||
for entry, err := r.Next(); entry != nil && err == nil; entry, err = r.Next() {
|
||||
if entry.Tag != TagSubprogram {
|
||||
continue
|
||||
for _, test := range tests {
|
||||
d := elfData(t, test.filename)
|
||||
subprograms := test.subprograms
|
||||
|
||||
r := d.Reader()
|
||||
i := 0
|
||||
for entry, err := r.Next(); entry != nil && err == nil; entry, err = r.Next() {
|
||||
if entry.Tag != TagSubprogram {
|
||||
continue
|
||||
}
|
||||
|
||||
if i > len(subprograms) {
|
||||
t.Fatalf("%s: too many subprograms (expected at most %d)", test.filename, i)
|
||||
}
|
||||
|
||||
if got := entry.Val(AttrName).(string); got != subprograms[i].name {
|
||||
t.Errorf("%s: subprogram %d name is %s, expected %s", test.filename, i, got, subprograms[i].name)
|
||||
}
|
||||
ranges, err := d.Ranges(entry)
|
||||
if err != nil {
|
||||
t.Errorf("%s: subprogram %d: %v", test.filename, i, err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(ranges, subprograms[i].ranges) {
|
||||
t.Errorf("%s: subprogram %d ranges are %x, expected %x", test.filename, i, ranges, subprograms[i].ranges)
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
if i > len(subprograms) {
|
||||
t.Fatalf("too many subprograms (expected at most %d)", i)
|
||||
if i < len(subprograms) {
|
||||
t.Errorf("%s: saw only %d subprograms, expected %d", test.filename, i, len(subprograms))
|
||||
}
|
||||
|
||||
if got := entry.Val(AttrName).(string); got != subprograms[i].name {
|
||||
t.Errorf("subprogram %d name is %s, expected %s", i, got, subprograms[i].name)
|
||||
}
|
||||
ranges, err := d.Ranges(entry)
|
||||
if err != nil {
|
||||
t.Errorf("subprogram %d: %v", i, err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(ranges, subprograms[i].ranges) {
|
||||
t.Errorf("subprogram %d ranges are %x, expected %x", i, ranges, subprograms[i].ranges)
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
if i < len(subprograms) {
|
||||
t.Errorf("saw only %d subprograms, expected %d", i, len(subprograms))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,10 +26,10 @@ type Data struct {
|
|||
str []byte
|
||||
|
||||
// New sections added in DWARF 5.
|
||||
addr *debugAddr
|
||||
addr []byte
|
||||
lineStr []byte
|
||||
strOffsets []byte
|
||||
rngLists *rngLists
|
||||
rngLists []byte
|
||||
|
||||
// parsed data
|
||||
abbrevCache map[uint64]abbrevTable
|
||||
|
@ -40,21 +40,6 @@ type Data struct {
|
|||
unit []unit
|
||||
}
|
||||
|
||||
// rngLists represents the contents of a debug_rnglists section (DWARFv5).
|
||||
type rngLists struct {
|
||||
is64 bool
|
||||
asize uint8
|
||||
data []byte
|
||||
ver uint16
|
||||
}
|
||||
|
||||
// debugAddr represents the contents of a debug_addr section (DWARFv5).
|
||||
type debugAddr struct {
|
||||
is64 bool
|
||||
asize uint8
|
||||
data []byte
|
||||
}
|
||||
|
||||
var errSegmentSelector = errors.New("non-zero segment_selector size not supported")
|
||||
|
||||
// New returns a new Data object initialized from the given parameters.
|
||||
|
@ -132,76 +117,14 @@ func (d *Data) AddSection(name string, contents []byte) error {
|
|||
var err error
|
||||
switch name {
|
||||
case ".debug_addr":
|
||||
d.addr, err = d.parseAddrHeader(contents)
|
||||
d.addr = contents
|
||||
case ".debug_line_str":
|
||||
d.lineStr = contents
|
||||
case ".debug_str_offsets":
|
||||
d.strOffsets = contents
|
||||
case ".debug_rnglists":
|
||||
d.rngLists, err = d.parseRngListsHeader(contents)
|
||||
d.rngLists = contents
|
||||
}
|
||||
// Just ignore names that we don't yet support.
|
||||
return err
|
||||
}
|
||||
|
||||
// parseRngListsHeader reads the header of a debug_rnglists section, see
|
||||
// DWARFv5 section 7.28 (page 242).
|
||||
func (d *Data) parseRngListsHeader(bytes []byte) (*rngLists, error) {
|
||||
rngLists := &rngLists{data: bytes}
|
||||
|
||||
buf := makeBuf(d, unknownFormat{}, "rnglists", 0, bytes)
|
||||
_, rngLists.is64 = buf.unitLength()
|
||||
|
||||
rngLists.ver = buf.uint16() // version
|
||||
|
||||
rngLists.asize = buf.uint8()
|
||||
segsize := buf.uint8()
|
||||
if segsize != 0 {
|
||||
return nil, errSegmentSelector
|
||||
}
|
||||
|
||||
// Header fields not read: offset_entry_count, offset table
|
||||
|
||||
return rngLists, nil
|
||||
}
|
||||
|
||||
func (rngLists *rngLists) version() int {
|
||||
return int(rngLists.ver)
|
||||
}
|
||||
|
||||
func (rngLists *rngLists) dwarf64() (bool, bool) {
|
||||
return rngLists.is64, true
|
||||
}
|
||||
|
||||
func (rngLists *rngLists) addrsize() int {
|
||||
return int(rngLists.asize)
|
||||
}
|
||||
|
||||
// parseAddrHeader reads the header of a debug_addr section, see DWARFv5
|
||||
// section 7.27 (page 241).
|
||||
func (d *Data) parseAddrHeader(bytes []byte) (*debugAddr, error) {
|
||||
addr := &debugAddr{data: bytes}
|
||||
|
||||
buf := makeBuf(d, unknownFormat{}, "addr", 0, bytes)
|
||||
_, addr.is64 = buf.unitLength()
|
||||
|
||||
addr.asize = buf.uint8()
|
||||
segsize := buf.uint8()
|
||||
if segsize != 0 {
|
||||
return nil, errSegmentSelector
|
||||
}
|
||||
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
func (addr *debugAddr) version() int {
|
||||
return 5
|
||||
}
|
||||
|
||||
func (addr *debugAddr) dwarf64() (bool, bool) {
|
||||
return addr.is64, true
|
||||
}
|
||||
|
||||
func (addr *debugAddr) addrsize() int {
|
||||
return int(addr.asize)
|
||||
}
|
||||
|
|
BIN
src/debug/dwarf/testdata/line-clang-dwarf5.elf
vendored
Normal file
BIN
src/debug/dwarf/testdata/line-clang-dwarf5.elf
vendored
Normal file
Binary file not shown.
BIN
src/debug/dwarf/testdata/line-gcc-dwarf5.elf
vendored
Normal file
BIN
src/debug/dwarf/testdata/line-gcc-dwarf5.elf
vendored
Normal file
Binary file not shown.
|
@ -4,7 +4,7 @@ go 1.16
|
|||
|
||||
require (
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
|
||||
golang.org/x/net v0.0.0-20201029221708-28c70e62bb1d
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
|
||||
golang.org/x/text v0.3.4 // indirect
|
||||
)
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20201029221708-28c70e62bb1d h1:dOiJ2n2cMwGLce/74I/QHMbnpk5GfY7InR8rczoMqRM=
|
||||
golang.org/x/net v0.0.0-20201029221708-28c70e62bb1d/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11 h1:lwlPPsmjDKK0J6eG6xDWd5XPehI0R024zxjDnw3esPA=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 h1:KmZPnMocC93w341XZp26yTJg8Za7lhb2KhkYmixoeso=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
|
||||
|
|
|
@ -10,6 +10,7 @@ package build
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/token"
|
||||
"internal/testenv"
|
||||
"io/fs"
|
||||
"os"
|
||||
|
@ -162,6 +163,9 @@ var depsRules = `
|
|||
< os
|
||||
< os/signal;
|
||||
|
||||
io/fs
|
||||
< embed;
|
||||
|
||||
unicode, fmt !< os, os/signal;
|
||||
|
||||
os/signal, STR
|
||||
|
@ -602,6 +606,7 @@ func findImports(pkg string) ([]string, error) {
|
|||
}
|
||||
var imports []string
|
||||
var haveImport = map[string]bool{}
|
||||
fset := token.NewFileSet()
|
||||
for _, file := range files {
|
||||
name := file.Name()
|
||||
if name == "slice_go14.go" || name == "slice_go18.go" {
|
||||
|
@ -611,8 +616,10 @@ func findImports(pkg string) ([]string, error) {
|
|||
if !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") {
|
||||
continue
|
||||
}
|
||||
var info fileInfo
|
||||
info.name = filepath.Join(dir, name)
|
||||
info := fileInfo{
|
||||
name: filepath.Join(dir, name),
|
||||
fset: fset,
|
||||
}
|
||||
f, err := os.Open(info.name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -840,3 +847,22 @@ func TestStdlibLowercase(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestFindImports tests that findImports works. See #43249.
|
||||
func TestFindImports(t *testing.T) {
|
||||
imports, err := findImports("go/build")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("go/build imports %q", imports)
|
||||
want := []string{"bytes", "os", "path/filepath", "strings"}
|
||||
wantLoop:
|
||||
for _, w := range want {
|
||||
for _, imp := range imports {
|
||||
if imp == w {
|
||||
continue wantLoop
|
||||
}
|
||||
}
|
||||
t.Errorf("expected to find %q in import list", w)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,10 @@ func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind {
|
|||
case 1:
|
||||
check.expr(x, e.Args[0])
|
||||
if x.mode != invalid {
|
||||
if e.Ellipsis.IsValid() {
|
||||
check.errorf(e.Args[0], _BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
|
||||
break
|
||||
}
|
||||
check.conversion(x, T)
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -1207,6 +1207,16 @@ const (
|
|||
// }
|
||||
_InvalidTypeSwitch
|
||||
|
||||
// _InvalidExprSwitch occurs when a switch expression is not comparable.
|
||||
//
|
||||
// Example:
|
||||
// func _() {
|
||||
// var a struct{ _ func() }
|
||||
// switch a /* ERROR cannot switch on a */ {
|
||||
// }
|
||||
// }
|
||||
_InvalidExprSwitch
|
||||
|
||||
/* control flow > select */
|
||||
|
||||
// _InvalidSelectCase occurs when a select case is not a channel send or
|
||||
|
|
43
src/go/types/fixedbugs/issue43110.src
Normal file
43
src/go/types/fixedbugs/issue43110.src
Normal file
|
@ -0,0 +1,43 @@
|
|||
// 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 p
|
||||
|
||||
type P *struct{}
|
||||
|
||||
func _() {
|
||||
// want an error even if the switch is empty
|
||||
var a struct{ _ func() }
|
||||
switch a /* ERROR cannot switch on a */ {
|
||||
}
|
||||
|
||||
switch a /* ERROR cannot switch on a */ {
|
||||
case a: // no follow-on error here
|
||||
}
|
||||
|
||||
// this is ok because f can be compared to nil
|
||||
var f func()
|
||||
switch f {
|
||||
}
|
||||
|
||||
switch f {
|
||||
case nil:
|
||||
}
|
||||
|
||||
switch (func())(nil) {
|
||||
case nil:
|
||||
}
|
||||
|
||||
switch (func())(nil) {
|
||||
case f /* ERROR cannot compare */ :
|
||||
}
|
||||
|
||||
switch nil /* ERROR use of untyped nil in switch expression */ {
|
||||
}
|
||||
|
||||
// this is ok
|
||||
switch P(nil) {
|
||||
case P(nil):
|
||||
}
|
||||
}
|
16
src/go/types/fixedbugs/issue43124.src
Normal file
16
src/go/types/fixedbugs/issue43124.src
Normal file
|
@ -0,0 +1,16 @@
|
|||
// 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 p
|
||||
|
||||
var _ = int(0 /* ERROR invalid use of \.\.\. in conversion to int */ ...)
|
||||
|
||||
// test case from issue
|
||||
|
||||
type M []string
|
||||
|
||||
var (
|
||||
x = []string{"a", "b"}
|
||||
_ = M(x /* ERROR invalid use of \.\.\. in conversion to M */ ...)
|
||||
)
|
|
@ -528,6 +528,10 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
|||
// By checking assignment of x to an invisible temporary
|
||||
// (as a compiler would), we get all the relevant checks.
|
||||
check.assignment(&x, nil, "switch expression")
|
||||
if x.mode != invalid && !Comparable(x.typ) && !hasNil(x.typ) {
|
||||
check.errorf(&x, _InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ)
|
||||
x.mode = invalid
|
||||
}
|
||||
} else {
|
||||
// spec: "A missing switch expression is
|
||||
// equivalent to the boolean value true."
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"text/template"
|
||||
)
|
||||
|
@ -1706,3 +1707,72 @@ func TestIssue31810(t *testing.T) {
|
|||
t.Errorf("%s got %q, expected %q", textCall, b.String(), "result")
|
||||
}
|
||||
}
|
||||
|
||||
// Issue 39807. There was a race applying escapeTemplate.
|
||||
|
||||
const raceText = `
|
||||
{{- define "jstempl" -}}
|
||||
var v = "v";
|
||||
{{- end -}}
|
||||
<script type="application/javascript">
|
||||
{{ template "jstempl" $ }}
|
||||
</script>
|
||||
`
|
||||
|
||||
func TestEscapeRace(t *testing.T) {
|
||||
tmpl := New("")
|
||||
_, err := tmpl.New("templ.html").Parse(raceText)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
const count = 20
|
||||
for i := 0; i < count; i++ {
|
||||
_, err := tmpl.New(fmt.Sprintf("x%d.html", i)).Parse(`{{ template "templ.html" .}}`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < 10; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for j := 0; j < count; j++ {
|
||||
sub := tmpl.Lookup(fmt.Sprintf("x%d.html", j))
|
||||
if err := sub.Execute(io.Discard, nil); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestRecursiveExecute(t *testing.T) {
|
||||
tmpl := New("")
|
||||
|
||||
recur := func() (HTML, error) {
|
||||
var sb strings.Builder
|
||||
if err := tmpl.ExecuteTemplate(&sb, "subroutine", nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return HTML(sb.String()), nil
|
||||
}
|
||||
|
||||
m := FuncMap{
|
||||
"recur": recur,
|
||||
}
|
||||
|
||||
top, err := tmpl.New("x.html").Funcs(m).Parse(`{{recur}}`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = tmpl.New("subroutine").Parse(`<a href="/x?p={{"'a<b'"}}">`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := top.Execute(io.Discard, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sync"
|
||||
"text/template"
|
||||
"text/template/parse"
|
||||
|
@ -26,7 +27,9 @@ type Template struct {
|
|||
// template's in sync.
|
||||
text *template.Template
|
||||
// The underlying template's parse tree, updated to be HTML-safe.
|
||||
Tree *parse.Tree
|
||||
Tree *parse.Tree
|
||||
// The original functions, before wrapping.
|
||||
funcMap FuncMap
|
||||
*nameSpace // common to all associated templates
|
||||
}
|
||||
|
||||
|
@ -35,7 +38,7 @@ var escapeOK = fmt.Errorf("template escaped correctly")
|
|||
|
||||
// nameSpace is the data structure shared by all templates in an association.
|
||||
type nameSpace struct {
|
||||
mu sync.Mutex
|
||||
mu sync.RWMutex
|
||||
set map[string]*Template
|
||||
escaped bool
|
||||
esc escaper
|
||||
|
@ -45,8 +48,8 @@ type nameSpace struct {
|
|||
// itself.
|
||||
func (t *Template) Templates() []*Template {
|
||||
ns := t.nameSpace
|
||||
ns.mu.Lock()
|
||||
defer ns.mu.Unlock()
|
||||
ns.mu.RLock()
|
||||
defer ns.mu.RUnlock()
|
||||
// Return a slice so we don't expose the map.
|
||||
m := make([]*Template, 0, len(ns.set))
|
||||
for _, v := range ns.set {
|
||||
|
@ -84,8 +87,8 @@ func (t *Template) checkCanParse() error {
|
|||
if t == nil {
|
||||
return nil
|
||||
}
|
||||
t.nameSpace.mu.Lock()
|
||||
defer t.nameSpace.mu.Unlock()
|
||||
t.nameSpace.mu.RLock()
|
||||
defer t.nameSpace.mu.RUnlock()
|
||||
if t.nameSpace.escaped {
|
||||
return fmt.Errorf("html/template: cannot Parse after Execute")
|
||||
}
|
||||
|
@ -94,6 +97,16 @@ func (t *Template) checkCanParse() error {
|
|||
|
||||
// escape escapes all associated templates.
|
||||
func (t *Template) escape() error {
|
||||
t.nameSpace.mu.RLock()
|
||||
escapeErr := t.escapeErr
|
||||
t.nameSpace.mu.RUnlock()
|
||||
if escapeErr != nil {
|
||||
if escapeErr == escapeOK {
|
||||
return nil
|
||||
}
|
||||
return escapeErr
|
||||
}
|
||||
|
||||
t.nameSpace.mu.Lock()
|
||||
defer t.nameSpace.mu.Unlock()
|
||||
t.nameSpace.escaped = true
|
||||
|
@ -121,6 +134,8 @@ func (t *Template) Execute(wr io.Writer, data interface{}) error {
|
|||
if err := t.escape(); err != nil {
|
||||
return err
|
||||
}
|
||||
t.nameSpace.mu.RLock()
|
||||
defer t.nameSpace.mu.RUnlock()
|
||||
return t.text.Execute(wr, data)
|
||||
}
|
||||
|
||||
|
@ -136,6 +151,8 @@ func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{})
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.nameSpace.mu.RLock()
|
||||
defer t.nameSpace.mu.RUnlock()
|
||||
return tmpl.text.Execute(wr, data)
|
||||
}
|
||||
|
||||
|
@ -143,13 +160,27 @@ func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{})
|
|||
// is escaped, or returns an error if it cannot be. It returns the named
|
||||
// template.
|
||||
func (t *Template) lookupAndEscapeTemplate(name string) (tmpl *Template, err error) {
|
||||
t.nameSpace.mu.Lock()
|
||||
defer t.nameSpace.mu.Unlock()
|
||||
t.nameSpace.escaped = true
|
||||
t.nameSpace.mu.RLock()
|
||||
tmpl = t.set[name]
|
||||
var escapeErr error
|
||||
if tmpl != nil {
|
||||
escapeErr = tmpl.escapeErr
|
||||
}
|
||||
t.nameSpace.mu.RUnlock()
|
||||
|
||||
if tmpl == nil {
|
||||
return nil, fmt.Errorf("html/template: %q is undefined", name)
|
||||
}
|
||||
if escapeErr != nil {
|
||||
if escapeErr != escapeOK {
|
||||
return nil, escapeErr
|
||||
}
|
||||
return tmpl, nil
|
||||
}
|
||||
|
||||
t.nameSpace.mu.Lock()
|
||||
defer t.nameSpace.mu.Unlock()
|
||||
t.nameSpace.escaped = true
|
||||
if tmpl.escapeErr != nil && tmpl.escapeErr != escapeOK {
|
||||
return nil, tmpl.escapeErr
|
||||
}
|
||||
|
@ -229,6 +260,7 @@ func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error
|
|||
nil,
|
||||
text,
|
||||
text.Tree,
|
||||
nil,
|
||||
t.nameSpace,
|
||||
}
|
||||
t.set[name] = ret
|
||||
|
@ -259,8 +291,10 @@ func (t *Template) Clone() (*Template, error) {
|
|||
nil,
|
||||
textClone,
|
||||
textClone.Tree,
|
||||
t.funcMap,
|
||||
ns,
|
||||
}
|
||||
ret.wrapFuncs()
|
||||
ret.set[ret.Name()] = ret
|
||||
for _, x := range textClone.Templates() {
|
||||
name := x.Name()
|
||||
|
@ -269,12 +303,15 @@ func (t *Template) Clone() (*Template, error) {
|
|||
return nil, fmt.Errorf("html/template: cannot Clone %q after it has executed", t.Name())
|
||||
}
|
||||
x.Tree = x.Tree.Copy()
|
||||
ret.set[name] = &Template{
|
||||
tc := &Template{
|
||||
nil,
|
||||
x,
|
||||
x.Tree,
|
||||
src.funcMap,
|
||||
ret.nameSpace,
|
||||
}
|
||||
tc.wrapFuncs()
|
||||
ret.set[name] = tc
|
||||
}
|
||||
// Return the template associated with the name of this template.
|
||||
return ret.set[ret.Name()], nil
|
||||
|
@ -288,6 +325,7 @@ func New(name string) *Template {
|
|||
nil,
|
||||
template.New(name),
|
||||
nil,
|
||||
nil,
|
||||
ns,
|
||||
}
|
||||
tmpl.set[name] = tmpl
|
||||
|
@ -313,6 +351,7 @@ func (t *Template) new(name string) *Template {
|
|||
nil,
|
||||
t.text.New(name),
|
||||
nil,
|
||||
nil,
|
||||
t.nameSpace,
|
||||
}
|
||||
if existing, ok := tmpl.set[name]; ok {
|
||||
|
@ -343,10 +382,35 @@ type FuncMap map[string]interface{}
|
|||
// type. However, it is legal to overwrite elements of the map. The return
|
||||
// value is the template, so calls can be chained.
|
||||
func (t *Template) Funcs(funcMap FuncMap) *Template {
|
||||
t.text.Funcs(template.FuncMap(funcMap))
|
||||
t.funcMap = funcMap
|
||||
t.wrapFuncs()
|
||||
return t
|
||||
}
|
||||
|
||||
// wrapFuncs records the functions with text/template. We wrap them to
|
||||
// unlock the nameSpace. See TestRecursiveExecute for a test case.
|
||||
func (t *Template) wrapFuncs() {
|
||||
if len(t.funcMap) == 0 {
|
||||
return
|
||||
}
|
||||
tfuncs := make(template.FuncMap, len(t.funcMap))
|
||||
for name, fn := range t.funcMap {
|
||||
fnv := reflect.ValueOf(fn)
|
||||
wrapper := func(args []reflect.Value) []reflect.Value {
|
||||
t.nameSpace.mu.RUnlock()
|
||||
defer t.nameSpace.mu.RLock()
|
||||
if fnv.Type().IsVariadic() {
|
||||
return fnv.CallSlice(args)
|
||||
} else {
|
||||
return fnv.Call(args)
|
||||
}
|
||||
}
|
||||
wrapped := reflect.MakeFunc(fnv.Type(), wrapper)
|
||||
tfuncs[name] = wrapped.Interface()
|
||||
}
|
||||
t.text.Funcs(tfuncs)
|
||||
}
|
||||
|
||||
// Delims sets the action delimiters to the specified strings, to be used in
|
||||
// subsequent calls to Parse, ParseFiles, or ParseGlob. Nested template
|
||||
// definitions will inherit the settings. An empty delimiter stands for the
|
||||
|
@ -360,8 +424,8 @@ func (t *Template) Delims(left, right string) *Template {
|
|||
// Lookup returns the template with the given name that is associated with t,
|
||||
// or nil if there is no such template.
|
||||
func (t *Template) Lookup(name string) *Template {
|
||||
t.nameSpace.mu.Lock()
|
||||
defer t.nameSpace.mu.Unlock()
|
||||
t.nameSpace.mu.RLock()
|
||||
defer t.nameSpace.mu.RUnlock()
|
||||
return t.set[name]
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@ import (
|
|||
//
|
||||
// The FS interface is the minimum implementation required of the file system.
|
||||
// A file system may implement additional interfaces,
|
||||
// such as fsutil.ReadFileFS, to provide additional or optimized functionality.
|
||||
// See io/fsutil for details.
|
||||
// such as ReadFileFS, to provide additional or optimized functionality.
|
||||
type FS interface {
|
||||
// Open opens the named file.
|
||||
//
|
||||
|
|
|
@ -804,3 +804,13 @@ func TestIssue37499(t *testing.T) {
|
|||
t.Fatalf("incorrect quotient: %s", s)
|
||||
}
|
||||
}
|
||||
|
||||
// TestIssue42552 triggers an edge case of recursive division
|
||||
// where the first division loop is never entered, and correcting
|
||||
// the remainder takes exactly two iterations in the final loop.
|
||||
func TestIssue42552(t *testing.T) {
|
||||
u := natFromString("0xc23b166884c3869092a520eceedeced2b00847bd256c9cf3b2c5e2227c15bd5e6ee7ef8a2f49236ad0eedf2c8a3b453cf6e0706f64285c526b372c4b1321245519d430540804a50b7ca8b6f1b34a2ec05cdbc24de7599af112d3e3c8db347e8799fe70f16e43c6566ba3aeb169463a3ecc486172deb2d9b80a3699c776e44fef20036bd946f1b4d054dd88a2c1aeb986199b0b2b7e58c42288824b74934d112fe1fc06e06b4d99fe1c5e725946b23210521e209cd507cce90b5f39a523f27e861f9e232aee50c3f585208b4573dcc0b897b6177f2ba20254fd5c50a033e849dee1b3a93bd2dc44ba8ca836cab2c2ae50e50b126284524fa0187af28628ff0face68d87709200329db1392852c8b8963fbe3d05fb1efe19f0ed5ca9fadc2f96f82187c24bb2512b2e85a66333a7e176605695211e1c8e0b9b9e82813e50654964945b1e1e66a90840396c7d10e23e47f364d2d3f660fa54598e18d1ca2ea4fe4f35a40a11f69f201c80b48eaee3e2e9b0eda63decf92bec08a70f731587d4ed0f218d5929285c8b2ccbc497e20db42de73885191fa453350335990184d8df805072f958d5354debda38f5421effaaafd6cb9b721ace74be0892d77679f62a4a126697cd35797f6858193da4ba1770c06aea2e5c59ec04b8ea26749e61b72ecdde403f3bc7e5e546cd799578cc939fa676dfd5e648576d4a06cbadb028adc2c0b461f145b2321f42e5e0f3b4fb898ecd461df07a6f5154067787bf74b5cc5c03704a1ce47494961931f0263b0aac32505102595957531a2de69dd71aac51f8a49902f81f21283dbe8e21e01e5d82517868826f86acf338d935aa6b4d5a25c8d540389b277dd9d64569d68baf0f71bd03dba45b92a7fc052601d1bd011a2fc6790a23f97c6fa5caeea040ab86841f268d39ce4f7caf01069df78bba098e04366492f0c2ac24f1bf16828752765fa523c9a4d42b71109d123e6be8c7b1ab3ccf8ea03404075fe1a9596f1bba1d267f9a7879ceece514818316c9c0583469d2367831fc42b517ea028a28df7c18d783d16ea2436cee2b15d52db68b5dfdee6b4d26f0905f9b030c911a04d078923a4136afea96eed6874462a482917353264cc9bee298f167ac65a6db4e4eda88044b39cc0b33183843eaa946564a00c3a0ab661f2c915e70bf0bb65bfbb6fa2eea20aed16bf2c1a1d00ec55fb4ff2f76b8e462ea70c19efa579c9ee78194b86708fdae66a9ce6e2cf3d366037798cfb50277ba6d2fd4866361022fd788ab7735b40b8b61d55e32243e06719e53992e9ac16c9c4b6e6933635c3c47c8f7e73e17dd54d0dd8aeba5d76de46894e7b3f9d3ec25ad78ee82297ba69905ea0fa094b8667faa2b8885e2187b3da80268aa1164761d7b0d6de206b676777348152b8ae1d4afed753bc63c739a5ca8ce7afb2b241a226bd9e502baba391b5b13f5054f070b65a9cf3a67063bfaa803ba390732cd03888f664023f888741d04d564e0b5674b0a183ace81452001b3fbb4214c77d42ca75376742c471e58f67307726d56a1032bd236610cbcbcd03d0d7a452900136897dc55bb3ce959d10d4e6a10fb635006bd8c41cd9ded2d3dfdd8f2e229590324a7370cb2124210b2330f4c56155caa09a2564932ceded8d92c79664dcdeb87faad7d3da006cc2ea267ee3df41e9677789cc5a8cc3b83add6491561b3047919e0648b1b2e97d7ad6f6c2aa80cab8e9ae10e1f75b1fdd0246151af709d259a6a0ed0b26bd711024965ecad7c41387de45443defce53f66612948694a6032279131c257119ed876a8e805dfb49576ef5c563574115ee87050d92d191bc761ef51d966918e2ef925639400069e3959d8fe19f36136e947ff430bf74e71da0aa5923b00000000")
|
||||
v := natFromString("0x838332321d443a3d30373d47301d47073847473a383d3030f25b3d3d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e00000000000000000041603038331c3d32f5303441e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e01c0a5459bfc7b9be9fcbb9d2383840464319434707303030f43a32f53034411c0a5459413820878787878787878787878787878787878787878787878787878787878787878787870630303a3a30334036605b923a6101f83638413943413960204337602043323801526040523241846038414143015238604060328452413841413638523c0240384141364036605b923a6101f83638413943413960204334602043323801526040523241846038414143015238604060328452413841413638523c02403841413638433030f25a8b83838383838383838383838383838383837d838383ffffffffffffffff838383838383838383000000000000000000030000007d26e27c7c8b83838383838383838383838383838383837d838383ffffffffffffffff83838383838383838383838383838383838383838383435960f535073030f3343200000000000000011881301938343030fa398383300000002300000000000000000000f11af4600c845252904141364138383c60406032414443095238010241414303364443434132305b595a15434160b042385341ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff47476043410536613603593a6005411c437405fcfcfcfcfcfcfc0000000000005a3b075815054359000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
|
||||
q := nat(nil).make(16)
|
||||
q.div(q, u, v)
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ func TestConnAndListener(t *testing.T) {
|
|||
}
|
||||
defer ls.teardown()
|
||||
ch := make(chan error, 1)
|
||||
handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
|
||||
handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) }
|
||||
if err := ls.buildup(handler); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -7651,6 +7651,9 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
|
|||
// we can keep it.
|
||||
bodyWriter.cancel()
|
||||
cs.abortRequestBodyWrite(http2errStopReqBodyWrite)
|
||||
if hasBody && !bodyWritten {
|
||||
<-bodyWriter.resc
|
||||
}
|
||||
}
|
||||
if re.err != nil {
|
||||
cc.forgetStreamID(cs.ID)
|
||||
|
@ -7671,6 +7674,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
|
|||
} else {
|
||||
bodyWriter.cancel()
|
||||
cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
|
||||
<-bodyWriter.resc
|
||||
}
|
||||
cc.forgetStreamID(cs.ID)
|
||||
return nil, cs.getStartedWrite(), http2errTimeout
|
||||
|
@ -7680,6 +7684,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
|
|||
} else {
|
||||
bodyWriter.cancel()
|
||||
cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
|
||||
<-bodyWriter.resc
|
||||
}
|
||||
cc.forgetStreamID(cs.ID)
|
||||
return nil, cs.getStartedWrite(), ctx.Err()
|
||||
|
@ -7689,6 +7694,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
|
|||
} else {
|
||||
bodyWriter.cancel()
|
||||
cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
|
||||
<-bodyWriter.resc
|
||||
}
|
||||
cc.forgetStreamID(cs.ID)
|
||||
return nil, cs.getStartedWrite(), http2errRequestCanceled
|
||||
|
@ -7698,6 +7704,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
|
|||
// forgetStreamID.
|
||||
return nil, cs.getStartedWrite(), cs.resetErr
|
||||
case err := <-bodyWriter.resc:
|
||||
bodyWritten = true
|
||||
// Prefer the read loop's response, if available. Issue 16102.
|
||||
select {
|
||||
case re := <-readLoopResCh:
|
||||
|
@ -7708,7 +7715,6 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
|
|||
cc.forgetStreamID(cs.ID)
|
||||
return nil, cs.getStartedWrite(), err
|
||||
}
|
||||
bodyWritten = true
|
||||
if d := cc.responseHeaderTimeout(); d != 0 {
|
||||
timer := time.NewTimer(d)
|
||||
defer timer.Stop()
|
||||
|
@ -9130,7 +9136,9 @@ func (t *http2Transport) getBodyWriterState(cs *http2clientStream, body io.Reade
|
|||
|
||||
func (s http2bodyWriterState) cancel() {
|
||||
if s.timer != nil {
|
||||
s.timer.Stop()
|
||||
if s.timer.Stop() {
|
||||
s.resc <- nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ func init() {
|
|||
func Cmdline(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||
fmt.Fprintf(w, strings.Join(os.Args, "\x00"))
|
||||
fmt.Fprint(w, strings.Join(os.Args, "\x00"))
|
||||
}
|
||||
|
||||
func sleep(r *http.Request, d time.Duration) {
|
||||
|
|
|
@ -361,7 +361,12 @@ func (r *Response) isProtocolSwitch() bool {
|
|||
// isProtocolSwitchResponse reports whether the response code and
|
||||
// response header indicate a successful protocol upgrade response.
|
||||
func isProtocolSwitchResponse(code int, h Header) bool {
|
||||
return code == StatusSwitchingProtocols &&
|
||||
h.Get("Upgrade") != "" &&
|
||||
return code == StatusSwitchingProtocols && isProtocolSwitchHeader(h)
|
||||
}
|
||||
|
||||
// isProtocolSwitchHeader reports whether the request or response header
|
||||
// is for a protocol switch.
|
||||
func isProtocolSwitchHeader(h Header) bool {
|
||||
return h.Get("Upgrade") != "" &&
|
||||
httpguts.HeaderValuesContainsToken(h["Connection"], "Upgrade")
|
||||
}
|
||||
|
|
|
@ -6481,6 +6481,10 @@ func TestDisableKeepAliveUpgrade(t *testing.T) {
|
|||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != StatusSwitchingProtocols {
|
||||
t.Fatalf("unexpected status code: %v", resp.StatusCode)
|
||||
}
|
||||
|
||||
rwc, ok := resp.Body.(io.ReadWriteCloser)
|
||||
if !ok {
|
||||
t.Fatalf("Response.Body is not a io.ReadWriteCloser: %T", resp.Body)
|
||||
|
|
|
@ -1837,7 +1837,7 @@ func (c *conn) serve(ctx context.Context) {
|
|||
if d := c.server.WriteTimeout; d != 0 {
|
||||
c.rwc.SetWriteDeadline(time.Now().Add(d))
|
||||
}
|
||||
if err := tlsConn.HandshakeContext(ctx); err != nil {
|
||||
if err := tlsConn.Handshake(); err != nil {
|
||||
// If the handshake failed due to the client not speaking
|
||||
// TLS, assume they're speaking plaintext HTTP and write a
|
||||
// 400 response on the TLS conn's underlying net.Conn.
|
||||
|
|
|
@ -1505,7 +1505,7 @@ func (t *Transport) decConnsPerHost(key connectMethodKey) {
|
|||
// Add TLS to a persistent connection, i.e. negotiate a TLS session. If pconn is already a TLS
|
||||
// tunnel, this function establishes a nested TLS session inside the encrypted channel.
|
||||
// The remote endpoint's name may be overridden by TLSClientConfig.ServerName.
|
||||
func (pconn *persistConn) addTLS(ctx context.Context, name string, trace *httptrace.ClientTrace) error {
|
||||
func (pconn *persistConn) addTLS(name string, trace *httptrace.ClientTrace) error {
|
||||
// Initiate TLS and check remote host name against certificate.
|
||||
cfg := cloneTLSConfig(pconn.t.TLSClientConfig)
|
||||
if cfg.ServerName == "" {
|
||||
|
@ -1527,7 +1527,7 @@ func (pconn *persistConn) addTLS(ctx context.Context, name string, trace *httptr
|
|||
if trace != nil && trace.TLSHandshakeStart != nil {
|
||||
trace.TLSHandshakeStart()
|
||||
}
|
||||
err := tlsConn.HandshakeContext(ctx)
|
||||
err := tlsConn.Handshake()
|
||||
if timer != nil {
|
||||
timer.Stop()
|
||||
}
|
||||
|
@ -1583,7 +1583,7 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers
|
|||
if trace != nil && trace.TLSHandshakeStart != nil {
|
||||
trace.TLSHandshakeStart()
|
||||
}
|
||||
if err := tc.HandshakeContext(ctx); err != nil {
|
||||
if err := tc.Handshake(); err != nil {
|
||||
go pconn.conn.Close()
|
||||
if trace != nil && trace.TLSHandshakeDone != nil {
|
||||
trace.TLSHandshakeDone(tls.ConnectionState{}, err)
|
||||
|
@ -1607,7 +1607,7 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers
|
|||
if firstTLSHost, _, err = net.SplitHostPort(cm.addr()); err != nil {
|
||||
return nil, wrapErr(err)
|
||||
}
|
||||
if err = pconn.addTLS(ctx, firstTLSHost, trace); err != nil {
|
||||
if err = pconn.addTLS(firstTLSHost, trace); err != nil {
|
||||
return nil, wrapErr(err)
|
||||
}
|
||||
}
|
||||
|
@ -1721,7 +1721,7 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers
|
|||
}
|
||||
|
||||
if cm.proxyURL != nil && cm.targetScheme == "https" {
|
||||
if err := pconn.addTLS(ctx, cm.tlsHost(), trace); err != nil {
|
||||
if err := pconn.addTLS(cm.tlsHost(), trace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
@ -2566,7 +2566,9 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
|
|||
continueCh = make(chan struct{}, 1)
|
||||
}
|
||||
|
||||
if pc.t.DisableKeepAlives && !req.wantsClose() {
|
||||
if pc.t.DisableKeepAlives &&
|
||||
!req.wantsClose() &&
|
||||
!isProtocolSwitchHeader(req.Header) {
|
||||
req.extraHeaders().Set("Connection", "close")
|
||||
}
|
||||
|
||||
|
|
|
@ -3734,7 +3734,7 @@ func TestTransportDialTLSContext(t *testing.T) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, c.HandshakeContext(ctx)
|
||||
return c, c.Handshake()
|
||||
}
|
||||
|
||||
req, err := NewRequest("GET", ts.URL, nil)
|
||||
|
|
|
@ -87,6 +87,7 @@ type localServer struct {
|
|||
lnmu sync.RWMutex
|
||||
Listener
|
||||
done chan bool // signal that indicates server stopped
|
||||
cl []Conn // accepted connection list
|
||||
}
|
||||
|
||||
func (ls *localServer) buildup(handler func(*localServer, Listener)) error {
|
||||
|
@ -99,10 +100,16 @@ func (ls *localServer) buildup(handler func(*localServer, Listener)) error {
|
|||
|
||||
func (ls *localServer) teardown() error {
|
||||
ls.lnmu.Lock()
|
||||
defer ls.lnmu.Unlock()
|
||||
if ls.Listener != nil {
|
||||
network := ls.Listener.Addr().Network()
|
||||
address := ls.Listener.Addr().String()
|
||||
ls.Listener.Close()
|
||||
for _, c := range ls.cl {
|
||||
if err := c.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
<-ls.done
|
||||
ls.Listener = nil
|
||||
switch network {
|
||||
|
@ -110,7 +117,6 @@ func (ls *localServer) teardown() error {
|
|||
os.Remove(address)
|
||||
}
|
||||
}
|
||||
ls.lnmu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -203,7 +209,7 @@ func newDualStackServer() (*dualStackServer, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func transponder(ln Listener, ch chan<- error) {
|
||||
func (ls *localServer) transponder(ln Listener, ch chan<- error) {
|
||||
defer close(ch)
|
||||
|
||||
switch ln := ln.(type) {
|
||||
|
@ -220,7 +226,7 @@ func transponder(ln Listener, ch chan<- error) {
|
|||
ch <- err
|
||||
return
|
||||
}
|
||||
defer c.Close()
|
||||
ls.cl = append(ls.cl, c)
|
||||
|
||||
network := ln.Addr().Network()
|
||||
if c.LocalAddr().Network() != network || c.RemoteAddr().Network() != network {
|
||||
|
|
|
@ -72,7 +72,7 @@ func TestTCPConnSpecificMethods(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
ch := make(chan error, 1)
|
||||
handler := func(ls *localServer, ln Listener) { transponder(ls.Listener, ch) }
|
||||
handler := func(ls *localServer, ln Listener) { ls.transponder(ls.Listener, ch) }
|
||||
ls, err := (&streamListener{Listener: ln}).newLocalServer()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
|
@ -86,7 +86,7 @@ func TestTCPServer(t *testing.T) {
|
|||
}
|
||||
for i := 0; i < N; i++ {
|
||||
ch := tpchs[i]
|
||||
handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
|
||||
handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) }
|
||||
if err := lss[i].buildup(handler); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ func TestUnixAndUnixpacketServer(t *testing.T) {
|
|||
}
|
||||
for i := 0; i < N; i++ {
|
||||
ch := tpchs[i]
|
||||
handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
|
||||
handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) }
|
||||
if err := lss[i].buildup(handler); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -393,7 +393,7 @@ func TestIPv6LinkLocalUnicastTCP(t *testing.T) {
|
|||
}
|
||||
defer ls.teardown()
|
||||
ch := make(chan error, 1)
|
||||
handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
|
||||
handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) }
|
||||
if err := ls.buildup(handler); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -336,16 +336,6 @@ func hasPrefix(s, prefix string) bool {
|
|||
return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
|
||||
}
|
||||
|
||||
// LastIndexByte from the strings package.
|
||||
func lastIndex(s string, sep byte) int {
|
||||
for i := len(s) - 1; i >= 0; i-- {
|
||||
if s[i] == sep {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func rename(oldname, newname string) error {
|
||||
dirname := oldname[:lastIndex(oldname, '/')+1]
|
||||
if hasPrefix(newname, dirname) {
|
||||
|
|
|
@ -675,22 +675,68 @@ func TestTime(t *testing.T) {
|
|||
<-done
|
||||
}
|
||||
|
||||
func TestNotifyContext(t *testing.T) {
|
||||
c, stop := NotifyContext(context.Background(), syscall.SIGINT)
|
||||
defer stop()
|
||||
var (
|
||||
checkNotifyContext = flag.Bool("check_notify_ctx", false, "if true, TestNotifyContext will fail if SIGINT is not received.")
|
||||
ctxNotifyTimes = flag.Int("ctx_notify_times", 1, "number of times a SIGINT signal should be received")
|
||||
)
|
||||
|
||||
if want, got := "signal.NotifyContext(context.Background, [interrupt])", fmt.Sprint(c); want != got {
|
||||
t.Errorf("c.String() = %q, want %q", got, want)
|
||||
func TestNotifyContextNotifications(t *testing.T) {
|
||||
if *checkNotifyContext {
|
||||
ctx, _ := NotifyContext(context.Background(), syscall.SIGINT)
|
||||
// We want to make sure not to be calling Stop() internally on NotifyContext() when processing a received signal.
|
||||
// Being able to wait for a number of received system signals allows us to do so.
|
||||
var wg sync.WaitGroup
|
||||
n := *ctxNotifyTimes
|
||||
wg.Add(n)
|
||||
for i := 0; i < n; i++ {
|
||||
go func() {
|
||||
syscall.Kill(syscall.Getpid(), syscall.SIGINT)
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
<-ctx.Done()
|
||||
fmt.Print("received SIGINT")
|
||||
// Sleep to give time to simultaneous signals to reach the process.
|
||||
// These signals must be ignored given stop() is not called on this code.
|
||||
// We want to guarantee a SIGINT doesn't cause a premature termination of the program.
|
||||
time.Sleep(settleTime)
|
||||
return
|
||||
}
|
||||
|
||||
syscall.Kill(syscall.Getpid(), syscall.SIGINT)
|
||||
select {
|
||||
case <-c.Done():
|
||||
if got := c.Err(); got != context.Canceled {
|
||||
t.Errorf("c.Err() = %q, want %q", got, context.Canceled)
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Errorf("timed out waiting for context to be done after SIGINT")
|
||||
t.Parallel()
|
||||
testCases := []struct {
|
||||
name string
|
||||
n int // number of times a SIGINT should be notified.
|
||||
}{
|
||||
{"once", 1},
|
||||
{"multiple", 10},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
var subTimeout time.Duration
|
||||
if deadline, ok := t.Deadline(); ok {
|
||||
subTimeout := time.Until(deadline)
|
||||
subTimeout -= subTimeout / 10 // Leave 10% headroom for cleaning up subprocess.
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-test.v",
|
||||
"-test.run=TestNotifyContextNotifications$",
|
||||
"-check_notify_ctx",
|
||||
fmt.Sprintf("-ctx_notify_times=%d", tc.n),
|
||||
}
|
||||
if subTimeout != 0 {
|
||||
args = append(args, fmt.Sprintf("-test.timeout=%v", subTimeout))
|
||||
}
|
||||
out, err := exec.Command(os.Args[0], args...).CombinedOutput()
|
||||
if err != nil {
|
||||
t.Errorf("ran test with -check_notify_ctx_notification and it failed with %v.\nOutput:\n%s", err, out)
|
||||
}
|
||||
if want := []byte("received SIGINT"); !bytes.Contains(out, want) {
|
||||
t.Errorf("got %q, wanted %q", out, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -768,34 +814,6 @@ func TestNotifyContextPrematureCancelParent(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNotifyContextSimultaneousNotifications(t *testing.T) {
|
||||
c, stop := NotifyContext(context.Background(), syscall.SIGINT)
|
||||
defer stop()
|
||||
|
||||
if want, got := "signal.NotifyContext(context.Background, [interrupt])", fmt.Sprint(c); want != got {
|
||||
t.Errorf("c.String() = %q, want %q", got, want)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
n := 10
|
||||
wg.Add(n)
|
||||
for i := 0; i < n; i++ {
|
||||
go func() {
|
||||
syscall.Kill(syscall.Getpid(), syscall.SIGINT)
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
select {
|
||||
case <-c.Done():
|
||||
if got := c.Err(); got != context.Canceled {
|
||||
t.Errorf("c.Err() = %q, want %q", got, context.Canceled)
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Errorf("expected context to be canceled")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotifyContextSimultaneousStop(t *testing.T) {
|
||||
c, stop := NotifyContext(context.Background(), syscall.SIGINT)
|
||||
defer stop()
|
||||
|
|
|
@ -4,10 +4,7 @@
|
|||
|
||||
package os
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
import "errors"
|
||||
|
||||
// fastrand provided by runtime.
|
||||
// We generate random temporary file names so that there's a good
|
||||
|
@ -62,7 +59,7 @@ func prefixAndSuffix(pattern string) (prefix, suffix string, err error) {
|
|||
return "", "", errPatternHasSeparator
|
||||
}
|
||||
}
|
||||
if pos := strings.LastIndex(pattern, "*"); pos != -1 {
|
||||
if pos := lastIndex(pattern, '*'); pos != -1 {
|
||||
prefix, suffix = pattern[:pos], pattern[pos+1:]
|
||||
} else {
|
||||
prefix = pattern
|
||||
|
@ -116,3 +113,13 @@ func joinPath(dir, name string) string {
|
|||
}
|
||||
return dir + string(PathSeparator) + name
|
||||
}
|
||||
|
||||
// LastIndexByte from the strings package.
|
||||
func lastIndex(s string, sep byte) int {
|
||||
for i := len(s) - 1; i >= 0; i-- {
|
||||
if s[i] == sep {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ func extractMetricDocs(t *testing.T) map[string]string {
|
|||
line := strings.TrimSpace(s.Text())
|
||||
switch state {
|
||||
case stateSearch:
|
||||
if line == "Supported metrics" {
|
||||
if line == "Below is the full list of supported metrics, ordered lexicographically." {
|
||||
state = stateNextMetric
|
||||
}
|
||||
case stateNextMetric:
|
||||
|
|
|
@ -42,8 +42,16 @@ did also, and a new key should be introduced.
|
|||
For more details on the precise definition of the metric key's path and unit formats, see
|
||||
the documentation of the Name field of the Description struct.
|
||||
|
||||
A note about floats
|
||||
|
||||
This package supports metrics whose values have a floating-point representation. In
|
||||
order to improve ease-of-use, this package promises to never produce the following
|
||||
classes of floating-point values: NaN, infinity.
|
||||
|
||||
Supported metrics
|
||||
|
||||
Below is the full list of supported metrics, ordered lexicographically.
|
||||
|
||||
/gc/cycles/automatic:gc-cycles
|
||||
Count of completed GC cycles generated by the Go runtime.
|
||||
|
||||
|
|
|
@ -30,6 +30,16 @@ func runtime_readMetrics(unsafe.Pointer, int, int)
|
|||
// The user of this API is encouraged to re-use the same slice between calls for
|
||||
// efficiency, but is not required to do so.
|
||||
//
|
||||
// Note that re-use has some caveats. Notably, Values should not be read or
|
||||
// manipulated while a Read with that value is outstanding; that is a data race.
|
||||
// This property includes pointer-typed Values (e.g. Float64Histogram) whose
|
||||
// underlying storage will be reused by Read when possible. To safely use such
|
||||
// values in a concurrent setting, all data must be deep-copied.
|
||||
//
|
||||
// It is safe to execute multiple Read calls concurrently, but their arguments
|
||||
// must share no underlying memory. When in doubt, create a new []Sample from
|
||||
// scratch, which is always safe, though may be inefficient.
|
||||
//
|
||||
// Sample values with names not appearing in All will have their Value populated
|
||||
// as KindBad to indicate that the name is unknown.
|
||||
func Read(m []Sample) {
|
||||
|
|
|
@ -284,32 +284,31 @@ static inline void startThread(cb* c) {
|
|||
*/
|
||||
import "C"
|
||||
|
||||
import "time"
|
||||
|
||||
var done chan bool
|
||||
var racy int
|
||||
|
||||
//export goCallback
|
||||
func goCallback() {
|
||||
racy++
|
||||
done <- true
|
||||
}
|
||||
|
||||
func main() {
|
||||
done = make(chan bool)
|
||||
var c C.cb
|
||||
C.startThread(&c)
|
||||
time.Sleep(time.Second)
|
||||
racy++
|
||||
<- done
|
||||
}
|
||||
`, `==================
|
||||
WARNING: DATA RACE
|
||||
Read at 0x[0-9,a-f]+ by main goroutine:
|
||||
main\.main\(\)
|
||||
.*/main\.go:34 \+0x[0-9,a-f]+
|
||||
Read at 0x[0-9,a-f]+ by .*:
|
||||
main\..*
|
||||
.*/main\.go:[0-9]+ \+0x[0-9,a-f]+(?s).*
|
||||
|
||||
Previous write at 0x[0-9,a-f]+ by goroutine [0-9]:
|
||||
main\.goCallback\(\)
|
||||
.*/main\.go:27 \+0x[0-9,a-f]+
|
||||
_cgoexp_[0-9a-z]+_goCallback\(\)
|
||||
.*_cgo_gotypes\.go:[0-9]+ \+0x[0-9,a-f]+
|
||||
Previous write at 0x[0-9,a-f]+ by .*:
|
||||
main\..*
|
||||
.*/main\.go:[0-9]+ \+0x[0-9,a-f]+(?s).*
|
||||
|
||||
Goroutine [0-9] \(running\) created at:
|
||||
runtime\.newextram\(\)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue