Файловый менеджер - Редактировать - /var/www/html/staticdata.zip
Ðазад
PK ! 1j~H] ] embed.gonu �[��� // Copyright 2020 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package staticdata import ( "path" "sort" "strings" "cmd/compile/internal/base" "cmd/compile/internal/ir" "cmd/compile/internal/objw" "cmd/compile/internal/types" "cmd/internal/obj" ) const ( embedUnknown = iota embedBytes embedString embedFiles ) func embedFileList(v *ir.Name, kind int) []string { // Build list of files to store. have := make(map[string]bool) var list []string for _, e := range *v.Embed { for _, pattern := range e.Patterns { files, ok := base.Flag.Cfg.Embed.Patterns[pattern] if !ok { base.ErrorfAt(e.Pos, 0, "invalid go:embed: build system did not map pattern: %s", pattern) } for _, file := range files { if base.Flag.Cfg.Embed.Files[file] == "" { base.ErrorfAt(e.Pos, 0, "invalid go:embed: build system did not map file: %s", file) continue } if !have[file] { have[file] = true list = append(list, file) } if kind == embedFiles { for dir := path.Dir(file); dir != "." && !have[dir]; dir = path.Dir(dir) { have[dir] = true list = append(list, dir+"/") } } } } } sort.Slice(list, func(i, j int) bool { return embedFileLess(list[i], list[j]) }) if kind == embedString || kind == embedBytes { if len(list) > 1 { base.ErrorfAt(v.Pos(), 0, "invalid go:embed: multiple files for type %v", v.Type()) return nil } } return list } // embedKind determines the kind of embedding variable. func embedKind(typ *types.Type) int { if typ.Sym() != nil && typ.Sym().Name == "FS" && typ.Sym().Pkg.Path == "embed" { return embedFiles } if typ.Kind() == types.TSTRING { return embedString } if typ.IsSlice() && typ.Elem().Kind() == types.TUINT8 { return embedBytes } return embedUnknown } func embedFileNameSplit(name string) (dir, elem string, isDir bool) { if name[len(name)-1] == '/' { isDir = true name = name[:len(name)-1] } i := len(name) - 1 for i >= 0 && name[i] != '/' { i-- } if i < 0 { return ".", name, isDir } return name[:i], name[i+1:], isDir } // embedFileLess implements the sort order for a list of embedded files. // See the comment inside ../../../../embed/embed.go's Files struct for rationale. func embedFileLess(x, y string) bool { xdir, xelem, _ := embedFileNameSplit(x) ydir, yelem, _ := embedFileNameSplit(y) return xdir < ydir || xdir == ydir && xelem < yelem } // WriteEmbed emits the init data for a //go:embed variable, // which is either a string, a []byte, or an embed.FS. func WriteEmbed(v *ir.Name) { // TODO(mdempsky): User errors should be reported by the frontend. commentPos := (*v.Embed)[0].Pos if base.Flag.Cfg.Embed.Patterns == nil { base.ErrorfAt(commentPos, 0, "invalid go:embed: build system did not supply embed configuration") return } kind := embedKind(v.Type()) if kind == embedUnknown { base.ErrorfAt(v.Pos(), 0, "go:embed cannot apply to var of type %v", v.Type()) return } files := embedFileList(v, kind) switch kind { case embedString, embedBytes: file := files[0] fsym, size, err := fileStringSym(v.Pos(), base.Flag.Cfg.Embed.Files[file], kind == embedString, nil) if err != nil { base.ErrorfAt(v.Pos(), 0, "embed %s: %v", file, err) } sym := v.Linksym() off := 0 off = objw.SymPtr(sym, off, fsym, 0) // data string off = objw.Uintptr(sym, off, uint64(size)) // len if kind == embedBytes { objw.Uintptr(sym, off, uint64(size)) // cap for slice } case embedFiles: slicedata := v.Sym().Pkg.Lookup(v.Sym().Name + `.files`).Linksym() off := 0 // []files pointed at by Files off = objw.SymPtr(slicedata, off, slicedata, 3*types.PtrSize) // []file, pointing just past slice off = objw.Uintptr(slicedata, off, uint64(len(files))) off = objw.Uintptr(slicedata, off, uint64(len(files))) // embed/embed.go type file is: // name string // data string // hash [16]byte // Emit one of these per file in the set. const hashSize = 16 hash := make([]byte, hashSize) for _, file := range files { off = objw.SymPtr(slicedata, off, StringSym(v.Pos(), file), 0) // file string off = objw.Uintptr(slicedata, off, uint64(len(file))) if strings.HasSuffix(file, "/") { // entry for directory - no data off = objw.Uintptr(slicedata, off, 0) off = objw.Uintptr(slicedata, off, 0) off += hashSize } else { fsym, size, err := fileStringSym(v.Pos(), base.Flag.Cfg.Embed.Files[file], true, hash) if err != nil { base.ErrorfAt(v.Pos(), 0, "embed %s: %v", file, err) } off = objw.SymPtr(slicedata, off, fsym, 0) // data string off = objw.Uintptr(slicedata, off, uint64(size)) off = int(slicedata.WriteBytes(base.Ctxt, int64(off), hash)) } } objw.Global(slicedata, int32(off), obj.RODATA|obj.LOCAL) sym := v.Linksym() objw.SymPtr(sym, 0, slicedata, 0) } } PK ! y�) ) data.gonu �[��� // Copyright 2009 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 staticdata import ( "encoding/base64" "fmt" "go/constant" "io" "os" "sort" "strconv" "sync" "cmd/compile/internal/base" "cmd/compile/internal/ir" "cmd/compile/internal/objw" "cmd/compile/internal/types" "cmd/internal/notsha256" "cmd/internal/obj" "cmd/internal/objabi" "cmd/internal/src" ) // InitAddrOffset writes the static name symbol lsym to n, it does not modify n. // It's the caller responsibility to make sure lsym is from ONAME/PEXTERN node. func InitAddrOffset(n *ir.Name, noff int64, lsym *obj.LSym, off int64) { if n.Op() != ir.ONAME { base.Fatalf("InitAddr n op %v", n.Op()) } if n.Sym() == nil { base.Fatalf("InitAddr nil n sym") } s := n.Linksym() s.WriteAddr(base.Ctxt, noff, types.PtrSize, lsym, off) } // InitAddr is InitAddrOffset, with offset fixed to 0. func InitAddr(n *ir.Name, noff int64, lsym *obj.LSym) { InitAddrOffset(n, noff, lsym, 0) } // InitSlice writes a static slice symbol {lsym, lencap, lencap} to n+noff, it does not modify n. // It's the caller responsibility to make sure lsym is from ONAME node. func InitSlice(n *ir.Name, noff int64, lsym *obj.LSym, lencap int64) { s := n.Linksym() s.WriteAddr(base.Ctxt, noff, types.PtrSize, lsym, 0) s.WriteInt(base.Ctxt, noff+types.SliceLenOffset, types.PtrSize, lencap) s.WriteInt(base.Ctxt, noff+types.SliceCapOffset, types.PtrSize, lencap) } func InitSliceBytes(nam *ir.Name, off int64, s string) { if nam.Op() != ir.ONAME { base.Fatalf("InitSliceBytes %v", nam) } InitSlice(nam, off, slicedata(nam.Pos(), s), int64(len(s))) } const ( stringSymPrefix = "go:string." stringSymPattern = ".gostring.%d.%s" ) // shortHashString converts the hash to a string for use with stringSymPattern. // We cut it to 16 bytes and then base64-encode to make it even smaller. func shortHashString(hash []byte) string { return base64.StdEncoding.EncodeToString(hash[:16]) } // StringSym returns a symbol containing the string s. // The symbol contains the string data, not a string header. func StringSym(pos src.XPos, s string) (data *obj.LSym) { var symname string if len(s) > 100 { // Huge strings are hashed to avoid long names in object files. // Indulge in some paranoia by writing the length of s, too, // as protection against length extension attacks. // Same pattern is known to fileStringSym below. h := notsha256.New() io.WriteString(h, s) symname = fmt.Sprintf(stringSymPattern, len(s), shortHashString(h.Sum(nil))) } else { // Small strings get named directly by their contents. symname = strconv.Quote(s) } symdata := base.Ctxt.Lookup(stringSymPrefix + symname) if !symdata.OnList() { off := dstringdata(symdata, 0, s, pos, "string") objw.Global(symdata, int32(off), obj.DUPOK|obj.RODATA|obj.LOCAL) symdata.Set(obj.AttrContentAddressable, true) } return symdata } // StringSymNoCommon is like StringSym, but produces a symbol that is not content- // addressable. This symbol is not supposed to appear in the final binary, it is // only used to pass string arguments to the linker like R_USENAMEDMETHOD does. func StringSymNoCommon(s string) (data *obj.LSym) { var nameSym obj.LSym nameSym.WriteString(base.Ctxt, 0, len(s), s) objw.Global(&nameSym, int32(len(s)), obj.RODATA) return &nameSym } // maxFileSize is the maximum file size permitted by the linker // (see issue #9862). const maxFileSize = int64(2e9) // fileStringSym returns a symbol for the contents and the size of file. // If readonly is true, the symbol shares storage with any literal string // or other file with the same content and is placed in a read-only section. // If readonly is false, the symbol is a read-write copy separate from any other, // for use as the backing store of a []byte. // The content hash of file is copied into hash. (If hash is nil, nothing is copied.) // The returned symbol contains the data itself, not a string header. func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj.LSym, int64, error) { f, err := os.Open(file) if err != nil { return nil, 0, err } defer f.Close() info, err := f.Stat() if err != nil { return nil, 0, err } if !info.Mode().IsRegular() { return nil, 0, fmt.Errorf("not a regular file") } size := info.Size() if size <= 1*1024 { data, err := io.ReadAll(f) if err != nil { return nil, 0, err } if int64(len(data)) != size { return nil, 0, fmt.Errorf("file changed between reads") } var sym *obj.LSym if readonly { sym = StringSym(pos, string(data)) } else { sym = slicedata(pos, string(data)) } if len(hash) > 0 { sum := notsha256.Sum256(data) copy(hash, sum[:]) } return sym, size, nil } if size > maxFileSize { // ggloblsym takes an int32, // and probably the rest of the toolchain // can't handle such big symbols either. // See golang.org/issue/9862. return nil, 0, fmt.Errorf("file too large (%d bytes > %d bytes)", size, maxFileSize) } // File is too big to read and keep in memory. // Compute hash if needed for read-only content hashing or if the caller wants it. var sum []byte if readonly || len(hash) > 0 { h := notsha256.New() n, err := io.Copy(h, f) if err != nil { return nil, 0, err } if n != size { return nil, 0, fmt.Errorf("file changed between reads") } sum = h.Sum(nil) copy(hash, sum) } var symdata *obj.LSym if readonly { symname := fmt.Sprintf(stringSymPattern, size, shortHashString(sum)) symdata = base.Ctxt.Lookup(stringSymPrefix + symname) if !symdata.OnList() { info := symdata.NewFileInfo() info.Name = file info.Size = size objw.Global(symdata, int32(size), obj.DUPOK|obj.RODATA|obj.LOCAL) // Note: AttrContentAddressable cannot be set here, // because the content-addressable-handling code // does not know about file symbols. } } else { // Emit a zero-length data symbol // and then fix up length and content to use file. symdata = slicedata(pos, "") symdata.Size = size symdata.Type = objabi.SNOPTRDATA info := symdata.NewFileInfo() info.Name = file info.Size = size } return symdata, size, nil } var slicedataGen int func slicedata(pos src.XPos, s string) *obj.LSym { slicedataGen++ symname := fmt.Sprintf(".gobytes.%d", slicedataGen) lsym := types.LocalPkg.Lookup(symname).LinksymABI(obj.ABI0) off := dstringdata(lsym, 0, s, pos, "slice") objw.Global(lsym, int32(off), obj.NOPTR|obj.LOCAL) return lsym } func dstringdata(s *obj.LSym, off int, t string, pos src.XPos, what string) int { // Objects that are too large will cause the data section to overflow right away, // causing a cryptic error message by the linker. Check for oversize objects here // and provide a useful error message instead. if int64(len(t)) > 2e9 { base.ErrorfAt(pos, 0, "%v with length %v is too big", what, len(t)) return 0 } s.WriteString(base.Ctxt, int64(off), len(t), t) return off + len(t) } var ( funcsymsmu sync.Mutex // protects funcsyms and associated package lookups (see func funcsym) funcsyms []*ir.Name // functions that need function value symbols ) // FuncLinksym returns n·f, the function value symbol for n. func FuncLinksym(n *ir.Name) *obj.LSym { if n.Op() != ir.ONAME || n.Class != ir.PFUNC { base.Fatalf("expected func name: %v", n) } s := n.Sym() // funcsymsmu here serves to protect not just mutations of funcsyms (below), // but also the package lookup of the func sym name, // since this function gets called concurrently from the backend. // There are no other concurrent package lookups in the backend, // except for the types package, which is protected separately. // Reusing funcsymsmu to also cover this package lookup // avoids a general, broader, expensive package lookup mutex. funcsymsmu.Lock() sf, existed := s.Pkg.LookupOK(ir.FuncSymName(s)) if !existed { funcsyms = append(funcsyms, n) } funcsymsmu.Unlock() return sf.Linksym() } func GlobalLinksym(n *ir.Name) *obj.LSym { if n.Op() != ir.ONAME || n.Class != ir.PEXTERN { base.Fatalf("expected global variable: %v", n) } return n.Linksym() } func WriteFuncSyms() { sort.Slice(funcsyms, func(i, j int) bool { return funcsyms[i].Linksym().Name < funcsyms[j].Linksym().Name }) for _, nam := range funcsyms { s := nam.Sym() sf := s.Pkg.Lookup(ir.FuncSymName(s)).Linksym() // While compiling package runtime, we might try to create // funcsyms for functions from both types.LocalPkg and // ir.Pkgs.Runtime. if base.Flag.CompilingRuntime && sf.OnList() { continue } // Function values must always reference ABIInternal // entry points. target := s.Linksym() if target.ABI() != obj.ABIInternal { base.Fatalf("expected ABIInternal: %v has %v", target, target.ABI()) } objw.SymPtr(sf, 0, target, 0) objw.Global(sf, int32(types.PtrSize), obj.DUPOK|obj.RODATA) } } // InitConst writes the static literal c to n. // Neither n nor c is modified. func InitConst(n *ir.Name, noff int64, c ir.Node, wid int) { if n.Op() != ir.ONAME { base.Fatalf("InitConst n op %v", n.Op()) } if n.Sym() == nil { base.Fatalf("InitConst nil n sym") } if c.Op() == ir.ONIL { return } if c.Op() != ir.OLITERAL { base.Fatalf("InitConst c op %v", c.Op()) } s := n.Linksym() switch u := c.Val(); u.Kind() { case constant.Bool: i := int64(obj.Bool2int(constant.BoolVal(u))) s.WriteInt(base.Ctxt, noff, wid, i) case constant.Int: s.WriteInt(base.Ctxt, noff, wid, ir.IntVal(c.Type(), u)) case constant.Float: f, _ := constant.Float64Val(u) switch c.Type().Kind() { case types.TFLOAT32: s.WriteFloat32(base.Ctxt, noff, float32(f)) case types.TFLOAT64: s.WriteFloat64(base.Ctxt, noff, f) } case constant.Complex: re, _ := constant.Float64Val(constant.Real(u)) im, _ := constant.Float64Val(constant.Imag(u)) switch c.Type().Kind() { case types.TCOMPLEX64: s.WriteFloat32(base.Ctxt, noff, float32(re)) s.WriteFloat32(base.Ctxt, noff+4, float32(im)) case types.TCOMPLEX128: s.WriteFloat64(base.Ctxt, noff, re) s.WriteFloat64(base.Ctxt, noff+8, im) } case constant.String: i := constant.StringVal(u) symdata := StringSym(n.Pos(), i) s.WriteAddr(base.Ctxt, noff, types.PtrSize, symdata, 0) s.WriteInt(base.Ctxt, noff+int64(types.PtrSize), types.PtrSize, int64(len(i))) default: base.Fatalf("InitConst unhandled OLITERAL %v", c) } } PK ! 1j~H] ] embed.gonu �[��� PK ! y�) ) � data.gonu �[��� PK � �<