diff --git a/cli/libpack/main_linux.go b/cli/libpack/main_linux.go new file mode 100644 index 0000000..1834727 --- /dev/null +++ b/cli/libpack/main_linux.go @@ -0,0 +1,281 @@ +package main + +import ( + "archive/tar" + _ "embed" + "encoding/hex" + "io" + "io/fs" + "os" + "os/exec" + "path/filepath" + "sort" + "strings" + + "github.com/klauspost/compress/zstd" + "github.com/sagernet/sing/common" + E "github.com/sagernet/sing/common/exceptions" + "github.com/sirupsen/logrus" + "github.com/u-root/u-root/pkg/ldd" +) + +func main() { + err := run0() + if err != nil { + logrus.Fatal(err) + } +} + +func run0() error { + os.Setenv("LD_LIBRARY_PATH", os.ExpandEnv("$LD_LIBRARY_PATH:/usr/local/lib:$PWD")) + + if len(os.Args) == 1 { + logrus.Fatal("missing executable path") + } + + realPath, err := filepath.Abs(os.Args[1]) + if err != nil { + return E.Cause(err, os.Args[1], " not found") + } + + if len(os.Args) == 2 { + os.Args = append(os.Args, realPath) + } + + realName := filepath.Base(realPath) + + output := os.Args[2] + output, err = filepath.Abs(output) + if err != nil { + return err + } + + cachePath, err := os.MkdirTemp("", "libpack") + if err != nil { + return err + } + defer os.RemoveAll(cachePath) + contentFile, err := os.Create(cachePath + "/content") + if err != nil { + return err + } + + writer, err := zstd.NewWriter(contentFile, zstd.WithEncoderLevel(zstd.SpeedBestCompression)) + if err != nil { + return err + } + + var ldName string + tarWriter := tar.NewWriter(writer) + libs, err := ldd.Ldd([]string{realPath}) + if err != nil { + return err + } + libs = common.Filter(libs, func(it *ldd.FileInfo) bool { + if strings.HasPrefix(it.Name(), "ld-") { + ldName = it.Name() + return false + } + /*if strings.HasPrefix(it.FullName, "/usr/lib") { + logrus.Info("skipped ", it.FullName) + return false + }*/ + return true + }) + if ldName == "" { + for _, lib := range libs { + logrus.Info(lib.FullName) + } + logrus.Fatal("not a dynamically linked executable i thk") + } + sort.Slice(libs, func(i, j int) bool { + lName := filepath.Base(libs[i].FullName) + rName := filepath.Base(libs[j].FullName) + if lName == realName { + return false + } else if rName == realName { + return true + } + return lName > rName + }) + for _, lib := range libs { + libName := filepath.Base(lib.FullName) + var linkName string + if lib.FileInfo.Mode()&fs.ModeSymlink != 0 { + linkName, err = os.Readlink(lib.FullName) + if err != nil { + return err + } + linkName = filepath.Base(libName) + if libName == linkName { + continue + } + logrus.Info(">> ", libName, " => ", linkName) + } else { + logrus.Info(">> ", libName) + } + header, err := tar.FileInfoHeader(lib.FileInfo, linkName) + if err != nil { + return err + } + header.Name = libName + err = tarWriter.WriteHeader(header) + if err != nil { + return err + } + libFile, err := os.Open(lib.FullName) + if err != nil { + return err + } + _, err = io.CopyN(tarWriter, libFile, header.Size) + libFile.Close() + if err != nil { + return err + } + } + err = tarWriter.Close() + if err != nil { + return err + } + err = writer.Close() + if err != nil { + return err + } + err = contentFile.Close() + if err != nil { + return err + } + + hash, err := common.SHA224File(cachePath + "/content") + if err != nil { + return err + } + + err = common.WriteFile(cachePath+"/main.go", []byte(`package main + +import ( + "archive/tar" + "bytes" + _ "embed" + "io" + "log" + "os" + "syscall" + + "github.com/klauspost/compress/zstd" + "github.com/sagernet/sing/common" +) + +//go:embed content +var content []byte + +const ( + execName = "`+realName+`" + hash = "`+hex.EncodeToString(hash)+`" +) + +var ( + basePath = os.TempDir() + "/.sing/" + execName + dirPath = basePath + "/" + hash + execPath = dirPath + "/" + execName +) + +func main() { + log.SetFlags(0) + + err := os.Setenv("LD_LIBRARY_PATH", dirPath) + if err != nil { + log.Fatalln(err) + } + + err = main0() + if err != nil { + log.Fatalln(err) + } +} + +//noinspection GoBoolExpressions +func main0() error { + if !common.FileExists(dirPath + "/" + hash) { + os.RemoveAll(basePath) + } + if common.FileExists(execPath) { + return syscall.Exec(execPath, os.Args, os.Environ()) + } + os.RemoveAll(basePath) + os.MkdirAll(dirPath, 0o755) + reader, err := zstd.NewReader(bytes.NewReader(content)) + if err != nil { + return err + } + tarReader := tar.NewReader(reader) + for { + header, err := tarReader.Next() + if err != nil { + if err == io.EOF { + break + } + return err + } + if header.FileInfo().IsDir() { + os.MkdirAll(dirPath+"/"+header.Name, 0o755) + continue + } + libFile, err := os.OpenFile(dirPath+"/"+header.Name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o755) + if err != nil { + return err + } + _, err = io.CopyN(libFile, tarReader, header.Size) + if err != nil { + return err + } + libFile.Close() + } + reader.Close() + return syscall.Exec(execPath, os.Args, os.Environ()) +}`)) + if err != nil { + return err + } + err = common.WriteFile(cachePath+"/go.mod", []byte(`module output + + go 1.18 + + require ( + github.com/klauspost/compress latest + github.com/sagernet/sing latest + )`)) + if err != nil { + return err + } + err = runAs(cachePath, "go", "mod", "tidy") + if err != nil { + return err + } + err = runAs(cachePath, "go", "build", "-o", output, "-trimpath", "-ldflags", "-s -w -buildid=", ".") + if err != nil { + return err + } + return nil +} + +func runAs(dir string, name string, args ...string) error { + var argc []string + for _, arg := range args { + if strings.Contains(arg, " ") { + argc = append(argc, "\"", arg, "\"") + } else { + argc = append(argc, arg) + } + } + logrus.Info(">> ", name, " ", strings.Join(argc, " ")) + + command := exec.Command(name, args...) + command.Dir = dir + command.Stdout = os.Stdout + command.Stderr = os.Stderr + command.Env = os.Environ() + command.Env = append(command.Env, "CGO_ENABLED=0") + + return command.Run() +} diff --git a/common/hash.go b/common/hash.go new file mode 100644 index 0000000..1a51dd1 --- /dev/null +++ b/common/hash.go @@ -0,0 +1,50 @@ +package common + +import ( + "crypto/sha256" + "crypto/sha512" + "io" + "os" +) + +func SHA224File(path string) ([]byte, error) { + file, err := os.Open(path) + if err != nil { + return nil, err + } + defer file.Close() + hash := sha256.New224() + _, err = io.Copy(hash, file) + if err != nil { + return nil, err + } + return hash.Sum(nil), nil +} + +func SHA256File(path string) ([]byte, error) { + file, err := os.Open(path) + if err != nil { + return nil, err + } + defer file.Close() + hash := sha256.New() + _, err = io.Copy(hash, file) + if err != nil { + return nil, err + } + return hash.Sum(nil), nil +} + +func SHA512File(path string) ([]byte, error) { + file, err := os.Open(path) + if err != nil { + return nil, err + } + defer file.Close() + hash := sha512.New() + _, err = io.Copy(hash, file) + if err != nil { + return nil, err + } + return hash.Sum(nil), nil +} diff --git a/go.mod b/go.mod index 1896a97..1a79c1e 100644 --- a/go.mod +++ b/go.mod @@ -6,19 +6,21 @@ require ( github.com/cloudflare/cloudflare-go v0.38.0 github.com/go-acme/lego/v4 v4.6.0 github.com/go-resty/resty/v2 v2.7.0 + github.com/klauspost/compress v1.15.2 github.com/openacid/low v0.1.21 github.com/oschwald/geoip2-golang v1.7.0 github.com/refraction-networking/utls v1.1.0 github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.4.0 + github.com/u-root/u-root v0.8.1-0.20220504042106-94cc250573fb github.com/ulikunitz/xz v0.5.10 github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e - github.com/v2fly/v2ray-core/v5 v5.0.5 - github.com/vishvananda/netlink v1.1.0 + github.com/v2fly/v2ray-core/v5 v5.0.6 + github.com/vishvananda/netlink v1.2.0-beta golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 - golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba + golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 golang.zx2c4.com/wireguard v0.0.0-20220407013110-ef5c587f782d google.golang.org/protobuf v1.28.0 lukechampine.com/blake3 v1.1.7 @@ -38,10 +40,10 @@ require ( github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect - golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57 // indirect + golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect - golang.org/x/tools v0.1.9 // indirect + golang.org/x/tools v0.1.11-0.20220325154526-54af36eca237 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect ) diff --git a/go.sum b/go.sum index 197ab62..945b12b 100644 --- a/go.sum +++ b/go.sum @@ -232,6 +232,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.15.2 h1:3WH+AG7s2+T8o3nrM/8u2rdqUEcQhmga7smjrT41nAw= +github.com/klauspost/compress v1.15.2/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= @@ -413,6 +415,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.287/go.mod github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.287/go.mod h1:CuOaLxOQr477GhMWAQPYQFUJrsZbW+ZqkAgP2uHDZXg= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/transip/gotransip/v6 v6.6.1/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g= +github.com/u-root/u-root v0.8.1-0.20220504042106-94cc250573fb h1:BtoOyojJgXlr/TOINOWxe+lgywETuKAalKCcPQi2up0= +github.com/u-root/u-root v0.8.1-0.20220504042106-94cc250573fb/go.mod h1:AAjVYNbjuRo6/5HRuoFEECNFjhgmRxXwTEdqLZW4IyQ= github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= @@ -420,15 +424,15 @@ github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF8gHIiADmOVOV5LS43gt3ONnlEl3xkwI= github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU= -github.com/v2fly/v2ray-core/v5 v5.0.5 h1:S9K9F1t9HMzrW3fzVYUu3cAVXArlkrkOnMresObncP0= -github.com/v2fly/v2ray-core/v5 v5.0.5/go.mod h1:Rv8eq9KRQWZt177euFJb7i2MOqrzfokVmuHGhlfo/zw= +github.com/v2fly/v2ray-core/v5 v5.0.6 h1:YTE2Ax2T6BpiDw39iGe9RrvwtID0SbQzEYY/5f3ID/I= +github.com/v2fly/v2ray-core/v5 v5.0.6/go.mod h1:Rv8eq9KRQWZt177euFJb7i2MOqrzfokVmuHGhlfo/zw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/vinyldns/go-vinyldns v0.9.16/go.mod h1:5qIJOdmzAnatKjurI+Tl4uTus7GJKJxb+zitufjHs3Q= -github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vishvananda/netlink v1.2.0-beta h1:CTNzkunO9iTkRaupF540+w47mexyQgNkA/ibnuKc39w= +github.com/vishvananda/netlink v1.2.0-beta/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= +github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg= github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vultr/govultr/v2 v2.7.1/go.mod h1:BvOhVe6/ZpjwcoL6/unkdQshmbS9VGbowI4QT+3DGVU= @@ -498,8 +502,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57 h1:LQmS1nU0twXLA96Kt7U9qtHJEbBk3z6Q0V4UXjZkpr4= -golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -567,7 +571,6 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -589,6 +592,7 @@ golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -604,8 +608,8 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba h1:AyHWHCBVlIYI5rgEM3o+1PLd0sLPcIAoaUckGQMaWtw= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -662,8 +666,8 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.11-0.20220325154526-54af36eca237 h1:mAhaIX1KEgotq+ju3XYdXUHvll7bzJDTgiDzIAKDdPc= +golang.org/x/tools v0.1.11-0.20220325154526-54af36eca237/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= 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-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=