From 3507ff977af7d301199ef8566eae75b6d23fd5bf Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 22 Mar 2023 19:38:09 +0100 Subject: [PATCH 001/114] proc: support multiple functions with the same name (#3297) The compiler produces ABI compatibility wrappers for some functions. We have changed the support for breakpoints to allow a single logical breakpoint to correspond to multiple physical breakpoints, take advantage of that to set breakpoints on both the ABI wrapper and the real function. Fixes #3296 --- pkg/locspec/locations.go | 3 ++- pkg/proc/amd64_arch.go | 4 ++-- pkg/proc/arm64_arch.go | 4 ++-- pkg/proc/bininfo.go | 36 +++++++++++++++++++++-------- pkg/proc/breakpoints.go | 9 ++++++-- pkg/proc/dwarf_expr_test.go | 8 +++---- pkg/proc/eval.go | 8 +++---- pkg/proc/fncall.go | 4 ++-- pkg/proc/i386_arch.go | 4 ++-- pkg/proc/native/proc_linux.go | 5 ++-- pkg/proc/proc_test.go | 38 ++++++++++++++++++++----------- service/test/integration2_test.go | 26 +++++++++++++++++++++ 12 files changed, 105 insertions(+), 44 deletions(-) diff --git a/pkg/locspec/locations.go b/pkg/locspec/locations.go index fd01f4a2ad..c16a5b24d7 100644 --- a/pkg/locspec/locations.go +++ b/pkg/locspec/locations.go @@ -450,7 +450,8 @@ func (loc *NormalLocationSpec) findFuncCandidates(bi *proc.BinaryInfo, limit int } candidateFuncs[fname] = struct{}{} } - for _, f := range bi.LookupFunc { + for _, fns := range bi.LookupFunc() { + f := fns[0] if len(candidateFuncs) >= limit { break } diff --git a/pkg/proc/amd64_arch.go b/pkg/proc/amd64_arch.go index a39e94c91d..1d4ab4b9d1 100644 --- a/pkg/proc/amd64_arch.go +++ b/pkg/proc/amd64_arch.go @@ -49,7 +49,7 @@ func AMD64Arch(goos string) *Arch { func amd64FixFrameUnwindContext(fctxt *frame.FrameContext, pc uint64, bi *BinaryInfo) *frame.FrameContext { a := bi.Arch if a.sigreturnfn == nil { - a.sigreturnfn = bi.LookupFunc["runtime.sigreturn"] + a.sigreturnfn = bi.lookupOneFunc("runtime.sigreturn") } if fctxt == nil || (a.sigreturnfn != nil && pc >= a.sigreturnfn.Entry && pc < a.sigreturnfn.End) { @@ -96,7 +96,7 @@ func amd64FixFrameUnwindContext(fctxt *frame.FrameContext, pc uint64, bi *Binary } if a.crosscall2fn == nil { - a.crosscall2fn = bi.LookupFunc["crosscall2"] + a.crosscall2fn = bi.lookupOneFunc("crosscall2") } if a.crosscall2fn != nil && pc >= a.crosscall2fn.Entry && pc < a.crosscall2fn.End { diff --git a/pkg/proc/arm64_arch.go b/pkg/proc/arm64_arch.go index 01272e6954..46ddd463b5 100644 --- a/pkg/proc/arm64_arch.go +++ b/pkg/proc/arm64_arch.go @@ -60,7 +60,7 @@ func ARM64Arch(goos string) *Arch { func arm64FixFrameUnwindContext(fctxt *frame.FrameContext, pc uint64, bi *BinaryInfo) *frame.FrameContext { a := bi.Arch if a.sigreturnfn == nil { - a.sigreturnfn = bi.LookupFunc["runtime.sigreturn"] + a.sigreturnfn = bi.lookupOneFunc("runtime.sigreturn") } if fctxt == nil || (a.sigreturnfn != nil && pc >= a.sigreturnfn.Entry && pc < a.sigreturnfn.End) { @@ -107,7 +107,7 @@ func arm64FixFrameUnwindContext(fctxt *frame.FrameContext, pc uint64, bi *Binary } if a.crosscall2fn == nil { - a.crosscall2fn = bi.LookupFunc["crosscall2"] + a.crosscall2fn = bi.lookupOneFunc("crosscall2") } if a.crosscall2fn != nil && pc >= a.crosscall2fn.Entry && pc < a.crosscall2fn.End { diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go index 950bdda1f8..5f862a9ef5 100644 --- a/pkg/proc/bininfo.go +++ b/pkg/proc/bininfo.go @@ -60,8 +60,8 @@ type BinaryInfo struct { Functions []Function // Sources is a list of all source files found in debug_line. Sources []string - // LookupFunc maps function names to a description of the function. - LookupFunc map[string]*Function + // lookupFunc maps function names to a description of the function. + lookupFunc map[string][]*Function // lookupGenericFunc maps function names, with their type parameters removed, to functions. // Functions that are not generic are not added to this map. lookupGenericFunc map[string][]*Function @@ -311,8 +311,8 @@ func allInlineCallRanges(tree *godwarf.Tree) []inlRange { // FindFunction returns the functions with name funcName. func (bi *BinaryInfo) FindFunction(funcName string) ([]*Function, error) { - if fn := bi.LookupFunc[funcName]; fn != nil { - return []*Function{fn}, nil + if fns := bi.LookupFunc()[funcName]; fns != nil { + return fns, nil } fns := bi.LookupGenericFunc()[funcName] if len(fns) == 0 { @@ -393,7 +393,7 @@ func FirstPCAfterPrologue(p Process, fn *Function, sameline bool) (uint64, error } func findRetPC(t *Target, name string) ([]uint64, error) { - fn := t.BinInfo().LookupFunc[name] + fn := t.BinInfo().lookupOneFunc(name) if fn == nil { return nil, fmt.Errorf("could not find %s", name) } @@ -2111,11 +2111,8 @@ func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugInfoBytes, debugLineB sort.Sort(functionsDebugInfoByEntry(bi.Functions)) sort.Sort(packageVarsByAddr(bi.packageVars)) - bi.LookupFunc = make(map[string]*Function) + bi.lookupFunc = nil bi.lookupGenericFunc = nil - for i := range bi.Functions { - bi.LookupFunc[bi.Functions[i].Name] = &bi.Functions[i] - } for _, cu := range image.compileUnits { if cu.lineInfo != nil { @@ -2129,7 +2126,7 @@ func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugInfoBytes, debugLineB if bi.regabi { // prepare patch for runtime.mallocgc's DIE - fn := bi.LookupFunc["runtime.mallocgc"] + fn := bi.lookupOneFunc("runtime.mallocgc") if fn != nil && fn.cu.image == image { tree, err := image.getDwarfTree(fn.offset) if err == nil { @@ -2166,6 +2163,25 @@ func (bi *BinaryInfo) LookupGenericFunc() map[string][]*Function { return bi.lookupGenericFunc } +func (bi *BinaryInfo) LookupFunc() map[string][]*Function { + if bi.lookupFunc == nil { + bi.lookupFunc = make(map[string][]*Function) + for i := range bi.Functions { + name := bi.Functions[i].Name + bi.lookupFunc[name] = append(bi.lookupFunc[name], &bi.Functions[i]) + } + } + return bi.lookupFunc +} + +func (bi *BinaryInfo) lookupOneFunc(name string) *Function { + fns := bi.LookupFunc()[name] + if fns == nil { + return nil + } + return fns[0] +} + // loadDebugInfoMapsCompileUnit loads entry from a single compile unit. func (bi *BinaryInfo) loadDebugInfoMapsCompileUnit(ctxt *loadDebugInfoMapsContext, image *Image, reader *reader.Reader, cu *compileUnit) { hasAttrGoPkgName := goversion.ProducerAfterOrEqual(cu.producer, 1, 13) diff --git a/pkg/proc/breakpoints.go b/pkg/proc/breakpoints.go index ce17cccb52..fb35aba28b 100644 --- a/pkg/proc/breakpoints.go +++ b/pkg/proc/breakpoints.go @@ -674,8 +674,13 @@ func (t *Target) setBreakpointInternal(logicalID int, addr uint64, kind Breakpoi if breaklet != nil && breaklet.Cond == nil { breaklet.Cond = lbp.Cond } - lbp.File = bp.File - lbp.Line = bp.Line + if lbp.File == "" && lbp.Line == 0 { + lbp.File = bp.File + lbp.Line = bp.Line + } else if bp.File != lbp.File || bp.Line != lbp.Line { + lbp.File = "" + lbp.Line = 0 + } fn := t.BinInfo().PCToFunc(bp.Addr) if fn != nil { lbp.FunctionName = fn.NameWithoutTypeParams() diff --git a/pkg/proc/dwarf_expr_test.go b/pkg/proc/dwarf_expr_test.go index 89acaaec15..88c9a46eb2 100644 --- a/pkg/proc/dwarf_expr_test.go +++ b/pkg/proc/dwarf_expr_test.go @@ -153,7 +153,7 @@ func TestDwarfExprRegisters(t *testing.T) { bi, _ := fakeBinaryInfo(t, dwb) - mainfn := bi.LookupFunc["main.main"] + mainfn := bi.LookupFunc()["main.main"][0] mem := newFakeMemory(fakeCFA(), uint64(0), uint64(testCases["b"])) regs := linutil.AMD64Registers{Regs: &linutil.AMD64PtraceRegs{}} regs.Regs.Rax = uint64(testCases["a"]) @@ -215,7 +215,7 @@ func TestDwarfExprComposite(t *testing.T) { bi, _ := fakeBinaryInfo(t, dwb) - mainfn := bi.LookupFunc["main.main"] + mainfn := bi.LookupFunc()["main.main"][0] mem := newFakeMemory(fakeCFA(), uint64(0), uint64(0), uint16(testCases["pair.v"]), []byte(stringVal)) var regs linutil.AMD64Registers @@ -289,7 +289,7 @@ func TestDwarfExprLoclist(t *testing.T) { bi, _ := fakeBinaryInfo(t, dwb) - mainfn := bi.LookupFunc["main.main"] + mainfn := bi.LookupFunc()["main.main"][0] mem := newFakeMemory(fakeCFA(), uint16(before), uint16(after)) const PC = 0x40100 @@ -326,7 +326,7 @@ func TestIssue1419(t *testing.T) { bi, _ := fakeBinaryInfo(t, dwb) - mainfn := bi.LookupFunc["main.main"] + mainfn := bi.LookupFunc()["main.main"][0] mem := newFakeMemory(fakeCFA()) diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index 1afa229488..83ff7d3dc9 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -2280,8 +2280,8 @@ func (v *Variable) findMethod(mname string) (*Variable, error) { //TODO(aarzilli): support generic functions? - if fn, ok := v.bi.LookupFunc[fmt.Sprintf("%s.%s.%s", pkg, receiver, mname)]; ok { - r, err := functionToVariable(fn, v.bi, v.mem) + if fns := v.bi.LookupFunc()[fmt.Sprintf("%s.%s.%s", pkg, receiver, mname)]; len(fns) == 1 { + r, err := functionToVariable(fns[0], v.bi, v.mem) if err != nil { return nil, err } @@ -2293,8 +2293,8 @@ func (v *Variable) findMethod(mname string) (*Variable, error) { return r, nil } - if fn, ok := v.bi.LookupFunc[fmt.Sprintf("%s.(*%s).%s", pkg, receiver, mname)]; ok { - r, err := functionToVariable(fn, v.bi, v.mem) + if fns := v.bi.LookupFunc()[fmt.Sprintf("%s.(*%s).%s", pkg, receiver, mname)]; len(fns) == 1 { + r, err := functionToVariable(fns[0], v.bi, v.mem) if err != nil { return nil, err } diff --git a/pkg/proc/fncall.go b/pkg/proc/fncall.go index 5e9b3bc67d..1310043414 100644 --- a/pkg/proc/fncall.go +++ b/pkg/proc/fncall.go @@ -1211,8 +1211,8 @@ func findCallInjectionStateForThread(t *Target, thread Thread) (*G, *callInjecti func debugCallFunction(bi *BinaryInfo) (*Function, int) { for version := maxDebugCallVersion; version >= 1; version-- { name := debugCallFunctionNamePrefix2 + "V" + strconv.Itoa(version) - fn, ok := bi.LookupFunc[name] - if ok && fn != nil { + fn := bi.lookupOneFunc(name) + if fn != nil { return fn, version } } diff --git a/pkg/proc/i386_arch.go b/pkg/proc/i386_arch.go index 50b9d41c77..aaafad0ecf 100644 --- a/pkg/proc/i386_arch.go +++ b/pkg/proc/i386_arch.go @@ -43,7 +43,7 @@ func I386Arch(goos string) *Arch { func i386FixFrameUnwindContext(fctxt *frame.FrameContext, pc uint64, bi *BinaryInfo) *frame.FrameContext { i := bi.Arch if i.sigreturnfn == nil { - i.sigreturnfn = bi.LookupFunc["runtime.sigreturn"] + i.sigreturnfn = bi.lookupOneFunc("runtime.sigreturn") } if fctxt == nil || (i.sigreturnfn != nil && pc >= i.sigreturnfn.Entry && pc < i.sigreturnfn.End) { @@ -90,7 +90,7 @@ func i386FixFrameUnwindContext(fctxt *frame.FrameContext, pc uint64, bi *BinaryI } if i.crosscall2fn == nil { - i.crosscall2fn = bi.LookupFunc["crosscall2"] + i.crosscall2fn = bi.lookupOneFunc("crosscall2") } // TODO(chainhelen), need to check whether there is a bad frame descriptor like amd64. diff --git a/pkg/proc/native/proc_linux.go b/pkg/proc/native/proc_linux.go index 4686ebe6e6..e549928b58 100644 --- a/pkg/proc/native/proc_linux.go +++ b/pkg/proc/native/proc_linux.go @@ -827,10 +827,11 @@ func (dbp *nativeProcess) SetUProbe(fnName string, goidOffset int64, args []ebpf return errors.New("too many arguments in traced function, max is 12 input+return") } - fn, ok := dbp.bi.LookupFunc[fnName] - if !ok { + fns := dbp.bi.LookupFunc()[fnName] + if len(fns) != 1 { return fmt.Errorf("could not find function: %s", fnName) } + fn := fns[0] offset, err := dbp.BinInfo().GStructOffset(dbp.Memory()) if err != nil { diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 61df0f78f3..3c18975eab 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -209,23 +209,35 @@ func TestExitAfterContinue(t *testing.T) { } func setFunctionBreakpoint(p *proc.Target, t testing.TB, fname string) *proc.Breakpoint { - _, f, l, _ := runtime.Caller(1) - f = filepath.Base(f) - + t.Helper() addrs, err := proc.FindFunctionLocation(p, fname, 0) if err != nil { - t.Fatalf("%s:%d: FindFunctionLocation(%s): %v", f, l, fname, err) + t.Fatalf("FindFunctionLocation(%s): %v", fname, err) } if len(addrs) != 1 { - t.Fatalf("%s:%d: setFunctionBreakpoint(%s): too many results %v", f, l, fname, addrs) + t.Fatalf("setFunctionBreakpoint(%s): too many results %v", fname, addrs) } bp, err := p.SetBreakpoint(int(addrs[0]), addrs[0], proc.UserBreakpoint, nil) if err != nil { - t.Fatalf("%s:%d: FindFunctionLocation(%s): %v", f, l, fname, err) + t.Fatalf("FindFunctionLocation(%s): %v", fname, err) } return bp } +func setFunctionBreakpointAll(p *proc.Target, t testing.TB, fname string) { + t.Helper() + addrs, err := proc.FindFunctionLocation(p, fname, 0) + if err != nil { + t.Fatalf("FindFunctionLocation(%s): %v", fname, err) + } + for _, addr := range addrs { + _, err := p.SetBreakpoint(int(addr), addr, proc.UserBreakpoint, nil) + if err != nil { + t.Fatalf("FindFunctionLocation(%s): %v", fname, err) + } + } +} + func setFileBreakpoint(p *proc.Target, t testing.TB, path string, lineno int) *proc.Breakpoint { _, f, l, _ := runtime.Caller(1) f = filepath.Base(f) @@ -1927,7 +1939,7 @@ func TestIssue332_Part2(t *testing.T) { assertNoError(err, t, "Registers()") pc := regs.PC() pcAfterPrologue := findFunctionLocation(p, t, "main.changeMe") - if pcAfterPrologue == p.BinInfo().LookupFunc["main.changeMe"].Entry { + if pcAfterPrologue == p.BinInfo().LookupFunc()["main.changeMe"][0].Entry { t.Fatalf("main.changeMe and main.changeMe:0 are the same (%x)", pcAfterPrologue) } if pc != pcAfterPrologue { @@ -2252,7 +2264,7 @@ func TestIssue573(t *testing.T) { func TestTestvariables2Prologue(t *testing.T) { withTestProcess("testvariables2", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { - addrEntry := p.BinInfo().LookupFunc["main.main"].Entry + addrEntry := p.BinInfo().LookupFunc()["main.main"][0].Entry addrPrologue := findFunctionLocation(p, t, "main.main") if addrEntry == addrPrologue { t.Fatalf("Prologue detection failed on testvariables2.go/main.main") @@ -3483,7 +3495,7 @@ func TestSystemstackOnRuntimeNewstack(t *testing.T) { assertNoError(err, t, "GetG") mainGoroutineID := g.ID - setFunctionBreakpoint(p, t, "runtime.newstack") + setFunctionBreakpointAll(p, t, "runtime.newstack") for { assertNoError(grp.Continue(), t, "second continue") g, err = proc.GetG(p.CurrentThread()) @@ -3710,7 +3722,7 @@ func TestDisassembleGlobalVars(t *testing.T) { t.Skip("On 386 linux when pie, symLookup can't look up global variables") } withTestProcess("teststepconcurrent", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { - mainfn := p.BinInfo().LookupFunc["main.main"] + mainfn := p.BinInfo().LookupFunc()["main.main"][0] regs, _ := p.CurrentThread().Registers() text, err := proc.Disassemble(p.Memory(), regs, p.Breakpoints(), p.BinInfo(), mainfn.Entry, mainfn.End) assertNoError(err, t, "Disassemble") @@ -4140,7 +4152,7 @@ func TestStepOutReturn(t *testing.T) { func TestOptimizationCheck(t *testing.T) { withTestProcess("continuetestprog", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { - fn := p.BinInfo().LookupFunc["main.main"] + fn := p.BinInfo().LookupFunc()["main.main"][0] if fn.Optimized() { t.Fatalf("main.main is optimized") } @@ -4148,7 +4160,7 @@ func TestOptimizationCheck(t *testing.T) { if goversion.VersionAfterOrEqual(runtime.Version(), 1, 10) { withTestProcessArgs("continuetestprog", t, ".", []string{}, protest.EnableOptimization|protest.EnableInlining, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { - fn := p.BinInfo().LookupFunc["main.main"] + fn := p.BinInfo().LookupFunc()["main.main"][0] if !fn.Optimized() { t.Fatalf("main.main is not optimized") } @@ -5818,7 +5830,7 @@ func TestCallInjectionFlagCorruption(t *testing.T) { protest.MustSupportFunctionCalls(t, testBackend) withTestProcessArgs("badflags", t, ".", []string{"0"}, 0, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { - mainfn := p.BinInfo().LookupFunc["main.main"] + mainfn := p.BinInfo().LookupFunc()["main.main"][0] // Find JNZ instruction on line :14 var addr uint64 diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go index 068ff1050e..4ea1dd1dfd 100644 --- a/service/test/integration2_test.go +++ b/service/test/integration2_test.go @@ -2991,3 +2991,29 @@ func TestClientServer_autoBreakpoints(t *testing.T) { } }) } + +func TestClientServer_breakpointOnFuncWithABIWrapper(t *testing.T) { + // Setting a breakpoint on an assembly function that has an ABI + // compatibility wrapper should end up setting a breakpoint on the real + // function (also setting a breakpoint on the wrapper is fine). + // Issue #3296 + protest.AllowRecording(t) + withTestClient2("math", t, func(c service.Client) { + bp, err := c.CreateBreakpoint(&api.Breakpoint{FunctionName: "runtime.schedinit"}) + assertNoError(err, t, "CreateBreakpoin()") + t.Log(bp) + + found := false + for _, pc := range bp.Addrs { + text, err := c.DisassemblePC(api.EvalScope{}, pc, api.IntelFlavour) + assertNoError(err, t, fmt.Sprint("DisassemblePC", pc)) + t.Log("First instruction for", pc, text[0]) + if strings.HasSuffix(text[0].Loc.File, "runtime/proc.go") { + found = true + } + } + if !found { + t.Error("breakpoint not set on the runtime/proc.go function") + } + }) +} From be88f980cdaf5b89f194aabfdd89cd7942aee880 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 27 Mar 2023 20:21:01 +0200 Subject: [PATCH 002/114] proc: fix escapeCheck infinite recursion if something can not be (#3311) deref'd Fix infinite recursion if escapeCheck, at some point during its recursion, creates an unreadable variable. The deeper reason for this is that we evaluate function calls in a very weird order so that we can always have stack space to store intermediate evaluation results. The variable 'value' happens to be stored in a register when we try to make the call and because of our weird evaluation strategy registers are no longer available to us when we evaluate 'value'. This is not a complete fix for the issue, the real fix would be to evaluate everything in its natural order, storing intermediate values in Delve's memory instead of the target's stack. To do this we need a mechanism to pin heap allocated objects, which at the moment does not exist. Updates #3310 --- _fixtures/reflecttypefncall.go | 16 ++++++++++++++++ pkg/proc/fncall.go | 3 +++ pkg/proc/proc_test.go | 10 ++++++++++ 3 files changed, 29 insertions(+) create mode 100644 _fixtures/reflecttypefncall.go diff --git a/_fixtures/reflecttypefncall.go b/_fixtures/reflecttypefncall.go new file mode 100644 index 0000000000..5fc5d30b6b --- /dev/null +++ b/_fixtures/reflecttypefncall.go @@ -0,0 +1,16 @@ +package main + +import ( + "fmt" + "reflect" +) + +func reflectFunc(value reflect.Value) { + fmt.Printf("%s\n", value.Type().Name()) +} + +func main() { + i := 2 + val := reflect.ValueOf(i) + reflectFunc(val) +} diff --git a/pkg/proc/fncall.go b/pkg/proc/fncall.go index 1310043414..f5dd79a952 100644 --- a/pkg/proc/fncall.go +++ b/pkg/proc/fncall.go @@ -760,6 +760,9 @@ func alignAddr(addr, align int64) int64 { } func escapeCheck(v *Variable, name string, stack stack) error { + if v.Unreadable != nil { + return fmt.Errorf("escape check for %s failed, variable unreadable: %v", name, v.Unreadable) + } switch v.Kind { case reflect.Ptr: var w *Variable diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 3c18975eab..4fdf77adec 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -6043,3 +6043,13 @@ func TestFollowExec(t *testing.T) { } }) } + +func TestEscapeCheckUnreadable(t *testing.T) { + // A failure in escapeCheck to dereference a field should not cause + // infinite recursion. See issue #3310. + withTestProcessArgs("reflecttypefncall", t, ".", []string{}, protest.AllNonOptimized, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { + setFileBreakpoint(p, t, fixture.Source, 9) + assertNoError(grp.Continue(), t, "Continue") + proc.EvalExpressionWithCalls(grp, p.SelectedGoroutine(), "value.Type()", normalLoadConfig, true) + }) +} From efb119d969db6bc29d1c9eb7e9aa5a30f2ee0d52 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Wed, 29 Mar 2023 19:40:58 +0300 Subject: [PATCH 003/114] terminal: Fix printing boolean values in Starlark scripts (#3314) --- pkg/terminal/starbind/conv.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/terminal/starbind/conv.go b/pkg/terminal/starbind/conv.go index 49b29b313a..595409a950 100644 --- a/pkg/terminal/starbind/conv.go +++ b/pkg/terminal/starbind/conv.go @@ -19,6 +19,8 @@ var autoLoadConfig = api.LoadConfig{MaxVariableRecurse: 1, MaxStringLen: 1024, M // decoding JSON) into a starlark.Value. func (env *Env) interfaceToStarlarkValue(v interface{}) starlark.Value { switch v := v.(type) { + case bool: + return starlark.Bool(bool(v)) case uint8: return starlark.MakeUint64(uint64(v)) case uint16: @@ -231,6 +233,9 @@ func (env *Env) variableValueToStarlarkValue(v *api.Variable, top bool) (starlar case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr: n, _ := strconv.ParseUint(v.Value, 0, 64) return starlark.MakeUint64(n), nil + case reflect.Bool: + n, _ := strconv.ParseBool(v.Value) + return starlark.Bool(n), nil case reflect.Float32, reflect.Float64: switch v.Value { case "+Inf": From 4c40e8141d36bbd27a6b21ac850df9b3c6e3c805 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Thu, 30 Mar 2023 17:54:04 +0200 Subject: [PATCH 004/114] proc: fix TestEvalExpression on Windows (#3313) On Windows the TZ environment variable does not affect the timezone of time.Time variables created using time.Unix. Find another way to make the test pass on our windows/arm64 builder (which is not set to the UTC timezone). --- _fixtures/testvariables2.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_fixtures/testvariables2.go b/_fixtures/testvariables2.go index ce9a7c1975..e4c314dd0c 100644 --- a/_fixtures/testvariables2.go +++ b/_fixtures/testvariables2.go @@ -4,8 +4,8 @@ import ( "fmt" "go/constant" "math" - "reflect" "os" + "reflect" "runtime" "time" "unsafe" @@ -367,7 +367,7 @@ func main() { w5.W5 = w5 os.Setenv("TZ", "UTC") - tim1 := time.Unix(233431200, 0) + tim1 := time.Unix(233431200, 0).UTC() loc, _ := time.LoadLocation("Mexico/BajaSur") tim2, _ := time.ParseInLocation("2006-01-02 15:04:05", "2022-06-07 02:03:04", loc) typedstringvar := String("blah") From d8ff5d1e43144605cf766f6a79ec5cd3371e07cb Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Tue, 4 Apr 2023 12:41:20 -0700 Subject: [PATCH 005/114] v1.20.2 --- CHANGELOG.md | 33 +++++++++++++++++++++++++++++++++ pkg/version/version.go | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76f5daeeaf..6ce138358f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,39 @@ All notable changes to this project will be documented in this file. This project adheres to Semantic Versioning. +## [1.20.2] 2023-04-05 + +### Added + +- New flag --rr-onprocess-pid to replay command (#3281, @jcpowermac) +- Added documentation for watching arbitrary address (#3268, @felixge) +- Allow extracting a DWARF entry field (#3258, @brancz) +- Add SetLoggerFactory to terminal/logflags package (#3257, @blaubaer) +- New config option for tab printing when printing source code (#3243, @thockin) +- Added documentation for debugging Go runtime with Delve (#3234, @aarzilli) + +### Fixed + +- Fix printing boolean values in Starlark scripts (#3314, @vitalif) +- Fix infinite recursion in escapeCheck (#3311, @aarzilli) +- Support multiple functions with same name (#3297, @aarzilli) +- Handle end_seq in dwarf/line correctly (#3277, @derekparker) +- Fix calls into SYS_PROCESS_VM_READV/WRITEV syscalls (#3273, @aarzilli) +- Fix exit status for trace subcommand (#3263, @derekparker) +- Fix stripping DYLD_INSERT_LIBRARIES on macOS (#3245, @aviramha) +- Fix handling of list colors via config (#3240, @derekparker) +- Fixes to FreeBSD backend (#3224, @aarzilli) + +### Changed + +- Add limit to maximum time.Time we try and format (#3294, @aarzilli) +- Add fuzzing tests to expression evaluator and variable loader (#3293, @aarzilli) +- Removed some support for Go 1.12 and earlier (#3271, @aarzilli) +- Moved util functions to dwarf package (#3252, @alexandear) +- Attempt to load DW_AT_specification if present (#3247, @brancz) +- Match go test behavior when dlv test gets list of go files (#3232, @aarzilli) +- Populate Value field in pointer Variable (#3229, @andreimatei) + ## [1.20.1] 2022-12-12 ### Fixed diff --git a/pkg/version/version.go b/pkg/version/version.go index 96e65b6c61..e0c278ad8e 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -17,7 +17,7 @@ type Version struct { var ( // DelveVersion is the current version of Delve. DelveVersion = Version{ - Major: "1", Minor: "20", Patch: "1", Metadata: "", + Major: "1", Minor: "20", Patch: "2", Metadata: "", Build: "$Id$", } ) From 74a69810fc05052e059c7f356035424c9ba18eb2 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Thu, 6 Apr 2023 11:37:45 +0300 Subject: [PATCH 006/114] proc: fix test by adding missing assert --- pkg/proc/proc_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 4fdf77adec..91c85fd9fd 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -1360,6 +1360,7 @@ func TestFrameEvaluation(t *testing.T) { assertNoError(err, t, "GetG()") frames, err := g.Stacktrace(40, 0) + assertNoError(err, t, "Stacktrace()") t.Logf("Goroutine %d %#v", g.ID, g.Thread) logStacktrace(t, p, frames) From 6605d467589d64084bf99f5cb72799d5281cf824 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Fri, 7 Apr 2023 08:30:11 +0300 Subject: [PATCH 007/114] proc: fix match condition in TestGnuDebuglink --- pkg/proc/proc_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 91c85fd9fd..274bc02061 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -5917,7 +5917,7 @@ func TestGnuDebuglink(t *testing.T) { for i := range normalBinInfo.Functions { normalFn := normalBinInfo.Functions[i] debuglinkFn := debuglinkBinInfo.Functions[i] - if normalFn.Entry != debuglinkFn.Entry || normalFn.Name != normalFn.Name { + if normalFn.Entry != debuglinkFn.Entry || normalFn.Name != debuglinkFn.Name { t.Fatalf("function definition mismatch") } } From 6d88b525094d766e899e93ea44bf707767ab5705 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 24 Apr 2023 21:10:50 +0200 Subject: [PATCH 008/114] proc: disable flaky tests on windows/arm64 (#3328) Disable some tests on windows/arm64 that are flaky. --- Documentation/backend_test_health.md | 3 ++- pkg/proc/proc_test.go | 3 +++ service/dap/server_test.go | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Documentation/backend_test_health.md b/Documentation/backend_test_health.md index 4f16ef93bb..d8b08ee5ce 100644 --- a/Documentation/backend_test_health.md +++ b/Documentation/backend_test_health.md @@ -21,6 +21,7 @@ Tests skipped by each supported backend: * 1 broken * 3 see https://github.com/go-delve/delve/issues/2768 * 1 upstream issue -* windows/arm64 skipped = 2 +* windows/arm64 skipped = 5 + * 3 broken * 1 broken - cgo stacktraces * 1 broken - step concurrent diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 274bc02061..d6a88bfae1 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -597,6 +597,7 @@ func TestNextGeneral(t *testing.T) { } func TestNextConcurrent(t *testing.T) { + skipOn(t, "broken", "windows", "arm64") testcases := []nextTest{ {8, 9}, {9, 10}, @@ -632,6 +633,7 @@ func TestNextConcurrent(t *testing.T) { } func TestNextConcurrentVariant2(t *testing.T) { + skipOn(t, "broken", "windows", "arm64") // Just like TestNextConcurrent but instead of removing the initial breakpoint we check that when it happens is for other goroutines testcases := []nextTest{ {8, 9}, @@ -1513,6 +1515,7 @@ func TestBreakpointCounts(t *testing.T) { } func TestHardcodedBreakpointCounts(t *testing.T) { + skipOn(t, "broken", "windows", "arm64") withTestProcess("hcbpcountstest", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { counts := map[int64]int{} for { diff --git a/service/dap/server_test.go b/service/dap/server_test.go index 8b775487c4..cdd4fdc7e3 100644 --- a/service/dap/server_test.go +++ b/service/dap/server_test.go @@ -3432,6 +3432,9 @@ func TestHaltPreventsAutoResume(t *testing.T) { // goroutine is hit the correct number of times and log points set in the // children goroutines produce the correct number of output events. func TestConcurrentBreakpointsLogPoints(t *testing.T) { + if runtime.GOOS == "windows" && runtime.GOARCH == "arm64" { + t.Skip("broken") + } tests := []struct { name string fixture string From 70b80623d1eb34f26b8cf214414b78fbe329b8ab Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 24 Apr 2023 21:11:50 +0200 Subject: [PATCH 009/114] service/dap: fix failing test on Go 1.21 (#3312) --- service/dap/server_test.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/service/dap/server_test.go b/service/dap/server_test.go index cdd4fdc7e3..09e5bd9be4 100644 --- a/service/dap/server_test.go +++ b/service/dap/server_test.go @@ -1920,15 +1920,7 @@ func TestScopesRequestsOptimized(t *testing.T) { client.StackTraceRequest(1, 0, 20) stack := client.ExpectStackTraceResponse(t) - startLineno := 66 - if runtime.GOOS == "windows" && goversion.VersionAfterOrEqual(runtime.Version(), 1, 15) { - // Go1.15 on windows inserts a NOP after the call to - // runtime.Breakpoint and marks it same line as the - // runtime.Breakpoint call, making this flaky, so skip the line check. - startLineno = -1 - } - - checkStackFramesExact(t, stack, "main.foobar", startLineno, 1000, 4, 4) + checkStackFramesExact(t, stack, "main.foobar", -1, 1000, 4, 4) client.ScopesRequest(1000) scopes := client.ExpectScopesResponse(t) From 36980dcbf98c6ab60329c29d430f8a9e731ca180 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 24 Apr 2023 21:12:54 +0200 Subject: [PATCH 010/114] proc: step breakpoints shouldn't hide normal breakpoints (#3287) When using Step on a function that has a dynamic CALL instruction we set a Step breakpoint on the call. When it is hit we determine the destination of the CALL by looking at registers, set a breakpoint there and continue. If the Step breakpoint is hit simultaneously with a normal breakpoint our Step logic will take precedence and the normal breakpoint hit will be hidden from the user. Move the Step logic to a breaklet callback so that it does not interfere with the decision to stop. --- _fixtures/stepshadow.go | 31 +++++++++++++++++++++ pkg/proc/breakpoints.go | 24 +++++++++++------ pkg/proc/proc_test.go | 60 +++++++++++++++++++++++++++++++++++++++++ pkg/proc/stackwatch.go | 8 +++--- pkg/proc/target.go | 4 +-- pkg/proc/target_exec.go | 52 +++++++++++++++++++++++------------ 6 files changed, 148 insertions(+), 31 deletions(-) create mode 100644 _fixtures/stepshadow.go diff --git a/_fixtures/stepshadow.go b/_fixtures/stepshadow.go new file mode 100644 index 0000000000..1356769831 --- /dev/null +++ b/_fixtures/stepshadow.go @@ -0,0 +1,31 @@ +package main + +import ( + "fmt" + "sync" +) + +func main() { + var wg sync.WaitGroup + wg.Add(1) + go goroutineA(&wg) + f := stacktraceme1 + for i := 0; i < 100; i++ { + fmt.Printf("main %d\n", i) + f() + } + wg.Wait() +} + +func goroutineA(wg *sync.WaitGroup) { + defer wg.Done() + for i := 0; i < 100; i++ { + stacktraceme2() + } +} + +func stacktraceme1() { +} + +func stacktraceme2() { +} diff --git a/pkg/proc/breakpoints.go b/pkg/proc/breakpoints.go index fb35aba28b..2e7cdf725c 100644 --- a/pkg/proc/breakpoints.go +++ b/pkg/proc/breakpoints.go @@ -96,7 +96,7 @@ type Breaklet struct { // the return value will determine if the breaklet should be considered // active. // The callback can have side-effects. - callback func(th Thread) bool + callback func(th Thread, p *Target) (bool, error) // For WatchOutOfScopeBreakpoints and StackResizeBreakpoints the watchpoint // field contains the watchpoint related to this out of scope sentinel. @@ -294,12 +294,6 @@ func (bpstate *BreakpointState) checkCond(tgt *Target, breaklet *Breaklet, threa } } active = active && nextDeferOk - if active { - bpstate.Stepping = true - if breaklet.Kind == StepBreakpoint { - bpstate.SteppingInto = true - } - } case WatchOutOfScopeBreakpoint: if breaklet.checkPanicCall { @@ -319,10 +313,24 @@ func (bpstate *BreakpointState) checkCond(tgt *Target, breaklet *Breaklet, threa if active { if breaklet.callback != nil { - active = breaklet.callback(thread) + var err error + active, err = breaklet.callback(thread, tgt) + if err != nil && bpstate.CondError == nil { + bpstate.CondError = err + } } bpstate.Active = active } + + if bpstate.Active { + switch breaklet.Kind { + case NextBreakpoint, NextDeferBreakpoint: + bpstate.Stepping = true + case StepBreakpoint: + bpstate.Stepping = true + bpstate.SteppingInto = true + } + } } // checkHitCond evaluates bp's hit condition on thread. diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index d6a88bfae1..34dec276ae 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -6057,3 +6057,63 @@ func TestEscapeCheckUnreadable(t *testing.T) { proc.EvalExpressionWithCalls(grp, p.SelectedGoroutine(), "value.Type()", normalLoadConfig, true) }) } + +func TestStepShadowConcurrentBreakpoint(t *testing.T) { + // Checks that a StepBreakpoint can not shadow a concurrently hit user breakpoint + withTestProcess("stepshadow", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { + break2 := setFunctionBreakpoint(p, t, "main.stacktraceme2") + breakMain := setFileBreakpoint(p, t, fixture.Source, 15) + assertNoError(grp.Continue(), t, "Continue()") + + stacktraceme1calls, stacktraceme2calls := 0, 0 + + for { + t.Logf("stop (%d %d):", stacktraceme1calls, stacktraceme2calls) + for _, th := range p.ThreadList() { + loc, _ := th.Location() + t.Logf("\t%s:%d\n", loc.File, loc.Line) + bp := th.Breakpoint().Breakpoint + if bp != nil && bp.Addr == break2.Addr { + stacktraceme2calls++ + } + // make stop on the breakpoint in main.main the selected goroutine so we can use step later + if bp != nil && bp.Addr == breakMain.Addr { + g, _ := proc.GetG(th) + p.SwitchGoroutine(g) + } + } + + file, lineno := currentLineNumber(p, t) + + var err error + var reason string + switch lineno { + default: + t.Fatalf("unexpected stop location %s:%d", file, lineno) + case 15: // loop in main.main + reason = "Step()" + err = grp.Step() + case 28: // main.stacktraceme1 + stacktraceme1calls++ + reason = "Continue()" + err = grp.Continue() + case 30, 31: // main.stacktraceme2 + reason = "Continue()" + err = grp.Continue() + } + if _, isexited := err.(proc.ErrProcessExited); isexited { + break + } + assertNoError(err, t, reason) + } + + t.Logf("%d %d\n", stacktraceme1calls, stacktraceme2calls) + + if stacktraceme1calls != 100 { + t.Errorf("wrong number of calls to stacktraceme1 found: %d", stacktraceme1calls) + } + if stacktraceme2calls != 100 { + t.Errorf("wrong number of calls to stacktraceme2 found: %d", stacktraceme2calls) + } + }) +} diff --git a/pkg/proc/stackwatch.go b/pkg/proc/stackwatch.go index a092bd674d..0e87427299 100644 --- a/pkg/proc/stackwatch.go +++ b/pkg/proc/stackwatch.go @@ -28,9 +28,9 @@ import ( func (t *Target) setStackWatchBreakpoints(scope *EvalScope, watchpoint *Breakpoint) error { // Watchpoint Out-of-scope Sentinel - woos := func(_ Thread) bool { + woos := func(_ Thread, _ *Target) (bool, error) { watchpointOutOfScope(t, watchpoint) - return true + return true, nil } topframe, retframe, err := topframe(scope.g, nil) @@ -111,9 +111,9 @@ func (t *Target) setStackWatchBreakpoints(scope *EvalScope, watchpoint *Breakpoi rszbreaklet := rszbp.Breaklets[len(rszbp.Breaklets)-1] rszbreaklet.watchpoint = watchpoint - rszbreaklet.callback = func(th Thread) bool { + rszbreaklet.callback = func(th Thread, _ *Target) (bool, error) { adjustStackWatchpoint(t, th, watchpoint) - return false // we never want this breakpoint to be shown to the user + return false, nil // we never want this breakpoint to be shown to the user } return nil diff --git a/pkg/proc/target.go b/pkg/proc/target.go index e1fafda0cd..05bae74f97 100644 --- a/pkg/proc/target.go +++ b/pkg/proc/target.go @@ -587,7 +587,7 @@ func (t *Target) dwrapUnwrap(fn *Function) *Function { return fn } -func (t *Target) pluginOpenCallback(Thread) bool { +func (t *Target) pluginOpenCallback(Thread, *Target) (bool, error) { logger := logflags.DebuggerLogger() for _, lbp := range t.Breakpoints().Logical { if isSuspended(t, lbp) { @@ -599,7 +599,7 @@ func (t *Target) pluginOpenCallback(Thread) bool { } } } - return false + return false, nil } func isSuspended(t *Target, lbp *LogicalBreakpoint) bool { diff --git a/pkg/proc/target_exec.go b/pkg/proc/target_exec.go index 6f45d588dd..ed9da60e00 100644 --- a/pkg/proc/target_exec.go +++ b/pkg/proc/target_exec.go @@ -173,22 +173,7 @@ func (grp *TargetGroup) Continue() error { if err := conditionErrors(grp); err != nil { return err } - if grp.GetDirection() == Forward { - text, err := disassembleCurrentInstruction(dbp, curthread, 0) - if err != nil { - return err - } - var fn *Function - if loc, _ := curthread.Location(); loc != nil { - fn = loc.Fn - } - // here we either set a breakpoint into the destination of the CALL - // instruction or we determined that the called function is hidden, - // either way we need to resume execution - if err = setStepIntoBreakpoint(dbp, fn, text, sameGoroutineCondition(dbp.SelectedGoroutine())); err != nil { - return err - } - } else { + if grp.GetDirection() == Backward { if err := dbp.ClearSteppingBreakpoints(); err != nil { return err } @@ -797,14 +782,47 @@ func setStepIntoBreakpoints(dbp *Target, curfn *Function, text []AsmInstruction, } } else { // Non-absolute call instruction, set a StepBreakpoint here - if _, err := allowDuplicateBreakpoint(dbp.SetBreakpoint(0, instr.Loc.PC, StepBreakpoint, sameGCond)); err != nil { + bp, err := allowDuplicateBreakpoint(dbp.SetBreakpoint(0, instr.Loc.PC, StepBreakpoint, sameGCond)) + if err != nil { return err } + breaklet := bp.Breaklets[len(bp.Breaklets)-1] + breaklet.callback = stepIntoCallback } } return nil } +// stepIntoCallback is a callback called when a StepBreakpoint is hit, it +// disassembles the current instruction to figure out its destination and +// sets a breakpoint on it. +func stepIntoCallback(curthread Thread, p *Target) (bool, error) { + if p.recman.GetDirection() != Forward { + // This should never happen, step into breakpoints with callbacks are only + // set when moving forward and direction changes are forbidden while + // breakpoints are set. + return true, nil + } + + text, err := disassembleCurrentInstruction(p, curthread, 0) + if err != nil { + return false, err + } + var fn *Function + if loc, _ := curthread.Location(); loc != nil { + fn = loc.Fn + } + g, _ := GetG(curthread) + // here we either set a breakpoint into the destination of the CALL + // instruction or we determined that the called function is hidden, + // either way we need to resume execution + if err = setStepIntoBreakpoint(p, fn, text, sameGoroutineCondition(g)); err != nil { + return false, err + } + + return false, nil +} + func setStepIntoBreakpointsReverse(dbp *Target, text []AsmInstruction, topframe Stackframe, sameGCond ast.Expr) error { bpmap := dbp.Breakpoints() // Set a breakpoint after every CALL instruction From 64d5ce26d691bf609d7e4cbe0e172d22f8aec999 Mon Sep 17 00:00:00 2001 From: Hengqi Chen Date: Tue, 25 Apr 2023 04:37:58 +0800 Subject: [PATCH 011/114] proc: Simplify eBPF backend implementation (#3325) * Remove standard C headers since we have vmlinux.h already * Simplify get_goroutine_id() implementation, this reduces a map and thus reduces runtime memory comsumption. While at it, unify all indention using 4 spaces. Signed-off-by: Hengqi Chen --- .../ebpf/bpf/include/function_vals.bpf.h | 62 +++--- .../internal/ebpf/bpf/include/trace.bpf.h | 10 +- pkg/proc/internal/ebpf/bpf/trace.bpf.c | 183 ++++++++---------- .../internal/ebpf/testhelper/testhelper.go | 1 + pkg/proc/internal/ebpf/trace_bpfel_x86.go | 3 - pkg/proc/internal/ebpf/trace_bpfel_x86.o | Bin 911488 -> 910336 bytes 6 files changed, 115 insertions(+), 144 deletions(-) diff --git a/pkg/proc/internal/ebpf/bpf/include/function_vals.bpf.h b/pkg/proc/internal/ebpf/bpf/include/function_vals.bpf.h index f26c78c876..6b0b8c8275 100644 --- a/pkg/proc/internal/ebpf/bpf/include/function_vals.bpf.h +++ b/pkg/proc/internal/ebpf/bpf/include/function_vals.bpf.h @@ -1,43 +1,41 @@ -#include - // function_parameter stores information about a single parameter to a function. typedef struct function_parameter { - // Type of the parameter as defined by the reflect.Kind enum. - unsigned int kind; - // Size of the variable in bytes. - unsigned int size; - - // Offset from stack pointer. This should only be set from the Go side. - int offset; - - // If true, the parameter is passed in a register. - bool in_reg; - // The number of register pieces the parameter is passed in. - int n_pieces; - // If in_reg is true, this represents the registers that the parameter is passed in. - // This is an array because the number of registers may vary and the parameter may be - // passed in multiple registers. - int reg_nums[6]; - - // The following are filled in by the eBPF program. - size_t daddr; // Data address. - char val[0x30]; // Value of the parameter. - char deref_val[0x30]; // Dereference value of the parameter. + // Type of the parameter as defined by the reflect.Kind enum. + unsigned int kind; + // Size of the variable in bytes. + unsigned int size; + + // Offset from stack pointer. This should only be set from the Go side. + int offset; + + // If true, the parameter is passed in a register. + bool in_reg; + // The number of register pieces the parameter is passed in. + int n_pieces; + // If in_reg is true, this represents the registers that the parameter is passed in. + // This is an array because the number of registers may vary and the parameter may be + // passed in multiple registers. + int reg_nums[6]; + + // The following are filled in by the eBPF program. + size_t daddr; // Data address. + char val[0x30]; // Value of the parameter. + char deref_val[0x30]; // Dereference value of the parameter. } function_parameter_t; // function_parameter_list holds info about the function parameters and // stores information on up to 6 parameters. typedef struct function_parameter_list { - unsigned int goid_offset; // Offset of the `goid` struct member. - long long g_addr_offset; // Offset of the Goroutine struct from the TLS segment. - int goroutine_id; + unsigned int goid_offset; // Offset of the `goid` struct member. + long long g_addr_offset; // Offset of the Goroutine struct from the TLS segment. + int goroutine_id; - unsigned long long int fn_addr; - bool is_ret; + unsigned long long int fn_addr; + bool is_ret; - unsigned int n_parameters; // number of parameters. - function_parameter_t params[6]; // list of parameters. + unsigned int n_parameters; // number of parameters. + function_parameter_t params[6]; // list of parameters. - unsigned int n_ret_parameters; // number of return parameters. - function_parameter_t ret_params[6]; // list of return parameters. + unsigned int n_ret_parameters; // number of return parameters. + function_parameter_t ret_params[6]; // list of return parameters. } function_parameter_list_t; diff --git a/pkg/proc/internal/ebpf/bpf/include/trace.bpf.h b/pkg/proc/internal/ebpf/bpf/include/trace.bpf.h index 971db59fa4..e037cb58d4 100644 --- a/pkg/proc/internal/ebpf/bpf/include/trace.bpf.h +++ b/pkg/proc/internal/ebpf/bpf/include/trace.bpf.h @@ -1,5 +1,6 @@ #include "vmlinux.h" #include "function_vals.bpf.h" +#include #include #include @@ -7,15 +8,10 @@ // Ring buffer to handle communication of variable values back to userspace. struct { - __uint(type, BPF_MAP_TYPE_RINGBUF); - __uint(max_entries, BPF_MAX_VAR_SIZ); + __uint(type, BPF_MAP_TYPE_RINGBUF); + __uint(max_entries, BPF_MAX_VAR_SIZ); } events SEC(".maps"); -struct { - __uint(type, BPF_MAP_TYPE_RINGBUF); - __uint(max_entries, BPF_MAX_VAR_SIZ); -} heap SEC(".maps"); - // Map which uses instruction address as key and function parameter info as the value. struct { __uint(max_entries, 42); diff --git a/pkg/proc/internal/ebpf/bpf/trace.bpf.c b/pkg/proc/internal/ebpf/bpf/trace.bpf.c index 584c71b9fa..e51aa5a611 100644 --- a/pkg/proc/internal/ebpf/bpf/trace.bpf.c +++ b/pkg/proc/internal/ebpf/bpf/trace.bpf.c @@ -1,5 +1,4 @@ #include "include/trace.bpf.h" -#include #define STRING_KIND 24 @@ -12,8 +11,8 @@ int parse_string_param(struct pt_regs *ctx, function_parameter_t *param) { u64 str_len; size_t str_addr; - memcpy(&str_addr, param->val, sizeof(str_addr)); - memcpy(&str_len, param->val + sizeof(str_addr), sizeof(str_len)); + __builtin_memcpy(&str_addr, param->val, sizeof(str_addr)); + __builtin_memcpy(&str_len, param->val + sizeof(str_addr), sizeof(str_len)); param->daddr = str_addr; if (str_addr != 0) { @@ -42,72 +41,72 @@ int parse_param_stack(struct pt_regs *ctx, function_parameter_t *param) { __always_inline void get_value_from_register(struct pt_regs *ctx, void *dest, int reg_num) { switch (reg_num) { - case 0: // RAX - memcpy(dest, &ctx->ax, sizeof(ctx->ax)); - break; - case 1: // RDX - memcpy(dest, &ctx->dx, sizeof(ctx->dx)); - break; - case 2: // RCX - memcpy(dest, &ctx->cx, sizeof(ctx->cx)); - break; - case 3: // RBX - memcpy(dest, &ctx->bx, sizeof(ctx->bx)); - break; - case 4: // RSI - memcpy(dest, &ctx->si, sizeof(ctx->si)); - break; - case 5: // RDI - memcpy(dest, &ctx->di, sizeof(ctx->di)); - break; - case 6: // RBP - memcpy(dest, &ctx->bp, sizeof(ctx->bp)); - break; - case 7: // RSP - memcpy(dest, &ctx->sp, sizeof(ctx->sp)); - break; - case 8: // R8 - memcpy(dest, &ctx->r8, sizeof(ctx->r8)); - break; - case 9: // R9 - memcpy(dest, &ctx->r9, sizeof(ctx->r9)); - break; - case 10: // R10 - memcpy(dest, &ctx->r10, sizeof(ctx->r10)); - break; - case 11: // R11 - memcpy(dest, &ctx->r11, sizeof(ctx->r11)); - break; - case 12: // R12 - memcpy(dest, &ctx->r12, sizeof(ctx->r12)); - break; - case 13: // R13 - memcpy(dest, &ctx->r13, sizeof(ctx->r13)); - break; - case 14: // R14 - memcpy(dest, &ctx->r14, sizeof(ctx->r14)); - break; - case 15: // R15 - memcpy(dest, &ctx->r15, sizeof(ctx->r15)); - break; + case 0: // RAX + __builtin_memcpy(dest, &ctx->ax, sizeof(ctx->ax)); + break; + case 1: // RDX + __builtin_memcpy(dest, &ctx->dx, sizeof(ctx->dx)); + break; + case 2: // RCX + __builtin_memcpy(dest, &ctx->cx, sizeof(ctx->cx)); + break; + case 3: // RBX + __builtin_memcpy(dest, &ctx->bx, sizeof(ctx->bx)); + break; + case 4: // RSI + __builtin_memcpy(dest, &ctx->si, sizeof(ctx->si)); + break; + case 5: // RDI + __builtin_memcpy(dest, &ctx->di, sizeof(ctx->di)); + break; + case 6: // RBP + __builtin_memcpy(dest, &ctx->bp, sizeof(ctx->bp)); + break; + case 7: // RSP + __builtin_memcpy(dest, &ctx->sp, sizeof(ctx->sp)); + break; + case 8: // R8 + __builtin_memcpy(dest, &ctx->r8, sizeof(ctx->r8)); + break; + case 9: // R9 + __builtin_memcpy(dest, &ctx->r9, sizeof(ctx->r9)); + break; + case 10: // R10 + __builtin_memcpy(dest, &ctx->r10, sizeof(ctx->r10)); + break; + case 11: // R11 + __builtin_memcpy(dest, &ctx->r11, sizeof(ctx->r11)); + break; + case 12: // R12 + __builtin_memcpy(dest, &ctx->r12, sizeof(ctx->r12)); + break; + case 13: // R13 + __builtin_memcpy(dest, &ctx->r13, sizeof(ctx->r13)); + break; + case 14: // R14 + __builtin_memcpy(dest, &ctx->r14, sizeof(ctx->r14)); + break; + case 15: // R15 + __builtin_memcpy(dest, &ctx->r15, sizeof(ctx->r15)); + break; } } __always_inline int parse_param_registers(struct pt_regs *ctx, function_parameter_t *param) { switch (param->n_pieces) { - case 6: - get_value_from_register(ctx, param->val+40, param->reg_nums[5]); - case 5: - get_value_from_register(ctx, param->val+32, param->reg_nums[4]); - case 4: - get_value_from_register(ctx, param->val+24, param->reg_nums[3]); - case 3: - get_value_from_register(ctx, param->val+16, param->reg_nums[2]); - case 2: - get_value_from_register(ctx, param->val+8, param->reg_nums[1]); - case 1: - get_value_from_register(ctx, param->val, param->reg_nums[0]); + case 6: + get_value_from_register(ctx, param->val+40, param->reg_nums[5]); + case 5: + get_value_from_register(ctx, param->val+32, param->reg_nums[4]); + case 4: + get_value_from_register(ctx, param->val+24, param->reg_nums[3]); + case 3: + get_value_from_register(ctx, param->val+16, param->reg_nums[2]); + case 2: + get_value_from_register(ctx, param->val+8, param->reg_nums[1]); + case 1: + get_value_from_register(ctx, param->val, param->reg_nums[0]); } return 0; } @@ -142,37 +141,17 @@ int parse_param(struct pt_regs *ctx, function_parameter_t *param) { __always_inline int get_goroutine_id(function_parameter_list_t *parsed_args) { - // Since eBPF programs have such strict stack requirements - // me must implement our own heap using a ringbuffer. - // Reserve some memory in our "heap" for the task_struct. struct task_struct *task; - task = bpf_ringbuf_reserve(&heap, sizeof(struct task_struct), 0); - if (!task) { - return 0; - } + size_t g_addr; + __u64 goid; // Get the current task. - __u64 task_ptr = bpf_get_current_task(); - if (!task_ptr) - { - bpf_ringbuf_discard(task, 0); - return 0; - } - // The bpf_get_current_task helper returns us the address of the task_struct in - // kernel memory. Use the bpf_probe_read_kernel helper to read the struct out of - // kernel memory. - bpf_probe_read_kernel(task, sizeof(struct task_struct), (void*)(task_ptr)); - + task = (struct task_struct *)bpf_get_current_task(); // Get the Goroutine ID which is stored in thread local storage. - __u64 goid; - size_t g_addr; - bpf_probe_read_user(&g_addr, sizeof(void *), (void*)(task->thread.fsbase+parsed_args->g_addr_offset)); + bpf_probe_read_user(&g_addr, sizeof(void *), (void*)(BPF_CORE_READ(task, thread.fsbase)+parsed_args->g_addr_offset)); bpf_probe_read_user(&goid, sizeof(void *), (void*)(g_addr+parsed_args->goid_offset)); parsed_args->goroutine_id = goid; - // Free back up the memory we reserved for the task_struct. - bpf_ringbuf_discard(task, 0); - return 1; } @@ -181,18 +160,18 @@ void parse_params(struct pt_regs *ctx, unsigned int n_params, function_parameter // Since we cannot loop in eBPF programs let's take adavantage of the // fact that in C switch cases will pass through automatically. switch (n_params) { - case 6: - parse_param(ctx, ¶ms[5]); - case 5: - parse_param(ctx, ¶ms[4]); - case 4: - parse_param(ctx, ¶ms[3]); - case 3: - parse_param(ctx, ¶ms[2]); - case 2: - parse_param(ctx, ¶ms[1]); - case 1: - parse_param(ctx, ¶ms[0]); + case 6: + parse_param(ctx, ¶ms[5]); + case 5: + parse_param(ctx, ¶ms[4]); + case 4: + parse_param(ctx, ¶ms[3]); + case 3: + parse_param(ctx, ¶ms[2]); + case 2: + parse_param(ctx, ¶ms[1]); + case 1: + parse_param(ctx, ¶ms[0]); } } @@ -207,7 +186,7 @@ int uprobe__dlv_trace(struct pt_regs *ctx) { return 1; } - parsed_args = bpf_ringbuf_reserve(&events, sizeof(function_parameter_list_t), 0); + parsed_args = bpf_ringbuf_reserve(&events, sizeof(function_parameter_list_t), 0); if (!parsed_args) { return 1; } @@ -220,8 +199,8 @@ int uprobe__dlv_trace(struct pt_regs *ctx) { parsed_args->n_parameters = args->n_parameters; parsed_args->n_ret_parameters = args->n_ret_parameters; parsed_args->is_ret = args->is_ret; - memcpy(parsed_args->params, args->params, sizeof(args->params)); - memcpy(parsed_args->ret_params, args->ret_params, sizeof(args->ret_params)); + __builtin_memcpy(parsed_args->params, args->params, sizeof(args->params)); + __builtin_memcpy(parsed_args->ret_params, args->ret_params, sizeof(args->ret_params)); if (!get_goroutine_id(parsed_args)) { bpf_ringbuf_discard(parsed_args, 0); diff --git a/pkg/proc/internal/ebpf/testhelper/testhelper.go b/pkg/proc/internal/ebpf/testhelper/testhelper.go index 2441990da2..3aef49f5d2 100644 --- a/pkg/proc/internal/ebpf/testhelper/testhelper.go +++ b/pkg/proc/internal/ebpf/testhelper/testhelper.go @@ -3,6 +3,7 @@ package testhelper +// #include // #include "../bpf/include/function_vals.bpf.h" import "C" diff --git a/pkg/proc/internal/ebpf/trace_bpfel_x86.go b/pkg/proc/internal/ebpf/trace_bpfel_x86.go index 61675e26c1..00880e507e 100644 --- a/pkg/proc/internal/ebpf/trace_bpfel_x86.go +++ b/pkg/proc/internal/ebpf/trace_bpfel_x86.go @@ -64,7 +64,6 @@ type traceProgramSpecs struct { type traceMapSpecs struct { ArgMap *ebpf.MapSpec `ebpf:"arg_map"` Events *ebpf.MapSpec `ebpf:"events"` - Heap *ebpf.MapSpec `ebpf:"heap"` } // traceObjects contains all objects after they have been loaded into the kernel. @@ -88,14 +87,12 @@ func (o *traceObjects) Close() error { type traceMaps struct { ArgMap *ebpf.Map `ebpf:"arg_map"` Events *ebpf.Map `ebpf:"events"` - Heap *ebpf.Map `ebpf:"heap"` } func (m *traceMaps) Close() error { return _TraceClose( m.ArgMap, m.Events, - m.Heap, ) } diff --git a/pkg/proc/internal/ebpf/trace_bpfel_x86.o b/pkg/proc/internal/ebpf/trace_bpfel_x86.o index cadd890231ba123dc17d328a64d11a37c7c7810c..5f8c720389aa516705faa3e1b478af7dfbb7cb10 100644 GIT binary patch literal 910336 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 DDLqX{ literal 911488 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 z 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

\n\t* can be the full path of a file or just a suffix\n\t* ::= .. | .(*). | . | . | (*). | \n\t must be unambiguous\n\t* // will return a location for each function matched by regex\n\t* + returns a location for the line that is lines after the current line\n\t* - returns a location for the line that is lines before the current line\n\t* returns a location for a line in the current file\n\t* *
returns the location corresponding to the specified address\n\nNOTE: this function does not actually set breakpoints." r["follow_exec"] = starlark.NewBuiltin("follow_exec", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -806,6 +828,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["follow_exec"] = "builtin follow_exec(Enable, Regex)\n\nfollow_exec enables or disables follow exec mode." r["follow_exec_enabled"] = starlark.NewBuiltin("follow_exec_enabled", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -818,6 +841,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["follow_exec_enabled"] = "builtin follow_exec_enabled()\n\nfollow_exec_enabled returns true if follow exec mode is enabled." r["function_return_locations"] = starlark.NewBuiltin("function_return_locations", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -848,6 +872,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["function_return_locations"] = "builtin function_return_locations(FnName)\n\nfunction_return_locations is the implements the client call of the same name. Look at client documentation for more information." r["get_breakpoint"] = starlark.NewBuiltin("get_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -886,6 +911,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["get_breakpoint"] = "builtin get_breakpoint(Id, Name)\n\nget_breakpoint gets a breakpoint by Name (if Name is not an empty string) or by ID." r["get_buffered_tracepoints"] = starlark.NewBuiltin("get_buffered_tracepoints", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -898,6 +924,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["get_buffered_tracepoints"] = "builtin get_buffered_tracepoints()" r["get_thread"] = starlark.NewBuiltin("get_thread", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -928,6 +955,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["get_thread"] = "builtin get_thread(Id)\n\nget_thread gets a thread by its ID." r["is_multiclient"] = starlark.NewBuiltin("is_multiclient", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -940,6 +968,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["is_multiclient"] = "builtin is_multiclient()" r["last_modified"] = starlark.NewBuiltin("last_modified", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -952,6 +981,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["last_modified"] = "builtin last_modified()" r["breakpoints"] = starlark.NewBuiltin("breakpoints", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -982,6 +1012,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["breakpoints"] = "builtin breakpoints(All)\n\nbreakpoints gets all breakpoints." r["checkpoints"] = starlark.NewBuiltin("checkpoints", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -994,6 +1025,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["checkpoints"] = "builtin checkpoints()" r["dynamic_libraries"] = starlark.NewBuiltin("dynamic_libraries", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1006,6 +1038,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["dynamic_libraries"] = "builtin dynamic_libraries()" r["function_args"] = starlark.NewBuiltin("function_args", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1048,6 +1081,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["function_args"] = "builtin function_args(Scope, Cfg)\n\nfunction_args lists all arguments to the current function" r["functions"] = starlark.NewBuiltin("functions", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1078,6 +1112,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["functions"] = "builtin functions(Filter)\n\nfunctions lists all functions in the process matching filter." r["goroutines"] = starlark.NewBuiltin("goroutines", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1132,6 +1167,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["goroutines"] = "builtin goroutines(Start, Count, Filters, GoroutineGroupingOptions)\n\ngoroutines lists all goroutines.\nIf Count is specified ListGoroutines will return at the first Count\ngoroutines and an index in Nextg, that can be passed as the Start\nparameter, to get more goroutines from ListGoroutines.\nPassing a value of Start that wasn't returned by ListGoroutines will skip\nan undefined number of goroutines.\n\nIf arg.Filters are specified the list of returned goroutines is filtered\napplying the specified filters.\nFor example:\n\n\tListGoroutinesFilter{ Kind: ListGoroutinesFilterUserLoc, Negated: false, Arg: \"afile.go\" }\n\nwill only return goroutines whose UserLoc contains \"afile.go\" as a substring.\nMore specifically a goroutine matches a location filter if the specified\nlocation, formatted like this:\n\n\tfilename:lineno in function\n\ncontains Arg[0] as a substring.\n\nFilters can also be applied to goroutine labels:\n\n\tListGoroutineFilter{ Kind: ListGoroutinesFilterLabel, Negated: false, Arg: \"key=value\" }\n\nthis filter will only return goroutines that have a key=value label.\n\nIf arg.GroupBy is not GoroutineFieldNone then the goroutines will\nbe grouped with the specified criterion.\nIf the value of arg.GroupBy is GoroutineLabel goroutines will\nbe grouped by the value of the label with key GroupByKey.\nFor each group a maximum of MaxExamples example goroutines are\nreturned, as well as the total number of goroutines in the group." r["local_vars"] = starlark.NewBuiltin("local_vars", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1174,6 +1210,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["local_vars"] = "builtin local_vars(Scope, Cfg)\n\nlocal_vars lists all local variables in scope." r["package_vars"] = starlark.NewBuiltin("package_vars", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1214,6 +1251,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["package_vars"] = "builtin package_vars(Filter, Cfg)\n\npackage_vars lists all package variables in the context of the current thread." r["packages_build_info"] = starlark.NewBuiltin("packages_build_info", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1244,6 +1282,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["packages_build_info"] = "builtin packages_build_info(IncludeFiles)\n\npackages_build_info returns the list of packages used by the program along with\nthe directory where each package was compiled and optionally the list of\nfiles constituting the package.\nNote that the directory path is a best guess and may be wrong is a tool\nother than cmd/go is used to perform the build." r["registers"] = starlark.NewBuiltin("registers", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1293,6 +1332,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["registers"] = "builtin registers(ThreadID, IncludeFp, Scope)\n\nregisters lists registers and their values.\nIf ListRegistersIn.Scope is not nil the registers of that eval scope will\nbe returned, otherwise ListRegistersIn.ThreadID will be used." r["sources"] = starlark.NewBuiltin("sources", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1323,6 +1363,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["sources"] = "builtin sources(Filter)\n\nsources lists all source files in the process matching filter." r["targets"] = starlark.NewBuiltin("targets", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1335,6 +1376,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["targets"] = "builtin targets()\n\ntargets returns the list of targets we are currently attached to." r["threads"] = starlark.NewBuiltin("threads", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1347,6 +1389,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["threads"] = "builtin threads()\n\nthreads lists all threads." r["types"] = starlark.NewBuiltin("types", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1377,6 +1420,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["types"] = "builtin types(Filter)\n\ntypes lists all types in the process matching filter." r["process_pid"] = starlark.NewBuiltin("process_pid", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1389,6 +1433,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["process_pid"] = "builtin process_pid()\n\nprocess_pid returns the pid of the process we are debugging." r["recorded"] = starlark.NewBuiltin("recorded", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1401,6 +1446,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["recorded"] = "builtin recorded()" r["restart"] = starlark.NewBuiltin("restart", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1471,6 +1517,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["restart"] = "builtin restart(Position, ResetArgs, NewArgs, Rerecord, Rebuild, NewRedirects)\n\nrestart restarts program." r["set_expr"] = starlark.NewBuiltin("set_expr", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1519,6 +1566,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["set_expr"] = "builtin set_expr(Scope, Symbol, Value)\n\nset_expr sets the value of a variable. Only numerical types and\npointers are currently supported." r["stacktrace"] = starlark.NewBuiltin("stacktrace", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1589,6 +1637,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["stacktrace"] = "builtin stacktrace(Id, Depth, Full, Defers, Opts, Cfg)\n\nstacktrace returns stacktrace of goroutine Id up to the specified Depth.\n\nIf Full is set it will also the variable of all local variables\nand function arguments of all stack frames." r["state"] = starlark.NewBuiltin("state", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1619,6 +1668,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["state"] = "builtin state(NonBlocking)\n\nstate returns the current debugger state." r["toggle_breakpoint"] = starlark.NewBuiltin("toggle_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1657,5 +1707,6 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) - return r + doc["toggle_breakpoint"] = "builtin toggle_breakpoint(Id, Name)\n\ntoggle_breakpoint toggles on or off a breakpoint by Name (if Name is not an\nempty string) or by ID." + return r, doc } From ccf17a6f429e600680d99db8d4b05b4feb10fa1e Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Wed, 14 Jun 2023 04:23:46 -0700 Subject: [PATCH 059/114] pkg/proc: enable basic debug functionality for stripped ELF binaries (#3408) We used to parse the .gopclntab section but removed support in favor of simply using DWARF debug information, due to lack of C symbols among other reasons. This makes it impossible to debug stripped binaries, which some distrubutions ship by default. Add back in basic support for .gopclntab which survives if the binary is stripped, allowing for rudimentary debugging such as basic program navigation, tracing, etc... --- cmd/dlv/dlv_test.go | 103 ----------------------------------- pkg/proc/bininfo.go | 83 ++++++++++++++++++++++++---- pkg/proc/breakpoints.go | 2 +- pkg/proc/fncall.go | 2 +- pkg/proc/goroutine_cache.go | 3 + pkg/proc/pclntab.go | 75 +++++++++++++++++++++++++ pkg/proc/proc_test.go | 75 ++++--------------------- pkg/proc/stack.go | 5 +- pkg/proc/target_exec.go | 13 +++-- pkg/proc/variables.go | 2 +- service/debugger/debugger.go | 7 +++ 11 files changed, 184 insertions(+), 186 deletions(-) create mode 100644 pkg/proc/pclntab.go diff --git a/cmd/dlv/dlv_test.go b/cmd/dlv/dlv_test.go index 06b8fd6020..aa1b100149 100644 --- a/cmd/dlv/dlv_test.go +++ b/cmd/dlv/dlv_test.go @@ -26,7 +26,6 @@ import ( "github.com/go-delve/delve/pkg/terminal" "github.com/go-delve/delve/service/dap" "github.com/go-delve/delve/service/dap/daptest" - "github.com/go-delve/delve/service/debugger" "github.com/go-delve/delve/service/rpc2" godap "github.com/google/go-dap" "golang.org/x/tools/go/packages" @@ -282,57 +281,6 @@ func TestContinue(t *testing.T) { cmd.Wait() } -// TestChildProcessExitWhenNoDebugInfo verifies that the child process exits when dlv launch the binary without debug info -func TestChildProcessExitWhenNoDebugInfo(t *testing.T) { - noDebugFlags := protest.LinkStrip - // -s doesn't strip symbols on Mac, use -w instead - if runtime.GOOS == "darwin" { - noDebugFlags = protest.LinkDisableDWARF - } - - if _, err := exec.LookPath("ps"); err != nil { - t.Skip("test skipped, `ps` not found") - } - - dlvbin := getDlvBin(t) - - fix := protest.BuildFixture("http_server", noDebugFlags) - - // dlv exec the binary file and expect error. - out, err := exec.Command(dlvbin, "exec", "--headless", "--log", fix.Path).CombinedOutput() - t.Log(string(out)) - if err == nil { - t.Fatalf("Expected err when launching the binary without debug info, but got nil") - } - // Test only for dlv's prefix of the error like "could not launch process: could not open debug info" - if !strings.Contains(string(out), "could not launch process") || !strings.Contains(string(out), debugger.NoDebugWarning) { - t.Fatalf("Expected logged error 'could not launch process: ... - %s'", debugger.NoDebugWarning) - } - - // search the running process named fix.Name - cmd := exec.Command("ps", "-aux") - stdout, err := cmd.StdoutPipe() - assertNoError(err, t, "stdout pipe") - defer stdout.Close() - - assertNoError(cmd.Start(), t, "start `ps -aux`") - - var foundFlag bool - scan := bufio.NewScanner(stdout) - for scan.Scan() { - t.Log(scan.Text()) - if strings.Contains(scan.Text(), fix.Name) { - foundFlag = true - break - } - } - cmd.Wait() - - if foundFlag { - t.Fatalf("Expected child process exited, but found it running") - } -} - // TestRedirect verifies that redirecting stdin works func TestRedirect(t *testing.T) { const listenAddr = "127.0.0.1:40573" @@ -711,57 +659,6 @@ func TestDAPCmd(t *testing.T) { cmd.Wait() } -func TestDAPCmdWithNoDebugBinary(t *testing.T) { - const listenAddr = "127.0.0.1:40579" - - dlvbin := getDlvBin(t) - - cmd := exec.Command(dlvbin, "dap", "--log", "--listen", listenAddr) - stdout, err := cmd.StdoutPipe() - assertNoError(err, t, "stdout pipe") - defer stdout.Close() - stderr, err := cmd.StderrPipe() - assertNoError(err, t, "stderr pipe") - defer stderr.Close() - assertNoError(cmd.Start(), t, "start dap instance") - - scanOut := bufio.NewScanner(stdout) - scanErr := bufio.NewScanner(stderr) - // Wait for the debug server to start - scanOut.Scan() - listening := "DAP server listening at: " + listenAddr - if scanOut.Text() != listening { - cmd.Process.Kill() // release the port - t.Fatalf("Unexpected stdout:\ngot %q\nwant %q", scanOut.Text(), listening) - } - go func() { // Capture logging - for scanErr.Scan() { - t.Log(scanErr.Text()) - } - }() - - // Exec the stripped debuggee and expect things to fail - noDebugFlags := protest.LinkStrip - // -s doesn't strip symbols on Mac, use -w instead - if runtime.GOOS == "darwin" { - noDebugFlags = protest.LinkDisableDWARF - } - fixture := protest.BuildFixture("increment", noDebugFlags) - go func() { - for scanOut.Scan() { - t.Errorf("Unexpected stdout: %s", scanOut.Text()) - } - }() - client := daptest.NewClient(listenAddr) - client.LaunchRequest("exec", fixture.Path, false) - client.ExpectErrorResponse(t) - client.DisconnectRequest() - client.ExpectDisconnectResponse(t) - client.ExpectTerminatedEvent(t) - client.Close() - cmd.Wait() -} - func newDAPRemoteClient(t *testing.T, addr string, isDlvAttach bool, isMulti bool) *daptest.Client { c := daptest.NewClient(addr) c.AttachRequest(map[string]interface{}{"mode": "remote", "stopOnEntry": true}) diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go index 4cd41dc4d8..3deafc6731 100644 --- a/pkg/proc/bininfo.go +++ b/pkg/proc/bininfo.go @@ -4,6 +4,7 @@ import ( "bytes" "debug/dwarf" "debug/elf" + "debug/gosym" "debug/macho" "debug/pe" "encoding/binary" @@ -332,7 +333,7 @@ func FindFunctionLocation(p Process, funcName string, lineOffset int) ([]uint64, if lineOffset > 0 { fn := origfns[0] - filename, lineno := fn.cu.lineInfo.PCToLine(fn.Entry, fn.Entry) + filename, lineno := bi.EntryLineForFunc(fn) return FindFileLocation(p, filename, lineno+lineOffset) } @@ -364,14 +365,16 @@ func FindFunctionLocation(p Process, funcName string, lineOffset int) ([]uint64, // If sameline is set FirstPCAfterPrologue will always return an // address associated with the same line as fn.Entry. func FirstPCAfterPrologue(p Process, fn *Function, sameline bool) (uint64, error) { - pc, _, line, ok := fn.cu.lineInfo.PrologueEndPC(fn.Entry, fn.End) - if ok { - if !sameline { - return pc, nil - } - _, entryLine := fn.cu.lineInfo.PCToLine(fn.Entry, fn.Entry) - if entryLine == line { - return pc, nil + if fn.cu.lineInfo != nil { + pc, _, line, ok := fn.cu.lineInfo.PrologueEndPC(fn.Entry, fn.End) + if ok { + if !sameline { + return pc, nil + } + _, entryLine := p.BinInfo().EntryLineForFunc(fn) + if entryLine == line { + return pc, nil + } } } @@ -380,7 +383,7 @@ func FirstPCAfterPrologue(p Process, fn *Function, sameline bool) (uint64, error return fn.Entry, err } - if pc == fn.Entry { + if pc == fn.Entry && fn.cu.lineInfo != nil { // Look for the first instruction with the stmt flag set, so that setting a // breakpoint with file:line and with the function name always result on // the same instruction being selected. @@ -601,6 +604,25 @@ func (fn *Function) PrologueEndPC() uint64 { return pc } +func (fn *Function) AllPCs(excludeFile string, excludeLine int) ([]uint64, error) { + if !fn.cu.image.Stripped() { + return fn.cu.lineInfo.AllPCsBetween(fn.Entry, fn.End-1, excludeFile, excludeLine) + } + var pcs []uint64 + fnFile, lastLine, _ := fn.cu.image.symTable.PCToLine(fn.Entry) + for pc := fn.Entry; pc < fn.End; pc++ { + f, line, pcfn := fn.cu.image.symTable.PCToLine(pc) + if pcfn == nil { + continue + } + if f == fnFile && line > lastLine { + lastLine = line + pcs = append(pcs, pc) + } + } + return pcs, nil +} + // From $GOROOT/src/runtime/traceback.go:597 // exportedRuntime reports whether the function is an exported runtime function. // It is only for runtime functions, so ASCII A-Z is fine. @@ -719,6 +741,9 @@ func (bi *BinaryInfo) LastModified() time.Time { // DwarfReader returns a reader for the dwarf data func (so *Image) DwarfReader() *reader.Reader { + if so.dwarf == nil { + return nil + } return reader.New(so.dwarf) } @@ -731,13 +756,26 @@ func (bi *BinaryInfo) Types() ([]string, error) { return types, nil } +func (bi *BinaryInfo) EntryLineForFunc(fn *Function) (string, int) { + return bi.pcToLine(fn, fn.Entry) +} + +func (bi *BinaryInfo) pcToLine(fn *Function, pc uint64) (string, int) { + if fn.cu.lineInfo == nil { + f, l, _ := fn.cu.image.symTable.PCToLine(pc) + return f, l + } + f, l := fn.cu.lineInfo.PCToLine(fn.Entry, pc) + return f, l +} + // PCToLine converts an instruction address to a file/line/function. func (bi *BinaryInfo) PCToLine(pc uint64) (string, int, *Function) { fn := bi.PCToFunc(pc) if fn == nil { return "", 0, nil } - f, ln := fn.cu.lineInfo.PCToLine(fn.Entry, pc) + f, ln := bi.pcToLine(fn, pc) return f, ln, fn } @@ -810,6 +848,8 @@ type Image struct { debugAddr *godwarf.DebugAddrSection debugLineStr []byte + symTable *gosym.Table + typeCache map[dwarf.Offset]godwarf.Type compileUnits []*compileUnit // compileUnits is sorted by increasing DWARF offset @@ -835,6 +875,10 @@ func (image *Image) registerRuntimeTypeToDIE(entry *dwarf.Entry, ardr *reader.Re } } +func (image *Image) Stripped() bool { + return image.dwarf == nil +} + // AddImage adds the specified image to bi, loading data asynchronously. // Addr is the relocated entry point for the executable and staticBase (i.e. // the relocation offset) for all other images. @@ -1405,7 +1449,22 @@ func loadBinaryInfoElf(bi *BinaryInfo, image *Image, path string, addr uint64, w var serr error sepFile, dwarfFile, serr = bi.openSeparateDebugInfo(image, elfFile, bi.DebugInfoDirectories) if serr != nil { - return serr + fmt.Fprintln(os.Stderr, "Warning: no debug info found, some functionality will be missing such as stack traces and variable evaluation.") + symTable, err := readPcLnTableElf(elfFile, path) + if err != nil { + return fmt.Errorf("could not create symbol table from %s ", path) + } + image.symTable = symTable + for _, f := range image.symTable.Funcs { + cu := &compileUnit{} + cu.image = image + fn := Function{Name: f.Name, Entry: f.Entry, End: f.End, cu: cu} + bi.Functions = append(bi.Functions, fn) + } + for f := range image.symTable.Files { + bi.Sources = append(bi.Sources, f) + } + return nil } image.sepDebugCloser = sepFile image.dwarf, err = dwarfFile.DWARF() diff --git a/pkg/proc/breakpoints.go b/pkg/proc/breakpoints.go index 2e7cdf725c..c5910e319c 100644 --- a/pkg/proc/breakpoints.go +++ b/pkg/proc/breakpoints.go @@ -554,7 +554,7 @@ func (t *Target) setEBPFTracepointOnFunc(fn *Function, goidOffset int64) error { if t.BinInfo().Producer() != "" && goversion.ProducerAfterOrEqual(t.BinInfo().Producer(), 1, 15) { variablesFlags |= reader.VariablesTrustDeclLine } - _, l, _ := t.BinInfo().PCToLine(fn.Entry) + _, l := t.BinInfo().EntryLineForFunc(fn) var args []ebpf.UProbeArgMap varEntries := reader.Variables(dwarfTree, fn.Entry, l, variablesFlags) diff --git a/pkg/proc/fncall.go b/pkg/proc/fncall.go index bd0df51534..a1b94a7291 100644 --- a/pkg/proc/fncall.go +++ b/pkg/proc/fncall.go @@ -1053,7 +1053,7 @@ func readStackVariable(t *Target, thread Thread, regs Registers, off uint64, typ func fakeFunctionEntryScope(scope *EvalScope, fn *Function, cfa int64, sp uint64) error { scope.PC = fn.Entry scope.Fn = fn - scope.File, scope.Line, _ = scope.BinInfo.PCToLine(fn.Entry) + scope.File, scope.Line = scope.BinInfo.EntryLineForFunc(fn) scope.Regs.CFA = cfa scope.Regs.Reg(scope.Regs.SPRegNum).Uint64Val = sp diff --git a/pkg/proc/goroutine_cache.go b/pkg/proc/goroutine_cache.go index 70e7f61cf5..4020dad014 100644 --- a/pkg/proc/goroutine_cache.go +++ b/pkg/proc/goroutine_cache.go @@ -12,6 +12,9 @@ func (gcache *goroutineCache) init(bi *BinaryInfo) { exeimage := bi.Images[0] rdr := exeimage.DwarfReader() + if rdr == nil { + return + } gcache.allglenAddr, _ = rdr.AddrFor("runtime.allglen", exeimage.StaticBase, bi.Arch.PtrSize()) diff --git a/pkg/proc/pclntab.go b/pkg/proc/pclntab.go new file mode 100644 index 0000000000..3451533233 --- /dev/null +++ b/pkg/proc/pclntab.go @@ -0,0 +1,75 @@ +package proc + +import ( + "bytes" + "debug/buildinfo" + "debug/elf" + "debug/gosym" + "encoding/binary" + "fmt" + "strings" +) + +// From go/src/debug/gosym/pclntab.go +const ( + go12magic = 0xfffffffb + go116magic = 0xfffffffa + go118magic = 0xfffffff0 + go120magic = 0xfffffff1 +) + +// Select the magic number based on the Go version +func magicNumber(goVersion string) []byte { + bs := make([]byte, 4) + var magic uint32 + if strings.Compare(goVersion, "go1.20") >= 0 { + magic = go120magic + } else if strings.Compare(goVersion, "go1.18") >= 0 { + magic = go118magic + } else if strings.Compare(goVersion, "go1.16") >= 0 { + magic = go116magic + } else { + magic = go12magic + } + binary.LittleEndian.PutUint32(bs, magic) + return bs +} + +func readPcLnTableElf(exe *elf.File, path string) (*gosym.Table, error) { + // Default section label is .gopclntab + sectionLabel := ".gopclntab" + + section := exe.Section(sectionLabel) + if section == nil { + // binary may be built with -pie + sectionLabel = ".data.rel.ro" + section = exe.Section(sectionLabel) + if section == nil { + return nil, fmt.Errorf("could not read section .gopclntab") + } + } + tableData, err := section.Data() + if err != nil { + return nil, fmt.Errorf("found section but could not read .gopclntab") + } + + bi, err := buildinfo.ReadFile(path) + if err != nil { + return nil, err + } + + // Find .gopclntab by magic number even if there is no section label + magic := magicNumber(bi.GoVersion) + pclntabIndex := bytes.Index(tableData, magic) + if pclntabIndex < 0 { + return nil, fmt.Errorf("could not find magic number in %s ", path) + } + tableData = tableData[pclntabIndex:] + addr := exe.Section(".text").Addr + lineTable := gosym.NewLineTable(tableData, addr) + symTable, err := gosym.NewTable([]byte{}, lineTable) + if err != nil { + return nil, fmt.Errorf("could not create symbol table from %s ", path) + } + return symTable, nil +} diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 874434c85c..10f7876d70 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -3165,69 +3165,18 @@ func TestShadowedFlag(t *testing.T) { }) } -func TestAttachStripped(t *testing.T) { - if testBackend == "lldb" && runtime.GOOS == "linux" { - bs, _ := ioutil.ReadFile("/proc/sys/kernel/yama/ptrace_scope") - if bs == nil || strings.TrimSpace(string(bs)) != "0" { - t.Logf("can not run TestAttachStripped: %v\n", bs) - return - } - } - if testBackend == "rr" { - return - } - if runtime.GOOS == "darwin" { - t.Log("-s does not produce stripped executables on macOS") - return - } - if buildMode != "" { - t.Skip("not enabled with buildmode=PIE") - } - fixture := protest.BuildFixture("testnextnethttp", protest.LinkStrip) - cmd := exec.Command(fixture.Path) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - assertNoError(cmd.Start(), t, "starting fixture") - - // wait for testnextnethttp to start listening - t0 := time.Now() - for { - conn, err := net.Dial("tcp", "127.0.0.1:9191") - if err == nil { - conn.Close() - break - } - time.Sleep(50 * time.Millisecond) - if time.Since(t0) > 10*time.Second { - t.Fatal("fixture did not start") - } - } - - var p *proc.TargetGroup - var err error - - switch testBackend { - case "native": - p, err = native.Attach(cmd.Process.Pid, []string{}) - case "lldb": - path := "" - if runtime.GOOS == "darwin" { - path = fixture.Path - } - p, err = gdbserial.LLDBAttach(cmd.Process.Pid, path, []string{}) - default: - t.Fatalf("unknown backend %q", testBackend) - } - - t.Logf("error is %v", err) - - if err == nil { - p.Detach(true) - t.Fatalf("expected error after attach, got nothing") - } else { - cmd.Process.Kill() - } - os.Remove(fixture.Path) +func TestDebugStripped(t *testing.T) { + // Currently only implemented for Linux ELF executables. + // TODO(derekparker): Add support for Mach-O and PE. + skipUnlessOn(t, "linux only", "linux") + withTestProcessArgs("testnextprog", t, "", []string{}, protest.LinkStrip, func(p *proc.Target, grp *proc.TargetGroup, f protest.Fixture) { + setFunctionBreakpoint(p, t, "main.main") + assertNoError(grp.Continue(), t, "Continue") + assertCurrentLocationFunction(p, t, "main.main") + assertLineNumber(p, t, 37, "first continue") + assertNoError(grp.Next(), t, "Next") + assertLineNumber(p, t, 38, "after next") + }) } func TestIssue844(t *testing.T) { diff --git a/pkg/proc/stack.go b/pkg/proc/stack.go index 9fdcb93e8a..d4791df812 100644 --- a/pkg/proc/stack.go +++ b/pkg/proc/stack.go @@ -253,6 +253,9 @@ func (it *stackIterator) Err() error { // frameBase calculates the frame base pseudo-register for DWARF for fn and // the current frame. func (it *stackIterator) frameBase(fn *Function) int64 { + if fn.cu.image.Stripped() { + return 0 + } dwarfTree, err := fn.cu.image.getDwarfTree(fn.offset) if err != nil { return 0 @@ -695,6 +698,6 @@ func (d *Defer) DeferredFunc(p *Target) (file string, line int, fn *Function) { if fn == nil { return "", 0, nil } - file, line = fn.cu.lineInfo.PCToLine(fn.Entry, fn.Entry) + file, line = bi.EntryLineForFunc(fn) return file, line, fn } diff --git a/pkg/proc/target_exec.go b/pkg/proc/target_exec.go index ed9da60e00..6473429409 100644 --- a/pkg/proc/target_exec.go +++ b/pkg/proc/target_exec.go @@ -392,7 +392,7 @@ func stepInstructionOut(dbp *Target, curthread Thread, fnname1, fnname2 string) } loc, err := curthread.Location() var locFnName string - if loc.Fn != nil { + if loc.Fn != nil && !loc.Fn.cu.image.Stripped() { locFnName = loc.Fn.Name // Calls to runtime.Breakpoint are inlined in some versions of Go when // inlining is enabled. Here we attempt to resolve any inlining. @@ -677,7 +677,7 @@ func next(dbp *Target, stepInto, inlinedStepOut bool) error { } } - if !backward { + if !backward && !topframe.Current.Fn.cu.image.Stripped() { _, err = setDeferBreakpoint(dbp, text, topframe, sameGCond, stepInto) if err != nil { return err @@ -685,7 +685,7 @@ func next(dbp *Target, stepInto, inlinedStepOut bool) error { } // Add breakpoints on all the lines in the current function - pcs, err := topframe.Current.Fn.cu.lineInfo.AllPCsBetween(topframe.Current.Fn.Entry, topframe.Current.Fn.End-1, topframe.Current.File, topframe.Current.Line) + pcs, err := topframe.Current.Fn.AllPCs(topframe.Current.File, topframe.Current.Line) if err != nil { return err } @@ -865,6 +865,11 @@ func FindDeferReturnCalls(text []AsmInstruction) []uint64 { // If includeCurrentFn is true it will also remove all instructions // belonging to the current function. func removeInlinedCalls(pcs []uint64, topframe Stackframe) ([]uint64, error) { + // TODO(derekparker) it should be possible to still use some internal + // runtime information to do this. + if topframe.Call.Fn == nil || topframe.Call.Fn.cu.image.Stripped() { + return pcs, nil + } dwarfTree, err := topframe.Call.Fn.cu.image.getDwarfTree(topframe.Call.Fn.offset) if err != nil { return pcs, err @@ -1061,7 +1066,7 @@ func skipAutogeneratedWrappersOut(g *G, thread Thread, startTopframe, startRetfr if frame.Current.Fn == nil { return } - file, line := frame.Current.Fn.cu.lineInfo.PCToLine(frame.Current.Fn.Entry, frame.Current.Fn.Entry) + file, line := g.Thread.BinInfo().EntryLineForFunc(frame.Current.Fn) if !isAutogeneratedOrDeferReturn(Location{File: file, Line: line, Fn: frame.Current.Fn}) { return &frames[i-1], &frames[i] } diff --git a/pkg/proc/variables.go b/pkg/proc/variables.go index 65f5040dc1..26b4fb713d 100644 --- a/pkg/proc/variables.go +++ b/pkg/proc/variables.go @@ -535,7 +535,7 @@ func (g *G) StartLoc(tgt *Target) Location { if fn == nil { return Location{PC: g.StartPC} } - f, l := fn.cu.lineInfo.PCToLine(fn.Entry, fn.Entry) + f, l := tgt.BinInfo().EntryLineForFunc(fn) return Location{PC: fn.Entry, File: f, Line: l, Fn: fn} } diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index 27441fbaf3..4a100e9b97 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -1315,6 +1315,13 @@ func (d *Debugger) collectBreakpointInformation(apiThread *api.Thread, thread pr tgt := d.target.TargetForThread(thread.ThreadID()) + // If we're dealing with a stripped binary don't attempt to load more + // information, we won't be able to. + img := tgt.BinInfo().PCToImage(bp.Addr) + if img != nil && img.Stripped() { + return nil + } + if bp.Goroutine { g, err := proc.GetG(thread) if err != nil { From 1d28ceccdcd20f8fa707dc665180f2836fc86ae1 Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Thu, 15 Jun 2023 03:07:32 -0700 Subject: [PATCH 060/114] pkg/proc: fix ebpf probe tracing backen uprobe handling (#3417) Uprobes get automatically cleaned and removed when the reference to the Link object is lost. Hold a reference to any active Uprobe Link for duration of Delve execution and ensure they are cleaned up at exit. Fixes ebpf probes don't work after time.Sleep() #3227 --- _fixtures/ebpf_trace2.go | 22 ++++++++++++++ cmd/dlv/dlv_test.go | 48 +++++++++++++++++++++++++++++++ pkg/proc/internal/ebpf/helpers.go | 9 +++++- 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 _fixtures/ebpf_trace2.go diff --git a/_fixtures/ebpf_trace2.go b/_fixtures/ebpf_trace2.go new file mode 100644 index 0000000000..6aff358df2 --- /dev/null +++ b/_fixtures/ebpf_trace2.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + "time" +) + +func main() { + i := int64(0) + for i = 0; i < 5; i++ { + tracedFunction(i) + } + for i = 5; i < 10; i++ { + tracedFunction(i) + time.Sleep(time.Second) + } +} + +//go:noinline +func tracedFunction(x int64) { + fmt.Println(x) +} diff --git a/cmd/dlv/dlv_test.go b/cmd/dlv/dlv_test.go index aa1b100149..153cc962d1 100644 --- a/cmd/dlv/dlv_test.go +++ b/cmd/dlv/dlv_test.go @@ -1157,6 +1157,54 @@ func TestTraceEBPF2(t *testing.T) { cmd.Wait() } +func TestTraceEBPF3(t *testing.T) { + if os.Getenv("CI") == "true" { + t.Skip("cannot run test in CI, requires kernel compiled with btf support") + } + if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { + t.Skip("not implemented on non linux/amd64 systems") + } + if !goversion.VersionAfterOrEqual(runtime.Version(), 1, 16) { + t.Skip("requires at least Go 1.16 to run test") + } + usr, err := user.Current() + if err != nil { + t.Fatal(err) + } + if usr.Uid != "0" { + t.Skip("test must be run as root") + } + + dlvbin := getDlvBinEBPF(t) + + expected := []byte(`> (1) main.tracedFunction(0) +> (1) main.tracedFunction(1) +> (1) main.tracedFunction(2) +> (1) main.tracedFunction(3) +> (1) main.tracedFunction(4) +> (1) main.tracedFunction(5) +> (1) main.tracedFunction(6) +> (1) main.tracedFunction(7) +> (1) main.tracedFunction(8) +> (1) main.tracedFunction(9)`) + + fixtures := protest.FindFixturesDir() + cmd := exec.Command(dlvbin, "trace", "--ebpf", "--output", filepath.Join(t.TempDir(), "__debug"), filepath.Join(fixtures, "ebpf_trace2.go"), "main.traced") + rdr, err := cmd.StderrPipe() + assertNoError(err, t, "stderr pipe") + defer rdr.Close() + + assertNoError(cmd.Start(), t, "running trace") + + output, err := ioutil.ReadAll(rdr) + assertNoError(err, t, "ReadAll") + + if !bytes.Contains(output, expected) { + t.Fatalf("expected:\n%s\ngot:\n%s", string(expected), string(output)) + } + cmd.Wait() +} + func TestDlvTestChdir(t *testing.T) { dlvbin := getDlvBin(t) diff --git a/pkg/proc/internal/ebpf/helpers.go b/pkg/proc/internal/ebpf/helpers.go index b856cef1cd..fbef79e950 100644 --- a/pkg/proc/internal/ebpf/helpers.go +++ b/pkg/proc/internal/ebpf/helpers.go @@ -61,6 +61,7 @@ type EBPFContext struct { bpfRingBuf *ringbuf.Reader executable *link.Executable bpfArgMap *ebpf.Map + links []link.Link parsedBpfEvents []RawUProbeParams m sync.Mutex @@ -70,13 +71,19 @@ func (ctx *EBPFContext) Close() { if ctx.objs != nil { ctx.objs.Close() } + if ctx.links != nil { + for _, l := range ctx.links { + l.Close() + } + } } func (ctx *EBPFContext) AttachUprobe(pid int, name string, offset uint64) error { if ctx.executable == nil { return errors.New("no eBPF program loaded") } - _, err := ctx.executable.Uprobe(name, ctx.objs.tracePrograms.UprobeDlvTrace, &link.UprobeOptions{PID: pid, Offset: offset}) + l, err := ctx.executable.Uprobe(name, ctx.objs.tracePrograms.UprobeDlvTrace, &link.UprobeOptions{PID: pid, Offset: offset}) + ctx.links = append(ctx.links, l) return err } From d006538bb68f9efcdefb55565bfde685d90bcf91 Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Thu, 15 Jun 2023 03:09:20 -0700 Subject: [PATCH 061/114] pkg/terminal: regenerate starlark mappings (#3418) --- pkg/terminal/starbind/starlark_mapping.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/terminal/starbind/starlark_mapping.go b/pkg/terminal/starbind/starlark_mapping.go index b2f9d1d517..5ff0433c37 100644 --- a/pkg/terminal/starbind/starlark_mapping.go +++ b/pkg/terminal/starbind/starlark_mapping.go @@ -1167,7 +1167,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) { } return env.interfaceToStarlarkValue(rpcRet), nil }) - doc["goroutines"] = "builtin goroutines(Start, Count, Filters, GoroutineGroupingOptions)\n\ngoroutines lists all goroutines.\nIf Count is specified ListGoroutines will return at the first Count\ngoroutines and an index in Nextg, that can be passed as the Start\nparameter, to get more goroutines from ListGoroutines.\nPassing a value of Start that wasn't returned by ListGoroutines will skip\nan undefined number of goroutines.\n\nIf arg.Filters are specified the list of returned goroutines is filtered\napplying the specified filters.\nFor example:\n\n\tListGoroutinesFilter{ Kind: ListGoroutinesFilterUserLoc, Negated: false, Arg: \"afile.go\" }\n\nwill only return goroutines whose UserLoc contains \"afile.go\" as a substring.\nMore specifically a goroutine matches a location filter if the specified\nlocation, formatted like this:\n\n\tfilename:lineno in function\n\ncontains Arg[0] as a substring.\n\nFilters can also be applied to goroutine labels:\n\n\tListGoroutineFilter{ Kind: ListGoroutinesFilterLabel, Negated: false, Arg: \"key=value\" }\n\nthis filter will only return goroutines that have a key=value label.\n\nIf arg.GroupBy is not GoroutineFieldNone then the goroutines will\nbe grouped with the specified criterion.\nIf the value of arg.GroupBy is GoroutineLabel goroutines will\nbe grouped by the value of the label with key GroupByKey.\nFor each group a maximum of MaxExamples example goroutines are\nreturned, as well as the total number of goroutines in the group." + doc["goroutines"] = "builtin goroutines(Start, Count, Filters, GoroutineGroupingOptions)\n\ngoroutines lists all goroutines.\nIf Count is specified ListGoroutines will return at the first Count\ngoroutines and an index in Nextg, that can be passed as the Start\nparameter, to get more goroutines from ListGoroutines.\nPassing a value of Start that wasn't returned by ListGoroutines will skip\nan undefined number of goroutines.\n\nIf arg.Filters are specified the list of returned goroutines is filtered\napplying the specified filters.\nFor example:\n\n\tListGoroutinesFilter{ Kind: ListGoroutinesFilterUserLoc, Negated: false, Arg: \"afile.go\" }\n\nwill only return goroutines whose UserLoc contains \"afile.go\" as a substring.\nMore specifically a goroutine matches a location filter if the specified\nlocation, formatted like this:\n\n\tfilename:lineno in function\n\ncontains Arg[0] as a substring.\n\nFilters can also be applied to goroutine labels:\n\n\tListGoroutineFilter{ Kind: ListGoroutinesFilterLabel, Negated: false, Arg: \"key=value\" }\n\nthis filter will only return goroutines that have a key=value label.\n\nIf arg.GroupBy is not GoroutineFieldNone then the goroutines will\nbe grouped with the specified criterion.\nIf the value of arg.GroupBy is GoroutineLabel goroutines will\nbe grouped by the value of the label with key GroupByKey.\nFor each group a maximum of MaxGroupMembers example goroutines are\nreturned, as well as the total number of goroutines in the group." r["local_vars"] = starlark.NewBuiltin("local_vars", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) From 95dac8f19bcfde94d522a481dcfe39b8640cd498 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Thu, 15 Jun 2023 17:00:59 +0200 Subject: [PATCH 062/114] service,terminal: when libraries don't have debug_info print reason (#3419) Print the reason why libraries don't have debug info in response to the 'libraries' command. --- pkg/terminal/command.go | 3 +++ service/api/conversions.go | 7 ++++++- service/api/types.go | 5 +++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index ef83ea4646..2f8731fbf3 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -2547,6 +2547,9 @@ func libraries(t *Term, ctx callContext, args string) error { d := digits(len(libs)) for i := range libs { fmt.Fprintf(t.stdout, "%"+strconv.Itoa(d)+"d. %#x %s\n", i, libs[i].Address, libs[i].Path) + if libs[i].LoadError != "" { + fmt.Fprintf(t.stdout, " Load error: %s", libs[i].LoadError) + } } return nil } diff --git a/service/api/conversions.go b/service/api/conversions.go index 0d66749eb6..08eb39298e 100644 --- a/service/api/conversions.go +++ b/service/api/conversions.go @@ -431,7 +431,12 @@ func ConvertRegisters(in *op.DwarfRegisters, dwarfRegisterToString func(int, *op // ConvertImage converts proc.Image to api.Image. func ConvertImage(image *proc.Image) Image { - return Image{Path: image.Path, Address: image.StaticBase} + err := image.LoadError() + lerr := "" + if err != nil { + lerr = err.Error() + } + return Image{Path: image.Path, Address: image.StaticBase, LoadError: lerr} } // ConvertDumpState converts proc.DumpState to api.DumpState. diff --git a/service/api/types.go b/service/api/types.go index c4a947c597..e658ad4a91 100644 --- a/service/api/types.go +++ b/service/api/types.go @@ -571,8 +571,9 @@ type Checkpoint struct { // Image represents a loaded shared object (go plugin or shared library) type Image struct { - Path string - Address uint64 + Path string + Address uint64 + LoadError string } // Ancestor represents a goroutine ancestor From 14d9c1881d476e606c6665c80449bfc55db3babd Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Thu, 15 Jun 2023 17:28:35 +0200 Subject: [PATCH 063/114] proc: only print warning when gopclntab can not be read for first image (#3420) Only print the warning that gopclntab can not be read for the first image (i.e. the executable file), also change the returned when neither DWARF nor gopclntab are found to preserve the DWARF error. --- pkg/proc/bininfo.go | 11 +++++++---- pkg/proc/pclntab.go | 5 ++--- pkg/proc/proc_test.go | 1 + 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go index 3deafc6731..9ade7bdcad 100644 --- a/pkg/proc/bininfo.go +++ b/pkg/proc/bininfo.go @@ -1443,16 +1443,19 @@ func loadBinaryInfoElf(bi *BinaryInfo, image *Image, path string, addr uint64, w bi.loadBuildID(image, elfFile) var debugInfoBytes []byte - image.dwarf, err = elfFile.DWARF() - if err != nil { + var dwerr error + image.dwarf, dwerr = elfFile.DWARF() + if dwerr != nil { var sepFile *os.File var serr error sepFile, dwarfFile, serr = bi.openSeparateDebugInfo(image, elfFile, bi.DebugInfoDirectories) if serr != nil { - fmt.Fprintln(os.Stderr, "Warning: no debug info found, some functionality will be missing such as stack traces and variable evaluation.") + if len(bi.Images) <= 1 { + fmt.Fprintln(os.Stderr, "Warning: no debug info found, some functionality will be missing such as stack traces and variable evaluation.") + } symTable, err := readPcLnTableElf(elfFile, path) if err != nil { - return fmt.Errorf("could not create symbol table from %s ", path) + return fmt.Errorf("could not read debug info (%v) and could not read go symbol table (%v)", dwerr, err) } image.symTable = symTable for _, f := range image.symTable.Funcs { diff --git a/pkg/proc/pclntab.go b/pkg/proc/pclntab.go index 3451533233..a2f23b948e 100644 --- a/pkg/proc/pclntab.go +++ b/pkg/proc/pclntab.go @@ -61,10 +61,9 @@ func readPcLnTableElf(exe *elf.File, path string) (*gosym.Table, error) { // Find .gopclntab by magic number even if there is no section label magic := magicNumber(bi.GoVersion) pclntabIndex := bytes.Index(tableData, magic) - if pclntabIndex < 0 { - return nil, fmt.Errorf("could not find magic number in %s ", path) + if pclntabIndex >= 0 { + tableData = tableData[pclntabIndex:] } - tableData = tableData[pclntabIndex:] addr := exe.Section(".text").Addr lineTable := gosym.NewLineTable(tableData, addr) symTable, err := gosym.NewTable([]byte{}, lineTable) diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 10f7876d70..6c5065fbb6 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -3169,6 +3169,7 @@ func TestDebugStripped(t *testing.T) { // Currently only implemented for Linux ELF executables. // TODO(derekparker): Add support for Mach-O and PE. skipUnlessOn(t, "linux only", "linux") + skipOn(t, "does not work with PIE", "pie") withTestProcessArgs("testnextprog", t, "", []string{}, protest.LinkStrip, func(p *proc.Target, grp *proc.TargetGroup, f protest.Fixture) { setFunctionBreakpoint(p, t, "main.main") assertNoError(grp.Continue(), t, "Continue") From 656c4f13df68bae53c3ec1aba71f4a90860b52ed Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Fri, 16 Jun 2023 00:38:19 -0700 Subject: [PATCH 064/114] pkg/proc: improve stripped binary support with PIE (#3421) Take into account static base for PIE binaries. --- pkg/proc/bininfo.go | 10 +++++----- pkg/proc/pclntab.go | 42 +----------------------------------------- pkg/proc/proc_test.go | 1 - 3 files changed, 6 insertions(+), 47 deletions(-) diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go index 9ade7bdcad..fb90d69ae2 100644 --- a/pkg/proc/bininfo.go +++ b/pkg/proc/bininfo.go @@ -609,15 +609,15 @@ func (fn *Function) AllPCs(excludeFile string, excludeLine int) ([]uint64, error return fn.cu.lineInfo.AllPCsBetween(fn.Entry, fn.End-1, excludeFile, excludeLine) } var pcs []uint64 - fnFile, lastLine, _ := fn.cu.image.symTable.PCToLine(fn.Entry) - for pc := fn.Entry; pc < fn.End; pc++ { + fnFile, lastLine, _ := fn.cu.image.symTable.PCToLine(fn.Entry - fn.cu.image.StaticBase) + for pc := fn.Entry - fn.cu.image.StaticBase; pc < fn.End-fn.cu.image.StaticBase; pc++ { f, line, pcfn := fn.cu.image.symTable.PCToLine(pc) if pcfn == nil { continue } if f == fnFile && line > lastLine { lastLine = line - pcs = append(pcs, pc) + pcs = append(pcs, pc+fn.cu.image.StaticBase) } } return pcs, nil @@ -762,7 +762,7 @@ func (bi *BinaryInfo) EntryLineForFunc(fn *Function) (string, int) { func (bi *BinaryInfo) pcToLine(fn *Function, pc uint64) (string, int) { if fn.cu.lineInfo == nil { - f, l, _ := fn.cu.image.symTable.PCToLine(pc) + f, l, _ := fn.cu.image.symTable.PCToLine(pc - fn.cu.image.StaticBase) return f, l } f, l := fn.cu.lineInfo.PCToLine(fn.Entry, pc) @@ -1461,7 +1461,7 @@ func loadBinaryInfoElf(bi *BinaryInfo, image *Image, path string, addr uint64, w for _, f := range image.symTable.Funcs { cu := &compileUnit{} cu.image = image - fn := Function{Name: f.Name, Entry: f.Entry, End: f.End, cu: cu} + fn := Function{Name: f.Name, Entry: f.Entry + image.StaticBase, End: f.End + image.StaticBase, cu: cu} bi.Functions = append(bi.Functions, fn) } for f := range image.symTable.Files { diff --git a/pkg/proc/pclntab.go b/pkg/proc/pclntab.go index a2f23b948e..8f82c0c173 100644 --- a/pkg/proc/pclntab.go +++ b/pkg/proc/pclntab.go @@ -1,40 +1,11 @@ package proc import ( - "bytes" - "debug/buildinfo" "debug/elf" "debug/gosym" - "encoding/binary" "fmt" - "strings" ) -// From go/src/debug/gosym/pclntab.go -const ( - go12magic = 0xfffffffb - go116magic = 0xfffffffa - go118magic = 0xfffffff0 - go120magic = 0xfffffff1 -) - -// Select the magic number based on the Go version -func magicNumber(goVersion string) []byte { - bs := make([]byte, 4) - var magic uint32 - if strings.Compare(goVersion, "go1.20") >= 0 { - magic = go120magic - } else if strings.Compare(goVersion, "go1.18") >= 0 { - magic = go118magic - } else if strings.Compare(goVersion, "go1.16") >= 0 { - magic = go116magic - } else { - magic = go12magic - } - binary.LittleEndian.PutUint32(bs, magic) - return bs -} - func readPcLnTableElf(exe *elf.File, path string) (*gosym.Table, error) { // Default section label is .gopclntab sectionLabel := ".gopclntab" @@ -42,7 +13,7 @@ func readPcLnTableElf(exe *elf.File, path string) (*gosym.Table, error) { section := exe.Section(sectionLabel) if section == nil { // binary may be built with -pie - sectionLabel = ".data.rel.ro" + sectionLabel = ".data.rel.ro.gopclntab" section = exe.Section(sectionLabel) if section == nil { return nil, fmt.Errorf("could not read section .gopclntab") @@ -53,17 +24,6 @@ func readPcLnTableElf(exe *elf.File, path string) (*gosym.Table, error) { return nil, fmt.Errorf("found section but could not read .gopclntab") } - bi, err := buildinfo.ReadFile(path) - if err != nil { - return nil, err - } - - // Find .gopclntab by magic number even if there is no section label - magic := magicNumber(bi.GoVersion) - pclntabIndex := bytes.Index(tableData, magic) - if pclntabIndex >= 0 { - tableData = tableData[pclntabIndex:] - } addr := exe.Section(".text").Addr lineTable := gosym.NewLineTable(tableData, addr) symTable, err := gosym.NewTable([]byte{}, lineTable) diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 6c5065fbb6..10f7876d70 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -3169,7 +3169,6 @@ func TestDebugStripped(t *testing.T) { // Currently only implemented for Linux ELF executables. // TODO(derekparker): Add support for Mach-O and PE. skipUnlessOn(t, "linux only", "linux") - skipOn(t, "does not work with PIE", "pie") withTestProcessArgs("testnextprog", t, "", []string{}, protest.LinkStrip, func(p *proc.Target, grp *proc.TargetGroup, f protest.Fixture) { setFunctionBreakpoint(p, t, "main.main") assertNoError(grp.Continue(), t, "Continue") From 322a138cf23876fba028ce1b22b64207fed81397 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Tue, 20 Jun 2023 15:53:18 +0300 Subject: [PATCH 065/114] service/dap: fix typos in comments (#3426) --- service/dap/server.go | 2 +- service/dap/server_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/service/dap/server.go b/service/dap/server.go index 80ad6570d9..8e8e193659 100644 --- a/service/dap/server.go +++ b/service/dap/server.go @@ -504,7 +504,7 @@ func (s *Session) address() string { // until it encounters an error or EOF, when it sends // a disconnect signal and returns. func (s *Session) ServeDAPCodec() { - // Close conn, but not the debugger in case we are in AcceptMuli mode. + // Close conn, but not the debugger in case we are in AcceptMulti mode. // If not, debugger will be shut down in Stop(). defer s.conn.Close() reader := bufio.NewReader(s.conn) diff --git a/service/dap/server_test.go b/service/dap/server_test.go index 3faee83799..b2a0d53ea5 100644 --- a/service/dap/server_test.go +++ b/service/dap/server_test.go @@ -992,7 +992,7 @@ func checkChildren(t *testing.T, got *dap.VariablesResponse, parentName string, // checkVar is a helper for verifying the values within a VariablesResponse. // -// i - index of the variable within VariablesRespose.Body.Variables array (-1 will search all vars for a match) +// i - index of the variable within VariablesResponse.Body.Variables array (-1 will search all vars for a match) // name - name of the variable // evalName - fully qualified variable name or alternative expression to load this variable // value - the value of the variable From afef1aec605eb605a27f780dc68a492a0fdd1352 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 20 Jun 2023 18:55:30 +0200 Subject: [PATCH 066/114] proc: skip TestDebugStripped on linux/386/pie (#3427) PIEs do not have a .data.rel.ro.gopclntab section on linux/386. Disable the test. --- pkg/proc/proc_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 10f7876d70..0cb84f6bdb 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -3169,6 +3169,7 @@ func TestDebugStripped(t *testing.T) { // Currently only implemented for Linux ELF executables. // TODO(derekparker): Add support for Mach-O and PE. skipUnlessOn(t, "linux only", "linux") + skipOn(t, "not working on linux/386 with PIE", "linux", "386", "pie") withTestProcessArgs("testnextprog", t, "", []string{}, protest.LinkStrip, func(p *proc.Target, grp *proc.TargetGroup, f protest.Fixture) { setFunctionBreakpoint(p, t, "main.main") assertNoError(grp.Continue(), t, "Continue") From 1647fa6b5e029f5785f5288b62120a8d1241f127 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 27 Jun 2023 18:04:52 +0200 Subject: [PATCH 067/114] all: Bump to v1.21.0 (#3428) Thank you @alexandear, @chenhengqi, @cuishuang, @alexsaezm, @suzmue, @spacewander, @ZekeLu, @fche, @andreimatei, @nozzy123nozzy --- CHANGELOG.md | 33 +++++++++++++++++++++++++++++++++ pkg/goversion/compat.go | 2 +- pkg/version/version.go | 2 +- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ce138358f..7e0fe09089 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,39 @@ All notable changes to this project will be documented in this file. This project adheres to Semantic Versioning. +## [1.21.0] 2023-06-23 + +### Added + +- Go 1.21 support (#3370, #3401, @aarzilli) +- Basic debug functionality for stripped executables (#3408, #3421, @derekparker) +- Core dumping on FreeBSD (#3305, @aarzilli) +- Ability to automatically attach to child processes when they are spawned (linux-only) (#3286, #3346, @aarzilli) +- Starlark scripts can now use the time module (#3375, @andreimatei) +- Online help for starlark interpreter (#3388, @aarzilli) +- `dlv trace` has a new option, `--timestamp`, that prints timestamps before every trace event (#3358, @spacewander) + +### Fixed + +- Stepping could hide normal breakpoint hits occurring simultaneously, in rare circumstances (#3287, @aarzilli) +- Internal error when defer locations can not be resolved (#3329, @aarzilli) +- Channels of certain types could be displayed incorrectly (#3362, @aarzilli) +- Formatted time wouldn't always be displayed when using DAP (#3349, @suzmue) +- Function call injection when parameters are in registers (#3365, @ZekeLu) +- Panic in Starlark interface when using partially loaded variables (#3386, @andreimatei) +- Use debug info directories configuration in `dlv trace` (#3405, @nozzy123nozzy) +- Updated DAP version (#3414, @suzmue) + +### Changed + +- Improved eBPF tracepoints (#3325, #3353, #3417, @chenhengqi, @derekparker) +- The name of the default output binary is now randomizes, which fixes some weird behavior when multiple instances of Delve are run simultaneously in the same directory (#3366, @aarzilli) +- Stderr of debuginfod-find is now suppressed (#3381, @fche) +- Better documentation for substitute-path (#3335, @aarzilli) +- `quit -c` will ask for confirmation when breakpoints still exist (#3398, @aarzilli) +- Miscellaneous improvements to documentation and tests (#3326, #3327, #3340, #3341, #3357, #3378, #3376, #3399, #3374, #3426, @alexandear, @cuishuang, @alexsaezm, @andreimatei) + + ## [1.20.2] 2023-04-05 ### Added diff --git a/pkg/goversion/compat.go b/pkg/goversion/compat.go index 5524ac9b5d..8471db796c 100644 --- a/pkg/goversion/compat.go +++ b/pkg/goversion/compat.go @@ -10,7 +10,7 @@ var ( MinSupportedVersionOfGoMajor = 1 MinSupportedVersionOfGoMinor = 18 MaxSupportedVersionOfGoMajor = 1 - MaxSupportedVersionOfGoMinor = 20 + MaxSupportedVersionOfGoMinor = 21 goTooOldErr = fmt.Sprintf("Go version %%s is too old for this version of Delve (minimum supported version %d.%d, suppress this error with --check-go-version=false)", MinSupportedVersionOfGoMajor, MinSupportedVersionOfGoMinor) goTooOldWarn = fmt.Sprintf("WARNING: undefined behavior - Go version %%s is too old for this version of Delve (minimum supported version %d.%d)", MinSupportedVersionOfGoMajor, MinSupportedVersionOfGoMinor) dlvTooOldErr = fmt.Sprintf("Version of Delve is too old for Go version %%s (maximum supported version %d.%d, suppress this error with --check-go-version=false)", MaxSupportedVersionOfGoMajor, MaxSupportedVersionOfGoMinor) diff --git a/pkg/version/version.go b/pkg/version/version.go index e0c278ad8e..fec0d226b2 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -17,7 +17,7 @@ type Version struct { var ( // DelveVersion is the current version of Delve. DelveVersion = Version{ - Major: "1", Minor: "20", Patch: "2", Metadata: "", + Major: "1", Minor: "21", Patch: "0", Metadata: "", Build: "$Id$", } ) From d963eb105719318b723b76634e3b8233b31eaf14 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 27 Jun 2023 18:33:07 +0200 Subject: [PATCH 068/114] proc: read context from sigtrampgo, fixes TestCgoStacktrace2 on 1.21 (#3401) * logflags,proc: flag to log stacktrace execution Add a log flag to write logs about what the stacktracer does. * proc: read context from sigtrampgo, fixes TestCgoStacktrace2 on 1.21 Changes stacktrace code to read the signal context from the arguments of sigtrampgo. Also changes the automatic fatalthrow breakpoint for go 1.21. In combination these two changes fix TestCgoStacktrace2 on Go 1.21 on various platforms. --- Documentation/backend_test_health.md | 16 +- Documentation/usage/dlv_log.md | 1 + cmd/dlv/cmds/commands.go | 1 + pkg/logflags/logflags.go | 12 + pkg/proc/amd64_arch.go | 19 +- pkg/proc/arm64_arch.go | 13 +- pkg/proc/breakpoints.go | 4 +- pkg/proc/core/core_test.go | 23 +- pkg/proc/eval.go | 8 +- pkg/proc/i386_arch.go | 19 +- pkg/proc/proc_test.go | 78 +-- pkg/proc/stack.go | 129 ++++- pkg/proc/stack_sigtramp.go | 773 +++++++++++++++++++++++++++ pkg/proc/stackwatch.go | 2 +- pkg/proc/target.go | 20 +- pkg/proc/target_exec.go | 18 +- pkg/proc/threads.go | 6 +- pkg/proc/variables.go | 2 +- pkg/proc/variables_fuzz_test.go | 2 +- service/debugger/debugger.go | 6 +- 20 files changed, 1004 insertions(+), 148 deletions(-) create mode 100644 pkg/proc/stack_sigtramp.go diff --git a/Documentation/backend_test_health.md b/Documentation/backend_test_health.md index d8b08ee5ce..4fbde47c9b 100644 --- a/Documentation/backend_test_health.md +++ b/Documentation/backend_test_health.md @@ -1,14 +1,12 @@ Tests skipped by each supported backend: -* 386 skipped = 7 - * 1 broken +* 386 skipped = 6 * 3 broken - cgo stacktraces * 3 not implemented -* arm64 skipped = 2 - * 1 broken +* arm64 skipped = 1 * 1 broken - global variable symbolication -* darwin/arm64 skipped = 1 - * 1 broken - cgo stacktraces +* darwin/arm64 skipped = 2 + * 2 broken - cgo stacktraces * darwin/lldb skipped = 1 * 1 upstream issue * freebsd skipped = 4 @@ -17,11 +15,9 @@ Tests skipped by each supported backend: * 1 broken * pie skipped = 2 * 2 upstream issue - https://github.com/golang/go/issues/29322 -* windows skipped = 5 +* windows skipped = 4 * 1 broken * 3 see https://github.com/go-delve/delve/issues/2768 - * 1 upstream issue -* windows/arm64 skipped = 5 +* windows/arm64 skipped = 4 * 3 broken - * 1 broken - cgo stacktraces * 1 broken - step concurrent diff --git a/Documentation/usage/dlv_log.md b/Documentation/usage/dlv_log.md index 39f92e158b..7dc6ed2c48 100644 --- a/Documentation/usage/dlv_log.md +++ b/Documentation/usage/dlv_log.md @@ -19,6 +19,7 @@ names selected from this list: dap Log all DAP messages fncall Log function call protocol minidump Log minidump loading + stack Log stacktracer Additionally --log-dest can be used to specify where the logs should be written. diff --git a/cmd/dlv/cmds/commands.go b/cmd/dlv/cmds/commands.go index 38221c9707..4791755107 100644 --- a/cmd/dlv/cmds/commands.go +++ b/cmd/dlv/cmds/commands.go @@ -412,6 +412,7 @@ names selected from this list: dap Log all DAP messages fncall Log function call protocol minidump Log minidump loading + stack Log stacktracer Additionally --log-dest can be used to specify where the logs should be written. diff --git a/pkg/logflags/logflags.go b/pkg/logflags/logflags.go index 233e9bb920..acf4cb5a7a 100644 --- a/pkg/logflags/logflags.go +++ b/pkg/logflags/logflags.go @@ -26,6 +26,7 @@ var rpc = false var dap = false var fnCall = false var minidump = false +var stack = false var logOut io.WriteCloser @@ -131,6 +132,15 @@ func MinidumpLogger() Logger { return makeLogger(minidump, Fields{"layer": "core", "kind": "minidump"}) } +// Stack returns true if the stacktracer should be logged. +func Stack() bool { + return stack +} + +func StackLogger() Logger { + return makeLogger(stack, Fields{"layer": "core", "kind": "stack"}) +} + // WriteDAPListeningMessage writes the "DAP server listening" message in dap mode. func WriteDAPListeningMessage(addr net.Addr) { writeListeningMessage("DAP", addr) @@ -215,6 +225,8 @@ func Setup(logFlag bool, logstr, logDest string) error { fnCall = true case "minidump": minidump = true + case "stack": + stack = true default: fmt.Fprintf(os.Stderr, "Warning: unknown log output value %q, run 'dlv help log' for usage.\n", logcmd) } diff --git a/pkg/proc/amd64_arch.go b/pkg/proc/amd64_arch.go index 2c6b66f300..dc426ac3d8 100644 --- a/pkg/proc/amd64_arch.go +++ b/pkg/proc/amd64_arch.go @@ -225,25 +225,16 @@ func amd64SwitchStack(it *stackIterator, _ *op.DwarfRegisters) bool { it.switchToGoroutineStack() return true - default: - if it.systemstack && it.top && it.g != nil && strings.HasPrefix(it.frame.Current.Fn.Name, "runtime.") && it.frame.Current.Fn.Name != "runtime.throw" && it.frame.Current.Fn.Name != "runtime.fatalthrow" { - // The runtime switches to the system stack in multiple places. - // This usually happens through a call to runtime.systemstack but there - // are functions that switch to the system stack manually (for example - // runtime.morestack). - // Since we are only interested in printing the system stack for cgo - // calls we switch directly to the goroutine stack if we detect that the - // function at the top of the stack is a runtime function. - // - // The function "runtime.throw" is deliberately excluded from this - // because it can end up in the stack during a cgo call and switching to - // the goroutine stack will exclude all the C functions from the stack - // trace. + case "runtime.newstack", "runtime.systemstack": + if it.systemstack && it.g != nil { it.switchToGoroutineStack() return true } return false + + default: + return false } } diff --git a/pkg/proc/arm64_arch.go b/pkg/proc/arm64_arch.go index 6de8c0bfa5..426fbbce4d 100644 --- a/pkg/proc/arm64_arch.go +++ b/pkg/proc/arm64_arch.go @@ -5,7 +5,6 @@ import ( "encoding/binary" "fmt" "runtime" - "strings" "github.com/go-delve/delve/pkg/dwarf/frame" "github.com/go-delve/delve/pkg/dwarf/op" @@ -269,15 +268,9 @@ func arm64SwitchStack(it *stackIterator, callFrameRegs *op.DwarfRegisters) bool it.switchToGoroutineStack() return true } - default: - if it.systemstack && it.top && it.g != nil && strings.HasPrefix(it.frame.Current.Fn.Name, "runtime.") && it.frame.Current.Fn.Name != "runtime.throw" && it.frame.Current.Fn.Name != "runtime.fatalthrow" { - // The runtime switches to the system stack in multiple places. - // This usually happens through a call to runtime.systemstack but there - // are functions that switch to the system stack manually (for example - // runtime.morestack). - // Since we are only interested in printing the system stack for cgo - // calls we switch directly to the goroutine stack if we detect that the - // function at the top of the stack is a runtime function. + + case "runtime.newstack", "runtime.systemstack": + if it.systemstack && it.g != nil { it.switchToGoroutineStack() return true } diff --git a/pkg/proc/breakpoints.go b/pkg/proc/breakpoints.go index c5910e319c..03fd305ac4 100644 --- a/pkg/proc/breakpoints.go +++ b/pkg/proc/breakpoints.go @@ -285,7 +285,7 @@ func (bpstate *BreakpointState) checkCond(tgt *Target, breaklet *Breaklet, threa nextDeferOk := true if breaklet.Kind&NextDeferBreakpoint != 0 { var err error - frames, err := ThreadStacktrace(thread, 2) + frames, err := ThreadStacktrace(tgt, thread, 2) if err == nil { nextDeferOk, _ = isPanicCall(frames) if !nextDeferOk { @@ -297,7 +297,7 @@ func (bpstate *BreakpointState) checkCond(tgt *Target, breaklet *Breaklet, threa case WatchOutOfScopeBreakpoint: if breaklet.checkPanicCall { - frames, err := ThreadStacktrace(thread, 2) + frames, err := ThreadStacktrace(tgt, thread, 2) if err == nil { ipc, _ := isPanicCall(frames) active = active && ipc diff --git a/pkg/proc/core/core_test.go b/pkg/proc/core/core_test.go index fa86493466..2744bf442e 100644 --- a/pkg/proc/core/core_test.go +++ b/pkg/proc/core/core_test.go @@ -245,8 +245,8 @@ func logRegisters(t *testing.T, regs proc.Registers, arch *proc.Arch) { } func TestCore(t *testing.T) { - if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { - return + if runtime.GOOS != "linux" || runtime.GOARCH == "386" { + t.Skip("unsupported") } if runtime.GOOS == "linux" && os.Getenv("CI") == "true" && buildMode == "pie" { t.Skip("disabled on linux, Github Actions, with PIE buildmode") @@ -268,7 +268,7 @@ func TestCore(t *testing.T) { var panickingStack []proc.Stackframe for _, g := range gs { t.Logf("Goroutine %d", g.ID) - stack, err := g.Stacktrace(10, 0) + stack, err := proc.GoroutineStacktrace(p, g, 10, 0) if err != nil { t.Errorf("Stacktrace() on goroutine %v = %v", g, err) } @@ -315,8 +315,11 @@ func TestCore(t *testing.T) { } func TestCoreFpRegisters(t *testing.T) { - if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { - return + if runtime.GOOS != "linux" || runtime.GOARCH == "386" { + t.Skip("unsupported") + } + if runtime.GOARCH != "amd64" { + t.Skip("test requires amd64") } // in go1.10 the crash is executed on a different thread and registers are // no longer available in the core dump. @@ -334,7 +337,7 @@ func TestCoreFpRegisters(t *testing.T) { var regs proc.Registers for _, thread := range p.ThreadList() { - frames, err := proc.ThreadStacktrace(thread, 10) + frames, err := proc.ThreadStacktrace(p, thread, 10) if err != nil { t.Errorf("ThreadStacktrace for %x = %v", thread.ThreadID(), err) continue @@ -402,8 +405,8 @@ func TestCoreFpRegisters(t *testing.T) { } func TestCoreWithEmptyString(t *testing.T) { - if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { - return + if runtime.GOOS != "linux" || runtime.GOARCH == "386" { + t.Skip("unsupported") } if runtime.GOOS == "linux" && os.Getenv("CI") == "true" && buildMode == "pie" { t.Skip("disabled on linux, Github Actions, with PIE buildmode") @@ -417,7 +420,7 @@ func TestCoreWithEmptyString(t *testing.T) { var mainFrame *proc.Stackframe mainSearch: for _, g := range gs { - stack, err := g.Stacktrace(10, 0) + stack, err := proc.GoroutineStacktrace(p, g, 10, 0) assertNoError(err, t, "Stacktrace()") for _, frame := range stack { if frame.Current.Fn != nil && frame.Current.Fn.Name == "main.main" { @@ -466,7 +469,7 @@ func TestMinidump(t *testing.T) { t.Logf("%d goroutines", len(gs)) foundMain, foundTime := false, false for _, g := range gs { - stack, err := g.Stacktrace(10, 0) + stack, err := proc.GoroutineStacktrace(p, g, 10, 0) if err != nil { t.Errorf("Stacktrace() on goroutine %v = %v", g, err) } diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index 83ff7d3dc9..b3b6db6824 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -90,9 +90,9 @@ func ConvertEvalScope(dbp *Target, gid int64, frame, deferCall int) (*EvalScope, var locs []Stackframe if g != nil { - locs, err = g.Stacktrace(frame+1, opts) + locs, err = GoroutineStacktrace(dbp, g, frame+1, opts) } else { - locs, err = ThreadStacktrace(ct, frame+1) + locs, err = ThreadStacktrace(dbp, ct, frame+1) } if err != nil { return nil, err @@ -145,7 +145,7 @@ func FrameToScope(t *Target, thread MemoryReadWriter, g *G, frames ...Stackframe // ThreadScope returns an EvalScope for the given thread. func ThreadScope(t *Target, thread Thread) (*EvalScope, error) { - locations, err := ThreadStacktrace(thread, 1) + locations, err := ThreadStacktrace(t, thread, 1) if err != nil { return nil, err } @@ -157,7 +157,7 @@ func ThreadScope(t *Target, thread Thread) (*EvalScope, error) { // GoroutineScope returns an EvalScope for the goroutine running on the given thread. func GoroutineScope(t *Target, thread Thread) (*EvalScope, error) { - locations, err := ThreadStacktrace(thread, 1) + locations, err := ThreadStacktrace(t, thread, 1) if err != nil { return nil, err } diff --git a/pkg/proc/i386_arch.go b/pkg/proc/i386_arch.go index aaafad0ecf..2bb53cc381 100644 --- a/pkg/proc/i386_arch.go +++ b/pkg/proc/i386_arch.go @@ -152,25 +152,16 @@ func i386SwitchStack(it *stackIterator, _ *op.DwarfRegisters) bool { it.switchToGoroutineStack() return true - default: - if it.systemstack && it.top && it.g != nil && strings.HasPrefix(it.frame.Current.Fn.Name, "runtime.") && it.frame.Current.Fn.Name != "runtime.throw" && it.frame.Current.Fn.Name != "runtime.fatalthrow" { - // The runtime switches to the system stack in multiple places. - // This usually happens through a call to runtime.systemstack but there - // are functions that switch to the system stack manually (for example - // runtime.morestack). - // Since we are only interested in printing the system stack for cgo - // calls we switch directly to the goroutine stack if we detect that the - // function at the top of the stack is a runtime function. - // - // The function "runtime.throw" is deliberately excluded from this - // because it can end up in the stack during a cgo call and switching to - // the goroutine stack will exclude all the C functions from the stack - // trace. + case "runtime.newstack", "runtime.systemstack": + if it.systemstack && it.g != nil { it.switchToGoroutineStack() return true } return false + + default: + return false } } diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 0cb84f6bdb..5df428a560 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -778,8 +778,8 @@ func TestRuntimeBreakpoint(t *testing.T) { }) } -func returnAddress(thread proc.Thread) (uint64, error) { - locations, err := proc.ThreadStacktrace(thread, 2) +func returnAddress(tgt *proc.Target, thread proc.Thread) (uint64, error) { + locations, err := proc.ThreadStacktrace(tgt, thread, 2) if err != nil { return 0, err } @@ -797,7 +797,7 @@ func TestFindReturnAddress(t *testing.T) { if err != nil { t.Fatal(err) } - addr, err := returnAddress(p.CurrentThread()) + addr, err := returnAddress(p, p.CurrentThread()) if err != nil { t.Fatal(err) } @@ -816,7 +816,7 @@ func TestFindReturnAddressTopOfStackFn(t *testing.T) { if err := grp.Continue(); err != nil { t.Fatal(err) } - if _, err := returnAddress(p.CurrentThread()); err == nil { + if _, err := returnAddress(p, p.CurrentThread()); err == nil { t.Fatal("expected error to be returned") } }) @@ -913,7 +913,7 @@ func TestStacktrace(t *testing.T) { for i := range stacks { assertNoError(grp.Continue(), t, "Continue()") - locations, err := proc.ThreadStacktrace(p.CurrentThread(), 40) + locations, err := proc.ThreadStacktrace(p, p.CurrentThread(), 40) assertNoError(err, t, "Stacktrace()") if len(locations) != len(stacks[i])+2 { @@ -941,7 +941,7 @@ func TestStacktrace2(t *testing.T) { withTestProcess("retstack", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { assertNoError(grp.Continue(), t, "Continue()") - locations, err := proc.ThreadStacktrace(p.CurrentThread(), 40) + locations, err := proc.ThreadStacktrace(p, p.CurrentThread(), 40) assertNoError(err, t, "Stacktrace()") if !stackMatch([]loc{{-1, "main.f"}, {16, "main.main"}}, locations, false) { for i := range locations { @@ -951,7 +951,7 @@ func TestStacktrace2(t *testing.T) { } assertNoError(grp.Continue(), t, "Continue()") - locations, err = proc.ThreadStacktrace(p.CurrentThread(), 40) + locations, err = proc.ThreadStacktrace(p, p.CurrentThread(), 40) assertNoError(err, t, "Stacktrace()") if !stackMatch([]loc{{-1, "main.g"}, {17, "main.main"}}, locations, false) { for i := range locations { @@ -1016,7 +1016,7 @@ func TestStacktraceGoroutine(t *testing.T) { mainCount := 0 for i, g := range gs { - locations, err := g.Stacktrace(40, 0) + locations, err := proc.GoroutineStacktrace(p, g, 40, 0) if err != nil { // On windows we do not have frame information for goroutines doing system calls. t.Logf("Could not retrieve goroutine stack for goid=%d: %v", g.ID, err) @@ -1174,7 +1174,7 @@ func TestIssue239(t *testing.T) { } func findFirstNonRuntimeFrame(p *proc.Target) (proc.Stackframe, error) { - frames, err := proc.ThreadStacktrace(p.CurrentThread(), 10) + frames, err := proc.ThreadStacktrace(p, p.CurrentThread(), 10) if err != nil { return proc.Stackframe{}, err } @@ -1328,7 +1328,7 @@ func TestFrameEvaluation(t *testing.T) { found := make([]bool, 10) for _, g := range gs { frame := -1 - frames, err := g.Stacktrace(40, 0) + frames, err := proc.GoroutineStacktrace(p, g, 40, 0) if err != nil { t.Logf("could not stacktrace goroutine %d: %v\n", g.ID, err) continue @@ -1375,7 +1375,7 @@ func TestFrameEvaluation(t *testing.T) { g, err := proc.GetG(p.CurrentThread()) assertNoError(err, t, "GetG()") - frames, err := g.Stacktrace(40, 0) + frames, err := proc.GoroutineStacktrace(p, g, 40, 0) assertNoError(err, t, "Stacktrace()") t.Logf("Goroutine %d %#v", g.ID, g.Thread) logStacktrace(t, p, frames) @@ -1916,7 +1916,7 @@ func TestIssue332_Part1(t *testing.T) { setFileBreakpoint(p, t, fixture.Source, 8) assertNoError(grp.Continue(), t, "Continue()") assertNoError(grp.Next(), t, "first Next()") - locations, err := proc.ThreadStacktrace(p.CurrentThread(), 2) + locations, err := proc.ThreadStacktrace(p, p.CurrentThread(), 2) assertNoError(err, t, "Stacktrace()") if locations[0].Call.Fn == nil { t.Fatalf("Not on a function") @@ -1943,7 +1943,7 @@ func TestIssue332_Part2(t *testing.T) { // step until we enter changeMe for { assertNoError(grp.Step(), t, "Step()") - locations, err := proc.ThreadStacktrace(p.CurrentThread(), 2) + locations, err := proc.ThreadStacktrace(p, p.CurrentThread(), 2) assertNoError(err, t, "Stacktrace()") if locations[0].Call.Fn == nil { t.Fatalf("Not on a function") @@ -2117,7 +2117,7 @@ func TestIssue462(t *testing.T) { }() assertNoError(grp.Continue(), t, "Continue()") - _, err := proc.ThreadStacktrace(p.CurrentThread(), 40) + _, err := proc.ThreadStacktrace(p, p.CurrentThread(), 40) assertNoError(err, t, "Stacktrace()") }) } @@ -2148,7 +2148,7 @@ func TestNextParked(t *testing.T) { if g.Thread != nil { continue } - frames, _ := g.Stacktrace(5, 0) + frames, _ := proc.GoroutineStacktrace(p, g, 5, 0) for _, frame := range frames { // line 11 is the line where wg.Done is called if frame.Current.Fn != nil && frame.Current.Fn.Name == "main.sayhi" && frame.Current.Line < 11 { @@ -2200,7 +2200,7 @@ func TestStepParked(t *testing.T) { } t.Logf("Parked g is: %v\n", parkedg) - frames, _ := parkedg.Stacktrace(20, 0) + frames, _ := proc.GoroutineStacktrace(p, parkedg, 20, 0) for _, frame := range frames { name := "" if frame.Call.Fn != nil { @@ -2464,7 +2464,7 @@ func TestStepConcurrentDirect(t *testing.T) { // loop exited break } - frames, err := proc.ThreadStacktrace(p.CurrentThread(), 20) + frames, err := proc.ThreadStacktrace(p, p.CurrentThread(), 20) if err != nil { t.Errorf("Could not get stacktrace of goroutine %d\n", p.SelectedGoroutine().ID) } else { @@ -3307,9 +3307,10 @@ func TestCgoStacktrace(t *testing.T) { t.Skip("disabled on macOS with go before version 1.8") } } - skipOn(t, "broken - cgo stacktraces", "386") - skipOn(t, "broken - cgo stacktraces", "windows", "arm64") + if !goversion.VersionAfterOrEqual(runtime.Version(), 1, 21) { + skipOn(t, "broken - cgo stacktraces", "windows", "arm64") + } protest.MustHaveCgo(t) // Tests that: @@ -3351,7 +3352,7 @@ func TestCgoStacktrace(t *testing.T) { } } - frames, err := g.Stacktrace(100, 0) + frames, err := proc.GoroutineStacktrace(p, g, 100, 0) assertNoError(err, t, fmt.Sprintf("Stacktrace at iteration step %d", itidx)) logStacktrace(t, p, frames) @@ -3381,7 +3382,7 @@ func TestCgoStacktrace(t *testing.T) { } // also check that ThreadStacktrace produces the same list of frames - threadFrames, err := proc.ThreadStacktrace(p.CurrentThread(), 100) + threadFrames, err := proc.ThreadStacktrace(p, p.CurrentThread(), 100) assertNoError(err, t, fmt.Sprintf("ThreadStacktrace at iteration step %d", itidx)) if len(threadFrames) != len(frames) { @@ -3443,7 +3444,7 @@ func TestSystemstackStacktrace(t *testing.T) { assertNoError(grp.Continue(), t, "second continue") g, err := proc.GetG(p.CurrentThread()) assertNoError(err, t, "GetG") - frames, err := g.Stacktrace(100, 0) + frames, err := proc.GoroutineStacktrace(p, g, 100, 0) assertNoError(err, t, "stacktrace") logStacktrace(t, p, frames) m := stacktraceCheck(t, []string{"!runtime.startpanic_m", "runtime.gopanic", "main.main"}, frames) @@ -3476,7 +3477,7 @@ func TestSystemstackOnRuntimeNewstack(t *testing.T) { break } } - frames, err := g.Stacktrace(100, 0) + frames, err := proc.GoroutineStacktrace(p, g, 100, 0) assertNoError(err, t, "stacktrace") logStacktrace(t, p, frames) m := stacktraceCheck(t, []string{"!runtime.newstack", "main.main"}, frames) @@ -3495,7 +3496,7 @@ func TestIssue1034(t *testing.T) { withTestProcess("cgostacktest/", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { setFunctionBreakpoint(p, t, "main.main") assertNoError(grp.Continue(), t, "Continue()") - frames, err := p.SelectedGoroutine().Stacktrace(10, 0) + frames, err := proc.GoroutineStacktrace(p, p.SelectedGoroutine(), 10, 0) assertNoError(err, t, "Stacktrace") scope := proc.FrameToScope(p, p.Memory(), nil, frames[2:]...) args, _ := scope.FunctionArguments(normalLoadConfig) @@ -3819,7 +3820,7 @@ func TestInlinedStacktraceAndVariables(t *testing.T) { // first inlined call assertNoError(grp.Continue(), t, "Continue") - frames, err := proc.ThreadStacktrace(p.CurrentThread(), 20) + frames, err := proc.ThreadStacktrace(p, p.CurrentThread(), 20) assertNoError(err, t, "ThreadStacktrace") t.Logf("Stacktrace:\n") for i := range frames { @@ -3846,7 +3847,7 @@ func TestInlinedStacktraceAndVariables(t *testing.T) { // second inlined call assertNoError(grp.Continue(), t, "Continue") - frames, err = proc.ThreadStacktrace(p.CurrentThread(), 20) + frames, err = proc.ThreadStacktrace(p, p.CurrentThread(), 20) assertNoError(err, t, "ThreadStacktrace (2)") t.Logf("Stacktrace 2:\n") for i := range frames { @@ -4161,7 +4162,7 @@ func TestIssue1264(t *testing.T) { func TestReadDefer(t *testing.T) { withTestProcess("deferstack", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { assertNoError(grp.Continue(), t, "Continue") - frames, err := p.SelectedGoroutine().Stacktrace(10, proc.StacktraceReadDefers) + frames, err := proc.GoroutineStacktrace(p, p.SelectedGoroutine(), 10, proc.StacktraceReadDefers) assertNoError(err, t, "Stacktrace") logStacktrace(t, p, frames) @@ -4372,7 +4373,7 @@ func TestIssue1469(t *testing.T) { t.Logf("too many threads running goroutine %d", gid) for _, thread := range gid2thread[gid] { t.Logf("\tThread %d", thread.ThreadID()) - frames, err := proc.ThreadStacktrace(thread, 20) + frames, err := proc.ThreadStacktrace(p, thread, 20) if err != nil { t.Logf("\t\tcould not get stacktrace %v", err) } @@ -4603,9 +4604,12 @@ func TestIssue1615(t *testing.T) { } func TestCgoStacktrace2(t *testing.T) { - skipOn(t, "upstream issue", "windows") - skipOn(t, "broken", "386") - skipOn(t, "broken", "arm64") + if !goversion.VersionAfterOrEqual(runtime.Version(), 1, 21) { + skipOn(t, "upstream issue", "windows") + skipOn(t, "broken", "arm64") + skipOn(t, "broken", "386") + } + skipOn(t, "broken - cgo stacktraces", "darwin", "arm64") protest.MustHaveCgo(t) // If a panic happens during cgo execution the stacktrace should show the C // function that caused the problem. @@ -4614,7 +4618,7 @@ func TestCgoStacktrace2(t *testing.T) { if _, exited := err.(proc.ErrProcessExited); exited { t.Fatal("process exited") } - frames, err := proc.ThreadStacktrace(p.CurrentThread(), 100) + frames, err := proc.ThreadStacktrace(p, p.CurrentThread(), 100) assertNoError(err, t, "Stacktrace()") logStacktrace(t, p, frames) m := stacktraceCheck(t, []string{"C.sigsegv", "C.testfn", "main.main"}, frames) @@ -4725,7 +4729,7 @@ func TestIssue1795(t *testing.T) { assertNoError(grp.Continue(), t, "Continue()") assertLineNumber(p, t, 12, "wrong line number after Continue (1),") assertNoError(grp.Continue(), t, "Continue()") - frames, err := proc.ThreadStacktrace(p.CurrentThread(), 40) + frames, err := proc.ThreadStacktrace(p, p.CurrentThread(), 40) assertNoError(err, t, "ThreadStacktrace()") logStacktrace(t, p, frames) if err := checkFrame(frames[0], "regexp.(*Regexp).doExecute", "", 0, false); err != nil { @@ -5066,7 +5070,7 @@ func TestStepOutPreservesGoroutine(t *testing.T) { bestg := []*proc.G{} for _, g := range gs { t.Logf("stacktracing goroutine %d (%v)\n", g.ID, g.CurrentLoc) - frames, err := g.Stacktrace(20, 0) + frames, err := proc.GoroutineStacktrace(p, g, 20, 0) assertNoError(err, t, "Stacktrace") for _, frame := range frames { if frame.Call.Fn != nil && frame.Call.Fn.Name == "main.coroutine" { @@ -5237,9 +5241,9 @@ func TestDump(t *testing.T) { t.Errorf("Goroutine mismatch\nlive:\t%s\ncore:\t%s", convertGoroutine(gos[i]), convertGoroutine(cgos[i])) } - frames, err := gos[i].Stacktrace(20, 0) + frames, err := proc.GoroutineStacktrace(p, gos[i], 20, 0) assertNoError(err, t, fmt.Sprintf("Stacktrace for goroutine %d - live process", gos[i].ID)) - cframes, err := cgos[i].Stacktrace(20, 0) + cframes, err := proc.GoroutineStacktrace(c, cgos[i], 20, 0) assertNoError(err, t, fmt.Sprintf("Stacktrace for goroutine %d - core dump", gos[i].ID)) if len(frames) != len(cframes) { @@ -5912,7 +5916,7 @@ func TestStacktraceExtlinkMac(t *testing.T) { withTestProcess("issue3194", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { setFunctionBreakpoint(p, t, "main.main") assertNoError(grp.Continue(), t, "First Continue()") - frames, err := proc.ThreadStacktrace(p.CurrentThread(), 10) + frames, err := proc.ThreadStacktrace(p, p.CurrentThread(), 10) assertNoError(err, t, "ThreadStacktrace") logStacktrace(t, p, frames) if len(frames) < 2 || frames[0].Call.Fn.Name != "main.main" || frames[1].Call.Fn.Name != "runtime.main" { diff --git a/pkg/proc/stack.go b/pkg/proc/stack.go index d4791df812..fb6260bcab 100644 --- a/pkg/proc/stack.go +++ b/pkg/proc/stack.go @@ -6,10 +6,12 @@ import ( "fmt" "go/constant" "reflect" + "strings" "github.com/go-delve/delve/pkg/dwarf/frame" "github.com/go-delve/delve/pkg/dwarf/op" "github.com/go-delve/delve/pkg/dwarf/reader" + "github.com/go-delve/delve/pkg/logflags" ) // This code is partly adapted from runtime.gentraceback in @@ -91,7 +93,7 @@ func (frame *Stackframe) FramePointerOffset() int64 { // ThreadStacktrace returns the stack trace for thread. // Note the locations in the array are return addresses not call addresses. -func ThreadStacktrace(thread Thread, depth int) ([]Stackframe, error) { +func ThreadStacktrace(tgt *Target, thread Thread, depth int) ([]Stackframe, error) { g, _ := GetG(thread) if g == nil { regs, err := thread.Registers() @@ -101,13 +103,13 @@ func ThreadStacktrace(thread Thread, depth int) ([]Stackframe, error) { so := thread.BinInfo().PCToImage(regs.PC()) dwarfRegs := *(thread.BinInfo().Arch.RegistersToDwarfRegisters(so.StaticBase, regs)) dwarfRegs.ChangeFunc = thread.SetReg - it := newStackIterator(thread.BinInfo(), thread.ProcessMemory(), dwarfRegs, 0, nil, 0) + it := newStackIterator(tgt, thread.BinInfo(), thread.ProcessMemory(), dwarfRegs, 0, nil, 0) return it.stacktrace(depth) } - return g.Stacktrace(depth, 0) + return GoroutineStacktrace(tgt, g, depth, 0) } -func (g *G) stackIterator(opts StacktraceOptions) (*stackIterator, error) { +func goroutineStackIterator(tgt *Target, g *G, opts StacktraceOptions) (*stackIterator, error) { bi := g.variable.bi if g.Thread != nil { regs, err := g.Thread.Registers() @@ -118,13 +120,13 @@ func (g *G) stackIterator(opts StacktraceOptions) (*stackIterator, error) { dwarfRegs := *(bi.Arch.RegistersToDwarfRegisters(so.StaticBase, regs)) dwarfRegs.ChangeFunc = g.Thread.SetReg return newStackIterator( - bi, g.variable.mem, + tgt, bi, g.variable.mem, dwarfRegs, g.stack.hi, g, opts), nil } so := g.variable.bi.PCToImage(g.PC) return newStackIterator( - bi, g.variable.mem, + tgt, bi, g.variable.mem, bi.Arch.addrAndStackRegsToDwarfRegisters(so.StaticBase, g.PC, g.SP, g.BP, g.LR), g.stack.hi, g, opts), nil } @@ -145,10 +147,10 @@ const ( StacktraceG ) -// Stacktrace returns the stack trace for a goroutine. +// GoroutineStacktrace returns the stack trace for a goroutine. // Note the locations in the array are return addresses not call addresses. -func (g *G) Stacktrace(depth int, opts StacktraceOptions) ([]Stackframe, error) { - it, err := g.stackIterator(opts) +func GoroutineStacktrace(tgt *Target, g *G, depth int, opts StacktraceOptions) ([]Stackframe, error) { + it, err := goroutineStackIterator(tgt, g, opts) if err != nil { return nil, err } @@ -173,13 +175,14 @@ func (n NullAddrError) Error() string { // required to iterate and walk the program // stack. type stackIterator struct { - pc uint64 - top bool - atend bool - frame Stackframe - bi *BinaryInfo - mem MemoryReadWriter - err error + pc uint64 + top bool + atend bool + frame Stackframe + target *Target + bi *BinaryInfo + mem MemoryReadWriter + err error stackhi uint64 systemstack bool @@ -194,12 +197,12 @@ type stackIterator struct { opts StacktraceOptions } -func newStackIterator(bi *BinaryInfo, mem MemoryReadWriter, regs op.DwarfRegisters, stackhi uint64, g *G, opts StacktraceOptions) *stackIterator { +func newStackIterator(tgt *Target, bi *BinaryInfo, mem MemoryReadWriter, regs op.DwarfRegisters, stackhi uint64, g *G, opts StacktraceOptions) *stackIterator { systemstack := true if g != nil { systemstack = g.SystemStack } - return &stackIterator{pc: regs.PC(), regs: regs, top: true, bi: bi, mem: mem, err: nil, atend: false, stackhi: stackhi, systemstack: systemstack, g: g, opts: opts} + return &stackIterator{pc: regs.PC(), regs: regs, top: true, target: tgt, bi: bi, mem: mem, err: nil, atend: false, stackhi: stackhi, systemstack: systemstack, g: g, opts: opts} } // Next points the iterator to the next stack frame. @@ -208,11 +211,54 @@ func (it *stackIterator) Next() bool { return false } + if logflags.Stack() { + logger := logflags.StackLogger() + w := &strings.Builder{} + fmt.Fprintf(w, "current pc = %#x CFA = %#x FrameBase = %#x ", it.pc, it.regs.CFA, it.regs.FrameBase) + for i := 0; i < it.regs.CurrentSize(); i++ { + reg := it.regs.Reg(uint64(i)) + if reg == nil { + continue + } + name, _, _ := it.bi.Arch.DwarfRegisterToString(i, reg) + fmt.Fprintf(w, " %s = %#x", name, reg.Uint64Val) + } + logger.Debugf("%s", w.String()) + } + callFrameRegs, ret, retaddr := it.advanceRegs() it.frame = it.newStackframe(ret, retaddr) + if logflags.Stack() { + logger := logflags.StackLogger() + fnname := "?" + if it.frame.Call.Fn != nil { + fnname = it.frame.Call.Fn.Name + } + logger.Debugf("new frame %#x %s:%d at %s", it.frame.Call.PC, it.frame.Call.File, it.frame.Call.Line, fnname) + } + + if it.frame.Current.Fn != nil && it.frame.Current.Fn.Name == "runtime.sigtrampgo" && it.target != nil { + regs, err := it.readSigtrampgoContext() + if err != nil { + logflags.DebuggerLogger().Errorf("could not read runtime.sigtrampgo context: %v", err) + } else { + so := it.bi.PCToImage(regs.PC()) + regs.StaticBase = so.StaticBase + it.pc = regs.PC() + it.regs = *regs + it.top = false + if it.g != nil && it.g.ID != 0 { + it.systemstack = !(uint64(it.regs.SP()) >= it.g.stack.lo && uint64(it.regs.SP()) < it.g.stack.hi) + } + logflags.StackLogger().Debugf("sigtramp context read") + return true + } + } + if it.opts&StacktraceSimple == 0 { if it.bi.Arch.switchStack(it, &callFrameRegs) { + logflags.StackLogger().Debugf("stack switched") return true } } @@ -398,11 +444,18 @@ func (it *stackIterator) advanceRegs() (callFrameRegs op.DwarfRegisters, ret uin framectx = it.bi.Arch.fixFrameUnwindContext(fde.EstablishFrame(it.pc), it.pc, it.bi) } + logger := logflags.StackLogger() + + logger.Debugf("advanceRegs at %#x", it.pc) + cfareg, err := it.executeFrameRegRule(0, framectx.CFA, 0) if cfareg == nil { it.err = fmt.Errorf("CFA becomes undefined at PC %#x: %v", it.pc, err) return op.DwarfRegisters{}, 0, 0 } + if logflags.Stack() { + logger.Debugf("\tCFA rule %s -> %#x", ruleString(&framectx.CFA, it.bi.Arch.RegnumToString), cfareg.Uint64Val) + } it.regs.CFA = int64(cfareg.Uint64Val) callimage := it.bi.PCToImage(it.pc) @@ -426,7 +479,16 @@ func (it *stackIterator) advanceRegs() (callFrameRegs op.DwarfRegisters, ret uin callFrameRegs.AddReg(callFrameRegs.SPRegNum, cfareg) for i, regRule := range framectx.Regs { + if logflags.Stack() { + logger.Debugf("\t%s rule %s ", it.bi.Arch.RegnumToString(i), ruleString(®Rule, it.bi.Arch.RegnumToString)) + + } reg, err := it.executeFrameRegRule(i, regRule, it.regs.CFA) + if reg != nil { + logger.Debugf("\t\t-> %#x", reg.Uint64Val) + } else { + logger.Debugf("\t\t-> nothing (%v)", err) + } callFrameRegs.AddReg(i, reg) if i == framectx.RetAddrReg { if reg == nil { @@ -701,3 +763,34 @@ func (d *Defer) DeferredFunc(p *Target) (file string, line int, fn *Function) { file, line = bi.EntryLineForFunc(fn) return file, line, fn } + +func ruleString(rule *frame.DWRule, regnumToString func(uint64) string) string { + switch rule.Rule { + case frame.RuleUndefined: + return "undefined" + case frame.RuleSameVal: + return "sameval" + case frame.RuleOffset: + return fmt.Sprintf("[cfa+%d]", rule.Offset) + case frame.RuleValOffset: + return fmt.Sprintf("cfa+%d", rule.Offset) + case frame.RuleRegister: + return fmt.Sprintf("R(%d)", rule.Reg) + case frame.RuleExpression: + w := &strings.Builder{} + op.PrettyPrint(w, rule.Expression, regnumToString) + return fmt.Sprintf("[expr(%s)]", w.String()) + case frame.RuleValExpression: + w := &strings.Builder{} + op.PrettyPrint(w, rule.Expression, regnumToString) + return fmt.Sprintf("expr(%s)", w.String()) + case frame.RuleArchitectural: + return "architectural" + case frame.RuleCFA: + return fmt.Sprintf("R(%d)+%d", rule.Reg, rule.Offset) + case frame.RuleFramePointer: + return fmt.Sprintf("[R(%d)] framepointer", rule.Reg) + default: + return fmt.Sprintf("unknown_rule(%d)", rule.Rule) + } +} diff --git a/pkg/proc/stack_sigtramp.go b/pkg/proc/stack_sigtramp.go new file mode 100644 index 0000000000..da7426747f --- /dev/null +++ b/pkg/proc/stack_sigtramp.go @@ -0,0 +1,773 @@ +package proc + +import ( + "encoding/binary" + "errors" + "fmt" + "unsafe" + + "github.com/go-delve/delve/pkg/dwarf/op" + "github.com/go-delve/delve/pkg/dwarf/regnum" + "github.com/go-delve/delve/pkg/logflags" +) + +// readSigtrampgoContext reads runtime.sigtrampgo context at the specified address +func (it *stackIterator) readSigtrampgoContext() (*op.DwarfRegisters, error) { + logger := logflags.DebuggerLogger() + scope := FrameToScope(it.target, it.mem, it.g, it.frame) + bi := it.bi + + findvar := func(name string) *Variable { + vars, _ := scope.Locals(0) + for i := range vars { + if vars[i].Name == name { + return vars[i] + } + } + return nil + } + + deref := func(v *Variable) (uint64, error) { + v.loadValue(loadSingleValue) + if v.Unreadable != nil { + return 0, fmt.Errorf("could not dereference %s: %v", v.Name, v.Unreadable) + } + if len(v.Children) < 1 { + return 0, fmt.Errorf("could not dereference %s (no children?)", v.Name) + } + logger.Debugf("%s address is %#x", v.Name, v.Children[0].Addr) + return v.Children[0].Addr, nil + } + + getctxaddr := func() (uint64, error) { + ctxvar := findvar("ctx") + if ctxvar == nil { + return 0, errors.New("ctx variable not found") + } + addr, err := deref(ctxvar) + if err != nil { + return 0, err + } + return addr, nil + } + + switch bi.GOOS { + case "windows": + epvar := findvar("ep") + if epvar == nil { + return nil, errors.New("ep variable not found") + } + epaddr, err := deref(epvar) + if err != nil { + return nil, err + } + switch bi.Arch.Name { + case "amd64": + return sigtrampContextWindowsAMD64(it.mem, epaddr) + case "arm64": + return sigtrampContextWindowsARM64(it.mem, epaddr) + default: + return nil, errors.New("not implemented") + } + case "linux": + addr, err := getctxaddr() + if err != nil { + return nil, err + } + + switch bi.Arch.Name { + case "386": + return sigtrampContextLinux386(it.mem, addr) + case "amd64": + return sigtrampContextLinuxAMD64(it.mem, addr) + case "arm64": + return sigtrampContextLinuxARM64(it.mem, addr) + default: + return nil, errors.New("not implemented") + } + case "freebsd": + addr, err := getctxaddr() + if err != nil { + return nil, err + } + return sigtrampContextFreebsdAMD64(it.mem, addr) + case "darwin": + addr, err := getctxaddr() + if err != nil { + return nil, err + } + switch bi.Arch.Name { + case "amd64": + return sigtrampContextDarwinAMD64(it.mem, addr) + case "arm64": + return sigtrampContextDarwinARM64(it.mem, addr) + default: + return nil, errors.New("not implemnted") + } + default: + return nil, errors.New("not implemented") + } +} + +func sigtrampContextLinuxAMD64(mem MemoryReader, addr uint64) (*op.DwarfRegisters, error) { + type stackt struct { + ss_sp uint64 + ss_flags int32 + pad_cgo_0 [4]byte + ss_size uintptr + } + + type mcontext struct { + r8 uint64 + r9 uint64 + r10 uint64 + r11 uint64 + r12 uint64 + r13 uint64 + r14 uint64 + r15 uint64 + rdi uint64 + rsi uint64 + rbp uint64 + rbx uint64 + rdx uint64 + rax uint64 + rcx uint64 + rsp uint64 + rip uint64 + eflags uint64 + cs uint16 + gs uint16 + fs uint16 + __pad0 uint16 + err uint64 + trapno uint64 + oldmask uint64 + cr2 uint64 + fpstate uint64 // pointer + __reserved1 [8]uint64 + } + + type fpxreg struct { + significand [4]uint16 + exponent uint16 + padding [3]uint16 + } + + type fpstate struct { + cwd uint16 + swd uint16 + ftw uint16 + fop uint16 + rip uint64 + rdp uint64 + mxcsr uint32 + mxcr_mask uint32 + _st [8]fpxreg + _xmm [16][4]uint32 + padding [24]uint32 + } + + type ucontext struct { + uc_flags uint64 + uc_link uint64 + uc_stack stackt + uc_mcontext mcontext + uc_sigmask [16]uint64 + __fpregs_mem fpstate + } + + buf := make([]byte, unsafe.Sizeof(ucontext{})) + _, err := mem.ReadMemory(buf, addr) + if err != nil { + return nil, err + } + regs := &(((*ucontext)(unsafe.Pointer(&buf[0]))).uc_mcontext) + dregs := make([]*op.DwarfRegister, regnum.AMD64MaxRegNum()+1) + dregs[regnum.AMD64_R8] = op.DwarfRegisterFromUint64(regs.r8) + dregs[regnum.AMD64_R9] = op.DwarfRegisterFromUint64(regs.r9) + dregs[regnum.AMD64_R10] = op.DwarfRegisterFromUint64(regs.r10) + dregs[regnum.AMD64_R11] = op.DwarfRegisterFromUint64(regs.r11) + dregs[regnum.AMD64_R12] = op.DwarfRegisterFromUint64(regs.r12) + dregs[regnum.AMD64_R13] = op.DwarfRegisterFromUint64(regs.r13) + dregs[regnum.AMD64_R14] = op.DwarfRegisterFromUint64(regs.r14) + dregs[regnum.AMD64_R15] = op.DwarfRegisterFromUint64(regs.r15) + dregs[regnum.AMD64_Rdi] = op.DwarfRegisterFromUint64(regs.rdi) + dregs[regnum.AMD64_Rsi] = op.DwarfRegisterFromUint64(regs.rsi) + dregs[regnum.AMD64_Rbp] = op.DwarfRegisterFromUint64(regs.rbp) + dregs[regnum.AMD64_Rbx] = op.DwarfRegisterFromUint64(regs.rbx) + dregs[regnum.AMD64_Rdx] = op.DwarfRegisterFromUint64(regs.rdx) + dregs[regnum.AMD64_Rax] = op.DwarfRegisterFromUint64(regs.rax) + dregs[regnum.AMD64_Rcx] = op.DwarfRegisterFromUint64(regs.rcx) + dregs[regnum.AMD64_Rsp] = op.DwarfRegisterFromUint64(regs.rsp) + dregs[regnum.AMD64_Rip] = op.DwarfRegisterFromUint64(regs.rip) + dregs[regnum.AMD64_Rflags] = op.DwarfRegisterFromUint64(regs.eflags) + dregs[regnum.AMD64_Cs] = op.DwarfRegisterFromUint64(uint64(regs.cs)) + dregs[regnum.AMD64_Gs] = op.DwarfRegisterFromUint64(uint64(regs.gs)) + dregs[regnum.AMD64_Fs] = op.DwarfRegisterFromUint64(uint64(regs.fs)) + return op.NewDwarfRegisters(0, dregs, binary.LittleEndian, regnum.AMD64_Rip, regnum.AMD64_Rsp, regnum.AMD64_Rbp, 0), nil +} + +func sigtrampContextLinux386(mem MemoryReader, addr uint64) (*op.DwarfRegisters, error) { + type sigcontext struct { + gs uint16 + __gsh uint16 + fs uint16 + __fsh uint16 + es uint16 + __esh uint16 + ds uint16 + __dsh uint16 + edi uint32 + esi uint32 + ebp uint32 + esp uint32 + ebx uint32 + edx uint32 + ecx uint32 + eax uint32 + trapno uint32 + err uint32 + eip uint32 + cs uint16 + __csh uint16 + eflags uint32 + esp_at_signal uint32 + ss uint16 + __ssh uint16 + fpstate uint32 // pointer + oldmask uint32 + cr2 uint32 + } + + type stackt struct { + ss_sp uint32 // pointer + ss_flags int32 + ss_size uint32 + } + + type ucontext struct { + uc_flags uint32 + uc_link uint32 // pointer + uc_stack stackt + uc_mcontext sigcontext + uc_sigmask uint32 + } + + buf := make([]byte, unsafe.Sizeof(ucontext{})) + _, err := mem.ReadMemory(buf, addr) + if err != nil { + return nil, err + } + regs := &(((*ucontext)(unsafe.Pointer(&buf[0]))).uc_mcontext) + dregs := make([]*op.DwarfRegister, regnum.I386MaxRegNum()+1) + dregs[regnum.I386_Gs] = op.DwarfRegisterFromUint64(uint64(regs.gs)) + dregs[regnum.I386_Fs] = op.DwarfRegisterFromUint64(uint64(regs.fs)) + dregs[regnum.I386_Es] = op.DwarfRegisterFromUint64(uint64(regs.es)) + dregs[regnum.I386_Ds] = op.DwarfRegisterFromUint64(uint64(regs.ds)) + dregs[regnum.I386_Edi] = op.DwarfRegisterFromUint64(uint64(regs.edi)) + dregs[regnum.I386_Esi] = op.DwarfRegisterFromUint64(uint64(regs.esi)) + dregs[regnum.I386_Ebp] = op.DwarfRegisterFromUint64(uint64(regs.ebp)) + dregs[regnum.I386_Esp] = op.DwarfRegisterFromUint64(uint64(regs.esp)) + dregs[regnum.I386_Ebx] = op.DwarfRegisterFromUint64(uint64(regs.ebx)) + dregs[regnum.I386_Edx] = op.DwarfRegisterFromUint64(uint64(regs.edx)) + dregs[regnum.I386_Ecx] = op.DwarfRegisterFromUint64(uint64(regs.ecx)) + dregs[regnum.I386_Eax] = op.DwarfRegisterFromUint64(uint64(regs.eax)) + dregs[regnum.I386_Eip] = op.DwarfRegisterFromUint64(uint64(regs.eip)) + dregs[regnum.I386_Cs] = op.DwarfRegisterFromUint64(uint64(regs.cs)) + dregs[regnum.I386_Ss] = op.DwarfRegisterFromUint64(uint64(regs.ss)) + return op.NewDwarfRegisters(0, dregs, binary.LittleEndian, regnum.I386_Eip, regnum.I386_Esp, regnum.I386_Ebp, 0), nil +} + +func sigtrampContextLinuxARM64(mem MemoryReader, addr uint64) (*op.DwarfRegisters, error) { + type sigcontext struct { + fault_address uint64 + regs [31]uint64 + sp uint64 + pc uint64 + pstate uint64 + _pad [8]byte + __reserved [4096]byte + } + + type stackt struct { + ss_sp uint64 // pointer + ss_flags int32 + pad_cgo_0 [4]byte + ss_size uint64 + } + + type ucontext struct { + uc_flags uint64 + uc_link uint64 // pointer + uc_stack stackt + uc_sigmask uint64 + _pad [(1024 - 64) / 8]byte + _pad2 [8]byte + uc_mcontext sigcontext + } + + buf := make([]byte, unsafe.Sizeof(ucontext{})) + _, err := mem.ReadMemory(buf, addr) + if err != nil { + return nil, err + } + regs := &(((*ucontext)(unsafe.Pointer(&buf[0]))).uc_mcontext) + dregs := make([]*op.DwarfRegister, regnum.ARM64MaxRegNum()+1) + for i := range regs.regs { + dregs[regnum.ARM64_X0+i] = op.DwarfRegisterFromUint64(regs.regs[i]) + } + dregs[regnum.ARM64_SP] = op.DwarfRegisterFromUint64(regs.sp) + dregs[regnum.ARM64_PC] = op.DwarfRegisterFromUint64(regs.pc) + return op.NewDwarfRegisters(0, dregs, binary.LittleEndian, regnum.ARM64_PC, regnum.ARM64_SP, regnum.ARM64_BP, regnum.ARM64_LR), nil +} + +func sigtrampContextFreebsdAMD64(mem MemoryReader, addr uint64) (*op.DwarfRegisters, error) { + type mcontext struct { + mc_onstack uint64 + mc_rdi uint64 + mc_rsi uint64 + mc_rdx uint64 + mc_rcx uint64 + mc_r8 uint64 + mc_r9 uint64 + mc_rax uint64 + mc_rbx uint64 + mc_rbp uint64 + mc_r10 uint64 + mc_r11 uint64 + mc_r12 uint64 + mc_r13 uint64 + mc_r14 uint64 + mc_r15 uint64 + mc_trapno uint32 + mc_fs uint16 + mc_gs uint16 + mc_addr uint64 + mc_flags uint32 + mc_es uint16 + mc_ds uint16 + mc_err uint64 + mc_rip uint64 + mc_cs uint64 + mc_rflags uint64 + mc_rsp uint64 + mc_ss uint64 + mc_len uint64 + mc_fpformat uint64 + mc_ownedfp uint64 + mc_fpstate [64]uint64 + mc_fsbase uint64 + mc_gsbase uint64 + mc_xfpustate uint64 + mc_xfpustate_len uint64 + mc_spare [4]uint64 + } + + type ucontext struct { + uc_sigmask struct { + __bits [4]uint32 + } + uc_mcontext mcontext + uc_link uint64 // pointer + uc_stack struct { + ss_sp uintptr + ss_size uintptr + ss_flags int32 + pad_cgo_0 [4]byte + } + uc_flags int32 + __spare__ [4]int32 + pad_cgo_0 [12]byte + } + + buf := make([]byte, unsafe.Sizeof(ucontext{})) + _, err := mem.ReadMemory(buf, addr) + if err != nil { + return nil, err + } + mctxt := ((*ucontext)(unsafe.Pointer(&buf[0]))).uc_mcontext + + dregs := make([]*op.DwarfRegister, regnum.AMD64MaxRegNum()+1) + + dregs[regnum.AMD64_Rdi] = op.DwarfRegisterFromUint64(mctxt.mc_rdi) + dregs[regnum.AMD64_Rsi] = op.DwarfRegisterFromUint64(mctxt.mc_rsi) + dregs[regnum.AMD64_Rdx] = op.DwarfRegisterFromUint64(mctxt.mc_rdx) + dregs[regnum.AMD64_Rcx] = op.DwarfRegisterFromUint64(mctxt.mc_rcx) + dregs[regnum.AMD64_R8] = op.DwarfRegisterFromUint64(mctxt.mc_r8) + dregs[regnum.AMD64_R9] = op.DwarfRegisterFromUint64(mctxt.mc_r9) + dregs[regnum.AMD64_Rax] = op.DwarfRegisterFromUint64(mctxt.mc_rax) + dregs[regnum.AMD64_Rbx] = op.DwarfRegisterFromUint64(mctxt.mc_rbx) + dregs[regnum.AMD64_Rbp] = op.DwarfRegisterFromUint64(mctxt.mc_rbp) + dregs[regnum.AMD64_R10] = op.DwarfRegisterFromUint64(mctxt.mc_r10) + dregs[regnum.AMD64_R11] = op.DwarfRegisterFromUint64(mctxt.mc_r11) + dregs[regnum.AMD64_R12] = op.DwarfRegisterFromUint64(mctxt.mc_r12) + dregs[regnum.AMD64_R13] = op.DwarfRegisterFromUint64(mctxt.mc_r13) + dregs[regnum.AMD64_R14] = op.DwarfRegisterFromUint64(mctxt.mc_r14) + dregs[regnum.AMD64_R15] = op.DwarfRegisterFromUint64(mctxt.mc_r15) + dregs[regnum.AMD64_Fs] = op.DwarfRegisterFromUint64(uint64(mctxt.mc_fs)) + dregs[regnum.AMD64_Gs] = op.DwarfRegisterFromUint64(uint64(mctxt.mc_gs)) + dregs[regnum.AMD64_Es] = op.DwarfRegisterFromUint64(uint64(mctxt.mc_es)) + dregs[regnum.AMD64_Ds] = op.DwarfRegisterFromUint64(uint64(mctxt.mc_ds)) + dregs[regnum.AMD64_Rip] = op.DwarfRegisterFromUint64(mctxt.mc_rip) + dregs[regnum.AMD64_Cs] = op.DwarfRegisterFromUint64(mctxt.mc_cs) + dregs[regnum.AMD64_Rflags] = op.DwarfRegisterFromUint64(mctxt.mc_rflags) + dregs[regnum.AMD64_Rsp] = op.DwarfRegisterFromUint64(mctxt.mc_rsp) + dregs[regnum.AMD64_Ss] = op.DwarfRegisterFromUint64(mctxt.mc_ss) + + return op.NewDwarfRegisters(0, dregs, binary.LittleEndian, regnum.AMD64_Rip, regnum.AMD64_Rsp, regnum.AMD64_Rbp, 0), nil +} + +func sigtrampContextFromExceptionPointers(mem MemoryReader, addr uint64) (uint64, error) { + type exceptionpointers struct { + record uint64 // pointer + context uint64 // pointer + } + buf := make([]byte, unsafe.Sizeof(exceptionpointers{})) + _, err := mem.ReadMemory(buf, addr) + if err != nil { + return 0, err + } + return ((*exceptionpointers)(unsafe.Pointer(&buf[0]))).context, nil + +} + +func sigtrampContextWindowsAMD64(mem MemoryReader, addr uint64) (*op.DwarfRegisters, error) { + type context struct { + p1home uint64 + p2home uint64 + p3home uint64 + p4home uint64 + p5home uint64 + p6home uint64 + contextflags uint32 + mxcsr uint32 + segcs uint16 + segds uint16 + seges uint16 + segfs uint16 + seggs uint16 + segss uint16 + eflags uint32 + dr0 uint64 + dr1 uint64 + dr2 uint64 + dr3 uint64 + dr6 uint64 + dr7 uint64 + rax uint64 + rcx uint64 + rdx uint64 + rbx uint64 + rsp uint64 + rbp uint64 + rsi uint64 + rdi uint64 + r8 uint64 + r9 uint64 + r10 uint64 + r11 uint64 + r12 uint64 + r13 uint64 + r14 uint64 + r15 uint64 + rip uint64 + anon0 [512]byte + vectorregister [26]struct { + low uint64 + high int64 + } + vectorcontrol uint64 + debugcontrol uint64 + lastbranchtorip uint64 + lastbranchfromrip uint64 + lastexceptiontorip uint64 + lastexceptionfromrip uint64 + } + + ctxtaddr, err := sigtrampContextFromExceptionPointers(mem, addr) + if err != nil { + return nil, err + } + buf := make([]byte, unsafe.Sizeof(context{})) + _, err = mem.ReadMemory(buf, ctxtaddr) + if err != nil { + return nil, fmt.Errorf("could not read context: %v", err) + } + ctxt := (*context)(unsafe.Pointer(&buf[0])) + + dregs := make([]*op.DwarfRegister, regnum.AMD64MaxRegNum()+1) + + dregs[regnum.AMD64_Cs] = op.DwarfRegisterFromUint64(uint64(ctxt.segcs)) + dregs[regnum.AMD64_Ds] = op.DwarfRegisterFromUint64(uint64(ctxt.segds)) + dregs[regnum.AMD64_Es] = op.DwarfRegisterFromUint64(uint64(ctxt.seges)) + dregs[regnum.AMD64_Fs] = op.DwarfRegisterFromUint64(uint64(ctxt.segfs)) + dregs[regnum.AMD64_Fs] = op.DwarfRegisterFromUint64(uint64(ctxt.seggs)) + dregs[regnum.AMD64_Ss] = op.DwarfRegisterFromUint64(uint64(ctxt.segss)) + dregs[regnum.AMD64_Rflags] = op.DwarfRegisterFromUint64(uint64(ctxt.eflags)) + dregs[regnum.AMD64_Rax] = op.DwarfRegisterFromUint64(ctxt.rax) + dregs[regnum.AMD64_Rcx] = op.DwarfRegisterFromUint64(ctxt.rcx) + dregs[regnum.AMD64_Rdx] = op.DwarfRegisterFromUint64(ctxt.rdx) + dregs[regnum.AMD64_Rbx] = op.DwarfRegisterFromUint64(ctxt.rbx) + dregs[regnum.AMD64_Rsp] = op.DwarfRegisterFromUint64(ctxt.rsp) + dregs[regnum.AMD64_Rbp] = op.DwarfRegisterFromUint64(ctxt.rbp) + dregs[regnum.AMD64_Rsi] = op.DwarfRegisterFromUint64(ctxt.rsi) + dregs[regnum.AMD64_Rdi] = op.DwarfRegisterFromUint64(ctxt.rdi) + dregs[regnum.AMD64_R8] = op.DwarfRegisterFromUint64(ctxt.r8) + dregs[regnum.AMD64_R9] = op.DwarfRegisterFromUint64(ctxt.r9) + dregs[regnum.AMD64_R10] = op.DwarfRegisterFromUint64(ctxt.r10) + dregs[regnum.AMD64_R11] = op.DwarfRegisterFromUint64(ctxt.r11) + dregs[regnum.AMD64_R12] = op.DwarfRegisterFromUint64(ctxt.r12) + dregs[regnum.AMD64_R13] = op.DwarfRegisterFromUint64(ctxt.r13) + dregs[regnum.AMD64_R14] = op.DwarfRegisterFromUint64(ctxt.r14) + dregs[regnum.AMD64_R15] = op.DwarfRegisterFromUint64(ctxt.r15) + dregs[regnum.AMD64_Rip] = op.DwarfRegisterFromUint64(ctxt.rip) + + return op.NewDwarfRegisters(0, dregs, binary.LittleEndian, regnum.AMD64_Rip, regnum.AMD64_Rsp, regnum.AMD64_Rbp, 0), nil +} + +func sigtrampContextWindowsARM64(mem MemoryReader, addr uint64) (*op.DwarfRegisters, error) { + type context struct { + contextflags uint32 + cpsr uint32 + x [31]uint64 // fp is x[29], lr is x[30] + xsp uint64 + pc uint64 + v [32]struct { + low uint64 + high int64 + } + fpcr uint32 + fpsr uint32 + bcr [8]uint32 + bvr [8]uint64 + wcr [2]uint32 + wvr [2]uint64 + } + + ctxtaddr, err := sigtrampContextFromExceptionPointers(mem, addr) + if err != nil { + return nil, err + } + buf := make([]byte, unsafe.Sizeof(context{})) + _, err = mem.ReadMemory(buf, ctxtaddr) + if err != nil { + return nil, fmt.Errorf("could not read context: %v", err) + } + ctxt := (*context)(unsafe.Pointer(&buf[0])) + + dregs := make([]*op.DwarfRegister, regnum.ARM64MaxRegNum()+1) + for i := range ctxt.x { + dregs[regnum.ARM64_X0+i] = op.DwarfRegisterFromUint64(ctxt.x[i]) + } + dregs[regnum.ARM64_SP] = op.DwarfRegisterFromUint64(ctxt.xsp) + dregs[regnum.ARM64_PC] = op.DwarfRegisterFromUint64(ctxt.pc) + return op.NewDwarfRegisters(0, dregs, binary.LittleEndian, regnum.ARM64_PC, regnum.ARM64_SP, regnum.ARM64_BP, regnum.ARM64_LR), nil +} + +func sigtrampContextDarwinAMD64(mem MemoryReader, addr uint64) (*op.DwarfRegisters, error) { + type ucontext struct { + uc_onstack int32 + uc_sigmask uint32 + uc_stack struct { + ss_sp uint64 // pointer + ss_size uintptr + ss_flags int32 + pad_cgo_0 [4]byte + } + uc_link uint64 // pointer + uc_mcsize uint64 + uc_mcontext uint64 // pointer + } + + type regmmst struct { + mmst_reg [10]int8 + mmst_rsrv [6]int8 + } + + type regxmm struct { + xmm_reg [16]int8 + } + + type floatstate64 struct { + fpu_reserved [2]int32 + fpu_fcw [2]byte + fpu_fsw [2]byte + fpu_ftw uint8 + fpu_rsrv1 uint8 + fpu_fop uint16 + fpu_ip uint32 + fpu_cs uint16 + fpu_rsrv2 uint16 + fpu_dp uint32 + fpu_ds uint16 + fpu_rsrv3 uint16 + fpu_mxcsr uint32 + fpu_mxcsrmask uint32 + fpu_stmm0 regmmst + fpu_stmm1 regmmst + fpu_stmm2 regmmst + fpu_stmm3 regmmst + fpu_stmm4 regmmst + fpu_stmm5 regmmst + fpu_stmm6 regmmst + fpu_stmm7 regmmst + fpu_xmm0 regxmm + fpu_xmm1 regxmm + fpu_xmm2 regxmm + fpu_xmm3 regxmm + fpu_xmm4 regxmm + fpu_xmm5 regxmm + fpu_xmm6 regxmm + fpu_xmm7 regxmm + fpu_xmm8 regxmm + fpu_xmm9 regxmm + fpu_xmm10 regxmm + fpu_xmm11 regxmm + fpu_xmm12 regxmm + fpu_xmm13 regxmm + fpu_xmm14 regxmm + fpu_xmm15 regxmm + fpu_rsrv4 [96]int8 + fpu_reserved1 int32 + } + + type regs64 struct { + rax uint64 + rbx uint64 + rcx uint64 + rdx uint64 + rdi uint64 + rsi uint64 + rbp uint64 + rsp uint64 + r8 uint64 + r9 uint64 + r10 uint64 + r11 uint64 + r12 uint64 + r13 uint64 + r14 uint64 + r15 uint64 + rip uint64 + rflags uint64 + cs uint64 + fs uint64 + gs uint64 + } + + type mcontext64 struct { + es struct { + trapno uint16 + cpu uint16 + err uint32 + faultvaddr uint64 + } + ss regs64 + fs floatstate64 + pad_cgo_0 [4]byte + } + + buf := make([]byte, unsafe.Sizeof(ucontext{})) + _, err := mem.ReadMemory(buf, addr) + if err != nil { + return nil, err + } + mctxtaddr := ((*ucontext)(unsafe.Pointer(&buf[0]))).uc_mcontext + + buf = make([]byte, unsafe.Sizeof(mcontext64{})) + _, err = mem.ReadMemory(buf, mctxtaddr) + if err != nil { + return nil, err + } + + ss := ((*mcontext64)(unsafe.Pointer(&buf[0]))).ss + dregs := make([]*op.DwarfRegister, regnum.AMD64MaxRegNum()+1) + dregs[regnum.AMD64_Rax] = op.DwarfRegisterFromUint64(ss.rax) + dregs[regnum.AMD64_Rbx] = op.DwarfRegisterFromUint64(ss.rbx) + dregs[regnum.AMD64_Rcx] = op.DwarfRegisterFromUint64(ss.rcx) + dregs[regnum.AMD64_Rdx] = op.DwarfRegisterFromUint64(ss.rdx) + dregs[regnum.AMD64_Rdi] = op.DwarfRegisterFromUint64(ss.rdi) + dregs[regnum.AMD64_Rsi] = op.DwarfRegisterFromUint64(ss.rsi) + dregs[regnum.AMD64_Rbp] = op.DwarfRegisterFromUint64(ss.rbp) + dregs[regnum.AMD64_Rsp] = op.DwarfRegisterFromUint64(ss.rsp) + dregs[regnum.AMD64_R8] = op.DwarfRegisterFromUint64(ss.r8) + dregs[regnum.AMD64_R9] = op.DwarfRegisterFromUint64(ss.r9) + dregs[regnum.AMD64_R10] = op.DwarfRegisterFromUint64(ss.r10) + dregs[regnum.AMD64_R11] = op.DwarfRegisterFromUint64(ss.r11) + dregs[regnum.AMD64_R12] = op.DwarfRegisterFromUint64(ss.r12) + dregs[regnum.AMD64_R13] = op.DwarfRegisterFromUint64(ss.r13) + dregs[regnum.AMD64_R14] = op.DwarfRegisterFromUint64(ss.r14) + dregs[regnum.AMD64_R15] = op.DwarfRegisterFromUint64(ss.r15) + dregs[regnum.AMD64_Rip] = op.DwarfRegisterFromUint64(ss.rip) + dregs[regnum.AMD64_Rflags] = op.DwarfRegisterFromUint64(ss.rflags) + dregs[regnum.AMD64_Cs] = op.DwarfRegisterFromUint64(ss.cs) + dregs[regnum.AMD64_Fs] = op.DwarfRegisterFromUint64(ss.fs) + dregs[regnum.AMD64_Gs] = op.DwarfRegisterFromUint64(ss.gs) + + return op.NewDwarfRegisters(0, dregs, binary.LittleEndian, regnum.AMD64_Rip, regnum.AMD64_Rsp, regnum.AMD64_Rbp, 0), nil +} + +func sigtrampContextDarwinARM64(mem MemoryReader, addr uint64) (*op.DwarfRegisters, error) { + type ucontext struct { + uc_onstack int32 + uc_sigmask uint32 + uc_stack struct { + ss_sp uint64 // pointer + ss_size uintptr + ss_flags int32 + pad_cgo_0 [4]byte + } + uc_link uint64 // pointer + uc_mcsize uint64 + uc_mcontext uint64 // pointer + } + + type regs64 struct { + x [29]uint64 // registers x0 to x28 + fp uint64 // frame register, x29 + lr uint64 // link register, x30 + sp uint64 // stack pointer, x31 + pc uint64 // program counter + cpsr uint32 // current program status register + __pad uint32 + } + + type mcontext64 struct { + es struct { + far uint64 // virtual fault addr + esr uint32 // exception syndrome + exc uint32 // number of arm exception taken + } + ss regs64 + ns struct { + v [64]uint64 // actually [32]uint128 + fpsr uint32 + fpcr uint32 + } + } + + buf := make([]byte, unsafe.Sizeof(ucontext{})) + _, err := mem.ReadMemory(buf, addr) + if err != nil { + return nil, err + } + mctxtaddr := ((*ucontext)(unsafe.Pointer(&buf[0]))).uc_mcontext + + buf = make([]byte, unsafe.Sizeof(mcontext64{})) + _, err = mem.ReadMemory(buf, mctxtaddr) + if err != nil { + return nil, err + } + + ss := ((*mcontext64)(unsafe.Pointer(&buf[0]))).ss + dregs := make([]*op.DwarfRegister, regnum.ARM64MaxRegNum()+1) + for i := range ss.x { + dregs[regnum.ARM64_X0+i] = op.DwarfRegisterFromUint64(ss.x[i]) + } + dregs[regnum.ARM64_BP] = op.DwarfRegisterFromUint64(ss.fp) + dregs[regnum.ARM64_LR] = op.DwarfRegisterFromUint64(ss.lr) + dregs[regnum.ARM64_SP] = op.DwarfRegisterFromUint64(ss.sp) + dregs[regnum.ARM64_PC] = op.DwarfRegisterFromUint64(ss.pc) + return op.NewDwarfRegisters(0, dregs, binary.LittleEndian, regnum.ARM64_PC, regnum.ARM64_SP, regnum.ARM64_BP, regnum.ARM64_LR), nil +} diff --git a/pkg/proc/stackwatch.go b/pkg/proc/stackwatch.go index 0e87427299..64f9dc027b 100644 --- a/pkg/proc/stackwatch.go +++ b/pkg/proc/stackwatch.go @@ -33,7 +33,7 @@ func (t *Target) setStackWatchBreakpoints(scope *EvalScope, watchpoint *Breakpoi return true, nil } - topframe, retframe, err := topframe(scope.g, nil) + topframe, retframe, err := topframe(t, scope.g, nil) if err != nil { return err } diff --git a/pkg/proc/target.go b/pkg/proc/target.go index 0a77344852..91d18584ac 100644 --- a/pkg/proc/target.go +++ b/pkg/proc/target.go @@ -396,20 +396,18 @@ func (t *Target) createUnrecoveredPanicBreakpoint() { // createFatalThrowBreakpoint creates the a breakpoint as runtime.fatalthrow. func (t *Target) createFatalThrowBreakpoint() { - fatalpcs, err := FindFunctionLocation(t.Process, "runtime.throw", 0) - if err == nil { - bp, err := t.SetBreakpoint(fatalThrowID, fatalpcs[0], UserBreakpoint, nil) - if err == nil { - bp.Logical.Name = FatalThrow - } - } - fatalpcs, err = FindFunctionLocation(t.Process, "runtime.fatal", 0) - if err == nil { - bp, err := t.SetBreakpoint(fatalThrowID, fatalpcs[0], UserBreakpoint, nil) + setFatalThrow := func(pcs []uint64, err error) { if err == nil { - bp.Logical.Name = FatalThrow + bp, err := t.SetBreakpoint(fatalThrowID, pcs[0], UserBreakpoint, nil) + if err == nil { + bp.Logical.Name = FatalThrow + } } } + setFatalThrow(FindFunctionLocation(t.Process, "runtime.throw", 0)) + setFatalThrow(FindFunctionLocation(t.Process, "runtime.fatal", 0)) + setFatalThrow(FindFunctionLocation(t.Process, "runtime.winthrow", 0)) + setFatalThrow(FindFunctionLocation(t.Process, "runtime.fatalsignal", 0)) } // createPluginOpenBreakpoint creates a breakpoint at the return instruction diff --git a/pkg/proc/target_exec.go b/pkg/proc/target_exec.go index 6473429409..dae0afae04 100644 --- a/pkg/proc/target_exec.go +++ b/pkg/proc/target_exec.go @@ -469,7 +469,7 @@ func (grp *TargetGroup) StepOut() error { selg := dbp.SelectedGoroutine() curthread := dbp.CurrentThread() - topframe, retframe, err := topframe(selg, curthread) + topframe, retframe, err := topframe(dbp, selg, curthread) if err != nil { return err } @@ -511,7 +511,7 @@ func (grp *TargetGroup) StepOut() error { } if topframe.Ret != 0 { - topframe, retframe := skipAutogeneratedWrappersOut(selg, curthread, &topframe, &retframe) + topframe, retframe := skipAutogeneratedWrappersOut(grp.Selected, selg, curthread, &topframe, &retframe) retFrameCond := astutil.And(sameGCond, frameoffCondition(retframe)) bp, err := allowDuplicateBreakpoint(dbp.SetBreakpoint(0, retframe.Current.PC, NextBreakpoint, retFrameCond)) if err != nil { @@ -600,7 +600,7 @@ func next(dbp *Target, stepInto, inlinedStepOut bool) error { backward := dbp.recman.GetDirection() == Backward selg := dbp.SelectedGoroutine() curthread := dbp.CurrentThread() - topframe, retframe, err := topframe(selg, curthread) + topframe, retframe, err := topframe(dbp, selg, curthread) if err != nil { return err } @@ -748,7 +748,7 @@ func next(dbp *Target, stepInto, inlinedStepOut bool) error { } if !topframe.Inlined { - topframe, retframe := skipAutogeneratedWrappersOut(selg, curthread, &topframe, &retframe) + topframe, retframe := skipAutogeneratedWrappersOut(dbp, selg, curthread, &topframe, &retframe) retFrameCond := astutil.And(sameGCond, frameoffCondition(retframe)) // Add a breakpoint on the return address for the current frame. @@ -1036,7 +1036,7 @@ func skipAutogeneratedWrappersIn(p Process, startfn *Function, startpc uint64) ( // step out breakpoint. // See genwrapper in: $GOROOT/src/cmd/compile/internal/gc/subr.go // It also skips runtime.deferreturn frames (which are only ever on the stack on Go 1.18 or later) -func skipAutogeneratedWrappersOut(g *G, thread Thread, startTopframe, startRetframe *Stackframe) (topframe, retframe *Stackframe) { +func skipAutogeneratedWrappersOut(tgt *Target, g *G, thread Thread, startTopframe, startRetframe *Stackframe) (topframe, retframe *Stackframe) { topframe, retframe = startTopframe, startRetframe if startTopframe.Ret == 0 { return @@ -1054,9 +1054,9 @@ func skipAutogeneratedWrappersOut(g *G, thread Thread, startTopframe, startRetfr var err error var frames []Stackframe if g == nil { - frames, err = ThreadStacktrace(thread, maxSkipAutogeneratedWrappers) + frames, err = ThreadStacktrace(tgt, thread, maxSkipAutogeneratedWrappers) } else { - frames, err = g.Stacktrace(maxSkipAutogeneratedWrappers, 0) + frames, err = GoroutineStacktrace(tgt, g, maxSkipAutogeneratedWrappers, 0) } if err != nil { return @@ -1152,9 +1152,9 @@ func stepOutReverse(p *Target, topframe, retframe Stackframe, sameGCond ast.Expr var frames []Stackframe if selg == nil { - frames, err = ThreadStacktrace(curthread, 3) + frames, err = ThreadStacktrace(p, curthread, 3) } else { - frames, err = selg.Stacktrace(3, 0) + frames, err = GoroutineStacktrace(p, selg, 3, 0) } if err != nil { return err diff --git a/pkg/proc/threads.go b/pkg/proc/threads.go index 8b55e4c7a8..df83a7af5a 100644 --- a/pkg/proc/threads.go +++ b/pkg/proc/threads.go @@ -67,14 +67,14 @@ func (t *CommonThread) ReturnValues(cfg LoadConfig) []*Variable { } // topframe returns the two topmost frames of g, or thread if g is nil. -func topframe(g *G, thread Thread) (Stackframe, Stackframe, error) { +func topframe(tgt *Target, g *G, thread Thread) (Stackframe, Stackframe, error) { var frames []Stackframe var err error if g == nil { - frames, err = ThreadStacktrace(thread, 1) + frames, err = ThreadStacktrace(tgt, thread, 1) } else { - frames, err = g.Stacktrace(1, StacktraceReadDefers) + frames, err = GoroutineStacktrace(tgt, g, 1, StacktraceReadDefers) } if err != nil { return Stackframe{}, Stackframe{}, err diff --git a/pkg/proc/variables.go b/pkg/proc/variables.go index 26b4fb713d..59ec833afa 100644 --- a/pkg/proc/variables.go +++ b/pkg/proc/variables.go @@ -497,7 +497,7 @@ func (g *G) Defer() *Defer { // UserCurrent returns the location the users code is at, // or was at before entering a runtime function. func (g *G) UserCurrent() Location { - it, err := g.stackIterator(0) + it, err := goroutineStackIterator(nil, g, 0) if err != nil { return g.CurrentLoc } diff --git a/pkg/proc/variables_fuzz_test.go b/pkg/proc/variables_fuzz_test.go index 07e28d3736..55ec7a26df 100644 --- a/pkg/proc/variables_fuzz_test.go +++ b/pkg/proc/variables_fuzz_test.go @@ -127,7 +127,7 @@ func doFuzzEvalExpressionSetup(f *testing.F) { // 3. Run all the test cases on the core file, register which memory addresses are read - frames, err := c.SelectedGoroutine().Stacktrace(2, 0) + frames, err := proc.GoroutineStacktrace(c, c.SelectedGoroutine(), 2, 0) assertNoError(err, f, "Stacktrace") mem := c.Memory() diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index 4a100e9b97..8c22db2cab 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -1331,7 +1331,7 @@ func (d *Debugger) collectBreakpointInformation(apiThread *api.Thread, thread pr } if bp.Stacktrace > 0 { - rawlocs, err := proc.ThreadStacktrace(thread, bp.Stacktrace) + rawlocs, err := proc.ThreadStacktrace(tgt, thread, bp.Stacktrace) if err != nil { return err } @@ -1757,9 +1757,9 @@ func (d *Debugger) Stacktrace(goroutineID int64, depth int, opts api.StacktraceO } if g == nil { - return proc.ThreadStacktrace(d.target.Selected.CurrentThread(), depth) + return proc.ThreadStacktrace(d.target.Selected, d.target.Selected.CurrentThread(), depth) } else { - return g.Stacktrace(depth, proc.StacktraceOptions(opts)) + return proc.GoroutineStacktrace(d.target.Selected, g, depth, proc.StacktraceOptions(opts)) } } From 53998cbb18934f6a62a13f676e106ade79d6d9a7 Mon Sep 17 00:00:00 2001 From: ttoad Date: Wed, 5 Jul 2023 23:39:01 +0800 Subject: [PATCH 069/114] pkg/proc,service/*: Supports sending output to clients when running programs remotely (#3253) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * wip: Support sending output when remote debug * wip: Support local output and remote output * wip: fix stderr and stdout assignment error * wip: optimize code * wip: Only if outputMode is "remote" is the redirected console output * wip: Redirected debugMode output(Not tested on windows) * wip: support remote debugging output redirection of windows * wip: real-time write back output * wip: support for windows * wip: fix windows remote debug not output * wip: fix truncated output redirection * wip: delete printfln * wip: use debugger.Config to pass redirect(macOS) * wip: use debugger.Config to pass redirect(linux) * wip: Change redirect to a concrete type * wip: s.wg.wait before sending "terminated" * wip: add proc/redirect test(darwin and linux) * Merge branch 'master' of github.com:tttoad/delve into feat-console * wip: Fix test failure on windows * fix: undefined: proc.Redirects * fix: compile failure * wip: Remove useless code * fix: filename error * fix: os.file not close * test: add server_test.redirect * fix: Remove 'eol' from end of file * fix: gdbserial: File not closed in file mode. (in reality, gdbserial will never use file mode) * feat: Remove "only-remote". Fix spelling mistakes. * fix: spelling mistakes * refactor: redirect * fix: stdout and stderr are not set to default values * fix: Restore code logic for rr.openRedirects() * fix: Optimization Code * fix: utiltest * fix: execpt out * fix: Resource release for redirects * fix: build failure * fix: clean->clear * fix: build failure * fix: test failure * fix: Optimization Code * style: remove useless code * refactor: namedpipe * refactor: namedpipe, launch ... * fix: freebsd compile failure * fix: proc_darwin compile failure * style: remove useless code * feat: add d.config.Stdxx check on debug.Restart * style: formatting and adding comments * style: formatting and adding comments * feat: add d.config.Stdxx check on debug.Restart * style: namedpipe->redirector * style: namedPipe->redirector --------- Co-authored-by: 李翔 --- _fixtures/out_redirect.go | 13 +++ cmd/dlv/cmds/commands.go | 5 +- pkg/proc/gdbserial/rr.go | 48 +++++++----- pkg/proc/gdbserial/rr_test.go | 2 +- pkg/proc/native/nonative_darwin.go | 2 +- pkg/proc/native/proc.go | 33 ++++---- pkg/proc/native/proc_darwin.go | 2 +- pkg/proc/native/proc_freebsd.go | 4 +- pkg/proc/native/proc_linux.go | 4 +- pkg/proc/native/proc_windows.go | 4 +- pkg/proc/proc_linux_test.go | 3 +- pkg/proc/proc_test.go | 6 +- pkg/proc/redirect.go | 12 +++ pkg/proc/redirector_other.go | 59 ++++++++++++++ pkg/proc/redirector_windows.go | 15 ++++ service/dap/server.go | 122 +++++++++++++++++++++++++++-- service/dap/server_test.go | 93 ++++++++++++++++++++++ service/dap/types.go | 3 + service/debugger/debugger.go | 31 +++++--- service/test/integration2_test.go | 4 +- 20 files changed, 399 insertions(+), 66 deletions(-) create mode 100644 _fixtures/out_redirect.go create mode 100644 pkg/proc/redirect.go create mode 100644 pkg/proc/redirector_other.go create mode 100644 pkg/proc/redirector_windows.go diff --git a/_fixtures/out_redirect.go b/_fixtures/out_redirect.go new file mode 100644 index 0000000000..faa48e926f --- /dev/null +++ b/_fixtures/out_redirect.go @@ -0,0 +1,13 @@ +package main + +import ( + "fmt" + "os" +) + +func main() { + fmt.Println("hello world!") + fmt.Fprintf(os.Stdout, "hello world!") + fmt.Fprintf(os.Stderr, "hello world!\n") + fmt.Fprintf(os.Stderr, "hello world! error!") +} diff --git a/cmd/dlv/cmds/commands.go b/cmd/dlv/cmds/commands.go index 4791755107..b8d2d7eb72 100644 --- a/cmd/dlv/cmds/commands.go +++ b/cmd/dlv/cmds/commands.go @@ -20,6 +20,7 @@ import ( "github.com/go-delve/delve/pkg/gobuild" "github.com/go-delve/delve/pkg/goversion" "github.com/go-delve/delve/pkg/logflags" + "github.com/go-delve/delve/pkg/proc" "github.com/go-delve/delve/pkg/terminal" "github.com/go-delve/delve/pkg/version" "github.com/go-delve/delve/service" @@ -1015,7 +1016,9 @@ func execute(attachPid int, processArgs []string, conf *config.Config, coreFile DebugInfoDirectories: conf.DebugInfoDirectories, CheckGoVersion: checkGoVersion, TTY: tty, - Redirects: redirects, + Stdin: redirects[0], + Stdout: proc.OutputRedirect{Path: redirects[1]}, + Stderr: proc.OutputRedirect{Path: redirects[2]}, DisableASLR: disableASLR, RrOnProcessPid: rrOnProcessPid, }, diff --git a/pkg/proc/gdbserial/rr.go b/pkg/proc/gdbserial/rr.go index 364191241f..d04f42a1fc 100644 --- a/pkg/proc/gdbserial/rr.go +++ b/pkg/proc/gdbserial/rr.go @@ -20,7 +20,7 @@ import ( // program. Returns a run function which will actually record the program, a // stop function which will prematurely terminate the recording of the // program. -func RecordAsync(cmd []string, wd string, quiet bool, redirects [3]string) (run func() (string, error), stop func() error, err error) { +func RecordAsync(cmd []string, wd string, quiet bool, stdin string, stdout proc.OutputRedirect, stderr proc.OutputRedirect) (run func() (string, error), stop func() error, err error) { if err := checkRRAvailable(); err != nil { return nil, nil, err } @@ -35,7 +35,7 @@ func RecordAsync(cmd []string, wd string, quiet bool, redirects [3]string) (run args = append(args, cmd...) rrcmd := exec.Command("rr", args...) var closefn func() - rrcmd.Stdin, rrcmd.Stdout, rrcmd.Stderr, closefn, err = openRedirects(redirects, quiet) + rrcmd.Stdin, rrcmd.Stdout, rrcmd.Stderr, closefn, err = openRedirects(stdin, stdout, stderr, quiet) if err != nil { return nil, nil, err } @@ -63,11 +63,11 @@ func RecordAsync(cmd []string, wd string, quiet bool, redirects [3]string) (run return run, stop, nil } -func openRedirects(redirects [3]string, quiet bool) (stdin, stdout, stderr *os.File, closefn func(), err error) { +func openRedirects(stdinPath string, stdoutOR proc.OutputRedirect, stderrOR proc.OutputRedirect, quiet bool) (stdin, stdout, stderr *os.File, closefn func(), err error) { toclose := []*os.File{} - if redirects[0] != "" { - stdin, err = os.Open(redirects[0]) + if stdinPath != "" { + stdin, err = os.Open(stdinPath) if err != nil { return nil, nil, nil, nil, err } @@ -76,27 +76,33 @@ func openRedirects(redirects [3]string, quiet bool) (stdin, stdout, stderr *os.F stdin = os.Stdin } - create := func(path string, dflt *os.File) *os.File { - if path == "" { - if quiet { - return nil + create := func(redirect proc.OutputRedirect, dflt *os.File) (f *os.File) { + if redirect.Path != "" { + f, err = os.Create(redirect.Path) + if f != nil { + toclose = append(toclose, f) } - return dflt + + return f + } else if redirect.File != nil { + toclose = append(toclose, redirect.File) + + return redirect.File } - var f *os.File - f, err = os.Create(path) - if f != nil { - toclose = append(toclose, f) + + if quiet { + return nil } - return f + + return dflt } - stdout = create(redirects[1], os.Stdout) + stdout = create(stdoutOR, os.Stdout) if err != nil { return nil, nil, nil, nil, err } - stderr = create(redirects[2], os.Stderr) + stderr = create(stderrOR, os.Stderr) if err != nil { return nil, nil, nil, nil, err } @@ -112,8 +118,8 @@ func openRedirects(redirects [3]string, quiet bool) (stdin, stdout, stderr *os.F // Record uses rr to record the execution of the specified program and // returns the trace directory's path. -func Record(cmd []string, wd string, quiet bool, redirects [3]string) (tracedir string, err error) { - run, _, err := RecordAsync(cmd, wd, quiet, redirects) +func Record(cmd []string, wd string, quiet bool, stdin string, stdout proc.OutputRedirect, stderr proc.OutputRedirect) (tracedir string, err error) { + run, _, err := RecordAsync(cmd, wd, quiet, stdin, stdout, stderr) if err != nil { return "", err } @@ -288,8 +294,8 @@ func rrParseGdbCommand(line string) rrInit { } // RecordAndReplay acts like calling Record and then Replay. -func RecordAndReplay(cmd []string, wd string, quiet bool, debugInfoDirs []string, redirects [3]string) (*proc.TargetGroup, string, error) { - tracedir, err := Record(cmd, wd, quiet, redirects) +func RecordAndReplay(cmd []string, wd string, quiet bool, debugInfoDirs []string, stdin string, stdout proc.OutputRedirect, stderr proc.OutputRedirect) (*proc.TargetGroup, string, error) { + tracedir, err := Record(cmd, wd, quiet, stdin, stdout, stderr) if tracedir == "" { return nil, "", err } diff --git a/pkg/proc/gdbserial/rr_test.go b/pkg/proc/gdbserial/rr_test.go index 9c96280f65..3eb97119c6 100644 --- a/pkg/proc/gdbserial/rr_test.go +++ b/pkg/proc/gdbserial/rr_test.go @@ -30,7 +30,7 @@ func withTestRecording(name string, t testing.TB, fn func(grp *proc.TargetGroup, t.Skip("test skipped, rr not found") } t.Log("recording") - grp, tracedir, err := gdbserial.RecordAndReplay([]string{fixture.Path}, ".", true, []string{}, [3]string{}) + grp, tracedir, err := gdbserial.RecordAndReplay([]string{fixture.Path}, ".", true, []string{}, "", proc.OutputRedirect{}, proc.OutputRedirect{}) if err != nil { t.Fatal("Launch():", err) } diff --git a/pkg/proc/native/nonative_darwin.go b/pkg/proc/native/nonative_darwin.go index b60ee32d54..616fe869eb 100644 --- a/pkg/proc/native/nonative_darwin.go +++ b/pkg/proc/native/nonative_darwin.go @@ -16,7 +16,7 @@ import ( var ErrNativeBackendDisabled = errors.New("native backend disabled during compilation") // Launch returns ErrNativeBackendDisabled. -func Launch(_ []string, _ string, _ proc.LaunchFlags, _ []string, _ string, _ [3]string) (*proc.TargetGroup, error) { +func Launch(_ []string, _ string, _ proc.LaunchFlags, _ []string, _ string, _ string, _ proc.OutputRedirect, _ proc.OutputRedirect) (*proc.TargetGroup, error) { return nil, ErrNativeBackendDisabled } diff --git a/pkg/proc/native/proc.go b/pkg/proc/native/proc.go index c886202b99..da5d88650e 100644 --- a/pkg/proc/native/proc.go +++ b/pkg/proc/native/proc.go @@ -376,11 +376,11 @@ func (dbp *nativeProcess) writeSoftwareBreakpoint(thread *nativeThread, addr uin return err } -func openRedirects(redirects [3]string, foreground bool) (stdin, stdout, stderr *os.File, closefn func(), err error) { +func openRedirects(stdinPath string, stdoutOR proc.OutputRedirect, stderrOR proc.OutputRedirect, foreground bool) (stdin, stdout, stderr *os.File, closefn func(), err error) { toclose := []*os.File{} - if redirects[0] != "" { - stdin, err = os.Open(redirects[0]) + if stdinPath != "" { + stdin, err = os.Open(stdinPath) if err != nil { return nil, nil, nil, nil, err } @@ -389,24 +389,29 @@ func openRedirects(redirects [3]string, foreground bool) (stdin, stdout, stderr stdin = os.Stdin } - create := func(path string, dflt *os.File) *os.File { - if path == "" { - return dflt - } - var f *os.File - f, err = os.Create(path) - if f != nil { - toclose = append(toclose, f) + create := func(redirect proc.OutputRedirect, dflt *os.File) (f *os.File) { + if redirect.Path != "" { + f, err = os.Create(redirect.Path) + if f != nil { + toclose = append(toclose, f) + } + + return f + } else if redirect.File != nil { + toclose = append(toclose, redirect.File) + + return redirect.File } - return f + + return dflt } - stdout = create(redirects[1], os.Stdout) + stdout = create(stdoutOR, os.Stdout) if err != nil { return nil, nil, nil, nil, err } - stderr = create(redirects[2], os.Stderr) + stderr = create(stderrOR, os.Stderr) if err != nil { return nil, nil, nil, nil, err } diff --git a/pkg/proc/native/proc_darwin.go b/pkg/proc/native/proc_darwin.go index 83eb2dbc7d..7a2bbb9b57 100644 --- a/pkg/proc/native/proc_darwin.go +++ b/pkg/proc/native/proc_darwin.go @@ -42,7 +42,7 @@ func (os *osProcessDetails) Close() {} // custom fork/exec process in order to take advantage of // PT_SIGEXC on Darwin which will turn Unix signals into // Mach exceptions. -func Launch(cmd []string, wd string, flags proc.LaunchFlags, _ []string, _ string, _ [3]string) (*proc.TargetGroup, error) { +func Launch(cmd []string, wd string, flags proc.LaunchFlags, _ []string, _ string, _ string, _ proc.OutputRedirect, _ proc.OutputRedirect) (*proc.TargetGroup, error) { argv0Go, err := filepath.Abs(cmd[0]) if err != nil { return nil, err diff --git a/pkg/proc/native/proc_freebsd.go b/pkg/proc/native/proc_freebsd.go index 51f4889658..23f64ed6cc 100644 --- a/pkg/proc/native/proc_freebsd.go +++ b/pkg/proc/native/proc_freebsd.go @@ -55,7 +55,7 @@ func (os *osProcessDetails) Close() {} // to be supplied to that process. `wd` is working directory of the program. // If the DWARF information cannot be found in the binary, Delve will look // for external debug files in the directories passed in. -func Launch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs []string, tty string, redirects [3]string) (*proc.TargetGroup, error) { +func Launch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs []string, tty string, stdinPath string, stdoutOR proc.OutputRedirect, stderrOR proc.OutputRedirect) (*proc.TargetGroup, error) { var ( process *exec.Cmd err error @@ -63,7 +63,7 @@ func Launch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs []str foreground := flags&proc.LaunchForeground != 0 - stdin, stdout, stderr, closefn, err := openRedirects(redirects, foreground) + stdin, stdout, stderr, closefn, err := openRedirects(stdinPath, stdoutOR, stderrOR, foreground) if err != nil { return nil, err } diff --git a/pkg/proc/native/proc_linux.go b/pkg/proc/native/proc_linux.go index a05ecb24f7..b61e663d51 100644 --- a/pkg/proc/native/proc_linux.go +++ b/pkg/proc/native/proc_linux.go @@ -62,7 +62,7 @@ func (os *osProcessDetails) Close() { // to be supplied to that process. `wd` is working directory of the program. // If the DWARF information cannot be found in the binary, Delve will look // for external debug files in the directories passed in. -func Launch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs []string, tty string, redirects [3]string) (*proc.TargetGroup, error) { +func Launch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs []string, tty string, stdinPath string, stdoutOR proc.OutputRedirect, stderrOR proc.OutputRedirect) (*proc.TargetGroup, error) { var ( process *exec.Cmd err error @@ -70,7 +70,7 @@ func Launch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs []str foreground := flags&proc.LaunchForeground != 0 - stdin, stdout, stderr, closefn, err := openRedirects(redirects, foreground) + stdin, stdout, stderr, closefn, err := openRedirects(stdinPath, stdoutOR, stderrOR, foreground) if err != nil { return nil, err } diff --git a/pkg/proc/native/proc_windows.go b/pkg/proc/native/proc_windows.go index 318533e83b..9cbf326430 100644 --- a/pkg/proc/native/proc_windows.go +++ b/pkg/proc/native/proc_windows.go @@ -25,12 +25,12 @@ type osProcessDetails struct { func (os *osProcessDetails) Close() {} // Launch creates and begins debugging a new process. -func Launch(cmd []string, wd string, flags proc.LaunchFlags, _ []string, _ string, redirects [3]string) (*proc.TargetGroup, error) { +func Launch(cmd []string, wd string, flags proc.LaunchFlags, _ []string, _ string, stdinPath string, stdoutOR proc.OutputRedirect, stderrOR proc.OutputRedirect) (*proc.TargetGroup, error) { argv0Go := cmd[0] env := proc.DisableAsyncPreemptEnv() - stdin, stdout, stderr, closefn, err := openRedirects(redirects, true) + stdin, stdout, stderr, closefn, err := openRedirects(stdinPath, stdoutOR, stderrOR, true) if err != nil { return nil, err } diff --git a/pkg/proc/proc_linux_test.go b/pkg/proc/proc_linux_test.go index d10e17ff4c..f105ce9148 100644 --- a/pkg/proc/proc_linux_test.go +++ b/pkg/proc/proc_linux_test.go @@ -6,6 +6,7 @@ import ( "path/filepath" "testing" + "github.com/go-delve/delve/pkg/proc" "github.com/go-delve/delve/pkg/proc/native" protest "github.com/go-delve/delve/pkg/proc/test" ) @@ -14,7 +15,7 @@ func TestLoadingExternalDebugInfo(t *testing.T) { fixture := protest.BuildFixture("locationsprog", 0) defer os.Remove(fixture.Path) stripAndCopyDebugInfo(fixture, t) - p, err := native.Launch(append([]string{fixture.Path}, ""), "", 0, []string{filepath.Dir(fixture.Path)}, "", [3]string{}) + p, err := native.Launch(append([]string{fixture.Path}, ""), "", 0, []string{filepath.Dir(fixture.Path)}, "", "", proc.OutputRedirect{}, proc.OutputRedirect{}) if err != nil { t.Fatal(err) } diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 5df428a560..ec12303f69 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -103,13 +103,13 @@ func withTestProcessArgs(name string, t testing.TB, wd string, args []string, bu switch testBackend { case "native": - grp, err = native.Launch(append([]string{fixture.Path}, args...), wd, 0, []string{}, "", [3]string{}) + grp, err = native.Launch(append([]string{fixture.Path}, args...), wd, 0, []string{}, "", "", proc.OutputRedirect{}, proc.OutputRedirect{}) case "lldb": grp, err = gdbserial.LLDBLaunch(append([]string{fixture.Path}, args...), wd, 0, []string{}, "", [3]string{}) case "rr": protest.MustHaveRecordingAllowed(t) t.Log("recording") - grp, tracedir, err = gdbserial.RecordAndReplay(append([]string{fixture.Path}, args...), wd, true, []string{}, [3]string{}) + grp, tracedir, err = gdbserial.RecordAndReplay(append([]string{fixture.Path}, args...), wd, true, []string{}, "", proc.OutputRedirect{}, proc.OutputRedirect{}) t.Logf("replaying %q", tracedir) default: t.Fatal("unknown backend") @@ -2247,7 +2247,7 @@ func TestUnsupportedArch(t *testing.T) { switch testBackend { case "native": - p, err = native.Launch([]string{outfile}, ".", 0, []string{}, "", [3]string{}) + p, err = native.Launch([]string{outfile}, ".", 0, []string{}, "", "", proc.OutputRedirect{}, proc.OutputRedirect{}) case "lldb": p, err = gdbserial.LLDBLaunch([]string{outfile}, ".", 0, []string{}, "", [3]string{}) default: diff --git a/pkg/proc/redirect.go b/pkg/proc/redirect.go new file mode 100644 index 0000000000..278d8853ff --- /dev/null +++ b/pkg/proc/redirect.go @@ -0,0 +1,12 @@ +package proc + +import "os" + +// OutputRedirect Specifies where the target program output will be redirected to. +// Only one of "Path" and "File" should be set. +type OutputRedirect struct { + // Path File path. + Path string + // File Redirect file. + File *os.File +} diff --git a/pkg/proc/redirector_other.go b/pkg/proc/redirector_other.go new file mode 100644 index 0000000000..2203eb71f8 --- /dev/null +++ b/pkg/proc/redirector_other.go @@ -0,0 +1,59 @@ +//go:build !windows +// +build !windows + +package proc + +import ( + "crypto/rand" + "encoding/hex" + "io" + "os" + "path/filepath" + "syscall" +) + +type openOnRead struct { + path string + rd io.ReadCloser +} + +func (oor *openOnRead) Read(p []byte) (n int, err error) { + if oor.rd != nil { + return oor.rd.Read(p) + } + + fh, err := os.OpenFile(oor.path, os.O_RDONLY, os.ModeNamedPipe) + if err != nil { + return 0, err + } + + oor.rd = fh + return oor.rd.Read(p) +} + +func (oor *openOnRead) Close() error { + defer os.Remove(oor.path) + + fh, _ := os.OpenFile(oor.path, os.O_WRONLY|syscall.O_NONBLOCK, 0) + if fh != nil { + fh.Close() + } + + return oor.rd.Close() +} + +func Redirector() (reader io.ReadCloser, output OutputRedirect, err error) { + r := make([]byte, 4) + if _, err = rand.Read(r); err != nil { + return reader, output, err + } + + var path = filepath.Join(os.TempDir(), hex.EncodeToString(r)) + + if err = syscall.Mkfifo(path, 0o600); err != nil { + _ = os.Remove(path) + return reader, output, err + } + + return &openOnRead{path: path}, OutputRedirect{Path: path}, nil +} diff --git a/pkg/proc/redirector_windows.go b/pkg/proc/redirector_windows.go new file mode 100644 index 0000000000..edd74a7ac3 --- /dev/null +++ b/pkg/proc/redirector_windows.go @@ -0,0 +1,15 @@ +//go:build windows +// +build windows + +package proc + +import ( + "io" + "os" +) + +func Redirector() (reader io.ReadCloser, output OutputRedirect, err error) { + reader, output.File, err = os.Pipe() + + return reader, output, err +} diff --git a/service/dap/server.go b/service/dap/server.go index 8e8e193659..75a06e98b2 100644 --- a/service/dap/server.go +++ b/service/dap/server.go @@ -157,6 +157,15 @@ type Session struct { // changeStateMu must be held for a request to protect itself from another goroutine // changing the state of the running process at the same time. changeStateMu sync.Mutex + + // stdoutReader the programs's stdout. + stdoutReader io.ReadCloser + + // stderrReader the program's stderr. + stderrReader io.ReadCloser + + // preTerminatedWG the WaitGroup that needs to wait before sending a terminated event. + preTerminatedWG sync.WaitGroup } // Config is all the information needed to start the debugger, handle @@ -969,7 +978,7 @@ func (s *Session) onLaunchRequest(request *dap.LaunchRequest) { var cmd string var out []byte - var err error + switch args.Mode { case "debug": cmd, out, err = gobuild.GoBuildCombinedOutput(args.Output, []string{args.Program}, args.BuildFlags) @@ -1020,9 +1029,51 @@ func (s *Session) onLaunchRequest(request *dap.LaunchRequest) { argsToLog.Cwd, _ = filepath.Abs(args.Cwd) s.config.log.Debugf("launching binary '%s' with config: %s", debugbinary, prettyPrint(argsToLog)) + var redirected = false + switch args.OutputMode { + case "remote": + redirected = true + case "local", "": + // noting + default: + s.sendShowUserErrorResponse(request.Request, FailedToLaunch, "Failed to launch", + fmt.Sprintf("invalid debug configuration - unsupported 'outputMode' attribute %q", args.OutputMode)) + return + } + + redirectedFunc := func(stdoutReader io.ReadCloser, stderrReader io.ReadCloser) { + runReadFunc := func(reader io.ReadCloser, category string) { + defer s.preTerminatedWG.Done() + defer reader.Close() + // Read output from `reader` and send to client + var out [1024]byte + for { + n, err := reader.Read(out[:]) + if err != nil { + if errors.Is(io.EOF, err) { + return + } + s.config.log.Errorf("failed read by %s - %v ", category, err) + return + } + outs := string(out[:n]) + s.send(&dap.OutputEvent{ + Event: *newEvent("output"), + Body: dap.OutputEventBody{ + Output: outs, + Category: category, + }}) + } + } + + s.preTerminatedWG.Add(2) + go runReadFunc(stdoutReader, "stdout") + go runReadFunc(stderrReader, "stderr") + } + if args.NoDebug { s.mu.Lock() - cmd, err := s.newNoDebugProcess(debugbinary, args.Args, s.config.Debugger.WorkingDir) + cmd, err := s.newNoDebugProcess(debugbinary, args.Args, s.config.Debugger.WorkingDir, redirected) s.mu.Unlock() if err != nil { s.sendShowUserErrorResponse(request.Request, FailedToLaunch, "Failed to launch", err.Error()) @@ -1034,9 +1085,14 @@ func (s *Session) onLaunchRequest(request *dap.LaunchRequest) { // Start the program on a different goroutine, so we can listen for disconnect request. go func() { + if redirected { + redirectedFunc(s.stdoutReader, s.stderrReader) + } + if err := cmd.Wait(); err != nil { s.config.log.Debugf("program exited with error: %v", err) } + close(s.noDebugProcess.exited) s.logToConsole(proc.ErrProcessExited{Pid: cmd.ProcessState.Pid(), Status: cmd.ProcessState.ExitCode()}.Error()) s.send(&dap.TerminatedEvent{Event: *newEvent("terminated")}) @@ -1044,6 +1100,35 @@ func (s *Session) onLaunchRequest(request *dap.LaunchRequest) { return } + var clear func() + if redirected { + var ( + readers [2]io.ReadCloser + outputRedirects [2]proc.OutputRedirect + ) + + for i := 0; i < 2; i++ { + readers[i], outputRedirects[i], err = proc.Redirector() + if err != nil { + s.sendShowUserErrorResponse(request.Request, InternalError, "Internal Error", + fmt.Sprintf("failed to generate stdio pipes - %v", err)) + return + } + } + + s.config.Debugger.Stdout = outputRedirects[0] + s.config.Debugger.Stderr = outputRedirects[1] + + redirectedFunc(readers[0], readers[1]) + clear = func() { + for index := range readers { + if closeErr := readers[index].Close(); closeErr != nil { + s.config.log.Warnf("failed to clear redirects - %v", closeErr) + } + } + } + } + func() { s.mu.Lock() defer s.mu.Unlock() // Make sure to unlock in case of panic that will become internal error @@ -1054,6 +1139,9 @@ func (s *Session) onLaunchRequest(request *dap.LaunchRequest) { gobuild.Remove(s.binaryToRemove) } s.sendShowUserErrorResponse(request.Request, FailedToLaunch, "Failed to launch", err.Error()) + if redirected { + clear() + } return } // Enable StepBack controls on supported backends @@ -1080,15 +1168,30 @@ func (s *Session) getPackageDir(pkg string) string { // newNoDebugProcess is called from onLaunchRequest (run goroutine) and // requires holding mu lock. It prepares process exec.Cmd to be started. -func (s *Session) newNoDebugProcess(program string, targetArgs []string, wd string) (*exec.Cmd, error) { +func (s *Session) newNoDebugProcess(program string, targetArgs []string, wd string, redirected bool) (cmd *exec.Cmd, err error) { if s.noDebugProcess != nil { return nil, fmt.Errorf("another launch request is in progress") } - cmd := exec.Command(program, targetArgs...) - cmd.Stdout, cmd.Stderr, cmd.Stdin, cmd.Dir = os.Stdout, os.Stderr, os.Stdin, wd - if err := cmd.Start(); err != nil { + + cmd = exec.Command(program, targetArgs...) + cmd.Stdin, cmd.Dir = os.Stdin, wd + + if redirected { + if s.stderrReader, err = cmd.StderrPipe(); err != nil { + return nil, err + } + + if s.stdoutReader, err = cmd.StdoutPipe(); err != nil { + return nil, err + } + } else { + cmd.Stdout, cmd.Stderr = os.Stdin, os.Stderr + } + + if err = cmd.Start(); err != nil { return nil, err } + s.noDebugProcess = &process{Cmd: cmd, exited: make(chan struct{})} return cmd, nil } @@ -1135,9 +1238,11 @@ func (s *Session) onDisconnectRequest(request *dap.DisconnectRequest) { status := "halted" if s.isRunningCmd() { status = "running" - } else if s, err := s.debugger.State(false); processExited(s, err) { + } else if state, err := s.debugger.State(false); processExited(state, err) { status = "exited" + s.preTerminatedWG.Wait() } + s.logToConsole(fmt.Sprintf("Closing client session, but leaving multi-client DAP server at %s with debuggee %s", s.config.Listener.Addr().String(), status)) s.send(&dap.DisconnectResponse{Response: *newResponse(request.Request)}) s.send(&dap.TerminatedEvent{Event: *newEvent("terminated")}) @@ -1171,6 +1276,7 @@ func (s *Session) onDisconnectRequest(request *dap.DisconnectRequest) { } else { s.send(&dap.DisconnectResponse{Response: *newResponse(request.Request)}) } + s.preTerminatedWG.Wait() // The debugging session has ended, so we send a terminated event. s.send(&dap.TerminatedEvent{Event: *newEvent("terminated")}) } @@ -2724,6 +2830,7 @@ func (s *Session) doCall(goid, frame int, expr string) (*api.DebuggerState, []*p GoroutineID: int64(goid), }, nil) if processExited(state, err) { + s.preTerminatedWG.Wait() e := &dap.TerminatedEvent{Event: *newEvent("terminated")} s.send(e) return nil, nil, errors.New("terminated") @@ -3470,6 +3577,7 @@ func (s *Session) runUntilStopAndNotify(command string, allowNextStateChange cha } if processExited(state, err) { + s.preTerminatedWG.Wait() s.send(&dap.TerminatedEvent{Event: *newEvent("terminated")}) return } diff --git a/service/dap/server_test.go b/service/dap/server_test.go index b2a0d53ea5..5618100ad3 100644 --- a/service/dap/server_test.go +++ b/service/dap/server_test.go @@ -2,6 +2,7 @@ package dap import ( "bufio" + "bytes" "flag" "fmt" "io" @@ -7366,6 +7367,98 @@ func TestDisassembleCgo(t *testing.T) { protest.AllNonOptimized, true) } + +func TestRedirect(t *testing.T) { + runTest(t, "out_redirect", func(client *daptest.Client, fixture protest.Fixture) { + // 1 >> initialize, << initialize + client.InitializeRequest() + initResp := client.ExpectInitializeResponseAndCapabilities(t) + if initResp.Seq != 0 || initResp.RequestSeq != 1 { + t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=1", initResp) + } + + // 2 >> launch, << initialized, << launch + client.LaunchRequestWithArgs(map[string]interface{}{ + "request": "launch", + "mode": "debug", + "program": fixture.Source, + "outputMode": "remote", + }) + initEvent := client.ExpectInitializedEvent(t) + if initEvent.Seq != 0 { + t.Errorf("\ngot %#v\nwant Seq=0", initEvent) + } + launchResp := client.ExpectLaunchResponse(t) + if launchResp.Seq != 0 || launchResp.RequestSeq != 2 { + t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=2", launchResp) + } + + // 5 >> configurationDone, << stopped, << configurationDone + client.ConfigurationDoneRequest() + + cdResp := client.ExpectConfigurationDoneResponse(t) + if cdResp.Seq != 0 || cdResp.RequestSeq != 3 { + t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=5", cdResp) + } + + // 6 << output, << terminated + var ( + stdout = bytes.NewBufferString("") + stderr = bytes.NewBufferString("") + ) + + terminatedPoint: + for { + message := client.ExpectMessage(t) + switch m := message.(type) { + case *dap.OutputEvent: + switch m.Body.Category { + case "stdout": + stdout.WriteString(m.Body.Output) + case "stderr": + stderr.WriteString(m.Body.Output) + default: + t.Errorf("\ngot %#v\nwant Category='stdout' or 'stderr'", m) + } + case *dap.TerminatedEvent: + break terminatedPoint + default: + t.Errorf("\n got %#v, want *dap.OutputEvent or *dap.TerminateResponse", m) + } + } + + var ( + expectStdout = "hello world!\nhello world!" + expectStderr = "hello world!\nhello world! error!" + ) + + // check output + if expectStdout != stdout.String() { + t.Errorf("\n got stdout: len:%d\n%s\nwant: len:%d\n%s", stdout.Len(), stdout.String(), len(expectStdout), string(expectStdout)) + } + + if expectStderr != stderr.String() { + t.Errorf("\n got stderr: len:%d \n%s\nwant: len:%d\n%s", stderr.Len(), stderr.String(), len(expectStderr), string(expectStderr)) + } + + // 7 >> disconnect, << disconnect + client.DisconnectRequest() + oep := client.ExpectOutputEventProcessExited(t, 0) + if oep.Seq != 0 || oep.Body.Category != "console" { + t.Errorf("\ngot %#v\nwant Seq=0 Category='console'", oep) + } + oed := client.ExpectOutputEventDetaching(t) + if oed.Seq != 0 || oed.Body.Category != "console" { + t.Errorf("\ngot %#v\nwant Seq=0 Category='console'", oed) + } + dResp := client.ExpectDisconnectResponse(t) + if dResp.Seq != 0 || dResp.RequestSeq != 4 { + t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=43", dResp) + } + client.ExpectTerminatedEvent(t) + }) +} + // Helper functions for checking ErrorMessage field values. func checkErrorMessageId(er *dap.ErrorMessage, id int) bool { diff --git a/service/dap/types.go b/service/dap/types.go index 5876ae6c78..aa5bbab65b 100644 --- a/service/dap/types.go +++ b/service/dap/types.go @@ -148,6 +148,9 @@ type LaunchConfig struct { // reference to other environment variables is not supported. Env map[string]*string `json:"env,omitempty"` + // The output mode specifies how to handle the program's output. + OutputMode string `json:"outputMode,omitempty"` + LaunchAttachCommonConfig } diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index 8c22db2cab..b666bb7439 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -136,8 +136,14 @@ type Config struct { // ExecuteKind contains the kind of the executed program. ExecuteKind ExecuteKind - // Redirects specifies redirect rules for stdin, stdout and stderr - Redirects [3]string + // Stdin Redirect file path for stdin + Stdin string + + // Redirects specifies redirect rules for stdout + Stdout proc.OutputRedirect + + // Redirects specifies redirect rules for stderr + Stderr proc.OutputRedirect // DisableASLR disables ASLR DisableASLR bool @@ -259,16 +265,16 @@ func (d *Debugger) Launch(processArgs []string, wd string) (*proc.TargetGroup, e switch d.config.Backend { case "native": - return native.Launch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Redirects) + return native.Launch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Stdin, d.config.Stdout, d.config.Stderr) case "lldb": - return betterGdbserialLaunchError(gdbserial.LLDBLaunch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Redirects)) + return betterGdbserialLaunchError(gdbserial.LLDBLaunch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, [3]string{d.config.Stdin, d.config.Stdout.Path, d.config.Stderr.Path})) case "rr": if d.target != nil { // restart should not call us if the backend is 'rr' panic("internal error: call to Launch with rr backend and target already exists") } - run, stop, err := gdbserial.RecordAsync(processArgs, wd, false, d.config.Redirects) + run, stop, err := gdbserial.RecordAsync(processArgs, wd, false, d.config.Stdin, d.config.Stdout, d.config.Stderr) if err != nil { return nil, err } @@ -303,9 +309,9 @@ func (d *Debugger) Launch(processArgs []string, wd string) (*proc.TargetGroup, e case "default": if runtime.GOOS == "darwin" { - return betterGdbserialLaunchError(gdbserial.LLDBLaunch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Redirects)) + return betterGdbserialLaunchError(gdbserial.LLDBLaunch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, [3]string{d.config.Stdin, d.config.Stdout.Path, d.config.Stderr.Path})) } - return native.Launch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Redirects) + return native.Launch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Stdin, d.config.Stdout, d.config.Stderr) default: return nil, fmt.Errorf("unknown backend %q", d.config.Backend) } @@ -472,12 +478,19 @@ func (d *Debugger) Restart(rerecord bool, pos string, resetArgs bool, newArgs [] return nil, ErrCanNotRestart } + if !resetArgs && (d.config.Stdout.File != nil || d.config.Stderr.File != nil) { + return nil, ErrCanNotRestart + + } + if err := d.detach(true); err != nil { return nil, err } if resetArgs { d.processArgs = append([]string{d.processArgs[0]}, newArgs...) - d.config.Redirects = newRedirects + d.config.Stdin = newRedirects[0] + d.config.Stdout = proc.OutputRedirect{Path: newRedirects[1]} + d.config.Stderr = proc.OutputRedirect{Path: newRedirects[2]} } var grp *proc.TargetGroup var err error @@ -501,7 +514,7 @@ func (d *Debugger) Restart(rerecord bool, pos string, resetArgs bool, newArgs [] } if recorded { - run, stop, err2 := gdbserial.RecordAsync(d.processArgs, d.config.WorkingDir, false, d.config.Redirects) + run, stop, err2 := gdbserial.RecordAsync(d.processArgs, d.config.WorkingDir, false, d.config.Stdin, d.config.Stdout, d.config.Stderr) if err2 != nil { return nil, err2 } diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go index a6c3b45e3f..6b03a852bd 100644 --- a/service/test/integration2_test.go +++ b/service/test/integration2_test.go @@ -85,7 +85,9 @@ func startServer(name string, buildFlags protest.BuildFlags, t *testing.T, redir Packages: []string{fixture.Source}, BuildFlags: "", // build flags can be an empty string here because the only test that uses it, does not set special flags. ExecuteKind: debugger.ExecutingGeneratedFile, - Redirects: redirects, + Stdin: redirects[0], + Stdout: proc.OutputRedirect{Path: redirects[1]}, + Stderr: proc.OutputRedirect{Path: redirects[2]}, }, }) if err := server.Run(); err != nil { From f0160554579a5a6361b5b693e9f4fd453baedd7c Mon Sep 17 00:00:00 2001 From: gocurr Date: Wed, 5 Jul 2023 23:48:33 +0800 Subject: [PATCH 070/114] pkg/dwarf/frame: fix FrameDescriptionEntries's Append (#3433) The current implementation has a bug to remove duplicates. It can be implemented by using fast-slow pointers. --- pkg/dwarf/frame/entries.go | 19 ++++---- pkg/dwarf/frame/entries_test.go | 83 +++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 8 deletions(-) diff --git a/pkg/dwarf/frame/entries.go b/pkg/dwarf/frame/entries.go index 1e4605ce1a..75b3cdf30d 100644 --- a/pkg/dwarf/frame/entries.go +++ b/pkg/dwarf/frame/entries.go @@ -91,18 +91,21 @@ func (fdes FrameDescriptionEntries) Append(otherFDEs FrameDescriptionEntries) Fr sort.SliceStable(r, func(i, j int) bool { return r[i].Begin() < r[j].Begin() }) + if len(r) < 2 { // fast path, no duplicates + return r + } + // remove duplicates - uniqFDEs := fdes[:0] - for _, fde := range fdes { - if len(uniqFDEs) > 0 { - last := uniqFDEs[len(uniqFDEs)-1] - if last.Begin() == fde.Begin() && last.End() == fde.End() { - continue + slow := 1 + for fast := 1; fast < len(r); fast++ { + if r[fast].Begin() != r[fast-1].Begin() || r[fast].End() != r[fast-1].End() { + if slow != fast { + r[slow] = r[fast] } + slow++ } - uniqFDEs = append(uniqFDEs, fde) } - return r + return r[:slow] } // ptrEnc represents a pointer encoding value, used during eh_frame decoding diff --git a/pkg/dwarf/frame/entries_test.go b/pkg/dwarf/frame/entries_test.go index 593d451689..9c6e23aa98 100644 --- a/pkg/dwarf/frame/entries_test.go +++ b/pkg/dwarf/frame/entries_test.go @@ -56,6 +56,89 @@ func TestFDEForPC(t *testing.T) { } } +func TestAppend(t *testing.T) { + equal := func(x, y FrameDescriptionEntries) bool { + if len(x) != len(y) { + return false + } + for i := range x { + if x[i].Begin() != y[i].Begin() || x[i].End() != y[i].End() { + return false + } + } + return true + } + var appendTests = []struct { + name string + f1 FrameDescriptionEntries + f2 FrameDescriptionEntries + want FrameDescriptionEntries + }{ + { + name: "nil", + f1: nil, + f2: nil, + want: nil, + }, + + { + name: "one", + f1: FrameDescriptionEntries{ + &FrameDescriptionEntry{begin: 10, size: 40}, + }, + f2: FrameDescriptionEntries{ + &FrameDescriptionEntry{begin: 10, size: 40}, + }, + want: FrameDescriptionEntries{ + &FrameDescriptionEntry{begin: 10, size: 40}, + }, + }, + { + name: "1 item", + f1: FrameDescriptionEntries{ + &FrameDescriptionEntry{begin: 10, size: 40}, + &FrameDescriptionEntry{begin: 10, size: 40}, + &FrameDescriptionEntry{begin: 50, size: 50}, + }, + f2: FrameDescriptionEntries{ + &FrameDescriptionEntry{begin: 10, size: 40}, + &FrameDescriptionEntry{begin: 50, size: 50}, + }, + want: FrameDescriptionEntries{ + &FrameDescriptionEntry{begin: 10, size: 40}, + &FrameDescriptionEntry{begin: 50, size: 50}, + }, + }, + { + name: "many", + f1: FrameDescriptionEntries{ + &FrameDescriptionEntry{begin: 10, size: 40}, + &FrameDescriptionEntry{begin: 100, size: 100}, + &FrameDescriptionEntry{begin: 50, size: 50}, + &FrameDescriptionEntry{begin: 50, size: 50}, + &FrameDescriptionEntry{begin: 300, size: 10}, + &FrameDescriptionEntry{begin: 300, size: 10}, + }, + f2: FrameDescriptionEntries{ + &FrameDescriptionEntry{begin: 10, size: 40}, + &FrameDescriptionEntry{begin: 100, size: 100}, + &FrameDescriptionEntry{begin: 100, size: 100}, + }, + want: FrameDescriptionEntries{ + &FrameDescriptionEntry{begin: 10, size: 40}, + &FrameDescriptionEntry{begin: 50, size: 50}, + &FrameDescriptionEntry{begin: 100, size: 100}, + &FrameDescriptionEntry{begin: 300, size: 10}, + }, + }, + } + for _, test := range appendTests { + if got := test.f1.Append(test.f2); !equal(got, test.want) { + t.Errorf("%v.Append(%v) = %v, want %v", test.f1, test.f2, got, test.want) + } + } +} + func BenchmarkFDEForPC(b *testing.B) { f, err := os.Open("testdata/frame") if err != nil { From 2d3fd35e0400f2dcb54721a1705dae00c7d3b9bd Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Wed, 5 Jul 2023 18:49:08 +0300 Subject: [PATCH 071/114] pkg,service: refactor to use %q instead of "%s" (#3430) --- pkg/locspec/locations.go | 10 ++++---- pkg/proc/eval.go | 32 +++++++++++++------------- pkg/proc/variables.go | 2 +- pkg/proc/variables_test.go | 10 ++++---- pkg/terminal/starlark_test.go | 2 +- service/debugger/debugger_test.go | 2 +- service/debugger/debugger_unix_test.go | 2 +- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/pkg/locspec/locations.go b/pkg/locspec/locations.go index caca22745d..0b1472fe30 100644 --- a/pkg/locspec/locations.go +++ b/pkg/locspec/locations.go @@ -69,7 +69,7 @@ func Parse(locStr string) (LocationSpec, error) { malformed := func(reason string) error { //lint:ignore ST1005 backwards compatibility - return fmt.Errorf("Malformed breakpoint location \"%s\" at %d: %s", locStr, len(locStr)-len(rest), reason) + return fmt.Errorf("Malformed breakpoint location %q at %d: %s", locStr, len(locStr)-len(rest), reason) } if len(rest) <= 0 { @@ -109,7 +109,7 @@ func Parse(locStr string) (LocationSpec, error) { func parseLocationSpecDefault(locStr, rest string) (LocationSpec, error) { malformed := func(reason string) error { //lint:ignore ST1005 backwards compatibility - return fmt.Errorf("Malformed breakpoint location \"%s\" at %d: %s", locStr, len(locStr)-len(rest), reason) + return fmt.Errorf("Malformed breakpoint location %q at %d: %s", locStr, len(locStr)-len(rest), reason) } v := strings.Split(rest, ":") @@ -365,7 +365,7 @@ func (ale AmbiguousLocationError) Error() string { } else { candidates = ale.CandidatesString } - return fmt.Sprintf("Location \"%s\" ambiguous: %s…", ale.Location, strings.Join(candidates, ", ")) + return fmt.Sprintf("Location %q ambiguous: %s…", ale.Location, strings.Join(candidates, ", ")) } // Find will return a list of locations that match the given location spec. @@ -396,7 +396,7 @@ func (loc *NormalLocationSpec) Find(t *proc.Target, processArgs []string, scope if matching := len(candidateFiles) + len(candidateFuncs); matching == 0 { if scope == nil { - return nil, fmt.Errorf("location \"%s\" not found", locStr) + return nil, fmt.Errorf("location %q not found", locStr) } // if no result was found this locations string could be an // expression that the user forgot to prefix with '*', try treating it as @@ -404,7 +404,7 @@ func (loc *NormalLocationSpec) Find(t *proc.Target, processArgs []string, scope addrSpec := &AddrLocationSpec{AddrExpr: locStr} locs, err := addrSpec.Find(t, processArgs, scope, locStr, includeNonExecutableLines, nil) if err != nil { - return nil, fmt.Errorf("location \"%s\" not found", locStr) + return nil, fmt.Errorf("location %q not found", locStr) } return locs, nil } else if matching > 1 { diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index b3b6db6824..3e6c87b428 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -363,7 +363,7 @@ func (scope *EvalScope) setValue(dstv, srcv *Variable, srcExpr string) error { if srcv.Unreadable != nil { //lint:ignore ST1005 backwards compatibility - return fmt.Errorf("Expression \"%s\" is unreadable: %v", srcExpr, srcv.Unreadable) + return fmt.Errorf("Expression %q is unreadable: %v", srcExpr, srcv.Unreadable) } // Numerical types @@ -437,12 +437,12 @@ func (scope *EvalScope) SetVariable(name, value string) error { if xv.Addr == 0 { //lint:ignore ST1005 backwards compatibility - return fmt.Errorf("Can not assign to \"%s\"", name) + return fmt.Errorf("Can not assign to %q", name) } if xv.Unreadable != nil { //lint:ignore ST1005 backwards compatibility - return fmt.Errorf("Expression \"%s\" is unreadable: %v", name, xv.Unreadable) + return fmt.Errorf("Expression %q is unreadable: %v", name, xv.Unreadable) } t, err = parser.ParseExpr(value) @@ -1400,7 +1400,7 @@ func (scope *EvalScope) evalTypeAssert(node *ast.TypeAssertExpr) (*Variable, err return nil, err } if xv.Kind != reflect.Interface { - return nil, fmt.Errorf("expression \"%s\" not an interface", exprToString(node.X)) + return nil, fmt.Errorf("expression %q not an interface", exprToString(node.X)) } xv.loadInterface(0, false, loadFullValue) if xv.Unreadable != nil { @@ -1451,7 +1451,7 @@ func (scope *EvalScope) evalIndex(node *ast.IndexExpr) (*Variable, error) { return nil, err } - cantindex := fmt.Errorf("expression \"%s\" (%s) does not support indexing", exprToString(node.X), xev.TypeString()) + cantindex := fmt.Errorf("expression %q (%s) does not support indexing", exprToString(node.X), xev.TypeString()) switch xev.Kind { case reflect.Ptr: @@ -1469,7 +1469,7 @@ func (scope *EvalScope) evalIndex(node *ast.IndexExpr) (*Variable, error) { case reflect.Slice, reflect.Array, reflect.String: if xev.Base == 0 { - return nil, fmt.Errorf("can not index \"%s\"", exprToString(node.X)) + return nil, fmt.Errorf("can not index %q", exprToString(node.X)) } n, err := idxev.asInt() if err != nil { @@ -1508,7 +1508,7 @@ func (scope *EvalScope) evalReslice(node *ast.SliceExpr) (*Variable, error) { } low, err = lowv.asInt() if err != nil { - return nil, fmt.Errorf("can not convert \"%s\" to int: %v", exprToString(node.Low), err) + return nil, fmt.Errorf("can not convert %q to int: %v", exprToString(node.Low), err) } } @@ -1521,14 +1521,14 @@ func (scope *EvalScope) evalReslice(node *ast.SliceExpr) (*Variable, error) { } high, err = highv.asInt() if err != nil { - return nil, fmt.Errorf("can not convert \"%s\" to int: %v", exprToString(node.High), err) + return nil, fmt.Errorf("can not convert %q to int: %v", exprToString(node.High), err) } } switch xev.Kind { case reflect.Slice, reflect.Array, reflect.String: if xev.Base == 0 { - return nil, fmt.Errorf("can not slice \"%s\"", exprToString(node.X)) + return nil, fmt.Errorf("can not slice %q", exprToString(node.X)) } return xev.reslice(low, high) case reflect.Map: @@ -1547,7 +1547,7 @@ func (scope *EvalScope) evalReslice(node *ast.SliceExpr) (*Variable, error) { } fallthrough default: - return nil, fmt.Errorf("can not slice \"%s\" (type %s)", exprToString(node.X), xev.TypeString()) + return nil, fmt.Errorf("can not slice %q (type %s)", exprToString(node.X), xev.TypeString()) } } @@ -1559,7 +1559,7 @@ func (scope *EvalScope) evalPointerDeref(node *ast.StarExpr) (*Variable, error) } if xev.Kind != reflect.Ptr { - return nil, fmt.Errorf("expression \"%s\" (%s) can not be dereferenced", exprToString(node.X), xev.TypeString()) + return nil, fmt.Errorf("expression %q (%s) can not be dereferenced", exprToString(node.X), xev.TypeString()) } if xev == nilVariable { @@ -1592,7 +1592,7 @@ func (scope *EvalScope) evalAddrOf(node *ast.UnaryExpr) (*Variable, error) { return nil, err } if xev.Addr == 0 || xev.DwarfType == nil { - return nil, fmt.Errorf("can not take address of \"%s\"", exprToString(node.X)) + return nil, fmt.Errorf("can not take address of %q", exprToString(node.X)) } return xev.pointerToVariable(), nil @@ -1660,7 +1660,7 @@ func (scope *EvalScope) evalUnary(node *ast.UnaryExpr) (*Variable, error) { return nil, errOperationOnSpecialFloat } if xv.Value == nil { - return nil, fmt.Errorf("operator %s can not be applied to \"%s\"", node.Op.String(), exprToString(node.X)) + return nil, fmt.Errorf("operator %s can not be applied to %q", node.Op.String(), exprToString(node.X)) } rc, err := constantUnaryOp(node.Op, xv.Value) if err != nil { @@ -1708,7 +1708,7 @@ func negotiateType(op token.Token, xv, yv *Variable) (godwarf.Type, error) { if xv.DwarfType != nil && yv.DwarfType != nil { if xv.DwarfType.String() != yv.DwarfType.String() { - return nil, fmt.Errorf("mismatched types \"%s\" and \"%s\"", xv.DwarfType.String(), yv.DwarfType.String()) + return nil, fmt.Errorf("mismatched types %q and %q", xv.DwarfType.String(), yv.DwarfType.String()) } return xv.DwarfType, nil } else if xv.DwarfType != nil && yv.DwarfType == nil { @@ -1813,11 +1813,11 @@ func (scope *EvalScope) evalBinary(node *ast.BinaryExpr) (*Variable, error) { yv.loadValue(loadFullValueLongerStrings) } if xv.Value == nil { - return nil, fmt.Errorf("operator %s can not be applied to \"%s\"", node.Op.String(), exprToString(node.X)) + return nil, fmt.Errorf("operator %s can not be applied to %q", node.Op.String(), exprToString(node.X)) } if yv.Value == nil { - return nil, fmt.Errorf("operator %s can not be applied to \"%s\"", node.Op.String(), exprToString(node.Y)) + return nil, fmt.Errorf("operator %s can not be applied to %q", node.Op.String(), exprToString(node.Y)) } rc, err := constantBinaryOp(op, xv.Value, yv.Value) diff --git a/pkg/proc/variables.go b/pkg/proc/variables.go index 59ec833afa..49ccbf7657 100644 --- a/pkg/proc/variables.go +++ b/pkg/proc/variables.go @@ -1422,7 +1422,7 @@ func (v *Variable) loadValueInternal(recurseLevel int, cfg LoadConfig) { case reflect.Func: v.readFunctionPtr() default: - v.Unreadable = fmt.Errorf("unknown or unsupported kind: \"%s\"", v.Kind.String()) + v.Unreadable = fmt.Errorf("unknown or unsupported kind: %q", v.Kind.String()) } } diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go index 7cc2dc5ef4..0f900570eb 100644 --- a/pkg/proc/variables_test.go +++ b/pkg/proc/variables_test.go @@ -500,7 +500,7 @@ func TestComplexSetting(t *testing.T) { variable, err := evalVariableWithCfg(p, "c128", pnormalLoadConfig) assertNoError(err, t, "EvalVariable()") if s := api.ConvertVar(variable).SinglelineString(); s != value { - t.Fatalf("Wrong value of c128: \"%s\", expected \"%s\" after setting it to \"%s\"", s, value, setExpr) + t.Fatalf("Wrong value of c128: %q, expected %q after setting it to %q", s, value, setExpr) } } @@ -890,7 +890,7 @@ func TestEvalAddrAndCast(t *testing.T) { c1addrstr := api.ConvertVar(c1addr).SinglelineString() t.Logf("&c1 → %s", c1addrstr) if !strings.HasPrefix(c1addrstr, "(*main.cstruct)(0x") { - t.Fatalf("Invalid value of EvalExpression(&c1) \"%s\"", c1addrstr) + t.Fatalf("Invalid value of EvalExpression(&c1) %q", c1addrstr) } aaddr, err := evalVariableWithCfg(p, "&(c1.pb.a)", pnormalLoadConfig) @@ -898,7 +898,7 @@ func TestEvalAddrAndCast(t *testing.T) { aaddrstr := api.ConvertVar(aaddr).SinglelineString() t.Logf("&(c1.pb.a) → %s", aaddrstr) if !strings.HasPrefix(aaddrstr, "(*main.astruct)(0x") { - t.Fatalf("invalid value of EvalExpression(&(c1.pb.a)) \"%s\"", aaddrstr) + t.Fatalf("invalid value of EvalExpression(&(c1.pb.a)) %q", aaddrstr) } a, err := evalVariableWithCfg(p, "*"+aaddrstr, pnormalLoadConfig) @@ -1667,11 +1667,11 @@ func TestBadUnsafePtr(t *testing.T) { } expErr := "couldn't read pointer" if !strings.Contains(err.Error(), expErr) { - t.Fatalf("expected \"%s\", got: \"%s\"", expErr, err) + t.Fatalf("expected %q, got: %q", expErr, err) } nexpErr := "nil pointer dereference" if strings.Contains(err.Error(), nexpErr) { - t.Fatalf("shouldn't have gotten \"%s\", but got: \"%s\"", nexpErr, err) + t.Fatalf("shouldn't have gotten %q, but got: %q", nexpErr, err) } }) } diff --git a/pkg/terminal/starlark_test.go b/pkg/terminal/starlark_test.go index 7f4f8706c8..45de48cf8d 100644 --- a/pkg/terminal/starlark_test.go +++ b/pkg/terminal/starlark_test.go @@ -219,7 +219,7 @@ v.Children[0].Children[0].Value.XXX t.Fatalf("expected error %q, got success", tc.expErr) } if !strings.Contains(err.Error(), tc.expErr) { - t.Fatalf("expected error %q, got \"%s\"", tc.expErr, err) + t.Fatalf("expected error %q, got %q", tc.expErr, err) } }) } diff --git a/service/debugger/debugger_test.go b/service/debugger/debugger_test.go index b8b05ece55..9af7a75fed 100644 --- a/service/debugger/debugger_test.go +++ b/service/debugger/debugger_test.go @@ -66,7 +66,7 @@ func TestDebugger_LaunchInvalidFormat(t *testing.T) { t.Fatalf("expected error but none was generated") } if err != api.ErrNotExecutable { - t.Fatalf("expected error \"%s\" got \"%v\"", api.ErrNotExecutable, err) + t.Fatalf("expected error %q got \"%v\"", api.ErrNotExecutable, err) } } diff --git a/service/debugger/debugger_unix_test.go b/service/debugger/debugger_unix_test.go index bb90dbd04b..07f78833a0 100644 --- a/service/debugger/debugger_unix_test.go +++ b/service/debugger/debugger_unix_test.go @@ -51,7 +51,7 @@ func TestDebugger_LaunchNoExecutablePerm(t *testing.T) { t.Fatalf("expected error but none was generated") } if err != api.ErrNotExecutable { - t.Fatalf("expected error \"%s\" got \"%v\"", api.ErrNotExecutable, err) + t.Fatalf("expected error %q got \"%v\"", api.ErrNotExecutable, err) } } From 80840dd2bf29581a3d4e4f538faf327231c100b1 Mon Sep 17 00:00:00 2001 From: gocurr Date: Thu, 6 Jul 2023 17:16:06 +0800 Subject: [PATCH 072/114] all: fix typos (#3434) --- CHANGELOG.md | 4 ++-- _fixtures/testvariables2.go | 4 ++-- pkg/proc/bininfo.go | 2 +- pkg/proc/proc_test.go | 4 ++-- pkg/proc/variables_test.go | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e0fe09089..b390e1a682 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -765,7 +765,7 @@ This project adheres to Semantic Versioning. - Fix behavior of next/step/stepout in several edge-cases (invalid return addresses, no current goroutine, after process exists, inside unknown code, inside assembly files) (@aarzilli) - Make sure the debugged executable we generated is deleted after exit (@alexbrainman) - Make sure rr trace directories are deleted when we delete the executable and after tests (@aarzilli) -- Return errors for commands sent after the target process exited instead of panicing (@derekparker) +- Return errors for commands sent after the target process exited instead of panicking (@derekparker) - Fixed typo in clear-checkpoint documentation (@iamzhout) ### Changed @@ -811,7 +811,7 @@ This project adheres to Semantic Versioning. - Windows: Handle delayed events (@aarzilli) - Fix Println call to be Printf (@derekparker) - Fix build on OSX (@koichi) -- Mark malformed maps as unreadable instead of panicing (@aarzilli) +- Mark malformed maps as unreadable instead of panicking (@aarzilli) - Fixed broken benchmarks (@derekparker) - Improve reliability of certain tests (@aarzilli) diff --git a/_fixtures/testvariables2.go b/_fixtures/testvariables2.go index b078e9d87d..ae1d795249 100644 --- a/_fixtures/testvariables2.go +++ b/_fixtures/testvariables2.go @@ -71,7 +71,7 @@ func (a *astruct) Error() string { return "not an error" } -func (a astruct) NonPointerRecieverMethod() { +func (a astruct) NonPointerReceiverMethod() { return } @@ -398,5 +398,5 @@ func main() { longslice := make([]int, 100, 100) runtime.Breakpoint() - fmt.Println(i1, i2, i3, p1, pp1, amb1, s1, s3, a0, a1, p2, p3, s2, as1, str1, f1, fn1, fn2, nilslice, nilptr, ch1, chnil, m1, mnil, m2, m3, m4, m5, upnil, up1, i4, i5, i6, err1, err2, errnil, iface1, iface2, ifacenil, arr1, parr, cpx1, const1, iface3, iface4, recursive1, recursive1.x, iface5, iface2fn1, iface2fn2, bencharr, benchparr, mapinf, mainMenu, b, b2, sd, anonstruct1, anonstruct2, anoniface1, anonfunc, mapanonstruct1, ifacearr, efacearr, ni8, ni16, ni32, ni64, pinf, ninf, nan, zsvmap, zsslice, zsvar, tm, rettm, errtypednil, emptyslice, emptymap, byteslice, bytestypeslice, runeslice, bytearray, bytetypearray, runearray, longstr, nilstruct, as2, as2.NonPointerRecieverMethod, s4, iface2map, issue1578, ll, unread, w2, w3, w4, w5, longarr, longslice, val, m6, m7, cl, tim1, tim2, typedstringvar, namedA1, namedA2, astructName1(namedA2), badslice, tim3, int3chan) + fmt.Println(i1, i2, i3, p1, pp1, amb1, s1, s3, a0, a1, p2, p3, s2, as1, str1, f1, fn1, fn2, nilslice, nilptr, ch1, chnil, m1, mnil, m2, m3, m4, m5, upnil, up1, i4, i5, i6, err1, err2, errnil, iface1, iface2, ifacenil, arr1, parr, cpx1, const1, iface3, iface4, recursive1, recursive1.x, iface5, iface2fn1, iface2fn2, bencharr, benchparr, mapinf, mainMenu, b, b2, sd, anonstruct1, anonstruct2, anoniface1, anonfunc, mapanonstruct1, ifacearr, efacearr, ni8, ni16, ni32, ni64, pinf, ninf, nan, zsvmap, zsslice, zsvar, tm, rettm, errtypednil, emptyslice, emptymap, byteslice, bytestypeslice, runeslice, bytearray, bytetypearray, runearray, longstr, nilstruct, as2, as2.NonPointerReceiverMethod, s4, iface2map, issue1578, ll, unread, w2, w3, w4, w5, longarr, longslice, val, m6, m7, cl, tim1, tim2, typedstringvar, namedA1, namedA2, astructName1(namedA2), badslice, tim3, int3chan) } diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go index fb90d69ae2..0e61779b6b 100644 --- a/pkg/proc/bininfo.go +++ b/pkg/proc/bininfo.go @@ -279,7 +279,7 @@ func FindFileLocation(p Process, filename string, lineno int) ([]uint64, error) return selectedPCs, nil } -// inlRnage is the range of an inlined call +// inlRange is the range of an inlined call type inlRange struct { off dwarf.Offset depth uint32 diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index ec12303f69..f00a10a777 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -372,7 +372,7 @@ func TestBreakpointInSeparateGoRoutine(t *testing.T) { }) } -func TestBreakpointWithNonExistantFunction(t *testing.T) { +func TestBreakpointWithNonExistentFunction(t *testing.T) { withTestProcess("testprog", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { _, err := p.SetBreakpoint(0, 0, proc.UserBreakpoint, nil) if err == nil { @@ -2402,7 +2402,7 @@ func TestIssue561(t *testing.T) { }) } -func TestGoroutineLables(t *testing.T) { +func TestGoroutineLabels(t *testing.T) { withTestProcess("goroutineLabels", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { assertNoError(grp.Continue(), t, "Continue()") g, err := proc.GetG(p.CurrentThread()) diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go index 0f900570eb..fa317aa7ac 100644 --- a/pkg/proc/variables_test.go +++ b/pkg/proc/variables_test.go @@ -771,9 +771,9 @@ func getEvalExpressionTestCases() []varTest { {"main.afunc2", true, `main.afunc2`, `main.afunc2`, `func()`, nil}, {"s2[0].Error", false, "main.(*astruct).Error", "main.(*astruct).Error", "func() string", nil}, - {"s2[0].NonPointerRecieverMethod", false, "main.astruct.NonPointerRecieverMethod", "main.astruct.NonPointerRecieverMethod", "func()", nil}, + {"s2[0].NonPointerReceiverMethod", false, "main.astruct.NonPointerReceiverMethod", "main.astruct.NonPointerReceiverMethod", "func()", nil}, {"as2.Error", false, "main.(*astruct).Error", "main.(*astruct).Error", "func() string", nil}, - {"as2.NonPointerRecieverMethod", false, "main.astruct.NonPointerRecieverMethod", "main.astruct.NonPointerRecieverMethod", "func()", nil}, + {"as2.NonPointerReceiverMethod", false, "main.astruct.NonPointerReceiverMethod", "main.astruct.NonPointerReceiverMethod", "func()", nil}, {`iface2map.(data)`, false, "…", "…", "map[string]interface {}", nil}, From 9f3e1461297ed914244063e7e80405a7f3a8296d Mon Sep 17 00:00:00 2001 From: Suzy Mueller Date: Thu, 6 Jul 2023 23:17:39 -0700 Subject: [PATCH 073/114] service/dap: fix test for debug in progress (#3407) The regular expression attempted to match for a network address, but actually does not match any network addresses. The two documentation includes "192.0.2.1:25" and "[2001:db8::1]:80" as examples, neither of which match the current regex. This change updates the regular expression to ensure that there is some text at the desired position, but not what the text is. --- service/dap/server_test.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/service/dap/server_test.go b/service/dap/server_test.go index 5618100ad3..3b142dca92 100644 --- a/service/dap/server_test.go +++ b/service/dap/server_test.go @@ -6813,8 +6813,8 @@ func TestLaunchAttachErrorWhenDebugInProgress(t *testing.T) { // Both launch and attach requests should go through for additional error checking client.AttachRequest(map[string]interface{}{"mode": "local", "processId": 100}) er := client.ExpectVisibleErrorResponse(t) - msgRe := regexp.MustCompile("Failed to attach: debug session already in progress at [0-9]+:[0-9]+ - use remote mode to connect to a server with an active debug session") - if er.Body.Error == nil || er.Body.Error.Id != FailedToAttach || msgRe.MatchString(er.Body.Error.Format) { + msgRe := regexp.MustCompile("Failed to attach: debug session already in progress at .+ - use remote mode to connect to a server with an active debug session") + if er.Body.Error == nil || er.Body.Error.Id != FailedToAttach || !msgRe.MatchString(er.Body.Error.Format) { t.Errorf("got %#v, want Id=%d Format=%q", er.Body.Error, FailedToAttach, msgRe) } tests := []string{"debug", "test", "exec", "replay", "core"} @@ -6822,8 +6822,8 @@ func TestLaunchAttachErrorWhenDebugInProgress(t *testing.T) { t.Run(mode, func(t *testing.T) { client.LaunchRequestWithArgs(map[string]interface{}{"mode": mode}) er := client.ExpectVisibleErrorResponse(t) - msgRe := regexp.MustCompile("Failed to launch: debug session already in progress at [0-9]+:[0-9]+ - use remote attach mode to connect to a server with an active debug session") - if er.Body.Error == nil || er.Body.Error.Id != FailedToLaunch || msgRe.MatchString(er.Body.Error.Format) { + msgRe := regexp.MustCompile("Failed to launch: debug session already in progress at .+ - use remote attach mode to connect to a server with an active debug session") + if er.Body.Error == nil || er.Body.Error.Id != FailedToLaunch || !msgRe.MatchString(er.Body.Error.Format) { t.Errorf("got %#v, want Id=%d Format=%q", er.Body.Error, FailedToLaunch, msgRe) } }) @@ -7367,7 +7367,6 @@ func TestDisassembleCgo(t *testing.T) { protest.AllNonOptimized, true) } - func TestRedirect(t *testing.T) { runTest(t, "out_redirect", func(client *daptest.Client, fixture protest.Fixture) { // 1 >> initialize, << initialize From 71f12207175a1cc09668f856340d8a543c87dcca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lex=20S=C3=A1ez?= Date: Fri, 7 Jul 2023 18:30:38 +0200 Subject: [PATCH 074/114] *: add ppc64le support (#2963) * Add vendor/golang.org/x/arch/ppc64 * Add ppc64le support --- Documentation/backend_test_health.md | 13 +- _fixtures/asmnilptr/main_ppc64le.s | 7 + _fixtures/cgostacktest/hello.c | 2 + _scripts/make.go | 3 + _scripts/test_linux.sh | 8 + cmd/dlv/dlv_test.go | 7 + pkg/dwarf/regnum/ppc64le.go | 115 + pkg/proc/arch.go | 1 + pkg/proc/bininfo.go | 6 + pkg/proc/dump.go | 2 + pkg/proc/linutil/regs_ppc64le_arch.go | 174 + pkg/proc/native/hwbreak_other.go | 4 +- pkg/proc/native/proc.go | 8 +- pkg/proc/native/ptrace_linux_64bit.go | 4 +- pkg/proc/native/registers_linux_ppc64le.go | 104 + pkg/proc/native/support_sentinel_linux.go | 8 +- pkg/proc/native/threads_linux_ppc64le.go | 25 + pkg/proc/ppc64le_arch.go | 234 + pkg/proc/ppc64le_disasm.go | 161 + pkg/proc/proc_test.go | 32 +- pkg/proc/stack.go | 6 +- pkg/proc/target_exec.go | 14 +- pkg/proc/test/support.go | 2 +- pkg/proc/variables_test.go | 5 + pkg/terminal/command_test.go | 15 + service/dap/server_test.go | 3 + service/debugger/debugger_test.go | 3 + service/debugger/debugger_unix_test.go | 3 + service/test/integration1_test.go | 9 + service/test/integration2_test.go | 12 + .../x/arch/ppc64/ppc64asm/decode.go | 179 + .../golang.org/x/arch/ppc64/ppc64asm/doc.go | 6 + .../golang.org/x/arch/ppc64/ppc64asm/field.go | 84 + .../golang.org/x/arch/ppc64/ppc64asm/gnu.go | 267 + .../golang.org/x/arch/ppc64/ppc64asm/inst.go | 344 ++ .../golang.org/x/arch/ppc64/ppc64asm/plan9.go | 245 + .../x/arch/ppc64/ppc64asm/tables.go | 5494 +++++++++++++++++ vendor/modules.txt | 1 + 38 files changed, 7593 insertions(+), 17 deletions(-) create mode 100644 _fixtures/asmnilptr/main_ppc64le.s create mode 100644 pkg/dwarf/regnum/ppc64le.go create mode 100644 pkg/proc/linutil/regs_ppc64le_arch.go create mode 100644 pkg/proc/native/registers_linux_ppc64le.go create mode 100644 pkg/proc/native/threads_linux_ppc64le.go create mode 100644 pkg/proc/ppc64le_arch.go create mode 100644 pkg/proc/ppc64le_disasm.go create mode 100644 vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go create mode 100644 vendor/golang.org/x/arch/ppc64/ppc64asm/doc.go create mode 100644 vendor/golang.org/x/arch/ppc64/ppc64asm/field.go create mode 100644 vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go create mode 100644 vendor/golang.org/x/arch/ppc64/ppc64asm/inst.go create mode 100644 vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go create mode 100644 vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go diff --git a/Documentation/backend_test_health.md b/Documentation/backend_test_health.md index 4fbde47c9b..72527ad1db 100644 --- a/Documentation/backend_test_health.md +++ b/Documentation/backend_test_health.md @@ -13,11 +13,22 @@ Tests skipped by each supported backend: * 4 not implemented * linux/386/pie skipped = 1 * 1 broken +* linux/ppc64le skipped = 1 + * 1 broken - cgo stacktraces +* linux/ppc64le/native skipped = 1 + * 1 broken in linux ppc64le +* linux/ppc64le/native/pie skipped = 11 + * 11 broken - pie mode * pie skipped = 2 * 2 upstream issue - https://github.com/golang/go/issues/29322 +* ppc64le skipped = 11 + * 6 broken + * 1 broken - global variable symbolication + * 4 not implemented * windows skipped = 4 * 1 broken * 3 see https://github.com/go-delve/delve/issues/2768 -* windows/arm64 skipped = 4 +* windows/arm64 skipped = 5 * 3 broken + * 1 broken - cgo stacktraces * 1 broken - step concurrent diff --git a/_fixtures/asmnilptr/main_ppc64le.s b/_fixtures/asmnilptr/main_ppc64le.s new file mode 100644 index 0000000000..fb57de19f6 --- /dev/null +++ b/_fixtures/asmnilptr/main_ppc64le.s @@ -0,0 +1,7 @@ +#include "textflag.h" + +TEXT ·asmFunc(SB),0,$0-16 + MOVD arg+0(FP), R5 + MOVD (R5), R5 + MOVD R5, ret+8(FP) + RET diff --git a/_fixtures/cgostacktest/hello.c b/_fixtures/cgostacktest/hello.c index edcef6b7e4..b779bf96aa 100644 --- a/_fixtures/cgostacktest/hello.c +++ b/_fixtures/cgostacktest/hello.c @@ -6,6 +6,8 @@ #define BREAKPOINT asm("int3;") #elif __i386__ #define BREAKPOINT asm("int3;") +#elif __PPC64__ +#define BREAKPOINT asm("tw 31,0,0;") #elif __aarch64__ #ifdef WIN32 #define BREAKPOINT asm("brk 0xF000;") diff --git a/_scripts/make.go b/_scripts/make.go index eef24266b1..ee75cff608 100644 --- a/_scripts/make.go +++ b/_scripts/make.go @@ -291,6 +291,9 @@ func tagFlags() string { if runtime.GOOS == "windows" && runtime.GOARCH == "arm64" { tags = append(tags, "exp.winarm64") } + if runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le" { + tags = append(tags, "exp.linuxppc64le") + } if Tags != nil && len(*Tags) > 0 { tags = append(tags, *Tags...) } diff --git a/_scripts/test_linux.sh b/_scripts/test_linux.sh index 44ca5d7b44..a84d73abb3 100755 --- a/_scripts/test_linux.sh +++ b/_scripts/test_linux.sh @@ -76,3 +76,11 @@ else exit $x fi +export GOARCH=ppc64le +go run _scripts/make.go --tags exp.linuxppc64le +x=$? +if [ "$version" = "gotip" ]; then + exit 0 +else + exit $x +fi diff --git a/cmd/dlv/dlv_test.go b/cmd/dlv/dlv_test.go index 153cc962d1..1dc474a393 100644 --- a/cmd/dlv/dlv_test.go +++ b/cmd/dlv/dlv_test.go @@ -213,6 +213,9 @@ func getDlvBin(t *testing.T) string { if runtime.GOOS == "windows" && runtime.GOARCH == "arm64" { tags = "-tags=exp.winarm64" } + if runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le" { + tags = "-tags=exp.linuxppc64le" + } return getDlvBinInternal(t, tags) } @@ -371,6 +374,10 @@ func TestGeneratedDoc(t *testing.T) { //TODO(qmuntal): investigate further when the Windows ARM64 backend is more stable. t.Skip("skipping test on Windows in CI") } + if runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le" { + //TODO(alexsaezm): finish CI integration + t.Skip("skipping test on Linux/PPC64LE in CI") + } // Checks gen-cli-docs.go var generatedBuf bytes.Buffer commands := terminal.DebugCommands(nil) diff --git a/pkg/dwarf/regnum/ppc64le.go b/pkg/dwarf/regnum/ppc64le.go new file mode 100644 index 0000000000..412225a464 --- /dev/null +++ b/pkg/dwarf/regnum/ppc64le.go @@ -0,0 +1,115 @@ +package regnum + +import "fmt" + +// The mapping between hardware registers and DWARF registers is specified +// in the 64-Bit ELF V2 ABI Specification of the Power Architecture in section +// 2.4 DWARF Definition +// https://openpowerfoundation.org/specifications/64bitelfabi/ + +const ( + // General Purpose Registers: from R0 to R31 + PPC64LE_FIRST_GPR = 0 + PPC64LE_R0 = PPC64LE_FIRST_GPR + PPC64LE_LAST_GPR = 31 + // Floating point registers: from F0 to F31 + PPC64LE_FIRST_FPR = 32 + PPC64LE_F0 = PPC64LE_FIRST_FPR + PPC64LE_LAST_FPR = 63 + // Vector (Altivec/VMX) registers: from V0 to V31 + PPC64LE_FIRST_VMX = 64 + PPC64LE_V0 = PPC64LE_FIRST_VMX + PPC64LE_LAST_VMX = 95 + // Vector Scalar (VSX) registers: from VS0 to VS63 + PPC64LE_FIRST_VSX = 96 + PPC64LE_VS0 = PPC64LE_FIRST_VSX + PPC64LE_LAST_VSX = 160 + // Condition Registers: from CR0 to CR7 + PPC64LE_CR0 = 0 + // Special registers + PPC64LE_SP = 1 // Stack frame pointer: Gpr[1] + PPC64LE_PC = 12 // The documentation refers to this as the CIA (Current Instruction Address) + PPC64LE_LR = 65 // Link register +) + +func PPC64LEToName(num uint64) string { + switch { + case num == PPC64LE_SP: + return "SP" + case num == PPC64LE_PC: + return "PC" + case num == PPC64LE_LR: + return "LR" + case isGPR(num): + return fmt.Sprintf("r%d", int(num-PPC64LE_FIRST_GPR)) + case isFPR(num): + return fmt.Sprintf("f%d", int(num-PPC64LE_FIRST_FPR)) + case isVMX(num): + return fmt.Sprintf("v%d", int(num-PPC64LE_FIRST_VMX)) + case isVSX(num): + return fmt.Sprintf("vs%d", int(num-PPC64LE_FIRST_VSX)) + default: + return fmt.Sprintf("unknown%d", num) + } +} + +// PPC64LEMaxRegNum is 172 registers in total, across 4 categories: +// General Purpose Registers or GPR (32 GPR + 9 special registers) +// Floating Point Registers or FPR (32 FPR + 1 special register) +// Altivec/VMX Registers or VMX (32 VMX + 2 special registers) +// VSX Registers or VSX (64 VSX) +// Documentation: https://lldb.llvm.org/cpp_reference/RegisterContextPOSIX__ppc64le_8cpp_source.html +func PPC64LEMaxRegNum() uint64 { + return 172 +} + +func isGPR(num uint64) bool { + return num < PPC64LE_LAST_GPR +} + +func isFPR(num uint64) bool { + return num >= PPC64LE_FIRST_FPR && num <= PPC64LE_LAST_FPR +} + +func isVMX(num uint64) bool { + return num >= PPC64LE_FIRST_VMX && num <= PPC64LE_LAST_VMX +} + +func isVSX(num uint64) bool { + return num >= PPC64LE_FIRST_VSX && num <= PPC64LE_LAST_VSX +} + +var PPC64LENameToDwarf = func() map[string]int { + r := make(map[string]int) + + r["nip"] = PPC64LE_PC + r["sp"] = PPC64LE_SP + r["bp"] = PPC64LE_SP + r["link"] = PPC64LE_LR + + // General Purpose Registers: from R0 to R31 + for i := 0; i <= 31; i++ { + r[fmt.Sprintf("r%d", i)] = PPC64LE_R0 + i + } + + // Floating point registers: from F0 to F31 + for i := 0; i <= 31; i++ { + r[fmt.Sprintf("f%d", i)] = PPC64LE_F0 + i + } + + // Vector (Altivec/VMX) registers: from V0 to V31 + for i := 0; i <= 31; i++ { + r[fmt.Sprintf("v%d", i)] = PPC64LE_V0 + i + } + + // Vector Scalar (VSX) registers: from VS0 to VS63 + for i := 0; i <= 63; i++ { + r[fmt.Sprintf("vs%d", i)] = PPC64LE_VS0 + i + } + + // Condition Registers: from CR0 to CR7 + for i := 0; i <= 7; i++ { + r[fmt.Sprintf("cr%d", i)] = PPC64LE_CR0 + i + } + return r +}() diff --git a/pkg/proc/arch.go b/pkg/proc/arch.go index 22de6b1686..6c182ea263 100644 --- a/pkg/proc/arch.go +++ b/pkg/proc/arch.go @@ -151,5 +151,6 @@ func nameToDwarfFunc(n2d map[string]int) func(string) (int, bool) { const ( crosscall2SPOffsetBad = 0x8 crosscall2SPOffsetWindowsAMD64 = 0x118 + crosscall2SPOffsetLinuxPPC64LE = 0x158 crosscall2SPOffset = 0x58 ) diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go index 0e61779b6b..2e08b32e59 100644 --- a/pkg/proc/bininfo.go +++ b/pkg/proc/bininfo.go @@ -129,6 +129,7 @@ var ( elf.EM_X86_64: true, elf.EM_AARCH64: true, elf.EM_386: true, + elf.EM_PPC64: true, } supportedWindowsArch = map[_PEMachine]bool{ @@ -687,6 +688,8 @@ func NewBinaryInfo(goos, goarch string) *BinaryInfo { r.Arch = AMD64Arch(goos) case "arm64": r.Arch = ARM64Arch(goos) + case "ppc64le": + r.Arch = PPC64LEArch(goos) } return r } @@ -1648,6 +1651,9 @@ func (bi *BinaryInfo) setGStructOffsetElf(image *Image, exe *elf.File, wg *sync. bi.gStructOffset = tlsg.Value + uint64(bi.Arch.PtrSize()*2) + ((tls.Vaddr - uint64(bi.Arch.PtrSize()*2)) & (tls.Align - 1)) + case elf.EM_PPC64: + _ = getSymbol(image, bi.logger, exe, "runtime.tls_g") + default: // we should never get here panic("architecture not supported") diff --git a/pkg/proc/dump.go b/pkg/proc/dump.go index bfa29cc9b5..ebda9d99d9 100644 --- a/pkg/proc/dump.go +++ b/pkg/proc/dump.go @@ -136,6 +136,8 @@ func (t *Target) Dump(out elfwriter.WriteCloserSeeker, flags DumpFlags, state *D fhdr.Machine = elf.EM_386 case "arm64": fhdr.Machine = elf.EM_AARCH64 + case "ppc64le": + fhdr.Machine = elf.EM_PPC64 default: panic("not implemented") } diff --git a/pkg/proc/linutil/regs_ppc64le_arch.go b/pkg/proc/linutil/regs_ppc64le_arch.go new file mode 100644 index 0000000000..56670ba59d --- /dev/null +++ b/pkg/proc/linutil/regs_ppc64le_arch.go @@ -0,0 +1,174 @@ +package linutil + +import ( + "fmt" + + "github.com/go-delve/delve/pkg/proc" +) + +// PPC64LERegisters implements the proc.Registers interface for the native/linux +// backend and core/linux backends, on PPC64LE. +type PPC64LERegisters struct { + Regs *PPC64LEPtraceRegs + Fpregs []proc.Register //Formatted floating point registers + Fpregset []byte //holding all floating point register values + loadFpRegs func(*PPC64LERegisters) error +} + +func NewPPC64LERegisters(regs *PPC64LEPtraceRegs, loadFpRegs func(*PPC64LERegisters) error) *PPC64LERegisters { + return &PPC64LERegisters{Regs: regs, loadFpRegs: loadFpRegs} +} + +// PPC64LEPtraceRegs is the struct used by the linux kernel to return the +// general purpose registers for PPC64LE CPUs. +// Copied from src/syscall/ztypes_linux_ppc64le.go#L518-L532 +type PPC64LEPtraceRegs struct { + Gpr [32]uint64 // 32 general-purpose registers, each 64 bits wide + Nip uint64 + Msr uint64 + Orig_gpr3 uint64 + Ctr uint64 + Link uint64 // Link register -- LLDB dwarf_lr_ppc64le = 65 + Xer uint64 // Fixed point exception register -- LLDB dwarf_xer_ppc64le = 76 + Ccr uint64 + Softe uint64 + Trap uint64 + Dar uint64 + Dsisr uint64 + Result uint64 +} + +// PC returns the value of the NIP register +// Also called the IAR/Instruction Address Register or NIP/Next Instruction Pointer +func (r *PPC64LERegisters) PC() uint64 { + return r.Regs.Nip +} + +// SP returns the value of Stack frame pointer stored in Gpr[1]. +func (r *PPC64LERegisters) SP() uint64 { + return r.Regs.Gpr[1] +} + +// LR The Link Register is a 64-bit register. It can be +// used to provide the branch target address for the +// Branch Conditional to Link Register instruction, and it +// holds the return address after Branch instructions for +// which LK=1 and after System Call Vectored instructions. +// Extracted from the 2.3.2 section of the PowerISA Book 3.1 +func (r *PPC64LERegisters) LR() uint64 { + return r.Regs.Link +} + +func (r *PPC64LERegisters) BP() uint64 { + return r.Regs.Gpr[1] +} + +// TLS returns the value of the thread pointer stored in Gpr[13] +func (r *PPC64LERegisters) TLS() uint64 { + return r.Regs.Gpr[13] +} + +// GAddr returns the address of the G variable +func (r *PPC64LERegisters) GAddr() (uint64, bool) { + return r.Regs.Gpr[30], true +} + +// Slice returns the registers as a list of (name, value) pairs. +func (r *PPC64LERegisters) Slice(floatingPoint bool) ([]proc.Register, error) { + var regs = []struct { + k string + v uint64 + }{ + {"R0", r.Regs.Gpr[0]}, + {"R1", r.Regs.Gpr[1]}, + {"R2", r.Regs.Gpr[2]}, + {"R3", r.Regs.Gpr[3]}, + {"R4", r.Regs.Gpr[4]}, + {"R5", r.Regs.Gpr[5]}, + {"R6", r.Regs.Gpr[6]}, + {"R7", r.Regs.Gpr[7]}, + {"R8", r.Regs.Gpr[8]}, + {"R9", r.Regs.Gpr[9]}, + {"R10", r.Regs.Gpr[10]}, + {"R11", r.Regs.Gpr[11]}, + {"R12", r.Regs.Gpr[12]}, + {"R13", r.Regs.Gpr[13]}, + {"R14", r.Regs.Gpr[14]}, + {"R15", r.Regs.Gpr[15]}, + {"R16", r.Regs.Gpr[16]}, + {"R17", r.Regs.Gpr[17]}, + {"R18", r.Regs.Gpr[18]}, + {"R19", r.Regs.Gpr[19]}, + {"R20", r.Regs.Gpr[20]}, + {"R21", r.Regs.Gpr[21]}, + {"R22", r.Regs.Gpr[22]}, + {"R23", r.Regs.Gpr[23]}, + {"R24", r.Regs.Gpr[24]}, + {"R25", r.Regs.Gpr[25]}, + {"R26", r.Regs.Gpr[26]}, + {"R27", r.Regs.Gpr[27]}, + {"R28", r.Regs.Gpr[28]}, + {"R29", r.Regs.Gpr[29]}, + {"R30", r.Regs.Gpr[30]}, + {"R31", r.Regs.Gpr[31]}, + {"Nip", r.Regs.Nip}, + {"MSr", r.Regs.Msr}, + {"Orig_gpr3", r.Regs.Orig_gpr3}, + {"Ctr", r.Regs.Ctr}, + {"Link", r.Regs.Link}, + {"Xer", r.Regs.Xer}, + {"Ccr", r.Regs.Ccr}, + {"Softe", r.Regs.Softe}, + {"Trap", r.Regs.Trap}, + {"Dar", r.Regs.Dar}, + {"Dsisr", r.Regs.Dsisr}, + {"Result", r.Regs.Result}, + } + out := make([]proc.Register, 0, len(regs)+len(r.Fpregs)) + for _, reg := range regs { + out = proc.AppendUint64Register(out, reg.k, reg.v) + } + var floatLoadError error + if floatingPoint { + if r.loadFpRegs != nil { + floatLoadError = r.loadFpRegs(r) + r.loadFpRegs = nil + } + out = append(out, r.Fpregs...) + } + return out, floatLoadError +} + +// Copy returns a copy of these registers that is guaranteed not to change. +func (r *PPC64LERegisters) Copy() (proc.Registers, error) { + if r.loadFpRegs != nil { + err := r.loadFpRegs(r) + r.loadFpRegs = nil + if err != nil { + return nil, err + } + } + var rr PPC64LERegisters + rr.Regs = &PPC64LEPtraceRegs{} + *(rr.Regs) = *(r.Regs) + if r.Fpregs != nil { + rr.Fpregs = make([]proc.Register, len(r.Fpregs)) + copy(rr.Fpregs, r.Fpregs) + } + if r.Fpregset != nil { + rr.Fpregset = make([]byte, len(r.Fpregset)) + copy(rr.Fpregset, r.Fpregset) + } + return &rr, nil +} + +type PPC64LEPtraceFpRegs struct { + Fp []byte +} + +func (fpregs *PPC64LEPtraceFpRegs) Decode() (regs []proc.Register) { + for i := 0; i < len(fpregs.Fp); i += 16 { + regs = proc.AppendBytesRegister(regs, fmt.Sprintf("V%d", i/16), fpregs.Fp[i:i+16]) + } + return +} diff --git a/pkg/proc/native/hwbreak_other.go b/pkg/proc/native/hwbreak_other.go index 261448303c..a728bca744 100644 --- a/pkg/proc/native/hwbreak_other.go +++ b/pkg/proc/native/hwbreak_other.go @@ -1,5 +1,5 @@ -//go:build (linux && 386) || (darwin && arm64) || (windows && arm64) -// +build linux,386 darwin,arm64 windows,arm64 +//go:build (linux && 386) || (darwin && arm64) || (windows && arm64) || (linux && ppc64le) +// +build linux,386 darwin,arm64 windows,arm64 linux,ppc64le package native diff --git a/pkg/proc/native/proc.go b/pkg/proc/native/proc.go index da5d88650e..cd84391f2d 100644 --- a/pkg/proc/native/proc.go +++ b/pkg/proc/native/proc.go @@ -321,7 +321,11 @@ func (dbp *nativeProcess) initialize(path string, debugInfoDirs []string) (*proc // look like the breakpoint was hit twice when it was "logically" only // executed once. // See: https://go-review.googlesource.com/c/go/+/208126 - DisableAsyncPreempt: runtime.GOOS == "windows" || (runtime.GOOS == "linux" && runtime.GOARCH == "arm64"), + // - on linux/ppc64le according to @laboger, they had issues in the past + // with gdb once AsyncPreempt was enabled. While implementing the port, + // few tests failed while it was enabled, but cannot be warrantied that + // disabling it fixed the issues. + DisableAsyncPreempt: runtime.GOOS == "windows" || (runtime.GOOS == "linux" && runtime.GOARCH == "arm64") || (runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le"), StopReason: stopReason, CanDump: runtime.GOOS == "linux" || runtime.GOOS == "freebsd" || (runtime.GOOS == "windows" && runtime.GOARCH == "amd64"), @@ -331,7 +335,7 @@ func (dbp *nativeProcess) initialize(path string, debugInfoDirs []string) (*proc if err != nil { return nil, err } - if dbp.bi.Arch.Name == "arm64" { + if dbp.bi.Arch.Name == "arm64" || dbp.bi.Arch.Name == "ppc64le" { dbp.iscgo = tgt.IsCgo() } return grp, nil diff --git a/pkg/proc/native/ptrace_linux_64bit.go b/pkg/proc/native/ptrace_linux_64bit.go index 542645bdd4..ebc0b4c028 100644 --- a/pkg/proc/native/ptrace_linux_64bit.go +++ b/pkg/proc/native/ptrace_linux_64bit.go @@ -1,5 +1,5 @@ -//go:build (linux && amd64) || (linux && arm64) -// +build linux,amd64 linux,arm64 +//go:build (linux && amd64) || (linux && arm64) || (linux && ppc64le) +// +build linux,amd64 linux,arm64 linux,ppc64le package native diff --git a/pkg/proc/native/registers_linux_ppc64le.go b/pkg/proc/native/registers_linux_ppc64le.go new file mode 100644 index 0000000000..4cbdee638b --- /dev/null +++ b/pkg/proc/native/registers_linux_ppc64le.go @@ -0,0 +1,104 @@ +package native + +import ( + "debug/elf" + "syscall" + "unsafe" + + "github.com/go-delve/delve/pkg/dwarf/op" + "github.com/go-delve/delve/pkg/dwarf/regnum" + "github.com/go-delve/delve/pkg/proc" + "github.com/go-delve/delve/pkg/proc/linutil" + sys "golang.org/x/sys/unix" +) + +const ( + _PPC64LE_GPREGS_SIZE = 44 * 8 + _PPC64LE_FPREGS_SIZE = 33*8 + 8 +) + +func ptraceGetGRegs(pid int, regs *linutil.PPC64LEPtraceRegs) (err error) { + sys.PtraceGetRegs(pid, (*sys.PtraceRegs)(regs)) + if err == syscall.Errno(0) { + err = nil + } + return +} + +func ptraceSetGRegs(pid int, regs *linutil.PPC64LEPtraceRegs) (err error) { + sys.PtraceSetRegs(pid, (*sys.PtraceRegs)(regs)) + if err == syscall.Errno(0) { + err = nil + } + return +} + +func ptraceGetFpRegset(tid int) (fpregset []byte, err error) { + var ppc64leFpregs [_PPC64LE_FPREGS_SIZE]byte + iov := sys.Iovec{Base: &ppc64leFpregs[0], Len: _PPC64LE_FPREGS_SIZE} + _, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_GETREGSET, uintptr(tid), uintptr(elf.NT_FPREGSET), uintptr(unsafe.Pointer(&iov)), 0, 0) + if err != syscall.Errno(0) { + if err == syscall.ENODEV { + err = nil + } + return + } else { + err = nil + } + + fpregset = ppc64leFpregs[:iov.Len-8] + return fpregset, err +} + +// SetPC sets PC to the value specified by 'pc'. +func (t *nativeThread) setPC(pc uint64) error { + ir, err := registers(t) + if err != nil { + return err + } + r := ir.(*linutil.PPC64LERegisters) + r.Regs.Nip = pc + t.dbp.execPtraceFunc(func() { err = ptraceSetGRegs(t.ID, r.Regs) }) + return err +} + +// SetReg changes the value of the specified register. +func (t *nativeThread) SetReg(regNum uint64, reg *op.DwarfRegister) error { + ir, err := registers(t) + if err != nil { + return err + } + r := ir.(*linutil.PPC64LERegisters) + + switch regNum { + case regnum.PPC64LE_PC: + r.Regs.Nip = reg.Uint64Val + case regnum.PPC64LE_SP: + r.Regs.Gpr[1] = reg.Uint64Val + case regnum.PPC64LE_LR: + r.Regs.Link = reg.Uint64Val + default: + panic("SetReg") + } + + t.dbp.execPtraceFunc(func() { err = ptraceSetGRegs(t.ID, r.Regs) }) + return err +} + +func registers(thread *nativeThread) (proc.Registers, error) { + var ( + regs linutil.PPC64LEPtraceRegs + err error + ) + + thread.dbp.execPtraceFunc(func() { err = ptraceGetGRegs(thread.ID, ®s) }) + if err != nil { + return nil, err + } + r := linutil.NewPPC64LERegisters(®s, func(r *linutil.PPC64LERegisters) error { + var floatLoadError error + r.Fpregs, r.Fpregset, floatLoadError = thread.fpRegisters() + return floatLoadError + }) + return r, nil +} diff --git a/pkg/proc/native/support_sentinel_linux.go b/pkg/proc/native/support_sentinel_linux.go index 1325f09cc4..b13e206e38 100644 --- a/pkg/proc/native/support_sentinel_linux.go +++ b/pkg/proc/native/support_sentinel_linux.go @@ -1,6 +1,10 @@ // This file is used to detect build on unsupported GOOS/GOARCH combinations. -//go:build linux && !amd64 && !arm64 && !386 -// +build linux,!amd64,!arm64,!386 +//go:build linux && !amd64 && !arm64 && !386 && !(ppc64le && exp.linuxppc64le) +// +build linux +// +build !amd64 +// +build !arm64 +// +build !386 +// +build !ppc64le !exp.linuxppc64le package your_linux_architecture_is_not_supported_by_delve diff --git a/pkg/proc/native/threads_linux_ppc64le.go b/pkg/proc/native/threads_linux_ppc64le.go new file mode 100644 index 0000000000..d9b53d1269 --- /dev/null +++ b/pkg/proc/native/threads_linux_ppc64le.go @@ -0,0 +1,25 @@ +package native + +import ( + "fmt" + + "github.com/go-delve/delve/pkg/proc" + "github.com/go-delve/delve/pkg/proc/linutil" +) + +func (t *nativeThread) fpRegisters() ([]proc.Register, []byte, error) { + var regs []proc.Register + var fpregs linutil.PPC64LEPtraceFpRegs + var err error + + t.dbp.execPtraceFunc(func() { fpregs.Fp, err = ptraceGetFpRegset(t.ID) }) + regs = fpregs.Decode() + if err != nil { + err = fmt.Errorf("could not get floating point registers: %v", err.Error()) + } + return regs, fpregs.Fp, err +} + +func (t *nativeThread) restoreRegisters(savedRegs proc.Registers) error { + panic("Unimplemented restoreRegisters method in threads_linux_ppc64le.go") +} diff --git a/pkg/proc/ppc64le_arch.go b/pkg/proc/ppc64le_arch.go new file mode 100644 index 0000000000..53c82125c2 --- /dev/null +++ b/pkg/proc/ppc64le_arch.go @@ -0,0 +1,234 @@ +package proc + +import ( + "encoding/binary" + "fmt" + "strings" + + "github.com/go-delve/delve/pkg/dwarf/frame" + + "github.com/go-delve/delve/pkg/dwarf/op" + "github.com/go-delve/delve/pkg/dwarf/regnum" +) + +// This is the unconditional trap, the same mnemonic that both clang and gcc use +// It's documented in Section C.6 Trap Mnemonics in the Power ISA Book 3 +var ppc64leBreakInstruction = []byte{0x08, 0x00, 0xe0, 0x7f} + +func PPC64LEArch(goos string) *Arch { + return &Arch{ + Name: "ppc64le", + ptrSize: 8, + maxInstructionLength: 4, + breakpointInstruction: ppc64leBreakInstruction, + breakInstrMovesPC: false, + derefTLS: false, // Chapter 3.7 of the ELF V2 ABI Specification + prologues: prologuesPPC64LE, + fixFrameUnwindContext: ppc64leFixFrameUnwindContext, + switchStack: ppc64leSwitchStack, + regSize: ppc64leRegSize, + RegistersToDwarfRegisters: ppc64leRegistersToDwarfRegisters, + addrAndStackRegsToDwarfRegisters: ppc64leAddrAndStackRegsToDwarfRegisters, + DwarfRegisterToString: ppc64leDwarfRegisterToString, + inhibitStepInto: func(*BinaryInfo, uint64) bool { return false }, + asmDecode: ppc64leAsmDecode, + usesLR: true, + PCRegNum: regnum.PPC64LE_PC, + SPRegNum: regnum.PPC64LE_SP, + LRRegNum: regnum.PPC64LE_LR, + asmRegisters: ppc64leAsmRegisters, + RegisterNameToDwarf: nameToDwarfFunc(regnum.PPC64LENameToDwarf), + } +} + +func ppc64leFixFrameUnwindContext(fctxt *frame.FrameContext, pc uint64, bi *BinaryInfo) *frame.FrameContext { + a := bi.Arch + if a.sigreturnfn == nil { + a.sigreturnfn = bi.lookupOneFunc("runtime.sigreturn") + } + if fctxt == nil || (a.sigreturnfn != nil && pc >= a.sigreturnfn.Entry && pc < a.sigreturnfn.End) { + return &frame.FrameContext{ + RetAddrReg: regnum.PPC64LE_LR, + Regs: map[uint64]frame.DWRule{ + regnum.PPC64LE_PC: { + Rule: frame.RuleOffset, + Offset: int64(-a.PtrSize()), + }, + regnum.PPC64LE_LR: { + Rule: frame.RuleOffset, + Offset: int64(-2 * a.PtrSize()), + }, + regnum.PPC64LE_SP: { + Rule: frame.RuleValOffset, + Offset: 0, + }, + }, + CFA: frame.DWRule{ + Rule: frame.RuleCFA, + Reg: regnum.PPC64LE_SP, + Offset: int64(2 * a.PtrSize()), + }, + } + } + if a.crosscall2fn == nil { + // This is used to fix issues with the c calling frames + a.crosscall2fn = bi.lookupOneFunc("crosscall2") + } + + // Checks if we marked the function as a crosscall and if we are currently in it + if a.crosscall2fn != nil && pc >= a.crosscall2fn.Entry && pc < a.crosscall2fn.End { + rule := fctxt.CFA + if rule.Offset == crosscall2SPOffsetBad { + // Linux support only + rule.Offset += crosscall2SPOffsetLinuxPPC64LE + } + fctxt.CFA = rule + } + if fctxt.Regs[regnum.PPC64LE_LR].Rule == frame.RuleUndefined { + fctxt.Regs[regnum.PPC64LE_LR] = frame.DWRule{ + Rule: frame.RuleFramePointer, + Reg: regnum.PPC64LE_LR, + Offset: 0, + } + } + return fctxt +} + +const ppc64cgocallSPOffsetSaveSlot = 32 +const ppc64prevG0schedSPOffsetSaveSlot = 40 + +func ppc64leSwitchStack(it *stackIterator, callFrameRegs *op.DwarfRegisters) bool { + if it.frame.Current.Fn == nil && it.systemstack && it.g != nil && it.top { + it.switchToGoroutineStack() + return true + } + if it.frame.Current.Fn != nil { + switch it.frame.Current.Fn.Name { + case "runtime.asmcgocall", "runtime.cgocallback_gofunc", "runtime.sigpanic", "runtime.cgocallback": + //do nothing + case "runtime.goexit", "runtime.rt0_go", "runtime.mcall": + // Look for "top of stack" functions. + it.atend = true + return true + case "crosscall2": + //The offsets get from runtime/cgo/asm_ppc64x.s:10 + newsp, _ := readUintRaw(it.mem, it.regs.SP()+8*24, int64(it.bi.Arch.PtrSize())) + newbp, _ := readUintRaw(it.mem, it.regs.SP()+8*14, int64(it.bi.Arch.PtrSize())) + newlr, _ := readUintRaw(it.mem, it.regs.SP()+16, int64(it.bi.Arch.PtrSize())) + if it.regs.Reg(it.regs.BPRegNum) != nil { + it.regs.Reg(it.regs.BPRegNum).Uint64Val = newbp + } else { + reg, _ := it.readRegisterAt(it.regs.BPRegNum, it.regs.SP()+8*14) + it.regs.AddReg(it.regs.BPRegNum, reg) + } + it.regs.Reg(it.regs.LRRegNum).Uint64Val = newlr + it.regs.Reg(it.regs.SPRegNum).Uint64Val = newsp + it.pc = newlr + return true + default: + if it.systemstack && it.top && it.g != nil && strings.HasPrefix(it.frame.Current.Fn.Name, "runtime.") && it.frame.Current.Fn.Name != "runtime.fatalthrow" { + // The runtime switches to the system stack in multiple places. + // This usually happens through a call to runtime.systemstack but there + // are functions that switch to the system stack manually (for example + // runtime.morestack). + // Since we are only interested in printing the system stack for cgo + // calls we switch directly to the goroutine stack if we detect that the + // function at the top of the stack is a runtime function. + it.switchToGoroutineStack() + return true + } + } + } + fn := it.bi.PCToFunc(it.frame.Ret) + if fn == nil { + return false + } + switch fn.Name { + case "runtime.asmcgocall": + if !it.systemstack { + return false + } + + // This function is called by a goroutine to execute a C function and + // switches from the goroutine stack to the system stack. + // Since we are unwinding the stack from callee to caller we have to switch + // from the system stack to the goroutine stack. + off, _ := readIntRaw(it.mem, + callFrameRegs.SP()+ppc64cgocallSPOffsetSaveSlot, + int64(it.bi.Arch.PtrSize())) + oldsp := callFrameRegs.SP() + newsp := uint64(int64(it.stackhi) - off) + + // runtime.asmcgocall can also be called from inside the system stack, + // in that case no stack switch actually happens + if newsp == oldsp { + return false + } + it.systemstack = false + callFrameRegs.Reg(callFrameRegs.SPRegNum).Uint64Val = uint64(int64(newsp)) + return false + + case "runtime.cgocallback_gofunc", "runtime.cgocallback": + // For a detailed description of how this works read the long comment at + // the start of $GOROOT/src/runtime/cgocall.go and the source code of + // runtime.cgocallback_gofunc in $GOROOT/src/runtime/asm_ppc64.s + // + // When a C functions calls back into go it will eventually call into + // runtime.cgocallback_gofunc which is the function that does the stack + // switch from the system stack back into the goroutine stack + // Since we are going backwards on the stack here we see the transition + // as goroutine stack -> system stack. + if it.systemstack { + return false + } + + it.loadG0SchedSP() + if it.g0_sched_sp <= 0 { + return false + } + // entering the system stack + callFrameRegs.Reg(callFrameRegs.SPRegNum).Uint64Val = it.g0_sched_sp + // reads the previous value of g0.sched.sp that runtime.cgocallback_gofunc saved on the stack + + // TODO: is this save slot correct? + it.g0_sched_sp, _ = readUintRaw(it.mem, callFrameRegs.SP()+ppc64prevG0schedSPOffsetSaveSlot, int64(it.bi.Arch.PtrSize())) + it.systemstack = true + return false + } + + return false +} + +// ppc64leRegSize returns the size (in bytes) of register regnum. +func ppc64leRegSize(regnum uint64) int { + return 8 // each register is a 64-bit register +} + +func ppc64leRegistersToDwarfRegisters(staticBase uint64, regs Registers) *op.DwarfRegisters { + dregs := initDwarfRegistersFromSlice(int(regnum.PPC64LEMaxRegNum()), regs, regnum.PPC64LENameToDwarf) + dr := op.NewDwarfRegisters(staticBase, dregs, binary.LittleEndian, regnum.PPC64LE_PC, regnum.PPC64LE_SP, regnum.PPC64LE_SP, regnum.PPC64LE_LR) + dr.SetLoadMoreCallback(loadMoreDwarfRegistersFromSliceFunc(dr, regs, regnum.PPC64LENameToDwarf)) + return dr +} + +func ppc64leAddrAndStackRegsToDwarfRegisters(staticBase, pc, sp, bp, lr uint64) op.DwarfRegisters { + dregs := make([]*op.DwarfRegister, regnum.PPC64LE_LR+1) + dregs[regnum.PPC64LE_PC] = op.DwarfRegisterFromUint64(pc) + dregs[regnum.PPC64LE_SP] = op.DwarfRegisterFromUint64(sp) + dregs[regnum.PPC64LE_LR] = op.DwarfRegisterFromUint64(lr) + + return *op.NewDwarfRegisters(staticBase, dregs, binary.LittleEndian, regnum.PPC64LE_PC, regnum.PPC64LE_SP, 0, regnum.PPC64LE_LR) +} + +func ppc64leDwarfRegisterToString(i int, reg *op.DwarfRegister) (name string, floatingPoint bool, repr string) { + name = regnum.PPC64LEToName(uint64(i)) + + if reg == nil { + return name, false, "" + } + + if reg.Bytes == nil || (reg.Bytes != nil && len(reg.Bytes) < 16) { + return name, false, fmt.Sprintf("%#016x", reg.Uint64Val) + } + return name, true, fmt.Sprintf("%#x", reg.Bytes) +} diff --git a/pkg/proc/ppc64le_disasm.go b/pkg/proc/ppc64le_disasm.go new file mode 100644 index 0000000000..c3f9a72e3a --- /dev/null +++ b/pkg/proc/ppc64le_disasm.go @@ -0,0 +1,161 @@ +package proc + +import ( + "encoding/binary" + + "github.com/go-delve/delve/pkg/dwarf/op" + "github.com/go-delve/delve/pkg/dwarf/regnum" + "golang.org/x/arch/ppc64/ppc64asm" +) + +// Possible stacksplit prologues are inserted by stacksplit in +// $GOROOT/src/cmd/internal/obj/ppc64/obj9.go. +var prologuesPPC64LE []opcodeSeq + +func init() { + // Note: these will be the gnu opcodes and not the Go opcodes. Verify the sequences are as expected. + var tinyStacksplit = opcodeSeq{uint64(ppc64asm.ADDI), uint64(ppc64asm.CMPLD), uint64(ppc64asm.BC)} + var smallStacksplit = opcodeSeq{uint64(ppc64asm.ADDI), uint64(ppc64asm.CMPLD), uint64(ppc64asm.BC)} + var bigStacksplit = opcodeSeq{uint64(ppc64asm.ADDI), uint64(ppc64asm.CMPLD), uint64(ppc64asm.BC), uint64(ppc64asm.STD), uint64(ppc64asm.STD), uint64(ppc64asm.MFSPR)} + + var unixGetG = opcodeSeq{uint64(ppc64asm.LD)} + prologuesPPC64LE = make([]opcodeSeq, 0, 3) + for _, getG := range []opcodeSeq{unixGetG} { + for _, stacksplit := range []opcodeSeq{tinyStacksplit, smallStacksplit, bigStacksplit} { + prologue := make(opcodeSeq, 0, len(getG)+len(stacksplit)) + prologue = append(prologue, getG...) + prologue = append(prologue, stacksplit...) + prologuesPPC64LE = append(prologuesPPC64LE, prologue) + } + } +} + +func ppc64leAsmDecode(asmInst *AsmInstruction, mem []byte, regs *op.DwarfRegisters, memrw MemoryReadWriter, bi *BinaryInfo) error { + asmInst.Size = 4 + asmInst.Bytes = mem[:asmInst.Size] + + inst, err := ppc64asm.Decode(mem, binary.LittleEndian) + if err != nil { + asmInst.Inst = (*ppc64ArchInst)(nil) + return err + } + asmInst.Inst = (*ppc64ArchInst)(&inst) + asmInst.Kind = OtherInstruction + + switch inst.Op { + case ppc64asm.BL, ppc64asm.BLA, ppc64asm.BCL, ppc64asm.BCLA, ppc64asm.BCLRL, ppc64asm.BCCTRL, ppc64asm.BCTARL: + // Pages 38-40 Book I v3.0 + asmInst.Kind = CallInstruction + case ppc64asm.RFEBB, ppc64asm.RFID, ppc64asm.HRFID, ppc64asm.RFI, ppc64asm.RFCI, ppc64asm.RFDI, ppc64asm.RFMCI, ppc64asm.RFGI, ppc64asm.BCLR: + asmInst.Kind = RetInstruction + case ppc64asm.B, ppc64asm.BA, ppc64asm.BC, ppc64asm.BCA, ppc64asm.BCCTR, ppc64asm.BCTAR: + // Pages 38-40 Book I v3.0 + asmInst.Kind = JmpInstruction + case ppc64asm.TD, ppc64asm.TDI, ppc64asm.TW, ppc64asm.TWI: + asmInst.Kind = HardBreakInstruction + } + + asmInst.DestLoc = resolveCallArgPPC64LE(&inst, asmInst.Loc.PC, asmInst.AtPC, regs, memrw, bi) + return nil +} + +func resolveCallArgPPC64LE(inst *ppc64asm.Inst, instAddr uint64, currentGoroutine bool, regs *op.DwarfRegisters, mem MemoryReadWriter, bininfo *BinaryInfo) *Location { + switch inst.Op { + case ppc64asm.BCLRL, ppc64asm.BCLR: + if regs != nil && regs.PC() == instAddr { + pc := regs.Reg(bininfo.Arch.LRRegNum).Uint64Val + file, line, fn := bininfo.PCToLine(pc) + if fn == nil { + return &Location{PC: pc} + } + return &Location{PC: pc, File: file, Line: line, Fn: fn} + } + return nil + case ppc64asm.B, ppc64asm.BL, ppc64asm.BLA, ppc64asm.BCL, ppc64asm.BCLA, ppc64asm.BCCTRL, ppc64asm.BCTARL: + // ok + default: + return nil + } + + var pc uint64 + var err error + + switch arg := inst.Args[0].(type) { + case ppc64asm.Imm: + pc = uint64(arg) + case ppc64asm.Reg: + if !currentGoroutine || regs == nil { + return nil + } + pc, err = bininfo.Arch.getAsmRegister(regs, int(arg)) + if err != nil { + return nil + } + case ppc64asm.PCRel: + pc = instAddr + uint64(arg) + default: + return nil + } + + file, line, fn := bininfo.PCToLine(pc) + if fn == nil { + return &Location{PC: pc} + } + return &Location{PC: pc, File: file, Line: line, Fn: fn} +} + +type ppc64ArchInst ppc64asm.Inst + +func (inst *ppc64ArchInst) Text(flavour AssemblyFlavour, pc uint64, symLookup func(uint64) (string, uint64)) string { + if inst == nil { + return "?" + } + + var text string + + switch flavour { + case GNUFlavour: + text = ppc64asm.GNUSyntax(ppc64asm.Inst(*inst), pc) + default: + text = ppc64asm.GoSyntax(ppc64asm.Inst(*inst), pc, symLookup) + } + + return text +} + +func (inst *ppc64ArchInst) OpcodeEquals(op uint64) bool { + if inst == nil { + return false + } + return uint64(inst.Op) == op +} + +var ppc64leAsmRegisters = func() map[int]asmRegister { + r := make(map[int]asmRegister) + + // General Purpose Registers: from R0 to R31 + for i := ppc64asm.R0; i <= ppc64asm.R31; i++ { + r[int(i)] = asmRegister{regnum.PPC64LE_R0 + uint64(i-ppc64asm.R0), 0, 0} + } + + // Floating point registers: from F0 to F31 + for i := ppc64asm.F0; i <= ppc64asm.F31; i++ { + r[int(i)] = asmRegister{regnum.PPC64LE_F0 + uint64(i-ppc64asm.F0), 0, 0} + } + + // Vector (Altivec/VMX) registers: from V0 to V31 + for i := ppc64asm.V0; i <= ppc64asm.V31; i++ { + r[int(i)] = asmRegister{regnum.PPC64LE_V0 + uint64(i-ppc64asm.V0), 0, 0} + } + + // Vector Scalar (VSX) registers: from VS0 to VS63 + for i := ppc64asm.VS0; i <= ppc64asm.VS63; i++ { + r[int(i)] = asmRegister{regnum.PPC64LE_VS0 + uint64(i-ppc64asm.VS0), 0, 0} + } + + // Condition Registers: from CR0 to CR7 + for i := ppc64asm.CR0; i <= ppc64asm.CR7; i++ { + r[int(i)] = asmRegister{regnum.PPC64LE_CR0 + uint64(i-ppc64asm.CR0), 0, 0} + } + return r +}() diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index f00a10a777..4e5d5ca987 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -809,6 +809,7 @@ func TestFindReturnAddress(t *testing.T) { } func TestFindReturnAddressTopOfStackFn(t *testing.T) { + skipOn(t, "broken in linux ppc64le", "linux", "ppc64le", "native") protest.AllowRecording(t) withTestProcess("testreturnaddress", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { fnName := "runtime.rt0_go" @@ -903,6 +904,7 @@ func (l1 *loc) match(l2 proc.Stackframe) bool { } func TestStacktrace(t *testing.T) { + skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") stacks := [][]loc{ {{4, "main.stacktraceme"}, {8, "main.func1"}, {16, "main.main"}}, {{4, "main.stacktraceme"}, {8, "main.func1"}, {12, "main.func2"}, {17, "main.main"}}, @@ -987,6 +989,7 @@ func stackMatch(stack []loc, locations []proc.Stackframe, skipRuntime bool) bool func TestStacktraceGoroutine(t *testing.T) { skipOn(t, "broken - cgo stacktraces", "darwin", "arm64") + skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") mainStack := []loc{{14, "main.stacktraceme"}, {29, "main.main"}} if goversion.VersionAfterOrEqual(runtime.Version(), 1, 11) { @@ -1311,6 +1314,7 @@ func TestVariableEvaluation(t *testing.T) { } func TestFrameEvaluation(t *testing.T) { + skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") protest.AllowRecording(t) lenient := false if runtime.GOOS == "windows" { @@ -2303,6 +2307,7 @@ func TestNextDeferReturnAndDirectCall(t *testing.T) { } func TestNextPanicAndDirectCall(t *testing.T) { + skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Next should not step into a deferred function if it is called // directly, only if it is called through a panic or a deferreturn. // Here we test the case where the function is called by a panic @@ -2320,6 +2325,7 @@ func TestStepCall(t *testing.T) { } func TestStepCallPtr(t *testing.T) { + skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that Step works correctly when calling functions with a // function pointer. if goversion.VersionAfterOrEqual(runtime.Version(), 1, 11) && !protest.RegabiSupported() { @@ -2339,6 +2345,7 @@ func TestStepCallPtr(t *testing.T) { } func TestStepReturnAndPanic(t *testing.T) { + skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that Step works correctly when returning from functions // and when a deferred function is called when panic'ing. testseq("defercall", contStep, []nextTest{ @@ -2350,6 +2357,7 @@ func TestStepReturnAndPanic(t *testing.T) { } func TestStepDeferReturn(t *testing.T) { + skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that Step works correctly when a deferred function is // called during a return. testseq("defercall", contStep, []nextTest{ @@ -2364,6 +2372,7 @@ func TestStepDeferReturn(t *testing.T) { } func TestStepIgnorePrivateRuntime(t *testing.T) { + skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that Step will ignore calls to private runtime functions // (such as runtime.convT2E in this case) switch { @@ -2742,6 +2751,7 @@ func TestIssue594(t *testing.T) { } func TestStepOutPanicAndDirectCall(t *testing.T) { + skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // StepOut should not step into a deferred function if it is called // directly, only if it is called through a panic. // Here we test the case where the function is called by a panic @@ -3170,6 +3180,7 @@ func TestDebugStripped(t *testing.T) { // TODO(derekparker): Add support for Mach-O and PE. skipUnlessOn(t, "linux only", "linux") skipOn(t, "not working on linux/386 with PIE", "linux", "386", "pie") + skipOn(t, "not working on linux/ppc64le when -gcflags=-N -l is passed", "linux", "ppc64le") withTestProcessArgs("testnextprog", t, "", []string{}, protest.LinkStrip, func(p *proc.Target, grp *proc.TargetGroup, f protest.Fixture) { setFunctionBreakpoint(p, t, "main.main") assertNoError(grp.Continue(), t, "Continue") @@ -3308,6 +3319,8 @@ func TestCgoStacktrace(t *testing.T) { } } skipOn(t, "broken - cgo stacktraces", "386") + skipOn(t, "broken - cgo stacktraces", "windows", "arm64") + skipOn(t, "broken - cgo stacktraces", "linux", "ppc64le") if !goversion.VersionAfterOrEqual(runtime.Version(), 1, 21) { skipOn(t, "broken - cgo stacktraces", "windows", "arm64") } @@ -3437,6 +3450,7 @@ func TestCgoSources(t *testing.T) { } func TestSystemstackStacktrace(t *testing.T) { + skipOn(t, "broken", "ppc64le") // check that we can follow a stack switch initiated by runtime.systemstack() withTestProcess("panic", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { setFunctionBreakpoint(p, t, "runtime.startpanic_m") @@ -3455,6 +3469,7 @@ func TestSystemstackStacktrace(t *testing.T) { } func TestSystemstackOnRuntimeNewstack(t *testing.T) { + skipOn(t, "broken", "ppc64le") // The bug being tested here manifests as follows: // - set a breakpoint somewhere or interrupt the program with Ctrl-C // - try to look at stacktraces of other goroutines @@ -3692,7 +3707,8 @@ func TestHaltKeepsSteppingBreakpoints(t *testing.T) { } func TestDisassembleGlobalVars(t *testing.T) { - skipOn(t, "broken - global variable symbolication", "arm64") // On ARM64 symLookup can't look up variables due to how they are loaded, see issue #1778 + skipOn(t, "broken - global variable symbolication", "arm64") // On ARM64 symLookup can't look up variables due to how they are loaded, see issue #1778 + skipOn(t, "broken - global variable symbolication", "ppc64le") // See comment on ARM64 above. // On 386 linux when pie, the generated code use __x86.get_pc_thunk to ensure position-independent. // Locate global variable by // `CALL __x86.get_pc_thunk.ax(SB) 0xb0f7f @@ -3878,6 +3894,7 @@ func TestInlinedStacktraceAndVariables(t *testing.T) { } func TestInlineStep(t *testing.T) { + skipOn(t, "broken", "ppc64le") if ver, _ := goversion.Parse(runtime.Version()); ver.Major >= 0 && !ver.AfterOrEqual(goversion.GoVersion{Major: 1, Minor: 10, Rev: -1}) { // Versions of go before 1.10 do not have DWARF information for inlined calls t.Skip("inlining not supported") @@ -4038,6 +4055,7 @@ func TestIssue951(t *testing.T) { } func TestDWZCompression(t *testing.T) { + skipOn(t, "broken", "ppc64le") // If dwz is not available in the system, skip this test if _, err := exec.LookPath("dwz"); err != nil { t.Skip("dwz not installed") @@ -4610,6 +4628,7 @@ func TestCgoStacktrace2(t *testing.T) { skipOn(t, "broken", "386") } skipOn(t, "broken - cgo stacktraces", "darwin", "arm64") + skipOn(t, "broken", "ppc64le") protest.MustHaveCgo(t) // If a panic happens during cgo execution the stacktrace should show the C // function that caused the problem. @@ -4718,6 +4737,7 @@ func TestIssue1795(t *testing.T) { if !goversion.VersionAfterOrEqual(runtime.Version(), 1, 13) { t.Skip("Test not relevant to Go < 1.13") } + skipOn(t, "broken", "ppc64le") withTestProcessArgs("issue1795", t, ".", []string{}, protest.EnableInlining|protest.EnableOptimization, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { assertNoError(grp.Continue(), t, "Continue()") assertLineNumber(p, t, 12, "wrong line number after Continue,") @@ -5149,6 +5169,7 @@ func TestDump(t *testing.T) { if (runtime.GOOS == "darwin" && testBackend == "native") || (runtime.GOOS == "windows" && runtime.GOARCH != "amd64") { t.Skip("not supported") } + skipOn(t, "not implemented", "ppc64le") convertRegisters := func(arch *proc.Arch, dregs op.DwarfRegisters) string { dregs.Reg(^uint64(0)) @@ -5398,6 +5419,7 @@ func TestVariablesWithExternalLinking(t *testing.T) { func TestWatchpointsBasic(t *testing.T) { skipOn(t, "not implemented", "freebsd") skipOn(t, "not implemented", "386") + skipOn(t, "not implemented", "ppc64le") skipOn(t, "see https://github.com/go-delve/delve/issues/2768", "windows") protest.AllowRecording(t) @@ -5458,6 +5480,7 @@ func TestWatchpointCounts(t *testing.T) { skipOn(t, "not implemented", "freebsd") skipOn(t, "not implemented", "386") skipOn(t, "see https://github.com/go-delve/delve/issues/2768", "windows") + skipOn(t, "not implemented", "ppc64le") protest.AllowRecording(t) withTestProcess("databpcountstest", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { @@ -5545,6 +5568,7 @@ func TestManualStopWhileStopped(t *testing.T) { } func TestDwrapStartLocation(t *testing.T) { + skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that the start location of a goroutine is unwrapped in Go 1.17 and later. withTestProcess("goroutinestackprog", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { setFunctionBreakpoint(p, t, "main.stacktraceme") @@ -5572,6 +5596,7 @@ func TestDwrapStartLocation(t *testing.T) { func TestWatchpointStack(t *testing.T) { skipOn(t, "not implemented", "freebsd") skipOn(t, "not implemented", "386") + skipOn(t, "not implemented", "ppc64le") skipOn(t, "see https://github.com/go-delve/delve/issues/2768", "windows") protest.AllowRecording(t) @@ -5768,13 +5793,15 @@ func TestNilPtrDerefInBreakInstr(t *testing.T) { asmfile = "main_arm64.s" case "386": asmfile = "main_386.s" + case "ppc64le": + asmfile = "main_ppc64le.s" default: t.Fatalf("assembly file for %s not provided", runtime.GOARCH) } withTestProcess("asmnilptr/", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { f := filepath.Join(fixture.BuildDir, asmfile) - f = strings.ReplaceAll(f, "\\", "/") + f = strings.Replace(f, "\\", "/", -1) setFileBreakpoint(p, t, f, 5) t.Logf("first continue") assertNoError(grp.Continue(), t, "Continue()") @@ -6042,6 +6069,7 @@ func TestEscapeCheckUnreadable(t *testing.T) { } func TestStepShadowConcurrentBreakpoint(t *testing.T) { + skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Checks that a StepBreakpoint can not shadow a concurrently hit user breakpoint withTestProcess("stepshadow", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { break2 := setFunctionBreakpoint(p, t, "main.stacktraceme2") diff --git a/pkg/proc/stack.go b/pkg/proc/stack.go index fb6260bcab..fc3feb007b 100644 --- a/pkg/proc/stack.go +++ b/pkg/proc/stack.go @@ -280,7 +280,7 @@ func (it *stackIterator) switchToGoroutineStack() { it.pc = it.g.PC it.regs.Reg(it.regs.SPRegNum).Uint64Val = it.g.SP it.regs.AddReg(it.regs.BPRegNum, op.DwarfRegisterFromUint64(it.g.BP)) - if it.bi.Arch.Name == "arm64" { + if it.bi.Arch.Name == "arm64" || it.bi.Arch.Name == "ppc64le" { it.regs.Reg(it.regs.LRRegNum).Uint64Val = it.g.LR } } @@ -475,7 +475,7 @@ func (it *stackIterator) advanceRegs() (callFrameRegs op.DwarfRegisters, ret uin // In the following line we copy GDB's behaviour by assuming this is // implicit. // See also the comment in dwarf2_frame_default_init in - // $GDB_SOURCE/dwarf2-frame.c + // $GDB_SOURCE/dwarf2/frame.c callFrameRegs.AddReg(callFrameRegs.SPRegNum, cfareg) for i, regRule := range framectx.Regs { @@ -504,7 +504,7 @@ func (it *stackIterator) advanceRegs() (callFrameRegs op.DwarfRegisters, ret uin } } - if it.bi.Arch.Name == "arm64" { + if it.bi.Arch.Name == "arm64" || it.bi.Arch.Name == "ppc64le" { if ret == 0 && it.regs.Reg(it.regs.LRRegNum) != nil { ret = it.regs.Reg(it.regs.LRRegNum).Uint64Val } diff --git a/pkg/proc/target_exec.go b/pkg/proc/target_exec.go index dae0afae04..630f83ab37 100644 --- a/pkg/proc/target_exec.go +++ b/pkg/proc/target_exec.go @@ -8,8 +8,11 @@ import ( "go/ast" "go/token" "path/filepath" + "runtime" "strings" + "golang.org/x/arch/ppc64/ppc64asm" + "github.com/go-delve/delve/pkg/astutil" "github.com/go-delve/delve/pkg/dwarf/reader" ) @@ -913,7 +916,16 @@ func setStepIntoBreakpoint(dbp *Target, curfn *Function, text []AsmInstruction, return nil } + pc := instr.DestLoc.PC fn := instr.DestLoc.Fn + if runtime.GOARCH == "ppc64le" && instr.Inst.OpcodeEquals(uint64(ppc64asm.BCLRL)) { + regs, err := dbp.CurrentThread().Registers() + if err != nil { + return err + } + lr := regs.LR() + fn = dbp.BinInfo().PCToFunc(lr) + } // Skip unexported runtime functions if !stepIntoUnexportedRuntime && fn != nil && fn.privateRuntime() { @@ -924,8 +936,6 @@ func setStepIntoBreakpoint(dbp *Target, curfn *Function, text []AsmInstruction, // or entire packages from being stepped into with 'step' // those extra checks should be done here. - pc := instr.DestLoc.PC - // Skip InhibitStepInto functions for different arch. if dbp.BinInfo().Arch.inhibitStepInto(dbp.BinInfo(), pc) { return nil diff --git a/pkg/proc/test/support.go b/pkg/proc/test/support.go index 2e882d99ba..7b87ced55c 100644 --- a/pkg/proc/test/support.go +++ b/pkg/proc/test/support.go @@ -310,7 +310,7 @@ func MustSupportFunctionCalls(t *testing.T, testBackend string) { if runtime.GOOS == "darwin" && os.Getenv("TRAVIS") == "true" && runtime.GOARCH == "amd64" { t.Skip("function call injection tests are failing on macOS on Travis-CI (see #1802)") } - if runtime.GOARCH == "386" { + if runtime.GOARCH == "386" || runtime.GOARCH == "ppc64le" { t.Skip(fmt.Errorf("%s does not support FunctionCall for now", runtime.GOARCH)) } if runtime.GOARCH == "arm64" { diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go index fa317aa7ac..01435e2b78 100644 --- a/pkg/proc/variables_test.go +++ b/pkg/proc/variables_test.go @@ -1462,6 +1462,7 @@ func assertCurrentLocationFunction(p *proc.Target, t *testing.T, fnname string) } func TestPluginVariables(t *testing.T) { + skipOn(t, "broken", "ppc64le") pluginFixtures := protest.WithPlugins(t, protest.AllNonOptimized, "plugin1/", "plugin2/") withTestProcessArgs("plugintest2", t, ".", []string{pluginFixtures[0].Path, pluginFixtures[1].Path}, protest.AllNonOptimized, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { @@ -1544,6 +1545,10 @@ func TestCgoEval(t *testing.T) { t.Skip("cgo doesn't work on darwin/arm64") } + if runtime.GOARCH == "ppc64le" { + t.Skip("skipped on ppc64le: broken") + } + protest.AllowRecording(t) withTestProcess("testvariablescgo/", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { assertNoError(grp.Continue(), t, "Continue() returned an error") diff --git a/pkg/terminal/command_test.go b/pkg/terminal/command_test.go index 36ac44e84c..925568ac16 100644 --- a/pkg/terminal/command_test.go +++ b/pkg/terminal/command_test.go @@ -305,6 +305,9 @@ func TestExitStatus(t *testing.T) { } func TestScopePrefix(t *testing.T) { + if runtime.GOARCH == "ppc64le" && buildMode == "pie" { + t.Skip("pie mode broken on ppc64le") + } const goroutinesLinePrefix = " Goroutine " const goroutinesCurLinePrefix = "* Goroutine " test.AllowRecording(t) @@ -873,6 +876,9 @@ func TestIssue1090(t *testing.T) { } func TestPrintContextParkedGoroutine(t *testing.T) { + if runtime.GOARCH == "ppc64le" && buildMode == "pie" { + t.Skip("pie mode broken on ppc64le") + } withTestTerminal("goroutinestackprog", t, func(term *FakeTerminal) { term.MustExec("break stacktraceme") term.MustExec("continue") @@ -946,6 +952,9 @@ func TestOptimizationCheck(t *testing.T) { } func TestTruncateStacktrace(t *testing.T) { + if runtime.GOARCH == "ppc64le" && buildMode == "pie" { + t.Skip("pie mode broken on ppc64le") + } const stacktraceTruncatedMessage = "(truncated)" withTestTerminal("stacktraceprog", t, func(term *FakeTerminal) { term.MustExec("break main.stacktraceme") @@ -966,6 +975,9 @@ func TestTruncateStacktrace(t *testing.T) { func TestIssue1493(t *testing.T) { // The 'regs' command without the '-a' option should only return // general purpose registers. + if runtime.GOARCH == "ppc64le" { + t.Skip("skipping, some registers such as vector registers are currently not loaded") + } withTestTerminal("continuetestprog", t, func(term *FakeTerminal) { r := term.MustExec("regs") nr := len(strings.Split(r, "\n")) @@ -1381,6 +1393,9 @@ func TestTranscript(t *testing.T) { } func TestDisassPosCmd(t *testing.T) { + if runtime.GOARCH == "ppc64le" && buildMode == "pie" { + t.Skip("pie mode broken on ppc64le") + } withTestTerminal("testvariables2", t, func(term *FakeTerminal) { term.MustExec("continue") out := term.MustExec("step-instruction") diff --git a/service/dap/server_test.go b/service/dap/server_test.go index 3b142dca92..c2d8dfebfa 100644 --- a/service/dap/server_test.go +++ b/service/dap/server_test.go @@ -2458,6 +2458,9 @@ func TestGlobalScopeAndVariables(t *testing.T) { // got loaded. It then steps into a function in another package and tests that // the registers were updated by checking PC. func TestRegistersScopeAndVariables(t *testing.T) { + if runtime.GOARCH == "ppc64le" { + t.Skip("skipped on ppc64le: broken") + } runTest(t, "consts", func(client *daptest.Client, fixture protest.Fixture) { runDebugSessionWithBPs(t, client, "launch", // Launch diff --git a/service/debugger/debugger_test.go b/service/debugger/debugger_test.go index 9af7a75fed..3e78257b04 100644 --- a/service/debugger/debugger_test.go +++ b/service/debugger/debugger_test.go @@ -53,6 +53,9 @@ func TestDebugger_LaunchInvalidFormat(t *testing.T) { if runtime.GOARCH == "arm64" && runtime.GOOS == "linux" { os.Setenv("GOARCH", "amd64") } + if runtime.GOARCH == "ppc64le" && runtime.GOOS == "linux" { + os.Setenv("GOARCH", "amd64") + } os.Setenv("GOOS", switchOS[runtime.GOOS]) exepath := filepath.Join(buildtestdir, debugname) if err := gobuild.GoBuild(debugname, []string{buildtestdir}, fmt.Sprintf("-o %s", exepath)); err != nil { diff --git a/service/debugger/debugger_unix_test.go b/service/debugger/debugger_unix_test.go index 07f78833a0..d0bc009ac4 100644 --- a/service/debugger/debugger_unix_test.go +++ b/service/debugger/debugger_unix_test.go @@ -36,6 +36,9 @@ func TestDebugger_LaunchNoExecutablePerm(t *testing.T) { if runtime.GOARCH == "arm64" && runtime.GOOS == "linux" { os.Setenv("GOARCH", "amd64") } + if runtime.GOARCH == "ppc64le" && runtime.GOOS == "linux" { + os.Setenv("GOARCH", "amd64") + } os.Setenv("GOOS", switchOS[runtime.GOOS]) exepath := filepath.Join(buildtestdir, debugname) defer os.Remove(exepath) diff --git a/service/test/integration1_test.go b/service/test/integration1_test.go index 93f4df82c6..9e9dd3ce5a 100644 --- a/service/test/integration1_test.go +++ b/service/test/integration1_test.go @@ -564,6 +564,9 @@ func Test1ClientServer_traceContinue2(t *testing.T) { } func Test1ClientServer_FindLocations(t *testing.T) { + if buildMode == "pie" && runtime.GOARCH == "ppc64le" { + t.Skip("skipped on ppc64le: broken") + } withTestClient1("locationsprog", t, func(c *rpc1.RPCClient) { someFunctionCallAddr := findLocationHelper(t, c, "locationsprog.go:26", false, 1, 0)[0] someFunctionLine1 := findLocationHelper(t, c, "locationsprog.go:27", false, 1, 0)[0] @@ -719,6 +722,9 @@ func Test1ClientServer_FullStacktrace(t *testing.T) { if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { t.Skip("cgo doesn't work on darwin/arm64") } + if runtime.GOARCH == "ppc64le" && buildMode == "pie" { + t.Skip("pie mode broken on ppc64le") + } lenient := false if runtime.GOOS == "windows" { @@ -858,6 +864,9 @@ func Test1Issue355(t *testing.T) { } func Test1Disasm(t *testing.T) { + if runtime.GOARCH == "ppc64le" { + t.Skip("skipped on ppc64le: broken") + } // Tests that disassembling by PC, range, and current PC all yield similar results // Tests that disassembly by current PC will return a disassembly containing the instruction at PC // Tests that stepping on a calculated CALL instruction will yield a disassembly that contains the diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go index 6b03a852bd..50f2644949 100644 --- a/service/test/integration2_test.go +++ b/service/test/integration2_test.go @@ -946,6 +946,9 @@ func TestClientServer_traceContinue2(t *testing.T) { } func TestClientServer_FindLocations(t *testing.T) { + if runtime.GOARCH == "ppc64le" && buildMode == "pie" { + t.Skip("pie mode broken on ppc64le") + } withTestClient2("locationsprog", t, func(c service.Client) { someFunctionCallAddr := findLocationHelper(t, c, "locationsprog.go:26", false, 1, 0)[0] someFunctionLine1 := findLocationHelper(t, c, "locationsprog.go:27", false, 1, 0)[0] @@ -1210,6 +1213,9 @@ func TestClientServer_FullStacktrace(t *testing.T) { if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { t.Skip("cgo doesn't work on darwin/arm64") } + if runtime.GOARCH == "ppc64le" && buildMode == "pie" { + t.Skip("pie mode broken on ppc64le") + } lenient := false if runtime.GOOS == "windows" { @@ -1362,6 +1368,9 @@ func TestIssue355(t *testing.T) { } func TestDisasm(t *testing.T) { + if runtime.GOARCH == "ppc64le" { + t.Skip("skipped on ppc64le: broken") + } // Tests that disassembling by PC, range, and current PC all yield similar results // Tests that disassembly by current PC will return a disassembly containing the instruction at PC // Tests that stepping on a calculated CALL instruction will yield a disassembly that contains the @@ -2858,6 +2867,9 @@ func assertLine(t *testing.T, state *api.DebuggerState, file string, lineno int) } func TestPluginSuspendedBreakpoint(t *testing.T) { + if runtime.GOARCH == "ppc64le" { + t.Skip("skipped on ppc64le: broken") + } // Tests that breakpoints created in a suspended state will be enabled automatically when a plugin is loaded. pluginFixtures := protest.WithPlugins(t, protest.AllNonOptimized, "plugin1/", "plugin2/") dir, err := filepath.Abs(protest.FindFixturesDir()) diff --git a/vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go b/vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go new file mode 100644 index 0000000000..5f04ff40e4 --- /dev/null +++ b/vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go @@ -0,0 +1,179 @@ +// Copyright 2014 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 ppc64asm + +import ( + "encoding/binary" + "fmt" + "log" +) + +const debugDecode = false + +// instFormat is a decoding rule for one specific instruction form. +// a uint32 instruction ins matches the rule if ins&Mask == Value +// DontCare bits should be zero, but the machine might not reject +// ones in those bits, they are mainly reserved for future expansion +// of the instruction set. +// The Args are stored in the same order as the instruction manual. +type instFormat struct { + Op Op + Mask uint32 + Value uint32 + DontCare uint32 + Args [5]*argField +} + +// argField indicate how to decode an argument to an instruction. +// First parse the value from the BitFields, shift it left by Shift +// bits to get the actual numerical value. +type argField struct { + Type ArgType + Shift uint8 + BitFields +} + +// Parse parses the Arg out from the given binary instruction i. +func (a argField) Parse(i uint32) Arg { + switch a.Type { + default: + return nil + case TypeUnknown: + return nil + case TypeReg: + return R0 + Reg(a.BitFields.Parse(i)) + case TypeCondRegBit: + return Cond0LT + CondReg(a.BitFields.Parse(i)) + case TypeCondRegField: + return CR0 + CondReg(a.BitFields.Parse(i)) + case TypeFPReg: + return F0 + Reg(a.BitFields.Parse(i)) + case TypeVecReg: + return V0 + Reg(a.BitFields.Parse(i)) + case TypeVecSReg: + return VS0 + Reg(a.BitFields.Parse(i)) + case TypeSpReg: + return SpReg(a.BitFields.Parse(i)) + case TypeImmSigned: + return Imm(a.BitFields.ParseSigned(i) << a.Shift) + case TypeImmUnsigned: + return Imm(a.BitFields.Parse(i) << a.Shift) + case TypePCRel: + return PCRel(a.BitFields.ParseSigned(i) << a.Shift) + case TypeLabel: + return Label(a.BitFields.ParseSigned(i) << a.Shift) + case TypeOffset: + return Offset(a.BitFields.ParseSigned(i) << a.Shift) + } +} + +type ArgType int8 + +const ( + TypeUnknown ArgType = iota + TypePCRel // PC-relative address + TypeLabel // absolute address + TypeReg // integer register + TypeCondRegBit // conditional register bit (0-31) + TypeCondRegField // conditional register field (0-7) + TypeFPReg // floating point register + TypeVecReg // vector register + TypeVecSReg // VSX register + TypeSpReg // special register (depends on Op) + TypeImmSigned // signed immediate + TypeImmUnsigned // unsigned immediate/flag/mask, this is the catch-all type + TypeOffset // signed offset in load/store + TypeLast // must be the last one +) + +func (t ArgType) String() string { + switch t { + default: + return fmt.Sprintf("ArgType(%d)", int(t)) + case TypeUnknown: + return "Unknown" + case TypeReg: + return "Reg" + case TypeCondRegBit: + return "CondRegBit" + case TypeCondRegField: + return "CondRegField" + case TypeFPReg: + return "FPReg" + case TypeVecReg: + return "VecReg" + case TypeVecSReg: + return "VecSReg" + case TypeSpReg: + return "SpReg" + case TypeImmSigned: + return "ImmSigned" + case TypeImmUnsigned: + return "ImmUnsigned" + case TypePCRel: + return "PCRel" + case TypeLabel: + return "Label" + case TypeOffset: + return "Offset" + } +} + +func (t ArgType) GoString() string { + s := t.String() + if t > 0 && t < TypeLast { + return "Type" + s + } + return s +} + +var ( + // Errors + errShort = fmt.Errorf("truncated instruction") + errUnknown = fmt.Errorf("unknown instruction") +) + +var decoderCover []bool + +// Decode decodes the leading bytes in src as a single instruction using +// byte order ord. +func Decode(src []byte, ord binary.ByteOrder) (inst Inst, err error) { + if len(src) < 4 { + return inst, errShort + } + if decoderCover == nil { + decoderCover = make([]bool, len(instFormats)) + } + inst.Len = 4 // only 4-byte instructions are supported + ui := ord.Uint32(src[:inst.Len]) + inst.Enc = ui + for i, iform := range instFormats { + if ui&iform.Mask != iform.Value { + continue + } + if ui&iform.DontCare != 0 { + if debugDecode { + log.Printf("Decode(%#x): unused bit is 1 for Op %s", ui, iform.Op) + } + // to match GNU objdump (libopcodes), we ignore don't care bits + } + for i, argfield := range iform.Args { + if argfield == nil { + break + } + inst.Args[i] = argfield.Parse(ui) + } + inst.Op = iform.Op + if debugDecode { + log.Printf("%#x: search entry %d", ui, i) + continue + } + break + } + if inst.Op == 0 && inst.Enc != 0 { + return inst, errUnknown + } + return inst, nil +} diff --git a/vendor/golang.org/x/arch/ppc64/ppc64asm/doc.go b/vendor/golang.org/x/arch/ppc64/ppc64asm/doc.go new file mode 100644 index 0000000000..5f4ef7d10a --- /dev/null +++ b/vendor/golang.org/x/arch/ppc64/ppc64asm/doc.go @@ -0,0 +1,6 @@ +// Copyright 2014 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 ppc64asm implements decoding of 64-bit PowerPC machine code. +package ppc64asm diff --git a/vendor/golang.org/x/arch/ppc64/ppc64asm/field.go b/vendor/golang.org/x/arch/ppc64/ppc64asm/field.go new file mode 100644 index 0000000000..26a4fdf1a0 --- /dev/null +++ b/vendor/golang.org/x/arch/ppc64/ppc64asm/field.go @@ -0,0 +1,84 @@ +// Copyright 2014 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 ppc64asm + +import ( + "fmt" + "strings" +) + +// A BitField is a bit-field in a 32-bit word. +// Bits are counted from 0 from the MSB to 31 as the LSB. +type BitField struct { + Offs uint8 // the offset of the left-most bit. + Bits uint8 // length in bits. +} + +func (b BitField) String() string { + if b.Bits > 1 { + return fmt.Sprintf("[%d:%d]", b.Offs, int(b.Offs+b.Bits)-1) + } else if b.Bits == 1 { + return fmt.Sprintf("[%d]", b.Offs) + } else { + return fmt.Sprintf("[%d, len=0]", b.Offs) + } +} + +// Parse extracts the bitfield b from i, and return it as an unsigned integer. +// Parse will panic if b is invalid. +func (b BitField) Parse(i uint32) uint32 { + if b.Bits > 32 || b.Bits == 0 || b.Offs > 31 || b.Offs+b.Bits > 32 { + panic(fmt.Sprintf("invalid bitfiled %v", b)) + } + return (i >> (32 - b.Offs - b.Bits)) & ((1 << b.Bits) - 1) +} + +// ParseSigned extracts the bitfield b from i, and return it as a signed integer. +// ParseSigned will panic if b is invalid. +func (b BitField) ParseSigned(i uint32) int32 { + u := int32(b.Parse(i)) + return u << (32 - b.Bits) >> (32 - b.Bits) +} + +// BitFields is a series of BitFields representing a single number. +type BitFields []BitField + +func (bs BitFields) String() string { + ss := make([]string, len(bs)) + for i, bf := range bs { + ss[i] = bf.String() + } + return fmt.Sprintf("<%s>", strings.Join(ss, "|")) +} + +func (bs *BitFields) Append(b BitField) { + *bs = append(*bs, b) +} + +// parse extracts the bitfields from i, concatenate them and return the result +// as an unsigned integer and the total length of all the bitfields. +// parse will panic if any bitfield in b is invalid, but it doesn't check if +// the sequence of bitfields is reasonable. +func (bs BitFields) parse(i uint32) (u uint32, Bits uint8) { + for _, b := range bs { + u = (u << b.Bits) | b.Parse(i) + Bits += b.Bits + } + return u, Bits +} + +// Parse extracts the bitfields from i, concatenate them and return the result +// as an unsigned integer. Parse will panic if any bitfield in b is invalid. +func (bs BitFields) Parse(i uint32) uint32 { + u, _ := bs.parse(i) + return u +} + +// Parse extracts the bitfields from i, concatenate them and return the result +// as a signed integer. Parse will panic if any bitfield in b is invalid. +func (bs BitFields) ParseSigned(i uint32) int32 { + u, l := bs.parse(i) + return int32(u) << (32 - l) >> (32 - l) +} diff --git a/vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go b/vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go new file mode 100644 index 0000000000..fc2916408c --- /dev/null +++ b/vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go @@ -0,0 +1,267 @@ +// Copyright 2014 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 ppc64asm + +import ( + "bytes" + "fmt" + "strings" +) + +var ( + condBit = [4]string{"lt", "gt", "eq", "so"} + condBitNeg = [4]string{"ge", "le", "ne", "so"} +) + +// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils. +// This form typically matches the syntax defined in the Power ISA Reference Manual. +func GNUSyntax(inst Inst, pc uint64) string { + var buf bytes.Buffer + // When there are all 0s, identify them as the disassembler + // in binutils would. + if inst.Enc == 0 { + return ".long 0x0" + } else if inst.Op == 0 { + return "error: unknown instruction" + } + + PC := pc + // Special handling for some ops + startArg := 0 + sep := " " + switch inst.Op.String() { + case "bc": + bo := gnuArg(&inst, 0, inst.Args[0], PC) + bi := inst.Args[1] + switch bi := bi.(type) { + case CondReg: + if bi >= CR0 { + if bi == CR0 && bo == "16" { + buf.WriteString("bdnz") + } + buf.WriteString(fmt.Sprintf("bc cr%d", bi-CR0)) + } + cr := bi / 4 + switch bo { + case "4": + bit := condBitNeg[(bi-Cond0LT)%4] + if cr == 0 { + buf.WriteString(fmt.Sprintf("b%s", bit)) + } else { + buf.WriteString(fmt.Sprintf("b%s cr%d,", bit, cr)) + sep = "" + } + case "12": + bit := condBit[(bi-Cond0LT)%4] + if cr == 0 { + buf.WriteString(fmt.Sprintf("b%s", bit)) + } else { + buf.WriteString(fmt.Sprintf("b%s cr%d,", bit, cr)) + sep = "" + } + case "8": + bit := condBit[(bi-Cond0LT)%4] + sep = "" + if cr == 0 { + buf.WriteString(fmt.Sprintf("bdnzt %s,", bit)) + } else { + buf.WriteString(fmt.Sprintf("bdnzt cr%d,%s,", cr, bit)) + } + case "16": + if cr == 0 && bi == Cond0LT { + buf.WriteString("bdnz") + } else { + buf.WriteString(fmt.Sprintf("bdnz cr%d,", cr)) + sep = "" + } + } + startArg = 2 + default: + fmt.Printf("Unexpected bi: %d for bc with bo: %s\n", bi, bo) + } + startArg = 2 + case "mtspr": + opcode := inst.Op.String() + buf.WriteString(opcode[0:2]) + switch spr := inst.Args[0].(type) { + case SpReg: + switch spr { + case 1: + buf.WriteString("xer") + startArg = 1 + case 8: + buf.WriteString("lr") + startArg = 1 + case 9: + buf.WriteString("ctr") + startArg = 1 + default: + buf.WriteString("spr") + } + default: + buf.WriteString("spr") + } + + case "mfspr": + opcode := inst.Op.String() + buf.WriteString(opcode[0:2]) + arg := inst.Args[0] + switch spr := inst.Args[1].(type) { + case SpReg: + switch spr { + case 1: + buf.WriteString("xer ") + buf.WriteString(gnuArg(&inst, 0, arg, PC)) + startArg = 2 + case 8: + buf.WriteString("lr ") + buf.WriteString(gnuArg(&inst, 0, arg, PC)) + startArg = 2 + case 9: + buf.WriteString("ctr ") + buf.WriteString(gnuArg(&inst, 0, arg, PC)) + startArg = 2 + case 268: + buf.WriteString("tb ") + buf.WriteString(gnuArg(&inst, 0, arg, PC)) + startArg = 2 + default: + buf.WriteString("spr") + } + default: + buf.WriteString("spr") + } + + default: + buf.WriteString(inst.Op.String()) + } + for i, arg := range inst.Args[:] { + if arg == nil { + break + } + if i < startArg { + continue + } + text := gnuArg(&inst, i, arg, PC) + if text == "" { + continue + } + buf.WriteString(sep) + sep = "," + buf.WriteString(text) + } + return buf.String() +} + +// gnuArg formats arg (which is the argIndex's arg in inst) according to GNU rules. +// NOTE: because GNUSyntax is the only caller of this func, and it receives a copy +// of inst, it's ok to modify inst.Args here. +func gnuArg(inst *Inst, argIndex int, arg Arg, pc uint64) string { + // special cases for load/store instructions + if _, ok := arg.(Offset); ok { + if argIndex+1 == len(inst.Args) || inst.Args[argIndex+1] == nil { + panic(fmt.Errorf("wrong table: offset not followed by register")) + } + } + switch arg := arg.(type) { + case Reg: + if isLoadStoreOp(inst.Op) && argIndex == 1 && arg == R0 { + return "0" + } + return arg.String() + case CondReg: + // The CondReg can either be found in a CMP, where the + // condition register field is being set, or in an instruction + // like a branch or isel that is testing a bit in a condition + // register field. + if arg == CR0 && strings.HasPrefix(inst.Op.String(), "cmp") { + return "" // don't show cr0 for cmp instructions + } else if arg >= CR0 { + return fmt.Sprintf("cr%d", int(arg-CR0)) + } + bit := condBit[(arg-Cond0LT)%4] + if arg <= Cond0SO { + return bit + } + return fmt.Sprintf("%s cr%d", bit, int(arg-Cond0LT)/4) + case Imm: + return fmt.Sprintf("%d", arg) + case SpReg: + switch int(arg) { + case 1: + return "xer" + case 8: + return "lr" + case 9: + return "ctr" + case 268: + return "tb" + default: + return fmt.Sprintf("%d", int(arg)) + } + case PCRel: + // If the arg is 0, use the relative address format. + // Otherwise the pc is meaningful, use absolute address. + if int(arg) == 0 { + return fmt.Sprintf(".%+#x", int(arg)) + } + addr := pc + uint64(int64(arg)) + return fmt.Sprintf("%#x", addr) + case Label: + return fmt.Sprintf("%#x", uint32(arg)) + case Offset: + reg := inst.Args[argIndex+1].(Reg) + removeArg(inst, argIndex+1) + if reg == R0 { + return fmt.Sprintf("%d(0)", int(arg)) + } + return fmt.Sprintf("%d(r%d)", int(arg), reg-R0) + } + return fmt.Sprintf("???(%v)", arg) +} + +// removeArg removes the arg in inst.Args[index]. +func removeArg(inst *Inst, index int) { + for i := index; i < len(inst.Args); i++ { + if i+1 < len(inst.Args) { + inst.Args[i] = inst.Args[i+1] + } else { + inst.Args[i] = nil + } + } +} + +// isLoadStoreOp returns true if op is a load or store instruction +func isLoadStoreOp(op Op) bool { + switch op { + case LBZ, LBZU, LBZX, LBZUX: + return true + case LHZ, LHZU, LHZX, LHZUX: + return true + case LHA, LHAU, LHAX, LHAUX: + return true + case LWZ, LWZU, LWZX, LWZUX: + return true + case LWA, LWAX, LWAUX: + return true + case LD, LDU, LDX, LDUX: + return true + case LQ: + return true + case STB, STBU, STBX, STBUX: + return true + case STH, STHU, STHX, STHUX: + return true + case STW, STWU, STWX, STWUX: + return true + case STD, STDU, STDX, STDUX: + return true + case STQ: + return true + case LHBRX, LWBRX, STHBRX, STWBRX: + return true + } + return false +} diff --git a/vendor/golang.org/x/arch/ppc64/ppc64asm/inst.go b/vendor/golang.org/x/arch/ppc64/ppc64asm/inst.go new file mode 100644 index 0000000000..870522a10b --- /dev/null +++ b/vendor/golang.org/x/arch/ppc64/ppc64asm/inst.go @@ -0,0 +1,344 @@ +// Copyright 2014 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 ppc64asm + +import ( + "bytes" + "fmt" +) + +type Inst struct { + Op Op // Opcode mnemonic + Enc uint32 // Raw encoding bits + Len int // Length of encoding in bytes. + Args Args // Instruction arguments, in Power ISA manual order. +} + +func (i Inst) String() string { + var buf bytes.Buffer + buf.WriteString(i.Op.String()) + for j, arg := range i.Args { + if arg == nil { + break + } + if j == 0 { + buf.WriteString(" ") + } else { + buf.WriteString(", ") + } + buf.WriteString(arg.String()) + } + return buf.String() +} + +// An Op is an instruction operation. +type Op uint16 + +func (o Op) String() string { + if int(o) >= len(opstr) || opstr[o] == "" { + return fmt.Sprintf("Op(%d)", int(o)) + } + return opstr[o] +} + +// An Arg is a single instruction argument, one of these types: Reg, CondReg, SpReg, Imm, PCRel, Label, or Offset. +type Arg interface { + IsArg() + String() string +} + +// An Args holds the instruction arguments. +// If an instruction has fewer than 4 arguments, +// the final elements in the array are nil. +type Args [5]Arg + +// A Reg is a single register. The zero value means R0, not the absence of a register. +// It also includes special registers. +type Reg uint16 + +const ( + _ Reg = iota + R0 + R1 + R2 + R3 + R4 + R5 + R6 + R7 + R8 + R9 + R10 + R11 + R12 + R13 + R14 + R15 + R16 + R17 + R18 + R19 + R20 + R21 + R22 + R23 + R24 + R25 + R26 + R27 + R28 + R29 + R30 + R31 + F0 + F1 + F2 + F3 + F4 + F5 + F6 + F7 + F8 + F9 + F10 + F11 + F12 + F13 + F14 + F15 + F16 + F17 + F18 + F19 + F20 + F21 + F22 + F23 + F24 + F25 + F26 + F27 + F28 + F29 + F30 + F31 + V0 // VSX extension, F0 is V0[0:63]. + V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 + V10 + V11 + V12 + V13 + V14 + V15 + V16 + V17 + V18 + V19 + V20 + V21 + V22 + V23 + V24 + V25 + V26 + V27 + V28 + V29 + V30 + V31 + VS0 + VS1 + VS2 + VS3 + VS4 + VS5 + VS6 + VS7 + VS8 + VS9 + VS10 + VS11 + VS12 + VS13 + VS14 + VS15 + VS16 + VS17 + VS18 + VS19 + VS20 + VS21 + VS22 + VS23 + VS24 + VS25 + VS26 + VS27 + VS28 + VS29 + VS30 + VS31 + VS32 + VS33 + VS34 + VS35 + VS36 + VS37 + VS38 + VS39 + VS40 + VS41 + VS42 + VS43 + VS44 + VS45 + VS46 + VS47 + VS48 + VS49 + VS50 + VS51 + VS52 + VS53 + VS54 + VS55 + VS56 + VS57 + VS58 + VS59 + VS60 + VS61 + VS62 + VS63 +) + +func (Reg) IsArg() {} +func (r Reg) String() string { + switch { + case R0 <= r && r <= R31: + return fmt.Sprintf("r%d", int(r-R0)) + case F0 <= r && r <= F31: + return fmt.Sprintf("f%d", int(r-F0)) + case V0 <= r && r <= V31: + return fmt.Sprintf("v%d", int(r-V0)) + case VS0 <= r && r <= VS63: + return fmt.Sprintf("vs%d", int(r-VS0)) + default: + return fmt.Sprintf("Reg(%d)", int(r)) + } +} + +// CondReg is a bit or field in the condition register. +type CondReg int8 + +const ( + _ CondReg = iota + // Condition Regster bits + Cond0LT + Cond0GT + Cond0EQ + Cond0SO + Cond1LT + Cond1GT + Cond1EQ + Cond1SO + Cond2LT + Cond2GT + Cond2EQ + Cond2SO + Cond3LT + Cond3GT + Cond3EQ + Cond3SO + Cond4LT + Cond4GT + Cond4EQ + Cond4SO + Cond5LT + Cond5GT + Cond5EQ + Cond5SO + Cond6LT + Cond6GT + Cond6EQ + Cond6SO + Cond7LT + Cond7GT + Cond7EQ + Cond7SO + // Condition Register Fields + CR0 + CR1 + CR2 + CR3 + CR4 + CR5 + CR6 + CR7 +) + +func (CondReg) IsArg() {} +func (c CondReg) String() string { + switch { + default: + return fmt.Sprintf("CondReg(%d)", int(c)) + case c >= CR0: + return fmt.Sprintf("CR%d", int(c-CR0)) + case c >= Cond0LT && c < CR0: + return fmt.Sprintf("Cond%d%s", int((c-Cond0LT)/4), [4]string{"LT", "GT", "EQ", "SO"}[(c-Cond0LT)%4]) + } +} + +// SpReg is a special register, its meaning depends on Op. +type SpReg uint16 + +const ( + SpRegZero SpReg = 0 +) + +func (SpReg) IsArg() {} +func (s SpReg) String() string { + return fmt.Sprintf("SpReg(%d)", int(s)) +} + +// PCRel is a PC-relative offset, used only in branch instructions. +type PCRel int32 + +func (PCRel) IsArg() {} +func (r PCRel) String() string { + return fmt.Sprintf("PC%+#x", int32(r)) +} + +// A Label is a code (text) address, used only in absolute branch instructions. +type Label uint32 + +func (Label) IsArg() {} +func (l Label) String() string { + return fmt.Sprintf("%#x", uint32(l)) +} + +// Imm represents an immediate number. +type Imm int32 + +func (Imm) IsArg() {} +func (i Imm) String() string { + return fmt.Sprintf("%d", int32(i)) +} + +// Offset represents a memory offset immediate. +type Offset int32 + +func (Offset) IsArg() {} +func (o Offset) String() string { + return fmt.Sprintf("%+d", int32(o)) +} diff --git a/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go b/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go new file mode 100644 index 0000000000..d039d9d500 --- /dev/null +++ b/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go @@ -0,0 +1,245 @@ +// Copyright 2015 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 ppc64asm + +import ( + "fmt" + "strings" +) + +// GoSyntax returns the Go assembler syntax for the instruction. +// The pc is the program counter of the first instruction, used for expanding +// PC-relative addresses into absolute ones. +// The symname function queries the symbol table for the program +// being disassembled. It returns the name and base address of the symbol +// containing the target, if any; otherwise it returns "", 0. +func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) string { + if symname == nil { + symname = func(uint64) (string, uint64) { return "", 0 } + } + if inst.Op == 0 && inst.Enc == 0 { + return "WORD $0" + } else if inst.Op == 0 { + return "?" + } + var args []string + for i, a := range inst.Args[:] { + if a == nil { + break + } + if s := plan9Arg(&inst, i, pc, a, symname); s != "" { + // In the case for some BC instructions, a CondReg arg has + // both the CR and the branch condition encoded in its value. + // plan9Arg will return a string with the string representation + // of these values separated by a blank that will be treated + // as 2 args from this point on. + if strings.IndexByte(s, ' ') > 0 { + t := strings.Split(s, " ") + args = append(args, t[0]) + args = append(args, t[1]) + } else { + args = append(args, s) + } + } + } + var op string + op = plan9OpMap[inst.Op] + if op == "" { + op = strings.ToUpper(inst.Op.String()) + if op[len(op)-1] == '.' { + op = op[:len(op)-1] + "CC" + } + } + // laid out the instruction + switch inst.Op { + default: // dst, sA, sB, ... + if len(args) == 0 { + return op + } else if len(args) == 1 { + return fmt.Sprintf("%s %s", op, args[0]) + } + args = append(args, args[0]) + return op + " " + strings.Join(args[1:], ",") + case SYNC: + if args[0] == "$1" { + return "LWSYNC" + } + return "HWSYNC" + + case ISEL: + return "ISEL " + args[3] + "," + args[1] + "," + args[2] + "," + args[0] + + // store instructions always have the memory operand at the end, no need to reorder + // indexed stores handled separately + case STB, STBU, + STH, STHU, + STW, STWU, + STD, STDU, + STQ: + return op + " " + strings.Join(args, ",") + + case CMPD, CMPDI, CMPLD, CMPLDI, CMPW, CMPWI, CMPLW, CMPLWI: + if len(args) == 2 { + return op + " " + args[0] + "," + args[1] + } else if len(args) == 3 { + return op + " " + args[0] + "," + args[1] + "," + args[2] + } + return op + " " + args[0] + " ??" + + case LIS: + return "ADDIS $0," + args[1] + "," + args[0] + // store instructions with index registers + case STBX, STBUX, STHX, STHUX, STWX, STWUX, STDX, STDUX, + STHBRX, STWBRX, STDBRX, STSWX, STFSX, STFSUX, STFDX, STFDUX, STFIWX, STFDPX: + return "MOV" + op[2:len(op)-1] + " " + args[0] + ",(" + args[2] + ")(" + args[1] + ")" + + case STDCXCC, STWCXCC, STHCXCC, STBCXCC: + return op + " " + args[0] + ",(" + args[2] + ")(" + args[1] + ")" + + case STXVD2X, STXVW4X: + return op + " " + args[0] + ",(" + args[2] + ")(" + args[1] + ")" + + // load instructions with index registers + case LBZX, LBZUX, LHZX, LHZUX, LWZX, LWZUX, LDX, LDUX, + LHBRX, LWBRX, LDBRX, LSWX, LFSX, LFSUX, LFDX, LFDUX, LFIWAX, LFIWZX: + return "MOV" + op[1:len(op)-1] + " (" + args[2] + ")(" + args[1] + ")," + args[0] + + case LDARX, LWARX, LHARX, LBARX: + return op + " (" + args[2] + ")(" + args[1] + ")," + args[0] + + case LXVD2X, LXVW4X: + return op + " (" + args[2] + ")(" + args[1] + ")," + args[0] + + case DCBT, DCBTST, DCBZ, DCBST: + return op + " (" + args[1] + ")" + + // branch instructions needs additional handling + case BCLR: + if int(inst.Args[0].(Imm))&20 == 20 { // unconditional + return "RET" + } + return op + " " + strings.Join(args, ", ") + case BC: + if int(inst.Args[0].(Imm))&0x1c == 12 { // jump on cond bit set + if len(args) == 4 { + return fmt.Sprintf("B%s %s,%s", args[1], args[2], args[3]) + } + return fmt.Sprintf("B%s %s", args[1], args[2]) + } else if int(inst.Args[0].(Imm))&0x1c == 4 && revCondMap[args[1]] != "" { // jump on cond bit not set + if len(args) == 4 { + return fmt.Sprintf("B%s %s,%s", revCondMap[args[1]], args[2], args[3]) + } + return fmt.Sprintf("B%s %s", revCondMap[args[1]], args[2]) + } + return op + " " + strings.Join(args, ",") + case BCCTR: + if int(inst.Args[0].(Imm))&20 == 20 { // unconditional + return "BR (CTR)" + } + return op + " " + strings.Join(args, ", ") + case BCCTRL: + if int(inst.Args[0].(Imm))&20 == 20 { // unconditional + return "BL (CTR)" + } + return op + " " + strings.Join(args, ",") + case BCA, BCL, BCLA, BCLRL, BCTAR, BCTARL: + return op + " " + strings.Join(args, ",") + } +} + +// plan9Arg formats arg (which is the argIndex's arg in inst) according to Plan 9 rules. +// NOTE: because Plan9Syntax is the only caller of this func, and it receives a copy +// of inst, it's ok to modify inst.Args here. +func plan9Arg(inst *Inst, argIndex int, pc uint64, arg Arg, symname func(uint64) (string, uint64)) string { + // special cases for load/store instructions + if _, ok := arg.(Offset); ok { + if argIndex+1 == len(inst.Args) || inst.Args[argIndex+1] == nil { + panic(fmt.Errorf("wrong table: offset not followed by register")) + } + } + switch arg := arg.(type) { + case Reg: + if isLoadStoreOp(inst.Op) && argIndex == 1 && arg == R0 { + return "0" + } + if arg == R30 { + return "g" + } + return strings.ToUpper(arg.String()) + case CondReg: + // This op is left as its numerical value, not mapped onto CR + condition + if inst.Op == ISEL { + return fmt.Sprintf("$%d", (arg - Cond0LT)) + } + if arg == CR0 && strings.HasPrefix(inst.Op.String(), "cmp") { + return "" // don't show cr0 for cmp instructions + } else if arg >= CR0 { + return fmt.Sprintf("CR%d", int(arg-CR0)) + } + bit := [4]string{"LT", "GT", "EQ", "SO"}[(arg-Cond0LT)%4] + if arg <= Cond0SO { + return bit + } + return fmt.Sprintf("%s CR%d", bit, int(arg-Cond0LT)/4) + case Imm: + return fmt.Sprintf("$%d", arg) + case SpReg: + switch arg { + case 8: + return "LR" + case 9: + return "CTR" + } + return fmt.Sprintf("SPR(%d)", int(arg)) + case PCRel: + addr := pc + uint64(int64(arg)) + if s, base := symname(addr); s != "" && base == addr { + return fmt.Sprintf("%s(SB)", s) + } + return fmt.Sprintf("%#x", addr) + case Label: + return fmt.Sprintf("%#x", int(arg)) + case Offset: + reg := inst.Args[argIndex+1].(Reg) + removeArg(inst, argIndex+1) + if reg == R0 { + return fmt.Sprintf("%d(0)", int(arg)) + } + return fmt.Sprintf("%d(R%d)", int(arg), reg-R0) + } + return fmt.Sprintf("???(%v)", arg) +} + +// revCondMap maps a conditional register bit to its inverse, if possible. +var revCondMap = map[string]string{ + "LT": "GE", "GT": "LE", "EQ": "NE", +} + +// plan9OpMap maps an Op to its Plan 9 mnemonics, if different than its GNU mnemonics. +var plan9OpMap = map[Op]string{ + LWARX: "LWAR", + LDARX: "LDAR", + LHARX: "LHAR", + LBARX: "LBAR", + ADDI: "ADD", + SRADI: "SRAD", + SUBF: "SUB", + LI: "MOVD", + LBZ: "MOVBZ", STB: "MOVB", + LBZU: "MOVBZU", STBU: "MOVBU", + LHZ: "MOVHZ", LHA: "MOVH", STH: "MOVH", + LHZU: "MOVHZU", STHU: "MOVHU", + LWZ: "MOVWZ", LWA: "MOVW", STW: "MOVW", + LWZU: "MOVWZU", STWU: "MOVWU", + LD: "MOVD", STD: "MOVD", + LDU: "MOVDU", STDU: "MOVDU", + CMPD: "CMP", CMPDI: "CMP", + CMPW: "CMPW", CMPWI: "CMPW", + CMPLD: "CMPU", CMPLDI: "CMPU", + CMPLW: "CMPWU", CMPLWI: "CMPWU", + MTSPR: "MOVD", MFSPR: "MOVD", // the width is ambiguous for SPRs + B: "BR", + BL: "CALL", +} diff --git a/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go b/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go new file mode 100644 index 0000000000..f536926dbc --- /dev/null +++ b/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go @@ -0,0 +1,5494 @@ +// DO NOT EDIT +// generated by: ppc64map -fmt=decoder ../pp64.csv + +package ppc64asm + +const ( + _ Op = iota + CNTLZW + CNTLZWCC + B + BA + BL + BLA + BC + BCA + BCL + BCLA + BCLR + BCLRL + BCCTR + BCCTRL + BCTAR + BCTARL + CRAND + CROR + CRNAND + CRXOR + CRNOR + CRANDC + MCRF + CREQV + CRORC + SC + CLRBHRB + MFBHRBE + LBZ + LBZU + LBZX + LBZUX + LHZ + LHZU + LHZX + LHZUX + LHA + LHAU + LHAX + LHAUX + LWZ + LWZU + LWZX + LWZUX + LWA + LWAX + LWAUX + LD + LDU + LDX + LDUX + STB + STBU + STBX + STBUX + STH + STHU + STHX + STHUX + STW + STWU + STWX + STWUX + STD + STDU + STDX + STDUX + LQ + STQ + LHBRX + LWBRX + STHBRX + STWBRX + LDBRX + STDBRX + LMW + STMW + LSWI + LSWX + STSWI + STSWX + LI + ADDI + LIS + ADDIS + ADD + ADDCC + ADDO + ADDOCC + ADDIC + SUBF + SUBFCC + SUBFO + SUBFOCC + ADDICCC + SUBFIC + ADDC + ADDCCC + ADDCO + ADDCOCC + SUBFC + SUBFCCC + SUBFCO + SUBFCOCC + ADDE + ADDECC + ADDEO + ADDEOCC + ADDME + ADDMECC + ADDMEO + ADDMEOCC + SUBFE + SUBFECC + SUBFEO + SUBFEOCC + SUBFME + SUBFMECC + SUBFMEO + SUBFMEOCC + ADDZE + ADDZECC + ADDZEO + ADDZEOCC + SUBFZE + SUBFZECC + SUBFZEO + SUBFZEOCC + NEG + NEGCC + NEGO + NEGOCC + MULLI + MULLW + MULLWCC + MULLWO + MULLWOCC + MULHW + MULHWCC + MULHWU + MULHWUCC + DIVW + DIVWCC + DIVWO + DIVWOCC + DIVWU + DIVWUCC + DIVWUO + DIVWUOCC + DIVWE + DIVWECC + DIVWEO + DIVWEOCC + DIVWEU + DIVWEUCC + DIVWEUO + DIVWEUOCC + MULLD + MULLDCC + MULLDO + MULLDOCC + MULHDU + MULHDUCC + MULHD + MULHDCC + DIVD + DIVDCC + DIVDO + DIVDOCC + DIVDU + DIVDUCC + DIVDUO + DIVDUOCC + DIVDE + DIVDECC + DIVDEO + DIVDEOCC + DIVDEU + DIVDEUCC + DIVDEUO + DIVDEUOCC + CMPWI + CMPDI + CMPW + CMPD + CMPLWI + CMPLDI + CMPLW + CMPLD + TWI + TW + TDI + ISEL + TD + ANDICC + ANDISCC + ORI + ORIS + XORI + XORIS + AND + ANDCC + XOR + XORCC + NAND + NANDCC + OR + ORCC + NOR + NORCC + ANDC + ANDCCC + EXTSB + EXTSBCC + EQV + EQVCC + ORC + ORCCC + EXTSH + EXTSHCC + CMPB + POPCNTB + POPCNTW + PRTYD + PRTYW + EXTSW + EXTSWCC + CNTLZD + CNTLZDCC + POPCNTD + BPERMD + RLWINM + RLWINMCC + RLWNM + RLWNMCC + RLWIMI + RLWIMICC + RLDICL + RLDICLCC + RLDICR + RLDICRCC + RLDIC + RLDICCC + RLDCL + RLDCLCC + RLDCR + RLDCRCC + RLDIMI + RLDIMICC + SLW + SLWCC + SRW + SRWCC + SRAWI + SRAWICC + SRAW + SRAWCC + SLD + SLDCC + SRD + SRDCC + SRADI + SRADICC + SRAD + SRADCC + CDTBCD + CBCDTD + ADDG6S + MTSPR + MFSPR + MTCRF + MFCR + MTSLE + MFVSRD + MFVSRWZ + MTVSRD + MTVSRWA + MTVSRWZ + MTOCRF + MFOCRF + MCRXR + MTDCRUX + MFDCRUX + LFS + LFSU + LFSX + LFSUX + LFD + LFDU + LFDX + LFDUX + LFIWAX + LFIWZX + STFS + STFSU + STFSX + STFSUX + STFD + STFDU + STFDX + STFDUX + STFIWX + LFDP + LFDPX + STFDP + STFDPX + FMR + FMRCC + FABS + FABSCC + FNABS + FNABSCC + FNEG + FNEGCC + FCPSGN + FCPSGNCC + FMRGEW + FMRGOW + FADD + FADDCC + FADDS + FADDSCC + FSUB + FSUBCC + FSUBS + FSUBSCC + FMUL + FMULCC + FMULS + FMULSCC + FDIV + FDIVCC + FDIVS + FDIVSCC + FSQRT + FSQRTCC + FSQRTS + FSQRTSCC + FRE + FRECC + FRES + FRESCC + FRSQRTE + FRSQRTECC + FRSQRTES + FRSQRTESCC + FTDIV + FTSQRT + FMADD + FMADDCC + FMADDS + FMADDSCC + FMSUB + FMSUBCC + FMSUBS + FMSUBSCC + FNMADD + FNMADDCC + FNMADDS + FNMADDSCC + FNMSUB + FNMSUBCC + FNMSUBS + FNMSUBSCC + FRSP + FRSPCC + FCTID + FCTIDCC + FCTIDZ + FCTIDZCC + FCTIDU + FCTIDUCC + FCTIDUZ + FCTIDUZCC + FCTIW + FCTIWCC + FCTIWZ + FCTIWZCC + FCTIWU + FCTIWUCC + FCTIWUZ + FCTIWUZCC + FCFID + FCFIDCC + FCFIDU + FCFIDUCC + FCFIDS + FCFIDSCC + FCFIDUS + FCFIDUSCC + FRIN + FRINCC + FRIZ + FRIZCC + FRIP + FRIPCC + FRIM + FRIMCC + FCMPU + FCMPO + FSEL + FSELCC + MFFS + MFFSCC + MCRFS + MTFSFI + MTFSFICC + MTFSF + MTFSFCC + MTFSB0 + MTFSB0CC + MTFSB1 + MTFSB1CC + LVEBX + LVEHX + LVEWX + LVX + LVXL + STVEBX + STVEHX + STVEWX + STVX + STVXL + LVSL + LVSR + VPKPX + VPKSDSS + VPKSDUS + VPKSHSS + VPKSHUS + VPKSWSS + VPKSWUS + VPKUDUM + VPKUDUS + VPKUHUM + VPKUHUS + VPKUWUM + VPKUWUS + VUPKHPX + VUPKLPX + VUPKHSB + VUPKHSH + VUPKHSW + VUPKLSB + VUPKLSH + VUPKLSW + VMRGHB + VMRGHH + VMRGLB + VMRGLH + VMRGHW + VMRGLW + VMRGEW + VMRGOW + VSPLTB + VSPLTH + VSPLTW + VSPLTISB + VSPLTISH + VSPLTISW + VPERM + VSEL + VSL + VSLDOI + VSLO + VSR + VSRO + VADDCUW + VADDSBS + VADDSHS + VADDSWS + VADDUBM + VADDUDM + VADDUHM + VADDUWM + VADDUBS + VADDUHS + VADDUWS + VADDUQM + VADDEUQM + VADDCUQ + VADDECUQ + VSUBCUW + VSUBSBS + VSUBSHS + VSUBSWS + VSUBUBM + VSUBUDM + VSUBUHM + VSUBUWM + VSUBUBS + VSUBUHS + VSUBUWS + VSUBUQM + VSUBEUQM + VSUBCUQ + VSUBECUQ + VMULESB + VMULEUB + VMULOSB + VMULOUB + VMULESH + VMULEUH + VMULOSH + VMULOUH + VMULESW + VMULEUW + VMULOSW + VMULOUW + VMULUWM + VMHADDSHS + VMHRADDSHS + VMLADDUHM + VMSUMUBM + VMSUMMBM + VMSUMSHM + VMSUMSHS + VMSUMUHM + VMSUMUHS + VSUMSWS + VSUM2SWS + VSUM4SBS + VSUM4SHS + VSUM4UBS + VAVGSB + VAVGSH + VAVGSW + VAVGUB + VAVGUW + VAVGUH + VMAXSB + VMAXSD + VMAXUB + VMAXUD + VMAXSH + VMAXSW + VMAXUH + VMAXUW + VMINSB + VMINSD + VMINUB + VMINUD + VMINSH + VMINSW + VMINUH + VMINUW + VCMPEQUB + VCMPEQUBCC + VCMPEQUH + VCMPEQUHCC + VCMPEQUW + VCMPEQUWCC + VCMPEQUD + VCMPEQUDCC + VCMPGTSB + VCMPGTSBCC + VCMPGTSD + VCMPGTSDCC + VCMPGTSH + VCMPGTSHCC + VCMPGTSW + VCMPGTSWCC + VCMPGTUB + VCMPGTUBCC + VCMPGTUD + VCMPGTUDCC + VCMPGTUH + VCMPGTUHCC + VCMPGTUW + VCMPGTUWCC + VAND + VANDC + VEQV + VNAND + VORC + VNOR + VOR + VXOR + VRLB + VRLH + VRLW + VRLD + VSLB + VSLH + VSLW + VSLD + VSRB + VSRH + VSRW + VSRD + VSRAB + VSRAH + VSRAW + VSRAD + VADDFP + VSUBFP + VMADDFP + VNMSUBFP + VMAXFP + VMINFP + VCTSXS + VCTUXS + VCFSX + VCFUX + VRFIM + VRFIN + VRFIP + VRFIZ + VCMPBFP + VCMPBFPCC + VCMPEQFP + VCMPEQFPCC + VCMPGEFP + VCMPGEFPCC + VCMPGTFP + VCMPGTFPCC + VEXPTEFP + VLOGEFP + VREFP + VRSQRTEFP + VCIPHER + VCIPHERLAST + VNCIPHER + VNCIPHERLAST + VSBOX + VSHASIGMAD + VSHASIGMAW + VPMSUMB + VPMSUMD + VPMSUMH + VPMSUMW + VPERMXOR + VGBBD + VCLZB + VCLZH + VCLZW + VCLZD + VPOPCNTB + VPOPCNTD + VPOPCNTH + VPOPCNTW + VBPERMQ + BCDADDCC + BCDSUBCC + MTVSCR + MFVSCR + DADD + DADDCC + DSUB + DSUBCC + DMUL + DMULCC + DDIV + DDIVCC + DCMPU + DCMPO + DTSTDC + DTSTDG + DTSTEX + DTSTSF + DQUAI + DQUAICC + DQUA + DQUACC + DRRND + DRRNDCC + DRINTX + DRINTXCC + DRINTN + DRINTNCC + DCTDP + DCTDPCC + DCTQPQ + DCTQPQCC + DRSP + DRSPCC + DRDPQ + DRDPQCC + DCFFIX + DCFFIXCC + DCFFIXQ + DCFFIXQCC + DCTFIX + DCTFIXCC + DDEDPD + DDEDPDCC + DENBCD + DENBCDCC + DXEX + DXEXCC + DIEX + DIEXCC + DSCLI + DSCLICC + DSCRI + DSCRICC + LXSDX + LXSIWAX + LXSIWZX + LXSSPX + LXVD2X + LXVDSX + LXVW4X + STXSDX + STXSIWX + STXSSPX + STXVD2X + STXVW4X + XSABSDP + XSADDDP + XSADDSP + XSCMPODP + XSCMPUDP + XSCPSGNDP + XSCVDPSP + XSCVDPSPN + XSCVDPSXDS + XSCVDPSXWS + XSCVDPUXDS + XSCVDPUXWS + XSCVSPDP + XSCVSPDPN + XSCVSXDDP + XSCVSXDSP + XSCVUXDDP + XSCVUXDSP + XSDIVDP + XSDIVSP + XSMADDADP + XSMADDASP + XSMAXDP + XSMINDP + XSMSUBADP + XSMSUBASP + XSMULDP + XSMULSP + XSNABSDP + XSNEGDP + XSNMADDADP + XSNMADDASP + XSNMSUBADP + XSNMSUBASP + XSRDPI + XSRDPIC + XSRDPIM + XSRDPIP + XSRDPIZ + XSREDP + XSRESP + XSRSP + XSRSQRTEDP + XSRSQRTESP + XSSQRTDP + XSSQRTSP + XSSUBDP + XSSUBSP + XSTDIVDP + XSTSQRTDP + XVABSDP + XVABSSP + XVADDDP + XVADDSP + XVCMPEQDP + XVCMPEQDPCC + XVCMPEQSP + XVCMPEQSPCC + XVCMPGEDP + XVCMPGEDPCC + XVCMPGESP + XVCMPGESPCC + XVCMPGTDP + XVCMPGTDPCC + XVCMPGTSP + XVCMPGTSPCC + XVCPSGNDP + XVCPSGNSP + XVCVDPSP + XVCVDPSXDS + XVCVDPSXWS + XVCVDPUXDS + XVCVDPUXWS + XVCVSPDP + XVCVSPSXDS + XVCVSPSXWS + XVCVSPUXDS + XVCVSPUXWS + XVCVSXDDP + XVCVSXDSP + XVCVSXWDP + XVCVSXWSP + XVCVUXDDP + XVCVUXDSP + XVCVUXWDP + XVCVUXWSP + XVDIVDP + XVDIVSP + XVMADDADP + XVMADDASP + XVMAXDP + XVMAXSP + XVMINDP + XVMINSP + XVMSUBADP + XVMSUBASP + XVMULDP + XVMULSP + XVNABSDP + XVNABSSP + XVNEGDP + XVNEGSP + XVNMADDADP + XVNMADDASP + XVNMSUBADP + XVNMSUBASP + XVRDPI + XVRDPIC + XVRDPIM + XVRDPIP + XVRDPIZ + XVREDP + XVRESP + XVRSPI + XVRSPIC + XVRSPIM + XVRSPIP + XVRSPIZ + XVRSQRTEDP + XVRSQRTESP + XVSQRTDP + XVSQRTSP + XVSUBDP + XVSUBSP + XVTDIVDP + XVTDIVSP + XVTSQRTDP + XVTSQRTSP + XXLAND + XXLANDC + XXLEQV + XXLNAND + XXLORC + XXLNOR + XXLOR + XXLXOR + XXMRGHW + XXMRGLW + XXPERMDI + XXSEL + XXSLDWI + XXSPLTW + BRINC + EVABS + EVADDIW + EVADDSMIAAW + EVADDSSIAAW + EVADDUMIAAW + EVADDUSIAAW + EVADDW + EVAND + EVCMPEQ + EVANDC + EVCMPGTS + EVCMPGTU + EVCMPLTU + EVCMPLTS + EVCNTLSW + EVCNTLZW + EVDIVWS + EVDIVWU + EVEQV + EVEXTSB + EVEXTSH + EVLDD + EVLDH + EVLDDX + EVLDHX + EVLDW + EVLHHESPLAT + EVLDWX + EVLHHESPLATX + EVLHHOSSPLAT + EVLHHOUSPLAT + EVLHHOSSPLATX + EVLHHOUSPLATX + EVLWHE + EVLWHOS + EVLWHEX + EVLWHOSX + EVLWHOU + EVLWHSPLAT + EVLWHOUX + EVLWHSPLATX + EVLWWSPLAT + EVMERGEHI + EVLWWSPLATX + EVMERGELO + EVMERGEHILO + EVMHEGSMFAA + EVMERGELOHI + EVMHEGSMFAN + EVMHEGSMIAA + EVMHEGUMIAA + EVMHEGSMIAN + EVMHEGUMIAN + EVMHESMF + EVMHESMFAAW + EVMHESMFA + EVMHESMFANW + EVMHESMI + EVMHESMIAAW + EVMHESMIA + EVMHESMIANW + EVMHESSF + EVMHESSFA + EVMHESSFAAW + EVMHESSFANW + EVMHESSIAAW + EVMHESSIANW + EVMHEUMI + EVMHEUMIAAW + EVMHEUMIA + EVMHEUMIANW + EVMHEUSIAAW + EVMHEUSIANW + EVMHOGSMFAA + EVMHOGSMIAA + EVMHOGSMFAN + EVMHOGSMIAN + EVMHOGUMIAA + EVMHOSMF + EVMHOGUMIAN + EVMHOSMFA + EVMHOSMFAAW + EVMHOSMI + EVMHOSMFANW + EVMHOSMIA + EVMHOSMIAAW + EVMHOSMIANW + EVMHOSSF + EVMHOSSFA + EVMHOSSFAAW + EVMHOSSFANW + EVMHOSSIAAW + EVMHOUMI + EVMHOSSIANW + EVMHOUMIA + EVMHOUMIAAW + EVMHOUSIAAW + EVMHOUMIANW + EVMHOUSIANW + EVMRA + EVMWHSMF + EVMWHSMI + EVMWHSMFA + EVMWHSMIA + EVMWHSSF + EVMWHUMI + EVMWHSSFA + EVMWHUMIA + EVMWLSMIAAW + EVMWLSSIAAW + EVMWLSMIANW + EVMWLSSIANW + EVMWLUMI + EVMWLUMIAAW + EVMWLUMIA + EVMWLUMIANW + EVMWLUSIAAW + EVMWSMF + EVMWLUSIANW + EVMWSMFA + EVMWSMFAA + EVMWSMI + EVMWSMIAA + EVMWSMFAN + EVMWSMIA + EVMWSMIAN + EVMWSSF + EVMWSSFA + EVMWSSFAA + EVMWUMI + EVMWSSFAN + EVMWUMIA + EVMWUMIAA + EVNAND + EVMWUMIAN + EVNEG + EVNOR + EVORC + EVOR + EVRLW + EVRLWI + EVSEL + EVRNDW + EVSLW + EVSPLATFI + EVSRWIS + EVSLWI + EVSPLATI + EVSRWIU + EVSRWS + EVSTDD + EVSRWU + EVSTDDX + EVSTDH + EVSTDW + EVSTDHX + EVSTDWX + EVSTWHE + EVSTWHO + EVSTWWE + EVSTWHEX + EVSTWHOX + EVSTWWEX + EVSTWWO + EVSUBFSMIAAW + EVSTWWOX + EVSUBFSSIAAW + EVSUBFUMIAAW + EVSUBFUSIAAW + EVSUBFW + EVSUBIFW + EVXOR + EVFSABS + EVFSNABS + EVFSNEG + EVFSADD + EVFSMUL + EVFSSUB + EVFSDIV + EVFSCMPGT + EVFSCMPLT + EVFSCMPEQ + EVFSTSTGT + EVFSTSTLT + EVFSTSTEQ + EVFSCFSI + EVFSCFSF + EVFSCFUI + EVFSCFUF + EVFSCTSI + EVFSCTUI + EVFSCTSIZ + EVFSCTUIZ + EVFSCTSF + EVFSCTUF + EFSABS + EFSNEG + EFSNABS + EFSADD + EFSMUL + EFSSUB + EFSDIV + EFSCMPGT + EFSCMPLT + EFSCMPEQ + EFSTSTGT + EFSTSTLT + EFSTSTEQ + EFSCFSI + EFSCFSF + EFSCTSI + EFSCFUI + EFSCFUF + EFSCTUI + EFSCTSIZ + EFSCTSF + EFSCTUIZ + EFSCTUF + EFDABS + EFDNEG + EFDNABS + EFDADD + EFDMUL + EFDSUB + EFDDIV + EFDCMPGT + EFDCMPEQ + EFDCMPLT + EFDTSTGT + EFDTSTLT + EFDCFSI + EFDTSTEQ + EFDCFUI + EFDCFSID + EFDCFSF + EFDCFUF + EFDCFUID + EFDCTSI + EFDCTUI + EFDCTSIDZ + EFDCTUIDZ + EFDCTSIZ + EFDCTSF + EFDCTUF + EFDCTUIZ + EFDCFS + EFSCFD + DLMZB + DLMZBCC + MACCHW + MACCHWCC + MACCHWO + MACCHWOCC + MACCHWS + MACCHWSCC + MACCHWSO + MACCHWSOCC + MACCHWU + MACCHWUCC + MACCHWUO + MACCHWUOCC + MACCHWSU + MACCHWSUCC + MACCHWSUO + MACCHWSUOCC + MACHHW + MACHHWCC + MACHHWO + MACHHWOCC + MACHHWS + MACHHWSCC + MACHHWSO + MACHHWSOCC + MACHHWU + MACHHWUCC + MACHHWUO + MACHHWUOCC + MACHHWSU + MACHHWSUCC + MACHHWSUO + MACHHWSUOCC + MACLHW + MACLHWCC + MACLHWO + MACLHWOCC + MACLHWS + MACLHWSCC + MACLHWSO + MACLHWSOCC + MACLHWU + MACLHWUCC + MACLHWUO + MACLHWUOCC + MULCHW + MULCHWCC + MACLHWSU + MACLHWSUCC + MACLHWSUO + MACLHWSUOCC + MULCHWU + MULCHWUCC + MULHHW + MULHHWCC + MULLHW + MULLHWCC + MULHHWU + MULHHWUCC + MULLHWU + MULLHWUCC + NMACCHW + NMACCHWCC + NMACCHWO + NMACCHWOCC + NMACCHWS + NMACCHWSCC + NMACCHWSO + NMACCHWSOCC + NMACHHW + NMACHHWCC + NMACHHWO + NMACHHWOCC + NMACHHWS + NMACHHWSCC + NMACHHWSO + NMACHHWSOCC + NMACLHW + NMACLHWCC + NMACLHWO + NMACLHWOCC + NMACLHWS + NMACLHWSCC + NMACLHWSO + NMACLHWSOCC + ICBI + ICBT + DCBA + DCBT + DCBTST + DCBZ + DCBST + DCBF + ISYNC + LBARX + LHARX + LWARX + STBCXCC + STHCXCC + STWCXCC + LDARX + STDCXCC + LQARX + STQCXCC + SYNC + EIEIO + MBAR + WAIT + TBEGINCC + TENDCC + TABORTCC + TABORTWCCC + TABORTWCICC + TABORTDCCC + TABORTDCICC + TSRCC + TCHECK + MFTB + RFEBB + LBDX + LHDX + LWDX + LDDX + LFDDX + STBDX + STHDX + STWDX + STDDX + STFDDX + DSN + ECIWX + ECOWX + RFID + HRFID + DOZE + NAP + SLEEP + RVWINKLE + LBZCIX + LWZCIX + LHZCIX + LDCIX + STBCIX + STWCIX + STHCIX + STDCIX + TRECLAIMCC + TRECHKPTCC + MTMSR + MTMSRD + MFMSR + SLBIE + SLBIA + SLBMTE + SLBMFEV + SLBMFEE + SLBFEECC + MTSR + MTSRIN + MFSR + MFSRIN + TLBIE + TLBIEL + TLBIA + TLBSYNC + MSGSND + MSGCLR + MSGSNDP + MSGCLRP + MTTMR + RFI + RFCI + RFDI + RFMCI + RFGI + EHPRIV + MTDCR + MTDCRX + MFDCR + MFDCRX + WRTEE + WRTEEI + LBEPX + LHEPX + LWEPX + LDEPX + STBEPX + STHEPX + STWEPX + STDEPX + DCBSTEP + DCBTEP + DCBFEP + DCBTSTEP + ICBIEP + DCBZEP + LFDEPX + STFDEPX + EVLDDEPX + EVSTDDEPX + LVEPX + LVEPXL + STVEPX + STVEPXL + DCBI + DCBLQCC + ICBLQCC + DCBTLS + DCBTSTLS + ICBTLS + ICBLC + DCBLC + TLBIVAX + TLBILX + TLBSX + TLBSRXCC + TLBRE + TLBWE + DNH + DCI + ICI + DCREAD + ICREAD + MFPMR + MTPMR + ADDEX + DARN + MADDHD + MADDHDU + MADDLD + CMPRB + CMPEQB + EXTSWSLI + EXTSWSLICC + MFVSRLD + MTVSRDD + MTVSRWS + MCRXRX + COPY + PASTECC +) + +var opstr = [...]string{ + CNTLZW: "cntlzw", + CNTLZWCC: "cntlzw.", + B: "b", + BA: "ba", + BL: "bl", + BLA: "bla", + BC: "bc", + BCA: "bca", + BCL: "bcl", + BCLA: "bcla", + BCLR: "bclr", + BCLRL: "bclrl", + BCCTR: "bcctr", + BCCTRL: "bcctrl", + BCTAR: "bctar", + BCTARL: "bctarl", + CRAND: "crand", + CROR: "cror", + CRNAND: "crnand", + CRXOR: "crxor", + CRNOR: "crnor", + CRANDC: "crandc", + MCRF: "mcrf", + CREQV: "creqv", + CRORC: "crorc", + SC: "sc", + CLRBHRB: "clrbhrb", + MFBHRBE: "mfbhrbe", + LBZ: "lbz", + LBZU: "lbzu", + LBZX: "lbzx", + LBZUX: "lbzux", + LHZ: "lhz", + LHZU: "lhzu", + LHZX: "lhzx", + LHZUX: "lhzux", + LHA: "lha", + LHAU: "lhau", + LHAX: "lhax", + LHAUX: "lhaux", + LWZ: "lwz", + LWZU: "lwzu", + LWZX: "lwzx", + LWZUX: "lwzux", + LWA: "lwa", + LWAX: "lwax", + LWAUX: "lwaux", + LD: "ld", + LDU: "ldu", + LDX: "ldx", + LDUX: "ldux", + STB: "stb", + STBU: "stbu", + STBX: "stbx", + STBUX: "stbux", + STH: "sth", + STHU: "sthu", + STHX: "sthx", + STHUX: "sthux", + STW: "stw", + STWU: "stwu", + STWX: "stwx", + STWUX: "stwux", + STD: "std", + STDU: "stdu", + STDX: "stdx", + STDUX: "stdux", + LQ: "lq", + STQ: "stq", + LHBRX: "lhbrx", + LWBRX: "lwbrx", + STHBRX: "sthbrx", + STWBRX: "stwbrx", + LDBRX: "ldbrx", + STDBRX: "stdbrx", + LMW: "lmw", + STMW: "stmw", + LSWI: "lswi", + LSWX: "lswx", + STSWI: "stswi", + STSWX: "stswx", + LI: "li", + ADDI: "addi", + LIS: "lis", + ADDIS: "addis", + ADD: "add", + ADDCC: "add.", + ADDO: "addo", + ADDOCC: "addo.", + ADDIC: "addic", + SUBF: "subf", + SUBFCC: "subf.", + SUBFO: "subfo", + SUBFOCC: "subfo.", + ADDICCC: "addic.", + SUBFIC: "subfic", + ADDC: "addc", + ADDCCC: "addc.", + ADDCO: "addco", + ADDCOCC: "addco.", + SUBFC: "subfc", + SUBFCCC: "subfc.", + SUBFCO: "subfco", + SUBFCOCC: "subfco.", + ADDE: "adde", + ADDECC: "adde.", + ADDEO: "addeo", + ADDEOCC: "addeo.", + ADDME: "addme", + ADDMECC: "addme.", + ADDMEO: "addmeo", + ADDMEOCC: "addmeo.", + SUBFE: "subfe", + SUBFECC: "subfe.", + SUBFEO: "subfeo", + SUBFEOCC: "subfeo.", + SUBFME: "subfme", + SUBFMECC: "subfme.", + SUBFMEO: "subfmeo", + SUBFMEOCC: "subfmeo.", + ADDZE: "addze", + ADDZECC: "addze.", + ADDZEO: "addzeo", + ADDZEOCC: "addzeo.", + SUBFZE: "subfze", + SUBFZECC: "subfze.", + SUBFZEO: "subfzeo", + SUBFZEOCC: "subfzeo.", + NEG: "neg", + NEGCC: "neg.", + NEGO: "nego", + NEGOCC: "nego.", + MULLI: "mulli", + MULLW: "mullw", + MULLWCC: "mullw.", + MULLWO: "mullwo", + MULLWOCC: "mullwo.", + MULHW: "mulhw", + MULHWCC: "mulhw.", + MULHWU: "mulhwu", + MULHWUCC: "mulhwu.", + DIVW: "divw", + DIVWCC: "divw.", + DIVWO: "divwo", + DIVWOCC: "divwo.", + DIVWU: "divwu", + DIVWUCC: "divwu.", + DIVWUO: "divwuo", + DIVWUOCC: "divwuo.", + DIVWE: "divwe", + DIVWECC: "divwe.", + DIVWEO: "divweo", + DIVWEOCC: "divweo.", + DIVWEU: "divweu", + DIVWEUCC: "divweu.", + DIVWEUO: "divweuo", + DIVWEUOCC: "divweuo.", + MULLD: "mulld", + MULLDCC: "mulld.", + MULLDO: "mulldo", + MULLDOCC: "mulldo.", + MULHDU: "mulhdu", + MULHDUCC: "mulhdu.", + MULHD: "mulhd", + MULHDCC: "mulhd.", + DIVD: "divd", + DIVDCC: "divd.", + DIVDO: "divdo", + DIVDOCC: "divdo.", + DIVDU: "divdu", + DIVDUCC: "divdu.", + DIVDUO: "divduo", + DIVDUOCC: "divduo.", + DIVDE: "divde", + DIVDECC: "divde.", + DIVDEO: "divdeo", + DIVDEOCC: "divdeo.", + DIVDEU: "divdeu", + DIVDEUCC: "divdeu.", + DIVDEUO: "divdeuo", + DIVDEUOCC: "divdeuo.", + CMPWI: "cmpwi", + CMPDI: "cmpdi", + CMPW: "cmpw", + CMPD: "cmpd", + CMPLWI: "cmplwi", + CMPLDI: "cmpldi", + CMPLW: "cmplw", + CMPLD: "cmpld", + TWI: "twi", + TW: "tw", + TDI: "tdi", + ISEL: "isel", + TD: "td", + ANDICC: "andi.", + ANDISCC: "andis.", + ORI: "ori", + ORIS: "oris", + XORI: "xori", + XORIS: "xoris", + AND: "and", + ANDCC: "and.", + XOR: "xor", + XORCC: "xor.", + NAND: "nand", + NANDCC: "nand.", + OR: "or", + ORCC: "or.", + NOR: "nor", + NORCC: "nor.", + ANDC: "andc", + ANDCCC: "andc.", + EXTSB: "extsb", + EXTSBCC: "extsb.", + EQV: "eqv", + EQVCC: "eqv.", + ORC: "orc", + ORCCC: "orc.", + EXTSH: "extsh", + EXTSHCC: "extsh.", + CMPB: "cmpb", + POPCNTB: "popcntb", + POPCNTW: "popcntw", + PRTYD: "prtyd", + PRTYW: "prtyw", + EXTSW: "extsw", + EXTSWCC: "extsw.", + CNTLZD: "cntlzd", + CNTLZDCC: "cntlzd.", + POPCNTD: "popcntd", + BPERMD: "bpermd", + RLWINM: "rlwinm", + RLWINMCC: "rlwinm.", + RLWNM: "rlwnm", + RLWNMCC: "rlwnm.", + RLWIMI: "rlwimi", + RLWIMICC: "rlwimi.", + RLDICL: "rldicl", + RLDICLCC: "rldicl.", + RLDICR: "rldicr", + RLDICRCC: "rldicr.", + RLDIC: "rldic", + RLDICCC: "rldic.", + RLDCL: "rldcl", + RLDCLCC: "rldcl.", + RLDCR: "rldcr", + RLDCRCC: "rldcr.", + RLDIMI: "rldimi", + RLDIMICC: "rldimi.", + SLW: "slw", + SLWCC: "slw.", + SRW: "srw", + SRWCC: "srw.", + SRAWI: "srawi", + SRAWICC: "srawi.", + SRAW: "sraw", + SRAWCC: "sraw.", + SLD: "sld", + SLDCC: "sld.", + SRD: "srd", + SRDCC: "srd.", + SRADI: "sradi", + SRADICC: "sradi.", + SRAD: "srad", + SRADCC: "srad.", + CDTBCD: "cdtbcd", + CBCDTD: "cbcdtd", + ADDG6S: "addg6s", + MTSPR: "mtspr", + MFSPR: "mfspr", + MTCRF: "mtcrf", + MFCR: "mfcr", + MTSLE: "mtsle", + MFVSRD: "mfvsrd", + MFVSRWZ: "mfvsrwz", + MTVSRD: "mtvsrd", + MTVSRWA: "mtvsrwa", + MTVSRWZ: "mtvsrwz", + MTOCRF: "mtocrf", + MFOCRF: "mfocrf", + MCRXR: "mcrxr", + MTDCRUX: "mtdcrux", + MFDCRUX: "mfdcrux", + LFS: "lfs", + LFSU: "lfsu", + LFSX: "lfsx", + LFSUX: "lfsux", + LFD: "lfd", + LFDU: "lfdu", + LFDX: "lfdx", + LFDUX: "lfdux", + LFIWAX: "lfiwax", + LFIWZX: "lfiwzx", + STFS: "stfs", + STFSU: "stfsu", + STFSX: "stfsx", + STFSUX: "stfsux", + STFD: "stfd", + STFDU: "stfdu", + STFDX: "stfdx", + STFDUX: "stfdux", + STFIWX: "stfiwx", + LFDP: "lfdp", + LFDPX: "lfdpx", + STFDP: "stfdp", + STFDPX: "stfdpx", + FMR: "fmr", + FMRCC: "fmr.", + FABS: "fabs", + FABSCC: "fabs.", + FNABS: "fnabs", + FNABSCC: "fnabs.", + FNEG: "fneg", + FNEGCC: "fneg.", + FCPSGN: "fcpsgn", + FCPSGNCC: "fcpsgn.", + FMRGEW: "fmrgew", + FMRGOW: "fmrgow", + FADD: "fadd", + FADDCC: "fadd.", + FADDS: "fadds", + FADDSCC: "fadds.", + FSUB: "fsub", + FSUBCC: "fsub.", + FSUBS: "fsubs", + FSUBSCC: "fsubs.", + FMUL: "fmul", + FMULCC: "fmul.", + FMULS: "fmuls", + FMULSCC: "fmuls.", + FDIV: "fdiv", + FDIVCC: "fdiv.", + FDIVS: "fdivs", + FDIVSCC: "fdivs.", + FSQRT: "fsqrt", + FSQRTCC: "fsqrt.", + FSQRTS: "fsqrts", + FSQRTSCC: "fsqrts.", + FRE: "fre", + FRECC: "fre.", + FRES: "fres", + FRESCC: "fres.", + FRSQRTE: "frsqrte", + FRSQRTECC: "frsqrte.", + FRSQRTES: "frsqrtes", + FRSQRTESCC: "frsqrtes.", + FTDIV: "ftdiv", + FTSQRT: "ftsqrt", + FMADD: "fmadd", + FMADDCC: "fmadd.", + FMADDS: "fmadds", + FMADDSCC: "fmadds.", + FMSUB: "fmsub", + FMSUBCC: "fmsub.", + FMSUBS: "fmsubs", + FMSUBSCC: "fmsubs.", + FNMADD: "fnmadd", + FNMADDCC: "fnmadd.", + FNMADDS: "fnmadds", + FNMADDSCC: "fnmadds.", + FNMSUB: "fnmsub", + FNMSUBCC: "fnmsub.", + FNMSUBS: "fnmsubs", + FNMSUBSCC: "fnmsubs.", + FRSP: "frsp", + FRSPCC: "frsp.", + FCTID: "fctid", + FCTIDCC: "fctid.", + FCTIDZ: "fctidz", + FCTIDZCC: "fctidz.", + FCTIDU: "fctidu", + FCTIDUCC: "fctidu.", + FCTIDUZ: "fctiduz", + FCTIDUZCC: "fctiduz.", + FCTIW: "fctiw", + FCTIWCC: "fctiw.", + FCTIWZ: "fctiwz", + FCTIWZCC: "fctiwz.", + FCTIWU: "fctiwu", + FCTIWUCC: "fctiwu.", + FCTIWUZ: "fctiwuz", + FCTIWUZCC: "fctiwuz.", + FCFID: "fcfid", + FCFIDCC: "fcfid.", + FCFIDU: "fcfidu", + FCFIDUCC: "fcfidu.", + FCFIDS: "fcfids", + FCFIDSCC: "fcfids.", + FCFIDUS: "fcfidus", + FCFIDUSCC: "fcfidus.", + FRIN: "frin", + FRINCC: "frin.", + FRIZ: "friz", + FRIZCC: "friz.", + FRIP: "frip", + FRIPCC: "frip.", + FRIM: "frim", + FRIMCC: "frim.", + FCMPU: "fcmpu", + FCMPO: "fcmpo", + FSEL: "fsel", + FSELCC: "fsel.", + MFFS: "mffs", + MFFSCC: "mffs.", + MCRFS: "mcrfs", + MTFSFI: "mtfsfi", + MTFSFICC: "mtfsfi.", + MTFSF: "mtfsf", + MTFSFCC: "mtfsf.", + MTFSB0: "mtfsb0", + MTFSB0CC: "mtfsb0.", + MTFSB1: "mtfsb1", + MTFSB1CC: "mtfsb1.", + LVEBX: "lvebx", + LVEHX: "lvehx", + LVEWX: "lvewx", + LVX: "lvx", + LVXL: "lvxl", + STVEBX: "stvebx", + STVEHX: "stvehx", + STVEWX: "stvewx", + STVX: "stvx", + STVXL: "stvxl", + LVSL: "lvsl", + LVSR: "lvsr", + VPKPX: "vpkpx", + VPKSDSS: "vpksdss", + VPKSDUS: "vpksdus", + VPKSHSS: "vpkshss", + VPKSHUS: "vpkshus", + VPKSWSS: "vpkswss", + VPKSWUS: "vpkswus", + VPKUDUM: "vpkudum", + VPKUDUS: "vpkudus", + VPKUHUM: "vpkuhum", + VPKUHUS: "vpkuhus", + VPKUWUM: "vpkuwum", + VPKUWUS: "vpkuwus", + VUPKHPX: "vupkhpx", + VUPKLPX: "vupklpx", + VUPKHSB: "vupkhsb", + VUPKHSH: "vupkhsh", + VUPKHSW: "vupkhsw", + VUPKLSB: "vupklsb", + VUPKLSH: "vupklsh", + VUPKLSW: "vupklsw", + VMRGHB: "vmrghb", + VMRGHH: "vmrghh", + VMRGLB: "vmrglb", + VMRGLH: "vmrglh", + VMRGHW: "vmrghw", + VMRGLW: "vmrglw", + VMRGEW: "vmrgew", + VMRGOW: "vmrgow", + VSPLTB: "vspltb", + VSPLTH: "vsplth", + VSPLTW: "vspltw", + VSPLTISB: "vspltisb", + VSPLTISH: "vspltish", + VSPLTISW: "vspltisw", + VPERM: "vperm", + VSEL: "vsel", + VSL: "vsl", + VSLDOI: "vsldoi", + VSLO: "vslo", + VSR: "vsr", + VSRO: "vsro", + VADDCUW: "vaddcuw", + VADDSBS: "vaddsbs", + VADDSHS: "vaddshs", + VADDSWS: "vaddsws", + VADDUBM: "vaddubm", + VADDUDM: "vaddudm", + VADDUHM: "vadduhm", + VADDUWM: "vadduwm", + VADDUBS: "vaddubs", + VADDUHS: "vadduhs", + VADDUWS: "vadduws", + VADDUQM: "vadduqm", + VADDEUQM: "vaddeuqm", + VADDCUQ: "vaddcuq", + VADDECUQ: "vaddecuq", + VSUBCUW: "vsubcuw", + VSUBSBS: "vsubsbs", + VSUBSHS: "vsubshs", + VSUBSWS: "vsubsws", + VSUBUBM: "vsububm", + VSUBUDM: "vsubudm", + VSUBUHM: "vsubuhm", + VSUBUWM: "vsubuwm", + VSUBUBS: "vsububs", + VSUBUHS: "vsubuhs", + VSUBUWS: "vsubuws", + VSUBUQM: "vsubuqm", + VSUBEUQM: "vsubeuqm", + VSUBCUQ: "vsubcuq", + VSUBECUQ: "vsubecuq", + VMULESB: "vmulesb", + VMULEUB: "vmuleub", + VMULOSB: "vmulosb", + VMULOUB: "vmuloub", + VMULESH: "vmulesh", + VMULEUH: "vmuleuh", + VMULOSH: "vmulosh", + VMULOUH: "vmulouh", + VMULESW: "vmulesw", + VMULEUW: "vmuleuw", + VMULOSW: "vmulosw", + VMULOUW: "vmulouw", + VMULUWM: "vmuluwm", + VMHADDSHS: "vmhaddshs", + VMHRADDSHS: "vmhraddshs", + VMLADDUHM: "vmladduhm", + VMSUMUBM: "vmsumubm", + VMSUMMBM: "vmsummbm", + VMSUMSHM: "vmsumshm", + VMSUMSHS: "vmsumshs", + VMSUMUHM: "vmsumuhm", + VMSUMUHS: "vmsumuhs", + VSUMSWS: "vsumsws", + VSUM2SWS: "vsum2sws", + VSUM4SBS: "vsum4sbs", + VSUM4SHS: "vsum4shs", + VSUM4UBS: "vsum4ubs", + VAVGSB: "vavgsb", + VAVGSH: "vavgsh", + VAVGSW: "vavgsw", + VAVGUB: "vavgub", + VAVGUW: "vavguw", + VAVGUH: "vavguh", + VMAXSB: "vmaxsb", + VMAXSD: "vmaxsd", + VMAXUB: "vmaxub", + VMAXUD: "vmaxud", + VMAXSH: "vmaxsh", + VMAXSW: "vmaxsw", + VMAXUH: "vmaxuh", + VMAXUW: "vmaxuw", + VMINSB: "vminsb", + VMINSD: "vminsd", + VMINUB: "vminub", + VMINUD: "vminud", + VMINSH: "vminsh", + VMINSW: "vminsw", + VMINUH: "vminuh", + VMINUW: "vminuw", + VCMPEQUB: "vcmpequb", + VCMPEQUBCC: "vcmpequb.", + VCMPEQUH: "vcmpequh", + VCMPEQUHCC: "vcmpequh.", + VCMPEQUW: "vcmpequw", + VCMPEQUWCC: "vcmpequw.", + VCMPEQUD: "vcmpequd", + VCMPEQUDCC: "vcmpequd.", + VCMPGTSB: "vcmpgtsb", + VCMPGTSBCC: "vcmpgtsb.", + VCMPGTSD: "vcmpgtsd", + VCMPGTSDCC: "vcmpgtsd.", + VCMPGTSH: "vcmpgtsh", + VCMPGTSHCC: "vcmpgtsh.", + VCMPGTSW: "vcmpgtsw", + VCMPGTSWCC: "vcmpgtsw.", + VCMPGTUB: "vcmpgtub", + VCMPGTUBCC: "vcmpgtub.", + VCMPGTUD: "vcmpgtud", + VCMPGTUDCC: "vcmpgtud.", + VCMPGTUH: "vcmpgtuh", + VCMPGTUHCC: "vcmpgtuh.", + VCMPGTUW: "vcmpgtuw", + VCMPGTUWCC: "vcmpgtuw.", + VAND: "vand", + VANDC: "vandc", + VEQV: "veqv", + VNAND: "vnand", + VORC: "vorc", + VNOR: "vnor", + VOR: "vor", + VXOR: "vxor", + VRLB: "vrlb", + VRLH: "vrlh", + VRLW: "vrlw", + VRLD: "vrld", + VSLB: "vslb", + VSLH: "vslh", + VSLW: "vslw", + VSLD: "vsld", + VSRB: "vsrb", + VSRH: "vsrh", + VSRW: "vsrw", + VSRD: "vsrd", + VSRAB: "vsrab", + VSRAH: "vsrah", + VSRAW: "vsraw", + VSRAD: "vsrad", + VADDFP: "vaddfp", + VSUBFP: "vsubfp", + VMADDFP: "vmaddfp", + VNMSUBFP: "vnmsubfp", + VMAXFP: "vmaxfp", + VMINFP: "vminfp", + VCTSXS: "vctsxs", + VCTUXS: "vctuxs", + VCFSX: "vcfsx", + VCFUX: "vcfux", + VRFIM: "vrfim", + VRFIN: "vrfin", + VRFIP: "vrfip", + VRFIZ: "vrfiz", + VCMPBFP: "vcmpbfp", + VCMPBFPCC: "vcmpbfp.", + VCMPEQFP: "vcmpeqfp", + VCMPEQFPCC: "vcmpeqfp.", + VCMPGEFP: "vcmpgefp", + VCMPGEFPCC: "vcmpgefp.", + VCMPGTFP: "vcmpgtfp", + VCMPGTFPCC: "vcmpgtfp.", + VEXPTEFP: "vexptefp", + VLOGEFP: "vlogefp", + VREFP: "vrefp", + VRSQRTEFP: "vrsqrtefp", + VCIPHER: "vcipher", + VCIPHERLAST: "vcipherlast", + VNCIPHER: "vncipher", + VNCIPHERLAST: "vncipherlast", + VSBOX: "vsbox", + VSHASIGMAD: "vshasigmad", + VSHASIGMAW: "vshasigmaw", + VPMSUMB: "vpmsumb", + VPMSUMD: "vpmsumd", + VPMSUMH: "vpmsumh", + VPMSUMW: "vpmsumw", + VPERMXOR: "vpermxor", + VGBBD: "vgbbd", + VCLZB: "vclzb", + VCLZH: "vclzh", + VCLZW: "vclzw", + VCLZD: "vclzd", + VPOPCNTB: "vpopcntb", + VPOPCNTD: "vpopcntd", + VPOPCNTH: "vpopcnth", + VPOPCNTW: "vpopcntw", + VBPERMQ: "vbpermq", + BCDADDCC: "bcdadd.", + BCDSUBCC: "bcdsub.", + MTVSCR: "mtvscr", + MFVSCR: "mfvscr", + DADD: "dadd", + DADDCC: "dadd.", + DSUB: "dsub", + DSUBCC: "dsub.", + DMUL: "dmul", + DMULCC: "dmul.", + DDIV: "ddiv", + DDIVCC: "ddiv.", + DCMPU: "dcmpu", + DCMPO: "dcmpo", + DTSTDC: "dtstdc", + DTSTDG: "dtstdg", + DTSTEX: "dtstex", + DTSTSF: "dtstsf", + DQUAI: "dquai", + DQUAICC: "dquai.", + DQUA: "dqua", + DQUACC: "dqua.", + DRRND: "drrnd", + DRRNDCC: "drrnd.", + DRINTX: "drintx", + DRINTXCC: "drintx.", + DRINTN: "drintn", + DRINTNCC: "drintn.", + DCTDP: "dctdp", + DCTDPCC: "dctdp.", + DCTQPQ: "dctqpq", + DCTQPQCC: "dctqpq.", + DRSP: "drsp", + DRSPCC: "drsp.", + DRDPQ: "drdpq", + DRDPQCC: "drdpq.", + DCFFIX: "dcffix", + DCFFIXCC: "dcffix.", + DCFFIXQ: "dcffixq", + DCFFIXQCC: "dcffixq.", + DCTFIX: "dctfix", + DCTFIXCC: "dctfix.", + DDEDPD: "ddedpd", + DDEDPDCC: "ddedpd.", + DENBCD: "denbcd", + DENBCDCC: "denbcd.", + DXEX: "dxex", + DXEXCC: "dxex.", + DIEX: "diex", + DIEXCC: "diex.", + DSCLI: "dscli", + DSCLICC: "dscli.", + DSCRI: "dscri", + DSCRICC: "dscri.", + LXSDX: "lxsdx", + LXSIWAX: "lxsiwax", + LXSIWZX: "lxsiwzx", + LXSSPX: "lxsspx", + LXVD2X: "lxvd2x", + LXVDSX: "lxvdsx", + LXVW4X: "lxvw4x", + STXSDX: "stxsdx", + STXSIWX: "stxsiwx", + STXSSPX: "stxsspx", + STXVD2X: "stxvd2x", + STXVW4X: "stxvw4x", + XSABSDP: "xsabsdp", + XSADDDP: "xsadddp", + XSADDSP: "xsaddsp", + XSCMPODP: "xscmpodp", + XSCMPUDP: "xscmpudp", + XSCPSGNDP: "xscpsgndp", + XSCVDPSP: "xscvdpsp", + XSCVDPSPN: "xscvdpspn", + XSCVDPSXDS: "xscvdpsxds", + XSCVDPSXWS: "xscvdpsxws", + XSCVDPUXDS: "xscvdpuxds", + XSCVDPUXWS: "xscvdpuxws", + XSCVSPDP: "xscvspdp", + XSCVSPDPN: "xscvspdpn", + XSCVSXDDP: "xscvsxddp", + XSCVSXDSP: "xscvsxdsp", + XSCVUXDDP: "xscvuxddp", + XSCVUXDSP: "xscvuxdsp", + XSDIVDP: "xsdivdp", + XSDIVSP: "xsdivsp", + XSMADDADP: "xsmaddadp", + XSMADDASP: "xsmaddasp", + XSMAXDP: "xsmaxdp", + XSMINDP: "xsmindp", + XSMSUBADP: "xsmsubadp", + XSMSUBASP: "xsmsubasp", + XSMULDP: "xsmuldp", + XSMULSP: "xsmulsp", + XSNABSDP: "xsnabsdp", + XSNEGDP: "xsnegdp", + XSNMADDADP: "xsnmaddadp", + XSNMADDASP: "xsnmaddasp", + XSNMSUBADP: "xsnmsubadp", + XSNMSUBASP: "xsnmsubasp", + XSRDPI: "xsrdpi", + XSRDPIC: "xsrdpic", + XSRDPIM: "xsrdpim", + XSRDPIP: "xsrdpip", + XSRDPIZ: "xsrdpiz", + XSREDP: "xsredp", + XSRESP: "xsresp", + XSRSP: "xsrsp", + XSRSQRTEDP: "xsrsqrtedp", + XSRSQRTESP: "xsrsqrtesp", + XSSQRTDP: "xssqrtdp", + XSSQRTSP: "xssqrtsp", + XSSUBDP: "xssubdp", + XSSUBSP: "xssubsp", + XSTDIVDP: "xstdivdp", + XSTSQRTDP: "xstsqrtdp", + XVABSDP: "xvabsdp", + XVABSSP: "xvabssp", + XVADDDP: "xvadddp", + XVADDSP: "xvaddsp", + XVCMPEQDP: "xvcmpeqdp", + XVCMPEQDPCC: "xvcmpeqdp.", + XVCMPEQSP: "xvcmpeqsp", + XVCMPEQSPCC: "xvcmpeqsp.", + XVCMPGEDP: "xvcmpgedp", + XVCMPGEDPCC: "xvcmpgedp.", + XVCMPGESP: "xvcmpgesp", + XVCMPGESPCC: "xvcmpgesp.", + XVCMPGTDP: "xvcmpgtdp", + XVCMPGTDPCC: "xvcmpgtdp.", + XVCMPGTSP: "xvcmpgtsp", + XVCMPGTSPCC: "xvcmpgtsp.", + XVCPSGNDP: "xvcpsgndp", + XVCPSGNSP: "xvcpsgnsp", + XVCVDPSP: "xvcvdpsp", + XVCVDPSXDS: "xvcvdpsxds", + XVCVDPSXWS: "xvcvdpsxws", + XVCVDPUXDS: "xvcvdpuxds", + XVCVDPUXWS: "xvcvdpuxws", + XVCVSPDP: "xvcvspdp", + XVCVSPSXDS: "xvcvspsxds", + XVCVSPSXWS: "xvcvspsxws", + XVCVSPUXDS: "xvcvspuxds", + XVCVSPUXWS: "xvcvspuxws", + XVCVSXDDP: "xvcvsxddp", + XVCVSXDSP: "xvcvsxdsp", + XVCVSXWDP: "xvcvsxwdp", + XVCVSXWSP: "xvcvsxwsp", + XVCVUXDDP: "xvcvuxddp", + XVCVUXDSP: "xvcvuxdsp", + XVCVUXWDP: "xvcvuxwdp", + XVCVUXWSP: "xvcvuxwsp", + XVDIVDP: "xvdivdp", + XVDIVSP: "xvdivsp", + XVMADDADP: "xvmaddadp", + XVMADDASP: "xvmaddasp", + XVMAXDP: "xvmaxdp", + XVMAXSP: "xvmaxsp", + XVMINDP: "xvmindp", + XVMINSP: "xvminsp", + XVMSUBADP: "xvmsubadp", + XVMSUBASP: "xvmsubasp", + XVMULDP: "xvmuldp", + XVMULSP: "xvmulsp", + XVNABSDP: "xvnabsdp", + XVNABSSP: "xvnabssp", + XVNEGDP: "xvnegdp", + XVNEGSP: "xvnegsp", + XVNMADDADP: "xvnmaddadp", + XVNMADDASP: "xvnmaddasp", + XVNMSUBADP: "xvnmsubadp", + XVNMSUBASP: "xvnmsubasp", + XVRDPI: "xvrdpi", + XVRDPIC: "xvrdpic", + XVRDPIM: "xvrdpim", + XVRDPIP: "xvrdpip", + XVRDPIZ: "xvrdpiz", + XVREDP: "xvredp", + XVRESP: "xvresp", + XVRSPI: "xvrspi", + XVRSPIC: "xvrspic", + XVRSPIM: "xvrspim", + XVRSPIP: "xvrspip", + XVRSPIZ: "xvrspiz", + XVRSQRTEDP: "xvrsqrtedp", + XVRSQRTESP: "xvrsqrtesp", + XVSQRTDP: "xvsqrtdp", + XVSQRTSP: "xvsqrtsp", + XVSUBDP: "xvsubdp", + XVSUBSP: "xvsubsp", + XVTDIVDP: "xvtdivdp", + XVTDIVSP: "xvtdivsp", + XVTSQRTDP: "xvtsqrtdp", + XVTSQRTSP: "xvtsqrtsp", + XXLAND: "xxland", + XXLANDC: "xxlandc", + XXLEQV: "xxleqv", + XXLNAND: "xxlnand", + XXLORC: "xxlorc", + XXLNOR: "xxlnor", + XXLOR: "xxlor", + XXLXOR: "xxlxor", + XXMRGHW: "xxmrghw", + XXMRGLW: "xxmrglw", + XXPERMDI: "xxpermdi", + XXSEL: "xxsel", + XXSLDWI: "xxsldwi", + XXSPLTW: "xxspltw", + BRINC: "brinc", + EVABS: "evabs", + EVADDIW: "evaddiw", + EVADDSMIAAW: "evaddsmiaaw", + EVADDSSIAAW: "evaddssiaaw", + EVADDUMIAAW: "evaddumiaaw", + EVADDUSIAAW: "evaddusiaaw", + EVADDW: "evaddw", + EVAND: "evand", + EVCMPEQ: "evcmpeq", + EVANDC: "evandc", + EVCMPGTS: "evcmpgts", + EVCMPGTU: "evcmpgtu", + EVCMPLTU: "evcmpltu", + EVCMPLTS: "evcmplts", + EVCNTLSW: "evcntlsw", + EVCNTLZW: "evcntlzw", + EVDIVWS: "evdivws", + EVDIVWU: "evdivwu", + EVEQV: "eveqv", + EVEXTSB: "evextsb", + EVEXTSH: "evextsh", + EVLDD: "evldd", + EVLDH: "evldh", + EVLDDX: "evlddx", + EVLDHX: "evldhx", + EVLDW: "evldw", + EVLHHESPLAT: "evlhhesplat", + EVLDWX: "evldwx", + EVLHHESPLATX: "evlhhesplatx", + EVLHHOSSPLAT: "evlhhossplat", + EVLHHOUSPLAT: "evlhhousplat", + EVLHHOSSPLATX: "evlhhossplatx", + EVLHHOUSPLATX: "evlhhousplatx", + EVLWHE: "evlwhe", + EVLWHOS: "evlwhos", + EVLWHEX: "evlwhex", + EVLWHOSX: "evlwhosx", + EVLWHOU: "evlwhou", + EVLWHSPLAT: "evlwhsplat", + EVLWHOUX: "evlwhoux", + EVLWHSPLATX: "evlwhsplatx", + EVLWWSPLAT: "evlwwsplat", + EVMERGEHI: "evmergehi", + EVLWWSPLATX: "evlwwsplatx", + EVMERGELO: "evmergelo", + EVMERGEHILO: "evmergehilo", + EVMHEGSMFAA: "evmhegsmfaa", + EVMERGELOHI: "evmergelohi", + EVMHEGSMFAN: "evmhegsmfan", + EVMHEGSMIAA: "evmhegsmiaa", + EVMHEGUMIAA: "evmhegumiaa", + EVMHEGSMIAN: "evmhegsmian", + EVMHEGUMIAN: "evmhegumian", + EVMHESMF: "evmhesmf", + EVMHESMFAAW: "evmhesmfaaw", + EVMHESMFA: "evmhesmfa", + EVMHESMFANW: "evmhesmfanw", + EVMHESMI: "evmhesmi", + EVMHESMIAAW: "evmhesmiaaw", + EVMHESMIA: "evmhesmia", + EVMHESMIANW: "evmhesmianw", + EVMHESSF: "evmhessf", + EVMHESSFA: "evmhessfa", + EVMHESSFAAW: "evmhessfaaw", + EVMHESSFANW: "evmhessfanw", + EVMHESSIAAW: "evmhessiaaw", + EVMHESSIANW: "evmhessianw", + EVMHEUMI: "evmheumi", + EVMHEUMIAAW: "evmheumiaaw", + EVMHEUMIA: "evmheumia", + EVMHEUMIANW: "evmheumianw", + EVMHEUSIAAW: "evmheusiaaw", + EVMHEUSIANW: "evmheusianw", + EVMHOGSMFAA: "evmhogsmfaa", + EVMHOGSMIAA: "evmhogsmiaa", + EVMHOGSMFAN: "evmhogsmfan", + EVMHOGSMIAN: "evmhogsmian", + EVMHOGUMIAA: "evmhogumiaa", + EVMHOSMF: "evmhosmf", + EVMHOGUMIAN: "evmhogumian", + EVMHOSMFA: "evmhosmfa", + EVMHOSMFAAW: "evmhosmfaaw", + EVMHOSMI: "evmhosmi", + EVMHOSMFANW: "evmhosmfanw", + EVMHOSMIA: "evmhosmia", + EVMHOSMIAAW: "evmhosmiaaw", + EVMHOSMIANW: "evmhosmianw", + EVMHOSSF: "evmhossf", + EVMHOSSFA: "evmhossfa", + EVMHOSSFAAW: "evmhossfaaw", + EVMHOSSFANW: "evmhossfanw", + EVMHOSSIAAW: "evmhossiaaw", + EVMHOUMI: "evmhoumi", + EVMHOSSIANW: "evmhossianw", + EVMHOUMIA: "evmhoumia", + EVMHOUMIAAW: "evmhoumiaaw", + EVMHOUSIAAW: "evmhousiaaw", + EVMHOUMIANW: "evmhoumianw", + EVMHOUSIANW: "evmhousianw", + EVMRA: "evmra", + EVMWHSMF: "evmwhsmf", + EVMWHSMI: "evmwhsmi", + EVMWHSMFA: "evmwhsmfa", + EVMWHSMIA: "evmwhsmia", + EVMWHSSF: "evmwhssf", + EVMWHUMI: "evmwhumi", + EVMWHSSFA: "evmwhssfa", + EVMWHUMIA: "evmwhumia", + EVMWLSMIAAW: "evmwlsmiaaw", + EVMWLSSIAAW: "evmwlssiaaw", + EVMWLSMIANW: "evmwlsmianw", + EVMWLSSIANW: "evmwlssianw", + EVMWLUMI: "evmwlumi", + EVMWLUMIAAW: "evmwlumiaaw", + EVMWLUMIA: "evmwlumia", + EVMWLUMIANW: "evmwlumianw", + EVMWLUSIAAW: "evmwlusiaaw", + EVMWSMF: "evmwsmf", + EVMWLUSIANW: "evmwlusianw", + EVMWSMFA: "evmwsmfa", + EVMWSMFAA: "evmwsmfaa", + EVMWSMI: "evmwsmi", + EVMWSMIAA: "evmwsmiaa", + EVMWSMFAN: "evmwsmfan", + EVMWSMIA: "evmwsmia", + EVMWSMIAN: "evmwsmian", + EVMWSSF: "evmwssf", + EVMWSSFA: "evmwssfa", + EVMWSSFAA: "evmwssfaa", + EVMWUMI: "evmwumi", + EVMWSSFAN: "evmwssfan", + EVMWUMIA: "evmwumia", + EVMWUMIAA: "evmwumiaa", + EVNAND: "evnand", + EVMWUMIAN: "evmwumian", + EVNEG: "evneg", + EVNOR: "evnor", + EVORC: "evorc", + EVOR: "evor", + EVRLW: "evrlw", + EVRLWI: "evrlwi", + EVSEL: "evsel", + EVRNDW: "evrndw", + EVSLW: "evslw", + EVSPLATFI: "evsplatfi", + EVSRWIS: "evsrwis", + EVSLWI: "evslwi", + EVSPLATI: "evsplati", + EVSRWIU: "evsrwiu", + EVSRWS: "evsrws", + EVSTDD: "evstdd", + EVSRWU: "evsrwu", + EVSTDDX: "evstddx", + EVSTDH: "evstdh", + EVSTDW: "evstdw", + EVSTDHX: "evstdhx", + EVSTDWX: "evstdwx", + EVSTWHE: "evstwhe", + EVSTWHO: "evstwho", + EVSTWWE: "evstwwe", + EVSTWHEX: "evstwhex", + EVSTWHOX: "evstwhox", + EVSTWWEX: "evstwwex", + EVSTWWO: "evstwwo", + EVSUBFSMIAAW: "evsubfsmiaaw", + EVSTWWOX: "evstwwox", + EVSUBFSSIAAW: "evsubfssiaaw", + EVSUBFUMIAAW: "evsubfumiaaw", + EVSUBFUSIAAW: "evsubfusiaaw", + EVSUBFW: "evsubfw", + EVSUBIFW: "evsubifw", + EVXOR: "evxor", + EVFSABS: "evfsabs", + EVFSNABS: "evfsnabs", + EVFSNEG: "evfsneg", + EVFSADD: "evfsadd", + EVFSMUL: "evfsmul", + EVFSSUB: "evfssub", + EVFSDIV: "evfsdiv", + EVFSCMPGT: "evfscmpgt", + EVFSCMPLT: "evfscmplt", + EVFSCMPEQ: "evfscmpeq", + EVFSTSTGT: "evfststgt", + EVFSTSTLT: "evfststlt", + EVFSTSTEQ: "evfststeq", + EVFSCFSI: "evfscfsi", + EVFSCFSF: "evfscfsf", + EVFSCFUI: "evfscfui", + EVFSCFUF: "evfscfuf", + EVFSCTSI: "evfsctsi", + EVFSCTUI: "evfsctui", + EVFSCTSIZ: "evfsctsiz", + EVFSCTUIZ: "evfsctuiz", + EVFSCTSF: "evfsctsf", + EVFSCTUF: "evfsctuf", + EFSABS: "efsabs", + EFSNEG: "efsneg", + EFSNABS: "efsnabs", + EFSADD: "efsadd", + EFSMUL: "efsmul", + EFSSUB: "efssub", + EFSDIV: "efsdiv", + EFSCMPGT: "efscmpgt", + EFSCMPLT: "efscmplt", + EFSCMPEQ: "efscmpeq", + EFSTSTGT: "efststgt", + EFSTSTLT: "efststlt", + EFSTSTEQ: "efststeq", + EFSCFSI: "efscfsi", + EFSCFSF: "efscfsf", + EFSCTSI: "efsctsi", + EFSCFUI: "efscfui", + EFSCFUF: "efscfuf", + EFSCTUI: "efsctui", + EFSCTSIZ: "efsctsiz", + EFSCTSF: "efsctsf", + EFSCTUIZ: "efsctuiz", + EFSCTUF: "efsctuf", + EFDABS: "efdabs", + EFDNEG: "efdneg", + EFDNABS: "efdnabs", + EFDADD: "efdadd", + EFDMUL: "efdmul", + EFDSUB: "efdsub", + EFDDIV: "efddiv", + EFDCMPGT: "efdcmpgt", + EFDCMPEQ: "efdcmpeq", + EFDCMPLT: "efdcmplt", + EFDTSTGT: "efdtstgt", + EFDTSTLT: "efdtstlt", + EFDCFSI: "efdcfsi", + EFDTSTEQ: "efdtsteq", + EFDCFUI: "efdcfui", + EFDCFSID: "efdcfsid", + EFDCFSF: "efdcfsf", + EFDCFUF: "efdcfuf", + EFDCFUID: "efdcfuid", + EFDCTSI: "efdctsi", + EFDCTUI: "efdctui", + EFDCTSIDZ: "efdctsidz", + EFDCTUIDZ: "efdctuidz", + EFDCTSIZ: "efdctsiz", + EFDCTSF: "efdctsf", + EFDCTUF: "efdctuf", + EFDCTUIZ: "efdctuiz", + EFDCFS: "efdcfs", + EFSCFD: "efscfd", + DLMZB: "dlmzb", + DLMZBCC: "dlmzb.", + MACCHW: "macchw", + MACCHWCC: "macchw.", + MACCHWO: "macchwo", + MACCHWOCC: "macchwo.", + MACCHWS: "macchws", + MACCHWSCC: "macchws.", + MACCHWSO: "macchwso", + MACCHWSOCC: "macchwso.", + MACCHWU: "macchwu", + MACCHWUCC: "macchwu.", + MACCHWUO: "macchwuo", + MACCHWUOCC: "macchwuo.", + MACCHWSU: "macchwsu", + MACCHWSUCC: "macchwsu.", + MACCHWSUO: "macchwsuo", + MACCHWSUOCC: "macchwsuo.", + MACHHW: "machhw", + MACHHWCC: "machhw.", + MACHHWO: "machhwo", + MACHHWOCC: "machhwo.", + MACHHWS: "machhws", + MACHHWSCC: "machhws.", + MACHHWSO: "machhwso", + MACHHWSOCC: "machhwso.", + MACHHWU: "machhwu", + MACHHWUCC: "machhwu.", + MACHHWUO: "machhwuo", + MACHHWUOCC: "machhwuo.", + MACHHWSU: "machhwsu", + MACHHWSUCC: "machhwsu.", + MACHHWSUO: "machhwsuo", + MACHHWSUOCC: "machhwsuo.", + MACLHW: "maclhw", + MACLHWCC: "maclhw.", + MACLHWO: "maclhwo", + MACLHWOCC: "maclhwo.", + MACLHWS: "maclhws", + MACLHWSCC: "maclhws.", + MACLHWSO: "maclhwso", + MACLHWSOCC: "maclhwso.", + MACLHWU: "maclhwu", + MACLHWUCC: "maclhwu.", + MACLHWUO: "maclhwuo", + MACLHWUOCC: "maclhwuo.", + MULCHW: "mulchw", + MULCHWCC: "mulchw.", + MACLHWSU: "maclhwsu", + MACLHWSUCC: "maclhwsu.", + MACLHWSUO: "maclhwsuo", + MACLHWSUOCC: "maclhwsuo.", + MULCHWU: "mulchwu", + MULCHWUCC: "mulchwu.", + MULHHW: "mulhhw", + MULHHWCC: "mulhhw.", + MULLHW: "mullhw", + MULLHWCC: "mullhw.", + MULHHWU: "mulhhwu", + MULHHWUCC: "mulhhwu.", + MULLHWU: "mullhwu", + MULLHWUCC: "mullhwu.", + NMACCHW: "nmacchw", + NMACCHWCC: "nmacchw.", + NMACCHWO: "nmacchwo", + NMACCHWOCC: "nmacchwo.", + NMACCHWS: "nmacchws", + NMACCHWSCC: "nmacchws.", + NMACCHWSO: "nmacchwso", + NMACCHWSOCC: "nmacchwso.", + NMACHHW: "nmachhw", + NMACHHWCC: "nmachhw.", + NMACHHWO: "nmachhwo", + NMACHHWOCC: "nmachhwo.", + NMACHHWS: "nmachhws", + NMACHHWSCC: "nmachhws.", + NMACHHWSO: "nmachhwso", + NMACHHWSOCC: "nmachhwso.", + NMACLHW: "nmaclhw", + NMACLHWCC: "nmaclhw.", + NMACLHWO: "nmaclhwo", + NMACLHWOCC: "nmaclhwo.", + NMACLHWS: "nmaclhws", + NMACLHWSCC: "nmaclhws.", + NMACLHWSO: "nmaclhwso", + NMACLHWSOCC: "nmaclhwso.", + ICBI: "icbi", + ICBT: "icbt", + DCBA: "dcba", + DCBT: "dcbt", + DCBTST: "dcbtst", + DCBZ: "dcbz", + DCBST: "dcbst", + DCBF: "dcbf", + ISYNC: "isync", + LBARX: "lbarx", + LHARX: "lharx", + LWARX: "lwarx", + STBCXCC: "stbcx.", + STHCXCC: "sthcx.", + STWCXCC: "stwcx.", + LDARX: "ldarx", + STDCXCC: "stdcx.", + LQARX: "lqarx", + STQCXCC: "stqcx.", + SYNC: "sync", + EIEIO: "eieio", + MBAR: "mbar", + WAIT: "wait", + TBEGINCC: "tbegin.", + TENDCC: "tend.", + TABORTCC: "tabort.", + TABORTWCCC: "tabortwc.", + TABORTWCICC: "tabortwci.", + TABORTDCCC: "tabortdc.", + TABORTDCICC: "tabortdci.", + TSRCC: "tsr.", + TCHECK: "tcheck", + MFTB: "mftb", + RFEBB: "rfebb", + LBDX: "lbdx", + LHDX: "lhdx", + LWDX: "lwdx", + LDDX: "lddx", + LFDDX: "lfddx", + STBDX: "stbdx", + STHDX: "sthdx", + STWDX: "stwdx", + STDDX: "stddx", + STFDDX: "stfddx", + DSN: "dsn", + ECIWX: "eciwx", + ECOWX: "ecowx", + RFID: "rfid", + HRFID: "hrfid", + DOZE: "doze", + NAP: "nap", + SLEEP: "sleep", + RVWINKLE: "rvwinkle", + LBZCIX: "lbzcix", + LWZCIX: "lwzcix", + LHZCIX: "lhzcix", + LDCIX: "ldcix", + STBCIX: "stbcix", + STWCIX: "stwcix", + STHCIX: "sthcix", + STDCIX: "stdcix", + TRECLAIMCC: "treclaim.", + TRECHKPTCC: "trechkpt.", + MTMSR: "mtmsr", + MTMSRD: "mtmsrd", + MFMSR: "mfmsr", + SLBIE: "slbie", + SLBIA: "slbia", + SLBMTE: "slbmte", + SLBMFEV: "slbmfev", + SLBMFEE: "slbmfee", + SLBFEECC: "slbfee.", + MTSR: "mtsr", + MTSRIN: "mtsrin", + MFSR: "mfsr", + MFSRIN: "mfsrin", + TLBIE: "tlbie", + TLBIEL: "tlbiel", + TLBIA: "tlbia", + TLBSYNC: "tlbsync", + MSGSND: "msgsnd", + MSGCLR: "msgclr", + MSGSNDP: "msgsndp", + MSGCLRP: "msgclrp", + MTTMR: "mttmr", + RFI: "rfi", + RFCI: "rfci", + RFDI: "rfdi", + RFMCI: "rfmci", + RFGI: "rfgi", + EHPRIV: "ehpriv", + MTDCR: "mtdcr", + MTDCRX: "mtdcrx", + MFDCR: "mfdcr", + MFDCRX: "mfdcrx", + WRTEE: "wrtee", + WRTEEI: "wrteei", + LBEPX: "lbepx", + LHEPX: "lhepx", + LWEPX: "lwepx", + LDEPX: "ldepx", + STBEPX: "stbepx", + STHEPX: "sthepx", + STWEPX: "stwepx", + STDEPX: "stdepx", + DCBSTEP: "dcbstep", + DCBTEP: "dcbtep", + DCBFEP: "dcbfep", + DCBTSTEP: "dcbtstep", + ICBIEP: "icbiep", + DCBZEP: "dcbzep", + LFDEPX: "lfdepx", + STFDEPX: "stfdepx", + EVLDDEPX: "evlddepx", + EVSTDDEPX: "evstddepx", + LVEPX: "lvepx", + LVEPXL: "lvepxl", + STVEPX: "stvepx", + STVEPXL: "stvepxl", + DCBI: "dcbi", + DCBLQCC: "dcblq.", + ICBLQCC: "icblq.", + DCBTLS: "dcbtls", + DCBTSTLS: "dcbtstls", + ICBTLS: "icbtls", + ICBLC: "icblc", + DCBLC: "dcblc", + TLBIVAX: "tlbivax", + TLBILX: "tlbilx", + TLBSX: "tlbsx", + TLBSRXCC: "tlbsrx.", + TLBRE: "tlbre", + TLBWE: "tlbwe", + DNH: "dnh", + DCI: "dci", + ICI: "ici", + DCREAD: "dcread", + ICREAD: "icread", + MFPMR: "mfpmr", + MTPMR: "mtpmr", + ADDEX: "addex", + DARN: "darn", + MADDHD: "maddhd", + MADDHDU: "maddhdu", + MADDLD: "maddld", + CMPRB: "cmprb", + CMPEQB: "cmpeqb", + EXTSWSLI: "extswsli", + EXTSWSLICC: "extswsli.", + MFVSRLD: "mfvsrld", + MTVSRDD: "mtvsrdd", + MTVSRWS: "mtvsrws", + MCRXRX: "mcrxrx", + COPY: "copy", + PASTECC: "paste.", +} + +var ( + ap_Reg_11_15 = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{11, 5}}} + ap_Reg_6_10 = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{6, 5}}} + ap_PCRel_6_29_shift2 = &argField{Type: TypePCRel, Shift: 2, BitFields: BitFields{{6, 24}}} + ap_Label_6_29_shift2 = &argField{Type: TypeLabel, Shift: 2, BitFields: BitFields{{6, 24}}} + ap_ImmUnsigned_6_10 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{6, 5}}} + ap_CondRegBit_11_15 = &argField{Type: TypeCondRegBit, Shift: 0, BitFields: BitFields{{11, 5}}} + ap_PCRel_16_29_shift2 = &argField{Type: TypePCRel, Shift: 2, BitFields: BitFields{{16, 14}}} + ap_Label_16_29_shift2 = &argField{Type: TypeLabel, Shift: 2, BitFields: BitFields{{16, 14}}} + ap_ImmUnsigned_19_20 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{19, 2}}} + ap_CondRegBit_6_10 = &argField{Type: TypeCondRegBit, Shift: 0, BitFields: BitFields{{6, 5}}} + ap_CondRegBit_16_20 = &argField{Type: TypeCondRegBit, Shift: 0, BitFields: BitFields{{16, 5}}} + ap_CondRegField_6_8 = &argField{Type: TypeCondRegField, Shift: 0, BitFields: BitFields{{6, 3}}} + ap_CondRegField_11_13 = &argField{Type: TypeCondRegField, Shift: 0, BitFields: BitFields{{11, 3}}} + ap_ImmUnsigned_20_26 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{20, 7}}} + ap_SpReg_11_20 = &argField{Type: TypeSpReg, Shift: 0, BitFields: BitFields{{11, 10}}} + ap_Offset_16_31 = &argField{Type: TypeOffset, Shift: 0, BitFields: BitFields{{16, 16}}} + ap_Reg_16_20 = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{16, 5}}} + ap_Offset_16_29_shift2 = &argField{Type: TypeOffset, Shift: 2, BitFields: BitFields{{16, 14}}} + ap_Offset_16_27_shift4 = &argField{Type: TypeOffset, Shift: 4, BitFields: BitFields{{16, 12}}} + ap_ImmUnsigned_16_20 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 5}}} + ap_ImmSigned_16_31 = &argField{Type: TypeImmSigned, Shift: 0, BitFields: BitFields{{16, 16}}} + ap_ImmUnsigned_16_31 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 16}}} + ap_CondRegBit_21_25 = &argField{Type: TypeCondRegBit, Shift: 0, BitFields: BitFields{{21, 5}}} + ap_ImmUnsigned_21_25 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{21, 5}}} + ap_ImmUnsigned_26_30 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{26, 5}}} + ap_ImmUnsigned_30_30_16_20 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{30, 1}, {16, 5}}} + ap_ImmUnsigned_26_26_21_25 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{26, 1}, {21, 5}}} + ap_SpReg_16_20_11_15 = &argField{Type: TypeSpReg, Shift: 0, BitFields: BitFields{{16, 5}, {11, 5}}} + ap_ImmUnsigned_12_19 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{12, 8}}} + ap_ImmUnsigned_10_10 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{10, 1}}} + ap_VecSReg_31_31_6_10 = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{31, 1}, {6, 5}}} + ap_FPReg_6_10 = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{6, 5}}} + ap_FPReg_16_20 = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{16, 5}}} + ap_FPReg_11_15 = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{11, 5}}} + ap_FPReg_21_25 = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{21, 5}}} + ap_ImmUnsigned_16_19 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 4}}} + ap_ImmUnsigned_15_15 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{15, 1}}} + ap_ImmUnsigned_7_14 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{7, 8}}} + ap_ImmUnsigned_6_6 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{6, 1}}} + ap_VecReg_6_10 = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{6, 5}}} + ap_VecReg_11_15 = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{11, 5}}} + ap_VecReg_16_20 = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{16, 5}}} + ap_ImmUnsigned_12_15 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{12, 4}}} + ap_ImmUnsigned_13_15 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{13, 3}}} + ap_ImmUnsigned_14_15 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{14, 2}}} + ap_ImmSigned_11_15 = &argField{Type: TypeImmSigned, Shift: 0, BitFields: BitFields{{11, 5}}} + ap_VecReg_21_25 = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{21, 5}}} + ap_ImmUnsigned_22_25 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{22, 4}}} + ap_ImmUnsigned_11_15 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{11, 5}}} + ap_ImmUnsigned_16_16 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 1}}} + ap_ImmUnsigned_17_20 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{17, 4}}} + ap_ImmUnsigned_22_22 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{22, 1}}} + ap_ImmUnsigned_16_21 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 6}}} + ap_ImmUnsigned_21_22 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{21, 2}}} + ap_ImmUnsigned_11_12 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{11, 2}}} + ap_ImmUnsigned_11_11 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{11, 1}}} + ap_VecSReg_30_30_16_20 = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{30, 1}, {16, 5}}} + ap_VecSReg_29_29_11_15 = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{29, 1}, {11, 5}}} + ap_ImmUnsigned_22_23 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{22, 2}}} + ap_VecSReg_28_28_21_25 = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{28, 1}, {21, 5}}} + ap_CondRegField_29_31 = &argField{Type: TypeCondRegField, Shift: 0, BitFields: BitFields{{29, 3}}} + ap_ImmUnsigned_7_10 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{7, 4}}} + ap_ImmUnsigned_9_10 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{9, 2}}} + ap_ImmUnsigned_31_31 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{31, 1}}} + ap_ImmSigned_16_20 = &argField{Type: TypeImmSigned, Shift: 0, BitFields: BitFields{{16, 5}}} + ap_ImmUnsigned_20_20 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{20, 1}}} + ap_ImmUnsigned_8_10 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{8, 3}}} + ap_SpReg_12_15 = &argField{Type: TypeSpReg, Shift: 0, BitFields: BitFields{{12, 4}}} + ap_ImmUnsigned_6_20 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{6, 15}}} + ap_ImmUnsigned_11_20 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{11, 10}}} + ap_Reg_21_25 = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{21, 5}}} +) + +var instFormats = [...]instFormat{ + {CNTLZW, 0xfc0007ff, 0x7c000034, 0xf800, // Count Leading Zeros Word X-form (cntlzw RA, RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {CNTLZWCC, 0xfc0007ff, 0x7c000035, 0xf800, // Count Leading Zeros Word X-form (cntlzw. RA, RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {B, 0xfc000003, 0x48000000, 0x0, // Branch I-form (b target_addr) + [5]*argField{ap_PCRel_6_29_shift2}}, + {BA, 0xfc000003, 0x48000002, 0x0, // Branch I-form (ba target_addr) + [5]*argField{ap_Label_6_29_shift2}}, + {BL, 0xfc000003, 0x48000001, 0x0, // Branch I-form (bl target_addr) + [5]*argField{ap_PCRel_6_29_shift2}}, + {BLA, 0xfc000003, 0x48000003, 0x0, // Branch I-form (bla target_addr) + [5]*argField{ap_Label_6_29_shift2}}, + {BC, 0xfc000003, 0x40000000, 0x0, // Branch Conditional B-form (bc BO,BI,target_addr) + [5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_PCRel_16_29_shift2}}, + {BCA, 0xfc000003, 0x40000002, 0x0, // Branch Conditional B-form (bca BO,BI,target_addr) + [5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_Label_16_29_shift2}}, + {BCL, 0xfc000003, 0x40000001, 0x0, // Branch Conditional B-form (bcl BO,BI,target_addr) + [5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_PCRel_16_29_shift2}}, + {BCLA, 0xfc000003, 0x40000003, 0x0, // Branch Conditional B-form (bcla BO,BI,target_addr) + [5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_Label_16_29_shift2}}, + {BCLR, 0xfc0007ff, 0x4c000020, 0xe000, // Branch Conditional to Link Register XL-form (bclr BO,BI,BH) + [5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}}, + {BCLRL, 0xfc0007ff, 0x4c000021, 0xe000, // Branch Conditional to Link Register XL-form (bclrl BO,BI,BH) + [5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}}, + {BCCTR, 0xfc0007ff, 0x4c000420, 0xe000, // Branch Conditional to Count Register XL-form (bcctr BO,BI,BH) + [5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}}, + {BCCTRL, 0xfc0007ff, 0x4c000421, 0xe000, // Branch Conditional to Count Register XL-form (bcctrl BO,BI,BH) + [5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}}, + {BCTAR, 0xfc0007ff, 0x4c000460, 0xe000, // Branch Conditional to Branch Target Address Register XL-form (bctar BO,BI,BH) + [5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}}, + {BCTARL, 0xfc0007ff, 0x4c000461, 0xe000, // Branch Conditional to Branch Target Address Register XL-form (bctarl BO,BI,BH) + [5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}}, + {CRAND, 0xfc0007fe, 0x4c000202, 0x1, // Condition Register AND XL-form (crand BT,BA,BB) + [5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}}, + {CROR, 0xfc0007fe, 0x4c000382, 0x1, // Condition Register OR XL-form (cror BT,BA,BB) + [5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}}, + {CRNAND, 0xfc0007fe, 0x4c0001c2, 0x1, // Condition Register NAND XL-form (crnand BT,BA,BB) + [5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}}, + {CRXOR, 0xfc0007fe, 0x4c000182, 0x1, // Condition Register XOR XL-form (crxor BT,BA,BB) + [5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}}, + {CRNOR, 0xfc0007fe, 0x4c000042, 0x1, // Condition Register NOR XL-form (crnor BT,BA,BB) + [5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}}, + {CRANDC, 0xfc0007fe, 0x4c000102, 0x1, // Condition Register AND with Complement XL-form (crandc BT,BA,BB) + [5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}}, + {MCRF, 0xfc0007fe, 0x4c000000, 0x63f801, // Move Condition Register Field XL-form (mcrf BF,BFA) + [5]*argField{ap_CondRegField_6_8, ap_CondRegField_11_13}}, + {CREQV, 0xfc0007fe, 0x4c000242, 0x1, // Condition Register Equivalent XL-form (creqv BT,BA,BB) + [5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}}, + {CRORC, 0xfc0007fe, 0x4c000342, 0x1, // Condition Register OR with Complement XL-form (crorc BT,BA,BB) + [5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}}, + {SC, 0xfc000002, 0x44000002, 0x3fff01d, // System Call SC-form (sc LEV) + [5]*argField{ap_ImmUnsigned_20_26}}, + {CLRBHRB, 0xfc0007fe, 0x7c00035c, 0x3fff801, // Clear BHRB X-form (clrbhrb) + [5]*argField{}}, + {MFBHRBE, 0xfc0007fe, 0x7c00025c, 0x1, // Move From Branch History Rolling Buffer XFX-form (mfbhrbe RT,BHRBE) + [5]*argField{ap_Reg_6_10, ap_SpReg_11_20}}, + {LBZ, 0xfc000000, 0x88000000, 0x0, // Load Byte and Zero D-form (lbz RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {LBZU, 0xfc000000, 0x8c000000, 0x0, // Load Byte and Zero with Update D-form (lbzu RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {LBZX, 0xfc0007fe, 0x7c0000ae, 0x1, // Load Byte and Zero Indexed X-form (lbzx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LBZUX, 0xfc0007fe, 0x7c0000ee, 0x1, // Load Byte and Zero with Update Indexed X-form (lbzux RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LHZ, 0xfc000000, 0xa0000000, 0x0, // Load Halfword and Zero D-form (lhz RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {LHZU, 0xfc000000, 0xa4000000, 0x0, // Load Halfword and Zero with Update D-form (lhzu RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {LHZX, 0xfc0007fe, 0x7c00022e, 0x1, // Load Halfword and Zero Indexed X-form (lhzx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LHZUX, 0xfc0007fe, 0x7c00026e, 0x1, // Load Halfword and Zero with Update Indexed X-form (lhzux RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LHA, 0xfc000000, 0xa8000000, 0x0, // Load Halfword Algebraic D-form (lha RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {LHAU, 0xfc000000, 0xac000000, 0x0, // Load Halfword Algebraic with Update D-form (lhau RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {LHAX, 0xfc0007fe, 0x7c0002ae, 0x1, // Load Halfword Algebraic Indexed X-form (lhax RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LHAUX, 0xfc0007fe, 0x7c0002ee, 0x1, // Load Halfword Algebraic with Update Indexed X-form (lhaux RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LWZ, 0xfc000000, 0x80000000, 0x0, // Load Word and Zero D-form (lwz RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {LWZU, 0xfc000000, 0x84000000, 0x0, // Load Word and Zero with Update D-form (lwzu RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {LWZX, 0xfc0007fe, 0x7c00002e, 0x1, // Load Word and Zero Indexed X-form (lwzx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LWZUX, 0xfc0007fe, 0x7c00006e, 0x1, // Load Word and Zero with Update Indexed X-form (lwzux RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LWA, 0xfc000003, 0xe8000002, 0x0, // Load Word Algebraic DS-form (lwa RT,DS(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}}, + {LWAX, 0xfc0007fe, 0x7c0002aa, 0x1, // Load Word Algebraic Indexed X-form (lwax RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LWAUX, 0xfc0007fe, 0x7c0002ea, 0x1, // Load Word Algebraic with Update Indexed X-form (lwaux RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LD, 0xfc000003, 0xe8000000, 0x0, // Load Doubleword DS-form (ld RT,DS(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}}, + {LDU, 0xfc000003, 0xe8000001, 0x0, // Load Doubleword with Update DS-form (ldu RT,DS(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}}, + {LDX, 0xfc0007fe, 0x7c00002a, 0x1, // Load Doubleword Indexed X-form (ldx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LDUX, 0xfc0007fe, 0x7c00006a, 0x1, // Load Doubleword with Update Indexed X-form (ldux RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STB, 0xfc000000, 0x98000000, 0x0, // Store Byte D-form (stb RS,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {STBU, 0xfc000000, 0x9c000000, 0x0, // Store Byte with Update D-form (stbu RS,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {STBX, 0xfc0007fe, 0x7c0001ae, 0x1, // Store Byte Indexed X-form (stbx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STBUX, 0xfc0007fe, 0x7c0001ee, 0x1, // Store Byte with Update Indexed X-form (stbux RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STH, 0xfc000000, 0xb0000000, 0x0, // Store Halfword D-form (sth RS,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {STHU, 0xfc000000, 0xb4000000, 0x0, // Store Halfword with Update D-form (sthu RS,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {STHX, 0xfc0007fe, 0x7c00032e, 0x1, // Store Halfword Indexed X-form (sthx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STHUX, 0xfc0007fe, 0x7c00036e, 0x1, // Store Halfword with Update Indexed X-form (sthux RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STW, 0xfc000000, 0x90000000, 0x0, // Store Word D-form (stw RS,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {STWU, 0xfc000000, 0x94000000, 0x0, // Store Word with Update D-form (stwu RS,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {STWX, 0xfc0007fe, 0x7c00012e, 0x1, // Store Word Indexed X-form (stwx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STWUX, 0xfc0007fe, 0x7c00016e, 0x1, // Store Word with Update Indexed X-form (stwux RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STD, 0xfc000003, 0xf8000000, 0x0, // Store Doubleword DS-form (std RS,DS(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}}, + {STDU, 0xfc000003, 0xf8000001, 0x0, // Store Doubleword with Update DS-form (stdu RS,DS(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}}, + {STDX, 0xfc0007fe, 0x7c00012a, 0x1, // Store Doubleword Indexed X-form (stdx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STDUX, 0xfc0007fe, 0x7c00016a, 0x1, // Store Doubleword with Update Indexed X-form (stdux RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LQ, 0xfc000000, 0xe0000000, 0xf, // Load Quadword DQ-form (lq RTp,DQ(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_27_shift4, ap_Reg_11_15}}, + {STQ, 0xfc000003, 0xf8000002, 0x0, // Store Quadword DS-form (stq RSp,DS(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}}, + {LHBRX, 0xfc0007fe, 0x7c00062c, 0x1, // Load Halfword Byte-Reverse Indexed X-form (lhbrx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LWBRX, 0xfc0007fe, 0x7c00042c, 0x1, // Load Word Byte-Reverse Indexed X-form (lwbrx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STHBRX, 0xfc0007fe, 0x7c00072c, 0x1, // Store Halfword Byte-Reverse Indexed X-form (sthbrx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STWBRX, 0xfc0007fe, 0x7c00052c, 0x1, // Store Word Byte-Reverse Indexed X-form (stwbrx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LDBRX, 0xfc0007fe, 0x7c000428, 0x1, // Load Doubleword Byte-Reverse Indexed X-form (ldbrx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STDBRX, 0xfc0007fe, 0x7c000528, 0x1, // Store Doubleword Byte-Reverse Indexed X-form (stdbrx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LMW, 0xfc000000, 0xb8000000, 0x0, // Load Multiple Word D-form (lmw RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {STMW, 0xfc000000, 0xbc000000, 0x0, // Store Multiple Word D-form (stmw RS,D(RA)) + [5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {LSWI, 0xfc0007fe, 0x7c0004aa, 0x1, // Load String Word Immediate X-form (lswi RT,RA,NB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}}, + {LSWX, 0xfc0007fe, 0x7c00042a, 0x1, // Load String Word Indexed X-form (lswx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STSWI, 0xfc0007fe, 0x7c0005aa, 0x1, // Store String Word Immediate X-form (stswi RS,RA,NB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}}, + {STSWX, 0xfc0007fe, 0x7c00052a, 0x1, // Store String Word Indexed X-form (stswx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LI, 0xfc1f0000, 0x38000000, 0x0, // Add Immediate D-form (li RT,SI) + [5]*argField{ap_Reg_6_10, ap_ImmSigned_16_31}}, + {ADDI, 0xfc000000, 0x38000000, 0x0, // Add Immediate D-form (addi RT,RA,SI) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}}, + {LIS, 0xfc1f0000, 0x3c000000, 0x0, // Add Immediate Shifted D-form (lis RT, SI) + [5]*argField{ap_Reg_6_10, ap_ImmSigned_16_31}}, + {ADDIS, 0xfc000000, 0x3c000000, 0x0, // Add Immediate Shifted D-form (addis RT,RA,SI) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}}, + {ADD, 0xfc0007ff, 0x7c000214, 0x0, // Add XO-form (add RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ADDCC, 0xfc0007ff, 0x7c000215, 0x0, // Add XO-form (add. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ADDO, 0xfc0007ff, 0x7c000614, 0x0, // Add XO-form (addo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ADDOCC, 0xfc0007ff, 0x7c000615, 0x0, // Add XO-form (addo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ADDIC, 0xfc000000, 0x30000000, 0x0, // Add Immediate Carrying D-form (addic RT,RA,SI) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}}, + {SUBF, 0xfc0007ff, 0x7c000050, 0x0, // Subtract From XO-form (subf RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {SUBFCC, 0xfc0007ff, 0x7c000051, 0x0, // Subtract From XO-form (subf. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {SUBFO, 0xfc0007ff, 0x7c000450, 0x0, // Subtract From XO-form (subfo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {SUBFOCC, 0xfc0007ff, 0x7c000451, 0x0, // Subtract From XO-form (subfo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ADDICCC, 0xfc000000, 0x34000000, 0x0, // Add Immediate Carrying and Record D-form (addic. RT,RA,SI) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}}, + {SUBFIC, 0xfc000000, 0x20000000, 0x0, // Subtract From Immediate Carrying D-form (subfic RT,RA,SI) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}}, + {ADDC, 0xfc0007ff, 0x7c000014, 0x0, // Add Carrying XO-form (addc RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ADDCCC, 0xfc0007ff, 0x7c000015, 0x0, // Add Carrying XO-form (addc. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ADDCO, 0xfc0007ff, 0x7c000414, 0x0, // Add Carrying XO-form (addco RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ADDCOCC, 0xfc0007ff, 0x7c000415, 0x0, // Add Carrying XO-form (addco. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {SUBFC, 0xfc0007ff, 0x7c000010, 0x0, // Subtract From Carrying XO-form (subfc RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {SUBFCCC, 0xfc0007ff, 0x7c000011, 0x0, // Subtract From Carrying XO-form (subfc. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {SUBFCO, 0xfc0007ff, 0x7c000410, 0x0, // Subtract From Carrying XO-form (subfco RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {SUBFCOCC, 0xfc0007ff, 0x7c000411, 0x0, // Subtract From Carrying XO-form (subfco. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ADDE, 0xfc0007ff, 0x7c000114, 0x0, // Add Extended XO-form (adde RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ADDECC, 0xfc0007ff, 0x7c000115, 0x0, // Add Extended XO-form (adde. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ADDEO, 0xfc0007ff, 0x7c000514, 0x0, // Add Extended XO-form (addeo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ADDEOCC, 0xfc0007ff, 0x7c000515, 0x0, // Add Extended XO-form (addeo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ADDME, 0xfc0007ff, 0x7c0001d4, 0xf800, // Add to Minus One Extended XO-form (addme RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {ADDMECC, 0xfc0007ff, 0x7c0001d5, 0xf800, // Add to Minus One Extended XO-form (addme. RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {ADDMEO, 0xfc0007ff, 0x7c0005d4, 0xf800, // Add to Minus One Extended XO-form (addmeo RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {ADDMEOCC, 0xfc0007ff, 0x7c0005d5, 0xf800, // Add to Minus One Extended XO-form (addmeo. RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {SUBFE, 0xfc0007ff, 0x7c000110, 0x0, // Subtract From Extended XO-form (subfe RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {SUBFECC, 0xfc0007ff, 0x7c000111, 0x0, // Subtract From Extended XO-form (subfe. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {SUBFEO, 0xfc0007ff, 0x7c000510, 0x0, // Subtract From Extended XO-form (subfeo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {SUBFEOCC, 0xfc0007ff, 0x7c000511, 0x0, // Subtract From Extended XO-form (subfeo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {SUBFME, 0xfc0007ff, 0x7c0001d0, 0xf800, // Subtract From Minus One Extended XO-form (subfme RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {SUBFMECC, 0xfc0007ff, 0x7c0001d1, 0xf800, // Subtract From Minus One Extended XO-form (subfme. RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {SUBFMEO, 0xfc0007ff, 0x7c0005d0, 0xf800, // Subtract From Minus One Extended XO-form (subfmeo RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {SUBFMEOCC, 0xfc0007ff, 0x7c0005d1, 0xf800, // Subtract From Minus One Extended XO-form (subfmeo. RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {ADDZE, 0xfc0007ff, 0x7c000194, 0xf800, // Add to Zero Extended XO-form (addze RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {ADDZECC, 0xfc0007ff, 0x7c000195, 0xf800, // Add to Zero Extended XO-form (addze. RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {ADDZEO, 0xfc0007ff, 0x7c000594, 0xf800, // Add to Zero Extended XO-form (addzeo RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {ADDZEOCC, 0xfc0007ff, 0x7c000595, 0xf800, // Add to Zero Extended XO-form (addzeo. RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {SUBFZE, 0xfc0007ff, 0x7c000190, 0xf800, // Subtract From Zero Extended XO-form (subfze RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {SUBFZECC, 0xfc0007ff, 0x7c000191, 0xf800, // Subtract From Zero Extended XO-form (subfze. RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {SUBFZEO, 0xfc0007ff, 0x7c000590, 0xf800, // Subtract From Zero Extended XO-form (subfzeo RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {SUBFZEOCC, 0xfc0007ff, 0x7c000591, 0xf800, // Subtract From Zero Extended XO-form (subfzeo. RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {NEG, 0xfc0007ff, 0x7c0000d0, 0xf800, // Negate XO-form (neg RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {NEGCC, 0xfc0007ff, 0x7c0000d1, 0xf800, // Negate XO-form (neg. RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {NEGO, 0xfc0007ff, 0x7c0004d0, 0xf800, // Negate XO-form (nego RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {NEGOCC, 0xfc0007ff, 0x7c0004d1, 0xf800, // Negate XO-form (nego. RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {MULLI, 0xfc000000, 0x1c000000, 0x0, // Multiply Low Immediate D-form (mulli RT,RA,SI) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}}, + {MULLW, 0xfc0007ff, 0x7c0001d6, 0x0, // Multiply Low Word XO-form (mullw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULLWCC, 0xfc0007ff, 0x7c0001d7, 0x0, // Multiply Low Word XO-form (mullw. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULLWO, 0xfc0007ff, 0x7c0005d6, 0x0, // Multiply Low Word XO-form (mullwo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULLWOCC, 0xfc0007ff, 0x7c0005d7, 0x0, // Multiply Low Word XO-form (mullwo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULHW, 0xfc0003ff, 0x7c000096, 0x400, // Multiply High Word XO-form (mulhw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULHWCC, 0xfc0003ff, 0x7c000097, 0x400, // Multiply High Word XO-form (mulhw. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULHWU, 0xfc0003ff, 0x7c000016, 0x400, // Multiply High Word Unsigned XO-form (mulhwu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULHWUCC, 0xfc0003ff, 0x7c000017, 0x400, // Multiply High Word Unsigned XO-form (mulhwu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVW, 0xfc0007ff, 0x7c0003d6, 0x0, // Divide Word XO-form (divw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWCC, 0xfc0007ff, 0x7c0003d7, 0x0, // Divide Word XO-form (divw. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWO, 0xfc0007ff, 0x7c0007d6, 0x0, // Divide Word XO-form (divwo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWOCC, 0xfc0007ff, 0x7c0007d7, 0x0, // Divide Word XO-form (divwo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWU, 0xfc0007ff, 0x7c000396, 0x0, // Divide Word Unsigned XO-form (divwu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWUCC, 0xfc0007ff, 0x7c000397, 0x0, // Divide Word Unsigned XO-form (divwu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWUO, 0xfc0007ff, 0x7c000796, 0x0, // Divide Word Unsigned XO-form (divwuo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWUOCC, 0xfc0007ff, 0x7c000797, 0x0, // Divide Word Unsigned XO-form (divwuo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWE, 0xfc0007ff, 0x7c000356, 0x0, // Divide Word Extended XO-form (divwe RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWECC, 0xfc0007ff, 0x7c000357, 0x0, // Divide Word Extended XO-form (divwe. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWEO, 0xfc0007ff, 0x7c000756, 0x0, // Divide Word Extended XO-form (divweo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWEOCC, 0xfc0007ff, 0x7c000757, 0x0, // Divide Word Extended XO-form (divweo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWEU, 0xfc0007ff, 0x7c000316, 0x0, // Divide Word Extended Unsigned XO-form (divweu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWEUCC, 0xfc0007ff, 0x7c000317, 0x0, // Divide Word Extended Unsigned XO-form (divweu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWEUO, 0xfc0007ff, 0x7c000716, 0x0, // Divide Word Extended Unsigned XO-form (divweuo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVWEUOCC, 0xfc0007ff, 0x7c000717, 0x0, // Divide Word Extended Unsigned XO-form (divweuo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULLD, 0xfc0007ff, 0x7c0001d2, 0x0, // Multiply Low Doubleword XO-form (mulld RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULLDCC, 0xfc0007ff, 0x7c0001d3, 0x0, // Multiply Low Doubleword XO-form (mulld. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULLDO, 0xfc0007ff, 0x7c0005d2, 0x0, // Multiply Low Doubleword XO-form (mulldo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULLDOCC, 0xfc0007ff, 0x7c0005d3, 0x0, // Multiply Low Doubleword XO-form (mulldo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULHDU, 0xfc0003ff, 0x7c000012, 0x400, // Multiply High Doubleword Unsigned XO-form (mulhdu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULHDUCC, 0xfc0003ff, 0x7c000013, 0x400, // Multiply High Doubleword Unsigned XO-form (mulhdu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULHD, 0xfc0003ff, 0x7c000092, 0x400, // Multiply High Doubleword XO-form (mulhd RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULHDCC, 0xfc0003ff, 0x7c000093, 0x400, // Multiply High Doubleword XO-form (mulhd. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVD, 0xfc0007ff, 0x7c0003d2, 0x0, // Divide Doubleword XO-form (divd RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDCC, 0xfc0007ff, 0x7c0003d3, 0x0, // Divide Doubleword XO-form (divd. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDO, 0xfc0007ff, 0x7c0007d2, 0x0, // Divide Doubleword XO-form (divdo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDOCC, 0xfc0007ff, 0x7c0007d3, 0x0, // Divide Doubleword XO-form (divdo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDU, 0xfc0007ff, 0x7c000392, 0x0, // Divide Doubleword Unsigned XO-form (divdu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDUCC, 0xfc0007ff, 0x7c000393, 0x0, // Divide Doubleword Unsigned XO-form (divdu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDUO, 0xfc0007ff, 0x7c000792, 0x0, // Divide Doubleword Unsigned XO-form (divduo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDUOCC, 0xfc0007ff, 0x7c000793, 0x0, // Divide Doubleword Unsigned XO-form (divduo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDE, 0xfc0007ff, 0x7c000352, 0x0, // Divide Doubleword Extended XO-form (divde RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDECC, 0xfc0007ff, 0x7c000353, 0x0, // Divide Doubleword Extended XO-form (divde. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDEO, 0xfc0007ff, 0x7c000752, 0x0, // Divide Doubleword Extended XO-form (divdeo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDEOCC, 0xfc0007ff, 0x7c000753, 0x0, // Divide Doubleword Extended XO-form (divdeo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDEU, 0xfc0007ff, 0x7c000312, 0x0, // Divide Doubleword Extended Unsigned XO-form (divdeu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDEUCC, 0xfc0007ff, 0x7c000313, 0x0, // Divide Doubleword Extended Unsigned XO-form (divdeu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDEUO, 0xfc0007ff, 0x7c000712, 0x0, // Divide Doubleword Extended Unsigned XO-form (divdeuo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DIVDEUOCC, 0xfc0007ff, 0x7c000713, 0x0, // Divide Doubleword Extended Unsigned XO-form (divdeuo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {CMPWI, 0xfc200000, 0x2c000000, 0x400000, // Compare Immediate D-form (cmpwi BF,RA,SI) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_ImmSigned_16_31}}, + {CMPDI, 0xfc200000, 0x2c200000, 0x400000, // Compare Immediate D-form (cmpdi BF,RA,SI) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_ImmSigned_16_31}}, + {CMPW, 0xfc2007fe, 0x7c000000, 0x400001, // Compare X-form (cmpw BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {CMPD, 0xfc2007fe, 0x7c200000, 0x400001, // Compare X-form (cmpd BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {CMPLWI, 0xfc200000, 0x28000000, 0x400000, // Compare Logical Immediate D-form (cmplwi BF,RA,UI) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_ImmUnsigned_16_31}}, + {CMPLDI, 0xfc200000, 0x28200000, 0x400000, // Compare Logical Immediate D-form (cmpldi BF,RA,UI) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_ImmUnsigned_16_31}}, + {CMPLW, 0xfc2007fe, 0x7c000040, 0x400001, // Compare Logical X-form (cmplw BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {CMPLD, 0xfc2007fe, 0x7c200040, 0x400001, // Compare Logical X-form (cmpld BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {TWI, 0xfc000000, 0xc000000, 0x0, // Trap Word Immediate D-form (twi TO,RA,SI) + [5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}}, + {TW, 0xfc0007fe, 0x7c000008, 0x1, // Trap Word X-form (tw TO,RA,RB) + [5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {TDI, 0xfc000000, 0x8000000, 0x0, // Trap Doubleword Immediate D-form (tdi TO,RA,SI) + [5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}}, + {ISEL, 0xfc00003e, 0x7c00001e, 0x1, // Integer Select A-form (isel RT,RA,RB,BC) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_CondRegBit_21_25}}, + {TD, 0xfc0007fe, 0x7c000088, 0x1, // Trap Doubleword X-form (td TO,RA,RB) + [5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ANDICC, 0xfc000000, 0x70000000, 0x0, // AND Immediate D-form (andi. RA,RS,UI) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}}, + {ANDISCC, 0xfc000000, 0x74000000, 0x0, // AND Immediate Shifted D-form (andis. RA,RS,UI) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}}, + {ORI, 0xfc000000, 0x60000000, 0x0, // OR Immediate D-form (ori RA,RS,UI) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}}, + {ORIS, 0xfc000000, 0x64000000, 0x0, // OR Immediate Shifted D-form (oris RA,RS,UI) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}}, + {XORI, 0xfc000000, 0x68000000, 0x0, // XOR Immediate D-form (xori RA,RS,UI) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}}, + {XORIS, 0xfc000000, 0x6c000000, 0x0, // XOR Immediate Shifted D-form (xoris RA,RS,UI) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}}, + {AND, 0xfc0007ff, 0x7c000038, 0x0, // AND X-form (and RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {ANDCC, 0xfc0007ff, 0x7c000039, 0x0, // AND X-form (and. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {XOR, 0xfc0007ff, 0x7c000278, 0x0, // XOR X-form (xor RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {XORCC, 0xfc0007ff, 0x7c000279, 0x0, // XOR X-form (xor. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {NAND, 0xfc0007ff, 0x7c0003b8, 0x0, // NAND X-form (nand RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {NANDCC, 0xfc0007ff, 0x7c0003b9, 0x0, // NAND X-form (nand. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {OR, 0xfc0007ff, 0x7c000378, 0x0, // OR X-form (or RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {ORCC, 0xfc0007ff, 0x7c000379, 0x0, // OR X-form (or. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {NOR, 0xfc0007ff, 0x7c0000f8, 0x0, // NOR X-form (nor RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {NORCC, 0xfc0007ff, 0x7c0000f9, 0x0, // NOR X-form (nor. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {ANDC, 0xfc0007ff, 0x7c000078, 0x0, // AND with Complement X-form (andc RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {ANDCCC, 0xfc0007ff, 0x7c000079, 0x0, // AND with Complement X-form (andc. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {EXTSB, 0xfc0007ff, 0x7c000774, 0xf800, // Extend Sign Byte X-form (extsb RA,RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {EXTSBCC, 0xfc0007ff, 0x7c000775, 0xf800, // Extend Sign Byte X-form (extsb. RA,RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {EQV, 0xfc0007ff, 0x7c000238, 0x0, // Equivalent X-form (eqv RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {EQVCC, 0xfc0007ff, 0x7c000239, 0x0, // Equivalent X-form (eqv. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {ORC, 0xfc0007ff, 0x7c000338, 0x0, // OR with Complement X-form (orc RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {ORCCC, 0xfc0007ff, 0x7c000339, 0x0, // OR with Complement X-form (orc. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {EXTSH, 0xfc0007ff, 0x7c000734, 0xf800, // Extend Sign Halfword X-form (extsh RA,RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {EXTSHCC, 0xfc0007ff, 0x7c000735, 0xf800, // Extend Sign Halfword X-form (extsh. RA,RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {CMPB, 0xfc0007fe, 0x7c0003f8, 0x1, // Compare Bytes X-form (cmpb RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {POPCNTB, 0xfc0007fe, 0x7c0000f4, 0xf801, // Population Count Bytes X-form (popcntb RA, RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {POPCNTW, 0xfc0007fe, 0x7c0002f4, 0xf801, // Population Count Words X-form (popcntw RA, RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {PRTYD, 0xfc0007fe, 0x7c000174, 0xf801, // Parity Doubleword X-form (prtyd RA,RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {PRTYW, 0xfc0007fe, 0x7c000134, 0xf801, // Parity Word X-form (prtyw RA,RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {EXTSW, 0xfc0007ff, 0x7c0007b4, 0xf800, // Extend Sign Word X-form (extsw RA,RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {EXTSWCC, 0xfc0007ff, 0x7c0007b5, 0xf800, // Extend Sign Word X-form (extsw. RA,RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {CNTLZD, 0xfc0007ff, 0x7c000074, 0xf800, // Count Leading Zeros Doubleword X-form (cntlzd RA,RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {CNTLZDCC, 0xfc0007ff, 0x7c000075, 0xf800, // Count Leading Zeros Doubleword X-form (cntlzd. RA,RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {POPCNTD, 0xfc0007fe, 0x7c0003f4, 0xf801, // Population Count Doubleword X-form (popcntd RA, RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {BPERMD, 0xfc0007fe, 0x7c0001f8, 0x1, // Bit Permute Doubleword X-form (bpermd RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {RLWINM, 0xfc000001, 0x54000000, 0x0, // Rotate Left Word Immediate then AND with Mask M-form (rlwinm RA,RS,SH,MB,ME) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}}, + {RLWINMCC, 0xfc000001, 0x54000001, 0x0, // Rotate Left Word Immediate then AND with Mask M-form (rlwinm. RA,RS,SH,MB,ME) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}}, + {RLWNM, 0xfc000001, 0x5c000000, 0x0, // Rotate Left Word then AND with Mask M-form (rlwnm RA,RS,RB,MB,ME) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}}, + {RLWNMCC, 0xfc000001, 0x5c000001, 0x0, // Rotate Left Word then AND with Mask M-form (rlwnm. RA,RS,RB,MB,ME) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}}, + {RLWIMI, 0xfc000001, 0x50000000, 0x0, // Rotate Left Word Immediate then Mask Insert M-form (rlwimi RA,RS,SH,MB,ME) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}}, + {RLWIMICC, 0xfc000001, 0x50000001, 0x0, // Rotate Left Word Immediate then Mask Insert M-form (rlwimi. RA,RS,SH,MB,ME) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}}, + {RLDICL, 0xfc00001d, 0x78000000, 0x0, // Rotate Left Doubleword Immediate then Clear Left MD-form (rldicl RA,RS,SH,MB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}}, + {RLDICLCC, 0xfc00001d, 0x78000001, 0x0, // Rotate Left Doubleword Immediate then Clear Left MD-form (rldicl. RA,RS,SH,MB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}}, + {RLDICR, 0xfc00001d, 0x78000004, 0x0, // Rotate Left Doubleword Immediate then Clear Right MD-form (rldicr RA,RS,SH,ME) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}}, + {RLDICRCC, 0xfc00001d, 0x78000005, 0x0, // Rotate Left Doubleword Immediate then Clear Right MD-form (rldicr. RA,RS,SH,ME) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}}, + {RLDIC, 0xfc00001d, 0x78000008, 0x0, // Rotate Left Doubleword Immediate then Clear MD-form (rldic RA,RS,SH,MB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}}, + {RLDICCC, 0xfc00001d, 0x78000009, 0x0, // Rotate Left Doubleword Immediate then Clear MD-form (rldic. RA,RS,SH,MB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}}, + {RLDCL, 0xfc00001f, 0x78000010, 0x0, // Rotate Left Doubleword then Clear Left MDS-form (rldcl RA,RS,RB,MB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_26_26_21_25}}, + {RLDCLCC, 0xfc00001f, 0x78000011, 0x0, // Rotate Left Doubleword then Clear Left MDS-form (rldcl. RA,RS,RB,MB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_26_26_21_25}}, + {RLDCR, 0xfc00001f, 0x78000012, 0x0, // Rotate Left Doubleword then Clear Right MDS-form (rldcr RA,RS,RB,ME) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_26_26_21_25}}, + {RLDCRCC, 0xfc00001f, 0x78000013, 0x0, // Rotate Left Doubleword then Clear Right MDS-form (rldcr. RA,RS,RB,ME) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_26_26_21_25}}, + {RLDIMI, 0xfc00001d, 0x7800000c, 0x0, // Rotate Left Doubleword Immediate then Mask Insert MD-form (rldimi RA,RS,SH,MB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}}, + {RLDIMICC, 0xfc00001d, 0x7800000d, 0x0, // Rotate Left Doubleword Immediate then Mask Insert MD-form (rldimi. RA,RS,SH,MB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}}, + {SLW, 0xfc0007ff, 0x7c000030, 0x0, // Shift Left Word X-form (slw RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {SLWCC, 0xfc0007ff, 0x7c000031, 0x0, // Shift Left Word X-form (slw. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {SRW, 0xfc0007ff, 0x7c000430, 0x0, // Shift Right Word X-form (srw RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {SRWCC, 0xfc0007ff, 0x7c000431, 0x0, // Shift Right Word X-form (srw. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {SRAWI, 0xfc0007ff, 0x7c000670, 0x0, // Shift Right Algebraic Word Immediate X-form (srawi RA,RS,SH) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20}}, + {SRAWICC, 0xfc0007ff, 0x7c000671, 0x0, // Shift Right Algebraic Word Immediate X-form (srawi. RA,RS,SH) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20}}, + {SRAW, 0xfc0007ff, 0x7c000630, 0x0, // Shift Right Algebraic Word X-form (sraw RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {SRAWCC, 0xfc0007ff, 0x7c000631, 0x0, // Shift Right Algebraic Word X-form (sraw. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {SLD, 0xfc0007ff, 0x7c000036, 0x0, // Shift Left Doubleword X-form (sld RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {SLDCC, 0xfc0007ff, 0x7c000037, 0x0, // Shift Left Doubleword X-form (sld. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {SRD, 0xfc0007ff, 0x7c000436, 0x0, // Shift Right Doubleword X-form (srd RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {SRDCC, 0xfc0007ff, 0x7c000437, 0x0, // Shift Right Doubleword X-form (srd. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {SRADI, 0xfc0007fd, 0x7c000674, 0x0, // Shift Right Algebraic Doubleword Immediate XS-form (sradi RA,RS,SH) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20}}, + {SRADICC, 0xfc0007fd, 0x7c000675, 0x0, // Shift Right Algebraic Doubleword Immediate XS-form (sradi. RA,RS,SH) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20}}, + {SRAD, 0xfc0007ff, 0x7c000634, 0x0, // Shift Right Algebraic Doubleword X-form (srad RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {SRADCC, 0xfc0007ff, 0x7c000635, 0x0, // Shift Right Algebraic Doubleword X-form (srad. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {CDTBCD, 0xfc0007fe, 0x7c000234, 0xf801, // Convert Declets To Binary Coded Decimal X-form (cdtbcd RA, RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {CBCDTD, 0xfc0007fe, 0x7c000274, 0xf801, // Convert Binary Coded Decimal To Declets X-form (cbcdtd RA, RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {ADDG6S, 0xfc0003fe, 0x7c000094, 0x401, // Add and Generate Sixes XO-form (addg6s RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MTSPR, 0xfc0007fe, 0x7c0003a6, 0x1, // Move To Special Purpose Register XFX-form (mtspr SPR,RS) + [5]*argField{ap_SpReg_16_20_11_15, ap_Reg_6_10}}, + {MFSPR, 0xfc0007fe, 0x7c0002a6, 0x1, // Move From Special Purpose Register XFX-form (mfspr RT,SPR) + [5]*argField{ap_Reg_6_10, ap_SpReg_16_20_11_15}}, + {MTCRF, 0xfc1007fe, 0x7c000120, 0x801, // Move To Condition Register Fields XFX-form (mtcrf FXM,RS) + [5]*argField{ap_ImmUnsigned_12_19, ap_Reg_6_10}}, + {MFCR, 0xfc1007fe, 0x7c000026, 0xff801, // Move From Condition Register XFX-form (mfcr RT) + [5]*argField{ap_Reg_6_10}}, + {MTSLE, 0xfc0007fe, 0x7c000126, 0x3dff801, // Move To Split Little Endian X-form (mtsle L) + [5]*argField{ap_ImmUnsigned_10_10}}, + {MFVSRD, 0xfc0007fe, 0x7c000066, 0xf800, // Move From VSR Doubleword XX1-form (mfvsrd RA,XS) + [5]*argField{ap_Reg_11_15, ap_VecSReg_31_31_6_10}}, + {MFVSRWZ, 0xfc0007fe, 0x7c0000e6, 0xf800, // Move From VSR Word and Zero XX1-form (mfvsrwz RA,XS) + [5]*argField{ap_Reg_11_15, ap_VecSReg_31_31_6_10}}, + {MTVSRD, 0xfc0007fe, 0x7c000166, 0xf800, // Move To VSR Doubleword XX1-form (mtvsrd XT,RA) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}}, + {MTVSRWA, 0xfc0007fe, 0x7c0001a6, 0xf800, // Move To VSR Word Algebraic XX1-form (mtvsrwa XT,RA) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}}, + {MTVSRWZ, 0xfc0007fe, 0x7c0001e6, 0xf800, // Move To VSR Word and Zero XX1-form (mtvsrwz XT,RA) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}}, + {MTOCRF, 0xfc1007fe, 0x7c100120, 0x801, // Move To One Condition Register Field XFX-form (mtocrf FXM,RS) + [5]*argField{ap_ImmUnsigned_12_19, ap_Reg_6_10}}, + {MFOCRF, 0xfc1007fe, 0x7c100026, 0x801, // Move From One Condition Register Field XFX-form (mfocrf RT,FXM) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_12_19}}, + {MCRXR, 0xfc0007fe, 0x7c000400, 0x7ff801, // Move to Condition Register from XER X-form (mcrxr BF) + [5]*argField{ap_CondRegField_6_8}}, + {MTDCRUX, 0xfc0007fe, 0x7c000346, 0xf801, // Move To Device Control Register User-mode Indexed X-form (mtdcrux RS,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {MFDCRUX, 0xfc0007fe, 0x7c000246, 0xf801, // Move From Device Control Register User-mode Indexed X-form (mfdcrux RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {LFS, 0xfc000000, 0xc0000000, 0x0, // Load Floating-Point Single D-form (lfs FRT,D(RA)) + [5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {LFSU, 0xfc000000, 0xc4000000, 0x0, // Load Floating-Point Single with Update D-form (lfsu FRT,D(RA)) + [5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {LFSX, 0xfc0007fe, 0x7c00042e, 0x1, // Load Floating-Point Single Indexed X-form (lfsx FRT,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LFSUX, 0xfc0007fe, 0x7c00046e, 0x1, // Load Floating-Point Single with Update Indexed X-form (lfsux FRT,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LFD, 0xfc000000, 0xc8000000, 0x0, // Load Floating-Point Double D-form (lfd FRT,D(RA)) + [5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {LFDU, 0xfc000000, 0xcc000000, 0x0, // Load Floating-Point Double with Update D-form (lfdu FRT,D(RA)) + [5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {LFDX, 0xfc0007fe, 0x7c0004ae, 0x1, // Load Floating-Point Double Indexed X-form (lfdx FRT,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LFDUX, 0xfc0007fe, 0x7c0004ee, 0x1, // Load Floating-Point Double with Update Indexed X-form (lfdux FRT,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LFIWAX, 0xfc0007fe, 0x7c0006ae, 0x1, // Load Floating-Point as Integer Word Algebraic Indexed X-form (lfiwax FRT,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LFIWZX, 0xfc0007fe, 0x7c0006ee, 0x1, // Load Floating-Point as Integer Word and Zero Indexed X-form (lfiwzx FRT,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STFS, 0xfc000000, 0xd0000000, 0x0, // Store Floating-Point Single D-form (stfs FRS,D(RA)) + [5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {STFSU, 0xfc000000, 0xd4000000, 0x0, // Store Floating-Point Single with Update D-form (stfsu FRS,D(RA)) + [5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {STFSX, 0xfc0007fe, 0x7c00052e, 0x1, // Store Floating-Point Single Indexed X-form (stfsx FRS,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STFSUX, 0xfc0007fe, 0x7c00056e, 0x1, // Store Floating-Point Single with Update Indexed X-form (stfsux FRS,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STFD, 0xfc000000, 0xd8000000, 0x0, // Store Floating-Point Double D-form (stfd FRS,D(RA)) + [5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {STFDU, 0xfc000000, 0xdc000000, 0x0, // Store Floating-Point Double with Update D-form (stfdu FRS,D(RA)) + [5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}}, + {STFDX, 0xfc0007fe, 0x7c0005ae, 0x1, // Store Floating-Point Double Indexed X-form (stfdx FRS,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STFDUX, 0xfc0007fe, 0x7c0005ee, 0x1, // Store Floating-Point Double with Update Indexed X-form (stfdux FRS,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STFIWX, 0xfc0007fe, 0x7c0007ae, 0x1, // Store Floating-Point as Integer Word Indexed X-form (stfiwx FRS,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LFDP, 0xfc000003, 0xe4000000, 0x0, // Load Floating-Point Double Pair DS-form (lfdp FRTp,DS(RA)) + [5]*argField{ap_FPReg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}}, + {LFDPX, 0xfc0007fe, 0x7c00062e, 0x1, // Load Floating-Point Double Pair Indexed X-form (lfdpx FRTp,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STFDP, 0xfc000003, 0xf4000000, 0x0, // Store Floating-Point Double Pair DS-form (stfdp FRSp,DS(RA)) + [5]*argField{ap_FPReg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}}, + {STFDPX, 0xfc0007fe, 0x7c00072e, 0x1, // Store Floating-Point Double Pair Indexed X-form (stfdpx FRSp,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {FMR, 0xfc0007ff, 0xfc000090, 0x1f0000, // Floating Move Register X-form (fmr FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FMRCC, 0xfc0007ff, 0xfc000091, 0x1f0000, // Floating Move Register X-form (fmr. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FABS, 0xfc0007ff, 0xfc000210, 0x1f0000, // Floating Absolute Value X-form (fabs FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FABSCC, 0xfc0007ff, 0xfc000211, 0x1f0000, // Floating Absolute Value X-form (fabs. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FNABS, 0xfc0007ff, 0xfc000110, 0x1f0000, // Floating Negative Absolute Value X-form (fnabs FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FNABSCC, 0xfc0007ff, 0xfc000111, 0x1f0000, // Floating Negative Absolute Value X-form (fnabs. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FNEG, 0xfc0007ff, 0xfc000050, 0x1f0000, // Floating Negate X-form (fneg FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FNEGCC, 0xfc0007ff, 0xfc000051, 0x1f0000, // Floating Negate X-form (fneg. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCPSGN, 0xfc0007ff, 0xfc000010, 0x0, // Floating Copy Sign X-form (fcpsgn FRT, FRA, FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FCPSGNCC, 0xfc0007ff, 0xfc000011, 0x0, // Floating Copy Sign X-form (fcpsgn. FRT, FRA, FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FMRGEW, 0xfc0007fe, 0xfc00078c, 0x1, // Floating Merge Even Word X-form (fmrgew FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FMRGOW, 0xfc0007fe, 0xfc00068c, 0x1, // Floating Merge Odd Word X-form (fmrgow FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FADD, 0xfc00003f, 0xfc00002a, 0x7c0, // Floating Add [Single] A-form (fadd FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FADDCC, 0xfc00003f, 0xfc00002b, 0x7c0, // Floating Add [Single] A-form (fadd. FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FADDS, 0xfc00003f, 0xec00002a, 0x7c0, // Floating Add [Single] A-form (fadds FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FADDSCC, 0xfc00003f, 0xec00002b, 0x7c0, // Floating Add [Single] A-form (fadds. FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FSUB, 0xfc00003f, 0xfc000028, 0x7c0, // Floating Subtract [Single] A-form (fsub FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FSUBCC, 0xfc00003f, 0xfc000029, 0x7c0, // Floating Subtract [Single] A-form (fsub. FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FSUBS, 0xfc00003f, 0xec000028, 0x7c0, // Floating Subtract [Single] A-form (fsubs FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FSUBSCC, 0xfc00003f, 0xec000029, 0x7c0, // Floating Subtract [Single] A-form (fsubs. FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FMUL, 0xfc00003f, 0xfc000032, 0xf800, // Floating Multiply [Single] A-form (fmul FRT,FRA,FRC) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25}}, + {FMULCC, 0xfc00003f, 0xfc000033, 0xf800, // Floating Multiply [Single] A-form (fmul. FRT,FRA,FRC) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25}}, + {FMULS, 0xfc00003f, 0xec000032, 0xf800, // Floating Multiply [Single] A-form (fmuls FRT,FRA,FRC) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25}}, + {FMULSCC, 0xfc00003f, 0xec000033, 0xf800, // Floating Multiply [Single] A-form (fmuls. FRT,FRA,FRC) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25}}, + {FDIV, 0xfc00003f, 0xfc000024, 0x7c0, // Floating Divide [Single] A-form (fdiv FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FDIVCC, 0xfc00003f, 0xfc000025, 0x7c0, // Floating Divide [Single] A-form (fdiv. FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FDIVS, 0xfc00003f, 0xec000024, 0x7c0, // Floating Divide [Single] A-form (fdivs FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FDIVSCC, 0xfc00003f, 0xec000025, 0x7c0, // Floating Divide [Single] A-form (fdivs. FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FSQRT, 0xfc00003f, 0xfc00002c, 0x1f07c0, // Floating Square Root [Single] A-form (fsqrt FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FSQRTCC, 0xfc00003f, 0xfc00002d, 0x1f07c0, // Floating Square Root [Single] A-form (fsqrt. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FSQRTS, 0xfc00003f, 0xec00002c, 0x1f07c0, // Floating Square Root [Single] A-form (fsqrts FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FSQRTSCC, 0xfc00003f, 0xec00002d, 0x1f07c0, // Floating Square Root [Single] A-form (fsqrts. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRE, 0xfc00003f, 0xfc000030, 0x1f07c0, // Floating Reciprocal Estimate [Single] A-form (fre FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRECC, 0xfc00003f, 0xfc000031, 0x1f07c0, // Floating Reciprocal Estimate [Single] A-form (fre. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRES, 0xfc00003f, 0xec000030, 0x1f07c0, // Floating Reciprocal Estimate [Single] A-form (fres FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRESCC, 0xfc00003f, 0xec000031, 0x1f07c0, // Floating Reciprocal Estimate [Single] A-form (fres. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRSQRTE, 0xfc00003f, 0xfc000034, 0x1f07c0, // Floating Reciprocal Square Root Estimate [Single] A-form (frsqrte FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRSQRTECC, 0xfc00003f, 0xfc000035, 0x1f07c0, // Floating Reciprocal Square Root Estimate [Single] A-form (frsqrte. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRSQRTES, 0xfc00003f, 0xec000034, 0x1f07c0, // Floating Reciprocal Square Root Estimate [Single] A-form (frsqrtes FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRSQRTESCC, 0xfc00003f, 0xec000035, 0x1f07c0, // Floating Reciprocal Square Root Estimate [Single] A-form (frsqrtes. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FTDIV, 0xfc0007fe, 0xfc000100, 0x600001, // Floating Test for software Divide X-form (ftdiv BF,FRA,FRB) + [5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FTSQRT, 0xfc0007fe, 0xfc000140, 0x7f0001, // Floating Test for software Square Root X-form (ftsqrt BF,FRB) + [5]*argField{ap_CondRegField_6_8, ap_FPReg_16_20}}, + {FMADD, 0xfc00003f, 0xfc00003a, 0x0, // Floating Multiply-Add [Single] A-form (fmadd FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FMADDCC, 0xfc00003f, 0xfc00003b, 0x0, // Floating Multiply-Add [Single] A-form (fmadd. FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FMADDS, 0xfc00003f, 0xec00003a, 0x0, // Floating Multiply-Add [Single] A-form (fmadds FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FMADDSCC, 0xfc00003f, 0xec00003b, 0x0, // Floating Multiply-Add [Single] A-form (fmadds. FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FMSUB, 0xfc00003f, 0xfc000038, 0x0, // Floating Multiply-Subtract [Single] A-form (fmsub FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FMSUBCC, 0xfc00003f, 0xfc000039, 0x0, // Floating Multiply-Subtract [Single] A-form (fmsub. FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FMSUBS, 0xfc00003f, 0xec000038, 0x0, // Floating Multiply-Subtract [Single] A-form (fmsubs FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FMSUBSCC, 0xfc00003f, 0xec000039, 0x0, // Floating Multiply-Subtract [Single] A-form (fmsubs. FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FNMADD, 0xfc00003f, 0xfc00003e, 0x0, // Floating Negative Multiply-Add [Single] A-form (fnmadd FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FNMADDCC, 0xfc00003f, 0xfc00003f, 0x0, // Floating Negative Multiply-Add [Single] A-form (fnmadd. FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FNMADDS, 0xfc00003f, 0xec00003e, 0x0, // Floating Negative Multiply-Add [Single] A-form (fnmadds FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FNMADDSCC, 0xfc00003f, 0xec00003f, 0x0, // Floating Negative Multiply-Add [Single] A-form (fnmadds. FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FNMSUB, 0xfc00003f, 0xfc00003c, 0x0, // Floating Negative Multiply-Subtract [Single] A-form (fnmsub FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FNMSUBCC, 0xfc00003f, 0xfc00003d, 0x0, // Floating Negative Multiply-Subtract [Single] A-form (fnmsub. FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FNMSUBS, 0xfc00003f, 0xec00003c, 0x0, // Floating Negative Multiply-Subtract [Single] A-form (fnmsubs FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FNMSUBSCC, 0xfc00003f, 0xec00003d, 0x0, // Floating Negative Multiply-Subtract [Single] A-form (fnmsubs. FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FRSP, 0xfc0007ff, 0xfc000018, 0x1f0000, // Floating Round to Single-Precision X-form (frsp FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRSPCC, 0xfc0007ff, 0xfc000019, 0x1f0000, // Floating Round to Single-Precision X-form (frsp. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTID, 0xfc0007ff, 0xfc00065c, 0x1f0000, // Floating Convert To Integer Doubleword X-form (fctid FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIDCC, 0xfc0007ff, 0xfc00065d, 0x1f0000, // Floating Convert To Integer Doubleword X-form (fctid. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIDZ, 0xfc0007ff, 0xfc00065e, 0x1f0000, // Floating Convert To Integer Doubleword with round toward Zero X-form (fctidz FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIDZCC, 0xfc0007ff, 0xfc00065f, 0x1f0000, // Floating Convert To Integer Doubleword with round toward Zero X-form (fctidz. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIDU, 0xfc0007ff, 0xfc00075c, 0x1f0000, // Floating Convert To Integer Doubleword Unsigned X-form (fctidu FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIDUCC, 0xfc0007ff, 0xfc00075d, 0x1f0000, // Floating Convert To Integer Doubleword Unsigned X-form (fctidu. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIDUZ, 0xfc0007ff, 0xfc00075e, 0x1f0000, // Floating Convert To Integer Doubleword Unsigned with round toward Zero X-form (fctiduz FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIDUZCC, 0xfc0007ff, 0xfc00075f, 0x1f0000, // Floating Convert To Integer Doubleword Unsigned with round toward Zero X-form (fctiduz. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIW, 0xfc0007ff, 0xfc00001c, 0x1f0000, // Floating Convert To Integer Word X-form (fctiw FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIWCC, 0xfc0007ff, 0xfc00001d, 0x1f0000, // Floating Convert To Integer Word X-form (fctiw. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIWZ, 0xfc0007ff, 0xfc00001e, 0x1f0000, // Floating Convert To Integer Word with round toward Zero X-form (fctiwz FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIWZCC, 0xfc0007ff, 0xfc00001f, 0x1f0000, // Floating Convert To Integer Word with round toward Zero X-form (fctiwz. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIWU, 0xfc0007ff, 0xfc00011c, 0x1f0000, // Floating Convert To Integer Word Unsigned X-form (fctiwu FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIWUCC, 0xfc0007ff, 0xfc00011d, 0x1f0000, // Floating Convert To Integer Word Unsigned X-form (fctiwu. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIWUZ, 0xfc0007ff, 0xfc00011e, 0x1f0000, // Floating Convert To Integer Word Unsigned with round toward Zero X-form (fctiwuz FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCTIWUZCC, 0xfc0007ff, 0xfc00011f, 0x1f0000, // Floating Convert To Integer Word Unsigned with round toward Zero X-form (fctiwuz. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCFID, 0xfc0007ff, 0xfc00069c, 0x1f0000, // Floating Convert From Integer Doubleword X-form (fcfid FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCFIDCC, 0xfc0007ff, 0xfc00069d, 0x1f0000, // Floating Convert From Integer Doubleword X-form (fcfid. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCFIDU, 0xfc0007ff, 0xfc00079c, 0x1f0000, // Floating Convert From Integer Doubleword Unsigned X-form (fcfidu FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCFIDUCC, 0xfc0007ff, 0xfc00079d, 0x1f0000, // Floating Convert From Integer Doubleword Unsigned X-form (fcfidu. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCFIDS, 0xfc0007ff, 0xec00069c, 0x1f0000, // Floating Convert From Integer Doubleword Single X-form (fcfids FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCFIDSCC, 0xfc0007ff, 0xec00069d, 0x1f0000, // Floating Convert From Integer Doubleword Single X-form (fcfids. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCFIDUS, 0xfc0007ff, 0xec00079c, 0x1f0000, // Floating Convert From Integer Doubleword Unsigned Single X-form (fcfidus FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCFIDUSCC, 0xfc0007ff, 0xec00079d, 0x1f0000, // Floating Convert From Integer Doubleword Unsigned Single X-form (fcfidus. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRIN, 0xfc0007ff, 0xfc000310, 0x1f0000, // Floating Round to Integer Nearest X-form (frin FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRINCC, 0xfc0007ff, 0xfc000311, 0x1f0000, // Floating Round to Integer Nearest X-form (frin. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRIZ, 0xfc0007ff, 0xfc000350, 0x1f0000, // Floating Round to Integer Toward Zero X-form (friz FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRIZCC, 0xfc0007ff, 0xfc000351, 0x1f0000, // Floating Round to Integer Toward Zero X-form (friz. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRIP, 0xfc0007ff, 0xfc000390, 0x1f0000, // Floating Round to Integer Plus X-form (frip FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRIPCC, 0xfc0007ff, 0xfc000391, 0x1f0000, // Floating Round to Integer Plus X-form (frip. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRIM, 0xfc0007ff, 0xfc0003d0, 0x1f0000, // Floating Round to Integer Minus X-form (frim FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FRIMCC, 0xfc0007ff, 0xfc0003d1, 0x1f0000, // Floating Round to Integer Minus X-form (frim. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {FCMPU, 0xfc0007fe, 0xfc000000, 0x600001, // Floating Compare Unordered X-form (fcmpu BF,FRA,FRB) + [5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FCMPO, 0xfc0007fe, 0xfc000040, 0x600001, // Floating Compare Ordered X-form (fcmpo BF,FRA,FRB) + [5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}}, + {FSEL, 0xfc00003f, 0xfc00002e, 0x0, // Floating Select A-form (fsel FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {FSELCC, 0xfc00003f, 0xfc00002f, 0x0, // Floating Select A-form (fsel. FRT,FRA,FRC,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}}, + {MFFS, 0xfc0007ff, 0xfc00048e, 0x1ff800, // Move From FPSCR X-form (mffs FRT) + [5]*argField{ap_FPReg_6_10}}, + {MFFSCC, 0xfc0007ff, 0xfc00048f, 0x1ff800, // Move From FPSCR X-form (mffs. FRT) + [5]*argField{ap_FPReg_6_10}}, + {MCRFS, 0xfc0007fe, 0xfc000080, 0x63f801, // Move to Condition Register from FPSCR X-form (mcrfs BF,BFA) + [5]*argField{ap_CondRegField_6_8, ap_CondRegField_11_13}}, + {MTFSFI, 0xfc0007ff, 0xfc00010c, 0x7e0800, // Move To FPSCR Field Immediate X-form (mtfsfi BF,U,W) + [5]*argField{ap_CondRegField_6_8, ap_ImmUnsigned_16_19, ap_ImmUnsigned_15_15}}, + {MTFSFICC, 0xfc0007ff, 0xfc00010d, 0x7e0800, // Move To FPSCR Field Immediate X-form (mtfsfi. BF,U,W) + [5]*argField{ap_CondRegField_6_8, ap_ImmUnsigned_16_19, ap_ImmUnsigned_15_15}}, + {MTFSF, 0xfc0007ff, 0xfc00058e, 0x0, // Move To FPSCR Fields XFL-form (mtfsf FLM,FRB,L,W) + [5]*argField{ap_ImmUnsigned_7_14, ap_FPReg_16_20, ap_ImmUnsigned_6_6, ap_ImmUnsigned_15_15}}, + {MTFSFCC, 0xfc0007ff, 0xfc00058f, 0x0, // Move To FPSCR Fields XFL-form (mtfsf. FLM,FRB,L,W) + [5]*argField{ap_ImmUnsigned_7_14, ap_FPReg_16_20, ap_ImmUnsigned_6_6, ap_ImmUnsigned_15_15}}, + {MTFSB0, 0xfc0007ff, 0xfc00008c, 0x1ff800, // Move To FPSCR Bit 0 X-form (mtfsb0 BT) + [5]*argField{ap_CondRegBit_6_10}}, + {MTFSB0CC, 0xfc0007ff, 0xfc00008d, 0x1ff800, // Move To FPSCR Bit 0 X-form (mtfsb0. BT) + [5]*argField{ap_CondRegBit_6_10}}, + {MTFSB1, 0xfc0007ff, 0xfc00004c, 0x1ff800, // Move To FPSCR Bit 1 X-form (mtfsb1 BT) + [5]*argField{ap_CondRegBit_6_10}}, + {MTFSB1CC, 0xfc0007ff, 0xfc00004d, 0x1ff800, // Move To FPSCR Bit 1 X-form (mtfsb1. BT) + [5]*argField{ap_CondRegBit_6_10}}, + {LVEBX, 0xfc0007fe, 0x7c00000e, 0x1, // Load Vector Element Byte Indexed X-form (lvebx VRT,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LVEHX, 0xfc0007fe, 0x7c00004e, 0x1, // Load Vector Element Halfword Indexed X-form (lvehx VRT,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LVEWX, 0xfc0007fe, 0x7c00008e, 0x1, // Load Vector Element Word Indexed X-form (lvewx VRT,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LVX, 0xfc0007fe, 0x7c0000ce, 0x1, // Load Vector Indexed X-form (lvx VRT,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LVXL, 0xfc0007fe, 0x7c0002ce, 0x1, // Load Vector Indexed LRU X-form (lvxl VRT,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STVEBX, 0xfc0007fe, 0x7c00010e, 0x1, // Store Vector Element Byte Indexed X-form (stvebx VRS,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STVEHX, 0xfc0007fe, 0x7c00014e, 0x1, // Store Vector Element Halfword Indexed X-form (stvehx VRS,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STVEWX, 0xfc0007fe, 0x7c00018e, 0x1, // Store Vector Element Word Indexed X-form (stvewx VRS,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STVX, 0xfc0007fe, 0x7c0001ce, 0x1, // Store Vector Indexed X-form (stvx VRS,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STVXL, 0xfc0007fe, 0x7c0003ce, 0x1, // Store Vector Indexed LRU X-form (stvxl VRS,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LVSL, 0xfc0007fe, 0x7c00000c, 0x1, // Load Vector for Shift Left Indexed X-form (lvsl VRT,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LVSR, 0xfc0007fe, 0x7c00004c, 0x1, // Load Vector for Shift Right Indexed X-form (lvsr VRT,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {VPKPX, 0xfc0007ff, 0x1000030e, 0x0, // Vector Pack Pixel VX-form (vpkpx VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPKSDSS, 0xfc0007ff, 0x100005ce, 0x0, // Vector Pack Signed Doubleword Signed Saturate VX-form (vpksdss VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPKSDUS, 0xfc0007ff, 0x1000054e, 0x0, // Vector Pack Signed Doubleword Unsigned Saturate VX-form (vpksdus VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPKSHSS, 0xfc0007ff, 0x1000018e, 0x0, // Vector Pack Signed Halfword Signed Saturate VX-form (vpkshss VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPKSHUS, 0xfc0007ff, 0x1000010e, 0x0, // Vector Pack Signed Halfword Unsigned Saturate VX-form (vpkshus VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPKSWSS, 0xfc0007ff, 0x100001ce, 0x0, // Vector Pack Signed Word Signed Saturate VX-form (vpkswss VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPKSWUS, 0xfc0007ff, 0x1000014e, 0x0, // Vector Pack Signed Word Unsigned Saturate VX-form (vpkswus VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPKUDUM, 0xfc0007ff, 0x1000044e, 0x0, // Vector Pack Unsigned Doubleword Unsigned Modulo VX-form (vpkudum VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPKUDUS, 0xfc0007ff, 0x100004ce, 0x0, // Vector Pack Unsigned Doubleword Unsigned Saturate VX-form (vpkudus VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPKUHUM, 0xfc0007ff, 0x1000000e, 0x0, // Vector Pack Unsigned Halfword Unsigned Modulo VX-form (vpkuhum VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPKUHUS, 0xfc0007ff, 0x1000008e, 0x0, // Vector Pack Unsigned Halfword Unsigned Saturate VX-form (vpkuhus VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPKUWUM, 0xfc0007ff, 0x1000004e, 0x0, // Vector Pack Unsigned Word Unsigned Modulo VX-form (vpkuwum VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPKUWUS, 0xfc0007ff, 0x100000ce, 0x0, // Vector Pack Unsigned Word Unsigned Saturate VX-form (vpkuwus VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VUPKHPX, 0xfc0007ff, 0x1000034e, 0x1f0000, // Vector Unpack High Pixel VX-form (vupkhpx VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VUPKLPX, 0xfc0007ff, 0x100003ce, 0x1f0000, // Vector Unpack Low Pixel VX-form (vupklpx VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VUPKHSB, 0xfc0007ff, 0x1000020e, 0x1f0000, // Vector Unpack High Signed Byte VX-form (vupkhsb VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VUPKHSH, 0xfc0007ff, 0x1000024e, 0x1f0000, // Vector Unpack High Signed Halfword VX-form (vupkhsh VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VUPKHSW, 0xfc0007ff, 0x1000064e, 0x1f0000, // Vector Unpack High Signed Word VX-form (vupkhsw VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VUPKLSB, 0xfc0007ff, 0x1000028e, 0x1f0000, // Vector Unpack Low Signed Byte VX-form (vupklsb VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VUPKLSH, 0xfc0007ff, 0x100002ce, 0x1f0000, // Vector Unpack Low Signed Halfword VX-form (vupklsh VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VUPKLSW, 0xfc0007ff, 0x100006ce, 0x1f0000, // Vector Unpack Low Signed Word VX-form (vupklsw VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VMRGHB, 0xfc0007ff, 0x1000000c, 0x0, // Vector Merge High Byte VX-form (vmrghb VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMRGHH, 0xfc0007ff, 0x1000004c, 0x0, // Vector Merge High Halfword VX-form (vmrghh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMRGLB, 0xfc0007ff, 0x1000010c, 0x0, // Vector Merge Low Byte VX-form (vmrglb VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMRGLH, 0xfc0007ff, 0x1000014c, 0x0, // Vector Merge Low Halfword VX-form (vmrglh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMRGHW, 0xfc0007ff, 0x1000008c, 0x0, // Vector Merge High Word VX-form (vmrghw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMRGLW, 0xfc0007ff, 0x1000018c, 0x0, // Vector Merge Low Word VX-form (vmrglw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMRGEW, 0xfc0007ff, 0x1000078c, 0x0, // Vector Merge Even Word VX-form (vmrgew VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMRGOW, 0xfc0007ff, 0x1000068c, 0x0, // Vector Merge Odd Word VX-form (vmrgow VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSPLTB, 0xfc0007ff, 0x1000020c, 0x100000, // Vector Splat Byte VX-form (vspltb VRT,VRB,UIM) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_12_15}}, + {VSPLTH, 0xfc0007ff, 0x1000024c, 0x180000, // Vector Splat Halfword VX-form (vsplth VRT,VRB,UIM) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_13_15}}, + {VSPLTW, 0xfc0007ff, 0x1000028c, 0x1c0000, // Vector Splat Word VX-form (vspltw VRT,VRB,UIM) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_14_15}}, + {VSPLTISB, 0xfc0007ff, 0x1000030c, 0xf800, // Vector Splat Immediate Signed Byte VX-form (vspltisb VRT,SIM) + [5]*argField{ap_VecReg_6_10, ap_ImmSigned_11_15}}, + {VSPLTISH, 0xfc0007ff, 0x1000034c, 0xf800, // Vector Splat Immediate Signed Halfword VX-form (vspltish VRT,SIM) + [5]*argField{ap_VecReg_6_10, ap_ImmSigned_11_15}}, + {VSPLTISW, 0xfc0007ff, 0x1000038c, 0xf800, // Vector Splat Immediate Signed Word VX-form (vspltisw VRT,SIM) + [5]*argField{ap_VecReg_6_10, ap_ImmSigned_11_15}}, + {VPERM, 0xfc00003f, 0x1000002b, 0x0, // Vector Permute VA-form (vperm VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VSEL, 0xfc00003f, 0x1000002a, 0x0, // Vector Select VA-form (vsel VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VSL, 0xfc0007ff, 0x100001c4, 0x0, // Vector Shift Left VX-form (vsl VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSLDOI, 0xfc00003f, 0x1000002c, 0x400, // Vector Shift Left Double by Octet Immediate VA-form (vsldoi VRT,VRA,VRB,SHB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_22_25}}, + {VSLO, 0xfc0007ff, 0x1000040c, 0x0, // Vector Shift Left by Octet VX-form (vslo VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSR, 0xfc0007ff, 0x100002c4, 0x0, // Vector Shift Right VX-form (vsr VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSRO, 0xfc0007ff, 0x1000044c, 0x0, // Vector Shift Right by Octet VX-form (vsro VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDCUW, 0xfc0007ff, 0x10000180, 0x0, // Vector Add and Write Carry-Out Unsigned Word VX-form (vaddcuw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDSBS, 0xfc0007ff, 0x10000300, 0x0, // Vector Add Signed Byte Saturate VX-form (vaddsbs VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDSHS, 0xfc0007ff, 0x10000340, 0x0, // Vector Add Signed Halfword Saturate VX-form (vaddshs VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDSWS, 0xfc0007ff, 0x10000380, 0x0, // Vector Add Signed Word Saturate VX-form (vaddsws VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDUBM, 0xfc0007ff, 0x10000000, 0x0, // Vector Add Unsigned Byte Modulo VX-form (vaddubm VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDUDM, 0xfc0007ff, 0x100000c0, 0x0, // Vector Add Unsigned Doubleword Modulo VX-form (vaddudm VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDUHM, 0xfc0007ff, 0x10000040, 0x0, // Vector Add Unsigned Halfword Modulo VX-form (vadduhm VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDUWM, 0xfc0007ff, 0x10000080, 0x0, // Vector Add Unsigned Word Modulo VX-form (vadduwm VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDUBS, 0xfc0007ff, 0x10000200, 0x0, // Vector Add Unsigned Byte Saturate VX-form (vaddubs VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDUHS, 0xfc0007ff, 0x10000240, 0x0, // Vector Add Unsigned Halfword Saturate VX-form (vadduhs VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDUWS, 0xfc0007ff, 0x10000280, 0x0, // Vector Add Unsigned Word Saturate VX-form (vadduws VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDUQM, 0xfc0007ff, 0x10000100, 0x0, // Vector Add Unsigned Quadword Modulo VX-form (vadduqm VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDEUQM, 0xfc00003f, 0x1000003c, 0x0, // Vector Add Extended Unsigned Quadword Modulo VA-form (vaddeuqm VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VADDCUQ, 0xfc0007ff, 0x10000140, 0x0, // Vector Add & write Carry Unsigned Quadword VX-form (vaddcuq VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDECUQ, 0xfc00003f, 0x1000003d, 0x0, // Vector Add Extended & write Carry Unsigned Quadword VA-form (vaddecuq VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VSUBCUW, 0xfc0007ff, 0x10000580, 0x0, // Vector Subtract and Write Carry-Out Unsigned Word VX-form (vsubcuw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUBSBS, 0xfc0007ff, 0x10000700, 0x0, // Vector Subtract Signed Byte Saturate VX-form (vsubsbs VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUBSHS, 0xfc0007ff, 0x10000740, 0x0, // Vector Subtract Signed Halfword Saturate VX-form (vsubshs VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUBSWS, 0xfc0007ff, 0x10000780, 0x0, // Vector Subtract Signed Word Saturate VX-form (vsubsws VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUBUBM, 0xfc0007ff, 0x10000400, 0x0, // Vector Subtract Unsigned Byte Modulo VX-form (vsububm VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUBUDM, 0xfc0007ff, 0x100004c0, 0x0, // Vector Subtract Unsigned Doubleword Modulo VX-form (vsubudm VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUBUHM, 0xfc0007ff, 0x10000440, 0x0, // Vector Subtract Unsigned Halfword Modulo VX-form (vsubuhm VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUBUWM, 0xfc0007ff, 0x10000480, 0x0, // Vector Subtract Unsigned Word Modulo VX-form (vsubuwm VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUBUBS, 0xfc0007ff, 0x10000600, 0x0, // Vector Subtract Unsigned Byte Saturate VX-form (vsububs VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUBUHS, 0xfc0007ff, 0x10000640, 0x0, // Vector Subtract Unsigned Halfword Saturate VX-form (vsubuhs VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUBUWS, 0xfc0007ff, 0x10000680, 0x0, // Vector Subtract Unsigned Word Saturate VX-form (vsubuws VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUBUQM, 0xfc0007ff, 0x10000500, 0x0, // Vector Subtract Unsigned Quadword Modulo VX-form (vsubuqm VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUBEUQM, 0xfc00003f, 0x1000003e, 0x0, // Vector Subtract Extended Unsigned Quadword Modulo VA-form (vsubeuqm VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VSUBCUQ, 0xfc0007ff, 0x10000540, 0x0, // Vector Subtract & write Carry Unsigned Quadword VX-form (vsubcuq VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUBECUQ, 0xfc00003f, 0x1000003f, 0x0, // Vector Subtract Extended & write Carry Unsigned Quadword VA-form (vsubecuq VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VMULESB, 0xfc0007ff, 0x10000308, 0x0, // Vector Multiply Even Signed Byte VX-form (vmulesb VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMULEUB, 0xfc0007ff, 0x10000208, 0x0, // Vector Multiply Even Unsigned Byte VX-form (vmuleub VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMULOSB, 0xfc0007ff, 0x10000108, 0x0, // Vector Multiply Odd Signed Byte VX-form (vmulosb VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMULOUB, 0xfc0007ff, 0x10000008, 0x0, // Vector Multiply Odd Unsigned Byte VX-form (vmuloub VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMULESH, 0xfc0007ff, 0x10000348, 0x0, // Vector Multiply Even Signed Halfword VX-form (vmulesh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMULEUH, 0xfc0007ff, 0x10000248, 0x0, // Vector Multiply Even Unsigned Halfword VX-form (vmuleuh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMULOSH, 0xfc0007ff, 0x10000148, 0x0, // Vector Multiply Odd Signed Halfword VX-form (vmulosh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMULOUH, 0xfc0007ff, 0x10000048, 0x0, // Vector Multiply Odd Unsigned Halfword VX-form (vmulouh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMULESW, 0xfc0007ff, 0x10000388, 0x0, // Vector Multiply Even Signed Word VX-form (vmulesw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMULEUW, 0xfc0007ff, 0x10000288, 0x0, // Vector Multiply Even Unsigned Word VX-form (vmuleuw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMULOSW, 0xfc0007ff, 0x10000188, 0x0, // Vector Multiply Odd Signed Word VX-form (vmulosw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMULOUW, 0xfc0007ff, 0x10000088, 0x0, // Vector Multiply Odd Unsigned Word VX-form (vmulouw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMULUWM, 0xfc0007ff, 0x10000089, 0x0, // Vector Multiply Unsigned Word Modulo VX-form (vmuluwm VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMHADDSHS, 0xfc00003f, 0x10000020, 0x0, // Vector Multiply-High-Add Signed Halfword Saturate VA-form (vmhaddshs VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VMHRADDSHS, 0xfc00003f, 0x10000021, 0x0, // Vector Multiply-High-Round-Add Signed Halfword Saturate VA-form (vmhraddshs VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VMLADDUHM, 0xfc00003f, 0x10000022, 0x0, // Vector Multiply-Low-Add Unsigned Halfword Modulo VA-form (vmladduhm VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VMSUMUBM, 0xfc00003f, 0x10000024, 0x0, // Vector Multiply-Sum Unsigned Byte Modulo VA-form (vmsumubm VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VMSUMMBM, 0xfc00003f, 0x10000025, 0x0, // Vector Multiply-Sum Mixed Byte Modulo VA-form (vmsummbm VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VMSUMSHM, 0xfc00003f, 0x10000028, 0x0, // Vector Multiply-Sum Signed Halfword Modulo VA-form (vmsumshm VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VMSUMSHS, 0xfc00003f, 0x10000029, 0x0, // Vector Multiply-Sum Signed Halfword Saturate VA-form (vmsumshs VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VMSUMUHM, 0xfc00003f, 0x10000026, 0x0, // Vector Multiply-Sum Unsigned Halfword Modulo VA-form (vmsumuhm VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VMSUMUHS, 0xfc00003f, 0x10000027, 0x0, // Vector Multiply-Sum Unsigned Halfword Saturate VA-form (vmsumuhs VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VSUMSWS, 0xfc0007ff, 0x10000788, 0x0, // Vector Sum across Signed Word Saturate VX-form (vsumsws VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUM2SWS, 0xfc0007ff, 0x10000688, 0x0, // Vector Sum across Half Signed Word Saturate VX-form (vsum2sws VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUM4SBS, 0xfc0007ff, 0x10000708, 0x0, // Vector Sum across Quarter Signed Byte Saturate VX-form (vsum4sbs VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUM4SHS, 0xfc0007ff, 0x10000648, 0x0, // Vector Sum across Quarter Signed Halfword Saturate VX-form (vsum4shs VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUM4UBS, 0xfc0007ff, 0x10000608, 0x0, // Vector Sum across Quarter Unsigned Byte Saturate VX-form (vsum4ubs VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VAVGSB, 0xfc0007ff, 0x10000502, 0x0, // Vector Average Signed Byte VX-form (vavgsb VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VAVGSH, 0xfc0007ff, 0x10000542, 0x0, // Vector Average Signed Halfword VX-form (vavgsh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VAVGSW, 0xfc0007ff, 0x10000582, 0x0, // Vector Average Signed Word VX-form (vavgsw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VAVGUB, 0xfc0007ff, 0x10000402, 0x0, // Vector Average Unsigned Byte VX-form (vavgub VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VAVGUW, 0xfc0007ff, 0x10000482, 0x0, // Vector Average Unsigned Word VX-form (vavguw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VAVGUH, 0xfc0007ff, 0x10000442, 0x0, // Vector Average Unsigned Halfword VX-form (vavguh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMAXSB, 0xfc0007ff, 0x10000102, 0x0, // Vector Maximum Signed Byte VX-form (vmaxsb VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMAXSD, 0xfc0007ff, 0x100001c2, 0x0, // Vector Maximum Signed Doubleword VX-form (vmaxsd VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMAXUB, 0xfc0007ff, 0x10000002, 0x0, // Vector Maximum Unsigned Byte VX-form (vmaxub VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMAXUD, 0xfc0007ff, 0x100000c2, 0x0, // Vector Maximum Unsigned Doubleword VX-form (vmaxud VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMAXSH, 0xfc0007ff, 0x10000142, 0x0, // Vector Maximum Signed Halfword VX-form (vmaxsh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMAXSW, 0xfc0007ff, 0x10000182, 0x0, // Vector Maximum Signed Word VX-form (vmaxsw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMAXUH, 0xfc0007ff, 0x10000042, 0x0, // Vector Maximum Unsigned Halfword VX-form (vmaxuh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMAXUW, 0xfc0007ff, 0x10000082, 0x0, // Vector Maximum Unsigned Word VX-form (vmaxuw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMINSB, 0xfc0007ff, 0x10000302, 0x0, // Vector Minimum Signed Byte VX-form (vminsb VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMINSD, 0xfc0007ff, 0x100003c2, 0x0, // Vector Minimum Signed Doubleword VX-form (vminsd VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMINUB, 0xfc0007ff, 0x10000202, 0x0, // Vector Minimum Unsigned Byte VX-form (vminub VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMINUD, 0xfc0007ff, 0x100002c2, 0x0, // Vector Minimum Unsigned Doubleword VX-form (vminud VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMINSH, 0xfc0007ff, 0x10000342, 0x0, // Vector Minimum Signed Halfword VX-form (vminsh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMINSW, 0xfc0007ff, 0x10000382, 0x0, // Vector Minimum Signed Word VX-form (vminsw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMINUH, 0xfc0007ff, 0x10000242, 0x0, // Vector Minimum Unsigned Halfword VX-form (vminuh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMINUW, 0xfc0007ff, 0x10000282, 0x0, // Vector Minimum Unsigned Word VX-form (vminuw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPEQUB, 0xfc0007ff, 0x10000006, 0x0, // Vector Compare Equal To Unsigned Byte VC-form (vcmpequb VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPEQUBCC, 0xfc0007ff, 0x10000406, 0x0, // Vector Compare Equal To Unsigned Byte VC-form (vcmpequb. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPEQUH, 0xfc0007ff, 0x10000046, 0x0, // Vector Compare Equal To Unsigned Halfword VC-form (vcmpequh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPEQUHCC, 0xfc0007ff, 0x10000446, 0x0, // Vector Compare Equal To Unsigned Halfword VC-form (vcmpequh. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPEQUW, 0xfc0007ff, 0x10000086, 0x0, // Vector Compare Equal To Unsigned Word VC-form (vcmpequw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPEQUWCC, 0xfc0007ff, 0x10000486, 0x0, // Vector Compare Equal To Unsigned Word VC-form (vcmpequw. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPEQUD, 0xfc0007ff, 0x100000c7, 0x0, // Vector Compare Equal To Unsigned Doubleword VX-form (vcmpequd VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPEQUDCC, 0xfc0007ff, 0x100004c7, 0x0, // Vector Compare Equal To Unsigned Doubleword VX-form (vcmpequd. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTSB, 0xfc0007ff, 0x10000306, 0x0, // Vector Compare Greater Than Signed Byte VC-form (vcmpgtsb VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTSBCC, 0xfc0007ff, 0x10000706, 0x0, // Vector Compare Greater Than Signed Byte VC-form (vcmpgtsb. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTSD, 0xfc0007ff, 0x100003c7, 0x0, // Vector Compare Greater Than Signed Doubleword VX-form (vcmpgtsd VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTSDCC, 0xfc0007ff, 0x100007c7, 0x0, // Vector Compare Greater Than Signed Doubleword VX-form (vcmpgtsd. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTSH, 0xfc0007ff, 0x10000346, 0x0, // Vector Compare Greater Than Signed Halfword VC-form (vcmpgtsh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTSHCC, 0xfc0007ff, 0x10000746, 0x0, // Vector Compare Greater Than Signed Halfword VC-form (vcmpgtsh. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTSW, 0xfc0007ff, 0x10000386, 0x0, // Vector Compare Greater Than Signed Word VC-form (vcmpgtsw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTSWCC, 0xfc0007ff, 0x10000786, 0x0, // Vector Compare Greater Than Signed Word VC-form (vcmpgtsw. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTUB, 0xfc0007ff, 0x10000206, 0x0, // Vector Compare Greater Than Unsigned Byte VC-form (vcmpgtub VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTUBCC, 0xfc0007ff, 0x10000606, 0x0, // Vector Compare Greater Than Unsigned Byte VC-form (vcmpgtub. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTUD, 0xfc0007ff, 0x100002c7, 0x0, // Vector Compare Greater Than Unsigned Doubleword VX-form (vcmpgtud VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTUDCC, 0xfc0007ff, 0x100006c7, 0x0, // Vector Compare Greater Than Unsigned Doubleword VX-form (vcmpgtud. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTUH, 0xfc0007ff, 0x10000246, 0x0, // Vector Compare Greater Than Unsigned Halfword VC-form (vcmpgtuh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTUHCC, 0xfc0007ff, 0x10000646, 0x0, // Vector Compare Greater Than Unsigned Halfword VC-form (vcmpgtuh. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTUW, 0xfc0007ff, 0x10000286, 0x0, // Vector Compare Greater Than Unsigned Word VC-form (vcmpgtuw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTUWCC, 0xfc0007ff, 0x10000686, 0x0, // Vector Compare Greater Than Unsigned Word VC-form (vcmpgtuw. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VAND, 0xfc0007ff, 0x10000404, 0x0, // Vector Logical AND VX-form (vand VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VANDC, 0xfc0007ff, 0x10000444, 0x0, // Vector Logical AND with Complement VX-form (vandc VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VEQV, 0xfc0007ff, 0x10000684, 0x0, // Vector Logical Equivalent VX-form (veqv VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VNAND, 0xfc0007ff, 0x10000584, 0x0, // Vector Logical NAND VX-form (vnand VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VORC, 0xfc0007ff, 0x10000544, 0x0, // Vector Logical OR with Complement VX-form (vorc VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VNOR, 0xfc0007ff, 0x10000504, 0x0, // Vector Logical NOR VX-form (vnor VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VOR, 0xfc0007ff, 0x10000484, 0x0, // Vector Logical OR VX-form (vor VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VXOR, 0xfc0007ff, 0x100004c4, 0x0, // Vector Logical XOR VX-form (vxor VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VRLB, 0xfc0007ff, 0x10000004, 0x0, // Vector Rotate Left Byte VX-form (vrlb VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VRLH, 0xfc0007ff, 0x10000044, 0x0, // Vector Rotate Left Halfword VX-form (vrlh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VRLW, 0xfc0007ff, 0x10000084, 0x0, // Vector Rotate Left Word VX-form (vrlw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VRLD, 0xfc0007ff, 0x100000c4, 0x0, // Vector Rotate Left Doubleword VX-form (vrld VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSLB, 0xfc0007ff, 0x10000104, 0x0, // Vector Shift Left Byte VX-form (vslb VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSLH, 0xfc0007ff, 0x10000144, 0x0, // Vector Shift Left Halfword VX-form (vslh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSLW, 0xfc0007ff, 0x10000184, 0x0, // Vector Shift Left Word VX-form (vslw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSLD, 0xfc0007ff, 0x100005c4, 0x0, // Vector Shift Left Doubleword VX-form (vsld VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSRB, 0xfc0007ff, 0x10000204, 0x0, // Vector Shift Right Byte VX-form (vsrb VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSRH, 0xfc0007ff, 0x10000244, 0x0, // Vector Shift Right Halfword VX-form (vsrh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSRW, 0xfc0007ff, 0x10000284, 0x0, // Vector Shift Right Word VX-form (vsrw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSRD, 0xfc0007ff, 0x100006c4, 0x0, // Vector Shift Right Doubleword VX-form (vsrd VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSRAB, 0xfc0007ff, 0x10000304, 0x0, // Vector Shift Right Algebraic Byte VX-form (vsrab VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSRAH, 0xfc0007ff, 0x10000344, 0x0, // Vector Shift Right Algebraic Halfword VX-form (vsrah VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSRAW, 0xfc0007ff, 0x10000384, 0x0, // Vector Shift Right Algebraic Word VX-form (vsraw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSRAD, 0xfc0007ff, 0x100003c4, 0x0, // Vector Shift Right Algebraic Doubleword VX-form (vsrad VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VADDFP, 0xfc0007ff, 0x1000000a, 0x0, // Vector Add Single-Precision VX-form (vaddfp VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSUBFP, 0xfc0007ff, 0x1000004a, 0x0, // Vector Subtract Single-Precision VX-form (vsubfp VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMADDFP, 0xfc00003f, 0x1000002e, 0x0, // Vector Multiply-Add Single-Precision VA-form (vmaddfp VRT,VRA,VRC,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_21_25, ap_VecReg_16_20}}, + {VNMSUBFP, 0xfc00003f, 0x1000002f, 0x0, // Vector Negative Multiply-Subtract Single-Precision VA-form (vnmsubfp VRT,VRA,VRC,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_21_25, ap_VecReg_16_20}}, + {VMAXFP, 0xfc0007ff, 0x1000040a, 0x0, // Vector Maximum Single-Precision VX-form (vmaxfp VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VMINFP, 0xfc0007ff, 0x1000044a, 0x0, // Vector Minimum Single-Precision VX-form (vminfp VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCTSXS, 0xfc0007ff, 0x100003ca, 0x0, // Vector Convert To Signed Fixed-Point Word Saturate VX-form (vctsxs VRT,VRB,UIM) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}}, + {VCTUXS, 0xfc0007ff, 0x1000038a, 0x0, // Vector Convert To Unsigned Fixed-Point Word Saturate VX-form (vctuxs VRT,VRB,UIM) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}}, + {VCFSX, 0xfc0007ff, 0x1000034a, 0x0, // Vector Convert From Signed Fixed-Point Word VX-form (vcfsx VRT,VRB,UIM) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}}, + {VCFUX, 0xfc0007ff, 0x1000030a, 0x0, // Vector Convert From Unsigned Fixed-Point Word VX-form (vcfux VRT,VRB,UIM) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}}, + {VRFIM, 0xfc0007ff, 0x100002ca, 0x1f0000, // Vector Round to Single-Precision Integer toward -Infinity VX-form (vrfim VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VRFIN, 0xfc0007ff, 0x1000020a, 0x1f0000, // Vector Round to Single-Precision Integer Nearest VX-form (vrfin VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VRFIP, 0xfc0007ff, 0x1000028a, 0x1f0000, // Vector Round to Single-Precision Integer toward +Infinity VX-form (vrfip VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VRFIZ, 0xfc0007ff, 0x1000024a, 0x1f0000, // Vector Round to Single-Precision Integer toward Zero VX-form (vrfiz VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VCMPBFP, 0xfc0007ff, 0x100003c6, 0x0, // Vector Compare Bounds Single-Precision VC-form (vcmpbfp VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPBFPCC, 0xfc0007ff, 0x100007c6, 0x0, // Vector Compare Bounds Single-Precision VC-form (vcmpbfp. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPEQFP, 0xfc0007ff, 0x100000c6, 0x0, // Vector Compare Equal To Single-Precision VC-form (vcmpeqfp VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPEQFPCC, 0xfc0007ff, 0x100004c6, 0x0, // Vector Compare Equal To Single-Precision VC-form (vcmpeqfp. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGEFP, 0xfc0007ff, 0x100001c6, 0x0, // Vector Compare Greater Than or Equal To Single-Precision VC-form (vcmpgefp VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGEFPCC, 0xfc0007ff, 0x100005c6, 0x0, // Vector Compare Greater Than or Equal To Single-Precision VC-form (vcmpgefp. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTFP, 0xfc0007ff, 0x100002c6, 0x0, // Vector Compare Greater Than Single-Precision VC-form (vcmpgtfp VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCMPGTFPCC, 0xfc0007ff, 0x100006c6, 0x0, // Vector Compare Greater Than Single-Precision VC-form (vcmpgtfp. VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VEXPTEFP, 0xfc0007ff, 0x1000018a, 0x1f0000, // Vector 2 Raised to the Exponent Estimate Floating-Point VX-form (vexptefp VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VLOGEFP, 0xfc0007ff, 0x100001ca, 0x1f0000, // Vector Log Base 2 Estimate Floating-Point VX-form (vlogefp VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VREFP, 0xfc0007ff, 0x1000010a, 0x1f0000, // Vector Reciprocal Estimate Single-Precision VX-form (vrefp VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VRSQRTEFP, 0xfc0007ff, 0x1000014a, 0x1f0000, // Vector Reciprocal Square Root Estimate Single-Precision VX-form (vrsqrtefp VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VCIPHER, 0xfc0007ff, 0x10000508, 0x0, // Vector AES Cipher VX-form (vcipher VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VCIPHERLAST, 0xfc0007ff, 0x10000509, 0x0, // Vector AES Cipher Last VX-form (vcipherlast VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VNCIPHER, 0xfc0007ff, 0x10000548, 0x0, // Vector AES Inverse Cipher VX-form (vncipher VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VNCIPHERLAST, 0xfc0007ff, 0x10000549, 0x0, // Vector AES Inverse Cipher Last VX-form (vncipherlast VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VSBOX, 0xfc0007ff, 0x100005c8, 0xf800, // Vector AES SubBytes VX-form (vsbox VRT,VRA) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15}}, + {VSHASIGMAD, 0xfc0007ff, 0x100006c2, 0x0, // Vector SHA-512 Sigma Doubleword VX-form (vshasigmad VRT,VRA,ST,SIX) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_ImmUnsigned_16_16, ap_ImmUnsigned_17_20}}, + {VSHASIGMAW, 0xfc0007ff, 0x10000682, 0x0, // Vector SHA-256 Sigma Word VX-form (vshasigmaw VRT,VRA,ST,SIX) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_ImmUnsigned_16_16, ap_ImmUnsigned_17_20}}, + {VPMSUMB, 0xfc0007ff, 0x10000408, 0x0, // Vector Polynomial Multiply-Sum Byte VX-form (vpmsumb VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPMSUMD, 0xfc0007ff, 0x100004c8, 0x0, // Vector Polynomial Multiply-Sum Doubleword VX-form (vpmsumd VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPMSUMH, 0xfc0007ff, 0x10000448, 0x0, // Vector Polynomial Multiply-Sum Halfword VX-form (vpmsumh VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPMSUMW, 0xfc0007ff, 0x10000488, 0x0, // Vector Polynomial Multiply-Sum Word VX-form (vpmsumw VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {VPERMXOR, 0xfc00003f, 0x1000002d, 0x0, // Vector Permute and Exclusive-OR VA-form (vpermxor VRT,VRA,VRB,VRC) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}}, + {VGBBD, 0xfc0007ff, 0x1000050c, 0x1f0000, // Vector Gather Bits by Bytes by Doubleword VX-form (vgbbd VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VCLZB, 0xfc0007ff, 0x10000702, 0x1f0000, // Vector Count Leading Zeros Byte VX-form (vclzb VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VCLZH, 0xfc0007ff, 0x10000742, 0x1f0000, // Vector Count Leading Zeros Halfword VX-form (vclzh VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VCLZW, 0xfc0007ff, 0x10000782, 0x1f0000, // Vector Count Leading Zeros Word VX-form (vclzw VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VCLZD, 0xfc0007ff, 0x100007c2, 0x1f0000, // Vector Count Leading Zeros Doubleword (vclzd VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VPOPCNTB, 0xfc0007ff, 0x10000703, 0x1f0000, // Vector Population Count Byte (vpopcntb VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VPOPCNTD, 0xfc0007ff, 0x100007c3, 0x1f0000, // Vector Population Count Doubleword (vpopcntd VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VPOPCNTH, 0xfc0007ff, 0x10000743, 0x1f0000, // Vector Population Count Halfword (vpopcnth VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VPOPCNTW, 0xfc0007ff, 0x10000783, 0x1f0000, // Vector Population Count Word (vpopcntw VRT,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}}, + {VBPERMQ, 0xfc0007ff, 0x1000054c, 0x0, // Vector Bit Permute Quadword VX-form (vbpermq VRT,VRA,VRB) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}}, + {BCDADDCC, 0xfc0005ff, 0x10000401, 0x0, // Decimal Add Modulo VX-form (bcdadd. VRT,VRA,VRB,PS) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_22_22}}, + {BCDSUBCC, 0xfc0005ff, 0x10000441, 0x0, // Decimal Subtract Modulo VX-form (bcdsub. VRT,VRA,VRB,PS) + [5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_22_22}}, + {MTVSCR, 0xfc0007ff, 0x10000644, 0x3ff0000, // Move To Vector Status and Control Register VX-form (mtvscr VRB) + [5]*argField{ap_VecReg_16_20}}, + {MFVSCR, 0xfc0007ff, 0x10000604, 0x1ff800, // Move From Vector Status and Control Register VX-form (mfvscr VRT) + [5]*argField{ap_VecReg_6_10}}, + {DADD, 0xfc0007ff, 0xec000004, 0x0, // DFP Add [Quad] X-form (dadd FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {DADDCC, 0xfc0007ff, 0xec000005, 0x0, // DFP Add [Quad] X-form (dadd. FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {DSUB, 0xfc0007ff, 0xec000404, 0x0, // DFP Subtract [Quad] X-form (dsub FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {DSUBCC, 0xfc0007ff, 0xec000405, 0x0, // DFP Subtract [Quad] X-form (dsub. FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {DMUL, 0xfc0007ff, 0xec000044, 0x0, // DFP Multiply [Quad] X-form (dmul FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {DMULCC, 0xfc0007ff, 0xec000045, 0x0, // DFP Multiply [Quad] X-form (dmul. FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {DDIV, 0xfc0007ff, 0xec000444, 0x0, // DFP Divide [Quad] X-form (ddiv FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {DDIVCC, 0xfc0007ff, 0xec000445, 0x0, // DFP Divide [Quad] X-form (ddiv. FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {DCMPU, 0xfc0007fe, 0xec000504, 0x600001, // DFP Compare Unordered [Quad] X-form (dcmpu BF,FRA,FRB) + [5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}}, + {DCMPO, 0xfc0007fe, 0xec000104, 0x600001, // DFP Compare Ordered [Quad] X-form (dcmpo BF,FRA,FRB) + [5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}}, + {DTSTDC, 0xfc0003fe, 0xec000184, 0x600001, // DFP Test Data Class [Quad] Z22-form (dtstdc BF,FRA,DCM) + [5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_ImmUnsigned_16_21}}, + {DTSTDG, 0xfc0003fe, 0xec0001c4, 0x600001, // DFP Test Data Group [Quad] Z22-form (dtstdg BF,FRA,DGM) + [5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_ImmUnsigned_16_21}}, + {DTSTEX, 0xfc0007fe, 0xec000144, 0x600001, // DFP Test Exponent [Quad] X-form (dtstex BF,FRA,FRB) + [5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}}, + {DTSTSF, 0xfc0007fe, 0xec000544, 0x600001, // DFP Test Significance [Quad] X-form (dtstsf BF,FRA,FRB) + [5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}}, + {DQUAI, 0xfc0001ff, 0xec000086, 0x0, // DFP Quantize Immediate [Quad] Z23-form (dquai TE,FRT,FRB,RMC) + [5]*argField{ap_ImmSigned_11_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}}, + {DQUAICC, 0xfc0001ff, 0xec000087, 0x0, // DFP Quantize Immediate [Quad] Z23-form (dquai. TE,FRT,FRB,RMC) + [5]*argField{ap_ImmSigned_11_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}}, + {DQUA, 0xfc0001ff, 0xec000006, 0x0, // DFP Quantize [Quad] Z23-form (dqua FRT,FRA,FRB,RMC) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}}, + {DQUACC, 0xfc0001ff, 0xec000007, 0x0, // DFP Quantize [Quad] Z23-form (dqua. FRT,FRA,FRB,RMC) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}}, + {DRRND, 0xfc0001ff, 0xec000046, 0x0, // DFP Reround [Quad] Z23-form (drrnd FRT,FRA,FRB,RMC) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}}, + {DRRNDCC, 0xfc0001ff, 0xec000047, 0x0, // DFP Reround [Quad] Z23-form (drrnd. FRT,FRA,FRB,RMC) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}}, + {DRINTX, 0xfc0001ff, 0xec0000c6, 0x1e0000, // DFP Round To FP Integer With Inexact [Quad] Z23-form (drintx R,FRT,FRB,RMC) + [5]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}}, + {DRINTXCC, 0xfc0001ff, 0xec0000c7, 0x1e0000, // DFP Round To FP Integer With Inexact [Quad] Z23-form (drintx. R,FRT,FRB,RMC) + [5]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}}, + {DRINTN, 0xfc0001ff, 0xec0001c6, 0x1e0000, // DFP Round To FP Integer Without Inexact [Quad] Z23-form (drintn R,FRT,FRB,RMC) + [5]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}}, + {DRINTNCC, 0xfc0001ff, 0xec0001c7, 0x1e0000, // DFP Round To FP Integer Without Inexact [Quad] Z23-form (drintn. R,FRT,FRB,RMC) + [5]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}}, + {DCTDP, 0xfc0007ff, 0xec000204, 0x1f0000, // DFP Convert To DFP Long X-form (dctdp FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DCTDPCC, 0xfc0007ff, 0xec000205, 0x1f0000, // DFP Convert To DFP Long X-form (dctdp. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DCTQPQ, 0xfc0007ff, 0xfc000204, 0x1f0000, // DFP Convert To DFP Extended X-form (dctqpq FRTp,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DCTQPQCC, 0xfc0007ff, 0xfc000205, 0x1f0000, // DFP Convert To DFP Extended X-form (dctqpq. FRTp,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DRSP, 0xfc0007ff, 0xec000604, 0x1f0000, // DFP Round To DFP Short X-form (drsp FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DRSPCC, 0xfc0007ff, 0xec000605, 0x1f0000, // DFP Round To DFP Short X-form (drsp. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DRDPQ, 0xfc0007ff, 0xfc000604, 0x1f0000, // DFP Round To DFP Long X-form (drdpq FRTp,FRBp) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DRDPQCC, 0xfc0007ff, 0xfc000605, 0x1f0000, // DFP Round To DFP Long X-form (drdpq. FRTp,FRBp) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DCFFIX, 0xfc0007ff, 0xec000644, 0x1f0000, // DFP Convert From Fixed X-form (dcffix FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DCFFIXCC, 0xfc0007ff, 0xec000645, 0x1f0000, // DFP Convert From Fixed X-form (dcffix. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DCFFIXQ, 0xfc0007ff, 0xfc000644, 0x1f0000, // DFP Convert From Fixed Quad X-form (dcffixq FRTp,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DCFFIXQCC, 0xfc0007ff, 0xfc000645, 0x1f0000, // DFP Convert From Fixed Quad X-form (dcffixq. FRTp,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DCTFIX, 0xfc0007ff, 0xec000244, 0x1f0000, // DFP Convert To Fixed [Quad] X-form (dctfix FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DCTFIXCC, 0xfc0007ff, 0xec000245, 0x1f0000, // DFP Convert To Fixed [Quad] X-form (dctfix. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DDEDPD, 0xfc0007ff, 0xec000284, 0x70000, // DFP Decode DPD To BCD [Quad] X-form (ddedpd SP,FRT,FRB) + [5]*argField{ap_ImmUnsigned_11_12, ap_FPReg_6_10, ap_FPReg_16_20}}, + {DDEDPDCC, 0xfc0007ff, 0xec000285, 0x70000, // DFP Decode DPD To BCD [Quad] X-form (ddedpd. SP,FRT,FRB) + [5]*argField{ap_ImmUnsigned_11_12, ap_FPReg_6_10, ap_FPReg_16_20}}, + {DENBCD, 0xfc0007ff, 0xec000684, 0xf0000, // DFP Encode BCD To DPD [Quad] X-form (denbcd S,FRT,FRB) + [5]*argField{ap_ImmUnsigned_11_11, ap_FPReg_6_10, ap_FPReg_16_20}}, + {DENBCDCC, 0xfc0007ff, 0xec000685, 0xf0000, // DFP Encode BCD To DPD [Quad] X-form (denbcd. S,FRT,FRB) + [5]*argField{ap_ImmUnsigned_11_11, ap_FPReg_6_10, ap_FPReg_16_20}}, + {DXEX, 0xfc0007ff, 0xec0002c4, 0x1f0000, // DFP Extract Biased Exponent [Quad] X-form (dxex FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DXEXCC, 0xfc0007ff, 0xec0002c5, 0x1f0000, // DFP Extract Biased Exponent [Quad] X-form (dxex. FRT,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}}, + {DIEX, 0xfc0007ff, 0xec0006c4, 0x0, // DFP Insert Biased Exponent [Quad] X-form (diex FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {DIEXCC, 0xfc0007ff, 0xec0006c5, 0x0, // DFP Insert Biased Exponent [Quad] X-form (diex. FRT,FRA,FRB) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}}, + {DSCLI, 0xfc0003ff, 0xec000084, 0x0, // DFP Shift Significand Left Immediate [Quad] Z22-form (dscli FRT,FRA,SH) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}}, + {DSCLICC, 0xfc0003ff, 0xec000085, 0x0, // DFP Shift Significand Left Immediate [Quad] Z22-form (dscli. FRT,FRA,SH) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}}, + {DSCRI, 0xfc0003ff, 0xec0000c4, 0x0, // DFP Shift Significand Right Immediate [Quad] Z22-form (dscri FRT,FRA,SH) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}}, + {DSCRICC, 0xfc0003ff, 0xec0000c5, 0x0, // DFP Shift Significand Right Immediate [Quad] Z22-form (dscri. FRT,FRA,SH) + [5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}}, + {LXSDX, 0xfc0007fe, 0x7c000498, 0x0, // Load VSX Scalar Doubleword Indexed XX1-form (lxsdx XT,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LXSIWAX, 0xfc0007fe, 0x7c000098, 0x0, // Load VSX Scalar as Integer Word Algebraic Indexed XX1-form (lxsiwax XT,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LXSIWZX, 0xfc0007fe, 0x7c000018, 0x0, // Load VSX Scalar as Integer Word and Zero Indexed XX1-form (lxsiwzx XT,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LXSSPX, 0xfc0007fe, 0x7c000418, 0x0, // Load VSX Scalar Single-Precision Indexed XX1-form (lxsspx XT,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LXVD2X, 0xfc0007fe, 0x7c000698, 0x0, // Load VSX Vector Doubleword*2 Indexed XX1-form (lxvd2x XT,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LXVDSX, 0xfc0007fe, 0x7c000298, 0x0, // Load VSX Vector Doubleword & Splat Indexed XX1-form (lxvdsx XT,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LXVW4X, 0xfc0007fe, 0x7c000618, 0x0, // Load VSX Vector Word*4 Indexed XX1-form (lxvw4x XT,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STXSDX, 0xfc0007fe, 0x7c000598, 0x0, // Store VSX Scalar Doubleword Indexed XX1-form (stxsdx XS,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STXSIWX, 0xfc0007fe, 0x7c000118, 0x0, // Store VSX Scalar as Integer Word Indexed XX1-form (stxsiwx XS,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STXSSPX, 0xfc0007fe, 0x7c000518, 0x0, // Store VSX Scalar Single-Precision Indexed XX1-form (stxsspx XS,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STXVD2X, 0xfc0007fe, 0x7c000798, 0x0, // Store VSX Vector Doubleword*2 Indexed XX1-form (stxvd2x XS,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STXVW4X, 0xfc0007fe, 0x7c000718, 0x0, // Store VSX Vector Word*4 Indexed XX1-form (stxvw4x XS,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {XSABSDP, 0xfc0007fc, 0xf0000564, 0x1f0000, // VSX Scalar Absolute Value Double-Precision XX2-form (xsabsdp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSADDDP, 0xfc0007f8, 0xf0000100, 0x0, // VSX Scalar Add Double-Precision XX3-form (xsadddp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSADDSP, 0xfc0007f8, 0xf0000000, 0x0, // VSX Scalar Add Single-Precision XX3-form (xsaddsp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSCMPODP, 0xfc0007f8, 0xf0000158, 0x600001, // VSX Scalar Compare Ordered Double-Precision XX3-form (xscmpodp BF,XA,XB) + [5]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSCMPUDP, 0xfc0007f8, 0xf0000118, 0x600001, // VSX Scalar Compare Unordered Double-Precision XX3-form (xscmpudp BF,XA,XB) + [5]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSCPSGNDP, 0xfc0007f8, 0xf0000580, 0x0, // VSX Scalar Copy Sign Double-Precision XX3-form (xscpsgndp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSCVDPSP, 0xfc0007fc, 0xf0000424, 0x1f0000, // VSX Scalar round Double-Precision to single-precision and Convert to Single-Precision format XX2-form (xscvdpsp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSCVDPSPN, 0xfc0007fc, 0xf000042c, 0x1f0000, // VSX Scalar Convert Scalar Single-Precision to Vector Single-Precision format Non-signalling XX2-form (xscvdpspn XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSCVDPSXDS, 0xfc0007fc, 0xf0000560, 0x1f0000, // VSX Scalar truncate Double-Precision to integer and Convert to Signed Integer Doubleword format with Saturate XX2-form (xscvdpsxds XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSCVDPSXWS, 0xfc0007fc, 0xf0000160, 0x1f0000, // VSX Scalar truncate Double-Precision to integer and Convert to Signed Integer Word format with Saturate XX2-form (xscvdpsxws XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSCVDPUXDS, 0xfc0007fc, 0xf0000520, 0x1f0000, // VSX Scalar truncate Double-Precision integer and Convert to Unsigned Integer Doubleword format with Saturate XX2-form (xscvdpuxds XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSCVDPUXWS, 0xfc0007fc, 0xf0000120, 0x1f0000, // VSX Scalar truncate Double-Precision to integer and Convert to Unsigned Integer Word format with Saturate XX2-form (xscvdpuxws XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSCVSPDP, 0xfc0007fc, 0xf0000524, 0x1f0000, // VSX Scalar Convert Single-Precision to Double-Precision format XX2-form (xscvspdp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSCVSPDPN, 0xfc0007fc, 0xf000052c, 0x1f0000, // VSX Scalar Convert Single-Precision to Double-Precision format Non-signalling XX2-form (xscvspdpn XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSCVSXDDP, 0xfc0007fc, 0xf00005e0, 0x1f0000, // VSX Scalar Convert Signed Integer Doubleword to floating-point format and round to Double-Precision format XX2-form (xscvsxddp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSCVSXDSP, 0xfc0007fc, 0xf00004e0, 0x1f0000, // VSX Scalar Convert Signed Integer Doubleword to floating-point format and round to Single-Precision XX2-form (xscvsxdsp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSCVUXDDP, 0xfc0007fc, 0xf00005a0, 0x1f0000, // VSX Scalar Convert Unsigned Integer Doubleword to floating-point format and round to Double-Precision format XX2-form (xscvuxddp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSCVUXDSP, 0xfc0007fc, 0xf00004a0, 0x1f0000, // VSX Scalar Convert Unsigned Integer Doubleword to floating-point format and round to Single-Precision XX2-form (xscvuxdsp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSDIVDP, 0xfc0007f8, 0xf00001c0, 0x0, // VSX Scalar Divide Double-Precision XX3-form (xsdivdp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSDIVSP, 0xfc0007f8, 0xf00000c0, 0x0, // VSX Scalar Divide Single-Precision XX3-form (xsdivsp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSMADDADP, 0xfc0007f8, 0xf0000108, 0x0, // VSX Scalar Multiply-Add Double-Precision XX3-form (xsmaddadp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSMADDASP, 0xfc0007f8, 0xf0000008, 0x0, // VSX Scalar Multiply-Add Single-Precision XX3-form (xsmaddasp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSMAXDP, 0xfc0007f8, 0xf0000500, 0x0, // VSX Scalar Maximum Double-Precision XX3-form (xsmaxdp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSMINDP, 0xfc0007f8, 0xf0000540, 0x0, // VSX Scalar Minimum Double-Precision XX3-form (xsmindp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSMSUBADP, 0xfc0007f8, 0xf0000188, 0x0, // VSX Scalar Multiply-Subtract Double-Precision XX3-form (xsmsubadp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSMSUBASP, 0xfc0007f8, 0xf0000088, 0x0, // VSX Scalar Multiply-Subtract Single-Precision XX3-form (xsmsubasp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSMULDP, 0xfc0007f8, 0xf0000180, 0x0, // VSX Scalar Multiply Double-Precision XX3-form (xsmuldp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSMULSP, 0xfc0007f8, 0xf0000080, 0x0, // VSX Scalar Multiply Single-Precision XX3-form (xsmulsp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSNABSDP, 0xfc0007fc, 0xf00005a4, 0x1f0000, // VSX Scalar Negative Absolute Value Double-Precision XX2-form (xsnabsdp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSNEGDP, 0xfc0007fc, 0xf00005e4, 0x1f0000, // VSX Scalar Negate Double-Precision XX2-form (xsnegdp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSNMADDADP, 0xfc0007f8, 0xf0000508, 0x0, // VSX Scalar Negative Multiply-Add Double-Precision XX3-form (xsnmaddadp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSNMADDASP, 0xfc0007f8, 0xf0000408, 0x0, // VSX Scalar Negative Multiply-Add Single-Precision XX3-form (xsnmaddasp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSNMSUBADP, 0xfc0007f8, 0xf0000588, 0x0, // VSX Scalar Negative Multiply-Subtract Double-Precision XX3-form (xsnmsubadp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSNMSUBASP, 0xfc0007f8, 0xf0000488, 0x0, // VSX Scalar Negative Multiply-Subtract Single-Precision XX3-form (xsnmsubasp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSRDPI, 0xfc0007fc, 0xf0000124, 0x1f0000, // VSX Scalar Round to Double-Precision Integer using round to Nearest Away XX2-form (xsrdpi XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSRDPIC, 0xfc0007fc, 0xf00001ac, 0x1f0000, // VSX Scalar Round to Double-Precision Integer exact using Current rounding mode XX2-form (xsrdpic XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSRDPIM, 0xfc0007fc, 0xf00001e4, 0x1f0000, // VSX Scalar Round to Double-Precision Integer using round toward -Infinity XX2-form (xsrdpim XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSRDPIP, 0xfc0007fc, 0xf00001a4, 0x1f0000, // VSX Scalar Round to Double-Precision Integer using round toward +Infinity XX2-form (xsrdpip XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSRDPIZ, 0xfc0007fc, 0xf0000164, 0x1f0000, // VSX Scalar Round to Double-Precision Integer using round toward Zero XX2-form (xsrdpiz XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSREDP, 0xfc0007fc, 0xf0000168, 0x1f0000, // VSX Scalar Reciprocal Estimate Double-Precision XX2-form (xsredp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSRESP, 0xfc0007fc, 0xf0000068, 0x1f0000, // VSX Scalar Reciprocal Estimate Single-Precision XX2-form (xsresp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSRSP, 0xfc0007fc, 0xf0000464, 0x1f0000, // VSX Scalar Round to Single-Precision XX2-form (xsrsp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSRSQRTEDP, 0xfc0007fc, 0xf0000128, 0x1f0000, // VSX Scalar Reciprocal Square Root Estimate Double-Precision XX2-form (xsrsqrtedp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSRSQRTESP, 0xfc0007fc, 0xf0000028, 0x1f0000, // VSX Scalar Reciprocal Square Root Estimate Single-Precision XX2-form (xsrsqrtesp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSSQRTDP, 0xfc0007fc, 0xf000012c, 0x1f0000, // VSX Scalar Square Root Double-Precision XX2-form (xssqrtdp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSSQRTSP, 0xfc0007fc, 0xf000002c, 0x1f0000, // VSX Scalar Square Root Single-Precision XX-form (xssqrtsp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XSSUBDP, 0xfc0007f8, 0xf0000140, 0x0, // VSX Scalar Subtract Double-Precision XX3-form (xssubdp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSSUBSP, 0xfc0007f8, 0xf0000040, 0x0, // VSX Scalar Subtract Single-Precision XX3-form (xssubsp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSTDIVDP, 0xfc0007f8, 0xf00001e8, 0x600001, // VSX Scalar Test for software Divide Double-Precision XX3-form (xstdivdp BF,XA,XB) + [5]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XSTSQRTDP, 0xfc0007fc, 0xf00001a8, 0x7f0001, // VSX Scalar Test for software Square Root Double-Precision XX2-form (xstsqrtdp BF,XB) + [5]*argField{ap_CondRegField_6_8, ap_VecSReg_30_30_16_20}}, + {XVABSDP, 0xfc0007fc, 0xf0000764, 0x1f0000, // VSX Vector Absolute Value Double-Precision XX2-form (xvabsdp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVABSSP, 0xfc0007fc, 0xf0000664, 0x1f0000, // VSX Vector Absolute Value Single-Precision XX2-form (xvabssp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVADDDP, 0xfc0007f8, 0xf0000300, 0x0, // VSX Vector Add Double-Precision XX3-form (xvadddp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVADDSP, 0xfc0007f8, 0xf0000200, 0x0, // VSX Vector Add Single-Precision XX3-form (xvaddsp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCMPEQDP, 0xfc0007f8, 0xf0000318, 0x0, // VSX Vector Compare Equal To Double-Precision [ & Record ] XX3-form (xvcmpeqdp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCMPEQDPCC, 0xfc0007f8, 0xf0000718, 0x0, // VSX Vector Compare Equal To Double-Precision [ & Record ] XX3-form (xvcmpeqdp. XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCMPEQSP, 0xfc0007f8, 0xf0000218, 0x0, // VSX Vector Compare Equal To Single-Precision [ & Record ] XX3-form (xvcmpeqsp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCMPEQSPCC, 0xfc0007f8, 0xf0000618, 0x0, // VSX Vector Compare Equal To Single-Precision [ & Record ] XX3-form (xvcmpeqsp. XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCMPGEDP, 0xfc0007f8, 0xf0000398, 0x0, // VSX Vector Compare Greater Than or Equal To Double-Precision [ & Record ] XX3-form (xvcmpgedp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCMPGEDPCC, 0xfc0007f8, 0xf0000798, 0x0, // VSX Vector Compare Greater Than or Equal To Double-Precision [ & Record ] XX3-form (xvcmpgedp. XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCMPGESP, 0xfc0007f8, 0xf0000298, 0x0, // VSX Vector Compare Greater Than or Equal To Single-Precision [ & record CR6 ] XX3-form (xvcmpgesp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCMPGESPCC, 0xfc0007f8, 0xf0000698, 0x0, // VSX Vector Compare Greater Than or Equal To Single-Precision [ & record CR6 ] XX3-form (xvcmpgesp. XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCMPGTDP, 0xfc0007f8, 0xf0000358, 0x0, // VSX Vector Compare Greater Than Double-Precision [ & record CR6 ] XX3-form (xvcmpgtdp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCMPGTDPCC, 0xfc0007f8, 0xf0000758, 0x0, // VSX Vector Compare Greater Than Double-Precision [ & record CR6 ] XX3-form (xvcmpgtdp. XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCMPGTSP, 0xfc0007f8, 0xf0000258, 0x0, // VSX Vector Compare Greater Than Single-Precision [ & record CR6 ] XX3-form (xvcmpgtsp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCMPGTSPCC, 0xfc0007f8, 0xf0000658, 0x0, // VSX Vector Compare Greater Than Single-Precision [ & record CR6 ] XX3-form (xvcmpgtsp. XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCPSGNDP, 0xfc0007f8, 0xf0000780, 0x0, // VSX Vector Copy Sign Double-Precision XX3-form (xvcpsgndp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCPSGNSP, 0xfc0007f8, 0xf0000680, 0x0, // VSX Vector Copy Sign Single-Precision XX3-form (xvcpsgnsp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVCVDPSP, 0xfc0007fc, 0xf0000624, 0x1f0000, // VSX Vector round Double-Precision to single-precision and Convert to Single-Precision format XX2-form (xvcvdpsp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVDPSXDS, 0xfc0007fc, 0xf0000760, 0x1f0000, // VSX Vector truncate Double-Precision to integer and Convert to Signed Integer Doubleword format with Saturate XX2-form (xvcvdpsxds XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVDPSXWS, 0xfc0007fc, 0xf0000360, 0x1f0000, // VSX Vector truncate Double-Precision to integer and Convert to Signed Integer Word format with Saturate XX2-form (xvcvdpsxws XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVDPUXDS, 0xfc0007fc, 0xf0000720, 0x1f0000, // VSX Vector truncate Double-Precision to integer and Convert to Unsigned Integer Doubleword format with Saturate XX2-form (xvcvdpuxds XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVDPUXWS, 0xfc0007fc, 0xf0000320, 0x1f0000, // VSX Vector truncate Double-Precision to integer and Convert to Unsigned Integer Word format with Saturate XX2-form (xvcvdpuxws XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVSPDP, 0xfc0007fc, 0xf0000724, 0x1f0000, // VSX Vector Convert Single-Precision to Double-Precision format XX2-form (xvcvspdp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVSPSXDS, 0xfc0007fc, 0xf0000660, 0x1f0000, // VSX Vector truncate Single-Precision to integer and Convert to Signed Integer Doubleword format with Saturate XX2-form (xvcvspsxds XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVSPSXWS, 0xfc0007fc, 0xf0000260, 0x1f0000, // VSX Vector truncate Single-Precision to integer and Convert to Signed Integer Word format with Saturate XX2-form (xvcvspsxws XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVSPUXDS, 0xfc0007fc, 0xf0000620, 0x1f0000, // VSX Vector truncate Single-Precision to integer and Convert to Unsigned Integer Doubleword format with Saturate XX2-form (xvcvspuxds XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVSPUXWS, 0xfc0007fc, 0xf0000220, 0x1f0000, // VSX Vector truncate Single-Precision to integer and Convert to Unsigned Integer Word format with Saturate XX2-form (xvcvspuxws XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVSXDDP, 0xfc0007fc, 0xf00007e0, 0x1f0000, // VSX Vector Convert and round Signed Integer Doubleword to Double-Precision format XX2-form (xvcvsxddp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVSXDSP, 0xfc0007fc, 0xf00006e0, 0x1f0000, // VSX Vector Convert and round Signed Integer Doubleword to Single-Precision format XX2-form (xvcvsxdsp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVSXWDP, 0xfc0007fc, 0xf00003e0, 0x1f0000, // VSX Vector Convert Signed Integer Word to Double-Precision format XX2-form (xvcvsxwdp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVSXWSP, 0xfc0007fc, 0xf00002e0, 0x1f0000, // VSX Vector Convert and round Signed Integer Word to Single-Precision format XX2-form (xvcvsxwsp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVUXDDP, 0xfc0007fc, 0xf00007a0, 0x1f0000, // VSX Vector Convert and round Unsigned Integer Doubleword to Double-Precision format XX2-form (xvcvuxddp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVUXDSP, 0xfc0007fc, 0xf00006a0, 0x1f0000, // VSX Vector Convert and round Unsigned Integer Doubleword to Single-Precision format XX2-form (xvcvuxdsp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVUXWDP, 0xfc0007fc, 0xf00003a0, 0x1f0000, // VSX Vector Convert and round Unsigned Integer Word to Double-Precision format XX2-form (xvcvuxwdp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVCVUXWSP, 0xfc0007fc, 0xf00002a0, 0x1f0000, // VSX Vector Convert and round Unsigned Integer Word to Single-Precision format XX2-form (xvcvuxwsp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVDIVDP, 0xfc0007f8, 0xf00003c0, 0x0, // VSX Vector Divide Double-Precision XX3-form (xvdivdp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVDIVSP, 0xfc0007f8, 0xf00002c0, 0x0, // VSX Vector Divide Single-Precision XX3-form (xvdivsp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVMADDADP, 0xfc0007f8, 0xf0000308, 0x0, // VSX Vector Multiply-Add Double-Precision XX3-form (xvmaddadp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVMADDASP, 0xfc0007f8, 0xf0000208, 0x0, // VSX Vector Multiply-Add Single-Precision XX3-form (xvmaddasp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVMAXDP, 0xfc0007f8, 0xf0000700, 0x0, // VSX Vector Maximum Double-Precision XX3-form (xvmaxdp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVMAXSP, 0xfc0007f8, 0xf0000600, 0x0, // VSX Vector Maximum Single-Precision XX3-form (xvmaxsp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVMINDP, 0xfc0007f8, 0xf0000740, 0x0, // VSX Vector Minimum Double-Precision XX3-form (xvmindp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVMINSP, 0xfc0007f8, 0xf0000640, 0x0, // VSX Vector Minimum Single-Precision XX3-form (xvminsp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVMSUBADP, 0xfc0007f8, 0xf0000388, 0x0, // VSX Vector Multiply-Subtract Double-Precision XX3-form (xvmsubadp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVMSUBASP, 0xfc0007f8, 0xf0000288, 0x0, // VSX Vector Multiply-Subtract Single-Precision XX3-form (xvmsubasp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVMULDP, 0xfc0007f8, 0xf0000380, 0x0, // VSX Vector Multiply Double-Precision XX3-form (xvmuldp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVMULSP, 0xfc0007f8, 0xf0000280, 0x0, // VSX Vector Multiply Single-Precision XX3-form (xvmulsp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVNABSDP, 0xfc0007fc, 0xf00007a4, 0x1f0000, // VSX Vector Negative Absolute Value Double-Precision XX2-form (xvnabsdp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVNABSSP, 0xfc0007fc, 0xf00006a4, 0x1f0000, // VSX Vector Negative Absolute Value Single-Precision XX2-form (xvnabssp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVNEGDP, 0xfc0007fc, 0xf00007e4, 0x1f0000, // VSX Vector Negate Double-Precision XX2-form (xvnegdp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVNEGSP, 0xfc0007fc, 0xf00006e4, 0x1f0000, // VSX Vector Negate Single-Precision XX2-form (xvnegsp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVNMADDADP, 0xfc0007f8, 0xf0000708, 0x0, // VSX Vector Negative Multiply-Add Double-Precision XX3-form (xvnmaddadp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVNMADDASP, 0xfc0007f8, 0xf0000608, 0x0, // VSX Vector Negative Multiply-Add Single-Precision XX3-form (xvnmaddasp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVNMSUBADP, 0xfc0007f8, 0xf0000788, 0x0, // VSX Vector Negative Multiply-Subtract Double-Precision XX3-form (xvnmsubadp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVNMSUBASP, 0xfc0007f8, 0xf0000688, 0x0, // VSX Vector Negative Multiply-Subtract Single-Precision XX3-form (xvnmsubasp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVRDPI, 0xfc0007fc, 0xf0000324, 0x1f0000, // VSX Vector Round to Double-Precision Integer using round to Nearest Away XX2-form (xvrdpi XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVRDPIC, 0xfc0007fc, 0xf00003ac, 0x1f0000, // VSX Vector Round to Double-Precision Integer Exact using Current rounding mode XX2-form (xvrdpic XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVRDPIM, 0xfc0007fc, 0xf00003e4, 0x1f0000, // VSX Vector Round to Double-Precision Integer using round toward -Infinity XX2-form (xvrdpim XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVRDPIP, 0xfc0007fc, 0xf00003a4, 0x1f0000, // VSX Vector Round to Double-Precision Integer using round toward +Infinity XX2-form (xvrdpip XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVRDPIZ, 0xfc0007fc, 0xf0000364, 0x1f0000, // VSX Vector Round to Double-Precision Integer using round toward Zero XX2-form (xvrdpiz XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVREDP, 0xfc0007fc, 0xf0000368, 0x1f0000, // VSX Vector Reciprocal Estimate Double-Precision XX2-form (xvredp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVRESP, 0xfc0007fc, 0xf0000268, 0x1f0000, // VSX Vector Reciprocal Estimate Single-Precision XX2-form (xvresp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVRSPI, 0xfc0007fc, 0xf0000224, 0x1f0000, // VSX Vector Round to Single-Precision Integer using round to Nearest Away XX2-form (xvrspi XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVRSPIC, 0xfc0007fc, 0xf00002ac, 0x1f0000, // VSX Vector Round to Single-Precision Integer Exact using Current rounding mode XX2-form (xvrspic XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVRSPIM, 0xfc0007fc, 0xf00002e4, 0x1f0000, // VSX Vector Round to Single-Precision Integer using round toward -Infinity XX2-form (xvrspim XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVRSPIP, 0xfc0007fc, 0xf00002a4, 0x1f0000, // VSX Vector Round to Single-Precision Integer using round toward +Infinity XX2-form (xvrspip XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVRSPIZ, 0xfc0007fc, 0xf0000264, 0x1f0000, // VSX Vector Round to Single-Precision Integer using round toward Zero XX2-form (xvrspiz XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVRSQRTEDP, 0xfc0007fc, 0xf0000328, 0x1f0000, // VSX Vector Reciprocal Square Root Estimate Double-Precision XX2-form (xvrsqrtedp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVRSQRTESP, 0xfc0007fc, 0xf0000228, 0x1f0000, // VSX Vector Reciprocal Square Root Estimate Single-Precision XX2-form (xvrsqrtesp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVSQRTDP, 0xfc0007fc, 0xf000032c, 0x1f0000, // VSX Vector Square Root Double-Precision XX2-form (xvsqrtdp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVSQRTSP, 0xfc0007fc, 0xf000022c, 0x1f0000, // VSX Vector Square Root Single-Precision XX2-form (xvsqrtsp XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XVSUBDP, 0xfc0007f8, 0xf0000340, 0x0, // VSX Vector Subtract Double-Precision XX3-form (xvsubdp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVSUBSP, 0xfc0007f8, 0xf0000240, 0x0, // VSX Vector Subtract Single-Precision XX3-form (xvsubsp XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVTDIVDP, 0xfc0007f8, 0xf00003e8, 0x600001, // VSX Vector Test for software Divide Double-Precision XX3-form (xvtdivdp BF,XA,XB) + [5]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVTDIVSP, 0xfc0007f8, 0xf00002e8, 0x600001, // VSX Vector Test for software Divide Single-Precision XX3-form (xvtdivsp BF,XA,XB) + [5]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XVTSQRTDP, 0xfc0007fc, 0xf00003a8, 0x7f0001, // VSX Vector Test for software Square Root Double-Precision XX2-form (xvtsqrtdp BF,XB) + [5]*argField{ap_CondRegField_6_8, ap_VecSReg_30_30_16_20}}, + {XVTSQRTSP, 0xfc0007fc, 0xf00002a8, 0x7f0001, // VSX Vector Test for software Square Root Single-Precision XX2-form (xvtsqrtsp BF,XB) + [5]*argField{ap_CondRegField_6_8, ap_VecSReg_30_30_16_20}}, + {XXLAND, 0xfc0007f8, 0xf0000410, 0x0, // VSX Logical AND XX3-form (xxland XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XXLANDC, 0xfc0007f8, 0xf0000450, 0x0, // VSX Logical AND with Complement XX3-form (xxlandc XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XXLEQV, 0xfc0007f8, 0xf00005d0, 0x0, // VSX Logical Equivalence XX3-form (xxleqv XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XXLNAND, 0xfc0007f8, 0xf0000590, 0x0, // VSX Logical NAND XX3-form (xxlnand XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XXLORC, 0xfc0007f8, 0xf0000550, 0x0, // VSX Logical OR with Complement XX3-form (xxlorc XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XXLNOR, 0xfc0007f8, 0xf0000510, 0x0, // VSX Logical NOR XX3-form (xxlnor XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XXLOR, 0xfc0007f8, 0xf0000490, 0x0, // VSX Logical OR XX3-form (xxlor XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XXLXOR, 0xfc0007f8, 0xf00004d0, 0x0, // VSX Logical XOR XX3-form (xxlxor XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XXMRGHW, 0xfc0007f8, 0xf0000090, 0x0, // VSX Merge High Word XX3-form (xxmrghw XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XXMRGLW, 0xfc0007f8, 0xf0000190, 0x0, // VSX Merge Low Word XX3-form (xxmrglw XT,XA,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}}, + {XXPERMDI, 0xfc0004f8, 0xf0000050, 0x0, // VSX Permute Doubleword Immediate XX3-form (xxpermdi XT,XA,XB,DM) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_22_23}}, + {XXSEL, 0xfc000030, 0xf0000030, 0x0, // VSX Select XX4-form (xxsel XT,XA,XB,XC) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20, ap_VecSReg_28_28_21_25}}, + {XXSLDWI, 0xfc0004f8, 0xf0000010, 0x0, // VSX Shift Left Double by Word Immediate XX3-form (xxsldwi XT,XA,XB,SHW) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_22_23}}, + {XXSPLTW, 0xfc0007fc, 0xf0000290, 0x1c0000, // VSX Splat Word XX2-form (xxspltw XT,XB,UIM) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_14_15}}, + {BRINC, 0xfc0007ff, 0x1000020f, 0x0, // Bit Reversed Increment EVX-form (brinc RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVABS, 0xfc0007ff, 0x10000208, 0xf800, // Vector Absolute Value EVX-form (evabs RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVADDIW, 0xfc0007ff, 0x10000202, 0x0, // Vector Add Immediate Word EVX-form (evaddiw RT,RB,UI) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_11_15}}, + {EVADDSMIAAW, 0xfc0007ff, 0x100004c9, 0xf800, // Vector Add Signed, Modulo, Integer to Accumulator Word EVX-form (evaddsmiaaw RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVADDSSIAAW, 0xfc0007ff, 0x100004c1, 0xf800, // Vector Add Signed, Saturate, Integer to Accumulator Word EVX-form (evaddssiaaw RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVADDUMIAAW, 0xfc0007ff, 0x100004c8, 0xf800, // Vector Add Unsigned, Modulo, Integer to Accumulator Word EVX-form (evaddumiaaw RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVADDUSIAAW, 0xfc0007ff, 0x100004c0, 0xf800, // Vector Add Unsigned, Saturate, Integer to Accumulator Word EVX-form (evaddusiaaw RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVADDW, 0xfc0007ff, 0x10000200, 0x0, // Vector Add Word EVX-form (evaddw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVAND, 0xfc0007ff, 0x10000211, 0x0, // Vector AND EVX-form (evand RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVCMPEQ, 0xfc0007ff, 0x10000234, 0x600000, // Vector Compare Equal EVX-form (evcmpeq BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EVANDC, 0xfc0007ff, 0x10000212, 0x0, // Vector AND with Complement EVX-form (evandc RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVCMPGTS, 0xfc0007ff, 0x10000231, 0x600000, // Vector Compare Greater Than Signed EVX-form (evcmpgts BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EVCMPGTU, 0xfc0007ff, 0x10000230, 0x600000, // Vector Compare Greater Than Unsigned EVX-form (evcmpgtu BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EVCMPLTU, 0xfc0007ff, 0x10000232, 0x600000, // Vector Compare Less Than Unsigned EVX-form (evcmpltu BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EVCMPLTS, 0xfc0007ff, 0x10000233, 0x600000, // Vector Compare Less Than Signed EVX-form (evcmplts BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EVCNTLSW, 0xfc0007ff, 0x1000020e, 0xf800, // Vector Count Leading Signed Bits Word EVX-form (evcntlsw RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVCNTLZW, 0xfc0007ff, 0x1000020d, 0xf800, // Vector Count Leading Zeros Word EVX-form (evcntlzw RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVDIVWS, 0xfc0007ff, 0x100004c6, 0x0, // Vector Divide Word Signed EVX-form (evdivws RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVDIVWU, 0xfc0007ff, 0x100004c7, 0x0, // Vector Divide Word Unsigned EVX-form (evdivwu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVEQV, 0xfc0007ff, 0x10000219, 0x0, // Vector Equivalent EVX-form (eveqv RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVEXTSB, 0xfc0007ff, 0x1000020a, 0xf800, // Vector Extend Sign Byte EVX-form (evextsb RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVEXTSH, 0xfc0007ff, 0x1000020b, 0xf800, // Vector Extend Sign Halfword EVX-form (evextsh RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVLDD, 0xfc0007ff, 0x10000301, 0x0, // Vector Load Double Word into Double Word EVX-form (evldd RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVLDH, 0xfc0007ff, 0x10000305, 0x0, // Vector Load Double into Four Halfwords EVX-form (evldh RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVLDDX, 0xfc0007ff, 0x10000300, 0x0, // Vector Load Double Word into Double Word Indexed EVX-form (evlddx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVLDHX, 0xfc0007ff, 0x10000304, 0x0, // Vector Load Double into Four Halfwords Indexed EVX-form (evldhx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVLDW, 0xfc0007ff, 0x10000303, 0x0, // Vector Load Double into Two Words EVX-form (evldw RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVLHHESPLAT, 0xfc0007ff, 0x10000309, 0x0, // Vector Load Halfword into Halfwords Even and Splat EVX-form (evlhhesplat RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVLDWX, 0xfc0007ff, 0x10000302, 0x0, // Vector Load Double into Two Words Indexed EVX-form (evldwx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVLHHESPLATX, 0xfc0007ff, 0x10000308, 0x0, // Vector Load Halfword into Halfwords Even and Splat Indexed EVX-form (evlhhesplatx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVLHHOSSPLAT, 0xfc0007ff, 0x1000030f, 0x0, // Vector Load Halfword into Halfword Odd Signed and Splat EVX-form (evlhhossplat RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVLHHOUSPLAT, 0xfc0007ff, 0x1000030d, 0x0, // Vector Load Halfword into Halfword Odd Unsigned and Splat EVX-form (evlhhousplat RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVLHHOSSPLATX, 0xfc0007ff, 0x1000030e, 0x0, // Vector Load Halfword into Halfword Odd Signed and Splat Indexed EVX-form (evlhhossplatx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVLHHOUSPLATX, 0xfc0007ff, 0x1000030c, 0x0, // Vector Load Halfword into Halfword Odd Unsigned and Splat Indexed EVX-form (evlhhousplatx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVLWHE, 0xfc0007ff, 0x10000311, 0x0, // Vector Load Word into Two Halfwords Even EVX-form (evlwhe RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVLWHOS, 0xfc0007ff, 0x10000317, 0x0, // Vector Load Word into Two Halfwords Odd Signed (with sign extension) EVX-form (evlwhos RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVLWHEX, 0xfc0007ff, 0x10000310, 0x0, // Vector Load Word into Two Halfwords Even Indexed EVX-form (evlwhex RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVLWHOSX, 0xfc0007ff, 0x10000316, 0x0, // Vector Load Word into Two Halfwords Odd Signed Indexed (with sign extension) EVX-form (evlwhosx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVLWHOU, 0xfc0007ff, 0x10000315, 0x0, // Vector Load Word into Two Halfwords Odd Unsigned (zero-extended) EVX-form (evlwhou RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVLWHSPLAT, 0xfc0007ff, 0x1000031d, 0x0, // Vector Load Word into Two Halfwords and Splat EVX-form (evlwhsplat RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVLWHOUX, 0xfc0007ff, 0x10000314, 0x0, // Vector Load Word into Two Halfwords Odd Unsigned Indexed (zero-extended) EVX-form (evlwhoux RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVLWHSPLATX, 0xfc0007ff, 0x1000031c, 0x0, // Vector Load Word into Two Halfwords and Splat Indexed EVX-form (evlwhsplatx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVLWWSPLAT, 0xfc0007ff, 0x10000319, 0x0, // Vector Load Word into Word and Splat EVX-form (evlwwsplat RT,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVMERGEHI, 0xfc0007ff, 0x1000022c, 0x0, // Vector Merge High EVX-form (evmergehi RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVLWWSPLATX, 0xfc0007ff, 0x10000318, 0x0, // Vector Load Word into Word and Splat Indexed EVX-form (evlwwsplatx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMERGELO, 0xfc0007ff, 0x1000022d, 0x0, // Vector Merge Low EVX-form (evmergelo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMERGEHILO, 0xfc0007ff, 0x1000022e, 0x0, // Vector Merge High/Low EVX-form (evmergehilo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHEGSMFAA, 0xfc0007ff, 0x1000052b, 0x0, // Vector Multiply Halfwords, Even, Guarded, Signed, Modulo, Fractional and Accumulate EVX-form (evmhegsmfaa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMERGELOHI, 0xfc0007ff, 0x1000022f, 0x0, // Vector Merge Low/High EVX-form (evmergelohi RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHEGSMFAN, 0xfc0007ff, 0x100005ab, 0x0, // Vector Multiply Halfwords, Even, Guarded, Signed, Modulo, Fractional and Accumulate Negative EVX-form (evmhegsmfan RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHEGSMIAA, 0xfc0007ff, 0x10000529, 0x0, // Vector Multiply Halfwords, Even, Guarded, Signed, Modulo, Integer and Accumulate EVX-form (evmhegsmiaa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHEGUMIAA, 0xfc0007ff, 0x10000528, 0x0, // Vector Multiply Halfwords, Even, Guarded, Unsigned, Modulo, Integer and Accumulate EVX-form (evmhegumiaa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHEGSMIAN, 0xfc0007ff, 0x100005a9, 0x0, // Vector Multiply Halfwords, Even, Guarded, Signed, Modulo, Integer and Accumulate Negative EVX-form (evmhegsmian RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHEGUMIAN, 0xfc0007ff, 0x100005a8, 0x0, // Vector Multiply Halfwords, Even, Guarded, Unsigned, Modulo, Integer and Accumulate Negative EVX-form (evmhegumian RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHESMF, 0xfc0007ff, 0x1000040b, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Fractional EVX-form (evmhesmf RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHESMFAAW, 0xfc0007ff, 0x1000050b, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Fractional and Accumulate into Words EVX-form (evmhesmfaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHESMFA, 0xfc0007ff, 0x1000042b, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Fractional to Accumulator EVX-form (evmhesmfa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHESMFANW, 0xfc0007ff, 0x1000058b, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Fractional and Accumulate Negative into Words EVX-form (evmhesmfanw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHESMI, 0xfc0007ff, 0x10000409, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Integer EVX-form (evmhesmi RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHESMIAAW, 0xfc0007ff, 0x10000509, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Integer and Accumulate into Words EVX-form (evmhesmiaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHESMIA, 0xfc0007ff, 0x10000429, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Integer to Accumulator EVX-form (evmhesmia RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHESMIANW, 0xfc0007ff, 0x10000589, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Integer and Accumulate Negative into Words EVX-form (evmhesmianw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHESSF, 0xfc0007ff, 0x10000403, 0x0, // Vector Multiply Halfwords, Even, Signed, Saturate, Fractional EVX-form (evmhessf RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHESSFA, 0xfc0007ff, 0x10000423, 0x0, // Vector Multiply Halfwords, Even, Signed, Saturate, Fractional to Accumulator EVX-form (evmhessfa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHESSFAAW, 0xfc0007ff, 0x10000503, 0x0, // Vector Multiply Halfwords, Even, Signed, Saturate, Fractional and Accumulate into Words EVX-form (evmhessfaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHESSFANW, 0xfc0007ff, 0x10000583, 0x0, // Vector Multiply Halfwords, Even, Signed, Saturate, Fractional and Accumulate Negative into Words EVX-form (evmhessfanw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHESSIAAW, 0xfc0007ff, 0x10000501, 0x0, // Vector Multiply Halfwords, Even, Signed, Saturate, Integer and Accumulate into Words EVX-form (evmhessiaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHESSIANW, 0xfc0007ff, 0x10000581, 0x0, // Vector Multiply Halfwords, Even, Signed, Saturate, Integer and Accumulate Negative into Words EVX-form (evmhessianw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHEUMI, 0xfc0007ff, 0x10000408, 0x0, // Vector Multiply Halfwords, Even, Unsigned, Modulo, Integer EVX-form (evmheumi RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHEUMIAAW, 0xfc0007ff, 0x10000508, 0x0, // Vector Multiply Halfwords, Even, Unsigned, Modulo, Integer and Accumulate into Words EVX-form (evmheumiaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHEUMIA, 0xfc0007ff, 0x10000428, 0x0, // Vector Multiply Halfwords, Even, Unsigned, Modulo, Integer to Accumulator EVX-form (evmheumia RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHEUMIANW, 0xfc0007ff, 0x10000588, 0x0, // Vector Multiply Halfwords, Even, Unsigned, Modulo, Integer and Accumulate Negative into Words EVX-form (evmheumianw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHEUSIAAW, 0xfc0007ff, 0x10000500, 0x0, // Vector Multiply Halfwords, Even, Unsigned, Saturate, Integer and Accumulate into Words EVX-form (evmheusiaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHEUSIANW, 0xfc0007ff, 0x10000580, 0x0, // Vector Multiply Halfwords, Even, Unsigned, Saturate, Integer and Accumulate Negative into Words EVX-form (evmheusianw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOGSMFAA, 0xfc0007ff, 0x1000052f, 0x0, // Vector Multiply Halfwords, Odd, Guarded, Signed, Modulo, Fractional and Accumulate EVX-form (evmhogsmfaa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOGSMIAA, 0xfc0007ff, 0x1000052d, 0x0, // Vector Multiply Halfwords, Odd, Guarded, Signed, Modulo, Integer and Accumulate EVX-form (evmhogsmiaa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOGSMFAN, 0xfc0007ff, 0x100005af, 0x0, // Vector Multiply Halfwords, Odd, Guarded, Signed, Modulo, Fractional and Accumulate Negative EVX-form (evmhogsmfan RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOGSMIAN, 0xfc0007ff, 0x100005ad, 0x0, // Vector Multiply Halfwords, Odd, Guarded, Signed, Modulo, Integer and Accumulate Negative EVX-form (evmhogsmian RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOGUMIAA, 0xfc0007ff, 0x1000052c, 0x0, // Vector Multiply Halfwords, Odd, Guarded, Unsigned, Modulo, Integer and Accumulate EVX-form (evmhogumiaa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOSMF, 0xfc0007ff, 0x1000040f, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Fractional EVX-form (evmhosmf RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOGUMIAN, 0xfc0007ff, 0x100005ac, 0x0, // Vector Multiply Halfwords, Odd, Guarded, Unsigned, Modulo, Integer and Accumulate Negative EVX-form (evmhogumian RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOSMFA, 0xfc0007ff, 0x1000042f, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Fractional to Accumulator EVX-form (evmhosmfa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOSMFAAW, 0xfc0007ff, 0x1000050f, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Fractional and Accumulate into Words EVX-form (evmhosmfaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOSMI, 0xfc0007ff, 0x1000040d, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Integer EVX-form (evmhosmi RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOSMFANW, 0xfc0007ff, 0x1000058f, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Fractional and Accumulate Negative into Words EVX-form (evmhosmfanw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOSMIA, 0xfc0007ff, 0x1000042d, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Integer to Accumulator EVX-form (evmhosmia RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOSMIAAW, 0xfc0007ff, 0x1000050d, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Integer and Accumulate into Words EVX-form (evmhosmiaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOSMIANW, 0xfc0007ff, 0x1000058d, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Integer and Accumulate Negative into Words EVX-form (evmhosmianw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOSSF, 0xfc0007ff, 0x10000407, 0x0, // Vector Multiply Halfwords, Odd, Signed, Saturate, Fractional EVX-form (evmhossf RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOSSFA, 0xfc0007ff, 0x10000427, 0x0, // Vector Multiply Halfwords, Odd, Signed, Saturate, Fractional to Accumulator EVX-form (evmhossfa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOSSFAAW, 0xfc0007ff, 0x10000507, 0x0, // Vector Multiply Halfwords, Odd, Signed, Saturate, Fractional and Accumulate into Words EVX-form (evmhossfaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOSSFANW, 0xfc0007ff, 0x10000587, 0x0, // Vector Multiply Halfwords, Odd, Signed, Saturate, Fractional and Accumulate Negative into Words EVX-form (evmhossfanw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOSSIAAW, 0xfc0007ff, 0x10000505, 0x0, // Vector Multiply Halfwords, Odd, Signed, Saturate, Integer and Accumulate into Words EVX-form (evmhossiaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOUMI, 0xfc0007ff, 0x1000040c, 0x0, // Vector Multiply Halfwords, Odd, Unsigned, Modulo, Integer EVX-form (evmhoumi RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOSSIANW, 0xfc0007ff, 0x10000585, 0x0, // Vector Multiply Halfwords, Odd, Signed, Saturate, Integer and Accumulate Negative into Words EVX-form (evmhossianw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOUMIA, 0xfc0007ff, 0x1000042c, 0x0, // Vector Multiply Halfwords, Odd, Unsigned, Modulo, Integer to Accumulator EVX-form (evmhoumia RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOUMIAAW, 0xfc0007ff, 0x1000050c, 0x0, // Vector Multiply Halfwords, Odd, Unsigned, Modulo, Integer and Accumulate into Words EVX-form (evmhoumiaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOUSIAAW, 0xfc0007ff, 0x10000504, 0x0, // Vector Multiply Halfwords, Odd, Unsigned, Saturate, Integer and Accumulate into Words EVX-form (evmhousiaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOUMIANW, 0xfc0007ff, 0x1000058c, 0x0, // Vector Multiply Halfwords, Odd, Unsigned, Modulo, Integer and Accumulate Negative into Words EVX-form (evmhoumianw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMHOUSIANW, 0xfc0007ff, 0x10000584, 0x0, // Vector Multiply Halfwords, Odd, Unsigned, Saturate, Integer and Accumulate Negative into Words EVX-form (evmhousianw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMRA, 0xfc0007ff, 0x100004c4, 0xf800, // Initialize Accumulator EVX-form (evmra RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVMWHSMF, 0xfc0007ff, 0x1000044f, 0x0, // Vector Multiply Word High Signed, Modulo, Fractional EVX-form (evmwhsmf RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWHSMI, 0xfc0007ff, 0x1000044d, 0x0, // Vector Multiply Word High Signed, Modulo, Integer EVX-form (evmwhsmi RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWHSMFA, 0xfc0007ff, 0x1000046f, 0x0, // Vector Multiply Word High Signed, Modulo, Fractional to Accumulator EVX-form (evmwhsmfa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWHSMIA, 0xfc0007ff, 0x1000046d, 0x0, // Vector Multiply Word High Signed, Modulo, Integer to Accumulator EVX-form (evmwhsmia RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWHSSF, 0xfc0007ff, 0x10000447, 0x0, // Vector Multiply Word High Signed, Saturate, Fractional EVX-form (evmwhssf RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWHUMI, 0xfc0007ff, 0x1000044c, 0x0, // Vector Multiply Word High Unsigned, Modulo, Integer EVX-form (evmwhumi RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWHSSFA, 0xfc0007ff, 0x10000467, 0x0, // Vector Multiply Word High Signed, Saturate, Fractional to Accumulator EVX-form (evmwhssfa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWHUMIA, 0xfc0007ff, 0x1000046c, 0x0, // Vector Multiply Word High Unsigned, Modulo, Integer to Accumulator EVX-form (evmwhumia RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWLSMIAAW, 0xfc0007ff, 0x10000549, 0x0, // Vector Multiply Word Low Signed, Modulo, Integer and Accumulate into Words EVX-form (evmwlsmiaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWLSSIAAW, 0xfc0007ff, 0x10000541, 0x0, // Vector Multiply Word Low Signed, Saturate, Integer and Accumulate into Words EVX-form (evmwlssiaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWLSMIANW, 0xfc0007ff, 0x100005c9, 0x0, // Vector Multiply Word Low Signed, Modulo, Integer and Accumulate Negative in Words EVX-form (evmwlsmianw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWLSSIANW, 0xfc0007ff, 0x100005c1, 0x0, // Vector Multiply Word Low Signed, Saturate, Integer and Accumulate Negative in Words EVX-form (evmwlssianw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWLUMI, 0xfc0007ff, 0x10000448, 0x0, // Vector Multiply Word Low Unsigned, Modulo, Integer EVX-form (evmwlumi RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWLUMIAAW, 0xfc0007ff, 0x10000548, 0x0, // Vector Multiply Word Low Unsigned, Modulo, Integer and Accumulate into Words EVX-form (evmwlumiaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWLUMIA, 0xfc0007ff, 0x10000468, 0x0, // Vector Multiply Word Low Unsigned, Modulo, Integer to Accumulator EVX-form (evmwlumia RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWLUMIANW, 0xfc0007ff, 0x100005c8, 0x0, // Vector Multiply Word Low Unsigned, Modulo, Integer and Accumulate Negative in Words EVX-form (evmwlumianw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWLUSIAAW, 0xfc0007ff, 0x10000540, 0x0, // Vector Multiply Word Low Unsigned, Saturate, Integer and Accumulate into Words EVX-form (evmwlusiaaw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWSMF, 0xfc0007ff, 0x1000045b, 0x0, // Vector Multiply Word Signed, Modulo, Fractional EVX-form (evmwsmf RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWLUSIANW, 0xfc0007ff, 0x100005c0, 0x0, // Vector Multiply Word Low Unsigned, Saturate, Integer and Accumulate Negative in Words EVX-form (evmwlusianw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWSMFA, 0xfc0007ff, 0x1000047b, 0x0, // Vector Multiply Word Signed, Modulo, Fractional to Accumulator EVX-form (evmwsmfa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWSMFAA, 0xfc0007ff, 0x1000055b, 0x0, // Vector Multiply Word Signed, Modulo, Fractional and Accumulate EVX-form (evmwsmfaa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWSMI, 0xfc0007ff, 0x10000459, 0x0, // Vector Multiply Word Signed, Modulo, Integer EVX-form (evmwsmi RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWSMIAA, 0xfc0007ff, 0x10000559, 0x0, // Vector Multiply Word Signed, Modulo, Integer and Accumulate EVX-form (evmwsmiaa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWSMFAN, 0xfc0007ff, 0x100005db, 0x0, // Vector Multiply Word Signed, Modulo, Fractional and Accumulate Negative EVX-form (evmwsmfan RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWSMIA, 0xfc0007ff, 0x10000479, 0x0, // Vector Multiply Word Signed, Modulo, Integer to Accumulator EVX-form (evmwsmia RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWSMIAN, 0xfc0007ff, 0x100005d9, 0x0, // Vector Multiply Word Signed, Modulo, Integer and Accumulate Negative EVX-form (evmwsmian RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWSSF, 0xfc0007ff, 0x10000453, 0x0, // Vector Multiply Word Signed, Saturate, Fractional EVX-form (evmwssf RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWSSFA, 0xfc0007ff, 0x10000473, 0x0, // Vector Multiply Word Signed, Saturate, Fractional to Accumulator EVX-form (evmwssfa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWSSFAA, 0xfc0007ff, 0x10000553, 0x0, // Vector Multiply Word Signed, Saturate, Fractional and Accumulate EVX-form (evmwssfaa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWUMI, 0xfc0007ff, 0x10000458, 0x0, // Vector Multiply Word Unsigned, Modulo, Integer EVX-form (evmwumi RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWSSFAN, 0xfc0007ff, 0x100005d3, 0x0, // Vector Multiply Word Signed, Saturate, Fractional and Accumulate Negative EVX-form (evmwssfan RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWUMIA, 0xfc0007ff, 0x10000478, 0x0, // Vector Multiply Word Unsigned, Modulo, Integer to Accumulator EVX-form (evmwumia RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWUMIAA, 0xfc0007ff, 0x10000558, 0x0, // Vector Multiply Word Unsigned, Modulo, Integer and Accumulate EVX-form (evmwumiaa RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVNAND, 0xfc0007ff, 0x1000021e, 0x0, // Vector NAND EVX-form (evnand RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVMWUMIAN, 0xfc0007ff, 0x100005d8, 0x0, // Vector Multiply Word Unsigned, Modulo, Integer and Accumulate Negative EVX-form (evmwumian RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVNEG, 0xfc0007ff, 0x10000209, 0xf800, // Vector Negate EVX-form (evneg RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVNOR, 0xfc0007ff, 0x10000218, 0x0, // Vector NOR EVX-form (evnor RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVORC, 0xfc0007ff, 0x1000021b, 0x0, // Vector OR with Complement EVX-form (evorc RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVOR, 0xfc0007ff, 0x10000217, 0x0, // Vector OR EVX-form (evor RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVRLW, 0xfc0007ff, 0x10000228, 0x0, // Vector Rotate Left Word EVX-form (evrlw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVRLWI, 0xfc0007ff, 0x1000022a, 0x0, // Vector Rotate Left Word Immediate EVX-form (evrlwi RT,RA,UI) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}}, + {EVSEL, 0xfc0007f8, 0x10000278, 0x0, // Vector Select EVS-form (evsel RT,RA,RB,BFA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_CondRegField_29_31}}, + {EVRNDW, 0xfc0007ff, 0x1000020c, 0xf800, // Vector Round Word EVX-form (evrndw RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVSLW, 0xfc0007ff, 0x10000224, 0x0, // Vector Shift Left Word EVX-form (evslw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVSPLATFI, 0xfc0007ff, 0x1000022b, 0xf800, // Vector Splat Fractional Immediate EVX-form (evsplatfi RT,SI) + [5]*argField{ap_Reg_6_10, ap_ImmSigned_11_15}}, + {EVSRWIS, 0xfc0007ff, 0x10000223, 0x0, // Vector Shift Right Word Immediate Signed EVX-form (evsrwis RT,RA,UI) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}}, + {EVSLWI, 0xfc0007ff, 0x10000226, 0x0, // Vector Shift Left Word Immediate EVX-form (evslwi RT,RA,UI) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}}, + {EVSPLATI, 0xfc0007ff, 0x10000229, 0xf800, // Vector Splat Immediate EVX-form (evsplati RT,SI) + [5]*argField{ap_Reg_6_10, ap_ImmSigned_11_15}}, + {EVSRWIU, 0xfc0007ff, 0x10000222, 0x0, // Vector Shift Right Word Immediate Unsigned EVX-form (evsrwiu RT,RA,UI) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}}, + {EVSRWS, 0xfc0007ff, 0x10000221, 0x0, // Vector Shift Right Word Signed EVX-form (evsrws RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVSTDD, 0xfc0007ff, 0x10000321, 0x0, // Vector Store Double of Double EVX-form (evstdd RS,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVSRWU, 0xfc0007ff, 0x10000220, 0x0, // Vector Shift Right Word Unsigned EVX-form (evsrwu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVSTDDX, 0xfc0007ff, 0x10000320, 0x0, // Vector Store Double of Double Indexed EVX-form (evstddx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVSTDH, 0xfc0007ff, 0x10000325, 0x0, // Vector Store Double of Four Halfwords EVX-form (evstdh RS,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVSTDW, 0xfc0007ff, 0x10000323, 0x0, // Vector Store Double of Two Words EVX-form (evstdw RS,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVSTDHX, 0xfc0007ff, 0x10000324, 0x0, // Vector Store Double of Four Halfwords Indexed EVX-form (evstdhx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVSTDWX, 0xfc0007ff, 0x10000322, 0x0, // Vector Store Double of Two Words Indexed EVX-form (evstdwx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVSTWHE, 0xfc0007ff, 0x10000331, 0x0, // Vector Store Word of Two Halfwords from Even EVX-form (evstwhe RS,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVSTWHO, 0xfc0007ff, 0x10000335, 0x0, // Vector Store Word of Two Halfwords from Odd EVX-form (evstwho RS,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVSTWWE, 0xfc0007ff, 0x10000339, 0x0, // Vector Store Word of Word from Even EVX-form (evstwwe RS,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVSTWHEX, 0xfc0007ff, 0x10000330, 0x0, // Vector Store Word of Two Halfwords from Even Indexed EVX-form (evstwhex RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVSTWHOX, 0xfc0007ff, 0x10000334, 0x0, // Vector Store Word of Two Halfwords from Odd Indexed EVX-form (evstwhox RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVSTWWEX, 0xfc0007ff, 0x10000338, 0x0, // Vector Store Word of Word from Even Indexed EVX-form (evstwwex RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVSTWWO, 0xfc0007ff, 0x1000033d, 0x0, // Vector Store Word of Word from Odd EVX-form (evstwwo RS,D(RA)) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}}, + {EVSUBFSMIAAW, 0xfc0007ff, 0x100004cb, 0xf800, // Vector Subtract Signed, Modulo, Integer to Accumulator Word EVX-form (evsubfsmiaaw RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVSTWWOX, 0xfc0007ff, 0x1000033c, 0x0, // Vector Store Word of Word from Odd Indexed EVX-form (evstwwox RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVSUBFSSIAAW, 0xfc0007ff, 0x100004c3, 0xf800, // Vector Subtract Signed, Saturate, Integer to Accumulator Word EVX-form (evsubfssiaaw RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVSUBFUMIAAW, 0xfc0007ff, 0x100004ca, 0xf800, // Vector Subtract Unsigned, Modulo, Integer to Accumulator Word EVX-form (evsubfumiaaw RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVSUBFUSIAAW, 0xfc0007ff, 0x100004c2, 0xf800, // Vector Subtract Unsigned, Saturate, Integer to Accumulator Word EVX-form (evsubfusiaaw RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVSUBFW, 0xfc0007ff, 0x10000204, 0x0, // Vector Subtract from Word EVX-form (evsubfw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVSUBIFW, 0xfc0007ff, 0x10000206, 0x0, // Vector Subtract Immediate from Word EVX-form (evsubifw RT,UI,RB) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_11_15, ap_Reg_16_20}}, + {EVXOR, 0xfc0007ff, 0x10000216, 0x0, // Vector XOR EVX-form (evxor RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVFSABS, 0xfc0007ff, 0x10000284, 0xf800, // Vector Floating-Point Single-Precision Absolute Value EVX-form (evfsabs RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVFSNABS, 0xfc0007ff, 0x10000285, 0xf800, // Vector Floating-Point Single-Precision Negative Absolute Value EVX-form (evfsnabs RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVFSNEG, 0xfc0007ff, 0x10000286, 0xf800, // Vector Floating-Point Single-Precision Negate EVX-form (evfsneg RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EVFSADD, 0xfc0007ff, 0x10000280, 0x0, // Vector Floating-Point Single-Precision Add EVX-form (evfsadd RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVFSMUL, 0xfc0007ff, 0x10000288, 0x0, // Vector Floating-Point Single-Precision Multiply EVX-form (evfsmul RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVFSSUB, 0xfc0007ff, 0x10000281, 0x0, // Vector Floating-Point Single-Precision Subtract EVX-form (evfssub RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVFSDIV, 0xfc0007ff, 0x10000289, 0x0, // Vector Floating-Point Single-Precision Divide EVX-form (evfsdiv RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVFSCMPGT, 0xfc0007ff, 0x1000028c, 0x600000, // Vector Floating-Point Single-Precision Compare Greater Than EVX-form (evfscmpgt BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EVFSCMPLT, 0xfc0007ff, 0x1000028d, 0x600000, // Vector Floating-Point Single-Precision Compare Less Than EVX-form (evfscmplt BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EVFSCMPEQ, 0xfc0007ff, 0x1000028e, 0x600000, // Vector Floating-Point Single-Precision Compare Equal EVX-form (evfscmpeq BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EVFSTSTGT, 0xfc0007ff, 0x1000029c, 0x600000, // Vector Floating-Point Single-Precision Test Greater Than EVX-form (evfststgt BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EVFSTSTLT, 0xfc0007ff, 0x1000029d, 0x600000, // Vector Floating-Point Single-Precision Test Less Than EVX-form (evfststlt BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EVFSTSTEQ, 0xfc0007ff, 0x1000029e, 0x600000, // Vector Floating-Point Single-Precision Test Equal EVX-form (evfststeq BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EVFSCFSI, 0xfc0007ff, 0x10000291, 0x1f0000, // Vector Convert Floating-Point Single-Precision from Signed Integer EVX-form (evfscfsi RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EVFSCFSF, 0xfc0007ff, 0x10000293, 0x1f0000, // Vector Convert Floating-Point Single-Precision from Signed Fraction EVX-form (evfscfsf RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EVFSCFUI, 0xfc0007ff, 0x10000290, 0x1f0000, // Vector Convert Floating-Point Single-Precision from Unsigned Integer EVX-form (evfscfui RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EVFSCFUF, 0xfc0007ff, 0x10000292, 0x1f0000, // Vector Convert Floating-Point Single-Precision from Unsigned Fraction EVX-form (evfscfuf RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EVFSCTSI, 0xfc0007ff, 0x10000295, 0x1f0000, // Vector Convert Floating-Point Single-Precision to Signed Integer EVX-form (evfsctsi RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EVFSCTUI, 0xfc0007ff, 0x10000294, 0x1f0000, // Vector Convert Floating-Point Single-Precision to Unsigned Integer EVX-form (evfsctui RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EVFSCTSIZ, 0xfc0007ff, 0x1000029a, 0x1f0000, // Vector Convert Floating-Point Single-Precision to Signed Integer with Round toward Zero EVX-form (evfsctsiz RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EVFSCTUIZ, 0xfc0007ff, 0x10000298, 0x1f0000, // Vector Convert Floating-Point Single-Precision to Unsigned Integer with Round toward Zero EVX-form (evfsctuiz RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EVFSCTSF, 0xfc0007ff, 0x10000297, 0x1f0000, // Vector Convert Floating-Point Single-Precision to Signed Fraction EVX-form (evfsctsf RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EVFSCTUF, 0xfc0007ff, 0x10000296, 0x1f0000, // Vector Convert Floating-Point Single-Precision to Unsigned Fraction EVX-form (evfsctuf RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFSABS, 0xfc0007ff, 0x100002c4, 0xf800, // Floating-Point Single-Precision Absolute Value EVX-form (efsabs RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EFSNEG, 0xfc0007ff, 0x100002c6, 0xf800, // Floating-Point Single-Precision Negate EVX-form (efsneg RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EFSNABS, 0xfc0007ff, 0x100002c5, 0xf800, // Floating-Point Single-Precision Negative Absolute Value EVX-form (efsnabs RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EFSADD, 0xfc0007ff, 0x100002c0, 0x0, // Floating-Point Single-Precision Add EVX-form (efsadd RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EFSMUL, 0xfc0007ff, 0x100002c8, 0x0, // Floating-Point Single-Precision Multiply EVX-form (efsmul RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EFSSUB, 0xfc0007ff, 0x100002c1, 0x0, // Floating-Point Single-Precision Subtract EVX-form (efssub RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EFSDIV, 0xfc0007ff, 0x100002c9, 0x0, // Floating-Point Single-Precision Divide EVX-form (efsdiv RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EFSCMPGT, 0xfc0007ff, 0x100002cc, 0x600000, // Floating-Point Single-Precision Compare Greater Than EVX-form (efscmpgt BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EFSCMPLT, 0xfc0007ff, 0x100002cd, 0x600000, // Floating-Point Single-Precision Compare Less Than EVX-form (efscmplt BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EFSCMPEQ, 0xfc0007ff, 0x100002ce, 0x600000, // Floating-Point Single-Precision Compare Equal EVX-form (efscmpeq BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EFSTSTGT, 0xfc0007ff, 0x100002dc, 0x600000, // Floating-Point Single-Precision Test Greater Than EVX-form (efststgt BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EFSTSTLT, 0xfc0007ff, 0x100002dd, 0x600000, // Floating-Point Single-Precision Test Less Than EVX-form (efststlt BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EFSTSTEQ, 0xfc0007ff, 0x100002de, 0x600000, // Floating-Point Single-Precision Test Equal EVX-form (efststeq BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EFSCFSI, 0xfc0007ff, 0x100002d1, 0x1f0000, // Convert Floating-Point Single-Precision from Signed Integer EVX-form (efscfsi RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFSCFSF, 0xfc0007ff, 0x100002d3, 0x1f0000, // Convert Floating-Point Single-Precision from Signed Fraction EVX-form (efscfsf RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFSCTSI, 0xfc0007ff, 0x100002d5, 0x1f0000, // Convert Floating-Point Single-Precision to Signed Integer EVX-form (efsctsi RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFSCFUI, 0xfc0007ff, 0x100002d0, 0x1f0000, // Convert Floating-Point Single-Precision from Unsigned Integer EVX-form (efscfui RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFSCFUF, 0xfc0007ff, 0x100002d2, 0x1f0000, // Convert Floating-Point Single-Precision from Unsigned Fraction EVX-form (efscfuf RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFSCTUI, 0xfc0007ff, 0x100002d4, 0x1f0000, // Convert Floating-Point Single-Precision to Unsigned Integer EVX-form (efsctui RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFSCTSIZ, 0xfc0007ff, 0x100002da, 0x1f0000, // Convert Floating-Point Single-Precision to Signed Integer with Round toward Zero EVX-form (efsctsiz RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFSCTSF, 0xfc0007ff, 0x100002d7, 0x1f0000, // Convert Floating-Point Single-Precision to Signed Fraction EVX-form (efsctsf RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFSCTUIZ, 0xfc0007ff, 0x100002d8, 0x1f0000, // Convert Floating-Point Single-Precision to Unsigned Integer with Round toward Zero EVX-form (efsctuiz RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFSCTUF, 0xfc0007ff, 0x100002d6, 0x1f0000, // Convert Floating-Point Single-Precision to Unsigned Fraction EVX-form (efsctuf RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDABS, 0xfc0007ff, 0x100002e4, 0xf800, // Floating-Point Double-Precision Absolute Value EVX-form (efdabs RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EFDNEG, 0xfc0007ff, 0x100002e6, 0xf800, // Floating-Point Double-Precision Negate EVX-form (efdneg RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EFDNABS, 0xfc0007ff, 0x100002e5, 0xf800, // Floating-Point Double-Precision Negative Absolute Value EVX-form (efdnabs RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {EFDADD, 0xfc0007ff, 0x100002e0, 0x0, // Floating-Point Double-Precision Add EVX-form (efdadd RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EFDMUL, 0xfc0007ff, 0x100002e8, 0x0, // Floating-Point Double-Precision Multiply EVX-form (efdmul RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EFDSUB, 0xfc0007ff, 0x100002e1, 0x0, // Floating-Point Double-Precision Subtract EVX-form (efdsub RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EFDDIV, 0xfc0007ff, 0x100002e9, 0x0, // Floating-Point Double-Precision Divide EVX-form (efddiv RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EFDCMPGT, 0xfc0007ff, 0x100002ec, 0x600000, // Floating-Point Double-Precision Compare Greater Than EVX-form (efdcmpgt BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EFDCMPEQ, 0xfc0007ff, 0x100002ee, 0x600000, // Floating-Point Double-Precision Compare Equal EVX-form (efdcmpeq BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EFDCMPLT, 0xfc0007ff, 0x100002ed, 0x600000, // Floating-Point Double-Precision Compare Less Than EVX-form (efdcmplt BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EFDTSTGT, 0xfc0007ff, 0x100002fc, 0x600000, // Floating-Point Double-Precision Test Greater Than EVX-form (efdtstgt BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EFDTSTLT, 0xfc0007ff, 0x100002fd, 0x600000, // Floating-Point Double-Precision Test Less Than EVX-form (efdtstlt BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EFDCFSI, 0xfc0007ff, 0x100002f1, 0x1f0000, // Convert Floating-Point Double-Precision from Signed Integer EVX-form (efdcfsi RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDTSTEQ, 0xfc0007ff, 0x100002fe, 0x600000, // Floating-Point Double-Precision Test Equal EVX-form (efdtsteq BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {EFDCFUI, 0xfc0007ff, 0x100002f0, 0x1f0000, // Convert Floating-Point Double-Precision from Unsigned Integer EVX-form (efdcfui RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDCFSID, 0xfc0007ff, 0x100002e3, 0x1f0000, // Convert Floating-Point Double-Precision from Signed Integer Doubleword EVX-form (efdcfsid RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDCFSF, 0xfc0007ff, 0x100002f3, 0x1f0000, // Convert Floating-Point Double-Precision from Signed Fraction EVX-form (efdcfsf RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDCFUF, 0xfc0007ff, 0x100002f2, 0x1f0000, // Convert Floating-Point Double-Precision from Unsigned Fraction EVX-form (efdcfuf RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDCFUID, 0xfc0007ff, 0x100002e2, 0x1f0000, // Convert Floating-Point Double-Precision from Unsigned Integer Doubleword EVX-form (efdcfuid RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDCTSI, 0xfc0007ff, 0x100002f5, 0x1f0000, // Convert Floating-Point Double-Precision to Signed Integer EVX-form (efdctsi RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDCTUI, 0xfc0007ff, 0x100002f4, 0x1f0000, // Convert Floating-Point Double-Precision to Unsigned Integer EVX-form (efdctui RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDCTSIDZ, 0xfc0007ff, 0x100002eb, 0x1f0000, // Convert Floating-Point Double-Precision to Signed Integer Doubleword with Round toward Zero EVX-form (efdctsidz RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDCTUIDZ, 0xfc0007ff, 0x100002ea, 0x1f0000, // Convert Floating-Point Double-Precision to Unsigned Integer Doubleword with Round toward Zero EVX-form (efdctuidz RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDCTSIZ, 0xfc0007ff, 0x100002fa, 0x1f0000, // Convert Floating-Point Double-Precision to Signed Integer with Round toward Zero EVX-form (efdctsiz RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDCTSF, 0xfc0007ff, 0x100002f7, 0x1f0000, // Convert Floating-Point Double-Precision to Signed Fraction EVX-form (efdctsf RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDCTUF, 0xfc0007ff, 0x100002f6, 0x1f0000, // Convert Floating-Point Double-Precision to Unsigned Fraction EVX-form (efdctuf RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDCTUIZ, 0xfc0007ff, 0x100002f8, 0x1f0000, // Convert Floating-Point Double-Precision to Unsigned Integer with Round toward Zero EVX-form (efdctuiz RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFDCFS, 0xfc0007ff, 0x100002ef, 0x1f0000, // Floating-Point Double-Precision Convert from Single-Precision EVX-form (efdcfs RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {EFSCFD, 0xfc0007ff, 0x100002cf, 0x1f0000, // Floating-Point Single-Precision Convert from Double-Precision EVX-form (efscfd RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {DLMZB, 0xfc0007ff, 0x7c00009c, 0x0, // Determine Leftmost Zero Byte X-form (dlmzb RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {DLMZBCC, 0xfc0007ff, 0x7c00009d, 0x0, // Determine Leftmost Zero Byte X-form (dlmzb. RA,RS,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {MACCHW, 0xfc0007ff, 0x10000158, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (macchw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWCC, 0xfc0007ff, 0x10000159, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (macchw. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWO, 0xfc0007ff, 0x10000558, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (macchwo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWOCC, 0xfc0007ff, 0x10000559, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (macchwo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWS, 0xfc0007ff, 0x100001d8, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (macchws RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWSCC, 0xfc0007ff, 0x100001d9, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (macchws. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWSO, 0xfc0007ff, 0x100005d8, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (macchwso RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWSOCC, 0xfc0007ff, 0x100005d9, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (macchwso. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWU, 0xfc0007ff, 0x10000118, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Unsigned XO-form (macchwu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWUCC, 0xfc0007ff, 0x10000119, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Unsigned XO-form (macchwu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWUO, 0xfc0007ff, 0x10000518, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Unsigned XO-form (macchwuo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWUOCC, 0xfc0007ff, 0x10000519, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Unsigned XO-form (macchwuo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWSU, 0xfc0007ff, 0x10000198, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Unsigned XO-form (macchwsu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWSUCC, 0xfc0007ff, 0x10000199, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Unsigned XO-form (macchwsu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWSUO, 0xfc0007ff, 0x10000598, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Unsigned XO-form (macchwsuo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACCHWSUOCC, 0xfc0007ff, 0x10000599, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Unsigned XO-form (macchwsuo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHW, 0xfc0007ff, 0x10000058, 0x0, // Multiply Accumulate High Halfword to Word Modulo Signed XO-form (machhw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWCC, 0xfc0007ff, 0x10000059, 0x0, // Multiply Accumulate High Halfword to Word Modulo Signed XO-form (machhw. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWO, 0xfc0007ff, 0x10000458, 0x0, // Multiply Accumulate High Halfword to Word Modulo Signed XO-form (machhwo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWOCC, 0xfc0007ff, 0x10000459, 0x0, // Multiply Accumulate High Halfword to Word Modulo Signed XO-form (machhwo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWS, 0xfc0007ff, 0x100000d8, 0x0, // Multiply Accumulate High Halfword to Word Saturate Signed XO-form (machhws RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWSCC, 0xfc0007ff, 0x100000d9, 0x0, // Multiply Accumulate High Halfword to Word Saturate Signed XO-form (machhws. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWSO, 0xfc0007ff, 0x100004d8, 0x0, // Multiply Accumulate High Halfword to Word Saturate Signed XO-form (machhwso RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWSOCC, 0xfc0007ff, 0x100004d9, 0x0, // Multiply Accumulate High Halfword to Word Saturate Signed XO-form (machhwso. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWU, 0xfc0007ff, 0x10000018, 0x0, // Multiply Accumulate High Halfword to Word Modulo Unsigned XO-form (machhwu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWUCC, 0xfc0007ff, 0x10000019, 0x0, // Multiply Accumulate High Halfword to Word Modulo Unsigned XO-form (machhwu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWUO, 0xfc0007ff, 0x10000418, 0x0, // Multiply Accumulate High Halfword to Word Modulo Unsigned XO-form (machhwuo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWUOCC, 0xfc0007ff, 0x10000419, 0x0, // Multiply Accumulate High Halfword to Word Modulo Unsigned XO-form (machhwuo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWSU, 0xfc0007ff, 0x10000098, 0x0, // Multiply Accumulate High Halfword to Word Saturate Unsigned XO-form (machhwsu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWSUCC, 0xfc0007ff, 0x10000099, 0x0, // Multiply Accumulate High Halfword to Word Saturate Unsigned XO-form (machhwsu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWSUO, 0xfc0007ff, 0x10000498, 0x0, // Multiply Accumulate High Halfword to Word Saturate Unsigned XO-form (machhwsuo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACHHWSUOCC, 0xfc0007ff, 0x10000499, 0x0, // Multiply Accumulate High Halfword to Word Saturate Unsigned XO-form (machhwsuo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHW, 0xfc0007ff, 0x10000358, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (maclhw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWCC, 0xfc0007ff, 0x10000359, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (maclhw. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWO, 0xfc0007ff, 0x10000758, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (maclhwo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWOCC, 0xfc0007ff, 0x10000759, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (maclhwo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWS, 0xfc0007ff, 0x100003d8, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (maclhws RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWSCC, 0xfc0007ff, 0x100003d9, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (maclhws. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWSO, 0xfc0007ff, 0x100007d8, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (maclhwso RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWSOCC, 0xfc0007ff, 0x100007d9, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (maclhwso. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWU, 0xfc0007ff, 0x10000318, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Unsigned XO-form (maclhwu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWUCC, 0xfc0007ff, 0x10000319, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Unsigned XO-form (maclhwu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWUO, 0xfc0007ff, 0x10000718, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Unsigned XO-form (maclhwuo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWUOCC, 0xfc0007ff, 0x10000719, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Unsigned XO-form (maclhwuo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULCHW, 0xfc0007ff, 0x10000150, 0x0, // Multiply Cross Halfword to Word Signed X-form (mulchw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULCHWCC, 0xfc0007ff, 0x10000151, 0x0, // Multiply Cross Halfword to Word Signed X-form (mulchw. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWSU, 0xfc0007ff, 0x10000398, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Unsigned XO-form (maclhwsu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWSUCC, 0xfc0007ff, 0x10000399, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Unsigned XO-form (maclhwsu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWSUO, 0xfc0007ff, 0x10000798, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Unsigned XO-form (maclhwsuo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MACLHWSUOCC, 0xfc0007ff, 0x10000799, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Unsigned XO-form (maclhwsuo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULCHWU, 0xfc0007ff, 0x10000110, 0x0, // Multiply Cross Halfword to Word Unsigned X-form (mulchwu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULCHWUCC, 0xfc0007ff, 0x10000111, 0x0, // Multiply Cross Halfword to Word Unsigned X-form (mulchwu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULHHW, 0xfc0007ff, 0x10000050, 0x0, // Multiply High Halfword to Word Signed X-form (mulhhw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULHHWCC, 0xfc0007ff, 0x10000051, 0x0, // Multiply High Halfword to Word Signed X-form (mulhhw. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULLHW, 0xfc0007ff, 0x10000350, 0x0, // Multiply Low Halfword to Word Signed X-form (mullhw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULLHWCC, 0xfc0007ff, 0x10000351, 0x0, // Multiply Low Halfword to Word Signed X-form (mullhw. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULHHWU, 0xfc0007ff, 0x10000010, 0x0, // Multiply High Halfword to Word Unsigned X-form (mulhhwu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULHHWUCC, 0xfc0007ff, 0x10000011, 0x0, // Multiply High Halfword to Word Unsigned X-form (mulhhwu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULLHWU, 0xfc0007ff, 0x10000310, 0x0, // Multiply Low Halfword to Word Unsigned X-form (mullhwu RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MULLHWUCC, 0xfc0007ff, 0x10000311, 0x0, // Multiply Low Halfword to Word Unsigned X-form (mullhwu. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACCHW, 0xfc0007ff, 0x1000015c, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (nmacchw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACCHWCC, 0xfc0007ff, 0x1000015d, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (nmacchw. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACCHWO, 0xfc0007ff, 0x1000055c, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (nmacchwo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACCHWOCC, 0xfc0007ff, 0x1000055d, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (nmacchwo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACCHWS, 0xfc0007ff, 0x100001dc, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (nmacchws RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACCHWSCC, 0xfc0007ff, 0x100001dd, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (nmacchws. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACCHWSO, 0xfc0007ff, 0x100005dc, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (nmacchwso RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACCHWSOCC, 0xfc0007ff, 0x100005dd, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (nmacchwso. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACHHW, 0xfc0007ff, 0x1000005c, 0x0, // Negative Multiply Accumulate High Halfword to Word Modulo Signed XO-form (nmachhw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACHHWCC, 0xfc0007ff, 0x1000005d, 0x0, // Negative Multiply Accumulate High Halfword to Word Modulo Signed XO-form (nmachhw. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACHHWO, 0xfc0007ff, 0x1000045c, 0x0, // Negative Multiply Accumulate High Halfword to Word Modulo Signed XO-form (nmachhwo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACHHWOCC, 0xfc0007ff, 0x1000045d, 0x0, // Negative Multiply Accumulate High Halfword to Word Modulo Signed XO-form (nmachhwo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACHHWS, 0xfc0007ff, 0x100000dc, 0x0, // Negative Multiply Accumulate High Halfword to Word Saturate Signed XO-form (nmachhws RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACHHWSCC, 0xfc0007ff, 0x100000dd, 0x0, // Negative Multiply Accumulate High Halfword to Word Saturate Signed XO-form (nmachhws. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACHHWSO, 0xfc0007ff, 0x100004dc, 0x0, // Negative Multiply Accumulate High Halfword to Word Saturate Signed XO-form (nmachhwso RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACHHWSOCC, 0xfc0007ff, 0x100004dd, 0x0, // Negative Multiply Accumulate High Halfword to Word Saturate Signed XO-form (nmachhwso. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACLHW, 0xfc0007ff, 0x1000035c, 0x0, // Negative Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (nmaclhw RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACLHWCC, 0xfc0007ff, 0x1000035d, 0x0, // Negative Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (nmaclhw. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACLHWO, 0xfc0007ff, 0x1000075c, 0x0, // Negative Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (nmaclhwo RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACLHWOCC, 0xfc0007ff, 0x1000075d, 0x0, // Negative Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (nmaclhwo. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACLHWS, 0xfc0007ff, 0x100003dc, 0x0, // Negative Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (nmaclhws RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACLHWSCC, 0xfc0007ff, 0x100003dd, 0x0, // Negative Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (nmaclhws. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACLHWSO, 0xfc0007ff, 0x100007dc, 0x0, // Negative Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (nmaclhwso RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {NMACLHWSOCC, 0xfc0007ff, 0x100007dd, 0x0, // Negative Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (nmaclhwso. RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ICBI, 0xfc0007fe, 0x7c0007ac, 0x3e00001, // Instruction Cache Block Invalidate X-form (icbi RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {ICBT, 0xfc0007fe, 0x7c00002c, 0x2000001, // Instruction Cache Block Touch X-form (icbt CT, RA, RB) + [5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DCBA, 0xfc0007fe, 0x7c0005ec, 0x3e00001, // Data Cache Block Allocate X-form (dcba RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {DCBT, 0xfc0007fe, 0x7c00022c, 0x1, // Data Cache Block Touch X-form (dcbt RA,RB,TH) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_6_10}}, + {DCBT, 0xfc0007fe, 0x7c00022c, 0x1, // Data Cache Block Touch X-form (dcbt TH,RA,RB) + [5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DCBTST, 0xfc0007fe, 0x7c0001ec, 0x1, // Data Cache Block Touch for Store X-form (dcbtst RA,RB,TH) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_6_10}}, + {DCBTST, 0xfc0007fe, 0x7c0001ec, 0x1, // Data Cache Block Touch for Store X-form (dcbtst TH,RA,RB) + [5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DCBZ, 0xfc0007fe, 0x7c0007ec, 0x3e00001, // Data Cache Block set to Zero X-form (dcbz RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {DCBST, 0xfc0007fe, 0x7c00006c, 0x3e00001, // Data Cache Block Store X-form (dcbst RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {DCBF, 0xfc0007fe, 0x7c0000ac, 0x3800001, // Data Cache Block Flush X-form (dcbf RA,RB,L) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_9_10}}, + {ISYNC, 0xfc0007fe, 0x4c00012c, 0x3fff801, // Instruction Synchronize XL-form (isync) + [5]*argField{}}, + {LBARX, 0xfc0007ff, 0x7c000068, 0x0, // Load Byte And Reserve Indexed X-form [Category: Phased-In] (lbarx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LBARX, 0xfc0007fe, 0x7c000068, 0x0, // Load Byte And Reserve Indexed X-form [Category: Phased-In] (lbarx RT,RA,RB,EH) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}}, + {LHARX, 0xfc0007ff, 0x7c0000e8, 0x0, // Load Halfword And Reserve Indexed X-form [Category: Phased-In] (lharx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LHARX, 0xfc0007fe, 0x7c0000e8, 0x0, // Load Halfword And Reserve Indexed X-form [Category: Phased-In] (lharx RT,RA,RB,EH) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}}, + {LWARX, 0xfc0007ff, 0x7c000028, 0x0, // Load Word And Reserve Indexed X-form (lwarx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LWARX, 0xfc0007ff, 0x7c000028, 0x0, // Load Word And Reserve Indexed X-form (lwarx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LWARX, 0xfc0007fe, 0x7c000028, 0x0, // Load Word And Reserve Indexed X-form (lwarx RT,RA,RB,EH) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}}, + {STBCXCC, 0xfc0007ff, 0x7c00056d, 0x0, // Store Byte Conditional Indexed X-form [Category: Phased-In] (stbcx. RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STHCXCC, 0xfc0007ff, 0x7c0005ad, 0x0, // Store Halfword Conditional Indexed X-form [Category: Phased-In] (sthcx. RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STWCXCC, 0xfc0007ff, 0x7c00012d, 0x0, // Store Word Conditional Indexed X-form (stwcx. RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LDARX, 0xfc0007ff, 0x7c0000a8, 0x0, // Load Doubleword And Reserve Indexed X-form (ldarx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LDARX, 0xfc0007fe, 0x7c0000a8, 0x0, // Load Doubleword And Reserve Indexed X-form (ldarx RT,RA,RB,EH) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}}, + {STDCXCC, 0xfc0007ff, 0x7c0001ad, 0x0, // Store Doubleword Conditional Indexed X-form (stdcx. RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LQARX, 0xfc0007ff, 0x7c000228, 0x0, // Load Quadword And Reserve Indexed X-form (lqarx RTp,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LQARX, 0xfc0007fe, 0x7c000228, 0x0, // Load Quadword And Reserve Indexed X-form (lqarx RTp,RA,RB,EH) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}}, + {STQCXCC, 0xfc0007ff, 0x7c00016d, 0x0, // Store Quadword Conditional Indexed X-form (stqcx. RSp,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {SYNC, 0xfc0007fe, 0x7c0004ac, 0x390f801, // Synchronize X-form (sync L, E) + [5]*argField{ap_ImmUnsigned_9_10, ap_ImmUnsigned_12_15}}, + {EIEIO, 0xfc0007fe, 0x7c0006ac, 0x3fff801, // Enforce In-order Execution of I/O X-form (eieio) + [5]*argField{}}, + {MBAR, 0xfc0007fe, 0x7c0006ac, 0x1ff801, // Memory Barrier X-form (mbar MO) + [5]*argField{ap_ImmUnsigned_6_10}}, + {WAIT, 0xfc0007fe, 0x7c00007c, 0x39ff801, // Wait X-form (wait WC) + [5]*argField{ap_ImmUnsigned_9_10}}, + {TBEGINCC, 0xfc0007ff, 0x7c00051d, 0x1dff800, // Transaction Begin X-form (tbegin. R) + [5]*argField{ap_ImmUnsigned_10_10}}, + {TENDCC, 0xfc0007ff, 0x7c00055d, 0x1fff800, // Transaction End X-form (tend. A) + [5]*argField{ap_ImmUnsigned_6_6}}, + {TABORTCC, 0xfc0007ff, 0x7c00071d, 0x3e0f800, // Transaction Abort X-form (tabort. RA) + [5]*argField{ap_Reg_11_15}}, + {TABORTWCCC, 0xfc0007ff, 0x7c00061d, 0x0, // Transaction Abort Word Conditional X-form (tabortwc. TO,RA,RB) + [5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {TABORTWCICC, 0xfc0007ff, 0x7c00069d, 0x0, // Transaction Abort Word Conditional Immediate X-form (tabortwci. TO,RA,SI) + [5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_ImmSigned_16_20}}, + {TABORTDCCC, 0xfc0007ff, 0x7c00065d, 0x0, // Transaction Abort Doubleword Conditional X-form (tabortdc. TO,RA,RB) + [5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {TABORTDCICC, 0xfc0007ff, 0x7c0006dd, 0x0, // Transaction Abort Doubleword Conditional Immediate X-form (tabortdci. TO,RA, SI) + [5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_ImmSigned_16_20}}, + {TSRCC, 0xfc0007ff, 0x7c0005dd, 0x3dff800, // Transaction Suspend or Resume X-form (tsr. L) + [5]*argField{ap_ImmUnsigned_10_10}}, + {TCHECK, 0xfc0007fe, 0x7c00059c, 0x7ff801, // Transaction Check X-form (tcheck BF) + [5]*argField{ap_CondRegField_6_8}}, + {MFTB, 0xfc0007fe, 0x7c0002e6, 0x1, // Move From Time Base XFX-form (mftb RT,TBR) + [5]*argField{ap_Reg_6_10, ap_SpReg_16_20_11_15}}, + {RFEBB, 0xfc0007fe, 0x4c000124, 0x3fff001, // Return from Event-Based Branch XL-form (rfebb S) + [5]*argField{ap_ImmUnsigned_20_20}}, + {LBDX, 0xfc0007fe, 0x7c000406, 0x1, // Load Byte with Decoration Indexed X-form (lbdx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LHDX, 0xfc0007fe, 0x7c000446, 0x1, // Load Halfword with Decoration Indexed X-form (lhdx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LWDX, 0xfc0007fe, 0x7c000486, 0x1, // Load Word with Decoration Indexed X-form (lwdx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LDDX, 0xfc0007fe, 0x7c0004c6, 0x1, // Load Doubleword with Decoration Indexed X-form (lddx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LFDDX, 0xfc0007fe, 0x7c000646, 0x1, // Load Floating Doubleword with Decoration Indexed X-form (lfddx FRT,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STBDX, 0xfc0007fe, 0x7c000506, 0x1, // Store Byte with Decoration Indexed X-form (stbdx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STHDX, 0xfc0007fe, 0x7c000546, 0x1, // Store Halfword with Decoration Indexed X-form (sthdx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STWDX, 0xfc0007fe, 0x7c000586, 0x1, // Store Word with Decoration Indexed X-form (stwdx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STDDX, 0xfc0007fe, 0x7c0005c6, 0x1, // Store Doubleword with Decoration Indexed X-form (stddx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STFDDX, 0xfc0007fe, 0x7c000746, 0x1, // Store Floating Doubleword with Decoration Indexed X-form (stfddx FRS,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DSN, 0xfc0007fe, 0x7c0003c6, 0x3e00001, // Decorated Storage Notify X-form (dsn RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {ECIWX, 0xfc0007fe, 0x7c00026c, 0x1, // External Control In Word Indexed X-form (eciwx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ECOWX, 0xfc0007fe, 0x7c00036c, 0x1, // External Control Out Word Indexed X-form (ecowx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {SC, 0xfc000002, 0x44000002, 0x3fff01d, // System Call SC-form (sc LEV) + [5]*argField{ap_ImmUnsigned_20_26}}, + {RFID, 0xfc0007fe, 0x4c000024, 0x3fff801, // Return From Interrupt Doubleword XL-form (rfid) + [5]*argField{}}, + {HRFID, 0xfc0007fe, 0x4c000224, 0x3fff801, // Hypervisor Return From Interrupt Doubleword XL-form (hrfid) + [5]*argField{}}, + {DOZE, 0xfc0007fe, 0x4c000324, 0x3fff801, // Doze XL-form (doze) + [5]*argField{}}, + {NAP, 0xfc0007fe, 0x4c000364, 0x3fff801, // Nap XL-form (nap) + [5]*argField{}}, + {SLEEP, 0xfc0007fe, 0x4c0003a4, 0x3fff801, // Sleep XL-form (sleep) + [5]*argField{}}, + {RVWINKLE, 0xfc0007fe, 0x4c0003e4, 0x3fff801, // Rip Van Winkle XL-form (rvwinkle) + [5]*argField{}}, + {LBZCIX, 0xfc0007fe, 0x7c0006aa, 0x1, // Load Byte and Zero Caching Inhibited Indexed X-form (lbzcix RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LWZCIX, 0xfc0007fe, 0x7c00062a, 0x1, // Load Word and Zero Caching Inhibited Indexed X-form (lwzcix RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LHZCIX, 0xfc0007fe, 0x7c00066a, 0x1, // Load Halfword and Zero Caching Inhibited Indexed X-form (lhzcix RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LDCIX, 0xfc0007fe, 0x7c0006ea, 0x1, // Load Doubleword Caching Inhibited Indexed X-form (ldcix RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STBCIX, 0xfc0007fe, 0x7c0007aa, 0x1, // Store Byte Caching Inhibited Indexed X-form (stbcix RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STWCIX, 0xfc0007fe, 0x7c00072a, 0x1, // Store Word Caching Inhibited Indexed X-form (stwcix RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STHCIX, 0xfc0007fe, 0x7c00076a, 0x1, // Store Halfword Caching Inhibited Indexed X-form (sthcix RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STDCIX, 0xfc0007fe, 0x7c0007ea, 0x1, // Store Doubleword Caching Inhibited Indexed X-form (stdcix RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {TRECLAIMCC, 0xfc0007ff, 0x7c00075d, 0x3e0f800, // Transaction Reclaim X-form (treclaim. RA) + [5]*argField{ap_Reg_11_15}}, + {TRECHKPTCC, 0xfc0007ff, 0x7c0007dd, 0x3fff800, // Transaction Recheckpoint X-form (trechkpt.) + [5]*argField{}}, + {MTSPR, 0xfc0007fe, 0x7c0003a6, 0x1, // Move To Special Purpose Register XFX-form (mtspr SPR,RS) + [5]*argField{ap_SpReg_16_20_11_15, ap_Reg_6_10}}, + {MFSPR, 0xfc0007fe, 0x7c0002a6, 0x1, // Move From Special Purpose Register XFX-form (mfspr RT,SPR) + [5]*argField{ap_Reg_6_10, ap_SpReg_16_20_11_15}}, + {MTMSR, 0xfc0007fe, 0x7c000124, 0x1ef801, // Move To Machine State Register X-form (mtmsr RS,L) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_15_15}}, + {MTMSRD, 0xfc0007fe, 0x7c000164, 0x1ef801, // Move To Machine State Register Doubleword X-form (mtmsrd RS,L) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_15_15}}, + {MFMSR, 0xfc0007fe, 0x7c0000a6, 0x1ff801, // Move From Machine State Register X-form (mfmsr RT) + [5]*argField{ap_Reg_6_10}}, + {SLBIE, 0xfc0007fe, 0x7c000364, 0x3ff0001, // SLB Invalidate Entry X-form (slbie RB) + [5]*argField{ap_Reg_16_20}}, + {SLBIA, 0xfc0007fe, 0x7c0003e4, 0x31ff801, // SLB Invalidate All X-form (slbia IH) + [5]*argField{ap_ImmUnsigned_8_10}}, + {SLBMTE, 0xfc0007fe, 0x7c000324, 0x1f0001, // SLB Move To Entry X-form (slbmte RS,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {SLBMFEV, 0xfc0007fe, 0x7c0006a6, 0x1f0001, // SLB Move From Entry VSID X-form (slbmfev RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {SLBMFEE, 0xfc0007fe, 0x7c000726, 0x1f0001, // SLB Move From Entry ESID X-form (slbmfee RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {SLBFEECC, 0xfc0007ff, 0x7c0007a7, 0x1f0000, // SLB Find Entry ESID X-form (slbfee. RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {MTSR, 0xfc0007fe, 0x7c0001a4, 0x10f801, // Move To Segment Register X-form (mtsr SR,RS) + [5]*argField{ap_SpReg_12_15, ap_Reg_6_10}}, + {MTSRIN, 0xfc0007fe, 0x7c0001e4, 0x1f0001, // Move To Segment Register Indirect X-form (mtsrin RS,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {MFSR, 0xfc0007fe, 0x7c0004a6, 0x10f801, // Move From Segment Register X-form (mfsr RT,SR) + [5]*argField{ap_Reg_6_10, ap_SpReg_12_15}}, + {MFSRIN, 0xfc0007fe, 0x7c000526, 0x1f0001, // Move From Segment Register Indirect X-form (mfsrin RT,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_16_20}}, + {TLBIE, 0xfc0007fe, 0x7c000264, 0x1f0001, // TLB Invalidate Entry X-form (tlbie RB,RS) + [5]*argField{ap_Reg_16_20, ap_Reg_6_10}}, + {TLBIEL, 0xfc0007fe, 0x7c000224, 0x3ff0001, // TLB Invalidate Entry Local X-form (tlbiel RB) + [5]*argField{ap_Reg_16_20}}, + {TLBIA, 0xfc0007fe, 0x7c0002e4, 0x3fff801, // TLB Invalidate All X-form (tlbia) + [5]*argField{}}, + {TLBSYNC, 0xfc0007fe, 0x7c00046c, 0x3fff801, // TLB Synchronize X-form (tlbsync) + [5]*argField{}}, + {MSGSND, 0xfc0007fe, 0x7c00019c, 0x3ff0001, // Message Send X-form (msgsnd RB) + [5]*argField{ap_Reg_16_20}}, + {MSGCLR, 0xfc0007fe, 0x7c0001dc, 0x3ff0001, // Message Clear X-form (msgclr RB) + [5]*argField{ap_Reg_16_20}}, + {MSGSNDP, 0xfc0007fe, 0x7c00011c, 0x3ff0001, // Message Send Privileged X-form (msgsndp RB) + [5]*argField{ap_Reg_16_20}}, + {MSGCLRP, 0xfc0007fe, 0x7c00015c, 0x3ff0001, // Message Clear Privileged X-form (msgclrp RB) + [5]*argField{ap_Reg_16_20}}, + {MTTMR, 0xfc0007fe, 0x7c0003dc, 0x1, // Move To Thread Management Register XFX-form (mttmr TMR,RS) + [5]*argField{ap_SpReg_16_20_11_15, ap_Reg_6_10}}, + {SC, 0xfc000002, 0x44000002, 0x3fffffd, // System Call SC-form (sc) + [5]*argField{}}, + {RFI, 0xfc0007fe, 0x4c000064, 0x3fff801, // Return From Interrupt XL-form (rfi) + [5]*argField{}}, + {RFCI, 0xfc0007fe, 0x4c000066, 0x3fff801, // Return From Critical Interrupt XL-form (rfci) + [5]*argField{}}, + {RFDI, 0xfc0007fe, 0x4c00004e, 0x3fff801, // Return From Debug Interrupt X-form (rfdi) + [5]*argField{}}, + {RFMCI, 0xfc0007fe, 0x4c00004c, 0x3fff801, // Return From Machine Check Interrupt XL-form (rfmci) + [5]*argField{}}, + {RFGI, 0xfc0007fe, 0x4c0000cc, 0x3fff801, // Return From Guest Interrupt XL-form (rfgi) + [5]*argField{}}, + {EHPRIV, 0xfc0007fe, 0x7c00021c, 0x1, // Embedded Hypervisor Privilege XL-form (ehpriv OC) + [5]*argField{ap_ImmUnsigned_6_20}}, + {MTSPR, 0xfc0007fe, 0x7c0003a6, 0x1, // Move To Special Purpose Register XFX-form (mtspr SPR,RS) + [5]*argField{ap_SpReg_16_20_11_15, ap_Reg_6_10}}, + {MFSPR, 0xfc0007fe, 0x7c0002a6, 0x1, // Move From Special Purpose Register XFX-form (mfspr RT,SPR) + [5]*argField{ap_Reg_6_10, ap_SpReg_16_20_11_15}}, + {MTDCR, 0xfc0007fe, 0x7c000386, 0x1, // Move To Device Control Register XFX-form (mtdcr DCRN,RS) + [5]*argField{ap_SpReg_16_20_11_15, ap_Reg_6_10}}, + {MTDCRX, 0xfc0007fe, 0x7c000306, 0xf801, // Move To Device Control Register Indexed X-form (mtdcrx RA,RS) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10}}, + {MFDCR, 0xfc0007fe, 0x7c000286, 0x1, // Move From Device Control Register XFX-form (mfdcr RT,DCRN) + [5]*argField{ap_Reg_6_10, ap_SpReg_16_20_11_15}}, + {MFDCRX, 0xfc0007fe, 0x7c000206, 0xf801, // Move From Device Control Register Indexed X-form (mfdcrx RT,RA) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15}}, + {MTMSR, 0xfc0007fe, 0x7c000124, 0x1ff801, // Move To Machine State Register X-form (mtmsr RS) + [5]*argField{ap_Reg_6_10}}, + {MFMSR, 0xfc0007fe, 0x7c0000a6, 0x1ff801, // Move From Machine State Register X-form (mfmsr RT) + [5]*argField{ap_Reg_6_10}}, + {WRTEE, 0xfc0007fe, 0x7c000106, 0x1ff801, // Write MSR External Enable X-form (wrtee RS) + [5]*argField{ap_Reg_6_10}}, + {WRTEEI, 0xfc0007fe, 0x7c000146, 0x3ff7801, // Write MSR External Enable Immediate X-form (wrteei E) + [5]*argField{ap_ImmUnsigned_16_16}}, + {LBEPX, 0xfc0007fe, 0x7c0000be, 0x1, // Load Byte by External Process ID Indexed X-form (lbepx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LHEPX, 0xfc0007fe, 0x7c00023e, 0x1, // Load Halfword by External Process ID Indexed X-form (lhepx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LWEPX, 0xfc0007fe, 0x7c00003e, 0x1, // Load Word by External Process ID Indexed X-form (lwepx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LDEPX, 0xfc0007fe, 0x7c00003a, 0x1, // Load Doubleword by External Process ID Indexed X-form (ldepx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STBEPX, 0xfc0007fe, 0x7c0001be, 0x1, // Store Byte by External Process ID Indexed X-form (stbepx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STHEPX, 0xfc0007fe, 0x7c00033e, 0x1, // Store Halfword by External Process ID Indexed X-form (sthepx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STWEPX, 0xfc0007fe, 0x7c00013e, 0x1, // Store Word by External Process ID Indexed X-form (stwepx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STDEPX, 0xfc0007fe, 0x7c00013a, 0x1, // Store Doubleword by External Process ID Indexed X-form (stdepx RS,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DCBSTEP, 0xfc0007fe, 0x7c00007e, 0x3e00001, // Data Cache Block Store by External PID X-form (dcbstep RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {DCBTEP, 0xfc0007fe, 0x7c00027e, 0x1, // Data Cache Block Touch by External PID X-form (dcbtep TH,RA,RB) + [5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DCBFEP, 0xfc0007fe, 0x7c0000fe, 0x3800001, // Data Cache Block Flush by External PID X-form (dcbfep RA,RB,L) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_9_10}}, + {DCBTSTEP, 0xfc0007fe, 0x7c0001fe, 0x1, // Data Cache Block Touch for Store by External PID X-form (dcbtstep TH,RA,RB) + [5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ICBIEP, 0xfc0007fe, 0x7c0007be, 0x3e00001, // Instruction Cache Block Invalidate by External PID X-form (icbiep RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {DCBZEP, 0xfc0007fe, 0x7c0007fe, 0x3e00001, // Data Cache Block set to Zero by External PID X-form (dcbzep RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {LFDEPX, 0xfc0007fe, 0x7c0004be, 0x1, // Load Floating-Point Double by External Process ID Indexed X-form (lfdepx FRT,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STFDEPX, 0xfc0007fe, 0x7c0005be, 0x1, // Store Floating-Point Double by External Process ID Indexed X-form (stfdepx FRS,RA,RB) + [5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVLDDEPX, 0xfc0007fe, 0x7c00063e, 0x1, // Vector Load Doubleword into Doubleword by External Process ID Indexed EVX-form (evlddepx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {EVSTDDEPX, 0xfc0007fe, 0x7c00073e, 0x1, // Vector Store Doubleword into Doubleword by External Process ID Indexed EVX-form (evstddepx RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LVEPX, 0xfc0007fe, 0x7c00024e, 0x1, // Load Vector by External Process ID Indexed X-form (lvepx VRT,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LVEPXL, 0xfc0007fe, 0x7c00020e, 0x1, // Load Vector by External Process ID Indexed LRU X-form (lvepxl VRT,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STVEPX, 0xfc0007fe, 0x7c00064e, 0x1, // Store Vector by External Process ID Indexed X-form (stvepx VRS,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STVEPXL, 0xfc0007fe, 0x7c00060e, 0x1, // Store Vector by External Process ID Indexed LRU X-form (stvepxl VRS,RA,RB) + [5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DCBI, 0xfc0007fe, 0x7c0003ac, 0x3e00001, // Data Cache Block Invalidate X-form (dcbi RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {DCBLQCC, 0xfc0007ff, 0x7c00034d, 0x2000000, // Data Cache Block Lock Query X-form (dcblq. CT,RA,RB) + [5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ICBLQCC, 0xfc0007ff, 0x7c00018d, 0x2000000, // Instruction Cache Block Lock Query X-form (icblq. CT,RA,RB) + [5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DCBTLS, 0xfc0007fe, 0x7c00014c, 0x2000001, // Data Cache Block Touch and Lock Set X-form (dcbtls CT,RA,RB) + [5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DCBTSTLS, 0xfc0007fe, 0x7c00010c, 0x2000001, // Data Cache Block Touch for Store and Lock Set X-form (dcbtstls CT,RA,RB) + [5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ICBTLS, 0xfc0007fe, 0x7c0003cc, 0x2000001, // Instruction Cache Block Touch and Lock Set X-form (icbtls CT,RA,RB) + [5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ICBLC, 0xfc0007fe, 0x7c0001cc, 0x2000001, // Instruction Cache Block Lock Clear X-form (icblc CT,RA,RB) + [5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}}, + {DCBLC, 0xfc0007fe, 0x7c00030c, 0x2000001, // Data Cache Block Lock Clear X-form (dcblc CT,RA,RB) + [5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}}, + {TLBIVAX, 0xfc0007fe, 0x7c000624, 0x3e00001, // TLB Invalidate Virtual Address Indexed X-form (tlbivax RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {TLBILX, 0xfc0007fe, 0x7c000024, 0x3800001, // TLB Invalidate Local Indexed X-form (tlbilx RA,RB]) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {TLBSX, 0xfc0007fe, 0x7c000724, 0x3e00001, // TLB Search Indexed X-form (tlbsx RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {TLBSRXCC, 0xfc0007ff, 0x7c0006a5, 0x3e00000, // TLB Search and Reserve Indexed X-form (tlbsrx. RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {TLBRE, 0xfc0007fe, 0x7c000764, 0x3fff801, // TLB Read Entry X-form (tlbre) + [5]*argField{}}, + {TLBSYNC, 0xfc0007fe, 0x7c00046c, 0x3fff801, // TLB Synchronize X-form (tlbsync) + [5]*argField{}}, + {TLBWE, 0xfc0007fe, 0x7c0007a4, 0x3fff801, // TLB Write Entry X-form (tlbwe) + [5]*argField{}}, + {DNH, 0xfc0007fe, 0x4c00018c, 0x1, // Debugger Notify Halt XFX-form (dnh DUI,DUIS) + [5]*argField{ap_ImmUnsigned_6_10, ap_ImmUnsigned_11_20}}, + {MSGSND, 0xfc0007fe, 0x7c00019c, 0x3ff0001, // Message Send X-form (msgsnd RB) + [5]*argField{ap_Reg_16_20}}, + {MSGCLR, 0xfc0007fe, 0x7c0001dc, 0x3ff0001, // Message Clear X-form (msgclr RB) + [5]*argField{ap_Reg_16_20}}, + {DCI, 0xfc0007fe, 0x7c00038c, 0x21ff801, // Data Cache Invalidate X-form (dci CT) + [5]*argField{ap_ImmUnsigned_7_10}}, + {ICI, 0xfc0007fe, 0x7c00078c, 0x21ff801, // Instruction Cache Invalidate X-form (ici CT) + [5]*argField{ap_ImmUnsigned_7_10}}, + {DCREAD, 0xfc0007fe, 0x7c0003cc, 0x1, // Data Cache Read X-form (dcread RT,RA,RB) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {ICREAD, 0xfc0007fe, 0x7c0007cc, 0x3e00001, // Instruction Cache Read X-form (icread RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {MFPMR, 0xfc0007fe, 0x7c00029c, 0x1, // Move From Performance Monitor Register XFX-form (mfpmr RT,PMRN) + [5]*argField{ap_Reg_6_10, ap_SpReg_11_20}}, + {MTPMR, 0xfc0007fe, 0x7c00039c, 0x1, // Move To Performance Monitor Register XFX-form (mtpmr PMRN,RS) + [5]*argField{ap_SpReg_11_20, ap_Reg_6_10}}, + {ADDEX, 0xfc0001fe, 0x7c000154, 0x1, // Add Extended using alternate carry bit Z23-form (addex RT,RA,RB,CY) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_21_22}}, + {DARN, 0xfc0007fe, 0x7c0005e6, 0x1cf801, // Deliver A Random Number X-form (darn RT,L) + [5]*argField{ap_Reg_6_10, ap_ImmUnsigned_14_15}}, + {MADDHD, 0xfc00003f, 0x10000030, 0x0, // Multiply-Add High Doubleword VA-form (maddhd RT,RA,RB,RC) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_Reg_21_25}}, + {MADDHDU, 0xfc00003f, 0x10000031, 0x0, // Multiply-Add High Doubleword Unsigned VA-form (maddhdu RT,RA,RB,RC) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_Reg_21_25}}, + {MADDLD, 0xfc00003f, 0x10000033, 0x0, // Multiply-Add Low Doubleword VA-form (maddld RT,RA,RB,RC) + [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_Reg_21_25}}, + {CMPRB, 0xfc0007fe, 0x7c000180, 0x400001, // Compare Ranged Byte X-form (cmprb BF,L,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_ImmUnsigned_10_10, ap_Reg_11_15, ap_Reg_16_20}}, + {CMPEQB, 0xfc0007fe, 0x7c0001c0, 0x600001, // Compare Equal Byte X-form (cmpeqb BF,RA,RB) + [5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}}, + {BPERMD, 0xfc0007fe, 0x7c0001f8, 0x1, // Bit Permute Doubleword X-form (bpermd RA,RS,RB]) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}}, + {EXTSWSLI, 0xfc0007fd, 0x7c0006f4, 0x0, // Extend-Sign Word and Shift Left Immediate XS-form (extswsli RA,RS,SH) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20}}, + {EXTSWSLICC, 0xfc0007fd, 0x7c0006f5, 0x0, // Extend-Sign Word and Shift Left Immediate XS-form (extswsli. RA,RS,SH) + [5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20}}, + {MFVSRD, 0xfc0007fe, 0x7c000066, 0xf800, // Move From VSR Doubleword X-form (mfvsrd RA,XS) + [5]*argField{ap_Reg_11_15, ap_VecSReg_31_31_6_10}}, + {MFVSRLD, 0xfc0007fe, 0x7c000266, 0xf800, // Move From VSR Lower Doubleword X-form (mfvsrld RA,XS) + [5]*argField{ap_Reg_11_15, ap_VecSReg_31_31_6_10}}, + {MFVSRWZ, 0xfc0007fe, 0x7c0000e6, 0xf800, // Move From VSR Word and Zero X-form (mfvsrwz RA,XS) + [5]*argField{ap_Reg_11_15, ap_VecSReg_31_31_6_10}}, + {MTVSRD, 0xfc0007fe, 0x7c000166, 0xf800, // Move To VSR Doubleword X-form (mtvsrd XT,RA) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}}, + {MTVSRWA, 0xfc0007fe, 0x7c0001a6, 0xf800, // Move To VSR Word Algebraic X-form (mtvsrwa XT,RA) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}}, + {MTVSRWZ, 0xfc0007fe, 0x7c0001e6, 0xf800, // Move To VSR Word and Zero X-form (mtvsrwz XT,RA) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}}, + {MTVSRDD, 0xfc0007fe, 0x7c000366, 0x0, // Move To VSR Double Doubleword X-form (mtvsrdd XT,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {MTVSRWS, 0xfc0007fe, 0x7c000326, 0xf800, // Move To VSR Word & Splat X-form (mtvsrws XT,RA) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}}, + {MCRXRX, 0xfc0007fe, 0x7c000480, 0x7ff801, // Move to CR from XER Extended X-form (mcrxrx BF) + [5]*argField{ap_CondRegField_6_8}}, + {COPY, 0xfc2007fe, 0x7c20060c, 0x3c00001, // Copy X-form (copy RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, + {PASTECC, 0xfc2007ff, 0x7c20070d, 0x3c00000, // Paste X-form (paste. RA,RB) + [5]*argField{ap_Reg_11_15, ap_Reg_16_20}}, +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 783546ca5a..e2812d1f92 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -70,6 +70,7 @@ go.starlark.net/syntax # golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4 ## explicit golang.org/x/arch/arm64/arm64asm +golang.org/x/arch/ppc64/ppc64asm golang.org/x/arch/x86/x86asm # golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 golang.org/x/mod/semver From c1482ca9114555ac10787d2e5d3ad314754a25ff Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Fri, 7 Jul 2023 19:32:05 +0200 Subject: [PATCH 075/114] proc: check recursion level when loading pointers (#3431) Fixes #3429 --- _fixtures/testvariables2.go | 5 +++++ pkg/proc/variables.go | 13 ++++++++++++- pkg/proc/variables_test.go | 2 ++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/_fixtures/testvariables2.go b/_fixtures/testvariables2.go index ae1d795249..f800ae2da7 100644 --- a/_fixtures/testvariables2.go +++ b/_fixtures/testvariables2.go @@ -151,6 +151,8 @@ type ThreeInts struct { var _ I = (*W2)(nil) +type pptr *pptr + func main() { i1 := 1 i2 := 2 @@ -388,6 +390,9 @@ func main() { int3chan <- ThreeInts{a: 2} int3chan <- ThreeInts{a: 3} + var ptrinf2 pptr + ptrinf2 = &ptrinf2 + var amb1 = 1 runtime.Breakpoint() for amb1 := 0; amb1 < 10; amb1++ { diff --git a/pkg/proc/variables.go b/pkg/proc/variables.go index 49ccbf7657..c1b391ca3c 100644 --- a/pkg/proc/variables.go +++ b/pkg/proc/variables.go @@ -1305,10 +1305,21 @@ func (v *Variable) loadValueInternal(recurseLevel int, cfg LoadConfig) { // Don't increase the recursion level when dereferencing pointers // unless this is a pointer to interface (which could cause an infinite loop) nextLvl := recurseLevel + checkLvl := false if v.Children[0].Kind == reflect.Interface { nextLvl++ + } else if ptyp, isptr := v.RealType.(*godwarf.PtrType); isptr { + _, elemTypIsPtr := resolveTypedef(ptyp.Type).(*godwarf.PtrType) + if elemTypIsPtr { + nextLvl++ + checkLvl = true + } + } + if checkLvl && recurseLevel > cfg.MaxVariableRecurse { + v.Children[0].OnlyAddr = true + } else { + v.Children[0].loadValueInternal(nextLvl, cfg) } - v.Children[0].loadValueInternal(nextLvl, cfg) } else { v.Children[0].OnlyAddr = true } diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go index 01435e2b78..95da52166a 100644 --- a/pkg/proc/variables_test.go +++ b/pkg/proc/variables_test.go @@ -741,6 +741,8 @@ func getEvalExpressionTestCases() []varTest { {"emptymap", false, `map[string]string []`, `map[string]string []`, "map[string]string", nil}, {"mnil", false, `map[string]main.astruct nil`, `map[string]main.astruct nil`, "map[string]main.astruct", nil}, + {"ptrinf2", false, `**(main.pptr)(…`, `(main.pptr)(…`, "main.pptr", nil}, + // conversions between string/[]byte/[]rune (issue #548) {"runeslice", true, `[]int32 len: 4, cap: 4, [116,232,115,116]`, `[]int32 len: 4, cap: 4, [...]`, "[]int32", nil}, {"byteslice", true, `[]uint8 len: 5, cap: 5, [116,195,168,115,116]`, `[]uint8 len: 5, cap: 5, [...]`, "[]uint8", nil}, From db0bc26949ebaaec265968092785cdaade76fa20 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Fri, 7 Jul 2023 19:33:40 +0200 Subject: [PATCH 076/114] terminal,service: better printing of suspended breakpoints (#3415) Show the location expression that will be used to set a suspended breakpoint in the breakpoints list. Also change 'target' called without arguments to print a better error message and 'target follow-exec' without the last argument to print the state of follow-exec. --- pkg/proc/breakpoints.go | 1 + pkg/terminal/command.go | 18 ++++++++++++++++-- service/api/conversions.go | 5 ++++- service/api/types.go | 2 ++ service/dap/server.go | 2 +- service/debugger/debugger.go | 7 ++++--- 6 files changed, 28 insertions(+), 7 deletions(-) diff --git a/pkg/proc/breakpoints.go b/pkg/proc/breakpoints.go index 03fd305ac4..d846f204e9 100644 --- a/pkg/proc/breakpoints.go +++ b/pkg/proc/breakpoints.go @@ -1018,6 +1018,7 @@ type SetBreakpoint struct { File string Line int Expr func(*Target) []uint64 + ExprString string PidAddrs []PidAddr } diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index 2f8731fbf3..aa4137b764 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -1702,8 +1702,15 @@ func breakpoints(t *Term, ctx callContext, args string) error { enabled := "(enabled)" if bp.Disabled { enabled = "(disabled)" + } else if bp.ExprString != "" { + enabled = "(suspended)" + } + fmt.Fprintf(t.stdout, "%s %s", formatBreakpointName(bp, true), enabled) + if bp.ExprString != "" { + fmt.Fprintf(t.stdout, " at %s\n", bp.ExprString) + } else { + fmt.Fprintf(t.stdout, " at %v (%d)\n", t.formatBreakpointLocation(bp), bp.TotalHitCount) } - fmt.Fprintf(t.stdout, "%s %s at %v (%d)\n", formatBreakpointName(bp, true), enabled, t.formatBreakpointLocation(bp), bp.TotalHitCount) attrs := formatBreakpointAttrs("\t", bp, false) @@ -3277,7 +3284,12 @@ func target(t *Term, ctx callContext, args string) error { return nil case "follow-exec": if len(argv) == 1 { - return errors.New("not enough arguments") + if t.client.FollowExecEnabled() { + fmt.Fprintf(t.stdout, "Follow exec is enabled.\n") + } else { + fmt.Fprintf(t.stdout, "Follow exec is disabled.\n") + } + return nil } argv = config.Split2PartsBySpace(argv[1]) switch argv[0] { @@ -3316,6 +3328,8 @@ func target(t *Term, ctx callContext, args string) error { return fmt.Errorf("could not find target %d", pid) } return nil + case "": + return errors.New("not enough arguments for 'target'") default: return fmt.Errorf("unknown command 'target %s'", argv[0]) } diff --git a/service/api/conversions.go b/service/api/conversions.go index 08eb39298e..f64bd3fbee 100644 --- a/service/api/conversions.go +++ b/service/api/conversions.go @@ -54,8 +54,11 @@ func ConvertLogicalBreakpoint(lbp *proc.LogicalBreakpoint) *Breakpoint { } // ConvertPhysicalBreakpoints adds informations from physical breakpoints to an API breakpoint. -func ConvertPhysicalBreakpoints(b *Breakpoint, pids []int, bps []*proc.Breakpoint) { +func ConvertPhysicalBreakpoints(b *Breakpoint, lbp *proc.LogicalBreakpoint, pids []int, bps []*proc.Breakpoint) { if len(bps) == 0 { + if lbp != nil { + b.ExprString = lbp.Set.ExprString + } return } diff --git a/service/api/types.go b/service/api/types.go index e658ad4a91..13a1e8d2e7 100644 --- a/service/api/types.go +++ b/service/api/types.go @@ -92,6 +92,8 @@ type Breakpoint struct { // FunctionName is the name of the function at the current breakpoint, and // may not always be available. FunctionName string `json:"functionName,omitempty"` + // ExprString is the string that will be used to set a suspended breakpoint. + ExprString string // Breakpoint condition Cond string diff --git a/service/dap/server.go b/service/dap/server.go index 75a06e98b2..a8e7b343b9 100644 --- a/service/dap/server.go +++ b/service/dap/server.go @@ -1961,7 +1961,7 @@ func (s *Session) stoppedOnBreakpointGoroutineID(state *api.DebuggerState) (int6 return goid, nil } abp := api.ConvertLogicalBreakpoint(bp.Breakpoint.Logical) - api.ConvertPhysicalBreakpoints(abp, []int{0}, []*proc.Breakpoint{bp.Breakpoint}) + api.ConvertPhysicalBreakpoints(abp, bp.Breakpoint.Logical, []int{0}, []*proc.Breakpoint{bp.Breakpoint}) return goid, abp } diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index b666bb7439..e33ed5d730 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -617,7 +617,7 @@ func (d *Debugger) state(retLoadCfg *proc.LoadConfig, withBreakpointInfo bool) ( for t.Next() { for _, bp := range t.Breakpoints().WatchOutOfScope { abp := api.ConvertLogicalBreakpoint(bp.Logical) - api.ConvertPhysicalBreakpoints(abp, []int{t.Pid()}, []*proc.Breakpoint{bp}) + api.ConvertPhysicalBreakpoints(abp, bp.Logical, []int{t.Pid()}, []*proc.Breakpoint{bp}) state.WatchOutOfScope = append(state.WatchOutOfScope, abp) } } @@ -744,6 +744,7 @@ func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint, locExpr string, } return locs[0].PCs } + setbp.ExprString = locExpr } id := requestedBp.ID @@ -805,7 +806,7 @@ func (d *Debugger) convertBreakpoint(lbp *proc.LogicalBreakpoint) *api.Breakpoin } } } - api.ConvertPhysicalBreakpoints(abp, pids, bps) + api.ConvertPhysicalBreakpoints(abp, lbp, pids, bps) return abp } @@ -1039,7 +1040,7 @@ func (d *Debugger) Breakpoints(all bool) []*api.Breakpoint { } else { abp = &api.Breakpoint{} } - api.ConvertPhysicalBreakpoints(abp, []int{t.Pid()}, []*proc.Breakpoint{bp}) + api.ConvertPhysicalBreakpoints(abp, bp.Logical, []int{t.Pid()}, []*proc.Breakpoint{bp}) abp.VerboseDescr = bp.VerboseDescr() abps = append(abps, abp) } From 326c451b442ae279953c6ff42100972d957c8ce2 Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Fri, 7 Jul 2023 12:06:09 -0700 Subject: [PATCH 077/114] *: add linux/ppc64le targets (#3435) --- .teamcity/settings.kts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.teamcity/settings.kts b/.teamcity/settings.kts index 3ef170be55..f3ffc67181 100644 --- a/.teamcity/settings.kts +++ b/.teamcity/settings.kts @@ -45,6 +45,9 @@ val targets = arrayOf( "linux/arm64/1.20", "linux/arm64/tip", + "linux/ppc64le/1.20", + "linux/ppc64le/tip", + "windows/amd64/1.20", "windows/amd64/tip", From cbc45e1670dee79c25390c38e01e85ba0f049bed Mon Sep 17 00:00:00 2001 From: gocurr Date: Sun, 9 Jul 2023 14:27:05 +0800 Subject: [PATCH 078/114] pkg/proc: simplify code with trivial changes (#3436) --- pkg/proc/core/delve_core.go | 2 +- pkg/proc/gdbserial/gdbserver_conn.go | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/pkg/proc/core/delve_core.go b/pkg/proc/core/delve_core.go index 9a8d146cf5..0e5442b295 100644 --- a/pkg/proc/core/delve_core.go +++ b/pkg/proc/core/delve_core.go @@ -100,10 +100,10 @@ func threadsFromDelveNotes(p *process, notes []*note) (proc.Thread, error) { readerr = fmt.Errorf("maximum len exceeded (%d) reading %s", len, kind) return nil } - buf := make([]byte, len) if readerr != nil { return nil } + buf := make([]byte, len) _, readerr = body.Read(buf) return buf } diff --git a/pkg/proc/gdbserial/gdbserver_conn.go b/pkg/proc/gdbserial/gdbserver_conn.go index f6bde758ef..dc395635f7 100644 --- a/pkg/proc/gdbserial/gdbserver_conn.go +++ b/pkg/proc/gdbserial/gdbserver_conn.go @@ -1286,7 +1286,7 @@ func (conn *gdbConn) exec(cmd []byte, context string) ([]byte, error) { return conn.recv(cmd, context, false) } -var hexdigit = []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'} +const hexdigit = "0123456789abcdef" func (conn *gdbConn) send(cmd []byte) error { if len(cmd) == 0 || cmd[0] != '$' { @@ -1344,9 +1344,11 @@ func (conn *gdbConn) recv(cmd []byte, context string, binary bool) (resp []byte, if logflags.GdbWire() { out := resp partial := false - if idx := bytes.Index(out, []byte{'\n'}); idx >= 0 && !binary { - out = resp[:idx] - partial = true + if !binary { + if idx := bytes.Index(out, []byte{'\n'}); idx >= 0 { + out = resp[:idx] + partial = true + } } if len(out) > gdbWireMaxLen { out = out[:gdbWireMaxLen] From 0e3cae9dc921d8e10d930f3f7ce51d8b9bbc62ab Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Tue, 11 Jul 2023 17:10:41 +0300 Subject: [PATCH 079/114] service/dap: fix typos in comments (#3438) --- service/dap/server.go | 4 ++-- service/dap/server_test.go | 2 +- service/dap/types.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/service/dap/server.go b/service/dap/server.go index a8e7b343b9..a0b6583408 100644 --- a/service/dap/server.go +++ b/service/dap/server.go @@ -525,7 +525,7 @@ func (s *Session) ServeDAPCodec() { // potentially got some new DAP request that we do not yet have // decoding support for, so we can respond with an ErrorResponse. // - // Other errors, such as unmarshalling errors, will log the error and cause the server to trigger + // Other errors, such as unmarshaling errors, will log the error and cause the server to trigger // a stop. if err != nil { s.config.log.Debug("DAP error: ", err) @@ -588,7 +588,7 @@ func (s *Session) handleRequest(request dap.Message) { return } - // These requests, can be handled regardless of whether the targret is running + // These requests, can be handled regardless of whether the target is running switch request := request.(type) { case *dap.InitializeRequest: // Required s.onInitializeRequest(request) diff --git a/service/dap/server_test.go b/service/dap/server_test.go index c2d8dfebfa..7b818a6f21 100644 --- a/service/dap/server_test.go +++ b/service/dap/server_test.go @@ -2147,7 +2147,7 @@ func TestVariablesLoading(t *testing.T) { checkChildren(t, tm, "tm", 1) ref = checkVarExact(t, tm, 0, "v", "tm.v", "[]map[string]main.astruct len: 1, cap: 1, [[...]]", "[]map[string]main.astruct", hasChildren) if ref > 0 { - // Auto-loading of fully missing map chidlren happens here, but they get truncated at MaxArrayValuess + // Auto-loading of fully missing map chidlren happens here, but they get truncated at MaxArrayValues client.VariablesRequest(ref) tmV := client.ExpectVariablesResponse(t) checkChildren(t, tmV, "tm.v", 1) diff --git a/service/dap/types.go b/service/dap/types.go index aa5bbab65b..c7aed4a2b4 100644 --- a/service/dap/types.go +++ b/service/dap/types.go @@ -239,7 +239,7 @@ type AttachConfig struct { LaunchAttachCommonConfig } -// unmarshalLaunchAttachArgs wraps unmarshalling of launch/attach request's +// unmarshalLaunchAttachArgs wraps unmarshaling of launch/attach request's // arguments attribute. Upon unmarshal failure, it returns an error massaged // to be suitable for end-users. func unmarshalLaunchAttachArgs(input json.RawMessage, config interface{}) error { From 8023fa956ed29bfcdb7abafa0f7dff83d06d2d9c Mon Sep 17 00:00:00 2001 From: gocurr Date: Fri, 14 Jul 2023 02:30:32 +0800 Subject: [PATCH 080/114] all: use "len == 0" rather than "len <= 0" when checking empty slice/string (#3439) --- pkg/dwarf/dwarfbuilder/info.go | 4 ++-- pkg/dwarf/op/op.go | 8 ++++---- pkg/locspec/locations.go | 4 ++-- pkg/proc/bininfo.go | 2 +- pkg/proc/disasm.go | 2 +- pkg/proc/eval.go | 2 +- pkg/proc/fncall.go | 2 +- pkg/proc/gdbserial/gdbserver_conn.go | 2 +- pkg/proc/target_exec.go | 2 +- service/debugger/debugger.go | 2 +- service/test/integration1_test.go | 2 +- service/test/integration2_test.go | 2 +- 12 files changed, 17 insertions(+), 17 deletions(-) diff --git a/pkg/dwarf/dwarfbuilder/info.go b/pkg/dwarf/dwarfbuilder/info.go index 7cc5b94fb2..52b1fdba79 100644 --- a/pkg/dwarf/dwarfbuilder/info.go +++ b/pkg/dwarf/dwarfbuilder/info.go @@ -101,7 +101,7 @@ func (b *Builder) TagOpen(tag dwarf.Tag, name string) dwarf.Offset { // SetHasChildren sets the current DIE as having children (even if none are added). func (b *Builder) SetHasChildren() { - if len(b.tagStack) <= 0 { + if len(b.tagStack) == 0 { panic("NoChildren with no open tags") } b.tagStack[len(b.tagStack)-1].children = true @@ -109,7 +109,7 @@ func (b *Builder) SetHasChildren() { // TagClose closes the current DIE. func (b *Builder) TagClose() { - if len(b.tagStack) <= 0 { + if len(b.tagStack) == 0 { panic("TagClose with no open tags") } tag := b.tagStack[len(b.tagStack)-1] diff --git a/pkg/dwarf/op/op.go b/pkg/dwarf/op/op.go index e8a807f6d5..3d630dcd29 100644 --- a/pkg/dwarf/op/op.go +++ b/pkg/dwarf/op/op.go @@ -348,7 +348,7 @@ func constu(opcode Opcode, ctxt *context) error { } func dup(_ Opcode, ctxt *context) error { - if len(ctxt.stack) <= 0 { + if len(ctxt.stack) == 0 { return ErrStackUnderflow } ctxt.stack = append(ctxt.stack, ctxt.stack[len(ctxt.stack)-1]) @@ -356,7 +356,7 @@ func dup(_ Opcode, ctxt *context) error { } func drop(_ Opcode, ctxt *context) error { - if len(ctxt.stack) <= 0 { + if len(ctxt.stack) == 0 { return ErrStackUnderflow } ctxt.stack = ctxt.stack[:len(ctxt.stack)-1] @@ -541,7 +541,7 @@ func deref(op Opcode, ctxt *context) error { sz = int(n) } - if len(ctxt.stack) <= 0 { + if len(ctxt.stack) == 0 { return ErrStackUnderflow } @@ -549,7 +549,7 @@ func deref(op Opcode, ctxt *context) error { ctxt.stack = ctxt.stack[:len(ctxt.stack)-1] if op == DW_OP_xderef || op == DW_OP_xderef_size { - if len(ctxt.stack) <= 0 { + if len(ctxt.stack) == 0 { return ErrStackUnderflow } // the second element on the stack is the "address space identifier" which we don't do anything with diff --git a/pkg/locspec/locations.go b/pkg/locspec/locations.go index 0b1472fe30..92d83181e9 100644 --- a/pkg/locspec/locations.go +++ b/pkg/locspec/locations.go @@ -72,7 +72,7 @@ func Parse(locStr string) (LocationSpec, error) { return fmt.Errorf("Malformed breakpoint location %q at %d: %s", locStr, len(locStr)-len(rest), reason) } - if len(rest) <= 0 { + if len(rest) == 0 { return nil, malformed("empty string") } @@ -578,7 +578,7 @@ func SubstitutePath(path string, rules [][2]string) string { } func addressesToLocation(addrs []uint64) api.Location { - if len(addrs) <= 0 { + if len(addrs) == 0 { return api.Location{} } return api.Location{PC: addrs[0], PCs: addrs} diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go index 2e08b32e59..592774b0d3 100644 --- a/pkg/proc/bininfo.go +++ b/pkg/proc/bininfo.go @@ -2539,7 +2539,7 @@ func (bi *BinaryInfo) loadDebugInfoMapsInlinedCalls(ctxt *loadDebugInfoMapsConte } func uniq(s []string) []string { - if len(s) <= 0 { + if len(s) == 0 { return s } src, dst := 1, 1 diff --git a/pkg/proc/disasm.go b/pkg/proc/disasm.go index 92c5b3b6cc..837fa921a6 100644 --- a/pkg/proc/disasm.go +++ b/pkg/proc/disasm.go @@ -83,7 +83,7 @@ func firstPCAfterPrologueDisassembly(p Process, fn *Function, sameline bool) (ui return fn.Entry, err } - if len(text) <= 0 { + if len(text) == 0 { return fn.Entry, nil } diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index 3e6c87b428..220cb93a75 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -292,7 +292,7 @@ func (scope *EvalScope) Locals(flags localsFlags) ([]*Variable, error) { depths = append(depths, depth) } - if len(vars) <= 0 { + if len(vars) == 0 { return vars, nil } diff --git a/pkg/proc/fncall.go b/pkg/proc/fncall.go index a1b94a7291..39f38563d3 100644 --- a/pkg/proc/fncall.go +++ b/pkg/proc/fncall.go @@ -1127,7 +1127,7 @@ func isCallInjectionStop(t *Target, thread Thread, loc *Location) bool { off = -int64(len(thread.BinInfo().Arch.breakpointInstruction)) } text, err := disassembleCurrentInstruction(t, thread, off) - if err != nil || len(text) <= 0 { + if err != nil || len(text) == 0 { return false } return text[0].IsHardBreak() diff --git a/pkg/proc/gdbserial/gdbserver_conn.go b/pkg/proc/gdbserial/gdbserver_conn.go index dc395635f7..4c3a10c599 100644 --- a/pkg/proc/gdbserial/gdbserver_conn.go +++ b/pkg/proc/gdbserial/gdbserver_conn.go @@ -200,7 +200,7 @@ func (conn *gdbConn) qSupported(multiprocess bool) (features map[string]bool, er resp := strings.Split(string(respBuf), ";") features = make(map[string]bool) for _, stubfeature := range resp { - if len(stubfeature) <= 0 { + if len(stubfeature) == 0 { continue } else if equal := strings.Index(stubfeature, "="); equal >= 0 { if stubfeature[:equal] == "PacketSize" { diff --git a/pkg/proc/target_exec.go b/pkg/proc/target_exec.go index 630f83ab37..22c35719ac 100644 --- a/pkg/proc/target_exec.go +++ b/pkg/proc/target_exec.go @@ -899,7 +899,7 @@ func removePCsBetween(pcs []uint64, start, end uint64) []uint64 { } func setStepIntoBreakpoint(dbp *Target, curfn *Function, text []AsmInstruction, cond ast.Expr) error { - if len(text) <= 0 { + if len(text) == 0 { return nil } diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index e33ed5d730..57ece158e4 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -1414,7 +1414,7 @@ func (d *Debugger) Sources(filter string) ([]string, error) { } func uniq(s []string) []string { - if len(s) <= 0 { + if len(s) == 0 { return s } src, dst := 1, 1 diff --git a/service/test/integration1_test.go b/service/test/integration1_test.go index 9e9dd3ce5a..80a68193d7 100644 --- a/service/test/integration1_test.go +++ b/service/test/integration1_test.go @@ -484,7 +484,7 @@ func Test1ClientServer_traceContinue(t *testing.T) { t.Fatalf("No goroutine information") } - if len(bpi.Stacktrace) <= 0 { + if len(bpi.Stacktrace) == 0 { t.Fatalf("No stacktrace\n") } diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go index 50f2644949..adafb41dce 100644 --- a/service/test/integration2_test.go +++ b/service/test/integration2_test.go @@ -865,7 +865,7 @@ func TestClientServer_traceContinue(t *testing.T) { t.Fatalf("No goroutine information") } - if len(bpi.Stacktrace) <= 0 { + if len(bpi.Stacktrace) == 0 { t.Fatalf("No stacktrace\n") } From ca611db449ff5c7cab19171a591eeeae9f50936f Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Thu, 20 Jul 2023 12:29:59 +0200 Subject: [PATCH 081/114] terminal: restore breakpoints set with line offset on restart (#3425) Change FindLocation so it can return a substitute location expression and propagate it to pkg/terminal/command. When breakpoints are set using the syntax : or + produce a substitute location expression that doesn't depend on having a valid scope and can be used to restore the breakpoint. Fixes #3423 --- pkg/locspec/locations.go | 78 +++++++++++++++++-------------- pkg/terminal/command.go | 17 ++++--- pkg/terminal/command_test.go | 26 +++++++++++ service/client.go | 2 +- service/debugger/debugger.go | 23 +++++---- service/rpc1/server.go | 2 +- service/rpc2/client.go | 4 +- service/rpc2/server.go | 5 +- service/test/common_test.go | 4 +- service/test/integration2_test.go | 14 +++--- 10 files changed, 109 insertions(+), 66 deletions(-) diff --git a/pkg/locspec/locations.go b/pkg/locspec/locations.go index 92d83181e9..7ae05c4e72 100644 --- a/pkg/locspec/locations.go +++ b/pkg/locspec/locations.go @@ -20,7 +20,7 @@ const maxFindLocationCandidates = 5 // LocationSpec is an interface that represents a parsed location spec string. type LocationSpec interface { // Find returns all locations that match the location spec. - Find(t *proc.Target, processArgs []string, scope *proc.EvalScope, locStr string, includeNonExecutableLines bool, substitutePathRules [][2]string) ([]api.Location, error) + Find(t *proc.Target, processArgs []string, scope *proc.EvalScope, locStr string, includeNonExecutableLines bool, substitutePathRules [][2]string) ([]api.Location, string, error) } // NormalLocationSpec represents a basic location spec. @@ -269,15 +269,15 @@ func packageMatch(specPkg, symPkg string, packageMap map[string][]string) bool { // Find will search all functions in the target program and filter them via the // regex location spec. Only functions matching the regex will be returned. -func (loc *RegexLocationSpec) Find(t *proc.Target, _ []string, scope *proc.EvalScope, locStr string, includeNonExecutableLines bool, _ [][2]string) ([]api.Location, error) { +func (loc *RegexLocationSpec) Find(t *proc.Target, _ []string, scope *proc.EvalScope, locStr string, includeNonExecutableLines bool, _ [][2]string) ([]api.Location, string, error) { if scope == nil { //TODO(aarzilli): this needs only the list of function we should make it work - return nil, fmt.Errorf("could not determine location (scope is nil)") + return nil, "", fmt.Errorf("could not determine location (scope is nil)") } funcs := scope.BinInfo.Functions matches, err := regexFilterFuncs(loc.FuncRegex, funcs) if err != nil { - return nil, err + return nil, "", err } r := make([]api.Location, 0, len(matches)) for i := range matches { @@ -286,39 +286,39 @@ func (loc *RegexLocationSpec) Find(t *proc.Target, _ []string, scope *proc.EvalS r = append(r, addressesToLocation(addrs)) } } - return r, nil + return r, "", nil } // Find returns the locations specified via the address location spec. -func (loc *AddrLocationSpec) Find(t *proc.Target, _ []string, scope *proc.EvalScope, locStr string, includeNonExecutableLines bool, _ [][2]string) ([]api.Location, error) { +func (loc *AddrLocationSpec) Find(t *proc.Target, _ []string, scope *proc.EvalScope, locStr string, includeNonExecutableLines bool, _ [][2]string) ([]api.Location, string, error) { if scope == nil { addr, err := strconv.ParseInt(loc.AddrExpr, 0, 64) if err != nil { - return nil, fmt.Errorf("could not determine current location (scope is nil)") + return nil, "", fmt.Errorf("could not determine current location (scope is nil)") } - return []api.Location{{PC: uint64(addr)}}, nil + return []api.Location{{PC: uint64(addr)}}, "", nil } v, err := scope.EvalExpression(loc.AddrExpr, proc.LoadConfig{FollowPointers: true}) if err != nil { - return nil, err + return nil, "", err } if v.Unreadable != nil { - return nil, v.Unreadable + return nil, "", v.Unreadable } switch v.Kind { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: addr, _ := constant.Uint64Val(v.Value) - return []api.Location{{PC: addr}}, nil + return []api.Location{{PC: addr}}, "", nil case reflect.Func: fn := scope.BinInfo.PCToFunc(uint64(v.Base)) pc, err := proc.FirstPCAfterPrologue(t, fn, false) if err != nil { - return nil, err + return nil, "", err } - return []api.Location{{PC: pc}}, nil + return []api.Location{{PC: pc}}, v.Name, nil default: - return nil, fmt.Errorf("wrong expression kind: %v", v.Kind) + return nil, "", fmt.Errorf("wrong expression kind: %v", v.Kind) } } @@ -371,7 +371,7 @@ func (ale AmbiguousLocationError) Error() string { // Find will return a list of locations that match the given location spec. // This matches each other location spec that does not already have its own spec // implemented (such as regex, or addr). -func (loc *NormalLocationSpec) Find(t *proc.Target, processArgs []string, scope *proc.EvalScope, locStr string, includeNonExecutableLines bool, substitutePathRules [][2]string) ([]api.Location, error) { +func (loc *NormalLocationSpec) Find(t *proc.Target, processArgs []string, scope *proc.EvalScope, locStr string, includeNonExecutableLines bool, substitutePathRules [][2]string) ([]api.Location, string, error) { limit := maxFindLocationCandidates var candidateFiles []string for _, sourceFile := range t.BinInfo().Sources { @@ -396,19 +396,19 @@ func (loc *NormalLocationSpec) Find(t *proc.Target, processArgs []string, scope if matching := len(candidateFiles) + len(candidateFuncs); matching == 0 { if scope == nil { - return nil, fmt.Errorf("location %q not found", locStr) + return nil, "", fmt.Errorf("location %q not found", locStr) } // if no result was found this locations string could be an // expression that the user forgot to prefix with '*', try treating it as // such. addrSpec := &AddrLocationSpec{AddrExpr: locStr} - locs, err := addrSpec.Find(t, processArgs, scope, locStr, includeNonExecutableLines, nil) + locs, subst, err := addrSpec.Find(t, processArgs, scope, locStr, includeNonExecutableLines, nil) if err != nil { - return nil, fmt.Errorf("location %q not found", locStr) + return nil, "", fmt.Errorf("location %q not found", locStr) } - return locs, nil + return locs, subst, nil } else if matching > 1 { - return nil, AmbiguousLocationError{Location: locStr, CandidatesString: append(candidateFiles, candidateFuncs...)} + return nil, "", AmbiguousLocationError{Location: locStr, CandidatesString: append(candidateFiles, candidateFuncs...)} } // len(candidateFiles) + len(candidateFuncs) == 1 @@ -417,12 +417,12 @@ func (loc *NormalLocationSpec) Find(t *proc.Target, processArgs []string, scope if len(candidateFiles) == 1 { if loc.LineOffset < 0 { //lint:ignore ST1005 backwards compatibility - return nil, fmt.Errorf("Malformed breakpoint location, no line offset specified") + return nil, "", fmt.Errorf("Malformed breakpoint location, no line offset specified") } addrs, err = proc.FindFileLocation(t, candidateFiles[0], loc.LineOffset) if includeNonExecutableLines { if _, isCouldNotFindLine := err.(*proc.ErrCouldNotFindLine); isCouldNotFindLine { - return []api.Location{{File: candidateFiles[0], Line: loc.LineOffset}}, nil + return []api.Location{{File: candidateFiles[0], Line: loc.LineOffset}}, "", nil } } } else { // len(candidateFuncs) == 1 @@ -430,9 +430,9 @@ func (loc *NormalLocationSpec) Find(t *proc.Target, processArgs []string, scope } if err != nil { - return nil, err + return nil, "", err } - return []api.Location{addressesToLocation(addrs)}, nil + return []api.Location{addressesToLocation(addrs)}, "", nil } func (loc *NormalLocationSpec) findFuncCandidates(bi *proc.BinaryInfo, limit int) []string { @@ -585,42 +585,48 @@ func addressesToLocation(addrs []uint64) api.Location { } // Find returns the location after adding the offset amount to the current line number. -func (loc *OffsetLocationSpec) Find(t *proc.Target, _ []string, scope *proc.EvalScope, _ string, includeNonExecutableLines bool, _ [][2]string) ([]api.Location, error) { +func (loc *OffsetLocationSpec) Find(t *proc.Target, _ []string, scope *proc.EvalScope, _ string, includeNonExecutableLines bool, _ [][2]string) ([]api.Location, string, error) { if scope == nil { - return nil, fmt.Errorf("could not determine current location (scope is nil)") + return nil, "", fmt.Errorf("could not determine current location (scope is nil)") } + file, line, fn := scope.BinInfo.PCToLine(scope.PC) if loc.Offset == 0 { - return []api.Location{{PC: scope.PC}}, nil + subst := "" + if fn != nil { + subst = fmt.Sprintf("%s:%d", file, line) + } + return []api.Location{{PC: scope.PC}}, subst, nil } - file, line, fn := scope.BinInfo.PCToLine(scope.PC) if fn == nil { - return nil, fmt.Errorf("could not determine current location") + return nil, "", fmt.Errorf("could not determine current location") } + subst := fmt.Sprintf("%s:%d", file, line+loc.Offset) addrs, err := proc.FindFileLocation(t, file, line+loc.Offset) if includeNonExecutableLines { if _, isCouldNotFindLine := err.(*proc.ErrCouldNotFindLine); isCouldNotFindLine { - return []api.Location{{File: file, Line: line + loc.Offset}}, nil + return []api.Location{{File: file, Line: line + loc.Offset}}, subst, nil } } - return []api.Location{addressesToLocation(addrs)}, err + return []api.Location{addressesToLocation(addrs)}, subst, err } // Find will return the location at the given line in the current file. -func (loc *LineLocationSpec) Find(t *proc.Target, _ []string, scope *proc.EvalScope, _ string, includeNonExecutableLines bool, _ [][2]string) ([]api.Location, error) { +func (loc *LineLocationSpec) Find(t *proc.Target, _ []string, scope *proc.EvalScope, _ string, includeNonExecutableLines bool, _ [][2]string) ([]api.Location, string, error) { if scope == nil { - return nil, fmt.Errorf("could not determine current location (scope is nil)") + return nil, "", fmt.Errorf("could not determine current location (scope is nil)") } file, _, fn := scope.BinInfo.PCToLine(scope.PC) if fn == nil { - return nil, fmt.Errorf("could not determine current location") + return nil, "", fmt.Errorf("could not determine current location") } + subst := fmt.Sprintf("%s:%d", file, loc.Line) addrs, err := proc.FindFileLocation(t, file, loc.Line) if includeNonExecutableLines { if _, isCouldNotFindLine := err.(*proc.ErrCouldNotFindLine); isCouldNotFindLine { - return []api.Location{{File: file, Line: loc.Line}}, nil + return []api.Location{{File: file, Line: loc.Line}}, subst, nil } } - return []api.Location{addressesToLocation(addrs)}, err + return []api.Location{addressesToLocation(addrs)}, subst, err } func regexFilterFuncs(filter string, allFuncs []proc.Function) ([]string, error) { diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index aa4137b764..430b9b12e4 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -1634,7 +1634,7 @@ func clearAll(t *Term, ctx callContext, args string) error { var locPCs map[uint64]struct{} if args != "" { - locs, err := t.client.FindLocation(api.EvalScope{GoroutineID: -1, Frame: 0}, args, true, t.substitutePathRules()) + locs, _, err := t.client.FindLocation(api.EvalScope{GoroutineID: -1, Frame: 0}, args, true, t.substitutePathRules()) if err != nil { return err } @@ -1790,14 +1790,16 @@ func setBreakpoint(t *Term, ctx callContext, tracepoint bool, argstr string) ([] } requestedBp.Tracepoint = tracepoint - locs, findLocErr := t.client.FindLocation(ctx.Scope, spec, true, t.substitutePathRules()) + locs, substSpec, findLocErr := t.client.FindLocation(ctx.Scope, spec, true, t.substitutePathRules()) if findLocErr != nil && requestedBp.Name != "" { requestedBp.Name = "" spec = argstr var err2 error - locs, err2 = t.client.FindLocation(ctx.Scope, spec, true, t.substitutePathRules()) + var substSpec2 string + locs, substSpec2, err2 = t.client.FindLocation(ctx.Scope, spec, true, t.substitutePathRules()) if err2 == nil { findLocErr = nil + substSpec = substSpec2 } } if findLocErr != nil && shouldAskToSuspendBreakpoint(t) { @@ -1824,6 +1826,9 @@ func setBreakpoint(t *Term, ctx callContext, tracepoint bool, argstr string) ([] if findLocErr != nil { return nil, findLocErr } + if substSpec != "" { + spec = substSpec + } created := []*api.Breakpoint{} for _, loc := range locs { @@ -2431,7 +2436,7 @@ func getLocation(t *Term, ctx callContext, args string, showContext bool) (file return loc.File, loc.Line, true, nil default: - locs, err := t.client.FindLocation(ctx.Scope, args, false, t.substitutePathRules()) + locs, _, err := t.client.FindLocation(ctx.Scope, args, false, t.substitutePathRules()) if err != nil { return "", 0, false, err } @@ -2505,7 +2510,7 @@ func disassCommand(t *Term, ctx callContext, args string) error { switch cmd { case "": - locs, err := t.client.FindLocation(ctx.Scope, "+0", true, t.substitutePathRules()) + locs, _, err := t.client.FindLocation(ctx.Scope, "+0", true, t.substitutePathRules()) if err != nil { return err } @@ -2525,7 +2530,7 @@ func disassCommand(t *Term, ctx callContext, args string) error { } disasm, disasmErr = t.client.DisassembleRange(ctx.Scope, uint64(startpc), uint64(endpc), flavor) case "-l": - locs, err := t.client.FindLocation(ctx.Scope, rest, true, t.substitutePathRules()) + locs, _, err := t.client.FindLocation(ctx.Scope, rest, true, t.substitutePathRules()) if err != nil { return err } diff --git a/pkg/terminal/command_test.go b/pkg/terminal/command_test.go index 925568ac16..403c9e8da9 100644 --- a/pkg/terminal/command_test.go +++ b/pkg/terminal/command_test.go @@ -1419,3 +1419,29 @@ func TestCreateBreakpointByLocExpr(t *testing.T) { } }) } + +func TestRestartBreakpoints(t *testing.T) { + // Tests that breakpoints set using just a line number and with a line + // offset are preserved after restart. See issue #3423. + withTestTerminal("continuetestprog", t, func(term *FakeTerminal) { + term.MustExec("break main.main") + term.MustExec("continue") + term.MustExec("break 9") + term.MustExec("break +1") + out := term.MustExec("breakpoints") + t.Log("breakpoints before:\n", out) + term.MustExec("restart") + out = term.MustExec("breakpoints") + t.Log("breakpoints after:\n", out) + bps, err := term.client.ListBreakpoints(false) + assertNoError(t, err, "ListBreakpoints") + for _, bp := range bps { + if bp.ID < 0 { + continue + } + if bp.Addr == 0 { + t.Fatalf("breakpoint %d has address 0", bp.ID) + } + } + }) +} diff --git a/service/client.go b/service/client.go index 62a10c36f3..f0cdc668b4 100644 --- a/service/client.go +++ b/service/client.go @@ -143,7 +143,7 @@ type Client interface { // * *
returns the location corresponding to the specified address // NOTE: this function does not actually set breakpoints. // If findInstruction is true FindLocation will only return locations that correspond to instructions. - FindLocation(scope api.EvalScope, loc string, findInstruction bool, substitutePathRules [][2]string) ([]api.Location, error) + FindLocation(scope api.EvalScope, loc string, findInstruction bool, substitutePathRules [][2]string) ([]api.Location, string, error) // DisassembleRange disassemble code between startPC and endPC DisassembleRange(scope api.EvalScope, startPC, endPC uint64, flavour api.AssemblyFlavour) (api.AsmInstructions, error) diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index 57ece158e4..d8608cb1f9 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -737,7 +737,7 @@ func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint, locExpr string, return nil, err } setbp.Expr = func(t *proc.Target) []uint64 { - locs, err := loc.Find(t, d.processArgs, nil, locExpr, false, substitutePathRules) + locs, _, err := loc.Find(t, d.processArgs, nil, locExpr, false, substitutePathRules) if err != nil || len(locs) != 1 { logflags.DebuggerLogger().Debugf("could not evaluate breakpoint expression %q: %v (number of results %d)", locExpr, err, len(locs)) return nil @@ -1921,17 +1921,17 @@ func (d *Debugger) CurrentPackage() (string, error) { } // FindLocation will find the location specified by 'locStr'. -func (d *Debugger) FindLocation(goid int64, frame, deferredCall int, locStr string, includeNonExecutableLines bool, substitutePathRules [][2]string) ([]api.Location, error) { +func (d *Debugger) FindLocation(goid int64, frame, deferredCall int, locStr string, includeNonExecutableLines bool, substitutePathRules [][2]string) ([]api.Location, string, error) { d.targetMutex.Lock() defer d.targetMutex.Unlock() if _, err := d.target.Valid(); err != nil { - return nil, err + return nil, "", err } loc, err := locspec.Parse(locStr) if err != nil { - return nil, err + return nil, "", err } return d.findLocation(goid, frame, deferredCall, locStr, loc, includeNonExecutableLines, substitutePathRules) @@ -1949,18 +1949,23 @@ func (d *Debugger) FindLocationSpec(goid int64, frame, deferredCall int, locStr return nil, err } - return d.findLocation(goid, frame, deferredCall, locStr, locSpec, includeNonExecutableLines, substitutePathRules) + locs, _, err := d.findLocation(goid, frame, deferredCall, locStr, locSpec, includeNonExecutableLines, substitutePathRules) + return locs, err } -func (d *Debugger) findLocation(goid int64, frame, deferredCall int, locStr string, locSpec locspec.LocationSpec, includeNonExecutableLines bool, substitutePathRules [][2]string) ([]api.Location, error) { +func (d *Debugger) findLocation(goid int64, frame, deferredCall int, locStr string, locSpec locspec.LocationSpec, includeNonExecutableLines bool, substitutePathRules [][2]string) ([]api.Location, string, error) { locations := []api.Location{} t := proc.ValidTargets{Group: d.target} + subst := "" for t.Next() { pid := t.Pid() s, _ := proc.ConvertEvalScope(t.Target, goid, frame, deferredCall) - locs, err := locSpec.Find(t.Target, d.processArgs, s, locStr, includeNonExecutableLines, substitutePathRules) + locs, s1, err := locSpec.Find(t.Target, d.processArgs, s, locStr, includeNonExecutableLines, substitutePathRules) + if s1 != "" { + subst = s1 + } if err != nil { - return nil, err + return nil, "", err } for i := range locs { if locs[i].PC == 0 { @@ -1977,7 +1982,7 @@ func (d *Debugger) findLocation(goid int64, frame, deferredCall int, locStr stri } locations = append(locations, locs...) } - return locations, nil + return locations, subst, nil } // Disassemble code between startPC and endPC. diff --git a/service/rpc1/server.go b/service/rpc1/server.go index fc6dd78245..98a508ea96 100644 --- a/service/rpc1/server.go +++ b/service/rpc1/server.go @@ -306,7 +306,7 @@ type FindLocationArgs struct { func (c *RPCServer) FindLocation(args FindLocationArgs, answer *[]api.Location) error { var err error - *answer, err = c.debugger.FindLocation(args.Scope.GoroutineID, args.Scope.Frame, args.Scope.DeferredCall, args.Loc, false, nil) + *answer, _, err = c.debugger.FindLocation(args.Scope.GoroutineID, args.Scope.Frame, args.Scope.DeferredCall, args.Loc, false, nil) return err } diff --git a/service/rpc2/client.go b/service/rpc2/client.go index f28d0de5ca..e05ae8fbb3 100644 --- a/service/rpc2/client.go +++ b/service/rpc2/client.go @@ -414,10 +414,10 @@ func (c *RPCClient) AttachedToExistingProcess() bool { return out.Answer } -func (c *RPCClient) FindLocation(scope api.EvalScope, loc string, findInstructions bool, substitutePathRules [][2]string) ([]api.Location, error) { +func (c *RPCClient) FindLocation(scope api.EvalScope, loc string, findInstructions bool, substitutePathRules [][2]string) ([]api.Location, string, error) { var out FindLocationOut err := c.call("FindLocation", FindLocationIn{scope, loc, !findInstructions, substitutePathRules}, &out) - return out.Locations, err + return out.Locations, out.SubstituteLocExpr, err } // DisassembleRange disassembles code between startPC and endPC diff --git a/service/rpc2/server.go b/service/rpc2/server.go index f90153980a..7097bdcac8 100644 --- a/service/rpc2/server.go +++ b/service/rpc2/server.go @@ -705,7 +705,8 @@ type FindLocationIn struct { } type FindLocationOut struct { - Locations []api.Location + Locations []api.Location + SubstituteLocExpr string // if this isn't an empty string it should be passed as the location expression for CreateBreakpoint instead of the original location expression } // FindLocation returns concrete location information described by a location expression. @@ -723,7 +724,7 @@ type FindLocationOut struct { // NOTE: this function does not actually set breakpoints. func (c *RPCServer) FindLocation(arg FindLocationIn, out *FindLocationOut) error { var err error - out.Locations, err = c.debugger.FindLocation(arg.Scope.GoroutineID, arg.Scope.Frame, arg.Scope.DeferredCall, arg.Loc, arg.IncludeNonExecutableLines, arg.SubstitutePathRules) + out.Locations, out.SubstituteLocExpr, err = c.debugger.FindLocation(arg.Scope.GoroutineID, arg.Scope.Frame, arg.Scope.DeferredCall, arg.Loc, arg.IncludeNonExecutableLines, arg.SubstitutePathRules) return err } diff --git a/service/test/common_test.go b/service/test/common_test.go index ef6338e0f4..a91b63dba8 100644 --- a/service/test/common_test.go +++ b/service/test/common_test.go @@ -89,7 +89,7 @@ type locationFinder1 interface { } type locationFinder2 interface { - FindLocation(api.EvalScope, string, bool, [][2]string) ([]api.Location, error) + FindLocation(api.EvalScope, string, bool, [][2]string) ([]api.Location, string, error) } func findLocationHelper(t *testing.T, c interface{}, loc string, shouldErr bool, count int, checkAddr uint64) []uint64 { @@ -100,7 +100,7 @@ func findLocationHelper(t *testing.T, c interface{}, loc string, shouldErr bool, case locationFinder1: locs, err = c.FindLocation(api.EvalScope{GoroutineID: -1}, loc) case locationFinder2: - locs, err = c.FindLocation(api.EvalScope{GoroutineID: -1}, loc, false, nil) + locs, _, err = c.FindLocation(api.EvalScope{GoroutineID: -1}, loc, false, nil) default: t.Errorf("unexpected type %T passed to findLocationHelper", c) } diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go index adafb41dce..6aaa938ea2 100644 --- a/service/test/integration2_test.go +++ b/service/test/integration2_test.go @@ -997,14 +997,14 @@ func TestClientServer_FindLocations(t *testing.T) { findLocationHelper(t, c, `*amap["k"]`, false, 1, findLocationHelper(t, c, `amap["k"]`, false, 1, 0)[0]) - locsNoSubst, _ := c.FindLocation(api.EvalScope{GoroutineID: -1}, "_fixtures/locationsprog.go:35", false, nil) + locsNoSubst, _, _ := c.FindLocation(api.EvalScope{GoroutineID: -1}, "_fixtures/locationsprog.go:35", false, nil) sep := "/" if strings.Contains(locsNoSubst[0].File, "\\") { sep = "\\" } substRules := [][2]string{{strings.Replace(locsNoSubst[0].File, "locationsprog.go", "", 1), strings.Replace(locsNoSubst[0].File, "_fixtures"+sep+"locationsprog.go", "nonexistent", 1)}} t.Logf("substitute rules: %q -> %q", substRules[0][0], substRules[0][1]) - locsSubst, err := c.FindLocation(api.EvalScope{GoroutineID: -1}, "nonexistent/locationsprog.go:35", false, substRules) + locsSubst, _, err := c.FindLocation(api.EvalScope{GoroutineID: -1}, "nonexistent/locationsprog.go:35", false, substRules) if err != nil { t.Fatalf("FindLocation(locationsprog.go:35) with substitute rules: %v", err) } @@ -1114,7 +1114,7 @@ func TestClientServer_FindLocations(t *testing.T) { } func findLocationHelper2(t *testing.T, c service.Client, loc string, checkLoc *api.Location) *api.Location { - locs, err := c.FindLocation(api.EvalScope{GoroutineID: -1}, loc, false, nil) + locs, _, err := c.FindLocation(api.EvalScope{GoroutineID: -1}, loc, false, nil) if err != nil { t.Fatalf("FindLocation(%q) -> error %v", loc, err) } @@ -1360,7 +1360,7 @@ func TestIssue355(t *testing.T) { assertError(err, t, "ListGoroutines()") _, err = c.Stacktrace(gid, 10, 0, &normalLoadConfig) assertError(err, t, "Stacktrace()") - _, err = c.FindLocation(api.EvalScope{GoroutineID: gid}, "+1", false, nil) + _, _, err = c.FindLocation(api.EvalScope{GoroutineID: gid}, "+1", false, nil) assertError(err, t, "FindLocation()") _, err = c.DisassemblePC(api.EvalScope{GoroutineID: -1}, 0x40100, api.IntelFlavour) assertError(err, t, "DisassemblePC()") @@ -1380,7 +1380,7 @@ func TestDisasm(t *testing.T) { state := <-ch assertNoError(state.Err, t, "Continue()") - locs, err := c.FindLocation(api.EvalScope{GoroutineID: -1}, "main.main", false, nil) + locs, _, err := c.FindLocation(api.EvalScope{GoroutineID: -1}, "main.main", false, nil) assertNoError(err, t, "FindLocation()") if len(locs) != 1 { t.Fatalf("wrong number of locations for main.main: %d", len(locs)) @@ -1639,7 +1639,7 @@ func TestTypesCommand(t *testing.T) { func TestIssue406(t *testing.T) { protest.AllowRecording(t) withTestClient2("issue406", t, func(c service.Client) { - locs, err := c.FindLocation(api.EvalScope{GoroutineID: -1}, "issue406.go:146", false, nil) + locs, _, err := c.FindLocation(api.EvalScope{GoroutineID: -1}, "issue406.go:146", false, nil) assertNoError(err, t, "FindLocation()") _, err = c.CreateBreakpoint(&api.Breakpoint{Addr: locs[0].PC}) assertNoError(err, t, "CreateBreakpoint()") @@ -2253,7 +2253,7 @@ func TestUnknownMethodCall(t *testing.T) { func TestIssue1703(t *testing.T) { // Calling Disassemble when there is no current goroutine should work. withTestClient2("testnextprog", t, func(c service.Client) { - locs, err := c.FindLocation(api.EvalScope{GoroutineID: -1}, "main.main", true, nil) + locs, _, err := c.FindLocation(api.EvalScope{GoroutineID: -1}, "main.main", true, nil) assertNoError(err, t, "FindLocation") t.Logf("FindLocation: %#v", locs) text, err := c.DisassemblePC(api.EvalScope{GoroutineID: -1}, locs[0].PC, api.IntelFlavour) From a53f1bf45d4d3656e962db5211717fb7fc593041 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 26 Jul 2023 01:27:00 +0200 Subject: [PATCH 082/114] service/api: in multiline mode print address of pointers (#3448) When printing a pointer variable first print the address that it points to before printing its dereferenced value. Fixes #3446 --- pkg/proc/variables_test.go | 14 ++++++++++---- service/api/prettyprint.go | 18 +++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go index 95da52166a..82a63ce1c3 100644 --- a/pkg/proc/variables_test.go +++ b/pkg/proc/variables_test.go @@ -5,6 +5,7 @@ import ( "fmt" "go/constant" "io/ioutil" + "regexp" "runtime" "sort" "strconv" @@ -45,9 +46,14 @@ func matchStringOrPrefix(output, target string) bool { prefix := target[:len(target)-len("…")] b := strings.HasPrefix(output, prefix) return b - } else { - return output == target } + + if strings.HasPrefix(target, "/") && strings.HasSuffix(target, "/") { + rx := regexp.MustCompile(target[1 : len(target)-1]) + return rx.MatchString(output) + } + + return output == target } func assertVariable(t testing.TB, variable *proc.Variable, expected varTest) { @@ -309,7 +315,7 @@ func TestMultilineVariableEvaluation(t *testing.T) { {"a4", true, "[2]int [1,2]", "", "[2]int", nil}, {"a5", true, "[]int len: 5, cap: 5, [1,2,3,4,5]", "", "[]int", nil}, {"a6", true, "main.FooBar {Baz: 8, Bur: \"word\"}", "", "main.FooBar", nil}, - {"a7", true, "*main.FooBar {Baz: 5, Bur: \"strum\"}", "", "*main.FooBar", nil}, + {"a7", true, `/^\(\*main\.FooBar\)\(.*?\)\n\*main\.FooBar \{Baz: 5, Bur: "strum"\}$/`, "", "*main.FooBar", nil}, {"a8", true, "main.FooBar2 {Bur: 10, Baz: \"feh\"}", "", "main.FooBar2", nil}, {"a9", true, "*main.FooBar nil", "", "*main.FooBar", nil}, {"a8", true, "main.FooBar2 {Bur: 10, Baz: \"feh\"}", "", "main.FooBar2", nil}, // reread variable after member @@ -331,7 +337,7 @@ func TestMultilineVariableEvaluation(t *testing.T) { variable, err := evalVariableWithCfg(p, tc.name, pnormalLoadConfig) assertNoError(err, t, "EvalVariable() returned an error") if ms := api.ConvertVar(variable).MultilineString("", ""); !matchStringOrPrefix(ms, tc.value) { - t.Fatalf("Expected %s got %s (variable %s)\n", tc.value, ms, variable.Name) + t.Fatalf("Expected %s got %q (variable %s)\n", tc.value, ms, variable.Name) } } }) diff --git a/service/api/prettyprint.go b/service/api/prettyprint.go index cd10842779..677860ea41 100644 --- a/service/api/prettyprint.go +++ b/service/api/prettyprint.go @@ -63,12 +63,12 @@ func (v *Variable) writeTo(buf io.Writer, top, newlines, includeType bool, inden if v.Type == "" || len(v.Children) == 0 { fmt.Fprint(buf, "nil") } else if v.Children[0].OnlyAddr && v.Children[0].Addr != 0 { - if strings.Contains(v.Type, "/") { - fmt.Fprintf(buf, "(%q)(%#x)", v.Type, v.Children[0].Addr) - } else { - fmt.Fprintf(buf, "(%s)(%#x)", v.Type, v.Children[0].Addr) - } + v.writePointerTo(buf) } else { + if top && newlines && v.Children[0].Addr != 0 { + v.writePointerTo(buf) + fmt.Fprint(buf, "\n") + } fmt.Fprint(buf, "*") v.Children[0].writeTo(buf, false, newlines, includeType, indent, fmtstr) } @@ -145,6 +145,14 @@ func (v *Variable) writeTo(buf io.Writer, top, newlines, includeType bool, inden } } +func (v *Variable) writePointerTo(buf io.Writer) { + if strings.Contains(v.Type, "/") { + fmt.Fprintf(buf, "(%q)(%#x)", v.Type, v.Children[0].Addr) + } else { + fmt.Fprintf(buf, "(%s)(%#x)", v.Type, v.Children[0].Addr) + } +} + func (v *Variable) writeBasicType(buf io.Writer, fmtstr string) { if v.Value == "" && v.Kind != reflect.String { fmt.Fprintf(buf, "(unknown %s)", v.Kind) From 34104fb65d4ea2f6f61f55ef529b646f5feef5b2 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 26 Jul 2023 01:27:37 +0200 Subject: [PATCH 083/114] proc,ebpf: mark as unreadable args with unsupported types with ebpf (#3444) Only a few types can be read with ebpf, mark everything else as unreadable so that there are no downstream crashes. Fixes #3443 --- pkg/proc/target.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/proc/target.go b/pkg/proc/target.go index 91d18584ac..a79769536f 100644 --- a/pkg/proc/target.go +++ b/pkg/proc/target.go @@ -451,6 +451,11 @@ func (t *Target) GetBufferedTracepoints() []*UProbeTraceResult { v.Addr = ip.Addr v.Kind = ip.Kind + if v.RealType == nil { + v.Unreadable = errors.New("type not supported by ebpf") + return v + } + cachedMem := CreateLoadedCachedMemory(ip.Data) compMem, _ := CreateCompositeMemory(cachedMem, t.BinInfo().Arch, op.DwarfRegisters{}, ip.Pieces, ip.RealType.Common().ByteSize) v.mem = compMem From 7db57df266d04bb530cbae7dde0df8ed5143e557 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 26 Jul 2023 17:33:31 +0200 Subject: [PATCH 084/114] proc: replace use of runtime.GOARCH with Arch.Name (#3442) --- pkg/proc/target_exec.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/proc/target_exec.go b/pkg/proc/target_exec.go index 22c35719ac..c4d9201add 100644 --- a/pkg/proc/target_exec.go +++ b/pkg/proc/target_exec.go @@ -8,7 +8,6 @@ import ( "go/ast" "go/token" "path/filepath" - "runtime" "strings" "golang.org/x/arch/ppc64/ppc64asm" @@ -918,7 +917,7 @@ func setStepIntoBreakpoint(dbp *Target, curfn *Function, text []AsmInstruction, pc := instr.DestLoc.PC fn := instr.DestLoc.Fn - if runtime.GOARCH == "ppc64le" && instr.Inst.OpcodeEquals(uint64(ppc64asm.BCLRL)) { + if dbp.BinInfo().Arch.Name == "ppc64le" && instr.Inst.OpcodeEquals(uint64(ppc64asm.BCLRL)) { regs, err := dbp.CurrentThread().Registers() if err != nil { return err From b5c9edccffb8d6903811d7dacbc38a2076f61382 Mon Sep 17 00:00:00 2001 From: gocurr Date: Tue, 1 Aug 2023 23:35:59 +0800 Subject: [PATCH 085/114] pkg/terminal: use reflect.Value.IsValid to check a zero Value (#3450) I searched the source code of Go, and found no usages of "== (reflect.Value{})" and "!= (reflect.Value{})". I think it's more idiomatic to use "IsValid" to check a zero Value. --- pkg/terminal/colorize/colorize.go | 4 ++-- pkg/terminal/starbind/conv.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/terminal/colorize/colorize.go b/pkg/terminal/colorize/colorize.go index da60f416d5..6e7f8e8a6d 100644 --- a/pkg/terminal/colorize/colorize.go +++ b/pkg/terminal/colorize/colorize.go @@ -134,13 +134,13 @@ func Print(out io.Writer, path string, reader io.Reader, startLine, endLine, arr tokposval := nval.FieldByName("TokPos") tokval := nval.FieldByName("Tok") - if tokposval != (reflect.Value{}) && tokval != (reflect.Value{}) { + if tokposval.IsValid() && tokval.IsValid() { emit(tokval.Interface().(token.Token), tokposval.Interface().(token.Pos), token.NoPos) } for _, kwname := range []string{"Case", "Begin", "Defer", "For", "Func", "Go", "Interface", "Map", "Return", "Select", "Struct", "Switch"} { kwposval := nval.FieldByName(kwname) - if kwposval != (reflect.Value{}) { + if kwposval.IsValid() { kwpos, ok := kwposval.Interface().(token.Pos) if ok && kwpos != token.NoPos { emit(token.ILLEGAL, kwpos, token.NoPos) diff --git a/pkg/terminal/starbind/conv.go b/pkg/terminal/starbind/conv.go index 196c295bac..972ebbc717 100644 --- a/pkg/terminal/starbind/conv.go +++ b/pkg/terminal/starbind/conv.go @@ -181,7 +181,7 @@ func (v structAsStarlarkValue) Attr(name string) (starlark.Value, error) { return r, err } r := v.v.FieldByName(name) - if r == (reflect.Value{}) { + if !r.IsValid() { return starlark.None, fmt.Errorf("no field named %q in %T", name, v.v.Interface()) } return v.env.interfaceToStarlarkValue(r.Interface()), nil @@ -681,7 +681,7 @@ func unmarshalStarlarkValueIntl(val starlark.Value, dst reflect.Value, path stri } fieldName := string(k.(starlark.String)) dstfield := dst.FieldByName(fieldName) - if dstfield == (reflect.Value{}) { + if !dstfield.IsValid() { return converr(fmt.Sprintf("unknown field %s", fieldName)) } valfield, _, _ := val.Get(starlark.String(fieldName)) From ae67a45a1cee839d5aada1b3116e9a274937b692 Mon Sep 17 00:00:00 2001 From: Andrei Matei Date: Mon, 7 Aug 2023 15:11:05 -0400 Subject: [PATCH 086/114] starbind: fix Starlark slice unmarshaling (#3454) The unmarshaling code for slices wasn't actually setting the destination. This patch fixes it. --- pkg/terminal/starbind/conv.go | 3 ++- pkg/terminal/starbind/conv_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 pkg/terminal/starbind/conv_test.go diff --git a/pkg/terminal/starbind/conv.go b/pkg/terminal/starbind/conv.go index 972ebbc717..b421e15191 100644 --- a/pkg/terminal/starbind/conv.go +++ b/pkg/terminal/starbind/conv.go @@ -664,8 +664,9 @@ func unmarshalStarlarkValueIntl(val starlark.Value, dst reflect.Value, path stri if dst.Kind() != reflect.Slice { return converr() } + dst.Set(reflect.MakeSlice(dst.Type(), val.Len(), val.Len())) for i := 0; i < val.Len(); i++ { - cur := reflect.New(dst.Type().Elem()) + cur := dst.Index(i).Addr() err := unmarshalStarlarkValueIntl(val.Index(i), cur, path) if err != nil { return err diff --git a/pkg/terminal/starbind/conv_test.go b/pkg/terminal/starbind/conv_test.go new file mode 100644 index 0000000000..34c613aa29 --- /dev/null +++ b/pkg/terminal/starbind/conv_test.go @@ -0,0 +1,29 @@ +package starbind + +import ( + "go.starlark.net/starlark" + "testing" +) + +func TestConv(t *testing.T) { + script := ` +# A list global that we'll unmarhsal into a slice. +x = [1,2] +` + globals, err := starlark.ExecFile(&starlark.Thread{}, "test.star", script, nil) + starlarkVal, ok := globals["x"] + if !ok { + t.Fatal("missing global 'x'") + } + if err != nil { + t.Fatal(err) + } + var x []int + err = unmarshalStarlarkValue(starlarkVal, &x, "x") + if err != nil { + t.Fatal(err) + } + if len(x) != 2 || x[0] != 1 || x[1] != 2 { + t.Fatalf("expected [1 2], got: %v", x) + } +} From 2b785f293b6038586e84c5a09bc7932e8d839303 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 7 Aug 2023 22:55:45 +0200 Subject: [PATCH 087/114] logflags: simplify Logger interface (#3274) Remove methods we never used or used only very sparingly (Print) and we probably shouldn't be using at all (Fatal). --- pkg/logflags/logflags.go | 2 +- pkg/logflags/logger.go | 36 ------------------------------------ pkg/proc/bininfo.go | 2 +- service/dap/server.go | 11 ++++++----- 4 files changed, 8 insertions(+), 43 deletions(-) diff --git a/pkg/logflags/logflags.go b/pkg/logflags/logflags.go index acf4cb5a7a..571913239d 100644 --- a/pkg/logflags/logflags.go +++ b/pkg/logflags/logflags.go @@ -163,7 +163,7 @@ func writeListeningMessage(server string, addr net.Addr) { return } logger := rpcLogger(true) - logger.Warnln("Listening for remote connections (connections are not authenticated nor encrypted)") + logger.Warn("Listening for remote connections (connections are not authenticated nor encrypted)") } func WriteError(msg string) { diff --git a/pkg/logflags/logger.go b/pkg/logflags/logger.go index 14fd07ead3..8b79eaed33 100644 --- a/pkg/logflags/logger.go +++ b/pkg/logflags/logger.go @@ -8,39 +8,15 @@ import ( // Logger represents a generic interface for logging inside of // Delve codebase. type Logger interface { - // WithField returns a new Logger enriched with the given field. - WithField(key string, value interface{}) Logger - // WithFields returns a new Logger enriched with the given fields. - WithFields(fields Fields) Logger - // WithError returns a new Logger enriched with the given error. - WithError(err error) Logger - Debugf(format string, args ...interface{}) Infof(format string, args ...interface{}) - Printf(format string, args ...interface{}) Warnf(format string, args ...interface{}) - Warningf(format string, args ...interface{}) Errorf(format string, args ...interface{}) - Fatalf(format string, args ...interface{}) - Panicf(format string, args ...interface{}) Debug(args ...interface{}) Info(args ...interface{}) - Print(args ...interface{}) Warn(args ...interface{}) - Warning(args ...interface{}) Error(args ...interface{}) - Fatal(args ...interface{}) - Panic(args ...interface{}) - - Debugln(args ...interface{}) - Infoln(args ...interface{}) - Println(args ...interface{}) - Warnln(args ...interface{}) - Warningln(args ...interface{}) - Errorln(args ...interface{}) - Fatalln(args ...interface{}) - Panicln(args ...interface{}) } // LoggerFactory is used to create new Logger instances. @@ -63,15 +39,3 @@ type Fields map[string]interface{} type logrusLogger struct { *logrus.Entry } - -func (l *logrusLogger) WithField(key string, value interface{}) Logger { - return &logrusLogger{l.Entry.WithField(key, value)} -} - -func (l *logrusLogger) WithFields(fields Fields) Logger { - return &logrusLogger{l.Entry.WithFields(logrus.Fields(fields))} -} - -func (l *logrusLogger) WithError(err error) Logger { - return &logrusLogger{l.Entry.WithError(err)} -} diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go index 592774b0d3..c63fb16f4a 100644 --- a/pkg/proc/bininfo.go +++ b/pkg/proc/bininfo.go @@ -2143,7 +2143,7 @@ func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugInfoBytes, debugLineB if hasLineInfo && lineInfoOffset >= 0 && lineInfoOffset < int64(len(debugLineBytes)) { var logfn func(string, ...interface{}) if logflags.DebugLineErrors() { - logfn = logflags.DebugLineLogger().Printf + logfn = logflags.DebugLineLogger().Debugf } cu.lineInfo = line.Parse(compdir, bytes.NewBuffer(debugLineBytes[lineInfoOffset:]), image.debugLineStr, logfn, image.StaticBase, bi.GOOS == "windows", bi.Arch.PtrSize()) } diff --git a/service/dap/server.go b/service/dap/server.go index a0b6583408..990f9679ac 100644 --- a/service/dap/server.go +++ b/service/dap/server.go @@ -329,7 +329,8 @@ func NewSession(conn io.ReadWriteCloser, config *Config, debugger *debugger.Debu } config.log.Debugf("DAP connection %d started", sessionCount) if config.StopTriggered == nil { - config.log.Fatal("Session must be configured with StopTriggered") + config.log.Error("Session must be configured with StopTriggered") + os.Exit(1) } return &Session{ config: config, @@ -453,8 +454,8 @@ func (c *Config) triggerServerStop() { // we need to take that into consideration. func (s *Server) Run() { if s.listener == nil { - s.config.log.Fatal("Misconfigured server: no Listener is configured.") - return + s.config.log.Error("Misconfigured server: no Listener is configured.") + os.Exit(1) } go func() { @@ -492,8 +493,8 @@ func (s *Server) runSession(conn io.ReadWriteCloser) { // until a launch/attach request is received over the connection. func (s *Server) RunWithClient(conn net.Conn) { if s.listener != nil { - s.config.log.Fatal("RunWithClient must not be used when the Server is configured with a Listener") - return + s.config.log.Error("RunWithClient must not be used when the Server is configured with a Listener") + os.Exit(1) } s.config.log.Debugf("Connected to the client at %s", conn.RemoteAddr()) go s.runSession(conn) From dc5d8de320d150112f002f3147f994c151a1d346 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 9 Aug 2023 19:30:22 +0200 Subject: [PATCH 088/114] proc: add waitfor option to attach (#3445) Adds a waitfor option to 'dlv attach' that waits for a process with a name starting with a given prefix to appear before attaching to it. Debugserver on macOS does not support follow-fork mode, but has this feature instead which is not the same thing but still helps with multiprocess debugging somewhat. --- Documentation/backend_test_health.md | 2 + Documentation/usage/dlv_attach.md | 7 ++- Makefile | 2 +- cmd/dlv/cmds/commands.go | 70 +++++++++++++-------- pkg/proc/gdbserial/gdbserver.go | 20 +++++- pkg/proc/interface.go | 8 +++ pkg/proc/native/nonative_darwin.go | 6 +- pkg/proc/native/proc.go | 19 ++++++ pkg/proc/native/proc_darwin.go | 9 ++- pkg/proc/native/proc_freebsd.go | 52 ++++++++++++++-- pkg/proc/native/proc_linux.go | 58 ++++++++++++++++- pkg/proc/native/proc_windows.go | 60 +++++++++++++++--- pkg/proc/proc_test.go | 93 +++++++++++++++++++++++++++- pkg/proc/proc_unix_test.go | 2 +- pkg/proc/target.go | 6 ++ service/debugger/debugger.go | 31 +++++++--- 16 files changed, 389 insertions(+), 56 deletions(-) diff --git a/Documentation/backend_test_health.md b/Documentation/backend_test_health.md index 72527ad1db..2a6661d91e 100644 --- a/Documentation/backend_test_health.md +++ b/Documentation/backend_test_health.md @@ -5,6 +5,8 @@ Tests skipped by each supported backend: * 3 not implemented * arm64 skipped = 1 * 1 broken - global variable symbolication +* darwin skipped = 1 + * 1 waitfor implementation is delegated to debugserver * darwin/arm64 skipped = 2 * 2 broken - cgo stacktraces * darwin/lldb skipped = 1 diff --git a/Documentation/usage/dlv_attach.md b/Documentation/usage/dlv_attach.md index 3b9c22de2b..ac9164e24f 100644 --- a/Documentation/usage/dlv_attach.md +++ b/Documentation/usage/dlv_attach.md @@ -18,8 +18,11 @@ dlv attach pid [executable] [flags] ### Options ``` - --continue Continue the debugged process on start. - -h, --help help for attach + --continue Continue the debugged process on start. + -h, --help help for attach + --waitfor string Wait for a process with a name beginning with this prefix + --waitfor-duration float Total time to wait for a process + --waitfor-interval float Interval between checks of the process list, in millisecond (default 1) ``` ### Options inherited from parent commands diff --git a/Makefile b/Makefile index fef7998a18..fd9672e1ef 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ uninstall: @go run _scripts/make.go uninstall test: vet - @go run _scripts/make.go test + @go run _scripts/make.go test -v vet: @go vet $$(go list ./... | grep -v native) diff --git a/cmd/dlv/cmds/commands.go b/cmd/dlv/cmds/commands.go index b8d2d7eb72..dbb4bcdbb8 100644 --- a/cmd/dlv/cmds/commands.go +++ b/cmd/dlv/cmds/commands.go @@ -96,6 +96,10 @@ var ( loadConfErr error rrOnProcessPid int + + attachWaitFor string + attachWaitForInterval float64 + attachWaitForDuration float64 ) const dlvCommandLongDesc = `Delve is a source level debugger for Go programs. @@ -162,7 +166,7 @@ begin a new debug session. When exiting the debug session you will have the option to let the process continue or kill it. `, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - if len(args) == 0 { + if len(args) == 0 && attachWaitFor == "" { return errors.New("you must provide a PID") } return nil @@ -170,6 +174,9 @@ option to let the process continue or kill it. Run: attachCmd, } attachCommand.Flags().BoolVar(&continueOnStart, "continue", false, "Continue the debugged process on start.") + attachCommand.Flags().StringVar(&attachWaitFor, "waitfor", "", "Wait for a process with a name beginning with this prefix") + attachCommand.Flags().Float64Var(&attachWaitForInterval, "waitfor-interval", 1, "Interval between checks of the process list, in millisecond") + attachCommand.Flags().Float64Var(&attachWaitForDuration, "waitfor-duration", 0, "Total time to wait for a process") rootCommand.AddCommand(attachCommand) // 'connect' subcommand. @@ -305,7 +312,8 @@ to know what functions your process is executing. The output of the trace sub command is printed to stderr, so if you would like to only see the output of the trace operations you can redirect stdout.`, Run: func(cmd *cobra.Command, args []string) { - os.Exit(traceCmd(cmd, args, conf)) }, + os.Exit(traceCmd(cmd, args, conf)) + }, } traceCommand.Flags().IntVarP(&traceAttachPid, "pid", "p", 0, "Pid to attach to.") traceCommand.Flags().StringVarP(&traceExecFile, "exec", "e", "", "Binary file to exec and trace.") @@ -647,10 +655,10 @@ func traceCmd(cmd *cobra.Command, args []string, conf *config.Config) int { ProcessArgs: processArgs, APIVersion: 2, Debugger: debugger.Config{ - AttachPid: traceAttachPid, - WorkingDir: workingDir, - Backend: backend, - CheckGoVersion: checkGoVersion, + AttachPid: traceAttachPid, + WorkingDir: workingDir, + Backend: backend, + CheckGoVersion: checkGoVersion, DebugInfoDirectories: conf.DebugInfoDirectories, }, }) @@ -818,12 +826,17 @@ func getPackageDir(pkg []string) string { } func attachCmd(cmd *cobra.Command, args []string) { - pid, err := strconv.Atoi(args[0]) - if err != nil { - fmt.Fprintf(os.Stderr, "Invalid pid: %s\n", args[0]) - os.Exit(1) + var pid int + if len(args) > 0 { + var err error + pid, err = strconv.Atoi(args[0]) + if err != nil { + fmt.Fprintf(os.Stderr, "Invalid pid: %s\n", args[0]) + os.Exit(1) + } + args = args[1:] } - os.Exit(execute(pid, args[1:], conf, "", debugger.ExecutingOther, args, buildFlags)) + os.Exit(execute(pid, args, conf, "", debugger.ExecutingOther, args, buildFlags)) } func coreCmd(cmd *cobra.Command, args []string) { @@ -1005,22 +1018,25 @@ func execute(attachPid int, processArgs []string, conf *config.Config, coreFile CheckLocalConnUser: checkLocalConnUser, DisconnectChan: disconnectChan, Debugger: debugger.Config{ - AttachPid: attachPid, - WorkingDir: workingDir, - Backend: backend, - CoreFile: coreFile, - Foreground: headless && tty == "", - Packages: dlvArgs, - BuildFlags: buildFlags, - ExecuteKind: kind, - DebugInfoDirectories: conf.DebugInfoDirectories, - CheckGoVersion: checkGoVersion, - TTY: tty, - Stdin: redirects[0], - Stdout: proc.OutputRedirect{Path: redirects[1]}, - Stderr: proc.OutputRedirect{Path: redirects[2]}, - DisableASLR: disableASLR, - RrOnProcessPid: rrOnProcessPid, + AttachPid: attachPid, + WorkingDir: workingDir, + Backend: backend, + CoreFile: coreFile, + Foreground: headless && tty == "", + Packages: dlvArgs, + BuildFlags: buildFlags, + ExecuteKind: kind, + DebugInfoDirectories: conf.DebugInfoDirectories, + CheckGoVersion: checkGoVersion, + TTY: tty, + Stdin: redirects[0], + Stdout: proc.OutputRedirect{Path: redirects[1]}, + Stderr: proc.OutputRedirect{Path: redirects[2]}, + DisableASLR: disableASLR, + RrOnProcessPid: rrOnProcessPid, + AttachWaitFor: attachWaitFor, + AttachWaitForInterval: attachWaitForInterval, + AttachWaitForDuration: attachWaitForDuration, }, }) default: diff --git a/pkg/proc/gdbserial/gdbserver.go b/pkg/proc/gdbserial/gdbserver.go index b51545a044..bb57f3d587 100644 --- a/pkg/proc/gdbserial/gdbserver.go +++ b/pkg/proc/gdbserial/gdbserver.go @@ -588,7 +588,7 @@ func LLDBLaunch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs [ // Path is path to the target's executable, path only needs to be specified // for some stubs that do not provide an automated way of determining it // (for example debugserver). -func LLDBAttach(pid int, path string, debugInfoDirs []string) (*proc.TargetGroup, error) { +func LLDBAttach(pid int, path string, waitFor *proc.WaitFor, debugInfoDirs []string) (*proc.TargetGroup, error) { if runtime.GOOS == "windows" { return nil, ErrUnsupportedOS } @@ -609,12 +609,28 @@ func LLDBAttach(pid int, path string, debugInfoDirs []string) (*proc.TargetGroup if err != nil { return nil, err } - args := []string{"-R", fmt.Sprintf("127.0.0.1:%d", listener.Addr().(*net.TCPAddr).Port), "--attach=" + strconv.Itoa(pid)} + args := []string{"-R", fmt.Sprintf("127.0.0.1:%d", listener.Addr().(*net.TCPAddr).Port)} + + if waitFor.Valid() { + duration := int(waitFor.Duration.Seconds()) + if duration == 0 && waitFor.Duration != 0 { + // If duration is below the (second) resolution of debugserver pass 1 + // second (0 means infinite). + duration = 1 + } + args = append(args, "--waitfor="+waitFor.Name, fmt.Sprintf("--waitfor-interval=%d", waitFor.Interval.Microseconds()), fmt.Sprintf("--waitfor-duration=%d", duration)) + } else { + args = append(args, "--attach="+strconv.Itoa(pid)) + } + if canUnmaskSignals(debugserverExecutable) { args = append(args, "--unmask-signals") } process = commandLogger(debugserverExecutable, args...) } else { + if waitFor.Valid() { + return nil, proc.ErrWaitForNotImplemented + } if _, err = exec.LookPath("lldb-server"); err != nil { return nil, &ErrBackendUnavailable{} } diff --git a/pkg/proc/interface.go b/pkg/proc/interface.go index d2a0ef3550..84bd80ab1c 100644 --- a/pkg/proc/interface.go +++ b/pkg/proc/interface.go @@ -2,6 +2,7 @@ package proc import ( "sync" + "time" "github.com/go-delve/delve/pkg/elfwriter" "github.com/go-delve/delve/pkg/proc/internal/ebpf" @@ -142,3 +143,10 @@ func (cctx *ContinueOnceContext) GetManualStopRequested() bool { defer cctx.StopMu.Unlock() return cctx.manualStopRequested } + +// WaitFor is passed to native.Attach and gdbserver.LLDBAttach to wait for a +// process to start before attaching. +type WaitFor struct { + Name string + Interval, Duration time.Duration +} diff --git a/pkg/proc/native/nonative_darwin.go b/pkg/proc/native/nonative_darwin.go index 616fe869eb..0fa7be5275 100644 --- a/pkg/proc/native/nonative_darwin.go +++ b/pkg/proc/native/nonative_darwin.go @@ -21,10 +21,14 @@ func Launch(_ []string, _ string, _ proc.LaunchFlags, _ []string, _ string, _ st } // Attach returns ErrNativeBackendDisabled. -func Attach(_ int, _ []string) (*proc.TargetGroup, error) { +func Attach(_ int, _ *proc.WaitFor, _ []string) (*proc.TargetGroup, error) { return nil, ErrNativeBackendDisabled } +func waitForSearchProcess(string, map[int]struct{}) (int, error) { + return 0, proc.ErrWaitForNotImplemented +} + // waitStatus is a synonym for the platform-specific WaitStatus type waitStatus struct{} diff --git a/pkg/proc/native/proc.go b/pkg/proc/native/proc.go index cd84391f2d..aeb4b23f85 100644 --- a/pkg/proc/native/proc.go +++ b/pkg/proc/native/proc.go @@ -1,8 +1,10 @@ package native import ( + "errors" "os" "runtime" + "time" "github.com/go-delve/delve/pkg/proc" ) @@ -69,6 +71,23 @@ func newChildProcess(dbp *nativeProcess, pid int) *nativeProcess { } } +// WaitFor waits for a process as specified by waitFor. +func WaitFor(waitFor *proc.WaitFor) (int, error) { + t0 := time.Now() + seen := make(map[int]struct{}) + for (waitFor.Duration == 0) || (time.Since(t0) < waitFor.Duration) { + pid, err := waitForSearchProcess(waitFor.Name, seen) + if err != nil { + return 0, err + } + if pid != 0 { + return pid, nil + } + time.Sleep(waitFor.Interval) + } + return 0, errors.New("waitfor duration expired") +} + // BinInfo will return the binary info struct associated with this process. func (dbp *nativeProcess) BinInfo() *proc.BinaryInfo { return dbp.bi diff --git a/pkg/proc/native/proc_darwin.go b/pkg/proc/native/proc_darwin.go index 7a2bbb9b57..6332734487 100644 --- a/pkg/proc/native/proc_darwin.go +++ b/pkg/proc/native/proc_darwin.go @@ -136,8 +136,15 @@ func Launch(cmd []string, wd string, flags proc.LaunchFlags, _ []string, _ strin return tgt, err } +func waitForSearchProcess(string, map[int]struct{}) (int, error) { + return 0, proc.ErrWaitForNotImplemented +} + // Attach to an existing process with the given PID. -func Attach(pid int, _ []string) (*proc.TargetGroup, error) { +func Attach(pid int, waitFor *proc.WaitFor, _ []string) (*proc.TargetGroup, error) { + if waitFor.Valid() { + return nil, proc.ErrWaitForNotImplemented + } if err := macutil.CheckRosetta(); err != nil { return nil, err } diff --git a/pkg/proc/native/proc_freebsd.go b/pkg/proc/native/proc_freebsd.go index 23f64ed6cc..2d04b92f04 100644 --- a/pkg/proc/native/proc_freebsd.go +++ b/pkg/proc/native/proc_freebsd.go @@ -3,6 +3,7 @@ package native // #cgo LDFLAGS: -lprocstat // #include // #include "proc_freebsd.h" +// #include import "C" import ( "fmt" @@ -14,6 +15,7 @@ import ( sys "golang.org/x/sys/unix" + "github.com/go-delve/delve/pkg/logflags" "github.com/go-delve/delve/pkg/proc" "github.com/go-delve/delve/pkg/proc/internal/ebpf" @@ -121,7 +123,15 @@ func Launch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs []str // Attach to an existing process with the given PID. Once attached, if // the DWARF information cannot be found in the binary, Delve will look // for external debug files in the directories passed in. -func Attach(pid int, debugInfoDirs []string) (*proc.TargetGroup, error) { +func Attach(pid int, waitFor *proc.WaitFor, debugInfoDirs []string) (*proc.TargetGroup, error) { + if waitFor.Valid() { + var err error + pid, err = WaitFor(waitFor) + if err != nil { + return nil, err + } + } + dbp := newProcess(pid) var err error @@ -142,6 +152,31 @@ func Attach(pid int, debugInfoDirs []string) (*proc.TargetGroup, error) { return tgt, nil } +func waitForSearchProcess(pfx string, seen map[int]struct{}) (int, error) { + log := logflags.DebuggerLogger() + ps := C.procstat_open_sysctl() + defer C.procstat_close(ps) + var cnt C.uint + procs := C.procstat_getprocs(ps, C.KERN_PROC_PROC, 0, &cnt) + defer C.procstat_freeprocs(ps, procs) + proc := procs + for i := 0; i < int(cnt); i++ { + if _, isseen := seen[int(proc.ki_pid)]; isseen { + continue + } + seen[int(proc.ki_pid)] = struct{}{} + + argv := strings.Join(getCmdLineInternal(ps, proc), " ") + log.Debugf("waitfor: new process %q", argv) + if strings.HasPrefix(argv, pfx) { + return int(proc.ki_pid), nil + } + + proc = (*C.struct_kinfo_proc)(unsafe.Pointer(uintptr(unsafe.Pointer(proc)) + unsafe.Sizeof(*proc))) + } + return 0, nil +} + func initialize(dbp *nativeProcess) (string, error) { comm, _ := C.find_command_name(C.int(dbp.pid)) defer C.free(unsafe.Pointer(comm)) @@ -230,7 +265,17 @@ func findExecutable(path string, pid int) string { func getCmdLine(pid int) string { ps := C.procstat_open_sysctl() kp := C.kinfo_getproc(C.int(pid)) + goargv := getCmdLineInternal(ps, kp) + C.free(unsafe.Pointer(kp)) + C.procstat_close(ps) + return strings.Join(goargv, " ") +} + +func getCmdLineInternal(ps *C.struct_procstat, kp *C.struct_kinfo_proc) []string { argv := C.procstat_getargv(ps, kp, 0) + if argv == nil { + return nil + } goargv := []string{} for { arg := *argv @@ -240,9 +285,8 @@ func getCmdLine(pid int) string { argv = (**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(argv)) + unsafe.Sizeof(*argv))) goargv = append(goargv, C.GoString(arg)) } - C.free(unsafe.Pointer(kp)) - C.procstat_close(ps) - return strings.Join(goargv, " ") + C.procstat_freeargv(ps) + return goargv } func trapWait(procgrp *processGroup, pid int) (*nativeThread, error) { diff --git a/pkg/proc/native/proc_linux.go b/pkg/proc/native/proc_linux.go index b61e663d51..30a90d2682 100644 --- a/pkg/proc/native/proc_linux.go +++ b/pkg/proc/native/proc_linux.go @@ -19,6 +19,7 @@ import ( sys "golang.org/x/sys/unix" + "github.com/go-delve/delve/pkg/logflags" "github.com/go-delve/delve/pkg/proc" "github.com/go-delve/delve/pkg/proc/internal/ebpf" "github.com/go-delve/delve/pkg/proc/linutil" @@ -141,7 +142,15 @@ func Launch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs []str // Attach to an existing process with the given PID. Once attached, if // the DWARF information cannot be found in the binary, Delve will look // for external debug files in the directories passed in. -func Attach(pid int, debugInfoDirs []string) (*proc.TargetGroup, error) { +func Attach(pid int, waitFor *proc.WaitFor, debugInfoDirs []string) (*proc.TargetGroup, error) { + if waitFor.Valid() { + var err error + pid, err = WaitFor(waitFor) + if err != nil { + return nil, err + } + } + dbp := newProcess(pid) var err error @@ -169,6 +178,53 @@ func Attach(pid int, debugInfoDirs []string) (*proc.TargetGroup, error) { return tgt, nil } +func isProcDir(name string) bool { + for _, ch := range name { + if ch < '0' || ch > '9' { + return false + } + } + return true +} + +func waitForSearchProcess(pfx string, seen map[int]struct{}) (int, error) { + log := logflags.DebuggerLogger() + des, err := os.ReadDir("/proc") + if err != nil { + log.Errorf("error reading proc: %v", err) + return 0, nil + } + for _, de := range des { + if !de.IsDir() { + continue + } + name := de.Name() + if !isProcDir(name) { + continue + } + pid, _ := strconv.Atoi(name) + if _, isseen := seen[pid]; isseen { + continue + } + seen[pid] = struct{}{} + buf, err := os.ReadFile(filepath.Join("/proc", name, "cmdline")) + if err != nil { + // probably we just don't have permissions + continue + } + for i := range buf { + if buf[i] == 0 { + buf[i] = ' ' + } + } + log.Debugf("waitfor: new process %q", string(buf)) + if strings.HasPrefix(string(buf), pfx) { + return pid, nil + } + } + return 0, nil +} + func initialize(dbp *nativeProcess) (string, error) { comm, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/comm", dbp.pid)) if err == nil { diff --git a/pkg/proc/native/proc_windows.go b/pkg/proc/native/proc_windows.go index 9cbf326430..73e4a7a4f9 100644 --- a/pkg/proc/native/proc_windows.go +++ b/pkg/proc/native/proc_windows.go @@ -3,6 +3,7 @@ package native import ( "fmt" "os" + "strings" "syscall" "unicode/utf16" "unsafe" @@ -89,7 +90,7 @@ func initialize(dbp *nativeProcess) (string, error) { return "", proc.ErrProcessExited{Pid: dbp.pid, Status: exitCode} } - cmdline := dbp.getCmdLine() + cmdline := getCmdLine(dbp.os.hProcess) // Suspend all threads so that the call to _ContinueDebugEvent will // not resume the target. @@ -145,7 +146,7 @@ func findExePath(pid int) (string, error) { var debugPrivilegeRequested = false // Attach to an existing process with the given PID. -func Attach(pid int, _ []string) (*proc.TargetGroup, error) { +func Attach(pid int, waitFor *proc.WaitFor, _ []string) (*proc.TargetGroup, error) { var aperr error if !debugPrivilegeRequested { debugPrivilegeRequested = true @@ -156,6 +157,14 @@ func Attach(pid int, _ []string) (*proc.TargetGroup, error) { aperr = acquireDebugPrivilege() } + if waitFor.Valid() { + var err error + pid, err = WaitFor(waitFor) + if err != nil { + return nil, err + } + } + dbp := newProcess(pid) var err error dbp.execPtraceFunc(func() { @@ -214,6 +223,43 @@ func acquireDebugPrivilege() error { return nil } +func waitForSearchProcess(pfx string, seen map[int]struct{}) (int, error) { + log := logflags.DebuggerLogger() + handle, err := sys.CreateToolhelp32Snapshot(sys.TH32CS_SNAPPROCESS, 0) + if err != nil { + return 0, fmt.Errorf("could not get process list: %v", err) + } + defer sys.CloseHandle(handle) + + var entry sys.ProcessEntry32 + entry.Size = uint32(unsafe.Sizeof(entry)) + err = sys.Process32First(handle, &entry) + if err != nil { + return 0, fmt.Errorf("could not get process list: %v", err) + } + + for err = sys.Process32First(handle, &entry); err == nil; err = sys.Process32Next(handle, &entry) { + if _, isseen := seen[int(entry.ProcessID)]; isseen { + continue + } + seen[int(entry.ProcessID)] = struct{}{} + + hProcess, err := sys.OpenProcess(sys.PROCESS_QUERY_INFORMATION|sys.PROCESS_VM_READ, false, entry.ProcessID) + if err != nil { + continue + } + cmdline := getCmdLine(syscall.Handle(hProcess)) + sys.CloseHandle(hProcess) + + log.Debugf("waitfor: new process %q", cmdline) + if strings.HasPrefix(cmdline, pfx) { + return int(entry.ProcessID), nil + } + } + + return 0, nil +} + // kill kills the process. func (dbp *nativeProcess) kill() error { if dbp.exited { @@ -695,22 +741,22 @@ type _NTUnicodeString struct { Buffer uintptr } -func (dbp *nativeProcess) getCmdLine() string { +func getCmdLine(hProcess syscall.Handle) string { logger := logflags.DebuggerLogger() var info _PROCESS_BASIC_INFORMATION - err := sys.NtQueryInformationProcess(sys.Handle(dbp.os.hProcess), sys.ProcessBasicInformation, unsafe.Pointer(&info), uint32(unsafe.Sizeof(info)), nil) + err := sys.NtQueryInformationProcess(sys.Handle(hProcess), sys.ProcessBasicInformation, unsafe.Pointer(&info), uint32(unsafe.Sizeof(info)), nil) if err != nil { logger.Errorf("NtQueryInformationProcess: %v", err) return "" } var peb _PEB - err = _ReadProcessMemory(dbp.os.hProcess, info.PebBaseAddress, (*byte)(unsafe.Pointer(&peb)), unsafe.Sizeof(peb), nil) + err = _ReadProcessMemory(hProcess, info.PebBaseAddress, (*byte)(unsafe.Pointer(&peb)), unsafe.Sizeof(peb), nil) if err != nil { logger.Errorf("Reading PEB: %v", err) return "" } var upp _RTL_USER_PROCESS_PARAMETERS - err = _ReadProcessMemory(dbp.os.hProcess, peb.ProcessParameters, (*byte)(unsafe.Pointer(&upp)), unsafe.Sizeof(upp), nil) + err = _ReadProcessMemory(hProcess, peb.ProcessParameters, (*byte)(unsafe.Pointer(&upp)), unsafe.Sizeof(upp), nil) if err != nil { logger.Errorf("Reading ProcessParameters: %v", err) return "" @@ -720,7 +766,7 @@ func (dbp *nativeProcess) getCmdLine() string { return "" } buf := make([]byte, upp.CommandLine.Length) - err = _ReadProcessMemory(dbp.os.hProcess, upp.CommandLine.Buffer, &buf[0], uintptr(len(buf)), nil) + err = _ReadProcessMemory(hProcess, upp.CommandLine.Buffer, &buf[0], uintptr(len(buf)), nil) if err != nil { logger.Errorf("Reading CommandLine: %v", err) return "" diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 4e5d5ca987..fb77c44b12 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -20,6 +20,7 @@ import ( "sort" "strconv" "strings" + "sync" "testing" "text/tabwriter" "time" @@ -2912,13 +2913,13 @@ func TestAttachDetach(t *testing.T) { switch testBackend { case "native": - p, err = native.Attach(cmd.Process.Pid, []string{}) + p, err = native.Attach(cmd.Process.Pid, nil, []string{}) case "lldb": path := "" if runtime.GOOS == "darwin" { path = fixture.Path } - p, err = gdbserial.LLDBAttach(cmd.Process.Pid, path, []string{}) + p, err = gdbserial.LLDBAttach(cmd.Process.Pid, path, nil, []string{}) default: err = fmt.Errorf("unknown backend %q", testBackend) } @@ -6168,3 +6169,91 @@ func TestReadTargetArguments(t *testing.T) { } }) } + +func testWaitForSetup(t *testing.T, mu *sync.Mutex, started *bool) (*exec.Cmd, *proc.WaitFor) { + var buildFlags protest.BuildFlags + if buildMode == "pie" { + buildFlags |= protest.BuildModePIE + } + fixture := protest.BuildFixture("loopprog", buildFlags) + + cmd := exec.Command(fixture.Path) + + go func() { + time.Sleep(2 * time.Second) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + assertNoError(cmd.Start(), t, "starting fixture") + mu.Lock() + *started = true + mu.Unlock() + }() + + waitFor := &proc.WaitFor{Name: fixture.Path, Interval: 100 * time.Millisecond, Duration: 10 * time.Second} + + return cmd, waitFor +} + +func TestWaitFor(t *testing.T) { + skipOn(t, "waitfor implementation is delegated to debugserver", "darwin") + + var mu sync.Mutex + started := false + + cmd, waitFor := testWaitForSetup(t, &mu, &started) + + pid, err := native.WaitFor(waitFor) + assertNoError(err, t, "waitFor.Wait()") + if pid != cmd.Process.Pid { + t.Errorf("pid mismatch, expected %d got %d", pid, cmd.Process.Pid) + } + + cmd.Process.Kill() + cmd.Wait() +} + +func TestWaitForAttach(t *testing.T) { + if testBackend == "lldb" && runtime.GOOS == "linux" { + bs, _ := ioutil.ReadFile("/proc/sys/kernel/yama/ptrace_scope") + if bs == nil || strings.TrimSpace(string(bs)) != "0" { + t.Logf("can not run TestAttachDetach: %v\n", bs) + return + } + } + if testBackend == "rr" { + return + } + + var mu sync.Mutex + started := false + + cmd, waitFor := testWaitForSetup(t, &mu, &started) + + var p *proc.TargetGroup + var err error + + switch testBackend { + case "native": + p, err = native.Attach(0, waitFor, []string{}) + case "lldb": + path := "" + if runtime.GOOS == "darwin" { + path = waitFor.Name + } + p, err = gdbserial.LLDBAttach(0, path, waitFor, []string{}) + default: + err = fmt.Errorf("unknown backend %q", testBackend) + } + + assertNoError(err, t, "Attach") + + mu.Lock() + if !started { + t.Fatalf("attach succeeded but started is false") + } + mu.Unlock() + + p.Detach(true) + + cmd.Wait() +} diff --git a/pkg/proc/proc_unix_test.go b/pkg/proc/proc_unix_test.go index 0404995bec..5cc68acb1d 100644 --- a/pkg/proc/proc_unix_test.go +++ b/pkg/proc/proc_unix_test.go @@ -87,7 +87,7 @@ func TestSignalDeath(t *testing.T) { assertNoError(err, t, "StdoutPipe") cmd.Stderr = os.Stderr assertNoError(cmd.Start(), t, "starting fixture") - p, err := native.Attach(cmd.Process.Pid, []string{}) + p, err := native.Attach(cmd.Process.Pid, nil, []string{}) assertNoError(err, t, "Attach") stdout.Close() // target will receive SIGPIPE later on err = p.Continue() diff --git a/pkg/proc/target.go b/pkg/proc/target.go index a79769536f..a612f9addb 100644 --- a/pkg/proc/target.go +++ b/pkg/proc/target.go @@ -654,3 +654,9 @@ func (*dummyRecordingManipulation) ClearCheckpoint(int) error { return ErrNotRec func (*dummyRecordingManipulation) Restart(*ContinueOnceContext, string) (Thread, error) { return nil, ErrNotRecorded } + +var ErrWaitForNotImplemented = errors.New("waitfor not implemented") + +func (waitFor *WaitFor) Valid() bool { + return waitFor != nil && waitFor.Name != "" +} diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index d8608cb1f9..78a7792903 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -104,6 +104,15 @@ type Config struct { // AttachPid is the PID of an existing process to which the debugger should // attach. AttachPid int + // If AttachWaitFor is set the debugger will wait for a process with a name + // starting with WaitFor and attach to it. + AttachWaitFor string + // AttachWaitForInterval is the time (in milliseconds) that the debugger + // waits between checks for WaitFor. + AttachWaitForInterval float64 + // AttachWaitForDuration is the time (in milliseconds) that the debugger + // waits for WaitFor. + AttachWaitForDuration float64 // CoreFile specifies the path to the core dump to open. CoreFile string @@ -163,14 +172,22 @@ func New(config *Config, processArgs []string) (*Debugger, error) { // Create the process by either attaching or launching. switch { - case d.config.AttachPid > 0: + case d.config.AttachPid > 0 || d.config.AttachWaitFor != "": d.log.Infof("attaching to pid %d", d.config.AttachPid) path := "" if len(d.processArgs) > 0 { path = d.processArgs[0] } + var waitFor *proc.WaitFor + if d.config.AttachWaitFor != "" { + waitFor = &proc.WaitFor{ + Name: d.config.AttachWaitFor, + Interval: time.Duration(d.config.AttachWaitForInterval * float64(time.Millisecond)), + Duration: time.Duration(d.config.AttachWaitForDuration * float64(time.Millisecond)), + } + } var err error - d.target, err = d.Attach(d.config.AttachPid, path) + d.target, err = d.Attach(d.config.AttachPid, path, waitFor) if err != nil { err = go11DecodeErrorCheck(err) err = noDebugErrorWarning(err) @@ -345,17 +362,17 @@ func (d *Debugger) recordingRun(run func() (string, error)) (*proc.TargetGroup, } // Attach will attach to the process specified by 'pid'. -func (d *Debugger) Attach(pid int, path string) (*proc.TargetGroup, error) { +func (d *Debugger) Attach(pid int, path string, waitFor *proc.WaitFor) (*proc.TargetGroup, error) { switch d.config.Backend { case "native": - return native.Attach(pid, d.config.DebugInfoDirectories) + return native.Attach(pid, waitFor, d.config.DebugInfoDirectories) case "lldb": - return betterGdbserialLaunchError(gdbserial.LLDBAttach(pid, path, d.config.DebugInfoDirectories)) + return betterGdbserialLaunchError(gdbserial.LLDBAttach(pid, path, waitFor, d.config.DebugInfoDirectories)) case "default": if runtime.GOOS == "darwin" { - return betterGdbserialLaunchError(gdbserial.LLDBAttach(pid, path, d.config.DebugInfoDirectories)) + return betterGdbserialLaunchError(gdbserial.LLDBAttach(pid, path, waitFor, d.config.DebugInfoDirectories)) } - return native.Attach(pid, d.config.DebugInfoDirectories) + return native.Attach(pid, waitFor, d.config.DebugInfoDirectories) default: return nil, fmt.Errorf("unknown backend %q", d.config.Backend) } From caf6df0eb9180d539170c1d8b923adef5f7106ca Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 9 Aug 2023 19:37:55 +0200 Subject: [PATCH 089/114] Documentation,cmd/dlv: clean up command line usage help (#3395) Due to some very old mistakes too many of Delve's flags are declared as persistent on cobra's root command. For example the headless flag is a global flag but does not apply to connect, dap or trace; the backend flag does not apply to replay, core and dap; etc. Almost all global flags should have been declared as local flags on individual subcommands. Unfortunately we can not change this without breaking backwards compatibility, for example: dlv --headless debug would not parse if headless was a flag of debug instead of a global flag. Instead we alter usage function and the markdown generation script to strategically hide the flags that don't apply. Fixes #2361 --- Documentation/usage/dlv.md | 19 +----- Documentation/usage/dlv_attach.md | 4 -- Documentation/usage/dlv_connect.md | 21 ++----- Documentation/usage/dlv_core.md | 5 -- Documentation/usage/dlv_dap.md | 23 +++---- Documentation/usage/dlv_exec.md | 1 - Documentation/usage/dlv_replay.md | 5 -- Documentation/usage/dlv_trace.md | 25 +++----- Documentation/usage/dlv_version.md | 3 +- _scripts/gen-usage-docs.go | 16 +++-- cmd/dlv/cmds/commands.go | 20 +++++++ cmd/dlv/cmds/helphelpers/help.go | 96 ++++++++++++++++++++++++++++++ go.mod | 1 + vendor/modules.txt | 1 + 14 files changed, 153 insertions(+), 87 deletions(-) create mode 100644 cmd/dlv/cmds/helphelpers/help.go diff --git a/Documentation/usage/dlv.md b/Documentation/usage/dlv.md index 5e75d2a3ec..d0c1dfb4a3 100644 --- a/Documentation/usage/dlv.md +++ b/Documentation/usage/dlv.md @@ -18,23 +18,7 @@ Pass flags to the program you are debugging using `--`, for example: ### Options ``` - --accept-multiclient Allows a headless server to accept multiple client connections via JSON-RPC or DAP. - --allow-non-terminal-interactive Allows interactive sessions of Delve that don't have a terminal as stdin, stdout and stderr - --api-version int Selects JSON-RPC API version when headless. New clients should use v2. Can be reset via RPCServer.SetApiVersion. See Documentation/api/json-rpc/README.md. (default 1) - --backend string Backend selection (see 'dlv help backend'). (default "default") - --build-flags string Build flags, to be passed to the compiler. For example: --build-flags="-tags=integration -mod=vendor -cover -v" - --check-go-version Exits if the version of Go in use is not compatible (too old or too new) with the version of Delve. (default true) - --disable-aslr Disables address space randomization - --headless Run debug server only, in headless mode. Server will accept both JSON-RPC or DAP client connections. - -h, --help help for dlv - --init string Init file, executed by the terminal client. - -l, --listen string Debugging server listen address. (default "127.0.0.1:0") - --log Enable debugging server logging. - --log-dest string Writes logs to the specified file or file descriptor (see 'dlv help log'). - --log-output string Comma separated list of components that should produce debug output (see 'dlv help log') - --only-same-user Only connections from the same user that started this instance of Delve are allowed to connect. (default true) - -r, --redirect stringArray Specifies redirect rules for target process (see 'dlv help redirect') - --wd string Working directory for running the program. + -h, --help help for dlv ``` ### SEE ALSO @@ -46,7 +30,6 @@ Pass flags to the program you are debugging using `--`, for example: * [dlv debug](dlv_debug.md) - Compile and begin debugging main package in current directory, or the package specified. * [dlv exec](dlv_exec.md) - Execute a precompiled binary, and begin a debug session. * [dlv replay](dlv_replay.md) - Replays a rr trace. -* [dlv run](dlv_run.md) - Deprecated command. Use 'debug' instead. * [dlv test](dlv_test.md) - Compile test binary and begin debugging program. * [dlv trace](dlv_trace.md) - Compile and begin tracing program. * [dlv version](dlv_version.md) - Prints version. diff --git a/Documentation/usage/dlv_attach.md b/Documentation/usage/dlv_attach.md index ac9164e24f..a86973cdbe 100644 --- a/Documentation/usage/dlv_attach.md +++ b/Documentation/usage/dlv_attach.md @@ -32,9 +32,7 @@ dlv attach pid [executable] [flags] --allow-non-terminal-interactive Allows interactive sessions of Delve that don't have a terminal as stdin, stdout and stderr --api-version int Selects JSON-RPC API version when headless. New clients should use v2. Can be reset via RPCServer.SetApiVersion. See Documentation/api/json-rpc/README.md. (default 1) --backend string Backend selection (see 'dlv help backend'). (default "default") - --build-flags string Build flags, to be passed to the compiler. For example: --build-flags="-tags=integration -mod=vendor -cover -v" --check-go-version Exits if the version of Go in use is not compatible (too old or too new) with the version of Delve. (default true) - --disable-aslr Disables address space randomization --headless Run debug server only, in headless mode. Server will accept both JSON-RPC or DAP client connections. --init string Init file, executed by the terminal client. -l, --listen string Debugging server listen address. (default "127.0.0.1:0") @@ -42,8 +40,6 @@ dlv attach pid [executable] [flags] --log-dest string Writes logs to the specified file or file descriptor (see 'dlv help log'). --log-output string Comma separated list of components that should produce debug output (see 'dlv help log') --only-same-user Only connections from the same user that started this instance of Delve are allowed to connect. (default true) - -r, --redirect stringArray Specifies redirect rules for target process (see 'dlv help redirect') - --wd string Working directory for running the program. ``` ### SEE ALSO diff --git a/Documentation/usage/dlv_connect.md b/Documentation/usage/dlv_connect.md index 266e3ccea8..c83e94d0a6 100644 --- a/Documentation/usage/dlv_connect.md +++ b/Documentation/usage/dlv_connect.md @@ -19,22 +19,11 @@ dlv connect addr [flags] ### Options inherited from parent commands ``` - --accept-multiclient Allows a headless server to accept multiple client connections via JSON-RPC or DAP. - --allow-non-terminal-interactive Allows interactive sessions of Delve that don't have a terminal as stdin, stdout and stderr - --api-version int Selects JSON-RPC API version when headless. New clients should use v2. Can be reset via RPCServer.SetApiVersion. See Documentation/api/json-rpc/README.md. (default 1) - --backend string Backend selection (see 'dlv help backend'). (default "default") - --build-flags string Build flags, to be passed to the compiler. For example: --build-flags="-tags=integration -mod=vendor -cover -v" - --check-go-version Exits if the version of Go in use is not compatible (too old or too new) with the version of Delve. (default true) - --disable-aslr Disables address space randomization - --headless Run debug server only, in headless mode. Server will accept both JSON-RPC or DAP client connections. - --init string Init file, executed by the terminal client. - -l, --listen string Debugging server listen address. (default "127.0.0.1:0") - --log Enable debugging server logging. - --log-dest string Writes logs to the specified file or file descriptor (see 'dlv help log'). - --log-output string Comma separated list of components that should produce debug output (see 'dlv help log') - --only-same-user Only connections from the same user that started this instance of Delve are allowed to connect. (default true) - -r, --redirect stringArray Specifies redirect rules for target process (see 'dlv help redirect') - --wd string Working directory for running the program. + --backend string Backend selection (see 'dlv help backend'). (default "default") + --init string Init file, executed by the terminal client. + --log Enable debugging server logging. + --log-dest string Writes logs to the specified file or file descriptor (see 'dlv help log'). + --log-output string Comma separated list of components that should produce debug output (see 'dlv help log') ``` ### SEE ALSO diff --git a/Documentation/usage/dlv_core.md b/Documentation/usage/dlv_core.md index 51a2c33411..456e908c0e 100644 --- a/Documentation/usage/dlv_core.md +++ b/Documentation/usage/dlv_core.md @@ -28,10 +28,7 @@ dlv core [flags] --accept-multiclient Allows a headless server to accept multiple client connections via JSON-RPC or DAP. --allow-non-terminal-interactive Allows interactive sessions of Delve that don't have a terminal as stdin, stdout and stderr --api-version int Selects JSON-RPC API version when headless. New clients should use v2. Can be reset via RPCServer.SetApiVersion. See Documentation/api/json-rpc/README.md. (default 1) - --backend string Backend selection (see 'dlv help backend'). (default "default") - --build-flags string Build flags, to be passed to the compiler. For example: --build-flags="-tags=integration -mod=vendor -cover -v" --check-go-version Exits if the version of Go in use is not compatible (too old or too new) with the version of Delve. (default true) - --disable-aslr Disables address space randomization --headless Run debug server only, in headless mode. Server will accept both JSON-RPC or DAP client connections. --init string Init file, executed by the terminal client. -l, --listen string Debugging server listen address. (default "127.0.0.1:0") @@ -39,8 +36,6 @@ dlv core [flags] --log-dest string Writes logs to the specified file or file descriptor (see 'dlv help log'). --log-output string Comma separated list of components that should produce debug output (see 'dlv help log') --only-same-user Only connections from the same user that started this instance of Delve are allowed to connect. (default true) - -r, --redirect stringArray Specifies redirect rules for target process (see 'dlv help redirect') - --wd string Working directory for running the program. ``` ### SEE ALSO diff --git a/Documentation/usage/dlv_dap.md b/Documentation/usage/dlv_dap.md index b76fbe1f38..3f5f7db840 100644 --- a/Documentation/usage/dlv_dap.md +++ b/Documentation/usage/dlv_dap.md @@ -40,22 +40,13 @@ dlv dap [flags] ### Options inherited from parent commands ``` - --accept-multiclient Allows a headless server to accept multiple client connections via JSON-RPC or DAP. - --allow-non-terminal-interactive Allows interactive sessions of Delve that don't have a terminal as stdin, stdout and stderr - --api-version int Selects JSON-RPC API version when headless. New clients should use v2. Can be reset via RPCServer.SetApiVersion. See Documentation/api/json-rpc/README.md. (default 1) - --backend string Backend selection (see 'dlv help backend'). (default "default") - --build-flags string Build flags, to be passed to the compiler. For example: --build-flags="-tags=integration -mod=vendor -cover -v" - --check-go-version Exits if the version of Go in use is not compatible (too old or too new) with the version of Delve. (default true) - --disable-aslr Disables address space randomization - --headless Run debug server only, in headless mode. Server will accept both JSON-RPC or DAP client connections. - --init string Init file, executed by the terminal client. - -l, --listen string Debugging server listen address. (default "127.0.0.1:0") - --log Enable debugging server logging. - --log-dest string Writes logs to the specified file or file descriptor (see 'dlv help log'). - --log-output string Comma separated list of components that should produce debug output (see 'dlv help log') - --only-same-user Only connections from the same user that started this instance of Delve are allowed to connect. (default true) - -r, --redirect stringArray Specifies redirect rules for target process (see 'dlv help redirect') - --wd string Working directory for running the program. + --check-go-version Exits if the version of Go in use is not compatible (too old or too new) with the version of Delve. (default true) + --disable-aslr Disables address space randomization + -l, --listen string Debugging server listen address. (default "127.0.0.1:0") + --log Enable debugging server logging. + --log-dest string Writes logs to the specified file or file descriptor (see 'dlv help log'). + --log-output string Comma separated list of components that should produce debug output (see 'dlv help log') + --only-same-user Only connections from the same user that started this instance of Delve are allowed to connect. (default true) ``` ### SEE ALSO diff --git a/Documentation/usage/dlv_exec.md b/Documentation/usage/dlv_exec.md index 38e0716bfd..70d9653603 100644 --- a/Documentation/usage/dlv_exec.md +++ b/Documentation/usage/dlv_exec.md @@ -31,7 +31,6 @@ dlv exec [flags] --allow-non-terminal-interactive Allows interactive sessions of Delve that don't have a terminal as stdin, stdout and stderr --api-version int Selects JSON-RPC API version when headless. New clients should use v2. Can be reset via RPCServer.SetApiVersion. See Documentation/api/json-rpc/README.md. (default 1) --backend string Backend selection (see 'dlv help backend'). (default "default") - --build-flags string Build flags, to be passed to the compiler. For example: --build-flags="-tags=integration -mod=vendor -cover -v" --check-go-version Exits if the version of Go in use is not compatible (too old or too new) with the version of Delve. (default true) --disable-aslr Disables address space randomization --headless Run debug server only, in headless mode. Server will accept both JSON-RPC or DAP client connections. diff --git a/Documentation/usage/dlv_replay.md b/Documentation/usage/dlv_replay.md index 8cec2ef924..6f783563ef 100644 --- a/Documentation/usage/dlv_replay.md +++ b/Documentation/usage/dlv_replay.md @@ -27,10 +27,7 @@ dlv replay [trace directory] [flags] --accept-multiclient Allows a headless server to accept multiple client connections via JSON-RPC or DAP. --allow-non-terminal-interactive Allows interactive sessions of Delve that don't have a terminal as stdin, stdout and stderr --api-version int Selects JSON-RPC API version when headless. New clients should use v2. Can be reset via RPCServer.SetApiVersion. See Documentation/api/json-rpc/README.md. (default 1) - --backend string Backend selection (see 'dlv help backend'). (default "default") - --build-flags string Build flags, to be passed to the compiler. For example: --build-flags="-tags=integration -mod=vendor -cover -v" --check-go-version Exits if the version of Go in use is not compatible (too old or too new) with the version of Delve. (default true) - --disable-aslr Disables address space randomization --headless Run debug server only, in headless mode. Server will accept both JSON-RPC or DAP client connections. --init string Init file, executed by the terminal client. -l, --listen string Debugging server listen address. (default "127.0.0.1:0") @@ -38,8 +35,6 @@ dlv replay [trace directory] [flags] --log-dest string Writes logs to the specified file or file descriptor (see 'dlv help log'). --log-output string Comma separated list of components that should produce debug output (see 'dlv help log') --only-same-user Only connections from the same user that started this instance of Delve are allowed to connect. (default true) - -r, --redirect stringArray Specifies redirect rules for target process (see 'dlv help redirect') - --wd string Working directory for running the program. ``` ### SEE ALSO diff --git a/Documentation/usage/dlv_trace.md b/Documentation/usage/dlv_trace.md index a6428100b9..9fe9593324 100644 --- a/Documentation/usage/dlv_trace.md +++ b/Documentation/usage/dlv_trace.md @@ -34,22 +34,15 @@ dlv trace [package] regexp [flags] ### Options inherited from parent commands ``` - --accept-multiclient Allows a headless server to accept multiple client connections via JSON-RPC or DAP. - --allow-non-terminal-interactive Allows interactive sessions of Delve that don't have a terminal as stdin, stdout and stderr - --api-version int Selects JSON-RPC API version when headless. New clients should use v2. Can be reset via RPCServer.SetApiVersion. See Documentation/api/json-rpc/README.md. (default 1) - --backend string Backend selection (see 'dlv help backend'). (default "default") - --build-flags string Build flags, to be passed to the compiler. For example: --build-flags="-tags=integration -mod=vendor -cover -v" - --check-go-version Exits if the version of Go in use is not compatible (too old or too new) with the version of Delve. (default true) - --disable-aslr Disables address space randomization - --headless Run debug server only, in headless mode. Server will accept both JSON-RPC or DAP client connections. - --init string Init file, executed by the terminal client. - -l, --listen string Debugging server listen address. (default "127.0.0.1:0") - --log Enable debugging server logging. - --log-dest string Writes logs to the specified file or file descriptor (see 'dlv help log'). - --log-output string Comma separated list of components that should produce debug output (see 'dlv help log') - --only-same-user Only connections from the same user that started this instance of Delve are allowed to connect. (default true) - -r, --redirect stringArray Specifies redirect rules for target process (see 'dlv help redirect') - --wd string Working directory for running the program. + --backend string Backend selection (see 'dlv help backend'). (default "default") + --build-flags string Build flags, to be passed to the compiler. For example: --build-flags="-tags=integration -mod=vendor -cover -v" + --check-go-version Exits if the version of Go in use is not compatible (too old or too new) with the version of Delve. (default true) + --disable-aslr Disables address space randomization + --log Enable debugging server logging. + --log-dest string Writes logs to the specified file or file descriptor (see 'dlv help log'). + --log-output string Comma separated list of components that should produce debug output (see 'dlv help log') + -r, --redirect stringArray Specifies redirect rules for target process (see 'dlv help redirect') + --wd string Working directory for running the program. ``` ### SEE ALSO diff --git a/Documentation/usage/dlv_version.md b/Documentation/usage/dlv_version.md index b1d2101c7c..b04dd76eb6 100644 --- a/Documentation/usage/dlv_version.md +++ b/Documentation/usage/dlv_version.md @@ -9,8 +9,7 @@ dlv version [flags] ### Options ``` - -h, --help help for version - -v, --verbose print verbose version info + -h, --help help for version ``` ### Options inherited from parent commands diff --git a/_scripts/gen-usage-docs.go b/_scripts/gen-usage-docs.go index 02c9b4a9d4..ce226a3aaf 100644 --- a/_scripts/gen-usage-docs.go +++ b/_scripts/gen-usage-docs.go @@ -10,6 +10,7 @@ import ( "path/filepath" "github.com/go-delve/delve/cmd/dlv/cmds" + "github.com/go-delve/delve/cmd/dlv/cmds/helphelpers" "github.com/spf13/cobra/doc" ) @@ -21,12 +22,19 @@ func main() { usageDir = os.Args[1] } root := cmds.New(true) + + cmdnames := []string{} + for _, subcmd := range root.Commands() { + cmdnames = append(cmdnames, subcmd.Name()) + } + helphelpers.Prepare(root) doc.GenMarkdownTree(root, usageDir) + root = nil // GenMarkdownTree ignores additional help topic commands, so we have to do this manually - for _, cmd := range root.Commands() { - if cmd.Run == nil { - doc.GenMarkdownTree(cmd, usageDir) - } + for _, cmdname := range cmdnames { + cmd, _, _ := cmds.New(true).Find([]string{cmdname}) + helphelpers.Prepare(cmd) + doc.GenMarkdownTree(cmd, usageDir) } fh, err := os.OpenFile(filepath.Join(usageDir, "dlv.md"), os.O_APPEND|os.O_WRONLY, 0) if err != nil { diff --git a/cmd/dlv/cmds/commands.go b/cmd/dlv/cmds/commands.go index dbb4bcdbb8..fb71f26e6a 100644 --- a/cmd/dlv/cmds/commands.go +++ b/cmd/dlv/cmds/commands.go @@ -16,6 +16,7 @@ import ( "syscall" "time" + "github.com/go-delve/delve/cmd/dlv/cmds/helphelpers" "github.com/go-delve/delve/pkg/config" "github.com/go-delve/delve/pkg/gobuild" "github.com/go-delve/delve/pkg/goversion" @@ -276,6 +277,7 @@ or later, -gcflags="-N -l" on earlier versions of Go.`, fmt.Println("This command is deprecated, please use 'debug' instead.") os.Exit(0) }, + Hidden: true, } rootCommand.AddCommand(runCommand) @@ -452,6 +454,8 @@ File redirects can also be changed using the 'restart' command. rootCommand.DisableAutoGenTag = true + configUsageFunc(rootCommand) + return rootCommand } @@ -1099,3 +1103,19 @@ func parseRedirects(redirects []string) ([3]string, error) { } return r, nil } + +func configUsageFunc(cmd *cobra.Command) { + for _, subcmd := range cmd.Commands() { + configUsageFunc(subcmd) + } + + if cmd.Run == nil && cmd.Name() != "dlv" { + return + } + + usage := cmd.UsageFunc() + cmd.SetUsageFunc(func(cmd *cobra.Command) error { + helphelpers.Prepare(cmd) + return usage(cmd) + }) +} diff --git a/cmd/dlv/cmds/helphelpers/help.go b/cmd/dlv/cmds/helphelpers/help.go new file mode 100644 index 0000000000..aff5e9258f --- /dev/null +++ b/cmd/dlv/cmds/helphelpers/help.go @@ -0,0 +1,96 @@ +package helphelpers + +import ( + "github.com/spf13/cobra" + "github.com/spf13/pflag" +) + +// Prepare prepares cmd flag set for the invocation of its usage function by +// hiding flags that we want cobra to parse but we don't want to show to the +// user. +// We do this because not all flags associated with the root command are +// valid for all subcommands but we don't want to move them out of the root +// command and into subcommands, since that would change how cobra parses +// the command line. +// +// For example: +// +// dlv --headless debug +// +// must parse successfully even though the headless flag is not applicable +// to the 'connect' subcommand. +// +// Prepare is a destructive command, cmd can not be reused after it has been +// called. +func Prepare(cmd *cobra.Command) { + switch cmd.Name() { + case "dlv", "help", "run", "version": + hideAllFlags(cmd) + case "attach": + hideFlag(cmd, "build-flags") + hideFlag(cmd, "disable-aslr") + hideFlag(cmd, "redirect") + hideFlag(cmd, "wd") + case "connect": + hideFlag(cmd, "accept-multiclient") + hideFlag(cmd, "allow-non-terminal-interactive") + hideFlag(cmd, "api-version") + hideFlag(cmd, "build-flags") + hideFlag(cmd, "check-go-version") + hideFlag(cmd, "disable-aslr") + hideFlag(cmd, "headless") + hideFlag(cmd, "listen") + hideFlag(cmd, "only-same-user") + hideFlag(cmd, "redirect") + hideFlag(cmd, "wd") + case "dap": + hideFlag(cmd, "headless") + hideFlag(cmd, "accept-multiclient") + hideFlag(cmd, "init") + hideFlag(cmd, "backend") + hideFlag(cmd, "build-flags") + hideFlag(cmd, "wd") + hideFlag(cmd, "redirect") + hideFlag(cmd, "api-version") + hideFlag(cmd, "allow-non-terminal-interactive") + case "debug", "test": + // All flags apply + case "exec": + hideFlag(cmd, "build-flags") + case "replay", "core": + hideFlag(cmd, "backend") + hideFlag(cmd, "build-flags") + hideFlag(cmd, "disable-aslr") + hideFlag(cmd, "redirect") + hideFlag(cmd, "wd") + case "trace": + hideFlag(cmd, "accept-multiclient") + hideFlag(cmd, "allow-non-terminal-interactive") + hideFlag(cmd, "api-version") + hideFlag(cmd, "headless") + hideFlag(cmd, "init") + hideFlag(cmd, "listen") + hideFlag(cmd, "only-same-user") + } +} + +func hideAllFlags(cmd *cobra.Command) { + cmd.PersistentFlags().VisitAll(func(flag *pflag.Flag) { + flag.Hidden = true + }) + cmd.Flags().VisitAll(func(flag *pflag.Flag) { + flag.Hidden = true + }) +} + +func hideFlag(cmd *cobra.Command, name string) { + if cmd == nil { + return + } + flag := cmd.Flags().Lookup(name) + if flag != nil { + flag.Hidden = true + return + } + hideFlag(cmd.Parent(), name) +} diff --git a/go.mod b/go.mod index 9385f2d4a3..e0bf91d182 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/mattn/go-runewidth v0.0.13 // indirect github.com/sirupsen/logrus v1.6.0 github.com/spf13/cobra v1.1.3 + github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.7.0 // indirect go.starlark.net v0.0.0-20220816155156-cfacd8902214 golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4 diff --git a/vendor/modules.txt b/vendor/modules.txt index e2812d1f92..e9e284efa3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -55,6 +55,7 @@ github.com/sirupsen/logrus github.com/spf13/cobra github.com/spf13/cobra/doc # github.com/spf13/pflag v1.0.5 +## explicit github.com/spf13/pflag # github.com/stretchr/testify v1.7.0 ## explicit From e49c81cc5d8e647778154337b7d39e532cc6edb4 Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Fri, 11 Aug 2023 08:51:28 -0700 Subject: [PATCH 090/114] *: Fix ppc64le test runs (#3460) We must pass the build tag through during the 'vet' check, and additionally there was some extra commands at the end of test_linux.sh that were not necessary. --- Makefile | 2 +- _scripts/test_linux.sh | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/Makefile b/Makefile index fd9672e1ef..7e756a4dd5 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ test: vet @go run _scripts/make.go test -v vet: - @go vet $$(go list ./... | grep -v native) + @go vet -tags exp.linuxppc64le $$(go list -tags exp.linuxppc64le ./... | grep -v native) test-proc-run: @go run _scripts/make.go test -s proc -r $(RUN) diff --git a/_scripts/test_linux.sh b/_scripts/test_linux.sh index a84d73abb3..ea5666629d 100755 --- a/_scripts/test_linux.sh +++ b/_scripts/test_linux.sh @@ -75,12 +75,3 @@ if [ "$version" = "gotip" ]; then else exit $x fi - -export GOARCH=ppc64le -go run _scripts/make.go --tags exp.linuxppc64le -x=$? -if [ "$version" = "gotip" ]; then - exit 0 -else - exit $x -fi From 891a1f080d61b6879a2d93578c000eac49c1059b Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Fri, 11 Aug 2023 17:52:35 +0200 Subject: [PATCH 091/114] goversion,teamcity: update test matrix and fix build scripts (#3463) Update test matrix to remove 1.18 and add 1.21, fix build scripts to deal with the new format returned by: https://golang.org/VERSION?m=text which now has an extra second line with the time. --- .teamcity/settings.kts | 16 ++++++++-------- _scripts/test_linux.sh | 2 +- _scripts/test_mac.sh | 2 +- _scripts/test_windows.ps1 | 2 +- pkg/goversion/compat.go | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.teamcity/settings.kts b/.teamcity/settings.kts index f3ffc67181..ecb23afc4c 100644 --- a/.teamcity/settings.kts +++ b/.teamcity/settings.kts @@ -35,29 +35,29 @@ To debug in IntelliJ Idea, open the 'Maven Projects' tool window (View version = "2020.2" val targets = arrayOf( - "linux/amd64/1.18", "linux/amd64/1.19", "linux/amd64/1.20", + "linux/amd64/1.21", "linux/amd64/tip", - "linux/386/1.20", + "linux/386/1.21", - "linux/arm64/1.20", + "linux/arm64/1.21", "linux/arm64/tip", - "linux/ppc64le/1.20", + "linux/ppc64le/1.21", "linux/ppc64le/tip", - "windows/amd64/1.20", + "windows/amd64/1.21", "windows/amd64/tip", - "windows/arm64/1.20", + "windows/arm64/1.21", "windows/arm64/tip", - "mac/amd64/1.20", + "mac/amd64/1.21", "mac/amd64/tip", - "mac/arm64/1.20", + "mac/arm64/1.21", "mac/arm64/tip" ) diff --git a/_scripts/test_linux.sh b/_scripts/test_linux.sh index ea5666629d..e788ad1b4a 100755 --- a/_scripts/test_linux.sh +++ b/_scripts/test_linux.sh @@ -22,7 +22,7 @@ function getgo { if [ "$version" = "gotip" ]; then echo Building Go from tip - getgo $(curl https://go.dev/VERSION?m=text) + getgo $(curl https://go.dev/VERSION?m=text | head -1) export GOROOT_BOOTSTRAP=$GOROOT export GOROOT=/usr/local/go/go-tip git clone https://go.googlesource.com/go /usr/local/go/go-tip diff --git a/_scripts/test_mac.sh b/_scripts/test_mac.sh index 72ba4957c7..78b2159406 100644 --- a/_scripts/test_mac.sh +++ b/_scripts/test_mac.sh @@ -8,7 +8,7 @@ ARCH=$2 TMPDIR=$3 if [ "$GOVERSION" = "gotip" ]; then - bootstrapver=$(curl https://go.dev/VERSION?m=text) + bootstrapver=$(curl https://go.dev/VERSION?m=text | head -1) cd $TMPDIR curl -sSL "https://storage.googleapis.com/golang/$bootstrapver.darwin-$ARCH.tar.gz" | tar -xz cd - diff --git a/_scripts/test_windows.ps1 b/_scripts/test_windows.ps1 index 6c2b595c0e..d1c6005c3e 100644 --- a/_scripts/test_windows.ps1 +++ b/_scripts/test_windows.ps1 @@ -57,7 +57,7 @@ function GetGo($version) { if ($version -eq "gotip") { #Exit 0 - $latest = Invoke-WebRequest -Uri "https://golang.org/VERSION?m=text" -UseBasicParsing | Select-Object -ExpandProperty Content -ErrorAction Stop + $latest = (Invoke-WebRequest -Uri "https://golang.org/VERSION?m=text" -UseBasicParsing | Select-Object -ExpandProperty Content -ErrorAction Stop).Split([Environment]::NewLine) | select -first 1 GetGo $latest $env:GOROOT_BOOTSTRAP = $env:GOROOT $env:GOROOT = "$binDir\go\go-tip" diff --git a/pkg/goversion/compat.go b/pkg/goversion/compat.go index 8471db796c..fa2c3392e2 100644 --- a/pkg/goversion/compat.go +++ b/pkg/goversion/compat.go @@ -8,7 +8,7 @@ import ( var ( MinSupportedVersionOfGoMajor = 1 - MinSupportedVersionOfGoMinor = 18 + MinSupportedVersionOfGoMinor = 19 MaxSupportedVersionOfGoMajor = 1 MaxSupportedVersionOfGoMinor = 21 goTooOldErr = fmt.Sprintf("Go version %%s is too old for this version of Delve (minimum supported version %d.%d, suppress this error with --check-go-version=false)", MinSupportedVersionOfGoMajor, MinSupportedVersionOfGoMinor) From 17d1f4c8299599c6d7ae3f41c7edbe9dbe753098 Mon Sep 17 00:00:00 2001 From: gocurr Date: Sat, 12 Aug 2023 15:41:30 +0800 Subject: [PATCH 092/114] service/dap: use == to test io.EOF (#3464) The documentation of io.EOF: Read must return EOF itself, not an error wrapping EOF, because callers will test for EOF using ==. This is a trivial change; people may think it's normal use of "errors.Is", even it's OK, it could be replaced with "errors.Is(err, io.EOF)" in idiomatic way. --- service/dap/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/dap/server.go b/service/dap/server.go index 990f9679ac..50c409f740 100644 --- a/service/dap/server.go +++ b/service/dap/server.go @@ -1051,7 +1051,7 @@ func (s *Session) onLaunchRequest(request *dap.LaunchRequest) { for { n, err := reader.Read(out[:]) if err != nil { - if errors.Is(io.EOF, err) { + if err == io.EOF { return } s.config.log.Errorf("failed read by %s - %v ", category, err) From 894ba6340067cd35fca85275fae09b32a1a3eb6a Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 14 Aug 2023 20:07:57 +0200 Subject: [PATCH 093/114] teamcity: hold back linux/386 builds to 1.20 (#3465) Programs built with `-gcflags='all=-N -l'` do not work on linux/386/1.21 due to https://github.com/golang/go/issues/61975 --- .teamcity/settings.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.teamcity/settings.kts b/.teamcity/settings.kts index ecb23afc4c..fda747c64d 100644 --- a/.teamcity/settings.kts +++ b/.teamcity/settings.kts @@ -40,7 +40,7 @@ val targets = arrayOf( "linux/amd64/1.21", "linux/amd64/tip", - "linux/386/1.21", + "linux/386/1.20", "linux/arm64/1.21", "linux/arm64/tip", From ec07c27fc734508151c5fcd70985eb403f6ae627 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 15 Aug 2023 00:31:05 +0200 Subject: [PATCH 094/114] proc: fix PIE support on macOS (#3467) Go1.22 switched to emitting PIE by default and also changed some details of the PIE implementation. This breaks delve entirely on macOS. Fix how relocations are handled on macOS. --- pkg/proc/bininfo.go | 16 +++++++++++----- pkg/proc/gdbserial/gdbserver.go | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go index c63fb16f4a..4183196dcc 100644 --- a/pkg/proc/bininfo.go +++ b/pkg/proc/bininfo.go @@ -1805,11 +1805,17 @@ func loadBinaryInfoMacho(bi *BinaryInfo, image *Image, path string, entryPoint u } if entryPoint != 0 { - // This is a little bit hacky. We use the entryPoint variable, but it - // actually holds the address of the mach-o header. We can use this - // to calculate the offset to the non-aslr location of the mach-o header - // (which is 0x100000000) - image.StaticBase = entryPoint - 0x100000000 + machoOff := uint64(0x100000000) + for _, ld := range exe.Loads { + if seg, _ := ld.(*macho.Segment); seg != nil { + if seg.Name == "__TEXT" { + machoOff = seg.Addr + break + } + } + } + logflags.DebuggerLogger().Debugf("entryPoint %#x machoOff %#x", entryPoint, machoOff) + image.StaticBase = entryPoint - machoOff } image.closer = exe diff --git a/pkg/proc/gdbserial/gdbserver.go b/pkg/proc/gdbserial/gdbserver.go index bb57f3d587..311a21cd02 100644 --- a/pkg/proc/gdbserial/gdbserver.go +++ b/pkg/proc/gdbserial/gdbserver.go @@ -662,7 +662,7 @@ func LLDBAttach(pid int, path string, waitFor *proc.WaitFor, debugInfoDirs []str // debugging PIEs. func (p *gdbProcess) EntryPoint() (uint64, error) { var entryPoint uint64 - if p.bi.GOOS == "darwin" && p.bi.Arch.Name == "arm64" { + if p.bi.GOOS == "darwin" { // There is no auxv on darwin, however, we can get the location of the mach-o // header from the debugserver by going through the loaded libraries, which includes // the exe itself From 281f3920ddc339e425a1b99d5d853d52021bc860 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 15 Aug 2023 00:32:15 +0200 Subject: [PATCH 095/114] proc: fix stacktraces on freebsd/amd64/go1.20 (#3458) TestStacktraceGoroutine failed intermittently on freebsd/amd64/go1.20. This happens because of two windows, in the scheduler (right after parking a goroutine and just before resuming a parked goroutine) where a thread is associated with a goroutine but running in the system stack and there is no systemstack_switch frame to connect the two stacks. --- pkg/proc/amd64_arch.go | 10 +++++++++- pkg/proc/arm64_arch.go | 11 ++++++++++- pkg/proc/i386_arch.go | 10 +++++++++- pkg/proc/ppc64le_arch.go | 9 ++++++++- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/pkg/proc/amd64_arch.go b/pkg/proc/amd64_arch.go index dc426ac3d8..26a16fa087 100644 --- a/pkg/proc/amd64_arch.go +++ b/pkg/proc/amd64_arch.go @@ -200,11 +200,19 @@ func amd64SwitchStack(it *stackIterator, _ *op.DwarfRegisters) bool { return true - case "runtime.goexit", "runtime.rt0_go", "runtime.mcall": + case "runtime.goexit", "runtime.rt0_go": // Look for "top of stack" functions. it.atend = true return true + case "runtime.mcall": + if it.systemstack && it.g != nil { + it.switchToGoroutineStack() + return true + } + it.atend = true + return true + case "runtime.mstart": // Calls to runtime.systemstack will switch to the systemstack then: // 1. alter the goroutine stack so that it looks like systemstack_switch diff --git a/pkg/proc/arm64_arch.go b/pkg/proc/arm64_arch.go index 426fbbce4d..2e646be4e5 100644 --- a/pkg/proc/arm64_arch.go +++ b/pkg/proc/arm64_arch.go @@ -217,10 +217,19 @@ func arm64SwitchStack(it *stackIterator, callFrameRegs *op.DwarfRegisters) bool return true } - case "runtime.goexit", "runtime.rt0_go", "runtime.mcall": + case "runtime.goexit", "runtime.rt0_go": // Look for "top of stack" functions. it.atend = true return true + + case "runtime.mcall": + if it.systemstack && it.g != nil { + it.switchToGoroutineStack() + return true + } + it.atend = true + return true + case "crosscall2": // The offsets get from runtime/cgo/asm_arm64.s:10 bpoff := uint64(14) diff --git a/pkg/proc/i386_arch.go b/pkg/proc/i386_arch.go index 2bb53cc381..f04aa0d3dd 100644 --- a/pkg/proc/i386_arch.go +++ b/pkg/proc/i386_arch.go @@ -127,11 +127,19 @@ func i386SwitchStack(it *stackIterator, _ *op.DwarfRegisters) bool { switch it.frame.Current.Fn.Name { case "runtime.asmcgocall", "runtime.cgocallback_gofunc": // TODO(chainhelen), need to support cgo stacktraces. return false - case "runtime.goexit", "runtime.rt0_go", "runtime.mcall": + case "runtime.goexit", "runtime.rt0_go": // Look for "top of stack" functions. it.atend = true return true + case "runtime.mcall": + if it.systemstack && it.g != nil { + it.switchToGoroutineStack() + return true + } + it.atend = true + return true + case "runtime.mstart": // Calls to runtime.systemstack will switch to the systemstack then: // 1. alter the goroutine stack so that it looks like systemstack_switch diff --git a/pkg/proc/ppc64le_arch.go b/pkg/proc/ppc64le_arch.go index 53c82125c2..ded9889637 100644 --- a/pkg/proc/ppc64le_arch.go +++ b/pkg/proc/ppc64le_arch.go @@ -106,10 +106,17 @@ func ppc64leSwitchStack(it *stackIterator, callFrameRegs *op.DwarfRegisters) boo switch it.frame.Current.Fn.Name { case "runtime.asmcgocall", "runtime.cgocallback_gofunc", "runtime.sigpanic", "runtime.cgocallback": //do nothing - case "runtime.goexit", "runtime.rt0_go", "runtime.mcall": + case "runtime.goexit", "runtime.rt0_go": // Look for "top of stack" functions. it.atend = true return true + case "runtime.mcall": + if it.systemstack && it.g != nil { + it.switchToGoroutineStack() + return true + } + it.atend = true + return true case "crosscall2": //The offsets get from runtime/cgo/asm_ppc64x.s:10 newsp, _ := readUintRaw(it.mem, it.regs.SP()+8*24, int64(it.bi.Arch.PtrSize())) From 4ce596b9dd6ab54a72fda89c7d923f40a4a39bd6 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 15 Aug 2023 00:34:29 +0200 Subject: [PATCH 096/114] locspec: fix SubstitutePath when converting a Windows path to Linux (#3453) Normalize separators when converting a Windows path into a Linux path. Fixes #3447 --- pkg/locspec/locations.go | 57 +++++++++++++++++++++++++++-------- pkg/locspec/locations_test.go | 6 +++- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/pkg/locspec/locations.go b/pkg/locspec/locations.go index 7ae05c4e72..9832ffb13f 100644 --- a/pkg/locspec/locations.go +++ b/pkg/locspec/locations.go @@ -508,6 +508,49 @@ func hasPathSeparatorPrefix(path string) bool { return strings.HasPrefix(path, "/") || strings.HasPrefix(path, "\\") } +func pickSeparator(to string) string { + var sep byte + for i := range to { + if to[i] == '/' || to[i] == '\\' { + if sep == 0 { + sep = to[i] + } else if sep != to[i] { + return "" + } + } + } + return string(sep) +} + +func joinPath(to, rest string) string { + sep := pickSeparator(to) + + switch sep { + case "/": + rest = strings.ReplaceAll(rest, "\\", sep) + case "\\": + rest = strings.ReplaceAll(rest, "/", sep) + default: + sep = "/" + } + + toEndsWithSlash := hasPathSeparatorSuffix(to) + restStartsWithSlash := hasPathSeparatorPrefix(rest) + + switch { + case toEndsWithSlash && restStartsWithSlash: + return to[:len(to)-1] + rest + case toEndsWithSlash && !restStartsWithSlash: + return to + rest + case !toEndsWithSlash && restStartsWithSlash: + return to + rest + case !toEndsWithSlash && !restStartsWithSlash: + fallthrough + default: + return to + sep + rest + } +} + // SubstitutePath applies the specified path substitution rules to path. func SubstitutePath(path string, rules [][2]string) string { // Look for evidence that we are dealing with windows somewhere, if we are use case-insensitive matching @@ -559,19 +602,7 @@ func SubstitutePath(path string, rules [][2]string) string { return rest } - toEndsWithSlash := hasPathSeparatorSuffix(to) - restStartsWithSlash := hasPathSeparatorPrefix(rest) - - switch { - case toEndsWithSlash && restStartsWithSlash: - return to[:len(to)-1] + rest - case toEndsWithSlash && !restStartsWithSlash: - return to + rest - case !toEndsWithSlash && restStartsWithSlash: - return to + rest - case !toEndsWithSlash && !restStartsWithSlash: - return to + "/" + rest - } + return joinPath(to, rest) } } return path diff --git a/pkg/locspec/locations_test.go b/pkg/locspec/locations_test.go index cc10beb33d..617126a10f 100644 --- a/pkg/locspec/locations_test.go +++ b/pkg/locspec/locations_test.go @@ -160,7 +160,7 @@ func platformCases() []tCase { {[]tRule{{`c:\tmp\path`, `d:\new\path2`}}, `c:\tmp\path\file.go`, `d:\new\path2\file.go`}, {[]tRule{{`c:\tmp\path\`, `d:\new\path2\`}}, `c:\tmp\path\file.go`, `d:\new\path2\file.go`}, {[]tRule{{`c:\tmp\path`, `d:\new\path2\`}}, `c:\tmp\path\file.go`, `d:\new\path2\file.go`}, - {[]tRule{{`c:\tmp\path\`, `d:\new\path2`}}, `c:\tmp\path\file.go`, `d:\new\path2/file.go`}, + {[]tRule{{`c:\tmp\path\`, `d:\new\path2`}}, `c:\tmp\path\file.go`, `d:\new\path2\file.go`}, // Should apply to directory prefixes {[]tRule{{`c:\tmp\path`, `d:\new\path2`}}, `c:\tmp\path-2\file.go`, `c:\tmp\path-2\file.go`}, // Should apply to exact matches @@ -168,11 +168,15 @@ func platformCases() []tCase { // Should be case-insensitive {[]tRule{{`c:\tmp\path`, `d:\new\path2`}}, `C:\TmP\PaTh\file.go`, `d:\new\path2\file.go`}, } + casesCross := []tCase{ + {[]tRule{{"C:\\some\\repo", "/go/src/github.com/some/repo/"}}, `c:\some\repo\folder\file.go`, "/go/src/github.com/some/repo/folder/file.go"}, + } r := append(casesUnix, casesLinux...) r = append(r, casesFreebsd...) r = append(r, casesDarwin...) r = append(r, casesWindows...) + r = append(r, casesCross...) return r } From e56490e78f94a153e771bd069b634e6e537d18b4 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 15 Aug 2023 00:37:57 +0200 Subject: [PATCH 097/114] gobuild: pass user specified -C argument first (#3456) The -C argument must come first on the command line of 'go build' if the flags specified by the user via build-flags start with -C pass it first. Replaces #3380 --- pkg/gobuild/gobuild.go | 15 +++++++++++++-- pkg/gobuild/gobuild_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 pkg/gobuild/gobuild_test.go diff --git a/pkg/gobuild/gobuild.go b/pkg/gobuild/gobuild.go index c42318e895..b495c2e13e 100644 --- a/pkg/gobuild/gobuild.go +++ b/pkg/gobuild/gobuild.go @@ -61,13 +61,24 @@ func GoTestBuildCombinedOutput(debugname string, pkgs []string, buildflags strin } func goBuildArgs(debugname string, pkgs []string, buildflags string, isTest bool) []string { - args := []string{"-o", debugname} + var args []string + + bfv := config.SplitQuotedFields(buildflags, '\'') + if len(bfv) >= 2 && bfv[0] == "-C" { + args = append(args, bfv[:2]...) + bfv = bfv[2:] + } else if len(bfv) >= 1 && strings.HasPrefix(bfv[0], "-C=") { + args = append(args, bfv[0]) + bfv = bfv[1:] + } + + args = append(args, "-o", debugname) if isTest { args = append([]string{"-c"}, args...) } args = append(args, "-gcflags", "all=-N -l") if buildflags != "" { - args = append(args, config.SplitQuotedFields(buildflags, '\'')...) + args = append(args, bfv...) } args = append(args, pkgs...) return args diff --git a/pkg/gobuild/gobuild_test.go b/pkg/gobuild/gobuild_test.go new file mode 100644 index 0000000000..4f249ee837 --- /dev/null +++ b/pkg/gobuild/gobuild_test.go @@ -0,0 +1,27 @@ +package gobuild + +import ( + "reflect" + "testing" + + "github.com/go-delve/delve/pkg/config" +) + +func TestGoBuildArgsDashC(t *testing.T) { + testCases := []struct{ in, tgt string }{ + {"-C somedir", "-C somedir -o debug -gcflags 'all=-N -l' pkg"}, + {"-C", "-o debug -gcflags 'all=-N -l' -C pkg"}, + {"-C=somedir", "-C=somedir -o debug -gcflags 'all=-N -l' pkg"}, + {"-C somedir -other -args", "-C somedir -o debug -gcflags 'all=-N -l' -other -args pkg"}, + {"-C=somedir -other -args", "-C=somedir -o debug -gcflags 'all=-N -l' -other -args pkg"}, + } + + for _, tc := range testCases { + out := goBuildArgs("debug", []string{"pkg"}, tc.in, false) + tgt := config.SplitQuotedFields(tc.tgt, '\'') + t.Logf("%q -> %q", tc.in, out) + if !reflect.DeepEqual(out, tgt) { + t.Errorf("output mismatch input %q\noutput %q\ntarget %q", tc.in, out, tgt) + } + } +} From 1ec7320b1c08fc88452df5db16011e22c55d79c0 Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Mon, 14 Aug 2023 22:01:30 -0700 Subject: [PATCH 098/114] *: remove deepsource.toml (#3468) We don't use deepsource anymore so this is just leftover configuration. --- .deepsource.toml | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 .deepsource.toml diff --git a/.deepsource.toml b/.deepsource.toml deleted file mode 100644 index 5f2b68ef2a..0000000000 --- a/.deepsource.toml +++ /dev/null @@ -1,13 +0,0 @@ -version = 1 - -test_patterns = ["**/*_test.go"] - -exclude_patterns = ["vendor/**", "_fixtures/**", "_scripts/**"] - -[[analyzers]] -name = "go" -enabled = true - - [analyzers.meta] - import_path = "github.com/go-delve/delve" - dependencies_vendored = true From b07ef66fe46e09934252b2d72b6b0f7b7b78b401 Mon Sep 17 00:00:00 2001 From: Ccheers <1048315650@qq.com> Date: Wed, 16 Aug 2023 21:17:03 +0800 Subject: [PATCH 099/114] Update target.go (#3471) fix(proc): fix nil pointer panic --- pkg/proc/target.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/proc/target.go b/pkg/proc/target.go index a612f9addb..58e6c2f703 100644 --- a/pkg/proc/target.go +++ b/pkg/proc/target.go @@ -356,8 +356,12 @@ func setAsyncPreemptOff(p *Target, v int64) { scope := globalScope(p, p.BinInfo(), p.BinInfo().Images[0], p.Memory()) // +rtype -var debug anytype debugv, err := scope.findGlobal("runtime", "debug") - if err != nil || debugv.Unreadable != nil { - logger.Warnf("could not find runtime/debug variable (or unreadable): %v %v", err, debugv.Unreadable) + if err != nil { + logger.Warnf("could not find runtime/debug variable (or unreadable): %v", err) + return + } + if debugv.Unreadable != nil { + logger.Warnf("runtime/debug variable unreadable: %v", err, debugv.Unreadable) return } asyncpreemptoffv, err := debugv.structMember("asyncpreemptoff") // +rtype int32 From 53688a102f030985651fddaea5d1efa1e03720d9 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 16 Aug 2023 18:55:02 +0200 Subject: [PATCH 100/114] goversion: parse new version format and simplify version representation (#3470) Add parsing for the new version format with toolchain (X.Y.Z-something) and simplify internal representation of versions so that revision, beta version and rc version are all represented on a single field with rc and beta versions being negative numbers (this limits rc versions to a maximum of 1000 which will not be a problem in practice). --- pkg/goversion/compat.go | 13 +++--- pkg/goversion/go_version.go | 88 ++++++++++++++++++++++++++--------- pkg/goversion/version_test.go | 83 ++++++++++++++++++++++++++++----- pkg/proc/scope_test.go | 2 +- 4 files changed, 144 insertions(+), 42 deletions(-) diff --git a/pkg/goversion/compat.go b/pkg/goversion/compat.go index fa2c3392e2..029f4dbb9a 100644 --- a/pkg/goversion/compat.go +++ b/pkg/goversion/compat.go @@ -24,20 +24,19 @@ func Compatible(producer string, warnonly bool) error { if ver.IsDevel() { return nil } - verstr := fmt.Sprintf("%d.%d.%d", ver.Major, ver.Minor, ver.Rev) - if !ver.AfterOrEqual(GoVersion{MinSupportedVersionOfGoMajor, MinSupportedVersionOfGoMinor, -1, 0, 0, ""}) { + if !ver.AfterOrEqual(GoVersion{MinSupportedVersionOfGoMajor, MinSupportedVersionOfGoMinor, betaRev(0), "", ""}) { if warnonly { - logflags.WriteError(fmt.Sprintf(goTooOldWarn, verstr)) + logflags.WriteError(fmt.Sprintf(goTooOldWarn, ver.String())) return nil } - return fmt.Errorf(goTooOldErr, verstr) + return fmt.Errorf(goTooOldErr, ver.String()) } - if ver.AfterOrEqual(GoVersion{MaxSupportedVersionOfGoMajor, MaxSupportedVersionOfGoMinor + 1, -1, 0, 0, ""}) { + if ver.AfterOrEqual(GoVersion{MaxSupportedVersionOfGoMajor, MaxSupportedVersionOfGoMinor + 1, betaRev(0), "", ""}) { if warnonly { - logflags.WriteError(fmt.Sprintf(dlvTooOldWarn, verstr)) + logflags.WriteError(fmt.Sprintf(dlvTooOldWarn, ver.String())) return nil } - return fmt.Errorf(dlvTooOldErr, verstr) + return fmt.Errorf(dlvTooOldErr, ver.String()) } return nil } diff --git a/pkg/goversion/go_version.go b/pkg/goversion/go_version.go index b980ffac74..08b94afb2b 100644 --- a/pkg/goversion/go_version.go +++ b/pkg/goversion/go_version.go @@ -1,6 +1,7 @@ package goversion import ( + "fmt" "os/exec" "strconv" "strings" @@ -10,16 +11,28 @@ import ( // the Go compiler version used to compile // the target binary. type GoVersion struct { - Major int - Minor int - Rev int - Beta int - RC int - Proposal string + Major int + Minor int + Rev int // revision number or negative number for beta and rc releases + Proposal string + Toolchain string +} + +const ( + betaStart = -1000 + betaEnd = -2000 +) + +func betaRev(beta int) int { + return beta + betaEnd +} + +func rcRev(rc int) int { + return rc + betaStart } var ( - GoVer18Beta = GoVersion{1, 8, -1, 0, 0, ""} + GoVer18Beta = GoVersion{1, 8, betaRev(0), "", ""} ) // Parse parses a go version string @@ -28,7 +41,7 @@ func Parse(ver string) (GoVersion, bool) { var err1, err2, err3 error if strings.HasPrefix(ver, "devel") { - return GoVersion{-1, 0, 0, 0, 0, ""}, true + return GoVersion{-1, 0, 0, "", ""}, true } if strings.HasPrefix(ver, "go") { @@ -40,15 +53,22 @@ func Parse(ver string) (GoVersion, bool) { var vr []string if vr = strings.SplitN(v[1], "beta", 2); len(vr) == 2 { - r.Beta, err3 = strconv.Atoi(vr[1]) + // old beta releases goX.YbetaZ + var beta int + beta, err3 = strconv.Atoi(vr[1]) + r.Rev = betaRev(beta) } else if vr = strings.SplitN(v[1], "b", 2); len(vr) == 2 { + // old boringcrypto version goX.YbZ if _, err := strconv.Atoi(vr[1]); err != nil { return GoVersion{}, false } } else { vr = strings.SplitN(v[1], "rc", 2) if len(vr) == 2 { - r.RC, err3 = strconv.Atoi(vr[1]) + // rc release goX.YrcZ + var rc int + rc, err3 = strconv.Atoi(vr[1]) + r.Rev = rcRev(rc) } else { r.Minor, err2 = strconv.Atoi(v[1]) if err2 != nil { @@ -58,8 +78,9 @@ func Parse(ver string) (GoVersion, bool) { } } + // old major release (if none of the options above apply) goX.Y + r.Minor, err2 = strconv.Atoi(vr[0]) - r.Rev = -1 r.Proposal = "" if err1 != nil || err2 != nil || err3 != nil { @@ -73,10 +94,15 @@ func Parse(ver string) (GoVersion, bool) { r.Major, err1 = strconv.Atoi(v[0]) r.Minor, err2 = strconv.Atoi(v[1]) - vr := strings.SplitN(v[2], "b", 2) - if len(vr) == 2 { + if vr := strings.SplitN(v[2], "-", 2); len(vr) == 2 { + // minor version with toolchain modifier goX.Y.Z-anything + r.Rev, err3 = strconv.Atoi(vr[0]) + r.Toolchain = vr[1] + } else if vr := strings.SplitN(v[2], "b", 2); len(vr) == 2 { + // old boringcrypto version goX.Y.ZbW r.Rev, err3 = strconv.Atoi(vr[0]) } else { + // minor version goX.Y.Z r.Rev, err3 = strconv.Atoi(v[2]) } @@ -89,6 +115,8 @@ func Parse(ver string) (GoVersion, bool) { case 4: + // old proposal release goX.Y.Z.anything + r.Major, err1 = strconv.Atoi(v[0]) r.Minor, err2 = strconv.Atoi(v[1]) r.Rev, err3 = strconv.Atoi(v[2]) @@ -128,14 +156,6 @@ func (v *GoVersion) AfterOrEqual(b GoVersion) bool { return true } - if v.Beta < b.Beta { - return false - } - - if v.RC < b.RC { - return false - } - return true } @@ -145,6 +165,28 @@ func (v *GoVersion) IsDevel() bool { return v.Major < 0 } +func (v *GoVersion) String() string { + switch { + case v.Rev < betaStart: + // beta version + return fmt.Sprintf("go%d.%dbeta%d", v.Major, v.Minor, v.Rev-betaEnd) + case v.Rev < 0: + // rc version + return fmt.Sprintf("go%d.%drc%d", v.Major, v.Minor, v.Rev-betaStart) + case v.Proposal != "": + // with proposal + return fmt.Sprintf("go%d.%d.%d.%s", v.Major, v.Minor, v.Rev, v.Proposal) + case v.Rev == 0 && v.Minor < 21: + // old major version + return fmt.Sprintf("go%d.%d", v.Major, v.Minor) + case v.Toolchain != "": + return fmt.Sprintf("go%d.%d.%d-%s", v.Major, v.Minor, v.Rev, v.Toolchain) + default: + // post go1.21 major version or minor version + return fmt.Sprintf("go%d.%d.%d", v.Major, v.Minor, v.Rev) + } +} + const goVersionPrefix = "go version " // Installed runs "go version" and parses the output @@ -178,7 +220,7 @@ func VersionAfterOrEqualRev(version string, major, minor, rev int) bool { if ver.IsDevel() { return true } - return ver.AfterOrEqual(GoVersion{major, minor, rev, 0, 0, ""}) + return ver.AfterOrEqual(GoVersion{major, minor, rev, "", ""}) } const producerVersionPrefix = "Go cmd/compile " @@ -190,7 +232,7 @@ func ProducerAfterOrEqual(producer string, major, minor int) bool { if ver.IsDevel() { return true } - return ver.AfterOrEqual(GoVersion{major, minor, -1, 0, 0, ""}) + return ver.AfterOrEqual(GoVersion{major, minor, 0, "", ""}) } func ParseProducer(producer string) GoVersion { diff --git a/pkg/goversion/version_test.go b/pkg/goversion/version_test.go index dd67814141..6bf6f22e53 100644 --- a/pkg/goversion/version_test.go +++ b/pkg/goversion/version_test.go @@ -5,27 +5,51 @@ import ( "testing" ) -func versionAfterOrEqual(t *testing.T, verStr string, ver GoVersion) { +func parseVer(t *testing.T, verStr string) GoVersion { pver, ok := Parse(verStr) if !ok { t.Fatalf("Could not parse version string <%s>", verStr) } + return pver +} + +func versionAfterOrEqual(t *testing.T, verStr string, ver GoVersion) { + t.Helper() + pver := parseVer(t, verStr) if !pver.AfterOrEqual(ver) { t.Fatalf("Version <%s> parsed as %v not after %v", verStr, pver, ver) } t.Logf("version string <%s> → %v", verStr, ver) } -func TestParseVersionString(t *testing.T) { - versionAfterOrEqual(t, "go1.4", GoVersion{1, 4, 0, 0, 0, ""}) - versionAfterOrEqual(t, "go1.5.0", GoVersion{1, 5, 0, 0, 0, ""}) - versionAfterOrEqual(t, "go1.4.2", GoVersion{1, 4, 2, 0, 0, ""}) - versionAfterOrEqual(t, "go1.5beta2", GoVersion{1, 5, -1, 2, 0, ""}) - versionAfterOrEqual(t, "go1.5rc2", GoVersion{1, 5, -1, 0, 2, ""}) - versionAfterOrEqual(t, "go1.6.1 (appengine-1.9.37)", GoVersion{1, 6, 1, 0, 0, ""}) - versionAfterOrEqual(t, "go1.8.1.typealias", GoVersion{1, 6, 1, 0, 0, ""}) - versionAfterOrEqual(t, "go1.8b1", GoVersion{1, 8, -1, 0, 0, ""}) - versionAfterOrEqual(t, "go1.16.4b7", GoVersion{1, 16, 4, 0, 0, ""}) +func versionAfterOrEqual2(t *testing.T, verStr1, verStr2 string) { + t.Helper() + pver1 := parseVer(t, verStr1) + pver2 := parseVer(t, verStr2) + if !pver1.AfterOrEqual(pver2) { + t.Fatalf("Version <%s> %#v not after or equal to <%s> %#v", verStr1, pver1, verStr2, pver2) + } +} + +func versionEqual(t *testing.T, verStr string, ver GoVersion) { + t.Helper() + pver := parseVer(t, verStr) + if pver != ver { + t.Fatalf("Version <%s> parsed as %v not equal to %v", verStr, pver, ver) + } + t.Logf("version string <%s> → %v", verStr, ver) +} + +func TestParseVersionStringAfterOrEqual(t *testing.T) { + versionAfterOrEqual(t, "go1.4", GoVersion{1, 4, 0, "", ""}) + versionAfterOrEqual(t, "go1.5.0", GoVersion{1, 5, 0, "", ""}) + versionAfterOrEqual(t, "go1.4.2", GoVersion{1, 4, 2, "", ""}) + versionAfterOrEqual(t, "go1.5beta2", GoVersion{1, 5, betaRev(2), "", ""}) + versionAfterOrEqual(t, "go1.5rc2", GoVersion{1, 5, rcRev(2), "", ""}) + versionAfterOrEqual(t, "go1.6.1 (appengine-1.9.37)", GoVersion{1, 6, 1, "", ""}) + versionAfterOrEqual(t, "go1.8.1.typealias", GoVersion{1, 6, 1, "", ""}) + versionAfterOrEqual(t, "go1.8b1", GoVersion{1, 8, 0, "", ""}) + versionAfterOrEqual(t, "go1.16.4b7", GoVersion{1, 16, 4, "", ""}) ver, ok := Parse("devel +17efbfc Tue Jul 28 17:39:19 2015 +0000 linux/amd64") if !ok { t.Fatalf("Could not parse devel version string") @@ -33,6 +57,43 @@ func TestParseVersionString(t *testing.T) { if !ver.IsDevel() { t.Fatalf("Devel version string not correctly recognized") } + + versionAfterOrEqual2(t, "go1.16", "go1.16b1") + versionAfterOrEqual2(t, "go1.16", "go1.16rc1") + versionAfterOrEqual2(t, "go1.16rc1", "go1.16beta1") + versionAfterOrEqual2(t, "go1.16beta2", "go1.16beta1") + versionAfterOrEqual2(t, "go1.16rc10", "go1.16rc8") +} + +func TestParseVersionStringEqual(t *testing.T) { + versionEqual(t, "go1.4", GoVersion{1, 4, 0, "", ""}) + versionEqual(t, "go1.5.0", GoVersion{1, 5, 0, "", ""}) + versionEqual(t, "go1.4.2", GoVersion{1, 4, 2, "", ""}) + versionEqual(t, "go1.5beta2", GoVersion{1, 5, betaRev(2), "", ""}) + versionEqual(t, "go1.5rc2", GoVersion{1, 5, rcRev(2), "", ""}) + versionEqual(t, "go1.6.1 (appengine-1.9.37)", GoVersion{1, 6, 1, "", ""}) + versionEqual(t, "go1.8.1.typealias", GoVersion{1, 8, 1, "typealias", ""}) + versionEqual(t, "go1.8b1", GoVersion{1, 8, 0, "", ""}) + versionEqual(t, "go1.16.4b7", GoVersion{1, 16, 4, "", ""}) + versionEqual(t, "go1.21.1-something", GoVersion{1, 21, 1, "", "something"}) + versionEqual(t, "devel +17efbfc Tue Jul 28 17:39:19 2015 +0000 linux/amd64", GoVersion{Major: -1}) +} + +func TestRoundtrip(t *testing.T) { + for _, verStr := range []string{ + "go1.4", + "go1.4.2", + "go1.5beta2", + "go1.5rc2", + "go1.8.1.typealias", + "go1.21.1-something", + "go1.21.0", + } { + pver := parseVer(t, verStr) + if pver.String() != verStr { + t.Fatalf("roundtrip mismatch <%s> -> %#v -> <%s>", verStr, pver, pver.String()) + } + } } func TestInstalled(t *testing.T) { diff --git a/pkg/proc/scope_test.go b/pkg/proc/scope_test.go index 8ca4665f05..daca5ad4dc 100644 --- a/pkg/proc/scope_test.go +++ b/pkg/proc/scope_test.go @@ -19,7 +19,7 @@ import ( ) func TestScopeWithEscapedVariable(t *testing.T) { - if ver, _ := goversion.Parse(runtime.Version()); ver.Major >= 0 && !ver.AfterOrEqual(goversion.GoVersion{Major: 1, Minor: 9, Rev: -1, Beta: 3}) { + if ver, _ := goversion.Parse(runtime.Version()); ver.Major >= 0 && !ver.AfterOrEqual(goversion.GoVersion{Major: 1, Minor: 9}) { return } From 8aa005015868d92feed24786ce1798e79c58c951 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Fri, 18 Aug 2023 00:24:43 +0300 Subject: [PATCH 101/114] pkg,service: make receiver names consistent (#3473) --- pkg/dwarf/godwarf/type.go | 2 +- pkg/dwarf/op/regs.go | 14 ++++++------ pkg/proc/amd64util/xsave.go | 38 ++++++++++++++++----------------- pkg/proc/arch.go | 4 ++-- pkg/proc/core/core.go | 8 +++---- pkg/proc/disasm.go | 4 ++-- pkg/proc/gdbserial/gdbserver.go | 9 ++++---- pkg/proc/scope_test.go | 12 +++++------ pkg/proc/target.go | 32 +++++++++++++-------------- pkg/proc/target_exec.go | 20 ++++++++--------- pkg/terminal/docgen.go | 6 +++--- service/rpc1/server.go | 14 ++++++------ service/rpc2/server.go | 14 ++++++------ 13 files changed, 89 insertions(+), 88 deletions(-) diff --git a/pkg/dwarf/godwarf/type.go b/pkg/dwarf/godwarf/type.go index e06c118e30..f0afb76c0c 100644 --- a/pkg/dwarf/godwarf/type.go +++ b/pkg/dwarf/godwarf/type.go @@ -102,7 +102,7 @@ type BasicType struct { BitOffset int64 } -func (b *BasicType) Basic() *BasicType { return b } +func (t *BasicType) Basic() *BasicType { return t } func (t *BasicType) String() string { return t.stringIntl(nil) } diff --git a/pkg/dwarf/op/regs.go b/pkg/dwarf/op/regs.go index 7696b92893..bd95e792a9 100644 --- a/pkg/dwarf/op/regs.go +++ b/pkg/dwarf/op/regs.go @@ -165,19 +165,19 @@ func (reg *DwarfRegister) FillBytes() { binary.LittleEndian.PutUint64(reg.Bytes, reg.Uint64Val) } -// Overwrite takes the contents of reg1 and overwrites them with the contents +// Overwrite takes the contents of reg and overwrites them with the contents // of reg2 in little-endian order, returning a new register. The new register // will always contain the complete contents of both registers, so if reg2 is -// larger than reg1, the final register will be reg2's size. -func (reg1 *DwarfRegister) Overwrite(reg2 *DwarfRegister) *DwarfRegister { - reg1.FillBytes() +// larger than reg, the final register will be reg2's size. +func (reg *DwarfRegister) Overwrite(reg2 *DwarfRegister) *DwarfRegister { + reg.FillBytes() reg2.FillBytes() - width := len(reg1.Bytes) - if len(reg2.Bytes) > len(reg1.Bytes) { + width := len(reg.Bytes) + if len(reg2.Bytes) > len(reg.Bytes) { width = len(reg2.Bytes) } b := make([]byte, width) - copy(b, reg1.Bytes) + copy(b, reg.Bytes) copy(b, reg2.Bytes) return DwarfRegisterFromBytes(b) } diff --git a/pkg/proc/amd64util/xsave.go b/pkg/proc/amd64util/xsave.go index 16e621fd7e..3d0a7c8648 100644 --- a/pkg/proc/amd64util/xsave.go +++ b/pkg/proc/amd64util/xsave.go @@ -36,34 +36,34 @@ type AMD64PtraceFpRegs struct { } // Decode decodes an XSAVE area to a list of name/value pairs of registers. -func (xsave *AMD64Xstate) Decode() []proc.Register { +func (xstate *AMD64Xstate) Decode() []proc.Register { var regs []proc.Register // x87 registers - regs = proc.AppendUint64Register(regs, "CW", uint64(xsave.Cwd)) - regs = proc.AppendUint64Register(regs, "SW", uint64(xsave.Swd)) - regs = proc.AppendUint64Register(regs, "TW", uint64(xsave.Ftw)) - regs = proc.AppendUint64Register(regs, "FOP", uint64(xsave.Fop)) - regs = proc.AppendUint64Register(regs, "FIP", xsave.Rip) - regs = proc.AppendUint64Register(regs, "FDP", xsave.Rdp) - - for i := 0; i < len(xsave.StSpace); i += 4 { + regs = proc.AppendUint64Register(regs, "CW", uint64(xstate.Cwd)) + regs = proc.AppendUint64Register(regs, "SW", uint64(xstate.Swd)) + regs = proc.AppendUint64Register(regs, "TW", uint64(xstate.Ftw)) + regs = proc.AppendUint64Register(regs, "FOP", uint64(xstate.Fop)) + regs = proc.AppendUint64Register(regs, "FIP", xstate.Rip) + regs = proc.AppendUint64Register(regs, "FDP", xstate.Rdp) + + for i := 0; i < len(xstate.StSpace); i += 4 { var buf bytes.Buffer - binary.Write(&buf, binary.LittleEndian, uint64(xsave.StSpace[i+1])<<32|uint64(xsave.StSpace[i])) - binary.Write(&buf, binary.LittleEndian, uint16(xsave.StSpace[i+2])) + binary.Write(&buf, binary.LittleEndian, uint64(xstate.StSpace[i+1])<<32|uint64(xstate.StSpace[i])) + binary.Write(&buf, binary.LittleEndian, uint16(xstate.StSpace[i+2])) regs = proc.AppendBytesRegister(regs, fmt.Sprintf("ST(%d)", i/4), buf.Bytes()) } // SSE registers - regs = proc.AppendUint64Register(regs, "MXCSR", uint64(xsave.Mxcsr)) - regs = proc.AppendUint64Register(regs, "MXCSR_MASK", uint64(xsave.MxcrMask)) + regs = proc.AppendUint64Register(regs, "MXCSR", uint64(xstate.Mxcsr)) + regs = proc.AppendUint64Register(regs, "MXCSR_MASK", uint64(xstate.MxcrMask)) - for i := 0; i < len(xsave.XmmSpace); i += 16 { + for i := 0; i < len(xstate.XmmSpace); i += 16 { n := i / 16 - regs = proc.AppendBytesRegister(regs, fmt.Sprintf("XMM%d", n), xsave.XmmSpace[i:i+16]) - if xsave.AvxState { - regs = proc.AppendBytesRegister(regs, fmt.Sprintf("YMM%d", n), xsave.YmmSpace[i:i+16]) - if xsave.Avx512State { - regs = proc.AppendBytesRegister(regs, fmt.Sprintf("ZMM%d", n), xsave.ZmmSpace[n*32:(n+1)*32]) + regs = proc.AppendBytesRegister(regs, fmt.Sprintf("XMM%d", n), xstate.XmmSpace[i:i+16]) + if xstate.AvxState { + regs = proc.AppendBytesRegister(regs, fmt.Sprintf("YMM%d", n), xstate.YmmSpace[i:i+16]) + if xstate.Avx512State { + regs = proc.AppendBytesRegister(regs, fmt.Sprintf("ZMM%d", n), xstate.ZmmSpace[n*32:(n+1)*32]) } } } diff --git a/pkg/proc/arch.go b/pkg/proc/arch.go index 6c182ea263..a44f368296 100644 --- a/pkg/proc/arch.go +++ b/pkg/proc/arch.go @@ -124,8 +124,8 @@ func (a *Arch) DerefTLS() bool { // getAsmRegister returns the value of the asm register asmreg using the asmRegisters table of arch. // The interpretation of asmreg is architecture specific and defined by the disassembler. // A mask value of 0 inside asmRegisters is equivalent to ^uint64(0). -func (arch *Arch) getAsmRegister(regs *op.DwarfRegisters, asmreg int) (uint64, error) { - hwreg, ok := arch.asmRegisters[asmreg] +func (a *Arch) getAsmRegister(regs *op.DwarfRegisters, asmreg int) (uint64, error) { + hwreg, ok := a.asmRegisters[asmreg] if !ok { return 0, ErrUnknownRegister } diff --git a/pkg/proc/core/core.go b/pkg/proc/core/core.go index 358c0b085f..d69f83a430 100644 --- a/pkg/proc/core/core.go +++ b/pkg/proc/core/core.go @@ -277,18 +277,18 @@ func (p *process) SupportsBPF() bool { return false } -func (dbp *process) SetUProbe(fnName string, goidOffset int64, args []ebpf.UProbeArgMap) error { +func (p *process) SetUProbe(fnName string, goidOffset int64, args []ebpf.UProbeArgMap) error { panic("not implemented") } // StartCallInjection notifies the backend that we are about to inject a function call. func (p *process) StartCallInjection() (func(), error) { return func() {}, nil } -func (dbp *process) EnableURetProbes() error { +func (p *process) EnableURetProbes() error { panic("not implemented") } -func (dbp *process) DisableURetProbes() error { +func (p *process) DisableURetProbes() error { panic("not implemented") } @@ -492,6 +492,6 @@ func (p *process) DumpProcessNotes(notes []elfwriter.Note, threadDone func()) (t return false, notes, nil } -func (dbp *process) GetBufferedTracepoints() []ebpf.RawUProbeParams { +func (p *process) GetBufferedTracepoints() []ebpf.RawUProbeParams { return nil } diff --git a/pkg/proc/disasm.go b/pkg/proc/disasm.go index 837fa921a6..9928abd354 100644 --- a/pkg/proc/disasm.go +++ b/pkg/proc/disasm.go @@ -176,6 +176,6 @@ func disassemble(memrw MemoryReadWriter, regs Registers, breakpoints *Breakpoint // Text will return the assembly instructions in human readable format according to // the flavour specified. -func (inst *AsmInstruction) Text(flavour AssemblyFlavour, bi *BinaryInfo) string { - return inst.Inst.Text(flavour, inst.Loc.PC, bi.symLookup) +func (instr *AsmInstruction) Text(flavour AssemblyFlavour, bi *BinaryInfo) string { + return instr.Inst.Text(flavour, instr.Loc.PC, bi.symLookup) } diff --git a/pkg/proc/gdbserial/gdbserver.go b/pkg/proc/gdbserial/gdbserver.go index 311a21cd02..99650f7f16 100644 --- a/pkg/proc/gdbserial/gdbserver.go +++ b/pkg/proc/gdbserial/gdbserver.go @@ -77,6 +77,8 @@ import ( "sync" "time" + isatty "github.com/mattn/go-isatty" + "github.com/go-delve/delve/pkg/dwarf/op" "github.com/go-delve/delve/pkg/elfwriter" "github.com/go-delve/delve/pkg/logflags" @@ -84,7 +86,6 @@ import ( "github.com/go-delve/delve/pkg/proc/internal/ebpf" "github.com/go-delve/delve/pkg/proc/linutil" "github.com/go-delve/delve/pkg/proc/macutil" - isatty "github.com/mattn/go-isatty" ) const ( @@ -375,11 +376,11 @@ func (p *gdbProcess) SupportsBPF() bool { return false } -func (dbp *gdbProcess) GetBufferedTracepoints() []ebpf.RawUProbeParams { +func (p *gdbProcess) GetBufferedTracepoints() []ebpf.RawUProbeParams { return nil } -func (dbp *gdbProcess) SetUProbe(fnName string, goidOffset int64, args []ebpf.UProbeArgMap) error { +func (p *gdbProcess) SetUProbe(fnName string, goidOffset int64, args []ebpf.UProbeArgMap) error { panic("not implemented") } @@ -1977,7 +1978,7 @@ func (regs *gdbRegisters) byName(name string) uint64 { return binary.LittleEndian.Uint64(reg.value) } -func (r *gdbRegisters) FloatLoadError() error { +func (regs *gdbRegisters) FloatLoadError() error { return nil } diff --git a/pkg/proc/scope_test.go b/pkg/proc/scope_test.go index daca5ad4dc..eccc67e0e6 100644 --- a/pkg/proc/scope_test.go +++ b/pkg/proc/scope_test.go @@ -237,7 +237,7 @@ func (check *scopeCheck) Parse(descr string, t *testing.T) { } } -func (scopeCheck *scopeCheck) checkLocalsAndArgs(p *proc.Target, t *testing.T) (*proc.EvalScope, bool) { +func (check *scopeCheck) checkLocalsAndArgs(p *proc.Target, t *testing.T) (*proc.EvalScope, bool) { scope, err := proc.GoroutineScope(p, p.CurrentThread()) assertNoError(err, t, "GoroutineScope()") @@ -249,16 +249,16 @@ func (scopeCheck *scopeCheck) checkLocalsAndArgs(p *proc.Target, t *testing.T) ( assertNoError(err, t, "LocalVariables()") for _, arg := range args { - scopeCheck.checkVar(arg, t) + check.checkVar(arg, t) } for _, local := range locals { - scopeCheck.checkVar(local, t) + check.checkVar(local, t) } - for i := range scopeCheck.varChecks { - if !scopeCheck.varChecks[i].ok { - t.Errorf("%d: variable %s not found", scopeCheck.line, scopeCheck.varChecks[i].name) + for i := range check.varChecks { + if !check.varChecks[i].ok { + t.Errorf("%d: variable %s not found", check.line, check.varChecks[i].name) ok = false } } diff --git a/pkg/proc/target.go b/pkg/proc/target.go index 58e6c2f703..49953bbb52 100644 --- a/pkg/proc/target.go +++ b/pkg/proc/target.go @@ -296,28 +296,28 @@ func (t *Target) SelectedGoroutine() *G { } // SwitchGoroutine will change the selected and active goroutine. -func (p *Target) SwitchGoroutine(g *G) error { - if ok, err := p.Valid(); !ok { +func (t *Target) SwitchGoroutine(g *G) error { + if ok, err := t.Valid(); !ok { return err } if g == nil { return nil } if g.Thread != nil { - return p.SwitchThread(g.Thread.ThreadID()) + return t.SwitchThread(g.Thread.ThreadID()) } - p.selectedGoroutine = g + t.selectedGoroutine = g return nil } // SwitchThread will change the selected and active thread. -func (p *Target) SwitchThread(tid int) error { - if ok, err := p.Valid(); !ok { +func (t *Target) SwitchThread(tid int) error { + if ok, err := t.Valid(); !ok { return err } - if th, ok := p.FindThread(tid); ok { - p.currentThread = th - p.selectedGoroutine, _ = GetG(p.CurrentThread()) + if th, ok := t.FindThread(tid); ok { + t.currentThread = th + t.selectedGoroutine, _ = GetG(t.CurrentThread()) return nil } return fmt.Errorf("thread %d does not exist", tid) @@ -490,16 +490,16 @@ func (t *Target) GetBufferedTracepoints() []*UProbeTraceResult { // ResumeNotify specifies a channel that will be closed the next time // Continue finishes resuming the targets. -func (t *TargetGroup) ResumeNotify(ch chan<- struct{}) { - t.cctx.ResumeChan = ch +func (grp *TargetGroup) ResumeNotify(ch chan<- struct{}) { + grp.cctx.ResumeChan = ch } // RequestManualStop attempts to stop all the processes' threads. -func (t *TargetGroup) RequestManualStop() error { - t.cctx.StopMu.Lock() - defer t.cctx.StopMu.Unlock() - t.cctx.manualStopRequested = true - return t.Selected.proc.RequestManualStop(t.cctx) +func (grp *TargetGroup) RequestManualStop() error { + grp.cctx.StopMu.Lock() + defer grp.cctx.StopMu.Unlock() + grp.cctx.manualStopRequested = true + return grp.Selected.proc.RequestManualStop(grp.cctx) } const ( diff --git a/pkg/proc/target_exec.go b/pkg/proc/target_exec.go index c4d9201add..6a99d74596 100644 --- a/pkg/proc/target_exec.go +++ b/pkg/proc/target_exec.go @@ -1248,8 +1248,8 @@ func (w *onNextGoroutineWalker) Visit(n ast.Node) ast.Visitor { return w } -func (tgt *Target) clearHardcodedBreakpoints() { - threads := tgt.ThreadList() +func (t *Target) clearHardcodedBreakpoints() { + threads := t.ThreadList() for _, thread := range threads { if thread.Breakpoint().Breakpoint != nil && thread.Breakpoint().LogicalID() == hardcodedBreakpointID { thread.Breakpoint().Active = false @@ -1263,10 +1263,10 @@ func (tgt *Target) clearHardcodedBreakpoints() { // program's text) and sets a fake breakpoint on them with logical id // hardcodedBreakpointID. // It checks trapthread and all threads that have SoftExc returning true. -func (tgt *Target) handleHardcodedBreakpoints(trapthread Thread, threads []Thread) error { - mem := tgt.Memory() - arch := tgt.BinInfo().Arch - recorded, _ := tgt.recman.Recorded() +func (t *Target) handleHardcodedBreakpoints(trapthread Thread, threads []Thread) error { + mem := t.Memory() + arch := t.BinInfo().Arch + recorded, _ := t.recman.Recorded() isHardcodedBreakpoint := func(thread Thread, pc uint64) uint64 { for _, bpinstr := range [][]byte{arch.BreakpointInstruction(), arch.AltBreakpointInstruction()} { @@ -1310,7 +1310,7 @@ func (tgt *Target) handleHardcodedBreakpoints(trapthread Thread, threads []Threa hcbp.Logical = &LogicalBreakpoint{} hcbp.Logical.Name = HardcodedBreakpoint hcbp.Breaklets = []*Breaklet{{Kind: UserBreakpoint, LogicalID: hardcodedBreakpointID}} - tgt.StopReason = StopHardcodedBreakpoint + t.StopReason = StopHardcodedBreakpoint } for _, thread := range threads { @@ -1330,7 +1330,7 @@ func (tgt *Target) handleHardcodedBreakpoints(trapthread Thread, threads []Threa switch { case loc.Fn.Name == "runtime.breakpoint": - if recorded, _ := tgt.recman.Recorded(); recorded { + if recorded, _ := t.recman.Recorded(); recorded { setHardcodedBreakpoint(thread, loc) continue } @@ -1344,11 +1344,11 @@ func (tgt *Target) handleHardcodedBreakpoints(trapthread Thread, threads []Threa // runtime.Breakpoint. // On go < 1.8 it was sufficient to single-step twice on go1.8 a change // to the compiler requires 4 steps. - if err := stepInstructionOut(tgt, thread, "runtime.breakpoint", "runtime.Breakpoint"); err != nil { + if err := stepInstructionOut(t, thread, "runtime.breakpoint", "runtime.Breakpoint"); err != nil { return err } setHardcodedBreakpoint(thread, loc) - case g == nil || tgt.fncallForG[g.ID] == nil: + case g == nil || t.fncallForG[g.ID] == nil: if isHardcodedBreakpoint(thread, loc.PC) > 0 { stepOverBreak(thread, loc.PC) setHardcodedBreakpoint(thread, loc) diff --git a/pkg/terminal/docgen.go b/pkg/terminal/docgen.go index 1cea225cc4..23115fc598 100644 --- a/pkg/terminal/docgen.go +++ b/pkg/terminal/docgen.go @@ -38,7 +38,7 @@ func replaceDocPath(s string) string { } } -func (commands *Commands) WriteMarkdown(w io.Writer) { +func (c *Commands) WriteMarkdown(w io.Writer) { fmt.Fprint(w, "# Configuration and Command History\n\n") fmt.Fprint(w, "If `$XDG_CONFIG_HOME` is set, then configuration and command history files are located in `$XDG_CONFIG_HOME/dlv`. ") fmt.Fprint(w, "Otherwise, they are located in `$HOME/.config/dlv` on Linux and `$HOME/.dlv` on other systems.\n\n") @@ -52,7 +52,7 @@ func (commands *Commands) WriteMarkdown(w io.Writer) { fmt.Fprint(w, "Command | Description\n") fmt.Fprint(w, "--------|------------\n") - for _, cmd := range commands.cmds { + for _, cmd := range c.cmds { if cmd.group != cgd.group { continue } @@ -66,7 +66,7 @@ func (commands *Commands) WriteMarkdown(w io.Writer) { } - for _, cmd := range commands.cmds { + for _, cmd := range c.cmds { fmt.Fprintf(w, "## %s\n%s\n\n", cmd.aliases[0], replaceDocPath(cmd.helpMsg)) if len(cmd.aliases) > 1 { fmt.Fprint(w, "Aliases:") diff --git a/service/rpc1/server.go b/service/rpc1/server.go index 98a508ea96..8881637c3f 100644 --- a/service/rpc1/server.go +++ b/service/rpc1/server.go @@ -292,8 +292,8 @@ func (s *RPCServer) ListGoroutines(arg interface{}, goroutines *[]*api.Goroutine return nil } -func (c *RPCServer) AttachedToExistingProcess(arg interface{}, answer *bool) error { - if c.config.Debugger.AttachPid != 0 { +func (s *RPCServer) AttachedToExistingProcess(arg interface{}, answer *bool) error { + if s.config.Debugger.AttachPid != 0 { *answer = true } return nil @@ -304,9 +304,9 @@ type FindLocationArgs struct { Loc string } -func (c *RPCServer) FindLocation(args FindLocationArgs, answer *[]api.Location) error { +func (s *RPCServer) FindLocation(args FindLocationArgs, answer *[]api.Location) error { var err error - *answer, _, err = c.debugger.FindLocation(args.Scope.GoroutineID, args.Scope.Frame, args.Scope.DeferredCall, args.Loc, false, nil) + *answer, _, err = s.debugger.FindLocation(args.Scope.GoroutineID, args.Scope.Frame, args.Scope.DeferredCall, args.Loc, false, nil) return err } @@ -316,15 +316,15 @@ type DisassembleRequest struct { Flavour api.AssemblyFlavour } -func (c *RPCServer) Disassemble(args DisassembleRequest, answer *api.AsmInstructions) error { +func (s *RPCServer) Disassemble(args DisassembleRequest, answer *api.AsmInstructions) error { var err error - insts, err := c.debugger.Disassemble(args.Scope.GoroutineID, args.StartPC, args.EndPC) + insts, err := s.debugger.Disassemble(args.Scope.GoroutineID, args.StartPC, args.EndPC) if err != nil { return err } *answer = make(api.AsmInstructions, len(insts)) for i := range insts { - (*answer)[i] = api.ConvertAsmInstruction(insts[i], c.debugger.AsmInstructionText(&insts[i], proc.AssemblyFlavour(args.Flavour))) + (*answer)[i] = api.ConvertAsmInstruction(insts[i], s.debugger.AsmInstructionText(&insts[i], proc.AssemblyFlavour(args.Flavour))) } return nil } diff --git a/service/rpc2/server.go b/service/rpc2/server.go index 7097bdcac8..c6536e061b 100644 --- a/service/rpc2/server.go +++ b/service/rpc2/server.go @@ -684,8 +684,8 @@ type AttachedToExistingProcessOut struct { } // AttachedToExistingProcess returns whether we attached to a running process or not -func (c *RPCServer) AttachedToExistingProcess(arg AttachedToExistingProcessIn, out *AttachedToExistingProcessOut) error { - if c.config.Debugger.AttachPid != 0 { +func (s *RPCServer) AttachedToExistingProcess(arg AttachedToExistingProcessIn, out *AttachedToExistingProcessOut) error { + if s.config.Debugger.AttachPid != 0 { out.Answer = true } return nil @@ -722,9 +722,9 @@ type FindLocationOut struct { // * *
returns the location corresponding to the specified address // // NOTE: this function does not actually set breakpoints. -func (c *RPCServer) FindLocation(arg FindLocationIn, out *FindLocationOut) error { +func (s *RPCServer) FindLocation(arg FindLocationIn, out *FindLocationOut) error { var err error - out.Locations, out.SubstituteLocExpr, err = c.debugger.FindLocation(arg.Scope.GoroutineID, arg.Scope.Frame, arg.Scope.DeferredCall, arg.Loc, arg.IncludeNonExecutableLines, arg.SubstitutePathRules) + out.Locations, out.SubstituteLocExpr, err = s.debugger.FindLocation(arg.Scope.GoroutineID, arg.Scope.Frame, arg.Scope.DeferredCall, arg.Loc, arg.IncludeNonExecutableLines, arg.SubstitutePathRules) return err } @@ -745,15 +745,15 @@ type DisassembleOut struct { // Scope is used to mark the instruction the specified goroutine is stopped at. // // Disassemble will also try to calculate the destination address of an absolute indirect CALL if it happens to be the instruction the selected goroutine is stopped at. -func (c *RPCServer) Disassemble(arg DisassembleIn, out *DisassembleOut) error { +func (s *RPCServer) Disassemble(arg DisassembleIn, out *DisassembleOut) error { var err error - insts, err := c.debugger.Disassemble(arg.Scope.GoroutineID, arg.StartPC, arg.EndPC) + insts, err := s.debugger.Disassemble(arg.Scope.GoroutineID, arg.StartPC, arg.EndPC) if err != nil { return err } out.Disassemble = make(api.AsmInstructions, len(insts)) for i := range insts { - out.Disassemble[i] = api.ConvertAsmInstruction(insts[i], c.debugger.AsmInstructionText(&insts[i], proc.AssemblyFlavour(arg.Flavour))) + out.Disassemble[i] = api.ConvertAsmInstruction(insts[i], s.debugger.AsmInstructionText(&insts[i], proc.AssemblyFlavour(arg.Flavour))) } return nil } From f0b534ddcc8c2004ce292e0b9e76a4987fe3e13d Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Fri, 18 Aug 2023 10:56:44 -0700 Subject: [PATCH 102/114] pkg/proc: add support for more types in ebpf tracing backend (#3474) --- _fixtures/ebpf_trace3.go | 23 ++++++++++++++ cmd/dlv/dlv_test.go | 52 +++++++++++++++++++++++++++++-- pkg/proc/internal/ebpf/helpers.go | 4 ++- 3 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 _fixtures/ebpf_trace3.go diff --git a/_fixtures/ebpf_trace3.go b/_fixtures/ebpf_trace3.go new file mode 100644 index 0000000000..3ef67377b1 --- /dev/null +++ b/_fixtures/ebpf_trace3.go @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + "time" +) + +func main() { + str := "abcdefghijklmnopqrstuvqxyz" + i := int64(0) + for i = 0; i < 5; i++ { + tracedFunction(i, i%5 == 0, str[i]) + } + for i = 5; i < 10; i++ { + tracedFunction(i, i%5 == 0, str[i]) + time.Sleep(time.Millisecond) + } +} + +//go:noinline +func tracedFunction(x int64, b bool, r byte) { + fmt.Println(x, b, r) +} diff --git a/cmd/dlv/dlv_test.go b/cmd/dlv/dlv_test.go index 1dc474a393..4ac90563fc 100644 --- a/cmd/dlv/dlv_test.go +++ b/cmd/dlv/dlv_test.go @@ -1098,10 +1098,10 @@ func TestTraceEBPF(t *testing.T) { output, err := ioutil.ReadAll(rdr) assertNoError(err, t, "ReadAll") + cmd.Wait() if !bytes.Contains(output, expected) { t.Fatalf("expected:\n%s\ngot:\n%s", string(expected), string(output)) } - cmd.Wait() } func TestTraceEBPF2(t *testing.T) { @@ -1158,10 +1158,10 @@ func TestTraceEBPF2(t *testing.T) { output, err := ioutil.ReadAll(rdr) assertNoError(err, t, "ReadAll") + cmd.Wait() if !bytes.Contains(output, expected) { t.Fatalf("expected:\n%s\ngot:\n%s", string(expected), string(output)) } - cmd.Wait() } func TestTraceEBPF3(t *testing.T) { @@ -1206,10 +1206,58 @@ func TestTraceEBPF3(t *testing.T) { output, err := ioutil.ReadAll(rdr) assertNoError(err, t, "ReadAll") + cmd.Wait() if !bytes.Contains(output, expected) { t.Fatalf("expected:\n%s\ngot:\n%s", string(expected), string(output)) } +} + +func TestTraceEBPF4(t *testing.T) { + if os.Getenv("CI") == "true" { + t.Skip("cannot run test in CI, requires kernel compiled with btf support") + } + if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { + t.Skip("not implemented on non linux/amd64 systems") + } + if !goversion.VersionAfterOrEqual(runtime.Version(), 1, 16) { + t.Skip("requires at least Go 1.16 to run test") + } + usr, err := user.Current() + if err != nil { + t.Fatal(err) + } + if usr.Uid != "0" { + t.Skip("test must be run as root") + } + + dlvbin := getDlvBinEBPF(t) + + expected := []byte(`> (1) main.tracedFunction(0, true, 97) +> (1) main.tracedFunction(1, false, 98) +> (1) main.tracedFunction(2, false, 99) +> (1) main.tracedFunction(3, false, 100) +> (1) main.tracedFunction(4, false, 101) +> (1) main.tracedFunction(5, true, 102) +> (1) main.tracedFunction(6, false, 103) +> (1) main.tracedFunction(7, false, 104) +> (1) main.tracedFunction(8, false, 105) +> (1) main.tracedFunction(9, false, 106)`) + + fixtures := protest.FindFixturesDir() + cmd := exec.Command(dlvbin, "trace", "--ebpf", "--output", filepath.Join(t.TempDir(), "__debug"), filepath.Join(fixtures, "ebpf_trace3.go"), "main.traced") + rdr, err := cmd.StderrPipe() + assertNoError(err, t, "stderr pipe") + defer rdr.Close() + + assertNoError(cmd.Start(), t, "running trace") + + output, err := ioutil.ReadAll(rdr) + assertNoError(err, t, "ReadAll") + cmd.Wait() + if !bytes.Contains(output, expected) { + t.Fatalf("expected:\n%s\ngot:\n%s", string(expected), string(output)) + } } func TestDlvTestChdir(t *testing.T) { diff --git a/pkg/proc/internal/ebpf/helpers.go b/pkg/proc/internal/ebpf/helpers.go index fbef79e950..cddb4af71a 100644 --- a/pkg/proc/internal/ebpf/helpers.go +++ b/pkg/proc/internal/ebpf/helpers.go @@ -186,7 +186,9 @@ func parseFunctionParameterList(rawParamBytes []byte) RawUProbeParams { iparam.Addr = FakeAddressBase switch iparam.Kind { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + iparam.RealType = &godwarf.UintType{BasicType: godwarf.BasicType{CommonType: godwarf.CommonType{ByteSize: 8}}} + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Bool: iparam.RealType = &godwarf.IntType{BasicType: godwarf.BasicType{CommonType: godwarf.CommonType{ByteSize: 8}}} case reflect.String: strLen := binary.LittleEndian.Uint64(val[8:]) From 6a0423a1e922652dc28ff980d9c61056c2e75231 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 21 Aug 2023 21:30:56 +0200 Subject: [PATCH 103/114] proc: when stepping set condition on thread ID if there is no curg (#3475) If there is no current goroutine when 'next', 'step' or 'stepout' are used set a condition that the thread ID should stay the same instead. This makes stepping work for multithreaded C programs or Go programs that have threads started by cgo code. Fixes #3262 --- pkg/astutil/astutil.go | 10 ++++++++-- pkg/proc/core/core_test.go | 4 ++-- pkg/proc/eval.go | 35 +++++++++++++++++++++------------ pkg/proc/proc_test.go | 10 +++++----- pkg/proc/stack_sigtramp.go | 2 +- pkg/proc/stackwatch.go | 2 +- pkg/proc/target_exec.go | 38 ++++++++++++++++++++++++------------ pkg/proc/variables_test.go | 4 ++-- service/debugger/debugger.go | 2 +- 9 files changed, 68 insertions(+), 39 deletions(-) diff --git a/pkg/astutil/astutil.go b/pkg/astutil/astutil.go index 6d861826b7..9b39448ede 100644 --- a/pkg/astutil/astutil.go +++ b/pkg/astutil/astutil.go @@ -30,11 +30,17 @@ func Int(n int64) *ast.BasicLit { } // And returns an expression evaluating 'x && y'. -func And(x, y ast.Expr) *ast.BinaryExpr { +func And(x, y ast.Expr) ast.Expr { + if x == nil || y == nil { + return nil + } return &ast.BinaryExpr{Op: token.LAND, X: x, Y: y} } // Or returns an expression evaluating 'x || y'. -func Or(x, y ast.Expr) *ast.BinaryExpr { +func Or(x, y ast.Expr) ast.Expr { + if x == nil || y == nil { + return nil + } return &ast.BinaryExpr{Op: token.LOR, X: x, Y: y} } diff --git a/pkg/proc/core/core_test.go b/pkg/proc/core/core_test.go index 2744bf442e..63c3399635 100644 --- a/pkg/proc/core/core_test.go +++ b/pkg/proc/core/core_test.go @@ -299,7 +299,7 @@ func TestCore(t *testing.T) { if mainFrame == nil { t.Fatalf("Couldn't find main in stack %v", panickingStack) } - msg, err := proc.FrameToScope(p, p.Memory(), nil, *mainFrame).EvalExpression("msg", proc.LoadConfig{MaxStringLen: 64}) + msg, err := proc.FrameToScope(p, p.Memory(), nil, p.CurrentThread().ThreadID(), *mainFrame).EvalExpression("msg", proc.LoadConfig{MaxStringLen: 64}) if err != nil { t.Fatalf("Couldn't EvalVariable(msg, ...): %v", err) } @@ -434,7 +434,7 @@ mainSearch: t.Fatal("could not find main.main frame") } - scope := proc.FrameToScope(p, p.Memory(), nil, *mainFrame) + scope := proc.FrameToScope(p, p.Memory(), nil, p.CurrentThread().ThreadID(), *mainFrame) loadConfig := proc.LoadConfig{FollowPointers: true, MaxVariableRecurse: 1, MaxStringLen: 64, MaxArrayValues: 64, MaxStructFields: -1} v1, err := scope.EvalExpression("t", loadConfig) assertNoError(err, t, "EvalVariable(t)") diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index 220cb93a75..0692e36c4b 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -31,12 +31,13 @@ const goDictionaryName = ".dict" // current location (PC), and canonical frame address. type EvalScope struct { Location - Regs op.DwarfRegisters - Mem MemoryReadWriter // Target's memory - g *G - BinInfo *BinaryInfo - target *Target - loadCfg *LoadConfig + Regs op.DwarfRegisters + Mem MemoryReadWriter // Target's memory + g *G + threadID int + BinInfo *BinaryInfo + target *Target + loadCfg *LoadConfig frameOffset int64 @@ -78,6 +79,7 @@ func ConvertEvalScope(dbp *Target, gid int64, frame, deferCall int) (*EvalScope, return nil, err } ct := dbp.CurrentThread() + threadID := ct.ThreadID() g, err := FindGoroutine(dbp, gid) if err != nil { return nil, err @@ -90,6 +92,9 @@ func ConvertEvalScope(dbp *Target, gid int64, frame, deferCall int) (*EvalScope, var locs []Stackframe if g != nil { + if g.Thread != nil { + threadID = g.Thread.ThreadID() + } locs, err = GoroutineStacktrace(dbp, g, frame+1, opts) } else { locs, err = ThreadStacktrace(dbp, ct, frame+1) @@ -115,7 +120,7 @@ func ConvertEvalScope(dbp *Target, gid int64, frame, deferCall int) (*EvalScope, return d.EvalScope(dbp, ct) } - return FrameToScope(dbp, dbp.Memory(), g, locs[frame:]...), nil + return FrameToScope(dbp, dbp.Memory(), g, threadID, locs[frame:]...), nil } // FrameToScope returns a new EvalScope for frames[0]. @@ -123,7 +128,7 @@ func ConvertEvalScope(dbp *Target, gid int64, frame, deferCall int) (*EvalScope, // frames[0].Regs.SP() and frames[1].Regs.CFA will be cached. // Otherwise all memory between frames[0].Regs.SP() and frames[0].Regs.CFA // will be cached. -func FrameToScope(t *Target, thread MemoryReadWriter, g *G, frames ...Stackframe) *EvalScope { +func FrameToScope(t *Target, thread MemoryReadWriter, g *G, threadID int, frames ...Stackframe) *EvalScope { // Creates a cacheMem that will preload the entire stack frame the first // time any local variable is read. // Remember that the stack grows downward in memory. @@ -138,7 +143,7 @@ func FrameToScope(t *Target, thread MemoryReadWriter, g *G, frames ...Stackframe thread = cacheMemory(thread, minaddr, int(maxaddr-minaddr)) } - s := &EvalScope{Location: frames[0].Call, Regs: frames[0].Regs, Mem: thread, g: g, BinInfo: t.BinInfo(), target: t, frameOffset: frames[0].FrameOffset()} + s := &EvalScope{Location: frames[0].Call, Regs: frames[0].Regs, Mem: thread, g: g, BinInfo: t.BinInfo(), target: t, frameOffset: frames[0].FrameOffset(), threadID: threadID} s.PC = frames[0].lastpc return s } @@ -152,7 +157,7 @@ func ThreadScope(t *Target, thread Thread) (*EvalScope, error) { if len(locations) < 1 { return nil, errors.New("could not decode first frame") } - return FrameToScope(t, thread.ProcessMemory(), nil, locations...), nil + return FrameToScope(t, thread.ProcessMemory(), nil, thread.ThreadID(), locations...), nil } // GoroutineScope returns an EvalScope for the goroutine running on the given thread. @@ -168,7 +173,11 @@ func GoroutineScope(t *Target, thread Thread) (*EvalScope, error) { if err != nil { return nil, err } - return FrameToScope(t, thread.ProcessMemory(), g, locations...), nil + threadID := 0 + if g.Thread != nil { + threadID = g.Thread.ThreadID() + } + return FrameToScope(t, thread.ProcessMemory(), g, threadID, locations...), nil } // EvalExpression returns the value of the given expression. @@ -634,7 +643,7 @@ func (scope *EvalScope) evalAST(t ast.Expr) (*Variable, error) { if scope.g == nil { typ, err := scope.BinInfo.findType("runtime.g") if err != nil { - return nil, fmt.Errorf("blah: %v", err) + return nil, fmt.Errorf("could not find runtime.g: %v", err) } gvar := newVariable("curg", fakeAddressUnresolv, typ, scope.BinInfo, scope.Mem) gvar.loaded = true @@ -646,6 +655,8 @@ func (scope *EvalScope) evalAST(t ast.Expr) (*Variable, error) { return scope.g.variable.clone(), nil } else if maybePkg.Name == "runtime" && node.Sel.Name == "frameoff" { return newConstant(constant.MakeInt64(scope.frameOffset), scope.Mem), nil + } else if maybePkg.Name == "runtime" && node.Sel.Name == "threadid" { + return newConstant(constant.MakeInt64(int64(scope.threadID)), scope.Mem), nil } else if v, err := scope.findGlobal(maybePkg.Name, node.Sel.Name); err == nil { return v, nil } diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index fb77c44b12..633752f181 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -1199,7 +1199,7 @@ func evalVariableOrError(p *proc.Target, symbol string) (*proc.Variable, error) var frame proc.Stackframe frame, err = findFirstNonRuntimeFrame(p) if err == nil { - scope = proc.FrameToScope(p, p.Memory(), nil, frame) + scope = proc.FrameToScope(p, p.Memory(), nil, 0, frame) } } else { scope, err = proc.GoroutineScope(p, p.CurrentThread()) @@ -3101,7 +3101,7 @@ func TestIssue871(t *testing.T) { var frame proc.Stackframe frame, err = findFirstNonRuntimeFrame(p) if err == nil { - scope = proc.FrameToScope(p, p.Memory(), nil, frame) + scope = proc.FrameToScope(p, p.Memory(), nil, 0, frame) } } else { scope, err = proc.GoroutineScope(p, p.CurrentThread()) @@ -3514,7 +3514,7 @@ func TestIssue1034(t *testing.T) { assertNoError(grp.Continue(), t, "Continue()") frames, err := proc.GoroutineStacktrace(p, p.SelectedGoroutine(), 10, 0) assertNoError(err, t, "Stacktrace") - scope := proc.FrameToScope(p, p.Memory(), nil, frames[2:]...) + scope := proc.FrameToScope(p, p.Memory(), nil, 0, frames[2:]...) args, _ := scope.FunctionArguments(normalLoadConfig) assertNoError(err, t, "FunctionArguments()") if len(args) > 0 { @@ -5277,8 +5277,8 @@ func TestDump(t *testing.T) { t.Errorf("Frame mismatch %d.%d\nlive:\t%s\ncore:\t%s", gos[i].ID, j, convertFrame(p.BinInfo().Arch, &frames[j]), convertFrame(p.BinInfo().Arch, &cframes[j])) } if frames[j].Call.Fn != nil && frames[j].Call.Fn.Name == "main.main" { - scope = proc.FrameToScope(p, p.Memory(), gos[i], frames[j:]...) - cscope = proc.FrameToScope(c, c.Memory(), cgos[i], cframes[j:]...) + scope = proc.FrameToScope(p, p.Memory(), gos[i], 0, frames[j:]...) + cscope = proc.FrameToScope(c, c.Memory(), cgos[i], 0, cframes[j:]...) } } } diff --git a/pkg/proc/stack_sigtramp.go b/pkg/proc/stack_sigtramp.go index da7426747f..bbf0fe52bc 100644 --- a/pkg/proc/stack_sigtramp.go +++ b/pkg/proc/stack_sigtramp.go @@ -14,7 +14,7 @@ import ( // readSigtrampgoContext reads runtime.sigtrampgo context at the specified address func (it *stackIterator) readSigtrampgoContext() (*op.DwarfRegisters, error) { logger := logflags.DebuggerLogger() - scope := FrameToScope(it.target, it.mem, it.g, it.frame) + scope := FrameToScope(it.target, it.mem, it.g, 0, it.frame) bi := it.bi findvar := func(name string) *Variable { diff --git a/pkg/proc/stackwatch.go b/pkg/proc/stackwatch.go index 64f9dc027b..99ee6db760 100644 --- a/pkg/proc/stackwatch.go +++ b/pkg/proc/stackwatch.go @@ -38,7 +38,7 @@ func (t *Target) setStackWatchBreakpoints(scope *EvalScope, watchpoint *Breakpoi return err } - sameGCond := sameGoroutineCondition(scope.g) + sameGCond := sameGoroutineCondition(scope.BinInfo, scope.g, 0) retFrameCond := astutil.And(sameGCond, frameoffCondition(&retframe)) var deferpc uint64 diff --git a/pkg/proc/target_exec.go b/pkg/proc/target_exec.go index 6a99d74596..3f2454079e 100644 --- a/pkg/proc/target_exec.go +++ b/pkg/proc/target_exec.go @@ -444,9 +444,21 @@ func (grp *TargetGroup) Step() (err error) { // sameGoroutineCondition returns an expression that evaluates to true when // the current goroutine is g. -func sameGoroutineCondition(g *G) ast.Expr { +func sameGoroutineCondition(bi *BinaryInfo, g *G, threadID int) ast.Expr { if g == nil { - return nil + if len(bi.Images[0].compileUnits) == 0 { + // It's unclear what the right behavior is here. We are probably + // debugging a process without debug info, this means we can't properly + // create a same goroutine condition (we don't have a description for the + // runtime.g type). If we don't set the condition then 'next' (and step, + // stepout) will work for single-threaded programs (in limited + // circumstances) but fail in presence of any concurrency. + // If we set a thread ID condition even single threaded programs can fail + // due to goroutine migration, but sometimes it will work even with + // concurrency. + return nil + } + return astutil.Eql(astutil.PkgVar("runtime", "threadid"), astutil.Int(int64(threadID))) } return astutil.Eql(astutil.Sel(astutil.PkgVar("runtime", "curg"), "goid"), astutil.Int(int64(g.ID))) } @@ -492,7 +504,7 @@ func (grp *TargetGroup) StepOut() error { return grp.Continue() } - sameGCond := sameGoroutineCondition(selg) + sameGCond := sameGoroutineCondition(dbp.BinInfo(), selg, curthread.ThreadID()) if backward { if err := stepOutReverse(dbp, topframe, retframe, sameGCond); err != nil { @@ -544,7 +556,7 @@ func (grp *TargetGroup) StepInstruction() (err error) { if g.Thread == nil { // Step called on parked goroutine if _, err := dbp.SetBreakpoint(0, g.PC, NextBreakpoint, - sameGoroutineCondition(dbp.SelectedGoroutine())); err != nil { + sameGoroutineCondition(dbp.BinInfo(), dbp.SelectedGoroutine(), thread.ThreadID())); err != nil { return err } return grp.Continue() @@ -637,7 +649,7 @@ func next(dbp *Target, stepInto, inlinedStepOut bool) error { } } - sameGCond := sameGoroutineCondition(selg) + sameGCond := sameGoroutineCondition(dbp.BinInfo(), selg, curthread.ThreadID()) var firstPCAfterPrologue uint64 @@ -667,10 +679,7 @@ func next(dbp *Target, stepInto, inlinedStepOut bool) error { return err } - var sameFrameCond ast.Expr - if sameGCond != nil { - sameFrameCond = astutil.And(sameGCond, frameoffCondition(&topframe)) - } + sameFrameCond := astutil.And(sameGCond, frameoffCondition(&topframe)) if stepInto && !backward { err := setStepIntoBreakpoints(dbp, topframe.Current.Fn, text, topframe, sameGCond) @@ -818,7 +827,7 @@ func stepIntoCallback(curthread Thread, p *Target) (bool, error) { // here we either set a breakpoint into the destination of the CALL // instruction or we determined that the called function is hidden, // either way we need to resume execution - if err = setStepIntoBreakpoint(p, fn, text, sameGoroutineCondition(g)); err != nil { + if err = setStepIntoBreakpoint(p, fn, text, sameGoroutineCondition(p.BinInfo(), g, curthread.ThreadID())); err != nil { return false, err } @@ -1241,9 +1250,12 @@ type onNextGoroutineWalker struct { } func (w *onNextGoroutineWalker) Visit(n ast.Node) ast.Visitor { - if binx, isbin := n.(*ast.BinaryExpr); isbin && binx.Op == token.EQL && exprToString(binx.X) == "runtime.curg.goid" { - w.ret, w.err = evalBreakpointCondition(w.tgt, w.thread, n.(ast.Expr)) - return nil + if binx, isbin := n.(*ast.BinaryExpr); isbin && binx.Op == token.EQL { + x := exprToString(binx.X) + if x == "runtime.curg.goid" || x == "runtime.threadid" { + w.ret, w.err = evalBreakpointCondition(w.tgt, w.thread, n.(ast.Expr)) + return nil + } } return w } diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go index 82a63ce1c3..d074ee1fdf 100644 --- a/pkg/proc/variables_test.go +++ b/pkg/proc/variables_test.go @@ -82,7 +82,7 @@ func evalScope(p *proc.Target) (*proc.EvalScope, error) { if err != nil { return nil, err } - return proc.FrameToScope(p, p.Memory(), nil, frame), nil + return proc.FrameToScope(p, p.Memory(), nil, p.CurrentThread().ThreadID(), frame), nil } func evalVariableWithCfg(p *proc.Target, symbol string, cfg proc.LoadConfig) (*proc.Variable, error) { @@ -417,7 +417,7 @@ func TestLocalVariables(t *testing.T) { var frame proc.Stackframe frame, err = findFirstNonRuntimeFrame(p) if err == nil { - scope = proc.FrameToScope(p, p.Memory(), nil, frame) + scope = proc.FrameToScope(p, p.Memory(), nil, p.CurrentThread().ThreadID(), frame) } } else { scope, err = proc.GoroutineScope(p, p.CurrentThread()) diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index 78a7792903..c07eb1b563 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -1863,7 +1863,7 @@ func (d *Debugger) convertStacktrace(rawlocs []proc.Stackframe, cfg *proc.LoadCo } if cfg != nil && rawlocs[i].Current.Fn != nil { var err error - scope := proc.FrameToScope(d.target.Selected, d.target.Selected.Memory(), nil, rawlocs[i:]...) + scope := proc.FrameToScope(d.target.Selected, d.target.Selected.Memory(), nil, 0, rawlocs[i:]...) locals, err := scope.LocalVariables(*cfg) if err != nil { return nil, err From 32b937c953720deb55f34b2abe0e64d8164904bf Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 22 Aug 2023 18:24:25 +0200 Subject: [PATCH 104/114] teamcity: misc changes to CI (#3476) - add architecture rule for ppc64le so that incompatible agents don't pick up the build - disable PIE tests on linux/ppc64le (the tests claim it doesn't work) - enable PIE tests on darwin/amd64 now that the entry point calculation has been fixed - remove dependency on wget and curl in the test script for linux to reduce test time - only install git in the linux test script when we need it - remove staticcheck from linux/ppc64le builds (it takes almost 5 minutes between installation and execution and makes the test timeout sometimes) - drop windows/arm64/tip build, the windows/arm64 build is broken anyway and since there is only one agent it makes CI runs slow - drop linux/ppc64le/tip build, there is only one agent, it's slow and it will always timeout. CI runs in excess of 1h are too long. --- .teamcity/settings.kts | 3 +-- _scripts/make.go | 9 ++++++++- _scripts/test_linux.sh | 19 +++++++++++++------ pkg/proc/proc_test.go | 1 + 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/.teamcity/settings.kts b/.teamcity/settings.kts index fda747c64d..9d12b453e9 100644 --- a/.teamcity/settings.kts +++ b/.teamcity/settings.kts @@ -46,13 +46,11 @@ val targets = arrayOf( "linux/arm64/tip", "linux/ppc64le/1.21", - "linux/ppc64le/tip", "windows/amd64/1.21", "windows/amd64/tip", "windows/arm64/1.21", - "windows/arm64/tip", "mac/amd64/1.21", "mac/amd64/tip", @@ -231,6 +229,7 @@ class TestBuild(val os: String, val arch: String, version: String, buildId: Abso when (arch) { "386", "amd64" -> equals("teamcity.agent.jvm.os.arch", if (os == "mac") "x86_64" else "amd64") "arm64" -> equals("teamcity.agent.jvm.os.arch", "aarch64") + "ppc64le" -> equals("teamcity.agent.jvm.os.arch", "ppc64le") } when (os) { "linux" -> { diff --git a/_scripts/make.go b/_scripts/make.go index ee75cff608..cd1adc0db1 100644 --- a/_scripts/make.go +++ b/_scripts/make.go @@ -398,7 +398,9 @@ func testStandard() { dopie := false switch runtime.GOOS { case "linux": - dopie = true + if runtime.GOARCH != "ppc64le" { + dopie = true + } case "windows": // windows/arm64 always uses pie buildmode, no need to test everything again. // only on Go 1.15 or later, with CGO_ENABLED and gcc found in path @@ -413,6 +415,11 @@ func testStandard() { } } } + case "darwin": + if runtime.GOARCH == "amd64" { + // arm64 can only build in pie mode + dopie = true + } } if dopie { fmt.Println("\nTesting PIE buildmode, default backend") diff --git a/_scripts/test_linux.sh b/_scripts/test_linux.sh index e788ad1b4a..523456c6ef 100755 --- a/_scripts/test_linux.sh +++ b/_scripts/test_linux.sh @@ -3,17 +3,21 @@ set -e set -x apt-get -qq update -apt-get install -y dwz wget make git gcc curl jq lsof - -dwz --version +apt-get install -y gcc curl jq lsof version=$1 arch=$2 + +if [ "$arch" != "ppc64le" ]; then + apt-get install -y dwz + dwz --version +fi + function getgo { export GOROOT=/usr/local/go/$1 if [ ! -d "$GOROOT" ]; then - wget -q https://dl.google.com/go/"$1".linux-"${arch}".tar.gz + curl -sO https://dl.google.com/go/"$1".linux-"${arch}".tar.gz mkdir -p /usr/local/go tar -C /usr/local/go -xzf "$1".linux-"${arch}".tar.gz mv -f /usr/local/go/go "$GOROOT" @@ -25,6 +29,7 @@ if [ "$version" = "gotip" ]; then getgo $(curl https://go.dev/VERSION?m=text | head -1) export GOROOT_BOOTSTRAP=$GOROOT export GOROOT=/usr/local/go/go-tip + apt-get install -y git git clone https://go.googlesource.com/go /usr/local/go/go-tip cd /usr/local/go/go-tip/src ./make.bash @@ -44,7 +49,9 @@ GOPATH=$(pwd)/go export GOPATH export PATH=$PATH:$GOROOT/bin:$GOPATH/bin go version -go install honnef.co/go/tools/cmd/staticcheck@2023.1 || true +if [ "$arch" != "ppc64le" ]; then + go install honnef.co/go/tools/cmd/staticcheck@2023.1 || true +fi uname -a echo "$PATH" @@ -68,7 +75,7 @@ if [ "$arch" = "386" ]; then fi set +e -make test +go run _scripts/make.go test x=$? if [ "$version" = "gotip" ]; then exit 0 diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 633752f181..6973e98e39 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -5941,6 +5941,7 @@ func TestStacktraceExtlinkMac(t *testing.T) { // Tests stacktrace for programs built using external linker. // See issue #3194 skipUnlessOn(t, "darwin only", "darwin") + skipOn(t, "broken on darwin/amd64/pie", "darwin", "amd64", "pie") withTestProcess("issue3194", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { setFunctionBreakpoint(p, t, "main.main") assertNoError(grp.Continue(), t, "First Continue()") From 5f01e72bb8b06a01f554aeb0e3047018c7233a99 Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Tue, 22 Aug 2023 22:45:44 -0700 Subject: [PATCH 105/114] cmd/dlv: handle ctrl-c during tracing (#3477) Ensure we send a Halt command to stop the process being traced so that the deferred Detach can run ensuring proper cleanup upon exit. Fixes #3228 --- cmd/dlv/cmds/commands.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cmd/dlv/cmds/commands.go b/cmd/dlv/cmds/commands.go index fb71f26e6a..e6af4c6255 100644 --- a/cmd/dlv/cmds/commands.go +++ b/cmd/dlv/cmds/commands.go @@ -672,6 +672,15 @@ func traceCmd(cmd *cobra.Command, args []string, conf *config.Config) int { } client := rpc2.NewClientFromConn(clientConn) defer client.Detach(true) + + ch := make(chan os.Signal, 1) + signal.Notify(ch, syscall.SIGINT) + + go func() { + <-ch + client.Halt() + }() + funcs, err := client.ListFunctions(regexp) if err != nil { fmt.Fprintln(os.Stderr, err) From 789f8b405444179926e28bf6a3cf9d1c726e83a2 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 23 Aug 2023 18:49:54 +0200 Subject: [PATCH 106/114] proc: remove unused functions (#3479) --- pkg/proc/eval.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index 0692e36c4b..51161e4493 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -613,17 +613,6 @@ func (scope *EvalScope) image() *Image { return scope.BinInfo.funcToImage(scope.Fn) } -// DwarfReader returns the DwarfReader containing the -// Dwarf information for the target process. -func (scope *EvalScope) DwarfReader() *reader.Reader { - return scope.image().DwarfReader() -} - -// PtrSize returns the size of a pointer. -func (scope *EvalScope) PtrSize() int { - return scope.BinInfo.Arch.PtrSize() -} - func (scope *EvalScope) evalAST(t ast.Expr) (*Variable, error) { switch node := t.(type) { case *ast.CallExpr: From 908876d6aaf1c769bc12ff293490d520bdf9ba09 Mon Sep 17 00:00:00 2001 From: Javier Honduvilla Coto Date: Wed, 23 Aug 2023 20:56:58 +0100 Subject: [PATCH 107/114] DWARF CFI: use a stack for restore/remember opcodes (#3480) Implementing the `DW_CFA_remember_state` and `DW_CFA_restore_state` according to the DWARF specification requires us to create a stack that can store an arbitrary number of elements, that is, there could be multiple "pushes" before "popping" them. From the 5th revision of the spec [0]: > 6.4.2.4 Row State Instructions > DW_CFA_remember_state > The DW_CFA_remember_state instruction takes no operands. The required > action is to push the set of rules for every register onto an implicit stack. > DW_CFA_restore_state > DW_CFA_restore_state > The DW_CFA_restore_state instruction takes no operands. The required action > is to pop the set of rules off the implicit stack and place them in the > current row. - [0]: https://dwarfstd.org/doc/DWARF5.pdf Signed-off-by: Francisco Javier Honduvilla Coto --- pkg/dwarf/frame/table.go | 79 +++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 22 deletions(-) diff --git a/pkg/dwarf/frame/table.go b/pkg/dwarf/frame/table.go index c49d2115b8..628d7b366e 100644 --- a/pkg/dwarf/frame/table.go +++ b/pkg/dwarf/frame/table.go @@ -18,18 +18,46 @@ type DWRule struct { // FrameContext wrapper of FDE context type FrameContext struct { - loc uint64 - order binary.ByteOrder - address uint64 - CFA DWRule - Regs map[uint64]DWRule - initialRegs map[uint64]DWRule - prevRegs map[uint64]DWRule - buf *bytes.Buffer - cie *CommonInformationEntry - RetAddrReg uint64 - codeAlignment uint64 - dataAlignment int64 + loc uint64 + order binary.ByteOrder + address uint64 + CFA DWRule + Regs map[uint64]DWRule + initialRegs map[uint64]DWRule + buf *bytes.Buffer + cie *CommonInformationEntry + RetAddrReg uint64 + codeAlignment uint64 + dataAlignment int64 + rememberedState *stateStack +} + +type rowState struct { + cfa DWRule + regs map[uint64]DWRule +} + +// stateStack is a stack where `DW_CFA_remember_state` pushes +// its CFA and registers state and `DW_CFA_restore_state` +// pops them. +type stateStack struct { + items []rowState +} + +func newStateStack() *stateStack { + return &stateStack{ + items: make([]rowState, 0), + } +} + +func (stack *stateStack) push(state rowState) { + stack.items = append(stack.items, state) +} + +func (stack *stateStack) pop() rowState { + restored := stack.items[len(stack.items)-1] + stack.items = stack.items[0 : len(stack.items)-1] + return restored } // Instructions used to recreate the table from the .debug_frame data. @@ -119,14 +147,14 @@ func executeCIEInstructions(cie *CommonInformationEntry) *FrameContext { initialInstructions := make([]byte, len(cie.InitialInstructions)) copy(initialInstructions, cie.InitialInstructions) frame := &FrameContext{ - cie: cie, - Regs: make(map[uint64]DWRule), - RetAddrReg: cie.ReturnAddressRegister, - initialRegs: make(map[uint64]DWRule), - prevRegs: make(map[uint64]DWRule), - codeAlignment: cie.CodeAlignmentFactor, - dataAlignment: cie.DataAlignmentFactor, - buf: bytes.NewBuffer(initialInstructions), + cie: cie, + Regs: make(map[uint64]DWRule), + RetAddrReg: cie.ReturnAddressRegister, + initialRegs: make(map[uint64]DWRule), + codeAlignment: cie.CodeAlignmentFactor, + dataAlignment: cie.DataAlignmentFactor, + buf: bytes.NewBuffer(initialInstructions), + rememberedState: newStateStack(), } frame.executeDwarfProgram() @@ -308,11 +336,18 @@ func register(frame *FrameContext) { } func rememberstate(frame *FrameContext) { - frame.prevRegs = frame.Regs + clonedRegs := make(map[uint64]DWRule, len(frame.Regs)) + for k, v := range frame.Regs { + clonedRegs[k] = v + } + frame.rememberedState.push(rowState{cfa: frame.CFA, regs: clonedRegs}) } func restorestate(frame *FrameContext) { - frame.Regs = frame.prevRegs + restored := frame.rememberedState.pop() + + frame.CFA = restored.cfa + frame.Regs = restored.regs } func restoreextended(frame *FrameContext) { From 80e6c28ab23db4f5df690ae1081e5bf24c458de6 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 23 Aug 2023 21:57:34 +0200 Subject: [PATCH 108/114] proc: disable "wait-for" tests on freebsd (#3482) They are flaky in CI, I can not reproduce the problem locally. --- Documentation/backend_test_health.md | 3 ++- pkg/proc/proc_test.go | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/backend_test_health.md b/Documentation/backend_test_health.md index 2a6661d91e..e93bbce121 100644 --- a/Documentation/backend_test_health.md +++ b/Documentation/backend_test_health.md @@ -11,7 +11,8 @@ Tests skipped by each supported backend: * 2 broken - cgo stacktraces * darwin/lldb skipped = 1 * 1 upstream issue -* freebsd skipped = 4 +* freebsd skipped = 6 + * 2 flaky * 4 not implemented * linux/386/pie skipped = 1 * 1 broken diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 6973e98e39..968dcaa9d3 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -6197,6 +6197,7 @@ func testWaitForSetup(t *testing.T, mu *sync.Mutex, started *bool) (*exec.Cmd, * func TestWaitFor(t *testing.T) { skipOn(t, "waitfor implementation is delegated to debugserver", "darwin") + skipOn(t, "flaky", "freebsd") var mu sync.Mutex started := false @@ -6214,6 +6215,7 @@ func TestWaitFor(t *testing.T) { } func TestWaitForAttach(t *testing.T) { + skipOn(t, "flaky", "freebsd") if testBackend == "lldb" && runtime.GOOS == "linux" { bs, _ := ioutil.ReadFile("/proc/sys/kernel/yama/ptrace_scope") if bs == nil || strings.TrimSpace(string(bs)) != "0" { From 0b35fe6d428109e190bfcfce903829fe8842e042 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 23 Aug 2023 22:02:34 +0200 Subject: [PATCH 109/114] proc,service,terminal: add ways to list goroutines waiting on a channel (#3481) Adds -chan option to the goroutines command to list only the goroutines running on a specified channel. Also when printing a variable if it is a channel also print the list of goroutines that are waiting on it. --- Documentation/cli/README.md | 10 ++- Documentation/cli/starlark.md | 2 +- _fixtures/changoroutines.go | 26 +++++++ pkg/proc/eval.go | 83 +++++++++++++++++++++++ pkg/terminal/command.go | 34 ++++++++-- pkg/terminal/starbind/starlark_mapping.go | 13 +++- service/api/command.go | 8 +++ service/api/types.go | 17 ++--- service/client.go | 2 +- service/debugger/debugger.go | 27 ++++++++ service/rpc2/client.go | 6 +- service/rpc2/server.go | 37 +++++++++- service/test/integration2_test.go | 71 ++++++++++++++++++- 13 files changed, 313 insertions(+), 23 deletions(-) create mode 100644 _fixtures/changoroutines.go diff --git a/Documentation/cli/README.md b/Documentation/cli/README.md index 01818a5036..2754e69551 100644 --- a/Documentation/cli/README.md +++ b/Documentation/cli/README.md @@ -386,7 +386,7 @@ Aliases: gr ## goroutines List program goroutines. - goroutines [-u|-r|-g|-s] [-t [depth]] [-l] [-with loc expr] [-without loc expr] [-group argument] [-exec command] + goroutines [-u|-r|-g|-s] [-t [depth]] [-l] [-with loc expr] [-without loc expr] [-group argument] [-chan expr] [-exec command] Print out info for every goroutine. The flag controls what information is shown along with each goroutine: @@ -437,6 +437,14 @@ To only display user (or runtime) goroutines, use: goroutines -with user goroutines -without user +CHANNELS + +To only show goroutines waiting to send to or receive from a specific channel use: + + goroutines -chan expr + +Note that 'expr' must not contain spaces. + GROUPING goroutines -group (userloc|curloc|goloc|startloc|running|user) diff --git a/Documentation/cli/starlark.md b/Documentation/cli/starlark.md index 5b35dab759..da0b3d3a26 100644 --- a/Documentation/cli/starlark.md +++ b/Documentation/cli/starlark.md @@ -51,7 +51,7 @@ checkpoints() | Equivalent to API call [ListCheckpoints](https://godoc.org/githu dynamic_libraries() | Equivalent to API call [ListDynamicLibraries](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ListDynamicLibraries) function_args(Scope, Cfg) | Equivalent to API call [ListFunctionArgs](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ListFunctionArgs) functions(Filter) | Equivalent to API call [ListFunctions](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ListFunctions) -goroutines(Start, Count, Filters, GoroutineGroupingOptions) | Equivalent to API call [ListGoroutines](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ListGoroutines) +goroutines(Start, Count, Filters, GoroutineGroupingOptions, EvalScope) | Equivalent to API call [ListGoroutines](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ListGoroutines) local_vars(Scope, Cfg) | Equivalent to API call [ListLocalVars](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ListLocalVars) package_vars(Filter, Cfg) | Equivalent to API call [ListPackageVars](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ListPackageVars) packages_build_info(IncludeFiles) | Equivalent to API call [ListPackagesBuildInfo](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ListPackagesBuildInfo) diff --git a/_fixtures/changoroutines.go b/_fixtures/changoroutines.go new file mode 100644 index 0000000000..7f8b884880 --- /dev/null +++ b/_fixtures/changoroutines.go @@ -0,0 +1,26 @@ +package main + +import ( + "runtime" + "time" +) + +func main() { + blockingchan1 := make(chan int) + blockingchan2 := make(chan int) + + go sendToChan("one", blockingchan1) + go sendToChan("two", blockingchan1) + go recvFromChan(blockingchan2) + time.Sleep(time.Second) + + runtime.Breakpoint() +} + +func sendToChan(name string, ch chan<- int) { + ch <- 1 +} + +func recvFromChan(ch <-chan int) { + <-ch +} diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index 51161e4493..02e010106e 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -214,6 +214,89 @@ func (scope *EvalScope) EvalExpression(expr string, cfg LoadConfig) (*Variable, return ev, nil } +// ChanGoroutines returns the list of goroutines waiting to receive from or +// send to the channel. +func (scope *EvalScope) ChanGoroutines(expr string, start, count int) ([]int64, error) { + t, err := parser.ParseExpr(expr) + if err != nil { + return nil, err + } + v, err := scope.evalAST(t) + if err != nil { + return nil, err + } + if v.Kind != reflect.Chan { + return nil, nil + } + + structMemberMulti := func(v *Variable, names ...string) *Variable { + for _, name := range names { + var err error + v, err = v.structMember(name) + if err != nil { + return nil + } + } + return v + } + + waitqFirst := func(qname string) *Variable { + qvar := structMemberMulti(v, qname, "first") + if qvar == nil { + return nil + } + return qvar.maybeDereference() + } + + var goids []int64 + + waitqToGoIDSlice := func(qvar *Variable) error { + if qvar == nil { + return nil + } + for { + if qvar.Addr == 0 { + return nil + } + if len(goids) > count { + return nil + } + goidVar := structMemberMulti(qvar, "g", "goid") + if goidVar == nil { + return nil + } + goidVar.loadValue(loadSingleValue) + if goidVar.Unreadable != nil { + return goidVar.Unreadable + } + goid, _ := constant.Int64Val(goidVar.Value) + if start > 0 { + start-- + } else { + goids = append(goids, goid) + } + + nextVar, err := qvar.structMember("next") + if err != nil { + return err + } + qvar = nextVar.maybeDereference() + } + } + + recvqVar := waitqFirst("recvq") + err = waitqToGoIDSlice(recvqVar) + if err != nil { + return nil, err + } + sendqVar := waitqFirst("sendq") + err = waitqToGoIDSlice(sendqVar) + if err != nil { + return nil, err + } + return goids, nil +} + func isAssignment(err error) (int, bool) { el, isScannerErr := err.(scanner.ErrorList) if isScannerErr && el[0].Msg == "expected '==', found '='" { diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index 430b9b12e4..886eb27a36 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -228,7 +228,7 @@ If called with the locspec argument it will delete all the breakpoints matching toggle `}, {aliases: []string{"goroutines", "grs"}, group: goroutineCmds, cmdFn: c.goroutines, helpMsg: `List program goroutines. - goroutines [-u|-r|-g|-s] [-t [depth]] [-l] [-with loc expr] [-without loc expr] [-group argument] [-exec command] + goroutines [-u|-r|-g|-s] [-t [depth]] [-l] [-with loc expr] [-without loc expr] [-group argument] [-chan expr] [-exec command] Print out info for every goroutine. The flag controls what information is shown along with each goroutine: @@ -279,6 +279,14 @@ To only display user (or runtime) goroutines, use: goroutines -with user goroutines -without user +CHANNELS + +To only show goroutines waiting to send to or receive from a specific channel use: + + goroutines -chan expr + +Note that 'expr' must not contain spaces. + GROUPING goroutines -group (userloc|curloc|goloc|startloc|running|user) @@ -318,7 +326,7 @@ Called with more arguments it will execute a command on the specified goroutine. breakpoints [-a] Specifying -a prints all physical breakpoint, including internal breakpoints.`}, - {aliases: []string{"print", "p"}, group: dataCmds, allowedPrefixes: onPrefix | deferredPrefix, cmdFn: printVar, helpMsg: `Evaluate an expression. + {aliases: []string{"print", "p"}, group: dataCmds, allowedPrefixes: onPrefix | deferredPrefix, cmdFn: c.printVar, helpMsg: `Evaluate an expression. [goroutine ] [frame ] print [%format] @@ -902,7 +910,7 @@ func (c *Commands) goroutines(t *Term, ctx callContext, argstr string) error { fmt.Fprintf(t.stdout, "interrupted\n") return nil } - gs, groups, start, tooManyGroups, err = t.client.ListGoroutinesWithFilter(start, batchSize, filters, &group) + gs, groups, start, tooManyGroups, err = t.client.ListGoroutinesWithFilter(start, batchSize, filters, &group, &api.EvalScope{GoroutineID: -1, Frame: c.frame}) if err != nil { return err } @@ -2090,7 +2098,9 @@ func parseFormatArg(args string) (fmtstr, argsOut string) { return v[0], v[1] } -func printVar(t *Term, ctx callContext, args string) error { +const maxPrintVarChanGoroutines = 100 + +func (c *Commands) printVar(t *Term, ctx callContext, args string) error { if len(args) == 0 { return fmt.Errorf("not enough arguments") } @@ -2105,6 +2115,22 @@ func printVar(t *Term, ctx callContext, args string) error { } fmt.Fprintln(t.stdout, val.MultilineString("", fmtstr)) + + if val.Kind == reflect.Chan { + fmt.Fprintln(t.stdout) + gs, _, _, _, err := t.client.ListGoroutinesWithFilter(0, maxPrintVarChanGoroutines, []api.ListGoroutinesFilter{{Kind: api.GoroutineWaitingOnChannel, Arg: fmt.Sprintf("*(*%q)(%#x)", val.Type, val.Addr)}}, nil, &ctx.Scope) + if err != nil { + fmt.Fprintf(t.stdout, "Error reading channel wait queue: %v", err) + } else { + fmt.Fprintln(t.stdout, "Goroutines waiting on this channel:") + state, err := t.client.GetState() + if err != nil { + fmt.Fprintf(t.stdout, "Error printing channel wait queue: %v", err) + } + var done bool + c.printGoroutines(t, ctx, "", gs, api.FglUserCurrent, 0, 0, "", &done, state) + } + } return nil } diff --git a/pkg/terminal/starbind/starlark_mapping.go b/pkg/terminal/starbind/starlark_mapping.go index 5ff0433c37..967e1bf94c 100644 --- a/pkg/terminal/starbind/starlark_mapping.go +++ b/pkg/terminal/starbind/starlark_mapping.go @@ -1143,6 +1143,15 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) { return starlark.None, decorateError(thread, err) } } + if len(args) > 4 && args[4] != starlark.None { + err := unmarshalStarlarkValue(args[4], &rpcArgs.EvalScope, "EvalScope") + if err != nil { + return starlark.None, decorateError(thread, err) + } + } else { + scope := env.ctx.Scope() + rpcArgs.EvalScope = &scope + } for _, kv := range kwargs { var err error switch kv[0].(starlark.String) { @@ -1154,6 +1163,8 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) { err = unmarshalStarlarkValue(kv[1], &rpcArgs.Filters, "Filters") case "GoroutineGroupingOptions": err = unmarshalStarlarkValue(kv[1], &rpcArgs.GoroutineGroupingOptions, "GoroutineGroupingOptions") + case "EvalScope": + err = unmarshalStarlarkValue(kv[1], &rpcArgs.EvalScope, "EvalScope") default: err = fmt.Errorf("unknown argument %q", kv[0]) } @@ -1167,7 +1178,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) { } return env.interfaceToStarlarkValue(rpcRet), nil }) - doc["goroutines"] = "builtin goroutines(Start, Count, Filters, GoroutineGroupingOptions)\n\ngoroutines lists all goroutines.\nIf Count is specified ListGoroutines will return at the first Count\ngoroutines and an index in Nextg, that can be passed as the Start\nparameter, to get more goroutines from ListGoroutines.\nPassing a value of Start that wasn't returned by ListGoroutines will skip\nan undefined number of goroutines.\n\nIf arg.Filters are specified the list of returned goroutines is filtered\napplying the specified filters.\nFor example:\n\n\tListGoroutinesFilter{ Kind: ListGoroutinesFilterUserLoc, Negated: false, Arg: \"afile.go\" }\n\nwill only return goroutines whose UserLoc contains \"afile.go\" as a substring.\nMore specifically a goroutine matches a location filter if the specified\nlocation, formatted like this:\n\n\tfilename:lineno in function\n\ncontains Arg[0] as a substring.\n\nFilters can also be applied to goroutine labels:\n\n\tListGoroutineFilter{ Kind: ListGoroutinesFilterLabel, Negated: false, Arg: \"key=value\" }\n\nthis filter will only return goroutines that have a key=value label.\n\nIf arg.GroupBy is not GoroutineFieldNone then the goroutines will\nbe grouped with the specified criterion.\nIf the value of arg.GroupBy is GoroutineLabel goroutines will\nbe grouped by the value of the label with key GroupByKey.\nFor each group a maximum of MaxGroupMembers example goroutines are\nreturned, as well as the total number of goroutines in the group." + doc["goroutines"] = "builtin goroutines(Start, Count, Filters, GoroutineGroupingOptions, EvalScope)\n\ngoroutines lists all goroutines.\nIf Count is specified ListGoroutines will return at the first Count\ngoroutines and an index in Nextg, that can be passed as the Start\nparameter, to get more goroutines from ListGoroutines.\nPassing a value of Start that wasn't returned by ListGoroutines will skip\nan undefined number of goroutines.\n\nIf arg.Filters are specified the list of returned goroutines is filtered\napplying the specified filters.\nFor example:\n\n\tListGoroutinesFilter{ Kind: ListGoroutinesFilterUserLoc, Negated: false, Arg: \"afile.go\" }\n\nwill only return goroutines whose UserLoc contains \"afile.go\" as a substring.\nMore specifically a goroutine matches a location filter if the specified\nlocation, formatted like this:\n\n\tfilename:lineno in function\n\ncontains Arg[0] as a substring.\n\nFilters can also be applied to goroutine labels:\n\n\tListGoroutineFilter{ Kind: ListGoroutinesFilterLabel, Negated: false, Arg: \"key=value\" }\n\nthis filter will only return goroutines that have a key=value label.\n\nIf arg.GroupBy is not GoroutineFieldNone then the goroutines will\nbe grouped with the specified criterion.\nIf the value of arg.GroupBy is GoroutineLabel goroutines will\nbe grouped by the value of the label with key GroupByKey.\nFor each group a maximum of MaxGroupMembers example goroutines are\nreturned, as well as the total number of goroutines in the group." r["local_vars"] = starlark.NewBuiltin("local_vars", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) diff --git a/service/api/command.go b/service/api/command.go index 86e43cd039..922d14546d 100644 --- a/service/api/command.go +++ b/service/api/command.go @@ -1,6 +1,7 @@ package api import ( + "errors" "fmt" "strconv" "strings" @@ -99,6 +100,13 @@ func ParseGoroutineArgs(argstr string) ([]ListGoroutinesFilter, GoroutineGroupin } batchSize = 0 // grouping only works well if run on all goroutines + case "-chan": + i++ + if i >= len(args) { + return nil, GoroutineGroupingOptions{}, 0, 0, 0, 0, "", errors.New("not enough arguments after -chan") + } + filters = append(filters, ListGoroutinesFilter{Kind: GoroutineWaitingOnChannel, Arg: args[i]}) + case "-exec": flags |= PrintGoroutinesExec cmd = strings.Join(args[i+1:], " ") diff --git a/service/api/types.go b/service/api/types.go index 13a1e8d2e7..6e893a5327 100644 --- a/service/api/types.go +++ b/service/api/types.go @@ -635,14 +635,15 @@ type ListGoroutinesFilter struct { type GoroutineField uint8 const ( - GoroutineFieldNone GoroutineField = iota - GoroutineCurrentLoc // the goroutine's CurrentLoc - GoroutineUserLoc // the goroutine's UserLoc - GoroutineGoLoc // the goroutine's GoStatementLoc - GoroutineStartLoc // the goroutine's StartLoc - GoroutineLabel // the goroutine's label - GoroutineRunning // the goroutine is running - GoroutineUser // the goroutine is a user goroutine + GoroutineFieldNone GoroutineField = iota + GoroutineCurrentLoc // the goroutine's CurrentLoc + GoroutineUserLoc // the goroutine's UserLoc + GoroutineGoLoc // the goroutine's GoStatementLoc + GoroutineStartLoc // the goroutine's StartLoc + GoroutineLabel // the goroutine's label + GoroutineRunning // the goroutine is running + GoroutineUser // the goroutine is a user goroutine + GoroutineWaitingOnChannel // the goroutine is waiting on the channel specified by the argument ) // GoroutineGroup represents a group of goroutines in the return value of diff --git a/service/client.go b/service/client.go index f0cdc668b4..6e42224f0e 100644 --- a/service/client.go +++ b/service/client.go @@ -120,7 +120,7 @@ type Client interface { // ListGoroutines lists all goroutines. ListGoroutines(start, count int) ([]*api.Goroutine, int, error) // ListGoroutinesWithFilter lists goroutines matching the filters - ListGoroutinesWithFilter(start, count int, filters []api.ListGoroutinesFilter, group *api.GoroutineGroupingOptions) ([]*api.Goroutine, []api.GoroutineGroup, int, bool, error) + ListGoroutinesWithFilter(start, count int, filters []api.ListGoroutinesFilter, group *api.GoroutineGroupingOptions, scope *api.EvalScope) ([]*api.Goroutine, []api.GoroutineGroup, int, bool, error) // Stacktrace returns stacktrace Stacktrace(goroutineID int64, depth int, opts api.StacktraceOptions, cfg *api.LoadConfig) ([]api.Stackframe, error) diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index c07eb1b563..3e73621c67 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -1688,6 +1688,8 @@ func matchGoroutineFilter(tgt *proc.Target, g *proc.G, filter *api.ListGoroutine val = g.Thread != nil case api.GoroutineUser: val = !g.System(tgt) + case api.GoroutineWaitingOnChannel: + val = true // handled elsewhere } if filter.Negated { val = !val @@ -2325,6 +2327,31 @@ func (d *Debugger) DebugInfoDirectories() []string { return d.target.Selected.BinInfo().DebugInfoDirectories } +// ChanGoroutines returns the list of goroutines waiting on the channel specified by expr. +func (d *Debugger) ChanGoroutines(goid int64, frame, deferredCall int, expr string, start, count int) ([]*proc.G, error) { + d.targetMutex.Lock() + defer d.targetMutex.Unlock() + s, err := proc.ConvertEvalScope(d.target.Selected, goid, frame, deferredCall) + if err != nil { + return nil, err + } + + goids, err := s.ChanGoroutines(expr, start, count) + if err != nil { + return nil, err + } + + gs := make([]*proc.G, len(goids)) + for i := range goids { + g, err := proc.FindGoroutine(d.target.Selected, goids[i]) + if g == nil { + g = &proc.G{Unreadable: err} + } + gs[i] = g + } + return gs, nil +} + func go11DecodeErrorCheck(err error) error { if _, isdecodeerr := err.(dwarf.DecodeError); !isdecodeerr { return err diff --git a/service/rpc2/client.go b/service/rpc2/client.go index e05ae8fbb3..22f88382f7 100644 --- a/service/rpc2/client.go +++ b/service/rpc2/client.go @@ -383,16 +383,16 @@ func (c *RPCClient) ListFunctionArgs(scope api.EvalScope, cfg api.LoadConfig) ([ func (c *RPCClient) ListGoroutines(start, count int) ([]*api.Goroutine, int, error) { var out ListGoroutinesOut - err := c.call("ListGoroutines", ListGoroutinesIn{start, count, nil, api.GoroutineGroupingOptions{}}, &out) + err := c.call("ListGoroutines", ListGoroutinesIn{start, count, nil, api.GoroutineGroupingOptions{}, nil}, &out) return out.Goroutines, out.Nextg, err } -func (c *RPCClient) ListGoroutinesWithFilter(start, count int, filters []api.ListGoroutinesFilter, group *api.GoroutineGroupingOptions) ([]*api.Goroutine, []api.GoroutineGroup, int, bool, error) { +func (c *RPCClient) ListGoroutinesWithFilter(start, count int, filters []api.ListGoroutinesFilter, group *api.GoroutineGroupingOptions, scope *api.EvalScope) ([]*api.Goroutine, []api.GoroutineGroup, int, bool, error) { if group == nil { group = &api.GoroutineGroupingOptions{} } var out ListGoroutinesOut - err := c.call("ListGoroutines", ListGoroutinesIn{start, count, filters, *group}, &out) + err := c.call("ListGoroutines", ListGoroutinesIn{start, count, filters, *group, scope}, &out) return out.Goroutines, out.Groups, out.Nextg, out.TooManyGroups, err } diff --git a/service/rpc2/server.go b/service/rpc2/server.go index c6536e061b..ab18d23202 100644 --- a/service/rpc2/server.go +++ b/service/rpc2/server.go @@ -534,7 +534,8 @@ func (s *RPCServer) Eval(arg EvalIn, out *EvalOut) error { if cfg == nil { cfg = &api.LoadConfig{FollowPointers: true, MaxVariableRecurse: 1, MaxStringLen: 64, MaxArrayValues: 64, MaxStructFields: -1} } - v, err := s.debugger.EvalVariableInScope(arg.Scope.GoroutineID, arg.Scope.Frame, arg.Scope.DeferredCall, arg.Expr, *api.LoadConfigToProc(cfg)) + pcfg := *api.LoadConfigToProc(cfg) + v, err := s.debugger.EvalVariableInScope(arg.Scope.GoroutineID, arg.Scope.Frame, arg.Scope.DeferredCall, arg.Expr, pcfg) if err != nil { return err } @@ -617,6 +618,8 @@ type ListGoroutinesIn struct { Filters []api.ListGoroutinesFilter api.GoroutineGroupingOptions + + EvalScope *api.EvalScope } type ListGoroutinesOut struct { @@ -663,7 +666,37 @@ func (s *RPCServer) ListGoroutines(arg ListGoroutinesIn, out *ListGoroutinesOut) //TODO(aarzilli): if arg contains a running goroutines filter (not negated) // and start == 0 and count == 0 then we can optimize this by just looking // at threads directly. - gs, nextg, err := s.debugger.Goroutines(arg.Start, arg.Count) + + var gs []*proc.G + var nextg int + var err error + var gsLoaded bool + + for _, filter := range arg.Filters { + if filter.Kind == api.GoroutineWaitingOnChannel { + if filter.Negated { + return errors.New("channel filter can not be negated") + } + if arg.Count == 0 { + return errors.New("count == 0 not allowed with a channel filter") + } + if arg.EvalScope == nil { + return errors.New("channel filter without eval scope") + } + gs, err = s.debugger.ChanGoroutines(arg.EvalScope.GoroutineID, arg.EvalScope.Frame, arg.EvalScope.DeferredCall, filter.Arg, arg.Start, arg.Count) + if len(gs) == arg.Count { + nextg = arg.Start + len(gs) + } else { + nextg = -1 + } + gsLoaded = true + break + } + } + + if !gsLoaded { + gs, nextg, err = s.debugger.Goroutines(arg.Start, arg.Count) + } if err != nil { return err } diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go index 6aaa938ea2..2d7f64f77f 100644 --- a/service/test/integration2_test.go +++ b/service/test/integration2_test.go @@ -2577,7 +2577,7 @@ func TestGoroutinesGrouping(t *testing.T) { withTestClient2("goroutinegroup", t, func(c service.Client) { state := <-c.Continue() assertNoError(state.Err, t, "Continue") - _, ggrp, _, _, err := c.ListGoroutinesWithFilter(0, 0, nil, &api.GoroutineGroupingOptions{GroupBy: api.GoroutineLabel, GroupByKey: "name", MaxGroupMembers: 5, MaxGroups: 10}) + _, ggrp, _, _, err := c.ListGoroutinesWithFilter(0, 0, nil, &api.GoroutineGroupingOptions{GroupBy: api.GoroutineLabel, GroupByKey: "name", MaxGroupMembers: 5, MaxGroups: 10}, nil) assertNoError(err, t, "ListGoroutinesWithFilter (group by label)") t.Logf("%#v\n", ggrp) if len(ggrp) < 5 { @@ -2590,7 +2590,7 @@ func TestGoroutinesGrouping(t *testing.T) { break } } - gs, _, _, _, err := c.ListGoroutinesWithFilter(0, 0, []api.ListGoroutinesFilter{{Kind: api.GoroutineLabel, Arg: "name="}}, nil) + gs, _, _, _, err := c.ListGoroutinesWithFilter(0, 0, []api.ListGoroutinesFilter{{Kind: api.GoroutineLabel, Arg: "name="}}, nil, nil) assertNoError(err, t, "ListGoroutinesWithFilter (filter unnamed)") if len(gs) != unnamedCount { t.Errorf("wrong number of goroutines returned by filter: %d (expected %d)\n", len(gs), unnamedCount) @@ -3031,3 +3031,70 @@ func TestClientServer_breakpointOnFuncWithABIWrapper(t *testing.T) { } }) } + +var waitReasonStrings = [...]string{ + "", + "GC assist marking", + "IO wait", + "chan receive (nil chan)", + "chan send (nil chan)", + "dumping heap", + "garbage collection", + "garbage collection scan", + "panicwait", + "select", + "select (no cases)", + "GC assist wait", + "GC sweep wait", + "GC scavenge wait", + "chan receive", + "chan send", + "finalizer wait", + "force gc (idle)", + "semacquire", + "sleep", + "sync.Cond.Wait", + "timer goroutine (idle)", + "trace reader (blocked)", + "wait for GC cycle", + "GC worker (idle)", + "preempted", + "debug call", +} + +func TestClientServer_chanGoroutines(t *testing.T) { + protest.AllowRecording(t) + withTestClient2("changoroutines", t, func(c service.Client) { + state := <-c.Continue() + assertNoError(state.Err, t, "Continue()") + + countRecvSend := func(gs []*api.Goroutine) (recvq, sendq int) { + for _, g := range gs { + t.Logf("\tID: %d WaitReason: %s\n", g.ID, waitReasonStrings[g.WaitReason]) + switch waitReasonStrings[g.WaitReason] { + case "chan send": + sendq++ + case "chan receive": + recvq++ + } + } + return + } + + gs, _, _, _, err := c.ListGoroutinesWithFilter(0, 100, []api.ListGoroutinesFilter{{Kind: api.GoroutineWaitingOnChannel, Arg: "blockingchan1"}}, nil, &api.EvalScope{GoroutineID: -1}) + assertNoError(err, t, "ListGoroutinesWithFilter(blockingchan1)") + t.Logf("blockingchan1 gs:") + recvq, sendq := countRecvSend(gs) + if len(gs) != 2 || recvq != 0 || sendq != 2 { + t.Error("wrong number of goroutines for blockingchan1") + } + + gs, _, _, _, err = c.ListGoroutinesWithFilter(0, 100, []api.ListGoroutinesFilter{{Kind: api.GoroutineWaitingOnChannel, Arg: "blockingchan2"}}, nil, &api.EvalScope{GoroutineID: -1}) + assertNoError(err, t, "ListGoroutinesWithFilter(blockingchan2)") + t.Logf("blockingchan2 gs:") + recvq, sendq = countRecvSend(gs) + if len(gs) != 1 || recvq != 1 || sendq != 0 { + t.Error("wrong number of goroutines for blockingchan2") + } + }) +} From 7f094c81e9fe4c83a218a6de73a2a63e99faa4f3 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 28 Aug 2023 21:46:19 +0200 Subject: [PATCH 110/114] proc: refactorings to implement follow-exec mode on Windows (#3441) Miscellaneous non-functional changes to prepare for adding support for follow-exec mode on Windows: - removed (*nativeProcess).wait function from Windows backend (unused). - move close of ptraceDoneChan from release to handlePtraceFuncs, this makes postExit callable by a function executed by execPtraceFunc. - change addTarget to detach before creating the target object if we don't actually want to attach to the child process, also moved the detach call to (*processGroup).add instead of having one in addTarget and one in the code that calls (*processGroup).add. - changed Detach to be a method of TargetGroup/ProcessGroup, the Windows backend will need access to the process group to call WaitForDebugEvent. - moved resume method to processGroup. First all threads stopped at a breakpoint need to be stepped, then all other threads can be resumed. This is true also for linux even though it didn't cause the current tests to fail. --- pkg/proc/core/core.go | 2 +- pkg/proc/gdbserial/gdbserver.go | 6 ++-- pkg/proc/interface.go | 2 +- pkg/proc/native/nonative_darwin.go | 4 +-- pkg/proc/native/proc.go | 48 ++++++++++++++++++++++-------- pkg/proc/native/proc_darwin.go | 10 +++++-- pkg/proc/native/proc_freebsd.go | 9 +++--- pkg/proc/native/proc_linux.go | 33 ++++++++++++-------- pkg/proc/native/proc_windows.go | 13 ++++---- pkg/proc/target.go | 22 -------------- pkg/proc/target_group.go | 41 ++++++++++++++++++++----- 11 files changed, 114 insertions(+), 76 deletions(-) diff --git a/pkg/proc/core/core.go b/pkg/proc/core/core.go index d69f83a430..2156d10eff 100644 --- a/pkg/proc/core/core.go +++ b/pkg/proc/core/core.go @@ -454,7 +454,7 @@ func (p *process) Memory() proc.MemoryReadWriter { // Detach will always return nil and have no // effect as you cannot detach from a core file // and have it continue execution or exit. -func (p *process) Detach(bool) error { +func (p *process) Detach(int, bool) error { return nil } diff --git a/pkg/proc/gdbserial/gdbserver.go b/pkg/proc/gdbserial/gdbserver.go index 99650f7f16..5648f77c20 100644 --- a/pkg/proc/gdbserial/gdbserver.go +++ b/pkg/proc/gdbserial/gdbserver.go @@ -749,7 +749,7 @@ func (p *gdbProcess) initialize(path, cmdline string, debugInfoDirs []string, st }) _, err = addTarget(p, p.conn.pid, p.currentThread, path, stopReason, cmdline) if err != nil { - p.Detach(true) + p.Detach(p.conn.pid, true) return nil, err } return grp, nil @@ -1059,7 +1059,9 @@ func (p *gdbProcess) getCtrlC(cctx *proc.ContinueOnceContext) bool { // Detach will detach from the target process, // if 'kill' is true it will also kill the process. -func (p *gdbProcess) Detach(kill bool) error { +// The _pid argument is unused as follow exec +// mode is not implemented with this backend. +func (p *gdbProcess) Detach(_pid int, kill bool) error { if kill && !p.exited { err := p.conn.kill() if err != nil { diff --git a/pkg/proc/interface.go b/pkg/proc/interface.go index 84bd80ab1c..2114f1aac7 100644 --- a/pkg/proc/interface.go +++ b/pkg/proc/interface.go @@ -11,6 +11,7 @@ import ( // ProcessGroup is a group of processes that are resumed at the same time. type ProcessGroup interface { ContinueOnce(*ContinueOnceContext) (Thread, StopReason, error) + Detach(int, bool) error } // Process represents the target of the debugger. This @@ -43,7 +44,6 @@ type ProcessInternal interface { // also returns an error describing why the Process is invalid (either // ErrProcessExited or ErrProcessDetached). Valid() (bool, error) - Detach(bool) error // RequestManualStop attempts to stop all the process' threads. RequestManualStop(cctx *ContinueOnceContext) error diff --git a/pkg/proc/native/nonative_darwin.go b/pkg/proc/native/nonative_darwin.go index 0fa7be5275..3a20b9289e 100644 --- a/pkg/proc/native/nonative_darwin.go +++ b/pkg/proc/native/nonative_darwin.go @@ -57,7 +57,7 @@ func (dbp *nativeProcess) requestManualStop() (err error) { panic(ErrNativeBackendDisabled) } -func (dbp *nativeProcess) resume() error { +func (*processGroup) resume() error { panic(ErrNativeBackendDisabled) } @@ -73,7 +73,7 @@ func (dbp *nativeProcess) updateThreadList() error { panic(ErrNativeBackendDisabled) } -func (dbp *nativeProcess) kill() (err error) { +func (*processGroup) kill(dbp *nativeProcess) (err error) { panic(ErrNativeBackendDisabled) } diff --git a/pkg/proc/native/proc.go b/pkg/proc/native/proc.go index aeb4b23f85..a73ef590f5 100644 --- a/pkg/proc/native/proc.go +++ b/pkg/proc/native/proc.go @@ -96,17 +96,24 @@ func (dbp *nativeProcess) BinInfo() *proc.BinaryInfo { // StartCallInjection notifies the backend that we are about to inject a function call. func (dbp *nativeProcess) StartCallInjection() (func(), error) { return func() {}, nil } +// detachWithoutGroup is a helper function to detach from a process which we +// haven't added to a process group yet. +func detachWithoutGroup(dbp *nativeProcess, kill bool) error { + grp := &processGroup{procs: []*nativeProcess{dbp}} + return grp.Detach(dbp.pid, kill) +} + // Detach from the process being debugged, optionally killing it. -func (dbp *nativeProcess) Detach(kill bool) (err error) { +func (procgrp *processGroup) Detach(pid int, kill bool) (err error) { + dbp := procgrp.procForPid(pid) if dbp.exited { return nil } if kill && dbp.childProcess { - err := dbp.kill() + err := procgrp.kill(dbp) if err != nil { return err } - dbp.bi.Close() return nil } dbp.execPtraceFunc(func() { @@ -226,8 +233,25 @@ func (procgrp *processGroup) procForThread(tid int) *nativeProcess { return nil } +func (procgrp *processGroup) procForPid(pid int) *nativeProcess { + for _, p := range procgrp.procs { + if p.pid == pid { + return p + } + } + return nil +} + func (procgrp *processGroup) add(p *nativeProcess, pid int, currentThread proc.Thread, path string, stopReason proc.StopReason, cmdline string) (*proc.Target, error) { tgt, err := procgrp.addTarget(p, pid, currentThread, path, stopReason, cmdline) + if tgt == nil { + i := len(procgrp.procs) + procgrp.procs = append(procgrp.procs, p) + procgrp.Detach(p.pid, false) + if i == len(procgrp.procs)-1 { + procgrp.procs = procgrp.procs[:i] + } + } if err != nil { return nil, err } @@ -246,15 +270,15 @@ func (procgrp *processGroup) ContinueOnce(cctx *proc.ContinueOnceContext) (proc. } for { + err := procgrp.resume() + if err != nil { + return nil, proc.StopUnknown, err + } for _, dbp := range procgrp.procs { - if dbp.exited { - continue - } - if err := dbp.resume(); err != nil { - return nil, proc.StopUnknown, err - } - for _, th := range dbp.threads { - th.CurrentBreakpoint.Clear() + if valid, _ := dbp.Valid(); valid { + for _, th := range dbp.threads { + th.CurrentBreakpoint.Clear() + } } } @@ -377,6 +401,7 @@ func (pt *ptraceThread) handlePtraceFuncs() { fn() pt.ptraceDoneChan <- nil } + close(pt.ptraceDoneChan) } func (dbp *nativeProcess) execPtraceFunc(fn func()) { @@ -473,6 +498,5 @@ func (pt *ptraceThread) release() { pt.ptraceRefCnt-- if pt.ptraceRefCnt == 0 { close(pt.ptraceChan) - close(pt.ptraceDoneChan) } } diff --git a/pkg/proc/native/proc_darwin.go b/pkg/proc/native/proc_darwin.go index 6332734487..1e2fe3d726 100644 --- a/pkg/proc/native/proc_darwin.go +++ b/pkg/proc/native/proc_darwin.go @@ -71,7 +71,7 @@ func Launch(cmd []string, wd string, flags proc.LaunchFlags, _ []string, _ strin dbp := newProcess(0) defer func() { if err != nil && dbp.pid != 0 { - _ = dbp.Detach(true) + _ = detachWithoutGroup(dbp, true) } }() var pid int @@ -172,14 +172,14 @@ func Attach(pid int, waitFor *proc.WaitFor, _ []string) (*proc.TargetGroup, erro tgt, err := dbp.initialize("", []string{}) if err != nil { - dbp.Detach(false) + detachWithoutGroup(dbp, false) return nil, err } return tgt, nil } // Kill kills the process. -func (dbp *nativeProcess) kill() (err error) { +func (procgrp *processGroup) kill(dbp *nativeProcess) (err error) { if dbp.exited { return nil } @@ -420,6 +420,10 @@ func (dbp *nativeProcess) exitGuard(err error) error { return err } +func (procgrp *processGroup) resume() error { + return procgrp.procs[0].resume() +} + func (dbp *nativeProcess) resume() error { // all threads stopped over a breakpoint are made to step over it for _, thread := range dbp.threads { diff --git a/pkg/proc/native/proc_freebsd.go b/pkg/proc/native/proc_freebsd.go index 2d04b92f04..f1b740b87f 100644 --- a/pkg/proc/native/proc_freebsd.go +++ b/pkg/proc/native/proc_freebsd.go @@ -79,7 +79,7 @@ func Launch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs []str dbp := newProcess(0) defer func() { if err != nil && dbp.pid != 0 { - _ = dbp.Detach(true) + _ = detachWithoutGroup(dbp, true) } }() dbp.execPtraceFunc(func() { @@ -146,7 +146,7 @@ func Attach(pid int, waitFor *proc.WaitFor, debugInfoDirs []string) (*proc.Targe tgt, err := dbp.initialize(findExecutable("", dbp.pid), debugInfoDirs) if err != nil { - dbp.Detach(false) + detachWithoutGroup(dbp, false) return nil, err } return tgt, nil @@ -186,7 +186,7 @@ func initialize(dbp *nativeProcess) (string, error) { } // kill kills the target process. -func (dbp *nativeProcess) kill() (err error) { +func (procgrp *processGroup) kill(dbp *nativeProcess) (err error) { if dbp.exited { return nil } @@ -425,7 +425,8 @@ func (dbp *nativeProcess) exitGuard(err error) error { } // Used by ContinueOnce -func (dbp *nativeProcess) resume() error { +func (procgrp *processGroup) resume() error { + dbp := procgrp.procs[0] // all threads stopped over a breakpoint are made to step over it for _, thread := range dbp.threads { if thread.CurrentBreakpoint.Breakpoint != nil { diff --git a/pkg/proc/native/proc_linux.go b/pkg/proc/native/proc_linux.go index 30a90d2682..1f9201551c 100644 --- a/pkg/proc/native/proc_linux.go +++ b/pkg/proc/native/proc_linux.go @@ -85,7 +85,7 @@ func Launch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs []str dbp := newProcess(0) defer func() { if err != nil && dbp.pid != 0 { - _ = dbp.Detach(true) + _ = detachWithoutGroup(dbp, true) } }() dbp.execPtraceFunc(func() { @@ -165,7 +165,7 @@ func Attach(pid int, waitFor *proc.WaitFor, debugInfoDirs []string) (*proc.Targe tgt, err := dbp.initialize(findExecutable("", dbp.pid), debugInfoDirs) if err != nil { - _ = dbp.Detach(false) + _ = detachWithoutGroup(dbp, false) return nil, err } @@ -261,7 +261,7 @@ func (dbp *nativeProcess) GetBufferedTracepoints() []ebpf.RawUProbeParams { } // kill kills the target process. -func (dbp *nativeProcess) kill() error { +func (procgrp *processGroup) kill(dbp *nativeProcess) error { if dbp.exited { return nil } @@ -519,7 +519,6 @@ func trapWaitInternal(procgrp *processGroup, pid int, options trapWaitOptions) ( cmdline, _ := dbp.initializeBasic() tgt, err := procgrp.add(dbp, dbp.pid, dbp.memthread, findExecutable("", dbp.pid), proc.StopLaunched, cmdline) if err != nil { - _ = dbp.Detach(false) return nil, err } if halt { @@ -648,20 +647,28 @@ func exitGuard(dbp *nativeProcess, procgrp *processGroup, err error) error { return err } -func (dbp *nativeProcess) resume() error { +func (procgrp *processGroup) resume() error { // all threads stopped over a breakpoint are made to step over it - for _, thread := range dbp.threads { - if thread.CurrentBreakpoint.Breakpoint != nil { - if err := thread.StepInstruction(); err != nil { - return err + for _, dbp := range procgrp.procs { + if valid, _ := dbp.Valid(); valid { + for _, thread := range dbp.threads { + if thread.CurrentBreakpoint.Breakpoint != nil { + if err := thread.StepInstruction(); err != nil { + return err + } + thread.CurrentBreakpoint.Clear() + } } - thread.CurrentBreakpoint.Clear() } } // everything is resumed - for _, thread := range dbp.threads { - if err := thread.resume(); err != nil && err != sys.ESRCH { - return err + for _, dbp := range procgrp.procs { + if valid, _ := dbp.Valid(); valid { + for _, thread := range dbp.threads { + if err := thread.resume(); err != nil && err != sys.ESRCH { + return err + } + } } } return nil diff --git a/pkg/proc/native/proc_windows.go b/pkg/proc/native/proc_windows.go index 73e4a7a4f9..923390b29a 100644 --- a/pkg/proc/native/proc_windows.go +++ b/pkg/proc/native/proc_windows.go @@ -65,7 +65,7 @@ func Launch(cmd []string, wd string, flags proc.LaunchFlags, _ []string, _ strin tgt, err := dbp.initialize(argv0Go, []string{}) if err != nil { - dbp.Detach(true) + detachWithoutGroup(dbp, true) return nil, err } return tgt, nil @@ -183,7 +183,7 @@ func Attach(pid int, waitFor *proc.WaitFor, _ []string) (*proc.TargetGroup, erro } tgt, err := dbp.initialize(exepath, []string{}) if err != nil { - dbp.Detach(true) + detachWithoutGroup(dbp, true) return nil, err } return tgt, nil @@ -261,7 +261,7 @@ func waitForSearchProcess(pfx string, seen map[int]struct{}) (int, error) { } // kill kills the process. -func (dbp *nativeProcess) kill() error { +func (procgrp *processGroup) kill(dbp *nativeProcess) error { if dbp.exited { return nil } @@ -496,15 +496,12 @@ func trapWait(procgrp *processGroup, pid int) (*nativeThread, error) { return th, nil } -func (dbp *nativeProcess) wait(pid, options int) (int, *sys.WaitStatus, error) { - return 0, nil, fmt.Errorf("not implemented: wait") -} - func (dbp *nativeProcess) exitGuard(err error) error { return err } -func (dbp *nativeProcess) resume() error { +func (procgrp *processGroup) resume() error { + dbp := procgrp.procs[0] for _, thread := range dbp.threads { if thread.CurrentBreakpoint.Breakpoint != nil { if err := thread.StepInstruction(); err != nil { diff --git a/pkg/proc/target.go b/pkg/proc/target.go index 49953bbb52..4aec306b43 100644 --- a/pkg/proc/target.go +++ b/pkg/proc/target.go @@ -323,28 +323,6 @@ func (t *Target) SwitchThread(tid int) error { return fmt.Errorf("thread %d does not exist", tid) } -// detach will detach the target from the underlying process. -// This means the debugger will no longer receive events from the process -// we were previously debugging. -// If kill is true then the process will be killed when we detach. -func (t *Target) detach(kill bool) error { - if !kill { - if t.asyncPreemptChanged { - setAsyncPreemptOff(t, t.asyncPreemptOff) - } - for _, bp := range t.Breakpoints().M { - if bp != nil { - err := t.ClearBreakpoint(bp.Addr) - if err != nil { - return err - } - } - } - } - t.StopReason = StopUnknown - return t.proc.Detach(kill) -} - // setAsyncPreemptOff enables or disables async goroutine preemption by // writing the value 'v' to runtime.debug.asyncpreemptoff. // A value of '1' means off, a value of '0' means on. diff --git a/pkg/proc/target_group.go b/pkg/proc/target_group.go index e388310c3c..b391986d12 100644 --- a/pkg/proc/target_group.go +++ b/pkg/proc/target_group.go @@ -97,18 +97,21 @@ func Restart(grp, oldgrp *TargetGroup, discard func(*LogicalBreakpoint, error)) func (grp *TargetGroup) addTarget(p ProcessInternal, pid int, currentThread Thread, path string, stopReason StopReason, cmdline string) (*Target, error) { logger := logflags.DebuggerLogger() + if len(grp.targets) > 0 { + if !grp.followExecEnabled { + logger.Debugf("Detaching from child target (follow-exec disabled) %d %q", pid, cmdline) + return nil, nil + } + if grp.followExecRegex != nil && !grp.followExecRegex.MatchString(cmdline) { + logger.Debugf("Detaching from child target (follow-exec regex not matched) %d %q", pid, cmdline) + return nil, nil + } + } t, err := grp.newTarget(p, pid, currentThread, path, cmdline) if err != nil { return nil, err } t.StopReason = stopReason - if grp.followExecRegex != nil && len(grp.targets) > 0 { - if !grp.followExecRegex.MatchString(cmdline) { - logger.Debugf("Detaching from child target %d %q", t.Pid(), t.CmdLine) - t.detach(false) - return nil, nil - } - } logger.Debugf("Adding target %d %q", t.Pid(), t.CmdLine) if t.partOfGroup { panic("internal error: target is already part of group") @@ -178,7 +181,7 @@ func (grp *TargetGroup) Detach(kill bool) error { if !isvalid { continue } - err := t.detach(kill) + err := grp.detachTarget(t, kill) if err != nil { errs = append(errs, fmt.Sprintf("could not detach process %d: %v", t.Pid(), err)) } @@ -189,6 +192,28 @@ func (grp *TargetGroup) Detach(kill bool) error { return nil } +// detachTarget will detach the target from the underlying process. +// This means the debugger will no longer receive events from the process +// we were previously debugging. +// If kill is true then the process will be killed when we detach. +func (grp *TargetGroup) detachTarget(t *Target, kill bool) error { + if !kill { + if t.asyncPreemptChanged { + setAsyncPreemptOff(t, t.asyncPreemptOff) + } + for _, bp := range t.Breakpoints().M { + if bp != nil { + err := t.ClearBreakpoint(bp.Addr) + if err != nil { + return err + } + } + } + } + t.StopReason = StopUnknown + return grp.procgrp.Detach(t.Pid(), kill) +} + // HasSteppingBreakpoints returns true if any of the targets has stepping breakpoints set. func (grp *TargetGroup) HasSteppingBreakpoints() bool { for _, t := range grp.targets { From e404917db738f51b34250c28a9f4604ab4dc6afd Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Tue, 29 Aug 2023 15:44:18 +0300 Subject: [PATCH 111/114] pkg,service: fix typos in comments, exceptions, tests (#3486) --- cmd/dlv/dlv_test.go | 2 +- pkg/proc/proc_test.go | 2 +- pkg/proc/stack_sigtramp.go | 2 +- pkg/proc/variables.go | 2 +- pkg/terminal/starbind/conv_test.go | 2 +- service/dap/server_test.go | 2 +- service/debugger/debugger.go | 2 +- service/test/integration2_test.go | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cmd/dlv/dlv_test.go b/cmd/dlv/dlv_test.go index 4ac90563fc..550e729054 100644 --- a/cmd/dlv/dlv_test.go +++ b/cmd/dlv/dlv_test.go @@ -995,7 +995,7 @@ func TestTracePid(t *testing.T) { assertNoError(targetCmd.Start(), t, "execute issue2023") if targetCmd.Process == nil || targetCmd.Process.Pid == 0 { - t.Fatal("expected target process runninng") + t.Fatal("expected target process running") } defer targetCmd.Process.Kill() diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 968dcaa9d3..8e4010624e 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -4565,7 +4565,7 @@ func TestCallConcurrent(t *testing.T) { gid2 := p.SelectedGoroutine().ID t.Logf("starting second injection in %d / %d", p.SelectedGoroutine().ID, p.CurrentThread().ThreadID()) - assertNoError(proc.EvalExpressionWithCalls(grp, p.SelectedGoroutine(), "Foo(10, 2)", normalLoadConfig, false), t, "EvalExpressioniWithCalls") + assertNoError(proc.EvalExpressionWithCalls(grp, p.SelectedGoroutine(), "Foo(10, 2)", normalLoadConfig, false), t, "EvalExpressionWithCalls") for { returned += testCallConcurrentCheckReturns(p, t, gid1, gid2) diff --git a/pkg/proc/stack_sigtramp.go b/pkg/proc/stack_sigtramp.go index bbf0fe52bc..f66025f99d 100644 --- a/pkg/proc/stack_sigtramp.go +++ b/pkg/proc/stack_sigtramp.go @@ -102,7 +102,7 @@ func (it *stackIterator) readSigtrampgoContext() (*op.DwarfRegisters, error) { case "arm64": return sigtrampContextDarwinARM64(it.mem, addr) default: - return nil, errors.New("not implemnted") + return nil, errors.New("not implemented") } default: return nil, errors.New("not implemented") diff --git a/pkg/proc/variables.go b/pkg/proc/variables.go index c1b391ca3c..60c13f969a 100644 --- a/pkg/proc/variables.go +++ b/pkg/proc/variables.go @@ -50,7 +50,7 @@ const ( FloatIsNormal floatSpecial = iota // FloatIsNaN means the float is a special NaN value. FloatIsNaN - // FloatIsPosInf means the float is a special positive inifitiy value. + // FloatIsPosInf means the float is a special positive infinity value. FloatIsPosInf // FloatIsNegInf means the float is a special negative infinity value. FloatIsNegInf diff --git a/pkg/terminal/starbind/conv_test.go b/pkg/terminal/starbind/conv_test.go index 34c613aa29..85e3062a52 100644 --- a/pkg/terminal/starbind/conv_test.go +++ b/pkg/terminal/starbind/conv_test.go @@ -7,7 +7,7 @@ import ( func TestConv(t *testing.T) { script := ` -# A list global that we'll unmarhsal into a slice. +# A list global that we'll unmarshal into a slice. x = [1,2] ` globals, err := starlark.ExecFile(&starlark.Thread{}, "test.star", script, nil) diff --git a/service/dap/server_test.go b/service/dap/server_test.go index 7b818a6f21..26b642d733 100644 --- a/service/dap/server_test.go +++ b/service/dap/server_test.go @@ -2176,7 +2176,7 @@ func TestVariablesLoading(t *testing.T) { checkChildren(t, tm, "tm", 1) ref = checkVarExact(t, tm, 0, "v", "", "[]map[string]main.astruct len: 1, cap: 1, [[...]]", "[]map[string]main.astruct", hasChildren) if ref > 0 { - // Auto-loading of fully missing map chidlren happens here, but they get trancated at MaxArrayValuess + // Auto-loading of fully missing map chidlren happens here, but they get trancated at MaxArrayValues client.VariablesRequest(ref) tmV := client.ExpectVariablesResponse(t) checkChildren(t, tmV, "tm.v", 1) diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index 3e73621c67..291957a551 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -2248,7 +2248,7 @@ func (d *Debugger) DumpWait(wait time.Duration) *proc.DumpState { return &d.dumpState } -// DumpCancel canels a dump in progress +// DumpCancel cancels a dump in progress func (d *Debugger) DumpCancel() error { d.dumpState.Mutex.Lock() d.dumpState.Canceled = true diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go index 2d7f64f77f..fa41dbfc4b 100644 --- a/service/test/integration2_test.go +++ b/service/test/integration2_test.go @@ -2987,7 +2987,7 @@ func TestClientServer_createBreakpointWithID(t *testing.T) { } func TestClientServer_autoBreakpoints(t *testing.T) { - // Check that unrecoverd-panic and fatal-throw breakpoints are visible in + // Check that unrecovered-panic and fatal-throw breakpoints are visible in // the breakpoint list. protest.AllowRecording(t) withTestClient2("math", t, func(c service.Client) { From 7fb9ddae4d6520acab87abff9ecaa9dbdf3330f6 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 29 Aug 2023 18:24:10 +0200 Subject: [PATCH 112/114] api,dap: fix hexadecimal printing of vars with symbolic const values (#3487) Fix hexadecimal printing of variables that can be represented using symbolic const values in DAP as well as the command line interface. Fixes #3485 --- pkg/proc/variables_test.go | 25 +++++++++++++++---------- service/api/prettyprint.go | 15 +++++++++++++-- service/dap/server.go | 2 +- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go index d074ee1fdf..df57f29f95 100644 --- a/pkg/proc/variables_test.go +++ b/pkg/proc/variables_test.go @@ -1104,16 +1104,16 @@ func TestPackageRenames(t *testing.T) { func TestConstants(t *testing.T) { testcases := []varTest{ - {"a", true, "constTwo (2)", "", "main.ConstType", nil}, - {"b", true, "constThree (3)", "", "main.ConstType", nil}, - {"c", true, "bitZero|bitOne (3)", "", "main.BitFieldType", nil}, - {"d", true, "33", "", "main.BitFieldType", nil}, - {"e", true, "10", "", "main.ConstType", nil}, - {"f", true, "0", "", "main.BitFieldType", nil}, - {"bitZero", true, "1", "", "main.BitFieldType", nil}, - {"bitOne", true, "2", "", "main.BitFieldType", nil}, - {"constTwo", true, "2", "", "main.ConstType", nil}, - {"pkg.SomeConst", false, "2", "", "int", nil}, + {"a", true, "constTwo (2)", "0x2", "main.ConstType", nil}, + {"b", true, "constThree (3)", "0x3", "main.ConstType", nil}, + {"c", true, "bitZero|bitOne (3)", "0x3", "main.BitFieldType", nil}, + {"d", true, "33", "0x21", "main.BitFieldType", nil}, + {"e", true, "10", "0xa", "main.ConstType", nil}, + {"f", true, "0", "0x0", "main.BitFieldType", nil}, + {"bitZero", true, "1", "0x1", "main.BitFieldType", nil}, + {"bitOne", true, "2", "0x2", "main.BitFieldType", nil}, + {"constTwo", true, "2", "0x2", "main.ConstType", nil}, + {"pkg.SomeConst", false, "2", "0x2", "int", nil}, } ver, _ := goversion.Parse(runtime.Version()) if ver.Major > 0 && !ver.AfterOrEqual(goversion.GoVersion{Major: 1, Minor: 10, Rev: -1}) { @@ -1126,6 +1126,11 @@ func TestConstants(t *testing.T) { variable, err := evalVariableWithCfg(p, testcase.name, pnormalLoadConfig) assertNoError(err, t, fmt.Sprintf("EvalVariable(%s)", testcase.name)) assertVariable(t, variable, testcase) + cv := api.ConvertVar(variable) + str := cv.SinglelineStringFormatted("%#x") + if str != testcase.alternate { + t.Errorf("for %s expected %q got %q when formatting in hexadecimal", testcase.name, testcase.alternate, str) + } } }) } diff --git a/service/api/prettyprint.go b/service/api/prettyprint.go index 677860ea41..a34b9c6f2d 100644 --- a/service/api/prettyprint.go +++ b/service/api/prettyprint.go @@ -173,7 +173,7 @@ func (v *Variable) writeBasicType(buf io.Writer, fmtstr string) { buf.Write([]byte(v.Value)) return } - n, _ := strconv.ParseInt(v.Value, 10, 64) + n, _ := strconv.ParseInt(ExtractIntValue(v.Value), 10, 64) fmt.Fprintf(buf, fmtstr, n) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: @@ -181,7 +181,7 @@ func (v *Variable) writeBasicType(buf io.Writer, fmtstr string) { buf.Write([]byte(v.Value)) return } - n, _ := strconv.ParseUint(v.Value, 10, 64) + n, _ := strconv.ParseUint(ExtractIntValue(v.Value), 10, 64) fmt.Fprintf(buf, fmtstr, n) case reflect.Float32, reflect.Float64: @@ -215,6 +215,17 @@ func (v *Variable) writeBasicType(buf io.Writer, fmtstr string) { } } +func ExtractIntValue(s string) string { + if s == "" || s[len(s)-1] != ')' { + return s + } + open := strings.LastIndex(s, "(") + if open < 0 { + return s + } + return s[open+1 : len(s)-1] +} + func (v *Variable) writeSliceTo(buf io.Writer, newlines, includeType bool, indent, fmtstr string) { if includeType { fmt.Fprintf(buf, "%s len: %d, cap: %d, ", v.Type, v.Len, v.Cap) diff --git a/service/dap/server.go b/service/dap/server.go index 50c409f740..5bb38f1b9b 100644 --- a/service/dap/server.go +++ b/service/dap/server.go @@ -2593,7 +2593,7 @@ func (s *Session) convertVariableWithOpts(v *proc.Variable, qualifiedNameOrExpr switch v.Kind { case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - n, _ := strconv.ParseUint(api.ConvertVar(v).Value, 10, 64) + n, _ := strconv.ParseUint(api.ExtractIntValue(api.ConvertVar(v).Value), 10, 64) value = fmt.Sprintf("%s = %#x", value, n) case reflect.UnsafePointer: // Skip child reference From f469a0a57a49a2d8846d1081814acee923bb55ec Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 30 Aug 2023 19:22:08 +0200 Subject: [PATCH 113/114] go.mod: update version of github.com/cilium/ebpf (#3491) Fixes #3490 --- go.mod | 25 +- go.sum | 42 +- pkg/proc/native/ptrace_freebsd.go | 2 +- vendor/github.com/cilium/ebpf/.clang-format | 2 + vendor/github.com/cilium/ebpf/.golangci.yaml | 4 +- vendor/github.com/cilium/ebpf/ARCHITECTURE.md | 68 +- vendor/github.com/cilium/ebpf/CONTRIBUTING.md | 26 +- vendor/github.com/cilium/ebpf/MAINTAINERS.md | 3 + vendor/github.com/cilium/ebpf/Makefile | 86 +- vendor/github.com/cilium/ebpf/README.md | 38 +- vendor/github.com/cilium/ebpf/asm/alu.go | 16 +- vendor/github.com/cilium/ebpf/asm/func.go | 67 +- .../github.com/cilium/ebpf/asm/func_string.go | 48 +- .../github.com/cilium/ebpf/asm/instruction.go | 570 ++++- vendor/github.com/cilium/ebpf/asm/jump.go | 82 +- .../github.com/cilium/ebpf/asm/load_store.go | 16 +- vendor/github.com/cilium/ebpf/asm/metadata.go | 80 + vendor/github.com/cilium/ebpf/asm/opcode.go | 132 +- .../cilium/ebpf/asm/opcode_string.go | 18 +- vendor/github.com/cilium/ebpf/asm/register.go | 8 +- .../cilium/ebpf/attachtype_string.go | 5 +- vendor/github.com/cilium/ebpf/btf/btf.go | 869 +++++++ .../ebpf/{internal => }/btf/btf_types.go | 234 +- .../{internal => }/btf/btf_types_string.go | 38 +- .../cilium/ebpf/{internal => }/btf/core.go | 585 +++-- .../cilium/ebpf/{internal => }/btf/doc.go | 3 - vendor/github.com/cilium/ebpf/btf/ext_info.go | 768 ++++++ vendor/github.com/cilium/ebpf/btf/format.go | 344 +++ vendor/github.com/cilium/ebpf/btf/handle.go | 287 +++ vendor/github.com/cilium/ebpf/btf/marshal.go | 543 ++++ vendor/github.com/cilium/ebpf/btf/strings.go | 214 ++ .../github.com/cilium/ebpf/btf/traversal.go | 141 ++ vendor/github.com/cilium/ebpf/btf/types.go | 1258 +++++++++ .../github.com/cilium/ebpf/btf/workarounds.go | 26 + vendor/github.com/cilium/ebpf/collection.go | 463 ++-- vendor/github.com/cilium/ebpf/doc.go | 9 + vendor/github.com/cilium/ebpf/elf_reader.go | 823 +++--- .../github.com/cilium/ebpf/elf_reader_fuzz.go | 22 - vendor/github.com/cilium/ebpf/go.mod | 9 - vendor/github.com/cilium/ebpf/go.sum | 13 - vendor/github.com/cilium/ebpf/info.go | 210 +- .../github.com/cilium/ebpf/internal/align.go | 6 +- .../cilium/ebpf/internal/btf/btf.go | 798 ------ .../cilium/ebpf/internal/btf/ext_info.go | 312 --- .../cilium/ebpf/internal/btf/fuzz.go | 50 - .../cilium/ebpf/internal/btf/info.go | 48 - .../cilium/ebpf/internal/btf/strings.go | 54 - .../cilium/ebpf/internal/btf/syscalls.go | 31 - .../cilium/ebpf/internal/btf/types.go | 957 ------- .../github.com/cilium/ebpf/internal/buffer.go | 31 + vendor/github.com/cilium/ebpf/internal/cpu.go | 17 +- .../github.com/cilium/ebpf/internal/deque.go | 91 + vendor/github.com/cilium/ebpf/internal/elf.go | 34 + .../github.com/cilium/ebpf/internal/endian.go | 29 - .../cilium/ebpf/internal/endian_be.go | 12 + .../cilium/ebpf/internal/endian_le.go | 12 + .../cilium/ebpf/internal/epoll/poller.go | 225 ++ .../github.com/cilium/ebpf/internal/errors.go | 195 +- vendor/github.com/cilium/ebpf/internal/fd.go | 69 - .../cilium/ebpf/internal/feature.go | 178 +- vendor/github.com/cilium/ebpf/internal/io.go | 114 +- .../cilium/ebpf/internal/kconfig/kconfig.go | 267 ++ .../cilium/ebpf/internal/memoize.go | 26 + .../github.com/cilium/ebpf/internal/output.go | 97 + .../cilium/ebpf/internal/pinning.go | 31 +- .../cilium/ebpf/internal/platform.go | 43 + .../github.com/cilium/ebpf/internal/prog.go | 11 + vendor/github.com/cilium/ebpf/internal/ptr.go | 31 - .../github.com/cilium/ebpf/internal/statfs.go | 23 + .../cilium/ebpf/internal/sys/doc.go | 6 + .../github.com/cilium/ebpf/internal/sys/fd.go | 133 + .../cilium/ebpf/internal/sys/fd_trace.go | 93 + .../ebpf/internal/sys/mapflags_string.go | 49 + .../cilium/ebpf/internal/sys/ptr.go | 52 + .../ebpf/internal/{ => sys}/ptr_32_be.go | 3 +- .../ebpf/internal/{ => sys}/ptr_32_le.go | 3 +- .../cilium/ebpf/internal/{ => sys}/ptr_64.go | 3 +- .../cilium/ebpf/internal/sys/signals.go | 83 + .../cilium/ebpf/internal/sys/syscall.go | 178 ++ .../cilium/ebpf/internal/sys/types.go | 1117 ++++++++ .../cilium/ebpf/internal/syscall.go | 304 --- .../cilium/ebpf/internal/syscall_string.go | 56 - .../cilium/ebpf/internal/tracefs/kprobe.go | 359 +++ .../ebpf/internal/tracefs/probetype_string.go | 24 + .../cilium/ebpf/internal/tracefs/uprobe.go | 16 + .../cilium/ebpf/internal/unix/doc.go | 11 + .../cilium/ebpf/internal/unix/types_linux.go | 202 +- .../cilium/ebpf/internal/unix/types_other.go | 201 +- .../github.com/cilium/ebpf/internal/vdso.go | 153 ++ .../cilium/ebpf/internal/version.go | 105 +- vendor/github.com/cilium/ebpf/link/cgroup.go | 71 +- .../github.com/cilium/ebpf/link/freplace.go | 88 - vendor/github.com/cilium/ebpf/link/iter.go | 39 +- vendor/github.com/cilium/ebpf/link/kprobe.go | 463 ++-- .../cilium/ebpf/link/kprobe_multi.go | 180 ++ vendor/github.com/cilium/ebpf/link/link.go | 245 +- vendor/github.com/cilium/ebpf/link/netns.go | 28 +- .../github.com/cilium/ebpf/link/perf_event.go | 298 ++- .../github.com/cilium/ebpf/link/platform.go | 25 - vendor/github.com/cilium/ebpf/link/program.go | 10 +- vendor/github.com/cilium/ebpf/link/query.go | 63 + .../cilium/ebpf/link/raw_tracepoint.go | 60 +- .../cilium/ebpf/link/socket_filter.go | 40 + .../github.com/cilium/ebpf/link/syscalls.go | 144 +- .../github.com/cilium/ebpf/link/tracepoint.go | 38 +- vendor/github.com/cilium/ebpf/link/tracing.go | 199 ++ vendor/github.com/cilium/ebpf/link/uprobe.go | 238 +- vendor/github.com/cilium/ebpf/link/xdp.go | 54 + vendor/github.com/cilium/ebpf/linker.go | 422 +++- vendor/github.com/cilium/ebpf/map.go | 653 +++-- vendor/github.com/cilium/ebpf/marshalers.go | 42 +- vendor/github.com/cilium/ebpf/prog.go | 841 +++--- .../github.com/cilium/ebpf/ringbuf/reader.go | 228 +- .../github.com/cilium/ebpf/rlimit/rlimit.go | 16 +- vendor/github.com/cilium/ebpf/run-tests.sh | 97 +- vendor/github.com/cilium/ebpf/syscalls.go | 413 +-- vendor/github.com/cilium/ebpf/types.go | 39 +- vendor/github.com/cilium/ebpf/types_string.go | 11 +- vendor/github.com/cosiner/argv/go.mod | 3 - vendor/github.com/creack/pty/go.mod | 4 - vendor/github.com/derekparker/trie/go.mod | 3 - vendor/github.com/go-delve/liner/go.mod | 6 - vendor/github.com/go-delve/liner/go.sum | 4 - vendor/github.com/google/go-dap/go.mod | 5 - .../github.com/google/go-dap/schematypes.go | 1 - .../go-windows-terminal-sequences/go.mod | 1 - vendor/github.com/mattn/go-runewidth/go.mod | 5 - vendor/github.com/mattn/go-runewidth/go.sum | 2 - vendor/github.com/rivo/uniseg/go.mod | 3 - .../github.com/russross/blackfriday/v2/go.mod | 1 - .../shurcooL/sanitized_anchor_name/go.mod | 1 - vendor/github.com/sirupsen/logrus/go.mod | 11 - vendor/github.com/sirupsen/logrus/go.sum | 12 - vendor/github.com/spf13/cobra/go.mod | 12 - vendor/github.com/spf13/cobra/go.sum | 313 --- vendor/github.com/spf13/pflag/go.mod | 3 - vendor/github.com/spf13/pflag/go.sum | 0 vendor/golang.org/x/exp/LICENSE | 27 + vendor/golang.org/x/exp/PATENTS | 22 + .../x/exp/constraints/constraints.go | 50 + vendor/golang.org/x/exp/maps/maps.go | 94 + vendor/golang.org/x/exp/slices/slices.go | 258 ++ vendor/golang.org/x/exp/slices/sort.go | 126 + vendor/golang.org/x/exp/slices/zsortfunc.go | 479 ++++ .../golang.org/x/exp/slices/zsortordered.go | 481 ++++ vendor/golang.org/x/sys/execabs/execabs.go | 2 +- .../golang.org/x/sys/execabs/execabs_go118.go | 6 + .../golang.org/x/sys/execabs/execabs_go119.go | 12 +- vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s | 31 + vendor/golang.org/x/sys/unix/dirent.go | 4 +- vendor/golang.org/x/sys/unix/gccgo.go | 4 +- vendor/golang.org/x/sys/unix/gccgo_c.c | 4 +- vendor/golang.org/x/sys/unix/ioctl.go | 21 +- vendor/golang.org/x/sys/unix/ioctl_zos.go | 8 +- vendor/golang.org/x/sys/unix/mkall.sh | 27 +- vendor/golang.org/x/sys/unix/mkerrors.sh | 4 +- vendor/golang.org/x/sys/unix/ptrace_darwin.go | 6 + vendor/golang.org/x/sys/unix/ptrace_ios.go | 6 + vendor/golang.org/x/sys/unix/sockcmsg_unix.go | 14 + vendor/golang.org/x/sys/unix/syscall.go | 10 +- vendor/golang.org/x/sys/unix/syscall_aix.go | 5 +- vendor/golang.org/x/sys/unix/syscall_bsd.go | 3 +- .../x/sys/unix/syscall_darwin.1_12.go | 32 - .../x/sys/unix/syscall_darwin.1_13.go | 108 - .../golang.org/x/sys/unix/syscall_darwin.go | 103 +- .../x/sys/unix/syscall_darwin_amd64.go | 1 + .../x/sys/unix/syscall_darwin_arm64.go | 1 + .../x/sys/unix/syscall_dragonfly.go | 2 + .../golang.org/x/sys/unix/syscall_freebsd.go | 44 +- .../x/sys/unix/syscall_freebsd_386.go | 12 +- .../x/sys/unix/syscall_freebsd_amd64.go | 12 +- .../x/sys/unix/syscall_freebsd_arm.go | 10 +- .../x/sys/unix/syscall_freebsd_arm64.go | 10 +- .../x/sys/unix/syscall_freebsd_riscv64.go | 10 +- vendor/golang.org/x/sys/unix/syscall_hurd.go | 30 + .../golang.org/x/sys/unix/syscall_hurd_386.go | 29 + .../golang.org/x/sys/unix/syscall_illumos.go | 106 - vendor/golang.org/x/sys/unix/syscall_linux.go | 101 +- .../golang.org/x/sys/unix/syscall_netbsd.go | 20 +- .../golang.org/x/sys/unix/syscall_openbsd.go | 2 + .../x/sys/unix/syscall_openbsd_libc.go | 4 +- .../x/sys/unix/syscall_openbsd_ppc64.go | 42 + .../x/sys/unix/syscall_openbsd_riscv64.go | 42 + .../golang.org/x/sys/unix/syscall_solaris.go | 120 +- vendor/golang.org/x/sys/unix/syscall_unix.go | 77 +- .../golang.org/x/sys/unix/syscall_unix_gc.go | 6 +- .../x/sys/unix/syscall_zos_s390x.go | 177 +- vendor/golang.org/x/sys/unix/sysvshm_unix.go | 13 +- vendor/golang.org/x/sys/unix/timestruct.go | 2 +- vendor/golang.org/x/sys/unix/xattr_bsd.go | 104 +- vendor/golang.org/x/sys/unix/zerrors_linux.go | 40 +- .../x/sys/unix/zerrors_linux_386.go | 1 + .../x/sys/unix/zerrors_linux_amd64.go | 1 + .../x/sys/unix/zerrors_linux_arm.go | 1 + .../x/sys/unix/zerrors_linux_arm64.go | 1 + .../x/sys/unix/zerrors_linux_loong64.go | 1 + .../x/sys/unix/zerrors_linux_mips.go | 1 + .../x/sys/unix/zerrors_linux_mips64.go | 1 + .../x/sys/unix/zerrors_linux_mips64le.go | 1 + .../x/sys/unix/zerrors_linux_mipsle.go | 1 + .../x/sys/unix/zerrors_linux_ppc.go | 1 + .../x/sys/unix/zerrors_linux_ppc64.go | 1 + .../x/sys/unix/zerrors_linux_ppc64le.go | 1 + .../x/sys/unix/zerrors_linux_riscv64.go | 1 + .../x/sys/unix/zerrors_linux_s390x.go | 1 + .../x/sys/unix/zerrors_linux_sparc64.go | 1 + .../x/sys/unix/zerrors_openbsd_386.go | 356 ++- .../x/sys/unix/zerrors_openbsd_amd64.go | 189 +- .../x/sys/unix/zerrors_openbsd_arm.go | 348 ++- .../x/sys/unix/zerrors_openbsd_arm64.go | 160 +- .../x/sys/unix/zerrors_openbsd_mips64.go | 95 +- .../x/sys/unix/zerrors_openbsd_ppc64.go | 1905 ++++++++++++++ .../x/sys/unix/zerrors_openbsd_riscv64.go | 1904 ++++++++++++++ .../x/sys/unix/zptrace_armnn_linux.go | 8 +- .../x/sys/unix/zptrace_linux_arm64.go | 4 +- .../x/sys/unix/zptrace_mipsnn_linux.go | 8 +- .../x/sys/unix/zptrace_mipsnnle_linux.go | 8 +- .../x/sys/unix/zptrace_x86_linux.go | 8 +- .../golang.org/x/sys/unix/zsyscall_aix_ppc.go | 10 + .../x/sys/unix/zsyscall_aix_ppc64.go | 10 + .../x/sys/unix/zsyscall_aix_ppc64_gc.go | 7 + .../x/sys/unix/zsyscall_aix_ppc64_gccgo.go | 8 + .../x/sys/unix/zsyscall_darwin_amd64.1_13.go | 40 - .../x/sys/unix/zsyscall_darwin_amd64.1_13.s | 25 - .../x/sys/unix/zsyscall_darwin_amd64.go | 48 +- .../x/sys/unix/zsyscall_darwin_amd64.s | 21 +- .../x/sys/unix/zsyscall_darwin_arm64.1_13.go | 40 - .../x/sys/unix/zsyscall_darwin_arm64.1_13.s | 25 - .../x/sys/unix/zsyscall_darwin_arm64.go | 48 +- .../x/sys/unix/zsyscall_darwin_arm64.s | 21 +- .../x/sys/unix/zsyscall_dragonfly_amd64.go | 20 + .../x/sys/unix/zsyscall_freebsd_386.go | 30 + .../x/sys/unix/zsyscall_freebsd_amd64.go | 30 + .../x/sys/unix/zsyscall_freebsd_arm.go | 30 + .../x/sys/unix/zsyscall_freebsd_arm64.go | 30 + .../x/sys/unix/zsyscall_freebsd_riscv64.go | 30 + .../x/sys/unix/zsyscall_illumos_amd64.go | 28 +- .../golang.org/x/sys/unix/zsyscall_linux.go | 31 + .../x/sys/unix/zsyscall_netbsd_386.go | 20 + .../x/sys/unix/zsyscall_netbsd_amd64.go | 20 + .../x/sys/unix/zsyscall_netbsd_arm.go | 20 + .../x/sys/unix/zsyscall_netbsd_arm64.go | 20 + .../x/sys/unix/zsyscall_openbsd_386.go | 22 + .../x/sys/unix/zsyscall_openbsd_386.s | 137 +- .../x/sys/unix/zsyscall_openbsd_amd64.go | 22 + .../x/sys/unix/zsyscall_openbsd_amd64.s | 137 +- .../x/sys/unix/zsyscall_openbsd_arm.go | 22 + .../x/sys/unix/zsyscall_openbsd_arm.s | 137 +- .../x/sys/unix/zsyscall_openbsd_arm64.go | 22 + .../x/sys/unix/zsyscall_openbsd_arm64.s | 137 +- .../x/sys/unix/zsyscall_openbsd_mips64.go | 820 +++++- .../x/sys/unix/zsyscall_openbsd_mips64.s | 669 +++++ .../x/sys/unix/zsyscall_openbsd_ppc64.go | 2243 +++++++++++++++++ .../x/sys/unix/zsyscall_openbsd_ppc64.s | 802 ++++++ .../x/sys/unix/zsyscall_openbsd_riscv64.go | 2243 +++++++++++++++++ .../x/sys/unix/zsyscall_openbsd_riscv64.s | 669 +++++ .../x/sys/unix/zsyscall_solaris_amd64.go | 52 +- .../x/sys/unix/zsyscall_zos_s390x.go | 10 + .../x/sys/unix/zsysctl_openbsd_386.go | 51 +- .../x/sys/unix/zsysctl_openbsd_amd64.go | 17 +- .../x/sys/unix/zsysctl_openbsd_arm.go | 51 +- .../x/sys/unix/zsysctl_openbsd_arm64.go | 11 +- .../x/sys/unix/zsysctl_openbsd_mips64.go | 3 +- .../x/sys/unix/zsysctl_openbsd_ppc64.go | 281 +++ .../x/sys/unix/zsysctl_openbsd_riscv64.go | 282 +++ .../x/sys/unix/zsysnum_openbsd_mips64.go | 1 + .../x/sys/unix/zsysnum_openbsd_ppc64.go | 218 ++ .../x/sys/unix/zsysnum_openbsd_riscv64.go | 219 ++ .../x/sys/unix/ztypes_freebsd_386.go | 2 +- .../x/sys/unix/ztypes_freebsd_amd64.go | 2 +- .../x/sys/unix/ztypes_freebsd_arm.go | 2 +- .../x/sys/unix/ztypes_freebsd_arm64.go | 2 +- .../x/sys/unix/ztypes_freebsd_riscv64.go | 2 +- .../x/sys/unix/ztypes_illumos_amd64.go | 42 - vendor/golang.org/x/sys/unix/ztypes_linux.go | 349 ++- .../golang.org/x/sys/unix/ztypes_linux_386.go | 8 +- .../x/sys/unix/ztypes_linux_amd64.go | 8 +- .../golang.org/x/sys/unix/ztypes_linux_arm.go | 8 +- .../x/sys/unix/ztypes_linux_arm64.go | 8 +- .../x/sys/unix/ztypes_linux_loong64.go | 8 +- .../x/sys/unix/ztypes_linux_mips.go | 8 +- .../x/sys/unix/ztypes_linux_mips64.go | 8 +- .../x/sys/unix/ztypes_linux_mips64le.go | 8 +- .../x/sys/unix/ztypes_linux_mipsle.go | 8 +- .../golang.org/x/sys/unix/ztypes_linux_ppc.go | 8 +- .../x/sys/unix/ztypes_linux_ppc64.go | 8 +- .../x/sys/unix/ztypes_linux_ppc64le.go | 8 +- .../x/sys/unix/ztypes_linux_riscv64.go | 8 +- .../x/sys/unix/ztypes_linux_s390x.go | 8 +- .../x/sys/unix/ztypes_linux_sparc64.go | 8 +- .../x/sys/unix/ztypes_netbsd_386.go | 84 + .../x/sys/unix/ztypes_netbsd_amd64.go | 84 + .../x/sys/unix/ztypes_netbsd_arm.go | 84 + .../x/sys/unix/ztypes_netbsd_arm64.go | 84 + .../x/sys/unix/ztypes_openbsd_386.go | 97 +- .../x/sys/unix/ztypes_openbsd_amd64.go | 33 +- .../x/sys/unix/ztypes_openbsd_arm.go | 9 +- .../x/sys/unix/ztypes_openbsd_arm64.go | 9 +- .../x/sys/unix/ztypes_openbsd_mips64.go | 9 +- .../x/sys/unix/ztypes_openbsd_ppc64.go | 571 +++++ .../x/sys/unix/ztypes_openbsd_riscv64.go | 571 +++++ .../x/sys/unix/ztypes_solaris_amd64.go | 35 + .../golang.org/x/sys/unix/ztypes_zos_s390x.go | 11 +- vendor/golang.org/x/sys/windows/syscall.go | 10 +- .../x/sys/windows/syscall_windows.go | 56 +- .../golang.org/x/sys/windows/types_windows.go | 130 + .../x/sys/windows/zsyscall_windows.go | 122 + .../x/tools/go/gcexportdata/gcexportdata.go | 6 +- .../x/tools/go/internal/gcimporter/iimport.go | 4 +- .../go/internal/gcimporter/ureader_yes.go | 93 +- .../x/tools/go/internal/pkgbits/decoder.go | 5 +- .../x/tools/go/internal/pkgbits/encoder.go | 18 +- .../x/tools/go/internal/pkgbits/reloc.go | 4 +- .../golang.org/x/tools/go/packages/golist.go | 9 +- .../x/tools/go/packages/packages.go | 42 +- .../x/tools/internal/gocommand/invoke.go | 83 +- .../x/tools/internal/gocommand/version.go | 13 +- vendor/gopkg.in/yaml.v2/go.mod | 5 - vendor/modules.txt | 58 +- 319 files changed, 32713 insertions(+), 8584 deletions(-) create mode 100644 vendor/github.com/cilium/ebpf/MAINTAINERS.md create mode 100644 vendor/github.com/cilium/ebpf/asm/metadata.go create mode 100644 vendor/github.com/cilium/ebpf/btf/btf.go rename vendor/github.com/cilium/ebpf/{internal => }/btf/btf_types.go (51%) rename vendor/github.com/cilium/ebpf/{internal => }/btf/btf_types_string.go (52%) rename vendor/github.com/cilium/ebpf/{internal => }/btf/core.go (58%) rename vendor/github.com/cilium/ebpf/{internal => }/btf/doc.go (71%) create mode 100644 vendor/github.com/cilium/ebpf/btf/ext_info.go create mode 100644 vendor/github.com/cilium/ebpf/btf/format.go create mode 100644 vendor/github.com/cilium/ebpf/btf/handle.go create mode 100644 vendor/github.com/cilium/ebpf/btf/marshal.go create mode 100644 vendor/github.com/cilium/ebpf/btf/strings.go create mode 100644 vendor/github.com/cilium/ebpf/btf/traversal.go create mode 100644 vendor/github.com/cilium/ebpf/btf/types.go create mode 100644 vendor/github.com/cilium/ebpf/btf/workarounds.go delete mode 100644 vendor/github.com/cilium/ebpf/elf_reader_fuzz.go delete mode 100644 vendor/github.com/cilium/ebpf/go.mod delete mode 100644 vendor/github.com/cilium/ebpf/go.sum delete mode 100644 vendor/github.com/cilium/ebpf/internal/btf/btf.go delete mode 100644 vendor/github.com/cilium/ebpf/internal/btf/ext_info.go delete mode 100644 vendor/github.com/cilium/ebpf/internal/btf/fuzz.go delete mode 100644 vendor/github.com/cilium/ebpf/internal/btf/info.go delete mode 100644 vendor/github.com/cilium/ebpf/internal/btf/strings.go delete mode 100644 vendor/github.com/cilium/ebpf/internal/btf/syscalls.go delete mode 100644 vendor/github.com/cilium/ebpf/internal/btf/types.go create mode 100644 vendor/github.com/cilium/ebpf/internal/buffer.go create mode 100644 vendor/github.com/cilium/ebpf/internal/deque.go delete mode 100644 vendor/github.com/cilium/ebpf/internal/endian.go create mode 100644 vendor/github.com/cilium/ebpf/internal/endian_be.go create mode 100644 vendor/github.com/cilium/ebpf/internal/endian_le.go create mode 100644 vendor/github.com/cilium/ebpf/internal/epoll/poller.go delete mode 100644 vendor/github.com/cilium/ebpf/internal/fd.go create mode 100644 vendor/github.com/cilium/ebpf/internal/kconfig/kconfig.go create mode 100644 vendor/github.com/cilium/ebpf/internal/memoize.go create mode 100644 vendor/github.com/cilium/ebpf/internal/output.go create mode 100644 vendor/github.com/cilium/ebpf/internal/platform.go create mode 100644 vendor/github.com/cilium/ebpf/internal/prog.go delete mode 100644 vendor/github.com/cilium/ebpf/internal/ptr.go create mode 100644 vendor/github.com/cilium/ebpf/internal/statfs.go create mode 100644 vendor/github.com/cilium/ebpf/internal/sys/doc.go create mode 100644 vendor/github.com/cilium/ebpf/internal/sys/fd.go create mode 100644 vendor/github.com/cilium/ebpf/internal/sys/fd_trace.go create mode 100644 vendor/github.com/cilium/ebpf/internal/sys/mapflags_string.go create mode 100644 vendor/github.com/cilium/ebpf/internal/sys/ptr.go rename vendor/github.com/cilium/ebpf/internal/{ => sys}/ptr_32_be.go (81%) rename vendor/github.com/cilium/ebpf/internal/{ => sys}/ptr_32_le.go (78%) rename vendor/github.com/cilium/ebpf/internal/{ => sys}/ptr_64.go (73%) create mode 100644 vendor/github.com/cilium/ebpf/internal/sys/signals.go create mode 100644 vendor/github.com/cilium/ebpf/internal/sys/syscall.go create mode 100644 vendor/github.com/cilium/ebpf/internal/sys/types.go delete mode 100644 vendor/github.com/cilium/ebpf/internal/syscall.go delete mode 100644 vendor/github.com/cilium/ebpf/internal/syscall_string.go create mode 100644 vendor/github.com/cilium/ebpf/internal/tracefs/kprobe.go create mode 100644 vendor/github.com/cilium/ebpf/internal/tracefs/probetype_string.go create mode 100644 vendor/github.com/cilium/ebpf/internal/tracefs/uprobe.go create mode 100644 vendor/github.com/cilium/ebpf/internal/unix/doc.go create mode 100644 vendor/github.com/cilium/ebpf/internal/vdso.go delete mode 100644 vendor/github.com/cilium/ebpf/link/freplace.go create mode 100644 vendor/github.com/cilium/ebpf/link/kprobe_multi.go delete mode 100644 vendor/github.com/cilium/ebpf/link/platform.go create mode 100644 vendor/github.com/cilium/ebpf/link/query.go create mode 100644 vendor/github.com/cilium/ebpf/link/socket_filter.go create mode 100644 vendor/github.com/cilium/ebpf/link/tracing.go create mode 100644 vendor/github.com/cilium/ebpf/link/xdp.go delete mode 100644 vendor/github.com/cosiner/argv/go.mod delete mode 100644 vendor/github.com/creack/pty/go.mod delete mode 100644 vendor/github.com/derekparker/trie/go.mod delete mode 100644 vendor/github.com/go-delve/liner/go.mod delete mode 100644 vendor/github.com/go-delve/liner/go.sum delete mode 100644 vendor/github.com/google/go-dap/go.mod delete mode 100644 vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod delete mode 100644 vendor/github.com/mattn/go-runewidth/go.mod delete mode 100644 vendor/github.com/mattn/go-runewidth/go.sum delete mode 100644 vendor/github.com/rivo/uniseg/go.mod delete mode 100644 vendor/github.com/russross/blackfriday/v2/go.mod delete mode 100644 vendor/github.com/shurcooL/sanitized_anchor_name/go.mod delete mode 100644 vendor/github.com/sirupsen/logrus/go.mod delete mode 100644 vendor/github.com/sirupsen/logrus/go.sum delete mode 100644 vendor/github.com/spf13/cobra/go.mod delete mode 100644 vendor/github.com/spf13/cobra/go.sum delete mode 100644 vendor/github.com/spf13/pflag/go.mod delete mode 100644 vendor/github.com/spf13/pflag/go.sum create mode 100644 vendor/golang.org/x/exp/LICENSE create mode 100644 vendor/golang.org/x/exp/PATENTS create mode 100644 vendor/golang.org/x/exp/constraints/constraints.go create mode 100644 vendor/golang.org/x/exp/maps/maps.go create mode 100644 vendor/golang.org/x/exp/slices/slices.go create mode 100644 vendor/golang.org/x/exp/slices/sort.go create mode 100644 vendor/golang.org/x/exp/slices/zsortfunc.go create mode 100644 vendor/golang.org/x/exp/slices/zsortordered.go create mode 100644 vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_hurd.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_hurd_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_riscv64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s create mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_riscv64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_illumos_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_riscv64.go delete mode 100644 vendor/gopkg.in/yaml.v2/go.mod diff --git a/go.mod b/go.mod index e0bf91d182..8feb2840b7 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,9 @@ module github.com/go-delve/delve -go 1.16 +go 1.17 require ( - github.com/cilium/ebpf v0.7.0 + github.com/cilium/ebpf v0.11.0 github.com/cosiner/argv v0.1.0 github.com/creack/pty v1.1.9 github.com/derekparker/trie v0.0.0-20221213183930-4c74548207f4 @@ -12,14 +12,25 @@ require ( github.com/hashicorp/golang-lru v0.5.4 github.com/mattn/go-colorable v0.0.9 github.com/mattn/go-isatty v0.0.3 - github.com/mattn/go-runewidth v0.0.13 // indirect github.com/sirupsen/logrus v1.6.0 github.com/spf13/cobra v1.1.3 - github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/testify v1.7.0 // indirect + github.com/spf13/pflag v1.0.5 go.starlark.net v0.0.0-20220816155156-cfacd8902214 golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4 - golang.org/x/sys v0.0.0-20220908164124-27713097b956 - golang.org/x/tools v0.1.12 + golang.org/x/sys v0.6.0 + golang.org/x/tools v0.2.0 gopkg.in/yaml.v2 v2.4.0 ) + +require ( + github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/russross/blackfriday/v2 v2.0.1 // indirect + github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/stretchr/testify v1.7.0 // indirect + golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 // indirect + golang.org/x/mod v0.6.0 // indirect +) diff --git a/go.sum b/go.sum index 9cf8af0c48..33009268ab 100644 --- a/go.sum +++ b/go.sum @@ -28,8 +28,8 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.7.0 h1:1k/q3ATgxSXRdrmPfH8d7YK0GfqVsEKZAX9dQZvs56k= -github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= +github.com/cilium/ebpf v0.11.0 h1:V8gS/bTCCjX9uUnkUFUpPsksM8n1lXBAvHcpiFk1X2Y= +github.com/cilium/ebpf v0.11.0/go.mod h1:WE7CZAnqOL2RouJ4f1uyNhqr2P4CCvXFIqdRDUgWsVs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -52,8 +52,8 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA= +github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-delve/liner v1.2.3-0.20220127212407-d32d89dd2a5d h1:pxjSLshkZJGLVm0wv20f/H0oTWiq/egkoJQ2ja6LEvo= @@ -87,8 +87,9 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-dap v0.9.1 h1:d8dETjgHMR9/xs+Xza+NrZmB7jxIS5OtM2uRsyJVA/c= github.com/google/go-dap v0.9.1/go.mod h1:HAeyoSd2WIfTfg+0GRXcFrb+RnojAtGNh+k+XTIxJDE= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -138,11 +139,12 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -167,6 +169,7 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -186,6 +189,8 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -234,11 +239,14 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI= +golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -252,8 +260,9 @@ golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= 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-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -270,6 +279,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -295,20 +305,22 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -330,11 +342,11 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= diff --git a/pkg/proc/native/ptrace_freebsd.go b/pkg/proc/native/ptrace_freebsd.go index 6ccffe6b84..699aba0b0f 100644 --- a/pkg/proc/native/ptrace_freebsd.go +++ b/pkg/proc/native/ptrace_freebsd.go @@ -55,7 +55,7 @@ func ptraceGetLwpList(pid int) (tids []int32) { // Get info of the thread that caused wpid's process to stop. func ptraceGetLwpInfo(wpid int) (info sys.PtraceLwpInfoStruct, err error) { - err = sys.PtraceLwpInfo(wpid, uintptr(unsafe.Pointer(&info))) + err = sys.PtraceLwpInfo(wpid, &info) return info, err } diff --git a/vendor/github.com/cilium/ebpf/.clang-format b/vendor/github.com/cilium/ebpf/.clang-format index 4eb94b1baa..3f74dc0236 100644 --- a/vendor/github.com/cilium/ebpf/.clang-format +++ b/vendor/github.com/cilium/ebpf/.clang-format @@ -14,4 +14,6 @@ KeepEmptyLinesAtTheStartOfBlocks: false TabWidth: 4 UseTab: ForContinuationAndIndentation ColumnLimit: 1000 +# Go compiler comments need to stay unindented. +CommentPragmas: '^go:.*' ... diff --git a/vendor/github.com/cilium/ebpf/.golangci.yaml b/vendor/github.com/cilium/ebpf/.golangci.yaml index dc62dd6d0f..06743dfc91 100644 --- a/vendor/github.com/cilium/ebpf/.golangci.yaml +++ b/vendor/github.com/cilium/ebpf/.golangci.yaml @@ -9,7 +9,6 @@ issues: linters: disable-all: true enable: - - deadcode - errcheck - goimports - gosimple @@ -17,10 +16,9 @@ linters: - ineffassign - misspell - staticcheck - - structcheck - typecheck - unused - - varcheck + - gofmt # Could be enabled later: # - gocyclo diff --git a/vendor/github.com/cilium/ebpf/ARCHITECTURE.md b/vendor/github.com/cilium/ebpf/ARCHITECTURE.md index 6cbb31b648..26f555eb7a 100644 --- a/vendor/github.com/cilium/ebpf/ARCHITECTURE.md +++ b/vendor/github.com/cilium/ebpf/ARCHITECTURE.md @@ -1,7 +1,21 @@ Architecture of the library === - ELF -> Specifications -> Objects -> Links +```mermaid +graph RL + Program --> ProgramSpec --> ELF + btf.Spec --> ELF + Map --> MapSpec --> ELF + Links --> Map & Program + ProgramSpec -.-> btf.Spec + MapSpec -.-> btf.Spec + subgraph Collection + Program & Map + end + subgraph CollectionSpec + ProgramSpec & MapSpec & btf.Spec + end +``` ELF --- @@ -11,7 +25,7 @@ an ELF file which contains program byte code (aka BPF), but also metadata for maps used by the program. The metadata follows the conventions set by libbpf shipped with the kernel. Certain ELF sections have special meaning and contain structures defined by libbpf. Newer versions of clang emit -additional metadata in BPF Type Format (aka BTF). +additional metadata in [BPF Type Format](#BTF). The library aims to be compatible with libbpf so that moving from a C toolchain to a Go one creates little friction. To that end, the [ELF reader](elf_reader.go) @@ -20,41 +34,33 @@ if possible. The output of the ELF reader is a `CollectionSpec` which encodes all of the information contained in the ELF in a form that is easy to work with -in Go. - -### BTF - -The BPF Type Format describes more than just the types used by a BPF program. It -includes debug aids like which source line corresponds to which instructions and -what global variables are used. - -[BTF parsing](internal/btf/) lives in a separate internal package since exposing -it would mean an additional maintenance burden, and because the API still -has sharp corners. The most important concept is the `btf.Type` interface, which -also describes things that aren't really types like `.rodata` or `.bss` sections. -`btf.Type`s can form cyclical graphs, which can easily lead to infinite loops if -one is not careful. Hopefully a safe pattern to work with `btf.Type` emerges as -we write more code that deals with it. +in Go. The returned `CollectionSpec` should be deterministic: reading the same ELF +file on different systems must produce the same output. +As a corollary, any changes that depend on the runtime environment like the +current kernel version must happen when creating [Objects](#Objects). Specifications --- -`CollectionSpec`, `ProgramSpec` and `MapSpec` are blueprints for in-kernel +`CollectionSpec` is a very simple container for `ProgramSpec`, `MapSpec` and +`btf.Spec`. Avoid adding functionality to it if possible. + +`ProgramSpec` and `MapSpec` are blueprints for in-kernel objects and contain everything necessary to execute the relevant `bpf(2)` -syscalls. Since the ELF reader outputs a `CollectionSpec` it's possible to -modify clang-compiled BPF code, for example to rewrite constants. At the same -time the [asm](asm/) package provides an assembler that can be used to generate -`ProgramSpec` on the fly. +syscalls. They refer to `btf.Spec` for type information such as `Map` key and +value types. -Creating a spec should never require any privileges or be restricted in any way, -for example by only allowing programs in native endianness. This ensures that -the library stays flexible. +The [asm](asm/) package provides an assembler that can be used to generate +`ProgramSpec` on the fly. Objects --- -`Program` and `Map` are the result of loading specs into the kernel. Sometimes -loading a spec will fail because the kernel is too old, or a feature is not +`Program` and `Map` are the result of loading specifications into the kernel. +Features that depend on knowledge of the current system (e.g kernel version) +are implemented at this point. + +Sometimes loading a spec will fail because the kernel is too old, or a feature is not enabled. There are multiple ways the library deals with that: * Fallback: older kernels don't allow naming programs and maps. The library @@ -73,8 +79,14 @@ useful when our higher-level API doesn't support a particular use case. Links --- -BPF can be attached to many different points in the kernel and newer BPF hooks +Programs can be attached to many different points in the kernel and newer BPF hooks tend to use bpf_link to do so. Older hooks unfortunately use a combination of syscalls, netlink messages, etc. Adding support for a new link type should not pull in large dependencies like netlink, so XDP programs or tracepoints are out of scope. + +Each bpf_link_type has one corresponding Go type, e.g. `link.tracing` corresponds +to BPF_LINK_TRACING. In general, these types should be unexported as long as they +don't export methods outside of the Link interface. Each Go type may have multiple +exported constructors. For example `AttachTracing` and `AttachLSM` create a +tracing link, but are distinct functions since they may require different arguments. diff --git a/vendor/github.com/cilium/ebpf/CONTRIBUTING.md b/vendor/github.com/cilium/ebpf/CONTRIBUTING.md index 0d29eae81e..bf57da9395 100644 --- a/vendor/github.com/cilium/ebpf/CONTRIBUTING.md +++ b/vendor/github.com/cilium/ebpf/CONTRIBUTING.md @@ -5,15 +5,23 @@ the form of pull requests and issues reporting bugs or suggesting new features are welcome. Please take a look at [the architecture](ARCHITECTURE.md) to get a better understanding for the high-level goals. -New features must be accompanied by tests. Before starting work on any large -feature, please [join](https://ebpf.io/slack) the -[#ebpf-go](https://cilium.slack.com/messages/ebpf-go) channel on Slack to -discuss the design first. +## Adding a new feature -When submitting pull requests, consider writing details about what problem you -are solving and why the proposed approach solves that problem in commit messages -and/or pull request description to help future library users and maintainers to -reason about the proposed changes. +1. [Join](https://ebpf.io/slack) the +[#ebpf-go](https://cilium.slack.com/messages/ebpf-go) channel to discuss your requirements and how the feature can be implemented. The most important part is figuring out how much new exported API is necessary. **The less new API is required the easier it will be to land the feature.** +2. (*optional*) Create a draft PR if you want to discuss the implementation or have hit a problem. It's fine if this doesn't compile or contains debug statements. +3. Create a PR that is ready to merge. This must pass CI and have tests. + +### API stability + +The library doesn't guarantee the stability of its API at the moment. + +1. If possible avoid breakage by introducing new API and deprecating the old one + at the same time. If an API was deprecated in v0.x it can be removed in v0.x+1. +2. Breaking API in a way that causes compilation failures is acceptable but must + have good reasons. +3. Changing the semantics of the API without causing compilation failures is + heavily discouraged. ## Running the tests @@ -35,6 +43,6 @@ Examples: ./run-tests.sh 5.4 # Run a subset of tests: -./run-tests.sh 5.4 go test ./link +./run-tests.sh 5.4 ./link ``` diff --git a/vendor/github.com/cilium/ebpf/MAINTAINERS.md b/vendor/github.com/cilium/ebpf/MAINTAINERS.md new file mode 100644 index 0000000000..a56a03e394 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/MAINTAINERS.md @@ -0,0 +1,3 @@ +# Maintainers + +Maintainers can be found in the [Cilium Maintainers file](https://github.com/cilium/community/blob/main/roles/Maintainers.md) diff --git a/vendor/github.com/cilium/ebpf/Makefile b/vendor/github.com/cilium/ebpf/Makefile index 0bc15c0810..abcd6c1a47 100644 --- a/vendor/github.com/cilium/ebpf/Makefile +++ b/vendor/github.com/cilium/ebpf/Makefile @@ -1,23 +1,34 @@ # The development version of clang is distributed as the 'clang' binary, # while stable/released versions have a version number attached. # Pin the default clang to a stable version. -CLANG ?= clang-12 -CFLAGS := -target bpf -O2 -g -Wall -Werror $(CFLAGS) +CLANG ?= clang-14 +STRIP ?= llvm-strip-14 +OBJCOPY ?= llvm-objcopy-14 +CFLAGS := -O2 -g -Wall -Werror $(CFLAGS) + +CI_KERNEL_URL ?= https://github.com/cilium/ci-kernels/raw/master/ # Obtain an absolute path to the directory of the Makefile. # Assume the Makefile is in the root of the repository. REPODIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) UIDGID := $(shell stat -c '%u:%g' ${REPODIR}) +# Prefer podman if installed, otherwise use docker. +# Note: Setting the var at runtime will always override. +CONTAINER_ENGINE ?= $(if $(shell command -v podman), podman, docker) +CONTAINER_RUN_ARGS ?= $(if $(filter ${CONTAINER_ENGINE}, podman), --log-driver=none, --user "${UIDGID}") + IMAGE := $(shell cat ${REPODIR}/testdata/docker/IMAGE) VERSION := $(shell cat ${REPODIR}/testdata/docker/VERSION) + # clang <8 doesn't tag relocs properly (STT_NOTYPE) # clang 9 is the first version emitting BTF TARGETS := \ testdata/loader-clang-7 \ testdata/loader-clang-9 \ testdata/loader-$(CLANG) \ + testdata/manyprogs \ testdata/btf_map_init \ testdata/invalid_map \ testdata/raw_tracepoint \ @@ -26,48 +37,79 @@ TARGETS := \ testdata/strings \ testdata/freplace \ testdata/iproute2_map_compat \ - internal/btf/testdata/relocs + testdata/map_spin_lock \ + testdata/subprog_reloc \ + testdata/fwd_decl \ + testdata/kconfig \ + testdata/kconfig_config \ + testdata/kfunc \ + testdata/invalid-kfunc \ + testdata/kfunc-kmod \ + btf/testdata/relocs \ + btf/testdata/relocs_read \ + btf/testdata/relocs_read_tgt \ + cmd/bpf2go/testdata/minimal -.PHONY: all clean docker-all docker-shell +.PHONY: all clean container-all container-shell generate -.DEFAULT_TARGET = docker-all +.DEFAULT_TARGET = container-all -# Build all ELF binaries using a Dockerized LLVM toolchain. -docker-all: - docker run --rm --user "${UIDGID}" \ +# Build all ELF binaries using a containerized LLVM toolchain. +container-all: + +${CONTAINER_ENGINE} run --rm -ti ${CONTAINER_RUN_ARGS} \ -v "${REPODIR}":/ebpf -w /ebpf --env MAKEFLAGS \ --env CFLAGS="-fdebug-prefix-map=/ebpf=." \ + --env HOME="/tmp" \ "${IMAGE}:${VERSION}" \ make all -# (debug) Drop the user into a shell inside the Docker container as root. -docker-shell: - docker run --rm -ti \ +# (debug) Drop the user into a shell inside the container as root. +container-shell: + ${CONTAINER_ENGINE} run --rm -ti \ -v "${REPODIR}":/ebpf -w /ebpf \ "${IMAGE}:${VERSION}" clean: -$(RM) testdata/*.elf - -$(RM) internal/btf/testdata/*.elf + -$(RM) btf/testdata/*.elf -all: $(addsuffix -el.elf,$(TARGETS)) $(addsuffix -eb.elf,$(TARGETS)) +format: + find . -type f -name "*.c" | xargs clang-format -i + +all: format $(addsuffix -el.elf,$(TARGETS)) $(addsuffix -eb.elf,$(TARGETS)) generate ln -srf testdata/loader-$(CLANG)-el.elf testdata/loader-el.elf ln -srf testdata/loader-$(CLANG)-eb.elf testdata/loader-eb.elf +# $BPF_CLANG is used in go:generate invocations. +generate: export BPF_CLANG := $(CLANG) +generate: export BPF_CFLAGS := $(CFLAGS) +generate: + go generate ./... + testdata/loader-%-el.elf: testdata/loader.c - $* $(CFLAGS) -mlittle-endian -c $< -o $@ + $* $(CFLAGS) -target bpfel -c $< -o $@ + $(STRIP) -g $@ testdata/loader-%-eb.elf: testdata/loader.c - $* $(CFLAGS) -mbig-endian -c $< -o $@ + $* $(CFLAGS) -target bpfeb -c $< -o $@ + $(STRIP) -g $@ %-el.elf: %.c - $(CLANG) $(CFLAGS) -mlittle-endian -c $< -o $@ + $(CLANG) $(CFLAGS) -target bpfel -c $< -o $@ + $(STRIP) -g $@ %-eb.elf : %.c - $(CLANG) $(CFLAGS) -mbig-endian -c $< -o $@ + $(CLANG) $(CFLAGS) -target bpfeb -c $< -o $@ + $(STRIP) -g $@ -# Usage: make VMLINUX=/path/to/vmlinux vmlinux-btf -.PHONY: vmlinux-btf -vmlinux-btf: internal/btf/testdata/vmlinux-btf.gz -internal/btf/testdata/vmlinux-btf.gz: $(VMLINUX) - objcopy --dump-section .BTF=/dev/stdout "$<" /dev/null | gzip > "$@" +.PHONY: generate-btf +generate-btf: KERNEL_VERSION?=5.19 +generate-btf: + $(eval TMP := $(shell mktemp -d)) + curl -fL "$(CI_KERNEL_URL)/linux-$(KERNEL_VERSION).bz" -o "$(TMP)/bzImage" + /lib/modules/$(uname -r)/build/scripts/extract-vmlinux "$(TMP)/bzImage" > "$(TMP)/vmlinux" + $(OBJCOPY) --dump-section .BTF=/dev/stdout "$(TMP)/vmlinux" /dev/null | gzip > "btf/testdata/vmlinux.btf.gz" + curl -fL "$(CI_KERNEL_URL)/linux-$(KERNEL_VERSION)-selftests-bpf.tgz" -o "$(TMP)/selftests.tgz" + tar -xf "$(TMP)/selftests.tgz" --to-stdout tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.ko | \ + $(OBJCOPY) --dump-section .BTF="btf/testdata/btf_testmod.btf" - /dev/null + $(RM) -r "$(TMP)" diff --git a/vendor/github.com/cilium/ebpf/README.md b/vendor/github.com/cilium/ebpf/README.md index 01e2fff92b..eff08d8df6 100644 --- a/vendor/github.com/cilium/ebpf/README.md +++ b/vendor/github.com/cilium/ebpf/README.md @@ -4,33 +4,37 @@ ![HoneyGopher](.github/images/cilium-ebpf.png) -eBPF is a pure Go library that provides utilities for loading, compiling, and +ebpf-go is a pure Go library that provides utilities for loading, compiling, and debugging eBPF programs. It has minimal external dependencies and is intended to be used in long running processes. -The library is maintained by [Cloudflare](https://www.cloudflare.com) and -[Cilium](https://www.cilium.io). - -See [ebpf.io](https://ebpf.io) for other projects from the eBPF ecosystem. +See [ebpf.io](https://ebpf.io) for complementary projects from the wider eBPF +ecosystem. ## Getting Started A small collection of Go and eBPF programs that serve as examples for building your own tools can be found under [examples/](examples/). -Contributions are highly encouraged, as they highlight certain use cases of +[Contributions](CONTRIBUTING.md) are highly encouraged, as they highlight certain use cases of eBPF and the library, and help shape the future of the project. ## Getting Help -Please -[join](https://ebpf.io/slack) the +The community actively monitors our [GitHub Discussions](https://github.com/cilium/ebpf/discussions) page. +Please search for existing threads before starting a new one. Refrain from +opening issues on the bug tracker if you're just starting out or if you're not +sure if something is a bug in the library code. + +Alternatively, [join](https://ebpf.io/slack) the [#ebpf-go](https://cilium.slack.com/messages/ebpf-go) channel on Slack if you -have questions regarding the library. +have other questions regarding the project. Note that this channel is ephemeral +and has its history erased past a certain point, which is less helpful for +others running into the same problem later. ## Packages -This library includes the following packages: +This library includes the following packages: * [asm](https://pkg.go.dev/github.com/cilium/ebpf/asm) contains a basic assembler, allowing you to write eBPF assembly instructions directly @@ -38,20 +42,25 @@ This library includes the following packages: * [cmd/bpf2go](https://pkg.go.dev/github.com/cilium/ebpf/cmd/bpf2go) allows compiling and embedding eBPF programs written in C within Go code. As well as compiling the C code, it auto-generates Go code for loading and manipulating - the eBPF program and map objects. + the eBPF program and map objects. * [link](https://pkg.go.dev/github.com/cilium/ebpf/link) allows attaching eBPF to various hooks * [perf](https://pkg.go.dev/github.com/cilium/ebpf/perf) allows reading from a `PERF_EVENT_ARRAY` * [ringbuf](https://pkg.go.dev/github.com/cilium/ebpf/ringbuf) allows reading from a `BPF_MAP_TYPE_RINGBUF` map - +* [features](https://pkg.go.dev/github.com/cilium/ebpf/features) implements the equivalent + of `bpftool feature probe` for discovering BPF-related kernel features using native Go. +* [rlimit](https://pkg.go.dev/github.com/cilium/ebpf/rlimit) provides a convenient API to lift + the `RLIMIT_MEMLOCK` constraint on kernels before 5.11. +* [btf](https://pkg.go.dev/github.com/cilium/ebpf/btf) allows reading the BPF Type Format. ## Requirements * A version of Go that is [supported by upstream](https://golang.org/doc/devel/release.html#policy) -* Linux >= 4.9. CI is run against LTS releases. +* Linux >= 4.9. CI is run against kernel.org LTS releases. 4.4 should work but is + not tested against. ## Regenerating Testdata @@ -59,6 +68,9 @@ Run `make` in the root of this repository to rebuild testdata in all subpackages. This requires Docker, as it relies on a standardized build environment to keep the build output stable. +It is possible to regenerate data using Podman by overriding the `CONTAINER_*` +variables: `CONTAINER_ENGINE=podman CONTAINER_RUN_ARGS= make`. + The toolchain image build files are kept in [testdata/docker/](testdata/docker/). ## License diff --git a/vendor/github.com/cilium/ebpf/asm/alu.go b/vendor/github.com/cilium/ebpf/asm/alu.go index 70ccc4d151..3f60245f2b 100644 --- a/vendor/github.com/cilium/ebpf/asm/alu.go +++ b/vendor/github.com/cilium/ebpf/asm/alu.go @@ -4,10 +4,10 @@ package asm // Source of ALU / ALU64 / Branch operations // -// msb lsb -// +----+-+---+ -// |op |S|cls| -// +----+-+---+ +// msb lsb +// +----+-+---+ +// |op |S|cls| +// +----+-+---+ type Source uint8 const sourceMask OpCode = 0x08 @@ -39,10 +39,10 @@ const ( // ALUOp are ALU / ALU64 operations // -// msb lsb -// +----+-+---+ -// |OP |s|cls| -// +----+-+---+ +// msb lsb +// +----+-+---+ +// |OP |s|cls| +// +----+-+---+ type ALUOp uint8 const aluMask OpCode = 0xf0 diff --git a/vendor/github.com/cilium/ebpf/asm/func.go b/vendor/github.com/cilium/ebpf/asm/func.go index bfa5d59c97..18f6a75db5 100644 --- a/vendor/github.com/cilium/ebpf/asm/func.go +++ b/vendor/github.com/cilium/ebpf/asm/func.go @@ -5,19 +5,23 @@ package asm // BuiltinFunc is a built-in eBPF function. type BuiltinFunc int32 +func (_ BuiltinFunc) Max() BuiltinFunc { + return maxBuiltinFunc - 1 +} + // eBPF built-in functions // // You can regenerate this list using the following gawk script: // -// /FN\(.+\),/ { -// match($1, /\((.+)\)/, r) -// split(r[1], p, "_") -// printf "Fn" -// for (i in p) { -// printf "%s%s", toupper(substr(p[i], 1, 1)), substr(p[i], 2) -// } -// print "" -// } +// /FN\(.+\),/ { +// match($1, /\(([a-z_0-9]+),/, r) +// split(r[1], p, "_") +// printf "Fn" +// for (i in p) { +// printf "%s%s", toupper(substr(p[i], 1, 1)), substr(p[i], 2) +// } +// print "" +// } // // The script expects include/uapi/linux/bpf.h as it's input. const ( @@ -190,6 +194,51 @@ const ( FnSysBpf FnBtfFindByNameKind FnSysClose + FnTimerInit + FnTimerSetCallback + FnTimerStart + FnTimerCancel + FnGetFuncIp + FnGetAttachCookie + FnTaskPtRegs + FnGetBranchSnapshot + FnTraceVprintk + FnSkcToUnixSock + FnKallsymsLookupName + FnFindVma + FnLoop + FnStrncmp + FnGetFuncArg + FnGetFuncRet + FnGetFuncArgCnt + FnGetRetval + FnSetRetval + FnXdpGetBuffLen + FnXdpLoadBytes + FnXdpStoreBytes + FnCopyFromUserTask + FnSkbSetTstamp + FnImaFileHash + FnKptrXchg + FnMapLookupPercpuElem + FnSkcToMptcpSock + FnDynptrFromMem + FnRingbufReserveDynptr + FnRingbufSubmitDynptr + FnRingbufDiscardDynptr + FnDynptrRead + FnDynptrWrite + FnDynptrData + FnTcpRawGenSyncookieIpv4 + FnTcpRawGenSyncookieIpv6 + FnTcpRawCheckSyncookieIpv4 + FnTcpRawCheckSyncookieIpv6 + FnKtimeGetTaiNs + FnUserRingbufDrain + FnCgrpStorageGet + FnCgrpStorageDelete + + maxBuiltinFunc ) // Call emits a function call. diff --git a/vendor/github.com/cilium/ebpf/asm/func_string.go b/vendor/github.com/cilium/ebpf/asm/func_string.go index 5a0e333639..47150bc4f2 100644 --- a/vendor/github.com/cilium/ebpf/asm/func_string.go +++ b/vendor/github.com/cilium/ebpf/asm/func_string.go @@ -177,11 +177,55 @@ func _() { _ = x[FnSysBpf-166] _ = x[FnBtfFindByNameKind-167] _ = x[FnSysClose-168] + _ = x[FnTimerInit-169] + _ = x[FnTimerSetCallback-170] + _ = x[FnTimerStart-171] + _ = x[FnTimerCancel-172] + _ = x[FnGetFuncIp-173] + _ = x[FnGetAttachCookie-174] + _ = x[FnTaskPtRegs-175] + _ = x[FnGetBranchSnapshot-176] + _ = x[FnTraceVprintk-177] + _ = x[FnSkcToUnixSock-178] + _ = x[FnKallsymsLookupName-179] + _ = x[FnFindVma-180] + _ = x[FnLoop-181] + _ = x[FnStrncmp-182] + _ = x[FnGetFuncArg-183] + _ = x[FnGetFuncRet-184] + _ = x[FnGetFuncArgCnt-185] + _ = x[FnGetRetval-186] + _ = x[FnSetRetval-187] + _ = x[FnXdpGetBuffLen-188] + _ = x[FnXdpLoadBytes-189] + _ = x[FnXdpStoreBytes-190] + _ = x[FnCopyFromUserTask-191] + _ = x[FnSkbSetTstamp-192] + _ = x[FnImaFileHash-193] + _ = x[FnKptrXchg-194] + _ = x[FnMapLookupPercpuElem-195] + _ = x[FnSkcToMptcpSock-196] + _ = x[FnDynptrFromMem-197] + _ = x[FnRingbufReserveDynptr-198] + _ = x[FnRingbufSubmitDynptr-199] + _ = x[FnRingbufDiscardDynptr-200] + _ = x[FnDynptrRead-201] + _ = x[FnDynptrWrite-202] + _ = x[FnDynptrData-203] + _ = x[FnTcpRawGenSyncookieIpv4-204] + _ = x[FnTcpRawGenSyncookieIpv6-205] + _ = x[FnTcpRawCheckSyncookieIpv4-206] + _ = x[FnTcpRawCheckSyncookieIpv6-207] + _ = x[FnKtimeGetTaiNs-208] + _ = x[FnUserRingbufDrain-209] + _ = x[FnCgrpStorageGet-210] + _ = x[FnCgrpStorageDelete-211] + _ = x[maxBuiltinFunc-212] } -const _BuiltinFunc_name = "FnUnspecFnMapLookupElemFnMapUpdateElemFnMapDeleteElemFnProbeReadFnKtimeGetNsFnTracePrintkFnGetPrandomU32FnGetSmpProcessorIdFnSkbStoreBytesFnL3CsumReplaceFnL4CsumReplaceFnTailCallFnCloneRedirectFnGetCurrentPidTgidFnGetCurrentUidGidFnGetCurrentCommFnGetCgroupClassidFnSkbVlanPushFnSkbVlanPopFnSkbGetTunnelKeyFnSkbSetTunnelKeyFnPerfEventReadFnRedirectFnGetRouteRealmFnPerfEventOutputFnSkbLoadBytesFnGetStackidFnCsumDiffFnSkbGetTunnelOptFnSkbSetTunnelOptFnSkbChangeProtoFnSkbChangeTypeFnSkbUnderCgroupFnGetHashRecalcFnGetCurrentTaskFnProbeWriteUserFnCurrentTaskUnderCgroupFnSkbChangeTailFnSkbPullDataFnCsumUpdateFnSetHashInvalidFnGetNumaNodeIdFnSkbChangeHeadFnXdpAdjustHeadFnProbeReadStrFnGetSocketCookieFnGetSocketUidFnSetHashFnSetsockoptFnSkbAdjustRoomFnRedirectMapFnSkRedirectMapFnSockMapUpdateFnXdpAdjustMetaFnPerfEventReadValueFnPerfProgReadValueFnGetsockoptFnOverrideReturnFnSockOpsCbFlagsSetFnMsgRedirectMapFnMsgApplyBytesFnMsgCorkBytesFnMsgPullDataFnBindFnXdpAdjustTailFnSkbGetXfrmStateFnGetStackFnSkbLoadBytesRelativeFnFibLookupFnSockHashUpdateFnMsgRedirectHashFnSkRedirectHashFnLwtPushEncapFnLwtSeg6StoreBytesFnLwtSeg6AdjustSrhFnLwtSeg6ActionFnRcRepeatFnRcKeydownFnSkbCgroupIdFnGetCurrentCgroupIdFnGetLocalStorageFnSkSelectReuseportFnSkbAncestorCgroupIdFnSkLookupTcpFnSkLookupUdpFnSkReleaseFnMapPushElemFnMapPopElemFnMapPeekElemFnMsgPushDataFnMsgPopDataFnRcPointerRelFnSpinLockFnSpinUnlockFnSkFullsockFnTcpSockFnSkbEcnSetCeFnGetListenerSockFnSkcLookupTcpFnTcpCheckSyncookieFnSysctlGetNameFnSysctlGetCurrentValueFnSysctlGetNewValueFnSysctlSetNewValueFnStrtolFnStrtoulFnSkStorageGetFnSkStorageDeleteFnSendSignalFnTcpGenSyncookieFnSkbOutputFnProbeReadUserFnProbeReadKernelFnProbeReadUserStrFnProbeReadKernelStrFnTcpSendAckFnSendSignalThreadFnJiffies64FnReadBranchRecordsFnGetNsCurrentPidTgidFnXdpOutputFnGetNetnsCookieFnGetCurrentAncestorCgroupIdFnSkAssignFnKtimeGetBootNsFnSeqPrintfFnSeqWriteFnSkCgroupIdFnSkAncestorCgroupIdFnRingbufOutputFnRingbufReserveFnRingbufSubmitFnRingbufDiscardFnRingbufQueryFnCsumLevelFnSkcToTcp6SockFnSkcToTcpSockFnSkcToTcpTimewaitSockFnSkcToTcpRequestSockFnSkcToUdp6SockFnGetTaskStackFnLoadHdrOptFnStoreHdrOptFnReserveHdrOptFnInodeStorageGetFnInodeStorageDeleteFnDPathFnCopyFromUserFnSnprintfBtfFnSeqPrintfBtfFnSkbCgroupClassidFnRedirectNeighFnPerCpuPtrFnThisCpuPtrFnRedirectPeerFnTaskStorageGetFnTaskStorageDeleteFnGetCurrentTaskBtfFnBprmOptsSetFnKtimeGetCoarseNsFnImaInodeHashFnSockFromFileFnCheckMtuFnForEachMapElemFnSnprintfFnSysBpfFnBtfFindByNameKindFnSysClose" +const _BuiltinFunc_name = "FnUnspecFnMapLookupElemFnMapUpdateElemFnMapDeleteElemFnProbeReadFnKtimeGetNsFnTracePrintkFnGetPrandomU32FnGetSmpProcessorIdFnSkbStoreBytesFnL3CsumReplaceFnL4CsumReplaceFnTailCallFnCloneRedirectFnGetCurrentPidTgidFnGetCurrentUidGidFnGetCurrentCommFnGetCgroupClassidFnSkbVlanPushFnSkbVlanPopFnSkbGetTunnelKeyFnSkbSetTunnelKeyFnPerfEventReadFnRedirectFnGetRouteRealmFnPerfEventOutputFnSkbLoadBytesFnGetStackidFnCsumDiffFnSkbGetTunnelOptFnSkbSetTunnelOptFnSkbChangeProtoFnSkbChangeTypeFnSkbUnderCgroupFnGetHashRecalcFnGetCurrentTaskFnProbeWriteUserFnCurrentTaskUnderCgroupFnSkbChangeTailFnSkbPullDataFnCsumUpdateFnSetHashInvalidFnGetNumaNodeIdFnSkbChangeHeadFnXdpAdjustHeadFnProbeReadStrFnGetSocketCookieFnGetSocketUidFnSetHashFnSetsockoptFnSkbAdjustRoomFnRedirectMapFnSkRedirectMapFnSockMapUpdateFnXdpAdjustMetaFnPerfEventReadValueFnPerfProgReadValueFnGetsockoptFnOverrideReturnFnSockOpsCbFlagsSetFnMsgRedirectMapFnMsgApplyBytesFnMsgCorkBytesFnMsgPullDataFnBindFnXdpAdjustTailFnSkbGetXfrmStateFnGetStackFnSkbLoadBytesRelativeFnFibLookupFnSockHashUpdateFnMsgRedirectHashFnSkRedirectHashFnLwtPushEncapFnLwtSeg6StoreBytesFnLwtSeg6AdjustSrhFnLwtSeg6ActionFnRcRepeatFnRcKeydownFnSkbCgroupIdFnGetCurrentCgroupIdFnGetLocalStorageFnSkSelectReuseportFnSkbAncestorCgroupIdFnSkLookupTcpFnSkLookupUdpFnSkReleaseFnMapPushElemFnMapPopElemFnMapPeekElemFnMsgPushDataFnMsgPopDataFnRcPointerRelFnSpinLockFnSpinUnlockFnSkFullsockFnTcpSockFnSkbEcnSetCeFnGetListenerSockFnSkcLookupTcpFnTcpCheckSyncookieFnSysctlGetNameFnSysctlGetCurrentValueFnSysctlGetNewValueFnSysctlSetNewValueFnStrtolFnStrtoulFnSkStorageGetFnSkStorageDeleteFnSendSignalFnTcpGenSyncookieFnSkbOutputFnProbeReadUserFnProbeReadKernelFnProbeReadUserStrFnProbeReadKernelStrFnTcpSendAckFnSendSignalThreadFnJiffies64FnReadBranchRecordsFnGetNsCurrentPidTgidFnXdpOutputFnGetNetnsCookieFnGetCurrentAncestorCgroupIdFnSkAssignFnKtimeGetBootNsFnSeqPrintfFnSeqWriteFnSkCgroupIdFnSkAncestorCgroupIdFnRingbufOutputFnRingbufReserveFnRingbufSubmitFnRingbufDiscardFnRingbufQueryFnCsumLevelFnSkcToTcp6SockFnSkcToTcpSockFnSkcToTcpTimewaitSockFnSkcToTcpRequestSockFnSkcToUdp6SockFnGetTaskStackFnLoadHdrOptFnStoreHdrOptFnReserveHdrOptFnInodeStorageGetFnInodeStorageDeleteFnDPathFnCopyFromUserFnSnprintfBtfFnSeqPrintfBtfFnSkbCgroupClassidFnRedirectNeighFnPerCpuPtrFnThisCpuPtrFnRedirectPeerFnTaskStorageGetFnTaskStorageDeleteFnGetCurrentTaskBtfFnBprmOptsSetFnKtimeGetCoarseNsFnImaInodeHashFnSockFromFileFnCheckMtuFnForEachMapElemFnSnprintfFnSysBpfFnBtfFindByNameKindFnSysCloseFnTimerInitFnTimerSetCallbackFnTimerStartFnTimerCancelFnGetFuncIpFnGetAttachCookieFnTaskPtRegsFnGetBranchSnapshotFnTraceVprintkFnSkcToUnixSockFnKallsymsLookupNameFnFindVmaFnLoopFnStrncmpFnGetFuncArgFnGetFuncRetFnGetFuncArgCntFnGetRetvalFnSetRetvalFnXdpGetBuffLenFnXdpLoadBytesFnXdpStoreBytesFnCopyFromUserTaskFnSkbSetTstampFnImaFileHashFnKptrXchgFnMapLookupPercpuElemFnSkcToMptcpSockFnDynptrFromMemFnRingbufReserveDynptrFnRingbufSubmitDynptrFnRingbufDiscardDynptrFnDynptrReadFnDynptrWriteFnDynptrDataFnTcpRawGenSyncookieIpv4FnTcpRawGenSyncookieIpv6FnTcpRawCheckSyncookieIpv4FnTcpRawCheckSyncookieIpv6FnKtimeGetTaiNsFnUserRingbufDrainFnCgrpStorageGetFnCgrpStorageDeletemaxBuiltinFunc" -var _BuiltinFunc_index = [...]uint16{0, 8, 23, 38, 53, 64, 76, 89, 104, 123, 138, 153, 168, 178, 193, 212, 230, 246, 264, 277, 289, 306, 323, 338, 348, 363, 380, 394, 406, 416, 433, 450, 466, 481, 497, 512, 528, 544, 568, 583, 596, 608, 624, 639, 654, 669, 683, 700, 714, 723, 735, 750, 763, 778, 793, 808, 828, 847, 859, 875, 894, 910, 925, 939, 952, 958, 973, 990, 1000, 1022, 1033, 1049, 1066, 1082, 1096, 1115, 1133, 1148, 1158, 1169, 1182, 1202, 1219, 1238, 1259, 1272, 1285, 1296, 1309, 1321, 1334, 1347, 1359, 1373, 1383, 1395, 1407, 1416, 1429, 1446, 1460, 1479, 1494, 1517, 1536, 1555, 1563, 1572, 1586, 1603, 1615, 1632, 1643, 1658, 1675, 1693, 1713, 1725, 1743, 1754, 1773, 1794, 1805, 1821, 1849, 1859, 1875, 1886, 1896, 1908, 1928, 1943, 1959, 1974, 1990, 2004, 2015, 2030, 2044, 2066, 2087, 2102, 2116, 2128, 2141, 2156, 2173, 2193, 2200, 2214, 2227, 2241, 2259, 2274, 2285, 2297, 2311, 2327, 2346, 2365, 2378, 2396, 2410, 2424, 2434, 2450, 2460, 2468, 2487, 2497} +var _BuiltinFunc_index = [...]uint16{0, 8, 23, 38, 53, 64, 76, 89, 104, 123, 138, 153, 168, 178, 193, 212, 230, 246, 264, 277, 289, 306, 323, 338, 348, 363, 380, 394, 406, 416, 433, 450, 466, 481, 497, 512, 528, 544, 568, 583, 596, 608, 624, 639, 654, 669, 683, 700, 714, 723, 735, 750, 763, 778, 793, 808, 828, 847, 859, 875, 894, 910, 925, 939, 952, 958, 973, 990, 1000, 1022, 1033, 1049, 1066, 1082, 1096, 1115, 1133, 1148, 1158, 1169, 1182, 1202, 1219, 1238, 1259, 1272, 1285, 1296, 1309, 1321, 1334, 1347, 1359, 1373, 1383, 1395, 1407, 1416, 1429, 1446, 1460, 1479, 1494, 1517, 1536, 1555, 1563, 1572, 1586, 1603, 1615, 1632, 1643, 1658, 1675, 1693, 1713, 1725, 1743, 1754, 1773, 1794, 1805, 1821, 1849, 1859, 1875, 1886, 1896, 1908, 1928, 1943, 1959, 1974, 1990, 2004, 2015, 2030, 2044, 2066, 2087, 2102, 2116, 2128, 2141, 2156, 2173, 2193, 2200, 2214, 2227, 2241, 2259, 2274, 2285, 2297, 2311, 2327, 2346, 2365, 2378, 2396, 2410, 2424, 2434, 2450, 2460, 2468, 2487, 2497, 2508, 2526, 2538, 2551, 2562, 2579, 2591, 2610, 2624, 2639, 2659, 2668, 2674, 2683, 2695, 2707, 2722, 2733, 2744, 2759, 2773, 2788, 2806, 2820, 2833, 2843, 2864, 2880, 2895, 2917, 2938, 2960, 2972, 2985, 2997, 3021, 3045, 3071, 3097, 3112, 3130, 3146, 3165, 3179} func (i BuiltinFunc) String() string { if i < 0 || i >= BuiltinFunc(len(_BuiltinFunc_index)-1) { diff --git a/vendor/github.com/cilium/ebpf/asm/instruction.go b/vendor/github.com/cilium/ebpf/asm/instruction.go index 64d717d156..ef01eaa35a 100644 --- a/vendor/github.com/cilium/ebpf/asm/instruction.go +++ b/vendor/github.com/cilium/ebpf/asm/instruction.go @@ -8,8 +8,10 @@ import ( "fmt" "io" "math" + "sort" "strings" + "github.com/cilium/ebpf/internal/sys" "github.com/cilium/ebpf/internal/unix" ) @@ -19,6 +21,10 @@ const InstructionSize = 8 // RawInstructionOffset is an offset in units of raw BPF instructions. type RawInstructionOffset uint64 +var ErrUnreferencedSymbol = errors.New("unreferenced symbol") +var ErrUnsatisfiedMapReference = errors.New("unsatisfied map reference") +var ErrUnsatisfiedProgramReference = errors.New("unsatisfied program reference") + // Bytes returns the offset of an instruction in bytes. func (rio RawInstructionOffset) Bytes() uint64 { return uint64(rio) * InstructionSize @@ -26,50 +32,57 @@ func (rio RawInstructionOffset) Bytes() uint64 { // Instruction is a single eBPF instruction. type Instruction struct { - OpCode OpCode - Dst Register - Src Register - Offset int16 - Constant int64 - Reference string - Symbol string -} - -// Sym creates a symbol. -func (ins Instruction) Sym(name string) Instruction { - ins.Symbol = name - return ins + OpCode OpCode + Dst Register + Src Register + Offset int16 + Constant int64 + + // Metadata contains optional metadata about this instruction. + Metadata Metadata } // Unmarshal decodes a BPF instruction. func (ins *Instruction) Unmarshal(r io.Reader, bo binary.ByteOrder) (uint64, error) { - var bi bpfInstruction - err := binary.Read(r, bo, &bi) - if err != nil { + data := make([]byte, InstructionSize) + if _, err := io.ReadFull(r, data); err != nil { return 0, err } - ins.OpCode = bi.OpCode - ins.Offset = bi.Offset - ins.Constant = int64(bi.Constant) - ins.Dst, ins.Src, err = bi.Registers.Unmarshal(bo) - if err != nil { - return 0, fmt.Errorf("can't unmarshal registers: %s", err) + ins.OpCode = OpCode(data[0]) + + regs := data[1] + switch bo { + case binary.LittleEndian: + ins.Dst, ins.Src = Register(regs&0xF), Register(regs>>4) + case binary.BigEndian: + ins.Dst, ins.Src = Register(regs>>4), Register(regs&0xf) } - if !bi.OpCode.IsDWordLoad() { + ins.Offset = int16(bo.Uint16(data[2:4])) + // Convert to int32 before widening to int64 + // to ensure the signed bit is carried over. + ins.Constant = int64(int32(bo.Uint32(data[4:8]))) + + if !ins.OpCode.IsDWordLoad() { return InstructionSize, nil } - var bi2 bpfInstruction - if err := binary.Read(r, bo, &bi2); err != nil { + // Pull another instruction from the stream to retrieve the second + // half of the 64-bit immediate value. + if _, err := io.ReadFull(r, data); err != nil { // No Wrap, to avoid io.EOF clash return 0, errors.New("64bit immediate is missing second half") } - if bi2.OpCode != 0 || bi2.Offset != 0 || bi2.Registers != 0 { + + // Require that all fields other than the value are zero. + if bo.Uint32(data[0:4]) != 0 { return 0, errors.New("64bit immediate has non-zero fields") } - ins.Constant = int64(uint64(uint32(bi2.Constant))<<32 | uint64(uint32(bi.Constant))) + + cons1 := uint32(ins.Constant) + cons2 := int32(bo.Uint32(data[4:8])) + ins.Constant = int64(cons2)<<32 | int64(cons1) return 2 * InstructionSize, nil } @@ -93,14 +106,12 @@ func (ins Instruction) Marshal(w io.Writer, bo binary.ByteOrder) (uint64, error) return 0, fmt.Errorf("can't marshal registers: %s", err) } - bpfi := bpfInstruction{ - ins.OpCode, - regs, - ins.Offset, - cons, - } - - if err := binary.Write(w, bo, &bpfi); err != nil { + data := make([]byte, InstructionSize) + data[0] = byte(ins.OpCode) + data[1] = byte(regs) + bo.PutUint16(data[2:4], uint16(ins.Offset)) + bo.PutUint32(data[4:8], uint32(cons)) + if _, err := w.Write(data); err != nil { return 0, err } @@ -108,42 +119,76 @@ func (ins Instruction) Marshal(w io.Writer, bo binary.ByteOrder) (uint64, error) return InstructionSize, nil } - bpfi = bpfInstruction{ - Constant: int32(ins.Constant >> 32), - } - - if err := binary.Write(w, bo, &bpfi); err != nil { + // The first half of the second part of a double-wide instruction + // must be zero. The second half carries the value. + bo.PutUint32(data[0:4], 0) + bo.PutUint32(data[4:8], uint32(ins.Constant>>32)) + if _, err := w.Write(data); err != nil { return 0, err } return 2 * InstructionSize, nil } +// AssociateMap associates a Map with this Instruction. +// +// Implicitly clears the Instruction's Reference field. +// +// Returns an error if the Instruction is not a map load. +func (ins *Instruction) AssociateMap(m FDer) error { + if !ins.IsLoadFromMap() { + return errors.New("not a load from a map") + } + + ins.Metadata.Set(referenceMeta{}, nil) + ins.Metadata.Set(mapMeta{}, m) + + return nil +} + // RewriteMapPtr changes an instruction to use a new map fd. // // Returns an error if the instruction doesn't load a map. +// +// Deprecated: use AssociateMap instead. If you cannot provide a Map, +// wrap an fd in a type implementing FDer. func (ins *Instruction) RewriteMapPtr(fd int) error { - if !ins.OpCode.IsDWordLoad() { - return fmt.Errorf("%s is not a 64 bit load", ins.OpCode) - } - - if ins.Src != PseudoMapFD && ins.Src != PseudoMapValue { + if !ins.IsLoadFromMap() { return errors.New("not a load from a map") } + ins.encodeMapFD(fd) + + return nil +} + +func (ins *Instruction) encodeMapFD(fd int) { // Preserve the offset value for direct map loads. offset := uint64(ins.Constant) & (math.MaxUint32 << 32) rawFd := uint64(uint32(fd)) ins.Constant = int64(offset | rawFd) - return nil } // MapPtr returns the map fd for this instruction. // // The result is undefined if the instruction is not a load from a map, // see IsLoadFromMap. +// +// Deprecated: use Map() instead. func (ins *Instruction) MapPtr() int { - return int(int32(uint64(ins.Constant) & math.MaxUint32)) + // If there is a map associated with the instruction, return its FD. + if fd := ins.Metadata.Get(mapMeta{}); fd != nil { + return fd.(FDer).FD() + } + + // Fall back to the fd stored in the Constant field + return ins.mapFd() +} + +// mapFd returns the map file descriptor stored in the 32 least significant +// bits of ins' Constant field. +func (ins *Instruction) mapFd() int { + return int(int32(ins.Constant)) } // RewriteMapOffset changes the offset of a direct load from a map. @@ -181,6 +226,25 @@ func (ins *Instruction) IsFunctionCall() bool { return ins.OpCode.JumpOp() == Call && ins.Src == PseudoCall } +// IsKfuncCall returns true if the instruction calls a kfunc. +// +// This is not the same thing as a BPF helper call. +func (ins *Instruction) IsKfuncCall() bool { + return ins.OpCode.JumpOp() == Call && ins.Src == PseudoKfuncCall +} + +// IsLoadOfFunctionPointer returns true if the instruction loads a function pointer. +func (ins *Instruction) IsLoadOfFunctionPointer() bool { + return ins.OpCode.IsDWordLoad() && ins.Src == PseudoFunc +} + +// IsFunctionReference returns true if the instruction references another BPF +// function, either by invoking a Call jump operation or by loading a function +// pointer. +func (ins *Instruction) IsFunctionReference() bool { + return ins.IsFunctionCall() || ins.IsLoadOfFunctionPointer() +} + // IsBuiltinCall returns true if the instruction is a built-in call, i.e. BPF helper call. func (ins *Instruction) IsBuiltinCall() bool { return ins.OpCode.JumpOp() == Call && ins.Src == R0 && ins.Dst == R0 @@ -213,21 +277,30 @@ func (ins Instruction) Format(f fmt.State, c rune) { } if ins.IsLoadFromMap() { - fd := ins.MapPtr() + fd := ins.mapFd() + m := ins.Map() switch ins.Src { case PseudoMapFD: - fmt.Fprintf(f, "LoadMapPtr dst: %s fd: %d", ins.Dst, fd) + if m != nil { + fmt.Fprintf(f, "LoadMapPtr dst: %s map: %s", ins.Dst, m) + } else { + fmt.Fprintf(f, "LoadMapPtr dst: %s fd: %d", ins.Dst, fd) + } case PseudoMapValue: - fmt.Fprintf(f, "LoadMapValue dst: %s, fd: %d off: %d", ins.Dst, fd, ins.mapOffset()) + if m != nil { + fmt.Fprintf(f, "LoadMapValue dst: %s, map: %s off: %d", ins.Dst, m, ins.mapOffset()) + } else { + fmt.Fprintf(f, "LoadMapValue dst: %s, fd: %d off: %d", ins.Dst, fd, ins.mapOffset()) + } } goto ref } fmt.Fprintf(f, "%v ", op) - switch cls := op.Class(); cls { - case LdClass, LdXClass, StClass, StXClass: + switch cls := op.Class(); { + case cls.isLoadOrStore(): switch op.Mode() { case ImmMode: fmt.Fprintf(f, "dst: %s imm: %d", ins.Dst, ins.Constant) @@ -241,7 +314,7 @@ func (ins Instruction) Format(f fmt.State, c rune) { fmt.Fprintf(f, "dst: %s src: %s", ins.Dst, ins.Src) } - case ALU64Class, ALUClass: + case cls.IsALU(): fmt.Fprintf(f, "dst: %s ", ins.Dst) if op.ALUOp() == Swap || op.Source() == ImmSource { fmt.Fprintf(f, "imm: %d", ins.Constant) @@ -249,13 +322,17 @@ func (ins Instruction) Format(f fmt.State, c rune) { fmt.Fprintf(f, "src: %s", ins.Src) } - case JumpClass: + case cls.IsJump(): switch jop := op.JumpOp(); jop { case Call: - if ins.Src == PseudoCall { + switch ins.Src { + case PseudoCall: // bpf-to-bpf call fmt.Fprint(f, ins.Constant) - } else { + case PseudoKfuncCall: + // kfunc call + fmt.Fprintf(f, "Kfunc(%d)", ins.Constant) + default: fmt.Fprint(f, BuiltinFunc(ins.Constant)) } @@ -270,42 +347,219 @@ func (ins Instruction) Format(f fmt.State, c rune) { } ref: - if ins.Reference != "" { - fmt.Fprintf(f, " <%s>", ins.Reference) + if ins.Reference() != "" { + fmt.Fprintf(f, " <%s>", ins.Reference()) } } +func (ins Instruction) equal(other Instruction) bool { + return ins.OpCode == other.OpCode && + ins.Dst == other.Dst && + ins.Src == other.Src && + ins.Offset == other.Offset && + ins.Constant == other.Constant +} + +// Size returns the amount of bytes ins would occupy in binary form. +func (ins Instruction) Size() uint64 { + return uint64(InstructionSize * ins.OpCode.rawInstructions()) +} + +// WithMetadata sets the given Metadata on the Instruction. e.g. to copy +// Metadata from another Instruction when replacing it. +func (ins Instruction) WithMetadata(meta Metadata) Instruction { + ins.Metadata = meta + return ins +} + +type symbolMeta struct{} + +// WithSymbol marks the Instruction as a Symbol, which other Instructions +// can point to using corresponding calls to WithReference. +func (ins Instruction) WithSymbol(name string) Instruction { + ins.Metadata.Set(symbolMeta{}, name) + return ins +} + +// Sym creates a symbol. +// +// Deprecated: use WithSymbol instead. +func (ins Instruction) Sym(name string) Instruction { + return ins.WithSymbol(name) +} + +// Symbol returns the value ins has been marked with using WithSymbol, +// otherwise returns an empty string. A symbol is often an Instruction +// at the start of a function body. +func (ins Instruction) Symbol() string { + sym, _ := ins.Metadata.Get(symbolMeta{}).(string) + return sym +} + +type referenceMeta struct{} + +// WithReference makes ins reference another Symbol or map by name. +func (ins Instruction) WithReference(ref string) Instruction { + ins.Metadata.Set(referenceMeta{}, ref) + return ins +} + +// Reference returns the Symbol or map name referenced by ins, if any. +func (ins Instruction) Reference() string { + ref, _ := ins.Metadata.Get(referenceMeta{}).(string) + return ref +} + +type mapMeta struct{} + +// Map returns the Map referenced by ins, if any. +// An Instruction will contain a Map if e.g. it references an existing, +// pinned map that was opened during ELF loading. +func (ins Instruction) Map() FDer { + fd, _ := ins.Metadata.Get(mapMeta{}).(FDer) + return fd +} + +type sourceMeta struct{} + +// WithSource adds source information about the Instruction. +func (ins Instruction) WithSource(src fmt.Stringer) Instruction { + ins.Metadata.Set(sourceMeta{}, src) + return ins +} + +// Source returns source information about the Instruction. The field is +// present when the compiler emits BTF line info about the Instruction and +// usually contains the line of source code responsible for it. +func (ins Instruction) Source() fmt.Stringer { + str, _ := ins.Metadata.Get(sourceMeta{}).(fmt.Stringer) + return str +} + +// A Comment can be passed to Instruction.WithSource to add a comment +// to an instruction. +type Comment string + +func (s Comment) String() string { + return string(s) +} + +// FDer represents a resource tied to an underlying file descriptor. +// Used as a stand-in for e.g. ebpf.Map since that type cannot be +// imported here and FD() is the only method we rely on. +type FDer interface { + FD() int +} + // Instructions is an eBPF program. type Instructions []Instruction +// Unmarshal unmarshals an Instructions from a binary instruction stream. +// All instructions in insns are replaced by instructions decoded from r. +func (insns *Instructions) Unmarshal(r io.Reader, bo binary.ByteOrder) error { + if len(*insns) > 0 { + *insns = nil + } + + var offset uint64 + for { + var ins Instruction + n, err := ins.Unmarshal(r, bo) + if errors.Is(err, io.EOF) { + break + } + if err != nil { + return fmt.Errorf("offset %d: %w", offset, err) + } + + *insns = append(*insns, ins) + offset += n + } + + return nil +} + +// Name returns the name of the function insns belongs to, if any. +func (insns Instructions) Name() string { + if len(insns) == 0 { + return "" + } + return insns[0].Symbol() +} + func (insns Instructions) String() string { return fmt.Sprint(insns) } +// Size returns the amount of bytes insns would occupy in binary form. +func (insns Instructions) Size() uint64 { + var sum uint64 + for _, ins := range insns { + sum += ins.Size() + } + return sum +} + +// AssociateMap updates all Instructions that Reference the given symbol +// to point to an existing Map m instead. +// +// Returns ErrUnreferencedSymbol error if no references to symbol are found +// in insns. If symbol is anything else than the symbol name of map (e.g. +// a bpf2bpf subprogram), an error is returned. +func (insns Instructions) AssociateMap(symbol string, m FDer) error { + if symbol == "" { + return errors.New("empty symbol") + } + + var found bool + for i := range insns { + ins := &insns[i] + if ins.Reference() != symbol { + continue + } + + if err := ins.AssociateMap(m); err != nil { + return err + } + + found = true + } + + if !found { + return fmt.Errorf("symbol %s: %w", symbol, ErrUnreferencedSymbol) + } + + return nil +} + // RewriteMapPtr rewrites all loads of a specific map pointer to a new fd. // -// Returns an error if the symbol isn't used, see IsUnreferencedSymbol. +// Returns ErrUnreferencedSymbol if the symbol isn't used. +// +// Deprecated: use AssociateMap instead. func (insns Instructions) RewriteMapPtr(symbol string, fd int) error { if symbol == "" { return errors.New("empty symbol") } - found := false + var found bool for i := range insns { ins := &insns[i] - if ins.Reference != symbol { + if ins.Reference() != symbol { continue } - if err := ins.RewriteMapPtr(fd); err != nil { - return err + if !ins.IsLoadFromMap() { + return errors.New("not a load from a map") } + ins.encodeMapFD(fd) + found = true } if !found { - return &unreferencedSymbolError{symbol} + return fmt.Errorf("symbol %s: %w", symbol, ErrUnreferencedSymbol) } return nil @@ -317,31 +571,61 @@ func (insns Instructions) SymbolOffsets() (map[string]int, error) { offsets := make(map[string]int) for i, ins := range insns { - if ins.Symbol == "" { + if ins.Symbol() == "" { continue } - if _, ok := offsets[ins.Symbol]; ok { - return nil, fmt.Errorf("duplicate symbol %s", ins.Symbol) + if _, ok := offsets[ins.Symbol()]; ok { + return nil, fmt.Errorf("duplicate symbol %s", ins.Symbol()) } - offsets[ins.Symbol] = i + offsets[ins.Symbol()] = i } return offsets, nil } +// FunctionReferences returns a set of symbol names these Instructions make +// bpf-to-bpf calls to. +func (insns Instructions) FunctionReferences() []string { + calls := make(map[string]struct{}) + for _, ins := range insns { + if ins.Constant != -1 { + // BPF-to-BPF calls have -1 constants. + continue + } + + if ins.Reference() == "" { + continue + } + + if !ins.IsFunctionReference() { + continue + } + + calls[ins.Reference()] = struct{}{} + } + + result := make([]string, 0, len(calls)) + for call := range calls { + result = append(result, call) + } + + sort.Strings(result) + return result +} + // ReferenceOffsets returns the set of references and their offset in // the instructions. func (insns Instructions) ReferenceOffsets() map[string][]int { offsets := make(map[string][]int) for i, ins := range insns { - if ins.Reference == "" { + if ins.Reference() == "" { continue } - offsets[ins.Reference] = append(offsets[ins.Reference], i) + offsets[ins.Reference()] = append(offsets[ins.Reference()], i) } return offsets @@ -392,18 +676,36 @@ func (insns Instructions) Format(f fmt.State, c rune) { iter := insns.Iterate() for iter.Next() { - if iter.Ins.Symbol != "" { - fmt.Fprintf(f, "%s%s:\n", symIndent, iter.Ins.Symbol) + if iter.Ins.Symbol() != "" { + fmt.Fprintf(f, "%s%s:\n", symIndent, iter.Ins.Symbol()) + } + if src := iter.Ins.Source(); src != nil { + line := strings.TrimSpace(src.String()) + if line != "" { + fmt.Fprintf(f, "%s%*s; %s\n", indent, offsetWidth, " ", line) + } } fmt.Fprintf(f, "%s%*d: %v\n", indent, offsetWidth, iter.Offset, iter.Ins) } } // Marshal encodes a BPF program into the kernel format. +// +// insns may be modified if there are unresolved jumps or bpf2bpf calls. +// +// Returns ErrUnsatisfiedProgramReference if there is a Reference Instruction +// without a matching Symbol Instruction within insns. func (insns Instructions) Marshal(w io.Writer, bo binary.ByteOrder) error { + if err := insns.encodeFunctionReferences(); err != nil { + return err + } + + if err := insns.encodeMapPointers(); err != nil { + return err + } + for i, ins := range insns { - _, err := ins.Marshal(w, bo) - if err != nil { + if _, err := ins.Marshal(w, bo); err != nil { return fmt.Errorf("instruction %d: %w", i, err) } } @@ -429,6 +731,95 @@ func (insns Instructions) Tag(bo binary.ByteOrder) (string, error) { return hex.EncodeToString(h.Sum(nil)[:unix.BPF_TAG_SIZE]), nil } +// encodeFunctionReferences populates the Offset (or Constant, depending on +// the instruction type) field of instructions with a Reference field to point +// to the offset of the corresponding instruction with a matching Symbol field. +// +// Only Reference Instructions that are either jumps or BPF function references +// (calls or function pointer loads) are populated. +// +// Returns ErrUnsatisfiedProgramReference if there is a Reference Instruction +// without at least one corresponding Symbol Instruction within insns. +func (insns Instructions) encodeFunctionReferences() error { + // Index the offsets of instructions tagged as a symbol. + symbolOffsets := make(map[string]RawInstructionOffset) + iter := insns.Iterate() + for iter.Next() { + ins := iter.Ins + + if ins.Symbol() == "" { + continue + } + + if _, ok := symbolOffsets[ins.Symbol()]; ok { + return fmt.Errorf("duplicate symbol %s", ins.Symbol()) + } + + symbolOffsets[ins.Symbol()] = iter.Offset + } + + // Find all instructions tagged as references to other symbols. + // Depending on the instruction type, populate their constant or offset + // fields to point to the symbol they refer to within the insn stream. + iter = insns.Iterate() + for iter.Next() { + i := iter.Index + offset := iter.Offset + ins := iter.Ins + + if ins.Reference() == "" { + continue + } + + switch { + case ins.IsFunctionReference() && ins.Constant == -1: + symOffset, ok := symbolOffsets[ins.Reference()] + if !ok { + return fmt.Errorf("%s at insn %d: symbol %q: %w", ins.OpCode, i, ins.Reference(), ErrUnsatisfiedProgramReference) + } + + ins.Constant = int64(symOffset - offset - 1) + + case ins.OpCode.Class().IsJump() && ins.Offset == -1: + symOffset, ok := symbolOffsets[ins.Reference()] + if !ok { + return fmt.Errorf("%s at insn %d: symbol %q: %w", ins.OpCode, i, ins.Reference(), ErrUnsatisfiedProgramReference) + } + + ins.Offset = int16(symOffset - offset - 1) + } + } + + return nil +} + +// encodeMapPointers finds all Map Instructions and encodes their FDs +// into their Constant fields. +func (insns Instructions) encodeMapPointers() error { + iter := insns.Iterate() + for iter.Next() { + ins := iter.Ins + + if !ins.IsLoadFromMap() { + continue + } + + m := ins.Map() + if m == nil { + continue + } + + fd := m.FD() + if fd < 0 { + return fmt.Errorf("map %s: %w", m, sys.ErrClosedFd) + } + + ins.encodeMapFD(m.FD()) + } + + return nil +} + // Iterate allows iterating a BPF program while keeping track of // various offsets. // @@ -464,13 +855,6 @@ func (iter *InstructionIterator) Next() bool { return true } -type bpfInstruction struct { - OpCode OpCode - Registers bpfRegisters - Offset int16 - Constant int32 -} - type bpfRegisters uint8 func newBPFRegisters(dst, src Register, bo binary.ByteOrder) (bpfRegisters, error) { @@ -484,28 +868,10 @@ func newBPFRegisters(dst, src Register, bo binary.ByteOrder) (bpfRegisters, erro } } -func (r bpfRegisters) Unmarshal(bo binary.ByteOrder) (dst, src Register, err error) { - switch bo { - case binary.LittleEndian: - return Register(r & 0xF), Register(r >> 4), nil - case binary.BigEndian: - return Register(r >> 4), Register(r & 0xf), nil - default: - return 0, 0, fmt.Errorf("unrecognized ByteOrder %T", bo) - } -} - -type unreferencedSymbolError struct { - symbol string -} - -func (use *unreferencedSymbolError) Error() string { - return fmt.Sprintf("unreferenced symbol %s", use.symbol) -} - // IsUnreferencedSymbol returns true if err was caused by // an unreferenced symbol. +// +// Deprecated: use errors.Is(err, asm.ErrUnreferencedSymbol). func IsUnreferencedSymbol(err error) bool { - _, ok := err.(*unreferencedSymbolError) - return ok + return errors.Is(err, ErrUnreferencedSymbol) } diff --git a/vendor/github.com/cilium/ebpf/asm/jump.go b/vendor/github.com/cilium/ebpf/asm/jump.go index 7757179de6..2c8a3dbb7a 100644 --- a/vendor/github.com/cilium/ebpf/asm/jump.go +++ b/vendor/github.com/cilium/ebpf/asm/jump.go @@ -4,10 +4,10 @@ package asm // JumpOp affect control flow. // -// msb lsb -// +----+-+---+ -// |OP |s|cls| -// +----+-+---+ +// msb lsb +// +----+-+---+ +// |OP |s|cls| +// +----+-+---+ type JumpOp uint8 const jumpMask OpCode = aluMask @@ -60,50 +60,68 @@ func (op JumpOp) Op(source Source) OpCode { return OpCode(JumpClass).SetJumpOp(op).SetSource(source) } -// Imm compares dst to value, and adjusts PC by offset if the condition is fulfilled. +// Imm compares 64 bit dst to 64 bit value (sign extended), and adjusts PC by offset if the condition is fulfilled. func (op JumpOp) Imm(dst Register, value int32, label string) Instruction { - if op == Exit || op == Call || op == Ja { - return Instruction{OpCode: InvalidOpCode} - } + return Instruction{ + OpCode: op.opCode(JumpClass, ImmSource), + Dst: dst, + Offset: -1, + Constant: int64(value), + }.WithReference(label) +} +// Imm32 compares 32 bit dst to 32 bit value, and adjusts PC by offset if the condition is fulfilled. +// Requires kernel 5.1. +func (op JumpOp) Imm32(dst Register, value int32, label string) Instruction { return Instruction{ - OpCode: OpCode(JumpClass).SetJumpOp(op).SetSource(ImmSource), - Dst: dst, - Offset: -1, - Constant: int64(value), - Reference: label, - } + OpCode: op.opCode(Jump32Class, ImmSource), + Dst: dst, + Offset: -1, + Constant: int64(value), + }.WithReference(label) } -// Reg compares dst to src, and adjusts PC by offset if the condition is fulfilled. +// Reg compares 64 bit dst to 64 bit src, and adjusts PC by offset if the condition is fulfilled. func (op JumpOp) Reg(dst, src Register, label string) Instruction { - if op == Exit || op == Call || op == Ja { - return Instruction{OpCode: InvalidOpCode} - } + return Instruction{ + OpCode: op.opCode(JumpClass, RegSource), + Dst: dst, + Src: src, + Offset: -1, + }.WithReference(label) +} +// Reg32 compares 32 bit dst to 32 bit src, and adjusts PC by offset if the condition is fulfilled. +// Requires kernel 5.1. +func (op JumpOp) Reg32(dst, src Register, label string) Instruction { return Instruction{ - OpCode: OpCode(JumpClass).SetJumpOp(op).SetSource(RegSource), - Dst: dst, - Src: src, - Offset: -1, - Reference: label, + OpCode: op.opCode(Jump32Class, RegSource), + Dst: dst, + Src: src, + Offset: -1, + }.WithReference(label) +} + +func (op JumpOp) opCode(class Class, source Source) OpCode { + if op == Exit || op == Call || op == Ja { + return InvalidOpCode } + + return OpCode(class).SetJumpOp(op).SetSource(source) } // Label adjusts PC to the address of the label. func (op JumpOp) Label(label string) Instruction { if op == Call { return Instruction{ - OpCode: OpCode(JumpClass).SetJumpOp(Call), - Src: PseudoCall, - Constant: -1, - Reference: label, - } + OpCode: OpCode(JumpClass).SetJumpOp(Call), + Src: PseudoCall, + Constant: -1, + }.WithReference(label) } return Instruction{ - OpCode: OpCode(JumpClass).SetJumpOp(op), - Offset: -1, - Reference: label, - } + OpCode: OpCode(JumpClass).SetJumpOp(op), + Offset: -1, + }.WithReference(label) } diff --git a/vendor/github.com/cilium/ebpf/asm/load_store.go b/vendor/github.com/cilium/ebpf/asm/load_store.go index 85ed286b02..f109497aeb 100644 --- a/vendor/github.com/cilium/ebpf/asm/load_store.go +++ b/vendor/github.com/cilium/ebpf/asm/load_store.go @@ -4,10 +4,10 @@ package asm // Mode for load and store operations // -// msb lsb -// +---+--+---+ -// |MDE|sz|cls| -// +---+--+---+ +// msb lsb +// +---+--+---+ +// |MDE|sz|cls| +// +---+--+---+ type Mode uint8 const modeMask OpCode = 0xe0 @@ -30,10 +30,10 @@ const ( // Size of load and store operations // -// msb lsb -// +---+--+---+ -// |mde|SZ|cls| -// +---+--+---+ +// msb lsb +// +---+--+---+ +// |mde|SZ|cls| +// +---+--+---+ type Size uint8 const sizeMask OpCode = 0x18 diff --git a/vendor/github.com/cilium/ebpf/asm/metadata.go b/vendor/github.com/cilium/ebpf/asm/metadata.go new file mode 100644 index 0000000000..dd368a9360 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/asm/metadata.go @@ -0,0 +1,80 @@ +package asm + +// Metadata contains metadata about an instruction. +type Metadata struct { + head *metaElement +} + +type metaElement struct { + next *metaElement + key, value interface{} +} + +// Find the element containing key. +// +// Returns nil if there is no such element. +func (m *Metadata) find(key interface{}) *metaElement { + for e := m.head; e != nil; e = e.next { + if e.key == key { + return e + } + } + return nil +} + +// Remove an element from the linked list. +// +// Copies as many elements of the list as necessary to remove r, but doesn't +// perform a full copy. +func (m *Metadata) remove(r *metaElement) { + current := &m.head + for e := m.head; e != nil; e = e.next { + if e == r { + // We've found the element we want to remove. + *current = e.next + + // No need to copy the tail. + return + } + + // There is another element in front of the one we want to remove. + // We have to copy it to be able to change metaElement.next. + cpy := &metaElement{key: e.key, value: e.value} + *current = cpy + current = &cpy.next + } +} + +// Set a key to a value. +// +// If value is nil, the key is removed. Avoids modifying old metadata by +// copying if necessary. +func (m *Metadata) Set(key, value interface{}) { + if e := m.find(key); e != nil { + if e.value == value { + // Key is present and the value is the same. Nothing to do. + return + } + + // Key is present with a different value. Create a copy of the list + // which doesn't have the element in it. + m.remove(e) + } + + // m.head is now a linked list that doesn't contain key. + if value == nil { + return + } + + m.head = &metaElement{key: key, value: value, next: m.head} +} + +// Get the value of a key. +// +// Returns nil if no value with the given key is present. +func (m *Metadata) Get(key interface{}) interface{} { + if e := m.find(key); e != nil { + return e.value + } + return nil +} diff --git a/vendor/github.com/cilium/ebpf/asm/opcode.go b/vendor/github.com/cilium/ebpf/asm/opcode.go index 6edc3cf591..9e3c30b0b3 100644 --- a/vendor/github.com/cilium/ebpf/asm/opcode.go +++ b/vendor/github.com/cilium/ebpf/asm/opcode.go @@ -7,60 +7,73 @@ import ( //go:generate stringer -output opcode_string.go -type=Class -type encoding int - -const ( - unknownEncoding encoding = iota - loadOrStore - jumpOrALU -) - // Class of operations // -// msb lsb -// +---+--+---+ -// | ?? |CLS| -// +---+--+---+ +// msb lsb +// +---+--+---+ +// | ?? |CLS| +// +---+--+---+ type Class uint8 const classMask OpCode = 0x07 const ( - // LdClass load memory + // LdClass loads immediate values into registers. + // Also used for non-standard load operations from cBPF. LdClass Class = 0x00 - // LdXClass load memory from constant + // LdXClass loads memory into registers. LdXClass Class = 0x01 - // StClass load register from memory + // StClass stores immediate values to memory. StClass Class = 0x02 - // StXClass load register from constant + // StXClass stores registers to memory. StXClass Class = 0x03 - // ALUClass arithmetic operators + // ALUClass describes arithmetic operators. ALUClass Class = 0x04 - // JumpClass jump operators + // JumpClass describes jump operators. JumpClass Class = 0x05 - // ALU64Class arithmetic in 64 bit mode + // Jump32Class describes jump operators with 32-bit comparisons. + // Requires kernel 5.1. + Jump32Class Class = 0x06 + // ALU64Class describes arithmetic operators in 64-bit mode. ALU64Class Class = 0x07 ) -func (cls Class) encoding() encoding { - switch cls { - case LdClass, LdXClass, StClass, StXClass: - return loadOrStore - case ALU64Class, ALUClass, JumpClass: - return jumpOrALU - default: - return unknownEncoding - } +// IsLoad checks if this is either LdClass or LdXClass. +func (cls Class) IsLoad() bool { + return cls == LdClass || cls == LdXClass +} + +// IsStore checks if this is either StClass or StXClass. +func (cls Class) IsStore() bool { + return cls == StClass || cls == StXClass +} + +func (cls Class) isLoadOrStore() bool { + return cls.IsLoad() || cls.IsStore() +} + +// IsALU checks if this is either ALUClass or ALU64Class. +func (cls Class) IsALU() bool { + return cls == ALUClass || cls == ALU64Class +} + +// IsJump checks if this is either JumpClass or Jump32Class. +func (cls Class) IsJump() bool { + return cls == JumpClass || cls == Jump32Class +} + +func (cls Class) isJumpOrALU() bool { + return cls.IsJump() || cls.IsALU() } // OpCode is a packed eBPF opcode. // // Its encoding is defined by a Class value: // -// msb lsb -// +----+-+---+ -// | ???? |CLS| -// +----+-+---+ +// msb lsb +// +----+-+---+ +// | ???? |CLS| +// +----+-+---+ type OpCode uint8 // InvalidOpCode is returned by setters on OpCode @@ -86,7 +99,7 @@ func (op OpCode) Class() Class { // Mode returns the mode for load and store operations. func (op OpCode) Mode() Mode { - if op.Class().encoding() != loadOrStore { + if !op.Class().isLoadOrStore() { return InvalidMode } return Mode(op & modeMask) @@ -94,7 +107,7 @@ func (op OpCode) Mode() Mode { // Size returns the size for load and store operations. func (op OpCode) Size() Size { - if op.Class().encoding() != loadOrStore { + if !op.Class().isLoadOrStore() { return InvalidSize } return Size(op & sizeMask) @@ -102,7 +115,7 @@ func (op OpCode) Size() Size { // Source returns the source for branch and ALU operations. func (op OpCode) Source() Source { - if op.Class().encoding() != jumpOrALU || op.ALUOp() == Swap { + if !op.Class().isJumpOrALU() || op.ALUOp() == Swap { return InvalidSource } return Source(op & sourceMask) @@ -110,7 +123,7 @@ func (op OpCode) Source() Source { // ALUOp returns the ALUOp. func (op OpCode) ALUOp() ALUOp { - if op.Class().encoding() != jumpOrALU { + if !op.Class().IsALU() { return InvalidALUOp } return ALUOp(op & aluMask) @@ -125,18 +138,27 @@ func (op OpCode) Endianness() Endianness { } // JumpOp returns the JumpOp. +// Returns InvalidJumpOp if it doesn't encode a jump. func (op OpCode) JumpOp() JumpOp { - if op.Class().encoding() != jumpOrALU { + if !op.Class().IsJump() { return InvalidJumpOp } - return JumpOp(op & jumpMask) + + jumpOp := JumpOp(op & jumpMask) + + // Some JumpOps are only supported by JumpClass, not Jump32Class. + if op.Class() == Jump32Class && (jumpOp == Exit || jumpOp == Call || jumpOp == Ja) { + return InvalidJumpOp + } + + return jumpOp } // SetMode sets the mode on load and store operations. // // Returns InvalidOpCode if op is of the wrong class. func (op OpCode) SetMode(mode Mode) OpCode { - if op.Class().encoding() != loadOrStore || !valid(OpCode(mode), modeMask) { + if !op.Class().isLoadOrStore() || !valid(OpCode(mode), modeMask) { return InvalidOpCode } return (op & ^modeMask) | OpCode(mode) @@ -146,7 +168,7 @@ func (op OpCode) SetMode(mode Mode) OpCode { // // Returns InvalidOpCode if op is of the wrong class. func (op OpCode) SetSize(size Size) OpCode { - if op.Class().encoding() != loadOrStore || !valid(OpCode(size), sizeMask) { + if !op.Class().isLoadOrStore() || !valid(OpCode(size), sizeMask) { return InvalidOpCode } return (op & ^sizeMask) | OpCode(size) @@ -156,7 +178,7 @@ func (op OpCode) SetSize(size Size) OpCode { // // Returns InvalidOpCode if op is of the wrong class. func (op OpCode) SetSource(source Source) OpCode { - if op.Class().encoding() != jumpOrALU || !valid(OpCode(source), sourceMask) { + if !op.Class().isJumpOrALU() || !valid(OpCode(source), sourceMask) { return InvalidOpCode } return (op & ^sourceMask) | OpCode(source) @@ -166,8 +188,7 @@ func (op OpCode) SetSource(source Source) OpCode { // // Returns InvalidOpCode if op is of the wrong class. func (op OpCode) SetALUOp(alu ALUOp) OpCode { - class := op.Class() - if (class != ALUClass && class != ALU64Class) || !valid(OpCode(alu), aluMask) { + if !op.Class().IsALU() || !valid(OpCode(alu), aluMask) { return InvalidOpCode } return (op & ^aluMask) | OpCode(alu) @@ -177,17 +198,25 @@ func (op OpCode) SetALUOp(alu ALUOp) OpCode { // // Returns InvalidOpCode if op is of the wrong class. func (op OpCode) SetJumpOp(jump JumpOp) OpCode { - if op.Class() != JumpClass || !valid(OpCode(jump), jumpMask) { + if !op.Class().IsJump() || !valid(OpCode(jump), jumpMask) { + return InvalidOpCode + } + + newOp := (op & ^jumpMask) | OpCode(jump) + + // Check newOp is legal. + if newOp.JumpOp() == InvalidJumpOp { return InvalidOpCode } - return (op & ^jumpMask) | OpCode(jump) + + return newOp } func (op OpCode) String() string { var f strings.Builder - switch class := op.Class(); class { - case LdClass, LdXClass, StClass, StXClass: + switch class := op.Class(); { + case class.isLoadOrStore(): f.WriteString(strings.TrimSuffix(class.String(), "Class")) mode := op.Mode() @@ -204,7 +233,7 @@ func (op OpCode) String() string { f.WriteString("B") } - case ALU64Class, ALUClass: + case class.IsALU(): f.WriteString(op.ALUOp().String()) if op.ALUOp() == Swap { @@ -218,8 +247,13 @@ func (op OpCode) String() string { f.WriteString(strings.TrimSuffix(op.Source().String(), "Source")) } - case JumpClass: + case class.IsJump(): f.WriteString(op.JumpOp().String()) + + if class == Jump32Class { + f.WriteString("32") + } + if jop := op.JumpOp(); jop != Exit && jop != Call { f.WriteString(strings.TrimSuffix(op.Source().String(), "Source")) } diff --git a/vendor/github.com/cilium/ebpf/asm/opcode_string.go b/vendor/github.com/cilium/ebpf/asm/opcode_string.go index 079ce1db0b..58bc3e7e7f 100644 --- a/vendor/github.com/cilium/ebpf/asm/opcode_string.go +++ b/vendor/github.com/cilium/ebpf/asm/opcode_string.go @@ -14,25 +14,17 @@ func _() { _ = x[StXClass-3] _ = x[ALUClass-4] _ = x[JumpClass-5] + _ = x[Jump32Class-6] _ = x[ALU64Class-7] } -const ( - _Class_name_0 = "LdClassLdXClassStClassStXClassALUClassJumpClass" - _Class_name_1 = "ALU64Class" -) +const _Class_name = "LdClassLdXClassStClassStXClassALUClassJumpClassJump32ClassALU64Class" -var ( - _Class_index_0 = [...]uint8{0, 7, 15, 22, 30, 38, 47} -) +var _Class_index = [...]uint8{0, 7, 15, 22, 30, 38, 47, 58, 68} func (i Class) String() string { - switch { - case 0 <= i && i <= 5: - return _Class_name_0[_Class_index_0[i]:_Class_index_0[i+1]] - case i == 7: - return _Class_name_1 - default: + if i >= Class(len(_Class_index)-1) { return "Class(" + strconv.FormatInt(int64(i), 10) + ")" } + return _Class_name[_Class_index[i]:_Class_index[i+1]] } diff --git a/vendor/github.com/cilium/ebpf/asm/register.go b/vendor/github.com/cilium/ebpf/asm/register.go index 76cb44bffc..457a3b8a88 100644 --- a/vendor/github.com/cilium/ebpf/asm/register.go +++ b/vendor/github.com/cilium/ebpf/asm/register.go @@ -35,9 +35,11 @@ const ( // Pseudo registers used by 64bit loads and jumps const ( - PseudoMapFD = R1 // BPF_PSEUDO_MAP_FD - PseudoMapValue = R2 // BPF_PSEUDO_MAP_VALUE - PseudoCall = R1 // BPF_PSEUDO_CALL + PseudoMapFD = R1 // BPF_PSEUDO_MAP_FD + PseudoMapValue = R2 // BPF_PSEUDO_MAP_VALUE + PseudoCall = R1 // BPF_PSEUDO_CALL + PseudoFunc = R4 // BPF_PSEUDO_FUNC + PseudoKfuncCall = R2 // BPF_PSEUDO_KFUNC_CALL ) func (r Register) String() string { diff --git a/vendor/github.com/cilium/ebpf/attachtype_string.go b/vendor/github.com/cilium/ebpf/attachtype_string.go index de355ed909..add2a3b5cc 100644 --- a/vendor/github.com/cilium/ebpf/attachtype_string.go +++ b/vendor/github.com/cilium/ebpf/attachtype_string.go @@ -51,11 +51,12 @@ func _() { _ = x[AttachSkReuseportSelect-39] _ = x[AttachSkReuseportSelectOrMigrate-40] _ = x[AttachPerfEvent-41] + _ = x[AttachTraceKprobeMulti-42] } -const _AttachType_name = "NoneCGroupInetEgressCGroupInetSockCreateCGroupSockOpsSkSKBStreamParserSkSKBStreamVerdictCGroupDeviceSkMsgVerdictCGroupInet4BindCGroupInet6BindCGroupInet4ConnectCGroupInet6ConnectCGroupInet4PostBindCGroupInet6PostBindCGroupUDP4SendmsgCGroupUDP6SendmsgLircMode2FlowDissectorCGroupSysctlCGroupUDP4RecvmsgCGroupUDP6RecvmsgCGroupGetsockoptCGroupSetsockoptTraceRawTpTraceFEntryTraceFExitModifyReturnLSMMacTraceIterCgroupInet4GetPeernameCgroupInet6GetPeernameCgroupInet4GetSocknameCgroupInet6GetSocknameXDPDevMapCgroupInetSockReleaseXDPCPUMapSkLookupXDPSkSKBVerdictSkReuseportSelectSkReuseportSelectOrMigratePerfEvent" +const _AttachType_name = "NoneCGroupInetEgressCGroupInetSockCreateCGroupSockOpsSkSKBStreamParserSkSKBStreamVerdictCGroupDeviceSkMsgVerdictCGroupInet4BindCGroupInet6BindCGroupInet4ConnectCGroupInet6ConnectCGroupInet4PostBindCGroupInet6PostBindCGroupUDP4SendmsgCGroupUDP6SendmsgLircMode2FlowDissectorCGroupSysctlCGroupUDP4RecvmsgCGroupUDP6RecvmsgCGroupGetsockoptCGroupSetsockoptTraceRawTpTraceFEntryTraceFExitModifyReturnLSMMacTraceIterCgroupInet4GetPeernameCgroupInet6GetPeernameCgroupInet4GetSocknameCgroupInet6GetSocknameXDPDevMapCgroupInetSockReleaseXDPCPUMapSkLookupXDPSkSKBVerdictSkReuseportSelectSkReuseportSelectOrMigratePerfEventTraceKprobeMulti" -var _AttachType_index = [...]uint16{0, 4, 20, 40, 53, 70, 88, 100, 112, 127, 142, 160, 178, 197, 216, 233, 250, 259, 272, 284, 301, 318, 334, 350, 360, 371, 381, 393, 399, 408, 430, 452, 474, 496, 505, 526, 535, 543, 546, 558, 575, 601, 610} +var _AttachType_index = [...]uint16{0, 4, 20, 40, 53, 70, 88, 100, 112, 127, 142, 160, 178, 197, 216, 233, 250, 259, 272, 284, 301, 318, 334, 350, 360, 371, 381, 393, 399, 408, 430, 452, 474, 496, 505, 526, 535, 543, 546, 558, 575, 601, 610, 626} func (i AttachType) String() string { if i >= AttachType(len(_AttachType_index)-1) { diff --git a/vendor/github.com/cilium/ebpf/btf/btf.go b/vendor/github.com/cilium/ebpf/btf/btf.go new file mode 100644 index 0000000000..86eb7d6819 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/btf/btf.go @@ -0,0 +1,869 @@ +package btf + +import ( + "bufio" + "debug/elf" + "encoding/binary" + "errors" + "fmt" + "io" + "math" + "os" + "reflect" + "sync" + + "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/sys" + "github.com/cilium/ebpf/internal/unix" +) + +const btfMagic = 0xeB9F + +// Errors returned by BTF functions. +var ( + ErrNotSupported = internal.ErrNotSupported + ErrNotFound = errors.New("not found") + ErrNoExtendedInfo = errors.New("no extended info") + ErrMultipleMatches = errors.New("multiple matching types") +) + +// ID represents the unique ID of a BTF object. +type ID = sys.BTFID + +// Spec allows querying a set of Types and loading the set into the +// kernel. +type Spec struct { + // All types contained by the spec, not including types from the base in + // case the spec was parsed from split BTF. + types []Type + + // Type IDs indexed by type. + typeIDs map[Type]TypeID + + // The ID of the first type in types. + firstTypeID TypeID + + // Types indexed by essential name. + // Includes all struct flavors and types with the same name. + namedTypes map[essentialName][]Type + + // String table from ELF, may be nil. + strings *stringTable + + // Byte order of the ELF we decoded the spec from, may be nil. + byteOrder binary.ByteOrder +} + +var btfHeaderLen = binary.Size(&btfHeader{}) + +type btfHeader struct { + Magic uint16 + Version uint8 + Flags uint8 + HdrLen uint32 + + TypeOff uint32 + TypeLen uint32 + StringOff uint32 + StringLen uint32 +} + +// typeStart returns the offset from the beginning of the .BTF section +// to the start of its type entries. +func (h *btfHeader) typeStart() int64 { + return int64(h.HdrLen + h.TypeOff) +} + +// stringStart returns the offset from the beginning of the .BTF section +// to the start of its string table. +func (h *btfHeader) stringStart() int64 { + return int64(h.HdrLen + h.StringOff) +} + +// newSpec creates a Spec containing only Void. +func newSpec() *Spec { + return &Spec{ + []Type{(*Void)(nil)}, + map[Type]TypeID{(*Void)(nil): 0}, + 0, + make(map[essentialName][]Type), + nil, + nil, + } +} + +// LoadSpec opens file and calls LoadSpecFromReader on it. +func LoadSpec(file string) (*Spec, error) { + fh, err := os.Open(file) + if err != nil { + return nil, err + } + defer fh.Close() + + return LoadSpecFromReader(fh) +} + +// LoadSpecFromReader reads from an ELF or a raw BTF blob. +// +// Returns ErrNotFound if reading from an ELF which contains no BTF. ExtInfos +// may be nil. +func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) { + file, err := internal.NewSafeELFFile(rd) + if err != nil { + if bo := guessRawBTFByteOrder(rd); bo != nil { + return loadRawSpec(io.NewSectionReader(rd, 0, math.MaxInt64), bo, nil) + } + + return nil, err + } + + return loadSpecFromELF(file) +} + +// LoadSpecAndExtInfosFromReader reads from an ELF. +// +// ExtInfos may be nil if the ELF doesn't contain section metadata. +// Returns ErrNotFound if the ELF contains no BTF. +func LoadSpecAndExtInfosFromReader(rd io.ReaderAt) (*Spec, *ExtInfos, error) { + file, err := internal.NewSafeELFFile(rd) + if err != nil { + return nil, nil, err + } + + spec, err := loadSpecFromELF(file) + if err != nil { + return nil, nil, err + } + + extInfos, err := loadExtInfosFromELF(file, spec) + if err != nil && !errors.Is(err, ErrNotFound) { + return nil, nil, err + } + + return spec, extInfos, nil +} + +// symbolOffsets extracts all symbols offsets from an ELF and indexes them by +// section and variable name. +// +// References to variables in BTF data sections carry unsigned 32-bit offsets. +// Some ELF symbols (e.g. in vmlinux) may point to virtual memory that is well +// beyond this range. Since these symbols cannot be described by BTF info, +// ignore them here. +func symbolOffsets(file *internal.SafeELFFile) (map[symbol]uint32, error) { + symbols, err := file.Symbols() + if err != nil { + return nil, fmt.Errorf("can't read symbols: %v", err) + } + + offsets := make(map[symbol]uint32) + for _, sym := range symbols { + if idx := sym.Section; idx >= elf.SHN_LORESERVE && idx <= elf.SHN_HIRESERVE { + // Ignore things like SHN_ABS + continue + } + + if sym.Value > math.MaxUint32 { + // VarSecinfo offset is u32, cannot reference symbols in higher regions. + continue + } + + if int(sym.Section) >= len(file.Sections) { + return nil, fmt.Errorf("symbol %s: invalid section %d", sym.Name, sym.Section) + } + + secName := file.Sections[sym.Section].Name + offsets[symbol{secName, sym.Name}] = uint32(sym.Value) + } + + return offsets, nil +} + +func loadSpecFromELF(file *internal.SafeELFFile) (*Spec, error) { + var ( + btfSection *elf.Section + sectionSizes = make(map[string]uint32) + ) + + for _, sec := range file.Sections { + switch sec.Name { + case ".BTF": + btfSection = sec + default: + if sec.Type != elf.SHT_PROGBITS && sec.Type != elf.SHT_NOBITS { + break + } + + if sec.Size > math.MaxUint32 { + return nil, fmt.Errorf("section %s exceeds maximum size", sec.Name) + } + + sectionSizes[sec.Name] = uint32(sec.Size) + } + } + + if btfSection == nil { + return nil, fmt.Errorf("btf: %w", ErrNotFound) + } + + offsets, err := symbolOffsets(file) + if err != nil { + return nil, err + } + + if btfSection.ReaderAt == nil { + return nil, fmt.Errorf("compressed BTF is not supported") + } + + spec, err := loadRawSpec(btfSection.ReaderAt, file.ByteOrder, nil) + if err != nil { + return nil, err + } + + err = fixupDatasec(spec.types, sectionSizes, offsets) + if err != nil { + return nil, err + } + + return spec, nil +} + +func loadRawSpec(btf io.ReaderAt, bo binary.ByteOrder, base *Spec) (*Spec, error) { + var ( + baseStrings *stringTable + firstTypeID TypeID + err error + ) + + if base != nil { + if base.firstTypeID != 0 { + return nil, fmt.Errorf("can't use split BTF as base") + } + + if base.strings == nil { + return nil, fmt.Errorf("parse split BTF: base must be loaded from an ELF") + } + + baseStrings = base.strings + + firstTypeID, err = base.nextTypeID() + if err != nil { + return nil, err + } + } + + rawTypes, rawStrings, err := parseBTF(btf, bo, baseStrings) + if err != nil { + return nil, err + } + + types, err := inflateRawTypes(rawTypes, rawStrings, base) + if err != nil { + return nil, err + } + + typeIDs, typesByName := indexTypes(types, firstTypeID) + + return &Spec{ + namedTypes: typesByName, + typeIDs: typeIDs, + types: types, + firstTypeID: firstTypeID, + strings: rawStrings, + byteOrder: bo, + }, nil +} + +func indexTypes(types []Type, firstTypeID TypeID) (map[Type]TypeID, map[essentialName][]Type) { + namedTypes := 0 + for _, typ := range types { + if typ.TypeName() != "" { + // Do a pre-pass to figure out how big types by name has to be. + // Most types have unique names, so it's OK to ignore essentialName + // here. + namedTypes++ + } + } + + typeIDs := make(map[Type]TypeID, len(types)) + typesByName := make(map[essentialName][]Type, namedTypes) + + for i, typ := range types { + if name := newEssentialName(typ.TypeName()); name != "" { + typesByName[name] = append(typesByName[name], typ) + } + typeIDs[typ] = firstTypeID + TypeID(i) + } + + return typeIDs, typesByName +} + +// LoadKernelSpec returns the current kernel's BTF information. +// +// Defaults to /sys/kernel/btf/vmlinux and falls back to scanning the file system +// for vmlinux ELFs. Returns an error wrapping ErrNotSupported if BTF is not enabled. +func LoadKernelSpec() (*Spec, error) { + spec, _, err := kernelSpec() + if err != nil { + return nil, err + } + return spec.Copy(), nil +} + +var kernelBTF struct { + sync.RWMutex + spec *Spec + // True if the spec was read from an ELF instead of raw BTF in /sys. + fallback bool +} + +// FlushKernelSpec removes any cached kernel type information. +func FlushKernelSpec() { + kernelBTF.Lock() + defer kernelBTF.Unlock() + + kernelBTF.spec, kernelBTF.fallback = nil, false +} + +func kernelSpec() (*Spec, bool, error) { + kernelBTF.RLock() + spec, fallback := kernelBTF.spec, kernelBTF.fallback + kernelBTF.RUnlock() + + if spec == nil { + kernelBTF.Lock() + defer kernelBTF.Unlock() + + spec, fallback = kernelBTF.spec, kernelBTF.fallback + } + + if spec != nil { + return spec, fallback, nil + } + + spec, fallback, err := loadKernelSpec() + if err != nil { + return nil, false, err + } + + kernelBTF.spec, kernelBTF.fallback = spec, fallback + return spec, fallback, nil +} + +func loadKernelSpec() (_ *Spec, fallback bool, _ error) { + fh, err := os.Open("/sys/kernel/btf/vmlinux") + if err == nil { + defer fh.Close() + + spec, err := loadRawSpec(fh, internal.NativeEndian, nil) + return spec, false, err + } + + file, err := findVMLinux() + if err != nil { + return nil, false, err + } + defer file.Close() + + spec, err := loadSpecFromELF(file) + return spec, true, err +} + +// findVMLinux scans multiple well-known paths for vmlinux kernel images. +func findVMLinux() (*internal.SafeELFFile, error) { + release, err := internal.KernelRelease() + if err != nil { + return nil, err + } + + // use same list of locations as libbpf + // https://github.com/libbpf/libbpf/blob/9a3a42608dbe3731256a5682a125ac1e23bced8f/src/btf.c#L3114-L3122 + locations := []string{ + "/boot/vmlinux-%s", + "/lib/modules/%s/vmlinux-%[1]s", + "/lib/modules/%s/build/vmlinux", + "/usr/lib/modules/%s/kernel/vmlinux", + "/usr/lib/debug/boot/vmlinux-%s", + "/usr/lib/debug/boot/vmlinux-%s.debug", + "/usr/lib/debug/lib/modules/%s/vmlinux", + } + + for _, loc := range locations { + file, err := internal.OpenSafeELFFile(fmt.Sprintf(loc, release)) + if errors.Is(err, os.ErrNotExist) { + continue + } + return file, err + } + + return nil, fmt.Errorf("no BTF found for kernel version %s: %w", release, internal.ErrNotSupported) +} + +// parseBTFHeader parses the header of the .BTF section. +func parseBTFHeader(r io.Reader, bo binary.ByteOrder) (*btfHeader, error) { + var header btfHeader + if err := binary.Read(r, bo, &header); err != nil { + return nil, fmt.Errorf("can't read header: %v", err) + } + + if header.Magic != btfMagic { + return nil, fmt.Errorf("incorrect magic value %v", header.Magic) + } + + if header.Version != 1 { + return nil, fmt.Errorf("unexpected version %v", header.Version) + } + + if header.Flags != 0 { + return nil, fmt.Errorf("unsupported flags %v", header.Flags) + } + + remainder := int64(header.HdrLen) - int64(binary.Size(&header)) + if remainder < 0 { + return nil, errors.New("header length shorter than btfHeader size") + } + + if _, err := io.CopyN(internal.DiscardZeroes{}, r, remainder); err != nil { + return nil, fmt.Errorf("header padding: %v", err) + } + + return &header, nil +} + +func guessRawBTFByteOrder(r io.ReaderAt) binary.ByteOrder { + buf := new(bufio.Reader) + for _, bo := range []binary.ByteOrder{ + binary.LittleEndian, + binary.BigEndian, + } { + buf.Reset(io.NewSectionReader(r, 0, math.MaxInt64)) + if _, err := parseBTFHeader(buf, bo); err == nil { + return bo + } + } + + return nil +} + +// parseBTF reads a .BTF section into memory and parses it into a list of +// raw types and a string table. +func parseBTF(btf io.ReaderAt, bo binary.ByteOrder, baseStrings *stringTable) ([]rawType, *stringTable, error) { + buf := internal.NewBufferedSectionReader(btf, 0, math.MaxInt64) + header, err := parseBTFHeader(buf, bo) + if err != nil { + return nil, nil, fmt.Errorf("parsing .BTF header: %v", err) + } + + rawStrings, err := readStringTable(io.NewSectionReader(btf, header.stringStart(), int64(header.StringLen)), + baseStrings) + if err != nil { + return nil, nil, fmt.Errorf("can't read type names: %w", err) + } + + buf.Reset(io.NewSectionReader(btf, header.typeStart(), int64(header.TypeLen))) + rawTypes, err := readTypes(buf, bo, header.TypeLen) + if err != nil { + return nil, nil, fmt.Errorf("can't read types: %w", err) + } + + return rawTypes, rawStrings, nil +} + +type symbol struct { + section string + name string +} + +// fixupDatasec attempts to patch up missing info in Datasecs and its members by +// supplementing them with information from the ELF headers and symbol table. +func fixupDatasec(types []Type, sectionSizes map[string]uint32, offsets map[symbol]uint32) error { + for _, typ := range types { + ds, ok := typ.(*Datasec) + if !ok { + continue + } + + name := ds.Name + + // Some Datasecs are virtual and don't have corresponding ELF sections. + switch name { + case ".ksyms": + // .ksyms describes forward declarations of kfunc signatures. + // Nothing to fix up, all sizes and offsets are 0. + for _, vsi := range ds.Vars { + _, ok := vsi.Type.(*Func) + if !ok { + // Only Funcs are supported in the .ksyms Datasec. + return fmt.Errorf("data section %s: expected *btf.Func, not %T: %w", name, vsi.Type, ErrNotSupported) + } + } + + continue + case ".kconfig": + // .kconfig has a size of 0 and has all members' offsets set to 0. + // Fix up all offsets and set the Datasec's size. + if err := fixupDatasecLayout(ds); err != nil { + return err + } + + // Fix up extern to global linkage to avoid a BTF verifier error. + for _, vsi := range ds.Vars { + vsi.Type.(*Var).Linkage = GlobalVar + } + + continue + } + + if ds.Size != 0 { + continue + } + + ds.Size, ok = sectionSizes[name] + if !ok { + return fmt.Errorf("data section %s: missing size", name) + } + + for i := range ds.Vars { + symName := ds.Vars[i].Type.TypeName() + ds.Vars[i].Offset, ok = offsets[symbol{name, symName}] + if !ok { + return fmt.Errorf("data section %s: missing offset for symbol %s", name, symName) + } + } + } + + return nil +} + +// fixupDatasecLayout populates ds.Vars[].Offset according to var sizes and +// alignment. Calculate and set ds.Size. +func fixupDatasecLayout(ds *Datasec) error { + var off uint32 + + for i, vsi := range ds.Vars { + v, ok := vsi.Type.(*Var) + if !ok { + return fmt.Errorf("member %d: unsupported type %T", i, vsi.Type) + } + + size, err := Sizeof(v.Type) + if err != nil { + return fmt.Errorf("variable %s: getting size: %w", v.Name, err) + } + align, err := alignof(v.Type) + if err != nil { + return fmt.Errorf("variable %s: getting alignment: %w", v.Name, err) + } + + // Align the current member based on the offset of the end of the previous + // member and the alignment of the current member. + off = internal.Align(off, uint32(align)) + + ds.Vars[i].Offset = off + + off += uint32(size) + } + + ds.Size = off + + return nil +} + +// Copy creates a copy of Spec. +func (s *Spec) Copy() *Spec { + types := copyTypes(s.types, nil) + typeIDs, typesByName := indexTypes(types, s.firstTypeID) + + // NB: Other parts of spec are not copied since they are immutable. + return &Spec{ + types, + typeIDs, + s.firstTypeID, + typesByName, + s.strings, + s.byteOrder, + } +} + +type sliceWriter []byte + +func (sw sliceWriter) Write(p []byte) (int, error) { + if len(p) != len(sw) { + return 0, errors.New("size doesn't match") + } + + return copy(sw, p), nil +} + +// nextTypeID returns the next unallocated type ID or an error if there are no +// more type IDs. +func (s *Spec) nextTypeID() (TypeID, error) { + id := s.firstTypeID + TypeID(len(s.types)) + if id < s.firstTypeID { + return 0, fmt.Errorf("no more type IDs") + } + return id, nil +} + +// TypeByID returns the BTF Type with the given type ID. +// +// Returns an error wrapping ErrNotFound if a Type with the given ID +// does not exist in the Spec. +func (s *Spec) TypeByID(id TypeID) (Type, error) { + if id < s.firstTypeID { + return nil, fmt.Errorf("look up type with ID %d (first ID is %d): %w", id, s.firstTypeID, ErrNotFound) + } + + index := int(id - s.firstTypeID) + if index >= len(s.types) { + return nil, fmt.Errorf("look up type with ID %d: %w", id, ErrNotFound) + } + + return s.types[index], nil +} + +// TypeID returns the ID for a given Type. +// +// Returns an error wrapping ErrNoFound if the type isn't part of the Spec. +func (s *Spec) TypeID(typ Type) (TypeID, error) { + if _, ok := typ.(*Void); ok { + // Equality is weird for void, since it is a zero sized type. + return 0, nil + } + + id, ok := s.typeIDs[typ] + if !ok { + return 0, fmt.Errorf("no ID for type %s: %w", typ, ErrNotFound) + } + + return id, nil +} + +// AnyTypesByName returns a list of BTF Types with the given name. +// +// If the BTF blob describes multiple compilation units like vmlinux, multiple +// Types with the same name and kind can exist, but might not describe the same +// data structure. +// +// Returns an error wrapping ErrNotFound if no matching Type exists in the Spec. +func (s *Spec) AnyTypesByName(name string) ([]Type, error) { + types := s.namedTypes[newEssentialName(name)] + if len(types) == 0 { + return nil, fmt.Errorf("type name %s: %w", name, ErrNotFound) + } + + // Return a copy to prevent changes to namedTypes. + result := make([]Type, 0, len(types)) + for _, t := range types { + // Match against the full name, not just the essential one + // in case the type being looked up is a struct flavor. + if t.TypeName() == name { + result = append(result, t) + } + } + return result, nil +} + +// AnyTypeByName returns a Type with the given name. +// +// Returns an error if multiple types of that name exist. +func (s *Spec) AnyTypeByName(name string) (Type, error) { + types, err := s.AnyTypesByName(name) + if err != nil { + return nil, err + } + + if len(types) > 1 { + return nil, fmt.Errorf("found multiple types: %v", types) + } + + return types[0], nil +} + +// TypeByName searches for a Type with a specific name. Since multiple Types +// with the same name can exist, the parameter typ is taken to narrow down the +// search in case of a clash. +// +// typ must be a non-nil pointer to an implementation of a Type. On success, the +// address of the found Type will be copied to typ. +// +// Returns an error wrapping ErrNotFound if no matching Type exists in the Spec. +// Returns an error wrapping ErrMultipleTypes if multiple candidates are found. +func (s *Spec) TypeByName(name string, typ interface{}) error { + typeInterface := reflect.TypeOf((*Type)(nil)).Elem() + + // typ may be **T or *Type + typValue := reflect.ValueOf(typ) + if typValue.Kind() != reflect.Ptr { + return fmt.Errorf("%T is not a pointer", typ) + } + + typPtr := typValue.Elem() + if !typPtr.CanSet() { + return fmt.Errorf("%T cannot be set", typ) + } + + wanted := typPtr.Type() + if wanted == typeInterface { + // This is *Type. Unwrap the value's type. + wanted = typPtr.Elem().Type() + } + + if !wanted.AssignableTo(typeInterface) { + return fmt.Errorf("%T does not satisfy Type interface", typ) + } + + types, err := s.AnyTypesByName(name) + if err != nil { + return err + } + + var candidate Type + for _, typ := range types { + if reflect.TypeOf(typ) != wanted { + continue + } + + if candidate != nil { + return fmt.Errorf("type %s(%T): %w", name, typ, ErrMultipleMatches) + } + + candidate = typ + } + + if candidate == nil { + return fmt.Errorf("%s %s: %w", wanted, name, ErrNotFound) + } + + typPtr.Set(reflect.ValueOf(candidate)) + + return nil +} + +// LoadSplitSpecFromReader loads split BTF from a reader. +// +// Types from base are used to resolve references in the split BTF. +// The returned Spec only contains types from the split BTF, not from the base. +func LoadSplitSpecFromReader(r io.ReaderAt, base *Spec) (*Spec, error) { + return loadRawSpec(r, internal.NativeEndian, base) +} + +// TypesIterator iterates over types of a given spec. +type TypesIterator struct { + types []Type + index int + // The last visited type in the spec. + Type Type +} + +// Iterate returns the types iterator. +func (s *Spec) Iterate() *TypesIterator { + // We share the backing array of types with the Spec. This is safe since + // we don't allow deletion or shuffling of types. + return &TypesIterator{types: s.types, index: 0} +} + +// Next returns true as long as there are any remaining types. +func (iter *TypesIterator) Next() bool { + if len(iter.types) <= iter.index { + return false + } + + iter.Type = iter.types[iter.index] + iter.index++ + return true +} + +// haveBTF attempts to load a BTF blob containing an Int. It should pass on any +// kernel that supports BPF_BTF_LOAD. +var haveBTF = internal.NewFeatureTest("BTF", "4.18", func() error { + // 0-length anonymous integer + err := probeBTF(&Int{}) + if errors.Is(err, unix.EINVAL) || errors.Is(err, unix.EPERM) { + return internal.ErrNotSupported + } + return err +}) + +// haveMapBTF attempts to load a minimal BTF blob containing a Var. It is +// used as a proxy for .bss, .data and .rodata map support, which generally +// come with a Var and Datasec. These were introduced in Linux 5.2. +var haveMapBTF = internal.NewFeatureTest("Map BTF (Var/Datasec)", "5.2", func() error { + if err := haveBTF(); err != nil { + return err + } + + v := &Var{ + Name: "a", + Type: &Pointer{(*Void)(nil)}, + } + + err := probeBTF(v) + if errors.Is(err, unix.EINVAL) || errors.Is(err, unix.EPERM) { + // Treat both EINVAL and EPERM as not supported: creating the map may still + // succeed without Btf* attrs. + return internal.ErrNotSupported + } + return err +}) + +// haveProgBTF attempts to load a BTF blob containing a Func and FuncProto. It +// is used as a proxy for ext_info (func_info) support, which depends on +// Func(Proto) by definition. +var haveProgBTF = internal.NewFeatureTest("Program BTF (func/line_info)", "5.0", func() error { + if err := haveBTF(); err != nil { + return err + } + + fn := &Func{ + Name: "a", + Type: &FuncProto{Return: (*Void)(nil)}, + } + + err := probeBTF(fn) + if errors.Is(err, unix.EINVAL) || errors.Is(err, unix.EPERM) { + return internal.ErrNotSupported + } + return err +}) + +var haveFuncLinkage = internal.NewFeatureTest("BTF func linkage", "5.6", func() error { + if err := haveProgBTF(); err != nil { + return err + } + + fn := &Func{ + Name: "a", + Type: &FuncProto{Return: (*Void)(nil)}, + Linkage: GlobalFunc, + } + + err := probeBTF(fn) + if errors.Is(err, unix.EINVAL) { + return internal.ErrNotSupported + } + return err +}) + +func probeBTF(typ Type) error { + b, err := NewBuilder([]Type{typ}) + if err != nil { + return err + } + + buf, err := b.Marshal(nil, nil) + if err != nil { + return err + } + + fd, err := sys.BtfLoad(&sys.BtfLoadAttr{ + Btf: sys.NewSlicePointer(buf), + BtfSize: uint32(len(buf)), + }) + + if err == nil { + fd.Close() + } + + return err +} diff --git a/vendor/github.com/cilium/ebpf/internal/btf/btf_types.go b/vendor/github.com/cilium/ebpf/btf/btf_types.go similarity index 51% rename from vendor/github.com/cilium/ebpf/internal/btf/btf_types.go rename to vendor/github.com/cilium/ebpf/btf/btf_types.go index d98c73ca59..a253b7c9b9 100644 --- a/vendor/github.com/cilium/ebpf/internal/btf/btf_types.go +++ b/vendor/github.com/cilium/ebpf/btf/btf_types.go @@ -4,35 +4,41 @@ import ( "encoding/binary" "fmt" "io" + "unsafe" ) -//go:generate stringer -linecomment -output=btf_types_string.go -type=FuncLinkage,VarLinkage +//go:generate stringer -linecomment -output=btf_types_string.go -type=FuncLinkage,VarLinkage,btfKind // btfKind describes a Type. type btfKind uint8 // Equivalents of the BTF_KIND_* constants. const ( - kindUnknown btfKind = iota - kindInt - kindPointer - kindArray - kindStruct - kindUnion - kindEnum - kindForward - kindTypedef - kindVolatile - kindConst - kindRestrict + kindUnknown btfKind = iota // Unknown + kindInt // Int + kindPointer // Pointer + kindArray // Array + kindStruct // Struct + kindUnion // Union + kindEnum // Enum + kindForward // Forward + kindTypedef // Typedef + kindVolatile // Volatile + kindConst // Const + kindRestrict // Restrict // Added ~4.20 - kindFunc - kindFuncProto + kindFunc // Func + kindFuncProto // FuncProto // Added ~5.1 - kindVar - kindDatasec + kindVar // Var + kindDatasec // Datasec // Added ~5.13 - kindFloat + kindFloat // Float + // Added 5.16 + kindDeclTag // DeclTag + kindTypeTag // TypeTag + // Added 6.0 + kindEnum64 // Enum64 ) // FuncLinkage describes BTF function linkage metadata. @@ -63,6 +69,8 @@ const ( btfTypeKindFlagMask = 1 ) +var btfTypeLen = binary.Size(btfType{}) + // btfType is equivalent to struct btf_type in Documentation/bpf/btf.rst. type btfType struct { NameOff uint32 @@ -85,58 +93,26 @@ type btfType struct { SizeType uint32 } -func (k btfKind) String() string { - switch k { - case kindUnknown: - return "Unknown" - case kindInt: - return "Integer" - case kindPointer: - return "Pointer" - case kindArray: - return "Array" - case kindStruct: - return "Struct" - case kindUnion: - return "Union" - case kindEnum: - return "Enumeration" - case kindForward: - return "Forward" - case kindTypedef: - return "Typedef" - case kindVolatile: - return "Volatile" - case kindConst: - return "Const" - case kindRestrict: - return "Restrict" - case kindFunc: - return "Function" - case kindFuncProto: - return "Function Proto" - case kindVar: - return "Variable" - case kindDatasec: - return "Section" - case kindFloat: - return "Float" - default: - return fmt.Sprintf("Unknown (%d)", k) - } -} - func mask(len uint32) uint32 { return (1 << len) - 1 } +func readBits(value, len, shift uint32) uint32 { + return (value >> shift) & mask(len) +} + +func writeBits(value, len, shift, new uint32) uint32 { + value &^= mask(len) << shift + value |= (new & mask(len)) << shift + return value +} + func (bt *btfType) info(len, shift uint32) uint32 { - return (bt.Info >> shift) & mask(len) + return readBits(bt.Info, len, shift) } func (bt *btfType) setInfo(value, len, shift uint32) { - bt.Info &^= mask(len) << shift - bt.Info |= (value & mask(len)) << shift + bt.Info = writeBits(bt.Info, len, shift, value) } func (bt *btfType) Kind() btfKind { @@ -155,10 +131,43 @@ func (bt *btfType) SetVlen(vlen int) { bt.setInfo(uint32(vlen), btfTypeVlenMask, btfTypeVlenShift) } -func (bt *btfType) KindFlag() bool { +func (bt *btfType) kindFlagBool() bool { return bt.info(btfTypeKindFlagMask, btfTypeKindFlagShift) == 1 } +func (bt *btfType) setKindFlagBool(set bool) { + var value uint32 + if set { + value = 1 + } + bt.setInfo(value, btfTypeKindFlagMask, btfTypeKindFlagShift) +} + +// Bitfield returns true if the struct or union contain a bitfield. +func (bt *btfType) Bitfield() bool { + return bt.kindFlagBool() +} + +func (bt *btfType) SetBitfield(isBitfield bool) { + bt.setKindFlagBool(isBitfield) +} + +func (bt *btfType) FwdKind() FwdKind { + return FwdKind(bt.info(btfTypeKindFlagMask, btfTypeKindFlagShift)) +} + +func (bt *btfType) SetFwdKind(kind FwdKind) { + bt.setInfo(uint32(kind), btfTypeKindFlagMask, btfTypeKindFlagShift) +} + +func (bt *btfType) Signed() bool { + return bt.kindFlagBool() +} + +func (bt *btfType) SetSigned(signed bool) { + bt.setKindFlagBool(signed) +} + func (bt *btfType) Linkage() FuncLinkage { return FuncLinkage(bt.info(btfTypeVlenMask, btfTypeVlenShift)) } @@ -172,18 +181,35 @@ func (bt *btfType) Type() TypeID { return TypeID(bt.SizeType) } +func (bt *btfType) SetType(id TypeID) { + bt.SizeType = uint32(id) +} + func (bt *btfType) Size() uint32 { // TODO: Panic here if wrong kind? return bt.SizeType } +func (bt *btfType) SetSize(size uint32) { + bt.SizeType = size +} + +func (bt *btfType) Marshal(w io.Writer, bo binary.ByteOrder) error { + buf := make([]byte, unsafe.Sizeof(*bt)) + bo.PutUint32(buf[0:], bt.NameOff) + bo.PutUint32(buf[4:], bt.Info) + bo.PutUint32(buf[8:], bt.SizeType) + _, err := w.Write(buf) + return err +} + type rawType struct { btfType data interface{} } func (rt *rawType) Marshal(w io.Writer, bo binary.ByteOrder) error { - if err := binary.Write(w, bo, &rt.btfType); err != nil { + if err := rt.btfType.Marshal(w, bo); err != nil { return err } @@ -194,6 +220,50 @@ func (rt *rawType) Marshal(w io.Writer, bo binary.ByteOrder) error { return binary.Write(w, bo, rt.data) } +// btfInt encodes additional data for integers. +// +// ? ? ? ? e e e e o o o o o o o o ? ? ? ? ? ? ? ? b b b b b b b b +// ? = undefined +// e = encoding +// o = offset (bitfields?) +// b = bits (bitfields) +type btfInt struct { + Raw uint32 +} + +const ( + btfIntEncodingLen = 4 + btfIntEncodingShift = 24 + btfIntOffsetLen = 8 + btfIntOffsetShift = 16 + btfIntBitsLen = 8 + btfIntBitsShift = 0 +) + +func (bi btfInt) Encoding() IntEncoding { + return IntEncoding(readBits(bi.Raw, btfIntEncodingLen, btfIntEncodingShift)) +} + +func (bi *btfInt) SetEncoding(e IntEncoding) { + bi.Raw = writeBits(uint32(bi.Raw), btfIntEncodingLen, btfIntEncodingShift, uint32(e)) +} + +func (bi btfInt) Offset() Bits { + return Bits(readBits(bi.Raw, btfIntOffsetLen, btfIntOffsetShift)) +} + +func (bi *btfInt) SetOffset(offset uint32) { + bi.Raw = writeBits(bi.Raw, btfIntOffsetLen, btfIntOffsetShift, offset) +} + +func (bi btfInt) Bits() Bits { + return Bits(readBits(bi.Raw, btfIntBitsLen, btfIntBitsShift)) +} + +func (bi *btfInt) SetBits(bits byte) { + bi.Raw = writeBits(bi.Raw, btfIntBitsLen, btfIntBitsShift, uint32(bits)) +} + type btfArray struct { Type TypeID IndexType TypeID @@ -218,7 +288,13 @@ type btfVariable struct { type btfEnum struct { NameOff uint32 - Val int32 + Val uint32 +} + +type btfEnum64 struct { + NameOff uint32 + ValLo32 uint32 + ValHi32 uint32 } type btfParam struct { @@ -226,11 +302,18 @@ type btfParam struct { Type TypeID } -func readTypes(r io.Reader, bo binary.ByteOrder) ([]rawType, error) { - var ( - header btfType - types []rawType - ) +type btfDeclTag struct { + ComponentIdx uint32 +} + +func readTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32) ([]rawType, error) { + var header btfType + // because of the interleaving between types and struct members it is difficult to + // precompute the numbers of raw types this will parse + // this "guess" is a good first estimation + sizeOfbtfType := uintptr(btfTypeLen) + tyMaxCount := uintptr(typeLen) / sizeOfbtfType / 2 + types := make([]rawType, 0, tyMaxCount) for id := TypeID(1); ; id++ { if err := binary.Read(r, bo, &header); err == io.EOF { @@ -242,7 +325,7 @@ func readTypes(r io.Reader, bo binary.ByteOrder) ([]rawType, error) { var data interface{} switch header.Kind() { case kindInt: - data = new(uint32) + data = new(btfInt) case kindPointer: case kindArray: data = new(btfArray) @@ -265,6 +348,11 @@ func readTypes(r io.Reader, bo binary.ByteOrder) ([]rawType, error) { case kindDatasec: data = make([]btfVarSecinfo, header.Vlen()) case kindFloat: + case kindDeclTag: + data = new(btfDeclTag) + case kindTypeTag: + case kindEnum64: + data = make([]btfEnum64, header.Vlen()) default: return nil, fmt.Errorf("type id %v: unknown kind: %v", id, header.Kind()) } @@ -281,7 +369,3 @@ func readTypes(r io.Reader, bo binary.ByteOrder) ([]rawType, error) { types = append(types, rawType{header, data}) } } - -func intEncoding(raw uint32) (IntEncoding, uint32, byte) { - return IntEncoding((raw & 0x0f000000) >> 24), (raw & 0x00ff0000) >> 16, byte(raw & 0x000000ff) -} diff --git a/vendor/github.com/cilium/ebpf/internal/btf/btf_types_string.go b/vendor/github.com/cilium/ebpf/btf/btf_types_string.go similarity index 52% rename from vendor/github.com/cilium/ebpf/internal/btf/btf_types_string.go rename to vendor/github.com/cilium/ebpf/btf/btf_types_string.go index 0e0c17d68b..b7a1b80d15 100644 --- a/vendor/github.com/cilium/ebpf/internal/btf/btf_types_string.go +++ b/vendor/github.com/cilium/ebpf/btf/btf_types_string.go @@ -1,4 +1,4 @@ -// Code generated by "stringer -linecomment -output=btf_types_string.go -type=FuncLinkage,VarLinkage"; DO NOT EDIT. +// Code generated by "stringer -linecomment -output=btf_types_string.go -type=FuncLinkage,VarLinkage,btfKind"; DO NOT EDIT. package btf @@ -42,3 +42,39 @@ func (i VarLinkage) String() string { } return _VarLinkage_name[_VarLinkage_index[i]:_VarLinkage_index[i+1]] } +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[kindUnknown-0] + _ = x[kindInt-1] + _ = x[kindPointer-2] + _ = x[kindArray-3] + _ = x[kindStruct-4] + _ = x[kindUnion-5] + _ = x[kindEnum-6] + _ = x[kindForward-7] + _ = x[kindTypedef-8] + _ = x[kindVolatile-9] + _ = x[kindConst-10] + _ = x[kindRestrict-11] + _ = x[kindFunc-12] + _ = x[kindFuncProto-13] + _ = x[kindVar-14] + _ = x[kindDatasec-15] + _ = x[kindFloat-16] + _ = x[kindDeclTag-17] + _ = x[kindTypeTag-18] + _ = x[kindEnum64-19] +} + +const _btfKind_name = "UnknownIntPointerArrayStructUnionEnumForwardTypedefVolatileConstRestrictFuncFuncProtoVarDatasecFloatDeclTagTypeTagEnum64" + +var _btfKind_index = [...]uint8{0, 7, 10, 17, 22, 28, 33, 37, 44, 51, 59, 64, 72, 76, 85, 88, 95, 100, 107, 114, 120} + +func (i btfKind) String() string { + if i >= btfKind(len(_btfKind_index)-1) { + return "btfKind(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _btfKind_name[_btfKind_index[i]:_btfKind_index[i+1]] +} diff --git a/vendor/github.com/cilium/ebpf/internal/btf/core.go b/vendor/github.com/cilium/ebpf/btf/core.go similarity index 58% rename from vendor/github.com/cilium/ebpf/internal/btf/core.go rename to vendor/github.com/cilium/ebpf/btf/core.go index d02df9d50b..a5c40d36af 100644 --- a/vendor/github.com/cilium/ebpf/internal/btf/core.go +++ b/vendor/github.com/cilium/ebpf/btf/core.go @@ -1,11 +1,11 @@ package btf import ( + "encoding/binary" "errors" "fmt" "math" "reflect" - "sort" "strconv" "strings" @@ -17,50 +17,58 @@ import ( // COREFixup is the result of computing a CO-RE relocation for a target. type COREFixup struct { - Kind COREKind - Local uint32 - Target uint32 - Poison bool + kind coreKind + local uint32 + target uint32 + // True if there is no valid fixup. The instruction is replaced with an + // invalid dummy. + poison bool + // True if the validation of the local value should be skipped. Used by + // some kinds of bitfield relocations. + skipLocalValidation bool } -func (f COREFixup) equal(other COREFixup) bool { - return f.Local == other.Local && f.Target == other.Target +func (f *COREFixup) equal(other COREFixup) bool { + return f.local == other.local && f.target == other.target } -func (f COREFixup) String() string { - if f.Poison { - return fmt.Sprintf("%s=poison", f.Kind) +func (f *COREFixup) String() string { + if f.poison { + return fmt.Sprintf("%s=poison", f.kind) } - return fmt.Sprintf("%s=%d->%d", f.Kind, f.Local, f.Target) + return fmt.Sprintf("%s=%d->%d", f.kind, f.local, f.target) } -func (f COREFixup) apply(ins *asm.Instruction) error { - if f.Poison { - return errors.New("can't poison individual instruction") +func (f *COREFixup) Apply(ins *asm.Instruction) error { + if f.poison { + const badRelo = 0xbad2310 + + *ins = asm.BuiltinFunc(badRelo).Call() + return nil } switch class := ins.OpCode.Class(); class { case asm.LdXClass, asm.StClass, asm.StXClass: - if want := int16(f.Local); want != ins.Offset { - return fmt.Errorf("invalid offset %d, expected %d", ins.Offset, want) + if want := int16(f.local); !f.skipLocalValidation && want != ins.Offset { + return fmt.Errorf("invalid offset %d, expected %d", ins.Offset, f.local) } - if f.Target > math.MaxInt16 { - return fmt.Errorf("offset %d exceeds MaxInt16", f.Target) + if f.target > math.MaxInt16 { + return fmt.Errorf("offset %d exceeds MaxInt16", f.target) } - ins.Offset = int16(f.Target) + ins.Offset = int16(f.target) case asm.LdClass: if !ins.IsConstantLoad(asm.DWord) { return fmt.Errorf("not a dword-sized immediate load") } - if want := int64(f.Local); want != ins.Constant { - return fmt.Errorf("invalid immediate %d, expected %d", ins.Constant, want) + if want := int64(f.local); !f.skipLocalValidation && want != ins.Constant { + return fmt.Errorf("invalid immediate %d, expected %d (fixup: %v)", ins.Constant, want, f) } - ins.Constant = int64(f.Target) + ins.Constant = int64(f.target) case asm.ALUClass: if ins.OpCode.ALUOp() == asm.Swap { @@ -74,15 +82,15 @@ func (f COREFixup) apply(ins *asm.Instruction) error { return fmt.Errorf("invalid source %s", src) } - if want := int64(f.Local); want != ins.Constant { - return fmt.Errorf("invalid immediate %d, expected %d", ins.Constant, want) + if want := int64(f.local); !f.skipLocalValidation && want != ins.Constant { + return fmt.Errorf("invalid immediate %d, expected %d (fixup: %v, kind: %v, ins: %v)", ins.Constant, want, f, f.kind, ins) } - if f.Target > math.MaxInt32 { - return fmt.Errorf("immediate %d exceeds MaxInt32", f.Target) + if f.target > math.MaxInt32 { + return fmt.Errorf("immediate %d exceeds MaxInt32", f.target) } - ins.Constant = int64(f.Target) + ins.Constant = int64(f.target) default: return fmt.Errorf("invalid class %s", class) @@ -92,57 +100,14 @@ func (f COREFixup) apply(ins *asm.Instruction) error { } func (f COREFixup) isNonExistant() bool { - return f.Kind.checksForExistence() && f.Target == 0 -} - -type COREFixups map[uint64]COREFixup - -// Apply a set of CO-RE relocations to a BPF program. -func (fs COREFixups) Apply(insns asm.Instructions) (asm.Instructions, error) { - if len(fs) == 0 { - cpy := make(asm.Instructions, len(insns)) - copy(cpy, insns) - return insns, nil - } - - cpy := make(asm.Instructions, 0, len(insns)) - iter := insns.Iterate() - for iter.Next() { - fixup, ok := fs[iter.Offset.Bytes()] - if !ok { - cpy = append(cpy, *iter.Ins) - continue - } - - ins := *iter.Ins - if fixup.Poison { - const badRelo = asm.BuiltinFunc(0xbad2310) - - cpy = append(cpy, badRelo.Call()) - if ins.OpCode.IsDWordLoad() { - // 64 bit constant loads occupy two raw bpf instructions, so - // we need to add another instruction as padding. - cpy = append(cpy, badRelo.Call()) - } - - continue - } - - if err := fixup.apply(&ins); err != nil { - return nil, fmt.Errorf("instruction %d, offset %d: %s: %w", iter.Index, iter.Offset.Bytes(), fixup.Kind, err) - } - - cpy = append(cpy, ins) - } - - return cpy, nil + return f.kind.checksForExistence() && f.target == 0 } -// COREKind is the type of CO-RE relocation -type COREKind uint32 +// coreKind is the type of CO-RE relocation as specified in BPF source code. +type coreKind uint32 const ( - reloFieldByteOffset COREKind = iota /* field byte offset */ + reloFieldByteOffset coreKind = iota /* field byte offset */ reloFieldByteSize /* field size in bytes */ reloFieldExists /* field existence in target kernel */ reloFieldSigned /* field signedness (0 - unsigned, 1 - signed) */ @@ -156,7 +121,11 @@ const ( reloEnumvalValue /* enum value integer value */ ) -func (k COREKind) String() string { +func (k coreKind) checksForExistence() bool { + return k == reloEnumvalExists || k == reloTypeExists || k == reloFieldExists +} + +func (k coreKind) String() string { switch k { case reloFieldByteOffset: return "byte_off" @@ -187,19 +156,37 @@ func (k COREKind) String() string { } } -func (k COREKind) checksForExistence() bool { - return k == reloEnumvalExists || k == reloTypeExists || k == reloFieldExists -} +// CORERelocate calculates changes needed to adjust eBPF instructions for differences +// in types. +// +// Returns a list of fixups which can be applied to instructions to make them +// match the target type(s). +// +// Fixups are returned in the order of relos, e.g. fixup[i] is the solution +// for relos[i]. +func CORERelocate(relos []*CORERelocation, target *Spec, bo binary.ByteOrder) ([]COREFixup, error) { + if target == nil { + var err error + target, _, err = kernelSpec() + if err != nil { + return nil, fmt.Errorf("load kernel spec: %w", err) + } + } + + if bo != target.byteOrder { + return nil, fmt.Errorf("can't relocate %s against %s", bo, target.byteOrder) + } -func coreRelocate(local, target *Spec, relos coreRelos) (COREFixups, error) { - if local.byteOrder != target.byteOrder { - return nil, fmt.Errorf("can't relocate %s against %s", local.byteOrder, target.byteOrder) + type reloGroup struct { + relos []*CORERelocation + // Position of each relocation in relos. + indices []int } - var ids []TypeID - relosByID := make(map[TypeID]coreRelos) - result := make(COREFixups, len(relos)) - for _, relo := range relos { + // Split relocations into per Type lists. + relosByType := make(map[Type]*reloGroup) + result := make([]COREFixup, len(relos)) + for i, relo := range relos { if relo.kind == reloTypeIDLocal { // Filtering out reloTypeIDLocal here makes our lives a lot easier // down the line, since it doesn't have a target at all. @@ -207,47 +194,41 @@ func coreRelocate(local, target *Spec, relos coreRelos) (COREFixups, error) { return nil, fmt.Errorf("%s: unexpected accessor %v", relo.kind, relo.accessor) } - result[uint64(relo.insnOff)] = COREFixup{ - relo.kind, - uint32(relo.typeID), - uint32(relo.typeID), - false, + result[i] = COREFixup{ + kind: relo.kind, + local: uint32(relo.id), + // NB: Using relo.id as the target here is incorrect, since + // it doesn't match the BTF we generate on the fly. This isn't + // too bad for now since there are no uses of the local type ID + // in the kernel, yet. + target: uint32(relo.id), } continue } - relos, ok := relosByID[relo.typeID] + group, ok := relosByType[relo.typ] if !ok { - ids = append(ids, relo.typeID) + group = &reloGroup{} + relosByType[relo.typ] = group } - relosByID[relo.typeID] = append(relos, relo) + group.relos = append(group.relos, relo) + group.indices = append(group.indices, i) } - // Ensure we work on relocations in a deterministic order. - sort.Slice(ids, func(i, j int) bool { - return ids[i] < ids[j] - }) - - for _, id := range ids { - if int(id) >= len(local.types) { - return nil, fmt.Errorf("invalid type id %d", id) - } - - localType := local.types[id] - named, ok := localType.(NamedType) - if !ok || named.TypeName() == "" { + for localType, group := range relosByType { + localTypeName := localType.TypeName() + if localTypeName == "" { return nil, fmt.Errorf("relocate unnamed or anonymous type %s: %w", localType, ErrNotSupported) } - relos := relosByID[id] - targets := target.namedTypes[essentialName(named.TypeName())] - fixups, err := coreCalculateFixups(localType, targets, relos) + targets := target.namedTypes[newEssentialName(localTypeName)] + fixups, err := coreCalculateFixups(group.relos, target, targets, bo) if err != nil { return nil, fmt.Errorf("relocate %s: %w", localType, err) } - for i, relo := range relos { - result[uint64(relo.insnOff)] = fixups[i] + for j, index := range group.indices { + result[index] = fixups[j] } } @@ -256,36 +237,31 @@ func coreRelocate(local, target *Spec, relos coreRelos) (COREFixups, error) { var errAmbiguousRelocation = errors.New("ambiguous relocation") var errImpossibleRelocation = errors.New("impossible relocation") +var errIncompatibleTypes = errors.New("incompatible types") -// coreCalculateFixups calculates the fixups for the given relocations using -// the "best" target. +// coreCalculateFixups finds the target type that best matches all relocations. +// +// All relos must target the same type. // // The best target is determined by scoring: the less poisoning we have to do // the better the target is. -func coreCalculateFixups(local Type, targets []NamedType, relos coreRelos) ([]COREFixup, error) { - localID := local.ID() - local, err := copyType(local, skipQualifierAndTypedef) - if err != nil { - return nil, err - } - +func coreCalculateFixups(relos []*CORERelocation, targetSpec *Spec, targets []Type, bo binary.ByteOrder) ([]COREFixup, error) { bestScore := len(relos) var bestFixups []COREFixup - for i := range targets { - targetID := targets[i].ID() - target, err := copyType(targets[i], skipQualifierAndTypedef) + for _, target := range targets { + targetID, err := targetSpec.TypeID(target) if err != nil { - return nil, err + return nil, fmt.Errorf("target type ID: %w", err) } score := 0 // lower is better fixups := make([]COREFixup, 0, len(relos)) for _, relo := range relos { - fixup, err := coreCalculateFixup(local, localID, target, targetID, relo) + fixup, err := coreCalculateFixup(relo, target, targetID, bo) if err != nil { - return nil, fmt.Errorf("target %s: %w", target, err) + return nil, fmt.Errorf("target %s: %s: %w", target, relo.kind, err) } - if fixup.Poison || fixup.isNonExistant() { + if fixup.poison || fixup.isNonExistant() { score++ } fixups = append(fixups, fixup) @@ -307,49 +283,62 @@ func coreCalculateFixups(local Type, targets []NamedType, relos coreRelos) ([]CO // the fixups agree with each other. for i, fixup := range bestFixups { if !fixup.equal(fixups[i]) { - return nil, fmt.Errorf("%s: multiple types match: %w", fixup.Kind, errAmbiguousRelocation) + return nil, fmt.Errorf("%s: multiple types match: %w", fixup.kind, errAmbiguousRelocation) } } } if bestFixups == nil { // Nothing at all matched, probably because there are no suitable - // targets at all. Poison everything! + // targets at all. + // + // Poison everything except checksForExistence. bestFixups = make([]COREFixup, len(relos)) for i, relo := range relos { - bestFixups[i] = COREFixup{Kind: relo.kind, Poison: true} + if relo.kind.checksForExistence() { + bestFixups[i] = COREFixup{kind: relo.kind, local: 1, target: 0} + } else { + bestFixups[i] = COREFixup{kind: relo.kind, poison: true} + } } } return bestFixups, nil } +var errNoSignedness = errors.New("no signedness") + // coreCalculateFixup calculates the fixup for a single local type, target type // and relocation. -func coreCalculateFixup(local Type, localID TypeID, target Type, targetID TypeID, relo coreRelo) (COREFixup, error) { +func coreCalculateFixup(relo *CORERelocation, target Type, targetID TypeID, bo binary.ByteOrder) (COREFixup, error) { fixup := func(local, target uint32) (COREFixup, error) { - return COREFixup{relo.kind, local, target, false}, nil + return COREFixup{kind: relo.kind, local: local, target: target}, nil + } + fixupWithoutValidation := func(local, target uint32) (COREFixup, error) { + return COREFixup{kind: relo.kind, local: local, target: target, skipLocalValidation: true}, nil } poison := func() (COREFixup, error) { if relo.kind.checksForExistence() { return fixup(1, 0) } - return COREFixup{relo.kind, 0, 0, true}, nil + return COREFixup{kind: relo.kind, poison: true}, nil } zero := COREFixup{} + local := relo.typ + switch relo.kind { case reloTypeIDTarget, reloTypeSize, reloTypeExists: if len(relo.accessor) > 1 || relo.accessor[0] != 0 { - return zero, fmt.Errorf("%s: unexpected accessor %v", relo.kind, relo.accessor) + return zero, fmt.Errorf("unexpected accessor %v", relo.accessor) } err := coreAreTypesCompatible(local, target) - if errors.Is(err, errImpossibleRelocation) { + if errors.Is(err, errIncompatibleTypes) { return poison() } if err != nil { - return zero, fmt.Errorf("relocation %s: %w", relo.kind, err) + return zero, err } switch relo.kind { @@ -357,7 +346,7 @@ func coreCalculateFixup(local Type, localID TypeID, target Type, targetID TypeID return fixup(1, 1) case reloTypeIDTarget: - return fixup(uint32(localID), uint32(targetID)) + return fixup(uint32(relo.id), uint32(targetID)) case reloTypeSize: localSize, err := Sizeof(local) @@ -379,7 +368,7 @@ func coreCalculateFixup(local Type, localID TypeID, target Type, targetID TypeID return poison() } if err != nil { - return zero, fmt.Errorf("relocation %s: %w", relo.kind, err) + return zero, err } switch relo.kind { @@ -390,8 +379,8 @@ func coreCalculateFixup(local Type, localID TypeID, target Type, targetID TypeID return fixup(uint32(localValue.Value), uint32(targetValue.Value)) } - case reloFieldByteOffset, reloFieldByteSize, reloFieldExists: - if _, ok := target.(*Fwd); ok { + case reloFieldByteOffset, reloFieldByteSize, reloFieldExists, reloFieldLShiftU64, reloFieldRShiftU64, reloFieldSigned: + if _, ok := as[*Fwd](target); ok { // We can't relocate fields using a forward declaration, so // skip it. If a non-forward declaration is present in the BTF // we'll find it in one of the other iterations. @@ -403,7 +392,12 @@ func coreCalculateFixup(local Type, localID TypeID, target Type, targetID TypeID return poison() } if err != nil { - return zero, fmt.Errorf("target %s: %w", target, err) + return zero, err + } + + maybeSkipValidation := func(f COREFixup, err error) (COREFixup, error) { + f.skipLocalValidation = localField.bitfieldSize > 0 + return f, err } switch relo.kind { @@ -411,7 +405,7 @@ func coreCalculateFixup(local Type, localID TypeID, target Type, targetID TypeID return fixup(1, 1) case reloFieldByteOffset: - return fixup(localField.offset/8, targetField.offset/8) + return maybeSkipValidation(fixup(localField.offset, targetField.offset)) case reloFieldByteSize: localSize, err := Sizeof(localField.Type) @@ -423,13 +417,68 @@ func coreCalculateFixup(local Type, localID TypeID, target Type, targetID TypeID if err != nil { return zero, err } + return maybeSkipValidation(fixup(uint32(localSize), uint32(targetSize))) + + case reloFieldLShiftU64: + var target uint32 + if bo == binary.LittleEndian { + targetSize, err := targetField.sizeBits() + if err != nil { + return zero, err + } - return fixup(uint32(localSize), uint32(targetSize)) + target = uint32(64 - targetField.bitfieldOffset - targetSize) + } else { + loadWidth, err := Sizeof(targetField.Type) + if err != nil { + return zero, err + } + target = uint32(64 - Bits(loadWidth*8) + targetField.bitfieldOffset) + } + return fixupWithoutValidation(0, target) + + case reloFieldRShiftU64: + targetSize, err := targetField.sizeBits() + if err != nil { + return zero, err + } + + return fixupWithoutValidation(0, uint32(64-targetSize)) + + case reloFieldSigned: + switch local := UnderlyingType(localField.Type).(type) { + case *Enum: + target, ok := as[*Enum](targetField.Type) + if !ok { + return zero, fmt.Errorf("target isn't *Enum but %T", targetField.Type) + } + + return fixup(boolToUint32(local.Signed), boolToUint32(target.Signed)) + case *Int: + target, ok := as[*Int](targetField.Type) + if !ok { + return zero, fmt.Errorf("target isn't *Int but %T", targetField.Type) + } + + return fixup( + uint32(local.Encoding&Signed), + uint32(target.Encoding&Signed), + ) + default: + return zero, fmt.Errorf("type %T: %w", local, errNoSignedness) + } } } - return zero, fmt.Errorf("relocation %s: %w", relo.kind, ErrNotSupported) + return zero, ErrNotSupported +} + +func boolToUint32(val bool) uint32 { + if val { + return 1 + } + return 0 } /* coreAccessor contains a path through a struct. It contains at least one index. @@ -462,7 +511,7 @@ func coreCalculateFixup(local Type, localID TypeID, target Type, targetID TypeID */ type coreAccessor []int -func parseCoreAccessor(accessor string) (coreAccessor, error) { +func parseCOREAccessor(accessor string) (coreAccessor, error) { if accessor == "" { return nil, fmt.Errorf("empty accessor") } @@ -491,7 +540,7 @@ func (ca coreAccessor) String() string { } func (ca coreAccessor) enumValue(t Type) (*EnumValue, error) { - e, ok := t.(*Enum) + e, ok := as[*Enum](t) if !ok { return nil, fmt.Errorf("not an enum: %s", t) } @@ -508,18 +557,77 @@ func (ca coreAccessor) enumValue(t Type) (*EnumValue, error) { return &e.Values[i], nil } +// coreField represents the position of a "child" of a composite type from the +// start of that type. +// +// /- start of composite +// | offset * 8 | bitfieldOffset | bitfieldSize | ... | +// \- start of field end of field -/ type coreField struct { - Type Type + Type Type + + // The position of the field from the start of the composite type in bytes. offset uint32 + + // The offset of the bitfield in bits from the start of the field. + bitfieldOffset Bits + + // The size of the bitfield in bits. + // + // Zero if the field is not a bitfield. + bitfieldSize Bits } -func adjustOffset(base uint32, t Type, n int) (uint32, error) { - size, err := Sizeof(t) +func (cf *coreField) adjustOffsetToNthElement(n int) error { + if n == 0 { + return nil + } + + size, err := Sizeof(cf.Type) if err != nil { - return 0, err + return err + } + + cf.offset += uint32(n) * uint32(size) + return nil +} + +func (cf *coreField) adjustOffsetBits(offset Bits) error { + align, err := alignof(cf.Type) + if err != nil { + return err + } + + // We can compute the load offset by: + // 1) converting the bit offset to bytes with a flooring division. + // 2) dividing and multiplying that offset by the alignment, yielding the + // load size aligned offset. + offsetBytes := uint32(offset/8) / uint32(align) * uint32(align) + + // The number of bits remaining is the bit offset less the number of bits + // we can "skip" with the aligned offset. + cf.bitfieldOffset = offset - Bits(offsetBytes*8) + + // We know that cf.offset is aligned at to at least align since we get it + // from the compiler via BTF. Adding an aligned offsetBytes preserves the + // alignment. + cf.offset += offsetBytes + return nil +} + +func (cf *coreField) sizeBits() (Bits, error) { + if cf.bitfieldSize > 0 { + return cf.bitfieldSize, nil } - return base + (uint32(n) * uint32(size) * 8), nil + // Someone is trying to access a non-bitfield via a bit shift relocation. + // This happens when a field changes from a bitfield to a regular field + // between kernel versions. Synthesise the size to make the shifts work. + size, err := Sizeof(cf.Type) + if err != nil { + return 0, err + } + return Bits(size * 8), nil } // coreFindField descends into the local type using the accessor and tries to @@ -527,49 +635,52 @@ func adjustOffset(base uint32, t Type, n int) (uint32, error) { // // Returns the field and the offset of the field from the start of // target in bits. -func coreFindField(local Type, localAcc coreAccessor, target Type) (_, _ coreField, _ error) { +func coreFindField(localT Type, localAcc coreAccessor, targetT Type) (coreField, coreField, error) { + local := coreField{Type: localT} + target := coreField{Type: targetT} + + if err := coreAreMembersCompatible(local.Type, target.Type); err != nil { + return coreField{}, coreField{}, fmt.Errorf("fields: %w", err) + } + // The first index is used to offset a pointer of the base type like // when accessing an array. - localOffset, err := adjustOffset(0, local, localAcc[0]) - if err != nil { + if err := local.adjustOffsetToNthElement(localAcc[0]); err != nil { return coreField{}, coreField{}, err } - targetOffset, err := adjustOffset(0, target, localAcc[0]) - if err != nil { + if err := target.adjustOffsetToNthElement(localAcc[0]); err != nil { return coreField{}, coreField{}, err } - if err := coreAreMembersCompatible(local, target); err != nil { - return coreField{}, coreField{}, fmt.Errorf("fields: %w", err) - } - var localMaybeFlex, targetMaybeFlex bool - for _, acc := range localAcc[1:] { - switch localType := local.(type) { + for i, acc := range localAcc[1:] { + switch localType := UnderlyingType(local.Type).(type) { case composite: // For composite types acc is used to find the field in the local type, // and then we try to find a field in target with the same name. localMembers := localType.members() if acc >= len(localMembers) { - return coreField{}, coreField{}, fmt.Errorf("invalid accessor %d for %s", acc, local) + return coreField{}, coreField{}, fmt.Errorf("invalid accessor %d for %s", acc, localType) } localMember := localMembers[acc] if localMember.Name == "" { - _, ok := localMember.Type.(composite) + localMemberType, ok := as[composite](localMember.Type) if !ok { return coreField{}, coreField{}, fmt.Errorf("unnamed field with type %s: %s", localMember.Type, ErrNotSupported) } // This is an anonymous struct or union, ignore it. - local = localMember.Type - localOffset += localMember.OffsetBits + local = coreField{ + Type: localMemberType, + offset: local.offset + localMember.Offset.Bytes(), + } localMaybeFlex = false continue } - targetType, ok := target.(composite) + targetType, ok := as[composite](target.Type) if !ok { return coreField{}, coreField{}, fmt.Errorf("target not composite: %w", errImpossibleRelocation) } @@ -579,20 +690,43 @@ func coreFindField(local Type, localAcc coreAccessor, target Type) (_, _ coreFie return coreField{}, coreField{}, err } - if targetMember.BitfieldSize > 0 { - return coreField{}, coreField{}, fmt.Errorf("field %q is a bitfield: %w", targetMember.Name, ErrNotSupported) + local = coreField{ + Type: localMember.Type, + offset: local.offset, + bitfieldSize: localMember.BitfieldSize, } - - local = localMember.Type localMaybeFlex = acc == len(localMembers)-1 - localOffset += localMember.OffsetBits - target = targetMember.Type + + target = coreField{ + Type: targetMember.Type, + offset: target.offset, + bitfieldSize: targetMember.BitfieldSize, + } targetMaybeFlex = last - targetOffset += targetMember.OffsetBits + + if local.bitfieldSize == 0 && target.bitfieldSize == 0 { + local.offset += localMember.Offset.Bytes() + target.offset += targetMember.Offset.Bytes() + break + } + + // Either of the members is a bitfield. Make sure we're at the + // end of the accessor. + if next := i + 1; next < len(localAcc[1:]) { + return coreField{}, coreField{}, fmt.Errorf("can't descend into bitfield") + } + + if err := local.adjustOffsetBits(localMember.Offset); err != nil { + return coreField{}, coreField{}, err + } + + if err := target.adjustOffsetBits(targetMember.Offset); err != nil { + return coreField{}, coreField{}, err + } case *Array: // For arrays, acc is the index in the target. - targetType, ok := target.(*Array) + targetType, ok := as[*Array](target.Type) if !ok { return coreField{}, coreField{}, fmt.Errorf("target not array: %w", errImpossibleRelocation) } @@ -611,17 +745,23 @@ func coreFindField(local Type, localAcc coreAccessor, target Type) (_, _ coreFie return coreField{}, coreField{}, fmt.Errorf("out of bounds access of target: %w", errImpossibleRelocation) } - local = localType.Type + local = coreField{ + Type: localType.Type, + offset: local.offset, + } localMaybeFlex = false - localOffset, err = adjustOffset(localOffset, local, acc) - if err != nil { + + if err := local.adjustOffsetToNthElement(acc); err != nil { return coreField{}, coreField{}, err } - target = targetType.Type + target = coreField{ + Type: targetType.Type, + offset: target.offset, + } targetMaybeFlex = false - targetOffset, err = adjustOffset(targetOffset, target, acc) - if err != nil { + + if err := target.adjustOffsetToNthElement(acc); err != nil { return coreField{}, coreField{}, err } @@ -629,12 +769,12 @@ func coreFindField(local Type, localAcc coreAccessor, target Type) (_, _ coreFie return coreField{}, coreField{}, fmt.Errorf("relocate field of %T: %w", localType, ErrNotSupported) } - if err := coreAreMembersCompatible(local, target); err != nil { + if err := coreAreMembersCompatible(local.Type, target.Type); err != nil { return coreField{}, coreField{}, err } } - return coreField{local, localOffset}, coreField{target, targetOffset}, nil + return local, target, nil } // coreFindMember finds a member in a composite type while handling anonymous @@ -646,7 +786,7 @@ func coreFindMember(typ composite, name string) (Member, bool, error) { type offsetTarget struct { composite - offset uint32 + offset Bits } targets := []offsetTarget{{typ, 0}} @@ -670,7 +810,7 @@ func coreFindMember(typ composite, name string) (Member, bool, error) { for j, member := range members { if member.Name == name { // NB: This is safe because member is a copy. - member.OffsetBits += target.offset + member.Offset += target.offset return member, j == len(members)-1, nil } @@ -680,12 +820,12 @@ func coreFindMember(typ composite, name string) (Member, bool, error) { continue } - comp, ok := member.Type.(composite) + comp, ok := as[composite](member.Type) if !ok { return Member{}, false, fmt.Errorf("anonymous non-composite type %T not allowed", member.Type) } - targets = append(targets, offsetTarget{comp, target.offset + member.OffsetBits}) + targets = append(targets, offsetTarget{comp, target.offset + member.Offset}) } } @@ -699,14 +839,14 @@ func coreFindEnumValue(local Type, localAcc coreAccessor, target Type) (localVal return nil, nil, err } - targetEnum, ok := target.(*Enum) + targetEnum, ok := as[*Enum](target) if !ok { return nil, nil, errImpossibleRelocation } - localName := essentialName(localValue.Name) + localName := newEssentialName(localValue.Name) for i, targetValue := range targetEnum.Values { - if essentialName(targetValue.Name) != localName { + if newEssentialName(targetValue.Name) != localName { continue } @@ -716,6 +856,13 @@ func coreFindEnumValue(local Type, localAcc coreAccessor, target Type) (localVal return nil, nil, errImpossibleRelocation } +// CheckTypeCompatibility checks local and target types for Compatibility according to CO-RE rules. +// +// Only layout compatibility is checked, ignoring names of the root type. +func CheckTypeCompatibility(localType Type, targetType Type) error { + return coreAreTypesCompatible(localType, targetType) +} + /* The comment below is from bpf_core_types_are_compat in libbpf.c: * * Check local and target types for compatibility. This check is used for @@ -737,51 +884,46 @@ func coreFindEnumValue(local Type, localAcc coreAccessor, target Type) (localVal * These rules are not set in stone and probably will be adjusted as we get * more experience with using BPF CO-RE relocations. * - * Returns errImpossibleRelocation if types are not compatible. + * Returns errIncompatibleTypes if types are not compatible. */ func coreAreTypesCompatible(localType Type, targetType Type) error { + var ( localTs, targetTs typeDeque l, t = &localType, &targetType depth = 0 ) - for ; l != nil && t != nil; l, t = localTs.shift(), targetTs.shift() { + for ; l != nil && t != nil; l, t = localTs.Shift(), targetTs.Shift() { if depth >= maxTypeDepth { return errors.New("types are nested too deep") } - localType = *l - targetType = *t + localType = UnderlyingType(*l) + targetType = UnderlyingType(*t) if reflect.TypeOf(localType) != reflect.TypeOf(targetType) { - return fmt.Errorf("type mismatch: %w", errImpossibleRelocation) + return fmt.Errorf("type mismatch: %w", errIncompatibleTypes) } switch lv := (localType).(type) { - case *Void, *Struct, *Union, *Enum, *Fwd: + case *Void, *Struct, *Union, *Enum, *Fwd, *Int: // Nothing to do here - case *Int: - tv := targetType.(*Int) - if lv.isBitfield() || tv.isBitfield() { - return fmt.Errorf("bitfield: %w", errImpossibleRelocation) - } - case *Pointer, *Array: depth++ - localType.walk(&localTs) - targetType.walk(&targetTs) + walkType(localType, localTs.Push) + walkType(targetType, targetTs.Push) case *FuncProto: tv := targetType.(*FuncProto) if len(lv.Params) != len(tv.Params) { - return fmt.Errorf("function param mismatch: %w", errImpossibleRelocation) + return fmt.Errorf("function param mismatch: %w", errIncompatibleTypes) } depth++ - localType.walk(&localTs) - targetType.walk(&targetTs) + walkType(localType, localTs.Push) + walkType(targetType, targetTs.Push) default: return fmt.Errorf("unsupported type %T", localType) @@ -825,13 +967,16 @@ func coreAreTypesCompatible(localType Type, targetType Type) error { * Returns errImpossibleRelocation if the members are not compatible. */ func coreAreMembersCompatible(localType Type, targetType Type) error { + localType = UnderlyingType(localType) + targetType = UnderlyingType(targetType) + doNamesMatch := func(a, b string) error { if a == "" || b == "" { // allow anonymous and named type to match return nil } - if essentialName(a) == essentialName(b) { + if newEssentialName(a) == newEssentialName(b) { return nil } @@ -849,7 +994,7 @@ func coreAreMembersCompatible(localType Type, targetType Type) error { } switch lv := localType.(type) { - case *Array, *Pointer, *Float: + case *Array, *Pointer, *Float, *Int: return nil case *Enum: @@ -860,29 +1005,7 @@ func coreAreMembersCompatible(localType Type, targetType Type) error { tv := targetType.(*Fwd) return doNamesMatch(lv.Name, tv.Name) - case *Int: - tv := targetType.(*Int) - if lv.isBitfield() || tv.isBitfield() { - return fmt.Errorf("bitfield: %w", errImpossibleRelocation) - } - return nil - default: return fmt.Errorf("type %s: %w", localType, ErrNotSupported) } } - -func skipQualifierAndTypedef(typ Type) (Type, error) { - result := typ - for depth := 0; depth <= maxTypeDepth; depth++ { - switch v := (result).(type) { - case qualifier: - result = v.qualify() - case *Typedef: - result = v.Type - default: - return result, nil - } - } - return nil, errors.New("exceeded type depth") -} diff --git a/vendor/github.com/cilium/ebpf/internal/btf/doc.go b/vendor/github.com/cilium/ebpf/btf/doc.go similarity index 71% rename from vendor/github.com/cilium/ebpf/internal/btf/doc.go rename to vendor/github.com/cilium/ebpf/btf/doc.go index ad2576cb23..b1f4b1fc3e 100644 --- a/vendor/github.com/cilium/ebpf/internal/btf/doc.go +++ b/vendor/github.com/cilium/ebpf/btf/doc.go @@ -2,7 +2,4 @@ // // The canonical documentation lives in the Linux kernel repository and is // available at https://www.kernel.org/doc/html/latest/bpf/btf.html -// -// The API is very much unstable. You should only use this via the main -// ebpf library. package btf diff --git a/vendor/github.com/cilium/ebpf/btf/ext_info.go b/vendor/github.com/cilium/ebpf/btf/ext_info.go new file mode 100644 index 0000000000..b764fb7bcc --- /dev/null +++ b/vendor/github.com/cilium/ebpf/btf/ext_info.go @@ -0,0 +1,768 @@ +package btf + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "io" + "math" + "sort" + + "github.com/cilium/ebpf/asm" + "github.com/cilium/ebpf/internal" +) + +// ExtInfos contains ELF section metadata. +type ExtInfos struct { + // The slices are sorted by offset in ascending order. + funcInfos map[string][]funcInfo + lineInfos map[string][]lineInfo + relocationInfos map[string][]coreRelocationInfo +} + +// loadExtInfosFromELF parses ext infos from the .BTF.ext section in an ELF. +// +// Returns an error wrapping ErrNotFound if no ext infos are present. +func loadExtInfosFromELF(file *internal.SafeELFFile, spec *Spec) (*ExtInfos, error) { + section := file.Section(".BTF.ext") + if section == nil { + return nil, fmt.Errorf("btf ext infos: %w", ErrNotFound) + } + + if section.ReaderAt == nil { + return nil, fmt.Errorf("compressed ext_info is not supported") + } + + return loadExtInfos(section.ReaderAt, file.ByteOrder, spec, spec.strings) +} + +// loadExtInfos parses bare ext infos. +func loadExtInfos(r io.ReaderAt, bo binary.ByteOrder, spec *Spec, strings *stringTable) (*ExtInfos, error) { + // Open unbuffered section reader. binary.Read() calls io.ReadFull on + // the header structs, resulting in one syscall per header. + headerRd := io.NewSectionReader(r, 0, math.MaxInt64) + extHeader, err := parseBTFExtHeader(headerRd, bo) + if err != nil { + return nil, fmt.Errorf("parsing BTF extension header: %w", err) + } + + coreHeader, err := parseBTFExtCOREHeader(headerRd, bo, extHeader) + if err != nil { + return nil, fmt.Errorf("parsing BTF CO-RE header: %w", err) + } + + buf := internal.NewBufferedSectionReader(r, extHeader.funcInfoStart(), int64(extHeader.FuncInfoLen)) + btfFuncInfos, err := parseFuncInfos(buf, bo, strings) + if err != nil { + return nil, fmt.Errorf("parsing BTF function info: %w", err) + } + + funcInfos := make(map[string][]funcInfo, len(btfFuncInfos)) + for section, bfis := range btfFuncInfos { + funcInfos[section], err = newFuncInfos(bfis, spec) + if err != nil { + return nil, fmt.Errorf("section %s: func infos: %w", section, err) + } + } + + buf = internal.NewBufferedSectionReader(r, extHeader.lineInfoStart(), int64(extHeader.LineInfoLen)) + btfLineInfos, err := parseLineInfos(buf, bo, strings) + if err != nil { + return nil, fmt.Errorf("parsing BTF line info: %w", err) + } + + lineInfos := make(map[string][]lineInfo, len(btfLineInfos)) + for section, blis := range btfLineInfos { + lineInfos[section], err = newLineInfos(blis, strings) + if err != nil { + return nil, fmt.Errorf("section %s: line infos: %w", section, err) + } + } + + if coreHeader == nil || coreHeader.COREReloLen == 0 { + return &ExtInfos{funcInfos, lineInfos, nil}, nil + } + + var btfCORERelos map[string][]bpfCORERelo + buf = internal.NewBufferedSectionReader(r, extHeader.coreReloStart(coreHeader), int64(coreHeader.COREReloLen)) + btfCORERelos, err = parseCORERelos(buf, bo, strings) + if err != nil { + return nil, fmt.Errorf("parsing CO-RE relocation info: %w", err) + } + + coreRelos := make(map[string][]coreRelocationInfo, len(btfCORERelos)) + for section, brs := range btfCORERelos { + coreRelos[section], err = newRelocationInfos(brs, spec, strings) + if err != nil { + return nil, fmt.Errorf("section %s: CO-RE relocations: %w", section, err) + } + } + + return &ExtInfos{funcInfos, lineInfos, coreRelos}, nil +} + +type funcInfoMeta struct{} +type coreRelocationMeta struct{} + +// Assign per-section metadata from BTF to a section's instructions. +func (ei *ExtInfos) Assign(insns asm.Instructions, section string) { + funcInfos := ei.funcInfos[section] + lineInfos := ei.lineInfos[section] + reloInfos := ei.relocationInfos[section] + + iter := insns.Iterate() + for iter.Next() { + if len(funcInfos) > 0 && funcInfos[0].offset == iter.Offset { + *iter.Ins = WithFuncMetadata(*iter.Ins, funcInfos[0].fn) + funcInfos = funcInfos[1:] + } + + if len(lineInfos) > 0 && lineInfos[0].offset == iter.Offset { + *iter.Ins = iter.Ins.WithSource(lineInfos[0].line) + lineInfos = lineInfos[1:] + } + + if len(reloInfos) > 0 && reloInfos[0].offset == iter.Offset { + iter.Ins.Metadata.Set(coreRelocationMeta{}, reloInfos[0].relo) + reloInfos = reloInfos[1:] + } + } +} + +// MarshalExtInfos encodes function and line info embedded in insns into kernel +// wire format. +// +// Returns ErrNotSupported if the kernel doesn't support BTF-associated programs. +func MarshalExtInfos(insns asm.Instructions) (_ *Handle, funcInfos, lineInfos []byte, _ error) { + // Bail out early if the kernel doesn't support Func(Proto). If this is the + // case, func_info will also be unsupported. + if err := haveProgBTF(); err != nil { + return nil, nil, nil, err + } + + iter := insns.Iterate() + for iter.Next() { + _, ok := iter.Ins.Source().(*Line) + fn := FuncMetadata(iter.Ins) + if ok || fn != nil { + goto marshal + } + } + + return nil, nil, nil, nil + +marshal: + var b Builder + var fiBuf, liBuf bytes.Buffer + for { + if fn := FuncMetadata(iter.Ins); fn != nil { + fi := &funcInfo{ + fn: fn, + offset: iter.Offset, + } + if err := fi.marshal(&fiBuf, &b); err != nil { + return nil, nil, nil, fmt.Errorf("write func info: %w", err) + } + } + + if line, ok := iter.Ins.Source().(*Line); ok { + li := &lineInfo{ + line: line, + offset: iter.Offset, + } + if err := li.marshal(&liBuf, &b); err != nil { + return nil, nil, nil, fmt.Errorf("write line info: %w", err) + } + } + + if !iter.Next() { + break + } + } + + handle, err := NewHandle(&b) + return handle, fiBuf.Bytes(), liBuf.Bytes(), err +} + +// btfExtHeader is found at the start of the .BTF.ext section. +type btfExtHeader struct { + Magic uint16 + Version uint8 + Flags uint8 + + // HdrLen is larger than the size of struct btfExtHeader when it is + // immediately followed by a btfExtCOREHeader. + HdrLen uint32 + + FuncInfoOff uint32 + FuncInfoLen uint32 + LineInfoOff uint32 + LineInfoLen uint32 +} + +// parseBTFExtHeader parses the header of the .BTF.ext section. +func parseBTFExtHeader(r io.Reader, bo binary.ByteOrder) (*btfExtHeader, error) { + var header btfExtHeader + if err := binary.Read(r, bo, &header); err != nil { + return nil, fmt.Errorf("can't read header: %v", err) + } + + if header.Magic != btfMagic { + return nil, fmt.Errorf("incorrect magic value %v", header.Magic) + } + + if header.Version != 1 { + return nil, fmt.Errorf("unexpected version %v", header.Version) + } + + if header.Flags != 0 { + return nil, fmt.Errorf("unsupported flags %v", header.Flags) + } + + if int64(header.HdrLen) < int64(binary.Size(&header)) { + return nil, fmt.Errorf("header length shorter than btfExtHeader size") + } + + return &header, nil +} + +// funcInfoStart returns the offset from the beginning of the .BTF.ext section +// to the start of its func_info entries. +func (h *btfExtHeader) funcInfoStart() int64 { + return int64(h.HdrLen + h.FuncInfoOff) +} + +// lineInfoStart returns the offset from the beginning of the .BTF.ext section +// to the start of its line_info entries. +func (h *btfExtHeader) lineInfoStart() int64 { + return int64(h.HdrLen + h.LineInfoOff) +} + +// coreReloStart returns the offset from the beginning of the .BTF.ext section +// to the start of its CO-RE relocation entries. +func (h *btfExtHeader) coreReloStart(ch *btfExtCOREHeader) int64 { + return int64(h.HdrLen + ch.COREReloOff) +} + +// btfExtCOREHeader is found right after the btfExtHeader when its HdrLen +// field is larger than its size. +type btfExtCOREHeader struct { + COREReloOff uint32 + COREReloLen uint32 +} + +// parseBTFExtCOREHeader parses the tail of the .BTF.ext header. If additional +// header bytes are present, extHeader.HdrLen will be larger than the struct, +// indicating the presence of a CO-RE extension header. +func parseBTFExtCOREHeader(r io.Reader, bo binary.ByteOrder, extHeader *btfExtHeader) (*btfExtCOREHeader, error) { + extHdrSize := int64(binary.Size(&extHeader)) + remainder := int64(extHeader.HdrLen) - extHdrSize + + if remainder == 0 { + return nil, nil + } + + var coreHeader btfExtCOREHeader + if err := binary.Read(r, bo, &coreHeader); err != nil { + return nil, fmt.Errorf("can't read header: %v", err) + } + + return &coreHeader, nil +} + +type btfExtInfoSec struct { + SecNameOff uint32 + NumInfo uint32 +} + +// parseExtInfoSec parses a btf_ext_info_sec header within .BTF.ext, +// appearing within func_info and line_info sub-sections. +// These headers appear once for each program section in the ELF and are +// followed by one or more func/line_info records for the section. +func parseExtInfoSec(r io.Reader, bo binary.ByteOrder, strings *stringTable) (string, *btfExtInfoSec, error) { + var infoHeader btfExtInfoSec + if err := binary.Read(r, bo, &infoHeader); err != nil { + return "", nil, fmt.Errorf("read ext info header: %w", err) + } + + secName, err := strings.Lookup(infoHeader.SecNameOff) + if err != nil { + return "", nil, fmt.Errorf("get section name: %w", err) + } + if secName == "" { + return "", nil, fmt.Errorf("extinfo header refers to empty section name") + } + + if infoHeader.NumInfo == 0 { + return "", nil, fmt.Errorf("section %s has zero records", secName) + } + + return secName, &infoHeader, nil +} + +// parseExtInfoRecordSize parses the uint32 at the beginning of a func_infos +// or line_infos segment that describes the length of all extInfoRecords in +// that segment. +func parseExtInfoRecordSize(r io.Reader, bo binary.ByteOrder) (uint32, error) { + const maxRecordSize = 256 + + var recordSize uint32 + if err := binary.Read(r, bo, &recordSize); err != nil { + return 0, fmt.Errorf("can't read record size: %v", err) + } + + if recordSize < 4 { + // Need at least InsnOff worth of bytes per record. + return 0, errors.New("record size too short") + } + if recordSize > maxRecordSize { + return 0, fmt.Errorf("record size %v exceeds %v", recordSize, maxRecordSize) + } + + return recordSize, nil +} + +// The size of a FuncInfo in BTF wire format. +var FuncInfoSize = uint32(binary.Size(bpfFuncInfo{})) + +type funcInfo struct { + fn *Func + offset asm.RawInstructionOffset +} + +type bpfFuncInfo struct { + // Instruction offset of the function within an ELF section. + InsnOff uint32 + TypeID TypeID +} + +func newFuncInfo(fi bpfFuncInfo, spec *Spec) (*funcInfo, error) { + typ, err := spec.TypeByID(fi.TypeID) + if err != nil { + return nil, err + } + + fn, ok := typ.(*Func) + if !ok { + return nil, fmt.Errorf("type ID %d is a %T, but expected a Func", fi.TypeID, typ) + } + + // C doesn't have anonymous functions, but check just in case. + if fn.Name == "" { + return nil, fmt.Errorf("func with type ID %d doesn't have a name", fi.TypeID) + } + + return &funcInfo{ + fn, + asm.RawInstructionOffset(fi.InsnOff), + }, nil +} + +func newFuncInfos(bfis []bpfFuncInfo, spec *Spec) ([]funcInfo, error) { + fis := make([]funcInfo, 0, len(bfis)) + for _, bfi := range bfis { + fi, err := newFuncInfo(bfi, spec) + if err != nil { + return nil, fmt.Errorf("offset %d: %w", bfi.InsnOff, err) + } + fis = append(fis, *fi) + } + sort.Slice(fis, func(i, j int) bool { + return fis[i].offset <= fis[j].offset + }) + return fis, nil +} + +// marshal into the BTF wire format. +func (fi *funcInfo) marshal(w *bytes.Buffer, b *Builder) error { + id, err := b.Add(fi.fn) + if err != nil { + return err + } + bfi := bpfFuncInfo{ + InsnOff: uint32(fi.offset), + TypeID: id, + } + buf := make([]byte, FuncInfoSize) + internal.NativeEndian.PutUint32(buf, bfi.InsnOff) + internal.NativeEndian.PutUint32(buf[4:], uint32(bfi.TypeID)) + _, err = w.Write(buf) + return err +} + +// parseFuncInfos parses a func_info sub-section within .BTF.ext ito a map of +// func infos indexed by section name. +func parseFuncInfos(r io.Reader, bo binary.ByteOrder, strings *stringTable) (map[string][]bpfFuncInfo, error) { + recordSize, err := parseExtInfoRecordSize(r, bo) + if err != nil { + return nil, err + } + + result := make(map[string][]bpfFuncInfo) + for { + secName, infoHeader, err := parseExtInfoSec(r, bo, strings) + if errors.Is(err, io.EOF) { + return result, nil + } + if err != nil { + return nil, err + } + + records, err := parseFuncInfoRecords(r, bo, recordSize, infoHeader.NumInfo) + if err != nil { + return nil, fmt.Errorf("section %v: %w", secName, err) + } + + result[secName] = records + } +} + +// parseFuncInfoRecords parses a stream of func_infos into a funcInfos. +// These records appear after a btf_ext_info_sec header in the func_info +// sub-section of .BTF.ext. +func parseFuncInfoRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, recordNum uint32) ([]bpfFuncInfo, error) { + var out []bpfFuncInfo + var fi bpfFuncInfo + + if exp, got := FuncInfoSize, recordSize; exp != got { + // BTF blob's record size is longer than we know how to parse. + return nil, fmt.Errorf("expected FuncInfo record size %d, but BTF blob contains %d", exp, got) + } + + for i := uint32(0); i < recordNum; i++ { + if err := binary.Read(r, bo, &fi); err != nil { + return nil, fmt.Errorf("can't read function info: %v", err) + } + + if fi.InsnOff%asm.InstructionSize != 0 { + return nil, fmt.Errorf("offset %v is not aligned with instruction size", fi.InsnOff) + } + + // ELF tracks offset in bytes, the kernel expects raw BPF instructions. + // Convert as early as possible. + fi.InsnOff /= asm.InstructionSize + + out = append(out, fi) + } + + return out, nil +} + +var LineInfoSize = uint32(binary.Size(bpfLineInfo{})) + +// Line represents the location and contents of a single line of source +// code a BPF ELF was compiled from. +type Line struct { + fileName string + line string + lineNumber uint32 + lineColumn uint32 +} + +func (li *Line) FileName() string { + return li.fileName +} + +func (li *Line) Line() string { + return li.line +} + +func (li *Line) LineNumber() uint32 { + return li.lineNumber +} + +func (li *Line) LineColumn() uint32 { + return li.lineColumn +} + +func (li *Line) String() string { + return li.line +} + +type lineInfo struct { + line *Line + offset asm.RawInstructionOffset +} + +// Constants for the format of bpfLineInfo.LineCol. +const ( + bpfLineShift = 10 + bpfLineMax = (1 << (32 - bpfLineShift)) - 1 + bpfColumnMax = (1 << bpfLineShift) - 1 +) + +type bpfLineInfo struct { + // Instruction offset of the line within the whole instruction stream, in instructions. + InsnOff uint32 + FileNameOff uint32 + LineOff uint32 + LineCol uint32 +} + +func newLineInfo(li bpfLineInfo, strings *stringTable) (*lineInfo, error) { + line, err := strings.Lookup(li.LineOff) + if err != nil { + return nil, fmt.Errorf("lookup of line: %w", err) + } + + fileName, err := strings.Lookup(li.FileNameOff) + if err != nil { + return nil, fmt.Errorf("lookup of filename: %w", err) + } + + lineNumber := li.LineCol >> bpfLineShift + lineColumn := li.LineCol & bpfColumnMax + + return &lineInfo{ + &Line{ + fileName, + line, + lineNumber, + lineColumn, + }, + asm.RawInstructionOffset(li.InsnOff), + }, nil +} + +func newLineInfos(blis []bpfLineInfo, strings *stringTable) ([]lineInfo, error) { + lis := make([]lineInfo, 0, len(blis)) + for _, bli := range blis { + li, err := newLineInfo(bli, strings) + if err != nil { + return nil, fmt.Errorf("offset %d: %w", bli.InsnOff, err) + } + lis = append(lis, *li) + } + sort.Slice(lis, func(i, j int) bool { + return lis[i].offset <= lis[j].offset + }) + return lis, nil +} + +// marshal writes the binary representation of the LineInfo to w. +func (li *lineInfo) marshal(w *bytes.Buffer, b *Builder) error { + line := li.line + if line.lineNumber > bpfLineMax { + return fmt.Errorf("line %d exceeds %d", line.lineNumber, bpfLineMax) + } + + if line.lineColumn > bpfColumnMax { + return fmt.Errorf("column %d exceeds %d", line.lineColumn, bpfColumnMax) + } + + fileNameOff, err := b.addString(line.fileName) + if err != nil { + return fmt.Errorf("file name %q: %w", line.fileName, err) + } + + lineOff, err := b.addString(line.line) + if err != nil { + return fmt.Errorf("line %q: %w", line.line, err) + } + + bli := bpfLineInfo{ + uint32(li.offset), + fileNameOff, + lineOff, + (line.lineNumber << bpfLineShift) | line.lineColumn, + } + + buf := make([]byte, LineInfoSize) + internal.NativeEndian.PutUint32(buf, bli.InsnOff) + internal.NativeEndian.PutUint32(buf[4:], bli.FileNameOff) + internal.NativeEndian.PutUint32(buf[8:], bli.LineOff) + internal.NativeEndian.PutUint32(buf[12:], bli.LineCol) + _, err = w.Write(buf) + return err +} + +// parseLineInfos parses a line_info sub-section within .BTF.ext ito a map of +// line infos indexed by section name. +func parseLineInfos(r io.Reader, bo binary.ByteOrder, strings *stringTable) (map[string][]bpfLineInfo, error) { + recordSize, err := parseExtInfoRecordSize(r, bo) + if err != nil { + return nil, err + } + + result := make(map[string][]bpfLineInfo) + for { + secName, infoHeader, err := parseExtInfoSec(r, bo, strings) + if errors.Is(err, io.EOF) { + return result, nil + } + if err != nil { + return nil, err + } + + records, err := parseLineInfoRecords(r, bo, recordSize, infoHeader.NumInfo) + if err != nil { + return nil, fmt.Errorf("section %v: %w", secName, err) + } + + result[secName] = records + } +} + +// parseLineInfoRecords parses a stream of line_infos into a lineInfos. +// These records appear after a btf_ext_info_sec header in the line_info +// sub-section of .BTF.ext. +func parseLineInfoRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, recordNum uint32) ([]bpfLineInfo, error) { + var out []bpfLineInfo + var li bpfLineInfo + + if exp, got := uint32(binary.Size(li)), recordSize; exp != got { + // BTF blob's record size is longer than we know how to parse. + return nil, fmt.Errorf("expected LineInfo record size %d, but BTF blob contains %d", exp, got) + } + + for i := uint32(0); i < recordNum; i++ { + if err := binary.Read(r, bo, &li); err != nil { + return nil, fmt.Errorf("can't read line info: %v", err) + } + + if li.InsnOff%asm.InstructionSize != 0 { + return nil, fmt.Errorf("offset %v is not aligned with instruction size", li.InsnOff) + } + + // ELF tracks offset in bytes, the kernel expects raw BPF instructions. + // Convert as early as possible. + li.InsnOff /= asm.InstructionSize + + out = append(out, li) + } + + return out, nil +} + +// bpfCORERelo matches the kernel's struct bpf_core_relo. +type bpfCORERelo struct { + InsnOff uint32 + TypeID TypeID + AccessStrOff uint32 + Kind coreKind +} + +type CORERelocation struct { + // The local type of the relocation, stripped of typedefs and qualifiers. + typ Type + accessor coreAccessor + kind coreKind + // The ID of the local type in the source BTF. + id TypeID +} + +func (cr *CORERelocation) String() string { + return fmt.Sprintf("CORERelocation(%s, %s[%s], local_id=%d)", cr.kind, cr.typ, cr.accessor, cr.id) +} + +func CORERelocationMetadata(ins *asm.Instruction) *CORERelocation { + relo, _ := ins.Metadata.Get(coreRelocationMeta{}).(*CORERelocation) + return relo +} + +type coreRelocationInfo struct { + relo *CORERelocation + offset asm.RawInstructionOffset +} + +func newRelocationInfo(relo bpfCORERelo, spec *Spec, strings *stringTable) (*coreRelocationInfo, error) { + typ, err := spec.TypeByID(relo.TypeID) + if err != nil { + return nil, err + } + + accessorStr, err := strings.Lookup(relo.AccessStrOff) + if err != nil { + return nil, err + } + + accessor, err := parseCOREAccessor(accessorStr) + if err != nil { + return nil, fmt.Errorf("accessor %q: %s", accessorStr, err) + } + + return &coreRelocationInfo{ + &CORERelocation{ + typ, + accessor, + relo.Kind, + relo.TypeID, + }, + asm.RawInstructionOffset(relo.InsnOff), + }, nil +} + +func newRelocationInfos(brs []bpfCORERelo, spec *Spec, strings *stringTable) ([]coreRelocationInfo, error) { + rs := make([]coreRelocationInfo, 0, len(brs)) + for _, br := range brs { + relo, err := newRelocationInfo(br, spec, strings) + if err != nil { + return nil, fmt.Errorf("offset %d: %w", br.InsnOff, err) + } + rs = append(rs, *relo) + } + sort.Slice(rs, func(i, j int) bool { + return rs[i].offset < rs[j].offset + }) + return rs, nil +} + +var extInfoReloSize = binary.Size(bpfCORERelo{}) + +// parseCORERelos parses a core_relos sub-section within .BTF.ext ito a map of +// CO-RE relocations indexed by section name. +func parseCORERelos(r io.Reader, bo binary.ByteOrder, strings *stringTable) (map[string][]bpfCORERelo, error) { + recordSize, err := parseExtInfoRecordSize(r, bo) + if err != nil { + return nil, err + } + + if recordSize != uint32(extInfoReloSize) { + return nil, fmt.Errorf("expected record size %d, got %d", extInfoReloSize, recordSize) + } + + result := make(map[string][]bpfCORERelo) + for { + secName, infoHeader, err := parseExtInfoSec(r, bo, strings) + if errors.Is(err, io.EOF) { + return result, nil + } + if err != nil { + return nil, err + } + + records, err := parseCOREReloRecords(r, bo, recordSize, infoHeader.NumInfo) + if err != nil { + return nil, fmt.Errorf("section %v: %w", secName, err) + } + + result[secName] = records + } +} + +// parseCOREReloRecords parses a stream of CO-RE relocation entries into a +// coreRelos. These records appear after a btf_ext_info_sec header in the +// core_relos sub-section of .BTF.ext. +func parseCOREReloRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, recordNum uint32) ([]bpfCORERelo, error) { + var out []bpfCORERelo + + var relo bpfCORERelo + for i := uint32(0); i < recordNum; i++ { + if err := binary.Read(r, bo, &relo); err != nil { + return nil, fmt.Errorf("can't read CO-RE relocation: %v", err) + } + + if relo.InsnOff%asm.InstructionSize != 0 { + return nil, fmt.Errorf("offset %v is not aligned with instruction size", relo.InsnOff) + } + + // ELF tracks offset in bytes, the kernel expects raw BPF instructions. + // Convert as early as possible. + relo.InsnOff /= asm.InstructionSize + + out = append(out, relo) + } + + return out, nil +} diff --git a/vendor/github.com/cilium/ebpf/btf/format.go b/vendor/github.com/cilium/ebpf/btf/format.go new file mode 100644 index 0000000000..e85220259e --- /dev/null +++ b/vendor/github.com/cilium/ebpf/btf/format.go @@ -0,0 +1,344 @@ +package btf + +import ( + "errors" + "fmt" + "strings" +) + +var errNestedTooDeep = errors.New("nested too deep") + +// GoFormatter converts a Type to Go syntax. +// +// A zero GoFormatter is valid to use. +type GoFormatter struct { + w strings.Builder + + // Types present in this map are referred to using the given name if they + // are encountered when outputting another type. + Names map[Type]string + + // Identifier is called for each field of struct-like types. By default the + // field name is used as is. + Identifier func(string) string + + // EnumIdentifier is called for each element of an enum. By default the + // name of the enum type is concatenated with Identifier(element). + EnumIdentifier func(name, element string) string +} + +// TypeDeclaration generates a Go type declaration for a BTF type. +func (gf *GoFormatter) TypeDeclaration(name string, typ Type) (string, error) { + gf.w.Reset() + if err := gf.writeTypeDecl(name, typ); err != nil { + return "", err + } + return gf.w.String(), nil +} + +func (gf *GoFormatter) identifier(s string) string { + if gf.Identifier != nil { + return gf.Identifier(s) + } + + return s +} + +func (gf *GoFormatter) enumIdentifier(name, element string) string { + if gf.EnumIdentifier != nil { + return gf.EnumIdentifier(name, element) + } + + return name + gf.identifier(element) +} + +// writeTypeDecl outputs a declaration of the given type. +// +// It encodes https://golang.org/ref/spec#Type_declarations: +// +// type foo struct { bar uint32; } +// type bar int32 +func (gf *GoFormatter) writeTypeDecl(name string, typ Type) error { + if name == "" { + return fmt.Errorf("need a name for type %s", typ) + } + + typ = skipQualifiers(typ) + fmt.Fprintf(&gf.w, "type %s ", name) + if err := gf.writeTypeLit(typ, 0); err != nil { + return err + } + + e, ok := typ.(*Enum) + if !ok || len(e.Values) == 0 { + return nil + } + + gf.w.WriteString("; const ( ") + for _, ev := range e.Values { + id := gf.enumIdentifier(name, ev.Name) + fmt.Fprintf(&gf.w, "%s %s = %d; ", id, name, ev.Value) + } + gf.w.WriteString(")") + + return nil +} + +// writeType outputs the name of a named type or a literal describing the type. +// +// It encodes https://golang.org/ref/spec#Types. +// +// foo (if foo is a named type) +// uint32 +func (gf *GoFormatter) writeType(typ Type, depth int) error { + typ = skipQualifiers(typ) + + name := gf.Names[typ] + if name != "" { + gf.w.WriteString(name) + return nil + } + + return gf.writeTypeLit(typ, depth) +} + +// writeTypeLit outputs a literal describing the type. +// +// The function ignores named types. +// +// It encodes https://golang.org/ref/spec#TypeLit. +// +// struct { bar uint32; } +// uint32 +func (gf *GoFormatter) writeTypeLit(typ Type, depth int) error { + depth++ + if depth > maxTypeDepth { + return errNestedTooDeep + } + + var err error + switch v := skipQualifiers(typ).(type) { + case *Int: + err = gf.writeIntLit(v) + + case *Enum: + if !v.Signed { + gf.w.WriteRune('u') + } + switch v.Size { + case 1: + gf.w.WriteString("int8") + case 2: + gf.w.WriteString("int16") + case 4: + gf.w.WriteString("int32") + case 8: + gf.w.WriteString("int64") + default: + err = fmt.Errorf("invalid enum size %d", v.Size) + } + + case *Typedef: + err = gf.writeType(v.Type, depth) + + case *Array: + fmt.Fprintf(&gf.w, "[%d]", v.Nelems) + err = gf.writeType(v.Type, depth) + + case *Struct: + err = gf.writeStructLit(v.Size, v.Members, depth) + + case *Union: + // Always choose the first member to represent the union in Go. + err = gf.writeStructLit(v.Size, v.Members[:1], depth) + + case *Datasec: + err = gf.writeDatasecLit(v, depth) + + default: + return fmt.Errorf("type %T: %w", v, ErrNotSupported) + } + + if err != nil { + return fmt.Errorf("%s: %w", typ, err) + } + + return nil +} + +func (gf *GoFormatter) writeIntLit(i *Int) error { + bits := i.Size * 8 + switch i.Encoding { + case Bool: + if i.Size != 1 { + return fmt.Errorf("bool with size %d", i.Size) + } + gf.w.WriteString("bool") + case Char: + if i.Size != 1 { + return fmt.Errorf("char with size %d", i.Size) + } + // BTF doesn't have a way to specify the signedness of a char. Assume + // we are dealing with unsigned, since this works nicely with []byte + // in Go code. + fallthrough + case Unsigned, Signed: + stem := "uint" + if i.Encoding == Signed { + stem = "int" + } + if i.Size > 8 { + fmt.Fprintf(&gf.w, "[%d]byte /* %s%d */", i.Size, stem, i.Size*8) + } else { + fmt.Fprintf(&gf.w, "%s%d", stem, bits) + } + default: + return fmt.Errorf("can't encode %s", i.Encoding) + } + return nil +} + +func (gf *GoFormatter) writeStructLit(size uint32, members []Member, depth int) error { + gf.w.WriteString("struct { ") + + prevOffset := uint32(0) + skippedBitfield := false + for i, m := range members { + if m.BitfieldSize > 0 { + skippedBitfield = true + continue + } + + offset := m.Offset.Bytes() + if n := offset - prevOffset; skippedBitfield && n > 0 { + fmt.Fprintf(&gf.w, "_ [%d]byte /* unsupported bitfield */; ", n) + } else { + gf.writePadding(n) + } + + fieldSize, err := Sizeof(m.Type) + if err != nil { + return fmt.Errorf("field %d: %w", i, err) + } + + prevOffset = offset + uint32(fieldSize) + if prevOffset > size { + return fmt.Errorf("field %d of size %d exceeds type size %d", i, fieldSize, size) + } + + if err := gf.writeStructField(m, depth); err != nil { + return fmt.Errorf("field %d: %w", i, err) + } + } + + gf.writePadding(size - prevOffset) + gf.w.WriteString("}") + return nil +} + +func (gf *GoFormatter) writeStructField(m Member, depth int) error { + if m.BitfieldSize > 0 { + return fmt.Errorf("bitfields are not supported") + } + if m.Offset%8 != 0 { + return fmt.Errorf("unsupported offset %d", m.Offset) + } + + if m.Name == "" { + // Special case a nested anonymous union like + // struct foo { union { int bar; int baz }; } + // by replacing the whole union with its first member. + union, ok := m.Type.(*Union) + if !ok { + return fmt.Errorf("anonymous fields are not supported") + + } + + if len(union.Members) == 0 { + return errors.New("empty anonymous union") + } + + depth++ + if depth > maxTypeDepth { + return errNestedTooDeep + } + + m := union.Members[0] + size, err := Sizeof(m.Type) + if err != nil { + return err + } + + if err := gf.writeStructField(m, depth); err != nil { + return err + } + + gf.writePadding(union.Size - uint32(size)) + return nil + + } + + fmt.Fprintf(&gf.w, "%s ", gf.identifier(m.Name)) + + if err := gf.writeType(m.Type, depth); err != nil { + return err + } + + gf.w.WriteString("; ") + return nil +} + +func (gf *GoFormatter) writeDatasecLit(ds *Datasec, depth int) error { + gf.w.WriteString("struct { ") + + prevOffset := uint32(0) + for i, vsi := range ds.Vars { + v, ok := vsi.Type.(*Var) + if !ok { + return fmt.Errorf("can't format %s as part of data section", vsi.Type) + } + + if v.Linkage != GlobalVar { + // Ignore static, extern, etc. for now. + continue + } + + if v.Name == "" { + return fmt.Errorf("variable %d: empty name", i) + } + + gf.writePadding(vsi.Offset - prevOffset) + prevOffset = vsi.Offset + vsi.Size + + fmt.Fprintf(&gf.w, "%s ", gf.identifier(v.Name)) + + if err := gf.writeType(v.Type, depth); err != nil { + return fmt.Errorf("variable %d: %w", i, err) + } + + gf.w.WriteString("; ") + } + + gf.writePadding(ds.Size - prevOffset) + gf.w.WriteString("}") + return nil +} + +func (gf *GoFormatter) writePadding(bytes uint32) { + if bytes > 0 { + fmt.Fprintf(&gf.w, "_ [%d]byte; ", bytes) + } +} + +func skipQualifiers(typ Type) Type { + result := typ + for depth := 0; depth <= maxTypeDepth; depth++ { + switch v := (result).(type) { + case qualifier: + result = v.qualify() + default: + return result + } + } + return &cycle{typ} +} diff --git a/vendor/github.com/cilium/ebpf/btf/handle.go b/vendor/github.com/cilium/ebpf/btf/handle.go new file mode 100644 index 0000000000..b6b3e87f50 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/btf/handle.go @@ -0,0 +1,287 @@ +package btf + +import ( + "bytes" + "errors" + "fmt" + "math" + "os" + + "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/sys" + "github.com/cilium/ebpf/internal/unix" +) + +// Handle is a reference to BTF loaded into the kernel. +type Handle struct { + fd *sys.FD + + // Size of the raw BTF in bytes. + size uint32 + + needsKernelBase bool +} + +// NewHandle loads the contents of a [Builder] into the kernel. +// +// Returns an error wrapping ErrNotSupported if the kernel doesn't support BTF. +func NewHandle(b *Builder) (*Handle, error) { + small := getByteSlice() + defer putByteSlice(small) + + buf, err := b.Marshal(*small, KernelMarshalOptions()) + if err != nil { + return nil, fmt.Errorf("marshal BTF: %w", err) + } + + return NewHandleFromRawBTF(buf) +} + +// NewHandleFromRawBTF loads raw BTF into the kernel. +// +// Returns an error wrapping ErrNotSupported if the kernel doesn't support BTF. +func NewHandleFromRawBTF(btf []byte) (*Handle, error) { + if uint64(len(btf)) > math.MaxUint32 { + return nil, errors.New("BTF exceeds the maximum size") + } + + attr := &sys.BtfLoadAttr{ + Btf: sys.NewSlicePointer(btf), + BtfSize: uint32(len(btf)), + } + + fd, err := sys.BtfLoad(attr) + if err == nil { + return &Handle{fd, attr.BtfSize, false}, nil + } + + if err := haveBTF(); err != nil { + return nil, err + } + + logBuf := make([]byte, 64*1024) + attr.BtfLogBuf = sys.NewSlicePointer(logBuf) + attr.BtfLogSize = uint32(len(logBuf)) + attr.BtfLogLevel = 1 + + // Up until at least kernel 6.0, the BTF verifier does not return ENOSPC + // if there are other verification errors. ENOSPC is only returned when + // the BTF blob is correct, a log was requested, and the provided buffer + // is too small. + _, ve := sys.BtfLoad(attr) + return nil, internal.ErrorWithLog("load btf", err, logBuf, errors.Is(ve, unix.ENOSPC)) +} + +// NewHandleFromID returns the BTF handle for a given id. +// +// Prefer calling [ebpf.Program.Handle] or [ebpf.Map.Handle] if possible. +// +// Returns ErrNotExist, if there is no BTF with the given id. +// +// Requires CAP_SYS_ADMIN. +func NewHandleFromID(id ID) (*Handle, error) { + fd, err := sys.BtfGetFdById(&sys.BtfGetFdByIdAttr{ + Id: uint32(id), + }) + if err != nil { + return nil, fmt.Errorf("get FD for ID %d: %w", id, err) + } + + info, err := newHandleInfoFromFD(fd) + if err != nil { + _ = fd.Close() + return nil, err + } + + return &Handle{fd, info.size, info.IsModule()}, nil +} + +// Spec parses the kernel BTF into Go types. +// +// base must contain type information for vmlinux if the handle is for +// a kernel module. It may be nil otherwise. +func (h *Handle) Spec(base *Spec) (*Spec, error) { + var btfInfo sys.BtfInfo + btfBuffer := make([]byte, h.size) + btfInfo.Btf, btfInfo.BtfSize = sys.NewSlicePointerLen(btfBuffer) + + if err := sys.ObjInfo(h.fd, &btfInfo); err != nil { + return nil, err + } + + if h.needsKernelBase && base == nil { + return nil, fmt.Errorf("missing base types") + } + + return loadRawSpec(bytes.NewReader(btfBuffer), internal.NativeEndian, base) +} + +// Close destroys the handle. +// +// Subsequent calls to FD will return an invalid value. +func (h *Handle) Close() error { + if h == nil { + return nil + } + + return h.fd.Close() +} + +// FD returns the file descriptor for the handle. +func (h *Handle) FD() int { + return h.fd.Int() +} + +// Info returns metadata about the handle. +func (h *Handle) Info() (*HandleInfo, error) { + return newHandleInfoFromFD(h.fd) +} + +// HandleInfo describes a Handle. +type HandleInfo struct { + // ID of this handle in the kernel. The ID is only valid as long as the + // associated handle is kept alive. + ID ID + + // Name is an identifying name for the BTF, currently only used by the + // kernel. + Name string + + // IsKernel is true if the BTF originated with the kernel and not + // userspace. + IsKernel bool + + // Size of the raw BTF in bytes. + size uint32 +} + +func newHandleInfoFromFD(fd *sys.FD) (*HandleInfo, error) { + // We invoke the syscall once with a empty BTF and name buffers to get size + // information to allocate buffers. Then we invoke it a second time with + // buffers to receive the data. + var btfInfo sys.BtfInfo + if err := sys.ObjInfo(fd, &btfInfo); err != nil { + return nil, fmt.Errorf("get BTF info for fd %s: %w", fd, err) + } + + if btfInfo.NameLen > 0 { + // NameLen doesn't account for the terminating NUL. + btfInfo.NameLen++ + } + + // Don't pull raw BTF by default, since it may be quite large. + btfSize := btfInfo.BtfSize + btfInfo.BtfSize = 0 + + nameBuffer := make([]byte, btfInfo.NameLen) + btfInfo.Name, btfInfo.NameLen = sys.NewSlicePointerLen(nameBuffer) + if err := sys.ObjInfo(fd, &btfInfo); err != nil { + return nil, err + } + + return &HandleInfo{ + ID: ID(btfInfo.Id), + Name: unix.ByteSliceToString(nameBuffer), + IsKernel: btfInfo.KernelBtf != 0, + size: btfSize, + }, nil +} + +// IsVmlinux returns true if the BTF is for the kernel itself. +func (i *HandleInfo) IsVmlinux() bool { + return i.IsKernel && i.Name == "vmlinux" +} + +// IsModule returns true if the BTF is for a kernel module. +func (i *HandleInfo) IsModule() bool { + return i.IsKernel && i.Name != "vmlinux" +} + +// HandleIterator allows enumerating BTF blobs loaded into the kernel. +type HandleIterator struct { + // The ID of the current handle. Only valid after a call to Next. + ID ID + // The current Handle. Only valid until a call to Next. + // See Take if you want to retain the handle. + Handle *Handle + err error +} + +// Next retrieves a handle for the next BTF object. +// +// Returns true if another BTF object was found. Call [HandleIterator.Err] after +// the function returns false. +func (it *HandleIterator) Next() bool { + id := it.ID + for { + attr := &sys.BtfGetNextIdAttr{Id: id} + err := sys.BtfGetNextId(attr) + if errors.Is(err, os.ErrNotExist) { + // There are no more BTF objects. + break + } else if err != nil { + it.err = fmt.Errorf("get next BTF ID: %w", err) + break + } + + id = attr.NextId + handle, err := NewHandleFromID(id) + if errors.Is(err, os.ErrNotExist) { + // Try again with the next ID. + continue + } else if err != nil { + it.err = fmt.Errorf("retrieve handle for ID %d: %w", id, err) + break + } + + it.Handle.Close() + it.ID, it.Handle = id, handle + return true + } + + // No more handles or we encountered an error. + it.Handle.Close() + it.Handle = nil + return false +} + +// Take the ownership of the current handle. +// +// It's the callers responsibility to close the handle. +func (it *HandleIterator) Take() *Handle { + handle := it.Handle + it.Handle = nil + return handle +} + +// Err returns an error if iteration failed for some reason. +func (it *HandleIterator) Err() error { + return it.err +} + +// FindHandle returns the first handle for which predicate returns true. +// +// Requires CAP_SYS_ADMIN. +// +// Returns an error wrapping ErrNotFound if predicate never returns true or if +// there is no BTF loaded into the kernel. +func FindHandle(predicate func(info *HandleInfo) bool) (*Handle, error) { + it := new(HandleIterator) + defer it.Handle.Close() + + for it.Next() { + info, err := it.Handle.Info() + if err != nil { + return nil, fmt.Errorf("info for ID %d: %w", it.ID, err) + } + + if predicate(info) { + return it.Take(), nil + } + } + if err := it.Err(); err != nil { + return nil, fmt.Errorf("iterate handles: %w", err) + } + + return nil, fmt.Errorf("find handle: %w", ErrNotFound) +} diff --git a/vendor/github.com/cilium/ebpf/btf/marshal.go b/vendor/github.com/cilium/ebpf/btf/marshal.go new file mode 100644 index 0000000000..bfe53b4107 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/btf/marshal.go @@ -0,0 +1,543 @@ +package btf + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "math" + "sync" + + "github.com/cilium/ebpf/internal" + + "golang.org/x/exp/slices" +) + +type MarshalOptions struct { + // Target byte order. Defaults to the system's native endianness. + Order binary.ByteOrder + // Remove function linkage information for compatibility with <5.6 kernels. + StripFuncLinkage bool +} + +// KernelMarshalOptions will generate BTF suitable for the current kernel. +func KernelMarshalOptions() *MarshalOptions { + return &MarshalOptions{ + Order: internal.NativeEndian, + StripFuncLinkage: haveFuncLinkage() != nil, + } +} + +// encoder turns Types into raw BTF. +type encoder struct { + MarshalOptions + + pending internal.Deque[Type] + buf *bytes.Buffer + strings *stringTableBuilder + ids map[Type]TypeID + lastID TypeID +} + +var bufferPool = sync.Pool{ + New: func() any { + buf := make([]byte, btfHeaderLen+128) + return &buf + }, +} + +func getByteSlice() *[]byte { + return bufferPool.Get().(*[]byte) +} + +func putByteSlice(buf *[]byte) { + *buf = (*buf)[:0] + bufferPool.Put(buf) +} + +// Builder turns Types into raw BTF. +// +// The default value may be used and represents an empty BTF blob. Void is +// added implicitly if necessary. +type Builder struct { + // Explicitly added types. + types []Type + // IDs for all added types which the user knows about. + stableIDs map[Type]TypeID + // Explicitly added strings. + strings *stringTableBuilder +} + +// NewBuilder creates a Builder from a list of types. +// +// It is more efficient than calling [Add] individually. +// +// Returns an error if adding any of the types fails. +func NewBuilder(types []Type) (*Builder, error) { + b := &Builder{ + make([]Type, 0, len(types)), + make(map[Type]TypeID, len(types)), + nil, + } + + for _, typ := range types { + _, err := b.Add(typ) + if err != nil { + return nil, fmt.Errorf("add %s: %w", typ, err) + } + } + + return b, nil +} + +// Add a Type and allocate a stable ID for it. +// +// Adding the identical Type multiple times is valid and will return the same ID. +// +// See [Type] for details on identity. +func (b *Builder) Add(typ Type) (TypeID, error) { + if b.stableIDs == nil { + b.stableIDs = make(map[Type]TypeID) + } + + if _, ok := typ.(*Void); ok { + // Equality is weird for void, since it is a zero sized type. + return 0, nil + } + + if ds, ok := typ.(*Datasec); ok { + if err := datasecResolveWorkaround(b, ds); err != nil { + return 0, err + } + } + + id, ok := b.stableIDs[typ] + if ok { + return id, nil + } + + b.types = append(b.types, typ) + + id = TypeID(len(b.types)) + if int(id) != len(b.types) { + return 0, fmt.Errorf("no more type IDs") + } + + b.stableIDs[typ] = id + return id, nil +} + +// Marshal encodes all types in the Marshaler into BTF wire format. +// +// opts may be nil. +func (b *Builder) Marshal(buf []byte, opts *MarshalOptions) ([]byte, error) { + stb := b.strings + if stb == nil { + // Assume that most types are named. This makes encoding large BTF like + // vmlinux a lot cheaper. + stb = newStringTableBuilder(len(b.types)) + } else { + // Avoid modifying the Builder's string table. + stb = b.strings.Copy() + } + + if opts == nil { + opts = &MarshalOptions{Order: internal.NativeEndian} + } + + // Reserve space for the BTF header. + buf = slices.Grow(buf, btfHeaderLen)[:btfHeaderLen] + + w := internal.NewBuffer(buf) + defer internal.PutBuffer(w) + + e := encoder{ + MarshalOptions: *opts, + buf: w, + strings: stb, + lastID: TypeID(len(b.types)), + ids: make(map[Type]TypeID, len(b.types)), + } + + // Ensure that types are marshaled in the exact order they were Add()ed. + // Otherwise the ID returned from Add() won't match. + e.pending.Grow(len(b.types)) + for _, typ := range b.types { + e.pending.Push(typ) + e.ids[typ] = b.stableIDs[typ] + } + + if err := e.deflatePending(); err != nil { + return nil, err + } + + length := e.buf.Len() + typeLen := uint32(length - btfHeaderLen) + + stringLen := e.strings.Length() + buf = e.strings.AppendEncoded(e.buf.Bytes()) + + // Fill out the header, and write it out. + header := &btfHeader{ + Magic: btfMagic, + Version: 1, + Flags: 0, + HdrLen: uint32(btfHeaderLen), + TypeOff: 0, + TypeLen: typeLen, + StringOff: typeLen, + StringLen: uint32(stringLen), + } + + err := binary.Write(sliceWriter(buf[:btfHeaderLen]), e.Order, header) + if err != nil { + return nil, fmt.Errorf("write header: %v", err) + } + + return buf, nil +} + +// addString adds a string to the resulting BTF. +// +// Adding the same string multiple times will return the same result. +// +// Returns an identifier into the string table or an error if the string +// contains invalid characters. +func (b *Builder) addString(str string) (uint32, error) { + if b.strings == nil { + b.strings = newStringTableBuilder(0) + } + + return b.strings.Add(str) +} + +func (e *encoder) allocateID(typ Type) error { + id := e.lastID + 1 + if id < e.lastID { + return errors.New("type ID overflow") + } + + e.pending.Push(typ) + e.ids[typ] = id + e.lastID = id + return nil +} + +// id returns the ID for the given type or panics with an error. +func (e *encoder) id(typ Type) TypeID { + if _, ok := typ.(*Void); ok { + return 0 + } + + id, ok := e.ids[typ] + if !ok { + panic(fmt.Errorf("no ID for type %v", typ)) + } + + return id +} + +func (e *encoder) deflatePending() error { + // Declare root outside of the loop to avoid repeated heap allocations. + var root Type + skip := func(t Type) (skip bool) { + if t == root { + // Force descending into the current root type even if it already + // has an ID. Otherwise we miss children of types that have their + // ID pre-allocated via Add. + return false + } + + _, isVoid := t.(*Void) + _, alreadyEncoded := e.ids[t] + return isVoid || alreadyEncoded + } + + for !e.pending.Empty() { + root = e.pending.Shift() + + // Allocate IDs for all children of typ, including transitive dependencies. + iter := postorderTraversal(root, skip) + for iter.Next() { + if iter.Type == root { + // The iterator yields root at the end, do not allocate another ID. + break + } + + if err := e.allocateID(iter.Type); err != nil { + return err + } + } + + if err := e.deflateType(root); err != nil { + id := e.ids[root] + return fmt.Errorf("deflate %v with ID %d: %w", root, id, err) + } + } + + return nil +} + +func (e *encoder) deflateType(typ Type) (err error) { + defer func() { + if r := recover(); r != nil { + var ok bool + err, ok = r.(error) + if !ok { + panic(r) + } + } + }() + + var raw rawType + raw.NameOff, err = e.strings.Add(typ.TypeName()) + if err != nil { + return err + } + + switch v := typ.(type) { + case *Void: + return errors.New("Void is implicit in BTF wire format") + + case *Int: + raw.SetKind(kindInt) + raw.SetSize(v.Size) + + var bi btfInt + bi.SetEncoding(v.Encoding) + // We need to set bits in addition to size, since btf_type_int_is_regular + // otherwise flags this as a bitfield. + bi.SetBits(byte(v.Size) * 8) + raw.data = bi + + case *Pointer: + raw.SetKind(kindPointer) + raw.SetType(e.id(v.Target)) + + case *Array: + raw.SetKind(kindArray) + raw.data = &btfArray{ + e.id(v.Type), + e.id(v.Index), + v.Nelems, + } + + case *Struct: + raw.SetKind(kindStruct) + raw.SetSize(v.Size) + raw.data, err = e.convertMembers(&raw.btfType, v.Members) + + case *Union: + raw.SetKind(kindUnion) + raw.SetSize(v.Size) + raw.data, err = e.convertMembers(&raw.btfType, v.Members) + + case *Enum: + raw.SetSize(v.size()) + raw.SetVlen(len(v.Values)) + raw.SetSigned(v.Signed) + + if v.has64BitValues() { + raw.SetKind(kindEnum64) + raw.data, err = e.deflateEnum64Values(v.Values) + } else { + raw.SetKind(kindEnum) + raw.data, err = e.deflateEnumValues(v.Values) + } + + case *Fwd: + raw.SetKind(kindForward) + raw.SetFwdKind(v.Kind) + + case *Typedef: + raw.SetKind(kindTypedef) + raw.SetType(e.id(v.Type)) + + case *Volatile: + raw.SetKind(kindVolatile) + raw.SetType(e.id(v.Type)) + + case *Const: + raw.SetKind(kindConst) + raw.SetType(e.id(v.Type)) + + case *Restrict: + raw.SetKind(kindRestrict) + raw.SetType(e.id(v.Type)) + + case *Func: + raw.SetKind(kindFunc) + raw.SetType(e.id(v.Type)) + if !e.StripFuncLinkage { + raw.SetLinkage(v.Linkage) + } + + case *FuncProto: + raw.SetKind(kindFuncProto) + raw.SetType(e.id(v.Return)) + raw.SetVlen(len(v.Params)) + raw.data, err = e.deflateFuncParams(v.Params) + + case *Var: + raw.SetKind(kindVar) + raw.SetType(e.id(v.Type)) + raw.data = btfVariable{uint32(v.Linkage)} + + case *Datasec: + raw.SetKind(kindDatasec) + raw.SetSize(v.Size) + raw.SetVlen(len(v.Vars)) + raw.data = e.deflateVarSecinfos(v.Vars) + + case *Float: + raw.SetKind(kindFloat) + raw.SetSize(v.Size) + + case *declTag: + raw.SetKind(kindDeclTag) + raw.SetType(e.id(v.Type)) + raw.data = &btfDeclTag{uint32(v.Index)} + raw.NameOff, err = e.strings.Add(v.Value) + + case *typeTag: + raw.SetKind(kindTypeTag) + raw.SetType(e.id(v.Type)) + raw.NameOff, err = e.strings.Add(v.Value) + + default: + return fmt.Errorf("don't know how to deflate %T", v) + } + + if err != nil { + return err + } + + return raw.Marshal(e.buf, e.Order) +} + +func (e *encoder) convertMembers(header *btfType, members []Member) ([]btfMember, error) { + bms := make([]btfMember, 0, len(members)) + isBitfield := false + for _, member := range members { + isBitfield = isBitfield || member.BitfieldSize > 0 + + offset := member.Offset + if isBitfield { + offset = member.BitfieldSize<<24 | (member.Offset & 0xffffff) + } + + nameOff, err := e.strings.Add(member.Name) + if err != nil { + return nil, err + } + + bms = append(bms, btfMember{ + nameOff, + e.id(member.Type), + uint32(offset), + }) + } + + header.SetVlen(len(members)) + header.SetBitfield(isBitfield) + return bms, nil +} + +func (e *encoder) deflateEnumValues(values []EnumValue) ([]btfEnum, error) { + bes := make([]btfEnum, 0, len(values)) + for _, value := range values { + nameOff, err := e.strings.Add(value.Name) + if err != nil { + return nil, err + } + + if value.Value > math.MaxUint32 { + return nil, fmt.Errorf("value of enum %q exceeds 32 bits", value.Name) + } + + bes = append(bes, btfEnum{ + nameOff, + uint32(value.Value), + }) + } + + return bes, nil +} + +func (e *encoder) deflateEnum64Values(values []EnumValue) ([]btfEnum64, error) { + bes := make([]btfEnum64, 0, len(values)) + for _, value := range values { + nameOff, err := e.strings.Add(value.Name) + if err != nil { + return nil, err + } + + bes = append(bes, btfEnum64{ + nameOff, + uint32(value.Value), + uint32(value.Value >> 32), + }) + } + + return bes, nil +} + +func (e *encoder) deflateFuncParams(params []FuncParam) ([]btfParam, error) { + bps := make([]btfParam, 0, len(params)) + for _, param := range params { + nameOff, err := e.strings.Add(param.Name) + if err != nil { + return nil, err + } + + bps = append(bps, btfParam{ + nameOff, + e.id(param.Type), + }) + } + return bps, nil +} + +func (e *encoder) deflateVarSecinfos(vars []VarSecinfo) []btfVarSecinfo { + vsis := make([]btfVarSecinfo, 0, len(vars)) + for _, v := range vars { + vsis = append(vsis, btfVarSecinfo{ + e.id(v.Type), + v.Offset, + v.Size, + }) + } + return vsis +} + +// MarshalMapKV creates a BTF object containing a map key and value. +// +// The function is intended for the use of the ebpf package and may be removed +// at any point in time. +func MarshalMapKV(key, value Type) (_ *Handle, keyID, valueID TypeID, err error) { + var b Builder + + if key != nil { + keyID, err = b.Add(key) + if err != nil { + return nil, 0, 0, fmt.Errorf("add key type: %w", err) + } + } + + if value != nil { + valueID, err = b.Add(value) + if err != nil { + return nil, 0, 0, fmt.Errorf("add value type: %w", err) + } + } + + handle, err := NewHandle(&b) + if err != nil { + // Check for 'full' map BTF support, since kernels between 4.18 and 5.2 + // already support BTF blobs for maps without Var or Datasec just fine. + if err := haveMapBTF(); err != nil { + return nil, 0, 0, err + } + } + return handle, keyID, valueID, err +} diff --git a/vendor/github.com/cilium/ebpf/btf/strings.go b/vendor/github.com/cilium/ebpf/btf/strings.go new file mode 100644 index 0000000000..bc6aff2814 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/btf/strings.go @@ -0,0 +1,214 @@ +package btf + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "io" + "strings" + + "golang.org/x/exp/maps" +) + +type stringTable struct { + base *stringTable + offsets []uint32 + strings []string +} + +// sizedReader is implemented by bytes.Reader, io.SectionReader, strings.Reader, etc. +type sizedReader interface { + io.Reader + Size() int64 +} + +func readStringTable(r sizedReader, base *stringTable) (*stringTable, error) { + // When parsing split BTF's string table, the first entry offset is derived + // from the last entry offset of the base BTF. + firstStringOffset := uint32(0) + if base != nil { + idx := len(base.offsets) - 1 + firstStringOffset = base.offsets[idx] + uint32(len(base.strings[idx])) + 1 + } + + // Derived from vmlinux BTF. + const averageStringLength = 16 + + n := int(r.Size() / averageStringLength) + offsets := make([]uint32, 0, n) + strings := make([]string, 0, n) + + offset := firstStringOffset + scanner := bufio.NewScanner(r) + scanner.Split(splitNull) + for scanner.Scan() { + str := scanner.Text() + offsets = append(offsets, offset) + strings = append(strings, str) + offset += uint32(len(str)) + 1 + } + if err := scanner.Err(); err != nil { + return nil, err + } + + if len(strings) == 0 { + return nil, errors.New("string table is empty") + } + + if firstStringOffset == 0 && strings[0] != "" { + return nil, errors.New("first item in string table is non-empty") + } + + return &stringTable{base, offsets, strings}, nil +} + +func splitNull(data []byte, atEOF bool) (advance int, token []byte, err error) { + i := bytes.IndexByte(data, 0) + if i == -1 { + if atEOF && len(data) > 0 { + return 0, nil, errors.New("string table isn't null terminated") + } + return 0, nil, nil + } + + return i + 1, data[:i], nil +} + +func (st *stringTable) Lookup(offset uint32) (string, error) { + if st.base != nil && offset <= st.base.offsets[len(st.base.offsets)-1] { + return st.base.lookup(offset) + } + return st.lookup(offset) +} + +func (st *stringTable) lookup(offset uint32) (string, error) { + i := search(st.offsets, offset) + if i == len(st.offsets) || st.offsets[i] != offset { + return "", fmt.Errorf("offset %d isn't start of a string", offset) + } + + return st.strings[i], nil +} + +func (st *stringTable) Marshal(w io.Writer) error { + for _, str := range st.strings { + _, err := io.WriteString(w, str) + if err != nil { + return err + } + _, err = w.Write([]byte{0}) + if err != nil { + return err + } + } + return nil +} + +// Num returns the number of strings in the table. +func (st *stringTable) Num() int { + return len(st.strings) +} + +// search is a copy of sort.Search specialised for uint32. +// +// Licensed under https://go.dev/LICENSE +func search(ints []uint32, needle uint32) int { + // Define f(-1) == false and f(n) == true. + // Invariant: f(i-1) == false, f(j) == true. + i, j := 0, len(ints) + for i < j { + h := int(uint(i+j) >> 1) // avoid overflow when computing h + // i ≤ h < j + if !(ints[h] >= needle) { + i = h + 1 // preserves f(i-1) == false + } else { + j = h // preserves f(j) == true + } + } + // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i. + return i +} + +// stringTableBuilder builds BTF string tables. +type stringTableBuilder struct { + length uint32 + strings map[string]uint32 +} + +// newStringTableBuilder creates a builder with the given capacity. +// +// capacity may be zero. +func newStringTableBuilder(capacity int) *stringTableBuilder { + var stb stringTableBuilder + + if capacity == 0 { + // Use the runtime's small default size. + stb.strings = make(map[string]uint32) + } else { + stb.strings = make(map[string]uint32, capacity) + } + + // Ensure that the empty string is at index 0. + stb.append("") + return &stb +} + +// Add a string to the table. +// +// Adding the same string multiple times will only store it once. +func (stb *stringTableBuilder) Add(str string) (uint32, error) { + if strings.IndexByte(str, 0) != -1 { + return 0, fmt.Errorf("string contains null: %q", str) + } + + offset, ok := stb.strings[str] + if ok { + return offset, nil + } + + return stb.append(str), nil +} + +func (stb *stringTableBuilder) append(str string) uint32 { + offset := stb.length + stb.length += uint32(len(str)) + 1 + stb.strings[str] = offset + return offset +} + +// Lookup finds the offset of a string in the table. +// +// Returns an error if str hasn't been added yet. +func (stb *stringTableBuilder) Lookup(str string) (uint32, error) { + offset, ok := stb.strings[str] + if !ok { + return 0, fmt.Errorf("string %q is not in table", str) + } + + return offset, nil +} + +// Length returns the length in bytes. +func (stb *stringTableBuilder) Length() int { + return int(stb.length) +} + +// AppendEncoded appends the string table to the end of the provided buffer. +func (stb *stringTableBuilder) AppendEncoded(buf []byte) []byte { + n := len(buf) + buf = append(buf, make([]byte, stb.Length())...) + strings := buf[n:] + for str, offset := range stb.strings { + copy(strings[offset:], str) + } + return buf +} + +// Copy the string table builder. +func (stb *stringTableBuilder) Copy() *stringTableBuilder { + return &stringTableBuilder{ + stb.length, + maps.Clone(stb.strings), + } +} diff --git a/vendor/github.com/cilium/ebpf/btf/traversal.go b/vendor/github.com/cilium/ebpf/btf/traversal.go new file mode 100644 index 0000000000..a3a9dec940 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/btf/traversal.go @@ -0,0 +1,141 @@ +package btf + +import ( + "fmt" + + "github.com/cilium/ebpf/internal" +) + +// Functions to traverse a cyclic graph of types. The below was very useful: +// https://eli.thegreenplace.net/2015/directed-graph-traversal-orderings-and-applications-to-data-flow-analysis/#post-order-and-reverse-post-order + +type postorderIterator struct { + // Iteration skips types for which this function returns true. + skip func(Type) bool + // The root type. May be nil if skip(root) is true. + root Type + + // Contains types which need to be either walked or yielded. + types typeDeque + // Contains a boolean whether the type has been walked or not. + walked internal.Deque[bool] + // The set of types which has been pushed onto types. + pushed map[Type]struct{} + + // The current type. Only valid after a call to Next(). + Type Type +} + +// postorderTraversal iterates all types reachable from root by visiting the +// leaves of the graph first. +// +// Types for which skip returns true are ignored. skip may be nil. +func postorderTraversal(root Type, skip func(Type) (skip bool)) postorderIterator { + // Avoid allocations for the common case of a skipped root. + if skip != nil && skip(root) { + return postorderIterator{} + } + + po := postorderIterator{root: root, skip: skip} + walkType(root, po.push) + + return po +} + +func (po *postorderIterator) push(t *Type) { + if _, ok := po.pushed[*t]; ok || *t == po.root { + return + } + + if po.skip != nil && po.skip(*t) { + return + } + + if po.pushed == nil { + // Lazily allocate pushed to avoid an allocation for Types without children. + po.pushed = make(map[Type]struct{}) + } + + po.pushed[*t] = struct{}{} + po.types.Push(t) + po.walked.Push(false) +} + +// Next returns true if there is another Type to traverse. +func (po *postorderIterator) Next() bool { + for !po.types.Empty() { + t := po.types.Pop() + + if !po.walked.Pop() { + // Push the type again, so that we re-evaluate it in done state + // after all children have been handled. + po.types.Push(t) + po.walked.Push(true) + + // Add all direct children to todo. + walkType(*t, po.push) + } else { + // We've walked this type previously, so we now know that all + // children have been handled. + po.Type = *t + return true + } + } + + // Only return root once. + po.Type, po.root = po.root, nil + return po.Type != nil +} + +// walkType calls fn on each child of typ. +func walkType(typ Type, fn func(*Type)) { + // Explicitly type switch on the most common types to allow the inliner to + // do its work. This avoids allocating intermediate slices from walk() on + // the heap. + switch v := typ.(type) { + case *Void, *Int, *Enum, *Fwd, *Float: + // No children to traverse. + case *Pointer: + fn(&v.Target) + case *Array: + fn(&v.Index) + fn(&v.Type) + case *Struct: + for i := range v.Members { + fn(&v.Members[i].Type) + } + case *Union: + for i := range v.Members { + fn(&v.Members[i].Type) + } + case *Typedef: + fn(&v.Type) + case *Volatile: + fn(&v.Type) + case *Const: + fn(&v.Type) + case *Restrict: + fn(&v.Type) + case *Func: + fn(&v.Type) + case *FuncProto: + fn(&v.Return) + for i := range v.Params { + fn(&v.Params[i].Type) + } + case *Var: + fn(&v.Type) + case *Datasec: + for i := range v.Vars { + fn(&v.Vars[i].Type) + } + case *declTag: + fn(&v.Type) + case *typeTag: + fn(&v.Type) + case *cycle: + // cycle has children, but we ignore them deliberately. + default: + panic(fmt.Sprintf("don't know how to walk Type %T", v)) + } +} diff --git a/vendor/github.com/cilium/ebpf/btf/types.go b/vendor/github.com/cilium/ebpf/btf/types.go new file mode 100644 index 0000000000..68d4a17571 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/btf/types.go @@ -0,0 +1,1258 @@ +package btf + +import ( + "errors" + "fmt" + "io" + "math" + "reflect" + "strings" + + "github.com/cilium/ebpf/asm" + "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/sys" +) + +const maxTypeDepth = 32 + +// TypeID identifies a type in a BTF section. +type TypeID = sys.TypeID + +// Type represents a type described by BTF. +// +// Identity of Type follows the [Go specification]: two Types are considered +// equal if they have the same concrete type and the same dynamic value, aka +// they point at the same location in memory. This means that the following +// Types are considered distinct even though they have the same "shape". +// +// a := &Int{Size: 1} +// b := &Int{Size: 1} +// a != b +// +// [Go specification]: https://go.dev/ref/spec#Comparison_operators +type Type interface { + // Type can be formatted using the %s and %v verbs. %s outputs only the + // identity of the type, without any detail. %v outputs additional detail. + // + // Use the '+' flag to include the address of the type. + // + // Use the width to specify how many levels of detail to output, for example + // %1v will output detail for the root type and a short description of its + // children. %2v would output details of the root type and its children + // as well as a short description of the grandchildren. + fmt.Formatter + + // Name of the type, empty for anonymous types and types that cannot + // carry a name, like Void and Pointer. + TypeName() string + + // Make a copy of the type, without copying Type members. + copy() Type + + // New implementations must update walkType. +} + +var ( + _ Type = (*Int)(nil) + _ Type = (*Struct)(nil) + _ Type = (*Union)(nil) + _ Type = (*Enum)(nil) + _ Type = (*Fwd)(nil) + _ Type = (*Func)(nil) + _ Type = (*Typedef)(nil) + _ Type = (*Var)(nil) + _ Type = (*Datasec)(nil) + _ Type = (*Float)(nil) + _ Type = (*declTag)(nil) + _ Type = (*typeTag)(nil) + _ Type = (*cycle)(nil) +) + +// Void is the unit type of BTF. +type Void struct{} + +func (v *Void) Format(fs fmt.State, verb rune) { formatType(fs, verb, v) } +func (v *Void) TypeName() string { return "" } +func (v *Void) size() uint32 { return 0 } +func (v *Void) copy() Type { return (*Void)(nil) } + +type IntEncoding byte + +// Valid IntEncodings. +// +// These may look like they are flags, but they aren't. +const ( + Unsigned IntEncoding = 0 + Signed IntEncoding = 1 + Char IntEncoding = 2 + Bool IntEncoding = 4 +) + +func (ie IntEncoding) String() string { + switch ie { + case Char: + // NB: There is no way to determine signedness for char. + return "char" + case Bool: + return "bool" + case Signed: + return "signed" + case Unsigned: + return "unsigned" + default: + return fmt.Sprintf("IntEncoding(%d)", byte(ie)) + } +} + +// Int is an integer of a given length. +// +// See https://www.kernel.org/doc/html/latest/bpf/btf.html#btf-kind-int +type Int struct { + Name string + + // The size of the integer in bytes. + Size uint32 + Encoding IntEncoding +} + +func (i *Int) Format(fs fmt.State, verb rune) { + formatType(fs, verb, i, i.Encoding, "size=", i.Size*8) +} + +func (i *Int) TypeName() string { return i.Name } +func (i *Int) size() uint32 { return i.Size } +func (i *Int) copy() Type { + cpy := *i + return &cpy +} + +// Pointer is a pointer to another type. +type Pointer struct { + Target Type +} + +func (p *Pointer) Format(fs fmt.State, verb rune) { + formatType(fs, verb, p, "target=", p.Target) +} + +func (p *Pointer) TypeName() string { return "" } +func (p *Pointer) size() uint32 { return 8 } +func (p *Pointer) copy() Type { + cpy := *p + return &cpy +} + +// Array is an array with a fixed number of elements. +type Array struct { + Index Type + Type Type + Nelems uint32 +} + +func (arr *Array) Format(fs fmt.State, verb rune) { + formatType(fs, verb, arr, "index=", arr.Index, "type=", arr.Type, "n=", arr.Nelems) +} + +func (arr *Array) TypeName() string { return "" } + +func (arr *Array) copy() Type { + cpy := *arr + return &cpy +} + +// Struct is a compound type of consecutive members. +type Struct struct { + Name string + // The size of the struct including padding, in bytes + Size uint32 + Members []Member +} + +func (s *Struct) Format(fs fmt.State, verb rune) { + formatType(fs, verb, s, "fields=", len(s.Members)) +} + +func (s *Struct) TypeName() string { return s.Name } + +func (s *Struct) size() uint32 { return s.Size } + +func (s *Struct) copy() Type { + cpy := *s + cpy.Members = copyMembers(s.Members) + return &cpy +} + +func (s *Struct) members() []Member { + return s.Members +} + +// Union is a compound type where members occupy the same memory. +type Union struct { + Name string + // The size of the union including padding, in bytes. + Size uint32 + Members []Member +} + +func (u *Union) Format(fs fmt.State, verb rune) { + formatType(fs, verb, u, "fields=", len(u.Members)) +} + +func (u *Union) TypeName() string { return u.Name } + +func (u *Union) size() uint32 { return u.Size } + +func (u *Union) copy() Type { + cpy := *u + cpy.Members = copyMembers(u.Members) + return &cpy +} + +func (u *Union) members() []Member { + return u.Members +} + +func copyMembers(orig []Member) []Member { + cpy := make([]Member, len(orig)) + copy(cpy, orig) + return cpy +} + +type composite interface { + Type + members() []Member +} + +var ( + _ composite = (*Struct)(nil) + _ composite = (*Union)(nil) +) + +// A value in bits. +type Bits uint32 + +// Bytes converts a bit value into bytes. +func (b Bits) Bytes() uint32 { + return uint32(b / 8) +} + +// Member is part of a Struct or Union. +// +// It is not a valid Type. +type Member struct { + Name string + Type Type + Offset Bits + BitfieldSize Bits +} + +// Enum lists possible values. +type Enum struct { + Name string + // Size of the enum value in bytes. + Size uint32 + // True if the values should be interpreted as signed integers. + Signed bool + Values []EnumValue +} + +func (e *Enum) Format(fs fmt.State, verb rune) { + formatType(fs, verb, e, "size=", e.Size, "values=", len(e.Values)) +} + +func (e *Enum) TypeName() string { return e.Name } + +// EnumValue is part of an Enum +// +// Is is not a valid Type +type EnumValue struct { + Name string + Value uint64 +} + +func (e *Enum) size() uint32 { return e.Size } +func (e *Enum) copy() Type { + cpy := *e + cpy.Values = make([]EnumValue, len(e.Values)) + copy(cpy.Values, e.Values) + return &cpy +} + +// has64BitValues returns true if the Enum contains a value larger than 32 bits. +// Kernels before 6.0 have enum values that overrun u32 replaced with zeroes. +// +// 64-bit enums have their Enum.Size attributes correctly set to 8, but if we +// use the size attribute as a heuristic during BTF marshaling, we'll emit +// ENUM64s to kernels that don't support them. +func (e *Enum) has64BitValues() bool { + for _, v := range e.Values { + if v.Value > math.MaxUint32 { + return true + } + } + return false +} + +// FwdKind is the type of forward declaration. +type FwdKind int + +// Valid types of forward declaration. +const ( + FwdStruct FwdKind = iota + FwdUnion +) + +func (fk FwdKind) String() string { + switch fk { + case FwdStruct: + return "struct" + case FwdUnion: + return "union" + default: + return fmt.Sprintf("%T(%d)", fk, int(fk)) + } +} + +// Fwd is a forward declaration of a Type. +type Fwd struct { + Name string + Kind FwdKind +} + +func (f *Fwd) Format(fs fmt.State, verb rune) { + formatType(fs, verb, f, f.Kind) +} + +func (f *Fwd) TypeName() string { return f.Name } + +func (f *Fwd) copy() Type { + cpy := *f + return &cpy +} + +// Typedef is an alias of a Type. +type Typedef struct { + Name string + Type Type +} + +func (td *Typedef) Format(fs fmt.State, verb rune) { + formatType(fs, verb, td, td.Type) +} + +func (td *Typedef) TypeName() string { return td.Name } + +func (td *Typedef) copy() Type { + cpy := *td + return &cpy +} + +// Volatile is a qualifier. +type Volatile struct { + Type Type +} + +func (v *Volatile) Format(fs fmt.State, verb rune) { + formatType(fs, verb, v, v.Type) +} + +func (v *Volatile) TypeName() string { return "" } + +func (v *Volatile) qualify() Type { return v.Type } +func (v *Volatile) copy() Type { + cpy := *v + return &cpy +} + +// Const is a qualifier. +type Const struct { + Type Type +} + +func (c *Const) Format(fs fmt.State, verb rune) { + formatType(fs, verb, c, c.Type) +} + +func (c *Const) TypeName() string { return "" } + +func (c *Const) qualify() Type { return c.Type } +func (c *Const) copy() Type { + cpy := *c + return &cpy +} + +// Restrict is a qualifier. +type Restrict struct { + Type Type +} + +func (r *Restrict) Format(fs fmt.State, verb rune) { + formatType(fs, verb, r, r.Type) +} + +func (r *Restrict) TypeName() string { return "" } + +func (r *Restrict) qualify() Type { return r.Type } +func (r *Restrict) copy() Type { + cpy := *r + return &cpy +} + +// Func is a function definition. +type Func struct { + Name string + Type Type + Linkage FuncLinkage +} + +func FuncMetadata(ins *asm.Instruction) *Func { + fn, _ := ins.Metadata.Get(funcInfoMeta{}).(*Func) + return fn +} + +// WithFuncMetadata adds a btf.Func to the Metadata of asm.Instruction. +func WithFuncMetadata(ins asm.Instruction, fn *Func) asm.Instruction { + ins.Metadata.Set(funcInfoMeta{}, fn) + return ins +} + +func (f *Func) Format(fs fmt.State, verb rune) { + formatType(fs, verb, f, f.Linkage, "proto=", f.Type) +} + +func (f *Func) TypeName() string { return f.Name } + +func (f *Func) copy() Type { + cpy := *f + return &cpy +} + +// FuncProto is a function declaration. +type FuncProto struct { + Return Type + Params []FuncParam +} + +func (fp *FuncProto) Format(fs fmt.State, verb rune) { + formatType(fs, verb, fp, "args=", len(fp.Params), "return=", fp.Return) +} + +func (fp *FuncProto) TypeName() string { return "" } + +func (fp *FuncProto) copy() Type { + cpy := *fp + cpy.Params = make([]FuncParam, len(fp.Params)) + copy(cpy.Params, fp.Params) + return &cpy +} + +type FuncParam struct { + Name string + Type Type +} + +// Var is a global variable. +type Var struct { + Name string + Type Type + Linkage VarLinkage +} + +func (v *Var) Format(fs fmt.State, verb rune) { + formatType(fs, verb, v, v.Linkage) +} + +func (v *Var) TypeName() string { return v.Name } + +func (v *Var) copy() Type { + cpy := *v + return &cpy +} + +// Datasec is a global program section containing data. +type Datasec struct { + Name string + Size uint32 + Vars []VarSecinfo +} + +func (ds *Datasec) Format(fs fmt.State, verb rune) { + formatType(fs, verb, ds) +} + +func (ds *Datasec) TypeName() string { return ds.Name } + +func (ds *Datasec) size() uint32 { return ds.Size } + +func (ds *Datasec) copy() Type { + cpy := *ds + cpy.Vars = make([]VarSecinfo, len(ds.Vars)) + copy(cpy.Vars, ds.Vars) + return &cpy +} + +// VarSecinfo describes variable in a Datasec. +// +// It is not a valid Type. +type VarSecinfo struct { + // Var or Func. + Type Type + Offset uint32 + Size uint32 +} + +// Float is a float of a given length. +type Float struct { + Name string + + // The size of the float in bytes. + Size uint32 +} + +func (f *Float) Format(fs fmt.State, verb rune) { + formatType(fs, verb, f, "size=", f.Size*8) +} + +func (f *Float) TypeName() string { return f.Name } +func (f *Float) size() uint32 { return f.Size } +func (f *Float) copy() Type { + cpy := *f + return &cpy +} + +// declTag associates metadata with a declaration. +type declTag struct { + Type Type + Value string + // The index this tag refers to in the target type. For composite types, + // a value of -1 indicates that the tag refers to the whole type. Otherwise + // it indicates which member or argument the tag applies to. + Index int +} + +func (dt *declTag) Format(fs fmt.State, verb rune) { + formatType(fs, verb, dt, "type=", dt.Type, "value=", dt.Value, "index=", dt.Index) +} + +func (dt *declTag) TypeName() string { return "" } +func (dt *declTag) copy() Type { + cpy := *dt + return &cpy +} + +// typeTag associates metadata with a type. +type typeTag struct { + Type Type + Value string +} + +func (tt *typeTag) Format(fs fmt.State, verb rune) { + formatType(fs, verb, tt, "type=", tt.Type, "value=", tt.Value) +} + +func (tt *typeTag) TypeName() string { return "" } +func (tt *typeTag) qualify() Type { return tt.Type } +func (tt *typeTag) copy() Type { + cpy := *tt + return &cpy +} + +// cycle is a type which had to be elided since it exceeded maxTypeDepth. +type cycle struct { + root Type +} + +func (c *cycle) ID() TypeID { return math.MaxUint32 } +func (c *cycle) Format(fs fmt.State, verb rune) { formatType(fs, verb, c, "root=", c.root) } +func (c *cycle) TypeName() string { return "" } +func (c *cycle) copy() Type { + cpy := *c + return &cpy +} + +type sizer interface { + size() uint32 +} + +var ( + _ sizer = (*Int)(nil) + _ sizer = (*Pointer)(nil) + _ sizer = (*Struct)(nil) + _ sizer = (*Union)(nil) + _ sizer = (*Enum)(nil) + _ sizer = (*Datasec)(nil) +) + +type qualifier interface { + qualify() Type +} + +var ( + _ qualifier = (*Const)(nil) + _ qualifier = (*Restrict)(nil) + _ qualifier = (*Volatile)(nil) + _ qualifier = (*typeTag)(nil) +) + +var errUnsizedType = errors.New("type is unsized") + +// Sizeof returns the size of a type in bytes. +// +// Returns an error if the size can't be computed. +func Sizeof(typ Type) (int, error) { + var ( + n = int64(1) + elem int64 + ) + + for i := 0; i < maxTypeDepth; i++ { + switch v := typ.(type) { + case *Array: + if n > 0 && int64(v.Nelems) > math.MaxInt64/n { + return 0, fmt.Errorf("type %s: overflow", typ) + } + + // Arrays may be of zero length, which allows + // n to be zero as well. + n *= int64(v.Nelems) + typ = v.Type + continue + + case sizer: + elem = int64(v.size()) + + case *Typedef: + typ = v.Type + continue + + case qualifier: + typ = v.qualify() + continue + + default: + return 0, fmt.Errorf("type %T: %w", typ, errUnsizedType) + } + + if n > 0 && elem > math.MaxInt64/n { + return 0, fmt.Errorf("type %s: overflow", typ) + } + + size := n * elem + if int64(int(size)) != size { + return 0, fmt.Errorf("type %s: overflow", typ) + } + + return int(size), nil + } + + return 0, fmt.Errorf("type %s: exceeded type depth", typ) +} + +// alignof returns the alignment of a type. +// +// Returns an error if the Type can't be aligned, like an integer with an uneven +// size. Currently only supports the subset of types necessary for bitfield +// relocations. +func alignof(typ Type) (int, error) { + var n int + + switch t := UnderlyingType(typ).(type) { + case *Enum: + n = int(t.size()) + case *Int: + n = int(t.Size) + case *Array: + return alignof(t.Type) + default: + return 0, fmt.Errorf("can't calculate alignment of %T", t) + } + + if !pow(n) { + return 0, fmt.Errorf("alignment value %d is not a power of two", n) + } + + return n, nil +} + +// pow returns true if n is a power of two. +func pow(n int) bool { + return n != 0 && (n&(n-1)) == 0 +} + +// Transformer modifies a given Type and returns the result. +// +// For example, UnderlyingType removes any qualifiers or typedefs from a type. +// See the example on Copy for how to use a transform. +type Transformer func(Type) Type + +// Copy a Type recursively. +// +// typ may form a cycle. If transform is not nil, it is called with the +// to be copied type, and the returned value is copied instead. +func Copy(typ Type, transform Transformer) Type { + copies := copier{copies: make(map[Type]Type)} + copies.copy(&typ, transform) + return typ +} + +// copy a slice of Types recursively. +// +// See Copy for the semantics. +func copyTypes(types []Type, transform Transformer) []Type { + result := make([]Type, len(types)) + copy(result, types) + + copies := copier{copies: make(map[Type]Type, len(types))} + for i := range result { + copies.copy(&result[i], transform) + } + + return result +} + +type copier struct { + copies map[Type]Type + work typeDeque +} + +func (c *copier) copy(typ *Type, transform Transformer) { + for t := typ; t != nil; t = c.work.Pop() { + // *t is the identity of the type. + if cpy := c.copies[*t]; cpy != nil { + *t = cpy + continue + } + + var cpy Type + if transform != nil { + cpy = transform(*t).copy() + } else { + cpy = (*t).copy() + } + + c.copies[*t] = cpy + *t = cpy + + // Mark any nested types for copying. + walkType(cpy, c.work.Push) + } +} + +type typeDeque = internal.Deque[*Type] + +// inflateRawTypes takes a list of raw btf types linked via type IDs, and turns +// it into a graph of Types connected via pointers. +// +// If base is provided, then the raw types are considered to be of a split BTF +// (e.g., a kernel module). +// +// Returns a slice of types indexed by TypeID. Since BTF ignores compilation +// units, multiple types may share the same name. A Type may form a cyclic graph +// by pointing at itself. +func inflateRawTypes(rawTypes []rawType, rawStrings *stringTable, base *Spec) ([]Type, error) { + types := make([]Type, 0, len(rawTypes)+1) // +1 for Void added to base types + + // Void is defined to always be type ID 0, and is thus omitted from BTF. + types = append(types, (*Void)(nil)) + + firstTypeID := TypeID(0) + if base != nil { + var err error + firstTypeID, err = base.nextTypeID() + if err != nil { + return nil, err + } + + // Split BTF doesn't contain Void. + types = types[:0] + } + + type fixupDef struct { + id TypeID + typ *Type + } + + var fixups []fixupDef + fixup := func(id TypeID, typ *Type) bool { + if id < firstTypeID { + if baseType, err := base.TypeByID(id); err == nil { + *typ = baseType + return true + } + } + + idx := int(id - firstTypeID) + if idx < len(types) { + // We've already inflated this type, fix it up immediately. + *typ = types[idx] + return true + } + + fixups = append(fixups, fixupDef{id, typ}) + return false + } + + type assertion struct { + id TypeID + typ *Type + want reflect.Type + } + + var assertions []assertion + fixupAndAssert := func(id TypeID, typ *Type, want reflect.Type) error { + if !fixup(id, typ) { + assertions = append(assertions, assertion{id, typ, want}) + return nil + } + + // The type has already been fixed up, check the type immediately. + if reflect.TypeOf(*typ) != want { + return fmt.Errorf("type ID %d: expected %s, got %T", id, want, *typ) + } + return nil + } + + type bitfieldFixupDef struct { + id TypeID + m *Member + } + + var ( + legacyBitfields = make(map[TypeID][2]Bits) // offset, size + bitfieldFixups []bitfieldFixupDef + ) + convertMembers := func(raw []btfMember, kindFlag bool) ([]Member, error) { + // NB: The fixup below relies on pre-allocating this array to + // work, since otherwise append might re-allocate members. + members := make([]Member, 0, len(raw)) + for i, btfMember := range raw { + name, err := rawStrings.Lookup(btfMember.NameOff) + if err != nil { + return nil, fmt.Errorf("can't get name for member %d: %w", i, err) + } + + members = append(members, Member{ + Name: name, + Offset: Bits(btfMember.Offset), + }) + + m := &members[i] + fixup(raw[i].Type, &m.Type) + + if kindFlag { + m.BitfieldSize = Bits(btfMember.Offset >> 24) + m.Offset &= 0xffffff + // We ignore legacy bitfield definitions if the current composite + // is a new-style bitfield. This is kind of safe since offset and + // size on the type of the member must be zero if kindFlat is set + // according to spec. + continue + } + + // This may be a legacy bitfield, try to fix it up. + data, ok := legacyBitfields[raw[i].Type] + if ok { + // Bingo! + m.Offset += data[0] + m.BitfieldSize = data[1] + continue + } + + if m.Type != nil { + // We couldn't find a legacy bitfield, but we know that the member's + // type has already been inflated. Hence we know that it can't be + // a legacy bitfield and there is nothing left to do. + continue + } + + // We don't have fixup data, and the type we're pointing + // at hasn't been inflated yet. No choice but to defer + // the fixup. + bitfieldFixups = append(bitfieldFixups, bitfieldFixupDef{ + raw[i].Type, + m, + }) + } + return members, nil + } + + var declTags []*declTag + for _, raw := range rawTypes { + var ( + id = firstTypeID + TypeID(len(types)) + typ Type + ) + + if id < firstTypeID { + return nil, fmt.Errorf("no more type IDs") + } + + name, err := rawStrings.Lookup(raw.NameOff) + if err != nil { + return nil, fmt.Errorf("get name for type id %d: %w", id, err) + } + + switch raw.Kind() { + case kindInt: + size := raw.Size() + bi := raw.data.(*btfInt) + if bi.Offset() > 0 || bi.Bits().Bytes() != size { + legacyBitfields[id] = [2]Bits{bi.Offset(), bi.Bits()} + } + typ = &Int{name, raw.Size(), bi.Encoding()} + + case kindPointer: + ptr := &Pointer{nil} + fixup(raw.Type(), &ptr.Target) + typ = ptr + + case kindArray: + btfArr := raw.data.(*btfArray) + arr := &Array{nil, nil, btfArr.Nelems} + fixup(btfArr.IndexType, &arr.Index) + fixup(btfArr.Type, &arr.Type) + typ = arr + + case kindStruct: + members, err := convertMembers(raw.data.([]btfMember), raw.Bitfield()) + if err != nil { + return nil, fmt.Errorf("struct %s (id %d): %w", name, id, err) + } + typ = &Struct{name, raw.Size(), members} + + case kindUnion: + members, err := convertMembers(raw.data.([]btfMember), raw.Bitfield()) + if err != nil { + return nil, fmt.Errorf("union %s (id %d): %w", name, id, err) + } + typ = &Union{name, raw.Size(), members} + + case kindEnum: + rawvals := raw.data.([]btfEnum) + vals := make([]EnumValue, 0, len(rawvals)) + signed := raw.Signed() + for i, btfVal := range rawvals { + name, err := rawStrings.Lookup(btfVal.NameOff) + if err != nil { + return nil, fmt.Errorf("get name for enum value %d: %s", i, err) + } + value := uint64(btfVal.Val) + if signed { + // Sign extend values to 64 bit. + value = uint64(int32(btfVal.Val)) + } + vals = append(vals, EnumValue{name, value}) + } + typ = &Enum{name, raw.Size(), signed, vals} + + case kindForward: + typ = &Fwd{name, raw.FwdKind()} + + case kindTypedef: + typedef := &Typedef{name, nil} + fixup(raw.Type(), &typedef.Type) + typ = typedef + + case kindVolatile: + volatile := &Volatile{nil} + fixup(raw.Type(), &volatile.Type) + typ = volatile + + case kindConst: + cnst := &Const{nil} + fixup(raw.Type(), &cnst.Type) + typ = cnst + + case kindRestrict: + restrict := &Restrict{nil} + fixup(raw.Type(), &restrict.Type) + typ = restrict + + case kindFunc: + fn := &Func{name, nil, raw.Linkage()} + if err := fixupAndAssert(raw.Type(), &fn.Type, reflect.TypeOf((*FuncProto)(nil))); err != nil { + return nil, err + } + typ = fn + + case kindFuncProto: + rawparams := raw.data.([]btfParam) + params := make([]FuncParam, 0, len(rawparams)) + for i, param := range rawparams { + name, err := rawStrings.Lookup(param.NameOff) + if err != nil { + return nil, fmt.Errorf("get name for func proto parameter %d: %s", i, err) + } + params = append(params, FuncParam{ + Name: name, + }) + } + for i := range params { + fixup(rawparams[i].Type, ¶ms[i].Type) + } + + fp := &FuncProto{nil, params} + fixup(raw.Type(), &fp.Return) + typ = fp + + case kindVar: + variable := raw.data.(*btfVariable) + v := &Var{name, nil, VarLinkage(variable.Linkage)} + fixup(raw.Type(), &v.Type) + typ = v + + case kindDatasec: + btfVars := raw.data.([]btfVarSecinfo) + vars := make([]VarSecinfo, 0, len(btfVars)) + for _, btfVar := range btfVars { + vars = append(vars, VarSecinfo{ + Offset: btfVar.Offset, + Size: btfVar.Size, + }) + } + for i := range vars { + fixup(btfVars[i].Type, &vars[i].Type) + } + typ = &Datasec{name, raw.Size(), vars} + + case kindFloat: + typ = &Float{name, raw.Size()} + + case kindDeclTag: + btfIndex := raw.data.(*btfDeclTag).ComponentIdx + if uint64(btfIndex) > math.MaxInt { + return nil, fmt.Errorf("type id %d: index exceeds int", id) + } + + dt := &declTag{nil, name, int(int32(btfIndex))} + fixup(raw.Type(), &dt.Type) + typ = dt + + declTags = append(declTags, dt) + + case kindTypeTag: + tt := &typeTag{nil, name} + fixup(raw.Type(), &tt.Type) + typ = tt + + case kindEnum64: + rawvals := raw.data.([]btfEnum64) + vals := make([]EnumValue, 0, len(rawvals)) + for i, btfVal := range rawvals { + name, err := rawStrings.Lookup(btfVal.NameOff) + if err != nil { + return nil, fmt.Errorf("get name for enum64 value %d: %s", i, err) + } + value := (uint64(btfVal.ValHi32) << 32) | uint64(btfVal.ValLo32) + vals = append(vals, EnumValue{name, value}) + } + typ = &Enum{name, raw.Size(), raw.Signed(), vals} + + default: + return nil, fmt.Errorf("type id %d: unknown kind: %v", id, raw.Kind()) + } + + types = append(types, typ) + } + + for _, fixup := range fixups { + if fixup.id < firstTypeID { + return nil, fmt.Errorf("fixup for base type id %d is not expected", fixup.id) + } + + idx := int(fixup.id - firstTypeID) + if idx >= len(types) { + return nil, fmt.Errorf("reference to invalid type id: %d", fixup.id) + } + + *fixup.typ = types[idx] + } + + for _, bitfieldFixup := range bitfieldFixups { + if bitfieldFixup.id < firstTypeID { + return nil, fmt.Errorf("bitfield fixup from split to base types is not expected") + } + + data, ok := legacyBitfields[bitfieldFixup.id] + if ok { + // This is indeed a legacy bitfield, fix it up. + bitfieldFixup.m.Offset += data[0] + bitfieldFixup.m.BitfieldSize = data[1] + } + } + + for _, assertion := range assertions { + if reflect.TypeOf(*assertion.typ) != assertion.want { + return nil, fmt.Errorf("type ID %d: expected %s, got %T", assertion.id, assertion.want, *assertion.typ) + } + } + + for _, dt := range declTags { + switch t := dt.Type.(type) { + case *Var, *Typedef: + if dt.Index != -1 { + return nil, fmt.Errorf("type %s: index %d is not -1", dt, dt.Index) + } + + case composite: + if dt.Index >= len(t.members()) { + return nil, fmt.Errorf("type %s: index %d exceeds members of %s", dt, dt.Index, t) + } + + case *Func: + if dt.Index >= len(t.Type.(*FuncProto).Params) { + return nil, fmt.Errorf("type %s: index %d exceeds params of %s", dt, dt.Index, t) + } + + default: + return nil, fmt.Errorf("type %s: decl tag for type %s is not supported", dt, t) + } + } + + return types, nil +} + +// essentialName represents the name of a BTF type stripped of any flavor +// suffixes after a ___ delimiter. +type essentialName string + +// newEssentialName returns name without a ___ suffix. +// +// CO-RE has the concept of 'struct flavors', which are used to deal with +// changes in kernel data structures. Anything after three underscores +// in a type name is ignored for the purpose of finding a candidate type +// in the kernel's BTF. +func newEssentialName(name string) essentialName { + if name == "" { + return "" + } + lastIdx := strings.LastIndex(name, "___") + if lastIdx > 0 { + return essentialName(name[:lastIdx]) + } + return essentialName(name) +} + +// UnderlyingType skips qualifiers and Typedefs. +func UnderlyingType(typ Type) Type { + result := typ + for depth := 0; depth <= maxTypeDepth; depth++ { + switch v := (result).(type) { + case qualifier: + result = v.qualify() + case *Typedef: + result = v.Type + default: + return result + } + } + return &cycle{typ} +} + +// as returns typ if is of type T. Otherwise it peels qualifiers and Typedefs +// until it finds a T. +// +// Returns the zero value and false if there is no T or if the type is nested +// too deeply. +func as[T Type](typ Type) (T, bool) { + for depth := 0; depth <= maxTypeDepth; depth++ { + switch v := (typ).(type) { + case T: + return v, true + case qualifier: + typ = v.qualify() + case *Typedef: + typ = v.Type + default: + goto notFound + } + } +notFound: + var zero T + return zero, false +} + +type formatState struct { + fmt.State + depth int +} + +// formattableType is a subset of Type, to ease unit testing of formatType. +type formattableType interface { + fmt.Formatter + TypeName() string +} + +// formatType formats a type in a canonical form. +// +// Handles cyclical types by only printing cycles up to a certain depth. Elements +// in extra are separated by spaces unless the preceding element is a string +// ending in '='. +func formatType(f fmt.State, verb rune, t formattableType, extra ...interface{}) { + if verb != 'v' && verb != 's' { + fmt.Fprintf(f, "{UNRECOGNIZED: %c}", verb) + return + } + + _, _ = io.WriteString(f, internal.GoTypeName(t)) + + if name := t.TypeName(); name != "" { + // Output BTF type name if present. + fmt.Fprintf(f, ":%q", name) + } + + if f.Flag('+') { + // Output address if requested. + fmt.Fprintf(f, ":%#p", t) + } + + if verb == 's' { + // %s omits details. + return + } + + var depth int + if ps, ok := f.(*formatState); ok { + depth = ps.depth + f = ps.State + } + + maxDepth, ok := f.Width() + if !ok { + maxDepth = 0 + } + + if depth > maxDepth { + // We've reached the maximum depth. This avoids infinite recursion even + // for cyclical types. + return + } + + if len(extra) == 0 { + return + } + + wantSpace := false + _, _ = io.WriteString(f, "[") + for _, arg := range extra { + if wantSpace { + _, _ = io.WriteString(f, " ") + } + + switch v := arg.(type) { + case string: + _, _ = io.WriteString(f, v) + wantSpace = len(v) > 0 && v[len(v)-1] != '=' + continue + + case formattableType: + v.Format(&formatState{f, depth + 1}, verb) + + default: + fmt.Fprint(f, arg) + } + + wantSpace = true + } + _, _ = io.WriteString(f, "]") +} diff --git a/vendor/github.com/cilium/ebpf/btf/workarounds.go b/vendor/github.com/cilium/ebpf/btf/workarounds.go new file mode 100644 index 0000000000..12a89b87ee --- /dev/null +++ b/vendor/github.com/cilium/ebpf/btf/workarounds.go @@ -0,0 +1,26 @@ +package btf + +// datasecResolveWorkaround ensures that certain vars in a Datasec are added +// to a Spec before the Datasec. This avoids a bug in kernel BTF validation. +// +// See https://lore.kernel.org/bpf/20230302123440.1193507-1-lmb@isovalent.com/ +func datasecResolveWorkaround(b *Builder, ds *Datasec) error { + for _, vsi := range ds.Vars { + v, ok := vsi.Type.(*Var) + if !ok { + continue + } + + switch v.Type.(type) { + case *Typedef, *Volatile, *Const, *Restrict, *typeTag: + // NB: We must never call Add on a Datasec, otherwise we risk + // infinite recursion. + _, err := b.Add(v.Type) + if err != nil { + return err + } + } + } + + return nil +} diff --git a/vendor/github.com/cilium/ebpf/collection.go b/vendor/github.com/cilium/ebpf/collection.go index 2ededc87a0..fb720bebdb 100644 --- a/vendor/github.com/cilium/ebpf/collection.go +++ b/vendor/github.com/cilium/ebpf/collection.go @@ -4,14 +4,13 @@ import ( "encoding/binary" "errors" "fmt" - "io" - "math" "reflect" "strings" "github.com/cilium/ebpf/asm" + "github.com/cilium/ebpf/btf" "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/btf" + "github.com/cilium/ebpf/internal/kconfig" ) // CollectionOptions control loading a collection into the kernel. @@ -20,6 +19,17 @@ import ( type CollectionOptions struct { Maps MapOptions Programs ProgramOptions + + // MapReplacements takes a set of Maps that will be used instead of + // creating new ones when loading the CollectionSpec. + // + // For each given Map, there must be a corresponding MapSpec in + // CollectionSpec.Maps, and its type, key/value size, max entries and flags + // must match the values of the MapSpec. + // + // The given Maps are Clone()d before being used in the Collection, so the + // caller can Close() them freely when they are no longer needed. + MapReplacements map[string]*Map } // CollectionSpec describes a collection. @@ -27,6 +37,10 @@ type CollectionSpec struct { Maps map[string]*MapSpec Programs map[string]*ProgramSpec + // Types holds type information about Maps and Programs. + // Modifications to Types are currently undefined behaviour. + Types *btf.Spec + // ByteOrder specifies whether the ELF was compiled for // big-endian or little-endian architectures. ByteOrder binary.ByteOrder @@ -42,6 +56,7 @@ func (cs *CollectionSpec) Copy() *CollectionSpec { Maps: make(map[string]*MapSpec, len(cs.Maps)), Programs: make(map[string]*ProgramSpec, len(cs.Programs)), ByteOrder: cs.ByteOrder, + Types: cs.Types, } for name, spec := range cs.Maps { @@ -61,19 +76,21 @@ func (cs *CollectionSpec) Copy() *CollectionSpec { // when calling NewCollection. Any named maps are removed from CollectionSpec.Maps. // // Returns an error if a named map isn't used in at least one program. +// +// Deprecated: Pass CollectionOptions.MapReplacements when loading the Collection +// instead. func (cs *CollectionSpec) RewriteMaps(maps map[string]*Map) error { for symbol, m := range maps { // have we seen a program that uses this symbol / map seen := false - fd := m.FD() for progName, progSpec := range cs.Programs { - err := progSpec.Instructions.RewriteMapPtr(symbol, fd) + err := progSpec.Instructions.AssociateMap(symbol, m) switch { case err == nil: seen = true - case asm.IsUnreferencedSymbol(err): + case errors.Is(err, asm.ErrUnreferencedSymbol): // Not all programs need to use the map default: @@ -92,12 +109,22 @@ func (cs *CollectionSpec) RewriteMaps(maps map[string]*Map) error { return nil } +// MissingConstantsError is returned by [CollectionSpec.RewriteConstants]. +type MissingConstantsError struct { + // The constants missing from .rodata. + Constants []string +} + +func (m *MissingConstantsError) Error() string { + return fmt.Sprintf("some constants are missing from .rodata: %s", strings.Join(m.Constants, ", ")) +} + // RewriteConstants replaces the value of multiple constants. // // The constant must be defined like so in the C program: // -// volatile const type foobar; -// volatile const type foobar = default; +// volatile const type foobar; +// volatile const type foobar = default; // // Replacement values must be of the same length as the C sizeof(type). // If necessary, they are marshalled according to the same rules as @@ -105,36 +132,73 @@ func (cs *CollectionSpec) RewriteMaps(maps map[string]*Map) error { // // From Linux 5.5 the verifier will use constants to eliminate dead code. // -// Returns an error if a constant doesn't exist. +// Returns an error wrapping [MissingConstantsError] if a constant doesn't exist. func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error { - rodata := cs.Maps[".rodata"] - if rodata == nil { - return errors.New("missing .rodata section") - } + replaced := make(map[string]bool) - if rodata.BTF == nil { - return errors.New(".rodata section has no BTF") - } + for name, spec := range cs.Maps { + if !strings.HasPrefix(name, ".rodata") { + continue + } - if n := len(rodata.Contents); n != 1 { - return fmt.Errorf("expected one key in .rodata, found %d", n) - } + b, ds, err := spec.dataSection() + if errors.Is(err, errMapNoBTFValue) { + // Data sections without a BTF Datasec are valid, but don't support + // constant replacements. + continue + } + if err != nil { + return fmt.Errorf("map %s: %w", name, err) + } - kv := rodata.Contents[0] - value, ok := kv.Value.([]byte) - if !ok { - return fmt.Errorf("first value in .rodata is %T not []byte", kv.Value) + // MapSpec.Copy() performs a shallow copy. Fully copy the byte slice + // to avoid any changes affecting other copies of the MapSpec. + cpy := make([]byte, len(b)) + copy(cpy, b) + + for _, v := range ds.Vars { + vname := v.Type.TypeName() + replacement, ok := consts[vname] + if !ok { + continue + } + + if _, ok := v.Type.(*btf.Var); !ok { + return fmt.Errorf("section %s: unexpected type %T for variable %s", name, v.Type, vname) + } + + if replaced[vname] { + return fmt.Errorf("section %s: duplicate variable %s", name, vname) + } + + if int(v.Offset+v.Size) > len(cpy) { + return fmt.Errorf("section %s: offset %d(+%d) for variable %s is out of bounds", name, v.Offset, v.Size, vname) + } + + b, err := marshalBytes(replacement, int(v.Size)) + if err != nil { + return fmt.Errorf("marshaling constant replacement %s: %w", vname, err) + } + + copy(cpy[v.Offset:v.Offset+v.Size], b) + + replaced[vname] = true + } + + spec.Contents[0] = MapKV{Key: uint32(0), Value: cpy} } - buf := make([]byte, len(value)) - copy(buf, value) + var missing []string + for c := range consts { + if !replaced[c] { + missing = append(missing, c) + } + } - err := patchValue(buf, rodata.BTF.Value, consts) - if err != nil { - return err + if len(missing) != 0 { + return fmt.Errorf("rewrite constants: %w", &MissingConstantsError{Constants: missing}) } - rodata.Contents[0] = MapKV{kv.Key, buf} return nil } @@ -150,11 +214,11 @@ func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error // The tag's value specifies the name of the program or map as // found in the CollectionSpec. // -// struct { -// Foo *ebpf.ProgramSpec `ebpf:"xdp_foo"` -// Bar *ebpf.MapSpec `ebpf:"bar_map"` -// Ignored int -// } +// struct { +// Foo *ebpf.ProgramSpec `ebpf:"xdp_foo"` +// Bar *ebpf.MapSpec `ebpf:"bar_map"` +// Ignored int +// } // // Returns an error if any of the eBPF objects can't be found, or // if the same MapSpec or ProgramSpec is assigned multiple times. @@ -187,6 +251,9 @@ func (cs *CollectionSpec) Assign(to interface{}) error { // LoadAndAssign loads Maps and Programs into the kernel and assigns them // to a struct. // +// Omitting Map/Program.Close() during application shutdown is an error. +// See the package documentation for details around Map and Program lifecycle. +// // This function is a shortcut to manually checking the presence // of maps and programs in a CollectionSpec. Consider using bpf2go // if this sounds useful. @@ -198,26 +265,32 @@ func (cs *CollectionSpec) Assign(to interface{}) error { // dependent resources are loaded into the kernel and populated with values if // specified. // -// struct { -// Foo *ebpf.Program `ebpf:"xdp_foo"` -// Bar *ebpf.Map `ebpf:"bar_map"` -// Ignored int -// } +// struct { +// Foo *ebpf.Program `ebpf:"xdp_foo"` +// Bar *ebpf.Map `ebpf:"bar_map"` +// Ignored int +// } // // opts may be nil. // // Returns an error if any of the fields can't be found, or // if the same Map or Program is assigned multiple times. func (cs *CollectionSpec) LoadAndAssign(to interface{}, opts *CollectionOptions) error { - loader := newCollectionLoader(cs, opts) - defer loader.cleanup() + loader, err := newCollectionLoader(cs, opts) + if err != nil { + return err + } + defer loader.close() // Support assigning Programs and Maps, lazy-loading the required objects. assignedMaps := make(map[string]bool) + assignedProgs := make(map[string]bool) + getValue := func(typ reflect.Type, name string) (interface{}, error) { switch typ { case reflect.TypeOf((*Program)(nil)): + assignedProgs[name] = true return loader.loadProgram(name) case reflect.TypeOf((*Map)(nil)): @@ -244,15 +317,26 @@ func (cs *CollectionSpec) LoadAndAssign(to interface{}, opts *CollectionOptions) switch m.typ { case ProgramArray: // Require all lazy-loaded ProgramArrays to be assigned to the given object. - // Without any references, they will be closed on the first GC and all tail - // calls into them will miss. - if !assignedMaps[n] { + // The kernel empties a ProgramArray once the last user space reference + // to it closes, which leads to failed tail calls. Combined with the library + // closing map fds via GC finalizers this can lead to surprising behaviour. + // Only allow unassigned ProgramArrays when the library hasn't pre-populated + // any entries from static value declarations. At this point, we know the map + // is empty and there's no way for the caller to interact with the map going + // forward. + if !assignedMaps[n] && len(cs.Maps[n].Contents) > 0 { return fmt.Errorf("ProgramArray %s must be assigned to prevent missed tail calls", n) } } } - loader.finalize() + // Prevent loader.cleanup() from closing assigned Maps and Programs. + for m := range assignedMaps { + delete(loader.maps, m) + } + for p := range assignedProgs { + delete(loader.programs, p) + } return nil } @@ -264,15 +348,26 @@ type Collection struct { Maps map[string]*Map } -// NewCollection creates a Collection from a specification. +// NewCollection creates a Collection from the given spec, creating and +// loading its declared resources into the kernel. +// +// Omitting Collection.Close() during application shutdown is an error. +// See the package documentation for details around Map and Program lifecycle. func NewCollection(spec *CollectionSpec) (*Collection, error) { return NewCollectionWithOptions(spec, CollectionOptions{}) } -// NewCollectionWithOptions creates a Collection from a specification. +// NewCollectionWithOptions creates a Collection from the given spec using +// options, creating and loading its declared resources into the kernel. +// +// Omitting Collection.Close() during application shutdown is an error. +// See the package documentation for details around Map and Program lifecycle. func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (*Collection, error) { - loader := newCollectionLoader(spec, &opts) - defer loader.cleanup() + loader, err := newCollectionLoader(spec, &opts) + if err != nil { + return nil, err + } + defer loader.close() // Create maps first, as their fds need to be linked into programs. for mapName := range spec.Maps { @@ -281,7 +376,11 @@ func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (*Co } } - for progName := range spec.Programs { + for progName, prog := range spec.Programs { + if prog.Type == UnspecifiedProgram { + continue + } + if _, err := loader.loadProgram(progName); err != nil { return nil, err } @@ -293,9 +392,9 @@ func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (*Co return nil, err } + // Prevent loader.cleanup from closing maps and programs. maps, progs := loader.maps, loader.programs - - loader.finalize() + loader.maps, loader.programs = nil, nil return &Collection{ progs, @@ -303,85 +402,40 @@ func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (*Co }, nil } -type handleCache struct { - btfHandles map[*btf.Spec]*btf.Handle - btfSpecs map[io.ReaderAt]*btf.Spec -} - -func newHandleCache() *handleCache { - return &handleCache{ - btfHandles: make(map[*btf.Spec]*btf.Handle), - btfSpecs: make(map[io.ReaderAt]*btf.Spec), - } -} - -func (hc handleCache) btfHandle(spec *btf.Spec) (*btf.Handle, error) { - if hc.btfHandles[spec] != nil { - return hc.btfHandles[spec], nil - } - - handle, err := btf.NewHandle(spec) - if err != nil { - return nil, err - } - - hc.btfHandles[spec] = handle - return handle, nil -} - -func (hc handleCache) btfSpec(rd io.ReaderAt) (*btf.Spec, error) { - if hc.btfSpecs[rd] != nil { - return hc.btfSpecs[rd], nil - } - - spec, err := btf.LoadSpecFromReader(rd) - if err != nil { - return nil, err - } - - hc.btfSpecs[rd] = spec - return spec, nil -} - -func (hc handleCache) close() { - for _, handle := range hc.btfHandles { - handle.Close() - } -} - type collectionLoader struct { coll *CollectionSpec opts *CollectionOptions maps map[string]*Map programs map[string]*Program - handles *handleCache } -func newCollectionLoader(coll *CollectionSpec, opts *CollectionOptions) *collectionLoader { +func newCollectionLoader(coll *CollectionSpec, opts *CollectionOptions) (*collectionLoader, error) { if opts == nil { opts = &CollectionOptions{} } + // Check for existing MapSpecs in the CollectionSpec for all provided replacement maps. + for name, m := range opts.MapReplacements { + spec, ok := coll.Maps[name] + if !ok { + return nil, fmt.Errorf("replacement map %s not found in CollectionSpec", name) + } + + if err := spec.Compatible(m); err != nil { + return nil, fmt.Errorf("using replacement map %s: %w", spec.Name, err) + } + } + return &collectionLoader{ coll, opts, make(map[string]*Map), make(map[string]*Program), - newHandleCache(), - } -} - -// finalize should be called when all the collectionLoader's resources -// have been successfully loaded into the kernel and populated with values. -func (cl *collectionLoader) finalize() { - cl.maps, cl.programs = nil, nil + }, nil } -// cleanup cleans up all resources left over in the collectionLoader. -// Call finalize() when Map and Program creation/population is successful -// to prevent them from getting closed. -func (cl *collectionLoader) cleanup() { - cl.handles.close() +// close all resources left over in the collectionLoader. +func (cl *collectionLoader) close() { for _, m := range cl.maps { m.Close() } @@ -400,7 +454,18 @@ func (cl *collectionLoader) loadMap(mapName string) (*Map, error) { return nil, fmt.Errorf("missing map %s", mapName) } - m, err := newMapWithOptions(mapSpec, cl.opts.Maps, cl.handles) + if replaceMap, ok := cl.opts.MapReplacements[mapName]; ok { + // Clone the map to avoid closing user's map later on. + m, err := replaceMap.Clone() + if err != nil { + return nil, err + } + + cl.maps[mapName] = m + return m, nil + } + + m, err := newMapWithOptions(mapSpec, cl.opts.Maps) if err != nil { return nil, fmt.Errorf("map %s: %w", mapName, err) } @@ -419,37 +484,41 @@ func (cl *collectionLoader) loadProgram(progName string) (*Program, error) { return nil, fmt.Errorf("unknown program %s", progName) } + // Bail out early if we know the kernel is going to reject the program. + // This skips loading map dependencies, saving some cleanup work later. + if progSpec.Type == UnspecifiedProgram { + return nil, fmt.Errorf("cannot load program %s: program type is unspecified", progName) + } + progSpec = progSpec.Copy() - // Rewrite any reference to a valid map. + // Rewrite any reference to a valid map in the program's instructions, + // which includes all of its dependencies. for i := range progSpec.Instructions { ins := &progSpec.Instructions[i] - if !ins.IsLoadFromMap() || ins.Reference == "" { + if !ins.IsLoadFromMap() || ins.Reference() == "" { continue } - if uint32(ins.Constant) != math.MaxUint32 { - // Don't overwrite maps already rewritten, users can - // rewrite programs in the spec themselves + // Don't overwrite map loads containing non-zero map fd's, + // they can be manually included by the caller. + // Map FDs/IDs are placed in the lower 32 bits of Constant. + if int32(ins.Constant) > 0 { continue } - m, err := cl.loadMap(ins.Reference) + m, err := cl.loadMap(ins.Reference()) if err != nil { return nil, fmt.Errorf("program %s: %w", progName, err) } - fd := m.FD() - if fd < 0 { - return nil, fmt.Errorf("map %s: %w", ins.Reference, internal.ErrClosedFd) - } - if err := ins.RewriteMapPtr(m.FD()); err != nil { - return nil, fmt.Errorf("program %s: map %s: %w", progName, ins.Reference, err) + if err := ins.AssociateMap(m); err != nil { + return nil, fmt.Errorf("program %s: map %s: %w", progName, ins.Reference(), err) } } - prog, err := newProgramWithOptions(progSpec, cl.opts.Programs, cl.handles) + prog, err := newProgramWithOptions(progSpec, cl.opts.Programs) if err != nil { return nil, fmt.Errorf("program %s: %w", progName, err) } @@ -465,26 +534,37 @@ func (cl *collectionLoader) populateMaps() error { return fmt.Errorf("missing map spec %s", mapName) } - mapSpec = mapSpec.Copy() - - // Replace any object stubs with loaded objects. - for i, kv := range mapSpec.Contents { - switch v := kv.Value.(type) { - case programStub: - // loadProgram is idempotent and could return an existing Program. - prog, err := cl.loadProgram(string(v)) - if err != nil { - return fmt.Errorf("loading program %s, for map %s: %w", v, mapName, err) + // MapSpecs that refer to inner maps or programs within the same + // CollectionSpec do so using strings. These strings are used as the key + // to look up the respective object in the Maps or Programs fields. + // Resolve those references to actual Map or Program resources that + // have been loaded into the kernel. + if mapSpec.Type.canStoreMap() || mapSpec.Type.canStoreProgram() { + mapSpec = mapSpec.Copy() + + for i, kv := range mapSpec.Contents { + objName, ok := kv.Value.(string) + if !ok { + continue } - mapSpec.Contents[i] = MapKV{kv.Key, prog} - case mapStub: - // loadMap is idempotent and could return an existing Map. - innerMap, err := cl.loadMap(string(v)) - if err != nil { - return fmt.Errorf("loading inner map %s, for map %s: %w", v, mapName, err) + switch t := mapSpec.Type; { + case t.canStoreProgram(): + // loadProgram is idempotent and could return an existing Program. + prog, err := cl.loadProgram(objName) + if err != nil { + return fmt.Errorf("loading program %s, for map %s: %w", objName, mapName, err) + } + mapSpec.Contents[i] = MapKV{kv.Key, prog} + + case t.canStoreMap(): + // loadMap is idempotent and could return an existing Map. + innerMap, err := cl.loadMap(objName) + if err != nil { + return fmt.Errorf("loading inner map %s, for map %s: %w", objName, mapName, err) + } + mapSpec.Contents[i] = MapKV{kv.Key, innerMap} } - mapSpec.Contents[i] = MapKV{kv.Key, innerMap} } } @@ -497,7 +577,100 @@ func (cl *collectionLoader) populateMaps() error { return nil } -// LoadCollection parses an object file and converts it to a collection. +// resolveKconfig resolves all variables declared in .kconfig and populates +// m.Contents. Does nothing if the given m.Contents is non-empty. +func resolveKconfig(m *MapSpec) error { + ds, ok := m.Value.(*btf.Datasec) + if !ok { + return errors.New("map value is not a Datasec") + } + + type configInfo struct { + offset uint32 + typ btf.Type + } + + configs := make(map[string]configInfo) + + data := make([]byte, ds.Size) + for _, vsi := range ds.Vars { + v := vsi.Type.(*btf.Var) + n := v.TypeName() + + switch n { + case "LINUX_KERNEL_VERSION": + if integer, ok := v.Type.(*btf.Int); !ok || integer.Size != 4 { + return fmt.Errorf("variable %s must be a 32 bits integer, got %s", n, v.Type) + } + + kv, err := internal.KernelVersion() + if err != nil { + return fmt.Errorf("getting kernel version: %w", err) + } + internal.NativeEndian.PutUint32(data[vsi.Offset:], kv.Kernel()) + + case "LINUX_HAS_SYSCALL_WRAPPER": + if integer, ok := v.Type.(*btf.Int); !ok || integer.Size != 4 { + return fmt.Errorf("variable %s must be a 32 bits integer, got %s", n, v.Type) + } + var value uint32 = 1 + if err := haveSyscallWrapper(); errors.Is(err, ErrNotSupported) { + value = 0 + } else if err != nil { + return fmt.Errorf("unable to derive a value for LINUX_HAS_SYSCALL_WRAPPER: %w", err) + } + + internal.NativeEndian.PutUint32(data[vsi.Offset:], value) + + default: // Catch CONFIG_*. + configs[n] = configInfo{ + offset: vsi.Offset, + typ: v.Type, + } + } + } + + // We only parse kconfig file if a CONFIG_* variable was found. + if len(configs) > 0 { + f, err := kconfig.Find() + if err != nil { + return fmt.Errorf("cannot find a kconfig file: %w", err) + } + defer f.Close() + + filter := make(map[string]struct{}, len(configs)) + for config := range configs { + filter[config] = struct{}{} + } + + kernelConfig, err := kconfig.Parse(f, filter) + if err != nil { + return fmt.Errorf("cannot parse kconfig file: %w", err) + } + + for n, info := range configs { + value, ok := kernelConfig[n] + if !ok { + return fmt.Errorf("config option %q does not exists for this kernel", n) + } + + err := kconfig.PutValue(data[info.offset:], info.typ, value) + if err != nil { + return fmt.Errorf("problem adding value for %s: %w", n, err) + } + } + } + + m.Contents = []MapKV{{uint32(0), data}} + + return nil +} + +// LoadCollection reads an object file and creates and loads its declared +// resources into the kernel. +// +// Omitting Collection.Close() during application shutdown is an error. +// See the package documentation for details around Map and Program lifecycle. func LoadCollection(file string) (*Collection, error) { spec, err := LoadCollectionSpec(file) if err != nil { diff --git a/vendor/github.com/cilium/ebpf/doc.go b/vendor/github.com/cilium/ebpf/doc.go index f7f34da8f4..396b3394d3 100644 --- a/vendor/github.com/cilium/ebpf/doc.go +++ b/vendor/github.com/cilium/ebpf/doc.go @@ -13,4 +13,13 @@ // your application as any other resource. // // Use the link subpackage to attach a loaded program to a hook in the kernel. +// +// Note that losing all references to Map and Program resources will cause +// their underlying file descriptors to be closed, potentially removing those +// objects from the kernel. Always retain a reference by e.g. deferring a +// Close() of a Collection or LoadAndAssign object until application exit. +// +// Special care needs to be taken when handling maps of type ProgramArray, +// as the kernel erases its contents when the last userspace or bpffs +// reference disappears, regardless of the map being in active use. package ebpf diff --git a/vendor/github.com/cilium/ebpf/elf_reader.go b/vendor/github.com/cilium/ebpf/elf_reader.go index 42010f43e5..8d92672eb1 100644 --- a/vendor/github.com/cilium/ebpf/elf_reader.go +++ b/vendor/github.com/cilium/ebpf/elf_reader.go @@ -13,11 +13,20 @@ import ( "strings" "github.com/cilium/ebpf/asm" + "github.com/cilium/ebpf/btf" "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/btf" "github.com/cilium/ebpf/internal/unix" ) +type kconfigMetaKey struct{} + +type kconfigMeta struct { + Map *MapSpec + Offset uint32 +} + +type kfuncMeta struct{} + // elfCode is a convenience to reduce the amount of arguments that have to // be passed around explicitly. You should treat its contents as immutable. type elfCode struct { @@ -26,6 +35,10 @@ type elfCode struct { license string version uint32 btf *btf.Spec + extInfo *btf.ExtInfos + maps map[string]*MapSpec + kfuncs map[string]*btf.Func + kconfig *MapSpec } // LoadCollectionSpec parses an ELF file into a CollectionSpec. @@ -49,7 +62,12 @@ func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) { if err != nil { return nil, err } - defer f.Close() + + // Checks if the ELF file is for BPF data. + // Old LLVM versions set e_machine to EM_NONE. + if f.File.Machine != unix.EM_NONE && f.File.Machine != elf.EM_BPF { + return nil, fmt.Errorf("unexpected machine type for BPF ELF: %s", f.File.Machine) + } var ( licenseSection *elf.Section @@ -95,100 +113,60 @@ func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) { return nil, fmt.Errorf("load version: %w", err) } - btfSpec, err := btf.LoadSpecFromReader(rd) + btfSpec, btfExtInfo, err := btf.LoadSpecAndExtInfosFromReader(rd) if err != nil && !errors.Is(err, btf.ErrNotFound) { return nil, fmt.Errorf("load BTF: %w", err) } - // Assign symbols to all the sections we're interested in. - symbols, err := f.Symbols() - if err != nil { - return nil, fmt.Errorf("load symbols: %v", err) - } - - for _, symbol := range symbols { - idx := symbol.Section - symType := elf.ST_TYPE(symbol.Info) - - section := sections[idx] - if section == nil { - continue - } - - // Older versions of LLVM don't tag symbols correctly, so keep - // all NOTYPE ones. - keep := symType == elf.STT_NOTYPE - switch section.kind { - case mapSection, btfMapSection, dataSection: - keep = keep || symType == elf.STT_OBJECT - case programSection: - keep = keep || symType == elf.STT_FUNC - } - if !keep || symbol.Name == "" { - continue - } - - section.symbols[symbol.Value] = symbol - } - ec := &elfCode{ SafeELFFile: f, sections: sections, license: license, version: version, btf: btfSpec, + extInfo: btfExtInfo, + maps: make(map[string]*MapSpec), + kfuncs: make(map[string]*btf.Func), } - // Go through relocation sections, and parse the ones for sections we're - // interested in. Make sure that relocations point at valid sections. - for idx, relSection := range relSections { - section := sections[idx] - if section == nil { - continue - } - - rels, err := ec.loadRelocations(relSection, symbols) - if err != nil { - return nil, fmt.Errorf("relocation for section %q: %w", section.Name, err) - } - - for _, rel := range rels { - target := sections[rel.Section] - if target == nil { - return nil, fmt.Errorf("section %q: reference to %q in section %s: %w", section.Name, rel.Name, rel.Section, ErrNotSupported) - } - - if target.Flags&elf.SHF_STRINGS > 0 { - return nil, fmt.Errorf("section %q: string is not stack allocated: %w", section.Name, ErrNotSupported) - } + symbols, err := f.Symbols() + if err != nil { + return nil, fmt.Errorf("load symbols: %v", err) + } - target.references++ - } + ec.assignSymbols(symbols) - section.relocations = rels + if err := ec.loadRelocations(relSections, symbols); err != nil { + return nil, fmt.Errorf("load relocations: %w", err) } - // Collect all the various ways to define maps. - maps := make(map[string]*MapSpec) - if err := ec.loadMaps(maps); err != nil { + if err := ec.loadMaps(); err != nil { return nil, fmt.Errorf("load maps: %w", err) } - if err := ec.loadBTFMaps(maps); err != nil { + if err := ec.loadBTFMaps(); err != nil { return nil, fmt.Errorf("load BTF maps: %w", err) } - if err := ec.loadDataSections(maps); err != nil { + if err := ec.loadDataSections(); err != nil { return nil, fmt.Errorf("load data sections: %w", err) } + if err := ec.loadKconfigSection(); err != nil { + return nil, fmt.Errorf("load virtual .kconfig section: %w", err) + } + + if err := ec.loadKsymsSection(); err != nil { + return nil, fmt.Errorf("load virtual .ksyms section: %w", err) + } + // Finally, collect programs and link them. - progs, err := ec.loadPrograms() + progs, err := ec.loadProgramSections() if err != nil { return nil, fmt.Errorf("load programs: %w", err) } - return &CollectionSpec{maps, progs, ec.ByteOrder}, nil + return &CollectionSpec{ec.maps, progs, btfSpec, ec.ByteOrder}, nil } func loadLicense(sec *elf.Section) (string, error) { @@ -247,12 +225,87 @@ func newElfSection(section *elf.Section, kind elfSectionKind) *elfSection { } } -func (ec *elfCode) loadPrograms() (map[string]*ProgramSpec, error) { - var ( - progs []*ProgramSpec - libs []*ProgramSpec - ) +// assignSymbols takes a list of symbols and assigns them to their +// respective sections, indexed by name. +func (ec *elfCode) assignSymbols(symbols []elf.Symbol) { + for _, symbol := range symbols { + symType := elf.ST_TYPE(symbol.Info) + symSection := ec.sections[symbol.Section] + if symSection == nil { + continue + } + + // Anonymous symbols only occur in debug sections which we don't process + // relocations for. Anonymous symbols are not referenced from other sections. + if symbol.Name == "" { + continue + } + + // Older versions of LLVM don't tag symbols correctly, so keep + // all NOTYPE ones. + switch symSection.kind { + case mapSection, btfMapSection, dataSection: + if symType != elf.STT_NOTYPE && symType != elf.STT_OBJECT { + continue + } + case programSection: + if symType != elf.STT_NOTYPE && symType != elf.STT_FUNC { + continue + } + // LLVM emits LBB_ (Local Basic Block) symbols that seem to be jump + // targets within sections, but BPF has no use for them. + if symType == elf.STT_NOTYPE && elf.ST_BIND(symbol.Info) == elf.STB_LOCAL && + strings.HasPrefix(symbol.Name, "LBB") { + continue + } + // Only collect symbols that occur in program/maps/data sections. + default: + continue + } + + symSection.symbols[symbol.Value] = symbol + } +} + +// loadRelocations iterates .rel* sections and extracts relocation entries for +// sections of interest. Makes sure relocations point at valid sections. +func (ec *elfCode) loadRelocations(relSections map[elf.SectionIndex]*elf.Section, symbols []elf.Symbol) error { + for idx, relSection := range relSections { + section := ec.sections[idx] + if section == nil { + continue + } + + rels, err := ec.loadSectionRelocations(relSection, symbols) + if err != nil { + return fmt.Errorf("relocation for section %q: %w", section.Name, err) + } + for _, rel := range rels { + target := ec.sections[rel.Section] + if target == nil { + return fmt.Errorf("section %q: reference to %q in section %s: %w", section.Name, rel.Name, rel.Section, ErrNotSupported) + } + + target.references++ + } + + section.relocations = rels + } + + return nil +} + +// loadProgramSections iterates ec's sections and emits a ProgramSpec +// for each function it finds. +// +// The resulting map is indexed by function name. +func (ec *elfCode) loadProgramSections() (map[string]*ProgramSpec, error) { + + progs := make(map[string]*ProgramSpec) + + // Generate a ProgramSpec for each function found in each program section. + var export []string for _, sec := range ec.sections { if sec.kind != programSection { continue @@ -262,86 +315,143 @@ func (ec *elfCode) loadPrograms() (map[string]*ProgramSpec, error) { return nil, fmt.Errorf("section %v: missing symbols", sec.Name) } - funcSym, ok := sec.symbols[0] - if !ok { - return nil, fmt.Errorf("section %v: no label at start", sec.Name) - } - - insns, length, err := ec.loadInstructions(sec) + funcs, err := ec.loadFunctions(sec) if err != nil { - return nil, fmt.Errorf("program %s: %w", funcSym.Name, err) + return nil, fmt.Errorf("section %v: %w", sec.Name, err) } progType, attachType, progFlags, attachTo := getProgType(sec.Name) - spec := &ProgramSpec{ - Name: funcSym.Name, - Type: progType, - Flags: progFlags, - AttachType: attachType, - AttachTo: attachTo, - License: ec.license, - KernelVersion: ec.version, - Instructions: insns, - ByteOrder: ec.ByteOrder, - } + for name, insns := range funcs { + spec := &ProgramSpec{ + Name: name, + Type: progType, + Flags: progFlags, + AttachType: attachType, + AttachTo: attachTo, + SectionName: sec.Name, + License: ec.license, + KernelVersion: ec.version, + Instructions: insns, + ByteOrder: ec.ByteOrder, + } - if ec.btf != nil { - spec.BTF, err = ec.btf.Program(sec.Name, length) - if err != nil && !errors.Is(err, btf.ErrNoExtendedInfo) { - return nil, fmt.Errorf("program %s: %w", funcSym.Name, err) + // Function names must be unique within a single ELF blob. + if progs[name] != nil { + return nil, fmt.Errorf("duplicate program name %s", name) } - } + progs[name] = spec - if spec.Type == UnspecifiedProgram { - // There is no single name we can use for "library" sections, - // since they may contain multiple functions. We'll decode the - // labels they contain later on, and then link sections that way. - libs = append(libs, spec) - } else { - progs = append(progs, spec) + if spec.SectionName != ".text" { + export = append(export, name) + } } } - res := make(map[string]*ProgramSpec, len(progs)) - for _, prog := range progs { - err := link(prog, libs) - if err != nil { - return nil, fmt.Errorf("program %s: %w", prog.Name, err) + flattenPrograms(progs, export) + + // Hide programs (e.g. library functions) that were not explicitly emitted + // to an ELF section. These could be exposed in a separate CollectionSpec + // field later to allow them to be modified. + for n, p := range progs { + if p.SectionName == ".text" { + delete(progs, n) } - res[prog.Name] = prog } - return res, nil + return progs, nil } -func (ec *elfCode) loadInstructions(section *elfSection) (asm.Instructions, uint64, error) { - var ( - r = bufio.NewReader(section.Open()) - insns asm.Instructions - offset uint64 - ) - for { - var ins asm.Instruction - n, err := ins.Unmarshal(r, ec.ByteOrder) - if err == io.EOF { - return insns, offset, nil - } - if err != nil { - return nil, 0, fmt.Errorf("offset %d: %w", offset, err) - } +// loadFunctions extracts instruction streams from the given program section +// starting at each symbol in the section. The section's symbols must already +// be narrowed down to STT_NOTYPE (emitted by clang <8) or STT_FUNC. +// +// The resulting map is indexed by function name. +func (ec *elfCode) loadFunctions(section *elfSection) (map[string]asm.Instructions, error) { + r := bufio.NewReader(section.Open()) + + // Decode the section's instruction stream. + var insns asm.Instructions + if err := insns.Unmarshal(r, ec.ByteOrder); err != nil { + return nil, fmt.Errorf("decoding instructions for section %s: %w", section.Name, err) + } + if len(insns) == 0 { + return nil, fmt.Errorf("no instructions found in section %s", section.Name) + } + + iter := insns.Iterate() + for iter.Next() { + ins := iter.Ins + offset := iter.Offset.Bytes() - ins.Symbol = section.symbols[offset].Name + // Tag Symbol Instructions. + if sym, ok := section.symbols[offset]; ok { + *ins = ins.WithSymbol(sym.Name) + } + // Apply any relocations for the current instruction. + // If no relocation is present, resolve any section-relative function calls. if rel, ok := section.relocations[offset]; ok { - if err = ec.relocateInstruction(&ins, rel); err != nil { - return nil, 0, fmt.Errorf("offset %d: relocate instruction: %w", offset, err) + if err := ec.relocateInstruction(ins, rel); err != nil { + return nil, fmt.Errorf("offset %d: relocating instruction: %w", offset, err) + } + } else { + if err := referenceRelativeJump(ins, offset, section.symbols); err != nil { + return nil, fmt.Errorf("offset %d: resolving relative jump: %w", offset, err) } } + } + + if ec.extInfo != nil { + ec.extInfo.Assign(insns, section.Name) + } + + return splitSymbols(insns) +} - insns = append(insns, ins) - offset += n +// referenceRelativeJump turns a relative jump to another bpf subprogram within +// the same ELF section into a Reference Instruction. +// +// Up to LLVM 9, calls to subprograms within the same ELF section are sometimes +// encoded using relative jumps instead of relocation entries. These jumps go +// out of bounds of the current program, so their targets must be memoized +// before the section's instruction stream is split. +// +// The relative jump Constant is blinded to -1 and the target Symbol is set as +// the Instruction's Reference so it can be resolved by the linker. +func referenceRelativeJump(ins *asm.Instruction, offset uint64, symbols map[uint64]elf.Symbol) error { + if !ins.IsFunctionReference() || ins.Constant == -1 { + return nil } + + tgt := jumpTarget(offset, *ins) + sym := symbols[tgt].Name + if sym == "" { + return fmt.Errorf("no jump target found at offset %d", tgt) + } + + *ins = ins.WithReference(sym) + ins.Constant = -1 + + return nil +} + +// jumpTarget takes ins' offset within an instruction stream (in bytes) +// and returns its absolute jump destination (in bytes) within the +// instruction stream. +func jumpTarget(offset uint64, ins asm.Instruction) uint64 { + // A relative jump instruction describes the amount of raw BPF instructions + // to jump, convert the offset into bytes. + dest := ins.Constant * asm.InstructionSize + + // The starting point of the jump is the end of the current instruction. + dest += int64(offset + asm.InstructionSize) + + if dest < 0 { + return 0 + } + + return uint64(dest) } func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) error { @@ -367,18 +477,12 @@ func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) err ins.Src = asm.PseudoMapFD - // Mark the instruction as needing an update when creating the - // collection. - if err := ins.RewriteMapPtr(-1); err != nil { - return err - } - case dataSection: var offset uint32 switch typ { case elf.STT_SECTION: if bind != elf.STB_LOCAL { - return fmt.Errorf("direct load: %s: unsupported relocation %s", name, bind) + return fmt.Errorf("direct load: %s: unsupported section relocation %s", name, bind) } // This is really a reference to a static symbol, which clang doesn't @@ -387,8 +491,17 @@ func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) err offset = uint32(uint64(ins.Constant)) case elf.STT_OBJECT: - if bind != elf.STB_GLOBAL { - return fmt.Errorf("direct load: %s: unsupported relocation %s", name, bind) + // LLVM 9 emits OBJECT-LOCAL symbols for anonymous constants. + if bind != elf.STB_GLOBAL && bind != elf.STB_LOCAL { + return fmt.Errorf("direct load: %s: unsupported object relocation %s", name, bind) + } + + offset = uint32(rel.Value) + + case elf.STT_NOTYPE: + // LLVM 7 emits NOTYPE-LOCAL symbols for anonymous constants. + if bind != elf.STB_LOCAL { + return fmt.Errorf("direct load: %s: unsupported untyped relocation %s", name, bind) } offset = uint32(rel.Value) @@ -406,53 +519,77 @@ func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) err ins.Constant = int64(uint64(offset) << 32) ins.Src = asm.PseudoMapValue - // Mark the instruction as needing an update when creating the - // collection. - if err := ins.RewriteMapPtr(-1); err != nil { - return err - } - case programSection: - if ins.OpCode.JumpOp() != asm.Call { - return fmt.Errorf("not a call instruction: %s", ins) - } + switch opCode := ins.OpCode; { + case opCode.JumpOp() == asm.Call: + if ins.Src != asm.PseudoCall { + return fmt.Errorf("call: %s: incorrect source register", name) + } - if ins.Src != asm.PseudoCall { - return fmt.Errorf("call: %s: incorrect source register", name) - } + switch typ { + case elf.STT_NOTYPE, elf.STT_FUNC: + if bind != elf.STB_GLOBAL { + return fmt.Errorf("call: %s: unsupported binding: %s", name, bind) + } - switch typ { - case elf.STT_NOTYPE, elf.STT_FUNC: - if bind != elf.STB_GLOBAL { - return fmt.Errorf("call: %s: unsupported binding: %s", name, bind) - } + case elf.STT_SECTION: + if bind != elf.STB_LOCAL { + return fmt.Errorf("call: %s: unsupported binding: %s", name, bind) + } - case elf.STT_SECTION: - if bind != elf.STB_LOCAL { - return fmt.Errorf("call: %s: unsupported binding: %s", name, bind) + // The function we want to call is in the indicated section, + // at the offset encoded in the instruction itself. Reverse + // the calculation to find the real function we're looking for. + // A value of -1 references the first instruction in the section. + offset := int64(int32(ins.Constant)+1) * asm.InstructionSize + sym, ok := target.symbols[uint64(offset)] + if !ok { + return fmt.Errorf("call: no symbol at offset %d", offset) + } + + name = sym.Name + ins.Constant = -1 + + default: + return fmt.Errorf("call: %s: invalid symbol type %s", name, typ) } + case opCode.IsDWordLoad(): + switch typ { + case elf.STT_FUNC: + if bind != elf.STB_GLOBAL { + return fmt.Errorf("load: %s: unsupported binding: %s", name, bind) + } + + case elf.STT_SECTION: + if bind != elf.STB_LOCAL { + return fmt.Errorf("load: %s: unsupported binding: %s", name, bind) + } + + // ins.Constant already contains the offset in bytes from the + // start of the section. This is different than a call to a + // static function. - // The function we want to call is in the indicated section, - // at the offset encoded in the instruction itself. Reverse - // the calculation to find the real function we're looking for. - // A value of -1 references the first instruction in the section. - offset := int64(int32(ins.Constant)+1) * asm.InstructionSize - if offset < 0 { - return fmt.Errorf("call: %s: invalid offset %d", name, offset) + default: + return fmt.Errorf("load: %s: invalid symbol type %s", name, typ) } - sym, ok := target.symbols[uint64(offset)] + sym, ok := target.symbols[uint64(ins.Constant)] if !ok { - return fmt.Errorf("call: %s: no symbol at offset %d", name, offset) + return fmt.Errorf("load: no symbol at offset %d", ins.Constant) } - ins.Constant = -1 name = sym.Name + ins.Constant = -1 + ins.Src = asm.PseudoFunc default: - return fmt.Errorf("call: %s: invalid symbol type %s", name, typ) + return fmt.Errorf("neither a call nor a load instruction: %v", ins) } + // The Undefined section is used for 'virtual' symbols that aren't backed by + // an ELF section. This includes symbol references from inline asm, forward + // function declarations, as well as extern kfunc declarations using __ksym + // and extern kconfig variables declared using __kconfig. case undefSection: if bind != elf.STB_GLOBAL { return fmt.Errorf("asm relocation: %s: unsupported binding: %s", name, bind) @@ -462,17 +599,46 @@ func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) err return fmt.Errorf("asm relocation: %s: unsupported type %s", name, typ) } - // There is nothing to do here but set ins.Reference. + kf := ec.kfuncs[name] + switch { + // If a Call instruction is found and the datasec has a btf.Func with a Name + // that matches the symbol name we mark the instruction as a call to a kfunc. + case kf != nil && ins.OpCode.JumpOp() == asm.Call: + ins.Metadata.Set(kfuncMeta{}, kf) + ins.Src = asm.PseudoKfuncCall + ins.Constant = -1 + + // If no kconfig map is found, this must be a symbol reference from inline + // asm (see testdata/loader.c:asm_relocation()) or a call to a forward + // function declaration (see testdata/fwd_decl.c). Don't interfere, These + // remain standard symbol references. + // extern __kconfig reads are represented as dword loads that need to be + // rewritten to pseudo map loads from .kconfig. If the map is present, + // require it to contain the symbol to disambiguate between inline asm + // relos and kconfigs. + case ec.kconfig != nil && ins.OpCode.IsDWordLoad(): + for _, vsi := range ec.kconfig.Value.(*btf.Datasec).Vars { + if vsi.Type.(*btf.Var).Name != rel.Name { + continue + } + + ins.Src = asm.PseudoMapValue + ins.Metadata.Set(kconfigMetaKey{}, &kconfigMeta{ec.kconfig, vsi.Offset}) + return nil + } + + return fmt.Errorf("kconfig %s not found in .kconfig", rel.Name) + } default: return fmt.Errorf("relocation to %q: %w", target.Name, ErrNotSupported) } - ins.Reference = name + *ins = ins.WithReference(name) return nil } -func (ec *elfCode) loadMaps(maps map[string]*MapSpec) error { +func (ec *elfCode) loadMaps() error { for _, sec := range ec.sections { if sec.kind != mapSection { continue @@ -498,7 +664,7 @@ func (ec *elfCode) loadMaps(maps map[string]*MapSpec) error { } mapName := mapSym.Name - if maps[mapName] != nil { + if ec.maps[mapName] != nil { return fmt.Errorf("section %v: map %v already exists", sec.Name, mapSym) } @@ -525,14 +691,14 @@ func (ec *elfCode) loadMaps(maps map[string]*MapSpec) error { return fmt.Errorf("map %s: reading map tail: %w", mapName, err) } if len(extra) > 0 { - spec.Extra = *bytes.NewReader(extra) + spec.Extra = bytes.NewReader(extra) } if err := spec.clampPerfEventArraySize(); err != nil { return fmt.Errorf("map %s: %w", mapName, err) } - maps[mapName] = &spec + ec.maps[mapName] = &spec } } @@ -542,7 +708,7 @@ func (ec *elfCode) loadMaps(maps map[string]*MapSpec) error { // loadBTFMaps iterates over all ELF sections marked as BTF map sections // (like .maps) and parses them into MapSpecs. Dump the .maps section and // any relocations with `readelf -x .maps -r `. -func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error { +func (ec *elfCode) loadBTFMaps() error { for _, sec := range ec.sections { if sec.kind != btfMapSection { continue @@ -554,7 +720,7 @@ func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error { // Each section must appear as a DataSec in the ELF's BTF blob. var ds *btf.Datasec - if err := ec.btf.FindType(sec.Name, &ds); err != nil { + if err := ec.btf.TypeByName(sec.Name, &ds); err != nil { return fmt.Errorf("cannot find section '%s' in BTF: %w", sec.Name, err) } @@ -581,7 +747,7 @@ func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error { return fmt.Errorf("section %v: map %s: initializing BTF map definitions: %w", sec.Name, name, internal.ErrNotSupported) } - if maps[name] != nil { + if ec.maps[name] != nil { return fmt.Errorf("section %v: map %s already exists", sec.Name, name) } @@ -600,7 +766,7 @@ func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error { return fmt.Errorf("map %v: %w", name, err) } - maps[name] = mapSpec + ec.maps[name] = mapSpec } // Drain the ELF section reader to make sure all bytes are accounted for @@ -617,14 +783,6 @@ func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error { return nil } -// A programStub is a placeholder for a Program to be inserted at a certain map key. -// It needs to be resolved into a Program later on in the loader process. -type programStub string - -// A mapStub is a placeholder for a Map to be inserted at a certain map key. -// It needs to be resolved into a Map later on in the loader process. -type mapStub string - // mapSpecFromBTF produces a MapSpec based on a btf.Struct def representing // a BTF map definition. The name and spec arguments will be copied to the // resulting MapSpec, and inner must be true on any resursive invocations. @@ -797,13 +955,6 @@ func mapSpecFromBTF(es *elfSection, vs *btf.VarSecinfo, def *btf.Struct, spec *b } } - if key == nil { - key = &btf.Void{} - } - if value == nil { - value = &btf.Void{} - } - return &MapSpec{ Name: SanitizeName(name, -1), Type: MapType(mapType), @@ -811,7 +962,8 @@ func mapSpecFromBTF(es *elfSection, vs *btf.VarSecinfo, def *btf.Struct, spec *b ValueSize: valueSize, MaxEntries: maxEntries, Flags: flags, - BTF: &btf.Map{Spec: spec, Key: key, Value: value}, + Key: key, + Value: value, Pinning: pinType, InnerMap: innerMapSpec, Contents: contents, @@ -863,7 +1015,7 @@ func resolveBTFValuesContents(es *elfSection, vs *btf.VarSecinfo, member btf.Mem // The offset of the 'values' member within the _struct_ (in bits) // is the starting point of the array. Convert to bytes. Add VarSecinfo // offset to get the absolute position in the ELF blob. - start := (member.OffsetBits / 8) + vs.Offset + start := member.Offset.Bytes() + vs.Offset // 'values' is encoded in BTF as a zero (variable) length struct // member, and its contents run until the end of the VarSecinfo. // Add VarSecinfo offset to get the absolute position in the ELF blob. @@ -898,18 +1050,18 @@ func resolveBTFValuesContents(es *elfSection, vs *btf.VarSecinfo, member btf.Mem // skipped here. switch t := elf.ST_TYPE(r.Info); t { case elf.STT_FUNC: - contents = append(contents, MapKV{uint32(k), programStub(r.Name)}) + contents = append(contents, MapKV{uint32(k), r.Name}) case elf.STT_OBJECT: - contents = append(contents, MapKV{uint32(k), mapStub(r.Name)}) + contents = append(contents, MapKV{uint32(k), r.Name}) default: - return nil, fmt.Errorf("unknown relocation type %v", t) + return nil, fmt.Errorf("unknown relocation type %v for symbol %s", t, r.Name) } } return contents, nil } -func (ec *elfCode) loadDataSections(maps map[string]*MapSpec) error { +func (ec *elfCode) loadDataSections() error { for _, sec := range ec.sections { if sec.kind != dataSection { continue @@ -921,134 +1073,219 @@ func (ec *elfCode) loadDataSections(maps map[string]*MapSpec) error { continue } - if ec.btf == nil { - return errors.New("data sections require BTF, make sure all consts are marked as static") + mapSpec := &MapSpec{ + Name: SanitizeName(sec.Name, -1), + Type: Array, + KeySize: 4, + ValueSize: uint32(sec.Size), + MaxEntries: 1, } - var datasec *btf.Datasec - if err := ec.btf.FindType(sec.Name, &datasec); err != nil { - return fmt.Errorf("data section %s: can't get BTF: %w", sec.Name, err) - } + switch sec.Type { + // Only open the section if we know there's actual data to be read. + case elf.SHT_PROGBITS: + data, err := sec.Data() + if err != nil { + return fmt.Errorf("data section %s: can't get contents: %w", sec.Name, err) + } - data, err := sec.Data() - if err != nil { - return fmt.Errorf("data section %s: can't get contents: %w", sec.Name, err) - } + if uint64(len(data)) > math.MaxUint32 { + return fmt.Errorf("data section %s: contents exceed maximum size", sec.Name) + } + mapSpec.Contents = []MapKV{{uint32(0), data}} - if uint64(len(data)) > math.MaxUint32 { - return fmt.Errorf("data section %s: contents exceed maximum size", sec.Name) + case elf.SHT_NOBITS: + // NOBITS sections like .bss contain only zeroes, and since data sections + // are Arrays, the kernel already preallocates them. Skip reading zeroes + // from the ELF. + default: + return fmt.Errorf("data section %s: unknown section type %s", sec.Name, sec.Type) } - mapSpec := &MapSpec{ - Name: SanitizeName(sec.Name, -1), - Type: Array, - KeySize: 4, - ValueSize: uint32(len(data)), - MaxEntries: 1, - Contents: []MapKV{{uint32(0), data}}, - BTF: &btf.Map{Spec: ec.btf, Key: &btf.Void{}, Value: datasec}, + // It is possible for a data section to exist without a corresponding BTF Datasec + // if it only contains anonymous values like macro-defined arrays. + if ec.btf != nil { + var ds *btf.Datasec + if ec.btf.TypeByName(sec.Name, &ds) == nil { + // Assign the spec's key and BTF only if the Datasec lookup was successful. + mapSpec.Key = &btf.Void{} + mapSpec.Value = ds + } } - switch sec.Name { - case ".rodata": + if strings.HasPrefix(sec.Name, ".rodata") { mapSpec.Flags = unix.BPF_F_RDONLY_PROG mapSpec.Freeze = true - case ".bss": - // The kernel already zero-initializes the map - mapSpec.Contents = nil } - maps[sec.Name] = mapSpec + ec.maps[sec.Name] = mapSpec + } + + return nil +} + +// loadKconfigSection handles the 'virtual' Datasec .kconfig that doesn't +// have a corresponding ELF section and exist purely in BTF. +func (ec *elfCode) loadKconfigSection() error { + if ec.btf == nil { + return nil + } + + var ds *btf.Datasec + err := ec.btf.TypeByName(".kconfig", &ds) + if errors.Is(err, btf.ErrNotFound) { + return nil + } + if err != nil { + return err + } + + if ds.Size == 0 { + return errors.New("zero-length .kconfig") } + + ec.kconfig = &MapSpec{ + Name: ".kconfig", + Type: Array, + KeySize: uint32(4), + ValueSize: ds.Size, + MaxEntries: 1, + Flags: unix.BPF_F_RDONLY_PROG | unix.BPF_F_MMAPABLE, + Freeze: true, + Key: &btf.Int{Size: 4}, + Value: ds, + } + + return nil +} + +// loadKsymsSection handles the 'virtual' Datasec .ksyms that doesn't +// have a corresponding ELF section and exist purely in BTF. +func (ec *elfCode) loadKsymsSection() error { + if ec.btf == nil { + return nil + } + + var ds *btf.Datasec + err := ec.btf.TypeByName(".ksyms", &ds) + if errors.Is(err, btf.ErrNotFound) { + return nil + } + if err != nil { + return err + } + + for _, v := range ds.Vars { + // we have already checked the .ksyms Datasec to only contain Func Vars. + ec.kfuncs[v.Type.TypeName()] = v.Type.(*btf.Func) + } + return nil } func getProgType(sectionName string) (ProgramType, AttachType, uint32, string) { - types := map[string]struct { + types := []struct { + prefix string progType ProgramType attachType AttachType progFlags uint32 }{ - // From https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/lib/bpf/libbpf.c - "socket": {SocketFilter, AttachNone, 0}, - "sk_reuseport/migrate": {SkReuseport, AttachSkReuseportSelectOrMigrate, 0}, - "sk_reuseport": {SkReuseport, AttachSkReuseportSelect, 0}, - "seccomp": {SocketFilter, AttachNone, 0}, - "kprobe/": {Kprobe, AttachNone, 0}, - "uprobe/": {Kprobe, AttachNone, 0}, - "kretprobe/": {Kprobe, AttachNone, 0}, - "uretprobe/": {Kprobe, AttachNone, 0}, - "tracepoint/": {TracePoint, AttachNone, 0}, - "raw_tracepoint/": {RawTracepoint, AttachNone, 0}, - "raw_tp/": {RawTracepoint, AttachNone, 0}, - "tp_btf/": {Tracing, AttachTraceRawTp, 0}, - "xdp": {XDP, AttachNone, 0}, - "perf_event": {PerfEvent, AttachNone, 0}, - "lwt_in": {LWTIn, AttachNone, 0}, - "lwt_out": {LWTOut, AttachNone, 0}, - "lwt_xmit": {LWTXmit, AttachNone, 0}, - "lwt_seg6local": {LWTSeg6Local, AttachNone, 0}, - "sockops": {SockOps, AttachCGroupSockOps, 0}, - "sk_skb/stream_parser": {SkSKB, AttachSkSKBStreamParser, 0}, - "sk_skb/stream_verdict": {SkSKB, AttachSkSKBStreamParser, 0}, - "sk_msg": {SkMsg, AttachSkSKBStreamVerdict, 0}, - "lirc_mode2": {LircMode2, AttachLircMode2, 0}, - "flow_dissector": {FlowDissector, AttachFlowDissector, 0}, - "iter/": {Tracing, AttachTraceIter, 0}, - "fentry/": {Tracing, AttachTraceFEntry, 0}, - "fmod_ret/": {Tracing, AttachModifyReturn, 0}, - "fexit/": {Tracing, AttachTraceFExit, 0}, - "fentry.s/": {Tracing, AttachTraceFEntry, unix.BPF_F_SLEEPABLE}, - "fmod_ret.s/": {Tracing, AttachModifyReturn, unix.BPF_F_SLEEPABLE}, - "fexit.s/": {Tracing, AttachTraceFExit, unix.BPF_F_SLEEPABLE}, - "sk_lookup/": {SkLookup, AttachSkLookup, 0}, - "freplace/": {Extension, AttachNone, 0}, - "lsm/": {LSM, AttachLSMMac, 0}, - "lsm.s/": {LSM, AttachLSMMac, unix.BPF_F_SLEEPABLE}, - - "cgroup_skb/ingress": {CGroupSKB, AttachCGroupInetIngress, 0}, - "cgroup_skb/egress": {CGroupSKB, AttachCGroupInetEgress, 0}, - "cgroup/dev": {CGroupDevice, AttachCGroupDevice, 0}, - "cgroup/skb": {CGroupSKB, AttachNone, 0}, - "cgroup/sock": {CGroupSock, AttachCGroupInetSockCreate, 0}, - "cgroup/post_bind4": {CGroupSock, AttachCGroupInet4PostBind, 0}, - "cgroup/post_bind6": {CGroupSock, AttachCGroupInet6PostBind, 0}, - "cgroup/bind4": {CGroupSockAddr, AttachCGroupInet4Bind, 0}, - "cgroup/bind6": {CGroupSockAddr, AttachCGroupInet6Bind, 0}, - "cgroup/connect4": {CGroupSockAddr, AttachCGroupInet4Connect, 0}, - "cgroup/connect6": {CGroupSockAddr, AttachCGroupInet6Connect, 0}, - "cgroup/sendmsg4": {CGroupSockAddr, AttachCGroupUDP4Sendmsg, 0}, - "cgroup/sendmsg6": {CGroupSockAddr, AttachCGroupUDP6Sendmsg, 0}, - "cgroup/recvmsg4": {CGroupSockAddr, AttachCGroupUDP4Recvmsg, 0}, - "cgroup/recvmsg6": {CGroupSockAddr, AttachCGroupUDP6Recvmsg, 0}, - "cgroup/sysctl": {CGroupSysctl, AttachCGroupSysctl, 0}, - "cgroup/getsockopt": {CGroupSockopt, AttachCGroupGetsockopt, 0}, - "cgroup/setsockopt": {CGroupSockopt, AttachCGroupSetsockopt, 0}, - "classifier": {SchedCLS, AttachNone, 0}, - "action": {SchedACT, AttachNone, 0}, - - "cgroup/getsockname4": {CGroupSockAddr, AttachCgroupInet4GetSockname, 0}, - "cgroup/getsockname6": {CGroupSockAddr, AttachCgroupInet6GetSockname, 0}, - "cgroup/getpeername4": {CGroupSockAddr, AttachCgroupInet4GetPeername, 0}, - "cgroup/getpeername6": {CGroupSockAddr, AttachCgroupInet6GetPeername, 0}, + // Please update the types from libbpf.c and follow the order of it. + // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/lib/bpf/libbpf.c + {"socket", SocketFilter, AttachNone, 0}, + {"sk_reuseport/migrate", SkReuseport, AttachSkReuseportSelectOrMigrate, 0}, + {"sk_reuseport", SkReuseport, AttachSkReuseportSelect, 0}, + {"kprobe/", Kprobe, AttachNone, 0}, + {"uprobe/", Kprobe, AttachNone, 0}, + {"kretprobe/", Kprobe, AttachNone, 0}, + {"uretprobe/", Kprobe, AttachNone, 0}, + {"tc", SchedCLS, AttachNone, 0}, + {"classifier", SchedCLS, AttachNone, 0}, + {"action", SchedACT, AttachNone, 0}, + {"tracepoint/", TracePoint, AttachNone, 0}, + {"tp/", TracePoint, AttachNone, 0}, + {"raw_tracepoint/", RawTracepoint, AttachNone, 0}, + {"raw_tp/", RawTracepoint, AttachNone, 0}, + {"raw_tracepoint.w/", RawTracepointWritable, AttachNone, 0}, + {"raw_tp.w/", RawTracepointWritable, AttachNone, 0}, + {"tp_btf/", Tracing, AttachTraceRawTp, 0}, + {"fentry/", Tracing, AttachTraceFEntry, 0}, + {"fmod_ret/", Tracing, AttachModifyReturn, 0}, + {"fexit/", Tracing, AttachTraceFExit, 0}, + {"fentry.s/", Tracing, AttachTraceFEntry, unix.BPF_F_SLEEPABLE}, + {"fmod_ret.s/", Tracing, AttachModifyReturn, unix.BPF_F_SLEEPABLE}, + {"fexit.s/", Tracing, AttachTraceFExit, unix.BPF_F_SLEEPABLE}, + {"freplace/", Extension, AttachNone, 0}, + {"lsm/", LSM, AttachLSMMac, 0}, + {"lsm.s/", LSM, AttachLSMMac, unix.BPF_F_SLEEPABLE}, + {"iter/", Tracing, AttachTraceIter, 0}, + {"iter.s/", Tracing, AttachTraceIter, unix.BPF_F_SLEEPABLE}, + {"syscall", Syscall, AttachNone, 0}, + {"xdp.frags_devmap/", XDP, AttachXDPDevMap, unix.BPF_F_XDP_HAS_FRAGS}, + {"xdp_devmap/", XDP, AttachXDPDevMap, 0}, + {"xdp.frags_cpumap/", XDP, AttachXDPCPUMap, unix.BPF_F_XDP_HAS_FRAGS}, + {"xdp_cpumap/", XDP, AttachXDPCPUMap, 0}, + {"xdp.frags", XDP, AttachNone, unix.BPF_F_XDP_HAS_FRAGS}, + {"xdp", XDP, AttachNone, 0}, + {"perf_event", PerfEvent, AttachNone, 0}, + {"lwt_in", LWTIn, AttachNone, 0}, + {"lwt_out", LWTOut, AttachNone, 0}, + {"lwt_xmit", LWTXmit, AttachNone, 0}, + {"lwt_seg6local", LWTSeg6Local, AttachNone, 0}, + {"cgroup_skb/ingress", CGroupSKB, AttachCGroupInetIngress, 0}, + {"cgroup_skb/egress", CGroupSKB, AttachCGroupInetEgress, 0}, + {"cgroup/skb", CGroupSKB, AttachNone, 0}, + {"cgroup/sock_create", CGroupSock, AttachCGroupInetSockCreate, 0}, + {"cgroup/sock_release", CGroupSock, AttachCgroupInetSockRelease, 0}, + {"cgroup/sock", CGroupSock, AttachCGroupInetSockCreate, 0}, + {"cgroup/post_bind4", CGroupSock, AttachCGroupInet4PostBind, 0}, + {"cgroup/post_bind6", CGroupSock, AttachCGroupInet6PostBind, 0}, + {"cgroup/dev", CGroupDevice, AttachCGroupDevice, 0}, + {"sockops", SockOps, AttachCGroupSockOps, 0}, + {"sk_skb/stream_parser", SkSKB, AttachSkSKBStreamParser, 0}, + {"sk_skb/stream_verdict", SkSKB, AttachSkSKBStreamVerdict, 0}, + {"sk_skb", SkSKB, AttachNone, 0}, + {"sk_msg", SkMsg, AttachSkMsgVerdict, 0}, + {"lirc_mode2", LircMode2, AttachLircMode2, 0}, + {"flow_dissector", FlowDissector, AttachFlowDissector, 0}, + {"cgroup/bind4", CGroupSockAddr, AttachCGroupInet4Bind, 0}, + {"cgroup/bind6", CGroupSockAddr, AttachCGroupInet6Bind, 0}, + {"cgroup/connect4", CGroupSockAddr, AttachCGroupInet4Connect, 0}, + {"cgroup/connect6", CGroupSockAddr, AttachCGroupInet6Connect, 0}, + {"cgroup/sendmsg4", CGroupSockAddr, AttachCGroupUDP4Sendmsg, 0}, + {"cgroup/sendmsg6", CGroupSockAddr, AttachCGroupUDP6Sendmsg, 0}, + {"cgroup/recvmsg4", CGroupSockAddr, AttachCGroupUDP4Recvmsg, 0}, + {"cgroup/recvmsg6", CGroupSockAddr, AttachCGroupUDP6Recvmsg, 0}, + {"cgroup/getpeername4", CGroupSockAddr, AttachCgroupInet4GetPeername, 0}, + {"cgroup/getpeername6", CGroupSockAddr, AttachCgroupInet6GetPeername, 0}, + {"cgroup/getsockname4", CGroupSockAddr, AttachCgroupInet4GetSockname, 0}, + {"cgroup/getsockname6", CGroupSockAddr, AttachCgroupInet6GetSockname, 0}, + {"cgroup/sysctl", CGroupSysctl, AttachCGroupSysctl, 0}, + {"cgroup/getsockopt", CGroupSockopt, AttachCGroupGetsockopt, 0}, + {"cgroup/setsockopt", CGroupSockopt, AttachCGroupSetsockopt, 0}, + {"struct_ops+", StructOps, AttachNone, 0}, + {"sk_lookup/", SkLookup, AttachSkLookup, 0}, + {"seccomp", SocketFilter, AttachNone, 0}, + {"kprobe.multi", Kprobe, AttachTraceKprobeMulti, 0}, + {"kretprobe.multi", Kprobe, AttachTraceKprobeMulti, 0}, } - for prefix, t := range types { - if !strings.HasPrefix(sectionName, prefix) { + for _, t := range types { + if !strings.HasPrefix(sectionName, t.prefix) { continue } - if !strings.HasSuffix(prefix, "/") { + if !strings.HasSuffix(t.prefix, "/") { return t.progType, t.attachType, t.progFlags, "" } - return t.progType, t.attachType, t.progFlags, sectionName[len(prefix):] + return t.progType, t.attachType, t.progFlags, sectionName[len(t.prefix):] } return UnspecifiedProgram, AttachNone, 0, "" } -func (ec *elfCode) loadRelocations(sec *elf.Section, symbols []elf.Symbol) (map[uint64]elf.Symbol, error) { +func (ec *elfCode) loadSectionRelocations(sec *elf.Section, symbols []elf.Symbol) (map[uint64]elf.Symbol, error) { rels := make(map[uint64]elf.Symbol) if sec.Entsize < 16 { diff --git a/vendor/github.com/cilium/ebpf/elf_reader_fuzz.go b/vendor/github.com/cilium/ebpf/elf_reader_fuzz.go deleted file mode 100644 index 5f4e0a0ad0..0000000000 --- a/vendor/github.com/cilium/ebpf/elf_reader_fuzz.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -// Use with https://github.com/dvyukov/go-fuzz - -package ebpf - -import "bytes" - -func FuzzLoadCollectionSpec(data []byte) int { - spec, err := LoadCollectionSpecFromReader(bytes.NewReader(data)) - if err != nil { - if spec != nil { - panic("spec is not nil") - } - return 0 - } - if spec == nil { - panic("spec is nil") - } - return 1 -} diff --git a/vendor/github.com/cilium/ebpf/go.mod b/vendor/github.com/cilium/ebpf/go.mod deleted file mode 100644 index f5edf690ab..0000000000 --- a/vendor/github.com/cilium/ebpf/go.mod +++ /dev/null @@ -1,9 +0,0 @@ -module github.com/cilium/ebpf - -go 1.16 - -require ( - github.com/frankban/quicktest v1.11.3 - github.com/google/go-cmp v0.5.4 - golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34 -) diff --git a/vendor/github.com/cilium/ebpf/go.sum b/vendor/github.com/cilium/ebpf/go.sum deleted file mode 100644 index 1ef5a4767e..0000000000 --- a/vendor/github.com/cilium/ebpf/go.sum +++ /dev/null @@ -1,13 +0,0 @@ -github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34 h1:GkvMjFtXUmahfDtashnc1mnrCtuBVcwse5QV2lUk/tI= -golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/vendor/github.com/cilium/ebpf/info.go b/vendor/github.com/cilium/ebpf/info.go index 65fa4d7d85..a02e8a4161 100644 --- a/vendor/github.com/cilium/ebpf/info.go +++ b/vendor/github.com/cilium/ebpf/info.go @@ -2,6 +2,7 @@ package ebpf import ( "bufio" + "bytes" "encoding/hex" "errors" "fmt" @@ -10,9 +11,13 @@ import ( "strings" "syscall" "time" + "unsafe" + "github.com/cilium/ebpf/asm" + "github.com/cilium/ebpf/btf" "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/btf" + "github.com/cilium/ebpf/internal/sys" + "github.com/cilium/ebpf/internal/unix" ) // MapInfo describes a map. @@ -23,12 +28,13 @@ type MapInfo struct { ValueSize uint32 MaxEntries uint32 Flags uint32 - // Name as supplied by user space at load time. + // Name as supplied by user space at load time. Available from 4.15. Name string } -func newMapInfoFromFd(fd *internal.FD) (*MapInfo, error) { - info, err := bpfGetMapInfoByFD(fd) +func newMapInfoFromFd(fd *sys.FD) (*MapInfo, error) { + var info sys.MapInfo + err := sys.ObjInfo(fd, &info) if errors.Is(err, syscall.EINVAL) { return newMapInfoFromProc(fd) } @@ -37,18 +43,17 @@ func newMapInfoFromFd(fd *internal.FD) (*MapInfo, error) { } return &MapInfo{ - MapType(info.map_type), - MapID(info.id), - info.key_size, - info.value_size, - info.max_entries, - info.map_flags, - // name is available from 4.15. - internal.CString(info.name[:]), + MapType(info.Type), + MapID(info.Id), + info.KeySize, + info.ValueSize, + info.MaxEntries, + uint32(info.MapFlags), + unix.ByteSliceToString(info.Name[:]), }, nil } -func newMapInfoFromProc(fd *internal.FD) (*MapInfo, error) { +func newMapInfoFromProc(fd *sys.FD) (*MapInfo, error) { var mi MapInfo err := scanFdInfo(fd, map[string]interface{}{ "map_type": &mi.Type, @@ -84,20 +89,23 @@ type programStats struct { type ProgramInfo struct { Type ProgramType id ProgramID - // Truncated hash of the BPF bytecode. + // Truncated hash of the BPF bytecode. Available from 4.13. Tag string - // Name as supplied by user space at load time. + // Name as supplied by user space at load time. Available from 4.15. Name string - // BTF for the program. - btf btf.ID - // IDS map ids related to program. - ids []MapID - stats *programStats + createdByUID uint32 + haveCreatedByUID bool + btf btf.ID + stats *programStats + + maps []MapID + insns []byte } -func newProgramInfoFromFd(fd *internal.FD) (*ProgramInfo, error) { - info, err := bpfGetProgInfoByFD(fd, nil) +func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) { + var info sys.ProgInfo + err := sys.ObjInfo(fd, &info) if errors.Is(err, syscall.EINVAL) { return newProgramInfoFromProc(fd) } @@ -105,32 +113,55 @@ func newProgramInfoFromFd(fd *internal.FD) (*ProgramInfo, error) { return nil, err } - var mapIDs []MapID - if info.nr_map_ids > 0 { - mapIDs = make([]MapID, info.nr_map_ids) - info, err = bpfGetProgInfoByFD(fd, mapIDs) - if err != nil { + pi := ProgramInfo{ + Type: ProgramType(info.Type), + id: ProgramID(info.Id), + Tag: hex.EncodeToString(info.Tag[:]), + Name: unix.ByteSliceToString(info.Name[:]), + btf: btf.ID(info.BtfId), + stats: &programStats{ + runtime: time.Duration(info.RunTimeNs), + runCount: info.RunCnt, + }, + } + + // Start with a clean struct for the second call, otherwise we may get EFAULT. + var info2 sys.ProgInfo + + if info.NrMapIds > 0 { + pi.maps = make([]MapID, info.NrMapIds) + info2.NrMapIds = info.NrMapIds + info2.MapIds = sys.NewPointer(unsafe.Pointer(&pi.maps[0])) + } else if haveProgramInfoMapIDs() == nil { + // This program really has no associated maps. + pi.maps = make([]MapID, 0) + } else { + // The kernel doesn't report associated maps. + pi.maps = nil + } + + // createdByUID and NrMapIds were introduced in the same kernel version. + if pi.maps != nil { + pi.createdByUID = info.CreatedByUid + pi.haveCreatedByUID = true + } + + if info.XlatedProgLen > 0 { + pi.insns = make([]byte, info.XlatedProgLen) + info2.XlatedProgLen = info.XlatedProgLen + info2.XlatedProgInsns = sys.NewSlicePointer(pi.insns) + } + + if info.NrMapIds > 0 || info.XlatedProgLen > 0 { + if err := sys.ObjInfo(fd, &info2); err != nil { return nil, err } } - return &ProgramInfo{ - Type: ProgramType(info.prog_type), - id: ProgramID(info.id), - // tag is available if the kernel supports BPF_PROG_GET_INFO_BY_FD. - Tag: hex.EncodeToString(info.tag[:]), - // name is available from 4.15. - Name: internal.CString(info.name[:]), - btf: btf.ID(info.btf_id), - ids: mapIDs, - stats: &programStats{ - runtime: time.Duration(info.run_time_ns), - runCount: info.run_cnt, - }, - }, nil + return &pi, nil } -func newProgramInfoFromProc(fd *internal.FD) (*ProgramInfo, error) { +func newProgramInfoFromProc(fd *sys.FD) (*ProgramInfo, error) { var info ProgramInfo err := scanFdInfo(fd, map[string]interface{}{ "prog_type": &info.Type, @@ -158,8 +189,18 @@ func (pi *ProgramInfo) ID() (ProgramID, bool) { return pi.id, pi.id > 0 } +// CreatedByUID returns the Uid that created the program. +// +// Available from 4.15. +// +// The bool return value indicates whether this optional field is available. +func (pi *ProgramInfo) CreatedByUID() (uint32, bool) { + return pi.createdByUID, pi.haveCreatedByUID +} + // BTFID returns the BTF ID associated with the program. // +// The ID is only valid as long as the associated program is kept alive. // Available from 5.0. // // The bool return value indicates whether this optional field is available and @@ -191,20 +232,50 @@ func (pi *ProgramInfo) Runtime() (time.Duration, bool) { return time.Duration(0), false } +// Instructions returns the 'xlated' instruction stream of the program +// after it has been verified and rewritten by the kernel. These instructions +// cannot be loaded back into the kernel as-is, this is mainly used for +// inspecting loaded programs for troubleshooting, dumping, etc. +// +// For example, map accesses are made to reference their kernel map IDs, +// not the FDs they had when the program was inserted. Note that before +// the introduction of bpf_insn_prepare_dump in kernel 4.16, xlated +// instructions were not sanitized, making the output even less reusable +// and less likely to round-trip or evaluate to the same program Tag. +// +// The first instruction is marked as a symbol using the Program's name. +// +// Available from 4.13. Requires CAP_BPF or equivalent. +func (pi *ProgramInfo) Instructions() (asm.Instructions, error) { + // If the calling process is not BPF-capable or if the kernel doesn't + // support getting xlated instructions, the field will be zero. + if len(pi.insns) == 0 { + return nil, fmt.Errorf("insufficient permissions or unsupported kernel: %w", ErrNotSupported) + } + + r := bytes.NewReader(pi.insns) + var insns asm.Instructions + if err := insns.Unmarshal(r, internal.NativeEndian); err != nil { + return nil, fmt.Errorf("unmarshaling instructions: %w", err) + } + + // Tag the first instruction with the name of the program, if available. + insns[0] = insns[0].WithSymbol(pi.Name) + + return insns, nil +} + // MapIDs returns the maps related to the program. // +// Available from 4.15. +// // The bool return value indicates whether this optional field is available. func (pi *ProgramInfo) MapIDs() ([]MapID, bool) { - return pi.ids, pi.ids != nil + return pi.maps, pi.maps != nil } -func scanFdInfo(fd *internal.FD, fields map[string]interface{}) error { - raw, err := fd.Value() - if err != nil { - return err - } - - fh, err := os.Open(fmt.Sprintf("/proc/self/fdinfo/%d", raw)) +func scanFdInfo(fd *sys.FD, fields map[string]interface{}) error { + fh, err := os.Open(fmt.Sprintf("/proc/self/fdinfo/%d", fd.Int())) if err != nil { return err } @@ -247,6 +318,10 @@ func scanFdInfoReader(r io.Reader, fields map[string]interface{}) error { return err } + if len(fields) > 0 && scanned == 0 { + return ErrNotSupported + } + if scanned != len(fields) { return errMissingFields } @@ -261,13 +336,38 @@ func scanFdInfoReader(r io.Reader, fields map[string]interface{}) error { // // Requires at least 5.8. func EnableStats(which uint32) (io.Closer, error) { - attr := internal.BPFEnableStatsAttr{ - StatsType: which, - } - - fd, err := internal.BPFEnableStats(&attr) + fd, err := sys.EnableStats(&sys.EnableStatsAttr{ + Type: which, + }) if err != nil { return nil, err } return fd, nil } + +var haveProgramInfoMapIDs = internal.NewFeatureTest("map IDs in program info", "4.15", func() error { + prog, err := progLoad(asm.Instructions{ + asm.LoadImm(asm.R0, 0, asm.DWord), + asm.Return(), + }, SocketFilter, "MIT") + if err != nil { + return err + } + defer prog.Close() + + err = sys.ObjInfo(prog, &sys.ProgInfo{ + // NB: Don't need to allocate MapIds since the program isn't using + // any maps. + NrMapIds: 1, + }) + if errors.Is(err, unix.EINVAL) { + // Most likely the syscall doesn't exist. + return internal.ErrNotSupported + } + if errors.Is(err, unix.E2BIG) { + // We've hit check_uarg_tail_zero on older kernels. + return internal.ErrNotSupported + } + + return err +}) diff --git a/vendor/github.com/cilium/ebpf/internal/align.go b/vendor/github.com/cilium/ebpf/internal/align.go index 8b4f2658ea..edc898fa96 100644 --- a/vendor/github.com/cilium/ebpf/internal/align.go +++ b/vendor/github.com/cilium/ebpf/internal/align.go @@ -1,6 +1,8 @@ package internal +import "golang.org/x/exp/constraints" + // Align returns 'n' updated to 'alignment' boundary. -func Align(n, alignment int) int { - return (int(n) + alignment - 1) / alignment * alignment +func Align[I constraints.Integer](n, alignment I) I { + return (n + alignment - 1) / alignment * alignment } diff --git a/vendor/github.com/cilium/ebpf/internal/btf/btf.go b/vendor/github.com/cilium/ebpf/internal/btf/btf.go deleted file mode 100644 index 2b5f6d226a..0000000000 --- a/vendor/github.com/cilium/ebpf/internal/btf/btf.go +++ /dev/null @@ -1,798 +0,0 @@ -package btf - -import ( - "bytes" - "debug/elf" - "encoding/binary" - "errors" - "fmt" - "io" - "math" - "os" - "reflect" - "sync" - "unsafe" - - "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/unix" -) - -const btfMagic = 0xeB9F - -// Errors returned by BTF functions. -var ( - ErrNotSupported = internal.ErrNotSupported - ErrNotFound = errors.New("not found") - ErrNoExtendedInfo = errors.New("no extended info") -) - -// ID represents the unique ID of a BTF object. -type ID uint32 - -// Spec represents decoded BTF. -type Spec struct { - rawTypes []rawType - strings stringTable - types []Type - namedTypes map[string][]NamedType - funcInfos map[string]extInfo - lineInfos map[string]extInfo - coreRelos map[string]coreRelos - byteOrder binary.ByteOrder -} - -type btfHeader struct { - Magic uint16 - Version uint8 - Flags uint8 - HdrLen uint32 - - TypeOff uint32 - TypeLen uint32 - StringOff uint32 - StringLen uint32 -} - -// LoadSpecFromReader reads BTF sections from an ELF. -// -// Returns ErrNotFound if the reader contains no BTF. -func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) { - file, err := internal.NewSafeELFFile(rd) - if err != nil { - return nil, err - } - defer file.Close() - - symbols, err := file.Symbols() - if err != nil { - return nil, fmt.Errorf("can't read symbols: %v", err) - } - - variableOffsets := make(map[variable]uint32) - for _, symbol := range symbols { - if idx := symbol.Section; idx >= elf.SHN_LORESERVE && idx <= elf.SHN_HIRESERVE { - // Ignore things like SHN_ABS - continue - } - - if int(symbol.Section) >= len(file.Sections) { - return nil, fmt.Errorf("symbol %s: invalid section %d", symbol.Name, symbol.Section) - } - - secName := file.Sections[symbol.Section].Name - if symbol.Value > math.MaxUint32 { - return nil, fmt.Errorf("section %s: symbol %s: size exceeds maximum", secName, symbol.Name) - } - - variableOffsets[variable{secName, symbol.Name}] = uint32(symbol.Value) - } - - return loadSpecFromELF(file, variableOffsets) -} - -func loadSpecFromELF(file *internal.SafeELFFile, variableOffsets map[variable]uint32) (*Spec, error) { - var ( - btfSection *elf.Section - btfExtSection *elf.Section - sectionSizes = make(map[string]uint32) - ) - - for _, sec := range file.Sections { - switch sec.Name { - case ".BTF": - btfSection = sec - case ".BTF.ext": - btfExtSection = sec - default: - if sec.Type != elf.SHT_PROGBITS && sec.Type != elf.SHT_NOBITS { - break - } - - if sec.Size > math.MaxUint32 { - return nil, fmt.Errorf("section %s exceeds maximum size", sec.Name) - } - - sectionSizes[sec.Name] = uint32(sec.Size) - } - } - - if btfSection == nil { - return nil, fmt.Errorf("btf: %w", ErrNotFound) - } - - spec, err := loadRawSpec(btfSection.Open(), file.ByteOrder, sectionSizes, variableOffsets) - if err != nil { - return nil, err - } - - if btfExtSection == nil { - return spec, nil - } - - spec.funcInfos, spec.lineInfos, spec.coreRelos, err = parseExtInfos(btfExtSection.Open(), file.ByteOrder, spec.strings) - if err != nil { - return nil, fmt.Errorf("can't read ext info: %w", err) - } - - return spec, nil -} - -// LoadRawSpec reads a blob of BTF data that isn't wrapped in an ELF file. -// -// Prefer using LoadSpecFromReader, since this function only supports a subset -// of BTF. -func LoadRawSpec(btf io.Reader, bo binary.ByteOrder) (*Spec, error) { - // This will return an error if we encounter a Datasec, since we can't fix - // it up. - return loadRawSpec(btf, bo, nil, nil) -} - -func loadRawSpec(btf io.Reader, bo binary.ByteOrder, sectionSizes map[string]uint32, variableOffsets map[variable]uint32) (*Spec, error) { - rawTypes, rawStrings, err := parseBTF(btf, bo) - if err != nil { - return nil, err - } - - err = fixupDatasec(rawTypes, rawStrings, sectionSizes, variableOffsets) - if err != nil { - return nil, err - } - - types, typesByName, err := inflateRawTypes(rawTypes, rawStrings) - if err != nil { - return nil, err - } - - return &Spec{ - rawTypes: rawTypes, - namedTypes: typesByName, - types: types, - strings: rawStrings, - byteOrder: bo, - }, nil -} - -var kernelBTF struct { - sync.Mutex - *Spec -} - -// LoadKernelSpec returns the current kernel's BTF information. -// -// Requires a >= 5.5 kernel with CONFIG_DEBUG_INFO_BTF enabled. Returns -// ErrNotSupported if BTF is not enabled. -func LoadKernelSpec() (*Spec, error) { - kernelBTF.Lock() - defer kernelBTF.Unlock() - - if kernelBTF.Spec != nil { - return kernelBTF.Spec, nil - } - - var err error - kernelBTF.Spec, err = loadKernelSpec() - return kernelBTF.Spec, err -} - -func loadKernelSpec() (*Spec, error) { - release, err := unix.KernelRelease() - if err != nil { - return nil, fmt.Errorf("can't read kernel release number: %w", err) - } - - fh, err := os.Open("/sys/kernel/btf/vmlinux") - if err == nil { - defer fh.Close() - - return LoadRawSpec(fh, internal.NativeEndian) - } - - // use same list of locations as libbpf - // https://github.com/libbpf/libbpf/blob/9a3a42608dbe3731256a5682a125ac1e23bced8f/src/btf.c#L3114-L3122 - locations := []string{ - "/boot/vmlinux-%s", - "/lib/modules/%s/vmlinux-%[1]s", - "/lib/modules/%s/build/vmlinux", - "/usr/lib/modules/%s/kernel/vmlinux", - "/usr/lib/debug/boot/vmlinux-%s", - "/usr/lib/debug/boot/vmlinux-%s.debug", - "/usr/lib/debug/lib/modules/%s/vmlinux", - } - - for _, loc := range locations { - path := fmt.Sprintf(loc, release) - - fh, err := os.Open(path) - if err != nil { - continue - } - defer fh.Close() - - file, err := internal.NewSafeELFFile(fh) - if err != nil { - return nil, err - } - defer file.Close() - - return loadSpecFromELF(file, nil) - } - - return nil, fmt.Errorf("no BTF for kernel version %s: %w", release, internal.ErrNotSupported) -} - -func parseBTF(btf io.Reader, bo binary.ByteOrder) ([]rawType, stringTable, error) { - rawBTF, err := io.ReadAll(btf) - if err != nil { - return nil, nil, fmt.Errorf("can't read BTF: %v", err) - } - - rd := bytes.NewReader(rawBTF) - - var header btfHeader - if err := binary.Read(rd, bo, &header); err != nil { - return nil, nil, fmt.Errorf("can't read header: %v", err) - } - - if header.Magic != btfMagic { - return nil, nil, fmt.Errorf("incorrect magic value %v", header.Magic) - } - - if header.Version != 1 { - return nil, nil, fmt.Errorf("unexpected version %v", header.Version) - } - - if header.Flags != 0 { - return nil, nil, fmt.Errorf("unsupported flags %v", header.Flags) - } - - remainder := int64(header.HdrLen) - int64(binary.Size(&header)) - if remainder < 0 { - return nil, nil, errors.New("header is too short") - } - - if _, err := io.CopyN(internal.DiscardZeroes{}, rd, remainder); err != nil { - return nil, nil, fmt.Errorf("header padding: %v", err) - } - - if _, err := rd.Seek(int64(header.HdrLen+header.StringOff), io.SeekStart); err != nil { - return nil, nil, fmt.Errorf("can't seek to start of string section: %v", err) - } - - rawStrings, err := readStringTable(io.LimitReader(rd, int64(header.StringLen))) - if err != nil { - return nil, nil, fmt.Errorf("can't read type names: %w", err) - } - - if _, err := rd.Seek(int64(header.HdrLen+header.TypeOff), io.SeekStart); err != nil { - return nil, nil, fmt.Errorf("can't seek to start of type section: %v", err) - } - - rawTypes, err := readTypes(io.LimitReader(rd, int64(header.TypeLen)), bo) - if err != nil { - return nil, nil, fmt.Errorf("can't read types: %w", err) - } - - return rawTypes, rawStrings, nil -} - -type variable struct { - section string - name string -} - -func fixupDatasec(rawTypes []rawType, rawStrings stringTable, sectionSizes map[string]uint32, variableOffsets map[variable]uint32) error { - for i, rawType := range rawTypes { - if rawType.Kind() != kindDatasec { - continue - } - - name, err := rawStrings.Lookup(rawType.NameOff) - if err != nil { - return err - } - - if name == ".kconfig" || name == ".ksyms" { - return fmt.Errorf("reference to %s: %w", name, ErrNotSupported) - } - - if rawTypes[i].SizeType != 0 { - continue - } - - size, ok := sectionSizes[name] - if !ok { - return fmt.Errorf("data section %s: missing size", name) - } - - rawTypes[i].SizeType = size - - secinfos := rawType.data.([]btfVarSecinfo) - for j, secInfo := range secinfos { - id := int(secInfo.Type - 1) - if id >= len(rawTypes) { - return fmt.Errorf("data section %s: invalid type id %d for variable %d", name, id, j) - } - - varName, err := rawStrings.Lookup(rawTypes[id].NameOff) - if err != nil { - return fmt.Errorf("data section %s: can't get name for type %d: %w", name, id, err) - } - - offset, ok := variableOffsets[variable{name, varName}] - if !ok { - return fmt.Errorf("data section %s: missing offset for variable %s", name, varName) - } - - secinfos[j].Offset = offset - } - } - - return nil -} - -// Copy creates a copy of Spec. -func (s *Spec) Copy() *Spec { - types, _ := copyTypes(s.types, nil) - namedTypes := make(map[string][]NamedType) - for _, typ := range types { - if named, ok := typ.(NamedType); ok { - name := essentialName(named.TypeName()) - namedTypes[name] = append(namedTypes[name], named) - } - } - - // NB: Other parts of spec are not copied since they are immutable. - return &Spec{ - s.rawTypes, - s.strings, - types, - namedTypes, - s.funcInfos, - s.lineInfos, - s.coreRelos, - s.byteOrder, - } -} - -type marshalOpts struct { - ByteOrder binary.ByteOrder - StripFuncLinkage bool -} - -func (s *Spec) marshal(opts marshalOpts) ([]byte, error) { - var ( - buf bytes.Buffer - header = new(btfHeader) - headerLen = binary.Size(header) - ) - - // Reserve space for the header. We have to write it last since - // we don't know the size of the type section yet. - _, _ = buf.Write(make([]byte, headerLen)) - - // Write type section, just after the header. - for _, raw := range s.rawTypes { - switch { - case opts.StripFuncLinkage && raw.Kind() == kindFunc: - raw.SetLinkage(StaticFunc) - } - - if err := raw.Marshal(&buf, opts.ByteOrder); err != nil { - return nil, fmt.Errorf("can't marshal BTF: %w", err) - } - } - - typeLen := uint32(buf.Len() - headerLen) - - // Write string section after type section. - _, _ = buf.Write(s.strings) - - // Fill out the header, and write it out. - header = &btfHeader{ - Magic: btfMagic, - Version: 1, - Flags: 0, - HdrLen: uint32(headerLen), - TypeOff: 0, - TypeLen: typeLen, - StringOff: typeLen, - StringLen: uint32(len(s.strings)), - } - - raw := buf.Bytes() - err := binary.Write(sliceWriter(raw[:headerLen]), opts.ByteOrder, header) - if err != nil { - return nil, fmt.Errorf("can't write header: %v", err) - } - - return raw, nil -} - -type sliceWriter []byte - -func (sw sliceWriter) Write(p []byte) (int, error) { - if len(p) != len(sw) { - return 0, errors.New("size doesn't match") - } - - return copy(sw, p), nil -} - -// Program finds the BTF for a specific section. -// -// Length is the number of bytes in the raw BPF instruction stream. -// -// Returns an error which may wrap ErrNoExtendedInfo if the Spec doesn't -// contain extended BTF info. -func (s *Spec) Program(name string, length uint64) (*Program, error) { - if length == 0 { - return nil, errors.New("length musn't be zero") - } - - if s.funcInfos == nil && s.lineInfos == nil && s.coreRelos == nil { - return nil, fmt.Errorf("BTF for section %s: %w", name, ErrNoExtendedInfo) - } - - funcInfos, funcOK := s.funcInfos[name] - lineInfos, lineOK := s.lineInfos[name] - relos, coreOK := s.coreRelos[name] - - if !funcOK && !lineOK && !coreOK { - return nil, fmt.Errorf("no extended BTF info for section %s", name) - } - - return &Program{s, length, funcInfos, lineInfos, relos}, nil -} - -// FindType searches for a type with a specific name. -// -// Called T a type that satisfies Type, typ must be a non-nil **T. -// On success, the address of the found type will be copied in typ. -// -// Returns an error wrapping ErrNotFound if no matching -// type exists in spec. -func (s *Spec) FindType(name string, typ interface{}) error { - typValue := reflect.ValueOf(typ) - if typValue.Kind() != reflect.Ptr { - return fmt.Errorf("%T is not a pointer", typ) - } - - typPtr := typValue.Elem() - if !typPtr.CanSet() { - return fmt.Errorf("%T cannot be set", typ) - } - - wanted := typPtr.Type() - if !wanted.AssignableTo(reflect.TypeOf((*Type)(nil)).Elem()) { - return fmt.Errorf("%T does not satisfy Type interface", typ) - } - - var candidate Type - for _, typ := range s.namedTypes[essentialName(name)] { - if reflect.TypeOf(typ) != wanted { - continue - } - - // Match against the full name, not just the essential one. - if typ.TypeName() != name { - continue - } - - if candidate != nil { - return fmt.Errorf("type %s: multiple candidates for %T", name, typ) - } - - candidate = typ - } - - if candidate == nil { - return fmt.Errorf("type %s: %w", name, ErrNotFound) - } - - typPtr.Set(reflect.ValueOf(candidate)) - - return nil -} - -// Handle is a reference to BTF loaded into the kernel. -type Handle struct { - spec *Spec - fd *internal.FD -} - -// NewHandle loads BTF into the kernel. -// -// Returns ErrNotSupported if BTF is not supported. -func NewHandle(spec *Spec) (*Handle, error) { - if err := haveBTF(); err != nil { - return nil, err - } - - if spec.byteOrder != internal.NativeEndian { - return nil, fmt.Errorf("can't load %s BTF on %s", spec.byteOrder, internal.NativeEndian) - } - - btf, err := spec.marshal(marshalOpts{ - ByteOrder: internal.NativeEndian, - StripFuncLinkage: haveFuncLinkage() != nil, - }) - if err != nil { - return nil, fmt.Errorf("can't marshal BTF: %w", err) - } - - if uint64(len(btf)) > math.MaxUint32 { - return nil, errors.New("BTF exceeds the maximum size") - } - - attr := &bpfLoadBTFAttr{ - btf: internal.NewSlicePointer(btf), - btfSize: uint32(len(btf)), - } - - fd, err := bpfLoadBTF(attr) - if err != nil { - logBuf := make([]byte, 64*1024) - attr.logBuf = internal.NewSlicePointer(logBuf) - attr.btfLogSize = uint32(len(logBuf)) - attr.btfLogLevel = 1 - _, logErr := bpfLoadBTF(attr) - return nil, internal.ErrorWithLog(err, logBuf, logErr) - } - - return &Handle{spec.Copy(), fd}, nil -} - -// NewHandleFromID returns the BTF handle for a given id. -// -// Returns ErrNotExist, if there is no BTF with the given id. -// -// Requires CAP_SYS_ADMIN. -func NewHandleFromID(id ID) (*Handle, error) { - fd, err := internal.BPFObjGetFDByID(internal.BPF_BTF_GET_FD_BY_ID, uint32(id)) - if err != nil { - return nil, fmt.Errorf("get BTF by id: %w", err) - } - - info, err := newInfoFromFd(fd) - if err != nil { - _ = fd.Close() - return nil, fmt.Errorf("get BTF spec for handle: %w", err) - } - - return &Handle{info.BTF, fd}, nil -} - -// Spec returns the Spec that defined the BTF loaded into the kernel. -func (h *Handle) Spec() *Spec { - return h.spec -} - -// Close destroys the handle. -// -// Subsequent calls to FD will return an invalid value. -func (h *Handle) Close() error { - return h.fd.Close() -} - -// FD returns the file descriptor for the handle. -func (h *Handle) FD() int { - value, err := h.fd.Value() - if err != nil { - return -1 - } - - return int(value) -} - -// Map is the BTF for a map. -type Map struct { - Spec *Spec - Key, Value Type -} - -// Program is the BTF information for a stream of instructions. -type Program struct { - spec *Spec - length uint64 - funcInfos, lineInfos extInfo - coreRelos coreRelos -} - -// Spec returns the BTF spec of this program. -func (p *Program) Spec() *Spec { - return p.spec -} - -// Append the information from other to the Program. -func (p *Program) Append(other *Program) error { - if other.spec != p.spec { - return fmt.Errorf("can't append program with different BTF specs") - } - - funcInfos, err := p.funcInfos.append(other.funcInfos, p.length) - if err != nil { - return fmt.Errorf("func infos: %w", err) - } - - lineInfos, err := p.lineInfos.append(other.lineInfos, p.length) - if err != nil { - return fmt.Errorf("line infos: %w", err) - } - - p.funcInfos = funcInfos - p.lineInfos = lineInfos - p.coreRelos = p.coreRelos.append(other.coreRelos, p.length) - p.length += other.length - return nil -} - -// FuncInfos returns the binary form of BTF function infos. -func (p *Program) FuncInfos() (recordSize uint32, bytes []byte, err error) { - bytes, err = p.funcInfos.MarshalBinary() - if err != nil { - return 0, nil, fmt.Errorf("func infos: %w", err) - } - - return p.funcInfos.recordSize, bytes, nil -} - -// LineInfos returns the binary form of BTF line infos. -func (p *Program) LineInfos() (recordSize uint32, bytes []byte, err error) { - bytes, err = p.lineInfos.MarshalBinary() - if err != nil { - return 0, nil, fmt.Errorf("line infos: %w", err) - } - - return p.lineInfos.recordSize, bytes, nil -} - -// Fixups returns the changes required to adjust the program to the target. -// -// Passing a nil target will relocate against the running kernel. -func (p *Program) Fixups(target *Spec) (COREFixups, error) { - if len(p.coreRelos) == 0 { - return nil, nil - } - - if target == nil { - var err error - target, err = LoadKernelSpec() - if err != nil { - return nil, err - } - } - - return coreRelocate(p.spec, target, p.coreRelos) -} - -type bpfLoadBTFAttr struct { - btf internal.Pointer - logBuf internal.Pointer - btfSize uint32 - btfLogSize uint32 - btfLogLevel uint32 -} - -func bpfLoadBTF(attr *bpfLoadBTFAttr) (*internal.FD, error) { - fd, err := internal.BPF(internal.BPF_BTF_LOAD, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - - return internal.NewFD(uint32(fd)), nil -} - -func marshalBTF(types interface{}, strings []byte, bo binary.ByteOrder) []byte { - const minHeaderLength = 24 - - typesLen := uint32(binary.Size(types)) - header := btfHeader{ - Magic: btfMagic, - Version: 1, - HdrLen: minHeaderLength, - TypeOff: 0, - TypeLen: typesLen, - StringOff: typesLen, - StringLen: uint32(len(strings)), - } - - buf := new(bytes.Buffer) - _ = binary.Write(buf, bo, &header) - _ = binary.Write(buf, bo, types) - buf.Write(strings) - - return buf.Bytes() -} - -var haveBTF = internal.FeatureTest("BTF", "5.1", func() error { - var ( - types struct { - Integer btfType - Var btfType - btfVar struct{ Linkage uint32 } - } - strings = []byte{0, 'a', 0} - ) - - // We use a BTF_KIND_VAR here, to make sure that - // the kernel understands BTF at least as well as we - // do. BTF_KIND_VAR was introduced ~5.1. - types.Integer.SetKind(kindPointer) - types.Var.NameOff = 1 - types.Var.SetKind(kindVar) - types.Var.SizeType = 1 - - btf := marshalBTF(&types, strings, internal.NativeEndian) - - fd, err := bpfLoadBTF(&bpfLoadBTFAttr{ - btf: internal.NewSlicePointer(btf), - btfSize: uint32(len(btf)), - }) - if errors.Is(err, unix.EINVAL) || errors.Is(err, unix.EPERM) { - // Treat both EINVAL and EPERM as not supported: loading the program - // might still succeed without BTF. - return internal.ErrNotSupported - } - if err != nil { - return err - } - - fd.Close() - return nil -}) - -var haveFuncLinkage = internal.FeatureTest("BTF func linkage", "5.6", func() error { - if err := haveBTF(); err != nil { - return err - } - - var ( - types struct { - FuncProto btfType - Func btfType - } - strings = []byte{0, 'a', 0} - ) - - types.FuncProto.SetKind(kindFuncProto) - types.Func.SetKind(kindFunc) - types.Func.SizeType = 1 // aka FuncProto - types.Func.NameOff = 1 - types.Func.SetLinkage(GlobalFunc) - - btf := marshalBTF(&types, strings, internal.NativeEndian) - - fd, err := bpfLoadBTF(&bpfLoadBTFAttr{ - btf: internal.NewSlicePointer(btf), - btfSize: uint32(len(btf)), - }) - if errors.Is(err, unix.EINVAL) { - return internal.ErrNotSupported - } - if err != nil { - return err - } - - fd.Close() - return nil -}) diff --git a/vendor/github.com/cilium/ebpf/internal/btf/ext_info.go b/vendor/github.com/cilium/ebpf/internal/btf/ext_info.go deleted file mode 100644 index cdae2ec408..0000000000 --- a/vendor/github.com/cilium/ebpf/internal/btf/ext_info.go +++ /dev/null @@ -1,312 +0,0 @@ -package btf - -import ( - "bufio" - "bytes" - "encoding/binary" - "errors" - "fmt" - "io" - - "github.com/cilium/ebpf/asm" - "github.com/cilium/ebpf/internal" -) - -type btfExtHeader struct { - Magic uint16 - Version uint8 - Flags uint8 - HdrLen uint32 - - FuncInfoOff uint32 - FuncInfoLen uint32 - LineInfoOff uint32 - LineInfoLen uint32 -} - -type btfExtCoreHeader struct { - CoreReloOff uint32 - CoreReloLen uint32 -} - -func parseExtInfos(r io.ReadSeeker, bo binary.ByteOrder, strings stringTable) (funcInfo, lineInfo map[string]extInfo, relos map[string]coreRelos, err error) { - var header btfExtHeader - var coreHeader btfExtCoreHeader - if err := binary.Read(r, bo, &header); err != nil { - return nil, nil, nil, fmt.Errorf("can't read header: %v", err) - } - - if header.Magic != btfMagic { - return nil, nil, nil, fmt.Errorf("incorrect magic value %v", header.Magic) - } - - if header.Version != 1 { - return nil, nil, nil, fmt.Errorf("unexpected version %v", header.Version) - } - - if header.Flags != 0 { - return nil, nil, nil, fmt.Errorf("unsupported flags %v", header.Flags) - } - - remainder := int64(header.HdrLen) - int64(binary.Size(&header)) - if remainder < 0 { - return nil, nil, nil, errors.New("header is too short") - } - - coreHdrSize := int64(binary.Size(&coreHeader)) - if remainder >= coreHdrSize { - if err := binary.Read(r, bo, &coreHeader); err != nil { - return nil, nil, nil, fmt.Errorf("can't read CO-RE relocation header: %v", err) - } - remainder -= coreHdrSize - } - - // Of course, the .BTF.ext header has different semantics than the - // .BTF ext header. We need to ignore non-null values. - _, err = io.CopyN(io.Discard, r, remainder) - if err != nil { - return nil, nil, nil, fmt.Errorf("header padding: %v", err) - } - - if _, err := r.Seek(int64(header.HdrLen+header.FuncInfoOff), io.SeekStart); err != nil { - return nil, nil, nil, fmt.Errorf("can't seek to function info section: %v", err) - } - - buf := bufio.NewReader(io.LimitReader(r, int64(header.FuncInfoLen))) - funcInfo, err = parseExtInfo(buf, bo, strings) - if err != nil { - return nil, nil, nil, fmt.Errorf("function info: %w", err) - } - - if _, err := r.Seek(int64(header.HdrLen+header.LineInfoOff), io.SeekStart); err != nil { - return nil, nil, nil, fmt.Errorf("can't seek to line info section: %v", err) - } - - buf = bufio.NewReader(io.LimitReader(r, int64(header.LineInfoLen))) - lineInfo, err = parseExtInfo(buf, bo, strings) - if err != nil { - return nil, nil, nil, fmt.Errorf("line info: %w", err) - } - - if coreHeader.CoreReloOff > 0 && coreHeader.CoreReloLen > 0 { - if _, err := r.Seek(int64(header.HdrLen+coreHeader.CoreReloOff), io.SeekStart); err != nil { - return nil, nil, nil, fmt.Errorf("can't seek to CO-RE relocation section: %v", err) - } - - relos, err = parseExtInfoRelos(io.LimitReader(r, int64(coreHeader.CoreReloLen)), bo, strings) - if err != nil { - return nil, nil, nil, fmt.Errorf("CO-RE relocation info: %w", err) - } - } - - return funcInfo, lineInfo, relos, nil -} - -type btfExtInfoSec struct { - SecNameOff uint32 - NumInfo uint32 -} - -type extInfoRecord struct { - InsnOff uint64 - Opaque []byte -} - -type extInfo struct { - byteOrder binary.ByteOrder - recordSize uint32 - records []extInfoRecord -} - -func (ei extInfo) append(other extInfo, offset uint64) (extInfo, error) { - if other.byteOrder != ei.byteOrder { - return extInfo{}, fmt.Errorf("ext_info byte order mismatch, want %v (got %v)", ei.byteOrder, other.byteOrder) - } - - if other.recordSize != ei.recordSize { - return extInfo{}, fmt.Errorf("ext_info record size mismatch, want %d (got %d)", ei.recordSize, other.recordSize) - } - - records := make([]extInfoRecord, 0, len(ei.records)+len(other.records)) - records = append(records, ei.records...) - for _, info := range other.records { - records = append(records, extInfoRecord{ - InsnOff: info.InsnOff + offset, - Opaque: info.Opaque, - }) - } - return extInfo{ei.byteOrder, ei.recordSize, records}, nil -} - -func (ei extInfo) MarshalBinary() ([]byte, error) { - if ei.byteOrder != internal.NativeEndian { - return nil, fmt.Errorf("%s is not the native byte order", ei.byteOrder) - } - - if len(ei.records) == 0 { - return nil, nil - } - - buf := bytes.NewBuffer(make([]byte, 0, int(ei.recordSize)*len(ei.records))) - for _, info := range ei.records { - // The kernel expects offsets in number of raw bpf instructions, - // while the ELF tracks it in bytes. - insnOff := uint32(info.InsnOff / asm.InstructionSize) - if err := binary.Write(buf, internal.NativeEndian, insnOff); err != nil { - return nil, fmt.Errorf("can't write instruction offset: %v", err) - } - - buf.Write(info.Opaque) - } - - return buf.Bytes(), nil -} - -func parseExtInfo(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[string]extInfo, error) { - const maxRecordSize = 256 - - var recordSize uint32 - if err := binary.Read(r, bo, &recordSize); err != nil { - return nil, fmt.Errorf("can't read record size: %v", err) - } - - if recordSize < 4 { - // Need at least insnOff - return nil, errors.New("record size too short") - } - if recordSize > maxRecordSize { - return nil, fmt.Errorf("record size %v exceeds %v", recordSize, maxRecordSize) - } - - result := make(map[string]extInfo) - for { - secName, infoHeader, err := parseExtInfoHeader(r, bo, strings) - if errors.Is(err, io.EOF) { - return result, nil - } - - var records []extInfoRecord - for i := uint32(0); i < infoHeader.NumInfo; i++ { - var byteOff uint32 - if err := binary.Read(r, bo, &byteOff); err != nil { - return nil, fmt.Errorf("section %v: can't read extended info offset: %v", secName, err) - } - - buf := make([]byte, int(recordSize-4)) - if _, err := io.ReadFull(r, buf); err != nil { - return nil, fmt.Errorf("section %v: can't read record: %v", secName, err) - } - - if byteOff%asm.InstructionSize != 0 { - return nil, fmt.Errorf("section %v: offset %v is not aligned with instruction size", secName, byteOff) - } - - records = append(records, extInfoRecord{uint64(byteOff), buf}) - } - - result[secName] = extInfo{ - bo, - recordSize, - records, - } - } -} - -// bpfCoreRelo matches `struct bpf_core_relo` from the kernel -type bpfCoreRelo struct { - InsnOff uint32 - TypeID TypeID - AccessStrOff uint32 - Kind COREKind -} - -type coreRelo struct { - insnOff uint32 - typeID TypeID - accessor coreAccessor - kind COREKind -} - -type coreRelos []coreRelo - -// append two slices of extInfoRelo to each other. The InsnOff of b are adjusted -// by offset. -func (r coreRelos) append(other coreRelos, offset uint64) coreRelos { - result := make([]coreRelo, 0, len(r)+len(other)) - result = append(result, r...) - for _, relo := range other { - relo.insnOff += uint32(offset) - result = append(result, relo) - } - return result -} - -var extInfoReloSize = binary.Size(bpfCoreRelo{}) - -func parseExtInfoRelos(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[string]coreRelos, error) { - var recordSize uint32 - if err := binary.Read(r, bo, &recordSize); err != nil { - return nil, fmt.Errorf("read record size: %v", err) - } - - if recordSize != uint32(extInfoReloSize) { - return nil, fmt.Errorf("expected record size %d, got %d", extInfoReloSize, recordSize) - } - - result := make(map[string]coreRelos) - for { - secName, infoHeader, err := parseExtInfoHeader(r, bo, strings) - if errors.Is(err, io.EOF) { - return result, nil - } - - var relos coreRelos - for i := uint32(0); i < infoHeader.NumInfo; i++ { - var relo bpfCoreRelo - if err := binary.Read(r, bo, &relo); err != nil { - return nil, fmt.Errorf("section %v: read record: %v", secName, err) - } - - if relo.InsnOff%asm.InstructionSize != 0 { - return nil, fmt.Errorf("section %v: offset %v is not aligned with instruction size", secName, relo.InsnOff) - } - - accessorStr, err := strings.Lookup(relo.AccessStrOff) - if err != nil { - return nil, err - } - - accessor, err := parseCoreAccessor(accessorStr) - if err != nil { - return nil, fmt.Errorf("accessor %q: %s", accessorStr, err) - } - - relos = append(relos, coreRelo{ - relo.InsnOff, - relo.TypeID, - accessor, - relo.Kind, - }) - } - - result[secName] = relos - } -} - -func parseExtInfoHeader(r io.Reader, bo binary.ByteOrder, strings stringTable) (string, *btfExtInfoSec, error) { - var infoHeader btfExtInfoSec - if err := binary.Read(r, bo, &infoHeader); err != nil { - return "", nil, fmt.Errorf("read ext info header: %w", err) - } - - secName, err := strings.Lookup(infoHeader.SecNameOff) - if err != nil { - return "", nil, fmt.Errorf("get section name: %w", err) - } - - if infoHeader.NumInfo == 0 { - return "", nil, fmt.Errorf("section %s has zero records", secName) - } - - return secName, &infoHeader, nil -} diff --git a/vendor/github.com/cilium/ebpf/internal/btf/fuzz.go b/vendor/github.com/cilium/ebpf/internal/btf/fuzz.go deleted file mode 100644 index 220b285afe..0000000000 --- a/vendor/github.com/cilium/ebpf/internal/btf/fuzz.go +++ /dev/null @@ -1,50 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -// Use with https://github.com/dvyukov/go-fuzz - -package btf - -import ( - "bytes" - "encoding/binary" - - "github.com/cilium/ebpf/internal" -) - -func FuzzSpec(data []byte) int { - if len(data) < binary.Size(btfHeader{}) { - return -1 - } - - spec, err := loadNakedSpec(bytes.NewReader(data), internal.NativeEndian, nil, nil) - if err != nil { - if spec != nil { - panic("spec is not nil") - } - return 0 - } - if spec == nil { - panic("spec is nil") - } - return 1 -} - -func FuzzExtInfo(data []byte) int { - if len(data) < binary.Size(btfExtHeader{}) { - return -1 - } - - table := stringTable("\x00foo\x00barfoo\x00") - info, err := parseExtInfo(bytes.NewReader(data), internal.NativeEndian, table) - if err != nil { - if info != nil { - panic("info is not nil") - } - return 0 - } - if info == nil { - panic("info is nil") - } - return 1 -} diff --git a/vendor/github.com/cilium/ebpf/internal/btf/info.go b/vendor/github.com/cilium/ebpf/internal/btf/info.go deleted file mode 100644 index 6a9b5d2e0b..0000000000 --- a/vendor/github.com/cilium/ebpf/internal/btf/info.go +++ /dev/null @@ -1,48 +0,0 @@ -package btf - -import ( - "bytes" - - "github.com/cilium/ebpf/internal" -) - -// info describes a BTF object. -type info struct { - BTF *Spec - ID ID - // Name is an identifying name for the BTF, currently only used by the - // kernel. - Name string - // KernelBTF is true if the BTf originated with the kernel and not - // userspace. - KernelBTF bool -} - -func newInfoFromFd(fd *internal.FD) (*info, error) { - // We invoke the syscall once with a empty BTF and name buffers to get size - // information to allocate buffers. Then we invoke it a second time with - // buffers to receive the data. - bpfInfo, err := bpfGetBTFInfoByFD(fd, nil, nil) - if err != nil { - return nil, err - } - - btfBuffer := make([]byte, bpfInfo.btfSize) - nameBuffer := make([]byte, bpfInfo.nameLen) - bpfInfo, err = bpfGetBTFInfoByFD(fd, btfBuffer, nameBuffer) - if err != nil { - return nil, err - } - - spec, err := loadRawSpec(bytes.NewReader(btfBuffer), internal.NativeEndian, nil, nil) - if err != nil { - return nil, err - } - - return &info{ - BTF: spec, - ID: ID(bpfInfo.id), - Name: internal.CString(nameBuffer), - KernelBTF: bpfInfo.kernelBTF != 0, - }, nil -} diff --git a/vendor/github.com/cilium/ebpf/internal/btf/strings.go b/vendor/github.com/cilium/ebpf/internal/btf/strings.go deleted file mode 100644 index 9876aa227c..0000000000 --- a/vendor/github.com/cilium/ebpf/internal/btf/strings.go +++ /dev/null @@ -1,54 +0,0 @@ -package btf - -import ( - "bytes" - "errors" - "fmt" - "io" -) - -type stringTable []byte - -func readStringTable(r io.Reader) (stringTable, error) { - contents, err := io.ReadAll(r) - if err != nil { - return nil, fmt.Errorf("can't read string table: %v", err) - } - - if len(contents) < 1 { - return nil, errors.New("string table is empty") - } - - if contents[0] != '\x00' { - return nil, errors.New("first item in string table is non-empty") - } - - if contents[len(contents)-1] != '\x00' { - return nil, errors.New("string table isn't null terminated") - } - - return stringTable(contents), nil -} - -func (st stringTable) Lookup(offset uint32) (string, error) { - if int64(offset) > int64(^uint(0)>>1) { - return "", fmt.Errorf("offset %d overflows int", offset) - } - - pos := int(offset) - if pos >= len(st) { - return "", fmt.Errorf("offset %d is out of bounds", offset) - } - - if pos > 0 && st[pos-1] != '\x00' { - return "", fmt.Errorf("offset %d isn't start of a string", offset) - } - - str := st[pos:] - end := bytes.IndexByte(str, '\x00') - if end == -1 { - return "", fmt.Errorf("offset %d isn't null terminated", offset) - } - - return string(str[:end]), nil -} diff --git a/vendor/github.com/cilium/ebpf/internal/btf/syscalls.go b/vendor/github.com/cilium/ebpf/internal/btf/syscalls.go deleted file mode 100644 index a4f80abd01..0000000000 --- a/vendor/github.com/cilium/ebpf/internal/btf/syscalls.go +++ /dev/null @@ -1,31 +0,0 @@ -package btf - -import ( - "fmt" - "unsafe" - - "github.com/cilium/ebpf/internal" -) - -type bpfBTFInfo struct { - btf internal.Pointer - btfSize uint32 - id uint32 - name internal.Pointer - nameLen uint32 - kernelBTF uint32 -} - -func bpfGetBTFInfoByFD(fd *internal.FD, btf, name []byte) (*bpfBTFInfo, error) { - info := bpfBTFInfo{ - btf: internal.NewSlicePointer(btf), - btfSize: uint32(len(btf)), - name: internal.NewSlicePointer(name), - nameLen: uint32(len(name)), - } - if err := internal.BPFObjGetInfoByFD(fd, unsafe.Pointer(&info), unsafe.Sizeof(info)); err != nil { - return nil, fmt.Errorf("can't get program info: %w", err) - } - - return &info, nil -} diff --git a/vendor/github.com/cilium/ebpf/internal/btf/types.go b/vendor/github.com/cilium/ebpf/internal/btf/types.go deleted file mode 100644 index 5c8e7c6e59..0000000000 --- a/vendor/github.com/cilium/ebpf/internal/btf/types.go +++ /dev/null @@ -1,957 +0,0 @@ -package btf - -import ( - "fmt" - "math" - "strings" -) - -const maxTypeDepth = 32 - -// TypeID identifies a type in a BTF section. -type TypeID uint32 - -// ID implements part of the Type interface. -func (tid TypeID) ID() TypeID { - return tid -} - -// Type represents a type described by BTF. -type Type interface { - ID() TypeID - - String() string - - // Make a copy of the type, without copying Type members. - copy() Type - - // Enumerate all nested Types. Repeated calls must visit nested - // types in the same order. - walk(*typeDeque) -} - -// NamedType is a type with a name. -type NamedType interface { - Type - - // Name of the type, empty for anonymous types. - TypeName() string -} - -var ( - _ NamedType = (*Int)(nil) - _ NamedType = (*Struct)(nil) - _ NamedType = (*Union)(nil) - _ NamedType = (*Enum)(nil) - _ NamedType = (*Fwd)(nil) - _ NamedType = (*Func)(nil) - _ NamedType = (*Typedef)(nil) - _ NamedType = (*Var)(nil) - _ NamedType = (*Datasec)(nil) - _ NamedType = (*Float)(nil) -) - -// Void is the unit type of BTF. -type Void struct{} - -func (v *Void) ID() TypeID { return 0 } -func (v *Void) String() string { return "void#0" } -func (v *Void) size() uint32 { return 0 } -func (v *Void) copy() Type { return (*Void)(nil) } -func (v *Void) walk(*typeDeque) {} - -type IntEncoding byte - -const ( - Signed IntEncoding = 1 << iota - Char - Bool -) - -// Int is an integer of a given length. -type Int struct { - TypeID - Name string - - // The size of the integer in bytes. - Size uint32 - Encoding IntEncoding - // OffsetBits is the starting bit offset. Currently always 0. - // See https://www.kernel.org/doc/html/latest/bpf/btf.html#btf-kind-int - OffsetBits uint32 - Bits byte -} - -func (i *Int) String() string { - var s strings.Builder - - switch { - case i.Encoding&Char != 0: - s.WriteString("char") - case i.Encoding&Bool != 0: - s.WriteString("bool") - default: - if i.Encoding&Signed == 0 { - s.WriteRune('u') - } - s.WriteString("int") - fmt.Fprintf(&s, "%d", i.Size*8) - } - - fmt.Fprintf(&s, "#%d", i.TypeID) - - if i.Bits > 0 { - fmt.Fprintf(&s, "[bits=%d]", i.Bits) - } - - return s.String() -} - -func (i *Int) TypeName() string { return i.Name } -func (i *Int) size() uint32 { return i.Size } -func (i *Int) walk(*typeDeque) {} -func (i *Int) copy() Type { - cpy := *i - return &cpy -} - -func (i *Int) isBitfield() bool { - return i.OffsetBits > 0 -} - -// Pointer is a pointer to another type. -type Pointer struct { - TypeID - Target Type -} - -func (p *Pointer) String() string { - return fmt.Sprintf("pointer#%d[target=#%d]", p.TypeID, p.Target.ID()) -} - -func (p *Pointer) size() uint32 { return 8 } -func (p *Pointer) walk(tdq *typeDeque) { tdq.push(&p.Target) } -func (p *Pointer) copy() Type { - cpy := *p - return &cpy -} - -// Array is an array with a fixed number of elements. -type Array struct { - TypeID - Type Type - Nelems uint32 -} - -func (arr *Array) String() string { - return fmt.Sprintf("array#%d[type=#%d n=%d]", arr.TypeID, arr.Type.ID(), arr.Nelems) -} - -func (arr *Array) walk(tdq *typeDeque) { tdq.push(&arr.Type) } -func (arr *Array) copy() Type { - cpy := *arr - return &cpy -} - -// Struct is a compound type of consecutive members. -type Struct struct { - TypeID - Name string - // The size of the struct including padding, in bytes - Size uint32 - Members []Member -} - -func (s *Struct) String() string { - return fmt.Sprintf("struct#%d[%q]", s.TypeID, s.Name) -} - -func (s *Struct) TypeName() string { return s.Name } - -func (s *Struct) size() uint32 { return s.Size } - -func (s *Struct) walk(tdq *typeDeque) { - for i := range s.Members { - tdq.push(&s.Members[i].Type) - } -} - -func (s *Struct) copy() Type { - cpy := *s - cpy.Members = copyMembers(s.Members) - return &cpy -} - -func (s *Struct) members() []Member { - return s.Members -} - -// Union is a compound type where members occupy the same memory. -type Union struct { - TypeID - Name string - // The size of the union including padding, in bytes. - Size uint32 - Members []Member -} - -func (u *Union) String() string { - return fmt.Sprintf("union#%d[%q]", u.TypeID, u.Name) -} - -func (u *Union) TypeName() string { return u.Name } - -func (u *Union) size() uint32 { return u.Size } - -func (u *Union) walk(tdq *typeDeque) { - for i := range u.Members { - tdq.push(&u.Members[i].Type) - } -} - -func (u *Union) copy() Type { - cpy := *u - cpy.Members = copyMembers(u.Members) - return &cpy -} - -func (u *Union) members() []Member { - return u.Members -} - -func copyMembers(orig []Member) []Member { - cpy := make([]Member, len(orig)) - copy(cpy, orig) - return cpy -} - -type composite interface { - members() []Member -} - -var ( - _ composite = (*Struct)(nil) - _ composite = (*Union)(nil) -) - -// Member is part of a Struct or Union. -// -// It is not a valid Type. -type Member struct { - Name string - Type Type - // OffsetBits is the bit offset of this member. - OffsetBits uint32 - BitfieldSize uint32 -} - -// Enum lists possible values. -type Enum struct { - TypeID - Name string - Values []EnumValue -} - -func (e *Enum) String() string { - return fmt.Sprintf("enum#%d[%q]", e.TypeID, e.Name) -} - -func (e *Enum) TypeName() string { return e.Name } - -// EnumValue is part of an Enum -// -// Is is not a valid Type -type EnumValue struct { - Name string - Value int32 -} - -func (e *Enum) size() uint32 { return 4 } -func (e *Enum) walk(*typeDeque) {} -func (e *Enum) copy() Type { - cpy := *e - cpy.Values = make([]EnumValue, len(e.Values)) - copy(cpy.Values, e.Values) - return &cpy -} - -// FwdKind is the type of forward declaration. -type FwdKind int - -// Valid types of forward declaration. -const ( - FwdStruct FwdKind = iota - FwdUnion -) - -func (fk FwdKind) String() string { - switch fk { - case FwdStruct: - return "struct" - case FwdUnion: - return "union" - default: - return fmt.Sprintf("%T(%d)", fk, int(fk)) - } -} - -// Fwd is a forward declaration of a Type. -type Fwd struct { - TypeID - Name string - Kind FwdKind -} - -func (f *Fwd) String() string { - return fmt.Sprintf("fwd#%d[%s %q]", f.TypeID, f.Kind, f.Name) -} - -func (f *Fwd) TypeName() string { return f.Name } - -func (f *Fwd) walk(*typeDeque) {} -func (f *Fwd) copy() Type { - cpy := *f - return &cpy -} - -// Typedef is an alias of a Type. -type Typedef struct { - TypeID - Name string - Type Type -} - -func (td *Typedef) String() string { - return fmt.Sprintf("typedef#%d[%q #%d]", td.TypeID, td.Name, td.Type.ID()) -} - -func (td *Typedef) TypeName() string { return td.Name } - -func (td *Typedef) walk(tdq *typeDeque) { tdq.push(&td.Type) } -func (td *Typedef) copy() Type { - cpy := *td - return &cpy -} - -// Volatile is a qualifier. -type Volatile struct { - TypeID - Type Type -} - -func (v *Volatile) String() string { - return fmt.Sprintf("volatile#%d[#%d]", v.TypeID, v.Type.ID()) -} - -func (v *Volatile) qualify() Type { return v.Type } -func (v *Volatile) walk(tdq *typeDeque) { tdq.push(&v.Type) } -func (v *Volatile) copy() Type { - cpy := *v - return &cpy -} - -// Const is a qualifier. -type Const struct { - TypeID - Type Type -} - -func (c *Const) String() string { - return fmt.Sprintf("const#%d[#%d]", c.TypeID, c.Type.ID()) -} - -func (c *Const) qualify() Type { return c.Type } -func (c *Const) walk(tdq *typeDeque) { tdq.push(&c.Type) } -func (c *Const) copy() Type { - cpy := *c - return &cpy -} - -// Restrict is a qualifier. -type Restrict struct { - TypeID - Type Type -} - -func (r *Restrict) String() string { - return fmt.Sprintf("restrict#%d[#%d]", r.TypeID, r.Type.ID()) -} - -func (r *Restrict) qualify() Type { return r.Type } -func (r *Restrict) walk(tdq *typeDeque) { tdq.push(&r.Type) } -func (r *Restrict) copy() Type { - cpy := *r - return &cpy -} - -// Func is a function definition. -type Func struct { - TypeID - Name string - Type Type - Linkage FuncLinkage -} - -func (f *Func) String() string { - return fmt.Sprintf("func#%d[%s %q proto=#%d]", f.TypeID, f.Linkage, f.Name, f.Type.ID()) -} - -func (f *Func) TypeName() string { return f.Name } - -func (f *Func) walk(tdq *typeDeque) { tdq.push(&f.Type) } -func (f *Func) copy() Type { - cpy := *f - return &cpy -} - -// FuncProto is a function declaration. -type FuncProto struct { - TypeID - Return Type - Params []FuncParam -} - -func (fp *FuncProto) String() string { - var s strings.Builder - fmt.Fprintf(&s, "proto#%d[", fp.TypeID) - for _, param := range fp.Params { - fmt.Fprintf(&s, "%q=#%d, ", param.Name, param.Type.ID()) - } - fmt.Fprintf(&s, "return=#%d]", fp.Return.ID()) - return s.String() -} - -func (fp *FuncProto) walk(tdq *typeDeque) { - tdq.push(&fp.Return) - for i := range fp.Params { - tdq.push(&fp.Params[i].Type) - } -} - -func (fp *FuncProto) copy() Type { - cpy := *fp - cpy.Params = make([]FuncParam, len(fp.Params)) - copy(cpy.Params, fp.Params) - return &cpy -} - -type FuncParam struct { - Name string - Type Type -} - -// Var is a global variable. -type Var struct { - TypeID - Name string - Type Type - Linkage VarLinkage -} - -func (v *Var) String() string { - return fmt.Sprintf("var#%d[%s %q]", v.TypeID, v.Linkage, v.Name) -} - -func (v *Var) TypeName() string { return v.Name } - -func (v *Var) walk(tdq *typeDeque) { tdq.push(&v.Type) } -func (v *Var) copy() Type { - cpy := *v - return &cpy -} - -// Datasec is a global program section containing data. -type Datasec struct { - TypeID - Name string - Size uint32 - Vars []VarSecinfo -} - -func (ds *Datasec) String() string { - return fmt.Sprintf("section#%d[%q]", ds.TypeID, ds.Name) -} - -func (ds *Datasec) TypeName() string { return ds.Name } - -func (ds *Datasec) size() uint32 { return ds.Size } - -func (ds *Datasec) walk(tdq *typeDeque) { - for i := range ds.Vars { - tdq.push(&ds.Vars[i].Type) - } -} - -func (ds *Datasec) copy() Type { - cpy := *ds - cpy.Vars = make([]VarSecinfo, len(ds.Vars)) - copy(cpy.Vars, ds.Vars) - return &cpy -} - -// VarSecinfo describes variable in a Datasec. -// -// It is not a valid Type. -type VarSecinfo struct { - Type Type - Offset uint32 - Size uint32 -} - -// Float is a float of a given length. -type Float struct { - TypeID - Name string - - // The size of the float in bytes. - Size uint32 -} - -func (f *Float) String() string { - return fmt.Sprintf("float%d#%d[%q]", f.Size*8, f.TypeID, f.Name) -} - -func (f *Float) TypeName() string { return f.Name } -func (f *Float) size() uint32 { return f.Size } -func (f *Float) walk(*typeDeque) {} -func (f *Float) copy() Type { - cpy := *f - return &cpy -} - -type sizer interface { - size() uint32 -} - -var ( - _ sizer = (*Int)(nil) - _ sizer = (*Pointer)(nil) - _ sizer = (*Struct)(nil) - _ sizer = (*Union)(nil) - _ sizer = (*Enum)(nil) - _ sizer = (*Datasec)(nil) -) - -type qualifier interface { - qualify() Type -} - -var ( - _ qualifier = (*Const)(nil) - _ qualifier = (*Restrict)(nil) - _ qualifier = (*Volatile)(nil) -) - -// Sizeof returns the size of a type in bytes. -// -// Returns an error if the size can't be computed. -func Sizeof(typ Type) (int, error) { - var ( - n = int64(1) - elem int64 - ) - - for i := 0; i < maxTypeDepth; i++ { - switch v := typ.(type) { - case *Array: - if n > 0 && int64(v.Nelems) > math.MaxInt64/n { - return 0, fmt.Errorf("type %s: overflow", typ) - } - - // Arrays may be of zero length, which allows - // n to be zero as well. - n *= int64(v.Nelems) - typ = v.Type - continue - - case sizer: - elem = int64(v.size()) - - case *Typedef: - typ = v.Type - continue - - case qualifier: - typ = v.qualify() - continue - - default: - return 0, fmt.Errorf("unsized type %T", typ) - } - - if n > 0 && elem > math.MaxInt64/n { - return 0, fmt.Errorf("type %s: overflow", typ) - } - - size := n * elem - if int64(int(size)) != size { - return 0, fmt.Errorf("type %s: overflow", typ) - } - - return int(size), nil - } - - return 0, fmt.Errorf("type %s: exceeded type depth", typ) -} - -// copy a Type recursively. -// -// typ may form a cycle. -// -// Returns any errors from transform verbatim. -func copyType(typ Type, transform func(Type) (Type, error)) (Type, error) { - copies := make(copier) - return typ, copies.copy(&typ, transform) -} - -// copy a slice of Types recursively. -// -// Types may form a cycle. -// -// Returns any errors from transform verbatim. -func copyTypes(types []Type, transform func(Type) (Type, error)) ([]Type, error) { - result := make([]Type, len(types)) - copy(result, types) - - copies := make(copier) - for i := range result { - if err := copies.copy(&result[i], transform); err != nil { - return nil, err - } - } - - return result, nil -} - -type copier map[Type]Type - -func (c copier) copy(typ *Type, transform func(Type) (Type, error)) error { - var work typeDeque - for t := typ; t != nil; t = work.pop() { - // *t is the identity of the type. - if cpy := c[*t]; cpy != nil { - *t = cpy - continue - } - - var cpy Type - if transform != nil { - tf, err := transform(*t) - if err != nil { - return fmt.Errorf("copy %s: %w", *t, err) - } - cpy = tf.copy() - } else { - cpy = (*t).copy() - } - - c[*t] = cpy - *t = cpy - - // Mark any nested types for copying. - cpy.walk(&work) - } - - return nil -} - -// typeDeque keeps track of pointers to types which still -// need to be visited. -type typeDeque struct { - types []*Type - read, write uint64 - mask uint64 -} - -func (dq *typeDeque) empty() bool { - return dq.read == dq.write -} - -// push adds a type to the stack. -func (dq *typeDeque) push(t *Type) { - if dq.write-dq.read < uint64(len(dq.types)) { - dq.types[dq.write&dq.mask] = t - dq.write++ - return - } - - new := len(dq.types) * 2 - if new == 0 { - new = 8 - } - - types := make([]*Type, new) - pivot := dq.read & dq.mask - n := copy(types, dq.types[pivot:]) - n += copy(types[n:], dq.types[:pivot]) - types[n] = t - - dq.types = types - dq.mask = uint64(new) - 1 - dq.read, dq.write = 0, uint64(n+1) -} - -// shift returns the first element or null. -func (dq *typeDeque) shift() *Type { - if dq.empty() { - return nil - } - - index := dq.read & dq.mask - t := dq.types[index] - dq.types[index] = nil - dq.read++ - return t -} - -// pop returns the last element or null. -func (dq *typeDeque) pop() *Type { - if dq.empty() { - return nil - } - - dq.write-- - index := dq.write & dq.mask - t := dq.types[index] - dq.types[index] = nil - return t -} - -// all returns all elements. -// -// The deque is empty after calling this method. -func (dq *typeDeque) all() []*Type { - length := dq.write - dq.read - types := make([]*Type, 0, length) - for t := dq.shift(); t != nil; t = dq.shift() { - types = append(types, t) - } - return types -} - -// inflateRawTypes takes a list of raw btf types linked via type IDs, and turns -// it into a graph of Types connected via pointers. -// -// Returns a map of named types (so, where NameOff is non-zero) and a slice of types -// indexed by TypeID. Since BTF ignores compilation units, multiple types may share -// the same name. A Type may form a cyclic graph by pointing at itself. -func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type, namedTypes map[string][]NamedType, err error) { - type fixupDef struct { - id TypeID - expectedKind btfKind - typ *Type - } - - var fixups []fixupDef - fixup := func(id TypeID, expectedKind btfKind, typ *Type) { - fixups = append(fixups, fixupDef{id, expectedKind, typ}) - } - - convertMembers := func(raw []btfMember, kindFlag bool) ([]Member, error) { - // NB: The fixup below relies on pre-allocating this array to - // work, since otherwise append might re-allocate members. - members := make([]Member, 0, len(raw)) - for i, btfMember := range raw { - name, err := rawStrings.Lookup(btfMember.NameOff) - if err != nil { - return nil, fmt.Errorf("can't get name for member %d: %w", i, err) - } - m := Member{ - Name: name, - OffsetBits: btfMember.Offset, - } - if kindFlag { - m.BitfieldSize = btfMember.Offset >> 24 - m.OffsetBits &= 0xffffff - } - members = append(members, m) - } - for i := range members { - fixup(raw[i].Type, kindUnknown, &members[i].Type) - } - return members, nil - } - - types = make([]Type, 0, len(rawTypes)) - types = append(types, (*Void)(nil)) - namedTypes = make(map[string][]NamedType) - - for i, raw := range rawTypes { - var ( - // Void is defined to always be type ID 0, and is thus - // omitted from BTF. - id = TypeID(i + 1) - typ Type - ) - - name, err := rawStrings.Lookup(raw.NameOff) - if err != nil { - return nil, nil, fmt.Errorf("get name for type id %d: %w", id, err) - } - - switch raw.Kind() { - case kindInt: - encoding, offset, bits := intEncoding(*raw.data.(*uint32)) - typ = &Int{id, name, raw.Size(), encoding, offset, bits} - - case kindPointer: - ptr := &Pointer{id, nil} - fixup(raw.Type(), kindUnknown, &ptr.Target) - typ = ptr - - case kindArray: - btfArr := raw.data.(*btfArray) - - // IndexType is unused according to btf.rst. - // Don't make it available right now. - arr := &Array{id, nil, btfArr.Nelems} - fixup(btfArr.Type, kindUnknown, &arr.Type) - typ = arr - - case kindStruct: - members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag()) - if err != nil { - return nil, nil, fmt.Errorf("struct %s (id %d): %w", name, id, err) - } - typ = &Struct{id, name, raw.Size(), members} - - case kindUnion: - members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag()) - if err != nil { - return nil, nil, fmt.Errorf("union %s (id %d): %w", name, id, err) - } - typ = &Union{id, name, raw.Size(), members} - - case kindEnum: - rawvals := raw.data.([]btfEnum) - vals := make([]EnumValue, 0, len(rawvals)) - for i, btfVal := range rawvals { - name, err := rawStrings.Lookup(btfVal.NameOff) - if err != nil { - return nil, nil, fmt.Errorf("get name for enum value %d: %s", i, err) - } - vals = append(vals, EnumValue{ - Name: name, - Value: btfVal.Val, - }) - } - typ = &Enum{id, name, vals} - - case kindForward: - if raw.KindFlag() { - typ = &Fwd{id, name, FwdUnion} - } else { - typ = &Fwd{id, name, FwdStruct} - } - - case kindTypedef: - typedef := &Typedef{id, name, nil} - fixup(raw.Type(), kindUnknown, &typedef.Type) - typ = typedef - - case kindVolatile: - volatile := &Volatile{id, nil} - fixup(raw.Type(), kindUnknown, &volatile.Type) - typ = volatile - - case kindConst: - cnst := &Const{id, nil} - fixup(raw.Type(), kindUnknown, &cnst.Type) - typ = cnst - - case kindRestrict: - restrict := &Restrict{id, nil} - fixup(raw.Type(), kindUnknown, &restrict.Type) - typ = restrict - - case kindFunc: - fn := &Func{id, name, nil, raw.Linkage()} - fixup(raw.Type(), kindFuncProto, &fn.Type) - typ = fn - - case kindFuncProto: - rawparams := raw.data.([]btfParam) - params := make([]FuncParam, 0, len(rawparams)) - for i, param := range rawparams { - name, err := rawStrings.Lookup(param.NameOff) - if err != nil { - return nil, nil, fmt.Errorf("get name for func proto parameter %d: %s", i, err) - } - params = append(params, FuncParam{ - Name: name, - }) - } - for i := range params { - fixup(rawparams[i].Type, kindUnknown, ¶ms[i].Type) - } - - fp := &FuncProto{id, nil, params} - fixup(raw.Type(), kindUnknown, &fp.Return) - typ = fp - - case kindVar: - variable := raw.data.(*btfVariable) - v := &Var{id, name, nil, VarLinkage(variable.Linkage)} - fixup(raw.Type(), kindUnknown, &v.Type) - typ = v - - case kindDatasec: - btfVars := raw.data.([]btfVarSecinfo) - vars := make([]VarSecinfo, 0, len(btfVars)) - for _, btfVar := range btfVars { - vars = append(vars, VarSecinfo{ - Offset: btfVar.Offset, - Size: btfVar.Size, - }) - } - for i := range vars { - fixup(btfVars[i].Type, kindVar, &vars[i].Type) - } - typ = &Datasec{id, name, raw.SizeType, vars} - - case kindFloat: - typ = &Float{id, name, raw.Size()} - - default: - return nil, nil, fmt.Errorf("type id %d: unknown kind: %v", id, raw.Kind()) - } - - types = append(types, typ) - - if named, ok := typ.(NamedType); ok { - if name := essentialName(named.TypeName()); name != "" { - namedTypes[name] = append(namedTypes[name], named) - } - } - } - - for _, fixup := range fixups { - i := int(fixup.id) - if i >= len(types) { - return nil, nil, fmt.Errorf("reference to invalid type id: %d", fixup.id) - } - - // Default void (id 0) to unknown - rawKind := kindUnknown - if i > 0 { - rawKind = rawTypes[i-1].Kind() - } - - if expected := fixup.expectedKind; expected != kindUnknown && rawKind != expected { - return nil, nil, fmt.Errorf("expected type id %d to have kind %s, found %s", fixup.id, expected, rawKind) - } - - *fixup.typ = types[i] - } - - return types, namedTypes, nil -} - -// essentialName returns name without a ___ suffix. -func essentialName(name string) string { - lastIdx := strings.LastIndex(name, "___") - if lastIdx > 0 { - return name[:lastIdx] - } - return name -} diff --git a/vendor/github.com/cilium/ebpf/internal/buffer.go b/vendor/github.com/cilium/ebpf/internal/buffer.go new file mode 100644 index 0000000000..81c6544330 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/buffer.go @@ -0,0 +1,31 @@ +package internal + +import ( + "bytes" + "sync" +) + +var bytesBufferPool = sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, +} + +// NewBuffer retrieves a [bytes.Buffer] from a pool an re-initialises it. +// +// The returned buffer should be passed to [PutBuffer]. +func NewBuffer(buf []byte) *bytes.Buffer { + wr := bytesBufferPool.Get().(*bytes.Buffer) + // Reinitialize the Buffer with a new backing slice since it is returned to + // the caller by wr.Bytes() below. Pooling is faster despite calling + // NewBuffer. The pooled alloc is still reused, it only needs to be zeroed. + *wr = *bytes.NewBuffer(buf) + return wr +} + +// PutBuffer releases a buffer to the pool. +func PutBuffer(buf *bytes.Buffer) { + // Release reference to the backing buffer. + *buf = *bytes.NewBuffer(nil) + bytesBufferPool.Put(buf) +} diff --git a/vendor/github.com/cilium/ebpf/internal/cpu.go b/vendor/github.com/cilium/ebpf/internal/cpu.go index 3affa1efb9..9e908b610b 100644 --- a/vendor/github.com/cilium/ebpf/internal/cpu.go +++ b/vendor/github.com/cilium/ebpf/internal/cpu.go @@ -4,24 +4,13 @@ import ( "fmt" "os" "strings" - "sync" ) -var sysCPU struct { - once sync.Once - err error - num int -} - // PossibleCPUs returns the max number of CPUs a system may possibly have // Logical CPU numbers must be of the form 0-n -func PossibleCPUs() (int, error) { - sysCPU.once.Do(func() { - sysCPU.num, sysCPU.err = parseCPUsFromFile("/sys/devices/system/cpu/possible") - }) - - return sysCPU.num, sysCPU.err -} +var PossibleCPUs = Memoize(func() (int, error) { + return parseCPUsFromFile("/sys/devices/system/cpu/possible") +}) func parseCPUsFromFile(path string) (int, error) { spec, err := os.ReadFile(path) diff --git a/vendor/github.com/cilium/ebpf/internal/deque.go b/vendor/github.com/cilium/ebpf/internal/deque.go new file mode 100644 index 0000000000..e3a3050215 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/deque.go @@ -0,0 +1,91 @@ +package internal + +import "math/bits" + +// Deque implements a double ended queue. +type Deque[T any] struct { + elems []T + read, write uint64 + mask uint64 +} + +// Reset clears the contents of the deque while retaining the backing buffer. +func (dq *Deque[T]) Reset() { + var zero T + + for i := dq.read; i < dq.write; i++ { + dq.elems[i&dq.mask] = zero + } + + dq.read, dq.write = 0, 0 +} + +func (dq *Deque[T]) Empty() bool { + return dq.read == dq.write +} + +// Push adds an element to the end. +func (dq *Deque[T]) Push(e T) { + dq.Grow(1) + dq.elems[dq.write&dq.mask] = e + dq.write++ +} + +// Shift returns the first element or the zero value. +func (dq *Deque[T]) Shift() T { + var zero T + + if dq.Empty() { + return zero + } + + index := dq.read & dq.mask + t := dq.elems[index] + dq.elems[index] = zero + dq.read++ + return t +} + +// Pop returns the last element or the zero value. +func (dq *Deque[T]) Pop() T { + var zero T + + if dq.Empty() { + return zero + } + + dq.write-- + index := dq.write & dq.mask + t := dq.elems[index] + dq.elems[index] = zero + return t +} + +// Grow the deque's capacity, if necessary, to guarantee space for another n +// elements. +func (dq *Deque[T]) Grow(n int) { + have := dq.write - dq.read + need := have + uint64(n) + if need < have { + panic("overflow") + } + if uint64(len(dq.elems)) >= need { + return + } + + // Round up to the new power of two which is at least 8. + // See https://jameshfisher.com/2018/03/30/round-up-power-2/ + capacity := 1 << (64 - bits.LeadingZeros64(need-1)) + if capacity < 8 { + capacity = 8 + } + + elems := make([]T, have, capacity) + pivot := dq.read & dq.mask + copied := copy(elems, dq.elems[pivot:]) + copy(elems[copied:], dq.elems[:pivot]) + + dq.elems = elems[:capacity] + dq.mask = uint64(capacity) - 1 + dq.read, dq.write = 0, have +} diff --git a/vendor/github.com/cilium/ebpf/internal/elf.go b/vendor/github.com/cilium/ebpf/internal/elf.go index 54a4313130..011581938d 100644 --- a/vendor/github.com/cilium/ebpf/internal/elf.go +++ b/vendor/github.com/cilium/ebpf/internal/elf.go @@ -35,6 +35,29 @@ func NewSafeELFFile(r io.ReaderAt) (safe *SafeELFFile, err error) { return &SafeELFFile{file}, nil } +// OpenSafeELFFile reads an ELF from a file. +// +// It works like NewSafeELFFile, with the exception that safe.Close will +// close the underlying file. +func OpenSafeELFFile(path string) (safe *SafeELFFile, err error) { + defer func() { + r := recover() + if r == nil { + return + } + + safe = nil + err = fmt.Errorf("reading ELF file panicked: %s", r) + }() + + file, err := elf.Open(path) + if err != nil { + return nil, err + } + + return &SafeELFFile{file}, nil +} + // Symbols is the safe version of elf.File.Symbols. func (se *SafeELFFile) Symbols() (syms []elf.Symbol, err error) { defer func() { @@ -66,3 +89,14 @@ func (se *SafeELFFile) DynamicSymbols() (syms []elf.Symbol, err error) { syms, err = se.File.DynamicSymbols() return } + +// SectionsByType returns all sections in the file with the specified section type. +func (se *SafeELFFile) SectionsByType(typ elf.SectionType) []*elf.Section { + sections := make([]*elf.Section, 0, 1) + for _, section := range se.Sections { + if section.Type == typ { + sections = append(sections, section) + } + } + return sections +} diff --git a/vendor/github.com/cilium/ebpf/internal/endian.go b/vendor/github.com/cilium/ebpf/internal/endian.go deleted file mode 100644 index 6ae99fcd5f..0000000000 --- a/vendor/github.com/cilium/ebpf/internal/endian.go +++ /dev/null @@ -1,29 +0,0 @@ -package internal - -import ( - "encoding/binary" - "unsafe" -) - -// NativeEndian is set to either binary.BigEndian or binary.LittleEndian, -// depending on the host's endianness. -var NativeEndian binary.ByteOrder - -// Clang is set to either "el" or "eb" depending on the host's endianness. -var ClangEndian string - -func init() { - if isBigEndian() { - NativeEndian = binary.BigEndian - ClangEndian = "eb" - } else { - NativeEndian = binary.LittleEndian - ClangEndian = "el" - } -} - -func isBigEndian() (ret bool) { - i := int(0x1) - bs := (*[int(unsafe.Sizeof(i))]byte)(unsafe.Pointer(&i)) - return bs[0] == 0 -} diff --git a/vendor/github.com/cilium/ebpf/internal/endian_be.go b/vendor/github.com/cilium/ebpf/internal/endian_be.go new file mode 100644 index 0000000000..96a2ac0de2 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/endian_be.go @@ -0,0 +1,12 @@ +//go:build armbe || arm64be || mips || mips64 || mips64p32 || ppc64 || s390 || s390x || sparc || sparc64 + +package internal + +import "encoding/binary" + +// NativeEndian is set to either binary.BigEndian or binary.LittleEndian, +// depending on the host's endianness. +var NativeEndian binary.ByteOrder = binary.BigEndian + +// ClangEndian is set to either "el" or "eb" depending on the host's endianness. +const ClangEndian = "eb" diff --git a/vendor/github.com/cilium/ebpf/internal/endian_le.go b/vendor/github.com/cilium/ebpf/internal/endian_le.go new file mode 100644 index 0000000000..fde4c55a6f --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/endian_le.go @@ -0,0 +1,12 @@ +//go:build 386 || amd64 || amd64p32 || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || ppc64le || riscv64 + +package internal + +import "encoding/binary" + +// NativeEndian is set to either binary.BigEndian or binary.LittleEndian, +// depending on the host's endianness. +var NativeEndian binary.ByteOrder = binary.LittleEndian + +// ClangEndian is set to either "el" or "eb" depending on the host's endianness. +const ClangEndian = "el" diff --git a/vendor/github.com/cilium/ebpf/internal/epoll/poller.go b/vendor/github.com/cilium/ebpf/internal/epoll/poller.go new file mode 100644 index 0000000000..48d9c1f735 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/epoll/poller.go @@ -0,0 +1,225 @@ +package epoll + +import ( + "fmt" + "math" + "os" + "runtime" + "sync" + "time" + + "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/unix" +) + +// Poller waits for readiness notifications from multiple file descriptors. +// +// The wait can be interrupted by calling Close. +type Poller struct { + // mutexes protect the fields declared below them. If you need to + // acquire both at once you must lock epollMu before eventMu. + epollMu sync.Mutex + epollFd int + + eventMu sync.Mutex + event *eventFd +} + +func New() (*Poller, error) { + epollFd, err := unix.EpollCreate1(unix.EPOLL_CLOEXEC) + if err != nil { + return nil, fmt.Errorf("create epoll fd: %v", err) + } + + p := &Poller{epollFd: epollFd} + p.event, err = newEventFd() + if err != nil { + unix.Close(epollFd) + return nil, err + } + + if err := p.Add(p.event.raw, 0); err != nil { + unix.Close(epollFd) + p.event.close() + return nil, fmt.Errorf("add eventfd: %w", err) + } + + runtime.SetFinalizer(p, (*Poller).Close) + return p, nil +} + +// Close the poller. +// +// Interrupts any calls to Wait. Multiple calls to Close are valid, but subsequent +// calls will return os.ErrClosed. +func (p *Poller) Close() error { + runtime.SetFinalizer(p, nil) + + // Interrupt Wait() via the event fd if it's currently blocked. + if err := p.wakeWait(); err != nil { + return err + } + + // Acquire the lock. This ensures that Wait isn't running. + p.epollMu.Lock() + defer p.epollMu.Unlock() + + // Prevent other calls to Close(). + p.eventMu.Lock() + defer p.eventMu.Unlock() + + if p.epollFd != -1 { + unix.Close(p.epollFd) + p.epollFd = -1 + } + + if p.event != nil { + p.event.close() + p.event = nil + } + + return nil +} + +// Add an fd to the poller. +// +// id is returned by Wait in the unix.EpollEvent.Pad field any may be zero. It +// must not exceed math.MaxInt32. +// +// Add is blocked by Wait. +func (p *Poller) Add(fd int, id int) error { + if int64(id) > math.MaxInt32 { + return fmt.Errorf("unsupported id: %d", id) + } + + p.epollMu.Lock() + defer p.epollMu.Unlock() + + if p.epollFd == -1 { + return fmt.Errorf("epoll add: %w", os.ErrClosed) + } + + // The representation of EpollEvent isn't entirely accurate. + // Pad is fully useable, not just padding. Hence we stuff the + // id in there, which allows us to identify the event later (e.g., + // in case of perf events, which CPU sent it). + event := unix.EpollEvent{ + Events: unix.EPOLLIN, + Fd: int32(fd), + Pad: int32(id), + } + + if err := unix.EpollCtl(p.epollFd, unix.EPOLL_CTL_ADD, fd, &event); err != nil { + return fmt.Errorf("add fd to epoll: %v", err) + } + + return nil +} + +// Wait for events. +// +// Returns the number of pending events or an error wrapping os.ErrClosed if +// Close is called, or os.ErrDeadlineExceeded if EpollWait timeout. +func (p *Poller) Wait(events []unix.EpollEvent, deadline time.Time) (int, error) { + p.epollMu.Lock() + defer p.epollMu.Unlock() + + if p.epollFd == -1 { + return 0, fmt.Errorf("epoll wait: %w", os.ErrClosed) + } + + for { + timeout := int(-1) + if !deadline.IsZero() { + msec := time.Until(deadline).Milliseconds() + if msec < 0 { + // Deadline is in the past. + msec = 0 + } else if msec > math.MaxInt { + // Deadline is too far in the future. + msec = math.MaxInt + } + timeout = int(msec) + } + + n, err := unix.EpollWait(p.epollFd, events, timeout) + if temp, ok := err.(temporaryError); ok && temp.Temporary() { + // Retry the syscall if we were interrupted, see https://github.com/golang/go/issues/20400 + continue + } + + if err != nil { + return 0, err + } + + if n == 0 { + return 0, fmt.Errorf("epoll wait: %w", os.ErrDeadlineExceeded) + } + + for _, event := range events[:n] { + if int(event.Fd) == p.event.raw { + // Since we don't read p.event the event is never cleared and + // we'll keep getting this wakeup until Close() acquires the + // lock and sets p.epollFd = -1. + return 0, fmt.Errorf("epoll wait: %w", os.ErrClosed) + } + } + + return n, nil + } +} + +type temporaryError interface { + Temporary() bool +} + +// wakeWait unblocks Wait if it's epoll_wait. +func (p *Poller) wakeWait() error { + p.eventMu.Lock() + defer p.eventMu.Unlock() + + if p.event == nil { + return fmt.Errorf("epoll wake: %w", os.ErrClosed) + } + + return p.event.add(1) +} + +// eventFd wraps a Linux eventfd. +// +// An eventfd acts like a counter: writes add to the counter, reads retrieve +// the counter and reset it to zero. Reads also block if the counter is zero. +// +// See man 2 eventfd. +type eventFd struct { + file *os.File + // prefer raw over file.Fd(), since the latter puts the file into blocking + // mode. + raw int +} + +func newEventFd() (*eventFd, error) { + fd, err := unix.Eventfd(0, unix.O_CLOEXEC|unix.O_NONBLOCK) + if err != nil { + return nil, err + } + file := os.NewFile(uintptr(fd), "event") + return &eventFd{file, fd}, nil +} + +func (efd *eventFd) close() error { + return efd.file.Close() +} + +func (efd *eventFd) add(n uint64) error { + var buf [8]byte + internal.NativeEndian.PutUint64(buf[:], 1) + _, err := efd.file.Write(buf[:]) + return err +} + +func (efd *eventFd) read() (uint64, error) { + var buf [8]byte + _, err := efd.file.Read(buf[:]) + return internal.NativeEndian.Uint64(buf[:]), err +} diff --git a/vendor/github.com/cilium/ebpf/internal/errors.go b/vendor/github.com/cilium/ebpf/internal/errors.go index 877bd72ee2..bda01e2fde 100644 --- a/vendor/github.com/cilium/ebpf/internal/errors.go +++ b/vendor/github.com/cilium/ebpf/internal/errors.go @@ -2,50 +2,197 @@ package internal import ( "bytes" - "errors" "fmt" + "io" "strings" - - "github.com/cilium/ebpf/internal/unix" ) -// ErrorWithLog returns an error that includes logs from the -// kernel verifier. +// ErrorWithLog wraps err in a VerifierError that includes the parsed verifier +// log buffer. // -// logErr should be the error returned by the syscall that generated -// the log. It is used to check for truncation of the output. -func ErrorWithLog(err error, log []byte, logErr error) error { - logStr := strings.Trim(CString(log), "\t\r\n ") - if errors.Is(logErr, unix.ENOSPC) { - logStr += " (truncated...)" +// The default error output is a summary of the full log. The latter can be +// accessed via VerifierError.Log or by formatting the error, see Format. +func ErrorWithLog(source string, err error, log []byte, truncated bool) *VerifierError { + const whitespace = "\t\r\v\n " + + // Convert verifier log C string by truncating it on the first 0 byte + // and trimming trailing whitespace before interpreting as a Go string. + if i := bytes.IndexByte(log, 0); i != -1 { + log = log[:i] + } + + log = bytes.Trim(log, whitespace) + if len(log) == 0 { + return &VerifierError{source, err, nil, truncated} + } + + logLines := bytes.Split(log, []byte{'\n'}) + lines := make([]string, 0, len(logLines)) + for _, line := range logLines { + // Don't remove leading white space on individual lines. We rely on it + // when outputting logs. + lines = append(lines, string(bytes.TrimRight(line, whitespace))) } - return &VerifierError{err, logStr} + return &VerifierError{source, err, lines, truncated} } // VerifierError includes information from the eBPF verifier. +// +// It summarises the log output, see Format if you want to output the full contents. type VerifierError struct { - cause error - log string + source string + // The error which caused this error. + Cause error + // The verifier output split into lines. + Log []string + // Whether the log output is truncated, based on several heuristics. + Truncated bool } func (le *VerifierError) Unwrap() error { - return le.cause + return le.Cause } func (le *VerifierError) Error() string { - if le.log == "" { - return le.cause.Error() + log := le.Log + if n := len(log); n > 0 && strings.HasPrefix(log[n-1], "processed ") { + // Get rid of "processed 39 insns (limit 1000000) ..." from summary. + log = log[:n-1] + } + + var b strings.Builder + fmt.Fprintf(&b, "%s: %s", le.source, le.Cause.Error()) + + n := len(log) + if n == 0 { + return b.String() + } + + lines := log[n-1:] + if n >= 2 && (includePreviousLine(log[n-1]) || le.Truncated) { + // Add one more line of context if it aids understanding the error. + lines = log[n-2:] + } + + for _, line := range lines { + b.WriteString(": ") + b.WriteString(strings.TrimSpace(line)) + } + + omitted := len(le.Log) - len(lines) + if omitted == 0 && !le.Truncated { + return b.String() + } + + b.WriteString(" (") + if le.Truncated { + b.WriteString("truncated") + } + + if omitted > 0 { + if le.Truncated { + b.WriteString(", ") + } + fmt.Fprintf(&b, "%d line(s) omitted", omitted) + } + b.WriteString(")") + + return b.String() +} + +// includePreviousLine returns true if the given line likely is better +// understood with additional context from the preceding line. +func includePreviousLine(line string) bool { + // We need to find a good trade off between understandable error messages + // and too much complexity here. Checking the string prefix is ok, requiring + // regular expressions to do it is probably overkill. + + if strings.HasPrefix(line, "\t") { + // [13] STRUCT drm_rect size=16 vlen=4 + // \tx1 type_id=2 + return true + } + + if len(line) >= 2 && line[0] == 'R' && line[1] >= '0' && line[1] <= '9' { + // 0: (95) exit + // R0 !read_ok + return true } - return fmt.Sprintf("%s: %s", le.cause, le.log) + if strings.HasPrefix(line, "invalid bpf_context access") { + // 0: (79) r6 = *(u64 *)(r1 +0) + // func '__x64_sys_recvfrom' arg0 type FWD is not a struct + // invalid bpf_context access off=0 size=8 + return true + } + + return false } -// CString turns a NUL / zero terminated byte buffer into a string. -func CString(in []byte) string { - inLen := bytes.IndexByte(in, 0) - if inLen == -1 { - return "" +// Format the error. +// +// Understood verbs are %s and %v, which are equivalent to calling Error(). %v +// allows outputting additional information using the following flags: +// +// %+v: Output the first lines, or all lines if no width is given. +// %-v: Output the last lines, or all lines if no width is given. +// +// Use width to specify how many lines to output. Use the '-' flag to output +// lines from the end of the log instead of the beginning. +func (le *VerifierError) Format(f fmt.State, verb rune) { + switch verb { + case 's': + _, _ = io.WriteString(f, le.Error()) + + case 'v': + n, haveWidth := f.Width() + if !haveWidth || n > len(le.Log) { + n = len(le.Log) + } + + if !f.Flag('+') && !f.Flag('-') { + if haveWidth { + _, _ = io.WriteString(f, "%!v(BADWIDTH)") + return + } + + _, _ = io.WriteString(f, le.Error()) + return + } + + if f.Flag('+') && f.Flag('-') { + _, _ = io.WriteString(f, "%!v(BADFLAG)") + return + } + + fmt.Fprintf(f, "%s: %s:", le.source, le.Cause.Error()) + + omitted := len(le.Log) - n + lines := le.Log[:n] + if f.Flag('-') { + // Print last instead of first lines. + lines = le.Log[len(le.Log)-n:] + if omitted > 0 { + fmt.Fprintf(f, "\n\t(%d line(s) omitted)", omitted) + } + } + + for _, line := range lines { + fmt.Fprintf(f, "\n\t%s", line) + } + + if !f.Flag('-') { + if omitted > 0 { + fmt.Fprintf(f, "\n\t(%d line(s) omitted)", omitted) + } + } + + if le.Truncated { + fmt.Fprintf(f, "\n\t(truncated)") + } + + default: + fmt.Fprintf(f, "%%!%c(BADVERB)", verb) } - return string(in[:inLen]) } diff --git a/vendor/github.com/cilium/ebpf/internal/fd.go b/vendor/github.com/cilium/ebpf/internal/fd.go deleted file mode 100644 index af04955bd5..0000000000 --- a/vendor/github.com/cilium/ebpf/internal/fd.go +++ /dev/null @@ -1,69 +0,0 @@ -package internal - -import ( - "errors" - "fmt" - "os" - "runtime" - "strconv" - - "github.com/cilium/ebpf/internal/unix" -) - -var ErrClosedFd = errors.New("use of closed file descriptor") - -type FD struct { - raw int64 -} - -func NewFD(value uint32) *FD { - fd := &FD{int64(value)} - runtime.SetFinalizer(fd, (*FD).Close) - return fd -} - -func (fd *FD) String() string { - return strconv.FormatInt(fd.raw, 10) -} - -func (fd *FD) Value() (uint32, error) { - if fd.raw < 0 { - return 0, ErrClosedFd - } - - return uint32(fd.raw), nil -} - -func (fd *FD) Close() error { - if fd.raw < 0 { - return nil - } - - value := int(fd.raw) - fd.raw = -1 - - fd.Forget() - return unix.Close(value) -} - -func (fd *FD) Forget() { - runtime.SetFinalizer(fd, nil) -} - -func (fd *FD) Dup() (*FD, error) { - if fd.raw < 0 { - return nil, ErrClosedFd - } - - dup, err := unix.FcntlInt(uintptr(fd.raw), unix.F_DUPFD_CLOEXEC, 0) - if err != nil { - return nil, fmt.Errorf("can't dup fd: %v", err) - } - - return NewFD(uint32(dup)), nil -} - -func (fd *FD) File(name string) *os.File { - fd.Forget() - return os.NewFile(uintptr(fd.raw), name) -} diff --git a/vendor/github.com/cilium/ebpf/internal/feature.go b/vendor/github.com/cilium/ebpf/internal/feature.go index c94a2e1ee0..b1f650751d 100644 --- a/vendor/github.com/cilium/ebpf/internal/feature.go +++ b/vendor/github.com/cilium/ebpf/internal/feature.go @@ -31,10 +31,20 @@ func (ufe *UnsupportedFeatureError) Is(target error) bool { return target == ErrNotSupported } -type featureTest struct { - sync.RWMutex - successful bool - result error +// FeatureTest caches the result of a [FeatureTestFn]. +// +// Fields should not be modified after creation. +type FeatureTest struct { + // The name of the feature being detected. + Name string + // Version in in the form Major.Minor[.Patch]. + Version string + // The feature test itself. + Fn FeatureTestFn + + mu sync.RWMutex + done bool + result error } // FeatureTestFn is used to determine whether the kernel supports @@ -42,59 +52,133 @@ type featureTest struct { // // The return values have the following semantics: // -// err == ErrNotSupported: the feature is not available -// err == nil: the feature is available -// err != nil: the test couldn't be executed +// err == ErrNotSupported: the feature is not available +// err == nil: the feature is available +// err != nil: the test couldn't be executed type FeatureTestFn func() error -// FeatureTest wraps a function so that it is run at most once. +// NewFeatureTest is a convenient way to create a single [FeatureTest]. +func NewFeatureTest(name, version string, fn FeatureTestFn) func() error { + ft := &FeatureTest{ + Name: name, + Version: version, + Fn: fn, + } + + return ft.execute +} + +// execute the feature test. // -// name should identify the tested feature, while version must be in the -// form Major.Minor[.Patch]. +// The result is cached if the test is conclusive. // -// Returns an error wrapping ErrNotSupported if the feature is not supported. -func FeatureTest(name, version string, fn FeatureTestFn) func() error { - v, err := NewVersion(version) - if err != nil { - return func() error { return err } +// See [FeatureTestFn] for the meaning of the returned error. +func (ft *FeatureTest) execute() error { + ft.mu.RLock() + result, done := ft.result, ft.done + ft.mu.RUnlock() + + if done { + return result } - ft := new(featureTest) - return func() error { - ft.RLock() - if ft.successful { - defer ft.RUnlock() - return ft.result - } - ft.RUnlock() - ft.Lock() - defer ft.Unlock() - // check one more time on the off - // chance that two go routines - // were able to call into the write - // lock - if ft.successful { - return ft.result - } - err := fn() - switch { - case errors.Is(err, ErrNotSupported): - ft.result = &UnsupportedFeatureError{ - MinimumVersion: v, - Name: name, - } - fallthrough + ft.mu.Lock() + defer ft.mu.Unlock() - case err == nil: - ft.successful = true + // The test may have been executed by another caller while we were + // waiting to acquire ft.mu. + if ft.done { + return ft.result + } + + err := ft.Fn() + if err == nil { + ft.done = true + return nil + } - default: - // We couldn't execute the feature test to a point - // where it could make a determination. - // Don't cache the result, just return it. - return fmt.Errorf("detect support for %s: %w", name, err) + if errors.Is(err, ErrNotSupported) { + var v Version + if ft.Version != "" { + v, err = NewVersion(ft.Version) + if err != nil { + return fmt.Errorf("feature %s: %w", ft.Name, err) + } + } + + ft.done = true + ft.result = &UnsupportedFeatureError{ + MinimumVersion: v, + Name: ft.Name, } return ft.result } + + // We couldn't execute the feature test to a point + // where it could make a determination. + // Don't cache the result, just return it. + return fmt.Errorf("detect support for %s: %w", ft.Name, err) +} + +// FeatureMatrix groups multiple related feature tests into a map. +// +// Useful when there is a small number of discrete features which are known +// at compile time. +// +// It must not be modified concurrently with calling [FeatureMatrix.Result]. +type FeatureMatrix[K comparable] map[K]*FeatureTest + +// Result returns the outcome of the feature test for the given key. +// +// It's safe to call this function concurrently. +func (fm FeatureMatrix[K]) Result(key K) error { + ft, ok := fm[key] + if !ok { + return fmt.Errorf("no feature probe for %v", key) + } + + return ft.execute() +} + +// FeatureCache caches a potentially unlimited number of feature probes. +// +// Useful when there is a high cardinality for a feature test. +type FeatureCache[K comparable] struct { + mu sync.RWMutex + newTest func(K) *FeatureTest + features map[K]*FeatureTest +} + +func NewFeatureCache[K comparable](newTest func(K) *FeatureTest) *FeatureCache[K] { + return &FeatureCache[K]{ + newTest: newTest, + features: make(map[K]*FeatureTest), + } +} + +func (fc *FeatureCache[K]) Result(key K) error { + // NB: Executing the feature test happens without fc.mu taken. + return fc.retrieve(key).execute() +} + +func (fc *FeatureCache[K]) retrieve(key K) *FeatureTest { + fc.mu.RLock() + ft := fc.features[key] + fc.mu.RUnlock() + + if ft != nil { + return ft + } + + fc.mu.Lock() + defer fc.mu.Unlock() + + if ft := fc.features[key]; ft != nil { + return ft + } + + ft = fc.newTest(key) + fc.features[key] = ft + return ft } diff --git a/vendor/github.com/cilium/ebpf/internal/io.go b/vendor/github.com/cilium/ebpf/internal/io.go index fa7402782d..1eaf4775ad 100644 --- a/vendor/github.com/cilium/ebpf/internal/io.go +++ b/vendor/github.com/cilium/ebpf/internal/io.go @@ -1,6 +1,39 @@ package internal -import "errors" +import ( + "bufio" + "bytes" + "compress/gzip" + "errors" + "fmt" + "io" + "os" + "path/filepath" + "sync" +) + +// NewBufferedSectionReader wraps an io.ReaderAt in an appropriately-sized +// buffered reader. It is a convenience function for reading subsections of +// ELF sections while minimizing the amount of read() syscalls made. +// +// Syscall overhead is non-negligible in continuous integration context +// where ELFs might be accessed over virtual filesystems with poor random +// access performance. Buffering reads makes sense because (sub)sections +// end up being read completely anyway. +// +// Use instead of the r.Seek() + io.LimitReader() pattern. +func NewBufferedSectionReader(ra io.ReaderAt, off, n int64) *bufio.Reader { + // Clamp the size of the buffer to one page to avoid slurping large parts + // of a file into memory. bufio.NewReader uses a hardcoded default buffer + // of 4096. Allow arches with larger pages to allocate more, but don't + // allocate a fixed 4k buffer if we only need to read a small segment. + buf := n + if ps := int64(os.Getpagesize()); n > ps { + buf = ps + } + + return bufio.NewReaderSize(io.NewSectionReader(ra, off, n), int(buf)) +} // DiscardZeroes makes sure that all written bytes are zero // before discarding them. @@ -14,3 +47,82 @@ func (DiscardZeroes) Write(p []byte) (int, error) { } return len(p), nil } + +// ReadAllCompressed decompresses a gzipped file into memory. +func ReadAllCompressed(file string) ([]byte, error) { + fh, err := os.Open(file) + if err != nil { + return nil, err + } + defer fh.Close() + + gz, err := gzip.NewReader(fh) + if err != nil { + return nil, err + } + defer gz.Close() + + return io.ReadAll(gz) +} + +// ReadUint64FromFile reads a uint64 from a file. +// +// format specifies the contents of the file in fmt.Scanf syntax. +func ReadUint64FromFile(format string, path ...string) (uint64, error) { + filename := filepath.Join(path...) + data, err := os.ReadFile(filename) + if err != nil { + return 0, fmt.Errorf("reading file %q: %w", filename, err) + } + + var value uint64 + n, err := fmt.Fscanf(bytes.NewReader(data), format, &value) + if err != nil { + return 0, fmt.Errorf("parsing file %q: %w", filename, err) + } + if n != 1 { + return 0, fmt.Errorf("parsing file %q: expected 1 item, got %d", filename, n) + } + + return value, nil +} + +type uint64FromFileKey struct { + format, path string +} + +var uint64FromFileCache = struct { + sync.RWMutex + values map[uint64FromFileKey]uint64 +}{ + values: map[uint64FromFileKey]uint64{}, +} + +// ReadUint64FromFileOnce is like readUint64FromFile but memoizes the result. +func ReadUint64FromFileOnce(format string, path ...string) (uint64, error) { + filename := filepath.Join(path...) + key := uint64FromFileKey{format, filename} + + uint64FromFileCache.RLock() + if value, ok := uint64FromFileCache.values[key]; ok { + uint64FromFileCache.RUnlock() + return value, nil + } + uint64FromFileCache.RUnlock() + + value, err := ReadUint64FromFile(format, filename) + if err != nil { + return 0, err + } + + uint64FromFileCache.Lock() + defer uint64FromFileCache.Unlock() + + if value, ok := uint64FromFileCache.values[key]; ok { + // Someone else got here before us, use what is cached. + return value, nil + } + + uint64FromFileCache.values[key] = value + return value, nil +} diff --git a/vendor/github.com/cilium/ebpf/internal/kconfig/kconfig.go b/vendor/github.com/cilium/ebpf/internal/kconfig/kconfig.go new file mode 100644 index 0000000000..d95e7eb0e5 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/kconfig/kconfig.go @@ -0,0 +1,267 @@ +package kconfig + +import ( + "bufio" + "bytes" + "compress/gzip" + "fmt" + "io" + "math" + "os" + "strconv" + "strings" + + "github.com/cilium/ebpf/btf" + "github.com/cilium/ebpf/internal" +) + +// Find find a kconfig file on the host. +// It first reads from /boot/config- of the current running kernel and tries +// /proc/config.gz if nothing was found in /boot. +// If none of the file provide a kconfig, it returns an error. +func Find() (*os.File, error) { + kernelRelease, err := internal.KernelRelease() + if err != nil { + return nil, fmt.Errorf("cannot get kernel release: %w", err) + } + + path := "/boot/config-" + kernelRelease + f, err := os.Open(path) + if err == nil { + return f, nil + } + + f, err = os.Open("/proc/config.gz") + if err == nil { + return f, nil + } + + return nil, fmt.Errorf("neither %s nor /proc/config.gz provide a kconfig", path) +} + +// Parse parses the kconfig file for which a reader is given. +// All the CONFIG_* which are in filter and which are set set will be +// put in the returned map as key with their corresponding value as map value. +// If filter is nil, no filtering will occur. +// If the kconfig file is not valid, error will be returned. +func Parse(source io.ReaderAt, filter map[string]struct{}) (map[string]string, error) { + var r io.Reader + zr, err := gzip.NewReader(io.NewSectionReader(source, 0, math.MaxInt64)) + if err != nil { + r = io.NewSectionReader(source, 0, math.MaxInt64) + } else { + // Source is gzip compressed, transparently decompress. + r = zr + } + + ret := make(map[string]string, len(filter)) + + s := bufio.NewScanner(r) + + for s.Scan() { + line := s.Bytes() + err = processKconfigLine(line, ret, filter) + if err != nil { + return nil, fmt.Errorf("cannot parse line: %w", err) + } + + if filter != nil && len(ret) == len(filter) { + break + } + } + + if err := s.Err(); err != nil { + return nil, fmt.Errorf("cannot parse: %w", err) + } + + if zr != nil { + return ret, zr.Close() + } + + return ret, nil +} + +// Golang translation of libbpf bpf_object__process_kconfig_line(): +// https://github.com/libbpf/libbpf/blob/fbd60dbff51c870f5e80a17c4f2fd639eb80af90/src/libbpf.c#L1874 +// It does the same checks but does not put the data inside the BPF map. +func processKconfigLine(line []byte, m map[string]string, filter map[string]struct{}) error { + // Ignore empty lines and "# CONFIG_* is not set". + if !bytes.HasPrefix(line, []byte("CONFIG_")) { + return nil + } + + key, value, found := bytes.Cut(line, []byte{'='}) + if !found { + return fmt.Errorf("line %q does not contain separator '='", line) + } + + if len(value) == 0 { + return fmt.Errorf("line %q has no value", line) + } + + if filter != nil { + // NB: map[string(key)] gets special optimisation help from the compiler + // and doesn't allocate. Don't turn this into a variable. + _, ok := filter[string(key)] + if !ok { + return nil + } + } + + // This can seem odd, but libbpf only sets the value the first time the key is + // met: + // https://github.com/torvalds/linux/blob/0d85b27b0cc6/tools/lib/bpf/libbpf.c#L1906-L1908 + _, ok := m[string(key)] + if !ok { + m[string(key)] = string(value) + } + + return nil +} + +// PutValue translates the value given as parameter depending on the BTF +// type, the translated value is then written to the byte array. +func PutValue(data []byte, typ btf.Type, value string) error { + typ = btf.UnderlyingType(typ) + + switch value { + case "y", "n", "m": + return putValueTri(data, typ, value) + default: + if strings.HasPrefix(value, `"`) { + return putValueString(data, typ, value) + } + return putValueNumber(data, typ, value) + } +} + +// Golang translation of libbpf_tristate enum: +// https://github.com/libbpf/libbpf/blob/fbd60dbff51c870f5e80a17c4f2fd639eb80af90/src/bpf_helpers.h#L169 +type triState int + +const ( + TriNo triState = 0 + TriYes triState = 1 + TriModule triState = 2 +) + +func putValueTri(data []byte, typ btf.Type, value string) error { + switch v := typ.(type) { + case *btf.Int: + if v.Encoding != btf.Bool { + return fmt.Errorf("cannot add tri value, expected btf.Bool, got: %v", v.Encoding) + } + + if v.Size != 1 { + return fmt.Errorf("cannot add tri value, expected size of 1 byte, got: %d", v.Size) + } + + switch value { + case "y": + data[0] = 1 + case "n": + data[0] = 0 + default: + return fmt.Errorf("cannot use %q for btf.Bool", value) + } + case *btf.Enum: + if v.Name != "libbpf_tristate" { + return fmt.Errorf("cannot use enum %q, only libbpf_tristate is supported", v.Name) + } + + var tri triState + switch value { + case "y": + tri = TriYes + case "m": + tri = TriModule + case "n": + tri = TriNo + default: + return fmt.Errorf("value %q is not support for libbpf_tristate", value) + } + + internal.NativeEndian.PutUint64(data, uint64(tri)) + default: + return fmt.Errorf("cannot add number value, expected btf.Int or btf.Enum, got: %T", v) + } + + return nil +} + +func putValueString(data []byte, typ btf.Type, value string) error { + array, ok := typ.(*btf.Array) + if !ok { + return fmt.Errorf("cannot add string value, expected btf.Array, got %T", array) + } + + contentType, ok := btf.UnderlyingType(array.Type).(*btf.Int) + if !ok { + return fmt.Errorf("cannot add string value, expected array of btf.Int, got %T", contentType) + } + + // Any Int, which is not bool, of one byte could be used to store char: + // https://github.com/torvalds/linux/blob/1a5304fecee5/tools/lib/bpf/libbpf.c#L3637-L3638 + if contentType.Size != 1 && contentType.Encoding != btf.Bool { + return fmt.Errorf("cannot add string value, expected array of btf.Int of size 1, got array of btf.Int of size: %v", contentType.Size) + } + + if !strings.HasPrefix(value, `"`) || !strings.HasSuffix(value, `"`) { + return fmt.Errorf(`value %q must start and finish with '"'`, value) + } + + str := strings.Trim(value, `"`) + + // We need to trim string if the bpf array is smaller. + if uint32(len(str)) >= array.Nelems { + str = str[:array.Nelems] + } + + // Write the string content to .kconfig. + copy(data, str) + + return nil +} + +func putValueNumber(data []byte, typ btf.Type, value string) error { + integer, ok := typ.(*btf.Int) + if !ok { + return fmt.Errorf("cannot add number value, expected *btf.Int, got: %T", integer) + } + + size := integer.Size + sizeInBits := size * 8 + + var n uint64 + var err error + if integer.Encoding == btf.Signed { + parsed, e := strconv.ParseInt(value, 0, int(sizeInBits)) + + n = uint64(parsed) + err = e + } else { + parsed, e := strconv.ParseUint(value, 0, int(sizeInBits)) + + n = uint64(parsed) + err = e + } + + if err != nil { + return fmt.Errorf("cannot parse value: %w", err) + } + + switch size { + case 1: + data[0] = byte(n) + case 2: + internal.NativeEndian.PutUint16(data, uint16(n)) + case 4: + internal.NativeEndian.PutUint32(data, uint32(n)) + case 8: + internal.NativeEndian.PutUint64(data, uint64(n)) + default: + return fmt.Errorf("size (%d) is not valid, expected: 1, 2, 4 or 8", size) + } + + return nil +} diff --git a/vendor/github.com/cilium/ebpf/internal/memoize.go b/vendor/github.com/cilium/ebpf/internal/memoize.go new file mode 100644 index 0000000000..3de0a3fb95 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/memoize.go @@ -0,0 +1,26 @@ +package internal + +import ( + "sync" +) + +type memoizedFunc[T any] struct { + once sync.Once + fn func() (T, error) + result T + err error +} + +func (mf *memoizedFunc[T]) do() (T, error) { + mf.once.Do(func() { + mf.result, mf.err = mf.fn() + }) + return mf.result, mf.err +} + +// Memoize the result of a function call. +// +// fn is only ever called once, even if it returns an error. +func Memoize[T any](fn func() (T, error)) func() (T, error) { + return (&memoizedFunc[T]{fn: fn}).do +} diff --git a/vendor/github.com/cilium/ebpf/internal/output.go b/vendor/github.com/cilium/ebpf/internal/output.go new file mode 100644 index 0000000000..dd6e6cbafe --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/output.go @@ -0,0 +1,97 @@ +package internal + +import ( + "bytes" + "errors" + "go/format" + "go/scanner" + "io" + "reflect" + "strings" + "unicode" +) + +// Identifier turns a C style type or field name into an exportable Go equivalent. +func Identifier(str string) string { + prev := rune(-1) + return strings.Map(func(r rune) rune { + // See https://golang.org/ref/spec#Identifiers + switch { + case unicode.IsLetter(r): + if prev == -1 { + r = unicode.ToUpper(r) + } + + case r == '_': + switch { + // The previous rune was deleted, or we are at the + // beginning of the string. + case prev == -1: + fallthrough + + // The previous rune is a lower case letter or a digit. + case unicode.IsDigit(prev) || (unicode.IsLetter(prev) && unicode.IsLower(prev)): + // delete the current rune, and force the + // next character to be uppercased. + r = -1 + } + + case unicode.IsDigit(r): + + default: + // Delete the current rune. prev is unchanged. + return -1 + } + + prev = r + return r + }, str) +} + +// WriteFormatted outputs a formatted src into out. +// +// If formatting fails it returns an informative error message. +func WriteFormatted(src []byte, out io.Writer) error { + formatted, err := format.Source(src) + if err == nil { + _, err = out.Write(formatted) + return err + } + + var el scanner.ErrorList + if !errors.As(err, &el) { + return err + } + + var nel scanner.ErrorList + for _, err := range el { + if !err.Pos.IsValid() { + nel = append(nel, err) + continue + } + + buf := src[err.Pos.Offset:] + nl := bytes.IndexRune(buf, '\n') + if nl == -1 { + nel = append(nel, err) + continue + } + + err.Msg += ": " + string(buf[:nl]) + nel = append(nel, err) + } + + return nel +} + +// GoTypeName is like %T, but elides the package name. +// +// Pointers to a type are peeled off. +func GoTypeName(t any) string { + rT := reflect.TypeOf(t) + for rT.Kind() == reflect.Pointer { + rT = rT.Elem() + } + // Doesn't return the correct Name for generic types due to https://github.com/golang/go/issues/55924 + return rT.Name() +} diff --git a/vendor/github.com/cilium/ebpf/internal/pinning.go b/vendor/github.com/cilium/ebpf/internal/pinning.go index 5329b432d7..01d892f934 100644 --- a/vendor/github.com/cilium/ebpf/internal/pinning.go +++ b/vendor/github.com/cilium/ebpf/internal/pinning.go @@ -4,24 +4,42 @@ import ( "errors" "fmt" "os" + "path/filepath" + "runtime" + "github.com/cilium/ebpf/internal/sys" "github.com/cilium/ebpf/internal/unix" ) -func Pin(currentPath, newPath string, fd *FD) error { +func Pin(currentPath, newPath string, fd *sys.FD) error { if newPath == "" { return errors.New("given pinning path cannot be empty") } if currentPath == newPath { return nil } + + fsType, err := FSType(filepath.Dir(newPath)) + if err != nil { + return err + } + if fsType != unix.BPF_FS_MAGIC { + return fmt.Errorf("%s is not on a bpf filesystem", newPath) + } + + defer runtime.KeepAlive(fd) + if currentPath == "" { - return BPFObjPin(newPath, fd) + return sys.ObjPin(&sys.ObjPinAttr{ + Pathname: sys.NewStringPointer(newPath), + BpfFd: fd.Uint(), + }) } - var err error + // Renameat2 is used instead of os.Rename to disallow the new path replacing // an existing path. - if err = unix.Renameat2(unix.AT_FDCWD, currentPath, unix.AT_FDCWD, newPath, unix.RENAME_NOREPLACE); err == nil { + err = unix.Renameat2(unix.AT_FDCWD, currentPath, unix.AT_FDCWD, newPath, unix.RENAME_NOREPLACE) + if err == nil { // Object is now moved to the new pinning path. return nil } @@ -29,7 +47,10 @@ func Pin(currentPath, newPath string, fd *FD) error { return fmt.Errorf("unable to move pinned object to new path %v: %w", newPath, err) } // Internal state not in sync with the file system so let's fix it. - return BPFObjPin(newPath, fd) + return sys.ObjPin(&sys.ObjPinAttr{ + Pathname: sys.NewStringPointer(newPath), + BpfFd: fd.Uint(), + }) } func Unpin(pinnedPath string) error { diff --git a/vendor/github.com/cilium/ebpf/internal/platform.go b/vendor/github.com/cilium/ebpf/internal/platform.go new file mode 100644 index 0000000000..6e90f2ef71 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/platform.go @@ -0,0 +1,43 @@ +package internal + +import ( + "runtime" +) + +// PlatformPrefix returns the platform-dependent syscall wrapper prefix used by +// the linux kernel. +// +// Based on https://github.com/golang/go/blob/master/src/go/build/syslist.go +// and https://github.com/libbpf/libbpf/blob/master/src/libbpf.c#L10047 +func PlatformPrefix() string { + switch runtime.GOARCH { + case "386": + return "__ia32_" + case "amd64", "amd64p32": + return "__x64_" + + case "arm", "armbe": + return "__arm_" + case "arm64", "arm64be": + return "__arm64_" + + case "mips", "mipsle", "mips64", "mips64le", "mips64p32", "mips64p32le": + return "__mips_" + + case "s390": + return "__s390_" + case "s390x": + return "__s390x_" + + case "riscv", "riscv64": + return "__riscv_" + + case "ppc": + return "__powerpc_" + case "ppc64", "ppc64le": + return "__powerpc64_" + + default: + return "" + } +} diff --git a/vendor/github.com/cilium/ebpf/internal/prog.go b/vendor/github.com/cilium/ebpf/internal/prog.go new file mode 100644 index 0000000000..d629145b62 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/prog.go @@ -0,0 +1,11 @@ +package internal + +// EmptyBPFContext is the smallest-possible BPF input context to be used for +// invoking `Program.{Run,Benchmark,Test}`. +// +// Programs require a context input buffer of at least 15 bytes. Looking in +// net/bpf/test_run.c, bpf_test_init() requires that the input is at least +// ETH_HLEN (14) bytes. As of Linux commit fd18942 ("bpf: Don't redirect packets +// with invalid pkt_len"), it also requires the skb to be non-empty after +// removing the Layer 2 header. +var EmptyBPFContext = make([]byte, 15) diff --git a/vendor/github.com/cilium/ebpf/internal/ptr.go b/vendor/github.com/cilium/ebpf/internal/ptr.go deleted file mode 100644 index f295de72cf..0000000000 --- a/vendor/github.com/cilium/ebpf/internal/ptr.go +++ /dev/null @@ -1,31 +0,0 @@ -package internal - -import ( - "unsafe" - - "github.com/cilium/ebpf/internal/unix" -) - -// NewPointer creates a 64-bit pointer from an unsafe Pointer. -func NewPointer(ptr unsafe.Pointer) Pointer { - return Pointer{ptr: ptr} -} - -// NewSlicePointer creates a 64-bit pointer from a byte slice. -func NewSlicePointer(buf []byte) Pointer { - if len(buf) == 0 { - return Pointer{} - } - - return Pointer{ptr: unsafe.Pointer(&buf[0])} -} - -// NewStringPointer creates a 64-bit pointer from a string. -func NewStringPointer(str string) Pointer { - p, err := unix.BytePtrFromString(str) - if err != nil { - return Pointer{} - } - - return Pointer{ptr: unsafe.Pointer(p)} -} diff --git a/vendor/github.com/cilium/ebpf/internal/statfs.go b/vendor/github.com/cilium/ebpf/internal/statfs.go new file mode 100644 index 0000000000..44c02d676e --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/statfs.go @@ -0,0 +1,23 @@ +package internal + +import ( + "unsafe" + + "github.com/cilium/ebpf/internal/unix" +) + +func FSType(path string) (int64, error) { + var statfs unix.Statfs_t + if err := unix.Statfs(path, &statfs); err != nil { + return 0, err + } + + fsType := int64(statfs.Type) + if unsafe.Sizeof(statfs.Type) == 4 { + // We're on a 32 bit arch, where statfs.Type is int32. bpfFSType is a + // negative number when interpreted as int32 so we need to cast via + // uint32 to avoid sign extension. + fsType = int64(uint32(statfs.Type)) + } + return fsType, nil +} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/doc.go b/vendor/github.com/cilium/ebpf/internal/sys/doc.go new file mode 100644 index 0000000000..dfe174448e --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/sys/doc.go @@ -0,0 +1,6 @@ +// Package sys contains bindings for the BPF syscall. +package sys + +// Regenerate types.go by invoking go generate in the current directory. + +//go:generate go run github.com/cilium/ebpf/internal/cmd/gentypes ../../btf/testdata/vmlinux.btf.gz diff --git a/vendor/github.com/cilium/ebpf/internal/sys/fd.go b/vendor/github.com/cilium/ebpf/internal/sys/fd.go new file mode 100644 index 0000000000..941a56fb91 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/sys/fd.go @@ -0,0 +1,133 @@ +package sys + +import ( + "fmt" + "math" + "os" + "runtime" + "strconv" + + "github.com/cilium/ebpf/internal/unix" +) + +var ErrClosedFd = unix.EBADF + +type FD struct { + raw int +} + +func newFD(value int) *FD { + if onLeakFD != nil { + // Attempt to store the caller's stack for the given fd value. + // Panic if fds contains an existing stack for the fd. + old, exist := fds.LoadOrStore(value, callersFrames()) + if exist { + f := old.(*runtime.Frames) + panic(fmt.Sprintf("found existing stack for fd %d:\n%s", value, FormatFrames(f))) + } + } + + fd := &FD{value} + runtime.SetFinalizer(fd, (*FD).finalize) + return fd +} + +// finalize is set as the FD's runtime finalizer and +// sends a leak trace before calling FD.Close(). +func (fd *FD) finalize() { + if fd.raw < 0 { + return + } + + // Invoke the fd leak callback. Calls LoadAndDelete to guarantee the callback + // is invoked at most once for one sys.FD allocation, runtime.Frames can only + // be unwound once. + f, ok := fds.LoadAndDelete(fd.Int()) + if ok && onLeakFD != nil { + onLeakFD(f.(*runtime.Frames)) + } + + _ = fd.Close() +} + +// NewFD wraps a raw fd with a finalizer. +// +// You must not use the raw fd after calling this function, since the underlying +// file descriptor number may change. This is because the BPF UAPI assumes that +// zero is not a valid fd value. +func NewFD(value int) (*FD, error) { + if value < 0 { + return nil, fmt.Errorf("invalid fd %d", value) + } + + fd := newFD(value) + if value != 0 { + return fd, nil + } + + dup, err := fd.Dup() + _ = fd.Close() + return dup, err +} + +func (fd *FD) String() string { + return strconv.FormatInt(int64(fd.raw), 10) +} + +func (fd *FD) Int() int { + return fd.raw +} + +func (fd *FD) Uint() uint32 { + if fd.raw < 0 || int64(fd.raw) > math.MaxUint32 { + // Best effort: this is the number most likely to be an invalid file + // descriptor. It is equal to -1 (on two's complement arches). + return math.MaxUint32 + } + return uint32(fd.raw) +} + +func (fd *FD) Close() error { + if fd.raw < 0 { + return nil + } + + return unix.Close(fd.disown()) +} + +func (fd *FD) disown() int { + value := int(fd.raw) + fds.Delete(int(value)) + fd.raw = -1 + + runtime.SetFinalizer(fd, nil) + return value +} + +func (fd *FD) Dup() (*FD, error) { + if fd.raw < 0 { + return nil, ErrClosedFd + } + + // Always require the fd to be larger than zero: the BPF API treats the value + // as "no argument provided". + dup, err := unix.FcntlInt(uintptr(fd.raw), unix.F_DUPFD_CLOEXEC, 1) + if err != nil { + return nil, fmt.Errorf("can't dup fd: %v", err) + } + + return newFD(dup), nil +} + +// File takes ownership of FD and turns it into an [*os.File]. +// +// You must not use the FD after the call returns. +// +// Returns nil if the FD is not valid. +func (fd *FD) File(name string) *os.File { + if fd.raw < 0 { + return nil + } + + return os.NewFile(uintptr(fd.disown()), name) +} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/fd_trace.go b/vendor/github.com/cilium/ebpf/internal/sys/fd_trace.go new file mode 100644 index 0000000000..cd50dd1f64 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/sys/fd_trace.go @@ -0,0 +1,93 @@ +package sys + +import ( + "bytes" + "fmt" + "runtime" + "sync" +) + +// OnLeakFD controls tracing [FD] lifetime to detect resources that are not +// closed by Close(). +// +// If fn is not nil, tracing is enabled for all FDs created going forward. fn is +// invoked for all FDs that are closed by the garbage collector instead of an +// explicit Close() by a caller. Calling OnLeakFD twice with a non-nil fn +// (without disabling tracing in the meantime) will cause a panic. +// +// If fn is nil, tracing will be disabled. Any FDs that have not been closed are +// considered to be leaked, fn will be invoked for them, and the process will be +// terminated. +// +// fn will be invoked at most once for every unique sys.FD allocation since a +// runtime.Frames can only be unwound once. +func OnLeakFD(fn func(*runtime.Frames)) { + // Enable leak tracing if new fn is provided. + if fn != nil { + if onLeakFD != nil { + panic("OnLeakFD called twice with non-nil fn") + } + + onLeakFD = fn + return + } + + // fn is nil past this point. + + if onLeakFD == nil { + return + } + + // Call onLeakFD for all open fds. + if fs := flushFrames(); len(fs) != 0 { + for _, f := range fs { + onLeakFD(f) + } + } + + onLeakFD = nil +} + +var onLeakFD func(*runtime.Frames) + +// fds is a registry of all file descriptors wrapped into sys.fds that were +// created while an fd tracer was active. +var fds sync.Map // map[int]*runtime.Frames + +// flushFrames removes all elements from fds and returns them as a slice. This +// deals with the fact that a runtime.Frames can only be unwound once using +// Next(). +func flushFrames() []*runtime.Frames { + var frames []*runtime.Frames + fds.Range(func(key, value any) bool { + frames = append(frames, value.(*runtime.Frames)) + fds.Delete(key) + return true + }) + return frames +} + +func callersFrames() *runtime.Frames { + c := make([]uintptr, 32) + + // Skip runtime.Callers and this function. + i := runtime.Callers(2, c) + if i == 0 { + return nil + } + + return runtime.CallersFrames(c) +} + +// FormatFrames formats a runtime.Frames as a human-readable string. +func FormatFrames(fs *runtime.Frames) string { + var b bytes.Buffer + for { + f, more := fs.Next() + b.WriteString(fmt.Sprintf("\t%s+%#x\n\t\t%s:%d\n", f.Function, f.PC-f.Entry, f.File, f.Line)) + if !more { + break + } + } + return b.String() +} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/mapflags_string.go b/vendor/github.com/cilium/ebpf/internal/sys/mapflags_string.go new file mode 100644 index 0000000000..c80744ae0e --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/sys/mapflags_string.go @@ -0,0 +1,49 @@ +// Code generated by "stringer -type MapFlags"; DO NOT EDIT. + +package sys + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[BPF_F_NO_PREALLOC-1] + _ = x[BPF_F_NO_COMMON_LRU-2] + _ = x[BPF_F_NUMA_NODE-4] + _ = x[BPF_F_RDONLY-8] + _ = x[BPF_F_WRONLY-16] + _ = x[BPF_F_STACK_BUILD_ID-32] + _ = x[BPF_F_ZERO_SEED-64] + _ = x[BPF_F_RDONLY_PROG-128] + _ = x[BPF_F_WRONLY_PROG-256] + _ = x[BPF_F_CLONE-512] + _ = x[BPF_F_MMAPABLE-1024] + _ = x[BPF_F_PRESERVE_ELEMS-2048] + _ = x[BPF_F_INNER_MAP-4096] +} + +const _MapFlags_name = "BPF_F_NO_PREALLOCBPF_F_NO_COMMON_LRUBPF_F_NUMA_NODEBPF_F_RDONLYBPF_F_WRONLYBPF_F_STACK_BUILD_IDBPF_F_ZERO_SEEDBPF_F_RDONLY_PROGBPF_F_WRONLY_PROGBPF_F_CLONEBPF_F_MMAPABLEBPF_F_PRESERVE_ELEMSBPF_F_INNER_MAP" + +var _MapFlags_map = map[MapFlags]string{ + 1: _MapFlags_name[0:17], + 2: _MapFlags_name[17:36], + 4: _MapFlags_name[36:51], + 8: _MapFlags_name[51:63], + 16: _MapFlags_name[63:75], + 32: _MapFlags_name[75:95], + 64: _MapFlags_name[95:110], + 128: _MapFlags_name[110:127], + 256: _MapFlags_name[127:144], + 512: _MapFlags_name[144:155], + 1024: _MapFlags_name[155:169], + 2048: _MapFlags_name[169:189], + 4096: _MapFlags_name[189:204], +} + +func (i MapFlags) String() string { + if str, ok := _MapFlags_map[i]; ok { + return str + } + return "MapFlags(" + strconv.FormatInt(int64(i), 10) + ")" +} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/ptr.go b/vendor/github.com/cilium/ebpf/internal/sys/ptr.go new file mode 100644 index 0000000000..e9bb590597 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/sys/ptr.go @@ -0,0 +1,52 @@ +package sys + +import ( + "unsafe" + + "github.com/cilium/ebpf/internal/unix" +) + +// NewPointer creates a 64-bit pointer from an unsafe Pointer. +func NewPointer(ptr unsafe.Pointer) Pointer { + return Pointer{ptr: ptr} +} + +// NewSlicePointer creates a 64-bit pointer from a byte slice. +func NewSlicePointer(buf []byte) Pointer { + if len(buf) == 0 { + return Pointer{} + } + + return Pointer{ptr: unsafe.Pointer(&buf[0])} +} + +// NewSlicePointerLen creates a 64-bit pointer from a byte slice. +// +// Useful to assign both the pointer and the length in one go. +func NewSlicePointerLen(buf []byte) (Pointer, uint32) { + return NewSlicePointer(buf), uint32(len(buf)) +} + +// NewStringPointer creates a 64-bit pointer from a string. +func NewStringPointer(str string) Pointer { + p, err := unix.BytePtrFromString(str) + if err != nil { + return Pointer{} + } + + return Pointer{ptr: unsafe.Pointer(p)} +} + +// NewStringSlicePointer allocates an array of Pointers to each string in the +// given slice of strings and returns a 64-bit pointer to the start of the +// resulting array. +// +// Use this function to pass arrays of strings as syscall arguments. +func NewStringSlicePointer(strings []string) Pointer { + sp := make([]Pointer, 0, len(strings)) + for _, s := range strings { + sp = append(sp, NewStringPointer(s)) + } + + return Pointer{ptr: unsafe.Pointer(&sp[0])} +} diff --git a/vendor/github.com/cilium/ebpf/internal/ptr_32_be.go b/vendor/github.com/cilium/ebpf/internal/sys/ptr_32_be.go similarity index 81% rename from vendor/github.com/cilium/ebpf/internal/ptr_32_be.go rename to vendor/github.com/cilium/ebpf/internal/sys/ptr_32_be.go index 8c114ddf47..6278c79c9e 100644 --- a/vendor/github.com/cilium/ebpf/internal/ptr_32_be.go +++ b/vendor/github.com/cilium/ebpf/internal/sys/ptr_32_be.go @@ -1,7 +1,6 @@ //go:build armbe || mips || mips64p32 -// +build armbe mips mips64p32 -package internal +package sys import ( "unsafe" diff --git a/vendor/github.com/cilium/ebpf/internal/ptr_32_le.go b/vendor/github.com/cilium/ebpf/internal/sys/ptr_32_le.go similarity index 78% rename from vendor/github.com/cilium/ebpf/internal/ptr_32_le.go rename to vendor/github.com/cilium/ebpf/internal/sys/ptr_32_le.go index e65a61e45d..c27b537e8e 100644 --- a/vendor/github.com/cilium/ebpf/internal/ptr_32_le.go +++ b/vendor/github.com/cilium/ebpf/internal/sys/ptr_32_le.go @@ -1,7 +1,6 @@ //go:build 386 || amd64p32 || arm || mipsle || mips64p32le -// +build 386 amd64p32 arm mipsle mips64p32le -package internal +package sys import ( "unsafe" diff --git a/vendor/github.com/cilium/ebpf/internal/ptr_64.go b/vendor/github.com/cilium/ebpf/internal/sys/ptr_64.go similarity index 73% rename from vendor/github.com/cilium/ebpf/internal/ptr_64.go rename to vendor/github.com/cilium/ebpf/internal/sys/ptr_64.go index 71a3afe307..2d7828230a 100644 --- a/vendor/github.com/cilium/ebpf/internal/ptr_64.go +++ b/vendor/github.com/cilium/ebpf/internal/sys/ptr_64.go @@ -1,7 +1,6 @@ //go:build !386 && !amd64p32 && !arm && !mipsle && !mips64p32le && !armbe && !mips && !mips64p32 -// +build !386,!amd64p32,!arm,!mipsle,!mips64p32le,!armbe,!mips,!mips64p32 -package internal +package sys import ( "unsafe" diff --git a/vendor/github.com/cilium/ebpf/internal/sys/signals.go b/vendor/github.com/cilium/ebpf/internal/sys/signals.go new file mode 100644 index 0000000000..7494c030c0 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/sys/signals.go @@ -0,0 +1,83 @@ +package sys + +import ( + "fmt" + "runtime" + "unsafe" + + "github.com/cilium/ebpf/internal/unix" +) + +// A sigset containing only SIGPROF. +var profSet unix.Sigset_t + +func init() { + // See sigsetAdd for details on the implementation. Open coded here so + // that the compiler will check the constant calculations for us. + profSet.Val[sigprofBit/wordBits] |= 1 << (sigprofBit % wordBits) +} + +// maskProfilerSignal locks the calling goroutine to its underlying OS thread +// and adds SIGPROF to the thread's signal mask. This prevents pprof from +// interrupting expensive syscalls like e.g. BPF_PROG_LOAD. +// +// The caller must defer unmaskProfilerSignal() to reverse the operation. +func maskProfilerSignal() { + runtime.LockOSThread() + + if err := unix.PthreadSigmask(unix.SIG_BLOCK, &profSet, nil); err != nil { + runtime.UnlockOSThread() + panic(fmt.Errorf("masking profiler signal: %w", err)) + } +} + +// unmaskProfilerSignal removes SIGPROF from the underlying thread's signal +// mask, allowing it to be interrupted for profiling once again. +// +// It also unlocks the current goroutine from its underlying OS thread. +func unmaskProfilerSignal() { + defer runtime.UnlockOSThread() + + if err := unix.PthreadSigmask(unix.SIG_UNBLOCK, &profSet, nil); err != nil { + panic(fmt.Errorf("unmasking profiler signal: %w", err)) + } +} + +const ( + // Signal is the nth bit in the bitfield. + sigprofBit = int(unix.SIGPROF - 1) + // The number of bits in one Sigset_t word. + wordBits = int(unsafe.Sizeof(unix.Sigset_t{}.Val[0])) * 8 +) + +// sigsetAdd adds signal to set. +// +// Note: Sigset_t.Val's value type is uint32 or uint64 depending on the arch. +// This function must be able to deal with both and so must avoid any direct +// references to u32 or u64 types. +func sigsetAdd(set *unix.Sigset_t, signal unix.Signal) error { + if signal < 1 { + return fmt.Errorf("signal %d must be larger than 0", signal) + } + + // For amd64, runtime.sigaddset() performs the following operation: + // set[(signal-1)/32] |= 1 << ((uint32(signal) - 1) & 31) + // + // This trick depends on sigset being two u32's, causing a signal in the the + // bottom 31 bits to be written to the low word if bit 32 is low, or the high + // word if bit 32 is high. + + // Signal is the nth bit in the bitfield. + bit := int(signal - 1) + // Word within the sigset the bit needs to be written to. + word := bit / wordBits + + if word >= len(set.Val) { + return fmt.Errorf("signal %d does not fit within unix.Sigset_t", signal) + } + + // Write the signal bit into its corresponding word at the corrected offset. + set.Val[word] |= 1 << (bit % wordBits) + + return nil +} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/syscall.go b/vendor/github.com/cilium/ebpf/internal/sys/syscall.go new file mode 100644 index 0000000000..4fae04db5d --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/sys/syscall.go @@ -0,0 +1,178 @@ +package sys + +import ( + "runtime" + "syscall" + "unsafe" + + "github.com/cilium/ebpf/internal/unix" +) + +// ENOTSUPP is a Linux internal error code that has leaked into UAPI. +// +// It is not the same as ENOTSUP or EOPNOTSUPP. +var ENOTSUPP = syscall.Errno(524) + +// BPF wraps SYS_BPF. +// +// Any pointers contained in attr must use the Pointer type from this package. +func BPF(cmd Cmd, attr unsafe.Pointer, size uintptr) (uintptr, error) { + // Prevent the Go profiler from repeatedly interrupting the verifier, + // which could otherwise lead to a livelock due to receiving EAGAIN. + if cmd == BPF_PROG_LOAD || cmd == BPF_PROG_RUN { + maskProfilerSignal() + defer unmaskProfilerSignal() + } + + for { + r1, _, errNo := unix.Syscall(unix.SYS_BPF, uintptr(cmd), uintptr(attr), size) + runtime.KeepAlive(attr) + + // As of ~4.20 the verifier can be interrupted by a signal, + // and returns EAGAIN in that case. + if errNo == unix.EAGAIN && cmd == BPF_PROG_LOAD { + continue + } + + var err error + if errNo != 0 { + err = wrappedErrno{errNo} + } + + return r1, err + } +} + +// Info is implemented by all structs that can be passed to the ObjInfo syscall. +// +// MapInfo +// ProgInfo +// LinkInfo +// BtfInfo +type Info interface { + info() (unsafe.Pointer, uint32) +} + +var _ Info = (*MapInfo)(nil) + +func (i *MapInfo) info() (unsafe.Pointer, uint32) { + return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i)) +} + +var _ Info = (*ProgInfo)(nil) + +func (i *ProgInfo) info() (unsafe.Pointer, uint32) { + return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i)) +} + +var _ Info = (*LinkInfo)(nil) + +func (i *LinkInfo) info() (unsafe.Pointer, uint32) { + return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i)) +} + +var _ Info = (*BtfInfo)(nil) + +func (i *BtfInfo) info() (unsafe.Pointer, uint32) { + return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i)) +} + +// ObjInfo retrieves information about a BPF Fd. +// +// info may be one of MapInfo, ProgInfo, LinkInfo and BtfInfo. +func ObjInfo(fd *FD, info Info) error { + ptr, len := info.info() + err := ObjGetInfoByFd(&ObjGetInfoByFdAttr{ + BpfFd: fd.Uint(), + InfoLen: len, + Info: NewPointer(ptr), + }) + runtime.KeepAlive(fd) + return err +} + +// BPFObjName is a null-terminated string made up of +// 'A-Za-z0-9_' characters. +type ObjName [unix.BPF_OBJ_NAME_LEN]byte + +// NewObjName truncates the result if it is too long. +func NewObjName(name string) ObjName { + var result ObjName + copy(result[:unix.BPF_OBJ_NAME_LEN-1], name) + return result +} + +// LogLevel controls the verbosity of the kernel's eBPF program verifier. +type LogLevel uint32 + +const ( + BPF_LOG_LEVEL1 LogLevel = 1 << iota + BPF_LOG_LEVEL2 + BPF_LOG_STATS +) + +// LinkID uniquely identifies a bpf_link. +type LinkID uint32 + +// BTFID uniquely identifies a BTF blob loaded into the kernel. +type BTFID uint32 + +// TypeID identifies a type in a BTF blob. +type TypeID uint32 + +// MapFlags control map behaviour. +type MapFlags uint32 + +//go:generate stringer -type MapFlags + +const ( + BPF_F_NO_PREALLOC MapFlags = 1 << iota + BPF_F_NO_COMMON_LRU + BPF_F_NUMA_NODE + BPF_F_RDONLY + BPF_F_WRONLY + BPF_F_STACK_BUILD_ID + BPF_F_ZERO_SEED + BPF_F_RDONLY_PROG + BPF_F_WRONLY_PROG + BPF_F_CLONE + BPF_F_MMAPABLE + BPF_F_PRESERVE_ELEMS + BPF_F_INNER_MAP +) + +// wrappedErrno wraps syscall.Errno to prevent direct comparisons with +// syscall.E* or unix.E* constants. +// +// You should never export an error of this type. +type wrappedErrno struct { + syscall.Errno +} + +func (we wrappedErrno) Unwrap() error { + return we.Errno +} + +func (we wrappedErrno) Error() string { + if we.Errno == ENOTSUPP { + return "operation not supported" + } + return we.Errno.Error() +} + +type syscallError struct { + error + errno syscall.Errno +} + +func Error(err error, errno syscall.Errno) error { + return &syscallError{err, errno} +} + +func (se *syscallError) Is(target error) bool { + return target == se.error +} + +func (se *syscallError) Unwrap() error { + return se.errno +} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/types.go b/vendor/github.com/cilium/ebpf/internal/sys/types.go new file mode 100644 index 0000000000..2af7759e5a --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/sys/types.go @@ -0,0 +1,1117 @@ +// Code generated by internal/cmd/gentypes; DO NOT EDIT. + +package sys + +import ( + "unsafe" +) + +type AdjRoomMode uint32 + +const ( + BPF_ADJ_ROOM_NET AdjRoomMode = 0 + BPF_ADJ_ROOM_MAC AdjRoomMode = 1 +) + +type AttachType uint32 + +const ( + BPF_CGROUP_INET_INGRESS AttachType = 0 + BPF_CGROUP_INET_EGRESS AttachType = 1 + BPF_CGROUP_INET_SOCK_CREATE AttachType = 2 + BPF_CGROUP_SOCK_OPS AttachType = 3 + BPF_SK_SKB_STREAM_PARSER AttachType = 4 + BPF_SK_SKB_STREAM_VERDICT AttachType = 5 + BPF_CGROUP_DEVICE AttachType = 6 + BPF_SK_MSG_VERDICT AttachType = 7 + BPF_CGROUP_INET4_BIND AttachType = 8 + BPF_CGROUP_INET6_BIND AttachType = 9 + BPF_CGROUP_INET4_CONNECT AttachType = 10 + BPF_CGROUP_INET6_CONNECT AttachType = 11 + BPF_CGROUP_INET4_POST_BIND AttachType = 12 + BPF_CGROUP_INET6_POST_BIND AttachType = 13 + BPF_CGROUP_UDP4_SENDMSG AttachType = 14 + BPF_CGROUP_UDP6_SENDMSG AttachType = 15 + BPF_LIRC_MODE2 AttachType = 16 + BPF_FLOW_DISSECTOR AttachType = 17 + BPF_CGROUP_SYSCTL AttachType = 18 + BPF_CGROUP_UDP4_RECVMSG AttachType = 19 + BPF_CGROUP_UDP6_RECVMSG AttachType = 20 + BPF_CGROUP_GETSOCKOPT AttachType = 21 + BPF_CGROUP_SETSOCKOPT AttachType = 22 + BPF_TRACE_RAW_TP AttachType = 23 + BPF_TRACE_FENTRY AttachType = 24 + BPF_TRACE_FEXIT AttachType = 25 + BPF_MODIFY_RETURN AttachType = 26 + BPF_LSM_MAC AttachType = 27 + BPF_TRACE_ITER AttachType = 28 + BPF_CGROUP_INET4_GETPEERNAME AttachType = 29 + BPF_CGROUP_INET6_GETPEERNAME AttachType = 30 + BPF_CGROUP_INET4_GETSOCKNAME AttachType = 31 + BPF_CGROUP_INET6_GETSOCKNAME AttachType = 32 + BPF_XDP_DEVMAP AttachType = 33 + BPF_CGROUP_INET_SOCK_RELEASE AttachType = 34 + BPF_XDP_CPUMAP AttachType = 35 + BPF_SK_LOOKUP AttachType = 36 + BPF_XDP AttachType = 37 + BPF_SK_SKB_VERDICT AttachType = 38 + BPF_SK_REUSEPORT_SELECT AttachType = 39 + BPF_SK_REUSEPORT_SELECT_OR_MIGRATE AttachType = 40 + BPF_PERF_EVENT AttachType = 41 + BPF_TRACE_KPROBE_MULTI AttachType = 42 + __MAX_BPF_ATTACH_TYPE AttachType = 43 +) + +type Cmd uint32 + +const ( + BPF_MAP_CREATE Cmd = 0 + BPF_MAP_LOOKUP_ELEM Cmd = 1 + BPF_MAP_UPDATE_ELEM Cmd = 2 + BPF_MAP_DELETE_ELEM Cmd = 3 + BPF_MAP_GET_NEXT_KEY Cmd = 4 + BPF_PROG_LOAD Cmd = 5 + BPF_OBJ_PIN Cmd = 6 + BPF_OBJ_GET Cmd = 7 + BPF_PROG_ATTACH Cmd = 8 + BPF_PROG_DETACH Cmd = 9 + BPF_PROG_TEST_RUN Cmd = 10 + BPF_PROG_RUN Cmd = 10 + BPF_PROG_GET_NEXT_ID Cmd = 11 + BPF_MAP_GET_NEXT_ID Cmd = 12 + BPF_PROG_GET_FD_BY_ID Cmd = 13 + BPF_MAP_GET_FD_BY_ID Cmd = 14 + BPF_OBJ_GET_INFO_BY_FD Cmd = 15 + BPF_PROG_QUERY Cmd = 16 + BPF_RAW_TRACEPOINT_OPEN Cmd = 17 + BPF_BTF_LOAD Cmd = 18 + BPF_BTF_GET_FD_BY_ID Cmd = 19 + BPF_TASK_FD_QUERY Cmd = 20 + BPF_MAP_LOOKUP_AND_DELETE_ELEM Cmd = 21 + BPF_MAP_FREEZE Cmd = 22 + BPF_BTF_GET_NEXT_ID Cmd = 23 + BPF_MAP_LOOKUP_BATCH Cmd = 24 + BPF_MAP_LOOKUP_AND_DELETE_BATCH Cmd = 25 + BPF_MAP_UPDATE_BATCH Cmd = 26 + BPF_MAP_DELETE_BATCH Cmd = 27 + BPF_LINK_CREATE Cmd = 28 + BPF_LINK_UPDATE Cmd = 29 + BPF_LINK_GET_FD_BY_ID Cmd = 30 + BPF_LINK_GET_NEXT_ID Cmd = 31 + BPF_ENABLE_STATS Cmd = 32 + BPF_ITER_CREATE Cmd = 33 + BPF_LINK_DETACH Cmd = 34 + BPF_PROG_BIND_MAP Cmd = 35 +) + +type FunctionId uint32 + +const ( + BPF_FUNC_unspec FunctionId = 0 + BPF_FUNC_map_lookup_elem FunctionId = 1 + BPF_FUNC_map_update_elem FunctionId = 2 + BPF_FUNC_map_delete_elem FunctionId = 3 + BPF_FUNC_probe_read FunctionId = 4 + BPF_FUNC_ktime_get_ns FunctionId = 5 + BPF_FUNC_trace_printk FunctionId = 6 + BPF_FUNC_get_prandom_u32 FunctionId = 7 + BPF_FUNC_get_smp_processor_id FunctionId = 8 + BPF_FUNC_skb_store_bytes FunctionId = 9 + BPF_FUNC_l3_csum_replace FunctionId = 10 + BPF_FUNC_l4_csum_replace FunctionId = 11 + BPF_FUNC_tail_call FunctionId = 12 + BPF_FUNC_clone_redirect FunctionId = 13 + BPF_FUNC_get_current_pid_tgid FunctionId = 14 + BPF_FUNC_get_current_uid_gid FunctionId = 15 + BPF_FUNC_get_current_comm FunctionId = 16 + BPF_FUNC_get_cgroup_classid FunctionId = 17 + BPF_FUNC_skb_vlan_push FunctionId = 18 + BPF_FUNC_skb_vlan_pop FunctionId = 19 + BPF_FUNC_skb_get_tunnel_key FunctionId = 20 + BPF_FUNC_skb_set_tunnel_key FunctionId = 21 + BPF_FUNC_perf_event_read FunctionId = 22 + BPF_FUNC_redirect FunctionId = 23 + BPF_FUNC_get_route_realm FunctionId = 24 + BPF_FUNC_perf_event_output FunctionId = 25 + BPF_FUNC_skb_load_bytes FunctionId = 26 + BPF_FUNC_get_stackid FunctionId = 27 + BPF_FUNC_csum_diff FunctionId = 28 + BPF_FUNC_skb_get_tunnel_opt FunctionId = 29 + BPF_FUNC_skb_set_tunnel_opt FunctionId = 30 + BPF_FUNC_skb_change_proto FunctionId = 31 + BPF_FUNC_skb_change_type FunctionId = 32 + BPF_FUNC_skb_under_cgroup FunctionId = 33 + BPF_FUNC_get_hash_recalc FunctionId = 34 + BPF_FUNC_get_current_task FunctionId = 35 + BPF_FUNC_probe_write_user FunctionId = 36 + BPF_FUNC_current_task_under_cgroup FunctionId = 37 + BPF_FUNC_skb_change_tail FunctionId = 38 + BPF_FUNC_skb_pull_data FunctionId = 39 + BPF_FUNC_csum_update FunctionId = 40 + BPF_FUNC_set_hash_invalid FunctionId = 41 + BPF_FUNC_get_numa_node_id FunctionId = 42 + BPF_FUNC_skb_change_head FunctionId = 43 + BPF_FUNC_xdp_adjust_head FunctionId = 44 + BPF_FUNC_probe_read_str FunctionId = 45 + BPF_FUNC_get_socket_cookie FunctionId = 46 + BPF_FUNC_get_socket_uid FunctionId = 47 + BPF_FUNC_set_hash FunctionId = 48 + BPF_FUNC_setsockopt FunctionId = 49 + BPF_FUNC_skb_adjust_room FunctionId = 50 + BPF_FUNC_redirect_map FunctionId = 51 + BPF_FUNC_sk_redirect_map FunctionId = 52 + BPF_FUNC_sock_map_update FunctionId = 53 + BPF_FUNC_xdp_adjust_meta FunctionId = 54 + BPF_FUNC_perf_event_read_value FunctionId = 55 + BPF_FUNC_perf_prog_read_value FunctionId = 56 + BPF_FUNC_getsockopt FunctionId = 57 + BPF_FUNC_override_return FunctionId = 58 + BPF_FUNC_sock_ops_cb_flags_set FunctionId = 59 + BPF_FUNC_msg_redirect_map FunctionId = 60 + BPF_FUNC_msg_apply_bytes FunctionId = 61 + BPF_FUNC_msg_cork_bytes FunctionId = 62 + BPF_FUNC_msg_pull_data FunctionId = 63 + BPF_FUNC_bind FunctionId = 64 + BPF_FUNC_xdp_adjust_tail FunctionId = 65 + BPF_FUNC_skb_get_xfrm_state FunctionId = 66 + BPF_FUNC_get_stack FunctionId = 67 + BPF_FUNC_skb_load_bytes_relative FunctionId = 68 + BPF_FUNC_fib_lookup FunctionId = 69 + BPF_FUNC_sock_hash_update FunctionId = 70 + BPF_FUNC_msg_redirect_hash FunctionId = 71 + BPF_FUNC_sk_redirect_hash FunctionId = 72 + BPF_FUNC_lwt_push_encap FunctionId = 73 + BPF_FUNC_lwt_seg6_store_bytes FunctionId = 74 + BPF_FUNC_lwt_seg6_adjust_srh FunctionId = 75 + BPF_FUNC_lwt_seg6_action FunctionId = 76 + BPF_FUNC_rc_repeat FunctionId = 77 + BPF_FUNC_rc_keydown FunctionId = 78 + BPF_FUNC_skb_cgroup_id FunctionId = 79 + BPF_FUNC_get_current_cgroup_id FunctionId = 80 + BPF_FUNC_get_local_storage FunctionId = 81 + BPF_FUNC_sk_select_reuseport FunctionId = 82 + BPF_FUNC_skb_ancestor_cgroup_id FunctionId = 83 + BPF_FUNC_sk_lookup_tcp FunctionId = 84 + BPF_FUNC_sk_lookup_udp FunctionId = 85 + BPF_FUNC_sk_release FunctionId = 86 + BPF_FUNC_map_push_elem FunctionId = 87 + BPF_FUNC_map_pop_elem FunctionId = 88 + BPF_FUNC_map_peek_elem FunctionId = 89 + BPF_FUNC_msg_push_data FunctionId = 90 + BPF_FUNC_msg_pop_data FunctionId = 91 + BPF_FUNC_rc_pointer_rel FunctionId = 92 + BPF_FUNC_spin_lock FunctionId = 93 + BPF_FUNC_spin_unlock FunctionId = 94 + BPF_FUNC_sk_fullsock FunctionId = 95 + BPF_FUNC_tcp_sock FunctionId = 96 + BPF_FUNC_skb_ecn_set_ce FunctionId = 97 + BPF_FUNC_get_listener_sock FunctionId = 98 + BPF_FUNC_skc_lookup_tcp FunctionId = 99 + BPF_FUNC_tcp_check_syncookie FunctionId = 100 + BPF_FUNC_sysctl_get_name FunctionId = 101 + BPF_FUNC_sysctl_get_current_value FunctionId = 102 + BPF_FUNC_sysctl_get_new_value FunctionId = 103 + BPF_FUNC_sysctl_set_new_value FunctionId = 104 + BPF_FUNC_strtol FunctionId = 105 + BPF_FUNC_strtoul FunctionId = 106 + BPF_FUNC_sk_storage_get FunctionId = 107 + BPF_FUNC_sk_storage_delete FunctionId = 108 + BPF_FUNC_send_signal FunctionId = 109 + BPF_FUNC_tcp_gen_syncookie FunctionId = 110 + BPF_FUNC_skb_output FunctionId = 111 + BPF_FUNC_probe_read_user FunctionId = 112 + BPF_FUNC_probe_read_kernel FunctionId = 113 + BPF_FUNC_probe_read_user_str FunctionId = 114 + BPF_FUNC_probe_read_kernel_str FunctionId = 115 + BPF_FUNC_tcp_send_ack FunctionId = 116 + BPF_FUNC_send_signal_thread FunctionId = 117 + BPF_FUNC_jiffies64 FunctionId = 118 + BPF_FUNC_read_branch_records FunctionId = 119 + BPF_FUNC_get_ns_current_pid_tgid FunctionId = 120 + BPF_FUNC_xdp_output FunctionId = 121 + BPF_FUNC_get_netns_cookie FunctionId = 122 + BPF_FUNC_get_current_ancestor_cgroup_id FunctionId = 123 + BPF_FUNC_sk_assign FunctionId = 124 + BPF_FUNC_ktime_get_boot_ns FunctionId = 125 + BPF_FUNC_seq_printf FunctionId = 126 + BPF_FUNC_seq_write FunctionId = 127 + BPF_FUNC_sk_cgroup_id FunctionId = 128 + BPF_FUNC_sk_ancestor_cgroup_id FunctionId = 129 + BPF_FUNC_ringbuf_output FunctionId = 130 + BPF_FUNC_ringbuf_reserve FunctionId = 131 + BPF_FUNC_ringbuf_submit FunctionId = 132 + BPF_FUNC_ringbuf_discard FunctionId = 133 + BPF_FUNC_ringbuf_query FunctionId = 134 + BPF_FUNC_csum_level FunctionId = 135 + BPF_FUNC_skc_to_tcp6_sock FunctionId = 136 + BPF_FUNC_skc_to_tcp_sock FunctionId = 137 + BPF_FUNC_skc_to_tcp_timewait_sock FunctionId = 138 + BPF_FUNC_skc_to_tcp_request_sock FunctionId = 139 + BPF_FUNC_skc_to_udp6_sock FunctionId = 140 + BPF_FUNC_get_task_stack FunctionId = 141 + BPF_FUNC_load_hdr_opt FunctionId = 142 + BPF_FUNC_store_hdr_opt FunctionId = 143 + BPF_FUNC_reserve_hdr_opt FunctionId = 144 + BPF_FUNC_inode_storage_get FunctionId = 145 + BPF_FUNC_inode_storage_delete FunctionId = 146 + BPF_FUNC_d_path FunctionId = 147 + BPF_FUNC_copy_from_user FunctionId = 148 + BPF_FUNC_snprintf_btf FunctionId = 149 + BPF_FUNC_seq_printf_btf FunctionId = 150 + BPF_FUNC_skb_cgroup_classid FunctionId = 151 + BPF_FUNC_redirect_neigh FunctionId = 152 + BPF_FUNC_per_cpu_ptr FunctionId = 153 + BPF_FUNC_this_cpu_ptr FunctionId = 154 + BPF_FUNC_redirect_peer FunctionId = 155 + BPF_FUNC_task_storage_get FunctionId = 156 + BPF_FUNC_task_storage_delete FunctionId = 157 + BPF_FUNC_get_current_task_btf FunctionId = 158 + BPF_FUNC_bprm_opts_set FunctionId = 159 + BPF_FUNC_ktime_get_coarse_ns FunctionId = 160 + BPF_FUNC_ima_inode_hash FunctionId = 161 + BPF_FUNC_sock_from_file FunctionId = 162 + BPF_FUNC_check_mtu FunctionId = 163 + BPF_FUNC_for_each_map_elem FunctionId = 164 + BPF_FUNC_snprintf FunctionId = 165 + BPF_FUNC_sys_bpf FunctionId = 166 + BPF_FUNC_btf_find_by_name_kind FunctionId = 167 + BPF_FUNC_sys_close FunctionId = 168 + BPF_FUNC_timer_init FunctionId = 169 + BPF_FUNC_timer_set_callback FunctionId = 170 + BPF_FUNC_timer_start FunctionId = 171 + BPF_FUNC_timer_cancel FunctionId = 172 + BPF_FUNC_get_func_ip FunctionId = 173 + BPF_FUNC_get_attach_cookie FunctionId = 174 + BPF_FUNC_task_pt_regs FunctionId = 175 + BPF_FUNC_get_branch_snapshot FunctionId = 176 + BPF_FUNC_trace_vprintk FunctionId = 177 + BPF_FUNC_skc_to_unix_sock FunctionId = 178 + BPF_FUNC_kallsyms_lookup_name FunctionId = 179 + BPF_FUNC_find_vma FunctionId = 180 + BPF_FUNC_loop FunctionId = 181 + BPF_FUNC_strncmp FunctionId = 182 + BPF_FUNC_get_func_arg FunctionId = 183 + BPF_FUNC_get_func_ret FunctionId = 184 + BPF_FUNC_get_func_arg_cnt FunctionId = 185 + BPF_FUNC_get_retval FunctionId = 186 + BPF_FUNC_set_retval FunctionId = 187 + BPF_FUNC_xdp_get_buff_len FunctionId = 188 + BPF_FUNC_xdp_load_bytes FunctionId = 189 + BPF_FUNC_xdp_store_bytes FunctionId = 190 + BPF_FUNC_copy_from_user_task FunctionId = 191 + BPF_FUNC_skb_set_tstamp FunctionId = 192 + BPF_FUNC_ima_file_hash FunctionId = 193 + BPF_FUNC_kptr_xchg FunctionId = 194 + BPF_FUNC_map_lookup_percpu_elem FunctionId = 195 + BPF_FUNC_skc_to_mptcp_sock FunctionId = 196 + BPF_FUNC_dynptr_from_mem FunctionId = 197 + BPF_FUNC_ringbuf_reserve_dynptr FunctionId = 198 + BPF_FUNC_ringbuf_submit_dynptr FunctionId = 199 + BPF_FUNC_ringbuf_discard_dynptr FunctionId = 200 + BPF_FUNC_dynptr_read FunctionId = 201 + BPF_FUNC_dynptr_write FunctionId = 202 + BPF_FUNC_dynptr_data FunctionId = 203 + __BPF_FUNC_MAX_ID FunctionId = 204 +) + +type HdrStartOff uint32 + +const ( + BPF_HDR_START_MAC HdrStartOff = 0 + BPF_HDR_START_NET HdrStartOff = 1 +) + +type LinkType uint32 + +const ( + BPF_LINK_TYPE_UNSPEC LinkType = 0 + BPF_LINK_TYPE_RAW_TRACEPOINT LinkType = 1 + BPF_LINK_TYPE_TRACING LinkType = 2 + BPF_LINK_TYPE_CGROUP LinkType = 3 + BPF_LINK_TYPE_ITER LinkType = 4 + BPF_LINK_TYPE_NETNS LinkType = 5 + BPF_LINK_TYPE_XDP LinkType = 6 + BPF_LINK_TYPE_PERF_EVENT LinkType = 7 + BPF_LINK_TYPE_KPROBE_MULTI LinkType = 8 + BPF_LINK_TYPE_STRUCT_OPS LinkType = 9 + MAX_BPF_LINK_TYPE LinkType = 10 +) + +type MapType uint32 + +const ( + BPF_MAP_TYPE_UNSPEC MapType = 0 + BPF_MAP_TYPE_HASH MapType = 1 + BPF_MAP_TYPE_ARRAY MapType = 2 + BPF_MAP_TYPE_PROG_ARRAY MapType = 3 + BPF_MAP_TYPE_PERF_EVENT_ARRAY MapType = 4 + BPF_MAP_TYPE_PERCPU_HASH MapType = 5 + BPF_MAP_TYPE_PERCPU_ARRAY MapType = 6 + BPF_MAP_TYPE_STACK_TRACE MapType = 7 + BPF_MAP_TYPE_CGROUP_ARRAY MapType = 8 + BPF_MAP_TYPE_LRU_HASH MapType = 9 + BPF_MAP_TYPE_LRU_PERCPU_HASH MapType = 10 + BPF_MAP_TYPE_LPM_TRIE MapType = 11 + BPF_MAP_TYPE_ARRAY_OF_MAPS MapType = 12 + BPF_MAP_TYPE_HASH_OF_MAPS MapType = 13 + BPF_MAP_TYPE_DEVMAP MapType = 14 + BPF_MAP_TYPE_SOCKMAP MapType = 15 + BPF_MAP_TYPE_CPUMAP MapType = 16 + BPF_MAP_TYPE_XSKMAP MapType = 17 + BPF_MAP_TYPE_SOCKHASH MapType = 18 + BPF_MAP_TYPE_CGROUP_STORAGE MapType = 19 + BPF_MAP_TYPE_REUSEPORT_SOCKARRAY MapType = 20 + BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE MapType = 21 + BPF_MAP_TYPE_QUEUE MapType = 22 + BPF_MAP_TYPE_STACK MapType = 23 + BPF_MAP_TYPE_SK_STORAGE MapType = 24 + BPF_MAP_TYPE_DEVMAP_HASH MapType = 25 + BPF_MAP_TYPE_STRUCT_OPS MapType = 26 + BPF_MAP_TYPE_RINGBUF MapType = 27 + BPF_MAP_TYPE_INODE_STORAGE MapType = 28 + BPF_MAP_TYPE_TASK_STORAGE MapType = 29 + BPF_MAP_TYPE_BLOOM_FILTER MapType = 30 +) + +type ProgType uint32 + +const ( + BPF_PROG_TYPE_UNSPEC ProgType = 0 + BPF_PROG_TYPE_SOCKET_FILTER ProgType = 1 + BPF_PROG_TYPE_KPROBE ProgType = 2 + BPF_PROG_TYPE_SCHED_CLS ProgType = 3 + BPF_PROG_TYPE_SCHED_ACT ProgType = 4 + BPF_PROG_TYPE_TRACEPOINT ProgType = 5 + BPF_PROG_TYPE_XDP ProgType = 6 + BPF_PROG_TYPE_PERF_EVENT ProgType = 7 + BPF_PROG_TYPE_CGROUP_SKB ProgType = 8 + BPF_PROG_TYPE_CGROUP_SOCK ProgType = 9 + BPF_PROG_TYPE_LWT_IN ProgType = 10 + BPF_PROG_TYPE_LWT_OUT ProgType = 11 + BPF_PROG_TYPE_LWT_XMIT ProgType = 12 + BPF_PROG_TYPE_SOCK_OPS ProgType = 13 + BPF_PROG_TYPE_SK_SKB ProgType = 14 + BPF_PROG_TYPE_CGROUP_DEVICE ProgType = 15 + BPF_PROG_TYPE_SK_MSG ProgType = 16 + BPF_PROG_TYPE_RAW_TRACEPOINT ProgType = 17 + BPF_PROG_TYPE_CGROUP_SOCK_ADDR ProgType = 18 + BPF_PROG_TYPE_LWT_SEG6LOCAL ProgType = 19 + BPF_PROG_TYPE_LIRC_MODE2 ProgType = 20 + BPF_PROG_TYPE_SK_REUSEPORT ProgType = 21 + BPF_PROG_TYPE_FLOW_DISSECTOR ProgType = 22 + BPF_PROG_TYPE_CGROUP_SYSCTL ProgType = 23 + BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE ProgType = 24 + BPF_PROG_TYPE_CGROUP_SOCKOPT ProgType = 25 + BPF_PROG_TYPE_TRACING ProgType = 26 + BPF_PROG_TYPE_STRUCT_OPS ProgType = 27 + BPF_PROG_TYPE_EXT ProgType = 28 + BPF_PROG_TYPE_LSM ProgType = 29 + BPF_PROG_TYPE_SK_LOOKUP ProgType = 30 + BPF_PROG_TYPE_SYSCALL ProgType = 31 +) + +type RetCode uint32 + +const ( + BPF_OK RetCode = 0 + BPF_DROP RetCode = 2 + BPF_REDIRECT RetCode = 7 + BPF_LWT_REROUTE RetCode = 128 +) + +type SkAction uint32 + +const ( + SK_DROP SkAction = 0 + SK_PASS SkAction = 1 +) + +type StackBuildIdStatus uint32 + +const ( + BPF_STACK_BUILD_ID_EMPTY StackBuildIdStatus = 0 + BPF_STACK_BUILD_ID_VALID StackBuildIdStatus = 1 + BPF_STACK_BUILD_ID_IP StackBuildIdStatus = 2 +) + +type StatsType uint32 + +const ( + BPF_STATS_RUN_TIME StatsType = 0 +) + +type XdpAction uint32 + +const ( + XDP_ABORTED XdpAction = 0 + XDP_DROP XdpAction = 1 + XDP_PASS XdpAction = 2 + XDP_TX XdpAction = 3 + XDP_REDIRECT XdpAction = 4 +) + +type BtfInfo struct { + Btf Pointer + BtfSize uint32 + Id BTFID + Name Pointer + NameLen uint32 + KernelBtf uint32 +} + +type FuncInfo struct { + InsnOff uint32 + TypeId uint32 +} + +type LineInfo struct { + InsnOff uint32 + FileNameOff uint32 + LineOff uint32 + LineCol uint32 +} + +type LinkInfo struct { + Type LinkType + Id LinkID + ProgId uint32 + _ [4]byte + Extra [16]uint8 +} + +type MapInfo struct { + Type uint32 + Id uint32 + KeySize uint32 + ValueSize uint32 + MaxEntries uint32 + MapFlags MapFlags + Name ObjName + Ifindex uint32 + BtfVmlinuxValueTypeId TypeID + NetnsDev uint64 + NetnsIno uint64 + BtfId uint32 + BtfKeyTypeId TypeID + BtfValueTypeId TypeID + _ [4]byte + MapExtra uint64 +} + +type ProgInfo struct { + Type uint32 + Id uint32 + Tag [8]uint8 + JitedProgLen uint32 + XlatedProgLen uint32 + JitedProgInsns uint64 + XlatedProgInsns Pointer + LoadTime uint64 + CreatedByUid uint32 + NrMapIds uint32 + MapIds Pointer + Name ObjName + Ifindex uint32 + _ [4]byte /* unsupported bitfield */ + NetnsDev uint64 + NetnsIno uint64 + NrJitedKsyms uint32 + NrJitedFuncLens uint32 + JitedKsyms uint64 + JitedFuncLens uint64 + BtfId BTFID + FuncInfoRecSize uint32 + FuncInfo uint64 + NrFuncInfo uint32 + NrLineInfo uint32 + LineInfo uint64 + JitedLineInfo uint64 + NrJitedLineInfo uint32 + LineInfoRecSize uint32 + JitedLineInfoRecSize uint32 + NrProgTags uint32 + ProgTags uint64 + RunTimeNs uint64 + RunCnt uint64 + RecursionMisses uint64 + VerifiedInsns uint32 + _ [4]byte +} + +type SkLookup struct { + Cookie uint64 + Family uint32 + Protocol uint32 + RemoteIp4 [4]uint8 + RemoteIp6 [16]uint8 + RemotePort uint16 + _ [2]byte + LocalIp4 [4]uint8 + LocalIp6 [16]uint8 + LocalPort uint32 + IngressIfindex uint32 + _ [4]byte +} + +type XdpMd struct { + Data uint32 + DataEnd uint32 + DataMeta uint32 + IngressIfindex uint32 + RxQueueIndex uint32 + EgressIfindex uint32 +} + +type BtfGetFdByIdAttr struct{ Id uint32 } + +func BtfGetFdById(attr *BtfGetFdByIdAttr) (*FD, error) { + fd, err := BPF(BPF_BTF_GET_FD_BY_ID, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type BtfGetNextIdAttr struct { + Id BTFID + NextId BTFID +} + +func BtfGetNextId(attr *BtfGetNextIdAttr) error { + _, err := BPF(BPF_BTF_GET_NEXT_ID, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type BtfLoadAttr struct { + Btf Pointer + BtfLogBuf Pointer + BtfSize uint32 + BtfLogSize uint32 + BtfLogLevel uint32 + _ [4]byte +} + +func BtfLoad(attr *BtfLoadAttr) (*FD, error) { + fd, err := BPF(BPF_BTF_LOAD, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type EnableStatsAttr struct{ Type uint32 } + +func EnableStats(attr *EnableStatsAttr) (*FD, error) { + fd, err := BPF(BPF_ENABLE_STATS, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type IterCreateAttr struct { + LinkFd uint32 + Flags uint32 +} + +func IterCreate(attr *IterCreateAttr) (*FD, error) { + fd, err := BPF(BPF_ITER_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type LinkCreateAttr struct { + ProgFd uint32 + TargetFd uint32 + AttachType AttachType + Flags uint32 + TargetBtfId TypeID + _ [28]byte +} + +func LinkCreate(attr *LinkCreateAttr) (*FD, error) { + fd, err := BPF(BPF_LINK_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type LinkCreateIterAttr struct { + ProgFd uint32 + TargetFd uint32 + AttachType AttachType + Flags uint32 + IterInfo Pointer + IterInfoLen uint32 + _ [20]byte +} + +func LinkCreateIter(attr *LinkCreateIterAttr) (*FD, error) { + fd, err := BPF(BPF_LINK_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type LinkCreateKprobeMultiAttr struct { + ProgFd uint32 + TargetFd uint32 + AttachType AttachType + Flags uint32 + KprobeMultiFlags uint32 + Count uint32 + Syms Pointer + Addrs Pointer + Cookies Pointer +} + +func LinkCreateKprobeMulti(attr *LinkCreateKprobeMultiAttr) (*FD, error) { + fd, err := BPF(BPF_LINK_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type LinkCreatePerfEventAttr struct { + ProgFd uint32 + TargetFd uint32 + AttachType AttachType + Flags uint32 + BpfCookie uint64 + _ [24]byte +} + +func LinkCreatePerfEvent(attr *LinkCreatePerfEventAttr) (*FD, error) { + fd, err := BPF(BPF_LINK_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type LinkCreateTracingAttr struct { + ProgFd uint32 + TargetFd uint32 + AttachType AttachType + Flags uint32 + TargetBtfId BTFID + _ [4]byte + Cookie uint64 + _ [16]byte +} + +func LinkCreateTracing(attr *LinkCreateTracingAttr) (*FD, error) { + fd, err := BPF(BPF_LINK_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type LinkUpdateAttr struct { + LinkFd uint32 + NewProgFd uint32 + Flags uint32 + OldProgFd uint32 +} + +func LinkUpdate(attr *LinkUpdateAttr) error { + _, err := BPF(BPF_LINK_UPDATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type MapCreateAttr struct { + MapType MapType + KeySize uint32 + ValueSize uint32 + MaxEntries uint32 + MapFlags MapFlags + InnerMapFd uint32 + NumaNode uint32 + MapName ObjName + MapIfindex uint32 + BtfFd uint32 + BtfKeyTypeId TypeID + BtfValueTypeId TypeID + BtfVmlinuxValueTypeId TypeID + MapExtra uint64 +} + +func MapCreate(attr *MapCreateAttr) (*FD, error) { + fd, err := BPF(BPF_MAP_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type MapDeleteBatchAttr struct { + InBatch Pointer + OutBatch Pointer + Keys Pointer + Values Pointer + Count uint32 + MapFd uint32 + ElemFlags uint64 + Flags uint64 +} + +func MapDeleteBatch(attr *MapDeleteBatchAttr) error { + _, err := BPF(BPF_MAP_DELETE_BATCH, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type MapDeleteElemAttr struct { + MapFd uint32 + _ [4]byte + Key Pointer + Value Pointer + Flags uint64 +} + +func MapDeleteElem(attr *MapDeleteElemAttr) error { + _, err := BPF(BPF_MAP_DELETE_ELEM, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type MapFreezeAttr struct{ MapFd uint32 } + +func MapFreeze(attr *MapFreezeAttr) error { + _, err := BPF(BPF_MAP_FREEZE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type MapGetFdByIdAttr struct{ Id uint32 } + +func MapGetFdById(attr *MapGetFdByIdAttr) (*FD, error) { + fd, err := BPF(BPF_MAP_GET_FD_BY_ID, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type MapGetNextIdAttr struct { + Id uint32 + NextId uint32 +} + +func MapGetNextId(attr *MapGetNextIdAttr) error { + _, err := BPF(BPF_MAP_GET_NEXT_ID, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type MapGetNextKeyAttr struct { + MapFd uint32 + _ [4]byte + Key Pointer + NextKey Pointer +} + +func MapGetNextKey(attr *MapGetNextKeyAttr) error { + _, err := BPF(BPF_MAP_GET_NEXT_KEY, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type MapLookupAndDeleteBatchAttr struct { + InBatch Pointer + OutBatch Pointer + Keys Pointer + Values Pointer + Count uint32 + MapFd uint32 + ElemFlags uint64 + Flags uint64 +} + +func MapLookupAndDeleteBatch(attr *MapLookupAndDeleteBatchAttr) error { + _, err := BPF(BPF_MAP_LOOKUP_AND_DELETE_BATCH, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type MapLookupAndDeleteElemAttr struct { + MapFd uint32 + _ [4]byte + Key Pointer + Value Pointer + Flags uint64 +} + +func MapLookupAndDeleteElem(attr *MapLookupAndDeleteElemAttr) error { + _, err := BPF(BPF_MAP_LOOKUP_AND_DELETE_ELEM, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type MapLookupBatchAttr struct { + InBatch Pointer + OutBatch Pointer + Keys Pointer + Values Pointer + Count uint32 + MapFd uint32 + ElemFlags uint64 + Flags uint64 +} + +func MapLookupBatch(attr *MapLookupBatchAttr) error { + _, err := BPF(BPF_MAP_LOOKUP_BATCH, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type MapLookupElemAttr struct { + MapFd uint32 + _ [4]byte + Key Pointer + Value Pointer + Flags uint64 +} + +func MapLookupElem(attr *MapLookupElemAttr) error { + _, err := BPF(BPF_MAP_LOOKUP_ELEM, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type MapUpdateBatchAttr struct { + InBatch Pointer + OutBatch Pointer + Keys Pointer + Values Pointer + Count uint32 + MapFd uint32 + ElemFlags uint64 + Flags uint64 +} + +func MapUpdateBatch(attr *MapUpdateBatchAttr) error { + _, err := BPF(BPF_MAP_UPDATE_BATCH, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type MapUpdateElemAttr struct { + MapFd uint32 + _ [4]byte + Key Pointer + Value Pointer + Flags uint64 +} + +func MapUpdateElem(attr *MapUpdateElemAttr) error { + _, err := BPF(BPF_MAP_UPDATE_ELEM, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type ObjGetAttr struct { + Pathname Pointer + BpfFd uint32 + FileFlags uint32 +} + +func ObjGet(attr *ObjGetAttr) (*FD, error) { + fd, err := BPF(BPF_OBJ_GET, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type ObjGetInfoByFdAttr struct { + BpfFd uint32 + InfoLen uint32 + Info Pointer +} + +func ObjGetInfoByFd(attr *ObjGetInfoByFdAttr) error { + _, err := BPF(BPF_OBJ_GET_INFO_BY_FD, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type ObjPinAttr struct { + Pathname Pointer + BpfFd uint32 + FileFlags uint32 +} + +func ObjPin(attr *ObjPinAttr) error { + _, err := BPF(BPF_OBJ_PIN, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type ProgAttachAttr struct { + TargetFd uint32 + AttachBpfFd uint32 + AttachType uint32 + AttachFlags uint32 + ReplaceBpfFd uint32 +} + +func ProgAttach(attr *ProgAttachAttr) error { + _, err := BPF(BPF_PROG_ATTACH, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type ProgBindMapAttr struct { + ProgFd uint32 + MapFd uint32 + Flags uint32 +} + +func ProgBindMap(attr *ProgBindMapAttr) error { + _, err := BPF(BPF_PROG_BIND_MAP, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type ProgDetachAttr struct { + TargetFd uint32 + AttachBpfFd uint32 + AttachType uint32 +} + +func ProgDetach(attr *ProgDetachAttr) error { + _, err := BPF(BPF_PROG_DETACH, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type ProgGetFdByIdAttr struct{ Id uint32 } + +func ProgGetFdById(attr *ProgGetFdByIdAttr) (*FD, error) { + fd, err := BPF(BPF_PROG_GET_FD_BY_ID, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type ProgGetNextIdAttr struct { + Id uint32 + NextId uint32 +} + +func ProgGetNextId(attr *ProgGetNextIdAttr) error { + _, err := BPF(BPF_PROG_GET_NEXT_ID, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type ProgLoadAttr struct { + ProgType ProgType + InsnCnt uint32 + Insns Pointer + License Pointer + LogLevel LogLevel + LogSize uint32 + LogBuf Pointer + KernVersion uint32 + ProgFlags uint32 + ProgName ObjName + ProgIfindex uint32 + ExpectedAttachType AttachType + ProgBtfFd uint32 + FuncInfoRecSize uint32 + FuncInfo Pointer + FuncInfoCnt uint32 + LineInfoRecSize uint32 + LineInfo Pointer + LineInfoCnt uint32 + AttachBtfId TypeID + AttachBtfObjFd uint32 + CoreReloCnt uint32 + FdArray Pointer + CoreRelos Pointer + CoreReloRecSize uint32 + _ [4]byte +} + +func ProgLoad(attr *ProgLoadAttr) (*FD, error) { + fd, err := BPF(BPF_PROG_LOAD, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type ProgQueryAttr struct { + TargetFd uint32 + AttachType AttachType + QueryFlags uint32 + AttachFlags uint32 + ProgIds Pointer + ProgCount uint32 + _ [4]byte +} + +func ProgQuery(attr *ProgQueryAttr) error { + _, err := BPF(BPF_PROG_QUERY, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type ProgRunAttr struct { + ProgFd uint32 + Retval uint32 + DataSizeIn uint32 + DataSizeOut uint32 + DataIn Pointer + DataOut Pointer + Repeat uint32 + Duration uint32 + CtxSizeIn uint32 + CtxSizeOut uint32 + CtxIn Pointer + CtxOut Pointer + Flags uint32 + Cpu uint32 + BatchSize uint32 + _ [4]byte +} + +func ProgRun(attr *ProgRunAttr) error { + _, err := BPF(BPF_PROG_TEST_RUN, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + return err +} + +type RawTracepointOpenAttr struct { + Name Pointer + ProgFd uint32 + _ [4]byte +} + +func RawTracepointOpen(attr *RawTracepointOpenAttr) (*FD, error) { + fd, err := BPF(BPF_RAW_TRACEPOINT_OPEN, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + if err != nil { + return nil, err + } + return NewFD(int(fd)) +} + +type CgroupLinkInfo struct { + CgroupId uint64 + AttachType AttachType + _ [4]byte +} + +type IterLinkInfo struct { + TargetName Pointer + TargetNameLen uint32 +} + +type NetNsLinkInfo struct { + NetnsIno uint32 + AttachType AttachType +} + +type RawTracepointLinkInfo struct { + TpName Pointer + TpNameLen uint32 + _ [4]byte +} + +type TracingLinkInfo struct { + AttachType AttachType + TargetObjId uint32 + TargetBtfId TypeID +} + +type XDPLinkInfo struct{ Ifindex uint32 } diff --git a/vendor/github.com/cilium/ebpf/internal/syscall.go b/vendor/github.com/cilium/ebpf/internal/syscall.go deleted file mode 100644 index b75037bb9d..0000000000 --- a/vendor/github.com/cilium/ebpf/internal/syscall.go +++ /dev/null @@ -1,304 +0,0 @@ -package internal - -import ( - "errors" - "fmt" - "path/filepath" - "runtime" - "syscall" - "unsafe" - - "github.com/cilium/ebpf/internal/unix" -) - -//go:generate stringer -output syscall_string.go -type=BPFCmd - -// BPFCmd identifies a subcommand of the bpf syscall. -type BPFCmd int - -// Well known BPF commands. -const ( - BPF_MAP_CREATE BPFCmd = iota - BPF_MAP_LOOKUP_ELEM - BPF_MAP_UPDATE_ELEM - BPF_MAP_DELETE_ELEM - BPF_MAP_GET_NEXT_KEY - BPF_PROG_LOAD - BPF_OBJ_PIN - BPF_OBJ_GET - BPF_PROG_ATTACH - BPF_PROG_DETACH - BPF_PROG_TEST_RUN - BPF_PROG_GET_NEXT_ID - BPF_MAP_GET_NEXT_ID - BPF_PROG_GET_FD_BY_ID - BPF_MAP_GET_FD_BY_ID - BPF_OBJ_GET_INFO_BY_FD - BPF_PROG_QUERY - BPF_RAW_TRACEPOINT_OPEN - BPF_BTF_LOAD - BPF_BTF_GET_FD_BY_ID - BPF_TASK_FD_QUERY - BPF_MAP_LOOKUP_AND_DELETE_ELEM - BPF_MAP_FREEZE - BPF_BTF_GET_NEXT_ID - BPF_MAP_LOOKUP_BATCH - BPF_MAP_LOOKUP_AND_DELETE_BATCH - BPF_MAP_UPDATE_BATCH - BPF_MAP_DELETE_BATCH - BPF_LINK_CREATE - BPF_LINK_UPDATE - BPF_LINK_GET_FD_BY_ID - BPF_LINK_GET_NEXT_ID - BPF_ENABLE_STATS - BPF_ITER_CREATE -) - -// BPF wraps SYS_BPF. -// -// Any pointers contained in attr must use the Pointer type from this package. -func BPF(cmd BPFCmd, attr unsafe.Pointer, size uintptr) (uintptr, error) { - r1, _, errNo := unix.Syscall(unix.SYS_BPF, uintptr(cmd), uintptr(attr), size) - runtime.KeepAlive(attr) - - var err error - if errNo != 0 { - err = wrappedErrno{errNo} - } - - return r1, err -} - -type BPFProgLoadAttr struct { - ProgType uint32 - InsCount uint32 - Instructions Pointer - License Pointer - LogLevel uint32 - LogSize uint32 - LogBuf Pointer - KernelVersion uint32 // since 4.1 2541517c32be - ProgFlags uint32 // since 4.11 e07b98d9bffe - ProgName BPFObjName // since 4.15 067cae47771c - ProgIfIndex uint32 // since 4.15 1f6f4cb7ba21 - ExpectedAttachType uint32 // since 4.17 5e43f899b03a - ProgBTFFd uint32 - FuncInfoRecSize uint32 - FuncInfo Pointer - FuncInfoCnt uint32 - LineInfoRecSize uint32 - LineInfo Pointer - LineInfoCnt uint32 - AttachBTFID uint32 - AttachProgFd uint32 -} - -// BPFProgLoad wraps BPF_PROG_LOAD. -func BPFProgLoad(attr *BPFProgLoadAttr) (*FD, error) { - for { - fd, err := BPF(BPF_PROG_LOAD, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - // As of ~4.20 the verifier can be interrupted by a signal, - // and returns EAGAIN in that case. - if errors.Is(err, unix.EAGAIN) { - continue - } - - if err != nil { - return nil, err - } - - return NewFD(uint32(fd)), nil - } -} - -type BPFProgAttachAttr struct { - TargetFd uint32 - AttachBpfFd uint32 - AttachType uint32 - AttachFlags uint32 - ReplaceBpfFd uint32 -} - -func BPFProgAttach(attr *BPFProgAttachAttr) error { - _, err := BPF(BPF_PROG_ATTACH, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type BPFProgDetachAttr struct { - TargetFd uint32 - AttachBpfFd uint32 - AttachType uint32 -} - -func BPFProgDetach(attr *BPFProgDetachAttr) error { - _, err := BPF(BPF_PROG_DETACH, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type BPFEnableStatsAttr struct { - StatsType uint32 -} - -func BPFEnableStats(attr *BPFEnableStatsAttr) (*FD, error) { - ptr, err := BPF(BPF_ENABLE_STATS, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, fmt.Errorf("enable stats: %w", err) - } - return NewFD(uint32(ptr)), nil - -} - -type bpfObjAttr struct { - fileName Pointer - fd uint32 - fileFlags uint32 -} - -const bpfFSType = 0xcafe4a11 - -// BPFObjPin wraps BPF_OBJ_PIN. -func BPFObjPin(fileName string, fd *FD) error { - dirName := filepath.Dir(fileName) - var statfs unix.Statfs_t - if err := unix.Statfs(dirName, &statfs); err != nil { - return err - } - if uint64(statfs.Type) != bpfFSType { - return fmt.Errorf("%s is not on a bpf filesystem", fileName) - } - - value, err := fd.Value() - if err != nil { - return err - } - - attr := bpfObjAttr{ - fileName: NewStringPointer(fileName), - fd: value, - } - _, err = BPF(BPF_OBJ_PIN, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) - if err != nil { - return fmt.Errorf("pin object %s: %w", fileName, err) - } - return nil -} - -// BPFObjGet wraps BPF_OBJ_GET. -func BPFObjGet(fileName string, flags uint32) (*FD, error) { - attr := bpfObjAttr{ - fileName: NewStringPointer(fileName), - fileFlags: flags, - } - ptr, err := BPF(BPF_OBJ_GET, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) - if err != nil { - return nil, fmt.Errorf("get object %s: %w", fileName, err) - } - return NewFD(uint32(ptr)), nil -} - -type bpfObjGetInfoByFDAttr struct { - fd uint32 - infoLen uint32 - info Pointer -} - -// BPFObjGetInfoByFD wraps BPF_OBJ_GET_INFO_BY_FD. -// -// Available from 4.13. -func BPFObjGetInfoByFD(fd *FD, info unsafe.Pointer, size uintptr) error { - value, err := fd.Value() - if err != nil { - return err - } - - attr := bpfObjGetInfoByFDAttr{ - fd: value, - infoLen: uint32(size), - info: NewPointer(info), - } - _, err = BPF(BPF_OBJ_GET_INFO_BY_FD, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) - if err != nil { - return fmt.Errorf("fd %v: %w", fd, err) - } - return nil -} - -type bpfGetFDByIDAttr struct { - id uint32 - next uint32 -} - -// BPFObjGetInfoByFD wraps BPF_*_GET_FD_BY_ID. -// -// Available from 4.13. -func BPFObjGetFDByID(cmd BPFCmd, id uint32) (*FD, error) { - attr := bpfGetFDByIDAttr{ - id: id, - } - ptr, err := BPF(cmd, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) - return NewFD(uint32(ptr)), err -} - -// BPFObjName is a null-terminated string made up of -// 'A-Za-z0-9_' characters. -type BPFObjName [unix.BPF_OBJ_NAME_LEN]byte - -// NewBPFObjName truncates the result if it is too long. -func NewBPFObjName(name string) BPFObjName { - var result BPFObjName - copy(result[:unix.BPF_OBJ_NAME_LEN-1], name) - return result -} - -type BPFMapCreateAttr struct { - MapType uint32 - KeySize uint32 - ValueSize uint32 - MaxEntries uint32 - Flags uint32 - InnerMapFd uint32 // since 4.12 56f668dfe00d - NumaNode uint32 // since 4.14 96eabe7a40aa - MapName BPFObjName // since 4.15 ad5b177bd73f - MapIfIndex uint32 - BTFFd uint32 - BTFKeyTypeID uint32 - BTFValueTypeID uint32 -} - -func BPFMapCreate(attr *BPFMapCreateAttr) (*FD, error) { - fd, err := BPF(BPF_MAP_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - - return NewFD(uint32(fd)), nil -} - -// wrappedErrno wraps syscall.Errno to prevent direct comparisons with -// syscall.E* or unix.E* constants. -// -// You should never export an error of this type. -type wrappedErrno struct { - syscall.Errno -} - -func (we wrappedErrno) Unwrap() error { - return we.Errno -} - -type syscallError struct { - error - errno syscall.Errno -} - -func SyscallError(err error, errno syscall.Errno) error { - return &syscallError{err, errno} -} - -func (se *syscallError) Is(target error) bool { - return target == se.error -} - -func (se *syscallError) Unwrap() error { - return se.errno -} diff --git a/vendor/github.com/cilium/ebpf/internal/syscall_string.go b/vendor/github.com/cilium/ebpf/internal/syscall_string.go deleted file mode 100644 index 85df047797..0000000000 --- a/vendor/github.com/cilium/ebpf/internal/syscall_string.go +++ /dev/null @@ -1,56 +0,0 @@ -// Code generated by "stringer -output syscall_string.go -type=BPFCmd"; DO NOT EDIT. - -package internal - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[BPF_MAP_CREATE-0] - _ = x[BPF_MAP_LOOKUP_ELEM-1] - _ = x[BPF_MAP_UPDATE_ELEM-2] - _ = x[BPF_MAP_DELETE_ELEM-3] - _ = x[BPF_MAP_GET_NEXT_KEY-4] - _ = x[BPF_PROG_LOAD-5] - _ = x[BPF_OBJ_PIN-6] - _ = x[BPF_OBJ_GET-7] - _ = x[BPF_PROG_ATTACH-8] - _ = x[BPF_PROG_DETACH-9] - _ = x[BPF_PROG_TEST_RUN-10] - _ = x[BPF_PROG_GET_NEXT_ID-11] - _ = x[BPF_MAP_GET_NEXT_ID-12] - _ = x[BPF_PROG_GET_FD_BY_ID-13] - _ = x[BPF_MAP_GET_FD_BY_ID-14] - _ = x[BPF_OBJ_GET_INFO_BY_FD-15] - _ = x[BPF_PROG_QUERY-16] - _ = x[BPF_RAW_TRACEPOINT_OPEN-17] - _ = x[BPF_BTF_LOAD-18] - _ = x[BPF_BTF_GET_FD_BY_ID-19] - _ = x[BPF_TASK_FD_QUERY-20] - _ = x[BPF_MAP_LOOKUP_AND_DELETE_ELEM-21] - _ = x[BPF_MAP_FREEZE-22] - _ = x[BPF_BTF_GET_NEXT_ID-23] - _ = x[BPF_MAP_LOOKUP_BATCH-24] - _ = x[BPF_MAP_LOOKUP_AND_DELETE_BATCH-25] - _ = x[BPF_MAP_UPDATE_BATCH-26] - _ = x[BPF_MAP_DELETE_BATCH-27] - _ = x[BPF_LINK_CREATE-28] - _ = x[BPF_LINK_UPDATE-29] - _ = x[BPF_LINK_GET_FD_BY_ID-30] - _ = x[BPF_LINK_GET_NEXT_ID-31] - _ = x[BPF_ENABLE_STATS-32] - _ = x[BPF_ITER_CREATE-33] -} - -const _BPFCmd_name = "BPF_MAP_CREATEBPF_MAP_LOOKUP_ELEMBPF_MAP_UPDATE_ELEMBPF_MAP_DELETE_ELEMBPF_MAP_GET_NEXT_KEYBPF_PROG_LOADBPF_OBJ_PINBPF_OBJ_GETBPF_PROG_ATTACHBPF_PROG_DETACHBPF_PROG_TEST_RUNBPF_PROG_GET_NEXT_IDBPF_MAP_GET_NEXT_IDBPF_PROG_GET_FD_BY_IDBPF_MAP_GET_FD_BY_IDBPF_OBJ_GET_INFO_BY_FDBPF_PROG_QUERYBPF_RAW_TRACEPOINT_OPENBPF_BTF_LOADBPF_BTF_GET_FD_BY_IDBPF_TASK_FD_QUERYBPF_MAP_LOOKUP_AND_DELETE_ELEMBPF_MAP_FREEZEBPF_BTF_GET_NEXT_IDBPF_MAP_LOOKUP_BATCHBPF_MAP_LOOKUP_AND_DELETE_BATCHBPF_MAP_UPDATE_BATCHBPF_MAP_DELETE_BATCHBPF_LINK_CREATEBPF_LINK_UPDATEBPF_LINK_GET_FD_BY_IDBPF_LINK_GET_NEXT_IDBPF_ENABLE_STATSBPF_ITER_CREATE" - -var _BPFCmd_index = [...]uint16{0, 14, 33, 52, 71, 91, 104, 115, 126, 141, 156, 173, 193, 212, 233, 253, 275, 289, 312, 324, 344, 361, 391, 405, 424, 444, 475, 495, 515, 530, 545, 566, 586, 602, 617} - -func (i BPFCmd) String() string { - if i < 0 || i >= BPFCmd(len(_BPFCmd_index)-1) { - return "BPFCmd(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _BPFCmd_name[_BPFCmd_index[i]:_BPFCmd_index[i+1]] -} diff --git a/vendor/github.com/cilium/ebpf/internal/tracefs/kprobe.go b/vendor/github.com/cilium/ebpf/internal/tracefs/kprobe.go new file mode 100644 index 0000000000..4059a099b0 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/tracefs/kprobe.go @@ -0,0 +1,359 @@ +package tracefs + +import ( + "crypto/rand" + "errors" + "fmt" + "os" + "path/filepath" + "runtime" + "strings" + "syscall" + + "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/unix" +) + +var ( + ErrInvalidInput = errors.New("invalid input") + + ErrInvalidMaxActive = errors.New("can only set maxactive on kretprobes") +) + +//go:generate stringer -type=ProbeType -linecomment + +type ProbeType uint8 + +const ( + Kprobe ProbeType = iota // kprobe + Uprobe // uprobe +) + +func (pt ProbeType) eventsFile() (*os.File, error) { + path, err := sanitizeTracefsPath(fmt.Sprintf("%s_events", pt.String())) + if err != nil { + return nil, err + } + + return os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0666) +} + +type ProbeArgs struct { + Type ProbeType + Symbol, Group, Path string + Offset, RefCtrOffset, Cookie uint64 + Pid, RetprobeMaxActive int + Ret bool +} + +// RandomGroup generates a pseudorandom string for use as a tracefs group name. +// Returns an error when the output string would exceed 63 characters (kernel +// limitation), when rand.Read() fails or when prefix contains characters not +// allowed by IsValidTraceID. +func RandomGroup(prefix string) (string, error) { + if !validIdentifier(prefix) { + return "", fmt.Errorf("prefix '%s' must be alphanumeric or underscore: %w", prefix, ErrInvalidInput) + } + + b := make([]byte, 8) + if _, err := rand.Read(b); err != nil { + return "", fmt.Errorf("reading random bytes: %w", err) + } + + group := fmt.Sprintf("%s_%x", prefix, b) + if len(group) > 63 { + return "", fmt.Errorf("group name '%s' cannot be longer than 63 characters: %w", group, ErrInvalidInput) + } + + return group, nil +} + +// validIdentifier implements the equivalent of a regex match +// against "^[a-zA-Z_][0-9a-zA-Z_]*$". +// +// Trace event groups, names and kernel symbols must adhere to this set +// of characters. Non-empty, first character must not be a number, all +// characters must be alphanumeric or underscore. +func validIdentifier(s string) bool { + if len(s) < 1 { + return false + } + for i, c := range []byte(s) { + switch { + case c >= 'a' && c <= 'z': + case c >= 'A' && c <= 'Z': + case c == '_': + case i > 0 && c >= '0' && c <= '9': + + default: + return false + } + } + + return true +} + +func sanitizeTracefsPath(path ...string) (string, error) { + base, err := getTracefsPath() + if err != nil { + return "", err + } + l := filepath.Join(path...) + p := filepath.Join(base, l) + if !strings.HasPrefix(p, base) { + return "", fmt.Errorf("path '%s' attempts to escape base path '%s': %w", l, base, ErrInvalidInput) + } + return p, nil +} + +// getTracefsPath will return a correct path to the tracefs mount point. +// Since kernel 4.1 tracefs should be mounted by default at /sys/kernel/tracing, +// but may be also be available at /sys/kernel/debug/tracing if debugfs is mounted. +// The available tracefs paths will depends on distribution choices. +var getTracefsPath = internal.Memoize(func() (string, error) { + for _, p := range []struct { + path string + fsType int64 + }{ + {"/sys/kernel/tracing", unix.TRACEFS_MAGIC}, + {"/sys/kernel/debug/tracing", unix.TRACEFS_MAGIC}, + // RHEL/CentOS + {"/sys/kernel/debug/tracing", unix.DEBUGFS_MAGIC}, + } { + if fsType, err := internal.FSType(p.path); err == nil && fsType == p.fsType { + return p.path, nil + } + } + + return "", errors.New("neither debugfs nor tracefs are mounted") +}) + +// sanitizeIdentifier replaces every invalid character for the tracefs api with an underscore. +// +// It is equivalent to calling regexp.MustCompile("[^a-zA-Z0-9]+").ReplaceAllString("_"). +func sanitizeIdentifier(s string) string { + var skip bool + return strings.Map(func(c rune) rune { + switch { + case c >= 'a' && c <= 'z', + c >= 'A' && c <= 'Z', + c >= '0' && c <= '9': + skip = false + return c + + case skip: + return -1 + + default: + skip = true + return '_' + } + }, s) +} + +// EventID reads a trace event's ID from tracefs given its group and name. +// The kernel requires group and name to be alphanumeric or underscore. +func EventID(group, name string) (uint64, error) { + if !validIdentifier(group) { + return 0, fmt.Errorf("invalid tracefs group: %q", group) + } + + if !validIdentifier(name) { + return 0, fmt.Errorf("invalid tracefs name: %q", name) + } + + path, err := sanitizeTracefsPath("events", group, name, "id") + if err != nil { + return 0, err + } + tid, err := internal.ReadUint64FromFile("%d\n", path) + if errors.Is(err, os.ErrNotExist) { + return 0, err + } + if err != nil { + return 0, fmt.Errorf("reading trace event ID of %s/%s: %w", group, name, err) + } + + return tid, nil +} + +func probePrefix(ret bool, maxActive int) string { + if ret { + if maxActive > 0 { + return fmt.Sprintf("r%d", maxActive) + } + return "r" + } + return "p" +} + +// Event represents an entry in a tracefs probe events file. +type Event struct { + typ ProbeType + group, name string + // event id allocated by the kernel. 0 if the event has already been removed. + id uint64 +} + +// NewEvent creates a new ephemeral trace event. +// +// Returns os.ErrNotExist if symbol is not a valid +// kernel symbol, or if it is not traceable with kprobes. Returns os.ErrExist +// if a probe with the same group and symbol already exists. Returns an error if +// args.RetprobeMaxActive is used on non kprobe types. Returns ErrNotSupported if +// the kernel is too old to support kretprobe maxactive. +func NewEvent(args ProbeArgs) (*Event, error) { + // Before attempting to create a trace event through tracefs, + // check if an event with the same group and name already exists. + // Kernels 4.x and earlier don't return os.ErrExist on writing a duplicate + // entry, so we need to rely on reads for detecting uniqueness. + eventName := sanitizeIdentifier(args.Symbol) + _, err := EventID(args.Group, eventName) + if err == nil { + return nil, fmt.Errorf("trace event %s/%s: %w", args.Group, eventName, os.ErrExist) + } + if err != nil && !errors.Is(err, os.ErrNotExist) { + return nil, fmt.Errorf("checking trace event %s/%s: %w", args.Group, eventName, err) + } + + // Open the kprobe_events file in tracefs. + f, err := args.Type.eventsFile() + if err != nil { + return nil, err + } + defer f.Close() + + var pe, token string + switch args.Type { + case Kprobe: + // The kprobe_events syntax is as follows (see Documentation/trace/kprobetrace.txt): + // p[:[GRP/]EVENT] [MOD:]SYM[+offs]|MEMADDR [FETCHARGS] : Set a probe + // r[MAXACTIVE][:[GRP/]EVENT] [MOD:]SYM[+0] [FETCHARGS] : Set a return probe + // -:[GRP/]EVENT : Clear a probe + // + // Some examples: + // r:ebpf_1234/r_my_kretprobe nf_conntrack_destroy + // p:ebpf_5678/p_my_kprobe __x64_sys_execve + // + // Leaving the kretprobe's MAXACTIVE set to 0 (or absent) will make the + // kernel default to NR_CPUS. This is desired in most eBPF cases since + // subsampling or rate limiting logic can be more accurately implemented in + // the eBPF program itself. + // See Documentation/kprobes.txt for more details. + if args.RetprobeMaxActive != 0 && !args.Ret { + return nil, ErrInvalidMaxActive + } + token = KprobeToken(args) + pe = fmt.Sprintf("%s:%s/%s %s", probePrefix(args.Ret, args.RetprobeMaxActive), args.Group, eventName, token) + case Uprobe: + // The uprobe_events syntax is as follows: + // p[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a probe + // r[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a return probe + // -:[GRP/]EVENT : Clear a probe + // + // Some examples: + // r:ebpf_1234/readline /bin/bash:0x12345 + // p:ebpf_5678/main_mySymbol /bin/mybin:0x12345(0x123) + // + // See Documentation/trace/uprobetracer.txt for more details. + if args.RetprobeMaxActive != 0 { + return nil, ErrInvalidMaxActive + } + token = UprobeToken(args) + pe = fmt.Sprintf("%s:%s/%s %s", probePrefix(args.Ret, 0), args.Group, eventName, token) + } + _, err = f.WriteString(pe) + + // Since commit 97c753e62e6c, ENOENT is correctly returned instead of EINVAL + // when trying to create a retprobe for a missing symbol. + if errors.Is(err, os.ErrNotExist) { + return nil, fmt.Errorf("token %s: not found: %w", token, err) + } + // Since commit ab105a4fb894, EILSEQ is returned when a kprobe sym+offset is resolved + // to an invalid insn boundary. The exact conditions that trigger this error are + // arch specific however. + if errors.Is(err, syscall.EILSEQ) { + return nil, fmt.Errorf("token %s: bad insn boundary: %w", token, os.ErrNotExist) + } + // ERANGE is returned when the `SYM[+offs]` token is too big and cannot + // be resolved. + if errors.Is(err, syscall.ERANGE) { + return nil, fmt.Errorf("token %s: offset too big: %w", token, os.ErrNotExist) + } + + if err != nil { + return nil, fmt.Errorf("token %s: writing '%s': %w", token, pe, err) + } + + // Get the newly-created trace event's id. + tid, err := EventID(args.Group, eventName) + if args.RetprobeMaxActive != 0 && errors.Is(err, os.ErrNotExist) { + // Kernels < 4.12 don't support maxactive and therefore auto generate + // group and event names from the symbol and offset. The symbol is used + // without any sanitization. + // See https://elixir.bootlin.com/linux/v4.10/source/kernel/trace/trace_kprobe.c#L712 + event := fmt.Sprintf("kprobes/r_%s_%d", args.Symbol, args.Offset) + if err := removeEvent(args.Type, event); err != nil { + return nil, fmt.Errorf("failed to remove spurious maxactive event: %s", err) + } + return nil, fmt.Errorf("create trace event with non-default maxactive: %w", internal.ErrNotSupported) + } + if err != nil { + return nil, fmt.Errorf("get trace event id: %w", err) + } + + evt := &Event{args.Type, args.Group, eventName, tid} + runtime.SetFinalizer(evt, (*Event).Close) + return evt, nil +} + +// Close removes the event from tracefs. +// +// Returns os.ErrClosed if the event has already been closed before. +func (evt *Event) Close() error { + if evt.id == 0 { + return os.ErrClosed + } + + evt.id = 0 + runtime.SetFinalizer(evt, nil) + pe := fmt.Sprintf("%s/%s", evt.group, evt.name) + return removeEvent(evt.typ, pe) +} + +func removeEvent(typ ProbeType, pe string) error { + f, err := typ.eventsFile() + if err != nil { + return err + } + defer f.Close() + + // See [k,u]probe_events syntax above. The probe type does not need to be specified + // for removals. + if _, err = f.WriteString("-:" + pe); err != nil { + return fmt.Errorf("remove event %q from %s: %w", pe, f.Name(), err) + } + + return nil +} + +// ID returns the tracefs ID associated with the event. +func (evt *Event) ID() uint64 { + return evt.id +} + +// Group returns the tracefs group used by the event. +func (evt *Event) Group() string { + return evt.group +} + +// KprobeToken creates the SYM[+offs] token for the tracefs api. +func KprobeToken(args ProbeArgs) string { + po := args.Symbol + + if args.Offset != 0 { + po += fmt.Sprintf("+%#x", args.Offset) + } + + return po +} diff --git a/vendor/github.com/cilium/ebpf/internal/tracefs/probetype_string.go b/vendor/github.com/cilium/ebpf/internal/tracefs/probetype_string.go new file mode 100644 index 0000000000..87cb0a059b --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/tracefs/probetype_string.go @@ -0,0 +1,24 @@ +// Code generated by "stringer -type=ProbeType -linecomment"; DO NOT EDIT. + +package tracefs + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[Kprobe-0] + _ = x[Uprobe-1] +} + +const _ProbeType_name = "kprobeuprobe" + +var _ProbeType_index = [...]uint8{0, 6, 12} + +func (i ProbeType) String() string { + if i >= ProbeType(len(_ProbeType_index)-1) { + return "ProbeType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _ProbeType_name[_ProbeType_index[i]:_ProbeType_index[i+1]] +} diff --git a/vendor/github.com/cilium/ebpf/internal/tracefs/uprobe.go b/vendor/github.com/cilium/ebpf/internal/tracefs/uprobe.go new file mode 100644 index 0000000000..994f31260d --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/tracefs/uprobe.go @@ -0,0 +1,16 @@ +package tracefs + +import "fmt" + +// UprobeToken creates the PATH:OFFSET(REF_CTR_OFFSET) token for the tracefs api. +func UprobeToken(args ProbeArgs) string { + po := fmt.Sprintf("%s:%#x", args.Path, args.Offset) + + if args.RefCtrOffset != 0 { + // This is not documented in Documentation/trace/uprobetracer.txt. + // elixir.bootlin.com/linux/v5.15-rc7/source/kernel/trace/trace.c#L5564 + po += fmt.Sprintf("(%#x)", args.RefCtrOffset) + } + + return po +} diff --git a/vendor/github.com/cilium/ebpf/internal/unix/doc.go b/vendor/github.com/cilium/ebpf/internal/unix/doc.go new file mode 100644 index 0000000000..d168d36f18 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/unix/doc.go @@ -0,0 +1,11 @@ +// Package unix re-exports Linux specific parts of golang.org/x/sys/unix. +// +// It avoids breaking compilation on other OS by providing stubs as follows: +// - Invoking a function always returns an error. +// - Errnos have distinct, non-zero values. +// - Constants have distinct but meaningless values. +// - Types use the same names for members, but may or may not follow the +// Linux layout. +package unix + +// Note: please don't add any custom API to this package. Use internal/sys instead. diff --git a/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go b/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go index 9aa70fa78c..7c9705919a 100644 --- a/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go +++ b/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go @@ -1,208 +1,202 @@ //go:build linux -// +build linux package unix import ( - "bytes" "syscall" linux "golang.org/x/sys/unix" ) const ( - ENOENT = linux.ENOENT - EEXIST = linux.EEXIST - EAGAIN = linux.EAGAIN - ENOSPC = linux.ENOSPC - EINVAL = linux.EINVAL - EPOLLIN = linux.EPOLLIN - EINTR = linux.EINTR - EPERM = linux.EPERM - ESRCH = linux.ESRCH - ENODEV = linux.ENODEV - EBADF = linux.EBADF - E2BIG = linux.E2BIG - // ENOTSUPP is not the same as ENOTSUP or EOPNOTSUP - ENOTSUPP = syscall.Errno(0x20c) - - BPF_F_NO_PREALLOC = linux.BPF_F_NO_PREALLOC - BPF_F_NUMA_NODE = linux.BPF_F_NUMA_NODE - BPF_F_RDONLY = linux.BPF_F_RDONLY - BPF_F_WRONLY = linux.BPF_F_WRONLY - BPF_F_RDONLY_PROG = linux.BPF_F_RDONLY_PROG - BPF_F_WRONLY_PROG = linux.BPF_F_WRONLY_PROG - BPF_F_SLEEPABLE = linux.BPF_F_SLEEPABLE - BPF_F_MMAPABLE = linux.BPF_F_MMAPABLE - BPF_F_INNER_MAP = linux.BPF_F_INNER_MAP - BPF_OBJ_NAME_LEN = linux.BPF_OBJ_NAME_LEN - BPF_TAG_SIZE = linux.BPF_TAG_SIZE - BPF_RINGBUF_BUSY_BIT = linux.BPF_RINGBUF_BUSY_BIT - BPF_RINGBUF_DISCARD_BIT = linux.BPF_RINGBUF_DISCARD_BIT - BPF_RINGBUF_HDR_SZ = linux.BPF_RINGBUF_HDR_SZ - SYS_BPF = linux.SYS_BPF - F_DUPFD_CLOEXEC = linux.F_DUPFD_CLOEXEC - EPOLL_CTL_ADD = linux.EPOLL_CTL_ADD - EPOLL_CLOEXEC = linux.EPOLL_CLOEXEC - O_CLOEXEC = linux.O_CLOEXEC - O_NONBLOCK = linux.O_NONBLOCK - PROT_READ = linux.PROT_READ - PROT_WRITE = linux.PROT_WRITE - MAP_SHARED = linux.MAP_SHARED - PERF_ATTR_SIZE_VER1 = linux.PERF_ATTR_SIZE_VER1 - PERF_TYPE_SOFTWARE = linux.PERF_TYPE_SOFTWARE - PERF_TYPE_TRACEPOINT = linux.PERF_TYPE_TRACEPOINT - PERF_COUNT_SW_BPF_OUTPUT = linux.PERF_COUNT_SW_BPF_OUTPUT - PERF_EVENT_IOC_DISABLE = linux.PERF_EVENT_IOC_DISABLE - PERF_EVENT_IOC_ENABLE = linux.PERF_EVENT_IOC_ENABLE - PERF_EVENT_IOC_SET_BPF = linux.PERF_EVENT_IOC_SET_BPF - PerfBitWatermark = linux.PerfBitWatermark - PERF_SAMPLE_RAW = linux.PERF_SAMPLE_RAW - PERF_FLAG_FD_CLOEXEC = linux.PERF_FLAG_FD_CLOEXEC - RLIM_INFINITY = linux.RLIM_INFINITY - RLIMIT_MEMLOCK = linux.RLIMIT_MEMLOCK - BPF_STATS_RUN_TIME = linux.BPF_STATS_RUN_TIME - PERF_RECORD_LOST = linux.PERF_RECORD_LOST - PERF_RECORD_SAMPLE = linux.PERF_RECORD_SAMPLE - AT_FDCWD = linux.AT_FDCWD - RENAME_NOREPLACE = linux.RENAME_NOREPLACE + ENOENT = linux.ENOENT + EEXIST = linux.EEXIST + EAGAIN = linux.EAGAIN + ENOSPC = linux.ENOSPC + EINVAL = linux.EINVAL + EPOLLIN = linux.EPOLLIN + EINTR = linux.EINTR + EPERM = linux.EPERM + ESRCH = linux.ESRCH + ENODEV = linux.ENODEV + EBADF = linux.EBADF + E2BIG = linux.E2BIG + EFAULT = linux.EFAULT + EACCES = linux.EACCES + EILSEQ = linux.EILSEQ + EOPNOTSUPP = linux.EOPNOTSUPP ) -// Statfs_t is a wrapper -type Statfs_t = linux.Statfs_t +const ( + BPF_F_NO_PREALLOC = linux.BPF_F_NO_PREALLOC + BPF_F_NUMA_NODE = linux.BPF_F_NUMA_NODE + BPF_F_RDONLY = linux.BPF_F_RDONLY + BPF_F_WRONLY = linux.BPF_F_WRONLY + BPF_F_RDONLY_PROG = linux.BPF_F_RDONLY_PROG + BPF_F_WRONLY_PROG = linux.BPF_F_WRONLY_PROG + BPF_F_SLEEPABLE = linux.BPF_F_SLEEPABLE + BPF_F_XDP_HAS_FRAGS = linux.BPF_F_XDP_HAS_FRAGS + BPF_F_MMAPABLE = linux.BPF_F_MMAPABLE + BPF_F_INNER_MAP = linux.BPF_F_INNER_MAP + BPF_F_KPROBE_MULTI_RETURN = linux.BPF_F_KPROBE_MULTI_RETURN + BPF_OBJ_NAME_LEN = linux.BPF_OBJ_NAME_LEN + BPF_TAG_SIZE = linux.BPF_TAG_SIZE + BPF_RINGBUF_BUSY_BIT = linux.BPF_RINGBUF_BUSY_BIT + BPF_RINGBUF_DISCARD_BIT = linux.BPF_RINGBUF_DISCARD_BIT + BPF_RINGBUF_HDR_SZ = linux.BPF_RINGBUF_HDR_SZ + SYS_BPF = linux.SYS_BPF + F_DUPFD_CLOEXEC = linux.F_DUPFD_CLOEXEC + EPOLL_CTL_ADD = linux.EPOLL_CTL_ADD + EPOLL_CLOEXEC = linux.EPOLL_CLOEXEC + O_CLOEXEC = linux.O_CLOEXEC + O_NONBLOCK = linux.O_NONBLOCK + PROT_NONE = linux.PROT_NONE + PROT_READ = linux.PROT_READ + PROT_WRITE = linux.PROT_WRITE + MAP_ANON = linux.MAP_ANON + MAP_SHARED = linux.MAP_SHARED + MAP_PRIVATE = linux.MAP_PRIVATE + PERF_ATTR_SIZE_VER1 = linux.PERF_ATTR_SIZE_VER1 + PERF_TYPE_SOFTWARE = linux.PERF_TYPE_SOFTWARE + PERF_TYPE_TRACEPOINT = linux.PERF_TYPE_TRACEPOINT + PERF_COUNT_SW_BPF_OUTPUT = linux.PERF_COUNT_SW_BPF_OUTPUT + PERF_EVENT_IOC_DISABLE = linux.PERF_EVENT_IOC_DISABLE + PERF_EVENT_IOC_ENABLE = linux.PERF_EVENT_IOC_ENABLE + PERF_EVENT_IOC_SET_BPF = linux.PERF_EVENT_IOC_SET_BPF + PerfBitWatermark = linux.PerfBitWatermark + PerfBitWriteBackward = linux.PerfBitWriteBackward + PERF_SAMPLE_RAW = linux.PERF_SAMPLE_RAW + PERF_FLAG_FD_CLOEXEC = linux.PERF_FLAG_FD_CLOEXEC + RLIM_INFINITY = linux.RLIM_INFINITY + RLIMIT_MEMLOCK = linux.RLIMIT_MEMLOCK + BPF_STATS_RUN_TIME = linux.BPF_STATS_RUN_TIME + PERF_RECORD_LOST = linux.PERF_RECORD_LOST + PERF_RECORD_SAMPLE = linux.PERF_RECORD_SAMPLE + AT_FDCWD = linux.AT_FDCWD + RENAME_NOREPLACE = linux.RENAME_NOREPLACE + SO_ATTACH_BPF = linux.SO_ATTACH_BPF + SO_DETACH_BPF = linux.SO_DETACH_BPF + SOL_SOCKET = linux.SOL_SOCKET + SIGPROF = linux.SIGPROF + SIG_BLOCK = linux.SIG_BLOCK + SIG_UNBLOCK = linux.SIG_UNBLOCK + EM_NONE = linux.EM_NONE + EM_BPF = linux.EM_BPF + BPF_FS_MAGIC = linux.BPF_FS_MAGIC + TRACEFS_MAGIC = linux.TRACEFS_MAGIC + DEBUGFS_MAGIC = linux.DEBUGFS_MAGIC +) -// Rlimit is a wrapper +type Statfs_t = linux.Statfs_t +type Stat_t = linux.Stat_t type Rlimit = linux.Rlimit +type Signal = linux.Signal +type Sigset_t = linux.Sigset_t +type PerfEventMmapPage = linux.PerfEventMmapPage +type EpollEvent = linux.EpollEvent +type PerfEventAttr = linux.PerfEventAttr +type Utsname = linux.Utsname -// Syscall is a wrapper func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) { return linux.Syscall(trap, a1, a2, a3) } -// FcntlInt is a wrapper +func PthreadSigmask(how int, set, oldset *Sigset_t) error { + return linux.PthreadSigmask(how, set, oldset) +} + func FcntlInt(fd uintptr, cmd, arg int) (int, error) { return linux.FcntlInt(fd, cmd, arg) } -// IoctlSetInt is a wrapper func IoctlSetInt(fd int, req uint, value int) error { return linux.IoctlSetInt(fd, req, value) } -// Statfs is a wrapper func Statfs(path string, buf *Statfs_t) (err error) { return linux.Statfs(path, buf) } -// Close is a wrapper func Close(fd int) (err error) { return linux.Close(fd) } -// EpollEvent is a wrapper -type EpollEvent = linux.EpollEvent - -// EpollWait is a wrapper func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { return linux.EpollWait(epfd, events, msec) } -// EpollCtl is a wrapper func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) { return linux.EpollCtl(epfd, op, fd, event) } -// Eventfd is a wrapper func Eventfd(initval uint, flags int) (fd int, err error) { return linux.Eventfd(initval, flags) } -// Write is a wrapper func Write(fd int, p []byte) (n int, err error) { return linux.Write(fd, p) } -// EpollCreate1 is a wrapper func EpollCreate1(flag int) (fd int, err error) { return linux.EpollCreate1(flag) } -// PerfEventMmapPage is a wrapper -type PerfEventMmapPage linux.PerfEventMmapPage - -// SetNonblock is a wrapper func SetNonblock(fd int, nonblocking bool) (err error) { return linux.SetNonblock(fd, nonblocking) } -// Mmap is a wrapper func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { return linux.Mmap(fd, offset, length, prot, flags) } -// Munmap is a wrapper func Munmap(b []byte) (err error) { return linux.Munmap(b) } -// PerfEventAttr is a wrapper -type PerfEventAttr = linux.PerfEventAttr - -// PerfEventOpen is a wrapper func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { return linux.PerfEventOpen(attr, pid, cpu, groupFd, flags) } -// Utsname is a wrapper -type Utsname = linux.Utsname - -// Uname is a wrapper func Uname(buf *Utsname) (err error) { return linux.Uname(buf) } -// Getpid is a wrapper func Getpid() int { return linux.Getpid() } -// Gettid is a wrapper func Gettid() int { return linux.Gettid() } -// Tgkill is a wrapper func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) { return linux.Tgkill(tgid, tid, sig) } -// BytePtrFromString is a wrapper func BytePtrFromString(s string) (*byte, error) { return linux.BytePtrFromString(s) } -// ByteSliceToString is a wrapper func ByteSliceToString(s []byte) string { return linux.ByteSliceToString(s) } -// Renameat2 is a wrapper func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) error { return linux.Renameat2(olddirfd, oldpath, newdirfd, newpath, flags) } -func KernelRelease() (string, error) { - var uname Utsname - err := Uname(&uname) - if err != nil { - return "", err - } +func Prlimit(pid, resource int, new, old *Rlimit) error { + return linux.Prlimit(pid, resource, new, old) +} - end := bytes.IndexByte(uname.Release[:], 0) - release := string(uname.Release[:end]) - return release, nil +func Open(path string, mode int, perm uint32) (int, error) { + return linux.Open(path, mode, perm) } -func Prlimit(pid, resource int, new, old *Rlimit) error { - return linux.Prlimit(pid, resource, new, old) +func Fstat(fd int, stat *Stat_t) error { + return linux.Fstat(fd, stat) +} + +func SetsockoptInt(fd, level, opt, value int) error { + return linux.SetsockoptInt(fd, level, opt, value) } diff --git a/vendor/github.com/cilium/ebpf/internal/unix/types_other.go b/vendor/github.com/cilium/ebpf/internal/unix/types_other.go index 4f50d896eb..5e86b5052a 100644 --- a/vendor/github.com/cilium/ebpf/internal/unix/types_other.go +++ b/vendor/github.com/cilium/ebpf/internal/unix/types_other.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux package unix @@ -11,65 +10,87 @@ import ( var errNonLinux = fmt.Errorf("unsupported platform %s/%s", runtime.GOOS, runtime.GOARCH) +// Errnos are distinct and non-zero. const ( - ENOENT = syscall.ENOENT - EEXIST = syscall.EEXIST - EAGAIN = syscall.EAGAIN - ENOSPC = syscall.ENOSPC - EINVAL = syscall.EINVAL - EINTR = syscall.EINTR - EPERM = syscall.EPERM - ESRCH = syscall.ESRCH - ENODEV = syscall.ENODEV - EBADF = syscall.Errno(0) - E2BIG = syscall.Errno(0) - // ENOTSUPP is not the same as ENOTSUP or EOPNOTSUP - ENOTSUPP = syscall.Errno(0x20c) - - BPF_F_NO_PREALLOC = 0 - BPF_F_NUMA_NODE = 0 - BPF_F_RDONLY = 0 - BPF_F_WRONLY = 0 - BPF_F_RDONLY_PROG = 0 - BPF_F_WRONLY_PROG = 0 - BPF_F_SLEEPABLE = 0 - BPF_F_MMAPABLE = 0 - BPF_F_INNER_MAP = 0 - BPF_OBJ_NAME_LEN = 0x10 - BPF_TAG_SIZE = 0x8 - BPF_RINGBUF_BUSY_BIT = 0 - BPF_RINGBUF_DISCARD_BIT = 0 - BPF_RINGBUF_HDR_SZ = 0 - SYS_BPF = 321 - F_DUPFD_CLOEXEC = 0x406 - EPOLLIN = 0x1 - EPOLL_CTL_ADD = 0x1 - EPOLL_CLOEXEC = 0x80000 - O_CLOEXEC = 0x80000 - O_NONBLOCK = 0x800 - PROT_READ = 0x1 - PROT_WRITE = 0x2 - MAP_SHARED = 0x1 - PERF_ATTR_SIZE_VER1 = 0 - PERF_TYPE_SOFTWARE = 0x1 - PERF_TYPE_TRACEPOINT = 0 - PERF_COUNT_SW_BPF_OUTPUT = 0xa - PERF_EVENT_IOC_DISABLE = 0 - PERF_EVENT_IOC_ENABLE = 0 - PERF_EVENT_IOC_SET_BPF = 0 - PerfBitWatermark = 0x4000 - PERF_SAMPLE_RAW = 0x400 - PERF_FLAG_FD_CLOEXEC = 0x8 - RLIM_INFINITY = 0x7fffffffffffffff - RLIMIT_MEMLOCK = 8 - BPF_STATS_RUN_TIME = 0 - PERF_RECORD_LOST = 2 - PERF_RECORD_SAMPLE = 9 - AT_FDCWD = -0x2 - RENAME_NOREPLACE = 0x1 + ENOENT syscall.Errno = iota + 1 + EEXIST + EAGAIN + ENOSPC + EINVAL + EINTR + EPERM + ESRCH + ENODEV + EBADF + E2BIG + EFAULT + EACCES + EILSEQ + EOPNOTSUPP +) + +// Constants are distinct to avoid breaking switch statements. +const ( + BPF_F_NO_PREALLOC = iota + BPF_F_NUMA_NODE + BPF_F_RDONLY + BPF_F_WRONLY + BPF_F_RDONLY_PROG + BPF_F_WRONLY_PROG + BPF_F_SLEEPABLE + BPF_F_MMAPABLE + BPF_F_INNER_MAP + BPF_F_KPROBE_MULTI_RETURN + BPF_F_XDP_HAS_FRAGS + BPF_OBJ_NAME_LEN + BPF_TAG_SIZE + BPF_RINGBUF_BUSY_BIT + BPF_RINGBUF_DISCARD_BIT + BPF_RINGBUF_HDR_SZ + SYS_BPF + F_DUPFD_CLOEXEC + EPOLLIN + EPOLL_CTL_ADD + EPOLL_CLOEXEC + O_CLOEXEC + O_NONBLOCK + PROT_NONE + PROT_READ + PROT_WRITE + MAP_ANON + MAP_SHARED + MAP_PRIVATE + PERF_ATTR_SIZE_VER1 + PERF_TYPE_SOFTWARE + PERF_TYPE_TRACEPOINT + PERF_COUNT_SW_BPF_OUTPUT + PERF_EVENT_IOC_DISABLE + PERF_EVENT_IOC_ENABLE + PERF_EVENT_IOC_SET_BPF + PerfBitWatermark + PerfBitWriteBackward + PERF_SAMPLE_RAW + PERF_FLAG_FD_CLOEXEC + RLIM_INFINITY + RLIMIT_MEMLOCK + BPF_STATS_RUN_TIME + PERF_RECORD_LOST + PERF_RECORD_SAMPLE + AT_FDCWD + RENAME_NOREPLACE + SO_ATTACH_BPF + SO_DETACH_BPF + SOL_SOCKET + SIGPROF + SIG_BLOCK + SIG_UNBLOCK + EM_NONE + EM_BPF + BPF_FS_MAGIC + TRACEFS_MAGIC + DEBUGFS_MAGIC ) -// Statfs_t is a wrapper type Statfs_t struct { Type int64 Bsize int64 @@ -85,70 +106,81 @@ type Statfs_t struct { Spare [4]int64 } -// Rlimit is a wrapper +type Stat_t struct { + Dev uint64 + Ino uint64 + Nlink uint64 + Mode uint32 + Uid uint32 + Gid uint32 + _ int32 + Rdev uint64 + Size int64 + Blksize int64 + Blocks int64 +} + type Rlimit struct { Cur uint64 Max uint64 } -// Syscall is a wrapper +type Signal int + +type Sigset_t struct { + Val [4]uint64 +} + func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) { - return 0, 0, syscall.Errno(1) + return 0, 0, syscall.ENOTSUP +} + +func PthreadSigmask(how int, set, oldset *Sigset_t) error { + return errNonLinux } -// FcntlInt is a wrapper func FcntlInt(fd uintptr, cmd, arg int) (int, error) { return -1, errNonLinux } -// IoctlSetInt is a wrapper func IoctlSetInt(fd int, req uint, value int) error { return errNonLinux } -// Statfs is a wrapper func Statfs(path string, buf *Statfs_t) error { return errNonLinux } -// Close is a wrapper func Close(fd int) (err error) { return errNonLinux } -// EpollEvent is a wrapper type EpollEvent struct { Events uint32 Fd int32 Pad int32 } -// EpollWait is a wrapper func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { return 0, errNonLinux } -// EpollCtl is a wrapper func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) { return errNonLinux } -// Eventfd is a wrapper func Eventfd(initval uint, flags int) (fd int, err error) { return 0, errNonLinux } -// Write is a wrapper func Write(fd int, p []byte) (n int, err error) { return 0, errNonLinux } -// EpollCreate1 is a wrapper func EpollCreate1(flag int) (fd int, err error) { return 0, errNonLinux } -// PerfEventMmapPage is a wrapper type PerfEventMmapPage struct { Version uint32 Compat_version uint32 @@ -175,22 +207,18 @@ type PerfEventMmapPage struct { Aux_size uint64 } -// SetNonblock is a wrapper func SetNonblock(fd int, nonblocking bool) (err error) { return errNonLinux } -// Mmap is a wrapper func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { return []byte{}, errNonLinux } -// Munmap is a wrapper func Munmap(b []byte) (err error) { return errNonLinux } -// PerfEventAttr is a wrapper type PerfEventAttr struct { Type uint32 Size uint32 @@ -212,56 +240,55 @@ type PerfEventAttr struct { Sample_max_stack uint16 } -// PerfEventOpen is a wrapper func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { return 0, errNonLinux } -// Utsname is a wrapper type Utsname struct { Release [65]byte Version [65]byte } -// Uname is a wrapper func Uname(buf *Utsname) (err error) { return errNonLinux } -// Getpid is a wrapper func Getpid() int { return -1 } -// Gettid is a wrapper func Gettid() int { return -1 } -// Tgkill is a wrapper func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) { return errNonLinux } -// BytePtrFromString is a wrapper func BytePtrFromString(s string) (*byte, error) { return nil, errNonLinux } -// ByteSliceToString is a wrapper func ByteSliceToString(s []byte) string { return "" } -// Renameat2 is a wrapper func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) error { return errNonLinux } -func KernelRelease() (string, error) { - return "", errNonLinux +func Prlimit(pid, resource int, new, old *Rlimit) error { + return errNonLinux } -func Prlimit(pid, resource int, new, old *Rlimit) error { +func Open(path string, mode int, perm uint32) (int, error) { + return -1, errNonLinux +} + +func Fstat(fd int, stat *Stat_t) error { + return errNonLinux +} + +func SetsockoptInt(fd, level, opt, value int) error { return errNonLinux } diff --git a/vendor/github.com/cilium/ebpf/internal/vdso.go b/vendor/github.com/cilium/ebpf/internal/vdso.go new file mode 100644 index 0000000000..10e639bf06 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/vdso.go @@ -0,0 +1,153 @@ +package internal + +import ( + "debug/elf" + "encoding/binary" + "errors" + "fmt" + "io" + "math" + "os" + + "github.com/cilium/ebpf/internal/unix" +) + +var ( + errAuxvNoVDSO = errors.New("no vdso address found in auxv") +) + +// vdsoVersion returns the LINUX_VERSION_CODE embedded in the vDSO library +// linked into the current process image. +func vdsoVersion() (uint32, error) { + // Read data from the auxiliary vector, which is normally passed directly + // to the process. Go does not expose that data, so we must read it from procfs. + // https://man7.org/linux/man-pages/man3/getauxval.3.html + av, err := os.Open("/proc/self/auxv") + if errors.Is(err, unix.EACCES) { + return 0, fmt.Errorf("opening auxv: %w (process may not be dumpable due to file capabilities)", err) + } + if err != nil { + return 0, fmt.Errorf("opening auxv: %w", err) + } + defer av.Close() + + vdsoAddr, err := vdsoMemoryAddress(av) + if err != nil { + return 0, fmt.Errorf("finding vDSO memory address: %w", err) + } + + // Use /proc/self/mem rather than unsafe.Pointer tricks. + mem, err := os.Open("/proc/self/mem") + if err != nil { + return 0, fmt.Errorf("opening mem: %w", err) + } + defer mem.Close() + + // Open ELF at provided memory address, as offset into /proc/self/mem. + c, err := vdsoLinuxVersionCode(io.NewSectionReader(mem, int64(vdsoAddr), math.MaxInt64)) + if err != nil { + return 0, fmt.Errorf("reading linux version code: %w", err) + } + + return c, nil +} + +// vdsoMemoryAddress returns the memory address of the vDSO library +// linked into the current process image. r is an io.Reader into an auxv blob. +func vdsoMemoryAddress(r io.Reader) (uint64, error) { + const ( + _AT_NULL = 0 // End of vector + _AT_SYSINFO_EHDR = 33 // Offset to vDSO blob in process image + ) + + // Loop through all tag/value pairs in auxv until we find `AT_SYSINFO_EHDR`, + // the address of a page containing the virtual Dynamic Shared Object (vDSO). + aux := struct{ Tag, Val uint64 }{} + for { + if err := binary.Read(r, NativeEndian, &aux); err != nil { + return 0, fmt.Errorf("reading auxv entry: %w", err) + } + + switch aux.Tag { + case _AT_SYSINFO_EHDR: + if aux.Val != 0 { + return aux.Val, nil + } + return 0, fmt.Errorf("invalid vDSO address in auxv") + // _AT_NULL is always the last tag/val pair in the aux vector + // and can be treated like EOF. + case _AT_NULL: + return 0, errAuxvNoVDSO + } + } +} + +// format described at https://www.man7.org/linux/man-pages/man5/elf.5.html in section 'Notes (Nhdr)' +type elfNoteHeader struct { + NameSize int32 + DescSize int32 + Type int32 +} + +// vdsoLinuxVersionCode returns the LINUX_VERSION_CODE embedded in +// the ELF notes section of the binary provided by the reader. +func vdsoLinuxVersionCode(r io.ReaderAt) (uint32, error) { + hdr, err := NewSafeELFFile(r) + if err != nil { + return 0, fmt.Errorf("reading vDSO ELF: %w", err) + } + + sections := hdr.SectionsByType(elf.SHT_NOTE) + if len(sections) == 0 { + return 0, fmt.Errorf("no note section found in vDSO ELF") + } + + for _, sec := range sections { + sr := sec.Open() + var n elfNoteHeader + + // Read notes until we find one named 'Linux'. + for { + if err := binary.Read(sr, hdr.ByteOrder, &n); err != nil { + if errors.Is(err, io.EOF) { + // We looked at all the notes in this section + break + } + return 0, fmt.Errorf("reading note header: %w", err) + } + + // If a note name is defined, it follows the note header. + var name string + if n.NameSize > 0 { + // Read the note name, aligned to 4 bytes. + buf := make([]byte, Align(n.NameSize, 4)) + if err := binary.Read(sr, hdr.ByteOrder, &buf); err != nil { + return 0, fmt.Errorf("reading note name: %w", err) + } + + // Read nul-terminated string. + name = unix.ByteSliceToString(buf[:n.NameSize]) + } + + // If a note descriptor is defined, it follows the name. + // It is possible for a note to have a descriptor but not a name. + if n.DescSize > 0 { + // LINUX_VERSION_CODE is a uint32 value. + if name == "Linux" && n.DescSize == 4 && n.Type == 0 { + var version uint32 + if err := binary.Read(sr, hdr.ByteOrder, &version); err != nil { + return 0, fmt.Errorf("reading note descriptor: %w", err) + } + return version, nil + } + + // Discard the note descriptor if it exists but we're not interested in it. + if _, err := io.CopyN(io.Discard, sr, int64(Align(n.DescSize, 4))); err != nil { + return 0, err + } + } + } + } + + return 0, fmt.Errorf("no Linux note in ELF") +} diff --git a/vendor/github.com/cilium/ebpf/internal/version.go b/vendor/github.com/cilium/ebpf/internal/version.go index 4915e58376..9b17ffb44d 100644 --- a/vendor/github.com/cilium/ebpf/internal/version.go +++ b/vendor/github.com/cilium/ebpf/internal/version.go @@ -2,9 +2,6 @@ package internal import ( "fmt" - "os" - "regexp" - "sync" "github.com/cilium/ebpf/internal/unix" ) @@ -17,20 +14,6 @@ const ( MagicKernelVersion = 0xFFFFFFFE ) -var ( - // Match between one and three decimals separated by dots, with the last - // segment (patch level) being optional on some kernels. - // The x.y.z string must appear at the start of a string or right after - // whitespace to prevent sequences like 'x.y.z-a.b.c' from matching 'a.b.c'. - rgxKernelVersion = regexp.MustCompile(`(?:\A|\s)\d{1,3}\.\d{1,3}(?:\.\d{1,3})?`) - - kernelVersion = struct { - once sync.Once - version Version - err error - }{} -) - // A Version in the form Major.Minor.Patch. type Version [3]uint16 @@ -46,6 +29,15 @@ func NewVersion(ver string) (Version, error) { return Version{major, minor, patch}, nil } +// NewVersionFromCode creates a version from a LINUX_VERSION_CODE. +func NewVersionFromCode(code uint32) Version { + return Version{ + uint16(uint8(code >> 16)), + uint16(uint8(code >> 8)), + uint16(uint8(code)), + } +} + func (v Version) String() string { if v[2] == 0 { return fmt.Sprintf("v%d.%d", v[0], v[1]) @@ -87,77 +79,28 @@ func (v Version) Kernel() uint32 { } // KernelVersion returns the version of the currently running kernel. -func KernelVersion() (Version, error) { - kernelVersion.once.Do(func() { - kernelVersion.version, kernelVersion.err = detectKernelVersion() - }) - - if kernelVersion.err != nil { - return Version{}, kernelVersion.err - } - return kernelVersion.version, nil -} +var KernelVersion = Memoize(func() (Version, error) { + return detectKernelVersion() +}) -// detectKernelVersion returns the version of the running kernel. It scans the -// following sources in order: /proc/version_signature, uname -v, uname -r. -// In each of those locations, the last-appearing x.y(.z) value is selected -// for parsing. The first location that yields a usable version number is -// returned. +// detectKernelVersion returns the version of the running kernel. func detectKernelVersion() (Version, error) { - - // Try reading /proc/version_signature for Ubuntu compatibility. - // Example format: Ubuntu 4.15.0-91.92-generic 4.15.18 - // This method exists in the kernel itself, see d18acd15c - // ("perf tools: Fix kernel version error in ubuntu"). - if pvs, err := os.ReadFile("/proc/version_signature"); err == nil { - // If /proc/version_signature exists, failing to parse it is an error. - // It only exists on Ubuntu, where the real patch level is not obtainable - // through any other method. - v, err := findKernelVersion(string(pvs)) - if err != nil { - return Version{}, err - } - return v, nil - } - - var uname unix.Utsname - if err := unix.Uname(&uname); err != nil { - return Version{}, fmt.Errorf("calling uname: %w", err) - } - - // Debian puts the version including the patch level in uname.Version. - // It is not an error if there's no version number in uname.Version, - // as most distributions don't use it. Parsing can continue on uname.Release. - // Example format: #1 SMP Debian 4.19.37-5+deb10u2 (2019-08-08) - if v, err := findKernelVersion(unix.ByteSliceToString(uname.Version[:])); err == nil { - return v, nil - } - - // Most other distributions have the full kernel version including patch - // level in uname.Release. - // Example format: 4.19.0-5-amd64, 5.5.10-arch1-1 - v, err := findKernelVersion(unix.ByteSliceToString(uname.Release[:])) + vc, err := vdsoVersion() if err != nil { return Version{}, err } - - return v, nil + return NewVersionFromCode(vc), nil } -// findKernelVersion matches s against rgxKernelVersion and parses the result -// into a Version. If s contains multiple matches, the last entry is selected. -func findKernelVersion(s string) (Version, error) { - m := rgxKernelVersion.FindAllString(s, -1) - if m == nil { - return Version{}, fmt.Errorf("no kernel version in string: %s", s) - } - // Pick the last match of the string in case there are multiple. - s = m[len(m)-1] - - v, err := NewVersion(s) - if err != nil { - return Version{}, fmt.Errorf("parsing version string %s: %w", s, err) +// KernelRelease returns the release string of the running kernel. +// Its format depends on the Linux distribution and corresponds to directory +// names in /lib/modules by convention. Some examples are 5.15.17-1-lts and +// 4.19.0-16-amd64. +func KernelRelease() (string, error) { + var uname unix.Utsname + if err := unix.Uname(&uname); err != nil { + return "", fmt.Errorf("uname failed: %w", err) } - return v, nil + return unix.ByteSliceToString(uname.Release[:]), nil } diff --git a/vendor/github.com/cilium/ebpf/link/cgroup.go b/vendor/github.com/cilium/ebpf/link/cgroup.go index 5540bb068c..58e85fe9d4 100644 --- a/vendor/github.com/cilium/ebpf/link/cgroup.go +++ b/vendor/github.com/cilium/ebpf/link/cgroup.go @@ -10,10 +10,15 @@ import ( type cgroupAttachFlags uint32 -// cgroup attach flags const ( + // Allow programs attached to sub-cgroups to override the verdict of this + // program. flagAllowOverride cgroupAttachFlags = 1 << iota + // Allow attaching multiple programs to the cgroup. Only works if the cgroup + // has zero or more programs attached using the Multi flag. Implies override. flagAllowMulti + // Set automatically by progAttachCgroup.Update(). Used for updating a + // specific given program attached in multi-mode. flagReplace ) @@ -27,45 +32,45 @@ type CgroupOptions struct { } // AttachCgroup links a BPF program to a cgroup. -func AttachCgroup(opts CgroupOptions) (Link, error) { +// +// If the running kernel doesn't support bpf_link, attempts to emulate its +// semantics using the legacy PROG_ATTACH mechanism. If bpf_link is not +// available, the returned [Link] will not support pinning to bpffs. +// +// If you need more control over attachment flags or the attachment mechanism +// used, look at [RawAttachProgram] and [AttachRawLink] instead. +func AttachCgroup(opts CgroupOptions) (cg Link, err error) { cgroup, err := os.Open(opts.Path) if err != nil { return nil, fmt.Errorf("can't open cgroup: %s", err) } - - clone, err := opts.Program.Clone() - if err != nil { + defer func() { + if _, ok := cg.(*progAttachCgroup); ok { + // Skip closing the cgroup handle if we return a valid progAttachCgroup, + // where the handle is retained to implement Update(). + return + } cgroup.Close() - return nil, err + }() + + cg, err = newLinkCgroup(cgroup, opts.Attach, opts.Program) + if err == nil { + return cg, nil } - var cg Link - cg, err = newLinkCgroup(cgroup, opts.Attach, clone) if errors.Is(err, ErrNotSupported) { - cg, err = newProgAttachCgroup(cgroup, opts.Attach, clone, flagAllowMulti) + cg, err = newProgAttachCgroup(cgroup, opts.Attach, opts.Program, flagAllowMulti) } if errors.Is(err, ErrNotSupported) { - cg, err = newProgAttachCgroup(cgroup, opts.Attach, clone, flagAllowOverride) + cg, err = newProgAttachCgroup(cgroup, opts.Attach, opts.Program, flagAllowOverride) } if err != nil { - cgroup.Close() - clone.Close() return nil, err } return cg, nil } -// LoadPinnedCgroup loads a pinned cgroup from a bpffs. -func LoadPinnedCgroup(fileName string, opts *ebpf.LoadPinOptions) (Link, error) { - link, err := LoadPinnedRawLink(fileName, CgroupType, opts) - if err != nil { - return nil, err - } - - return &linkCgroup{*link}, nil -} - type progAttachCgroup struct { cgroup *os.File current *ebpf.Program @@ -77,6 +82,8 @@ var _ Link = (*progAttachCgroup)(nil) func (cg *progAttachCgroup) isLink() {} +// newProgAttachCgroup attaches prog to cgroup using BPF_PROG_ATTACH. +// cgroup and prog are retained by [progAttachCgroup]. func newProgAttachCgroup(cgroup *os.File, attach ebpf.AttachType, prog *ebpf.Program, flags cgroupAttachFlags) (*progAttachCgroup, error) { if flags&flagAllowMulti > 0 { if err := haveProgAttachReplace(); err != nil { @@ -84,17 +91,24 @@ func newProgAttachCgroup(cgroup *os.File, attach ebpf.AttachType, prog *ebpf.Pro } } - err := RawAttachProgram(RawAttachProgramOptions{ + // Use a program handle that cannot be closed by the caller. + clone, err := prog.Clone() + if err != nil { + return nil, err + } + + err = RawAttachProgram(RawAttachProgramOptions{ Target: int(cgroup.Fd()), - Program: prog, + Program: clone, Flags: uint32(flags), Attach: attach, }) if err != nil { + clone.Close() return nil, fmt.Errorf("cgroup: %w", err) } - return &progAttachCgroup{cgroup, prog, attach, flags}, nil + return &progAttachCgroup{cgroup, clone, attach, flags}, nil } func (cg *progAttachCgroup) Close() error { @@ -148,7 +162,11 @@ func (cg *progAttachCgroup) Pin(string) error { } func (cg *progAttachCgroup) Unpin() error { - return fmt.Errorf("can't pin cgroup: %w", ErrNotSupported) + return fmt.Errorf("can't unpin cgroup: %w", ErrNotSupported) +} + +func (cg *progAttachCgroup) Info() (*Info, error) { + return nil, fmt.Errorf("can't get cgroup info: %w", ErrNotSupported) } type linkCgroup struct { @@ -157,6 +175,7 @@ type linkCgroup struct { var _ Link = (*linkCgroup)(nil) +// newLinkCgroup attaches prog to cgroup using BPF_LINK_CREATE. func newLinkCgroup(cgroup *os.File, attach ebpf.AttachType, prog *ebpf.Program) (*linkCgroup, error) { link, err := AttachRawLink(RawLinkOptions{ Target: int(cgroup.Fd()), diff --git a/vendor/github.com/cilium/ebpf/link/freplace.go b/vendor/github.com/cilium/ebpf/link/freplace.go deleted file mode 100644 index a698e1a9d3..0000000000 --- a/vendor/github.com/cilium/ebpf/link/freplace.go +++ /dev/null @@ -1,88 +0,0 @@ -package link - -import ( - "fmt" - - "github.com/cilium/ebpf" - "github.com/cilium/ebpf/internal/btf" -) - -type FreplaceLink struct { - RawLink -} - -// AttachFreplace attaches the given eBPF program to the function it replaces. -// -// The program and name can either be provided at link time, or can be provided -// at program load time. If they were provided at load time, they should be nil -// and empty respectively here, as they will be ignored by the kernel. -// Examples: -// -// AttachFreplace(dispatcher, "function", replacement) -// AttachFreplace(nil, "", replacement) -func AttachFreplace(targetProg *ebpf.Program, name string, prog *ebpf.Program) (*FreplaceLink, error) { - if (name == "") != (targetProg == nil) { - return nil, fmt.Errorf("must provide both or neither of name and targetProg: %w", errInvalidInput) - } - if prog == nil { - return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput) - } - if prog.Type() != ebpf.Extension { - return nil, fmt.Errorf("eBPF program type %s is not an Extension: %w", prog.Type(), errInvalidInput) - } - - var ( - target int - typeID btf.TypeID - ) - if targetProg != nil { - info, err := targetProg.Info() - if err != nil { - return nil, err - } - btfID, ok := info.BTFID() - if !ok { - return nil, fmt.Errorf("could not get BTF ID for program %s: %w", info.Name, errInvalidInput) - } - btfHandle, err := btf.NewHandleFromID(btfID) - if err != nil { - return nil, err - } - defer btfHandle.Close() - - var function *btf.Func - if err := btfHandle.Spec().FindType(name, &function); err != nil { - return nil, err - } - - target = targetProg.FD() - typeID = function.ID() - } - - link, err := AttachRawLink(RawLinkOptions{ - Target: target, - Program: prog, - Attach: ebpf.AttachNone, - BTF: typeID, - }) - if err != nil { - return nil, err - } - - return &FreplaceLink{*link}, nil -} - -// Update implements the Link interface. -func (f *FreplaceLink) Update(new *ebpf.Program) error { - return fmt.Errorf("freplace update: %w", ErrNotSupported) -} - -// LoadPinnedFreplace loads a pinned iterator from a bpffs. -func LoadPinnedFreplace(fileName string, opts *ebpf.LoadPinOptions) (*FreplaceLink, error) { - link, err := LoadPinnedRawLink(fileName, TracingType, opts) - if err != nil { - return nil, err - } - - return &FreplaceLink{*link}, err -} diff --git a/vendor/github.com/cilium/ebpf/link/iter.go b/vendor/github.com/cilium/ebpf/link/iter.go index 654d34ef84..d2b32ef331 100644 --- a/vendor/github.com/cilium/ebpf/link/iter.go +++ b/vendor/github.com/cilium/ebpf/link/iter.go @@ -6,7 +6,7 @@ import ( "unsafe" "github.com/cilium/ebpf" - "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/sys" ) type IterOptions struct { @@ -31,26 +31,26 @@ func AttachIter(opts IterOptions) (*Iter, error) { progFd := opts.Program.FD() if progFd < 0 { - return nil, fmt.Errorf("invalid program: %s", internal.ErrClosedFd) + return nil, fmt.Errorf("invalid program: %s", sys.ErrClosedFd) } var info bpfIterLinkInfoMap if opts.Map != nil { mapFd := opts.Map.FD() if mapFd < 0 { - return nil, fmt.Errorf("invalid map: %w", internal.ErrClosedFd) + return nil, fmt.Errorf("invalid map: %w", sys.ErrClosedFd) } info.map_fd = uint32(mapFd) } - attr := bpfLinkCreateIterAttr{ - prog_fd: uint32(progFd), - attach_type: ebpf.AttachTraceIter, - iter_info: internal.NewPointer(unsafe.Pointer(&info)), - iter_info_len: uint32(unsafe.Sizeof(info)), + attr := sys.LinkCreateIterAttr{ + ProgFd: uint32(progFd), + AttachType: sys.AttachType(ebpf.AttachTraceIter), + IterInfo: sys.NewPointer(unsafe.Pointer(&info)), + IterInfoLen: uint32(unsafe.Sizeof(info)), } - fd, err := bpfLinkCreateIter(&attr) + fd, err := sys.LinkCreateIter(&attr) if err != nil { return nil, fmt.Errorf("can't link iterator: %w", err) } @@ -58,16 +58,6 @@ func AttachIter(opts IterOptions) (*Iter, error) { return &Iter{RawLink{fd, ""}}, err } -// LoadPinnedIter loads a pinned iterator from a bpffs. -func LoadPinnedIter(fileName string, opts *ebpf.LoadPinOptions) (*Iter, error) { - link, err := LoadPinnedRawLink(fileName, IterType, opts) - if err != nil { - return nil, err - } - - return &Iter{*link}, err -} - // Iter represents an attached bpf_iter. type Iter struct { RawLink @@ -77,16 +67,11 @@ type Iter struct { // // Reading from the returned reader triggers the BPF program. func (it *Iter) Open() (io.ReadCloser, error) { - linkFd, err := it.fd.Value() - if err != nil { - return nil, err - } - - attr := &bpfIterCreateAttr{ - linkFd: linkFd, + attr := &sys.IterCreateAttr{ + LinkFd: it.fd.Uint(), } - fd, err := bpfIterCreate(attr) + fd, err := sys.IterCreate(attr) if err != nil { return nil, fmt.Errorf("can't create iterator: %w", err) } diff --git a/vendor/github.com/cilium/ebpf/link/kprobe.go b/vendor/github.com/cilium/ebpf/link/kprobe.go index b6577b5a99..b54ca90853 100644 --- a/vendor/github.com/cilium/ebpf/link/kprobe.go +++ b/vendor/github.com/cilium/ebpf/link/kprobe.go @@ -1,166 +1,198 @@ package link import ( - "bytes" - "crypto/rand" "errors" "fmt" "os" - "path/filepath" "runtime" - "sync" + "strings" "unsafe" "github.com/cilium/ebpf" "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/sys" + "github.com/cilium/ebpf/internal/tracefs" "github.com/cilium/ebpf/internal/unix" ) -var ( - kprobeEventsPath = filepath.Join(tracefsPath, "kprobe_events") - - kprobeRetprobeBit = struct { - once sync.Once - value uint64 - err error - }{} -) - -type probeType uint8 - -const ( - kprobeType probeType = iota - uprobeType -) - -func (pt probeType) String() string { - if pt == kprobeType { - return "kprobe" - } - return "uprobe" -} - -func (pt probeType) EventsPath() string { - if pt == kprobeType { - return kprobeEventsPath - } - return uprobeEventsPath -} - -func (pt probeType) PerfEventType(ret bool) perfEventType { - if pt == kprobeType { - if ret { - return kretprobeEvent - } - return kprobeEvent - } - if ret { - return uretprobeEvent - } - return uprobeEvent +// KprobeOptions defines additional parameters that will be used +// when loading Kprobes. +type KprobeOptions struct { + // Arbitrary value that can be fetched from an eBPF program + // via `bpf_get_attach_cookie()`. + // + // Needs kernel 5.15+. + Cookie uint64 + // Offset of the kprobe relative to the traced symbol. + // Can be used to insert kprobes at arbitrary offsets in kernel functions, + // e.g. in places where functions have been inlined. + Offset uint64 + // Increase the maximum number of concurrent invocations of a kretprobe. + // Required when tracing some long running functions in the kernel. + // + // Deprecated: this setting forces the use of an outdated kernel API and is not portable + // across kernel versions. + RetprobeMaxActive int + // Prefix used for the event name if the kprobe must be attached using tracefs. + // The group name will be formatted as `_`. + // The default empty string is equivalent to "ebpf" as the prefix. + TraceFSPrefix string } -func (pt probeType) RetprobeBit() (uint64, error) { - if pt == kprobeType { - return kretprobeBit() +func (ko *KprobeOptions) cookie() uint64 { + if ko == nil { + return 0 } - return uretprobeBit() + return ko.Cookie } // Kprobe attaches the given eBPF program to a perf event that fires when the // given kernel symbol starts executing. See /proc/kallsyms for available // symbols. For example, printk(): // -// kp, err := Kprobe("printk", prog) +// kp, err := Kprobe("printk", prog, nil) // // Losing the reference to the resulting Link (kp) will close the Kprobe // and prevent further execution of prog. The Link must be Closed during // program shutdown to avoid leaking system resources. -func Kprobe(symbol string, prog *ebpf.Program) (Link, error) { - k, err := kprobe(symbol, prog, false) +// +// If attaching to symbol fails, automatically retries with the running +// platform's syscall prefix (e.g. __x64_) to support attaching to syscalls +// in a portable fashion. +func Kprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions) (Link, error) { + k, err := kprobe(symbol, prog, opts, false) if err != nil { return nil, err } - err = k.attach(prog) + lnk, err := attachPerfEvent(k, prog, opts.cookie()) if err != nil { k.Close() return nil, err } - return k, nil + return lnk, nil } // Kretprobe attaches the given eBPF program to a perf event that fires right // before the given kernel symbol exits, with the function stack left intact. // See /proc/kallsyms for available symbols. For example, printk(): // -// kp, err := Kretprobe("printk", prog) +// kp, err := Kretprobe("printk", prog, nil) // // Losing the reference to the resulting Link (kp) will close the Kretprobe // and prevent further execution of prog. The Link must be Closed during // program shutdown to avoid leaking system resources. -func Kretprobe(symbol string, prog *ebpf.Program) (Link, error) { - k, err := kprobe(symbol, prog, true) +// +// If attaching to symbol fails, automatically retries with the running +// platform's syscall prefix (e.g. __x64_) to support attaching to syscalls +// in a portable fashion. +// +// On kernels 5.10 and earlier, setting a kretprobe on a nonexistent symbol +// incorrectly returns unix.EINVAL instead of os.ErrNotExist. +func Kretprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions) (Link, error) { + k, err := kprobe(symbol, prog, opts, true) if err != nil { return nil, err } - err = k.attach(prog) + lnk, err := attachPerfEvent(k, prog, opts.cookie()) if err != nil { k.Close() return nil, err } - return k, nil + return lnk, nil +} + +// isValidKprobeSymbol implements the equivalent of a regex match +// against "^[a-zA-Z_][0-9a-zA-Z_.]*$". +func isValidKprobeSymbol(s string) bool { + if len(s) < 1 { + return false + } + + for i, c := range []byte(s) { + switch { + case c >= 'a' && c <= 'z': + case c >= 'A' && c <= 'Z': + case c == '_': + case i > 0 && c >= '0' && c <= '9': + + // Allow `.` in symbol name. GCC-compiled kernel may change symbol name + // to have a `.isra.$n` suffix, like `udp_send_skb.isra.52`. + // See: https://gcc.gnu.org/gcc-10/changes.html + case i > 0 && c == '.': + + default: + return false + } + } + + return true } // kprobe opens a perf event on the given symbol and attaches prog to it. // If ret is true, create a kretprobe. -func kprobe(symbol string, prog *ebpf.Program, ret bool) (*perfEvent, error) { +func kprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions, ret bool) (*perfEvent, error) { if symbol == "" { return nil, fmt.Errorf("symbol name cannot be empty: %w", errInvalidInput) } if prog == nil { return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput) } - if !rgxTraceEvent.MatchString(symbol) { - return nil, fmt.Errorf("symbol '%s' must be alphanumeric or underscore: %w", symbol, errInvalidInput) + if !isValidKprobeSymbol(symbol) { + return nil, fmt.Errorf("symbol '%s' must be a valid symbol in /proc/kallsyms: %w", symbol, errInvalidInput) } if prog.Type() != ebpf.Kprobe { return nil, fmt.Errorf("eBPF program type %s is not a Kprobe: %w", prog.Type(), errInvalidInput) } + args := tracefs.ProbeArgs{ + Type: tracefs.Kprobe, + Pid: perfAllThreads, + Symbol: symbol, + Ret: ret, + } + + if opts != nil { + args.RetprobeMaxActive = opts.RetprobeMaxActive + args.Cookie = opts.Cookie + args.Offset = opts.Offset + args.Group = opts.TraceFSPrefix + } + // Use kprobe PMU if the kernel has it available. - tp, err := pmuKprobe(platformPrefix(symbol), ret) - if errors.Is(err, os.ErrNotExist) { - tp, err = pmuKprobe(symbol, ret) + tp, err := pmuProbe(args) + if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) { + if prefix := internal.PlatformPrefix(); prefix != "" { + args.Symbol = prefix + symbol + tp, err = pmuProbe(args) + } } if err == nil { return tp, nil } if err != nil && !errors.Is(err, ErrNotSupported) { - return nil, fmt.Errorf("creating perf_kprobe PMU: %w", err) + return nil, fmt.Errorf("creating perf_kprobe PMU (arch-specific fallback for %q): %w", symbol, err) } // Use tracefs if kprobe PMU is missing. - tp, err = tracefsKprobe(platformPrefix(symbol), ret) - if errors.Is(err, os.ErrNotExist) { - tp, err = tracefsKprobe(symbol, ret) + args.Symbol = symbol + tp, err = tracefsProbe(args) + if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) { + if prefix := internal.PlatformPrefix(); prefix != "" { + args.Symbol = prefix + symbol + tp, err = tracefsProbe(args) + } } if err != nil { - return nil, fmt.Errorf("creating trace event '%s' in tracefs: %w", symbol, err) + return nil, fmt.Errorf("creating tracefs event (arch-specific fallback for %q): %w", symbol, err) } return tp, nil } -// pmuKprobe opens a perf event based on the kprobe PMU. -// Returns os.ErrNotExist if the given symbol does not exist in the kernel. -func pmuKprobe(symbol string, ret bool) (*perfEvent, error) { - return pmuProbe(kprobeType, symbol, "", 0, perfAllThreads, ret) -} - // pmuProbe opens a perf event based on a Performance Monitoring Unit. // // Requires at least a 4.17 kernel. @@ -168,17 +200,25 @@ func pmuKprobe(symbol string, ret bool) (*perfEvent, error) { // 33ea4b24277b "perf/core: Implement the 'perf_uprobe' PMU" // // Returns ErrNotSupported if the kernel doesn't support perf_[k,u]probe PMU -func pmuProbe(typ probeType, symbol, path string, offset uint64, pid int, ret bool) (*perfEvent, error) { +func pmuProbe(args tracefs.ProbeArgs) (*perfEvent, error) { // Getting the PMU type will fail if the kernel doesn't support // the perf_[k,u]probe PMU. - et, err := getPMUEventType(typ) + eventType, err := internal.ReadUint64FromFileOnce("%d\n", "/sys/bus/event_source/devices", args.Type.String(), "type") + if errors.Is(err, os.ErrNotExist) { + return nil, fmt.Errorf("%s: %w", args.Type, ErrNotSupported) + } if err != nil { return nil, err } + // Use tracefs if we want to set kretprobe's retprobeMaxActive. + if args.RetprobeMaxActive != 0 { + return nil, fmt.Errorf("pmu probe: non-zero retprobeMaxActive: %w", ErrNotSupported) + } + var config uint64 - if ret { - bit, err := typ.RetprobeBit() + if args.Ret { + bit, err := internal.ReadUint64FromFileOnce("config:%d\n", "/sys/bus/event_source/devices", args.Type.String(), "/format/retprobe") if err != nil { return nil, err } @@ -186,73 +226,93 @@ func pmuProbe(typ probeType, symbol, path string, offset uint64, pid int, ret bo } var ( - attr unix.PerfEventAttr - sp unsafe.Pointer + attr unix.PerfEventAttr + sp unsafe.Pointer + token string ) - switch typ { - case kprobeType: + switch args.Type { + case tracefs.Kprobe: // Create a pointer to a NUL-terminated string for the kernel. - sp, err = unsafeStringPtr(symbol) + sp, err = unsafeStringPtr(args.Symbol) if err != nil { return nil, err } + token = tracefs.KprobeToken(args) + attr = unix.PerfEventAttr{ - Type: uint32(et), // PMU event type read from sysfs + // The minimum size required for PMU kprobes is PERF_ATTR_SIZE_VER1, + // since it added the config2 (Ext2) field. Use Ext2 as probe_offset. + Size: unix.PERF_ATTR_SIZE_VER1, + Type: uint32(eventType), // PMU event type read from sysfs Ext1: uint64(uintptr(sp)), // Kernel symbol to trace + Ext2: args.Offset, // Kernel symbol offset Config: config, // Retprobe flag } - case uprobeType: - sp, err = unsafeStringPtr(path) + case tracefs.Uprobe: + sp, err = unsafeStringPtr(args.Path) if err != nil { return nil, err } + if args.RefCtrOffset != 0 { + config |= args.RefCtrOffset << uprobeRefCtrOffsetShift + } + + token = tracefs.UprobeToken(args) + attr = unix.PerfEventAttr{ // The minimum size required for PMU uprobes is PERF_ATTR_SIZE_VER1, // since it added the config2 (Ext2) field. The Size field controls the // size of the internal buffer the kernel allocates for reading the // perf_event_attr argument from userspace. Size: unix.PERF_ATTR_SIZE_VER1, - Type: uint32(et), // PMU event type read from sysfs + Type: uint32(eventType), // PMU event type read from sysfs Ext1: uint64(uintptr(sp)), // Uprobe path - Ext2: offset, // Uprobe offset - Config: config, // Retprobe flag + Ext2: args.Offset, // Uprobe offset + Config: config, // RefCtrOffset, Retprobe flag } } - fd, err := unix.PerfEventOpen(&attr, pid, 0, -1, unix.PERF_FLAG_FD_CLOEXEC) + rawFd, err := unix.PerfEventOpen(&attr, args.Pid, 0, -1, unix.PERF_FLAG_FD_CLOEXEC) + // On some old kernels, kprobe PMU doesn't allow `.` in symbol names and + // return -EINVAL. Return ErrNotSupported to allow falling back to tracefs. + // https://github.com/torvalds/linux/blob/94710cac0ef4/kernel/trace/trace_kprobe.c#L340-L343 + if errors.Is(err, unix.EINVAL) && strings.Contains(args.Symbol, ".") { + return nil, fmt.Errorf("token %s: older kernels don't accept dots: %w", token, ErrNotSupported) + } // Since commit 97c753e62e6c, ENOENT is correctly returned instead of EINVAL - // when trying to create a kretprobe for a missing symbol. Make sure ENOENT - // is returned to the caller. - if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) { - return nil, fmt.Errorf("symbol '%s' not found: %w", symbol, os.ErrNotExist) + // when trying to create a retprobe for a missing symbol. + if errors.Is(err, os.ErrNotExist) { + return nil, fmt.Errorf("token %s: not found: %w", token, err) + } + // Since commit ab105a4fb894, EILSEQ is returned when a kprobe sym+offset is resolved + // to an invalid insn boundary. The exact conditions that trigger this error are + // arch specific however. + if errors.Is(err, unix.EILSEQ) { + return nil, fmt.Errorf("token %s: bad insn boundary: %w", token, os.ErrNotExist) } // Since at least commit cb9a19fe4aa51, ENOTSUPP is returned // when attempting to set a uprobe on a trap instruction. - if errors.Is(err, unix.ENOTSUPP) { - return nil, fmt.Errorf("failed setting uprobe on offset %#x (possible trap insn): %w", offset, err) + if errors.Is(err, sys.ENOTSUPP) { + return nil, fmt.Errorf("token %s: failed setting uprobe on offset %#x (possible trap insn): %w", token, args.Offset, err) } + if err != nil { - return nil, fmt.Errorf("opening perf event: %w", err) + return nil, fmt.Errorf("token %s: opening perf event: %w", token, err) } // Ensure the string pointer is not collected before PerfEventOpen returns. runtime.KeepAlive(sp) - // Kernel has perf_[k,u]probe PMU available, initialize perf event. - return &perfEvent{ - fd: internal.NewFD(uint32(fd)), - pmuID: et, - name: symbol, - typ: typ.PerfEventType(ret), - }, nil -} + fd, err := sys.NewFD(rawFd) + if err != nil { + return nil, err + } -// tracefsKprobe creates a Kprobe tracefs entry. -func tracefsKprobe(symbol string, ret bool) (*perfEvent, error) { - return tracefsProbe(kprobeType, symbol, "", 0, perfAllThreads, ret) + // Kernel has perf_[k,u]probe PMU available, initialize perf event. + return newPerfEvent(fd, nil), nil } // tracefsProbe creates a trace event by writing an entry to /[k,u]probe_events. @@ -261,184 +321,37 @@ func tracefsKprobe(symbol string, ret bool) (*perfEvent, error) { // Path and offset are only set in the case of uprobe(s) and are used to set // the executable/library path on the filesystem and the offset where the probe is inserted. // A perf event is then opened on the newly-created trace event and returned to the caller. -func tracefsProbe(typ probeType, symbol, path string, offset uint64, pid int, ret bool) (*perfEvent, error) { +func tracefsProbe(args tracefs.ProbeArgs) (*perfEvent, error) { + groupPrefix := "ebpf" + if args.Group != "" { + groupPrefix = args.Group + } + // Generate a random string for each trace event we attempt to create. // This value is used as the 'group' token in tracefs to allow creating // multiple kprobe trace events with the same name. - group, err := randomGroup("ebpf") + group, err := tracefs.RandomGroup(groupPrefix) if err != nil { return nil, fmt.Errorf("randomizing group name: %w", err) } - - // Before attempting to create a trace event through tracefs, - // check if an event with the same group and name already exists. - // Kernels 4.x and earlier don't return os.ErrExist on writing a duplicate - // entry, so we need to rely on reads for detecting uniqueness. - _, err = getTraceEventID(group, symbol) - if err == nil { - return nil, fmt.Errorf("trace event already exists: %s/%s", group, symbol) - } - if err != nil && !errors.Is(err, os.ErrNotExist) { - return nil, fmt.Errorf("checking trace event %s/%s: %w", group, symbol, err) - } + args.Group = group // Create the [k,u]probe trace event using tracefs. - if err := createTraceFSProbeEvent(typ, group, symbol, path, offset, ret); err != nil { - return nil, fmt.Errorf("creating probe entry on tracefs: %w", err) - } - - // Get the newly-created trace event's id. - tid, err := getTraceEventID(group, symbol) + evt, err := tracefs.NewEvent(args) if err != nil { - return nil, fmt.Errorf("getting trace event id: %w", err) + return nil, fmt.Errorf("creating probe entry on tracefs: %w", err) } // Kprobes are ephemeral tracepoints and share the same perf event type. - fd, err := openTracepointPerfEvent(tid, pid) + fd, err := openTracepointPerfEvent(evt.ID(), args.Pid) if err != nil { + // Make sure we clean up the created tracefs event when we return error. + // If a livepatch handler is already active on the symbol, the write to + // tracefs will succeed, a trace event will show up, but creating the + // perf event will fail with EBUSY. + _ = evt.Close() return nil, err } - return &perfEvent{ - fd: fd, - group: group, - name: symbol, - tracefsID: tid, - typ: typ.PerfEventType(ret), - }, nil -} - -// createTraceFSProbeEvent creates a new ephemeral trace event by writing to -// /[k,u]probe_events. Returns os.ErrNotExist if symbol is not a valid -// kernel symbol, or if it is not traceable with kprobes. Returns os.ErrExist -// if a probe with the same group and symbol already exists. -func createTraceFSProbeEvent(typ probeType, group, symbol, path string, offset uint64, ret bool) error { - // Open the kprobe_events file in tracefs. - f, err := os.OpenFile(typ.EventsPath(), os.O_APPEND|os.O_WRONLY, 0666) - if err != nil { - return fmt.Errorf("error opening '%s': %w", typ.EventsPath(), err) - } - defer f.Close() - - var pe string - switch typ { - case kprobeType: - // The kprobe_events syntax is as follows (see Documentation/trace/kprobetrace.txt): - // p[:[GRP/]EVENT] [MOD:]SYM[+offs]|MEMADDR [FETCHARGS] : Set a probe - // r[MAXACTIVE][:[GRP/]EVENT] [MOD:]SYM[+0] [FETCHARGS] : Set a return probe - // -:[GRP/]EVENT : Clear a probe - // - // Some examples: - // r:ebpf_1234/r_my_kretprobe nf_conntrack_destroy - // p:ebpf_5678/p_my_kprobe __x64_sys_execve - // - // Leaving the kretprobe's MAXACTIVE set to 0 (or absent) will make the - // kernel default to NR_CPUS. This is desired in most eBPF cases since - // subsampling or rate limiting logic can be more accurately implemented in - // the eBPF program itself. - // See Documentation/kprobes.txt for more details. - pe = fmt.Sprintf("%s:%s/%s %s", probePrefix(ret), group, symbol, symbol) - case uprobeType: - // The uprobe_events syntax is as follows: - // p[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a probe - // r[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a return probe - // -:[GRP/]EVENT : Clear a probe - // - // Some examples: - // r:ebpf_1234/readline /bin/bash:0x12345 - // p:ebpf_5678/main_mySymbol /bin/mybin:0x12345 - // - // See Documentation/trace/uprobetracer.txt for more details. - pathOffset := uprobePathOffset(path, offset) - pe = fmt.Sprintf("%s:%s/%s %s", probePrefix(ret), group, symbol, pathOffset) - } - _, err = f.WriteString(pe) - // Since commit 97c753e62e6c, ENOENT is correctly returned instead of EINVAL - // when trying to create a kretprobe for a missing symbol. Make sure ENOENT - // is returned to the caller. - if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) { - return fmt.Errorf("symbol %s not found: %w", symbol, os.ErrNotExist) - } - if err != nil { - return fmt.Errorf("writing '%s' to '%s': %w", pe, typ.EventsPath(), err) - } - - return nil -} - -// closeTraceFSProbeEvent removes the [k,u]probe with the given type, group and symbol -// from /[k,u]probe_events. -func closeTraceFSProbeEvent(typ probeType, group, symbol string) error { - f, err := os.OpenFile(typ.EventsPath(), os.O_APPEND|os.O_WRONLY, 0666) - if err != nil { - return fmt.Errorf("error opening %s: %w", typ.EventsPath(), err) - } - defer f.Close() - - // See [k,u]probe_events syntax above. The probe type does not need to be specified - // for removals. - pe := fmt.Sprintf("-:%s/%s", group, symbol) - if _, err = f.WriteString(pe); err != nil { - return fmt.Errorf("writing '%s' to '%s': %w", pe, typ.EventsPath(), err) - } - - return nil -} - -// randomGroup generates a pseudorandom string for use as a tracefs group name. -// Returns an error when the output string would exceed 63 characters (kernel -// limitation), when rand.Read() fails or when prefix contains characters not -// allowed by rgxTraceEvent. -func randomGroup(prefix string) (string, error) { - if !rgxTraceEvent.MatchString(prefix) { - return "", fmt.Errorf("prefix '%s' must be alphanumeric or underscore: %w", prefix, errInvalidInput) - } - - b := make([]byte, 8) - if _, err := rand.Read(b); err != nil { - return "", fmt.Errorf("reading random bytes: %w", err) - } - - group := fmt.Sprintf("%s_%x", prefix, b) - if len(group) > 63 { - return "", fmt.Errorf("group name '%s' cannot be longer than 63 characters: %w", group, errInvalidInput) - } - - return group, nil -} - -func probePrefix(ret bool) string { - if ret { - return "r" - } - return "p" -} - -// determineRetprobeBit reads a Performance Monitoring Unit's retprobe bit -// from /sys/bus/event_source/devices//format/retprobe. -func determineRetprobeBit(typ probeType) (uint64, error) { - p := filepath.Join("/sys/bus/event_source/devices/", typ.String(), "/format/retprobe") - - data, err := os.ReadFile(p) - if err != nil { - return 0, err - } - - var rp uint64 - n, err := fmt.Sscanf(string(bytes.TrimSpace(data)), "config:%d", &rp) - if err != nil { - return 0, fmt.Errorf("parse retprobe bit: %w", err) - } - if n != 1 { - return 0, fmt.Errorf("parse retprobe bit: expected 1 item, got %d", n) - } - - return rp, nil -} - -func kretprobeBit() (uint64, error) { - kprobeRetprobeBit.once.Do(func() { - kprobeRetprobeBit.value, kprobeRetprobeBit.err = determineRetprobeBit(kprobeType) - }) - return kprobeRetprobeBit.value, kprobeRetprobeBit.err + return newPerfEvent(fd, evt), nil } diff --git a/vendor/github.com/cilium/ebpf/link/kprobe_multi.go b/vendor/github.com/cilium/ebpf/link/kprobe_multi.go new file mode 100644 index 0000000000..697c6d7362 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/link/kprobe_multi.go @@ -0,0 +1,180 @@ +package link + +import ( + "errors" + "fmt" + "os" + "unsafe" + + "github.com/cilium/ebpf" + "github.com/cilium/ebpf/asm" + "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/sys" + "github.com/cilium/ebpf/internal/unix" +) + +// KprobeMultiOptions defines additional parameters that will be used +// when opening a KprobeMulti Link. +type KprobeMultiOptions struct { + // Symbols takes a list of kernel symbol names to attach an ebpf program to. + // + // Mutually exclusive with Addresses. + Symbols []string + + // Addresses takes a list of kernel symbol addresses in case they can not + // be referred to by name. + // + // Note that only start addresses can be specified, since the fprobe API + // limits the attach point to the function entry or return. + // + // Mutually exclusive with Symbols. + Addresses []uintptr + + // Cookies specifies arbitrary values that can be fetched from an eBPF + // program via `bpf_get_attach_cookie()`. + // + // If set, its length should be equal to the length of Symbols or Addresses. + // Each Cookie is assigned to the Symbol or Address specified at the + // corresponding slice index. + Cookies []uint64 +} + +// KprobeMulti attaches the given eBPF program to the entry point of a given set +// of kernel symbols. +// +// The difference with Kprobe() is that multi-kprobe accomplishes this in a +// single system call, making it significantly faster than attaching many +// probes one at a time. +// +// Requires at least Linux 5.18. +func KprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions) (Link, error) { + return kprobeMulti(prog, opts, 0) +} + +// KretprobeMulti attaches the given eBPF program to the return point of a given +// set of kernel symbols. +// +// The difference with Kretprobe() is that multi-kprobe accomplishes this in a +// single system call, making it significantly faster than attaching many +// probes one at a time. +// +// Requires at least Linux 5.18. +func KretprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions) (Link, error) { + return kprobeMulti(prog, opts, unix.BPF_F_KPROBE_MULTI_RETURN) +} + +func kprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions, flags uint32) (Link, error) { + if prog == nil { + return nil, errors.New("cannot attach a nil program") + } + + syms := uint32(len(opts.Symbols)) + addrs := uint32(len(opts.Addresses)) + cookies := uint32(len(opts.Cookies)) + + if syms == 0 && addrs == 0 { + return nil, fmt.Errorf("one of Symbols or Addresses is required: %w", errInvalidInput) + } + if syms != 0 && addrs != 0 { + return nil, fmt.Errorf("Symbols and Addresses are mutually exclusive: %w", errInvalidInput) + } + if cookies > 0 && cookies != syms && cookies != addrs { + return nil, fmt.Errorf("Cookies must be exactly Symbols or Addresses in length: %w", errInvalidInput) + } + + if err := haveBPFLinkKprobeMulti(); err != nil { + return nil, err + } + + attr := &sys.LinkCreateKprobeMultiAttr{ + ProgFd: uint32(prog.FD()), + AttachType: sys.BPF_TRACE_KPROBE_MULTI, + KprobeMultiFlags: flags, + } + + switch { + case syms != 0: + attr.Count = syms + attr.Syms = sys.NewStringSlicePointer(opts.Symbols) + + case addrs != 0: + attr.Count = addrs + attr.Addrs = sys.NewPointer(unsafe.Pointer(&opts.Addresses[0])) + } + + if cookies != 0 { + attr.Cookies = sys.NewPointer(unsafe.Pointer(&opts.Cookies[0])) + } + + fd, err := sys.LinkCreateKprobeMulti(attr) + if errors.Is(err, unix.ESRCH) { + return nil, fmt.Errorf("couldn't find one or more symbols: %w", os.ErrNotExist) + } + if errors.Is(err, unix.EINVAL) { + return nil, fmt.Errorf("%w (missing kernel symbol or prog's AttachType not AttachTraceKprobeMulti?)", err) + } + if err != nil { + return nil, err + } + + return &kprobeMultiLink{RawLink{fd, ""}}, nil +} + +type kprobeMultiLink struct { + RawLink +} + +var _ Link = (*kprobeMultiLink)(nil) + +func (kml *kprobeMultiLink) Update(prog *ebpf.Program) error { + return fmt.Errorf("update kprobe_multi: %w", ErrNotSupported) +} + +func (kml *kprobeMultiLink) Pin(string) error { + return fmt.Errorf("pin kprobe_multi: %w", ErrNotSupported) +} + +func (kml *kprobeMultiLink) Unpin() error { + return fmt.Errorf("unpin kprobe_multi: %w", ErrNotSupported) +} + +var haveBPFLinkKprobeMulti = internal.NewFeatureTest("bpf_link_kprobe_multi", "5.18", func() error { + prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ + Name: "probe_kpm_link", + Type: ebpf.Kprobe, + Instructions: asm.Instructions{ + asm.Mov.Imm(asm.R0, 0), + asm.Return(), + }, + AttachType: ebpf.AttachTraceKprobeMulti, + License: "MIT", + }) + if errors.Is(err, unix.E2BIG) { + // Kernel doesn't support AttachType field. + return internal.ErrNotSupported + } + if err != nil { + return err + } + defer prog.Close() + + fd, err := sys.LinkCreateKprobeMulti(&sys.LinkCreateKprobeMultiAttr{ + ProgFd: uint32(prog.FD()), + AttachType: sys.BPF_TRACE_KPROBE_MULTI, + Count: 1, + Syms: sys.NewStringSlicePointer([]string{"vprintk"}), + }) + switch { + case errors.Is(err, unix.EINVAL): + return internal.ErrNotSupported + // If CONFIG_FPROBE isn't set. + case errors.Is(err, unix.EOPNOTSUPP): + return internal.ErrNotSupported + case err != nil: + return err + } + + fd.Close() + + return nil +}) diff --git a/vendor/github.com/cilium/ebpf/link/link.go b/vendor/github.com/cilium/ebpf/link/link.go index 4926584696..36acd6ee4b 100644 --- a/vendor/github.com/cilium/ebpf/link/link.go +++ b/vendor/github.com/cilium/ebpf/link/link.go @@ -1,12 +1,14 @@ package link import ( + "bytes" + "encoding/binary" "fmt" - "unsafe" "github.com/cilium/ebpf" + "github.com/cilium/ebpf/btf" "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/btf" + "github.com/cilium/ebpf/internal/sys" ) var ErrNotSupported = internal.ErrNotSupported @@ -35,12 +37,74 @@ type Link interface { // not called. Close() error + // Info returns metadata on a link. + // + // May return an error wrapping ErrNotSupported. + Info() (*Info, error) + // Prevent external users from implementing this interface. isLink() } +// NewLinkFromFD creates a link from a raw fd. +// +// You should not use fd after calling this function. +func NewLinkFromFD(fd int) (Link, error) { + sysFD, err := sys.NewFD(fd) + if err != nil { + return nil, err + } + + return wrapRawLink(&RawLink{fd: sysFD}) +} + +// LoadPinnedLink loads a link that was persisted into a bpffs. +func LoadPinnedLink(fileName string, opts *ebpf.LoadPinOptions) (Link, error) { + raw, err := loadPinnedRawLink(fileName, opts) + if err != nil { + return nil, err + } + + return wrapRawLink(raw) +} + +// wrap a RawLink in a more specific type if possible. +// +// The function takes ownership of raw and closes it on error. +func wrapRawLink(raw *RawLink) (_ Link, err error) { + defer func() { + if err != nil { + raw.Close() + } + }() + + info, err := raw.Info() + if err != nil { + return nil, err + } + + switch info.Type { + case RawTracepointType: + return &rawTracepoint{*raw}, nil + case TracingType: + return &tracing{*raw}, nil + case CgroupType: + return &linkCgroup{*raw}, nil + case IterType: + return &Iter{*raw}, nil + case NetNsType: + return &NetNsLink{*raw}, nil + case KprobeMultiType: + return &kprobeMultiLink{*raw}, nil + case PerfEventType: + return nil, fmt.Errorf("recovering perf event fd: %w", ErrNotSupported) + default: + return raw, nil + } +} + // ID uniquely identifies a BPF link. -type ID uint32 +type ID = sys.LinkID // RawLinkOptions control the creation of a raw link. type RawLinkOptions struct { @@ -52,13 +116,53 @@ type RawLinkOptions struct { Attach ebpf.AttachType // BTF is the BTF of the attachment target. BTF btf.TypeID + // Flags control the attach behaviour. + Flags uint32 } -// RawLinkInfo contains metadata on a link. -type RawLinkInfo struct { +// Info contains metadata on a link. +type Info struct { Type Type ID ID Program ebpf.ProgramID + extra interface{} +} + +type TracingInfo sys.TracingLinkInfo +type CgroupInfo sys.CgroupLinkInfo +type NetNsInfo sys.NetNsLinkInfo +type XDPInfo sys.XDPLinkInfo + +// Tracing returns tracing type-specific link info. +// +// Returns nil if the type-specific link info isn't available. +func (r Info) Tracing() *TracingInfo { + e, _ := r.extra.(*TracingInfo) + return e +} + +// Cgroup returns cgroup type-specific link info. +// +// Returns nil if the type-specific link info isn't available. +func (r Info) Cgroup() *CgroupInfo { + e, _ := r.extra.(*CgroupInfo) + return e +} + +// NetNs returns netns type-specific link info. +// +// Returns nil if the type-specific link info isn't available. +func (r Info) NetNs() *NetNsInfo { + e, _ := r.extra.(*NetNsInfo) + return e +} + +// ExtraNetNs returns XDP type-specific link info. +// +// Returns nil if the type-specific link info isn't available. +func (r Info) XDP() *XDPInfo { + e, _ := r.extra.(*XDPInfo) + return e } // RawLink is the low-level API to bpf_link. @@ -66,7 +170,7 @@ type RawLinkInfo struct { // You should consider using the higher level interfaces in this // package instead. type RawLink struct { - fd *internal.FD + fd *sys.FD pinnedPath string } @@ -77,66 +181,46 @@ func AttachRawLink(opts RawLinkOptions) (*RawLink, error) { } if opts.Target < 0 { - return nil, fmt.Errorf("invalid target: %s", internal.ErrClosedFd) + return nil, fmt.Errorf("invalid target: %s", sys.ErrClosedFd) } progFd := opts.Program.FD() if progFd < 0 { - return nil, fmt.Errorf("invalid program: %s", internal.ErrClosedFd) + return nil, fmt.Errorf("invalid program: %s", sys.ErrClosedFd) } - attr := bpfLinkCreateAttr{ - targetFd: uint32(opts.Target), - progFd: uint32(progFd), - attachType: opts.Attach, - targetBTFID: uint32(opts.BTF), + attr := sys.LinkCreateAttr{ + TargetFd: uint32(opts.Target), + ProgFd: uint32(progFd), + AttachType: sys.AttachType(opts.Attach), + TargetBtfId: opts.BTF, + Flags: opts.Flags, } - fd, err := bpfLinkCreate(&attr) + fd, err := sys.LinkCreate(&attr) if err != nil { - return nil, fmt.Errorf("can't create link: %s", err) + return nil, fmt.Errorf("create link: %w", err) } return &RawLink{fd, ""}, nil } -// LoadPinnedRawLink loads a persisted link from a bpffs. -// -// Returns an error if the pinned link type doesn't match linkType. Pass -// UnspecifiedType to disable this behaviour. -func LoadPinnedRawLink(fileName string, linkType Type, opts *ebpf.LoadPinOptions) (*RawLink, error) { - fd, err := internal.BPFObjGet(fileName, opts.Marshal()) +func loadPinnedRawLink(fileName string, opts *ebpf.LoadPinOptions) (*RawLink, error) { + fd, err := sys.ObjGet(&sys.ObjGetAttr{ + Pathname: sys.NewStringPointer(fileName), + FileFlags: opts.Marshal(), + }) if err != nil { return nil, fmt.Errorf("load pinned link: %w", err) } - link := &RawLink{fd, fileName} - if linkType == UnspecifiedType { - return link, nil - } - - info, err := link.Info() - if err != nil { - link.Close() - return nil, fmt.Errorf("get pinned link info: %s", err) - } - - if info.Type != linkType { - link.Close() - return nil, fmt.Errorf("link type %v doesn't match %v", info.Type, linkType) - } - - return link, nil + return &RawLink{fd, fileName}, nil } func (l *RawLink) isLink() {} // FD returns the raw file descriptor. func (l *RawLink) FD() int { - fd, err := l.fd.Value() - if err != nil { - return -1 - } - return int(fd) + return l.fd.Int() } // Close breaks the link. @@ -167,6 +251,11 @@ func (l *RawLink) Unpin() error { return nil } +// IsPinned returns true if the Link has a non-empty pinned path. +func (l *RawLink) IsPinned() bool { + return l.pinnedPath != "" +} + // Update implements the Link interface. func (l *RawLink) Update(new *ebpf.Program) error { return l.UpdateArgs(RawLinkUpdateOptions{ @@ -185,49 +274,63 @@ type RawLinkUpdateOptions struct { func (l *RawLink) UpdateArgs(opts RawLinkUpdateOptions) error { newFd := opts.New.FD() if newFd < 0 { - return fmt.Errorf("invalid program: %s", internal.ErrClosedFd) + return fmt.Errorf("invalid program: %s", sys.ErrClosedFd) } var oldFd int if opts.Old != nil { oldFd = opts.Old.FD() if oldFd < 0 { - return fmt.Errorf("invalid replacement program: %s", internal.ErrClosedFd) + return fmt.Errorf("invalid replacement program: %s", sys.ErrClosedFd) } } - linkFd, err := l.fd.Value() - if err != nil { - return fmt.Errorf("can't update link: %s", err) - } - - attr := bpfLinkUpdateAttr{ - linkFd: linkFd, - newProgFd: uint32(newFd), - oldProgFd: uint32(oldFd), - flags: opts.Flags, + attr := sys.LinkUpdateAttr{ + LinkFd: l.fd.Uint(), + NewProgFd: uint32(newFd), + OldProgFd: uint32(oldFd), + Flags: opts.Flags, } - return bpfLinkUpdate(&attr) -} - -// struct bpf_link_info -type bpfLinkInfo struct { - typ uint32 - id uint32 - prog_id uint32 + return sys.LinkUpdate(&attr) } // Info returns metadata about the link. -func (l *RawLink) Info() (*RawLinkInfo, error) { - var info bpfLinkInfo - err := internal.BPFObjGetInfoByFD(l.fd, unsafe.Pointer(&info), unsafe.Sizeof(info)) - if err != nil { +func (l *RawLink) Info() (*Info, error) { + var info sys.LinkInfo + + if err := sys.ObjInfo(l.fd, &info); err != nil { return nil, fmt.Errorf("link info: %s", err) } - return &RawLinkInfo{ - Type(info.typ), - ID(info.id), - ebpf.ProgramID(info.prog_id), + var extra interface{} + switch info.Type { + case CgroupType: + extra = &CgroupInfo{} + case NetNsType: + extra = &NetNsInfo{} + case TracingType: + extra = &TracingInfo{} + case XDPType: + extra = &XDPInfo{} + case RawTracepointType, IterType, + PerfEventType, KprobeMultiType: + // Extra metadata not supported. + default: + return nil, fmt.Errorf("unknown link info type: %d", info.Type) + } + + if extra != nil { + buf := bytes.NewReader(info.Extra[:]) + err := binary.Read(buf, internal.NativeEndian, extra) + if err != nil { + return nil, fmt.Errorf("cannot read extra link info: %w", err) + } + } + + return &Info{ + info.Type, + info.Id, + ebpf.ProgramID(info.ProgId), + extra, }, nil } diff --git a/vendor/github.com/cilium/ebpf/link/netns.go b/vendor/github.com/cilium/ebpf/link/netns.go index 37e5b84c4d..344ecced6b 100644 --- a/vendor/github.com/cilium/ebpf/link/netns.go +++ b/vendor/github.com/cilium/ebpf/link/netns.go @@ -6,14 +6,9 @@ import ( "github.com/cilium/ebpf" ) -// NetNsInfo contains metadata about a network namespace link. -type NetNsInfo struct { - RawLinkInfo -} - // NetNsLink is a program attached to a network namespace. type NetNsLink struct { - *RawLink + RawLink } // AttachNetNs attaches a program to a network namespace. @@ -37,24 +32,5 @@ func AttachNetNs(ns int, prog *ebpf.Program) (*NetNsLink, error) { return nil, err } - return &NetNsLink{link}, nil -} - -// LoadPinnedNetNs loads a network namespace link from bpffs. -func LoadPinnedNetNs(fileName string, opts *ebpf.LoadPinOptions) (*NetNsLink, error) { - link, err := LoadPinnedRawLink(fileName, NetNsType, opts) - if err != nil { - return nil, err - } - - return &NetNsLink{link}, nil -} - -// Info returns information about the link. -func (nns *NetNsLink) Info() (*NetNsInfo, error) { - info, err := nns.RawLink.Info() - if err != nil { - return nil, err - } - return &NetNsInfo{*info}, nil + return &NetNsLink{*link}, nil } diff --git a/vendor/github.com/cilium/ebpf/link/perf_event.go b/vendor/github.com/cilium/ebpf/link/perf_event.go index 7e0443a75c..5f7a628b3d 100644 --- a/vendor/github.com/cilium/ebpf/link/perf_event.go +++ b/vendor/github.com/cilium/ebpf/link/perf_event.go @@ -1,19 +1,16 @@ package link import ( - "bytes" "errors" "fmt" - "os" - "path/filepath" - "regexp" "runtime" - "strconv" - "strings" "unsafe" "github.com/cilium/ebpf" + "github.com/cilium/ebpf/asm" "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/sys" + "github.com/cilium/ebpf/internal/tracefs" "github.com/cilium/ebpf/internal/unix" ) @@ -41,60 +38,96 @@ import ( // stops any further invocations of the attached eBPF program. var ( - tracefsPath = "/sys/kernel/debug/tracing" - - // Trace event groups, names and kernel symbols must adhere to this set - // of characters. Non-empty, first character must not be a number, all - // characters must be alphanumeric or underscore. - rgxTraceEvent = regexp.MustCompile("^[a-zA-Z_][0-9a-zA-Z_]*$") - - errInvalidInput = errors.New("invalid input") + errInvalidInput = tracefs.ErrInvalidInput ) const ( perfAllThreads = -1 ) -type perfEventType uint8 - -const ( - tracepointEvent perfEventType = iota - kprobeEvent - kretprobeEvent - uprobeEvent - uretprobeEvent -) - // A perfEvent represents a perf event kernel object. Exactly one eBPF program // can be attached to it. It is created based on a tracefs trace event or a // Performance Monitoring Unit (PMU). type perfEvent struct { + // Trace event backing this perfEvent. May be nil. + tracefsEvent *tracefs.Event + + // This is the perf event FD. + fd *sys.FD +} + +func newPerfEvent(fd *sys.FD, event *tracefs.Event) *perfEvent { + pe := &perfEvent{event, fd} + // Both event and fd have their own finalizer, but we want to + // guarantee that they are closed in a certain order. + runtime.SetFinalizer(pe, (*perfEvent).Close) + return pe +} + +func (pe *perfEvent) Close() error { + runtime.SetFinalizer(pe, nil) + + if err := pe.fd.Close(); err != nil { + return fmt.Errorf("closing perf event fd: %w", err) + } + + if pe.tracefsEvent != nil { + return pe.tracefsEvent.Close() + } + + return nil +} - // Group and name of the tracepoint/kprobe/uprobe. - group string - name string +// perfEventLink represents a bpf perf link. +type perfEventLink struct { + RawLink + pe *perfEvent +} - // PMU event ID read from sysfs. Valid IDs are non-zero. - pmuID uint64 - // ID of the trace event read from tracefs. Valid IDs are non-zero. - tracefsID uint64 +func (pl *perfEventLink) isLink() {} - // The event type determines the types of programs that can be attached. - typ perfEventType +// Pinning requires the underlying perf event FD to stay open. +// +// | PerfEvent FD | BpfLink FD | Works | +// |--------------|------------|-------| +// | Open | Open | Yes | +// | Closed | Open | No | +// | Open | Closed | No (Pin() -> EINVAL) | +// | Closed | Closed | No (Pin() -> EINVAL) | +// +// There is currently no pretty way to recover the perf event FD +// when loading a pinned link, so leave as not supported for now. +func (pl *perfEventLink) Pin(string) error { + return fmt.Errorf("perf event link pin: %w", ErrNotSupported) +} - fd *internal.FD +func (pl *perfEventLink) Unpin() error { + return fmt.Errorf("perf event link unpin: %w", ErrNotSupported) } -func (pe *perfEvent) isLink() {} +func (pl *perfEventLink) Close() error { + if err := pl.fd.Close(); err != nil { + return fmt.Errorf("perf link close: %w", err) + } -func (pe *perfEvent) Pin(string) error { - return fmt.Errorf("pin perf event: %w", ErrNotSupported) + if err := pl.pe.Close(); err != nil { + return fmt.Errorf("perf event close: %w", err) + } + return nil +} + +func (pl *perfEventLink) Update(prog *ebpf.Program) error { + return fmt.Errorf("perf event link update: %w", ErrNotSupported) } -func (pe *perfEvent) Unpin() error { - return fmt.Errorf("unpin perf event: %w", ErrNotSupported) +// perfEventIoctl implements Link and handles the perf event lifecycle +// via ioctl(). +type perfEventIoctl struct { + *perfEvent } +func (pi *perfEventIoctl) isLink() {} + // Since 4.15 (e87c6bc3852b "bpf: permit multiple bpf attachments for a single perf event"), // calling PERF_EVENT_IOC_SET_BPF appends the given program to a prog_array // owned by the perf event, which means multiple programs can be attached @@ -105,137 +138,89 @@ func (pe *perfEvent) Unpin() error { // // Detaching a program from a perf event is currently not possible, so a // program replacement mechanism cannot be implemented for perf events. -func (pe *perfEvent) Update(prog *ebpf.Program) error { - return fmt.Errorf("can't replace eBPF program in perf event: %w", ErrNotSupported) +func (pi *perfEventIoctl) Update(prog *ebpf.Program) error { + return fmt.Errorf("perf event ioctl update: %w", ErrNotSupported) } -func (pe *perfEvent) Close() error { - if pe.fd == nil { - return nil - } - - pfd, err := pe.fd.Value() - if err != nil { - return fmt.Errorf("getting perf event fd: %w", err) - } - - err = unix.IoctlSetInt(int(pfd), unix.PERF_EVENT_IOC_DISABLE, 0) - if err != nil { - return fmt.Errorf("disabling perf event: %w", err) - } - - err = pe.fd.Close() - if err != nil { - return fmt.Errorf("closing perf event fd: %w", err) - } +func (pi *perfEventIoctl) Pin(string) error { + return fmt.Errorf("perf event ioctl pin: %w", ErrNotSupported) +} - switch pe.typ { - case kprobeEvent, kretprobeEvent: - // Clean up kprobe tracefs entry. - if pe.tracefsID != 0 { - return closeTraceFSProbeEvent(kprobeType, pe.group, pe.name) - } - case uprobeEvent, uretprobeEvent: - // Clean up uprobe tracefs entry. - if pe.tracefsID != 0 { - return closeTraceFSProbeEvent(uprobeType, pe.group, pe.name) - } - case tracepointEvent: - // Tracepoint trace events don't hold any extra resources. - return nil - } +func (pi *perfEventIoctl) Unpin() error { + return fmt.Errorf("perf event ioctl unpin: %w", ErrNotSupported) +} - return nil +func (pi *perfEventIoctl) Info() (*Info, error) { + return nil, fmt.Errorf("perf event ioctl info: %w", ErrNotSupported) } // attach the given eBPF prog to the perf event stored in pe. // pe must contain a valid perf event fd. // prog's type must match the program type stored in pe. -func (pe *perfEvent) attach(prog *ebpf.Program) error { +func attachPerfEvent(pe *perfEvent, prog *ebpf.Program, cookie uint64) (Link, error) { if prog == nil { - return errors.New("cannot attach a nil program") - } - if pe.fd == nil { - return errors.New("cannot attach to nil perf event") + return nil, errors.New("cannot attach a nil program") } if prog.FD() < 0 { - return fmt.Errorf("invalid program: %w", internal.ErrClosedFd) + return nil, fmt.Errorf("invalid program: %w", sys.ErrClosedFd) } - switch pe.typ { - case kprobeEvent, kretprobeEvent, uprobeEvent, uretprobeEvent: - if t := prog.Type(); t != ebpf.Kprobe { - return fmt.Errorf("invalid program type (expected %s): %s", ebpf.Kprobe, t) - } - case tracepointEvent: - if t := prog.Type(); t != ebpf.TracePoint { - return fmt.Errorf("invalid program type (expected %s): %s", ebpf.TracePoint, t) - } - default: - return fmt.Errorf("unknown perf event type: %d", pe.typ) + + if err := haveBPFLinkPerfEvent(); err == nil { + return attachPerfEventLink(pe, prog, cookie) } - // The ioctl below will fail when the fd is invalid. - kfd, _ := pe.fd.Value() + if cookie != 0 { + return nil, fmt.Errorf("cookies are not supported: %w", ErrNotSupported) + } + return attachPerfEventIoctl(pe, prog) +} + +func attachPerfEventIoctl(pe *perfEvent, prog *ebpf.Program) (*perfEventIoctl, error) { // Assign the eBPF program to the perf event. - err := unix.IoctlSetInt(int(kfd), unix.PERF_EVENT_IOC_SET_BPF, prog.FD()) + err := unix.IoctlSetInt(pe.fd.Int(), unix.PERF_EVENT_IOC_SET_BPF, prog.FD()) if err != nil { - return fmt.Errorf("setting perf event bpf program: %w", err) + return nil, fmt.Errorf("setting perf event bpf program: %w", err) } // PERF_EVENT_IOC_ENABLE and _DISABLE ignore their given values. - if err := unix.IoctlSetInt(int(kfd), unix.PERF_EVENT_IOC_ENABLE, 0); err != nil { - return fmt.Errorf("enable perf event: %s", err) + if err := unix.IoctlSetInt(pe.fd.Int(), unix.PERF_EVENT_IOC_ENABLE, 0); err != nil { + return nil, fmt.Errorf("enable perf event: %s", err) } - // Close the perf event when its reference is lost to avoid leaking system resources. - runtime.SetFinalizer(pe, (*perfEvent).Close) - return nil + return &perfEventIoctl{pe}, nil } -// unsafeStringPtr returns an unsafe.Pointer to a NUL-terminated copy of str. -func unsafeStringPtr(str string) (unsafe.Pointer, error) { - p, err := unix.BytePtrFromString(str) - if err != nil { - return nil, err - } - return unsafe.Pointer(p), nil -} - -// getTraceEventID reads a trace event's ID from tracefs given its group and name. -// group and name must be alphanumeric or underscore, as required by the kernel. -func getTraceEventID(group, name string) (uint64, error) { - tid, err := uint64FromFile(tracefsPath, "events", group, name, "id") - if errors.Is(err, os.ErrNotExist) { - return 0, fmt.Errorf("trace event %s/%s: %w", group, name, os.ErrNotExist) - } +// Use the bpf api to attach the perf event (BPF_LINK_TYPE_PERF_EVENT, 5.15+). +// +// https://github.com/torvalds/linux/commit/b89fbfbb854c9afc3047e8273cc3a694650b802e +func attachPerfEventLink(pe *perfEvent, prog *ebpf.Program, cookie uint64) (*perfEventLink, error) { + fd, err := sys.LinkCreatePerfEvent(&sys.LinkCreatePerfEventAttr{ + ProgFd: uint32(prog.FD()), + TargetFd: pe.fd.Uint(), + AttachType: sys.BPF_PERF_EVENT, + BpfCookie: cookie, + }) if err != nil { - return 0, fmt.Errorf("reading trace event ID of %s/%s: %w", group, name, err) + return nil, fmt.Errorf("cannot create bpf perf link: %v", err) } - return tid, nil + return &perfEventLink{RawLink{fd: fd}, pe}, nil } -// getPMUEventType reads a Performance Monitoring Unit's type (numeric identifier) -// from /sys/bus/event_source/devices//type. -// -// Returns ErrNotSupported if the pmu type is not supported. -func getPMUEventType(typ probeType) (uint64, error) { - et, err := uint64FromFile("/sys/bus/event_source/devices", typ.String(), "type") - if errors.Is(err, os.ErrNotExist) { - return 0, fmt.Errorf("pmu type %s: %w", typ, ErrNotSupported) - } +// unsafeStringPtr returns an unsafe.Pointer to a NUL-terminated copy of str. +func unsafeStringPtr(str string) (unsafe.Pointer, error) { + p, err := unix.BytePtrFromString(str) if err != nil { - return 0, fmt.Errorf("reading pmu type %s: %w", typ, err) + return nil, err } - - return et, nil + return unsafe.Pointer(p), nil } // openTracepointPerfEvent opens a tracepoint-type perf event. System-wide // [k,u]probes created by writing to /[k,u]probe_events are tracepoints // behind the scenes, and can be attached to using these perf events. -func openTracepointPerfEvent(tid uint64, pid int) (*internal.FD, error) { +func openTracepointPerfEvent(tid uint64, pid int) (*sys.FD, error) { attr := unix.PerfEventAttr{ Type: unix.PERF_TYPE_TRACEPOINT, Config: tid, @@ -249,24 +234,37 @@ func openTracepointPerfEvent(tid uint64, pid int) (*internal.FD, error) { return nil, fmt.Errorf("opening tracepoint perf event: %w", err) } - return internal.NewFD(uint32(fd)), nil + return sys.NewFD(fd) } -// uint64FromFile reads a uint64 from a file. All elements of path are sanitized -// and joined onto base. Returns error if base no longer prefixes the path after -// joining all components. -func uint64FromFile(base string, path ...string) (uint64, error) { - l := filepath.Join(path...) - p := filepath.Join(base, l) - if !strings.HasPrefix(p, base) { - return 0, fmt.Errorf("path '%s' attempts to escape base path '%s': %w", l, base, errInvalidInput) - } - - data, err := os.ReadFile(p) +// Probe BPF perf link. +// +// https://elixir.bootlin.com/linux/v5.16.8/source/kernel/bpf/syscall.c#L4307 +// https://github.com/torvalds/linux/commit/b89fbfbb854c9afc3047e8273cc3a694650b802e +var haveBPFLinkPerfEvent = internal.NewFeatureTest("bpf_link_perf_event", "5.15", func() error { + prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ + Name: "probe_bpf_perf_link", + Type: ebpf.Kprobe, + Instructions: asm.Instructions{ + asm.Mov.Imm(asm.R0, 0), + asm.Return(), + }, + License: "MIT", + }) if err != nil { - return 0, fmt.Errorf("reading file %s: %w", p, err) + return err } - - et := bytes.TrimSpace(data) - return strconv.ParseUint(string(et), 10, 64) -} + defer prog.Close() + + _, err = sys.LinkCreatePerfEvent(&sys.LinkCreatePerfEventAttr{ + ProgFd: uint32(prog.FD()), + AttachType: sys.BPF_PERF_EVENT, + }) + if errors.Is(err, unix.EINVAL) { + return internal.ErrNotSupported + } + if errors.Is(err, unix.EBADF) { + return nil + } + return err +}) diff --git a/vendor/github.com/cilium/ebpf/link/platform.go b/vendor/github.com/cilium/ebpf/link/platform.go deleted file mode 100644 index eb6f7b7a37..0000000000 --- a/vendor/github.com/cilium/ebpf/link/platform.go +++ /dev/null @@ -1,25 +0,0 @@ -package link - -import ( - "fmt" - "runtime" -) - -func platformPrefix(symbol string) string { - - prefix := runtime.GOARCH - - // per https://github.com/golang/go/blob/master/src/go/build/syslist.go - switch prefix { - case "386": - prefix = "ia32" - case "amd64", "amd64p32": - prefix = "x64" - case "arm64", "arm64be": - prefix = "arm64" - default: - return symbol - } - - return fmt.Sprintf("__%s_%s", prefix, symbol) -} diff --git a/vendor/github.com/cilium/ebpf/link/program.go b/vendor/github.com/cilium/ebpf/link/program.go index b90c457467..ea31817377 100644 --- a/vendor/github.com/cilium/ebpf/link/program.go +++ b/vendor/github.com/cilium/ebpf/link/program.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/cilium/ebpf" - "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/sys" ) type RawAttachProgramOptions struct { @@ -34,7 +34,7 @@ func RawAttachProgram(opts RawAttachProgramOptions) error { replaceFd = uint32(opts.Replace.FD()) } - attr := internal.BPFProgAttachAttr{ + attr := sys.ProgAttachAttr{ TargetFd: uint32(opts.Target), AttachBpfFd: uint32(opts.Program.FD()), ReplaceBpfFd: replaceFd, @@ -42,7 +42,7 @@ func RawAttachProgram(opts RawAttachProgramOptions) error { AttachFlags: uint32(opts.Flags), } - if err := internal.BPFProgAttach(&attr); err != nil { + if err := sys.ProgAttach(&attr); err != nil { return fmt.Errorf("can't attach program: %w", err) } return nil @@ -63,12 +63,12 @@ func RawDetachProgram(opts RawDetachProgramOptions) error { return err } - attr := internal.BPFProgDetachAttr{ + attr := sys.ProgDetachAttr{ TargetFd: uint32(opts.Target), AttachBpfFd: uint32(opts.Program.FD()), AttachType: uint32(opts.Attach), } - if err := internal.BPFProgDetach(&attr); err != nil { + if err := sys.ProgDetach(&attr); err != nil { return fmt.Errorf("can't detach program: %w", err) } diff --git a/vendor/github.com/cilium/ebpf/link/query.go b/vendor/github.com/cilium/ebpf/link/query.go new file mode 100644 index 0000000000..c05656512d --- /dev/null +++ b/vendor/github.com/cilium/ebpf/link/query.go @@ -0,0 +1,63 @@ +package link + +import ( + "fmt" + "os" + "unsafe" + + "github.com/cilium/ebpf" + "github.com/cilium/ebpf/internal/sys" +) + +// QueryOptions defines additional parameters when querying for programs. +type QueryOptions struct { + // Path can be a path to a cgroup, netns or LIRC2 device + Path string + // Attach specifies the AttachType of the programs queried for + Attach ebpf.AttachType + // QueryFlags are flags for BPF_PROG_QUERY, e.g. BPF_F_QUERY_EFFECTIVE + QueryFlags uint32 +} + +// QueryPrograms retrieves ProgramIDs associated with the AttachType. +// +// Returns (nil, nil) if there are no programs attached to the queried kernel +// resource. Calling QueryPrograms on a kernel missing PROG_QUERY will result in +// ErrNotSupported. +func QueryPrograms(opts QueryOptions) ([]ebpf.ProgramID, error) { + if haveProgQuery() != nil { + return nil, fmt.Errorf("can't query program IDs: %w", ErrNotSupported) + } + + f, err := os.Open(opts.Path) + if err != nil { + return nil, fmt.Errorf("can't open file: %s", err) + } + defer f.Close() + + // query the number of programs to allocate correct slice size + attr := sys.ProgQueryAttr{ + TargetFd: uint32(f.Fd()), + AttachType: sys.AttachType(opts.Attach), + QueryFlags: opts.QueryFlags, + } + if err := sys.ProgQuery(&attr); err != nil { + return nil, fmt.Errorf("can't query program count: %w", err) + } + + // return nil if no progs are attached + if attr.ProgCount == 0 { + return nil, nil + } + + // we have at least one prog, so we query again + progIds := make([]ebpf.ProgramID, attr.ProgCount) + attr.ProgIds = sys.NewPointer(unsafe.Pointer(&progIds[0])) + attr.ProgCount = uint32(len(progIds)) + if err := sys.ProgQuery(&attr); err != nil { + return nil, fmt.Errorf("can't query program IDs: %w", err) + } + + return progIds, nil + +} diff --git a/vendor/github.com/cilium/ebpf/link/raw_tracepoint.go b/vendor/github.com/cilium/ebpf/link/raw_tracepoint.go index f4beb1e078..925e621cbb 100644 --- a/vendor/github.com/cilium/ebpf/link/raw_tracepoint.go +++ b/vendor/github.com/cilium/ebpf/link/raw_tracepoint.go @@ -1,10 +1,11 @@ package link import ( + "errors" "fmt" "github.com/cilium/ebpf" - "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/sys" ) type RawTracepointOptions struct { @@ -22,40 +23,65 @@ func AttachRawTracepoint(opts RawTracepointOptions) (Link, error) { return nil, fmt.Errorf("invalid program type %s, expected RawTracepoint(Writable)", t) } if opts.Program.FD() < 0 { - return nil, fmt.Errorf("invalid program: %w", internal.ErrClosedFd) + return nil, fmt.Errorf("invalid program: %w", sys.ErrClosedFd) } - fd, err := bpfRawTracepointOpen(&bpfRawTracepointOpenAttr{ - name: internal.NewStringPointer(opts.Name), - fd: uint32(opts.Program.FD()), + fd, err := sys.RawTracepointOpen(&sys.RawTracepointOpenAttr{ + Name: sys.NewStringPointer(opts.Name), + ProgFd: uint32(opts.Program.FD()), }) if err != nil { return nil, err } - return &progAttachRawTracepoint{fd: fd}, nil + err = haveBPFLink() + if errors.Is(err, ErrNotSupported) { + // Prior to commit 70ed506c3bbc ("bpf: Introduce pinnable bpf_link abstraction") + // raw_tracepoints are just a plain fd. + return &simpleRawTracepoint{fd}, nil + } + + if err != nil { + return nil, err + } + + return &rawTracepoint{RawLink{fd: fd}}, nil } -type progAttachRawTracepoint struct { - fd *internal.FD +type simpleRawTracepoint struct { + fd *sys.FD } -var _ Link = (*progAttachRawTracepoint)(nil) +var _ Link = (*simpleRawTracepoint)(nil) -func (rt *progAttachRawTracepoint) isLink() {} +func (frt *simpleRawTracepoint) isLink() {} -func (rt *progAttachRawTracepoint) Close() error { - return rt.fd.Close() +func (frt *simpleRawTracepoint) Close() error { + return frt.fd.Close() } -func (rt *progAttachRawTracepoint) Update(_ *ebpf.Program) error { - return fmt.Errorf("can't update raw_tracepoint: %w", ErrNotSupported) +func (frt *simpleRawTracepoint) Update(_ *ebpf.Program) error { + return fmt.Errorf("update raw_tracepoint: %w", ErrNotSupported) } -func (rt *progAttachRawTracepoint) Pin(_ string) error { - return fmt.Errorf("can't pin raw_tracepoint: %w", ErrNotSupported) +func (frt *simpleRawTracepoint) Pin(string) error { + return fmt.Errorf("pin raw_tracepoint: %w", ErrNotSupported) } -func (rt *progAttachRawTracepoint) Unpin() error { +func (frt *simpleRawTracepoint) Unpin() error { return fmt.Errorf("unpin raw_tracepoint: %w", ErrNotSupported) } + +func (frt *simpleRawTracepoint) Info() (*Info, error) { + return nil, fmt.Errorf("can't get raw_tracepoint info: %w", ErrNotSupported) +} + +type rawTracepoint struct { + RawLink +} + +var _ Link = (*rawTracepoint)(nil) + +func (rt *rawTracepoint) Update(_ *ebpf.Program) error { + return fmt.Errorf("update raw_tracepoint: %w", ErrNotSupported) +} diff --git a/vendor/github.com/cilium/ebpf/link/socket_filter.go b/vendor/github.com/cilium/ebpf/link/socket_filter.go new file mode 100644 index 0000000000..84f0b656f8 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/link/socket_filter.go @@ -0,0 +1,40 @@ +package link + +import ( + "syscall" + + "github.com/cilium/ebpf" + "github.com/cilium/ebpf/internal/unix" +) + +// AttachSocketFilter attaches a SocketFilter BPF program to a socket. +func AttachSocketFilter(conn syscall.Conn, program *ebpf.Program) error { + rawConn, err := conn.SyscallConn() + if err != nil { + return err + } + var ssoErr error + err = rawConn.Control(func(fd uintptr) { + ssoErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_ATTACH_BPF, program.FD()) + }) + if ssoErr != nil { + return ssoErr + } + return err +} + +// DetachSocketFilter detaches a SocketFilter BPF program from a socket. +func DetachSocketFilter(conn syscall.Conn) error { + rawConn, err := conn.SyscallConn() + if err != nil { + return err + } + var ssoErr error + err = rawConn.Control(func(fd uintptr) { + ssoErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_DETACH_BPF, 0) + }) + if ssoErr != nil { + return ssoErr + } + return err +} diff --git a/vendor/github.com/cilium/ebpf/link/syscalls.go b/vendor/github.com/cilium/ebpf/link/syscalls.go index a61499438b..c9c998c201 100644 --- a/vendor/github.com/cilium/ebpf/link/syscalls.go +++ b/vendor/github.com/cilium/ebpf/link/syscalls.go @@ -2,35 +2,34 @@ package link import ( "errors" - "unsafe" "github.com/cilium/ebpf" "github.com/cilium/ebpf/asm" "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/sys" "github.com/cilium/ebpf/internal/unix" ) // Type is the kind of link. -type Type uint32 +type Type = sys.LinkType // Valid link types. -// -// Equivalent to enum bpf_link_type. const ( - UnspecifiedType Type = iota - RawTracepointType - TracingType - CgroupType - IterType - NetNsType - XDPType + UnspecifiedType = sys.BPF_LINK_TYPE_UNSPEC + RawTracepointType = sys.BPF_LINK_TYPE_RAW_TRACEPOINT + TracingType = sys.BPF_LINK_TYPE_TRACING + CgroupType = sys.BPF_LINK_TYPE_CGROUP + IterType = sys.BPF_LINK_TYPE_ITER + NetNsType = sys.BPF_LINK_TYPE_NETNS + XDPType = sys.BPF_LINK_TYPE_XDP + PerfEventType = sys.BPF_LINK_TYPE_PERF_EVENT + KprobeMultiType = sys.BPF_LINK_TYPE_KPROBE_MULTI ) -var haveProgAttach = internal.FeatureTest("BPF_PROG_ATTACH", "4.10", func() error { +var haveProgAttach = internal.NewFeatureTest("BPF_PROG_ATTACH", "4.10", func() error { prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ - Type: ebpf.CGroupSKB, - AttachType: ebpf.AttachCGroupInetIngress, - License: "MIT", + Type: ebpf.CGroupSKB, + License: "MIT", Instructions: asm.Instructions{ asm.Mov.Imm(asm.R0, 0), asm.Return(), @@ -47,7 +46,7 @@ var haveProgAttach = internal.FeatureTest("BPF_PROG_ATTACH", "4.10", func() erro return nil }) -var haveProgAttachReplace = internal.FeatureTest("BPF_PROG_ATTACH atomic replacement", "5.5", func() error { +var haveProgAttachReplace = internal.NewFeatureTest("BPF_PROG_ATTACH atomic replacement of MULTI progs", "5.5", func() error { if err := haveProgAttach(); err != nil { return err } @@ -69,7 +68,7 @@ var haveProgAttachReplace = internal.FeatureTest("BPF_PROG_ATTACH atomic replace // We know that we have BPF_PROG_ATTACH since we can load CGroupSKB programs. // If passing BPF_F_REPLACE gives us EINVAL we know that the feature isn't // present. - attr := internal.BPFProgAttachAttr{ + attr := sys.ProgAttachAttr{ // We rely on this being checked after attachFlags. TargetFd: ^uint32(0), AttachBpfFd: uint32(prog.FD()), @@ -77,7 +76,7 @@ var haveProgAttachReplace = internal.FeatureTest("BPF_PROG_ATTACH atomic replace AttachFlags: uint32(flagReplace), } - err = internal.BPFProgAttach(&attr) + err = sys.ProgAttach(&attr) if errors.Is(err, unix.EINVAL) { return internal.ErrNotSupported } @@ -87,73 +86,14 @@ var haveProgAttachReplace = internal.FeatureTest("BPF_PROG_ATTACH atomic replace return err }) -type bpfLinkCreateAttr struct { - progFd uint32 - targetFd uint32 - attachType ebpf.AttachType - flags uint32 - targetBTFID uint32 -} - -func bpfLinkCreate(attr *bpfLinkCreateAttr) (*internal.FD, error) { - ptr, err := internal.BPF(internal.BPF_LINK_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return internal.NewFD(uint32(ptr)), nil -} - -type bpfLinkCreateIterAttr struct { - prog_fd uint32 - target_fd uint32 - attach_type ebpf.AttachType - flags uint32 - iter_info internal.Pointer - iter_info_len uint32 -} - -func bpfLinkCreateIter(attr *bpfLinkCreateIterAttr) (*internal.FD, error) { - ptr, err := internal.BPF(internal.BPF_LINK_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return internal.NewFD(uint32(ptr)), nil -} - -type bpfLinkUpdateAttr struct { - linkFd uint32 - newProgFd uint32 - flags uint32 - oldProgFd uint32 -} - -func bpfLinkUpdate(attr *bpfLinkUpdateAttr) error { - _, err := internal.BPF(internal.BPF_LINK_UPDATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -var haveBPFLink = internal.FeatureTest("bpf_link", "5.7", func() error { - prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ - Type: ebpf.CGroupSKB, - AttachType: ebpf.AttachCGroupInetIngress, - License: "MIT", - Instructions: asm.Instructions{ - asm.Mov.Imm(asm.R0, 0), - asm.Return(), - }, - }) - if err != nil { - return internal.ErrNotSupported - } - defer prog.Close() - - attr := bpfLinkCreateAttr{ +var haveBPFLink = internal.NewFeatureTest("bpf_link", "5.7", func() error { + attr := sys.LinkCreateAttr{ // This is a hopefully invalid file descriptor, which triggers EBADF. - targetFd: ^uint32(0), - progFd: uint32(prog.FD()), - attachType: ebpf.AttachCGroupInetIngress, + TargetFd: ^uint32(0), + ProgFd: ^uint32(0), + AttachType: sys.AttachType(ebpf.AttachCGroupInetIngress), } - _, err = bpfLinkCreate(&attr) + _, err := sys.LinkCreate(&attr) if errors.Is(err, unix.EINVAL) { return internal.ErrNotSupported } @@ -163,29 +103,21 @@ var haveBPFLink = internal.FeatureTest("bpf_link", "5.7", func() error { return err }) -type bpfIterCreateAttr struct { - linkFd uint32 - flags uint32 -} - -func bpfIterCreate(attr *bpfIterCreateAttr) (*internal.FD, error) { - ptr, err := internal.BPF(internal.BPF_ITER_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err == nil { - return internal.NewFD(uint32(ptr)), nil +var haveProgQuery = internal.NewFeatureTest("BPF_PROG_QUERY", "4.15", func() error { + attr := sys.ProgQueryAttr{ + // We rely on this being checked during the syscall. + // With an otherwise correct payload we expect EBADF here + // as an indication that the feature is present. + TargetFd: ^uint32(0), + AttachType: sys.AttachType(ebpf.AttachCGroupInetIngress), } - return nil, err -} - -type bpfRawTracepointOpenAttr struct { - name internal.Pointer - fd uint32 - _ uint32 -} -func bpfRawTracepointOpen(attr *bpfRawTracepointOpenAttr) (*internal.FD, error) { - ptr, err := internal.BPF(internal.BPF_RAW_TRACEPOINT_OPEN, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err == nil { - return internal.NewFD(uint32(ptr)), nil + err := sys.ProgQuery(&attr) + if errors.Is(err, unix.EINVAL) { + return internal.ErrNotSupported } - return nil, err -} + if errors.Is(err, unix.EBADF) { + return nil + } + return err +}) diff --git a/vendor/github.com/cilium/ebpf/link/tracepoint.go b/vendor/github.com/cilium/ebpf/link/tracepoint.go index 7423df86b1..95f5fae3b0 100644 --- a/vendor/github.com/cilium/ebpf/link/tracepoint.go +++ b/vendor/github.com/cilium/ebpf/link/tracepoint.go @@ -4,14 +4,25 @@ import ( "fmt" "github.com/cilium/ebpf" + "github.com/cilium/ebpf/internal/tracefs" ) +// TracepointOptions defines additional parameters that will be used +// when loading Tracepoints. +type TracepointOptions struct { + // Arbitrary value that can be fetched from an eBPF program + // via `bpf_get_attach_cookie()`. + // + // Needs kernel 5.15+. + Cookie uint64 +} + // Tracepoint attaches the given eBPF program to the tracepoint with the given -// group and name. See /sys/kernel/debug/tracing/events to find available +// group and name. See /sys/kernel/tracing/events to find available // tracepoints. The top-level directory is the group, the event's subdirectory // is the name. Example: // -// tp, err := Tracepoint("syscalls", "sys_enter_fork", prog) +// tp, err := Tracepoint("syscalls", "sys_enter_fork", prog, nil) // // Losing the reference to the resulting Link (tp) will close the Tracepoint // and prevent further execution of prog. The Link must be Closed during @@ -19,21 +30,18 @@ import ( // // Note that attaching eBPF programs to syscalls (sys_enter_*/sys_exit_*) is // only possible as of kernel 4.14 (commit cf5f5ce). -func Tracepoint(group, name string, prog *ebpf.Program) (Link, error) { +func Tracepoint(group, name string, prog *ebpf.Program, opts *TracepointOptions) (Link, error) { if group == "" || name == "" { return nil, fmt.Errorf("group and name cannot be empty: %w", errInvalidInput) } if prog == nil { return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput) } - if !rgxTraceEvent.MatchString(group) || !rgxTraceEvent.MatchString(name) { - return nil, fmt.Errorf("group and name '%s/%s' must be alphanumeric or underscore: %w", group, name, errInvalidInput) - } if prog.Type() != ebpf.TracePoint { return nil, fmt.Errorf("eBPF program type %s is not a Tracepoint: %w", prog.Type(), errInvalidInput) } - tid, err := getTraceEventID(group, name) + tid, err := tracefs.EventID(group, name) if err != nil { return nil, err } @@ -43,18 +51,18 @@ func Tracepoint(group, name string, prog *ebpf.Program) (Link, error) { return nil, err } - pe := &perfEvent{ - fd: fd, - tracefsID: tid, - group: group, - name: name, - typ: tracepointEvent, + var cookie uint64 + if opts != nil { + cookie = opts.Cookie } - if err := pe.attach(prog); err != nil { + pe := newPerfEvent(fd, nil) + + lnk, err := attachPerfEvent(pe, prog, cookie) + if err != nil { pe.Close() return nil, err } - return pe, nil + return lnk, nil } diff --git a/vendor/github.com/cilium/ebpf/link/tracing.go b/vendor/github.com/cilium/ebpf/link/tracing.go new file mode 100644 index 0000000000..1e1a7834d8 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/link/tracing.go @@ -0,0 +1,199 @@ +package link + +import ( + "errors" + "fmt" + + "github.com/cilium/ebpf" + "github.com/cilium/ebpf/btf" + "github.com/cilium/ebpf/internal/sys" + "github.com/cilium/ebpf/internal/unix" +) + +type tracing struct { + RawLink +} + +func (f *tracing) Update(new *ebpf.Program) error { + return fmt.Errorf("tracing update: %w", ErrNotSupported) +} + +// AttachFreplace attaches the given eBPF program to the function it replaces. +// +// The program and name can either be provided at link time, or can be provided +// at program load time. If they were provided at load time, they should be nil +// and empty respectively here, as they will be ignored by the kernel. +// Examples: +// +// AttachFreplace(dispatcher, "function", replacement) +// AttachFreplace(nil, "", replacement) +func AttachFreplace(targetProg *ebpf.Program, name string, prog *ebpf.Program) (Link, error) { + if (name == "") != (targetProg == nil) { + return nil, fmt.Errorf("must provide both or neither of name and targetProg: %w", errInvalidInput) + } + if prog == nil { + return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput) + } + if prog.Type() != ebpf.Extension { + return nil, fmt.Errorf("eBPF program type %s is not an Extension: %w", prog.Type(), errInvalidInput) + } + + var ( + target int + typeID btf.TypeID + ) + if targetProg != nil { + btfHandle, err := targetProg.Handle() + if err != nil { + return nil, err + } + defer btfHandle.Close() + + spec, err := btfHandle.Spec(nil) + if err != nil { + return nil, err + } + + var function *btf.Func + if err := spec.TypeByName(name, &function); err != nil { + return nil, err + } + + target = targetProg.FD() + typeID, err = spec.TypeID(function) + if err != nil { + return nil, err + } + } + + link, err := AttachRawLink(RawLinkOptions{ + Target: target, + Program: prog, + Attach: ebpf.AttachNone, + BTF: typeID, + }) + if errors.Is(err, sys.ENOTSUPP) { + // This may be returned by bpf_tracing_prog_attach via bpf_arch_text_poke. + return nil, fmt.Errorf("create raw tracepoint: %w", ErrNotSupported) + } + if err != nil { + return nil, err + } + + return &tracing{*link}, nil +} + +type TracingOptions struct { + // Program must be of type Tracing with attach type + // AttachTraceFEntry/AttachTraceFExit/AttachModifyReturn or + // AttachTraceRawTp. + Program *ebpf.Program + // Program attach type. Can be one of: + // - AttachTraceFEntry + // - AttachTraceFExit + // - AttachModifyReturn + // - AttachTraceRawTp + // This field is optional. + AttachType ebpf.AttachType + // Arbitrary value that can be fetched from an eBPF program + // via `bpf_get_attach_cookie()`. + Cookie uint64 +} + +type LSMOptions struct { + // Program must be of type LSM with attach type + // AttachLSMMac. + Program *ebpf.Program + // Arbitrary value that can be fetched from an eBPF program + // via `bpf_get_attach_cookie()`. + Cookie uint64 +} + +// attachBTFID links all BPF program types (Tracing/LSM) that they attach to a btf_id. +func attachBTFID(program *ebpf.Program, at ebpf.AttachType, cookie uint64) (Link, error) { + if program.FD() < 0 { + return nil, fmt.Errorf("invalid program %w", sys.ErrClosedFd) + } + + var ( + fd *sys.FD + err error + ) + switch at { + case ebpf.AttachTraceFEntry, ebpf.AttachTraceFExit, ebpf.AttachTraceRawTp, + ebpf.AttachModifyReturn, ebpf.AttachLSMMac: + // Attach via BPF link + fd, err = sys.LinkCreateTracing(&sys.LinkCreateTracingAttr{ + ProgFd: uint32(program.FD()), + AttachType: sys.AttachType(at), + Cookie: cookie, + }) + if err == nil { + break + } + if !errors.Is(err, unix.EINVAL) && !errors.Is(err, sys.ENOTSUPP) { + return nil, fmt.Errorf("create tracing link: %w", err) + } + fallthrough + case ebpf.AttachNone: + // Attach via RawTracepointOpen + if cookie > 0 { + return nil, fmt.Errorf("create raw tracepoint with cookie: %w", ErrNotSupported) + } + + fd, err = sys.RawTracepointOpen(&sys.RawTracepointOpenAttr{ + ProgFd: uint32(program.FD()), + }) + if errors.Is(err, sys.ENOTSUPP) { + // This may be returned by bpf_tracing_prog_attach via bpf_arch_text_poke. + return nil, fmt.Errorf("create raw tracepoint: %w", ErrNotSupported) + } + if err != nil { + return nil, fmt.Errorf("create raw tracepoint: %w", err) + } + default: + return nil, fmt.Errorf("invalid attach type: %s", at.String()) + } + + raw := RawLink{fd: fd} + info, err := raw.Info() + if err != nil { + raw.Close() + return nil, err + } + + if info.Type == RawTracepointType { + // Sadness upon sadness: a Tracing program with AttachRawTp returns + // a raw_tracepoint link. Other types return a tracing link. + return &rawTracepoint{raw}, nil + } + return &tracing{raw}, nil +} + +// AttachTracing links a tracing (fentry/fexit/fmod_ret) BPF program or +// a BTF-powered raw tracepoint (tp_btf) BPF Program to a BPF hook defined +// in kernel modules. +func AttachTracing(opts TracingOptions) (Link, error) { + if t := opts.Program.Type(); t != ebpf.Tracing { + return nil, fmt.Errorf("invalid program type %s, expected Tracing", t) + } + + switch opts.AttachType { + case ebpf.AttachTraceFEntry, ebpf.AttachTraceFExit, ebpf.AttachModifyReturn, + ebpf.AttachTraceRawTp, ebpf.AttachNone: + default: + return nil, fmt.Errorf("invalid attach type: %s", opts.AttachType.String()) + } + + return attachBTFID(opts.Program, opts.AttachType, opts.Cookie) +} + +// AttachLSM links a Linux security module (LSM) BPF Program to a BPF +// hook defined in kernel modules. +func AttachLSM(opts LSMOptions) (Link, error) { + if t := opts.Program.Type(); t != ebpf.LSM { + return nil, fmt.Errorf("invalid program type %s, expected LSM", t) + } + + return attachBTFID(opts.Program, ebpf.AttachLSMMac, opts.Cookie) +} diff --git a/vendor/github.com/cilium/ebpf/link/uprobe.go b/vendor/github.com/cilium/ebpf/link/uprobe.go index 59170ce046..272bac4151 100644 --- a/vendor/github.com/cilium/ebpf/link/uprobe.go +++ b/vendor/github.com/cilium/ebpf/link/uprobe.go @@ -5,26 +5,24 @@ import ( "errors" "fmt" "os" - "path/filepath" - "regexp" "sync" "github.com/cilium/ebpf" "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/tracefs" ) var ( - uprobeEventsPath = filepath.Join(tracefsPath, "uprobe_events") - - // rgxUprobeSymbol is used to strip invalid characters from the uprobe symbol - // as they are not allowed to be used as the EVENT token in tracefs. - rgxUprobeSymbol = regexp.MustCompile("[^a-zA-Z0-9]+") - - uprobeRetprobeBit = struct { - once sync.Once - value uint64 - err error - }{} + uprobeRefCtrOffsetPMUPath = "/sys/bus/event_source/devices/uprobe/format/ref_ctr_offset" + // elixir.bootlin.com/linux/v5.15-rc7/source/kernel/events/core.c#L9799 + uprobeRefCtrOffsetShift = 32 + haveRefCtrOffsetPMU = internal.NewFeatureTest("RefCtrOffsetPMU", "4.20", func() error { + _, err := os.Stat(uprobeRefCtrOffsetPMUPath) + if err != nil { + return internal.ErrNotSupported + } + return nil + }) // ErrNoSymbol indicates that the given symbol was not found // in the ELF symbols table. @@ -35,19 +33,54 @@ var ( type Executable struct { // Path of the executable on the filesystem. path string - // Parsed ELF symbols and dynamic symbols offsets. - offsets map[string]uint64 + // Parsed ELF and dynamic symbols' addresses. + addresses map[string]uint64 + // Keep track of symbol table lazy load. + addressesOnce sync.Once } // UprobeOptions defines additional parameters that will be used // when loading Uprobes. type UprobeOptions struct { - // Symbol offset. Must be provided in case of external symbols (shared libs). - // If set, overrides the offset eventually parsed from the executable. + // Symbol address. Must be provided in case of external symbols (shared libs). + // If set, overrides the address eventually parsed from the executable. + Address uint64 + // The offset relative to given symbol. Useful when tracing an arbitrary point + // inside the frame of given symbol. + // + // Note: this field changed from being an absolute offset to being relative + // to Address. Offset uint64 // Only set the uprobe on the given process ID. Useful when tracing // shared library calls or programs that have many running instances. PID int + // Automatically manage SDT reference counts (semaphores). + // + // If this field is set, the Kernel will increment/decrement the + // semaphore located in the process memory at the provided address on + // probe attach/detach. + // + // See also: + // sourceware.org/systemtap/wiki/UserSpaceProbeImplementation (Semaphore Handling) + // github.com/torvalds/linux/commit/1cc33161a83d + // github.com/torvalds/linux/commit/a6ca88b241d5 + RefCtrOffset uint64 + // Arbitrary value that can be fetched from an eBPF program + // via `bpf_get_attach_cookie()`. + // + // Needs kernel 5.15+. + Cookie uint64 + // Prefix used for the event name if the uprobe must be attached using tracefs. + // The group name will be formatted as `_`. + // The default empty string is equivalent to "ebpf" as the prefix. + TraceFSPrefix string +} + +func (uo *UprobeOptions) cookie() uint64 { + if uo == nil { + return 0 + } + return uo.Cookie } // To open a new Executable, use: @@ -60,32 +93,21 @@ func OpenExecutable(path string) (*Executable, error) { return nil, fmt.Errorf("path cannot be empty") } - f, err := os.Open(path) - if err != nil { - return nil, fmt.Errorf("open file '%s': %w", path, err) - } - defer f.Close() - - se, err := internal.NewSafeELFFile(f) + f, err := internal.OpenSafeELFFile(path) if err != nil { return nil, fmt.Errorf("parse ELF file: %w", err) } + defer f.Close() - if se.Type != elf.ET_EXEC && se.Type != elf.ET_DYN { + if f.Type != elf.ET_EXEC && f.Type != elf.ET_DYN { // ELF is not an executable or a shared object. return nil, errors.New("the given file is not an executable or a shared object") } - ex := Executable{ - path: path, - offsets: make(map[string]uint64), - } - - if err := ex.load(se); err != nil { - return nil, err - } - - return &ex, nil + return &Executable{ + path: path, + addresses: make(map[string]uint64), + }, nil } func (ex *Executable) load(f *internal.SafeELFFile) error { @@ -107,7 +129,7 @@ func (ex *Executable) load(f *internal.SafeELFFile) error { continue } - off := s.Value + address := s.Value // Loop over ELF segments. for _, prog := range f.Progs { @@ -123,46 +145,74 @@ func (ex *Executable) load(f *internal.SafeELFFile) error { // fn symbol offset = fn symbol VA - .text VA + .text offset // // stackoverflow.com/a/40249502 - off = s.Value - prog.Vaddr + prog.Off + address = s.Value - prog.Vaddr + prog.Off break } } - ex.offsets[s.Name] = off + ex.addresses[s.Name] = address } return nil } -func (ex *Executable) offset(symbol string) (uint64, error) { - if off, ok := ex.offsets[symbol]; ok { - // Symbols with location 0 from section undef are shared library calls and - // are relocated before the binary is executed. Dynamic linking is not - // implemented by the library, so mark this as unsupported for now. - // - // Since only offset values are stored and not elf.Symbol, if the value is 0, - // assume it's an external symbol. - if off == 0 { - return 0, fmt.Errorf("cannot resolve %s library call '%s', "+ - "consider providing the offset via options: %w", ex.path, symbol, ErrNotSupported) +// address calculates the address of a symbol in the executable. +// +// opts must not be nil. +func (ex *Executable) address(symbol string, opts *UprobeOptions) (uint64, error) { + if opts.Address > 0 { + return opts.Address + opts.Offset, nil + } + + var err error + ex.addressesOnce.Do(func() { + var f *internal.SafeELFFile + f, err = internal.OpenSafeELFFile(ex.path) + if err != nil { + err = fmt.Errorf("parse ELF file: %w", err) + return } - return off, nil + defer f.Close() + + err = ex.load(f) + }) + if err != nil { + return 0, fmt.Errorf("lazy load symbols: %w", err) } - return 0, fmt.Errorf("symbol %s: %w", symbol, ErrNoSymbol) + + address, ok := ex.addresses[symbol] + if !ok { + return 0, fmt.Errorf("symbol %s: %w", symbol, ErrNoSymbol) + } + + // Symbols with location 0 from section undef are shared library calls and + // are relocated before the binary is executed. Dynamic linking is not + // implemented by the library, so mark this as unsupported for now. + // + // Since only offset values are stored and not elf.Symbol, if the value is 0, + // assume it's an external symbol. + if address == 0 { + return 0, fmt.Errorf("cannot resolve %s library call '%s': %w "+ + "(consider providing UprobeOptions.Address)", ex.path, symbol, ErrNotSupported) + } + + return address + opts.Offset, nil } // Uprobe attaches the given eBPF program to a perf event that fires when the // given symbol starts executing in the given Executable. // For example, /bin/bash::main(): // -// ex, _ = OpenExecutable("/bin/bash") -// ex.Uprobe("main", prog, nil) +// ex, _ = OpenExecutable("/bin/bash") +// ex.Uprobe("main", prog, nil) // // When using symbols which belongs to shared libraries, // an offset must be provided via options: // // up, err := ex.Uprobe("main", prog, &UprobeOptions{Offset: 0x123}) // +// Note: Setting the Offset field in the options supersedes the symbol's offset. +// // Losing the reference to the resulting Link (up) will close the Uprobe // and prevent further execution of prog. The Link must be Closed during // program shutdown to avoid leaking system resources. @@ -175,26 +225,28 @@ func (ex *Executable) Uprobe(symbol string, prog *ebpf.Program, opts *UprobeOpti return nil, err } - err = u.attach(prog) + lnk, err := attachPerfEvent(u, prog, opts.cookie()) if err != nil { u.Close() return nil, err } - return u, nil + return lnk, nil } // Uretprobe attaches the given eBPF program to a perf event that fires right // before the given symbol exits. For example, /bin/bash::main(): // -// ex, _ = OpenExecutable("/bin/bash") -// ex.Uretprobe("main", prog, nil) +// ex, _ = OpenExecutable("/bin/bash") +// ex.Uretprobe("main", prog, nil) // // When using symbols which belongs to shared libraries, // an offset must be provided via options: // // up, err := ex.Uretprobe("main", prog, &UprobeOptions{Offset: 0x123}) // +// Note: Setting the Offset field in the options supersedes the symbol's offset. +// // Losing the reference to the resulting Link (up) will close the Uprobe // and prevent further execution of prog. The Link must be Closed during // program shutdown to avoid leaking system resources. @@ -207,13 +259,13 @@ func (ex *Executable) Uretprobe(symbol string, prog *ebpf.Program, opts *UprobeO return nil, err } - err = u.attach(prog) + lnk, err := attachPerfEvent(u, prog, opts.cookie()) if err != nil { u.Close() return nil, err } - return u, nil + return lnk, nil } // uprobe opens a perf event for the given binary/symbol and attaches prog to it. @@ -225,25 +277,40 @@ func (ex *Executable) uprobe(symbol string, prog *ebpf.Program, opts *UprobeOpti if prog.Type() != ebpf.Kprobe { return nil, fmt.Errorf("eBPF program type %s is not Kprobe: %w", prog.Type(), errInvalidInput) } + if opts == nil { + opts = &UprobeOptions{} + } - var offset uint64 - if opts != nil && opts.Offset != 0 { - offset = opts.Offset - } else { - off, err := ex.offset(symbol) - if err != nil { - return nil, err + offset, err := ex.address(symbol, opts) + if err != nil { + return nil, err + } + + pid := opts.PID + if pid == 0 { + pid = perfAllThreads + } + + if opts.RefCtrOffset != 0 { + if err := haveRefCtrOffsetPMU(); err != nil { + return nil, fmt.Errorf("uprobe ref_ctr_offset: %w", err) } - offset = off } - pid := perfAllThreads - if opts != nil && opts.PID != 0 { - pid = opts.PID + args := tracefs.ProbeArgs{ + Type: tracefs.Uprobe, + Symbol: symbol, + Path: ex.path, + Offset: offset, + Pid: pid, + RefCtrOffset: opts.RefCtrOffset, + Ret: ret, + Cookie: opts.Cookie, + Group: opts.TraceFSPrefix, } // Use uprobe PMU if the kernel has it available. - tp, err := pmuUprobe(symbol, ex.path, offset, pid, ret) + tp, err := pmuProbe(args) if err == nil { return tp, nil } @@ -252,37 +319,10 @@ func (ex *Executable) uprobe(symbol string, prog *ebpf.Program, opts *UprobeOpti } // Use tracefs if uprobe PMU is missing. - tp, err = tracefsUprobe(uprobeSanitizedSymbol(symbol), ex.path, offset, pid, ret) + tp, err = tracefsProbe(args) if err != nil { return nil, fmt.Errorf("creating trace event '%s:%s' in tracefs: %w", ex.path, symbol, err) } return tp, nil } - -// pmuUprobe opens a perf event based on the uprobe PMU. -func pmuUprobe(symbol, path string, offset uint64, pid int, ret bool) (*perfEvent, error) { - return pmuProbe(uprobeType, symbol, path, offset, pid, ret) -} - -// tracefsUprobe creates a Uprobe tracefs entry. -func tracefsUprobe(symbol, path string, offset uint64, pid int, ret bool) (*perfEvent, error) { - return tracefsProbe(uprobeType, symbol, path, offset, pid, ret) -} - -// uprobeSanitizedSymbol replaces every invalid characted for the tracefs api with an underscore. -func uprobeSanitizedSymbol(symbol string) string { - return rgxUprobeSymbol.ReplaceAllString(symbol, "_") -} - -// uprobePathOffset creates the PATH:OFFSET token for the tracefs api. -func uprobePathOffset(path string, offset uint64) string { - return fmt.Sprintf("%s:%#x", path, offset) -} - -func uretprobeBit() (uint64, error) { - uprobeRetprobeBit.once.Do(func() { - uprobeRetprobeBit.value, uprobeRetprobeBit.err = determineRetprobeBit(uprobeType) - }) - return uprobeRetprobeBit.value, uprobeRetprobeBit.err -} diff --git a/vendor/github.com/cilium/ebpf/link/xdp.go b/vendor/github.com/cilium/ebpf/link/xdp.go new file mode 100644 index 0000000000..aa8dd3a4cb --- /dev/null +++ b/vendor/github.com/cilium/ebpf/link/xdp.go @@ -0,0 +1,54 @@ +package link + +import ( + "fmt" + + "github.com/cilium/ebpf" +) + +// XDPAttachFlags represents how XDP program will be attached to interface. +type XDPAttachFlags uint32 + +const ( + // XDPGenericMode (SKB) links XDP BPF program for drivers which do + // not yet support native XDP. + XDPGenericMode XDPAttachFlags = 1 << (iota + 1) + // XDPDriverMode links XDP BPF program into the driver’s receive path. + XDPDriverMode + // XDPOffloadMode offloads the entire XDP BPF program into hardware. + XDPOffloadMode +) + +type XDPOptions struct { + // Program must be an XDP BPF program. + Program *ebpf.Program + + // Interface is the interface index to attach program to. + Interface int + + // Flags is one of XDPAttachFlags (optional). + // + // Only one XDP mode should be set, without flag defaults + // to driver/generic mode (best effort). + Flags XDPAttachFlags +} + +// AttachXDP links an XDP BPF program to an XDP hook. +func AttachXDP(opts XDPOptions) (Link, error) { + if t := opts.Program.Type(); t != ebpf.XDP { + return nil, fmt.Errorf("invalid program type %s, expected XDP", t) + } + + if opts.Interface < 1 { + return nil, fmt.Errorf("invalid interface index: %d", opts.Interface) + } + + rawLink, err := AttachRawLink(RawLinkOptions{ + Program: opts.Program, + Attach: ebpf.AttachXDP, + Target: opts.Interface, + Flags: uint32(opts.Flags), + }) + + return rawLink, err +} diff --git a/vendor/github.com/cilium/ebpf/linker.go b/vendor/github.com/cilium/ebpf/linker.go index f3b1629e70..e0dbfcffd3 100644 --- a/vendor/github.com/cilium/ebpf/linker.go +++ b/vendor/github.com/cilium/ebpf/linker.go @@ -1,159 +1,391 @@ package ebpf import ( + "encoding/binary" + "errors" "fmt" + "io" + "math" "github.com/cilium/ebpf/asm" + "github.com/cilium/ebpf/btf" + "github.com/cilium/ebpf/internal" ) -// link resolves bpf-to-bpf calls. -// -// Each library may contain multiple functions / labels, and is only linked -// if prog references one of these functions. -// -// Libraries also linked. -func link(prog *ProgramSpec, libs []*ProgramSpec) error { - var ( - linked = make(map[*ProgramSpec]bool) - pending = []asm.Instructions{prog.Instructions} - insns asm.Instructions - ) - for len(pending) > 0 { - insns, pending = pending[0], pending[1:] - for _, lib := range libs { - if linked[lib] { - continue - } +// handles stores handle objects to avoid gc cleanup +type handles []*btf.Handle - needed, err := needSection(insns, lib.Instructions) - if err != nil { - return fmt.Errorf("linking %s: %w", lib.Name, err) - } +func (hs *handles) add(h *btf.Handle) (int, error) { + if h == nil { + return 0, nil + } - if !needed { - continue - } + if len(*hs) == math.MaxInt16 { + return 0, fmt.Errorf("can't add more than %d module FDs to fdArray", math.MaxInt16) + } + + *hs = append(*hs, h) + + // return length of slice so that indexes start at 1 + return len(*hs), nil +} + +func (hs handles) fdArray() []int32 { + // first element of fda is reserved as no module can be indexed with 0 + fda := []int32{0} + for _, h := range hs { + fda = append(fda, int32(h.FD())) + } + + return fda +} + +func (hs handles) close() { + for _, h := range hs { + h.Close() + } +} + +// splitSymbols splits insns into subsections delimited by Symbol Instructions. +// insns cannot be empty and must start with a Symbol Instruction. +// +// The resulting map is indexed by Symbol name. +func splitSymbols(insns asm.Instructions) (map[string]asm.Instructions, error) { + if len(insns) == 0 { + return nil, errors.New("insns is empty") + } - linked[lib] = true - prog.Instructions = append(prog.Instructions, lib.Instructions...) - pending = append(pending, lib.Instructions) + if insns[0].Symbol() == "" { + return nil, errors.New("insns must start with a Symbol") + } - if prog.BTF != nil && lib.BTF != nil { - if err := prog.BTF.Append(lib.BTF); err != nil { - return fmt.Errorf("linking BTF of %s: %w", lib.Name, err) - } + var name string + progs := make(map[string]asm.Instructions) + for _, ins := range insns { + if sym := ins.Symbol(); sym != "" { + if progs[sym] != nil { + return nil, fmt.Errorf("insns contains duplicate Symbol %s", sym) } + name = sym } + + progs[name] = append(progs[name], ins) } - return nil + return progs, nil } -func needSection(insns, section asm.Instructions) (bool, error) { - // A map of symbols to the libraries which contain them. - symbols, err := section.SymbolOffsets() - if err != nil { - return false, err +// The linker is responsible for resolving bpf-to-bpf calls between programs +// within an ELF. Each BPF program must be a self-contained binary blob, +// so when an instruction in one ELF program section wants to jump to +// a function in another, the linker needs to pull in the bytecode +// (and BTF info) of the target function and concatenate the instruction +// streams. +// +// Later on in the pipeline, all call sites are fixed up with relative jumps +// within this newly-created instruction stream to then finally hand off to +// the kernel with BPF_PROG_LOAD. +// +// Each function is denoted by an ELF symbol and the compiler takes care of +// register setup before each jump instruction. + +// hasFunctionReferences returns true if insns contains one or more bpf2bpf +// function references. +func hasFunctionReferences(insns asm.Instructions) bool { + for _, i := range insns { + if i.IsFunctionReference() { + return true + } } + return false +} - for _, ins := range insns { - if ins.Reference == "" { - continue +// applyRelocations collects and applies any CO-RE relocations in insns. +// +// Passing a nil target will relocate against the running kernel. insns are +// modified in place. +func applyRelocations(insns asm.Instructions, target *btf.Spec, bo binary.ByteOrder) error { + var relos []*btf.CORERelocation + var reloInsns []*asm.Instruction + iter := insns.Iterate() + for iter.Next() { + if relo := btf.CORERelocationMetadata(iter.Ins); relo != nil { + relos = append(relos, relo) + reloInsns = append(reloInsns, iter.Ins) } + } - if ins.OpCode.JumpOp() != asm.Call || ins.Src != asm.PseudoCall { - continue + if len(relos) == 0 { + return nil + } + + if bo == nil { + bo = internal.NativeEndian + } + + fixups, err := btf.CORERelocate(relos, target, bo) + if err != nil { + return err + } + + for i, fixup := range fixups { + if err := fixup.Apply(reloInsns[i]); err != nil { + return fmt.Errorf("fixup for %s: %w", relos[i], err) } + } + + return nil +} + +// flattenPrograms resolves bpf-to-bpf calls for a set of programs. +// +// Links all programs in names by modifying their ProgramSpec in progs. +func flattenPrograms(progs map[string]*ProgramSpec, names []string) { + // Pre-calculate all function references. + refs := make(map[*ProgramSpec][]string) + for _, prog := range progs { + refs[prog] = prog.Instructions.FunctionReferences() + } + + // Create a flattened instruction stream, but don't modify progs yet to + // avoid linking multiple times. + flattened := make([]asm.Instructions, 0, len(names)) + for _, name := range names { + flattened = append(flattened, flattenInstructions(name, progs, refs)) + } + + // Finally, assign the flattened instructions. + for i, name := range names { + progs[name].Instructions = flattened[i] + } +} + +// flattenInstructions resolves bpf-to-bpf calls for a single program. +// +// Flattens the instructions of prog by concatenating the instructions of all +// direct and indirect dependencies. +// +// progs contains all referenceable programs, while refs contain the direct +// dependencies of each program. +func flattenInstructions(name string, progs map[string]*ProgramSpec, refs map[*ProgramSpec][]string) asm.Instructions { + prog := progs[name] + + insns := make(asm.Instructions, len(prog.Instructions)) + copy(insns, prog.Instructions) + + // Add all direct references of prog to the list of to be linked programs. + pending := make([]string, len(refs[prog])) + copy(pending, refs[prog]) + + // All references for which we've appended instructions. + linked := make(map[string]bool) + + // Iterate all pending references. We can't use a range since pending is + // modified in the body below. + for len(pending) > 0 { + var ref string + ref, pending = pending[0], pending[1:] - if ins.Constant != -1 { - // This is already a valid call, no need to link again. + if linked[ref] { + // We've already linked this ref, don't append instructions again. continue } - if _, ok := symbols[ins.Reference]; !ok { - // Symbol isn't available in this section + progRef := progs[ref] + if progRef == nil { + // We don't have instructions that go with this reference. This + // happens when calling extern functions. continue } - // At this point we know that at least one function in the - // library is called from insns, so we have to link it. - return true, nil + insns = append(insns, progRef.Instructions...) + linked[ref] = true + + // Make sure we link indirect references. + pending = append(pending, refs[progRef]...) } - // None of the functions in the section are called. - return false, nil + return insns } -func fixupJumpsAndCalls(insns asm.Instructions) error { - symbolOffsets := make(map[string]asm.RawInstructionOffset) +// fixupAndValidate is called by the ELF reader right before marshaling the +// instruction stream. It performs last-minute adjustments to the program and +// runs some sanity checks before sending it off to the kernel. +func fixupAndValidate(insns asm.Instructions) error { iter := insns.Iterate() for iter.Next() { ins := iter.Ins - if ins.Symbol == "" { - continue + // Map load was tagged with a Reference, but does not contain a Map pointer. + needsMap := ins.Reference() != "" || ins.Metadata.Get(kconfigMetaKey{}) != nil + if ins.IsLoadFromMap() && needsMap && ins.Map() == nil { + return fmt.Errorf("instruction %d: %w", iter.Index, asm.ErrUnsatisfiedMapReference) } - if _, ok := symbolOffsets[ins.Symbol]; ok { - return fmt.Errorf("duplicate symbol %s", ins.Symbol) + fixupProbeReadKernel(ins) + } + + return nil +} + +// fixupKfuncs loops over all instructions in search for kfunc calls. +// If at least one is found, the current kernels BTF and module BTFis are searched to set Instruction.Constant +// and Instruction.Offset to the correct values. +func fixupKfuncs(insns asm.Instructions) (handles, error) { + iter := insns.Iterate() + for iter.Next() { + ins := iter.Ins + if ins.IsKfuncCall() { + goto fixups } + } - symbolOffsets[ins.Symbol] = iter.Offset + return nil, nil + +fixups: + // only load the kernel spec if we found at least one kfunc call + kernelSpec, err := btf.LoadKernelSpec() + if err != nil { + return nil, err } - iter = insns.Iterate() - for iter.Next() { - i := iter.Index - offset := iter.Offset + fdArray := make(handles, 0) + for { ins := iter.Ins - if ins.Reference == "" { + if !ins.IsKfuncCall() { + if !iter.Next() { + // break loop if this was the last instruction in the stream. + break + } continue } - switch { - case ins.IsFunctionCall() && ins.Constant == -1: - // Rewrite bpf to bpf call - callOffset, ok := symbolOffsets[ins.Reference] - if !ok { - return fmt.Errorf("call at %d: reference to missing symbol %q", i, ins.Reference) - } + // check meta, if no meta return err + kfm, _ := ins.Metadata.Get(kfuncMeta{}).(*btf.Func) + if kfm == nil { + return nil, fmt.Errorf("kfunc call has no kfuncMeta") + } + + target := btf.Type((*btf.Func)(nil)) + spec, module, err := findTargetInKernel(kernelSpec, kfm.Name, &target) + if errors.Is(err, btf.ErrNotFound) { + return nil, fmt.Errorf("kfunc %q: %w", kfm.Name, ErrNotSupported) + } + if err != nil { + return nil, err + } - ins.Constant = int64(callOffset - offset - 1) + if err := btf.CheckTypeCompatibility(kfm.Type, target.(*btf.Func).Type); err != nil { + return nil, &incompatibleKfuncError{kfm.Name, err} + } - case ins.OpCode.Class() == asm.JumpClass && ins.Offset == -1: - // Rewrite jump to label - jumpOffset, ok := symbolOffsets[ins.Reference] - if !ok { - return fmt.Errorf("jump at %d: reference to missing symbol %q", i, ins.Reference) - } + id, err := spec.TypeID(target) + if err != nil { + return nil, err + } + + idx, err := fdArray.add(module) + if err != nil { + return nil, err + } + + ins.Constant = int64(id) + ins.Offset = int16(idx) + + if !iter.Next() { + break + } + } + + return fdArray, nil +} + +type incompatibleKfuncError struct { + name string + err error +} + +func (ike *incompatibleKfuncError) Error() string { + return fmt.Sprintf("kfunc %q: %s", ike.name, ike.err) +} + +// fixupProbeReadKernel replaces calls to bpf_probe_read_{kernel,user}(_str) +// with bpf_probe_read(_str) on kernels that don't support it yet. +func fixupProbeReadKernel(ins *asm.Instruction) { + if !ins.IsBuiltinCall() { + return + } + + // Kernel supports bpf_probe_read_kernel, nothing to do. + if haveProbeReadKernel() == nil { + return + } + + switch asm.BuiltinFunc(ins.Constant) { + case asm.FnProbeReadKernel, asm.FnProbeReadUser: + ins.Constant = int64(asm.FnProbeRead) + case asm.FnProbeReadKernelStr, asm.FnProbeReadUserStr: + ins.Constant = int64(asm.FnProbeReadStr) + } +} - ins.Offset = int16(jumpOffset - offset - 1) +// resolveKconfigReferences creates and populates a .kconfig map if necessary. +// +// Returns a nil Map and no error if no references exist. +func resolveKconfigReferences(insns asm.Instructions) (_ *Map, err error) { + closeOnError := func(c io.Closer) { + if err != nil { + c.Close() + } + } - case ins.IsLoadFromMap() && ins.MapPtr() == -1: - return fmt.Errorf("map %s: %w", ins.Reference, errUnsatisfiedReference) + var spec *MapSpec + iter := insns.Iterate() + for iter.Next() { + meta, _ := iter.Ins.Metadata.Get(kconfigMetaKey{}).(*kconfigMeta) + if meta != nil { + spec = meta.Map + break } } - // fixupBPFCalls replaces bpf_probe_read_{kernel,user}[_str] with bpf_probe_read[_str] on older kernels - // https://github.com/libbpf/libbpf/blob/master/src/libbpf.c#L6009 + if spec == nil { + return nil, nil + } + + cpy := spec.Copy() + if err := resolveKconfig(cpy); err != nil { + return nil, err + } + + kconfig, err := NewMap(cpy) + if err != nil { + return nil, err + } + defer closeOnError(kconfig) + + // Resolve all instructions which load from .kconfig map with actual map + // and offset inside it. iter = insns.Iterate() for iter.Next() { - ins := iter.Ins - if !ins.IsBuiltinCall() { + meta, _ := iter.Ins.Metadata.Get(kconfigMetaKey{}).(*kconfigMeta) + if meta == nil { continue } - switch asm.BuiltinFunc(ins.Constant) { - case asm.FnProbeReadKernel, asm.FnProbeReadUser: - if err := haveProbeReadKernel(); err != nil { - ins.Constant = int64(asm.FnProbeRead) - } - case asm.FnProbeReadKernelStr, asm.FnProbeReadUserStr: - if err := haveProbeReadKernel(); err != nil { - ins.Constant = int64(asm.FnProbeReadStr) - } + + if meta.Map != spec { + return nil, fmt.Errorf("instruction %d: reference to multiple .kconfig maps is not allowed", iter.Index) } + + if err := iter.Ins.AssociateMap(kconfig); err != nil { + return nil, fmt.Errorf("instruction %d: %w", iter.Index, err) + } + + // Encode a map read at the offset of the var in the datasec. + iter.Ins.Constant = int64(uint64(meta.Offset) << 32) + iter.Ins.Metadata.Set(kconfigMetaKey{}, nil) } - return nil + return kconfig, nil } diff --git a/vendor/github.com/cilium/ebpf/map.go b/vendor/github.com/cilium/ebpf/map.go index cca387ead0..a11664cc72 100644 --- a/vendor/github.com/cilium/ebpf/map.go +++ b/vendor/github.com/cilium/ebpf/map.go @@ -5,12 +5,16 @@ import ( "errors" "fmt" "io" + "math/rand" + "os" "path/filepath" "reflect" - "strings" + "time" + "unsafe" + "github.com/cilium/ebpf/btf" "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/btf" + "github.com/cilium/ebpf/internal/sys" "github.com/cilium/ebpf/internal/unix" ) @@ -19,7 +23,8 @@ var ( ErrKeyNotExist = errors.New("key does not exist") ErrKeyExist = errors.New("key already exists") ErrIterationAborted = errors.New("iteration aborted") - ErrMapIncompatible = errors.New("map's spec is incompatible with pinned map") + ErrMapIncompatible = errors.New("map spec is incompatible with existing map") + errMapNoBTFValue = errors.New("map spec does not contain a BTF Value") ) // MapOptions control loading a map into the kernel. @@ -67,12 +72,12 @@ type MapSpec struct { InnerMap *MapSpec // Extra trailing bytes found in the ELF map definition when using structs - // larger than libbpf's bpf_map_def. Must be empty before instantiating - // the MapSpec into a Map. - Extra bytes.Reader + // larger than libbpf's bpf_map_def. nil if no trailing bytes were present. + // Must be nil or empty before instantiating the MapSpec into a Map. + Extra *bytes.Reader - // The BTF associated with this map. - BTF *btf.Map + // The key and value type of this map. May be nil. + Key, Value btf.Type } func (ms *MapSpec) String() string { @@ -114,13 +119,42 @@ func (ms *MapSpec) clampPerfEventArraySize() error { return nil } +// dataSection returns the contents and BTF Datasec descriptor of the spec. +func (ms *MapSpec) dataSection() ([]byte, *btf.Datasec, error) { + + if ms.Value == nil { + return nil, nil, errMapNoBTFValue + } + + ds, ok := ms.Value.(*btf.Datasec) + if !ok { + return nil, nil, fmt.Errorf("map value BTF is a %T, not a *btf.Datasec", ms.Value) + } + + if n := len(ms.Contents); n != 1 { + return nil, nil, fmt.Errorf("expected one key, found %d", n) + } + + kv := ms.Contents[0] + value, ok := kv.Value.([]byte) + if !ok { + return nil, nil, fmt.Errorf("value at first map key is %T, not []byte", kv.Value) + } + + return value, ds, nil +} + // MapKV is used to initialize the contents of a Map. type MapKV struct { Key interface{} Value interface{} } -func (ms *MapSpec) checkCompatibility(m *Map) error { +// Compatible returns nil if an existing map may be used instead of creating +// one from the spec. +// +// Returns an error wrapping [ErrMapIncompatible] otherwise. +func (ms *MapSpec) Compatible(m *Map) error { switch { case m.typ != ms.Type: return fmt.Errorf("expected type %v, got %v: %w", ms.Type, m.typ, ErrMapIncompatible) @@ -131,10 +165,14 @@ func (ms *MapSpec) checkCompatibility(m *Map) error { case m.valueSize != ms.ValueSize: return fmt.Errorf("expected value size %v, got %v: %w", ms.ValueSize, m.valueSize, ErrMapIncompatible) - case m.maxEntries != ms.MaxEntries: + case !(ms.Type == PerfEventArray && ms.MaxEntries == 0) && + m.maxEntries != ms.MaxEntries: return fmt.Errorf("expected max entries %v, got %v: %w", ms.MaxEntries, m.maxEntries, ErrMapIncompatible) - case m.flags != ms.Flags: + // BPF_F_RDONLY_PROG is set unconditionally for devmaps. Explicitly allow + // this mismatch. + case !((ms.Type == DevMap || ms.Type == DevMapHash) && m.flags^ms.Flags == unix.BPF_F_RDONLY_PROG) && + m.flags != ms.Flags: return fmt.Errorf("expected flags %v, got %v: %w", ms.Flags, m.flags, ErrMapIncompatible) } return nil @@ -151,7 +189,7 @@ func (ms *MapSpec) checkCompatibility(m *Map) error { // if you require custom encoding. type Map struct { name string - fd *internal.FD + fd *sys.FD typ MapType keySize uint32 valueSize uint32 @@ -166,18 +204,19 @@ type Map struct { // // You should not use fd after calling this function. func NewMapFromFD(fd int) (*Map, error) { - if fd < 0 { - return nil, errors.New("invalid fd") + f, err := sys.NewFD(fd) + if err != nil { + return nil, err } - return newMapFromFD(internal.NewFD(uint32(fd))) + return newMapFromFD(f) } -func newMapFromFD(fd *internal.FD) (*Map, error) { +func newMapFromFD(fd *sys.FD) (*Map, error) { info, err := newMapInfoFromFd(fd) if err != nil { fd.Close() - return nil, fmt.Errorf("get map info: %s", err) + return nil, fmt.Errorf("get map info: %w", err) } return newMap(fd, info.Name, info.Type, info.KeySize, info.ValueSize, info.MaxEntries, info.Flags) @@ -201,23 +240,20 @@ func NewMap(spec *MapSpec) (*Map, error) { // // May return an error wrapping ErrMapIncompatible. func NewMapWithOptions(spec *MapSpec, opts MapOptions) (*Map, error) { - handles := newHandleCache() - defer handles.close() - - m, err := newMapWithOptions(spec, opts, handles) + m, err := newMapWithOptions(spec, opts) if err != nil { return nil, fmt.Errorf("creating map: %w", err) } - err = m.finalize(spec) - if err != nil { + if err := m.finalize(spec); err != nil { + m.Close() return nil, fmt.Errorf("populating map: %w", err) } return m, nil } -func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_ *Map, err error) { +func newMapWithOptions(spec *MapSpec, opts MapOptions) (_ *Map, err error) { closeOnError := func(c io.Closer) { if err != nil { c.Close() @@ -244,7 +280,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_ } defer closeOnError(m) - if err := spec.checkCompatibility(m); err != nil { + if err := spec.Compatible(m); err != nil { return nil, fmt.Errorf("use pinned map %s: %w", spec.Name, err) } @@ -257,7 +293,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_ return nil, fmt.Errorf("pin type %d: %w", int(spec.Pinning), ErrNotSupported) } - var innerFd *internal.FD + var innerFd *sys.FD if spec.Type == ArrayOfMaps || spec.Type == HashOfMaps { if spec.InnerMap == nil { return nil, fmt.Errorf("%s requires InnerMap", spec.Type) @@ -267,7 +303,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_ return nil, errors.New("inner maps cannot be pinned") } - template, err := spec.InnerMap.createMap(nil, opts, handles) + template, err := spec.InnerMap.createMap(nil, opts) if err != nil { return nil, fmt.Errorf("inner map: %w", err) } @@ -279,7 +315,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_ innerFd = template.fd } - m, err := spec.createMap(innerFd, opts, handles) + m, err := spec.createMap(innerFd, opts) if err != nil { return nil, err } @@ -288,7 +324,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_ if spec.Pinning == PinByName { path := filepath.Join(opts.PinPath, spec.Name) if err := m.Pin(path); err != nil { - return nil, fmt.Errorf("pin map: %s", err) + return nil, fmt.Errorf("pin map to %s: %w", path, err) } } @@ -297,21 +333,21 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_ // createMap validates the spec's properties and creates the map in the kernel // using the given opts. It does not populate or freeze the map. -func (spec *MapSpec) createMap(inner *internal.FD, opts MapOptions, handles *handleCache) (_ *Map, err error) { +func (spec *MapSpec) createMap(inner *sys.FD, opts MapOptions) (_ *Map, err error) { closeOnError := func(closer io.Closer) { if err != nil { closer.Close() } } - spec = spec.Copy() - // Kernels 4.13 through 5.4 used a struct bpf_map_def that contained // additional 'inner_map_idx' and later 'numa_node' fields. // In order to support loading these definitions, tolerate the presence of // extra bytes, but require them to be zeroes. - if _, err := io.Copy(internal.DiscardZeroes{}, &spec.Extra); err != nil { - return nil, errors.New("extra contains unhandled non-zero bytes, drain before creating map") + if spec.Extra != nil { + if _, err := io.Copy(internal.DiscardZeroes{}, spec.Extra); err != nil { + return nil, errors.New("extra contains unhandled non-zero bytes, drain before creating map") + } } switch spec.Type { @@ -323,17 +359,21 @@ func (spec *MapSpec) createMap(inner *internal.FD, opts MapOptions, handles *han if spec.ValueSize != 0 && spec.ValueSize != 4 { return nil, errors.New("ValueSize must be zero or four for map of map") } + + spec = spec.Copy() spec.ValueSize = 4 case PerfEventArray: if spec.KeySize != 0 && spec.KeySize != 4 { return nil, errors.New("KeySize must be zero or four for perf event array") } - spec.KeySize = 4 if spec.ValueSize != 0 && spec.ValueSize != 4 { return nil, errors.New("ValueSize must be zero or four for perf event array") } + + spec = spec.Copy() + spec.KeySize = 4 spec.ValueSize = 4 if spec.MaxEntries == 0 { @@ -360,50 +400,65 @@ func (spec *MapSpec) createMap(inner *internal.FD, opts MapOptions, handles *han return nil, fmt.Errorf("map create: %w", err) } } + if spec.Flags&unix.BPF_F_NO_PREALLOC > 0 { + if err := haveNoPreallocMaps(); err != nil { + return nil, fmt.Errorf("map create: %w", err) + } + } - attr := internal.BPFMapCreateAttr{ - MapType: uint32(spec.Type), + attr := sys.MapCreateAttr{ + MapType: sys.MapType(spec.Type), KeySize: spec.KeySize, ValueSize: spec.ValueSize, MaxEntries: spec.MaxEntries, - Flags: spec.Flags, + MapFlags: sys.MapFlags(spec.Flags), NumaNode: spec.NumaNode, } if inner != nil { - var err error - attr.InnerMapFd, err = inner.Value() - if err != nil { - return nil, fmt.Errorf("map create: %w", err) - } + attr.InnerMapFd = inner.Uint() } if haveObjName() == nil { - attr.MapName = internal.NewBPFObjName(spec.Name) + attr.MapName = sys.NewObjName(spec.Name) } - var btfDisabled bool - if spec.BTF != nil { - handle, err := handles.btfHandle(spec.BTF.Spec) - btfDisabled = errors.Is(err, btf.ErrNotSupported) - if err != nil && !btfDisabled { + if spec.Key != nil || spec.Value != nil { + handle, keyTypeID, valueTypeID, err := btf.MarshalMapKV(spec.Key, spec.Value) + if err != nil && !errors.Is(err, btf.ErrNotSupported) { return nil, fmt.Errorf("load BTF: %w", err) } if handle != nil { - attr.BTFFd = uint32(handle.FD()) - attr.BTFKeyTypeID = uint32(spec.BTF.Key.ID()) - attr.BTFValueTypeID = uint32(spec.BTF.Value.ID()) + defer handle.Close() + + // Use BTF k/v during map creation. + attr.BtfFd = uint32(handle.FD()) + attr.BtfKeyTypeId = keyTypeID + attr.BtfValueTypeId = valueTypeID } } - fd, err := internal.BPFMapCreate(&attr) + fd, err := sys.MapCreate(&attr) + // Some map types don't support BTF k/v in earlier kernel versions. + // Remove BTF metadata and retry map creation. + if (errors.Is(err, sys.ENOTSUPP) || errors.Is(err, unix.EINVAL)) && attr.BtfFd != 0 { + attr.BtfFd, attr.BtfKeyTypeId, attr.BtfValueTypeId = 0, 0, 0 + fd, err = sys.MapCreate(&attr) + } + if err != nil { if errors.Is(err, unix.EPERM) { - return nil, fmt.Errorf("map create: %w (MEMLOCK bay be too low, consider rlimit.RemoveMemlock)", err) + return nil, fmt.Errorf("map create: %w (MEMLOCK may be too low, consider rlimit.RemoveMemlock)", err) + } + if errors.Is(err, unix.EINVAL) && attr.MaxEntries == 0 { + return nil, fmt.Errorf("map create: %w (MaxEntries may be incorrectly set to zero)", err) } - if btfDisabled { - return nil, fmt.Errorf("map create without BTF: %w", err) + if errors.Is(err, unix.EINVAL) && spec.Type == UnspecifiedMap { + return nil, fmt.Errorf("map create: cannot use type %s", UnspecifiedMap) + } + if attr.BtfFd == 0 { + return nil, fmt.Errorf("map create: %w (without BTF k/v)", err) } return nil, fmt.Errorf("map create: %w", err) } @@ -419,7 +474,7 @@ func (spec *MapSpec) createMap(inner *internal.FD, opts MapOptions, handles *han // newMap allocates and returns a new Map structure. // Sets the fullValueSize on per-CPU maps. -func newMap(fd *internal.FD, name string, typ MapType, keySize, valueSize, maxEntries, flags uint32) (*Map, error) { +func newMap(fd *sys.FD, name string, typ MapType, keySize, valueSize, maxEntries, flags uint32) (*Map, error) { m := &Map{ name, fd, @@ -441,7 +496,7 @@ func newMap(fd *internal.FD, name string, typ MapType, keySize, valueSize, maxEn return nil, err } - m.fullValueSize = internal.Align(int(valueSize), 8) * possibleCPUs + m.fullValueSize = int(internal.Align(valueSize, 8)) * possibleCPUs return m, nil } @@ -482,6 +537,12 @@ func (m *Map) Info() (*MapInfo, error) { return newMapInfoFromFd(m.fd) } +// MapLookupFlags controls the behaviour of the map lookup calls. +type MapLookupFlags uint64 + +// LookupLock look up the value of a spin-locked map. +const LookupLock MapLookupFlags = 4 + // Lookup retrieves a value from a Map. // // Calls Close() on valueOut if it is of type **Map or **Program, @@ -489,8 +550,26 @@ func (m *Map) Info() (*MapInfo, error) { // // Returns an error if the key doesn't exist, see ErrKeyNotExist. func (m *Map) Lookup(key, valueOut interface{}) error { + return m.LookupWithFlags(key, valueOut, 0) +} + +// LookupWithFlags retrieves a value from a Map with flags. +// +// Passing LookupLock flag will look up the value of a spin-locked +// map without returning the lock. This must be specified if the +// elements contain a spinlock. +// +// Calls Close() on valueOut if it is of type **Map or **Program, +// and *valueOut is not nil. +// +// Returns an error if the key doesn't exist, see ErrKeyNotExist. +func (m *Map) LookupWithFlags(key, valueOut interface{}, flags MapLookupFlags) error { + if m.typ.hasPerCPUValue() { + return m.lookupPerCPU(key, valueOut, flags) + } + valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize) - if err := m.lookup(key, valuePtr); err != nil { + if err := m.lookup(key, valuePtr, flags); err != nil { return err } @@ -501,17 +580,25 @@ func (m *Map) Lookup(key, valueOut interface{}) error { // // Returns ErrKeyNotExist if the key doesn't exist. func (m *Map) LookupAndDelete(key, valueOut interface{}) error { - valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize) + return m.LookupAndDeleteWithFlags(key, valueOut, 0) +} - keyPtr, err := m.marshalKey(key) - if err != nil { - return fmt.Errorf("can't marshal key: %w", err) +// LookupAndDeleteWithFlags retrieves and deletes a value from a Map. +// +// Passing LookupLock flag will look up and delete the value of a spin-locked +// map without returning the lock. This must be specified if the elements +// contain a spinlock. +// +// Returns ErrKeyNotExist if the key doesn't exist. +func (m *Map) LookupAndDeleteWithFlags(key, valueOut interface{}, flags MapLookupFlags) error { + if m.typ.hasPerCPUValue() { + return m.lookupAndDeletePerCPU(key, valueOut, flags) } - if err := bpfMapLookupAndDelete(m.fd, keyPtr, valuePtr); err != nil { - return fmt.Errorf("lookup and delete failed: %w", err) + valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize) + if err := m.lookupAndDelete(key, valuePtr, flags); err != nil { + return err } - return m.unmarshalValue(valueOut, valueBytes) } @@ -520,9 +607,9 @@ func (m *Map) LookupAndDelete(key, valueOut interface{}) error { // Returns a nil value if a key doesn't exist. func (m *Map) LookupBytes(key interface{}) ([]byte, error) { valueBytes := make([]byte, m.fullValueSize) - valuePtr := internal.NewSlicePointer(valueBytes) + valuePtr := sys.NewSlicePointer(valueBytes) - err := m.lookup(key, valuePtr) + err := m.lookup(key, valuePtr, 0) if errors.Is(err, ErrKeyNotExist) { return nil, nil } @@ -530,18 +617,61 @@ func (m *Map) LookupBytes(key interface{}) ([]byte, error) { return valueBytes, err } -func (m *Map) lookup(key interface{}, valueOut internal.Pointer) error { +func (m *Map) lookupPerCPU(key, valueOut any, flags MapLookupFlags) error { + valueBytes := make([]byte, m.fullValueSize) + if err := m.lookup(key, sys.NewSlicePointer(valueBytes), flags); err != nil { + return err + } + return unmarshalPerCPUValue(valueOut, int(m.valueSize), valueBytes) +} + +func (m *Map) lookup(key interface{}, valueOut sys.Pointer, flags MapLookupFlags) error { keyPtr, err := m.marshalKey(key) if err != nil { return fmt.Errorf("can't marshal key: %w", err) } - if err = bpfMapLookupElem(m.fd, keyPtr, valueOut); err != nil { - return fmt.Errorf("lookup failed: %w", err) + attr := sys.MapLookupElemAttr{ + MapFd: m.fd.Uint(), + Key: keyPtr, + Value: valueOut, + Flags: uint64(flags), + } + + if err = sys.MapLookupElem(&attr); err != nil { + return fmt.Errorf("lookup: %w", wrapMapError(err)) } return nil } +func (m *Map) lookupAndDeletePerCPU(key, valueOut any, flags MapLookupFlags) error { + valueBytes := make([]byte, m.fullValueSize) + if err := m.lookupAndDelete(key, sys.NewSlicePointer(valueBytes), flags); err != nil { + return err + } + return unmarshalPerCPUValue(valueOut, int(m.valueSize), valueBytes) +} + +func (m *Map) lookupAndDelete(key any, valuePtr sys.Pointer, flags MapLookupFlags) error { + keyPtr, err := m.marshalKey(key) + if err != nil { + return fmt.Errorf("can't marshal key: %w", err) + } + + attr := sys.MapLookupAndDeleteElemAttr{ + MapFd: m.fd.Uint(), + Key: keyPtr, + Value: valuePtr, + Flags: uint64(flags), + } + + if err := sys.MapLookupAndDeleteElem(&attr); err != nil { + return fmt.Errorf("lookup and delete: %w", wrapMapError(err)) + } + + return nil +} + // MapUpdateFlags controls the behaviour of the Map.Update call. // // The exact semantics depend on the specific MapType. @@ -554,6 +684,8 @@ const ( UpdateNoExist MapUpdateFlags = 1 << (iota - 1) // UpdateExist updates an existing element. UpdateExist + // UpdateLock updates elements under bpf_spin_lock. + UpdateLock ) // Put replaces or creates a value in map. @@ -564,19 +696,43 @@ func (m *Map) Put(key, value interface{}) error { } // Update changes the value of a key. -func (m *Map) Update(key, value interface{}, flags MapUpdateFlags) error { - keyPtr, err := m.marshalKey(key) - if err != nil { - return fmt.Errorf("can't marshal key: %w", err) +func (m *Map) Update(key, value any, flags MapUpdateFlags) error { + if m.typ.hasPerCPUValue() { + return m.updatePerCPU(key, value, flags) } valuePtr, err := m.marshalValue(value) if err != nil { - return fmt.Errorf("can't marshal value: %w", err) + return fmt.Errorf("marshal value: %w", err) + } + + return m.update(key, valuePtr, flags) +} + +func (m *Map) updatePerCPU(key, value any, flags MapUpdateFlags) error { + valuePtr, err := marshalPerCPUValue(value, int(m.valueSize)) + if err != nil { + return fmt.Errorf("marshal value: %w", err) + } + + return m.update(key, valuePtr, flags) +} + +func (m *Map) update(key any, valuePtr sys.Pointer, flags MapUpdateFlags) error { + keyPtr, err := m.marshalKey(key) + if err != nil { + return fmt.Errorf("marshal key: %w", err) + } + + attr := sys.MapUpdateElemAttr{ + MapFd: m.fd.Uint(), + Key: keyPtr, + Value: valuePtr, + Flags: uint64(flags), } - if err = bpfMapUpdateElem(m.fd, keyPtr, valuePtr, uint64(flags)); err != nil { - return fmt.Errorf("update failed: %w", err) + if err = sys.MapUpdateElem(&attr); err != nil { + return fmt.Errorf("update: %w", wrapMapError(err)) } return nil @@ -591,8 +747,13 @@ func (m *Map) Delete(key interface{}) error { return fmt.Errorf("can't marshal key: %w", err) } - if err = bpfMapDeleteElem(m.fd, keyPtr); err != nil { - return fmt.Errorf("delete failed: %w", err) + attr := sys.MapDeleteElemAttr{ + MapFd: m.fd.Uint(), + Key: keyPtr, + } + + if err = sys.MapDeleteElem(&attr); err != nil { + return fmt.Errorf("delete: %w", wrapMapError(err)) } return nil } @@ -624,7 +785,7 @@ func (m *Map) NextKey(key, nextKeyOut interface{}) error { // Returns nil if there are no more keys. func (m *Map) NextKeyBytes(key interface{}) ([]byte, error) { nextKey := make([]byte, m.keySize) - nextKeyPtr := internal.NewSlicePointer(nextKey) + nextKeyPtr := sys.NewSlicePointer(nextKey) err := m.nextKey(key, nextKeyPtr) if errors.Is(err, ErrKeyNotExist) { @@ -634,9 +795,9 @@ func (m *Map) NextKeyBytes(key interface{}) ([]byte, error) { return nextKey, err } -func (m *Map) nextKey(key interface{}, nextKeyOut internal.Pointer) error { +func (m *Map) nextKey(key interface{}, nextKeyOut sys.Pointer) error { var ( - keyPtr internal.Pointer + keyPtr sys.Pointer err error ) @@ -647,12 +808,87 @@ func (m *Map) nextKey(key interface{}, nextKeyOut internal.Pointer) error { } } - if err = bpfMapGetNextKey(m.fd, keyPtr, nextKeyOut); err != nil { - return fmt.Errorf("next key failed: %w", err) + attr := sys.MapGetNextKeyAttr{ + MapFd: m.fd.Uint(), + Key: keyPtr, + NextKey: nextKeyOut, } + + if err = sys.MapGetNextKey(&attr); err != nil { + // Kernels 4.4.131 and earlier return EFAULT instead of a pointer to the + // first map element when a nil key pointer is specified. + if key == nil && errors.Is(err, unix.EFAULT) { + var guessKey []byte + guessKey, err = m.guessNonExistentKey() + if err != nil { + return err + } + + // Retry the syscall with a valid non-existing key. + attr.Key = sys.NewSlicePointer(guessKey) + if err = sys.MapGetNextKey(&attr); err == nil { + return nil + } + } + + return fmt.Errorf("next key: %w", wrapMapError(err)) + } + return nil } +var mmapProtectedPage = internal.Memoize(func() ([]byte, error) { + return unix.Mmap(-1, 0, os.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_SHARED) +}) + +// guessNonExistentKey attempts to perform a map lookup that returns ENOENT. +// This is necessary on kernels before 4.4.132, since those don't support +// iterating maps from the start by providing an invalid key pointer. +func (m *Map) guessNonExistentKey() ([]byte, error) { + // Map a protected page and use that as the value pointer. This saves some + // work copying out the value, which we're not interested in. + page, err := mmapProtectedPage() + if err != nil { + return nil, err + } + valuePtr := sys.NewSlicePointer(page) + + randKey := make([]byte, int(m.keySize)) + + for i := 0; i < 4; i++ { + switch i { + // For hash maps, the 0 key is less likely to be occupied. They're often + // used for storing data related to pointers, and their access pattern is + // generally scattered across the keyspace. + case 0: + // An all-0xff key is guaranteed to be out of bounds of any array, since + // those have a fixed key size of 4 bytes. The only corner case being + // arrays with 2^32 max entries, but those are prohibitively expensive + // in many environments. + case 1: + for r := range randKey { + randKey[r] = 0xff + } + // Inspired by BCC, 0x55 is an alternating binary pattern (0101), so + // is unlikely to be taken. + case 2: + for r := range randKey { + randKey[r] = 0x55 + } + // Last ditch effort, generate a random key. + case 3: + rand.New(rand.NewSource(time.Now().UnixNano())).Read(randKey) + } + + err := m.lookup(randKey, valuePtr, 0) + if errors.Is(err, ErrKeyNotExist) { + return randKey, nil + } + } + + return nil, errors.New("couldn't find non-existing key") +} + // BatchLookup looks up many elements in a map at once. // // "keysOut" and "valuesOut" must be of type slice, a pointer @@ -664,7 +900,7 @@ func (m *Map) nextKey(key interface{}, nextKeyOut internal.Pointer) error { // the end of all possible results, even when partial results // are returned. It should be used to evaluate when lookup is "done". func (m *Map) BatchLookup(prevKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) { - return m.batchLookup(internal.BPF_MAP_LOOKUP_BATCH, prevKey, nextKeyOut, keysOut, valuesOut, opts) + return m.batchLookup(sys.BPF_MAP_LOOKUP_BATCH, prevKey, nextKeyOut, keysOut, valuesOut, opts) } // BatchLookupAndDelete looks up many elements in a map at once, @@ -679,10 +915,10 @@ func (m *Map) BatchLookup(prevKey, nextKeyOut, keysOut, valuesOut interface{}, o // the end of all possible results, even when partial results // are returned. It should be used to evaluate when lookup is "done". func (m *Map) BatchLookupAndDelete(prevKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) { - return m.batchLookup(internal.BPF_MAP_LOOKUP_AND_DELETE_BATCH, prevKey, nextKeyOut, keysOut, valuesOut, opts) + return m.batchLookup(sys.BPF_MAP_LOOKUP_AND_DELETE_BATCH, prevKey, nextKeyOut, keysOut, valuesOut, opts) } -func (m *Map) batchLookup(cmd internal.BPFCmd, startKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) { +func (m *Map) batchLookup(cmd sys.Cmd, startKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) { if err := haveBatchAPI(); err != nil { return 0, err } @@ -702,29 +938,36 @@ func (m *Map) batchLookup(cmd internal.BPFCmd, startKey, nextKeyOut, keysOut, va return 0, fmt.Errorf("keysOut and valuesOut must be the same length") } keyBuf := make([]byte, count*int(m.keySize)) - keyPtr := internal.NewSlicePointer(keyBuf) + keyPtr := sys.NewSlicePointer(keyBuf) valueBuf := make([]byte, count*int(m.fullValueSize)) - valuePtr := internal.NewSlicePointer(valueBuf) + valuePtr := sys.NewSlicePointer(valueBuf) + nextPtr, nextBuf := makeBuffer(nextKeyOut, int(m.keySize)) - var ( - startPtr internal.Pointer - err error - retErr error - ) + attr := sys.MapLookupBatchAttr{ + MapFd: m.fd.Uint(), + Keys: keyPtr, + Values: valuePtr, + Count: uint32(count), + OutBatch: nextPtr, + } + + if opts != nil { + attr.ElemFlags = opts.ElemFlags + attr.Flags = opts.Flags + } + + var err error if startKey != nil { - startPtr, err = marshalPtr(startKey, int(m.keySize)) + attr.InBatch, err = marshalPtr(startKey, int(m.keySize)) if err != nil { return 0, err } } - nextPtr, nextBuf := makeBuffer(nextKeyOut, int(m.keySize)) - ct, err := bpfMapBatch(cmd, m.fd, startPtr, nextPtr, keyPtr, valuePtr, uint32(count), opts) - if err != nil { - if !errors.Is(err, ErrKeyNotExist) { - return 0, err - } - retErr = ErrKeyNotExist + _, sysErr := sys.BPF(cmd, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) + sysErr = wrapMapError(sysErr) + if sysErr != nil && !errors.Is(sysErr, unix.ENOENT) { + return 0, sysErr } err = m.unmarshalKey(nextKeyOut, nextBuf) @@ -737,9 +980,10 @@ func (m *Map) batchLookup(cmd internal.BPFCmd, startKey, nextKeyOut, keysOut, va } err = unmarshalBytes(valuesOut, valueBuf) if err != nil { - retErr = err + return 0, err } - return int(ct), retErr + + return int(attr.Count), sysErr } // BatchUpdate updates the map with multiple keys and values @@ -763,7 +1007,7 @@ func (m *Map) BatchUpdate(keys, values interface{}, opts *BatchOptions) (int, er } var ( count = keysValue.Len() - valuePtr internal.Pointer + valuePtr sys.Pointer err error ) if count != valuesValue.Len() { @@ -777,9 +1021,24 @@ func (m *Map) BatchUpdate(keys, values interface{}, opts *BatchOptions) (int, er if err != nil { return 0, err } - var nilPtr internal.Pointer - ct, err := bpfMapBatch(internal.BPF_MAP_UPDATE_BATCH, m.fd, nilPtr, nilPtr, keyPtr, valuePtr, uint32(count), opts) - return int(ct), err + + attr := sys.MapUpdateBatchAttr{ + MapFd: m.fd.Uint(), + Keys: keyPtr, + Values: valuePtr, + Count: uint32(count), + } + if opts != nil { + attr.ElemFlags = opts.ElemFlags + attr.Flags = opts.Flags + } + + err = sys.MapUpdateBatch(&attr) + if err != nil { + return int(attr.Count), fmt.Errorf("batch update: %w", wrapMapError(err)) + } + + return int(attr.Count), nil } // BatchDelete batch deletes entries in the map by keys. @@ -800,9 +1059,23 @@ func (m *Map) BatchDelete(keys interface{}, opts *BatchOptions) (int, error) { if err != nil { return 0, fmt.Errorf("cannot marshal keys: %v", err) } - var nilPtr internal.Pointer - ct, err := bpfMapBatch(internal.BPF_MAP_DELETE_BATCH, m.fd, nilPtr, nilPtr, keyPtr, nilPtr, uint32(count), opts) - return int(ct), err + + attr := sys.MapDeleteBatchAttr{ + MapFd: m.fd.Uint(), + Keys: keyPtr, + Count: uint32(count), + } + + if opts != nil { + attr.ElemFlags = opts.ElemFlags + attr.Flags = opts.Flags + } + + if err = sys.MapDeleteBatch(&attr); err != nil { + return int(attr.Count), fmt.Errorf("batch delete: %w", wrapMapError(err)) + } + + return int(attr.Count), nil } // Iterate traverses a map. @@ -815,7 +1088,8 @@ func (m *Map) Iterate() *MapIterator { return newMapIterator(m) } -// Close removes a Map +// Close the Map's underlying file descriptor, which could unload the +// Map from the kernel if it is not pinned or in use by a loaded Program. func (m *Map) Close() error { if m == nil { // This makes it easier to clean up when iterating maps @@ -830,14 +1104,7 @@ func (m *Map) Close() error { // // Calling this function is invalid after Close has been called. func (m *Map) FD() int { - fd, err := m.fd.Value() - if err != nil { - // Best effort: -1 is the number most likely to be an - // invalid file descriptor. - return -1 - } - - return int(fd) + return m.fd.Int() } // Clone creates a duplicate of the Map. @@ -877,7 +1144,8 @@ func (m *Map) Clone() (*Map, error) { // the new path already exists. Re-pinning across filesystems is not supported. // You can Clone a map to pin it to a different path. // -// This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs +// This requires bpffs to be mounted above fileName. +// See https://docs.cilium.io/en/stable/network/kubernetes/configuration/#mounting-bpffs-with-systemd func (m *Map) Pin(fileName string) error { if err := internal.Pin(m.pinnedPath, fileName, m.fd); err != nil { return err @@ -912,7 +1180,11 @@ func (m *Map) Freeze() error { return fmt.Errorf("can't freeze map: %w", err) } - if err := bpfMapFreeze(m.fd); err != nil { + attr := sys.MapFreezeAttr{ + MapFd: m.fd.Uint(), + } + + if err := sys.MapFreeze(&attr); err != nil { return fmt.Errorf("can't freeze map: %w", err) } return nil @@ -936,13 +1208,13 @@ func (m *Map) finalize(spec *MapSpec) error { return nil } -func (m *Map) marshalKey(data interface{}) (internal.Pointer, error) { +func (m *Map) marshalKey(data interface{}) (sys.Pointer, error) { if data == nil { if m.keySize == 0 { // Queues have a key length of zero, so passing nil here is valid. - return internal.NewPointer(nil), nil + return sys.NewPointer(nil), nil } - return internal.Pointer{}, errors.New("can't use nil as key of map") + return sys.Pointer{}, errors.New("can't use nil as key of map") } return marshalPtr(data, int(m.keySize)) @@ -957,11 +1229,7 @@ func (m *Map) unmarshalKey(data interface{}, buf []byte) error { return unmarshalBytes(data, buf) } -func (m *Map) marshalValue(data interface{}) (internal.Pointer, error) { - if m.typ.hasPerCPUValue() { - return marshalPerCPUValue(data, int(m.valueSize)) - } - +func (m *Map) marshalValue(data interface{}) (sys.Pointer, error) { var ( buf []byte err error @@ -970,13 +1238,13 @@ func (m *Map) marshalValue(data interface{}) (internal.Pointer, error) { switch value := data.(type) { case *Map: if !m.typ.canStoreMap() { - return internal.Pointer{}, fmt.Errorf("can't store map in %s", m.typ) + return sys.Pointer{}, fmt.Errorf("can't store map in %s", m.typ) } buf, err = marshalMap(value, int(m.valueSize)) case *Program: if !m.typ.canStoreProgram() { - return internal.Pointer{}, fmt.Errorf("can't store program in %s", m.typ) + return sys.Pointer{}, fmt.Errorf("can't store program in %s", m.typ) } buf, err = marshalProgram(value, int(m.valueSize)) @@ -985,10 +1253,10 @@ func (m *Map) marshalValue(data interface{}) (internal.Pointer, error) { } if err != nil { - return internal.Pointer{}, err + return sys.Pointer{}, err } - return internal.NewSlicePointer(buf), nil + return sys.NewSlicePointer(buf), nil } func (m *Map) unmarshalValue(value interface{}, buf []byte) error { @@ -1052,7 +1320,10 @@ func (m *Map) unmarshalValue(value interface{}, buf []byte) error { // LoadPinnedMap loads a Map from a BPF file. func LoadPinnedMap(fileName string, opts *LoadPinOptions) (*Map, error) { - fd, err := internal.BPFObjGet(fileName, opts.Marshal()) + fd, err := sys.ObjGet(&sys.ObjGetAttr{ + Pathname: sys.NewStringPointer(fileName), + FileFlags: opts.Marshal(), + }) if err != nil { return nil, err } @@ -1081,77 +1352,17 @@ func marshalMap(m *Map, length int) ([]byte, error) { return nil, fmt.Errorf("can't marshal map to %d bytes", length) } - fd, err := m.fd.Value() - if err != nil { - return nil, err - } - buf := make([]byte, 4) - internal.NativeEndian.PutUint32(buf, fd) + internal.NativeEndian.PutUint32(buf, m.fd.Uint()) return buf, nil } -func patchValue(value []byte, typ btf.Type, replacements map[string]interface{}) error { - replaced := make(map[string]bool) - replace := func(name string, offset, size int, replacement interface{}) error { - if offset+size > len(value) { - return fmt.Errorf("%s: offset %d(+%d) is out of bounds", name, offset, size) - } - - buf, err := marshalBytes(replacement, size) - if err != nil { - return fmt.Errorf("marshal %s: %w", name, err) - } - - copy(value[offset:offset+size], buf) - replaced[name] = true - return nil - } - - switch parent := typ.(type) { - case *btf.Datasec: - for _, secinfo := range parent.Vars { - name := string(secinfo.Type.(*btf.Var).Name) - replacement, ok := replacements[name] - if !ok { - continue - } - - err := replace(name, int(secinfo.Offset), int(secinfo.Size), replacement) - if err != nil { - return err - } - } - - default: - return fmt.Errorf("patching %T is not supported", typ) - } - - if len(replaced) == len(replacements) { - return nil - } - - var missing []string - for name := range replacements { - if !replaced[name] { - missing = append(missing, name) - } - } - - if len(missing) == 1 { - return fmt.Errorf("unknown field: %s", missing[0]) - } - - return fmt.Errorf("unknown fields: %s", strings.Join(missing, ",")) -} - // MapIterator iterates a Map. // // See Map.Iterate. type MapIterator struct { target *Map - prevKey interface{} - prevBytes []byte + curKey []byte count, maxEntries uint32 done bool err error @@ -1161,7 +1372,6 @@ func newMapIterator(target *Map) *MapIterator { return &MapIterator{ target: target, maxEntries: target.maxEntries, - prevBytes: make([]byte, target.keySize), } } @@ -1183,26 +1393,35 @@ func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool { // For array-like maps NextKeyBytes returns nil only on after maxEntries // iterations. for mi.count <= mi.maxEntries { - var nextBytes []byte - nextBytes, mi.err = mi.target.NextKeyBytes(mi.prevKey) + var nextKey []byte + if mi.curKey == nil { + // Pass nil interface to NextKeyBytes to make sure the Map's first key + // is returned. If we pass an uninitialized []byte instead, it'll see a + // non-nil interface and try to marshal it. + nextKey, mi.err = mi.target.NextKeyBytes(nil) + + mi.curKey = make([]byte, mi.target.keySize) + } else { + nextKey, mi.err = mi.target.NextKeyBytes(mi.curKey) + } if mi.err != nil { + mi.err = fmt.Errorf("get next key: %w", mi.err) return false } - if nextBytes == nil { + if nextKey == nil { mi.done = true return false } - // The user can get access to nextBytes since unmarshalBytes + // The user can get access to nextKey since unmarshalBytes // does not copy when unmarshaling into a []byte. // Make a copy to prevent accidental corruption of // iterator state. - copy(mi.prevBytes, nextBytes) - mi.prevKey = mi.prevBytes + copy(mi.curKey, nextKey) mi.count++ - mi.err = mi.target.Lookup(nextBytes, valueOut) + mi.err = mi.target.Lookup(nextKey, valueOut) if errors.Is(mi.err, ErrKeyNotExist) { // Even though the key should be valid, we couldn't look up // its value. If we're iterating a hash map this is probably @@ -1215,10 +1434,11 @@ func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool { continue } if mi.err != nil { + mi.err = fmt.Errorf("look up next key: %w", mi.err) return false } - mi.err = mi.target.unmarshalKey(keyOut, nextBytes) + mi.err = mi.target.unmarshalKey(keyOut, nextKey) return mi.err == nil } @@ -1239,29 +1459,20 @@ func (mi *MapIterator) Err() error { // // Returns ErrNotExist, if there is no next eBPF map. func MapGetNextID(startID MapID) (MapID, error) { - id, err := objGetNextID(internal.BPF_MAP_GET_NEXT_ID, uint32(startID)) - return MapID(id), err + attr := &sys.MapGetNextIdAttr{Id: uint32(startID)} + return MapID(attr.NextId), sys.MapGetNextId(attr) } // NewMapFromID returns the map for a given id. // // Returns ErrNotExist, if there is no eBPF map with the given id. func NewMapFromID(id MapID) (*Map, error) { - fd, err := internal.BPFObjGetFDByID(internal.BPF_MAP_GET_FD_BY_ID, uint32(id)) + fd, err := sys.MapGetFdById(&sys.MapGetFdByIdAttr{ + Id: uint32(id), + }) if err != nil { return nil, err } return newMapFromFD(fd) } - -// ID returns the systemwide unique ID of the map. -// -// Deprecated: use MapInfo.ID() instead. -func (m *Map) ID() (MapID, error) { - info, err := bpfGetMapInfoByFD(m.fd) - if err != nil { - return MapID(0), err - } - return MapID(info.id), nil -} diff --git a/vendor/github.com/cilium/ebpf/marshalers.go b/vendor/github.com/cilium/ebpf/marshalers.go index e461d673d7..a568bff920 100644 --- a/vendor/github.com/cilium/ebpf/marshalers.go +++ b/vendor/github.com/cilium/ebpf/marshalers.go @@ -12,6 +12,7 @@ import ( "unsafe" "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/sys" ) // marshalPtr converts an arbitrary value into a pointer suitable @@ -19,17 +20,17 @@ import ( // // As an optimization, it returns the original value if it is an // unsafe.Pointer. -func marshalPtr(data interface{}, length int) (internal.Pointer, error) { +func marshalPtr(data interface{}, length int) (sys.Pointer, error) { if ptr, ok := data.(unsafe.Pointer); ok { - return internal.NewPointer(ptr), nil + return sys.NewPointer(ptr), nil } buf, err := marshalBytes(data, length) if err != nil { - return internal.Pointer{}, err + return sys.Pointer{}, err } - return internal.NewSlicePointer(buf), nil + return sys.NewSlicePointer(buf), nil } // marshalBytes converts an arbitrary value into a byte buffer. @@ -56,8 +57,10 @@ func marshalBytes(data interface{}, length int) (buf []byte, err error) { case Map, *Map, Program, *Program: err = fmt.Errorf("can't marshal %T", value) default: - var wr bytes.Buffer - err = binary.Write(&wr, internal.NativeEndian, value) + wr := internal.NewBuffer(make([]byte, 0, length)) + defer internal.PutBuffer(wr) + + err = binary.Write(wr, internal.NativeEndian, value) if err != nil { err = fmt.Errorf("encoding %T: %v", value, err) } @@ -73,13 +76,13 @@ func marshalBytes(data interface{}, length int) (buf []byte, err error) { return buf, nil } -func makeBuffer(dst interface{}, length int) (internal.Pointer, []byte) { +func makeBuffer(dst interface{}, length int) (sys.Pointer, []byte) { if ptr, ok := dst.(unsafe.Pointer); ok { - return internal.NewPointer(ptr), nil + return sys.NewPointer(ptr), nil } buf := make([]byte, length) - return internal.NewSlicePointer(buf), buf + return sys.NewSlicePointer(buf), buf } var bytesReaderPool = sync.Pool{ @@ -98,14 +101,7 @@ var bytesReaderPool = sync.Pool{ func unmarshalBytes(data interface{}, buf []byte) error { switch value := data.(type) { case unsafe.Pointer: - var dst []byte - // Use unsafe.Slice when we drop support for pre1.17 (https://github.com/golang/go/issues/19367) - // We could opt for removing unsafe.Pointer support in the lib as well - sh := (*reflect.SliceHeader)(unsafe.Pointer(&dst)) - sh.Data = uintptr(value) - sh.Len = len(buf) - sh.Cap = len(buf) - + dst := unsafe.Slice((*byte)(value), len(buf)) copy(dst, buf) runtime.KeepAlive(value) return nil @@ -164,21 +160,21 @@ func unmarshalBytes(data interface{}, buf []byte) error { // Values are initialized to zero if the slice has less elements than CPUs. // // slice must have a type like []elementType. -func marshalPerCPUValue(slice interface{}, elemLength int) (internal.Pointer, error) { +func marshalPerCPUValue(slice interface{}, elemLength int) (sys.Pointer, error) { sliceType := reflect.TypeOf(slice) if sliceType.Kind() != reflect.Slice { - return internal.Pointer{}, errors.New("per-CPU value requires slice") + return sys.Pointer{}, errors.New("per-CPU value requires slice") } possibleCPUs, err := internal.PossibleCPUs() if err != nil { - return internal.Pointer{}, err + return sys.Pointer{}, err } sliceValue := reflect.ValueOf(slice) sliceLen := sliceValue.Len() if sliceLen > possibleCPUs { - return internal.Pointer{}, fmt.Errorf("per-CPU value exceeds number of CPUs") + return sys.Pointer{}, fmt.Errorf("per-CPU value exceeds number of CPUs") } alignedElemLength := internal.Align(elemLength, 8) @@ -188,14 +184,14 @@ func marshalPerCPUValue(slice interface{}, elemLength int) (internal.Pointer, er elem := sliceValue.Index(i).Interface() elemBytes, err := marshalBytes(elem, elemLength) if err != nil { - return internal.Pointer{}, err + return sys.Pointer{}, err } offset := i * alignedElemLength copy(buf[offset:offset+elemLength], elemBytes) } - return internal.NewSlicePointer(buf), nil + return sys.NewSlicePointer(buf), nil } // unmarshalPerCPUValue decodes a buffer into a slice containing one value per diff --git a/vendor/github.com/cilium/ebpf/prog.go b/vendor/github.com/cilium/ebpf/prog.go index 3549a3fe3f..70aaef5532 100644 --- a/vendor/github.com/cilium/ebpf/prog.go +++ b/vendor/github.com/cilium/ebpf/prog.go @@ -5,23 +5,23 @@ import ( "encoding/binary" "errors" "fmt" - "io" "math" "path/filepath" + "runtime" "strings" "time" + "unsafe" "github.com/cilium/ebpf/asm" + "github.com/cilium/ebpf/btf" "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/btf" + "github.com/cilium/ebpf/internal/sys" "github.com/cilium/ebpf/internal/unix" ) // ErrNotSupported is returned whenever the kernel doesn't support a feature. var ErrNotSupported = internal.ErrNotSupported -var errUnsatisfiedReference = errors.New("unsatisfied reference") - // ProgramID represents the unique ID of an eBPF program. type ProgramID uint32 @@ -36,20 +36,49 @@ const ( // verifier log. const DefaultVerifierLogSize = 64 * 1024 +// maxVerifierLogSize is the maximum size of verifier log buffer the kernel +// will accept before returning EINVAL. +const maxVerifierLogSize = math.MaxUint32 >> 2 + // ProgramOptions control loading a program into the kernel. type ProgramOptions struct { - // Controls the detail emitted by the kernel verifier. Set to non-zero - // to enable logging. - LogLevel uint32 - // Controls the output buffer size for the verifier. Defaults to - // DefaultVerifierLogSize. + // Bitmap controlling the detail emitted by the kernel's eBPF verifier log. + // LogLevel-type values can be ORed together to request specific kinds of + // verifier output. See the documentation on [ebpf.LogLevel] for details. + // + // opts.LogLevel = (ebpf.LogLevelBranch | ebpf.LogLevelStats) + // + // If left to its default value, the program will first be loaded without + // verifier output enabled. Upon error, the program load will be repeated + // with LogLevelBranch and the given (or default) LogSize value. + // + // Setting this to a non-zero value will unconditionally enable the verifier + // log, populating the [ebpf.Program.VerifierLog] field on successful loads + // and including detailed verifier errors if the program is rejected. This + // will always allocate an output buffer, but will result in only a single + // attempt at loading the program. + LogLevel LogLevel + + // Controls the output buffer size for the verifier log, in bytes. See the + // documentation on ProgramOptions.LogLevel for details about how this value + // is used. + // + // If this value is set too low to fit the verifier log, the resulting + // [ebpf.VerifierError]'s Truncated flag will be true, and the error string + // will also contain a hint to that effect. + // + // Defaults to DefaultVerifierLogSize. LogSize int - // An ELF containing the target BTF for this program. It is used both to - // find the correct function to trace and to apply CO-RE relocations. + + // Disables the verifier log completely, regardless of other options. + LogDisabled bool + + // Type information used for CO-RE relocations. + // // This is useful in environments where the kernel BTF is not available // (containers) or where it is in a non-standard location. Defaults to - // use the kernel BTF from a well-known location. - TargetBTF io.ReaderAt + // use the kernel BTF from a well-known location if nil. + KernelTypes *btf.Spec } // ProgramSpec defines a Program. @@ -59,13 +88,24 @@ type ProgramSpec struct { Name string // Type determines at which hook in the kernel a program will run. - Type ProgramType + Type ProgramType + + // AttachType of the program, needed to differentiate allowed context + // accesses in some newer program types like CGroupSockAddr. + // + // Available on kernels 4.17 and later. AttachType AttachType + // Name of a kernel data structure or function to attach to. Its // interpretation depends on Type and AttachType. AttachTo string + // The program to attach to. Must be provided manually. AttachTarget *Program + + // The name of the ELF section this program originated from. + SectionName string + Instructions asm.Instructions // Flags is passed to the kernel and specifies additional program @@ -84,11 +124,6 @@ type ProgramSpec struct { // detect this value automatically. KernelVersion uint32 - // The BTF associated with this program. Changing Instructions - // will most likely invalidate the contained data, and may - // result in errors when attempting to load it into the kernel. - BTF *btf.Program - // The byte order this program was compiled for, may be nil. ByteOrder binary.ByteOrder } @@ -112,6 +147,12 @@ func (ps *ProgramSpec) Tag() (string, error) { return ps.Instructions.Tag(internal.NativeEndian) } +// VerifierError is returned by [NewProgram] and [NewProgramWithOptions] if a +// program is rejected by the verifier. +// +// Use [errors.As] to access the error. +type VerifierError = internal.VerifierError + // Program represents BPF program loaded into the kernel. // // It is not safe to close a Program which is used by other goroutines. @@ -120,7 +161,7 @@ type Program struct { // otherwise it is empty. VerifierLog string - fd *internal.FD + fd *sys.FD name string pinnedPath string typ ProgramType @@ -128,8 +169,10 @@ type Program struct { // NewProgram creates a new Program. // -// Loading a program for the first time will perform -// feature detection by loading small, temporary programs. +// See [NewProgramWithOptions] for details. +// +// Returns a [VerifierError] containing the full verifier log if the program is +// rejected by the kernel. func NewProgram(spec *ProgramSpec) (*Program, error) { return NewProgramWithOptions(spec, ProgramOptions{}) } @@ -138,26 +181,38 @@ func NewProgram(spec *ProgramSpec) (*Program, error) { // // Loading a program for the first time will perform // feature detection by loading small, temporary programs. +// +// Returns a [VerifierError] containing the full verifier log if the program is +// rejected by the kernel. func NewProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, error) { - handles := newHandleCache() - defer handles.close() + if spec == nil { + return nil, errors.New("can't load a program from a nil spec") + } - prog, err := newProgramWithOptions(spec, opts, handles) - if errors.Is(err, errUnsatisfiedReference) { + prog, err := newProgramWithOptions(spec, opts) + if errors.Is(err, asm.ErrUnsatisfiedMapReference) { return nil, fmt.Errorf("cannot load program without loading its whole collection: %w", err) } return prog, err } -func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, handles *handleCache) (*Program, error) { +func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, error) { if len(spec.Instructions) == 0 { return nil, errors.New("instructions cannot be empty") } + if spec.Type == UnspecifiedProgram { + return nil, errors.New("can't load program of unspecified type") + } + if spec.ByteOrder != nil && spec.ByteOrder != internal.NativeEndian { return nil, fmt.Errorf("can't load %s program on %s", spec.ByteOrder, internal.NativeEndian) } + if opts.LogSize < 0 { + return nil, errors.New("ProgramOptions.LogSize must be a positive value; disable verifier logs using ProgramOptions.LogDisabled") + } + // Kernels before 5.0 (6c4fc209fcf9 "bpf: remove useless version check for prog load") // require the version field to be set to the value of the KERNEL_VERSION // macro for kprobe-type programs. @@ -171,159 +226,155 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, handles *hand kv = v.Kernel() } - attr := &internal.BPFProgLoadAttr{ - ProgType: uint32(spec.Type), + attr := &sys.ProgLoadAttr{ + ProgType: sys.ProgType(spec.Type), ProgFlags: spec.Flags, - ExpectedAttachType: uint32(spec.AttachType), - License: internal.NewStringPointer(spec.License), - KernelVersion: kv, + ExpectedAttachType: sys.AttachType(spec.AttachType), + License: sys.NewStringPointer(spec.License), + KernVersion: kv, } if haveObjName() == nil { - attr.ProgName = internal.NewBPFObjName(spec.Name) + attr.ProgName = sys.NewObjName(spec.Name) } - var err error - var targetBTF *btf.Spec - if opts.TargetBTF != nil { - targetBTF, err = handles.btfSpec(opts.TargetBTF) - if err != nil { - return nil, fmt.Errorf("load target BTF: %w", err) - } - } + insns := make(asm.Instructions, len(spec.Instructions)) + copy(insns, spec.Instructions) - var btfDisabled bool - var core btf.COREFixups - if spec.BTF != nil { - core, err = spec.BTF.Fixups(targetBTF) - if err != nil { - return nil, fmt.Errorf("CO-RE relocations: %w", err) - } + handle, fib, lib, err := btf.MarshalExtInfos(insns) + if err != nil && !errors.Is(err, btf.ErrNotSupported) { + return nil, fmt.Errorf("load ext_infos: %w", err) + } + if handle != nil { + defer handle.Close() - handle, err := handles.btfHandle(spec.BTF.Spec()) - btfDisabled = errors.Is(err, btf.ErrNotSupported) - if err != nil && !btfDisabled { - return nil, fmt.Errorf("load BTF: %w", err) - } + attr.ProgBtfFd = uint32(handle.FD()) - if handle != nil { - attr.ProgBTFFd = uint32(handle.FD()) + attr.FuncInfoRecSize = btf.FuncInfoSize + attr.FuncInfoCnt = uint32(len(fib)) / btf.FuncInfoSize + attr.FuncInfo = sys.NewSlicePointer(fib) - recSize, bytes, err := spec.BTF.LineInfos() - if err != nil { - return nil, fmt.Errorf("get BTF line infos: %w", err) - } - attr.LineInfoRecSize = recSize - attr.LineInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize)) - attr.LineInfo = internal.NewSlicePointer(bytes) + attr.LineInfoRecSize = btf.LineInfoSize + attr.LineInfoCnt = uint32(len(lib)) / btf.LineInfoSize + attr.LineInfo = sys.NewSlicePointer(lib) + } - recSize, bytes, err = spec.BTF.FuncInfos() - if err != nil { - return nil, fmt.Errorf("get BTF function infos: %w", err) - } - attr.FuncInfoRecSize = recSize - attr.FuncInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize)) - attr.FuncInfo = internal.NewSlicePointer(bytes) - } + if err := applyRelocations(insns, opts.KernelTypes, spec.ByteOrder); err != nil { + return nil, fmt.Errorf("apply CO-RE relocations: %w", err) } - insns, err := core.Apply(spec.Instructions) + kconfig, err := resolveKconfigReferences(insns) if err != nil { - return nil, fmt.Errorf("CO-RE fixup: %w", err) + return nil, fmt.Errorf("resolve .kconfig: %w", err) } + defer kconfig.Close() - if err := fixupJumpsAndCalls(insns); err != nil { + if err := fixupAndValidate(insns); err != nil { return nil, err } - buf := bytes.NewBuffer(make([]byte, 0, len(spec.Instructions)*asm.InstructionSize)) + handles, err := fixupKfuncs(insns) + if err != nil { + return nil, fmt.Errorf("fixing up kfuncs: %w", err) + } + defer handles.close() + + if len(handles) > 0 { + fdArray := handles.fdArray() + attr.FdArray = sys.NewPointer(unsafe.Pointer(&fdArray[0])) + } + + buf := bytes.NewBuffer(make([]byte, 0, insns.Size())) err = insns.Marshal(buf, internal.NativeEndian) if err != nil { return nil, err } bytecode := buf.Bytes() - attr.Instructions = internal.NewSlicePointer(bytecode) - attr.InsCount = uint32(len(bytecode) / asm.InstructionSize) - - if spec.AttachTo != "" { - if spec.AttachTarget != nil { - info, err := spec.AttachTarget.Info() - if err != nil { - return nil, fmt.Errorf("load target BTF: %w", err) - } - - btfID, ok := info.BTFID() - if !ok { - return nil, fmt.Errorf("load target BTF: no BTF info available") - } - btfHandle, err := btf.NewHandleFromID(btfID) - if err != nil { - return nil, fmt.Errorf("load target BTF: %w", err) - } - defer btfHandle.Close() + attr.Insns = sys.NewSlicePointer(bytecode) + attr.InsnCnt = uint32(len(bytecode) / asm.InstructionSize) - targetBTF = btfHandle.Spec() - if err != nil { - return nil, fmt.Errorf("load target BTF: %w", err) - } - } - - target, err := resolveBTFType(targetBTF, spec.AttachTo, spec.Type, spec.AttachType) + if spec.AttachTarget != nil { + targetID, err := findTargetInProgram(spec.AttachTarget, spec.AttachTo, spec.Type, spec.AttachType) if err != nil { - return nil, err + return nil, fmt.Errorf("attach %s/%s: %w", spec.Type, spec.AttachType, err) } - if target != nil { - attr.AttachBTFID = uint32(target.ID()) + + attr.AttachBtfId = targetID + attr.AttachBtfObjFd = uint32(spec.AttachTarget.FD()) + defer runtime.KeepAlive(spec.AttachTarget) + } else if spec.AttachTo != "" { + module, targetID, err := findProgramTargetInKernel(spec.AttachTo, spec.Type, spec.AttachType) + if err != nil && !errors.Is(err, errUnrecognizedAttachType) { + // We ignore errUnrecognizedAttachType since AttachTo may be non-empty + // for programs that don't attach anywhere. + return nil, fmt.Errorf("attach %s/%s: %w", spec.Type, spec.AttachType, err) } - if spec.AttachTarget != nil { - attr.AttachProgFd = uint32(spec.AttachTarget.FD()) + + attr.AttachBtfId = targetID + if module != nil { + attr.AttachBtfObjFd = uint32(module.FD()) + defer module.Close() } } - logSize := DefaultVerifierLogSize - if opts.LogSize > 0 { - logSize = opts.LogSize + if opts.LogSize == 0 { + opts.LogSize = DefaultVerifierLogSize } + // The caller requested a specific verifier log level. Set up the log buffer. var logBuf []byte - if opts.LogLevel > 0 { - logBuf = make([]byte, logSize) + if !opts.LogDisabled && opts.LogLevel != 0 { + logBuf = make([]byte, opts.LogSize) attr.LogLevel = opts.LogLevel attr.LogSize = uint32(len(logBuf)) - attr.LogBuf = internal.NewSlicePointer(logBuf) + attr.LogBuf = sys.NewSlicePointer(logBuf) } - fd, err := internal.BPFProgLoad(attr) + fd, err := sys.ProgLoad(attr) if err == nil { - return &Program{internal.CString(logBuf), fd, spec.Name, "", spec.Type}, nil + return &Program{unix.ByteSliceToString(logBuf), fd, spec.Name, "", spec.Type}, nil } - logErr := err - if opts.LogLevel == 0 && opts.LogSize >= 0 { - // Re-run with the verifier enabled to get better error messages. - logBuf = make([]byte, logSize) - attr.LogLevel = 1 + // An error occurred loading the program, but the caller did not explicitly + // enable the verifier log. Re-run with branch-level verifier logs enabled to + // obtain more info. Preserve the original error to return it to the caller. + // An undersized log buffer will result in ENOSPC regardless of the underlying + // cause. + var err2 error + if !opts.LogDisabled && opts.LogLevel == 0 { + logBuf = make([]byte, opts.LogSize) + attr.LogLevel = LogLevelBranch attr.LogSize = uint32(len(logBuf)) - attr.LogBuf = internal.NewSlicePointer(logBuf) + attr.LogBuf = sys.NewSlicePointer(logBuf) - fd, logErr = internal.BPFProgLoad(attr) - if logErr == nil { - fd.Close() - } + _, err2 = sys.ProgLoad(attr) } - if errors.Is(logErr, unix.EPERM) && logBuf[0] == 0 { - // EPERM due to RLIMIT_MEMLOCK happens before the verifier, so we can - // check that the log is empty to reduce false positives. - return nil, fmt.Errorf("load program: %w (MEMLOCK bay be too low, consider rlimit.RemoveMemlock)", logErr) - } + switch { + case errors.Is(err, unix.EPERM): + if len(logBuf) > 0 && logBuf[0] == 0 { + // EPERM due to RLIMIT_MEMLOCK happens before the verifier, so we can + // check that the log is empty to reduce false positives. + return nil, fmt.Errorf("load program: %w (MEMLOCK may be too low, consider rlimit.RemoveMemlock)", err) + } + + fallthrough + + case errors.Is(err, unix.EINVAL): + if hasFunctionReferences(spec.Instructions) { + if err := haveBPFToBPFCalls(); err != nil { + return nil, fmt.Errorf("load program: %w", err) + } + } - err = internal.ErrorWithLog(err, logBuf, logErr) - if btfDisabled { - return nil, fmt.Errorf("load program without BTF: %w", err) + if opts.LogSize > maxVerifierLogSize { + return nil, fmt.Errorf("load program: %w (ProgramOptions.LogSize exceeds maximum value of %d)", err, maxVerifierLogSize) + } } - return nil, fmt.Errorf("load program: %w", err) + + truncated := errors.Is(err, unix.ENOSPC) || errors.Is(err2, unix.ENOSPC) + return nil, internal.ErrorWithLog("load program", err, logBuf, truncated) } // NewProgramFromFD creates a program from a raw fd. @@ -332,18 +383,21 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, handles *hand // // Requires at least Linux 4.10. func NewProgramFromFD(fd int) (*Program, error) { - if fd < 0 { - return nil, errors.New("invalid fd") + f, err := sys.NewFD(fd) + if err != nil { + return nil, err } - return newProgramFromFD(internal.NewFD(uint32(fd))) + return newProgramFromFD(f) } // NewProgramFromID returns the program for a given id. // // Returns ErrNotExist, if there is no eBPF program with the given id. func NewProgramFromID(id ProgramID) (*Program, error) { - fd, err := internal.BPFObjGetFDByID(internal.BPF_PROG_GET_FD_BY_ID, uint32(id)) + fd, err := sys.ProgGetFdById(&sys.ProgGetFdByIdAttr{ + Id: uint32(id), + }) if err != nil { return nil, fmt.Errorf("get program by id: %w", err) } @@ -351,14 +405,14 @@ func NewProgramFromID(id ProgramID) (*Program, error) { return newProgramFromFD(fd) } -func newProgramFromFD(fd *internal.FD) (*Program, error) { +func newProgramFromFD(fd *sys.FD) (*Program, error) { info, err := newProgramInfoFromFd(fd) if err != nil { fd.Close() return nil, fmt.Errorf("discover program type: %w", err) } - return &Program{"", fd, "", "", info.Type}, nil + return &Program{"", fd, info.Name, "", info.Type}, nil } func (p *Program) String() string { @@ -380,18 +434,29 @@ func (p *Program) Info() (*ProgramInfo, error) { return newProgramInfoFromFd(p.fd) } -// FD gets the file descriptor of the Program. +// Handle returns a reference to the program's type information in the kernel. // -// It is invalid to call this function after Close has been called. -func (p *Program) FD() int { - fd, err := p.fd.Value() +// Returns ErrNotSupported if the kernel has no BTF support, or if there is no +// BTF associated with the program. +func (p *Program) Handle() (*btf.Handle, error) { + info, err := p.Info() if err != nil { - // Best effort: -1 is the number most likely to be an - // invalid file descriptor. - return -1 + return nil, err } - return int(fd) + id, ok := info.BTFID() + if !ok { + return nil, fmt.Errorf("program %s: retrieve BTF ID: %w", p, ErrNotSupported) + } + + return btf.NewHandleFromID(id) +} + +// FD gets the file descriptor of the Program. +// +// It is invalid to call this function after Close has been called. +func (p *Program) FD() int { + return p.fd.Int() } // Clone creates a duplicate of the Program. @@ -418,7 +483,8 @@ func (p *Program) Clone() (*Program, error) { // Calling Pin on a previously pinned program will overwrite the path, except when // the new path already exists. Re-pinning across filesystems is not supported. // -// This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs +// This requires bpffs to be mounted above fileName. +// See https://docs.cilium.io/en/stable/network/kubernetes/configuration/#mounting-bpffs-with-systemd func (p *Program) Pin(fileName string) error { if err := internal.Pin(p.pinnedPath, fileName, p.fd); err != nil { return err @@ -445,7 +511,9 @@ func (p *Program) IsPinned() bool { return p.pinnedPath != "" } -// Close unloads the program from the kernel. +// Close the Program's underlying file descriptor, which could unload +// the program from the kernel if it is not pinned or attached to a +// kernel hook. func (p *Program) Close() error { if p == nil { return nil @@ -454,6 +522,36 @@ func (p *Program) Close() error { return p.fd.Close() } +// Various options for Run'ing a Program +type RunOptions struct { + // Program's data input. Required field. + // + // The kernel expects at least 14 bytes input for an ethernet header for + // XDP and SKB programs. + Data []byte + // Program's data after Program has run. Caller must allocate. Optional field. + DataOut []byte + // Program's context input. Optional field. + Context interface{} + // Program's context after Program has run. Must be a pointer or slice. Optional field. + ContextOut interface{} + // Minimum number of times to run Program. Optional field. Defaults to 1. + // + // The program may be executed more often than this due to interruptions, e.g. + // when runtime.AllThreadsSyscall is invoked. + Repeat uint32 + // Optional flags. + Flags uint32 + // CPU to run Program on. Optional field. + // Note not all program types support this field. + CPU uint32 + // Called whenever the syscall is interrupted, and should be set to testing.B.ResetTimer + // or similar. Typically used during benchmarking. Optional field. + // + // Deprecated: use [testing.B.ReportMetric] with unit "ns/op" instead. + Reset func() +} + // Test runs the Program in the kernel with the given input and returns the // value returned by the eBPF program. outLen may be zero. // @@ -462,11 +560,38 @@ func (p *Program) Close() error { // // This function requires at least Linux 4.12. func (p *Program) Test(in []byte) (uint32, []byte, error) { - ret, out, _, err := p.testRun(in, 1, nil) + // Older kernels ignore the dataSizeOut argument when copying to user space. + // Combined with things like bpf_xdp_adjust_head() we don't really know what the final + // size will be. Hence we allocate an output buffer which we hope will always be large + // enough, and panic if the kernel wrote past the end of the allocation. + // See https://patchwork.ozlabs.org/cover/1006822/ + var out []byte + if len(in) > 0 { + out = make([]byte, len(in)+outputPad) + } + + opts := RunOptions{ + Data: in, + DataOut: out, + Repeat: 1, + } + + ret, _, err := p.run(&opts) if err != nil { - return ret, nil, fmt.Errorf("can't test program: %w", err) + return ret, nil, fmt.Errorf("test program: %w", err) } - return ret, out, nil + return ret, opts.DataOut, nil +} + +// Run runs the Program in kernel with given RunOptions. +// +// Note: the same restrictions from Test apply. +func (p *Program) Run(opts *RunOptions) (uint32, error) { + ret, _, err := p.run(opts) + if err != nil { + return ret, fmt.Errorf("run program: %w", err) + } + return ret, nil } // Benchmark runs the Program with the given input for a number of times @@ -476,20 +601,28 @@ func (p *Program) Test(in []byte) (uint32, []byte, error) { // run or an error. reset is called whenever the benchmark syscall is // interrupted, and should be set to testing.B.ResetTimer or similar. // -// Note: profiling a call to this function will skew it's results, see -// https://github.com/cilium/ebpf/issues/24 -// // This function requires at least Linux 4.12. func (p *Program) Benchmark(in []byte, repeat int, reset func()) (uint32, time.Duration, error) { - ret, _, total, err := p.testRun(in, repeat, reset) + if uint(repeat) > math.MaxUint32 { + return 0, 0, fmt.Errorf("repeat is too high") + } + + opts := RunOptions{ + Data: in, + Repeat: uint32(repeat), + Reset: reset, + } + + ret, total, err := p.run(&opts) if err != nil { - return ret, total, fmt.Errorf("can't benchmark program: %w", err) + return ret, total, fmt.Errorf("benchmark program: %w", err) } return ret, total, nil } -var haveProgTestRun = internal.FeatureTest("BPF_PROG_TEST_RUN", "4.12", func() error { +var haveProgRun = internal.NewFeatureTest("BPF_PROG_RUN", "4.12", func() error { prog, err := NewProgram(&ProgramSpec{ + // SocketFilter does not require privileges on newer kernels. Type: SocketFilter, Instructions: asm.Instructions{ asm.LoadImm(asm.R0, 0, asm.DWord), @@ -503,90 +636,131 @@ var haveProgTestRun = internal.FeatureTest("BPF_PROG_TEST_RUN", "4.12", func() e } defer prog.Close() - // Programs require at least 14 bytes input - in := make([]byte, 14) - attr := bpfProgTestRunAttr{ - fd: uint32(prog.FD()), - dataSizeIn: uint32(len(in)), - dataIn: internal.NewSlicePointer(in), + in := internal.EmptyBPFContext + attr := sys.ProgRunAttr{ + ProgFd: uint32(prog.FD()), + DataSizeIn: uint32(len(in)), + DataIn: sys.NewSlicePointer(in), } - err = bpfProgTestRun(&attr) - if errors.Is(err, unix.EINVAL) { + err = sys.ProgRun(&attr) + switch { + case errors.Is(err, unix.EINVAL): // Check for EINVAL specifically, rather than err != nil since we // otherwise misdetect due to insufficient permissions. return internal.ErrNotSupported - } - if errors.Is(err, unix.EINTR) { + + case errors.Is(err, unix.EINTR): // We know that PROG_TEST_RUN is supported if we get EINTR. return nil + + case errors.Is(err, sys.ENOTSUPP): + // The first PROG_TEST_RUN patches shipped in 4.12 didn't include + // a test runner for SocketFilter. ENOTSUPP means PROG_TEST_RUN is + // supported, but not for the program type used in the probe. + return nil } + return err }) -func (p *Program) testRun(in []byte, repeat int, reset func()) (uint32, []byte, time.Duration, error) { - if uint(repeat) > math.MaxUint32 { - return 0, nil, 0, fmt.Errorf("repeat is too high") +func (p *Program) run(opts *RunOptions) (uint32, time.Duration, error) { + if uint(len(opts.Data)) > math.MaxUint32 { + return 0, 0, fmt.Errorf("input is too long") } - if len(in) == 0 { - return 0, nil, 0, fmt.Errorf("missing input") + if err := haveProgRun(); err != nil { + return 0, 0, err } - if uint(len(in)) > math.MaxUint32 { - return 0, nil, 0, fmt.Errorf("input is too long") + var ctxBytes []byte + if opts.Context != nil { + ctx := new(bytes.Buffer) + if err := binary.Write(ctx, internal.NativeEndian, opts.Context); err != nil { + return 0, 0, fmt.Errorf("cannot serialize context: %v", err) + } + ctxBytes = ctx.Bytes() } - if err := haveProgTestRun(); err != nil { - return 0, nil, 0, err + var ctxOut []byte + if opts.ContextOut != nil { + ctxOut = make([]byte, binary.Size(opts.ContextOut)) } - // Older kernels ignore the dataSizeOut argument when copying to user space. - // Combined with things like bpf_xdp_adjust_head() we don't really know what the final - // size will be. Hence we allocate an output buffer which we hope will always be large - // enough, and panic if the kernel wrote past the end of the allocation. - // See https://patchwork.ozlabs.org/cover/1006822/ - out := make([]byte, len(in)+outputPad) - - fd, err := p.fd.Value() - if err != nil { - return 0, nil, 0, err + attr := sys.ProgRunAttr{ + ProgFd: p.fd.Uint(), + DataSizeIn: uint32(len(opts.Data)), + DataSizeOut: uint32(len(opts.DataOut)), + DataIn: sys.NewSlicePointer(opts.Data), + DataOut: sys.NewSlicePointer(opts.DataOut), + Repeat: uint32(opts.Repeat), + CtxSizeIn: uint32(len(ctxBytes)), + CtxSizeOut: uint32(len(ctxOut)), + CtxIn: sys.NewSlicePointer(ctxBytes), + CtxOut: sys.NewSlicePointer(ctxOut), + Flags: opts.Flags, + Cpu: opts.CPU, } - attr := bpfProgTestRunAttr{ - fd: fd, - dataSizeIn: uint32(len(in)), - dataSizeOut: uint32(len(out)), - dataIn: internal.NewSlicePointer(in), - dataOut: internal.NewSlicePointer(out), - repeat: uint32(repeat), + if attr.Repeat == 0 { + attr.Repeat = 1 } +retry: for { - err = bpfProgTestRun(&attr) + err := sys.ProgRun(&attr) if err == nil { - break + break retry } if errors.Is(err, unix.EINTR) { - if reset != nil { - reset() + if attr.Repeat == 1 { + // Older kernels check whether enough repetitions have been + // executed only after checking for pending signals. + // + // run signal? done? run ... + // + // As a result we can get EINTR for repeat==1 even though + // the program was run exactly once. Treat this as a + // successful run instead. + // + // Since commit 607b9cc92bd7 ("bpf: Consolidate shared test timing code") + // the conditions are reversed: + // run done? signal? ... + break retry } - continue + + if opts.Reset != nil { + opts.Reset() + } + continue retry } - return 0, nil, 0, fmt.Errorf("can't run test: %w", err) + if errors.Is(err, sys.ENOTSUPP) { + return 0, 0, fmt.Errorf("kernel doesn't support running %s: %w", p.Type(), ErrNotSupported) + } + + return 0, 0, err } - if int(attr.dataSizeOut) > cap(out) { - // Houston, we have a problem. The program created more data than we allocated, - // and the kernel wrote past the end of our buffer. - panic("kernel wrote past end of output buffer") + if opts.DataOut != nil { + if int(attr.DataSizeOut) > cap(opts.DataOut) { + // Houston, we have a problem. The program created more data than we allocated, + // and the kernel wrote past the end of our buffer. + panic("kernel wrote past end of output buffer") + } + opts.DataOut = opts.DataOut[:int(attr.DataSizeOut)] } - out = out[:int(attr.dataSizeOut)] - total := time.Duration(attr.duration) * time.Nanosecond - return attr.retval, out, total, nil + if len(ctxOut) != 0 { + b := bytes.NewReader(ctxOut) + if err := binary.Read(b, internal.NativeEndian, opts.ContextOut); err != nil { + return 0, 0, fmt.Errorf("failed to decode ContextOut: %v", err) + } + } + + total := time.Duration(attr.Duration) * time.Nanosecond + return attr.Retval, total, nil } func unmarshalProgram(buf []byte) (*Program, error) { @@ -605,70 +779,19 @@ func marshalProgram(p *Program, length int) ([]byte, error) { return nil, fmt.Errorf("can't marshal program to %d bytes", length) } - value, err := p.fd.Value() - if err != nil { - return nil, err - } - buf := make([]byte, 4) - internal.NativeEndian.PutUint32(buf, value) + internal.NativeEndian.PutUint32(buf, p.fd.Uint()) return buf, nil } -// Attach a Program. -// -// Deprecated: use link.RawAttachProgram instead. -func (p *Program) Attach(fd int, typ AttachType, flags AttachFlags) error { - if fd < 0 { - return errors.New("invalid fd") - } - - pfd, err := p.fd.Value() - if err != nil { - return err - } - - attr := internal.BPFProgAttachAttr{ - TargetFd: uint32(fd), - AttachBpfFd: pfd, - AttachType: uint32(typ), - AttachFlags: uint32(flags), - } - - return internal.BPFProgAttach(&attr) -} - -// Detach a Program. -// -// Deprecated: use link.RawDetachProgram instead. -func (p *Program) Detach(fd int, typ AttachType, flags AttachFlags) error { - if fd < 0 { - return errors.New("invalid fd") - } - - if flags != 0 { - return errors.New("flags must be zero") - } - - pfd, err := p.fd.Value() - if err != nil { - return err - } - - attr := internal.BPFProgDetachAttr{ - TargetFd: uint32(fd), - AttachBpfFd: pfd, - AttachType: uint32(typ), - } - - return internal.BPFProgDetach(&attr) -} - // LoadPinnedProgram loads a Program from a BPF file. // // Requires at least Linux 4.11. func LoadPinnedProgram(fileName string, opts *LoadPinOptions) (*Program, error) { - fd, err := internal.BPFObjGet(fileName, opts.Marshal()) + fd, err := sys.ObjGet(&sys.ObjGetAttr{ + Pathname: sys.NewStringPointer(fileName), + FileFlags: opts.Marshal(), + }) if err != nil { return nil, err } @@ -679,7 +802,14 @@ func LoadPinnedProgram(fileName string, opts *LoadPinOptions) (*Program, error) return nil, fmt.Errorf("info for %s: %w", fileName, err) } - return &Program{"", fd, filepath.Base(fileName), fileName, info.Type}, nil + var progName string + if haveObjName() == nil { + progName = info.Name + } else { + progName = filepath.Base(fileName) + } + + return &Program{"", fd, progName, fileName, info.Type}, nil } // SanitizeName replaces all invalid characters in name with replacement. @@ -702,60 +832,195 @@ func SanitizeName(name string, replacement rune) string { // // Returns ErrNotExist, if there is no next eBPF program. func ProgramGetNextID(startID ProgramID) (ProgramID, error) { - id, err := objGetNextID(internal.BPF_PROG_GET_NEXT_ID, uint32(startID)) - return ProgramID(id), err + attr := &sys.ProgGetNextIdAttr{Id: uint32(startID)} + return ProgramID(attr.NextId), sys.ProgGetNextId(attr) } -// ID returns the systemwide unique ID of the program. +// BindMap binds map to the program and is only released once program is released. // -// Deprecated: use ProgramInfo.ID() instead. -func (p *Program) ID() (ProgramID, error) { - info, err := bpfGetProgInfoByFD(p.fd, nil) - if err != nil { - return ProgramID(0), err +// This may be used in cases where metadata should be associated with the program +// which otherwise does not contain any references to the map. +func (p *Program) BindMap(m *Map) error { + attr := &sys.ProgBindMapAttr{ + ProgFd: uint32(p.FD()), + MapFd: uint32(m.FD()), } - return ProgramID(info.id), nil + + return sys.ProgBindMap(attr) } -func resolveBTFType(spec *btf.Spec, name string, progType ProgramType, attachType AttachType) (btf.Type, error) { +var errUnrecognizedAttachType = errors.New("unrecognized attach type") + +// find an attach target type in the kernel. +// +// name, progType and attachType determine which type we need to attach to. +// +// The attach target may be in a loaded kernel module. +// In that case the returned handle will be non-nil. +// The caller is responsible for closing the handle. +// +// Returns errUnrecognizedAttachType if the combination of progType and attachType +// is not recognised. +func findProgramTargetInKernel(name string, progType ProgramType, attachType AttachType) (*btf.Handle, btf.TypeID, error) { type match struct { p ProgramType a AttachType } - var typeName, featureName string + var ( + typeName, featureName string + target btf.Type + ) + switch (match{progType, attachType}) { case match{LSM, AttachLSMMac}: typeName = "bpf_lsm_" + name featureName = name + " LSM hook" + target = (*btf.Func)(nil) case match{Tracing, AttachTraceIter}: typeName = "bpf_iter_" + name featureName = name + " iterator" - case match{Extension, AttachNone}: + target = (*btf.Func)(nil) + case match{Tracing, AttachTraceFEntry}: typeName = name - featureName = fmt.Sprintf("freplace %s", name) + featureName = fmt.Sprintf("fentry %s", name) + target = (*btf.Func)(nil) + case match{Tracing, AttachTraceFExit}: + typeName = name + featureName = fmt.Sprintf("fexit %s", name) + target = (*btf.Func)(nil) + case match{Tracing, AttachModifyReturn}: + typeName = name + featureName = fmt.Sprintf("fmod_ret %s", name) + target = (*btf.Func)(nil) + case match{Tracing, AttachTraceRawTp}: + typeName = fmt.Sprintf("btf_trace_%s", name) + featureName = fmt.Sprintf("raw_tp %s", name) + target = (*btf.Typedef)(nil) default: - return nil, nil + return nil, 0, errUnrecognizedAttachType } - if spec == nil { - var err error - spec, err = btf.LoadKernelSpec() + spec, err := btf.LoadKernelSpec() + if err != nil { + return nil, 0, fmt.Errorf("load kernel spec: %w", err) + } + + spec, module, err := findTargetInKernel(spec, typeName, &target) + if errors.Is(err, btf.ErrNotFound) { + return nil, 0, &internal.UnsupportedFeatureError{Name: featureName} + } + // See cilium/ebpf#894. Until we can disambiguate between equally-named kernel + // symbols, we should explicitly refuse program loads. They will not reliably + // do what the caller intended. + if errors.Is(err, btf.ErrMultipleMatches) { + return nil, 0, fmt.Errorf("attaching to ambiguous kernel symbol is not supported: %w", err) + } + if err != nil { + return nil, 0, fmt.Errorf("find target for %s: %w", featureName, err) + } + + id, err := spec.TypeID(target) + return module, id, err +} + +// findTargetInKernel attempts to find a named type in the current kernel. +// +// target will point at the found type after a successful call. Searches both +// vmlinux and any loaded modules. +// +// Returns a non-nil handle if the type was found in a module, or btf.ErrNotFound +// if the type wasn't found at all. +func findTargetInKernel(kernelSpec *btf.Spec, typeName string, target *btf.Type) (*btf.Spec, *btf.Handle, error) { + err := kernelSpec.TypeByName(typeName, target) + if errors.Is(err, btf.ErrNotFound) { + spec, module, err := findTargetInModule(kernelSpec, typeName, target) if err != nil { - return nil, fmt.Errorf("load kernel spec: %w", err) + return nil, nil, fmt.Errorf("find target in modules: %w", err) } + return spec, module, nil } + if err != nil { + return nil, nil, fmt.Errorf("find target in vmlinux: %w", err) + } + return kernelSpec, nil, err +} - var target *btf.Func - err := spec.FindType(typeName, &target) - if errors.Is(err, btf.ErrNotFound) { - return nil, &internal.UnsupportedFeatureError{ - Name: featureName, +// findTargetInModule attempts to find a named type in any loaded module. +// +// base must contain the kernel's types and is used to parse kmod BTF. Modules +// are searched in the order they were loaded. +// +// Returns btf.ErrNotFound if the target can't be found in any module. +func findTargetInModule(base *btf.Spec, typeName string, target *btf.Type) (*btf.Spec, *btf.Handle, error) { + it := new(btf.HandleIterator) + defer it.Handle.Close() + + for it.Next() { + info, err := it.Handle.Info() + if err != nil { + return nil, nil, fmt.Errorf("get info for BTF ID %d: %w", it.ID, err) + } + + if !info.IsModule() { + continue + } + + spec, err := it.Handle.Spec(base) + if err != nil { + return nil, nil, fmt.Errorf("parse types for module %s: %w", info.Name, err) } + + err = spec.TypeByName(typeName, target) + if errors.Is(err, btf.ErrNotFound) { + continue + } + if err != nil { + return nil, nil, fmt.Errorf("lookup type in module %s: %w", info.Name, err) + } + + return spec, it.Take(), nil + } + if err := it.Err(); err != nil { + return nil, nil, fmt.Errorf("iterate modules: %w", err) + } + + return nil, nil, btf.ErrNotFound +} + +// find an attach target type in a program. +// +// Returns errUnrecognizedAttachType. +func findTargetInProgram(prog *Program, name string, progType ProgramType, attachType AttachType) (btf.TypeID, error) { + type match struct { + p ProgramType + a AttachType + } + + var typeName string + switch (match{progType, attachType}) { + case match{Extension, AttachNone}: + typeName = name + default: + return 0, errUnrecognizedAttachType } + + btfHandle, err := prog.Handle() + if err != nil { + return 0, fmt.Errorf("load target BTF: %w", err) + } + defer btfHandle.Close() + + spec, err := btfHandle.Spec(nil) + if err != nil { + return 0, err + } + + var targetFunc *btf.Func + err = spec.TypeByName(typeName, &targetFunc) if err != nil { - return nil, fmt.Errorf("resolve BTF for %s: %w", featureName, err) + return 0, fmt.Errorf("find target %s: %w", typeName, err) } - return target, nil + return spec.TypeID(targetFunc) } diff --git a/vendor/github.com/cilium/ebpf/ringbuf/reader.go b/vendor/github.com/cilium/ebpf/ringbuf/reader.go index 6efec763c3..12736acb73 100644 --- a/vendor/github.com/cilium/ebpf/ringbuf/reader.go +++ b/vendor/github.com/cilium/ebpf/ringbuf/reader.go @@ -5,32 +5,24 @@ import ( "errors" "fmt" "io" - "runtime" + "os" "sync" + "time" "github.com/cilium/ebpf" "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/epoll" "github.com/cilium/ebpf/internal/unix" ) var ( - ErrClosed = errors.New("ringbuf reader was closed") + ErrClosed = os.ErrClosed + errEOR = errors.New("end of ring") errDiscard = errors.New("sample discarded") errBusy = errors.New("sample not committed yet") ) -func addToEpoll(epollfd, fd int) error { - - event := unix.EpollEvent{ - Events: unix.EPOLLIN, - Fd: int32(fd), - } - - if err := unix.EpollCtl(epollfd, unix.EPOLL_CTL_ADD, fd, &event); err != nil { - return fmt.Errorf("can't add fd to epoll: %w", err) - } - return nil -} +var ringbufHeaderSize = binary.Size(ringbufHeader{}) // ringbufHeader from 'struct bpf_ringbuf_hdr' in kernel/bpf/ringbuf.c type ringbufHeader struct { @@ -54,23 +46,29 @@ type Record struct { RawSample []byte } -func readRecord(rd *ringbufEventRing) (r Record, err error) { +// Read a record from an event ring. +// +// buf must be at least ringbufHeaderSize bytes long. +func readRecord(rd *ringbufEventRing, rec *Record, buf []byte) error { rd.loadConsumer() - var header ringbufHeader - err = binary.Read(rd, internal.NativeEndian, &header) - if err == io.EOF { - return Record{}, err + + buf = buf[:ringbufHeaderSize] + if _, err := io.ReadFull(rd, buf); err == io.EOF { + return errEOR + } else if err != nil { + return fmt.Errorf("read event header: %w", err) } - if err != nil { - return Record{}, fmt.Errorf("can't read event header: %w", err) + header := ringbufHeader{ + internal.NativeEndian.Uint32(buf[0:4]), + internal.NativeEndian.Uint32(buf[4:8]), } if header.isBusy() { // the next sample in the ring is not committed yet so we // exit without storing the reader/consumer position // and start again from the same position. - return Record{}, fmt.Errorf("%w", errBusy) + return errBusy } /* read up to 8 byte alignment */ @@ -85,174 +83,144 @@ func readRecord(rd *ringbufEventRing) (r Record, err error) { rd.skipRead(dataLenAligned) rd.storeConsumer() - return Record{}, fmt.Errorf("%w", errDiscard) + return errDiscard } - data := make([]byte, dataLenAligned) + if cap(rec.RawSample) < int(dataLenAligned) { + rec.RawSample = make([]byte, dataLenAligned) + } else { + rec.RawSample = rec.RawSample[:dataLenAligned] + } - if _, err := io.ReadFull(rd, data); err != nil { - return Record{}, fmt.Errorf("can't read sample: %w", err) + if _, err := io.ReadFull(rd, rec.RawSample); err != nil { + return fmt.Errorf("read sample: %w", err) } rd.storeConsumer() - - return Record{RawSample: data[:header.dataLen()]}, nil + rec.RawSample = rec.RawSample[:header.dataLen()] + return nil } // Reader allows reading bpf_ringbuf_output // from user space. type Reader struct { - // mu protects read/write access to the Reader structure - mu sync.Mutex - - ring *ringbufEventRing + poller *epoll.Poller - epollFd int + // mu protects read/write access to the Reader structure + mu sync.Mutex + ring *ringbufEventRing epollEvents []unix.EpollEvent - - closeFd int - // Ensure we only close once - closeOnce sync.Once + header []byte + haveData bool + deadline time.Time } // NewReader creates a new BPF ringbuf reader. -func NewReader(ringbufMap *ebpf.Map) (r *Reader, err error) { +func NewReader(ringbufMap *ebpf.Map) (*Reader, error) { if ringbufMap.Type() != ebpf.RingBuf { return nil, fmt.Errorf("invalid Map type: %s", ringbufMap.Type()) } maxEntries := int(ringbufMap.MaxEntries()) if maxEntries == 0 || (maxEntries&(maxEntries-1)) != 0 { - return nil, fmt.Errorf("Ringbuffer map size %d is zero or not a power of two", maxEntries) + return nil, fmt.Errorf("ringbuffer map size %d is zero or not a power of two", maxEntries) } - epollFd, err := unix.EpollCreate1(unix.EPOLL_CLOEXEC) + poller, err := epoll.New() if err != nil { - return nil, fmt.Errorf("can't create epoll fd: %w", err) - } - - var ( - fds = []int{epollFd} - ring *ringbufEventRing - ) - - defer func() { - if err != nil { - // close epollFd and closeFd - for _, fd := range fds { - unix.Close(fd) - } - if ring != nil { - ring.Close() - } - } - }() - - ring, err = newRingBufEventRing(ringbufMap.FD(), maxEntries) - if err != nil { - return nil, fmt.Errorf("failed to create ringbuf ring: %w", err) - } - - if err := addToEpoll(epollFd, ringbufMap.FD()); err != nil { return nil, err } - closeFd, err := unix.Eventfd(0, unix.O_CLOEXEC|unix.O_NONBLOCK) - if err != nil { + if err := poller.Add(ringbufMap.FD(), 0); err != nil { + poller.Close() return nil, err } - fds = append(fds, closeFd) - if err := addToEpoll(epollFd, closeFd); err != nil { - return nil, err + ring, err := newRingBufEventRing(ringbufMap.FD(), maxEntries) + if err != nil { + poller.Close() + return nil, fmt.Errorf("failed to create ringbuf ring: %w", err) } - r = &Reader{ - ring: ring, - epollFd: epollFd, - // Allocate extra event for closeFd - epollEvents: make([]unix.EpollEvent, 2), - closeFd: closeFd, - } - runtime.SetFinalizer(r, (*Reader).Close) - return r, nil + return &Reader{ + poller: poller, + ring: ring, + epollEvents: make([]unix.EpollEvent, 1), + header: make([]byte, ringbufHeaderSize), + }, nil } // Close frees resources used by the reader. // // It interrupts calls to Read. func (r *Reader) Close() error { - var err error - r.closeOnce.Do(func() { - runtime.SetFinalizer(r, nil) - - // Interrupt Read() via the closeFd event fd. - var value [8]byte - internal.NativeEndian.PutUint64(value[:], 1) - - if _, err = unix.Write(r.closeFd, value[:]); err != nil { - err = fmt.Errorf("can't write event fd: %w", err) - return + if err := r.poller.Close(); err != nil { + if errors.Is(err, os.ErrClosed) { + return nil } + return err + } - // Acquire the lock. This ensures that Read isn't running. - r.mu.Lock() - defer r.mu.Unlock() - - unix.Close(r.epollFd) - unix.Close(r.closeFd) - r.epollFd, r.closeFd = -1, -1 + // Acquire the lock. This ensures that Read isn't running. + r.mu.Lock() + defer r.mu.Unlock() - if r.ring != nil { - r.ring.Close() - } + if r.ring != nil { + r.ring.Close() r.ring = nil - - }) - if err != nil { - return fmt.Errorf("close Reader: %w", err) } + return nil } +// SetDeadline controls how long Read and ReadInto will block waiting for samples. +// +// Passing a zero time.Time will remove the deadline. +func (r *Reader) SetDeadline(t time.Time) { + r.mu.Lock() + defer r.mu.Unlock() + + r.deadline = t +} + // Read the next record from the BPF ringbuf. // -// Calling Close interrupts the function. +// Returns os.ErrClosed if Close is called on the Reader, or os.ErrDeadlineExceeded +// if a deadline was set. func (r *Reader) Read() (Record, error) { + var rec Record + return rec, r.ReadInto(&rec) +} + +// ReadInto is like Read except that it allows reusing Record and associated buffers. +func (r *Reader) ReadInto(rec *Record) error { r.mu.Lock() defer r.mu.Unlock() - if r.epollFd == -1 { - return Record{}, fmt.Errorf("%w", ErrClosed) + if r.ring == nil { + return fmt.Errorf("ringbuffer: %w", ErrClosed) } for { - nEvents, err := unix.EpollWait(r.epollFd, r.epollEvents, -1) - if temp, ok := err.(temporaryError); ok && temp.Temporary() { - // Retry the syscall if we we're interrupted, see https://github.com/golang/go/issues/20400 - continue - } - - if err != nil { - return Record{}, err - } - - for _, event := range r.epollEvents[:nEvents] { - if int(event.Fd) == r.closeFd { - return Record{}, fmt.Errorf("%w", ErrClosed) + if !r.haveData { + _, err := r.poller.Wait(r.epollEvents[:cap(r.epollEvents)], r.deadline) + if err != nil { + return err } + r.haveData = true } - record, err := readRecord(r.ring) + for { + err := readRecord(r.ring, rec, r.header) + if err == errBusy || err == errDiscard { + continue + } + if err == errEOR { + r.haveData = false + break + } - if errors.Is(err, errBusy) || errors.Is(err, errDiscard) { - continue + return err } - - return record, err } } - -type temporaryError interface { - Temporary() bool -} diff --git a/vendor/github.com/cilium/ebpf/rlimit/rlimit.go b/vendor/github.com/cilium/ebpf/rlimit/rlimit.go index 22fc8177f2..2a6973744f 100644 --- a/vendor/github.com/cilium/ebpf/rlimit/rlimit.go +++ b/vendor/github.com/cilium/ebpf/rlimit/rlimit.go @@ -7,6 +7,7 @@ import ( "sync" "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/sys" "github.com/cilium/ebpf/internal/unix" ) @@ -36,14 +37,23 @@ func init() { } func detectMemcgAccounting() error { - // Reduce the limit to zero and store the previous limit. This should always succeed. + // Retrieve the original limit to prevent lowering Max, since + // doing so is a permanent operation when running unprivileged. var oldLimit unix.Rlimit + if err := unix.Prlimit(0, unix.RLIMIT_MEMLOCK, nil, &oldLimit); err != nil { + return fmt.Errorf("getting original memlock rlimit: %s", err) + } + + // Drop the current limit to zero, maintaining the old Max value. + // This is always permitted by the kernel for unprivileged users. + // Retrieve a new copy of the old limit tuple to minimize the chances + // of failing the restore operation below. zeroLimit := unix.Rlimit{Cur: 0, Max: oldLimit.Max} if err := unix.Prlimit(0, unix.RLIMIT_MEMLOCK, &zeroLimit, &oldLimit); err != nil { return fmt.Errorf("lowering memlock rlimit: %s", err) } - attr := internal.BPFMapCreateAttr{ + attr := sys.MapCreateAttr{ MapType: 2, /* Array */ KeySize: 4, ValueSize: 4, @@ -54,7 +64,7 @@ func detectMemcgAccounting() error { // the rlimit on pre-5.11 kernels, but against the memory cgroup budget on // kernels 5.11 and over. If this call succeeds with the process' memlock // rlimit set to 0, we can reasonably assume memcg accounting is supported. - fd, mapErr := internal.BPFMapCreate(&attr) + fd, mapErr := sys.MapCreate(&attr) // Restore old limits regardless of what happened. if err := unix.Prlimit(0, unix.RLIMIT_MEMLOCK, &oldLimit, nil); err != nil { diff --git a/vendor/github.com/cilium/ebpf/run-tests.sh b/vendor/github.com/cilium/ebpf/run-tests.sh index a079edc7e1..1d1490ad1d 100644 --- a/vendor/github.com/cilium/ebpf/run-tests.sh +++ b/vendor/github.com/cilium/ebpf/run-tests.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Test the current package under a different kernel. # Requires virtme and qemu to be installed. # Examples: @@ -6,6 +6,8 @@ # $ ./run-tests.sh 5.4 # Run a subset of tests: # $ ./run-tests.sh 5.4 ./link +# Run using a local kernel image +# $ ./run-tests.sh /path/to/bzImage set -euo pipefail @@ -48,21 +50,31 @@ if [[ "${1:-}" = "--exec-vm" ]]; then rm "${output}/fake-stdin" fi - if ! $sudo virtme-run --kimg "${input}/bzImage" --memory 768M --pwd \ - --rwdir="${testdir}=${testdir}" \ - --rodir=/run/input="${input}" \ - --rwdir=/run/output="${output}" \ - --script-sh "PATH=\"$PATH\" \"$script\" --exec-test $cmd" \ - --kopt possible_cpus=2; then # need at least two CPUs for some tests - exit 23 - fi + for ((i = 0; i < 3; i++)); do + if ! $sudo virtme-run --kimg "${input}/bzImage" --memory 768M --pwd \ + --rwdir="${testdir}=${testdir}" \ + --rodir=/run/input="${input}" \ + --rwdir=/run/output="${output}" \ + --script-sh "PATH=\"$PATH\" CI_MAX_KERNEL_VERSION="${CI_MAX_KERNEL_VERSION:-}" \"$script\" --exec-test $cmd" \ + --kopt possible_cpus=2; then # need at least two CPUs for some tests + exit 23 + fi + + if [[ -e "${output}/status" ]]; then + break + fi + + if [[ -v CI ]]; then + echo "Retrying test run due to qemu crash" + continue + fi - if [[ ! -e "${output}/success" ]]; then exit 42 - fi + done + rc=$(<"${output}/status") $sudo rm -r "$output" - exit 0 + exit $rc elif [[ "${1:-}" = "--exec-test" ]]; then shift @@ -73,42 +85,57 @@ elif [[ "${1:-}" = "--exec-test" ]]; then export KERNEL_SELFTESTS="/run/input/bpf" fi - dmesg -C - if ! "$@"; then - dmesg - exit 1 # this return code is "swallowed" by qemu + if [[ -f "/run/input/bpf/bpf_testmod/bpf_testmod.ko" ]]; then + insmod "/run/input/bpf/bpf_testmod/bpf_testmod.ko" fi - touch "/run/output/success" - exit 0 + + dmesg --clear + rc=0 + "$@" || rc=$? + dmesg + echo $rc > "/run/output/status" + exit $rc # this return code is "swallowed" by qemu fi -readonly kernel_version="${1:-}" -if [[ -z "${kernel_version}" ]]; then - echo "Expecting kernel version as first argument" +if [[ -z "${1:-}" ]]; then + echo "Expecting kernel version or path as first argument" exit 1 fi -shift -readonly kernel="linux-${kernel_version}.bz" -readonly selftests="linux-${kernel_version}-selftests-bpf.bz" readonly input="$(mktemp -d)" readonly tmp_dir="${TMPDIR:-/tmp}" -readonly branch="${BRANCH:-master}" fetch() { echo Fetching "${1}" - wget -nv -N -P "${tmp_dir}" "https://github.com/cilium/ci-kernels/raw/${branch}/${1}" + pushd "${tmp_dir}" > /dev/null + curl --no-progress-meter -L -O --fail --etag-compare "${1}.etag" --etag-save "${1}.etag" "https://github.com/cilium/ci-kernels/raw/${BRANCH:-master}/${1}" + local ret=$? + popd > /dev/null + return $ret } -fetch "${kernel}" -cp "${tmp_dir}/${kernel}" "${input}/bzImage" - -if fetch "${selftests}"; then - mkdir "${input}/bpf" - tar --strip-components=4 -xjf "${tmp_dir}/${selftests}" -C "${input}/bpf" +if [[ -f "${1}" ]]; then + readonly kernel="${1}" + cp "${1}" "${input}/bzImage" else - echo "No selftests found, disabling" +# LINUX_VERSION_CODE test compares this to discovered value. + export KERNEL_VERSION="${1}" + + readonly kernel="linux-${1}.bz" + readonly selftests="linux-${1}-selftests-bpf.tgz" + + fetch "${kernel}" + cp "${tmp_dir}/${kernel}" "${input}/bzImage" + + if fetch "${selftests}"; then + echo "Decompressing selftests" + mkdir "${input}/bpf" + tar --strip-components=4 -xf "${tmp_dir}/${selftests}" -C "${input}/bpf" + else + echo "No selftests found, disabling" + fi fi +shift args=(-short -coverpkg=./... -coverprofile=coverage.out -count 1 ./...) if (( $# > 0 )); then @@ -118,8 +145,8 @@ fi export GOFLAGS=-mod=readonly export CGO_ENABLED=0 -echo Testing on "${kernel_version}" +echo Testing on "${kernel}" go test -exec "$script --exec-vm $input" "${args[@]}" -echo "Test successful on ${kernel_version}" +echo "Test successful on ${kernel}" rm -r "${input}" diff --git a/vendor/github.com/cilium/ebpf/syscalls.go b/vendor/github.com/cilium/ebpf/syscalls.go index f8cb5f0e0c..fd21dea24f 100644 --- a/vendor/github.com/cilium/ebpf/syscalls.go +++ b/vendor/github.com/cilium/ebpf/syscalls.go @@ -5,17 +5,23 @@ import ( "errors" "fmt" "os" - "unsafe" + "runtime" "github.com/cilium/ebpf/asm" "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/sys" + "github.com/cilium/ebpf/internal/tracefs" "github.com/cilium/ebpf/internal/unix" ) -// ErrNotExist is returned when loading a non-existing map or program. -// -// Deprecated: use os.ErrNotExist instead. -var ErrNotExist = os.ErrNotExist +var ( + // pre-allocating these here since they may + // get called in hot code paths and cause + // unnecessary memory allocations + sysErrKeyNotExist = sys.Error(ErrKeyNotExist, unix.ENOENT) + sysErrKeyExist = sys.Error(ErrKeyExist, unix.EEXIST) + sysErrNotSupported = sys.Error(ErrNotSupported, sys.ENOTSUPP) +) // invalidBPFObjNameChar returns true if char may not appear in // a BPF object name. @@ -38,108 +44,24 @@ func invalidBPFObjNameChar(char rune) bool { } } -type bpfMapOpAttr struct { - mapFd uint32 - padding uint32 - key internal.Pointer - value internal.Pointer - flags uint64 -} - -type bpfBatchMapOpAttr struct { - inBatch internal.Pointer - outBatch internal.Pointer - keys internal.Pointer - values internal.Pointer - count uint32 - mapFd uint32 - elemFlags uint64 - flags uint64 -} - -type bpfMapInfo struct { - map_type uint32 // since 4.12 1e2709769086 - id uint32 - key_size uint32 - value_size uint32 - max_entries uint32 - map_flags uint32 - name internal.BPFObjName // since 4.15 ad5b177bd73f - ifindex uint32 // since 4.16 52775b33bb50 - btf_vmlinux_value_type_id uint32 // since 5.6 85d33df357b6 - netns_dev uint64 // since 4.16 52775b33bb50 - netns_ino uint64 - btf_id uint32 // since 4.18 78958fca7ead - btf_key_type_id uint32 // since 4.18 9b2cf328b2ec - btf_value_type_id uint32 -} - -type bpfProgInfo struct { - prog_type uint32 - id uint32 - tag [unix.BPF_TAG_SIZE]byte - jited_prog_len uint32 - xlated_prog_len uint32 - jited_prog_insns internal.Pointer - xlated_prog_insns internal.Pointer - load_time uint64 // since 4.15 cb4d2b3f03d8 - created_by_uid uint32 - nr_map_ids uint32 // since 4.15 cb4d2b3f03d8 - map_ids internal.Pointer - name internal.BPFObjName // since 4.15 067cae47771c - ifindex uint32 - gpl_compatible uint32 - netns_dev uint64 - netns_ino uint64 - nr_jited_ksyms uint32 - nr_jited_func_lens uint32 - jited_ksyms internal.Pointer - jited_func_lens internal.Pointer - btf_id uint32 - func_info_rec_size uint32 - func_info internal.Pointer - nr_func_info uint32 - nr_line_info uint32 - line_info internal.Pointer - jited_line_info internal.Pointer - nr_jited_line_info uint32 - line_info_rec_size uint32 - jited_line_info_rec_size uint32 - nr_prog_tags uint32 - prog_tags internal.Pointer - run_time_ns uint64 - run_cnt uint64 -} - -type bpfProgTestRunAttr struct { - fd uint32 - retval uint32 - dataSizeIn uint32 - dataSizeOut uint32 - dataIn internal.Pointer - dataOut internal.Pointer - repeat uint32 - duration uint32 -} - -type bpfMapFreezeAttr struct { - mapFd uint32 -} - -type bpfObjGetNextIDAttr struct { - startID uint32 - nextID uint32 - openFlags uint32 -} +func progLoad(insns asm.Instructions, typ ProgramType, license string) (*sys.FD, error) { + buf := bytes.NewBuffer(make([]byte, 0, insns.Size())) + if err := insns.Marshal(buf, internal.NativeEndian); err != nil { + return nil, err + } + bytecode := buf.Bytes() -func bpfProgTestRun(attr *bpfProgTestRunAttr) error { - _, err := internal.BPF(internal.BPF_PROG_TEST_RUN, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err + return sys.ProgLoad(&sys.ProgLoadAttr{ + ProgType: sys.ProgType(typ), + License: sys.NewStringPointer(license), + Insns: sys.NewSlicePointer(bytecode), + InsnCnt: uint32(len(bytecode) / asm.InstructionSize), + }) } -var haveNestedMaps = internal.FeatureTest("nested maps", "4.12", func() error { - _, err := internal.BPFMapCreate(&internal.BPFMapCreateAttr{ - MapType: uint32(ArrayOfMaps), +var haveNestedMaps = internal.NewFeatureTest("nested maps", "4.12", func() error { + _, err := sys.MapCreate(&sys.MapCreateAttr{ + MapType: sys.MapType(ArrayOfMaps), KeySize: 4, ValueSize: 4, MaxEntries: 1, @@ -155,15 +77,15 @@ var haveNestedMaps = internal.FeatureTest("nested maps", "4.12", func() error { return err }) -var haveMapMutabilityModifiers = internal.FeatureTest("read- and write-only maps", "5.2", func() error { +var haveMapMutabilityModifiers = internal.NewFeatureTest("read- and write-only maps", "5.2", func() error { // This checks BPF_F_RDONLY_PROG and BPF_F_WRONLY_PROG. Since // BPF_MAP_FREEZE appeared in 5.2 as well we don't do a separate check. - m, err := internal.BPFMapCreate(&internal.BPFMapCreateAttr{ - MapType: uint32(Array), + m, err := sys.MapCreate(&sys.MapCreateAttr{ + MapType: sys.MapType(Array), KeySize: 4, ValueSize: 4, MaxEntries: 1, - Flags: unix.BPF_F_RDONLY_PROG, + MapFlags: unix.BPF_F_RDONLY_PROG, }) if err != nil { return internal.ErrNotSupported @@ -172,14 +94,14 @@ var haveMapMutabilityModifiers = internal.FeatureTest("read- and write-only maps return nil }) -var haveMmapableMaps = internal.FeatureTest("mmapable maps", "5.5", func() error { +var haveMmapableMaps = internal.NewFeatureTest("mmapable maps", "5.5", func() error { // This checks BPF_F_MMAPABLE, which appeared in 5.5 for array maps. - m, err := internal.BPFMapCreate(&internal.BPFMapCreateAttr{ - MapType: uint32(Array), + m, err := sys.MapCreate(&sys.MapCreateAttr{ + MapType: sys.MapType(Array), KeySize: 4, ValueSize: 4, MaxEntries: 1, - Flags: unix.BPF_F_MMAPABLE, + MapFlags: unix.BPF_F_MMAPABLE, }) if err != nil { return internal.ErrNotSupported @@ -188,14 +110,14 @@ var haveMmapableMaps = internal.FeatureTest("mmapable maps", "5.5", func() error return nil }) -var haveInnerMaps = internal.FeatureTest("inner maps", "5.10", func() error { +var haveInnerMaps = internal.NewFeatureTest("inner maps", "5.10", func() error { // This checks BPF_F_INNER_MAP, which appeared in 5.10. - m, err := internal.BPFMapCreate(&internal.BPFMapCreateAttr{ - MapType: uint32(Array), + m, err := sys.MapCreate(&sys.MapCreateAttr{ + MapType: sys.MapType(Array), KeySize: 4, ValueSize: 4, MaxEntries: 1, - Flags: unix.BPF_F_INNER_MAP, + MapFlags: unix.BPF_F_INNER_MAP, }) if err != nil { return internal.ErrNotSupported @@ -204,111 +126,21 @@ var haveInnerMaps = internal.FeatureTest("inner maps", "5.10", func() error { return nil }) -func bpfMapLookupElem(m *internal.FD, key, valueOut internal.Pointer) error { - fd, err := m.Value() - if err != nil { - return err - } - - attr := bpfMapOpAttr{ - mapFd: fd, - key: key, - value: valueOut, - } - _, err = internal.BPF(internal.BPF_MAP_LOOKUP_ELEM, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) - return wrapMapError(err) -} - -func bpfMapLookupAndDelete(m *internal.FD, key, valueOut internal.Pointer) error { - fd, err := m.Value() - if err != nil { - return err - } - - attr := bpfMapOpAttr{ - mapFd: fd, - key: key, - value: valueOut, - } - _, err = internal.BPF(internal.BPF_MAP_LOOKUP_AND_DELETE_ELEM, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) - return wrapMapError(err) -} - -func bpfMapUpdateElem(m *internal.FD, key, valueOut internal.Pointer, flags uint64) error { - fd, err := m.Value() - if err != nil { - return err - } - - attr := bpfMapOpAttr{ - mapFd: fd, - key: key, - value: valueOut, - flags: flags, - } - _, err = internal.BPF(internal.BPF_MAP_UPDATE_ELEM, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) - return wrapMapError(err) -} - -func bpfMapDeleteElem(m *internal.FD, key internal.Pointer) error { - fd, err := m.Value() - if err != nil { - return err - } - - attr := bpfMapOpAttr{ - mapFd: fd, - key: key, - } - _, err = internal.BPF(internal.BPF_MAP_DELETE_ELEM, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) - return wrapMapError(err) -} - -func bpfMapGetNextKey(m *internal.FD, key, nextKeyOut internal.Pointer) error { - fd, err := m.Value() - if err != nil { - return err - } - - attr := bpfMapOpAttr{ - mapFd: fd, - key: key, - value: nextKeyOut, - } - _, err = internal.BPF(internal.BPF_MAP_GET_NEXT_KEY, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) - return wrapMapError(err) -} - -func objGetNextID(cmd internal.BPFCmd, start uint32) (uint32, error) { - attr := bpfObjGetNextIDAttr{ - startID: start, - } - _, err := internal.BPF(cmd, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) - return attr.nextID, err -} - -func bpfMapBatch(cmd internal.BPFCmd, m *internal.FD, inBatch, outBatch, keys, values internal.Pointer, count uint32, opts *BatchOptions) (uint32, error) { - fd, err := m.Value() +var haveNoPreallocMaps = internal.NewFeatureTest("prealloc maps", "4.6", func() error { + // This checks BPF_F_NO_PREALLOC, which appeared in 4.6. + m, err := sys.MapCreate(&sys.MapCreateAttr{ + MapType: sys.MapType(Hash), + KeySize: 4, + ValueSize: 4, + MaxEntries: 1, + MapFlags: unix.BPF_F_NO_PREALLOC, + }) if err != nil { - return 0, err - } - - attr := bpfBatchMapOpAttr{ - inBatch: inBatch, - outBatch: outBatch, - keys: keys, - values: values, - count: count, - mapFd: fd, - } - if opts != nil { - attr.elemFlags = opts.ElemFlags - attr.flags = opts.Flags + return internal.ErrNotSupported } - _, err = internal.BPF(cmd, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) - // always return count even on an error, as things like update might partially be fulfilled. - return attr.count, wrapMapError(err) -} + _ = m.Close() + return nil +}) func wrapMapError(err error) error { if err == nil { @@ -316,15 +148,15 @@ func wrapMapError(err error) error { } if errors.Is(err, unix.ENOENT) { - return internal.SyscallError(ErrKeyNotExist, unix.ENOENT) + return sysErrKeyNotExist } if errors.Is(err, unix.EEXIST) { - return internal.SyscallError(ErrKeyExist, unix.EEXIST) + return sysErrKeyExist } - if errors.Is(err, unix.ENOTSUPP) { - return internal.SyscallError(ErrNotSupported, unix.ENOTSUPP) + if errors.Is(err, sys.ENOTSUPP) { + return sysErrNotSupported } if errors.Is(err, unix.E2BIG) { @@ -334,51 +166,16 @@ func wrapMapError(err error) error { return err } -func bpfMapFreeze(m *internal.FD) error { - fd, err := m.Value() - if err != nil { - return err - } - - attr := bpfMapFreezeAttr{ - mapFd: fd, - } - _, err = internal.BPF(internal.BPF_MAP_FREEZE, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) - return err -} - -func bpfGetProgInfoByFD(fd *internal.FD, ids []MapID) (*bpfProgInfo, error) { - var info bpfProgInfo - if len(ids) > 0 { - info.nr_map_ids = uint32(len(ids)) - info.map_ids = internal.NewPointer(unsafe.Pointer(&ids[0])) - } - - if err := internal.BPFObjGetInfoByFD(fd, unsafe.Pointer(&info), unsafe.Sizeof(info)); err != nil { - return nil, fmt.Errorf("can't get program info: %w", err) - } - return &info, nil -} - -func bpfGetMapInfoByFD(fd *internal.FD) (*bpfMapInfo, error) { - var info bpfMapInfo - err := internal.BPFObjGetInfoByFD(fd, unsafe.Pointer(&info), unsafe.Sizeof(info)) - if err != nil { - return nil, fmt.Errorf("can't get map info: %w", err) - } - return &info, nil -} - -var haveObjName = internal.FeatureTest("object names", "4.15", func() error { - attr := internal.BPFMapCreateAttr{ - MapType: uint32(Array), +var haveObjName = internal.NewFeatureTest("object names", "4.15", func() error { + attr := sys.MapCreateAttr{ + MapType: sys.MapType(Array), KeySize: 4, ValueSize: 4, MaxEntries: 1, - MapName: internal.NewBPFObjName("feature_test"), + MapName: sys.NewObjName("feature_test"), } - fd, err := internal.BPFMapCreate(&attr) + fd, err := sys.MapCreate(&attr) if err != nil { return internal.ErrNotSupported } @@ -387,20 +184,20 @@ var haveObjName = internal.FeatureTest("object names", "4.15", func() error { return nil }) -var objNameAllowsDot = internal.FeatureTest("dot in object names", "5.2", func() error { +var objNameAllowsDot = internal.NewFeatureTest("dot in object names", "5.2", func() error { if err := haveObjName(); err != nil { return err } - attr := internal.BPFMapCreateAttr{ - MapType: uint32(Array), + attr := sys.MapCreateAttr{ + MapType: sys.MapType(Array), KeySize: 4, ValueSize: 4, MaxEntries: 1, - MapName: internal.NewBPFObjName(".test"), + MapName: sys.NewObjName(".test"), } - fd, err := internal.BPFMapCreate(&attr) + fd, err := sys.MapCreate(&attr) if err != nil { return internal.ErrNotSupported } @@ -409,33 +206,39 @@ var objNameAllowsDot = internal.FeatureTest("dot in object names", "5.2", func() return nil }) -var haveBatchAPI = internal.FeatureTest("map batch api", "5.6", func() error { +var haveBatchAPI = internal.NewFeatureTest("map batch api", "5.6", func() error { var maxEntries uint32 = 2 - attr := internal.BPFMapCreateAttr{ - MapType: uint32(Hash), + attr := sys.MapCreateAttr{ + MapType: sys.MapType(Hash), KeySize: 4, ValueSize: 4, MaxEntries: maxEntries, } - fd, err := internal.BPFMapCreate(&attr) + fd, err := sys.MapCreate(&attr) if err != nil { return internal.ErrNotSupported } defer fd.Close() + keys := []uint32{1, 2} values := []uint32{3, 4} kp, _ := marshalPtr(keys, 8) vp, _ := marshalPtr(values, 8) - nilPtr := internal.NewPointer(nil) - _, err = bpfMapBatch(internal.BPF_MAP_UPDATE_BATCH, fd, nilPtr, nilPtr, kp, vp, maxEntries, nil) + + err = sys.MapUpdateBatch(&sys.MapUpdateBatchAttr{ + MapFd: fd.Uint(), + Keys: kp, + Values: vp, + Count: maxEntries, + }) if err != nil { return internal.ErrNotSupported } return nil }) -var haveProbeReadKernel = internal.FeatureTest("bpf_probe_read_kernel", "5.5", func() error { +var haveProbeReadKernel = internal.NewFeatureTest("bpf_probe_read_kernel", "5.5", func() error { insns := asm.Instructions{ asm.Mov.Reg(asm.R1, asm.R10), asm.Add.Imm(asm.R1, -8), @@ -444,21 +247,59 @@ var haveProbeReadKernel = internal.FeatureTest("bpf_probe_read_kernel", "5.5", f asm.FnProbeReadKernel.Call(), asm.Return(), } - buf := bytes.NewBuffer(make([]byte, 0, len(insns)*asm.InstructionSize)) - if err := insns.Marshal(buf, internal.NativeEndian); err != nil { - return err - } - bytecode := buf.Bytes() - fd, err := internal.BPFProgLoad(&internal.BPFProgLoadAttr{ - ProgType: uint32(Kprobe), - License: internal.NewStringPointer("GPL"), - Instructions: internal.NewSlicePointer(bytecode), - InsCount: uint32(len(bytecode) / asm.InstructionSize), - }) + fd, err := progLoad(insns, Kprobe, "GPL") if err != nil { return internal.ErrNotSupported } _ = fd.Close() return nil }) + +var haveBPFToBPFCalls = internal.NewFeatureTest("bpf2bpf calls", "4.16", func() error { + insns := asm.Instructions{ + asm.Call.Label("prog2").WithSymbol("prog1"), + asm.Return(), + asm.Mov.Imm(asm.R0, 0).WithSymbol("prog2"), + asm.Return(), + } + + fd, err := progLoad(insns, SocketFilter, "MIT") + if errors.Is(err, unix.EINVAL) { + return internal.ErrNotSupported + } + if err != nil { + return err + } + _ = fd.Close() + return nil +}) + +var haveSyscallWrapper = internal.NewFeatureTest("syscall wrapper", "4.17", func() error { + prefix := internal.PlatformPrefix() + if prefix == "" { + return fmt.Errorf("unable to find the platform prefix for (%s)", runtime.GOARCH) + } + + args := tracefs.ProbeArgs{ + Type: tracefs.Kprobe, + Symbol: prefix + "sys_bpf", + Pid: -1, + } + + var err error + args.Group, err = tracefs.RandomGroup("ebpf_probe") + if err != nil { + return err + } + + evt, err := tracefs.NewEvent(args) + if errors.Is(err, os.ErrNotExist) { + return internal.ErrNotSupported + } + if err != nil { + return err + } + + return evt.Close() +}) diff --git a/vendor/github.com/cilium/ebpf/types.go b/vendor/github.com/cilium/ebpf/types.go index 84b83f9f98..35927e2ab8 100644 --- a/vendor/github.com/cilium/ebpf/types.go +++ b/vendor/github.com/cilium/ebpf/types.go @@ -1,6 +1,7 @@ package ebpf import ( + "github.com/cilium/ebpf/internal/sys" "github.com/cilium/ebpf/internal/unix" ) @@ -10,11 +11,6 @@ import ( // that will be initialized in the kernel. type MapType uint32 -// Max returns the latest supported MapType. -func (_ MapType) Max() MapType { - return maxMapType - 1 -} - // All the various map types that can be created const ( UnspecifiedMap MapType = iota @@ -99,16 +95,8 @@ const ( InodeStorage // TaskStorage - Specialized local storage map for task_struct. TaskStorage - // maxMapType - Bound enum of MapTypes, has to be last in enum. - maxMapType ) -// Deprecated: StructOpts was a typo, use StructOpsMap instead. -// -// Declared as a variable to prevent stringer from picking it up -// as an enum value. -var StructOpts MapType = StructOpsMap - // hasPerCPUValue returns true if the Map stores a value per CPU. func (mt MapType) hasPerCPUValue() bool { return mt == PerCPUHash || mt == PerCPUArray || mt == LRUCPUHash || mt == PerCPUCGroupStorage @@ -129,11 +117,6 @@ func (mt MapType) canStoreProgram() bool { // ProgramType of the eBPF program type ProgramType uint32 -// Max return the latest supported ProgramType. -func (_ ProgramType) Max() ProgramType { - return maxProgramType - 1 -} - // eBPF program types const ( UnspecifiedProgram ProgramType = iota @@ -167,7 +150,7 @@ const ( Extension LSM SkLookup - maxProgramType + Syscall ) // AttachType of the eBPF program, needed to differentiate allowed context accesses in @@ -223,6 +206,7 @@ const ( AttachSkReuseportSelect AttachSkReuseportSelectOrMigrate AttachPerfEvent + AttachTraceKprobeMulti ) // AttachFlags of the eBPF program used in BPF_PROG_ATTACH command @@ -276,3 +260,20 @@ type BatchOptions struct { ElemFlags uint64 Flags uint64 } + +// LogLevel controls the verbosity of the kernel's eBPF program verifier. +// These constants can be used for the ProgramOptions.LogLevel field. +type LogLevel = sys.LogLevel + +const ( + // Print verifier state at branch points. + LogLevelBranch = sys.BPF_LOG_LEVEL1 + + // Print verifier state for every instruction. + // Available since Linux v5.2. + LogLevelInstruction = sys.BPF_LOG_LEVEL2 + + // Print verifier errors and stats at the end of the verification process. + // Available since Linux v5.2. + LogLevelStats = sys.BPF_LOG_STATS +) diff --git a/vendor/github.com/cilium/ebpf/types_string.go b/vendor/github.com/cilium/ebpf/types_string.go index 81cbc9efde..5679f22543 100644 --- a/vendor/github.com/cilium/ebpf/types_string.go +++ b/vendor/github.com/cilium/ebpf/types_string.go @@ -38,12 +38,11 @@ func _() { _ = x[RingBuf-27] _ = x[InodeStorage-28] _ = x[TaskStorage-29] - _ = x[maxMapType-30] } -const _MapType_name = "UnspecifiedMapHashArrayProgramArrayPerfEventArrayPerCPUHashPerCPUArrayStackTraceCGroupArrayLRUHashLRUCPUHashLPMTrieArrayOfMapsHashOfMapsDevMapSockMapCPUMapXSKMapSockHashCGroupStorageReusePortSockArrayPerCPUCGroupStorageQueueStackSkStorageDevMapHashStructOpsMapRingBufInodeStorageTaskStoragemaxMapType" +const _MapType_name = "UnspecifiedMapHashArrayProgramArrayPerfEventArrayPerCPUHashPerCPUArrayStackTraceCGroupArrayLRUHashLRUCPUHashLPMTrieArrayOfMapsHashOfMapsDevMapSockMapCPUMapXSKMapSockHashCGroupStorageReusePortSockArrayPerCPUCGroupStorageQueueStackSkStorageDevMapHashStructOpsMapRingBufInodeStorageTaskStorage" -var _MapType_index = [...]uint16{0, 14, 18, 23, 35, 49, 59, 70, 80, 91, 98, 108, 115, 126, 136, 142, 149, 155, 161, 169, 182, 200, 219, 224, 229, 238, 248, 260, 267, 279, 290, 300} +var _MapType_index = [...]uint16{0, 14, 18, 23, 35, 49, 59, 70, 80, 91, 98, 108, 115, 126, 136, 142, 149, 155, 161, 169, 182, 200, 219, 224, 229, 238, 248, 260, 267, 279, 290} func (i MapType) String() string { if i >= MapType(len(_MapType_index)-1) { @@ -86,12 +85,12 @@ func _() { _ = x[Extension-28] _ = x[LSM-29] _ = x[SkLookup-30] - _ = x[maxProgramType-31] + _ = x[Syscall-31] } -const _ProgramType_name = "UnspecifiedProgramSocketFilterKprobeSchedCLSSchedACTTracePointXDPPerfEventCGroupSKBCGroupSockLWTInLWTOutLWTXmitSockOpsSkSKBCGroupDeviceSkMsgRawTracepointCGroupSockAddrLWTSeg6LocalLircMode2SkReuseportFlowDissectorCGroupSysctlRawTracepointWritableCGroupSockoptTracingStructOpsExtensionLSMSkLookupmaxProgramType" +const _ProgramType_name = "UnspecifiedProgramSocketFilterKprobeSchedCLSSchedACTTracePointXDPPerfEventCGroupSKBCGroupSockLWTInLWTOutLWTXmitSockOpsSkSKBCGroupDeviceSkMsgRawTracepointCGroupSockAddrLWTSeg6LocalLircMode2SkReuseportFlowDissectorCGroupSysctlRawTracepointWritableCGroupSockoptTracingStructOpsExtensionLSMSkLookupSyscall" -var _ProgramType_index = [...]uint16{0, 18, 30, 36, 44, 52, 62, 65, 74, 83, 93, 98, 104, 111, 118, 123, 135, 140, 153, 167, 179, 188, 199, 212, 224, 245, 258, 265, 274, 283, 286, 294, 308} +var _ProgramType_index = [...]uint16{0, 18, 30, 36, 44, 52, 62, 65, 74, 83, 93, 98, 104, 111, 118, 123, 135, 140, 153, 167, 179, 188, 199, 212, 224, 245, 258, 265, 274, 283, 286, 294, 301} func (i ProgramType) String() string { if i >= ProgramType(len(_ProgramType_index)-1) { diff --git a/vendor/github.com/cosiner/argv/go.mod b/vendor/github.com/cosiner/argv/go.mod deleted file mode 100644 index 6ed4ddac60..0000000000 --- a/vendor/github.com/cosiner/argv/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/cosiner/argv - -go 1.13 diff --git a/vendor/github.com/creack/pty/go.mod b/vendor/github.com/creack/pty/go.mod deleted file mode 100644 index e48decaf46..0000000000 --- a/vendor/github.com/creack/pty/go.mod +++ /dev/null @@ -1,4 +0,0 @@ -module github.com/creack/pty - -go 1.13 - diff --git a/vendor/github.com/derekparker/trie/go.mod b/vendor/github.com/derekparker/trie/go.mod deleted file mode 100644 index d8e6e6a1a7..0000000000 --- a/vendor/github.com/derekparker/trie/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/derekparker/trie - -go 1.19 diff --git a/vendor/github.com/go-delve/liner/go.mod b/vendor/github.com/go-delve/liner/go.mod deleted file mode 100644 index 1c9631ebef..0000000000 --- a/vendor/github.com/go-delve/liner/go.mod +++ /dev/null @@ -1,6 +0,0 @@ -module github.com/go-delve/liner - -require ( - github.com/mattn/go-runewidth v0.0.3 - golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 -) diff --git a/vendor/github.com/go-delve/liner/go.sum b/vendor/github.com/go-delve/liner/go.sum deleted file mode 100644 index 2074957d3d..0000000000 --- a/vendor/github.com/go-delve/liner/go.sum +++ /dev/null @@ -1,4 +0,0 @@ -github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4= -github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 h1:kwrAHlwJ0DUBZwQ238v+Uod/3eZ8B2K5rYsUHBQvzmI= -golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/vendor/github.com/google/go-dap/go.mod b/vendor/github.com/google/go-dap/go.mod deleted file mode 100644 index d90f6f0c9c..0000000000 --- a/vendor/github.com/google/go-dap/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module github.com/google/go-dap - -go 1.13 - -retract v0.9.0 diff --git a/vendor/github.com/google/go-dap/schematypes.go b/vendor/github.com/google/go-dap/schematypes.go index 54200bc8a4..8799020d35 100644 --- a/vendor/github.com/google/go-dap/schematypes.go +++ b/vendor/github.com/google/go-dap/schematypes.go @@ -2124,4 +2124,3 @@ var eventCtor = map[string]messageCtor{ "invalidated": func() Message { return &InvalidatedEvent{} }, "memory": func() Message { return &MemoryEvent{} }, } - \ No newline at end of file diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod b/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod deleted file mode 100644 index 716c613125..0000000000 --- a/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod +++ /dev/null @@ -1 +0,0 @@ -module github.com/konsorten/go-windows-terminal-sequences diff --git a/vendor/github.com/mattn/go-runewidth/go.mod b/vendor/github.com/mattn/go-runewidth/go.mod deleted file mode 100644 index 62dba1bfc8..0000000000 --- a/vendor/github.com/mattn/go-runewidth/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module github.com/mattn/go-runewidth - -go 1.9 - -require github.com/rivo/uniseg v0.2.0 diff --git a/vendor/github.com/mattn/go-runewidth/go.sum b/vendor/github.com/mattn/go-runewidth/go.sum deleted file mode 100644 index 03f902d56d..0000000000 --- a/vendor/github.com/mattn/go-runewidth/go.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= diff --git a/vendor/github.com/rivo/uniseg/go.mod b/vendor/github.com/rivo/uniseg/go.mod deleted file mode 100644 index a54280b2de..0000000000 --- a/vendor/github.com/rivo/uniseg/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/rivo/uniseg - -go 1.12 diff --git a/vendor/github.com/russross/blackfriday/v2/go.mod b/vendor/github.com/russross/blackfriday/v2/go.mod deleted file mode 100644 index 620b74e0ac..0000000000 --- a/vendor/github.com/russross/blackfriday/v2/go.mod +++ /dev/null @@ -1 +0,0 @@ -module github.com/russross/blackfriday/v2 diff --git a/vendor/github.com/shurcooL/sanitized_anchor_name/go.mod b/vendor/github.com/shurcooL/sanitized_anchor_name/go.mod deleted file mode 100644 index 1e25534759..0000000000 --- a/vendor/github.com/shurcooL/sanitized_anchor_name/go.mod +++ /dev/null @@ -1 +0,0 @@ -module github.com/shurcooL/sanitized_anchor_name diff --git a/vendor/github.com/sirupsen/logrus/go.mod b/vendor/github.com/sirupsen/logrus/go.mod deleted file mode 100644 index d41329679f..0000000000 --- a/vendor/github.com/sirupsen/logrus/go.mod +++ /dev/null @@ -1,11 +0,0 @@ -module github.com/sirupsen/logrus - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/konsorten/go-windows-terminal-sequences v1.0.3 - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/stretchr/testify v1.2.2 - golang.org/x/sys v0.0.0-20190422165155-953cdadca894 -) - -go 1.13 diff --git a/vendor/github.com/sirupsen/logrus/go.sum b/vendor/github.com/sirupsen/logrus/go.sum deleted file mode 100644 index 49c690f238..0000000000 --- a/vendor/github.com/sirupsen/logrus/go.sum +++ /dev/null @@ -1,12 +0,0 @@ -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/vendor/github.com/spf13/cobra/go.mod b/vendor/github.com/spf13/cobra/go.mod deleted file mode 100644 index ff56144056..0000000000 --- a/vendor/github.com/spf13/cobra/go.mod +++ /dev/null @@ -1,12 +0,0 @@ -module github.com/spf13/cobra - -go 1.12 - -require ( - github.com/cpuguy83/go-md2man/v2 v2.0.0 - github.com/inconshreveable/mousetrap v1.0.0 - github.com/mitchellh/go-homedir v1.1.0 - github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.7.0 - gopkg.in/yaml.v2 v2.4.0 -) diff --git a/vendor/github.com/spf13/cobra/go.sum b/vendor/github.com/spf13/cobra/go.sum deleted file mode 100644 index 9328ee3ee7..0000000000 --- a/vendor/github.com/spf13/cobra/go.sum +++ /dev/null @@ -1,313 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -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/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -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-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/vendor/github.com/spf13/pflag/go.mod b/vendor/github.com/spf13/pflag/go.mod deleted file mode 100644 index b2287eec13..0000000000 --- a/vendor/github.com/spf13/pflag/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/spf13/pflag - -go 1.12 diff --git a/vendor/github.com/spf13/pflag/go.sum b/vendor/github.com/spf13/pflag/go.sum deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/vendor/golang.org/x/exp/LICENSE b/vendor/golang.org/x/exp/LICENSE new file mode 100644 index 0000000000..6a66aea5ea --- /dev/null +++ b/vendor/golang.org/x/exp/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/exp/PATENTS b/vendor/golang.org/x/exp/PATENTS new file mode 100644 index 0000000000..733099041f --- /dev/null +++ b/vendor/golang.org/x/exp/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/exp/constraints/constraints.go b/vendor/golang.org/x/exp/constraints/constraints.go new file mode 100644 index 0000000000..2c033dff47 --- /dev/null +++ b/vendor/golang.org/x/exp/constraints/constraints.go @@ -0,0 +1,50 @@ +// Copyright 2021 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 constraints defines a set of useful constraints to be used +// with type parameters. +package constraints + +// Signed is a constraint that permits any signed integer type. +// If future releases of Go add new predeclared signed integer types, +// this constraint will be modified to include them. +type Signed interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 +} + +// Unsigned is a constraint that permits any unsigned integer type. +// If future releases of Go add new predeclared unsigned integer types, +// this constraint will be modified to include them. +type Unsigned interface { + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr +} + +// Integer is a constraint that permits any integer type. +// If future releases of Go add new predeclared integer types, +// this constraint will be modified to include them. +type Integer interface { + Signed | Unsigned +} + +// Float is a constraint that permits any floating-point type. +// If future releases of Go add new predeclared floating-point types, +// this constraint will be modified to include them. +type Float interface { + ~float32 | ~float64 +} + +// Complex is a constraint that permits any complex numeric type. +// If future releases of Go add new predeclared complex numeric types, +// this constraint will be modified to include them. +type Complex interface { + ~complex64 | ~complex128 +} + +// Ordered is a constraint that permits any ordered type: any type +// that supports the operators < <= >= >. +// If future releases of Go add new ordered types, +// this constraint will be modified to include them. +type Ordered interface { + Integer | Float | ~string +} diff --git a/vendor/golang.org/x/exp/maps/maps.go b/vendor/golang.org/x/exp/maps/maps.go new file mode 100644 index 0000000000..ecc0dabb74 --- /dev/null +++ b/vendor/golang.org/x/exp/maps/maps.go @@ -0,0 +1,94 @@ +// Copyright 2021 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 maps defines various functions useful with maps of any type. +package maps + +// Keys returns the keys of the map m. +// The keys will be in an indeterminate order. +func Keys[M ~map[K]V, K comparable, V any](m M) []K { + r := make([]K, 0, len(m)) + for k := range m { + r = append(r, k) + } + return r +} + +// Values returns the values of the map m. +// The values will be in an indeterminate order. +func Values[M ~map[K]V, K comparable, V any](m M) []V { + r := make([]V, 0, len(m)) + for _, v := range m { + r = append(r, v) + } + return r +} + +// Equal reports whether two maps contain the same key/value pairs. +// Values are compared using ==. +func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool { + if len(m1) != len(m2) { + return false + } + for k, v1 := range m1 { + if v2, ok := m2[k]; !ok || v1 != v2 { + return false + } + } + return true +} + +// EqualFunc is like Equal, but compares values using eq. +// Keys are still compared with ==. +func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool { + if len(m1) != len(m2) { + return false + } + for k, v1 := range m1 { + if v2, ok := m2[k]; !ok || !eq(v1, v2) { + return false + } + } + return true +} + +// Clear removes all entries from m, leaving it empty. +func Clear[M ~map[K]V, K comparable, V any](m M) { + for k := range m { + delete(m, k) + } +} + +// Clone returns a copy of m. This is a shallow clone: +// the new keys and values are set using ordinary assignment. +func Clone[M ~map[K]V, K comparable, V any](m M) M { + // Preserve nil in case it matters. + if m == nil { + return nil + } + r := make(M, len(m)) + for k, v := range m { + r[k] = v + } + return r +} + +// Copy copies all key/value pairs in src adding them to dst. +// When a key in src is already present in dst, +// the value in dst will be overwritten by the value associated +// with the key in src. +func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) { + for k, v := range src { + dst[k] = v + } +} + +// DeleteFunc deletes any key/value pairs from m for which del returns true. +func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool) { + for k, v := range m { + if del(k, v) { + delete(m, k) + } + } +} diff --git a/vendor/golang.org/x/exp/slices/slices.go b/vendor/golang.org/x/exp/slices/slices.go new file mode 100644 index 0000000000..cff0cd49ec --- /dev/null +++ b/vendor/golang.org/x/exp/slices/slices.go @@ -0,0 +1,258 @@ +// Copyright 2021 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 slices defines various functions useful with slices of any type. +// Unless otherwise specified, these functions all apply to the elements +// of a slice at index 0 <= i < len(s). +// +// Note that the less function in IsSortedFunc, SortFunc, SortStableFunc requires a +// strict weak ordering (https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings), +// or the sorting may fail to sort correctly. A common case is when sorting slices of +// floating-point numbers containing NaN values. +package slices + +import "golang.org/x/exp/constraints" + +// Equal reports whether two slices are equal: the same length and all +// elements equal. If the lengths are different, Equal returns false. +// Otherwise, the elements are compared in increasing index order, and the +// comparison stops at the first unequal pair. +// Floating point NaNs are not considered equal. +func Equal[E comparable](s1, s2 []E) bool { + if len(s1) != len(s2) { + return false + } + for i := range s1 { + if s1[i] != s2[i] { + return false + } + } + return true +} + +// EqualFunc reports whether two slices are equal using a comparison +// function on each pair of elements. If the lengths are different, +// EqualFunc returns false. Otherwise, the elements are compared in +// increasing index order, and the comparison stops at the first index +// for which eq returns false. +func EqualFunc[E1, E2 any](s1 []E1, s2 []E2, eq func(E1, E2) bool) bool { + if len(s1) != len(s2) { + return false + } + for i, v1 := range s1 { + v2 := s2[i] + if !eq(v1, v2) { + return false + } + } + return true +} + +// Compare compares the elements of s1 and s2. +// The elements are compared sequentially, starting at index 0, +// until one element is not equal to the other. +// The result of comparing the first non-matching elements is returned. +// If both slices are equal until one of them ends, the shorter slice is +// considered less than the longer one. +// The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2. +// Comparisons involving floating point NaNs are ignored. +func Compare[E constraints.Ordered](s1, s2 []E) int { + s2len := len(s2) + for i, v1 := range s1 { + if i >= s2len { + return +1 + } + v2 := s2[i] + switch { + case v1 < v2: + return -1 + case v1 > v2: + return +1 + } + } + if len(s1) < s2len { + return -1 + } + return 0 +} + +// CompareFunc is like Compare but uses a comparison function +// on each pair of elements. The elements are compared in increasing +// index order, and the comparisons stop after the first time cmp +// returns non-zero. +// The result is the first non-zero result of cmp; if cmp always +// returns 0 the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2), +// and +1 if len(s1) > len(s2). +func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int { + s2len := len(s2) + for i, v1 := range s1 { + if i >= s2len { + return +1 + } + v2 := s2[i] + if c := cmp(v1, v2); c != 0 { + return c + } + } + if len(s1) < s2len { + return -1 + } + return 0 +} + +// Index returns the index of the first occurrence of v in s, +// or -1 if not present. +func Index[E comparable](s []E, v E) int { + for i, vs := range s { + if v == vs { + return i + } + } + return -1 +} + +// IndexFunc returns the first index i satisfying f(s[i]), +// or -1 if none do. +func IndexFunc[E any](s []E, f func(E) bool) int { + for i, v := range s { + if f(v) { + return i + } + } + return -1 +} + +// Contains reports whether v is present in s. +func Contains[E comparable](s []E, v E) bool { + return Index(s, v) >= 0 +} + +// ContainsFunc reports whether at least one +// element e of s satisfies f(e). +func ContainsFunc[E any](s []E, f func(E) bool) bool { + return IndexFunc(s, f) >= 0 +} + +// Insert inserts the values v... into s at index i, +// returning the modified slice. +// In the returned slice r, r[i] == v[0]. +// Insert panics if i is out of range. +// This function is O(len(s) + len(v)). +func Insert[S ~[]E, E any](s S, i int, v ...E) S { + tot := len(s) + len(v) + if tot <= cap(s) { + s2 := s[:tot] + copy(s2[i+len(v):], s[i:]) + copy(s2[i:], v) + return s2 + } + s2 := make(S, tot) + copy(s2, s[:i]) + copy(s2[i:], v) + copy(s2[i+len(v):], s[i:]) + return s2 +} + +// Delete removes the elements s[i:j] from s, returning the modified slice. +// Delete panics if s[i:j] is not a valid slice of s. +// Delete modifies the contents of the slice s; it does not create a new slice. +// Delete is O(len(s)-j), so if many items must be deleted, it is better to +// make a single call deleting them all together than to delete one at a time. +// Delete might not modify the elements s[len(s)-(j-i):len(s)]. If those +// elements contain pointers you might consider zeroing those elements so that +// objects they reference can be garbage collected. +func Delete[S ~[]E, E any](s S, i, j int) S { + _ = s[i:j] // bounds check + + return append(s[:i], s[j:]...) +} + +// Replace replaces the elements s[i:j] by the given v, and returns the +// modified slice. Replace panics if s[i:j] is not a valid slice of s. +func Replace[S ~[]E, E any](s S, i, j int, v ...E) S { + _ = s[i:j] // verify that i:j is a valid subslice + tot := len(s[:i]) + len(v) + len(s[j:]) + if tot <= cap(s) { + s2 := s[:tot] + copy(s2[i+len(v):], s[j:]) + copy(s2[i:], v) + return s2 + } + s2 := make(S, tot) + copy(s2, s[:i]) + copy(s2[i:], v) + copy(s2[i+len(v):], s[j:]) + return s2 +} + +// Clone returns a copy of the slice. +// The elements are copied using assignment, so this is a shallow clone. +func Clone[S ~[]E, E any](s S) S { + // Preserve nil in case it matters. + if s == nil { + return nil + } + return append(S([]E{}), s...) +} + +// Compact replaces consecutive runs of equal elements with a single copy. +// This is like the uniq command found on Unix. +// Compact modifies the contents of the slice s; it does not create a new slice. +// When Compact discards m elements in total, it might not modify the elements +// s[len(s)-m:len(s)]. If those elements contain pointers you might consider +// zeroing those elements so that objects they reference can be garbage collected. +func Compact[S ~[]E, E comparable](s S) S { + if len(s) < 2 { + return s + } + i := 1 + last := s[0] + for _, v := range s[1:] { + if v != last { + s[i] = v + i++ + last = v + } + } + return s[:i] +} + +// CompactFunc is like Compact but uses a comparison function. +func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S { + if len(s) < 2 { + return s + } + i := 1 + last := s[0] + for _, v := range s[1:] { + if !eq(v, last) { + s[i] = v + i++ + last = v + } + } + return s[:i] +} + +// Grow increases the slice's capacity, if necessary, to guarantee space for +// another n elements. After Grow(n), at least n elements can be appended +// to the slice without another allocation. If n is negative or too large to +// allocate the memory, Grow panics. +func Grow[S ~[]E, E any](s S, n int) S { + if n < 0 { + panic("cannot be negative") + } + if n -= cap(s) - len(s); n > 0 { + // TODO(https://go.dev/issue/53888): Make using []E instead of S + // to workaround a compiler bug where the runtime.growslice optimization + // does not take effect. Revert when the compiler is fixed. + s = append([]E(s)[:cap(s)], make([]E, n)...)[:len(s)] + } + return s +} + +// Clip removes unused capacity from the slice, returning s[:len(s):len(s)]. +func Clip[S ~[]E, E any](s S) S { + return s[:len(s):len(s)] +} diff --git a/vendor/golang.org/x/exp/slices/sort.go b/vendor/golang.org/x/exp/slices/sort.go new file mode 100644 index 0000000000..f14f40da71 --- /dev/null +++ b/vendor/golang.org/x/exp/slices/sort.go @@ -0,0 +1,126 @@ +// Copyright 2022 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 slices + +import ( + "math/bits" + + "golang.org/x/exp/constraints" +) + +// Sort sorts a slice of any ordered type in ascending order. +// Sort may fail to sort correctly when sorting slices of floating-point +// numbers containing Not-a-number (NaN) values. +// Use slices.SortFunc(x, func(a, b float64) bool {return a < b || (math.IsNaN(a) && !math.IsNaN(b))}) +// instead if the input may contain NaNs. +func Sort[E constraints.Ordered](x []E) { + n := len(x) + pdqsortOrdered(x, 0, n, bits.Len(uint(n))) +} + +// SortFunc sorts the slice x in ascending order as determined by the less function. +// This sort is not guaranteed to be stable. +// +// SortFunc requires that less is a strict weak ordering. +// See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings. +func SortFunc[E any](x []E, less func(a, b E) bool) { + n := len(x) + pdqsortLessFunc(x, 0, n, bits.Len(uint(n)), less) +} + +// SortStableFunc sorts the slice x while keeping the original order of equal +// elements, using less to compare elements. +func SortStableFunc[E any](x []E, less func(a, b E) bool) { + stableLessFunc(x, len(x), less) +} + +// IsSorted reports whether x is sorted in ascending order. +func IsSorted[E constraints.Ordered](x []E) bool { + for i := len(x) - 1; i > 0; i-- { + if x[i] < x[i-1] { + return false + } + } + return true +} + +// IsSortedFunc reports whether x is sorted in ascending order, with less as the +// comparison function. +func IsSortedFunc[E any](x []E, less func(a, b E) bool) bool { + for i := len(x) - 1; i > 0; i-- { + if less(x[i], x[i-1]) { + return false + } + } + return true +} + +// BinarySearch searches for target in a sorted slice and returns the position +// where target is found, or the position where target would appear in the +// sort order; it also returns a bool saying whether the target is really found +// in the slice. The slice must be sorted in increasing order. +func BinarySearch[E constraints.Ordered](x []E, target E) (int, bool) { + // Inlining is faster than calling BinarySearchFunc with a lambda. + n := len(x) + // Define x[-1] < target and x[n] >= target. + // Invariant: x[i-1] < target, x[j] >= target. + i, j := 0, n + for i < j { + h := int(uint(i+j) >> 1) // avoid overflow when computing h + // i ≤ h < j + if x[h] < target { + i = h + 1 // preserves x[i-1] < target + } else { + j = h // preserves x[j] >= target + } + } + // i == j, x[i-1] < target, and x[j] (= x[i]) >= target => answer is i. + return i, i < n && x[i] == target +} + +// BinarySearchFunc works like BinarySearch, but uses a custom comparison +// function. The slice must be sorted in increasing order, where "increasing" is +// defined by cmp. cmp(a, b) is expected to return an integer comparing the two +// parameters: 0 if a == b, a negative number if a < b and a positive number if +// a > b. +func BinarySearchFunc[E, T any](x []E, target T, cmp func(E, T) int) (int, bool) { + n := len(x) + // Define cmp(x[-1], target) < 0 and cmp(x[n], target) >= 0 . + // Invariant: cmp(x[i - 1], target) < 0, cmp(x[j], target) >= 0. + i, j := 0, n + for i < j { + h := int(uint(i+j) >> 1) // avoid overflow when computing h + // i ≤ h < j + if cmp(x[h], target) < 0 { + i = h + 1 // preserves cmp(x[i - 1], target) < 0 + } else { + j = h // preserves cmp(x[j], target) >= 0 + } + } + // i == j, cmp(x[i-1], target) < 0, and cmp(x[j], target) (= cmp(x[i], target)) >= 0 => answer is i. + return i, i < n && cmp(x[i], target) == 0 +} + +type sortedHint int // hint for pdqsort when choosing the pivot + +const ( + unknownHint sortedHint = iota + increasingHint + decreasingHint +) + +// xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf +type xorshift uint64 + +func (r *xorshift) Next() uint64 { + *r ^= *r << 13 + *r ^= *r >> 17 + *r ^= *r << 5 + return uint64(*r) +} + +func nextPowerOfTwo(length int) uint { + return 1 << bits.Len(uint(length)) +} diff --git a/vendor/golang.org/x/exp/slices/zsortfunc.go b/vendor/golang.org/x/exp/slices/zsortfunc.go new file mode 100644 index 0000000000..2a632476c5 --- /dev/null +++ b/vendor/golang.org/x/exp/slices/zsortfunc.go @@ -0,0 +1,479 @@ +// Code generated by gen_sort_variants.go; DO NOT EDIT. + +// Copyright 2022 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 slices + +// insertionSortLessFunc sorts data[a:b] using insertion sort. +func insertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) { + for i := a + 1; i < b; i++ { + for j := i; j > a && less(data[j], data[j-1]); j-- { + data[j], data[j-1] = data[j-1], data[j] + } + } +} + +// siftDownLessFunc implements the heap property on data[lo:hi]. +// first is an offset into the array where the root of the heap lies. +func siftDownLessFunc[E any](data []E, lo, hi, first int, less func(a, b E) bool) { + root := lo + for { + child := 2*root + 1 + if child >= hi { + break + } + if child+1 < hi && less(data[first+child], data[first+child+1]) { + child++ + } + if !less(data[first+root], data[first+child]) { + return + } + data[first+root], data[first+child] = data[first+child], data[first+root] + root = child + } +} + +func heapSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) { + first := a + lo := 0 + hi := b - a + + // Build heap with greatest element at top. + for i := (hi - 1) / 2; i >= 0; i-- { + siftDownLessFunc(data, i, hi, first, less) + } + + // Pop elements, largest first, into end of data. + for i := hi - 1; i >= 0; i-- { + data[first], data[first+i] = data[first+i], data[first] + siftDownLessFunc(data, lo, i, first, less) + } +} + +// pdqsortLessFunc sorts data[a:b]. +// The algorithm based on pattern-defeating quicksort(pdqsort), but without the optimizations from BlockQuicksort. +// pdqsort paper: https://arxiv.org/pdf/2106.05123.pdf +// C++ implementation: https://github.com/orlp/pdqsort +// Rust implementation: https://docs.rs/pdqsort/latest/pdqsort/ +// limit is the number of allowed bad (very unbalanced) pivots before falling back to heapsort. +func pdqsortLessFunc[E any](data []E, a, b, limit int, less func(a, b E) bool) { + const maxInsertion = 12 + + var ( + wasBalanced = true // whether the last partitioning was reasonably balanced + wasPartitioned = true // whether the slice was already partitioned + ) + + for { + length := b - a + + if length <= maxInsertion { + insertionSortLessFunc(data, a, b, less) + return + } + + // Fall back to heapsort if too many bad choices were made. + if limit == 0 { + heapSortLessFunc(data, a, b, less) + return + } + + // If the last partitioning was imbalanced, we need to breaking patterns. + if !wasBalanced { + breakPatternsLessFunc(data, a, b, less) + limit-- + } + + pivot, hint := choosePivotLessFunc(data, a, b, less) + if hint == decreasingHint { + reverseRangeLessFunc(data, a, b, less) + // The chosen pivot was pivot-a elements after the start of the array. + // After reversing it is pivot-a elements before the end of the array. + // The idea came from Rust's implementation. + pivot = (b - 1) - (pivot - a) + hint = increasingHint + } + + // The slice is likely already sorted. + if wasBalanced && wasPartitioned && hint == increasingHint { + if partialInsertionSortLessFunc(data, a, b, less) { + return + } + } + + // Probably the slice contains many duplicate elements, partition the slice into + // elements equal to and elements greater than the pivot. + if a > 0 && !less(data[a-1], data[pivot]) { + mid := partitionEqualLessFunc(data, a, b, pivot, less) + a = mid + continue + } + + mid, alreadyPartitioned := partitionLessFunc(data, a, b, pivot, less) + wasPartitioned = alreadyPartitioned + + leftLen, rightLen := mid-a, b-mid + balanceThreshold := length / 8 + if leftLen < rightLen { + wasBalanced = leftLen >= balanceThreshold + pdqsortLessFunc(data, a, mid, limit, less) + a = mid + 1 + } else { + wasBalanced = rightLen >= balanceThreshold + pdqsortLessFunc(data, mid+1, b, limit, less) + b = mid + } + } +} + +// partitionLessFunc does one quicksort partition. +// Let p = data[pivot] +// Moves elements in data[a:b] around, so that data[i]

=p for inewpivot. +// On return, data[newpivot] = p +func partitionLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool) (newpivot int, alreadyPartitioned bool) { + data[a], data[pivot] = data[pivot], data[a] + i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned + + for i <= j && less(data[i], data[a]) { + i++ + } + for i <= j && !less(data[j], data[a]) { + j-- + } + if i > j { + data[j], data[a] = data[a], data[j] + return j, true + } + data[i], data[j] = data[j], data[i] + i++ + j-- + + for { + for i <= j && less(data[i], data[a]) { + i++ + } + for i <= j && !less(data[j], data[a]) { + j-- + } + if i > j { + break + } + data[i], data[j] = data[j], data[i] + i++ + j-- + } + data[j], data[a] = data[a], data[j] + return j, false +} + +// partitionEqualLessFunc partitions data[a:b] into elements equal to data[pivot] followed by elements greater than data[pivot]. +// It assumed that data[a:b] does not contain elements smaller than the data[pivot]. +func partitionEqualLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool) (newpivot int) { + data[a], data[pivot] = data[pivot], data[a] + i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned + + for { + for i <= j && !less(data[a], data[i]) { + i++ + } + for i <= j && less(data[a], data[j]) { + j-- + } + if i > j { + break + } + data[i], data[j] = data[j], data[i] + i++ + j-- + } + return i +} + +// partialInsertionSortLessFunc partially sorts a slice, returns true if the slice is sorted at the end. +func partialInsertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) bool { + const ( + maxSteps = 5 // maximum number of adjacent out-of-order pairs that will get shifted + shortestShifting = 50 // don't shift any elements on short arrays + ) + i := a + 1 + for j := 0; j < maxSteps; j++ { + for i < b && !less(data[i], data[i-1]) { + i++ + } + + if i == b { + return true + } + + if b-a < shortestShifting { + return false + } + + data[i], data[i-1] = data[i-1], data[i] + + // Shift the smaller one to the left. + if i-a >= 2 { + for j := i - 1; j >= 1; j-- { + if !less(data[j], data[j-1]) { + break + } + data[j], data[j-1] = data[j-1], data[j] + } + } + // Shift the greater one to the right. + if b-i >= 2 { + for j := i + 1; j < b; j++ { + if !less(data[j], data[j-1]) { + break + } + data[j], data[j-1] = data[j-1], data[j] + } + } + } + return false +} + +// breakPatternsLessFunc scatters some elements around in an attempt to break some patterns +// that might cause imbalanced partitions in quicksort. +func breakPatternsLessFunc[E any](data []E, a, b int, less func(a, b E) bool) { + length := b - a + if length >= 8 { + random := xorshift(length) + modulus := nextPowerOfTwo(length) + + for idx := a + (length/4)*2 - 1; idx <= a+(length/4)*2+1; idx++ { + other := int(uint(random.Next()) & (modulus - 1)) + if other >= length { + other -= length + } + data[idx], data[a+other] = data[a+other], data[idx] + } + } +} + +// choosePivotLessFunc chooses a pivot in data[a:b]. +// +// [0,8): chooses a static pivot. +// [8,shortestNinther): uses the simple median-of-three method. +// [shortestNinther,∞): uses the Tukey ninther method. +func choosePivotLessFunc[E any](data []E, a, b int, less func(a, b E) bool) (pivot int, hint sortedHint) { + const ( + shortestNinther = 50 + maxSwaps = 4 * 3 + ) + + l := b - a + + var ( + swaps int + i = a + l/4*1 + j = a + l/4*2 + k = a + l/4*3 + ) + + if l >= 8 { + if l >= shortestNinther { + // Tukey ninther method, the idea came from Rust's implementation. + i = medianAdjacentLessFunc(data, i, &swaps, less) + j = medianAdjacentLessFunc(data, j, &swaps, less) + k = medianAdjacentLessFunc(data, k, &swaps, less) + } + // Find the median among i, j, k and stores it into j. + j = medianLessFunc(data, i, j, k, &swaps, less) + } + + switch swaps { + case 0: + return j, increasingHint + case maxSwaps: + return j, decreasingHint + default: + return j, unknownHint + } +} + +// order2LessFunc returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a. +func order2LessFunc[E any](data []E, a, b int, swaps *int, less func(a, b E) bool) (int, int) { + if less(data[b], data[a]) { + *swaps++ + return b, a + } + return a, b +} + +// medianLessFunc returns x where data[x] is the median of data[a],data[b],data[c], where x is a, b, or c. +func medianLessFunc[E any](data []E, a, b, c int, swaps *int, less func(a, b E) bool) int { + a, b = order2LessFunc(data, a, b, swaps, less) + b, c = order2LessFunc(data, b, c, swaps, less) + a, b = order2LessFunc(data, a, b, swaps, less) + return b +} + +// medianAdjacentLessFunc finds the median of data[a - 1], data[a], data[a + 1] and stores the index into a. +func medianAdjacentLessFunc[E any](data []E, a int, swaps *int, less func(a, b E) bool) int { + return medianLessFunc(data, a-1, a, a+1, swaps, less) +} + +func reverseRangeLessFunc[E any](data []E, a, b int, less func(a, b E) bool) { + i := a + j := b - 1 + for i < j { + data[i], data[j] = data[j], data[i] + i++ + j-- + } +} + +func swapRangeLessFunc[E any](data []E, a, b, n int, less func(a, b E) bool) { + for i := 0; i < n; i++ { + data[a+i], data[b+i] = data[b+i], data[a+i] + } +} + +func stableLessFunc[E any](data []E, n int, less func(a, b E) bool) { + blockSize := 20 // must be > 0 + a, b := 0, blockSize + for b <= n { + insertionSortLessFunc(data, a, b, less) + a = b + b += blockSize + } + insertionSortLessFunc(data, a, n, less) + + for blockSize < n { + a, b = 0, 2*blockSize + for b <= n { + symMergeLessFunc(data, a, a+blockSize, b, less) + a = b + b += 2 * blockSize + } + if m := a + blockSize; m < n { + symMergeLessFunc(data, a, m, n, less) + } + blockSize *= 2 + } +} + +// symMergeLessFunc merges the two sorted subsequences data[a:m] and data[m:b] using +// the SymMerge algorithm from Pok-Son Kim and Arne Kutzner, "Stable Minimum +// Storage Merging by Symmetric Comparisons", in Susanne Albers and Tomasz +// Radzik, editors, Algorithms - ESA 2004, volume 3221 of Lecture Notes in +// Computer Science, pages 714-723. Springer, 2004. +// +// Let M = m-a and N = b-n. Wolog M < N. +// The recursion depth is bound by ceil(log(N+M)). +// The algorithm needs O(M*log(N/M + 1)) calls to data.Less. +// The algorithm needs O((M+N)*log(M)) calls to data.Swap. +// +// The paper gives O((M+N)*log(M)) as the number of assignments assuming a +// rotation algorithm which uses O(M+N+gcd(M+N)) assignments. The argumentation +// in the paper carries through for Swap operations, especially as the block +// swapping rotate uses only O(M+N) Swaps. +// +// symMerge assumes non-degenerate arguments: a < m && m < b. +// Having the caller check this condition eliminates many leaf recursion calls, +// which improves performance. +func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) { + // Avoid unnecessary recursions of symMerge + // by direct insertion of data[a] into data[m:b] + // if data[a:m] only contains one element. + if m-a == 1 { + // Use binary search to find the lowest index i + // such that data[i] >= data[a] for m <= i < b. + // Exit the search loop with i == b in case no such index exists. + i := m + j := b + for i < j { + h := int(uint(i+j) >> 1) + if less(data[h], data[a]) { + i = h + 1 + } else { + j = h + } + } + // Swap values until data[a] reaches the position before i. + for k := a; k < i-1; k++ { + data[k], data[k+1] = data[k+1], data[k] + } + return + } + + // Avoid unnecessary recursions of symMerge + // by direct insertion of data[m] into data[a:m] + // if data[m:b] only contains one element. + if b-m == 1 { + // Use binary search to find the lowest index i + // such that data[i] > data[m] for a <= i < m. + // Exit the search loop with i == m in case no such index exists. + i := a + j := m + for i < j { + h := int(uint(i+j) >> 1) + if !less(data[m], data[h]) { + i = h + 1 + } else { + j = h + } + } + // Swap values until data[m] reaches the position i. + for k := m; k > i; k-- { + data[k], data[k-1] = data[k-1], data[k] + } + return + } + + mid := int(uint(a+b) >> 1) + n := mid + m + var start, r int + if m > mid { + start = n - b + r = mid + } else { + start = a + r = m + } + p := n - 1 + + for start < r { + c := int(uint(start+r) >> 1) + if !less(data[p-c], data[c]) { + start = c + 1 + } else { + r = c + } + } + + end := n - start + if start < m && m < end { + rotateLessFunc(data, start, m, end, less) + } + if a < start && start < mid { + symMergeLessFunc(data, a, start, mid, less) + } + if mid < end && end < b { + symMergeLessFunc(data, mid, end, b, less) + } +} + +// rotateLessFunc rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data: +// Data of the form 'x u v y' is changed to 'x v u y'. +// rotate performs at most b-a many calls to data.Swap, +// and it assumes non-degenerate arguments: a < m && m < b. +func rotateLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) { + i := m - a + j := b - m + + for i != j { + if i > j { + swapRangeLessFunc(data, m-i, m, j, less) + i -= j + } else { + swapRangeLessFunc(data, m-i, m+j-i, i, less) + j -= i + } + } + // i == j + swapRangeLessFunc(data, m-i, m, i, less) +} diff --git a/vendor/golang.org/x/exp/slices/zsortordered.go b/vendor/golang.org/x/exp/slices/zsortordered.go new file mode 100644 index 0000000000..efaa1c8b71 --- /dev/null +++ b/vendor/golang.org/x/exp/slices/zsortordered.go @@ -0,0 +1,481 @@ +// Code generated by gen_sort_variants.go; DO NOT EDIT. + +// Copyright 2022 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 slices + +import "golang.org/x/exp/constraints" + +// insertionSortOrdered sorts data[a:b] using insertion sort. +func insertionSortOrdered[E constraints.Ordered](data []E, a, b int) { + for i := a + 1; i < b; i++ { + for j := i; j > a && (data[j] < data[j-1]); j-- { + data[j], data[j-1] = data[j-1], data[j] + } + } +} + +// siftDownOrdered implements the heap property on data[lo:hi]. +// first is an offset into the array where the root of the heap lies. +func siftDownOrdered[E constraints.Ordered](data []E, lo, hi, first int) { + root := lo + for { + child := 2*root + 1 + if child >= hi { + break + } + if child+1 < hi && (data[first+child] < data[first+child+1]) { + child++ + } + if !(data[first+root] < data[first+child]) { + return + } + data[first+root], data[first+child] = data[first+child], data[first+root] + root = child + } +} + +func heapSortOrdered[E constraints.Ordered](data []E, a, b int) { + first := a + lo := 0 + hi := b - a + + // Build heap with greatest element at top. + for i := (hi - 1) / 2; i >= 0; i-- { + siftDownOrdered(data, i, hi, first) + } + + // Pop elements, largest first, into end of data. + for i := hi - 1; i >= 0; i-- { + data[first], data[first+i] = data[first+i], data[first] + siftDownOrdered(data, lo, i, first) + } +} + +// pdqsortOrdered sorts data[a:b]. +// The algorithm based on pattern-defeating quicksort(pdqsort), but without the optimizations from BlockQuicksort. +// pdqsort paper: https://arxiv.org/pdf/2106.05123.pdf +// C++ implementation: https://github.com/orlp/pdqsort +// Rust implementation: https://docs.rs/pdqsort/latest/pdqsort/ +// limit is the number of allowed bad (very unbalanced) pivots before falling back to heapsort. +func pdqsortOrdered[E constraints.Ordered](data []E, a, b, limit int) { + const maxInsertion = 12 + + var ( + wasBalanced = true // whether the last partitioning was reasonably balanced + wasPartitioned = true // whether the slice was already partitioned + ) + + for { + length := b - a + + if length <= maxInsertion { + insertionSortOrdered(data, a, b) + return + } + + // Fall back to heapsort if too many bad choices were made. + if limit == 0 { + heapSortOrdered(data, a, b) + return + } + + // If the last partitioning was imbalanced, we need to breaking patterns. + if !wasBalanced { + breakPatternsOrdered(data, a, b) + limit-- + } + + pivot, hint := choosePivotOrdered(data, a, b) + if hint == decreasingHint { + reverseRangeOrdered(data, a, b) + // The chosen pivot was pivot-a elements after the start of the array. + // After reversing it is pivot-a elements before the end of the array. + // The idea came from Rust's implementation. + pivot = (b - 1) - (pivot - a) + hint = increasingHint + } + + // The slice is likely already sorted. + if wasBalanced && wasPartitioned && hint == increasingHint { + if partialInsertionSortOrdered(data, a, b) { + return + } + } + + // Probably the slice contains many duplicate elements, partition the slice into + // elements equal to and elements greater than the pivot. + if a > 0 && !(data[a-1] < data[pivot]) { + mid := partitionEqualOrdered(data, a, b, pivot) + a = mid + continue + } + + mid, alreadyPartitioned := partitionOrdered(data, a, b, pivot) + wasPartitioned = alreadyPartitioned + + leftLen, rightLen := mid-a, b-mid + balanceThreshold := length / 8 + if leftLen < rightLen { + wasBalanced = leftLen >= balanceThreshold + pdqsortOrdered(data, a, mid, limit) + a = mid + 1 + } else { + wasBalanced = rightLen >= balanceThreshold + pdqsortOrdered(data, mid+1, b, limit) + b = mid + } + } +} + +// partitionOrdered does one quicksort partition. +// Let p = data[pivot] +// Moves elements in data[a:b] around, so that data[i]

=p for inewpivot. +// On return, data[newpivot] = p +func partitionOrdered[E constraints.Ordered](data []E, a, b, pivot int) (newpivot int, alreadyPartitioned bool) { + data[a], data[pivot] = data[pivot], data[a] + i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned + + for i <= j && (data[i] < data[a]) { + i++ + } + for i <= j && !(data[j] < data[a]) { + j-- + } + if i > j { + data[j], data[a] = data[a], data[j] + return j, true + } + data[i], data[j] = data[j], data[i] + i++ + j-- + + for { + for i <= j && (data[i] < data[a]) { + i++ + } + for i <= j && !(data[j] < data[a]) { + j-- + } + if i > j { + break + } + data[i], data[j] = data[j], data[i] + i++ + j-- + } + data[j], data[a] = data[a], data[j] + return j, false +} + +// partitionEqualOrdered partitions data[a:b] into elements equal to data[pivot] followed by elements greater than data[pivot]. +// It assumed that data[a:b] does not contain elements smaller than the data[pivot]. +func partitionEqualOrdered[E constraints.Ordered](data []E, a, b, pivot int) (newpivot int) { + data[a], data[pivot] = data[pivot], data[a] + i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned + + for { + for i <= j && !(data[a] < data[i]) { + i++ + } + for i <= j && (data[a] < data[j]) { + j-- + } + if i > j { + break + } + data[i], data[j] = data[j], data[i] + i++ + j-- + } + return i +} + +// partialInsertionSortOrdered partially sorts a slice, returns true if the slice is sorted at the end. +func partialInsertionSortOrdered[E constraints.Ordered](data []E, a, b int) bool { + const ( + maxSteps = 5 // maximum number of adjacent out-of-order pairs that will get shifted + shortestShifting = 50 // don't shift any elements on short arrays + ) + i := a + 1 + for j := 0; j < maxSteps; j++ { + for i < b && !(data[i] < data[i-1]) { + i++ + } + + if i == b { + return true + } + + if b-a < shortestShifting { + return false + } + + data[i], data[i-1] = data[i-1], data[i] + + // Shift the smaller one to the left. + if i-a >= 2 { + for j := i - 1; j >= 1; j-- { + if !(data[j] < data[j-1]) { + break + } + data[j], data[j-1] = data[j-1], data[j] + } + } + // Shift the greater one to the right. + if b-i >= 2 { + for j := i + 1; j < b; j++ { + if !(data[j] < data[j-1]) { + break + } + data[j], data[j-1] = data[j-1], data[j] + } + } + } + return false +} + +// breakPatternsOrdered scatters some elements around in an attempt to break some patterns +// that might cause imbalanced partitions in quicksort. +func breakPatternsOrdered[E constraints.Ordered](data []E, a, b int) { + length := b - a + if length >= 8 { + random := xorshift(length) + modulus := nextPowerOfTwo(length) + + for idx := a + (length/4)*2 - 1; idx <= a+(length/4)*2+1; idx++ { + other := int(uint(random.Next()) & (modulus - 1)) + if other >= length { + other -= length + } + data[idx], data[a+other] = data[a+other], data[idx] + } + } +} + +// choosePivotOrdered chooses a pivot in data[a:b]. +// +// [0,8): chooses a static pivot. +// [8,shortestNinther): uses the simple median-of-three method. +// [shortestNinther,∞): uses the Tukey ninther method. +func choosePivotOrdered[E constraints.Ordered](data []E, a, b int) (pivot int, hint sortedHint) { + const ( + shortestNinther = 50 + maxSwaps = 4 * 3 + ) + + l := b - a + + var ( + swaps int + i = a + l/4*1 + j = a + l/4*2 + k = a + l/4*3 + ) + + if l >= 8 { + if l >= shortestNinther { + // Tukey ninther method, the idea came from Rust's implementation. + i = medianAdjacentOrdered(data, i, &swaps) + j = medianAdjacentOrdered(data, j, &swaps) + k = medianAdjacentOrdered(data, k, &swaps) + } + // Find the median among i, j, k and stores it into j. + j = medianOrdered(data, i, j, k, &swaps) + } + + switch swaps { + case 0: + return j, increasingHint + case maxSwaps: + return j, decreasingHint + default: + return j, unknownHint + } +} + +// order2Ordered returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a. +func order2Ordered[E constraints.Ordered](data []E, a, b int, swaps *int) (int, int) { + if data[b] < data[a] { + *swaps++ + return b, a + } + return a, b +} + +// medianOrdered returns x where data[x] is the median of data[a],data[b],data[c], where x is a, b, or c. +func medianOrdered[E constraints.Ordered](data []E, a, b, c int, swaps *int) int { + a, b = order2Ordered(data, a, b, swaps) + b, c = order2Ordered(data, b, c, swaps) + a, b = order2Ordered(data, a, b, swaps) + return b +} + +// medianAdjacentOrdered finds the median of data[a - 1], data[a], data[a + 1] and stores the index into a. +func medianAdjacentOrdered[E constraints.Ordered](data []E, a int, swaps *int) int { + return medianOrdered(data, a-1, a, a+1, swaps) +} + +func reverseRangeOrdered[E constraints.Ordered](data []E, a, b int) { + i := a + j := b - 1 + for i < j { + data[i], data[j] = data[j], data[i] + i++ + j-- + } +} + +func swapRangeOrdered[E constraints.Ordered](data []E, a, b, n int) { + for i := 0; i < n; i++ { + data[a+i], data[b+i] = data[b+i], data[a+i] + } +} + +func stableOrdered[E constraints.Ordered](data []E, n int) { + blockSize := 20 // must be > 0 + a, b := 0, blockSize + for b <= n { + insertionSortOrdered(data, a, b) + a = b + b += blockSize + } + insertionSortOrdered(data, a, n) + + for blockSize < n { + a, b = 0, 2*blockSize + for b <= n { + symMergeOrdered(data, a, a+blockSize, b) + a = b + b += 2 * blockSize + } + if m := a + blockSize; m < n { + symMergeOrdered(data, a, m, n) + } + blockSize *= 2 + } +} + +// symMergeOrdered merges the two sorted subsequences data[a:m] and data[m:b] using +// the SymMerge algorithm from Pok-Son Kim and Arne Kutzner, "Stable Minimum +// Storage Merging by Symmetric Comparisons", in Susanne Albers and Tomasz +// Radzik, editors, Algorithms - ESA 2004, volume 3221 of Lecture Notes in +// Computer Science, pages 714-723. Springer, 2004. +// +// Let M = m-a and N = b-n. Wolog M < N. +// The recursion depth is bound by ceil(log(N+M)). +// The algorithm needs O(M*log(N/M + 1)) calls to data.Less. +// The algorithm needs O((M+N)*log(M)) calls to data.Swap. +// +// The paper gives O((M+N)*log(M)) as the number of assignments assuming a +// rotation algorithm which uses O(M+N+gcd(M+N)) assignments. The argumentation +// in the paper carries through for Swap operations, especially as the block +// swapping rotate uses only O(M+N) Swaps. +// +// symMerge assumes non-degenerate arguments: a < m && m < b. +// Having the caller check this condition eliminates many leaf recursion calls, +// which improves performance. +func symMergeOrdered[E constraints.Ordered](data []E, a, m, b int) { + // Avoid unnecessary recursions of symMerge + // by direct insertion of data[a] into data[m:b] + // if data[a:m] only contains one element. + if m-a == 1 { + // Use binary search to find the lowest index i + // such that data[i] >= data[a] for m <= i < b. + // Exit the search loop with i == b in case no such index exists. + i := m + j := b + for i < j { + h := int(uint(i+j) >> 1) + if data[h] < data[a] { + i = h + 1 + } else { + j = h + } + } + // Swap values until data[a] reaches the position before i. + for k := a; k < i-1; k++ { + data[k], data[k+1] = data[k+1], data[k] + } + return + } + + // Avoid unnecessary recursions of symMerge + // by direct insertion of data[m] into data[a:m] + // if data[m:b] only contains one element. + if b-m == 1 { + // Use binary search to find the lowest index i + // such that data[i] > data[m] for a <= i < m. + // Exit the search loop with i == m in case no such index exists. + i := a + j := m + for i < j { + h := int(uint(i+j) >> 1) + if !(data[m] < data[h]) { + i = h + 1 + } else { + j = h + } + } + // Swap values until data[m] reaches the position i. + for k := m; k > i; k-- { + data[k], data[k-1] = data[k-1], data[k] + } + return + } + + mid := int(uint(a+b) >> 1) + n := mid + m + var start, r int + if m > mid { + start = n - b + r = mid + } else { + start = a + r = m + } + p := n - 1 + + for start < r { + c := int(uint(start+r) >> 1) + if !(data[p-c] < data[c]) { + start = c + 1 + } else { + r = c + } + } + + end := n - start + if start < m && m < end { + rotateOrdered(data, start, m, end) + } + if a < start && start < mid { + symMergeOrdered(data, a, start, mid) + } + if mid < end && end < b { + symMergeOrdered(data, mid, end, b) + } +} + +// rotateOrdered rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data: +// Data of the form 'x u v y' is changed to 'x v u y'. +// rotate performs at most b-a many calls to data.Swap, +// and it assumes non-degenerate arguments: a < m && m < b. +func rotateOrdered[E constraints.Ordered](data []E, a, m, b int) { + i := m - a + j := b - m + + for i != j { + if i > j { + swapRangeOrdered(data, m-i, m, j) + i -= j + } else { + swapRangeOrdered(data, m-i, m+j-i, i) + j -= i + } + } + // i == j + swapRangeOrdered(data, m-i, m, i) +} diff --git a/vendor/golang.org/x/sys/execabs/execabs.go b/vendor/golang.org/x/sys/execabs/execabs.go index b981cfbb4a..3bf40fdfec 100644 --- a/vendor/golang.org/x/sys/execabs/execabs.go +++ b/vendor/golang.org/x/sys/execabs/execabs.go @@ -63,7 +63,7 @@ func LookPath(file string) (string, error) { } func fixCmd(name string, cmd *exec.Cmd) { - if filepath.Base(name) == name && !filepath.IsAbs(cmd.Path) { + if filepath.Base(name) == name && !filepath.IsAbs(cmd.Path) && !isGo119ErrFieldSet(cmd) { // exec.Command was called with a bare binary name and // exec.LookPath returned a path which is not absolute. // Set cmd.lookPathErr and clear cmd.Path so that it diff --git a/vendor/golang.org/x/sys/execabs/execabs_go118.go b/vendor/golang.org/x/sys/execabs/execabs_go118.go index 6ab5f50894..2000064a81 100644 --- a/vendor/golang.org/x/sys/execabs/execabs_go118.go +++ b/vendor/golang.org/x/sys/execabs/execabs_go118.go @@ -7,6 +7,12 @@ package execabs +import "os/exec" + func isGo119ErrDot(err error) bool { return false } + +func isGo119ErrFieldSet(cmd *exec.Cmd) bool { + return false +} diff --git a/vendor/golang.org/x/sys/execabs/execabs_go119.go b/vendor/golang.org/x/sys/execabs/execabs_go119.go index 1e7a9ada0b..f364b34189 100644 --- a/vendor/golang.org/x/sys/execabs/execabs_go119.go +++ b/vendor/golang.org/x/sys/execabs/execabs_go119.go @@ -7,9 +7,15 @@ package execabs -import "strings" +import ( + "errors" + "os/exec" +) func isGo119ErrDot(err error) bool { - // TODO: return errors.Is(err, exec.ErrDot) - return strings.Contains(err.Error(), "current directory") + return errors.Is(err, exec.ErrDot) +} + +func isGo119ErrFieldSet(cmd *exec.Cmd) bool { + return cmd.Err != nil } diff --git a/vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s b/vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s new file mode 100644 index 0000000000..e5b9a84899 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s @@ -0,0 +1,31 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build (darwin || freebsd || netbsd || openbsd) && gc +// +build darwin freebsd netbsd openbsd +// +build gc + +#include "textflag.h" + +// +// System call support for ppc64, BSD +// + +// Just jump to package syscall's implementation for all these functions. +// The runtime may know about them. + +TEXT ·Syscall(SB),NOSPLIT,$0-56 + JMP syscall·Syscall(SB) + +TEXT ·Syscall6(SB),NOSPLIT,$0-80 + JMP syscall·Syscall6(SB) + +TEXT ·Syscall9(SB),NOSPLIT,$0-104 + JMP syscall·Syscall9(SB) + +TEXT ·RawSyscall(SB),NOSPLIT,$0-56 + JMP syscall·RawSyscall(SB) + +TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 + JMP syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/dirent.go b/vendor/golang.org/x/sys/unix/dirent.go index e74e5eaa3b..2499f977b0 100644 --- a/vendor/golang.org/x/sys/unix/dirent.go +++ b/vendor/golang.org/x/sys/unix/dirent.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris -// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris +//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos package unix diff --git a/vendor/golang.org/x/sys/unix/gccgo.go b/vendor/golang.org/x/sys/unix/gccgo.go index 0dee23222c..b06f52d748 100644 --- a/vendor/golang.org/x/sys/unix/gccgo.go +++ b/vendor/golang.org/x/sys/unix/gccgo.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build gccgo && !aix -// +build gccgo,!aix +//go:build gccgo && !aix && !hurd +// +build gccgo,!aix,!hurd package unix diff --git a/vendor/golang.org/x/sys/unix/gccgo_c.c b/vendor/golang.org/x/sys/unix/gccgo_c.c index 2cb1fefac6..f98a1c542f 100644 --- a/vendor/golang.org/x/sys/unix/gccgo_c.c +++ b/vendor/golang.org/x/sys/unix/gccgo_c.c @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build gccgo -// +build !aix +//go:build gccgo && !aix && !hurd +// +build gccgo,!aix,!hurd #include #include diff --git a/vendor/golang.org/x/sys/unix/ioctl.go b/vendor/golang.org/x/sys/unix/ioctl.go index 6c7ad052e6..7ce8dd406f 100644 --- a/vendor/golang.org/x/sys/unix/ioctl.go +++ b/vendor/golang.org/x/sys/unix/ioctl.go @@ -2,13 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris -// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris +//go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris +// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris package unix import ( - "runtime" "unsafe" ) @@ -27,7 +26,7 @@ func IoctlSetInt(fd int, req uint, value int) error { // passing the integer value directly. func IoctlSetPointerInt(fd int, req uint, value int) error { v := int32(value) - return ioctl(fd, req, uintptr(unsafe.Pointer(&v))) + return ioctlPtr(fd, req, unsafe.Pointer(&v)) } // IoctlSetWinsize performs an ioctl on fd with a *Winsize argument. @@ -36,9 +35,7 @@ func IoctlSetPointerInt(fd int, req uint, value int) error { func IoctlSetWinsize(fd int, req uint, value *Winsize) error { // TODO: if we get the chance, remove the req parameter and // hardcode TIOCSWINSZ. - err := ioctl(fd, req, uintptr(unsafe.Pointer(value))) - runtime.KeepAlive(value) - return err + return ioctlPtr(fd, req, unsafe.Pointer(value)) } // IoctlSetTermios performs an ioctl on fd with a *Termios. @@ -46,9 +43,7 @@ func IoctlSetWinsize(fd int, req uint, value *Winsize) error { // The req value will usually be TCSETA or TIOCSETA. func IoctlSetTermios(fd int, req uint, value *Termios) error { // TODO: if we get the chance, remove the req parameter. - err := ioctl(fd, req, uintptr(unsafe.Pointer(value))) - runtime.KeepAlive(value) - return err + return ioctlPtr(fd, req, unsafe.Pointer(value)) } // IoctlGetInt performs an ioctl operation which gets an integer value @@ -58,18 +53,18 @@ func IoctlSetTermios(fd int, req uint, value *Termios) error { // for those, IoctlRetInt should be used instead of this function. func IoctlGetInt(fd int, req uint) (int, error) { var value int - err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + err := ioctlPtr(fd, req, unsafe.Pointer(&value)) return value, err } func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { var value Winsize - err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + err := ioctlPtr(fd, req, unsafe.Pointer(&value)) return &value, err } func IoctlGetTermios(fd int, req uint) (*Termios, error) { var value Termios - err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + err := ioctlPtr(fd, req, unsafe.Pointer(&value)) return &value, err } diff --git a/vendor/golang.org/x/sys/unix/ioctl_zos.go b/vendor/golang.org/x/sys/unix/ioctl_zos.go index 5384e7d91d..6532f09af2 100644 --- a/vendor/golang.org/x/sys/unix/ioctl_zos.go +++ b/vendor/golang.org/x/sys/unix/ioctl_zos.go @@ -27,9 +27,7 @@ func IoctlSetInt(fd int, req uint, value int) error { func IoctlSetWinsize(fd int, req uint, value *Winsize) error { // TODO: if we get the chance, remove the req parameter and // hardcode TIOCSWINSZ. - err := ioctl(fd, req, uintptr(unsafe.Pointer(value))) - runtime.KeepAlive(value) - return err + return ioctlPtr(fd, req, unsafe.Pointer(value)) } // IoctlSetTermios performs an ioctl on fd with a *Termios. @@ -51,13 +49,13 @@ func IoctlSetTermios(fd int, req uint, value *Termios) error { // for those, IoctlRetInt should be used instead of this function. func IoctlGetInt(fd int, req uint) (int, error) { var value int - err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + err := ioctlPtr(fd, req, unsafe.Pointer(&value)) return value, err } func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { var value Winsize - err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + err := ioctlPtr(fd, req, unsafe.Pointer(&value)) return &value, err } diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh index 3b2335d5fc..8e3947c368 100644 --- a/vendor/golang.org/x/sys/unix/mkall.sh +++ b/vendor/golang.org/x/sys/unix/mkall.sh @@ -174,10 +174,28 @@ openbsd_arm64) mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" ;; openbsd_mips64) + mkasm="go run mkasm.go" + mkerrors="$mkerrors -m64" + mksyscall="go run mksyscall.go -openbsd -libc" + mksysctl="go run mksysctl_openbsd.go" + # Let the type of C char be signed for making the bare syscall + # API consistent across platforms. + mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" + ;; +openbsd_ppc64) + mkasm="go run mkasm.go" mkerrors="$mkerrors -m64" - mksyscall="go run mksyscall.go -openbsd" + mksyscall="go run mksyscall.go -openbsd -libc" + mksysctl="go run mksysctl_openbsd.go" + # Let the type of C char be signed for making the bare syscall + # API consistent across platforms. + mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" + ;; +openbsd_riscv64) + mkasm="go run mkasm.go" + mkerrors="$mkerrors -m64" + mksyscall="go run mksyscall.go -openbsd -libc" mksysctl="go run mksysctl_openbsd.go" - mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'" # Let the type of C char be signed for making the bare syscall # API consistent across platforms. mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" @@ -214,11 +232,6 @@ esac if [ "$GOOSARCH" == "aix_ppc64" ]; then # aix/ppc64 script generates files instead of writing to stdin. echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ; - elif [ "$GOOS" == "darwin" ]; then - # 1.12 and later, syscalls via libSystem - echo "$mksyscall -tags $GOOS,$GOARCH,go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go"; - # 1.13 and later, syscalls via libSystem (including syscallPtr) - echo "$mksyscall -tags $GOOS,$GOARCH,go1.13 syscall_darwin.1_13.go |gofmt >zsyscall_$GOOSARCH.1_13.go"; elif [ "$GOOS" == "illumos" ]; then # illumos code generation requires a --illumos switch echo "$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go"; diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 2ab44aa659..7456d9ddde 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -642,7 +642,7 @@ errors=$( signals=$( echo '#include ' | $CC -x c - -E -dM $ccflags | awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' | - egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' | + grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' | sort ) @@ -652,7 +652,7 @@ echo '#include ' | $CC -x c - -E -dM $ccflags | sort >_error.grep echo '#include ' | $CC -x c - -E -dM $ccflags | awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' | - egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' | + grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' | sort >_signal.grep echo '// mkerrors.sh' "$@" diff --git a/vendor/golang.org/x/sys/unix/ptrace_darwin.go b/vendor/golang.org/x/sys/unix/ptrace_darwin.go index 463c3eff7f..39dba6ca6a 100644 --- a/vendor/golang.org/x/sys/unix/ptrace_darwin.go +++ b/vendor/golang.org/x/sys/unix/ptrace_darwin.go @@ -7,6 +7,12 @@ package unix +import "unsafe" + func ptrace(request int, pid int, addr uintptr, data uintptr) error { return ptrace1(request, pid, addr, data) } + +func ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) error { + return ptrace1Ptr(request, pid, addr, data) +} diff --git a/vendor/golang.org/x/sys/unix/ptrace_ios.go b/vendor/golang.org/x/sys/unix/ptrace_ios.go index ed0509a011..9ea66330a9 100644 --- a/vendor/golang.org/x/sys/unix/ptrace_ios.go +++ b/vendor/golang.org/x/sys/unix/ptrace_ios.go @@ -7,6 +7,12 @@ package unix +import "unsafe" + func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { return ENOTSUP } + +func ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) { + return ENOTSUP +} diff --git a/vendor/golang.org/x/sys/unix/sockcmsg_unix.go b/vendor/golang.org/x/sys/unix/sockcmsg_unix.go index 453a942c5d..3865943f6e 100644 --- a/vendor/golang.org/x/sys/unix/sockcmsg_unix.go +++ b/vendor/golang.org/x/sys/unix/sockcmsg_unix.go @@ -52,6 +52,20 @@ func ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) { return msgs, nil } +// ParseOneSocketControlMessage parses a single socket control message from b, returning the message header, +// message data (a slice of b), and the remainder of b after that single message. +// When there are no remaining messages, len(remainder) == 0. +func ParseOneSocketControlMessage(b []byte) (hdr Cmsghdr, data []byte, remainder []byte, err error) { + h, dbuf, err := socketControlMessageHeaderAndData(b) + if err != nil { + return Cmsghdr{}, nil, nil, err + } + if i := cmsgAlignOf(int(h.Len)); i < len(b) { + remainder = b[i:] + } + return *h, dbuf, remainder, nil +} + func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) { h := (*Cmsghdr)(unsafe.Pointer(&b[0])) if h.Len < SizeofCmsghdr || uint64(h.Len) > uint64(len(b)) { diff --git a/vendor/golang.org/x/sys/unix/syscall.go b/vendor/golang.org/x/sys/unix/syscall.go index 649fa87405..63e8c83831 100644 --- a/vendor/golang.org/x/sys/unix/syscall.go +++ b/vendor/golang.org/x/sys/unix/syscall.go @@ -29,8 +29,6 @@ import ( "bytes" "strings" "unsafe" - - "golang.org/x/sys/internal/unsafeheader" ) // ByteSliceFromString returns a NUL-terminated slice of bytes @@ -82,13 +80,7 @@ func BytePtrToString(p *byte) string { ptr = unsafe.Pointer(uintptr(ptr) + 1) } - var s []byte - h := (*unsafeheader.Slice)(unsafe.Pointer(&s)) - h.Data = unsafe.Pointer(p) - h.Len = n - h.Cap = n - - return string(s) + return string(unsafe.Slice(p, n)) } // Single-word zero for use when we need a valid pointer to 0 bytes. diff --git a/vendor/golang.org/x/sys/unix/syscall_aix.go b/vendor/golang.org/x/sys/unix/syscall_aix.go index 2db1b51e99..d9f5544ccf 100644 --- a/vendor/golang.org/x/sys/unix/syscall_aix.go +++ b/vendor/golang.org/x/sys/unix/syscall_aix.go @@ -292,9 +292,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { break } } - - bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] - sa.Name = string(bytes) + sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n)) return sa, nil case AF_INET: @@ -411,6 +409,7 @@ func (w WaitStatus) CoreDump() bool { return w&0x80 == 0x80 } func (w WaitStatus) TrapCause() int { return -1 } //sys ioctl(fd int, req uint, arg uintptr) (err error) +//sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = ioctl // fcntl must never be called with cmd=F_DUP2FD because it doesn't work on AIX // There is no way to create a custom fcntl and to keep //sys fcntl easily, diff --git a/vendor/golang.org/x/sys/unix/syscall_bsd.go b/vendor/golang.org/x/sys/unix/syscall_bsd.go index eda42671f1..7705c3270b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_bsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_bsd.go @@ -245,8 +245,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { break } } - bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] - sa.Name = string(bytes) + sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n)) return sa, nil case AF_INET: diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go b/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go deleted file mode 100644 index b0098607c7..0000000000 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build darwin && go1.12 && !go1.13 -// +build darwin,go1.12,!go1.13 - -package unix - -import ( - "unsafe" -) - -const _SYS_GETDIRENTRIES64 = 344 - -func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { - // To implement this using libSystem we'd need syscall_syscallPtr for - // fdopendir. However, syscallPtr was only added in Go 1.13, so we fall - // back to raw syscalls for this func on Go 1.12. - var p unsafe.Pointer - if len(buf) > 0 { - p = unsafe.Pointer(&buf[0]) - } else { - p = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(_SYS_GETDIRENTRIES64, uintptr(fd), uintptr(p), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0) - n = int(r0) - if e1 != 0 { - return n, errnoErr(e1) - } - return n, nil -} diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go b/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go deleted file mode 100644 index 1596426b1e..0000000000 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build darwin && go1.13 -// +build darwin,go1.13 - -package unix - -import ( - "unsafe" - - "golang.org/x/sys/internal/unsafeheader" -) - -//sys closedir(dir uintptr) (err error) -//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) - -func fdopendir(fd int) (dir uintptr, err error) { - r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0) - dir = uintptr(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_fdopendir_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib" - -func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { - // Simulate Getdirentries using fdopendir/readdir_r/closedir. - // We store the number of entries to skip in the seek - // offset of fd. See issue #31368. - // It's not the full required semantics, but should handle the case - // of calling Getdirentries or ReadDirent repeatedly. - // It won't handle assigning the results of lseek to *basep, or handle - // the directory being edited underfoot. - skip, err := Seek(fd, 0, 1 /* SEEK_CUR */) - if err != nil { - return 0, err - } - - // We need to duplicate the incoming file descriptor - // because the caller expects to retain control of it, but - // fdopendir expects to take control of its argument. - // Just Dup'ing the file descriptor is not enough, as the - // result shares underlying state. Use Openat to make a really - // new file descriptor referring to the same directory. - fd2, err := Openat(fd, ".", O_RDONLY, 0) - if err != nil { - return 0, err - } - d, err := fdopendir(fd2) - if err != nil { - Close(fd2) - return 0, err - } - defer closedir(d) - - var cnt int64 - for { - var entry Dirent - var entryp *Dirent - e := readdir_r(d, &entry, &entryp) - if e != 0 { - return n, errnoErr(e) - } - if entryp == nil { - break - } - if skip > 0 { - skip-- - cnt++ - continue - } - - reclen := int(entry.Reclen) - if reclen > len(buf) { - // Not enough room. Return for now. - // The counter will let us know where we should start up again. - // Note: this strategy for suspending in the middle and - // restarting is O(n^2) in the length of the directory. Oh well. - break - } - - // Copy entry into return buffer. - var s []byte - hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s)) - hdr.Data = unsafe.Pointer(&entry) - hdr.Cap = reclen - hdr.Len = reclen - copy(buf, s) - - buf = buf[reclen:] - n += reclen - cnt++ - } - // Set the seek offset of the input fd to record - // how many files we've already returned. - _, err = Seek(fd, cnt, 0 /* SEEK_SET */) - if err != nil { - return n, err - } - - return n, nil -} diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 4f87f16ea7..7064d6ebab 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -14,11 +14,100 @@ package unix import ( "fmt" - "runtime" "syscall" "unsafe" ) +//sys closedir(dir uintptr) (err error) +//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) + +func fdopendir(fd int) (dir uintptr, err error) { + r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0) + dir = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fdopendir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib" + +func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { + // Simulate Getdirentries using fdopendir/readdir_r/closedir. + // We store the number of entries to skip in the seek + // offset of fd. See issue #31368. + // It's not the full required semantics, but should handle the case + // of calling Getdirentries or ReadDirent repeatedly. + // It won't handle assigning the results of lseek to *basep, or handle + // the directory being edited underfoot. + skip, err := Seek(fd, 0, 1 /* SEEK_CUR */) + if err != nil { + return 0, err + } + + // We need to duplicate the incoming file descriptor + // because the caller expects to retain control of it, but + // fdopendir expects to take control of its argument. + // Just Dup'ing the file descriptor is not enough, as the + // result shares underlying state. Use Openat to make a really + // new file descriptor referring to the same directory. + fd2, err := Openat(fd, ".", O_RDONLY, 0) + if err != nil { + return 0, err + } + d, err := fdopendir(fd2) + if err != nil { + Close(fd2) + return 0, err + } + defer closedir(d) + + var cnt int64 + for { + var entry Dirent + var entryp *Dirent + e := readdir_r(d, &entry, &entryp) + if e != 0 { + return n, errnoErr(e) + } + if entryp == nil { + break + } + if skip > 0 { + skip-- + cnt++ + continue + } + + reclen := int(entry.Reclen) + if reclen > len(buf) { + // Not enough room. Return for now. + // The counter will let us know where we should start up again. + // Note: this strategy for suspending in the middle and + // restarting is O(n^2) in the length of the directory. Oh well. + break + } + + // Copy entry into return buffer. + s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen) + copy(buf, s) + + buf = buf[reclen:] + n += reclen + cnt++ + } + // Set the seek offset of the input fd to record + // how many files we've already returned. + _, err = Seek(fd, cnt, 0 /* SEEK_SET */) + if err != nil { + return n, err + } + + return n, nil +} + // SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Len uint8 @@ -140,6 +229,7 @@ func direntNamlen(buf []byte) (uint64, bool) { func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } +func PtraceDenyAttach() (err error) { return ptrace(PT_DENY_ATTACH, 0, 0, 0) } //sysnb pipe(p *[2]int32) (err error) @@ -285,11 +375,10 @@ func Flistxattr(fd int, dest []byte) (sz int, err error) { func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) } //sys ioctl(fd int, req uint, arg uintptr) (err error) +//sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL func IoctlCtlInfo(fd int, ctlInfo *CtlInfo) error { - err := ioctl(fd, CTLIOCGINFO, uintptr(unsafe.Pointer(ctlInfo))) - runtime.KeepAlive(ctlInfo) - return err + return ioctlPtr(fd, CTLIOCGINFO, unsafe.Pointer(ctlInfo)) } // IfreqMTU is struct ifreq used to get or set a network device's MTU. @@ -303,16 +392,14 @@ type IfreqMTU struct { func IoctlGetIfreqMTU(fd int, ifname string) (*IfreqMTU, error) { var ifreq IfreqMTU copy(ifreq.Name[:], ifname) - err := ioctl(fd, SIOCGIFMTU, uintptr(unsafe.Pointer(&ifreq))) + err := ioctlPtr(fd, SIOCGIFMTU, unsafe.Pointer(&ifreq)) return &ifreq, err } // IoctlSetIfreqMTU performs the SIOCSIFMTU ioctl operation on fd to set the MTU // of the network device specified by ifreq.Name. func IoctlSetIfreqMTU(fd int, ifreq *IfreqMTU) error { - err := ioctl(fd, SIOCSIFMTU, uintptr(unsafe.Pointer(ifreq))) - runtime.KeepAlive(ifreq) - return err + return ioctlPtr(fd, SIOCSIFMTU, unsafe.Pointer(ifreq)) } //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go index b37310ce9b..9fa879806b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go @@ -47,5 +47,6 @@ func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, //sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64 //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 //sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace +//sys ptrace1Ptr(request int, pid int, addr unsafe.Pointer, data uintptr) (err error) = SYS_ptrace //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64 diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go index d51ec99630..f17b8c526a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go @@ -47,5 +47,6 @@ func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, //sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT //sys Lstat(path string, stat *Stat_t) (err error) //sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace +//sys ptrace1Ptr(request int, pid int, addr unsafe.Pointer, data uintptr) (err error) = SYS_ptrace //sys Stat(path string, stat *Stat_t) (err error) //sys Statfs(path string, stat *Statfs_t) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go index 61c0d0de15..221efc26bc 100644 --- a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go +++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go @@ -172,6 +172,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { } //sys ioctl(fd int, req uint, arg uintptr) (err error) +//sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL @@ -255,6 +256,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys Chmod(path string, mode uint32) (err error) //sys Chown(path string, uid int, gid int) (err error) //sys Chroot(path string) (err error) +//sys ClockGettime(clockid int32, time *Timespec) (err error) //sys Close(fd int) (err error) //sys Dup(fd int) (nfd int, err error) //sys Dup2(from int, to int) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go index de7c23e064..5bdde03e4a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go @@ -161,7 +161,8 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { return } -//sys ioctl(fd int, req uint, arg uintptr) (err error) +//sys ioctl(fd int, req uint, arg uintptr) (err error) = SYS_IOCTL +//sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL @@ -253,6 +254,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e } //sys ptrace(request int, pid int, addr uintptr, data int) (err error) +//sys ptracePtr(request int, pid int, addr unsafe.Pointer, data int) (err error) = SYS_PTRACE func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) @@ -267,19 +269,36 @@ func PtraceDetach(pid int) (err error) { } func PtraceGetFpRegs(pid int, fpregsout *FpReg) (err error) { - return ptrace(PT_GETFPREGS, pid, uintptr(unsafe.Pointer(fpregsout)), 0) + return ptracePtr(PT_GETFPREGS, pid, unsafe.Pointer(fpregsout), 0) } func PtraceGetRegs(pid int, regsout *Reg) (err error) { - return ptrace(PT_GETREGS, pid, uintptr(unsafe.Pointer(regsout)), 0) + return ptracePtr(PT_GETREGS, pid, unsafe.Pointer(regsout), 0) +} + +func PtraceIO(req int, pid int, offs uintptr, out []byte, countin int) (count int, err error) { + ioDesc := PtraceIoDesc{ + Op: int32(req), + Offs: offs, + } + if countin > 0 { + _ = out[:countin] // check bounds + ioDesc.Addr = &out[0] + } else if out != nil { + ioDesc.Addr = (*byte)(unsafe.Pointer(&_zero)) + } + ioDesc.SetLen(countin) + + err = ptracePtr(PT_IO, pid, unsafe.Pointer(&ioDesc), 0) + return int(ioDesc.Len), err } func PtraceLwpEvents(pid int, enable int) (err error) { return ptrace(PT_LWP_EVENTS, pid, 0, enable) } -func PtraceLwpInfo(pid int, info uintptr) (err error) { - return ptrace(PT_LWPINFO, pid, info, int(unsafe.Sizeof(PtraceLwpInfoStruct{}))) +func PtraceLwpInfo(pid int, info *PtraceLwpInfoStruct) (err error) { + return ptracePtr(PT_LWPINFO, pid, unsafe.Pointer(info), int(unsafe.Sizeof(*info))) } func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) { @@ -299,13 +318,25 @@ func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) { } func PtraceSetRegs(pid int, regs *Reg) (err error) { - return ptrace(PT_SETREGS, pid, uintptr(unsafe.Pointer(regs)), 0) + return ptracePtr(PT_SETREGS, pid, unsafe.Pointer(regs), 0) } func PtraceSingleStep(pid int) (err error) { return ptrace(PT_STEP, pid, 1, 0) } +func Dup3(oldfd, newfd, flags int) error { + if oldfd == newfd || flags&^O_CLOEXEC != 0 { + return EINVAL + } + how := F_DUP2FD + if flags&O_CLOEXEC != 0 { + how = F_DUP2FD_CLOEXEC + } + _, err := fcntl(oldfd, how, newfd) + return err +} + /* * Exposed directly */ @@ -319,6 +350,7 @@ func PtraceSingleStep(pid int) (err error) { //sys Chmod(path string, mode uint32) (err error) //sys Chown(path string, uid int, gid int) (err error) //sys Chroot(path string) (err error) +//sys ClockGettime(clockid int32, time *Timespec) (err error) //sys Close(fd int) (err error) //sys Dup(fd int) (nfd int, err error) //sys Dup2(from int, to int) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go b/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go index b11ede89a9..b8da510043 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go @@ -42,6 +42,10 @@ func (cmsg *Cmsghdr) SetLen(length int) { cmsg.Len = uint32(length) } +func (d *PtraceIoDesc) SetLen(length int) { + d.Len = uint32(length) +} + func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { var writtenOut uint64 = 0 _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0) @@ -57,11 +61,5 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func PtraceGetFsBase(pid int, fsbase *int64) (err error) { - return ptrace(PT_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0) -} - -func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) { - ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint32(countin)} - err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0) - return int(ioDesc.Len), err + return ptracePtr(PT_GETFSBASE, pid, unsafe.Pointer(fsbase), 0) } diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go index 9ed8eec6c2..47155c4839 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go @@ -42,6 +42,10 @@ func (cmsg *Cmsghdr) SetLen(length int) { cmsg.Len = uint32(length) } +func (d *PtraceIoDesc) SetLen(length int) { + d.Len = uint64(length) +} + func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { var writtenOut uint64 = 0 _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0) @@ -57,11 +61,5 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func PtraceGetFsBase(pid int, fsbase *int64) (err error) { - return ptrace(PT_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0) -} - -func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) { - ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint64(countin)} - err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0) - return int(ioDesc.Len), err + return ptracePtr(PT_GETFSBASE, pid, unsafe.Pointer(fsbase), 0) } diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go b/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go index f8ac982479..08932093fa 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go @@ -42,6 +42,10 @@ func (cmsg *Cmsghdr) SetLen(length int) { cmsg.Len = uint32(length) } +func (d *PtraceIoDesc) SetLen(length int) { + d.Len = uint32(length) +} + func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { var writtenOut uint64 = 0 _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0) @@ -55,9 +59,3 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e } func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) - -func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) { - ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint32(countin)} - err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0) - return int(ioDesc.Len), err -} diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go index 8e932036ec..d151a0d0e5 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go @@ -42,6 +42,10 @@ func (cmsg *Cmsghdr) SetLen(length int) { cmsg.Len = uint32(length) } +func (d *PtraceIoDesc) SetLen(length int) { + d.Len = uint64(length) +} + func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { var writtenOut uint64 = 0 _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0) @@ -55,9 +59,3 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e } func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) - -func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) { - ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint64(countin)} - err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0) - return int(ioDesc.Len), err -} diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd_riscv64.go b/vendor/golang.org/x/sys/unix/syscall_freebsd_riscv64.go index cbe1222789..d5cd64b378 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd_riscv64.go @@ -42,6 +42,10 @@ func (cmsg *Cmsghdr) SetLen(length int) { cmsg.Len = uint32(length) } +func (d *PtraceIoDesc) SetLen(length int) { + d.Len = uint64(length) +} + func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { var writtenOut uint64 = 0 _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0) @@ -55,9 +59,3 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e } func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) - -func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) { - ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint64(countin)} - err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0) - return int(ioDesc.Len), err -} diff --git a/vendor/golang.org/x/sys/unix/syscall_hurd.go b/vendor/golang.org/x/sys/unix/syscall_hurd.go new file mode 100644 index 0000000000..381fd4673b --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_hurd.go @@ -0,0 +1,30 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build hurd +// +build hurd + +package unix + +/* +#include +int ioctl(int, unsigned long int, uintptr_t); +*/ +import "C" + +func ioctl(fd int, req uint, arg uintptr) (err error) { + r0, er := C.ioctl(C.int(fd), C.ulong(req), C.uintptr_t(arg)) + if r0 == -1 && er != nil { + err = er + } + return +} + +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + r0, er := C.ioctl(C.int(fd), C.ulong(req), C.uintptr_t(uintptr(arg))) + if r0 == -1 && er != nil { + err = er + } + return +} diff --git a/vendor/golang.org/x/sys/unix/syscall_hurd_386.go b/vendor/golang.org/x/sys/unix/syscall_hurd_386.go new file mode 100644 index 0000000000..7cf54a3e4f --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_hurd_386.go @@ -0,0 +1,29 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build 386 && hurd +// +build 386,hurd + +package unix + +const ( + TIOCGETA = 0x62251713 +) + +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +type Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]uint8 + Ispeed int32 + Ospeed int32 +} diff --git a/vendor/golang.org/x/sys/unix/syscall_illumos.go b/vendor/golang.org/x/sys/unix/syscall_illumos.go index e48244a9c9..87db5a6a8c 100644 --- a/vendor/golang.org/x/sys/unix/syscall_illumos.go +++ b/vendor/golang.org/x/sys/unix/syscall_illumos.go @@ -10,8 +10,6 @@ package unix import ( - "fmt" - "runtime" "unsafe" ) @@ -79,107 +77,3 @@ func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) { } return } - -//sys putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error) - -func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) { - var clp, datap *strbuf - if len(cl) > 0 { - clp = &strbuf{ - Len: int32(len(cl)), - Buf: (*int8)(unsafe.Pointer(&cl[0])), - } - } - if len(data) > 0 { - datap = &strbuf{ - Len: int32(len(data)), - Buf: (*int8)(unsafe.Pointer(&data[0])), - } - } - return putmsg(fd, clp, datap, flags) -} - -//sys getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error) - -func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) { - var clp, datap *strbuf - if len(cl) > 0 { - clp = &strbuf{ - Maxlen: int32(len(cl)), - Buf: (*int8)(unsafe.Pointer(&cl[0])), - } - } - if len(data) > 0 { - datap = &strbuf{ - Maxlen: int32(len(data)), - Buf: (*int8)(unsafe.Pointer(&data[0])), - } - } - - if err = getmsg(fd, clp, datap, &flags); err != nil { - return nil, nil, 0, err - } - - if len(cl) > 0 { - retCl = cl[:clp.Len] - } - if len(data) > 0 { - retData = data[:datap.Len] - } - return retCl, retData, flags, nil -} - -func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) { - return ioctlRet(fd, req, uintptr(arg)) -} - -func IoctlSetString(fd int, req uint, val string) error { - bs := make([]byte, len(val)+1) - copy(bs[:len(bs)-1], val) - err := ioctl(fd, req, uintptr(unsafe.Pointer(&bs[0]))) - runtime.KeepAlive(&bs[0]) - return err -} - -// Lifreq Helpers - -func (l *Lifreq) SetName(name string) error { - if len(name) >= len(l.Name) { - return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1) - } - for i := range name { - l.Name[i] = int8(name[i]) - } - return nil -} - -func (l *Lifreq) SetLifruInt(d int) { - *(*int)(unsafe.Pointer(&l.Lifru[0])) = d -} - -func (l *Lifreq) GetLifruInt() int { - return *(*int)(unsafe.Pointer(&l.Lifru[0])) -} - -func (l *Lifreq) SetLifruUint(d uint) { - *(*uint)(unsafe.Pointer(&l.Lifru[0])) = d -} - -func (l *Lifreq) GetLifruUint() uint { - return *(*uint)(unsafe.Pointer(&l.Lifru[0])) -} - -func IoctlLifreq(fd int, req uint, l *Lifreq) error { - return ioctl(fd, req, uintptr(unsafe.Pointer(l))) -} - -// Strioctl Helpers - -func (s *Strioctl) SetInt(i int) { - s.Len = int32(unsafe.Sizeof(i)) - s.Dp = (*int8)(unsafe.Pointer(&i)) -} - -func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) { - return ioctlRet(fd, req, uintptr(unsafe.Pointer(s))) -} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 47146911f2..9735331530 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -1015,8 +1015,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { for n < len(pp.Path) && pp.Path[n] != 0 { n++ } - bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] - sa.Name = string(bytes) + sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n)) return sa, nil case AF_INET: @@ -1365,6 +1364,10 @@ func SetsockoptTCPRepairOpt(fd, level, opt int, o []TCPRepairOpt) (err error) { return setsockopt(fd, level, opt, unsafe.Pointer(&o[0]), uintptr(SizeofTCPRepairOpt*len(o))) } +func SetsockoptTCPMD5Sig(fd, level, opt int, s *TCPMD5Sig) error { + return setsockopt(fd, level, opt, unsafe.Pointer(s), unsafe.Sizeof(*s)) +} + // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html) // KeyctlInt calls keyctl commands in which each argument is an int. @@ -1554,6 +1557,7 @@ func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Sockle var iova [1]Iovec iova[0].Base = &dummy iova[0].SetLen(1) + iov = iova[:] } } msg.Control = &oob[0] @@ -1578,6 +1582,7 @@ func BindToDevice(fd int, device string) (err error) { } //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) +//sys ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) = SYS_PTRACE func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) { // The peek requests are machine-size oriented, so we wrap it @@ -1595,7 +1600,7 @@ func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err erro // boundary. n := 0 if addr%SizeofPtr != 0 { - err = ptrace(req, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) + err = ptracePtr(req, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0])) if err != nil { return 0, err } @@ -1607,7 +1612,7 @@ func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err erro for len(out) > 0 { // We use an internal buffer to guarantee alignment. // It's not documented if this is necessary, but we're paranoid. - err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) + err = ptracePtr(req, pid, addr+uintptr(n), unsafe.Pointer(&buf[0])) if err != nil { return n, err } @@ -1639,7 +1644,7 @@ func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (c n := 0 if addr%SizeofPtr != 0 { var buf [SizeofPtr]byte - err = ptrace(peekReq, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) + err = ptracePtr(peekReq, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0])) if err != nil { return 0, err } @@ -1666,7 +1671,7 @@ func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (c // Trailing edge. if len(data) > 0 { var buf [SizeofPtr]byte - err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) + err = ptracePtr(peekReq, pid, addr+uintptr(n), unsafe.Pointer(&buf[0])) if err != nil { return n, err } @@ -1695,11 +1700,11 @@ func PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) { } func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { - return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) + return ptracePtr(PTRACE_GETREGS, pid, 0, unsafe.Pointer(regsout)) } func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { - return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) + return ptracePtr(PTRACE_SETREGS, pid, 0, unsafe.Pointer(regs)) } func PtraceSetOptions(pid int, options int) (err error) { @@ -1708,7 +1713,7 @@ func PtraceSetOptions(pid int, options int) (err error) { func PtraceGetEventMsg(pid int) (msg uint, err error) { var data _C_long - err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data))) + err = ptracePtr(PTRACE_GETEVENTMSG, pid, 0, unsafe.Pointer(&data)) msg = uint(data) return } @@ -1799,6 +1804,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sysnb Capset(hdr *CapUserHeader, data *CapUserData) (err error) //sys Chdir(path string) (err error) //sys Chroot(path string) (err error) +//sys ClockAdjtime(clockid int32, buf *Timex) (state int, err error) //sys ClockGetres(clockid int32, res *Timespec) (err error) //sys ClockGettime(clockid int32, time *Timespec) (err error) //sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) @@ -1972,36 +1978,46 @@ func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) { //sys preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2 //sys pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2 -func bytes2iovec(bs [][]byte) []Iovec { - iovecs := make([]Iovec, len(bs)) - for i, b := range bs { - iovecs[i].SetLen(len(b)) +// minIovec is the size of the small initial allocation used by +// Readv, Writev, etc. +// +// This small allocation gets stack allocated, which lets the +// common use case of len(iovs) <= minIovs avoid more expensive +// heap allocations. +const minIovec = 8 + +// appendBytes converts bs to Iovecs and appends them to vecs. +func appendBytes(vecs []Iovec, bs [][]byte) []Iovec { + for _, b := range bs { + var v Iovec + v.SetLen(len(b)) if len(b) > 0 { - iovecs[i].Base = &b[0] + v.Base = &b[0] } else { - iovecs[i].Base = (*byte)(unsafe.Pointer(&_zero)) + v.Base = (*byte)(unsafe.Pointer(&_zero)) } + vecs = append(vecs, v) } - return iovecs + return vecs } -// offs2lohi splits offs into its lower and upper unsigned long. On 64-bit -// systems, hi will always be 0. On 32-bit systems, offs will be split in half. -// preadv/pwritev chose this calling convention so they don't need to add a -// padding-register for alignment on ARM. +// offs2lohi splits offs into its low and high order bits. func offs2lohi(offs int64) (lo, hi uintptr) { - return uintptr(offs), uintptr(uint64(offs) >> SizeofLong) + const longBits = SizeofLong * 8 + return uintptr(offs), uintptr(uint64(offs) >> (longBits - 1) >> 1) // two shifts to avoid false positive in vet } func Readv(fd int, iovs [][]byte) (n int, err error) { - iovecs := bytes2iovec(iovs) + iovecs := make([]Iovec, 0, minIovec) + iovecs = appendBytes(iovecs, iovs) n, err = readv(fd, iovecs) readvRacedetect(iovecs, n, err) return n, err } func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { - iovecs := bytes2iovec(iovs) + iovecs := make([]Iovec, 0, minIovec) + iovecs = appendBytes(iovecs, iovs) lo, hi := offs2lohi(offset) n, err = preadv(fd, iovecs, lo, hi) readvRacedetect(iovecs, n, err) @@ -2009,7 +2025,8 @@ func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { } func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { - iovecs := bytes2iovec(iovs) + iovecs := make([]Iovec, 0, minIovec) + iovecs = appendBytes(iovecs, iovs) lo, hi := offs2lohi(offset) n, err = preadv2(fd, iovecs, lo, hi, flags) readvRacedetect(iovecs, n, err) @@ -2036,7 +2053,8 @@ func readvRacedetect(iovecs []Iovec, n int, err error) { } func Writev(fd int, iovs [][]byte) (n int, err error) { - iovecs := bytes2iovec(iovs) + iovecs := make([]Iovec, 0, minIovec) + iovecs = appendBytes(iovecs, iovs) if raceenabled { raceReleaseMerge(unsafe.Pointer(&ioSync)) } @@ -2046,7 +2064,8 @@ func Writev(fd int, iovs [][]byte) (n int, err error) { } func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) { - iovecs := bytes2iovec(iovs) + iovecs := make([]Iovec, 0, minIovec) + iovecs = appendBytes(iovecs, iovs) if raceenabled { raceReleaseMerge(unsafe.Pointer(&ioSync)) } @@ -2057,7 +2076,8 @@ func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) { } func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { - iovecs := bytes2iovec(iovs) + iovecs := make([]Iovec, 0, minIovec) + iovecs = appendBytes(iovecs, iovs) if raceenabled { raceReleaseMerge(unsafe.Pointer(&ioSync)) } @@ -2138,6 +2158,14 @@ func isGroupMember(gid int) bool { return false } +func isCapDacOverrideSet() bool { + hdr := CapUserHeader{Version: LINUX_CAPABILITY_VERSION_3} + data := [2]CapUserData{} + err := Capget(&hdr, &data[0]) + + return err == nil && data[0].Effective&(1< 0 { + clp = &strbuf{ + Len: int32(len(cl)), + Buf: (*int8)(unsafe.Pointer(&cl[0])), + } + } + if len(data) > 0 { + datap = &strbuf{ + Len: int32(len(data)), + Buf: (*int8)(unsafe.Pointer(&data[0])), + } + } + return putmsg(fd, clp, datap, flags) +} + +//sys getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error) + +func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) { + var clp, datap *strbuf + if len(cl) > 0 { + clp = &strbuf{ + Maxlen: int32(len(cl)), + Buf: (*int8)(unsafe.Pointer(&cl[0])), + } + } + if len(data) > 0 { + datap = &strbuf{ + Maxlen: int32(len(data)), + Buf: (*int8)(unsafe.Pointer(&data[0])), + } + } + + if err = getmsg(fd, clp, datap, &flags); err != nil { + return nil, nil, 0, err + } + + if len(cl) > 0 { + retCl = cl[:clp.Len] + } + if len(data) > 0 { + retData = data[:datap.Len] + } + return retCl, retData, flags, nil +} + +func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) { + return ioctlRet(fd, req, uintptr(arg)) +} + +func IoctlSetString(fd int, req uint, val string) error { + bs := make([]byte, len(val)+1) + copy(bs[:len(bs)-1], val) + err := ioctlPtr(fd, req, unsafe.Pointer(&bs[0])) + runtime.KeepAlive(&bs[0]) + return err +} + +// Lifreq Helpers + +func (l *Lifreq) SetName(name string) error { + if len(name) >= len(l.Name) { + return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1) + } + for i := range name { + l.Name[i] = int8(name[i]) + } + return nil +} + +func (l *Lifreq) SetLifruInt(d int) { + *(*int)(unsafe.Pointer(&l.Lifru[0])) = d +} + +func (l *Lifreq) GetLifruInt() int { + return *(*int)(unsafe.Pointer(&l.Lifru[0])) +} + +func (l *Lifreq) SetLifruUint(d uint) { + *(*uint)(unsafe.Pointer(&l.Lifru[0])) = d +} + +func (l *Lifreq) GetLifruUint() uint { + return *(*uint)(unsafe.Pointer(&l.Lifru[0])) +} + +func IoctlLifreq(fd int, req uint, l *Lifreq) error { + return ioctlPtr(fd, req, unsafe.Pointer(l)) +} + +// Strioctl Helpers + +func (s *Strioctl) SetInt(i int) { + s.Len = int32(unsafe.Sizeof(i)) + s.Dp = (*int8)(unsafe.Pointer(&i)) +} + +func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) { + return ioctlPtrRet(fd, req, unsafe.Pointer(s)) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_unix.go b/vendor/golang.org/x/sys/unix/syscall_unix.go index 1ff5060b51..00f0aa3758 100644 --- a/vendor/golang.org/x/sys/unix/syscall_unix.go +++ b/vendor/golang.org/x/sys/unix/syscall_unix.go @@ -13,8 +13,6 @@ import ( "sync" "syscall" "unsafe" - - "golang.org/x/sys/internal/unsafeheader" ) var ( @@ -117,11 +115,7 @@ func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (d } // Use unsafe to convert addr into a []byte. - var b []byte - hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b)) - hdr.Data = unsafe.Pointer(addr) - hdr.Cap = length - hdr.Len = length + b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length) // Register mapping in m and return it. p := &b[cap(b)-1] @@ -337,6 +331,19 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { return } +// Recvmsg receives a message from a socket using the recvmsg system call. The +// received non-control data will be written to p, and any "out of band" +// control data will be written to oob. The flags are passed to recvmsg. +// +// The results are: +// - n is the number of non-control data bytes read into p +// - oobn is the number of control data bytes read into oob; this may be interpreted using [ParseSocketControlMessage] +// - recvflags is flags returned by recvmsg +// - from is the address of the sender +// +// If the underlying socket type is not SOCK_DGRAM, a received message +// containing oob data and a single '\0' of non-control data is treated as if +// the message contained only control data, i.e. n will be zero on return. func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { var iov [1]Iovec if len(p) > 0 { @@ -352,13 +359,9 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from return } -// RecvmsgBuffers receives a message from a socket using the recvmsg -// system call. The flags are passed to recvmsg. Any non-control data -// read is scattered into the buffers slices. The results are: -// - n is the number of non-control data read into bufs -// - oobn is the number of control data read into oob; this may be interpreted using [ParseSocketControlMessage] -// - recvflags is flags returned by recvmsg -// - from is the address of the sender +// RecvmsgBuffers receives a message from a socket using the recvmsg system +// call. This function is equivalent to Recvmsg, but non-control data read is +// scattered into the buffers slices. func RecvmsgBuffers(fd int, buffers [][]byte, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { iov := make([]Iovec, len(buffers)) for i := range buffers { @@ -377,11 +380,38 @@ func RecvmsgBuffers(fd int, buffers [][]byte, oob []byte, flags int) (n, oobn in return } +// Sendmsg sends a message on a socket to an address using the sendmsg system +// call. This function is equivalent to SendmsgN, but does not return the +// number of bytes actually sent. func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { _, err = SendmsgN(fd, p, oob, to, flags) return } +// SendmsgN sends a message on a socket to an address using the sendmsg system +// call. p contains the non-control data to send, and oob contains the "out of +// band" control data. The flags are passed to sendmsg. The number of +// non-control bytes actually written to the socket is returned. +// +// Some socket types do not support sending control data without accompanying +// non-control data. If p is empty, and oob contains control data, and the +// underlying socket type is not SOCK_DGRAM, p will be treated as containing a +// single '\0' and the return value will indicate zero bytes sent. +// +// The Go function Recvmsg, if called with an empty p and a non-empty oob, +// will read and ignore this additional '\0'. If the message is received by +// code that does not use Recvmsg, or that does not use Go at all, that code +// will need to be written to expect and ignore the additional '\0'. +// +// If you need to send non-empty oob with p actually empty, and if the +// underlying socket type supports it, you can do so via a raw system call as +// follows: +// +// msg := &unix.Msghdr{ +// Control: &oob[0], +// } +// msg.SetControllen(len(oob)) +// n, _, errno := unix.Syscall(unix.SYS_SENDMSG, uintptr(fd), uintptr(unsafe.Pointer(msg)), flags) func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { var iov [1]Iovec if len(p) > 0 { @@ -400,9 +430,8 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) } // SendmsgBuffers sends a message on a socket to an address using the sendmsg -// system call. The flags are passed to sendmsg. Any non-control data written -// is gathered from buffers. The function returns the number of bytes written -// to the socket. +// system call. This function is equivalent to SendmsgN, but the non-control +// data is gathered from buffers. func SendmsgBuffers(fd int, buffers [][]byte, oob []byte, to Sockaddr, flags int) (n int, err error) { iov := make([]Iovec, len(buffers)) for i := range buffers { @@ -429,11 +458,15 @@ func Send(s int, buf []byte, flags int) (err error) { } func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) { - ptr, n, err := to.sockaddr() - if err != nil { - return err + var ptr unsafe.Pointer + var salen _Socklen + if to != nil { + ptr, salen, err = to.sockaddr() + if err != nil { + return err + } } - return sendto(fd, p, flags, ptr, n) + return sendto(fd, p, flags, ptr, salen) } func SetsockoptByte(fd, level, opt int, value byte) (err error) { @@ -545,7 +578,7 @@ func Lutimes(path string, tv []Timeval) error { return UtimesNanoAt(AT_FDCWD, path, ts, AT_SYMLINK_NOFOLLOW) } -// emptyIovec reports whether there are no bytes in the slice of Iovec. +// emptyIovecs reports whether there are no bytes in the slice of Iovec. func emptyIovecs(iov []Iovec) bool { for i := range iov { if iov[i].Len > 0 { diff --git a/vendor/golang.org/x/sys/unix/syscall_unix_gc.go b/vendor/golang.org/x/sys/unix/syscall_unix_gc.go index 5898e9a52b..b6919ca580 100644 --- a/vendor/golang.org/x/sys/unix/syscall_unix_gc.go +++ b/vendor/golang.org/x/sys/unix/syscall_unix_gc.go @@ -2,11 +2,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build (darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris) && gc && !ppc64le && !ppc64 -// +build darwin dragonfly freebsd linux netbsd openbsd solaris +//go:build (darwin || dragonfly || freebsd || (linux && !ppc64 && !ppc64le) || netbsd || openbsd || solaris) && gc +// +build darwin dragonfly freebsd linux,!ppc64,!ppc64le netbsd openbsd solaris // +build gc -// +build !ppc64le -// +build !ppc64 package unix diff --git a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go index f8616f454e..b295497ae4 100644 --- a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go @@ -9,8 +9,10 @@ package unix import ( "bytes" + "fmt" "runtime" "sort" + "strings" "sync" "syscall" "unsafe" @@ -55,7 +57,13 @@ func (d *Dirent) NameString() string { if d == nil { return "" } - return string(d.Name[:d.Namlen]) + s := string(d.Name[:]) + idx := strings.IndexByte(s, 0) + if idx == -1 { + return s + } else { + return s[:idx] + } } func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { @@ -131,8 +139,7 @@ func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) { for n < int(pp.Len) && pp.Path[n] != 0 { n++ } - bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] - sa.Name = string(bytes) + sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n)) return sa, nil case AF_INET: @@ -206,6 +213,7 @@ func (cmsg *Cmsghdr) SetLen(length int) { //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) = SYS_MMAP //sys munmap(addr uintptr, length uintptr) (err error) = SYS_MUNMAP //sys ioctl(fd int, req uint, arg uintptr) (err error) = SYS_IOCTL +//sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL //sys Access(path string, mode uint32) (err error) = SYS___ACCESS_A //sys Chdir(path string) (err error) = SYS___CHDIR_A @@ -1230,6 +1238,14 @@ func Readdir(dir uintptr) (*Dirent, error) { return &ent, err } +func readdir_r(dirp uintptr, entry *direntLE, result **direntLE) (err error) { + r0, _, e1 := syscall_syscall(SYS___READDIR_R_A, dirp, uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result))) + if int64(r0) == -1 { + err = errnoErr(Errno(e1)) + } + return +} + func Closedir(dir uintptr) error { _, _, e := syscall_syscall(SYS_CLOSEDIR, dir, 0, 0) if e != 0 { @@ -1821,3 +1837,158 @@ func Unmount(name string, mtm int) (err error) { } return err } + +func fdToPath(dirfd int) (path string, err error) { + var buffer [1024]byte + // w_ctrl() + ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4, + []uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))}) + if ret == 0 { + zb := bytes.IndexByte(buffer[:], 0) + if zb == -1 { + zb = len(buffer) + } + // __e2a_l() + runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4, + []uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)}) + return string(buffer[:zb]), nil + } + // __errno() + errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, + []uintptr{})))) + // __errno2() + errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4, + []uintptr{})) + // strerror_r() + ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4, + []uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024}) + if ret == 0 { + zb := bytes.IndexByte(buffer[:], 0) + if zb == -1 { + zb = len(buffer) + } + return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2) + } else { + return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2) + } +} + +func direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) { + var d Dirent + + d.Ino = uint64(dirent.Ino) + offset, err := Telldir(dir) + if err != nil { + return d, err + } + + d.Off = int64(offset) + s := string(bytes.Split(dirent.Name[:], []byte{0})[0]) + copy(d.Name[:], s) + + d.Reclen = uint16(24 + len(d.NameString())) + var st Stat_t + path = path + "/" + s + err = Lstat(path, &st) + if err != nil { + return d, err + } + + d.Type = uint8(st.Mode >> 24) + return d, err +} + +func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { + // Simulation of Getdirentries port from the Darwin implementation. + // COMMENTS FROM DARWIN: + // It's not the full required semantics, but should handle the case + // of calling Getdirentries or ReadDirent repeatedly. + // It won't handle assigning the results of lseek to *basep, or handle + // the directory being edited underfoot. + + skip, err := Seek(fd, 0, 1 /* SEEK_CUR */) + if err != nil { + return 0, err + } + + // Get path from fd to avoid unavailable call (fdopendir) + path, err := fdToPath(fd) + if err != nil { + return 0, err + } + d, err := Opendir(path) + if err != nil { + return 0, err + } + defer Closedir(d) + + var cnt int64 + for { + var entryLE direntLE + var entrypLE *direntLE + e := readdir_r(d, &entryLE, &entrypLE) + if e != nil { + return n, e + } + if entrypLE == nil { + break + } + if skip > 0 { + skip-- + cnt++ + continue + } + + // Dirent on zos has a different structure + entry, e := direntLeToDirentUnix(&entryLE, d, path) + if e != nil { + return n, e + } + + reclen := int(entry.Reclen) + if reclen > len(buf) { + // Not enough room. Return for now. + // The counter will let us know where we should start up again. + // Note: this strategy for suspending in the middle and + // restarting is O(n^2) in the length of the directory. Oh well. + break + } + + // Copy entry into return buffer. + s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen) + copy(buf, s) + + buf = buf[reclen:] + n += reclen + cnt++ + } + // Set the seek offset of the input fd to record + // how many files we've already returned. + _, err = Seek(fd, cnt, 0 /* SEEK_SET */) + if err != nil { + return n, err + } + + return n, nil +} + +func ReadDirent(fd int, buf []byte) (n int, err error) { + var base = (*uintptr)(unsafe.Pointer(new(uint64))) + return Getdirentries(fd, buf, base) +} + +func direntIno(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) +} + +func direntReclen(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) +} + +func direntNamlen(buf []byte) (uint64, bool) { + reclen, ok := direntReclen(buf) + if !ok { + return 0, false + } + return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true +} diff --git a/vendor/golang.org/x/sys/unix/sysvshm_unix.go b/vendor/golang.org/x/sys/unix/sysvshm_unix.go index 0bb4c8de55..5bb41d17bc 100644 --- a/vendor/golang.org/x/sys/unix/sysvshm_unix.go +++ b/vendor/golang.org/x/sys/unix/sysvshm_unix.go @@ -7,11 +7,7 @@ package unix -import ( - "unsafe" - - "golang.org/x/sys/internal/unsafeheader" -) +import "unsafe" // SysvShmAttach attaches the Sysv shared memory segment associated with the // shared memory identifier id. @@ -34,12 +30,7 @@ func SysvShmAttach(id int, addr uintptr, flag int) ([]byte, error) { } // Use unsafe to convert addr into a []byte. - // TODO: convert to unsafe.Slice once we can assume Go 1.17 - var b []byte - hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b)) - hdr.Data = unsafe.Pointer(addr) - hdr.Cap = int(info.Segsz) - hdr.Len = int(info.Segsz) + b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), int(info.Segsz)) return b, nil } diff --git a/vendor/golang.org/x/sys/unix/timestruct.go b/vendor/golang.org/x/sys/unix/timestruct.go index 3d89304055..616b1b2848 100644 --- a/vendor/golang.org/x/sys/unix/timestruct.go +++ b/vendor/golang.org/x/sys/unix/timestruct.go @@ -9,7 +9,7 @@ package unix import "time" -// TimespecToNSec returns the time stored in ts as nanoseconds. +// TimespecToNsec returns the time stored in ts as nanoseconds. func TimespecToNsec(ts Timespec) int64 { return ts.Nano() } // NsecToTimespec converts a number of nanoseconds into a Timespec. diff --git a/vendor/golang.org/x/sys/unix/xattr_bsd.go b/vendor/golang.org/x/sys/unix/xattr_bsd.go index 25df1e3780..f5f8e9f366 100644 --- a/vendor/golang.org/x/sys/unix/xattr_bsd.go +++ b/vendor/golang.org/x/sys/unix/xattr_bsd.go @@ -36,9 +36,14 @@ func xattrnamespace(fullattr string) (ns int, attr string, err error) { func initxattrdest(dest []byte, idx int) (d unsafe.Pointer) { if len(dest) > idx { return unsafe.Pointer(&dest[idx]) - } else { - return unsafe.Pointer(_zero) } + if dest != nil { + // extattr_get_file and extattr_list_file treat NULL differently from + // a non-NULL pointer of length zero. Preserve the property of nilness, + // even if we can't use dest directly. + return unsafe.Pointer(&_zero) + } + return nil } // FreeBSD and NetBSD implement their own syscalls to handle extended attributes @@ -160,13 +165,12 @@ func Lremovexattr(link string, attr string) (err error) { } func Listxattr(file string, dest []byte) (sz int, err error) { - d := initxattrdest(dest, 0) destsiz := len(dest) // FreeBSD won't allow you to list xattrs from multiple namespaces - s := 0 + s, pos := 0, 0 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { - stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz) + stmp, e := ListxattrNS(file, nsid, dest[pos:]) /* Errors accessing system attrs are ignored so that * we can implement the Linux-like behavior of omitting errors that @@ -175,66 +179,102 @@ func Listxattr(file string, dest []byte) (sz int, err error) { * Linux will still error if we ask for user attributes on a file that * we don't have read permissions on, so don't ignore those errors */ - if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { - continue - } else if e != nil { + if e != nil { + if e == EPERM && nsid != EXTATTR_NAMESPACE_USER { + continue + } return s, e } s += stmp - destsiz -= s - if destsiz < 0 { - destsiz = 0 + pos = s + if pos > destsiz { + pos = destsiz } - d = initxattrdest(dest, s) } return s, nil } -func Flistxattr(fd int, dest []byte) (sz int, err error) { +func ListxattrNS(file string, nsid int, dest []byte) (sz int, err error) { d := initxattrdest(dest, 0) destsiz := len(dest) - s := 0 + s, e := ExtattrListFile(file, nsid, uintptr(d), destsiz) + if e != nil { + return 0, err + } + + return s, nil +} + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + destsiz := len(dest) + + s, pos := 0, 0 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { - stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz) - if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { - continue - } else if e != nil { + stmp, e := FlistxattrNS(fd, nsid, dest[pos:]) + + if e != nil { + if e == EPERM && nsid != EXTATTR_NAMESPACE_USER { + continue + } return s, e } s += stmp - destsiz -= s - if destsiz < 0 { - destsiz = 0 + pos = s + if pos > destsiz { + pos = destsiz } - d = initxattrdest(dest, s) } return s, nil } -func Llistxattr(link string, dest []byte) (sz int, err error) { +func FlistxattrNS(fd int, nsid int, dest []byte) (sz int, err error) { d := initxattrdest(dest, 0) destsiz := len(dest) - s := 0 + s, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz) + if e != nil { + return 0, err + } + + return s, nil +} + +func Llistxattr(link string, dest []byte) (sz int, err error) { + destsiz := len(dest) + + s, pos := 0, 0 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { - stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz) - if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { - continue - } else if e != nil { + stmp, e := LlistxattrNS(link, nsid, dest[pos:]) + + if e != nil { + if e == EPERM && nsid != EXTATTR_NAMESPACE_USER { + continue + } return s, e } s += stmp - destsiz -= s - if destsiz < 0 { - destsiz = 0 + pos = s + if pos > destsiz { + pos = destsiz } - d = initxattrdest(dest, s) + } + + return s, nil +} + +func LlistxattrNS(link string, nsid int, dest []byte) (sz int, err error) { + d := initxattrdest(dest, 0) + destsiz := len(dest) + + s, e := ExtattrListLink(link, nsid, uintptr(d), destsiz) + if e != nil { + return 0, err } return s, nil diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 785d693eb3..398c37e52d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -70,6 +70,7 @@ const ( ALG_SET_DRBG_ENTROPY = 0x6 ALG_SET_IV = 0x2 ALG_SET_KEY = 0x1 + ALG_SET_KEY_BY_KEY_SERIAL = 0x7 ALG_SET_OP = 0x3 ANON_INODE_FS_MAGIC = 0x9041934 ARPHRD_6LOWPAN = 0x339 @@ -457,7 +458,6 @@ const ( B600 = 0x8 B75 = 0x2 B9600 = 0xd - BALLOON_KVM_MAGIC = 0x13661366 BDEVFS_MAGIC = 0x62646576 BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d @@ -563,6 +563,7 @@ const ( BUS_USB = 0x3 BUS_VIRTUAL = 0x6 CAN_BCM = 0x2 + CAN_BUS_OFF_THRESHOLD = 0x100 CAN_CTRLMODE_3_SAMPLES = 0x4 CAN_CTRLMODE_BERR_REPORTING = 0x10 CAN_CTRLMODE_CC_LEN8_DLC = 0x100 @@ -577,9 +578,12 @@ const ( CAN_EFF_FLAG = 0x80000000 CAN_EFF_ID_BITS = 0x1d CAN_EFF_MASK = 0x1fffffff + CAN_ERROR_PASSIVE_THRESHOLD = 0x80 + CAN_ERROR_WARNING_THRESHOLD = 0x60 CAN_ERR_ACK = 0x20 CAN_ERR_BUSERROR = 0x80 CAN_ERR_BUSOFF = 0x40 + CAN_ERR_CNT = 0x200 CAN_ERR_CRTL = 0x4 CAN_ERR_CRTL_ACTIVE = 0x40 CAN_ERR_CRTL_RX_OVERFLOW = 0x1 @@ -771,6 +775,8 @@ const ( DEVLINK_GENL_MCGRP_CONFIG_NAME = "config" DEVLINK_GENL_NAME = "devlink" DEVLINK_GENL_VERSION = 0x1 + DEVLINK_PORT_FN_CAP_MIGRATABLE = 0x2 + DEVLINK_PORT_FN_CAP_ROCE = 0x1 DEVLINK_SB_THRESHOLD_TO_ALPHA_MAX = 0x14 DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS = 0x3 DEVMEM_MAGIC = 0x454d444d @@ -820,9 +826,9 @@ const ( DM_UUID_FLAG = 0x4000 DM_UUID_LEN = 0x81 DM_VERSION = 0xc138fd00 - DM_VERSION_EXTRA = "-ioctl (2022-02-22)" + DM_VERSION_EXTRA = "-ioctl (2022-07-28)" DM_VERSION_MAJOR = 0x4 - DM_VERSION_MINOR = 0x2e + DM_VERSION_MINOR = 0x2f DM_VERSION_PATCHLEVEL = 0x0 DT_BLK = 0x6 DT_CHR = 0x2 @@ -1049,6 +1055,7 @@ const ( ETH_P_CAIF = 0xf7 ETH_P_CAN = 0xc ETH_P_CANFD = 0xd + ETH_P_CANXL = 0xe ETH_P_CFM = 0x8902 ETH_P_CONTROL = 0x16 ETH_P_CUST = 0x6006 @@ -1060,6 +1067,7 @@ const ( ETH_P_DNA_RT = 0x6003 ETH_P_DSA = 0x1b ETH_P_DSA_8021Q = 0xdadb + ETH_P_DSA_A5PSW = 0xe001 ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada ETH_P_ERSPAN = 0x88be @@ -1194,8 +1202,10 @@ const ( FAN_MARK_EVICTABLE = 0x200 FAN_MARK_FILESYSTEM = 0x100 FAN_MARK_FLUSH = 0x80 + FAN_MARK_IGNORE = 0x400 FAN_MARK_IGNORED_MASK = 0x20 FAN_MARK_IGNORED_SURV_MODIFY = 0x40 + FAN_MARK_IGNORE_SURV = 0x440 FAN_MARK_INODE = 0x0 FAN_MARK_MOUNT = 0x10 FAN_MARK_ONLYDIR = 0x8 @@ -1253,7 +1263,10 @@ const ( FSCRYPT_MODE_AES_128_CBC = 0x5 FSCRYPT_MODE_AES_128_CTS = 0x6 FSCRYPT_MODE_AES_256_CTS = 0x4 + FSCRYPT_MODE_AES_256_HCTR2 = 0xa FSCRYPT_MODE_AES_256_XTS = 0x1 + FSCRYPT_MODE_SM4_CTS = 0x8 + FSCRYPT_MODE_SM4_XTS = 0x7 FSCRYPT_POLICY_FLAGS_PAD_16 = 0x2 FSCRYPT_POLICY_FLAGS_PAD_32 = 0x3 FSCRYPT_POLICY_FLAGS_PAD_4 = 0x0 @@ -1272,8 +1285,6 @@ const ( FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 FS_ENCRYPTION_MODE_INVALID = 0x0 - FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 - FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 FS_IOC_ADD_ENCRYPTION_KEY = 0xc0506617 FS_IOC_GET_ENCRYPTION_KEY_STATUS = 0xc080661a FS_IOC_GET_ENCRYPTION_POLICY_EX = 0xc0096616 @@ -1430,6 +1441,7 @@ const ( IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 + IFF_NO_CARRIER = 0x40 IFF_NO_PI = 0x1000 IFF_ONE_QUEUE = 0x2000 IFF_PERSIST = 0x800 @@ -1761,6 +1773,7 @@ const ( LANDLOCK_ACCESS_FS_REFER = 0x2000 LANDLOCK_ACCESS_FS_REMOVE_DIR = 0x10 LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20 + LANDLOCK_ACCESS_FS_TRUNCATE = 0x4000 LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2 LANDLOCK_CREATE_RULESET_VERSION = 0x1 LINUX_REBOOT_CMD_CAD_OFF = 0x0 @@ -1800,11 +1813,13 @@ const ( LWTUNNEL_IP_OPT_GENEVE_MAX = 0x3 LWTUNNEL_IP_OPT_VXLAN_MAX = 0x1 MADV_COLD = 0x14 + MADV_COLLAPSE = 0x19 MADV_DODUMP = 0x11 MADV_DOFORK = 0xb MADV_DONTDUMP = 0x10 MADV_DONTFORK = 0xa MADV_DONTNEED = 0x4 + MADV_DONTNEED_LOCKED = 0x18 MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 @@ -1846,7 +1861,7 @@ const ( MFD_ALLOW_SEALING = 0x2 MFD_CLOEXEC = 0x1 MFD_HUGETLB = 0x4 - MFD_HUGE_16GB = -0x78000000 + MFD_HUGE_16GB = 0x88000000 MFD_HUGE_16MB = 0x60000000 MFD_HUGE_1GB = 0x78000000 MFD_HUGE_1MB = 0x50000000 @@ -2153,6 +2168,7 @@ const ( PACKET_FANOUT_DATA = 0x16 PACKET_FANOUT_EBPF = 0x7 PACKET_FANOUT_FLAG_DEFRAG = 0x8000 + PACKET_FANOUT_FLAG_IGNORE_OUTGOING = 0x4000 PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 PACKET_FANOUT_HASH = 0x0 @@ -2212,6 +2228,11 @@ const ( PERF_AUX_FLAG_PARTIAL = 0x4 PERF_AUX_FLAG_PMU_FORMAT_TYPE_MASK = 0xff00 PERF_AUX_FLAG_TRUNCATED = 0x1 + PERF_BR_ARM64_DEBUG_DATA = 0x7 + PERF_BR_ARM64_DEBUG_EXIT = 0x5 + PERF_BR_ARM64_DEBUG_HALT = 0x4 + PERF_BR_ARM64_DEBUG_INST = 0x6 + PERF_BR_ARM64_FIQ = 0x3 PERF_FLAG_FD_CLOEXEC = 0x8 PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_OUTPUT = 0x2 @@ -2232,6 +2253,8 @@ const ( PERF_MEM_LOCK_NA = 0x1 PERF_MEM_LOCK_SHIFT = 0x18 PERF_MEM_LVLNUM_ANY_CACHE = 0xb + PERF_MEM_LVLNUM_CXL = 0x9 + PERF_MEM_LVLNUM_IO = 0xa PERF_MEM_LVLNUM_L1 = 0x1 PERF_MEM_LVLNUM_L2 = 0x2 PERF_MEM_LVLNUM_L3 = 0x3 @@ -2265,6 +2288,7 @@ const ( PERF_MEM_REMOTE_REMOTE = 0x1 PERF_MEM_REMOTE_SHIFT = 0x25 PERF_MEM_SNOOPX_FWD = 0x1 + PERF_MEM_SNOOPX_PEER = 0x2 PERF_MEM_SNOOPX_SHIFT = 0x26 PERF_MEM_SNOOP_HIT = 0x4 PERF_MEM_SNOOP_HITM = 0x10 @@ -2301,7 +2325,6 @@ const ( PERF_SAMPLE_BRANCH_PLM_ALL = 0x7 PERF_SAMPLE_WEIGHT_TYPE = 0x1004000 PIPEFS_MAGIC = 0x50495045 - PPC_CMM_MAGIC = 0xc7571590 PPPIOCGNPMODE = 0xc008744c PPPIOCNEWUNIT = 0xc004743e PRIO_PGRP = 0x1 @@ -2999,6 +3022,7 @@ const ( STATX_BLOCKS = 0x400 STATX_BTIME = 0x800 STATX_CTIME = 0x80 + STATX_DIOALIGN = 0x2000 STATX_GID = 0x10 STATX_INO = 0x100 STATX_MNT_ID = 0x1000 @@ -3392,9 +3416,7 @@ const ( XDP_ZEROCOPY = 0x4 XENFS_SUPER_MAGIC = 0xabba1974 XFS_SUPER_MAGIC = 0x58465342 - Z3FOLD_MAGIC = 0x33 ZONEFS_MAGIC = 0x5a4f4653 - ZSMALLOC_MAGIC = 0x58295829 _HIDIOCGRAWNAME_LEN = 0x80 _HIDIOCGRAWPHYS_LEN = 0x40 _HIDIOCGRAWUNIQ_LEN = 0x40 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 36c0dfc7c4..a46df0f1e5 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -133,6 +133,7 @@ const ( MEMGETREGIONCOUNT = 0x80044d07 MEMISLOCKED = 0x80084d17 MEMLOCK = 0x40084d05 + MEMREAD = 0xc03c4d1a MEMREADOOB = 0xc00c4d04 MEMSETBADBLOCK = 0x40084d0c MEMUNLOCK = 0x40084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index 4ff942703b..6cd4a3ea9d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -133,6 +133,7 @@ const ( MEMGETREGIONCOUNT = 0x80044d07 MEMISLOCKED = 0x80084d17 MEMLOCK = 0x40084d05 + MEMREAD = 0xc0404d1a MEMREADOOB = 0xc0104d04 MEMSETBADBLOCK = 0x40084d0c MEMUNLOCK = 0x40084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index 3eaa0fb78e..c7ebee24df 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -131,6 +131,7 @@ const ( MEMGETREGIONCOUNT = 0x80044d07 MEMISLOCKED = 0x80084d17 MEMLOCK = 0x40084d05 + MEMREAD = 0xc0404d1a MEMREADOOB = 0xc00c4d04 MEMSETBADBLOCK = 0x40084d0c MEMUNLOCK = 0x40084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index d7995bdc3a..9d5352c3e4 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -134,6 +134,7 @@ const ( MEMGETREGIONCOUNT = 0x80044d07 MEMISLOCKED = 0x80084d17 MEMLOCK = 0x40084d05 + MEMREAD = 0xc0404d1a MEMREADOOB = 0xc0104d04 MEMSETBADBLOCK = 0x40084d0c MEMUNLOCK = 0x40084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 928e24c205..f26a164f4a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -132,6 +132,7 @@ const ( MEMGETREGIONCOUNT = 0x80044d07 MEMISLOCKED = 0x80084d17 MEMLOCK = 0x40084d05 + MEMREAD = 0xc0404d1a MEMREADOOB = 0xc0104d04 MEMSETBADBLOCK = 0x40084d0c MEMUNLOCK = 0x40084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 179bffb474..890bc3c9b7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -131,6 +131,7 @@ const ( MEMGETREGIONCOUNT = 0x40044d07 MEMISLOCKED = 0x40084d17 MEMLOCK = 0x80084d05 + MEMREAD = 0xc0404d1a MEMREADOOB = 0xc00c4d04 MEMSETBADBLOCK = 0x80084d0c MEMUNLOCK = 0x80084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 1fba17bd75..549f26ac64 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -131,6 +131,7 @@ const ( MEMGETREGIONCOUNT = 0x40044d07 MEMISLOCKED = 0x40084d17 MEMLOCK = 0x80084d05 + MEMREAD = 0xc0404d1a MEMREADOOB = 0xc0104d04 MEMSETBADBLOCK = 0x80084d0c MEMUNLOCK = 0x80084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index b77dde3153..e0365e32c1 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -131,6 +131,7 @@ const ( MEMGETREGIONCOUNT = 0x40044d07 MEMISLOCKED = 0x40084d17 MEMLOCK = 0x80084d05 + MEMREAD = 0xc0404d1a MEMREADOOB = 0xc0104d04 MEMSETBADBLOCK = 0x80084d0c MEMUNLOCK = 0x80084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 78c6c751bf..fdccce15ca 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -131,6 +131,7 @@ const ( MEMGETREGIONCOUNT = 0x40044d07 MEMISLOCKED = 0x40084d17 MEMLOCK = 0x80084d05 + MEMREAD = 0xc0404d1a MEMREADOOB = 0xc00c4d04 MEMSETBADBLOCK = 0x80084d0c MEMUNLOCK = 0x80084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index 1c0d31f0b4..b2205c83fa 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -131,6 +131,7 @@ const ( MEMGETREGIONCOUNT = 0x40044d07 MEMISLOCKED = 0x40084d17 MEMLOCK = 0x80084d05 + MEMREAD = 0xc0404d1a MEMREADOOB = 0xc00c4d04 MEMSETBADBLOCK = 0x80084d0c MEMUNLOCK = 0x80084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 959dd9bb8f..81aa5ad0f6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -131,6 +131,7 @@ const ( MEMGETREGIONCOUNT = 0x40044d07 MEMISLOCKED = 0x40084d17 MEMLOCK = 0x80084d05 + MEMREAD = 0xc0404d1a MEMREADOOB = 0xc0104d04 MEMSETBADBLOCK = 0x80084d0c MEMUNLOCK = 0x80084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 5a873cdbc9..76807a1fd4 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -131,6 +131,7 @@ const ( MEMGETREGIONCOUNT = 0x40044d07 MEMISLOCKED = 0x40084d17 MEMLOCK = 0x80084d05 + MEMREAD = 0xc0404d1a MEMREADOOB = 0xc0104d04 MEMSETBADBLOCK = 0x80084d0c MEMUNLOCK = 0x80084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index e336d141e1..d4a5ab9e4e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -131,6 +131,7 @@ const ( MEMGETREGIONCOUNT = 0x80044d07 MEMISLOCKED = 0x80084d17 MEMLOCK = 0x40084d05 + MEMREAD = 0xc0404d1a MEMREADOOB = 0xc0104d04 MEMSETBADBLOCK = 0x40084d0c MEMUNLOCK = 0x40084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 390c01d92a..66e65db951 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -131,6 +131,7 @@ const ( MEMGETREGIONCOUNT = 0x80044d07 MEMISLOCKED = 0x80084d17 MEMLOCK = 0x40084d05 + MEMREAD = 0xc0404d1a MEMREADOOB = 0xc0104d04 MEMSETBADBLOCK = 0x40084d0c MEMUNLOCK = 0x40084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index 98a6e5f11f..f619252691 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -136,6 +136,7 @@ const ( MEMGETREGIONCOUNT = 0x40044d07 MEMISLOCKED = 0x40084d17 MEMLOCK = 0x80084d05 + MEMREAD = 0xc0404d1a MEMREADOOB = 0xc0104d04 MEMSETBADBLOCK = 0x80084d0c MEMUNLOCK = 0x80084d06 diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go index 6d56edc05a..af20e474b3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go @@ -46,6 +46,7 @@ const ( AF_SNA = 0xb AF_UNIX = 0x1 AF_UNSPEC = 0x0 + ALTWERASE = 0x200 ARPHRD_ETHER = 0x1 ARPHRD_FRELAY = 0xf ARPHRD_IEEE1394 = 0x18 @@ -108,6 +109,15 @@ const ( BPF_DIRECTION_IN = 0x1 BPF_DIRECTION_OUT = 0x2 BPF_DIV = 0x30 + BPF_FILDROP_CAPTURE = 0x1 + BPF_FILDROP_DROP = 0x2 + BPF_FILDROP_PASS = 0x0 + BPF_F_DIR_IN = 0x10 + BPF_F_DIR_MASK = 0x30 + BPF_F_DIR_OUT = 0x20 + BPF_F_DIR_SHIFT = 0x4 + BPF_F_FLOWID = 0x8 + BPF_F_PRI_MASK = 0x7 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -136,6 +146,7 @@ const ( BPF_OR = 0x40 BPF_RELEASE = 0x30bb6 BPF_RET = 0x6 + BPF_RND = 0xc0 BPF_RSH = 0x70 BPF_ST = 0x2 BPF_STX = 0x3 @@ -147,6 +158,12 @@ const ( BRKINT = 0x2 CFLUSH = 0xf CLOCAL = 0x8000 + CLOCK_BOOTTIME = 0x6 + CLOCK_MONOTONIC = 0x3 + CLOCK_PROCESS_CPUTIME_ID = 0x2 + CLOCK_REALTIME = 0x0 + CLOCK_THREAD_CPUTIME_ID = 0x4 + CLOCK_UPTIME = 0x5 CPUSTATES = 0x6 CP_IDLE = 0x5 CP_INTR = 0x4 @@ -170,7 +187,65 @@ const ( CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 + DIOCADDQUEUE = 0xc100445d + DIOCADDRULE = 0xccc84404 + DIOCADDSTATE = 0xc1084425 + DIOCCHANGERULE = 0xccc8441a + DIOCCLRIFFLAG = 0xc024445a + DIOCCLRSRCNODES = 0x20004455 + DIOCCLRSTATES = 0xc0d04412 + DIOCCLRSTATUS = 0xc0244416 + DIOCGETLIMIT = 0xc0084427 + DIOCGETQSTATS = 0xc1084460 + DIOCGETQUEUE = 0xc100445f + DIOCGETQUEUES = 0xc100445e + DIOCGETRULE = 0xccc84407 + DIOCGETRULES = 0xccc84406 + DIOCGETRULESET = 0xc444443b + DIOCGETRULESETS = 0xc444443a + DIOCGETSRCNODES = 0xc0084454 + DIOCGETSTATE = 0xc1084413 + DIOCGETSTATES = 0xc0084419 + DIOCGETSTATUS = 0xc1e84415 + DIOCGETSYNFLWATS = 0xc0084463 + DIOCGETTIMEOUT = 0xc008441e + DIOCIGETIFACES = 0xc0244457 + DIOCKILLSRCNODES = 0xc068445b + DIOCKILLSTATES = 0xc0d04429 + DIOCNATLOOK = 0xc0504417 + DIOCOSFPADD = 0xc084444f DIOCOSFPFLUSH = 0x2000444e + DIOCOSFPGET = 0xc0844450 + DIOCRADDADDRS = 0xc44c4443 + DIOCRADDTABLES = 0xc44c443d + DIOCRCLRADDRS = 0xc44c4442 + DIOCRCLRASTATS = 0xc44c4448 + DIOCRCLRTABLES = 0xc44c443c + DIOCRCLRTSTATS = 0xc44c4441 + DIOCRDELADDRS = 0xc44c4444 + DIOCRDELTABLES = 0xc44c443e + DIOCRGETADDRS = 0xc44c4446 + DIOCRGETASTATS = 0xc44c4447 + DIOCRGETTABLES = 0xc44c443f + DIOCRGETTSTATS = 0xc44c4440 + DIOCRINADEFINE = 0xc44c444d + DIOCRSETADDRS = 0xc44c4445 + DIOCRSETTFLAGS = 0xc44c444a + DIOCRTSTADDRS = 0xc44c4449 + DIOCSETDEBUG = 0xc0044418 + DIOCSETHOSTID = 0xc0044456 + DIOCSETIFFLAG = 0xc0244459 + DIOCSETLIMIT = 0xc0084428 + DIOCSETREASS = 0xc004445c + DIOCSETSTATUSIF = 0xc0244414 + DIOCSETSYNCOOKIES = 0xc0014462 + DIOCSETSYNFLWATS = 0xc0084461 + DIOCSETTIMEOUT = 0xc008441d + DIOCSTART = 0x20004401 + DIOCSTOP = 0x20004402 + DIOCXBEGIN = 0xc00c4451 + DIOCXCOMMIT = 0xc00c4452 + DIOCXROLLBACK = 0xc00c4453 DLT_ARCNET = 0x7 DLT_ATM_RFC1483 = 0xb DLT_AX25 = 0x3 @@ -186,6 +261,7 @@ const ( DLT_LOOP = 0xc DLT_MPLS = 0xdb DLT_NULL = 0x0 + DLT_OPENFLOW = 0x10b DLT_PFLOG = 0x75 DLT_PFSYNC = 0x12 DLT_PPP = 0x9 @@ -196,6 +272,23 @@ const ( DLT_RAW = 0xe DLT_SLIP = 0x8 DLT_SLIP_BSDOS = 0xf + DLT_USBPCAP = 0xf9 + DLT_USER0 = 0x93 + DLT_USER1 = 0x94 + DLT_USER10 = 0x9d + DLT_USER11 = 0x9e + DLT_USER12 = 0x9f + DLT_USER13 = 0xa0 + DLT_USER14 = 0xa1 + DLT_USER15 = 0xa2 + DLT_USER2 = 0x95 + DLT_USER3 = 0x96 + DLT_USER4 = 0x97 + DLT_USER5 = 0x98 + DLT_USER6 = 0x99 + DLT_USER7 = 0x9a + DLT_USER8 = 0x9b + DLT_USER9 = 0x9c DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -215,6 +308,8 @@ const ( EMUL_ENABLED = 0x1 EMUL_NATIVE = 0x2 ENDRUNDISC = 0x9 + ETH64_8021_RSVD_MASK = 0xfffffffffff0 + ETH64_8021_RSVD_PREFIX = 0x180c2000000 ETHERMIN = 0x2e ETHERMTU = 0x5dc ETHERTYPE_8023 = 0x4 @@ -267,6 +362,7 @@ const ( ETHERTYPE_DN = 0x6003 ETHERTYPE_DOGFIGHT = 0x1989 ETHERTYPE_DSMD = 0x8039 + ETHERTYPE_EAPOL = 0x888e ETHERTYPE_ECMA = 0x803 ETHERTYPE_ENCRYPT = 0x803d ETHERTYPE_ES = 0x805d @@ -298,6 +394,7 @@ const ( ETHERTYPE_LLDP = 0x88cc ETHERTYPE_LOGICRAFT = 0x8148 ETHERTYPE_LOOPBACK = 0x9000 + ETHERTYPE_MACSEC = 0x88e5 ETHERTYPE_MATRA = 0x807a ETHERTYPE_MAX = 0xffff ETHERTYPE_MERIT = 0x807c @@ -326,15 +423,17 @@ const ( ETHERTYPE_NCD = 0x8149 ETHERTYPE_NESTAR = 0x8006 ETHERTYPE_NETBEUI = 0x8191 + ETHERTYPE_NHRP = 0x2001 ETHERTYPE_NOVELL = 0x8138 ETHERTYPE_NS = 0x600 ETHERTYPE_NSAT = 0x601 ETHERTYPE_NSCOMPAT = 0x807 + ETHERTYPE_NSH = 0x984f ETHERTYPE_NTRAILER = 0x10 ETHERTYPE_OS9 = 0x7007 ETHERTYPE_OS9NET = 0x7009 ETHERTYPE_PACER = 0x80c6 - ETHERTYPE_PAE = 0x888e + ETHERTYPE_PBB = 0x88e7 ETHERTYPE_PCS = 0x4242 ETHERTYPE_PLANNING = 0x8044 ETHERTYPE_PPP = 0x880b @@ -409,28 +508,40 @@ const ( ETHER_CRC_POLY_LE = 0xedb88320 ETHER_HDR_LEN = 0xe ETHER_MAX_DIX_LEN = 0x600 + ETHER_MAX_HARDMTU_LEN = 0xff9b ETHER_MAX_LEN = 0x5ee ETHER_MIN_LEN = 0x40 ETHER_TYPE_LEN = 0x2 ETHER_VLAN_ENCAP_LEN = 0x4 EVFILT_AIO = -0x3 + EVFILT_DEVICE = -0x8 + EVFILT_EXCEPT = -0x9 EVFILT_PROC = -0x5 EVFILT_READ = -0x1 EVFILT_SIGNAL = -0x6 - EVFILT_SYSCOUNT = 0x7 + EVFILT_SYSCOUNT = 0x9 EVFILT_TIMER = -0x7 EVFILT_VNODE = -0x4 EVFILT_WRITE = -0x2 + EVL_ENCAPLEN = 0x4 + EVL_PRIO_BITS = 0xd + EVL_PRIO_MAX = 0x7 + EVL_VLID_MASK = 0xfff + EVL_VLID_MAX = 0xffe + EVL_VLID_MIN = 0x1 + EVL_VLID_NULL = 0x0 EV_ADD = 0x1 EV_CLEAR = 0x20 EV_DELETE = 0x2 EV_DISABLE = 0x8 + EV_DISPATCH = 0x80 EV_ENABLE = 0x4 EV_EOF = 0x8000 EV_ERROR = 0x4000 EV_FLAG1 = 0x2000 EV_ONESHOT = 0x10 - EV_SYSFLAGS = 0xf000 + EV_RECEIPT = 0x40 + EV_SYSFLAGS = 0xf800 EXTA = 0x4b00 EXTB = 0x9600 EXTPROC = 0x800 @@ -443,6 +554,7 @@ const ( F_GETFL = 0x3 F_GETLK = 0x7 F_GETOWN = 0x5 + F_ISATTY = 0xb F_OK = 0x0 F_RDLCK = 0x1 F_SETFD = 0x2 @@ -460,7 +572,6 @@ const ( IEXTEN = 0x400 IFAN_ARRIVAL = 0x0 IFAN_DEPARTURE = 0x1 - IFA_ROUTE = 0x1 IFF_ALLMULTI = 0x200 IFF_BROADCAST = 0x2 IFF_CANTCHANGE = 0x8e52 @@ -471,12 +582,12 @@ const ( IFF_LOOPBACK = 0x8 IFF_MULTICAST = 0x8000 IFF_NOARP = 0x80 - IFF_NOTRAILERS = 0x20 IFF_OACTIVE = 0x400 IFF_POINTOPOINT = 0x10 IFF_PROMISC = 0x100 IFF_RUNNING = 0x40 IFF_SIMPLEX = 0x800 + IFF_STATICARP = 0x20 IFF_UP = 0x1 IFNAMSIZ = 0x10 IFT_1822 = 0x2 @@ -605,6 +716,7 @@ const ( IFT_LINEGROUP = 0xd2 IFT_LOCALTALK = 0x2a IFT_LOOP = 0x18 + IFT_MBIM = 0xfa IFT_MEDIAMAILOVERIP = 0x8b IFT_MFSIGLINK = 0xa7 IFT_MIOX25 = 0x26 @@ -695,6 +807,7 @@ const ( IFT_VOICEOVERCABLE = 0xc6 IFT_VOICEOVERFRAMERELAY = 0x99 IFT_VOICEOVERIP = 0x68 + IFT_WIREGUARD = 0xfb IFT_X213 = 0x5d IFT_X25 = 0x5 IFT_X25DDN = 0x4 @@ -729,8 +842,6 @@ const ( IPPROTO_AH = 0x33 IPPROTO_CARP = 0x70 IPPROTO_DIVERT = 0x102 - IPPROTO_DIVERT_INIT = 0x2 - IPPROTO_DIVERT_RESP = 0x1 IPPROTO_DONE = 0x101 IPPROTO_DSTOPTS = 0x3c IPPROTO_EGP = 0x8 @@ -762,9 +873,11 @@ const ( IPPROTO_RAW = 0xff IPPROTO_ROUTING = 0x2b IPPROTO_RSVP = 0x2e + IPPROTO_SCTP = 0x84 IPPROTO_TCP = 0x6 IPPROTO_TP = 0x1d IPPROTO_UDP = 0x11 + IPPROTO_UDPLITE = 0x88 IPV6_AUTH_LEVEL = 0x35 IPV6_AUTOFLOWLABEL = 0x3b IPV6_CHECKSUM = 0x1a @@ -787,6 +900,7 @@ const ( IPV6_LEAVE_GROUP = 0xd IPV6_MAXHLIM = 0xff IPV6_MAXPACKET = 0xffff + IPV6_MINHOPCOUNT = 0x41 IPV6_MMTU = 0x500 IPV6_MULTICAST_HOPS = 0xa IPV6_MULTICAST_IF = 0x9 @@ -826,12 +940,12 @@ const ( IP_DEFAULT_MULTICAST_LOOP = 0x1 IP_DEFAULT_MULTICAST_TTL = 0x1 IP_DF = 0x4000 - IP_DIVERTFL = 0x1022 IP_DROP_MEMBERSHIP = 0xd IP_ESP_NETWORK_LEVEL = 0x16 IP_ESP_TRANS_LEVEL = 0x15 IP_HDRINCL = 0x2 IP_IPCOMP_LEVEL = 0x1d + IP_IPDEFTTL = 0x25 IP_IPSECFLOWINFO = 0x24 IP_IPSEC_LOCAL_AUTH = 0x1b IP_IPSEC_LOCAL_CRED = 0x19 @@ -865,10 +979,15 @@ const ( IP_RETOPTS = 0x8 IP_RF = 0x8000 IP_RTABLE = 0x1021 + IP_SENDSRCADDR = 0x7 IP_TOS = 0x3 IP_TTL = 0x4 ISIG = 0x80 ISTRIP = 0x20 + ITIMER_PROF = 0x2 + ITIMER_REAL = 0x0 + ITIMER_VIRTUAL = 0x1 + IUCLC = 0x1000 IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 @@ -900,10 +1019,11 @@ const ( MAP_INHERIT_COPY = 0x1 MAP_INHERIT_NONE = 0x2 MAP_INHERIT_SHARE = 0x0 - MAP_NOEXTEND = 0x100 - MAP_NORESERVE = 0x40 + MAP_INHERIT_ZERO = 0x3 + MAP_NOEXTEND = 0x0 + MAP_NORESERVE = 0x0 MAP_PRIVATE = 0x2 - MAP_RENAME = 0x20 + MAP_RENAME = 0x0 MAP_SHARED = 0x1 MAP_STACK = 0x4000 MAP_TRYFIXED = 0x0 @@ -922,6 +1042,7 @@ const ( MNT_NOATIME = 0x8000 MNT_NODEV = 0x10 MNT_NOEXEC = 0x4 + MNT_NOPERM = 0x20 MNT_NOSUID = 0x8 MNT_NOWAIT = 0x2 MNT_QUOTA = 0x2000 @@ -929,13 +1050,29 @@ const ( MNT_RELOAD = 0x40000 MNT_ROOTFS = 0x4000 MNT_SOFTDEP = 0x4000000 + MNT_STALLED = 0x100000 + MNT_SWAPPABLE = 0x200000 MNT_SYNCHRONOUS = 0x2 MNT_UPDATE = 0x10000 MNT_VISFLAGMASK = 0x400ffff MNT_WAIT = 0x1 MNT_WANTRDWR = 0x2000000 MNT_WXALLOWED = 0x800 + MOUNT_AFS = "afs" + MOUNT_CD9660 = "cd9660" + MOUNT_EXT2FS = "ext2fs" + MOUNT_FFS = "ffs" + MOUNT_FUSEFS = "fuse" + MOUNT_MFS = "mfs" + MOUNT_MSDOS = "msdos" + MOUNT_NCPFS = "ncpfs" + MOUNT_NFS = "nfs" + MOUNT_NTFS = "ntfs" + MOUNT_TMPFS = "tmpfs" + MOUNT_UDF = "udf" + MOUNT_UFS = "ffs" MSG_BCAST = 0x100 + MSG_CMSG_CLOEXEC = 0x800 MSG_CTRUNC = 0x20 MSG_DONTROUTE = 0x4 MSG_DONTWAIT = 0x80 @@ -946,6 +1083,7 @@ const ( MSG_PEEK = 0x2 MSG_TRUNC = 0x10 MSG_WAITALL = 0x40 + MSG_WAITFORONE = 0x1000 MS_ASYNC = 0x1 MS_INVALIDATE = 0x4 MS_SYNC = 0x2 @@ -953,12 +1091,16 @@ const ( NET_RT_DUMP = 0x1 NET_RT_FLAGS = 0x2 NET_RT_IFLIST = 0x3 - NET_RT_MAXID = 0x6 + NET_RT_IFNAMES = 0x6 + NET_RT_MAXID = 0x8 + NET_RT_SOURCE = 0x7 NET_RT_STATS = 0x4 NET_RT_TABLE = 0x5 NFDBITS = 0x20 NOFLSH = 0x80000000 + NOKERNINFO = 0x2000000 NOTE_ATTRIB = 0x8 + NOTE_CHANGE = 0x1 NOTE_CHILD = 0x4 NOTE_DELETE = 0x1 NOTE_EOF = 0x2 @@ -968,6 +1110,7 @@ const ( NOTE_FORK = 0x40000000 NOTE_LINK = 0x10 NOTE_LOWAT = 0x1 + NOTE_OOB = 0x4 NOTE_PCTRLMASK = 0xf0000000 NOTE_PDATAMASK = 0xfffff NOTE_RENAME = 0x20 @@ -977,11 +1120,13 @@ const ( NOTE_TRUNCATE = 0x80 NOTE_WRITE = 0x2 OCRNL = 0x10 + OLCUC = 0x20 ONLCR = 0x2 ONLRET = 0x80 ONOCR = 0x40 ONOEOT = 0x8 OPOST = 0x1 + OXTABS = 0x4 O_ACCMODE = 0x3 O_APPEND = 0x8 O_ASYNC = 0x40 @@ -1015,7 +1160,6 @@ const ( PROT_NONE = 0x0 PROT_READ = 0x1 PROT_WRITE = 0x2 - PT_MASK = 0x3ff000 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 RLIMIT_DATA = 0x2 @@ -1027,19 +1171,25 @@ const ( RLIMIT_STACK = 0x3 RLIM_INFINITY = 0x7fffffffffffffff RTAX_AUTHOR = 0x6 + RTAX_BFD = 0xb RTAX_BRD = 0x7 + RTAX_DNS = 0xc RTAX_DST = 0x0 RTAX_GATEWAY = 0x1 RTAX_GENMASK = 0x3 RTAX_IFA = 0x5 RTAX_IFP = 0x4 RTAX_LABEL = 0xa - RTAX_MAX = 0xb + RTAX_MAX = 0xf RTAX_NETMASK = 0x2 + RTAX_SEARCH = 0xe RTAX_SRC = 0x8 RTAX_SRCMASK = 0x9 + RTAX_STATIC = 0xd RTA_AUTHOR = 0x40 + RTA_BFD = 0x800 RTA_BRD = 0x80 + RTA_DNS = 0x1000 RTA_DST = 0x1 RTA_GATEWAY = 0x2 RTA_GENMASK = 0x8 @@ -1047,49 +1197,57 @@ const ( RTA_IFP = 0x10 RTA_LABEL = 0x400 RTA_NETMASK = 0x4 + RTA_SEARCH = 0x4000 RTA_SRC = 0x100 RTA_SRCMASK = 0x200 + RTA_STATIC = 0x2000 RTF_ANNOUNCE = 0x4000 + RTF_BFD = 0x1000000 RTF_BLACKHOLE = 0x1000 + RTF_BROADCAST = 0x400000 + RTF_CACHED = 0x20000 RTF_CLONED = 0x10000 RTF_CLONING = 0x100 + RTF_CONNECTED = 0x800000 RTF_DONE = 0x40 RTF_DYNAMIC = 0x10 - RTF_FMASK = 0x10f808 + RTF_FMASK = 0x110fc08 RTF_GATEWAY = 0x2 RTF_HOST = 0x4 RTF_LLINFO = 0x400 - RTF_MASK = 0x80 + RTF_LOCAL = 0x200000 RTF_MODIFIED = 0x20 RTF_MPATH = 0x40000 RTF_MPLS = 0x100000 + RTF_MULTICAST = 0x200 RTF_PERMANENT_ARP = 0x2000 RTF_PROTO1 = 0x8000 RTF_PROTO2 = 0x4000 RTF_PROTO3 = 0x2000 RTF_REJECT = 0x8 - RTF_SOURCE = 0x20000 RTF_STATIC = 0x800 - RTF_TUNNEL = 0x100000 RTF_UP = 0x1 RTF_USETRAILERS = 0x8000 - RTF_XRESOLVE = 0x200 + RTM_80211INFO = 0x15 RTM_ADD = 0x1 + RTM_BFD = 0x12 RTM_CHANGE = 0x3 + RTM_CHGADDRATTR = 0x14 RTM_DELADDR = 0xd RTM_DELETE = 0x2 RTM_DESYNC = 0x10 RTM_GET = 0x4 RTM_IFANNOUNCE = 0xf RTM_IFINFO = 0xe - RTM_LOCK = 0x8 + RTM_INVALIDATE = 0x11 RTM_LOSING = 0x5 RTM_MAXSIZE = 0x800 RTM_MISS = 0x7 RTM_NEWADDR = 0xc + RTM_PROPOSAL = 0x13 RTM_REDIRECT = 0x6 RTM_RESOLVE = 0xb - RTM_RTTUNIT = 0xf4240 + RTM_SOURCE = 0x16 RTM_VERSION = 0x5 RTV_EXPIRE = 0x4 RTV_HOPCOUNT = 0x2 @@ -1099,67 +1257,74 @@ const ( RTV_RTTVAR = 0x80 RTV_SPIPE = 0x10 RTV_SSTHRESH = 0x20 + RT_TABLEID_BITS = 0x8 + RT_TABLEID_MASK = 0xff RT_TABLEID_MAX = 0xff RUSAGE_CHILDREN = -0x1 RUSAGE_SELF = 0x0 RUSAGE_THREAD = 0x1 SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x4 + SEEK_CUR = 0x1 + SEEK_END = 0x2 + SEEK_SET = 0x0 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 SIOCADDMULTI = 0x80206931 SIOCAIFADDR = 0x8040691a SIOCAIFGROUP = 0x80246987 - SIOCALIFADDR = 0x8218691c SIOCATMARK = 0x40047307 - SIOCBRDGADD = 0x8054693c - SIOCBRDGADDS = 0x80546941 - SIOCBRDGARL = 0x806e694d + SIOCBRDGADD = 0x805c693c + SIOCBRDGADDL = 0x805c6949 + SIOCBRDGADDS = 0x805c6941 + SIOCBRDGARL = 0x808c694d SIOCBRDGDADDR = 0x81286947 - SIOCBRDGDEL = 0x8054693d - SIOCBRDGDELS = 0x80546942 - SIOCBRDGFLUSH = 0x80546948 - SIOCBRDGFRL = 0x806e694e + SIOCBRDGDEL = 0x805c693d + SIOCBRDGDELS = 0x805c6942 + SIOCBRDGFLUSH = 0x805c6948 + SIOCBRDGFRL = 0x808c694e SIOCBRDGGCACHE = 0xc0146941 SIOCBRDGGFD = 0xc0146952 SIOCBRDGGHT = 0xc0146951 - SIOCBRDGGIFFLGS = 0xc054693e + SIOCBRDGGIFFLGS = 0xc05c693e SIOCBRDGGMA = 0xc0146953 SIOCBRDGGPARAM = 0xc03c6958 SIOCBRDGGPRI = 0xc0146950 SIOCBRDGGRL = 0xc028694f - SIOCBRDGGSIFS = 0xc054693c SIOCBRDGGTO = 0xc0146946 - SIOCBRDGIFS = 0xc0546942 + SIOCBRDGIFS = 0xc05c6942 SIOCBRDGRTS = 0xc0186943 SIOCBRDGSADDR = 0xc1286944 SIOCBRDGSCACHE = 0x80146940 SIOCBRDGSFD = 0x80146952 SIOCBRDGSHT = 0x80146951 - SIOCBRDGSIFCOST = 0x80546955 - SIOCBRDGSIFFLGS = 0x8054693f - SIOCBRDGSIFPRIO = 0x80546954 + SIOCBRDGSIFCOST = 0x805c6955 + SIOCBRDGSIFFLGS = 0x805c693f + SIOCBRDGSIFPRIO = 0x805c6954 + SIOCBRDGSIFPROT = 0x805c694a SIOCBRDGSMA = 0x80146953 SIOCBRDGSPRI = 0x80146950 SIOCBRDGSPROTO = 0x8014695a SIOCBRDGSTO = 0x80146945 SIOCBRDGSTXHC = 0x80146959 + SIOCDELLABEL = 0x80206997 SIOCDELMULTI = 0x80206932 SIOCDIFADDR = 0x80206919 SIOCDIFGROUP = 0x80246989 + SIOCDIFPARENT = 0x802069b4 SIOCDIFPHYADDR = 0x80206949 - SIOCDLIFADDR = 0x8218691e + SIOCDPWE3NEIGHBOR = 0x802069de + SIOCDVNETID = 0x802069af SIOCGETKALIVE = 0xc01869a4 SIOCGETLABEL = 0x8020699a + SIOCGETMPWCFG = 0xc02069ae SIOCGETPFLOW = 0xc02069fe SIOCGETPFSYNC = 0xc02069f8 SIOCGETSGCNT = 0xc0147534 SIOCGETVIFCNT = 0xc0147533 SIOCGETVLAN = 0xc0206990 - SIOCGHIWAT = 0x40047301 SIOCGIFADDR = 0xc0206921 - SIOCGIFASYNCMAP = 0xc020697c SIOCGIFBRDADDR = 0xc0206923 SIOCGIFCONF = 0xc0086924 SIOCGIFDATA = 0xc020691b @@ -1168,40 +1333,53 @@ const ( SIOCGIFFLAGS = 0xc0206911 SIOCGIFGATTR = 0xc024698b SIOCGIFGENERIC = 0xc020693a + SIOCGIFGLIST = 0xc024698d SIOCGIFGMEMB = 0xc024698a SIOCGIFGROUP = 0xc0246988 SIOCGIFHARDMTU = 0xc02069a5 - SIOCGIFMEDIA = 0xc0286936 + SIOCGIFLLPRIO = 0xc02069b6 + SIOCGIFMEDIA = 0xc0386938 SIOCGIFMETRIC = 0xc0206917 SIOCGIFMTU = 0xc020697e SIOCGIFNETMASK = 0xc0206925 - SIOCGIFPDSTADDR = 0xc0206948 + SIOCGIFPAIR = 0xc02069b1 + SIOCGIFPARENT = 0xc02069b3 SIOCGIFPRIORITY = 0xc020699c - SIOCGIFPSRCADDR = 0xc0206947 SIOCGIFRDOMAIN = 0xc02069a0 SIOCGIFRTLABEL = 0xc0206983 - SIOCGIFTIMESLOT = 0xc0206986 + SIOCGIFRXR = 0x802069aa + SIOCGIFSFFPAGE = 0xc1126939 SIOCGIFXFLAGS = 0xc020699e - SIOCGLIFADDR = 0xc218691d SIOCGLIFPHYADDR = 0xc218694b + SIOCGLIFPHYDF = 0xc02069c2 + SIOCGLIFPHYECN = 0xc02069c8 SIOCGLIFPHYRTABLE = 0xc02069a2 SIOCGLIFPHYTTL = 0xc02069a9 - SIOCGLOWAT = 0x40047303 SIOCGPGRP = 0x40047309 + SIOCGPWE3 = 0xc0206998 + SIOCGPWE3CTRLWORD = 0xc02069dc + SIOCGPWE3FAT = 0xc02069dd + SIOCGPWE3NEIGHBOR = 0xc21869de + SIOCGRXHPRIO = 0xc02069db SIOCGSPPPPARAMS = 0xc0206994 + SIOCGTXHPRIO = 0xc02069c6 + SIOCGUMBINFO = 0xc02069be + SIOCGUMBPARAM = 0xc02069c0 SIOCGVH = 0xc02069f6 + SIOCGVNETFLOWID = 0xc02069c4 SIOCGVNETID = 0xc02069a7 + SIOCIFAFATTACH = 0x801169ab + SIOCIFAFDETACH = 0x801169ac SIOCIFCREATE = 0x8020697a SIOCIFDESTROY = 0x80206979 SIOCIFGCLONERS = 0xc00c6978 SIOCSETKALIVE = 0x801869a3 SIOCSETLABEL = 0x80206999 + SIOCSETMPWCFG = 0x802069ad SIOCSETPFLOW = 0x802069fd SIOCSETPFSYNC = 0x802069f7 SIOCSETVLAN = 0x8020698f - SIOCSHIWAT = 0x80047300 SIOCSIFADDR = 0x8020690c - SIOCSIFASYNCMAP = 0x8020697d SIOCSIFBRDADDR = 0x80206913 SIOCSIFDESCR = 0x80206980 SIOCSIFDSTADDR = 0x8020690e @@ -1209,25 +1387,37 @@ const ( SIOCSIFGATTR = 0x8024698c SIOCSIFGENERIC = 0x80206939 SIOCSIFLLADDR = 0x8020691f - SIOCSIFMEDIA = 0xc0206935 + SIOCSIFLLPRIO = 0x802069b5 + SIOCSIFMEDIA = 0xc0206937 SIOCSIFMETRIC = 0x80206918 SIOCSIFMTU = 0x8020697f SIOCSIFNETMASK = 0x80206916 - SIOCSIFPHYADDR = 0x80406946 + SIOCSIFPAIR = 0x802069b0 + SIOCSIFPARENT = 0x802069b2 SIOCSIFPRIORITY = 0x8020699b SIOCSIFRDOMAIN = 0x8020699f SIOCSIFRTLABEL = 0x80206982 - SIOCSIFTIMESLOT = 0x80206985 SIOCSIFXFLAGS = 0x8020699d SIOCSLIFPHYADDR = 0x8218694a + SIOCSLIFPHYDF = 0x802069c1 + SIOCSLIFPHYECN = 0x802069c7 SIOCSLIFPHYRTABLE = 0x802069a1 SIOCSLIFPHYTTL = 0x802069a8 - SIOCSLOWAT = 0x80047302 SIOCSPGRP = 0x80047308 + SIOCSPWE3CTRLWORD = 0x802069dc + SIOCSPWE3FAT = 0x802069dd + SIOCSPWE3NEIGHBOR = 0x821869de + SIOCSRXHPRIO = 0x802069db SIOCSSPPPPARAMS = 0x80206993 + SIOCSTXHPRIO = 0x802069c5 + SIOCSUMBPARAM = 0x802069bf SIOCSVH = 0xc02069f5 + SIOCSVNETFLOWID = 0x802069c3 SIOCSVNETID = 0x802069a6 + SOCK_CLOEXEC = 0x8000 SOCK_DGRAM = 0x2 + SOCK_DNS = 0x1000 + SOCK_NONBLOCK = 0x4000 SOCK_RAW = 0x3 SOCK_RDM = 0x4 SOCK_SEQPACKET = 0x5 @@ -1238,6 +1428,7 @@ const ( SO_BINDANY = 0x1000 SO_BROADCAST = 0x20 SO_DEBUG = 0x1 + SO_DOMAIN = 0x1024 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 SO_KEEPALIVE = 0x8 @@ -1245,6 +1436,7 @@ const ( SO_NETPROC = 0x1020 SO_OOBINLINE = 0x100 SO_PEERCRED = 0x1022 + SO_PROTOCOL = 0x1025 SO_RCVBUF = 0x1002 SO_RCVLOWAT = 0x1004 SO_RCVTIMEO = 0x1006 @@ -1258,6 +1450,7 @@ const ( SO_TIMESTAMP = 0x800 SO_TYPE = 0x1008 SO_USELOOPBACK = 0x40 + SO_ZEROIZE = 0x2000 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1287,9 +1480,24 @@ const ( S_IXOTH = 0x1 S_IXUSR = 0x40 TCIFLUSH = 0x1 + TCIOFF = 0x3 TCIOFLUSH = 0x3 + TCION = 0x4 TCOFLUSH = 0x2 - TCP_MAXBURST = 0x4 + TCOOFF = 0x1 + TCOON = 0x2 + TCPOPT_EOL = 0x0 + TCPOPT_MAXSEG = 0x2 + TCPOPT_NOP = 0x1 + TCPOPT_SACK = 0x5 + TCPOPT_SACK_HDR = 0x1010500 + TCPOPT_SACK_PERMITTED = 0x4 + TCPOPT_SACK_PERMIT_HDR = 0x1010402 + TCPOPT_SIGNATURE = 0x13 + TCPOPT_TIMESTAMP = 0x8 + TCPOPT_TSTAMP_HDR = 0x101080a + TCPOPT_WINDOW = 0x3 + TCP_INFO = 0x9 TCP_MAXSEG = 0x2 TCP_MAXWIN = 0xffff TCP_MAX_SACK = 0x3 @@ -1298,11 +1506,15 @@ const ( TCP_MSS = 0x200 TCP_NODELAY = 0x1 TCP_NOPUSH = 0x10 - TCP_NSTATES = 0xb + TCP_SACKHOLE_LIMIT = 0x80 TCP_SACK_ENABLE = 0x8 TCSAFLUSH = 0x2 + TIMER_ABSTIME = 0x1 + TIMER_RELTIME = 0x0 TIOCCBRK = 0x2000747a TIOCCDTR = 0x20007478 + TIOCCHKVERAUTH = 0x2000741e + TIOCCLRVERAUTH = 0x2000741d TIOCCONS = 0x80047462 TIOCDRAIN = 0x2000745e TIOCEXCL = 0x2000740d @@ -1357,17 +1569,21 @@ const ( TIOCSETAF = 0x802c7416 TIOCSETAW = 0x802c7415 TIOCSETD = 0x8004741b + TIOCSETVERAUTH = 0x8004741c TIOCSFLAGS = 0x8004745c TIOCSIG = 0x8004745f TIOCSPGRP = 0x80047476 TIOCSTART = 0x2000746e - TIOCSTAT = 0x80047465 - TIOCSTI = 0x80017472 + TIOCSTAT = 0x20007465 TIOCSTOP = 0x2000746f TIOCSTSTAMP = 0x8008745a TIOCSWINSZ = 0x80087467 TIOCUCNTL = 0x80047466 + TIOCUCNTL_CBRK = 0x7a + TIOCUCNTL_SBRK = 0x7b TOSTOP = 0x400000 + UTIME_NOW = -0x2 + UTIME_OMIT = -0x1 VDISCARD = 0xf VDSUSP = 0xb VEOF = 0x0 @@ -1378,6 +1594,19 @@ const ( VKILL = 0x5 VLNEXT = 0xe VMIN = 0x10 + VM_ANONMIN = 0x7 + VM_LOADAVG = 0x2 + VM_MALLOC_CONF = 0xc + VM_MAXID = 0xd + VM_MAXSLP = 0xa + VM_METER = 0x1 + VM_NKMEMPAGES = 0x6 + VM_PSSTRINGS = 0x3 + VM_SWAPENCRYPT = 0x5 + VM_USPACE = 0xb + VM_UVMEXP = 0x4 + VM_VNODEMIN = 0x9 + VM_VTEXTMIN = 0x8 VQUIT = 0x9 VREPRINT = 0x6 VSTART = 0xc @@ -1390,8 +1619,8 @@ const ( WCONTINUED = 0x8 WCOREFLAG = 0x80 WNOHANG = 0x1 - WSTOPPED = 0x7f WUNTRACED = 0x2 + XCASE = 0x1000000 ) // Errors @@ -1405,6 +1634,7 @@ const ( EALREADY = syscall.Errno(0x25) EAUTH = syscall.Errno(0x50) EBADF = syscall.Errno(0x9) + EBADMSG = syscall.Errno(0x5c) EBADRPC = syscall.Errno(0x48) EBUSY = syscall.Errno(0x10) ECANCELED = syscall.Errno(0x58) @@ -1431,7 +1661,7 @@ const ( EIPSEC = syscall.Errno(0x52) EISCONN = syscall.Errno(0x38) EISDIR = syscall.Errno(0x15) - ELAST = syscall.Errno(0x5b) + ELAST = syscall.Errno(0x5f) ELOOP = syscall.Errno(0x3e) EMEDIUMTYPE = syscall.Errno(0x56) EMFILE = syscall.Errno(0x18) @@ -1459,12 +1689,14 @@ const ( ENOTCONN = syscall.Errno(0x39) ENOTDIR = syscall.Errno(0x14) ENOTEMPTY = syscall.Errno(0x42) + ENOTRECOVERABLE = syscall.Errno(0x5d) ENOTSOCK = syscall.Errno(0x26) ENOTSUP = syscall.Errno(0x5b) ENOTTY = syscall.Errno(0x19) ENXIO = syscall.Errno(0x6) EOPNOTSUPP = syscall.Errno(0x2d) EOVERFLOW = syscall.Errno(0x57) + EOWNERDEAD = syscall.Errno(0x5e) EPERM = syscall.Errno(0x1) EPFNOSUPPORT = syscall.Errno(0x2e) EPIPE = syscall.Errno(0x20) @@ -1472,6 +1704,7 @@ const ( EPROCUNAVAIL = syscall.Errno(0x4c) EPROGMISMATCH = syscall.Errno(0x4b) EPROGUNAVAIL = syscall.Errno(0x4a) + EPROTO = syscall.Errno(0x5f) EPROTONOSUPPORT = syscall.Errno(0x2b) EPROTOTYPE = syscall.Errno(0x29) ERANGE = syscall.Errno(0x22) @@ -1568,7 +1801,7 @@ var errorList = [...]struct { {32, "EPIPE", "broken pipe"}, {33, "EDOM", "numerical argument out of domain"}, {34, "ERANGE", "result too large"}, - {35, "EWOULDBLOCK", "resource temporarily unavailable"}, + {35, "EAGAIN", "resource temporarily unavailable"}, {36, "EINPROGRESS", "operation now in progress"}, {37, "EALREADY", "operation already in progress"}, {38, "ENOTSOCK", "socket operation on non-socket"}, @@ -1624,7 +1857,11 @@ var errorList = [...]struct { {88, "ECANCELED", "operation canceled"}, {89, "EIDRM", "identifier removed"}, {90, "ENOMSG", "no message of desired type"}, - {91, "ELAST", "not supported"}, + {91, "ENOTSUP", "not supported"}, + {92, "EBADMSG", "bad message"}, + {93, "ENOTRECOVERABLE", "state not recoverable"}, + {94, "EOWNERDEAD", "previous owner died"}, + {95, "ELAST", "protocol error"}, } // Signal table @@ -1638,7 +1875,7 @@ var signalList = [...]struct { {3, "SIGQUIT", "quit"}, {4, "SIGILL", "illegal instruction"}, {5, "SIGTRAP", "trace/BPT trap"}, - {6, "SIGABRT", "abort trap"}, + {6, "SIGIOT", "abort trap"}, {7, "SIGEMT", "EMT trap"}, {8, "SIGFPE", "floating point exception"}, {9, "SIGKILL", "killed"}, @@ -1665,4 +1902,5 @@ var signalList = [...]struct { {30, "SIGUSR1", "user defined signal 1"}, {31, "SIGUSR2", "user defined signal 2"}, {32, "SIGTHR", "thread AST"}, + {28672, "SIGSTKSZ", "unknown signal"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go index 25cb609481..6015fcb2bf 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go @@ -109,6 +109,15 @@ const ( BPF_DIRECTION_IN = 0x1 BPF_DIRECTION_OUT = 0x2 BPF_DIV = 0x30 + BPF_FILDROP_CAPTURE = 0x1 + BPF_FILDROP_DROP = 0x2 + BPF_FILDROP_PASS = 0x0 + BPF_F_DIR_IN = 0x10 + BPF_F_DIR_MASK = 0x30 + BPF_F_DIR_OUT = 0x20 + BPF_F_DIR_SHIFT = 0x4 + BPF_F_FLOWID = 0x8 + BPF_F_PRI_MASK = 0x7 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -137,6 +146,7 @@ const ( BPF_OR = 0x40 BPF_RELEASE = 0x30bb6 BPF_RET = 0x6 + BPF_RND = 0xc0 BPF_RSH = 0x70 BPF_ST = 0x2 BPF_STX = 0x3 @@ -177,7 +187,65 @@ const ( CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 + DIOCADDQUEUE = 0xc110445d + DIOCADDRULE = 0xcd604404 + DIOCADDSTATE = 0xc1084425 + DIOCCHANGERULE = 0xcd60441a + DIOCCLRIFFLAG = 0xc028445a + DIOCCLRSRCNODES = 0x20004455 + DIOCCLRSTATES = 0xc0e04412 + DIOCCLRSTATUS = 0xc0284416 + DIOCGETLIMIT = 0xc0084427 + DIOCGETQSTATS = 0xc1204460 + DIOCGETQUEUE = 0xc110445f + DIOCGETQUEUES = 0xc110445e + DIOCGETRULE = 0xcd604407 + DIOCGETRULES = 0xcd604406 + DIOCGETRULESET = 0xc444443b + DIOCGETRULESETS = 0xc444443a + DIOCGETSRCNODES = 0xc0104454 + DIOCGETSTATE = 0xc1084413 + DIOCGETSTATES = 0xc0104419 + DIOCGETSTATUS = 0xc1e84415 + DIOCGETSYNFLWATS = 0xc0084463 + DIOCGETTIMEOUT = 0xc008441e + DIOCIGETIFACES = 0xc0284457 + DIOCKILLSRCNODES = 0xc080445b + DIOCKILLSTATES = 0xc0e04429 + DIOCNATLOOK = 0xc0504417 + DIOCOSFPADD = 0xc088444f DIOCOSFPFLUSH = 0x2000444e + DIOCOSFPGET = 0xc0884450 + DIOCRADDADDRS = 0xc4504443 + DIOCRADDTABLES = 0xc450443d + DIOCRCLRADDRS = 0xc4504442 + DIOCRCLRASTATS = 0xc4504448 + DIOCRCLRTABLES = 0xc450443c + DIOCRCLRTSTATS = 0xc4504441 + DIOCRDELADDRS = 0xc4504444 + DIOCRDELTABLES = 0xc450443e + DIOCRGETADDRS = 0xc4504446 + DIOCRGETASTATS = 0xc4504447 + DIOCRGETTABLES = 0xc450443f + DIOCRGETTSTATS = 0xc4504440 + DIOCRINADEFINE = 0xc450444d + DIOCRSETADDRS = 0xc4504445 + DIOCRSETTFLAGS = 0xc450444a + DIOCRTSTADDRS = 0xc4504449 + DIOCSETDEBUG = 0xc0044418 + DIOCSETHOSTID = 0xc0044456 + DIOCSETIFFLAG = 0xc0284459 + DIOCSETLIMIT = 0xc0084428 + DIOCSETREASS = 0xc004445c + DIOCSETSTATUSIF = 0xc0284414 + DIOCSETSYNCOOKIES = 0xc0014462 + DIOCSETSYNFLWATS = 0xc0084461 + DIOCSETTIMEOUT = 0xc008441d + DIOCSTART = 0x20004401 + DIOCSTOP = 0x20004402 + DIOCXBEGIN = 0xc0104451 + DIOCXCOMMIT = 0xc0104452 + DIOCXROLLBACK = 0xc0104453 DLT_ARCNET = 0x7 DLT_ATM_RFC1483 = 0xb DLT_AX25 = 0x3 @@ -240,6 +308,8 @@ const ( EMUL_ENABLED = 0x1 EMUL_NATIVE = 0x2 ENDRUNDISC = 0x9 + ETH64_8021_RSVD_MASK = 0xfffffffffff0 + ETH64_8021_RSVD_PREFIX = 0x180c2000000 ETHERMIN = 0x2e ETHERMTU = 0x5dc ETHERTYPE_8023 = 0x4 @@ -292,6 +362,7 @@ const ( ETHERTYPE_DN = 0x6003 ETHERTYPE_DOGFIGHT = 0x1989 ETHERTYPE_DSMD = 0x8039 + ETHERTYPE_EAPOL = 0x888e ETHERTYPE_ECMA = 0x803 ETHERTYPE_ENCRYPT = 0x803d ETHERTYPE_ES = 0x805d @@ -323,6 +394,7 @@ const ( ETHERTYPE_LLDP = 0x88cc ETHERTYPE_LOGICRAFT = 0x8148 ETHERTYPE_LOOPBACK = 0x9000 + ETHERTYPE_MACSEC = 0x88e5 ETHERTYPE_MATRA = 0x807a ETHERTYPE_MAX = 0xffff ETHERTYPE_MERIT = 0x807c @@ -351,15 +423,17 @@ const ( ETHERTYPE_NCD = 0x8149 ETHERTYPE_NESTAR = 0x8006 ETHERTYPE_NETBEUI = 0x8191 + ETHERTYPE_NHRP = 0x2001 ETHERTYPE_NOVELL = 0x8138 ETHERTYPE_NS = 0x600 ETHERTYPE_NSAT = 0x601 ETHERTYPE_NSCOMPAT = 0x807 + ETHERTYPE_NSH = 0x984f ETHERTYPE_NTRAILER = 0x10 ETHERTYPE_OS9 = 0x7007 ETHERTYPE_OS9NET = 0x7009 ETHERTYPE_PACER = 0x80c6 - ETHERTYPE_PAE = 0x888e + ETHERTYPE_PBB = 0x88e7 ETHERTYPE_PCS = 0x4242 ETHERTYPE_PLANNING = 0x8044 ETHERTYPE_PPP = 0x880b @@ -441,10 +515,11 @@ const ( ETHER_VLAN_ENCAP_LEN = 0x4 EVFILT_AIO = -0x3 EVFILT_DEVICE = -0x8 + EVFILT_EXCEPT = -0x9 EVFILT_PROC = -0x5 EVFILT_READ = -0x1 EVFILT_SIGNAL = -0x6 - EVFILT_SYSCOUNT = 0x8 + EVFILT_SYSCOUNT = 0x9 EVFILT_TIMER = -0x7 EVFILT_VNODE = -0x4 EVFILT_WRITE = -0x2 @@ -466,7 +541,7 @@ const ( EV_FLAG1 = 0x2000 EV_ONESHOT = 0x10 EV_RECEIPT = 0x40 - EV_SYSFLAGS = 0xf000 + EV_SYSFLAGS = 0xf800 EXTA = 0x4b00 EXTB = 0x9600 EXTPROC = 0x800 @@ -732,6 +807,7 @@ const ( IFT_VOICEOVERCABLE = 0xc6 IFT_VOICEOVERFRAMERELAY = 0x99 IFT_VOICEOVERIP = 0x68 + IFT_WIREGUARD = 0xfb IFT_X213 = 0x5d IFT_X25 = 0x5 IFT_X25DDN = 0x4 @@ -797,9 +873,11 @@ const ( IPPROTO_RAW = 0xff IPPROTO_ROUTING = 0x2b IPPROTO_RSVP = 0x2e + IPPROTO_SCTP = 0x84 IPPROTO_TCP = 0x6 IPPROTO_TP = 0x1d IPPROTO_UDP = 0x11 + IPPROTO_UDPLITE = 0x88 IPV6_AUTH_LEVEL = 0x35 IPV6_AUTOFLOWLABEL = 0x3b IPV6_CHECKSUM = 0x1a @@ -906,6 +984,9 @@ const ( IP_TTL = 0x4 ISIG = 0x80 ISTRIP = 0x20 + ITIMER_PROF = 0x2 + ITIMER_REAL = 0x0 + ITIMER_VIRTUAL = 0x1 IUCLC = 0x1000 IXANY = 0x800 IXOFF = 0x400 @@ -970,12 +1051,26 @@ const ( MNT_ROOTFS = 0x4000 MNT_SOFTDEP = 0x4000000 MNT_STALLED = 0x100000 + MNT_SWAPPABLE = 0x200000 MNT_SYNCHRONOUS = 0x2 MNT_UPDATE = 0x10000 MNT_VISFLAGMASK = 0x400ffff MNT_WAIT = 0x1 MNT_WANTRDWR = 0x2000000 MNT_WXALLOWED = 0x800 + MOUNT_AFS = "afs" + MOUNT_CD9660 = "cd9660" + MOUNT_EXT2FS = "ext2fs" + MOUNT_FFS = "ffs" + MOUNT_FUSEFS = "fuse" + MOUNT_MFS = "mfs" + MOUNT_MSDOS = "msdos" + MOUNT_NCPFS = "ncpfs" + MOUNT_NFS = "nfs" + MOUNT_NTFS = "ntfs" + MOUNT_TMPFS = "tmpfs" + MOUNT_UDF = "udf" + MOUNT_UFS = "ffs" MSG_BCAST = 0x100 MSG_CMSG_CLOEXEC = 0x800 MSG_CTRUNC = 0x20 @@ -988,6 +1083,7 @@ const ( MSG_PEEK = 0x2 MSG_TRUNC = 0x10 MSG_WAITALL = 0x40 + MSG_WAITFORONE = 0x1000 MS_ASYNC = 0x1 MS_INVALIDATE = 0x4 MS_SYNC = 0x2 @@ -996,7 +1092,8 @@ const ( NET_RT_FLAGS = 0x2 NET_RT_IFLIST = 0x3 NET_RT_IFNAMES = 0x6 - NET_RT_MAXID = 0x7 + NET_RT_MAXID = 0x8 + NET_RT_SOURCE = 0x7 NET_RT_STATS = 0x4 NET_RT_TABLE = 0x5 NFDBITS = 0x20 @@ -1013,6 +1110,7 @@ const ( NOTE_FORK = 0x40000000 NOTE_LINK = 0x10 NOTE_LOWAT = 0x1 + NOTE_OOB = 0x4 NOTE_PCTRLMASK = 0xf0000000 NOTE_PDATAMASK = 0xfffff NOTE_RENAME = 0x20 @@ -1130,9 +1228,11 @@ const ( RTF_STATIC = 0x800 RTF_UP = 0x1 RTF_USETRAILERS = 0x8000 + RTM_80211INFO = 0x15 RTM_ADD = 0x1 RTM_BFD = 0x12 RTM_CHANGE = 0x3 + RTM_CHGADDRATTR = 0x14 RTM_DELADDR = 0xd RTM_DELETE = 0x2 RTM_DESYNC = 0x10 @@ -1140,7 +1240,6 @@ const ( RTM_IFANNOUNCE = 0xf RTM_IFINFO = 0xe RTM_INVALIDATE = 0x11 - RTM_LOCK = 0x8 RTM_LOSING = 0x5 RTM_MAXSIZE = 0x800 RTM_MISS = 0x7 @@ -1148,7 +1247,7 @@ const ( RTM_PROPOSAL = 0x13 RTM_REDIRECT = 0x6 RTM_RESOLVE = 0xb - RTM_RTTUNIT = 0xf4240 + RTM_SOURCE = 0x16 RTM_VERSION = 0x5 RTV_EXPIRE = 0x4 RTV_HOPCOUNT = 0x2 @@ -1166,6 +1265,9 @@ const ( RUSAGE_THREAD = 0x1 SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x4 + SEEK_CUR = 0x1 + SEEK_END = 0x2 + SEEK_SET = 0x0 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1182,35 +1284,37 @@ const ( SIOCBRDGDELS = 0x80606942 SIOCBRDGFLUSH = 0x80606948 SIOCBRDGFRL = 0x808c694e - SIOCBRDGGCACHE = 0xc0186941 - SIOCBRDGGFD = 0xc0186952 - SIOCBRDGGHT = 0xc0186951 + SIOCBRDGGCACHE = 0xc0146941 + SIOCBRDGGFD = 0xc0146952 + SIOCBRDGGHT = 0xc0146951 SIOCBRDGGIFFLGS = 0xc060693e - SIOCBRDGGMA = 0xc0186953 + SIOCBRDGGMA = 0xc0146953 SIOCBRDGGPARAM = 0xc0406958 - SIOCBRDGGPRI = 0xc0186950 + SIOCBRDGGPRI = 0xc0146950 SIOCBRDGGRL = 0xc030694f - SIOCBRDGGTO = 0xc0186946 + SIOCBRDGGTO = 0xc0146946 SIOCBRDGIFS = 0xc0606942 SIOCBRDGRTS = 0xc0206943 SIOCBRDGSADDR = 0xc1286944 - SIOCBRDGSCACHE = 0x80186940 - SIOCBRDGSFD = 0x80186952 - SIOCBRDGSHT = 0x80186951 + SIOCBRDGSCACHE = 0x80146940 + SIOCBRDGSFD = 0x80146952 + SIOCBRDGSHT = 0x80146951 SIOCBRDGSIFCOST = 0x80606955 SIOCBRDGSIFFLGS = 0x8060693f SIOCBRDGSIFPRIO = 0x80606954 SIOCBRDGSIFPROT = 0x8060694a - SIOCBRDGSMA = 0x80186953 - SIOCBRDGSPRI = 0x80186950 - SIOCBRDGSPROTO = 0x8018695a - SIOCBRDGSTO = 0x80186945 - SIOCBRDGSTXHC = 0x80186959 + SIOCBRDGSMA = 0x80146953 + SIOCBRDGSPRI = 0x80146950 + SIOCBRDGSPROTO = 0x8014695a + SIOCBRDGSTO = 0x80146945 + SIOCBRDGSTXHC = 0x80146959 + SIOCDELLABEL = 0x80206997 SIOCDELMULTI = 0x80206932 SIOCDIFADDR = 0x80206919 SIOCDIFGROUP = 0x80286989 SIOCDIFPARENT = 0x802069b4 SIOCDIFPHYADDR = 0x80206949 + SIOCDPWE3NEIGHBOR = 0x802069de SIOCDVNETID = 0x802069af SIOCGETKALIVE = 0xc01869a4 SIOCGETLABEL = 0x8020699a @@ -1229,6 +1333,7 @@ const ( SIOCGIFFLAGS = 0xc0206911 SIOCGIFGATTR = 0xc028698b SIOCGIFGENERIC = 0xc020693a + SIOCGIFGLIST = 0xc028698d SIOCGIFGMEMB = 0xc028698a SIOCGIFGROUP = 0xc0286988 SIOCGIFHARDMTU = 0xc02069a5 @@ -1243,13 +1348,21 @@ const ( SIOCGIFRDOMAIN = 0xc02069a0 SIOCGIFRTLABEL = 0xc0206983 SIOCGIFRXR = 0x802069aa + SIOCGIFSFFPAGE = 0xc1126939 SIOCGIFXFLAGS = 0xc020699e SIOCGLIFPHYADDR = 0xc218694b SIOCGLIFPHYDF = 0xc02069c2 + SIOCGLIFPHYECN = 0xc02069c8 SIOCGLIFPHYRTABLE = 0xc02069a2 SIOCGLIFPHYTTL = 0xc02069a9 SIOCGPGRP = 0x40047309 + SIOCGPWE3 = 0xc0206998 + SIOCGPWE3CTRLWORD = 0xc02069dc + SIOCGPWE3FAT = 0xc02069dd + SIOCGPWE3NEIGHBOR = 0xc21869de + SIOCGRXHPRIO = 0xc02069db SIOCGSPPPPARAMS = 0xc0206994 + SIOCGTXHPRIO = 0xc02069c6 SIOCGUMBINFO = 0xc02069be SIOCGUMBPARAM = 0xc02069c0 SIOCGVH = 0xc02069f6 @@ -1287,19 +1400,20 @@ const ( SIOCSIFXFLAGS = 0x8020699d SIOCSLIFPHYADDR = 0x8218694a SIOCSLIFPHYDF = 0x802069c1 + SIOCSLIFPHYECN = 0x802069c7 SIOCSLIFPHYRTABLE = 0x802069a1 SIOCSLIFPHYTTL = 0x802069a8 SIOCSPGRP = 0x80047308 + SIOCSPWE3CTRLWORD = 0x802069dc + SIOCSPWE3FAT = 0x802069dd + SIOCSPWE3NEIGHBOR = 0x821869de + SIOCSRXHPRIO = 0x802069db SIOCSSPPPPARAMS = 0x80206993 + SIOCSTXHPRIO = 0x802069c5 SIOCSUMBPARAM = 0x802069bf SIOCSVH = 0xc02069f5 SIOCSVNETFLOWID = 0x802069c3 SIOCSVNETID = 0x802069a6 - SIOCSWGDPID = 0xc018695b - SIOCSWGMAXFLOW = 0xc0186960 - SIOCSWGMAXGROUP = 0xc018695d - SIOCSWSDPID = 0x8018695c - SIOCSWSPORTNO = 0xc060695f SOCK_CLOEXEC = 0x8000 SOCK_DGRAM = 0x2 SOCK_DNS = 0x1000 @@ -1314,6 +1428,7 @@ const ( SO_BINDANY = 0x1000 SO_BROADCAST = 0x20 SO_DEBUG = 0x1 + SO_DOMAIN = 0x1024 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 SO_KEEPALIVE = 0x8 @@ -1321,6 +1436,7 @@ const ( SO_NETPROC = 0x1020 SO_OOBINLINE = 0x100 SO_PEERCRED = 0x1022 + SO_PROTOCOL = 0x1025 SO_RCVBUF = 0x1002 SO_RCVLOWAT = 0x1004 SO_RCVTIMEO = 0x1006 @@ -1370,7 +1486,18 @@ const ( TCOFLUSH = 0x2 TCOOFF = 0x1 TCOON = 0x2 - TCP_MAXBURST = 0x4 + TCPOPT_EOL = 0x0 + TCPOPT_MAXSEG = 0x2 + TCPOPT_NOP = 0x1 + TCPOPT_SACK = 0x5 + TCPOPT_SACK_HDR = 0x1010500 + TCPOPT_SACK_PERMITTED = 0x4 + TCPOPT_SACK_PERMIT_HDR = 0x1010402 + TCPOPT_SIGNATURE = 0x13 + TCPOPT_TIMESTAMP = 0x8 + TCPOPT_TSTAMP_HDR = 0x101080a + TCPOPT_WINDOW = 0x3 + TCP_INFO = 0x9 TCP_MAXSEG = 0x2 TCP_MAXWIN = 0xffff TCP_MAX_SACK = 0x3 @@ -1379,8 +1506,11 @@ const ( TCP_MSS = 0x200 TCP_NODELAY = 0x1 TCP_NOPUSH = 0x10 + TCP_SACKHOLE_LIMIT = 0x80 TCP_SACK_ENABLE = 0x8 TCSAFLUSH = 0x2 + TIMER_ABSTIME = 0x1 + TIMER_RELTIME = 0x0 TIOCCBRK = 0x2000747a TIOCCDTR = 0x20007478 TIOCCHKVERAUTH = 0x2000741e @@ -1445,7 +1575,6 @@ const ( TIOCSPGRP = 0x80047476 TIOCSTART = 0x2000746e TIOCSTAT = 0x20007465 - TIOCSTI = 0x80017472 TIOCSTOP = 0x2000746f TIOCSTSTAMP = 0x8008745a TIOCSWINSZ = 0x80087467 @@ -1467,7 +1596,8 @@ const ( VMIN = 0x10 VM_ANONMIN = 0x7 VM_LOADAVG = 0x2 - VM_MAXID = 0xc + VM_MALLOC_CONF = 0xc + VM_MAXID = 0xd VM_MAXSLP = 0xa VM_METER = 0x1 VM_NKMEMPAGES = 0x6 @@ -1745,7 +1875,7 @@ var signalList = [...]struct { {3, "SIGQUIT", "quit"}, {4, "SIGILL", "illegal instruction"}, {5, "SIGTRAP", "trace/BPT trap"}, - {6, "SIGABRT", "abort trap"}, + {6, "SIGIOT", "abort trap"}, {7, "SIGEMT", "EMT trap"}, {8, "SIGFPE", "floating point exception"}, {9, "SIGKILL", "killed"}, @@ -1772,4 +1902,5 @@ var signalList = [...]struct { {30, "SIGUSR1", "user defined signal 1"}, {31, "SIGUSR2", "user defined signal 2"}, {32, "SIGTHR", "thread AST"}, + {28672, "SIGSTKSZ", "unknown signal"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go index aef6c08560..8d44955e44 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go @@ -46,6 +46,7 @@ const ( AF_SNA = 0xb AF_UNIX = 0x1 AF_UNSPEC = 0x0 + ALTWERASE = 0x200 ARPHRD_ETHER = 0x1 ARPHRD_FRELAY = 0xf ARPHRD_IEEE1394 = 0x18 @@ -82,7 +83,7 @@ const ( BIOCGFILDROP = 0x40044278 BIOCGHDRCMPLT = 0x40044274 BIOCGRSIG = 0x40044273 - BIOCGRTIMEOUT = 0x400c426e + BIOCGRTIMEOUT = 0x4010426e BIOCGSTATS = 0x4008426f BIOCIMMEDIATE = 0x80044270 BIOCLOCK = 0x20004276 @@ -96,7 +97,7 @@ const ( BIOCSFILDROP = 0x80044279 BIOCSHDRCMPLT = 0x80044275 BIOCSRSIG = 0x80044272 - BIOCSRTIMEOUT = 0x800c426d + BIOCSRTIMEOUT = 0x8010426d BIOCVERSION = 0x40044271 BPF_A = 0x10 BPF_ABS = 0x20 @@ -108,6 +109,15 @@ const ( BPF_DIRECTION_IN = 0x1 BPF_DIRECTION_OUT = 0x2 BPF_DIV = 0x30 + BPF_FILDROP_CAPTURE = 0x1 + BPF_FILDROP_DROP = 0x2 + BPF_FILDROP_PASS = 0x0 + BPF_F_DIR_IN = 0x10 + BPF_F_DIR_MASK = 0x30 + BPF_F_DIR_OUT = 0x20 + BPF_F_DIR_SHIFT = 0x4 + BPF_F_FLOWID = 0x8 + BPF_F_PRI_MASK = 0x7 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -136,6 +146,7 @@ const ( BPF_OR = 0x40 BPF_RELEASE = 0x30bb6 BPF_RET = 0x6 + BPF_RND = 0xc0 BPF_RSH = 0x70 BPF_ST = 0x2 BPF_STX = 0x3 @@ -147,6 +158,12 @@ const ( BRKINT = 0x2 CFLUSH = 0xf CLOCAL = 0x8000 + CLOCK_BOOTTIME = 0x6 + CLOCK_MONOTONIC = 0x3 + CLOCK_PROCESS_CPUTIME_ID = 0x2 + CLOCK_REALTIME = 0x0 + CLOCK_THREAD_CPUTIME_ID = 0x4 + CLOCK_UPTIME = 0x5 CPUSTATES = 0x6 CP_IDLE = 0x5 CP_INTR = 0x4 @@ -170,7 +187,65 @@ const ( CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 + DIOCADDQUEUE = 0xc100445d + DIOCADDRULE = 0xcce04404 + DIOCADDSTATE = 0xc1084425 + DIOCCHANGERULE = 0xcce0441a + DIOCCLRIFFLAG = 0xc024445a + DIOCCLRSRCNODES = 0x20004455 + DIOCCLRSTATES = 0xc0d04412 + DIOCCLRSTATUS = 0xc0244416 + DIOCGETLIMIT = 0xc0084427 + DIOCGETQSTATS = 0xc1084460 + DIOCGETQUEUE = 0xc100445f + DIOCGETQUEUES = 0xc100445e + DIOCGETRULE = 0xcce04407 + DIOCGETRULES = 0xcce04406 + DIOCGETRULESET = 0xc444443b + DIOCGETRULESETS = 0xc444443a + DIOCGETSRCNODES = 0xc0084454 + DIOCGETSTATE = 0xc1084413 + DIOCGETSTATES = 0xc0084419 + DIOCGETSTATUS = 0xc1e84415 + DIOCGETSYNFLWATS = 0xc0084463 + DIOCGETTIMEOUT = 0xc008441e + DIOCIGETIFACES = 0xc0244457 + DIOCKILLSRCNODES = 0xc068445b + DIOCKILLSTATES = 0xc0d04429 + DIOCNATLOOK = 0xc0504417 + DIOCOSFPADD = 0xc088444f DIOCOSFPFLUSH = 0x2000444e + DIOCOSFPGET = 0xc0884450 + DIOCRADDADDRS = 0xc44c4443 + DIOCRADDTABLES = 0xc44c443d + DIOCRCLRADDRS = 0xc44c4442 + DIOCRCLRASTATS = 0xc44c4448 + DIOCRCLRTABLES = 0xc44c443c + DIOCRCLRTSTATS = 0xc44c4441 + DIOCRDELADDRS = 0xc44c4444 + DIOCRDELTABLES = 0xc44c443e + DIOCRGETADDRS = 0xc44c4446 + DIOCRGETASTATS = 0xc44c4447 + DIOCRGETTABLES = 0xc44c443f + DIOCRGETTSTATS = 0xc44c4440 + DIOCRINADEFINE = 0xc44c444d + DIOCRSETADDRS = 0xc44c4445 + DIOCRSETTFLAGS = 0xc44c444a + DIOCRTSTADDRS = 0xc44c4449 + DIOCSETDEBUG = 0xc0044418 + DIOCSETHOSTID = 0xc0044456 + DIOCSETIFFLAG = 0xc0244459 + DIOCSETLIMIT = 0xc0084428 + DIOCSETREASS = 0xc004445c + DIOCSETSTATUSIF = 0xc0244414 + DIOCSETSYNCOOKIES = 0xc0014462 + DIOCSETSYNFLWATS = 0xc0084461 + DIOCSETTIMEOUT = 0xc008441d + DIOCSTART = 0x20004401 + DIOCSTOP = 0x20004402 + DIOCXBEGIN = 0xc00c4451 + DIOCXCOMMIT = 0xc00c4452 + DIOCXROLLBACK = 0xc00c4453 DLT_ARCNET = 0x7 DLT_ATM_RFC1483 = 0xb DLT_AX25 = 0x3 @@ -186,6 +261,7 @@ const ( DLT_LOOP = 0xc DLT_MPLS = 0xdb DLT_NULL = 0x0 + DLT_OPENFLOW = 0x10b DLT_PFLOG = 0x75 DLT_PFSYNC = 0x12 DLT_PPP = 0x9 @@ -196,6 +272,23 @@ const ( DLT_RAW = 0xe DLT_SLIP = 0x8 DLT_SLIP_BSDOS = 0xf + DLT_USBPCAP = 0xf9 + DLT_USER0 = 0x93 + DLT_USER1 = 0x94 + DLT_USER10 = 0x9d + DLT_USER11 = 0x9e + DLT_USER12 = 0x9f + DLT_USER13 = 0xa0 + DLT_USER14 = 0xa1 + DLT_USER15 = 0xa2 + DLT_USER2 = 0x95 + DLT_USER3 = 0x96 + DLT_USER4 = 0x97 + DLT_USER5 = 0x98 + DLT_USER6 = 0x99 + DLT_USER7 = 0x9a + DLT_USER8 = 0x9b + DLT_USER9 = 0x9c DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -215,6 +308,8 @@ const ( EMUL_ENABLED = 0x1 EMUL_NATIVE = 0x2 ENDRUNDISC = 0x9 + ETH64_8021_RSVD_MASK = 0xfffffffffff0 + ETH64_8021_RSVD_PREFIX = 0x180c2000000 ETHERMIN = 0x2e ETHERMTU = 0x5dc ETHERTYPE_8023 = 0x4 @@ -267,6 +362,7 @@ const ( ETHERTYPE_DN = 0x6003 ETHERTYPE_DOGFIGHT = 0x1989 ETHERTYPE_DSMD = 0x8039 + ETHERTYPE_EAPOL = 0x888e ETHERTYPE_ECMA = 0x803 ETHERTYPE_ENCRYPT = 0x803d ETHERTYPE_ES = 0x805d @@ -298,6 +394,7 @@ const ( ETHERTYPE_LLDP = 0x88cc ETHERTYPE_LOGICRAFT = 0x8148 ETHERTYPE_LOOPBACK = 0x9000 + ETHERTYPE_MACSEC = 0x88e5 ETHERTYPE_MATRA = 0x807a ETHERTYPE_MAX = 0xffff ETHERTYPE_MERIT = 0x807c @@ -326,15 +423,17 @@ const ( ETHERTYPE_NCD = 0x8149 ETHERTYPE_NESTAR = 0x8006 ETHERTYPE_NETBEUI = 0x8191 + ETHERTYPE_NHRP = 0x2001 ETHERTYPE_NOVELL = 0x8138 ETHERTYPE_NS = 0x600 ETHERTYPE_NSAT = 0x601 ETHERTYPE_NSCOMPAT = 0x807 + ETHERTYPE_NSH = 0x984f ETHERTYPE_NTRAILER = 0x10 ETHERTYPE_OS9 = 0x7007 ETHERTYPE_OS9NET = 0x7009 ETHERTYPE_PACER = 0x80c6 - ETHERTYPE_PAE = 0x888e + ETHERTYPE_PBB = 0x88e7 ETHERTYPE_PCS = 0x4242 ETHERTYPE_PLANNING = 0x8044 ETHERTYPE_PPP = 0x880b @@ -409,28 +508,40 @@ const ( ETHER_CRC_POLY_LE = 0xedb88320 ETHER_HDR_LEN = 0xe ETHER_MAX_DIX_LEN = 0x600 + ETHER_MAX_HARDMTU_LEN = 0xff9b ETHER_MAX_LEN = 0x5ee ETHER_MIN_LEN = 0x40 ETHER_TYPE_LEN = 0x2 ETHER_VLAN_ENCAP_LEN = 0x4 EVFILT_AIO = -0x3 + EVFILT_DEVICE = -0x8 + EVFILT_EXCEPT = -0x9 EVFILT_PROC = -0x5 EVFILT_READ = -0x1 EVFILT_SIGNAL = -0x6 - EVFILT_SYSCOUNT = 0x7 + EVFILT_SYSCOUNT = 0x9 EVFILT_TIMER = -0x7 EVFILT_VNODE = -0x4 EVFILT_WRITE = -0x2 + EVL_ENCAPLEN = 0x4 + EVL_PRIO_BITS = 0xd + EVL_PRIO_MAX = 0x7 + EVL_VLID_MASK = 0xfff + EVL_VLID_MAX = 0xffe + EVL_VLID_MIN = 0x1 + EVL_VLID_NULL = 0x0 EV_ADD = 0x1 EV_CLEAR = 0x20 EV_DELETE = 0x2 EV_DISABLE = 0x8 + EV_DISPATCH = 0x80 EV_ENABLE = 0x4 EV_EOF = 0x8000 EV_ERROR = 0x4000 EV_FLAG1 = 0x2000 EV_ONESHOT = 0x10 - EV_SYSFLAGS = 0xf000 + EV_RECEIPT = 0x40 + EV_SYSFLAGS = 0xf800 EXTA = 0x4b00 EXTB = 0x9600 EXTPROC = 0x800 @@ -443,6 +554,8 @@ const ( F_GETFL = 0x3 F_GETLK = 0x7 F_GETOWN = 0x5 + F_ISATTY = 0xb + F_OK = 0x0 F_RDLCK = 0x1 F_SETFD = 0x2 F_SETFL = 0x4 @@ -459,7 +572,6 @@ const ( IEXTEN = 0x400 IFAN_ARRIVAL = 0x0 IFAN_DEPARTURE = 0x1 - IFA_ROUTE = 0x1 IFF_ALLMULTI = 0x200 IFF_BROADCAST = 0x2 IFF_CANTCHANGE = 0x8e52 @@ -470,12 +582,12 @@ const ( IFF_LOOPBACK = 0x8 IFF_MULTICAST = 0x8000 IFF_NOARP = 0x80 - IFF_NOTRAILERS = 0x20 IFF_OACTIVE = 0x400 IFF_POINTOPOINT = 0x10 IFF_PROMISC = 0x100 IFF_RUNNING = 0x40 IFF_SIMPLEX = 0x800 + IFF_STATICARP = 0x20 IFF_UP = 0x1 IFNAMSIZ = 0x10 IFT_1822 = 0x2 @@ -604,6 +716,7 @@ const ( IFT_LINEGROUP = 0xd2 IFT_LOCALTALK = 0x2a IFT_LOOP = 0x18 + IFT_MBIM = 0xfa IFT_MEDIAMAILOVERIP = 0x8b IFT_MFSIGLINK = 0xa7 IFT_MIOX25 = 0x26 @@ -694,6 +807,7 @@ const ( IFT_VOICEOVERCABLE = 0xc6 IFT_VOICEOVERFRAMERELAY = 0x99 IFT_VOICEOVERIP = 0x68 + IFT_WIREGUARD = 0xfb IFT_X213 = 0x5d IFT_X25 = 0x5 IFT_X25DDN = 0x4 @@ -728,8 +842,6 @@ const ( IPPROTO_AH = 0x33 IPPROTO_CARP = 0x70 IPPROTO_DIVERT = 0x102 - IPPROTO_DIVERT_INIT = 0x2 - IPPROTO_DIVERT_RESP = 0x1 IPPROTO_DONE = 0x101 IPPROTO_DSTOPTS = 0x3c IPPROTO_EGP = 0x8 @@ -761,9 +873,11 @@ const ( IPPROTO_RAW = 0xff IPPROTO_ROUTING = 0x2b IPPROTO_RSVP = 0x2e + IPPROTO_SCTP = 0x84 IPPROTO_TCP = 0x6 IPPROTO_TP = 0x1d IPPROTO_UDP = 0x11 + IPPROTO_UDPLITE = 0x88 IPV6_AUTH_LEVEL = 0x35 IPV6_AUTOFLOWLABEL = 0x3b IPV6_CHECKSUM = 0x1a @@ -786,6 +900,7 @@ const ( IPV6_LEAVE_GROUP = 0xd IPV6_MAXHLIM = 0xff IPV6_MAXPACKET = 0xffff + IPV6_MINHOPCOUNT = 0x41 IPV6_MMTU = 0x500 IPV6_MULTICAST_HOPS = 0xa IPV6_MULTICAST_IF = 0x9 @@ -825,12 +940,12 @@ const ( IP_DEFAULT_MULTICAST_LOOP = 0x1 IP_DEFAULT_MULTICAST_TTL = 0x1 IP_DF = 0x4000 - IP_DIVERTFL = 0x1022 IP_DROP_MEMBERSHIP = 0xd IP_ESP_NETWORK_LEVEL = 0x16 IP_ESP_TRANS_LEVEL = 0x15 IP_HDRINCL = 0x2 IP_IPCOMP_LEVEL = 0x1d + IP_IPDEFTTL = 0x25 IP_IPSECFLOWINFO = 0x24 IP_IPSEC_LOCAL_AUTH = 0x1b IP_IPSEC_LOCAL_CRED = 0x19 @@ -864,10 +979,15 @@ const ( IP_RETOPTS = 0x8 IP_RF = 0x8000 IP_RTABLE = 0x1021 + IP_SENDSRCADDR = 0x7 IP_TOS = 0x3 IP_TTL = 0x4 ISIG = 0x80 ISTRIP = 0x20 + ITIMER_PROF = 0x2 + ITIMER_REAL = 0x0 + ITIMER_VIRTUAL = 0x1 + IUCLC = 0x1000 IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 @@ -922,6 +1042,7 @@ const ( MNT_NOATIME = 0x8000 MNT_NODEV = 0x10 MNT_NOEXEC = 0x4 + MNT_NOPERM = 0x20 MNT_NOSUID = 0x8 MNT_NOWAIT = 0x2 MNT_QUOTA = 0x2000 @@ -929,12 +1050,27 @@ const ( MNT_RELOAD = 0x40000 MNT_ROOTFS = 0x4000 MNT_SOFTDEP = 0x4000000 + MNT_STALLED = 0x100000 + MNT_SWAPPABLE = 0x200000 MNT_SYNCHRONOUS = 0x2 MNT_UPDATE = 0x10000 MNT_VISFLAGMASK = 0x400ffff MNT_WAIT = 0x1 MNT_WANTRDWR = 0x2000000 MNT_WXALLOWED = 0x800 + MOUNT_AFS = "afs" + MOUNT_CD9660 = "cd9660" + MOUNT_EXT2FS = "ext2fs" + MOUNT_FFS = "ffs" + MOUNT_FUSEFS = "fuse" + MOUNT_MFS = "mfs" + MOUNT_MSDOS = "msdos" + MOUNT_NCPFS = "ncpfs" + MOUNT_NFS = "nfs" + MOUNT_NTFS = "ntfs" + MOUNT_TMPFS = "tmpfs" + MOUNT_UDF = "udf" + MOUNT_UFS = "ffs" MSG_BCAST = 0x100 MSG_CMSG_CLOEXEC = 0x800 MSG_CTRUNC = 0x20 @@ -947,6 +1083,7 @@ const ( MSG_PEEK = 0x2 MSG_TRUNC = 0x10 MSG_WAITALL = 0x40 + MSG_WAITFORONE = 0x1000 MS_ASYNC = 0x1 MS_INVALIDATE = 0x4 MS_SYNC = 0x2 @@ -954,12 +1091,16 @@ const ( NET_RT_DUMP = 0x1 NET_RT_FLAGS = 0x2 NET_RT_IFLIST = 0x3 - NET_RT_MAXID = 0x6 + NET_RT_IFNAMES = 0x6 + NET_RT_MAXID = 0x8 + NET_RT_SOURCE = 0x7 NET_RT_STATS = 0x4 NET_RT_TABLE = 0x5 NFDBITS = 0x20 NOFLSH = 0x80000000 + NOKERNINFO = 0x2000000 NOTE_ATTRIB = 0x8 + NOTE_CHANGE = 0x1 NOTE_CHILD = 0x4 NOTE_DELETE = 0x1 NOTE_EOF = 0x2 @@ -969,6 +1110,7 @@ const ( NOTE_FORK = 0x40000000 NOTE_LINK = 0x10 NOTE_LOWAT = 0x1 + NOTE_OOB = 0x4 NOTE_PCTRLMASK = 0xf0000000 NOTE_PDATAMASK = 0xfffff NOTE_RENAME = 0x20 @@ -978,11 +1120,13 @@ const ( NOTE_TRUNCATE = 0x80 NOTE_WRITE = 0x2 OCRNL = 0x10 + OLCUC = 0x20 ONLCR = 0x2 ONLRET = 0x80 ONOCR = 0x40 ONOEOT = 0x8 OPOST = 0x1 + OXTABS = 0x4 O_ACCMODE = 0x3 O_APPEND = 0x8 O_ASYNC = 0x40 @@ -1027,19 +1171,25 @@ const ( RLIMIT_STACK = 0x3 RLIM_INFINITY = 0x7fffffffffffffff RTAX_AUTHOR = 0x6 + RTAX_BFD = 0xb RTAX_BRD = 0x7 + RTAX_DNS = 0xc RTAX_DST = 0x0 RTAX_GATEWAY = 0x1 RTAX_GENMASK = 0x3 RTAX_IFA = 0x5 RTAX_IFP = 0x4 RTAX_LABEL = 0xa - RTAX_MAX = 0xb + RTAX_MAX = 0xf RTAX_NETMASK = 0x2 + RTAX_SEARCH = 0xe RTAX_SRC = 0x8 RTAX_SRCMASK = 0x9 + RTAX_STATIC = 0xd RTA_AUTHOR = 0x40 + RTA_BFD = 0x800 RTA_BRD = 0x80 + RTA_DNS = 0x1000 RTA_DST = 0x1 RTA_GATEWAY = 0x2 RTA_GENMASK = 0x8 @@ -1047,24 +1197,29 @@ const ( RTA_IFP = 0x10 RTA_LABEL = 0x400 RTA_NETMASK = 0x4 + RTA_SEARCH = 0x4000 RTA_SRC = 0x100 RTA_SRCMASK = 0x200 + RTA_STATIC = 0x2000 RTF_ANNOUNCE = 0x4000 + RTF_BFD = 0x1000000 RTF_BLACKHOLE = 0x1000 RTF_BROADCAST = 0x400000 + RTF_CACHED = 0x20000 RTF_CLONED = 0x10000 RTF_CLONING = 0x100 + RTF_CONNECTED = 0x800000 RTF_DONE = 0x40 RTF_DYNAMIC = 0x10 - RTF_FMASK = 0x70f808 + RTF_FMASK = 0x110fc08 RTF_GATEWAY = 0x2 RTF_HOST = 0x4 RTF_LLINFO = 0x400 RTF_LOCAL = 0x200000 - RTF_MASK = 0x80 RTF_MODIFIED = 0x20 RTF_MPATH = 0x40000 RTF_MPLS = 0x100000 + RTF_MULTICAST = 0x200 RTF_PERMANENT_ARP = 0x2000 RTF_PROTO1 = 0x8000 RTF_PROTO2 = 0x4000 @@ -1073,23 +1228,26 @@ const ( RTF_STATIC = 0x800 RTF_UP = 0x1 RTF_USETRAILERS = 0x8000 - RTF_XRESOLVE = 0x200 + RTM_80211INFO = 0x15 RTM_ADD = 0x1 + RTM_BFD = 0x12 RTM_CHANGE = 0x3 + RTM_CHGADDRATTR = 0x14 RTM_DELADDR = 0xd RTM_DELETE = 0x2 RTM_DESYNC = 0x10 RTM_GET = 0x4 RTM_IFANNOUNCE = 0xf RTM_IFINFO = 0xe - RTM_LOCK = 0x8 + RTM_INVALIDATE = 0x11 RTM_LOSING = 0x5 RTM_MAXSIZE = 0x800 RTM_MISS = 0x7 RTM_NEWADDR = 0xc + RTM_PROPOSAL = 0x13 RTM_REDIRECT = 0x6 RTM_RESOLVE = 0xb - RTM_RTTUNIT = 0xf4240 + RTM_SOURCE = 0x16 RTM_VERSION = 0x5 RTV_EXPIRE = 0x4 RTV_HOPCOUNT = 0x2 @@ -1099,67 +1257,74 @@ const ( RTV_RTTVAR = 0x80 RTV_SPIPE = 0x10 RTV_SSTHRESH = 0x20 + RT_TABLEID_BITS = 0x8 + RT_TABLEID_MASK = 0xff RT_TABLEID_MAX = 0xff RUSAGE_CHILDREN = -0x1 RUSAGE_SELF = 0x0 RUSAGE_THREAD = 0x1 SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x4 + SEEK_CUR = 0x1 + SEEK_END = 0x2 + SEEK_SET = 0x0 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 SIOCADDMULTI = 0x80206931 SIOCAIFADDR = 0x8040691a SIOCAIFGROUP = 0x80246987 - SIOCALIFADDR = 0x8218691c SIOCATMARK = 0x40047307 - SIOCBRDGADD = 0x8054693c - SIOCBRDGADDS = 0x80546941 - SIOCBRDGARL = 0x806e694d + SIOCBRDGADD = 0x8060693c + SIOCBRDGADDL = 0x80606949 + SIOCBRDGADDS = 0x80606941 + SIOCBRDGARL = 0x808c694d SIOCBRDGDADDR = 0x81286947 - SIOCBRDGDEL = 0x8054693d - SIOCBRDGDELS = 0x80546942 - SIOCBRDGFLUSH = 0x80546948 - SIOCBRDGFRL = 0x806e694e + SIOCBRDGDEL = 0x8060693d + SIOCBRDGDELS = 0x80606942 + SIOCBRDGFLUSH = 0x80606948 + SIOCBRDGFRL = 0x808c694e SIOCBRDGGCACHE = 0xc0146941 SIOCBRDGGFD = 0xc0146952 SIOCBRDGGHT = 0xc0146951 - SIOCBRDGGIFFLGS = 0xc054693e + SIOCBRDGGIFFLGS = 0xc060693e SIOCBRDGGMA = 0xc0146953 - SIOCBRDGGPARAM = 0xc03c6958 + SIOCBRDGGPARAM = 0xc0406958 SIOCBRDGGPRI = 0xc0146950 SIOCBRDGGRL = 0xc028694f - SIOCBRDGGSIFS = 0xc054693c SIOCBRDGGTO = 0xc0146946 - SIOCBRDGIFS = 0xc0546942 + SIOCBRDGIFS = 0xc0606942 SIOCBRDGRTS = 0xc0186943 SIOCBRDGSADDR = 0xc1286944 SIOCBRDGSCACHE = 0x80146940 SIOCBRDGSFD = 0x80146952 SIOCBRDGSHT = 0x80146951 - SIOCBRDGSIFCOST = 0x80546955 - SIOCBRDGSIFFLGS = 0x8054693f - SIOCBRDGSIFPRIO = 0x80546954 + SIOCBRDGSIFCOST = 0x80606955 + SIOCBRDGSIFFLGS = 0x8060693f + SIOCBRDGSIFPRIO = 0x80606954 + SIOCBRDGSIFPROT = 0x8060694a SIOCBRDGSMA = 0x80146953 SIOCBRDGSPRI = 0x80146950 SIOCBRDGSPROTO = 0x8014695a SIOCBRDGSTO = 0x80146945 SIOCBRDGSTXHC = 0x80146959 + SIOCDELLABEL = 0x80206997 SIOCDELMULTI = 0x80206932 SIOCDIFADDR = 0x80206919 SIOCDIFGROUP = 0x80246989 + SIOCDIFPARENT = 0x802069b4 SIOCDIFPHYADDR = 0x80206949 - SIOCDLIFADDR = 0x8218691e + SIOCDPWE3NEIGHBOR = 0x802069de + SIOCDVNETID = 0x802069af SIOCGETKALIVE = 0xc01869a4 SIOCGETLABEL = 0x8020699a + SIOCGETMPWCFG = 0xc02069ae SIOCGETPFLOW = 0xc02069fe SIOCGETPFSYNC = 0xc02069f8 SIOCGETSGCNT = 0xc0147534 SIOCGETVIFCNT = 0xc0147533 SIOCGETVLAN = 0xc0206990 - SIOCGHIWAT = 0x40047301 SIOCGIFADDR = 0xc0206921 - SIOCGIFASYNCMAP = 0xc020697c SIOCGIFBRDADDR = 0xc0206923 SIOCGIFCONF = 0xc0086924 SIOCGIFDATA = 0xc020691b @@ -1168,41 +1333,53 @@ const ( SIOCGIFFLAGS = 0xc0206911 SIOCGIFGATTR = 0xc024698b SIOCGIFGENERIC = 0xc020693a + SIOCGIFGLIST = 0xc024698d SIOCGIFGMEMB = 0xc024698a SIOCGIFGROUP = 0xc0246988 SIOCGIFHARDMTU = 0xc02069a5 - SIOCGIFMEDIA = 0xc0286936 + SIOCGIFLLPRIO = 0xc02069b6 + SIOCGIFMEDIA = 0xc0386938 SIOCGIFMETRIC = 0xc0206917 SIOCGIFMTU = 0xc020697e SIOCGIFNETMASK = 0xc0206925 - SIOCGIFPDSTADDR = 0xc0206948 + SIOCGIFPAIR = 0xc02069b1 + SIOCGIFPARENT = 0xc02069b3 SIOCGIFPRIORITY = 0xc020699c - SIOCGIFPSRCADDR = 0xc0206947 SIOCGIFRDOMAIN = 0xc02069a0 SIOCGIFRTLABEL = 0xc0206983 SIOCGIFRXR = 0x802069aa - SIOCGIFTIMESLOT = 0xc0206986 + SIOCGIFSFFPAGE = 0xc1126939 SIOCGIFXFLAGS = 0xc020699e - SIOCGLIFADDR = 0xc218691d SIOCGLIFPHYADDR = 0xc218694b + SIOCGLIFPHYDF = 0xc02069c2 + SIOCGLIFPHYECN = 0xc02069c8 SIOCGLIFPHYRTABLE = 0xc02069a2 SIOCGLIFPHYTTL = 0xc02069a9 - SIOCGLOWAT = 0x40047303 SIOCGPGRP = 0x40047309 + SIOCGPWE3 = 0xc0206998 + SIOCGPWE3CTRLWORD = 0xc02069dc + SIOCGPWE3FAT = 0xc02069dd + SIOCGPWE3NEIGHBOR = 0xc21869de + SIOCGRXHPRIO = 0xc02069db SIOCGSPPPPARAMS = 0xc0206994 + SIOCGTXHPRIO = 0xc02069c6 + SIOCGUMBINFO = 0xc02069be + SIOCGUMBPARAM = 0xc02069c0 SIOCGVH = 0xc02069f6 + SIOCGVNETFLOWID = 0xc02069c4 SIOCGVNETID = 0xc02069a7 + SIOCIFAFATTACH = 0x801169ab + SIOCIFAFDETACH = 0x801169ac SIOCIFCREATE = 0x8020697a SIOCIFDESTROY = 0x80206979 SIOCIFGCLONERS = 0xc00c6978 SIOCSETKALIVE = 0x801869a3 SIOCSETLABEL = 0x80206999 + SIOCSETMPWCFG = 0x802069ad SIOCSETPFLOW = 0x802069fd SIOCSETPFSYNC = 0x802069f7 SIOCSETVLAN = 0x8020698f - SIOCSHIWAT = 0x80047300 SIOCSIFADDR = 0x8020690c - SIOCSIFASYNCMAP = 0x8020697d SIOCSIFBRDADDR = 0x80206913 SIOCSIFDESCR = 0x80206980 SIOCSIFDSTADDR = 0x8020690e @@ -1210,26 +1387,36 @@ const ( SIOCSIFGATTR = 0x8024698c SIOCSIFGENERIC = 0x80206939 SIOCSIFLLADDR = 0x8020691f - SIOCSIFMEDIA = 0xc0206935 + SIOCSIFLLPRIO = 0x802069b5 + SIOCSIFMEDIA = 0xc0206937 SIOCSIFMETRIC = 0x80206918 SIOCSIFMTU = 0x8020697f SIOCSIFNETMASK = 0x80206916 - SIOCSIFPHYADDR = 0x80406946 + SIOCSIFPAIR = 0x802069b0 + SIOCSIFPARENT = 0x802069b2 SIOCSIFPRIORITY = 0x8020699b SIOCSIFRDOMAIN = 0x8020699f SIOCSIFRTLABEL = 0x80206982 - SIOCSIFTIMESLOT = 0x80206985 SIOCSIFXFLAGS = 0x8020699d SIOCSLIFPHYADDR = 0x8218694a + SIOCSLIFPHYDF = 0x802069c1 + SIOCSLIFPHYECN = 0x802069c7 SIOCSLIFPHYRTABLE = 0x802069a1 SIOCSLIFPHYTTL = 0x802069a8 - SIOCSLOWAT = 0x80047302 SIOCSPGRP = 0x80047308 + SIOCSPWE3CTRLWORD = 0x802069dc + SIOCSPWE3FAT = 0x802069dd + SIOCSPWE3NEIGHBOR = 0x821869de + SIOCSRXHPRIO = 0x802069db SIOCSSPPPPARAMS = 0x80206993 + SIOCSTXHPRIO = 0x802069c5 + SIOCSUMBPARAM = 0x802069bf SIOCSVH = 0xc02069f5 + SIOCSVNETFLOWID = 0x802069c3 SIOCSVNETID = 0x802069a6 SOCK_CLOEXEC = 0x8000 SOCK_DGRAM = 0x2 + SOCK_DNS = 0x1000 SOCK_NONBLOCK = 0x4000 SOCK_RAW = 0x3 SOCK_RDM = 0x4 @@ -1241,6 +1428,7 @@ const ( SO_BINDANY = 0x1000 SO_BROADCAST = 0x20 SO_DEBUG = 0x1 + SO_DOMAIN = 0x1024 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 SO_KEEPALIVE = 0x8 @@ -1248,6 +1436,7 @@ const ( SO_NETPROC = 0x1020 SO_OOBINLINE = 0x100 SO_PEERCRED = 0x1022 + SO_PROTOCOL = 0x1025 SO_RCVBUF = 0x1002 SO_RCVLOWAT = 0x1004 SO_RCVTIMEO = 0x1006 @@ -1261,6 +1450,7 @@ const ( SO_TIMESTAMP = 0x800 SO_TYPE = 0x1008 SO_USELOOPBACK = 0x40 + SO_ZEROIZE = 0x2000 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1290,9 +1480,24 @@ const ( S_IXOTH = 0x1 S_IXUSR = 0x40 TCIFLUSH = 0x1 + TCIOFF = 0x3 TCIOFLUSH = 0x3 + TCION = 0x4 TCOFLUSH = 0x2 - TCP_MAXBURST = 0x4 + TCOOFF = 0x1 + TCOON = 0x2 + TCPOPT_EOL = 0x0 + TCPOPT_MAXSEG = 0x2 + TCPOPT_NOP = 0x1 + TCPOPT_SACK = 0x5 + TCPOPT_SACK_HDR = 0x1010500 + TCPOPT_SACK_PERMITTED = 0x4 + TCPOPT_SACK_PERMIT_HDR = 0x1010402 + TCPOPT_SIGNATURE = 0x13 + TCPOPT_TIMESTAMP = 0x8 + TCPOPT_TSTAMP_HDR = 0x101080a + TCPOPT_WINDOW = 0x3 + TCP_INFO = 0x9 TCP_MAXSEG = 0x2 TCP_MAXWIN = 0xffff TCP_MAX_SACK = 0x3 @@ -1301,11 +1506,15 @@ const ( TCP_MSS = 0x200 TCP_NODELAY = 0x1 TCP_NOPUSH = 0x10 - TCP_NSTATES = 0xb + TCP_SACKHOLE_LIMIT = 0x80 TCP_SACK_ENABLE = 0x8 TCSAFLUSH = 0x2 + TIMER_ABSTIME = 0x1 + TIMER_RELTIME = 0x0 TIOCCBRK = 0x2000747a TIOCCDTR = 0x20007478 + TIOCCHKVERAUTH = 0x2000741e + TIOCCLRVERAUTH = 0x2000741d TIOCCONS = 0x80047462 TIOCDRAIN = 0x2000745e TIOCEXCL = 0x2000740d @@ -1321,7 +1530,7 @@ const ( TIOCGFLAGS = 0x4004745d TIOCGPGRP = 0x40047477 TIOCGSID = 0x40047463 - TIOCGTSTAMP = 0x400c745b + TIOCGTSTAMP = 0x4010745b TIOCGWINSZ = 0x40087468 TIOCMBIC = 0x8004746b TIOCMBIS = 0x8004746c @@ -1360,17 +1569,21 @@ const ( TIOCSETAF = 0x802c7416 TIOCSETAW = 0x802c7415 TIOCSETD = 0x8004741b + TIOCSETVERAUTH = 0x8004741c TIOCSFLAGS = 0x8004745c TIOCSIG = 0x8004745f TIOCSPGRP = 0x80047476 TIOCSTART = 0x2000746e - TIOCSTAT = 0x80047465 - TIOCSTI = 0x80017472 + TIOCSTAT = 0x20007465 TIOCSTOP = 0x2000746f TIOCSTSTAMP = 0x8008745a TIOCSWINSZ = 0x80087467 TIOCUCNTL = 0x80047466 + TIOCUCNTL_CBRK = 0x7a + TIOCUCNTL_SBRK = 0x7b TOSTOP = 0x400000 + UTIME_NOW = -0x2 + UTIME_OMIT = -0x1 VDISCARD = 0xf VDSUSP = 0xb VEOF = 0x0 @@ -1381,6 +1594,19 @@ const ( VKILL = 0x5 VLNEXT = 0xe VMIN = 0x10 + VM_ANONMIN = 0x7 + VM_LOADAVG = 0x2 + VM_MALLOC_CONF = 0xc + VM_MAXID = 0xd + VM_MAXSLP = 0xa + VM_METER = 0x1 + VM_NKMEMPAGES = 0x6 + VM_PSSTRINGS = 0x3 + VM_SWAPENCRYPT = 0x5 + VM_USPACE = 0xb + VM_UVMEXP = 0x4 + VM_VNODEMIN = 0x9 + VM_VTEXTMIN = 0x8 VQUIT = 0x9 VREPRINT = 0x6 VSTART = 0xc @@ -1394,6 +1620,7 @@ const ( WCOREFLAG = 0x80 WNOHANG = 0x1 WUNTRACED = 0x2 + XCASE = 0x1000000 ) // Errors @@ -1407,6 +1634,7 @@ const ( EALREADY = syscall.Errno(0x25) EAUTH = syscall.Errno(0x50) EBADF = syscall.Errno(0x9) + EBADMSG = syscall.Errno(0x5c) EBADRPC = syscall.Errno(0x48) EBUSY = syscall.Errno(0x10) ECANCELED = syscall.Errno(0x58) @@ -1433,7 +1661,7 @@ const ( EIPSEC = syscall.Errno(0x52) EISCONN = syscall.Errno(0x38) EISDIR = syscall.Errno(0x15) - ELAST = syscall.Errno(0x5b) + ELAST = syscall.Errno(0x5f) ELOOP = syscall.Errno(0x3e) EMEDIUMTYPE = syscall.Errno(0x56) EMFILE = syscall.Errno(0x18) @@ -1461,12 +1689,14 @@ const ( ENOTCONN = syscall.Errno(0x39) ENOTDIR = syscall.Errno(0x14) ENOTEMPTY = syscall.Errno(0x42) + ENOTRECOVERABLE = syscall.Errno(0x5d) ENOTSOCK = syscall.Errno(0x26) ENOTSUP = syscall.Errno(0x5b) ENOTTY = syscall.Errno(0x19) ENXIO = syscall.Errno(0x6) EOPNOTSUPP = syscall.Errno(0x2d) EOVERFLOW = syscall.Errno(0x57) + EOWNERDEAD = syscall.Errno(0x5e) EPERM = syscall.Errno(0x1) EPFNOSUPPORT = syscall.Errno(0x2e) EPIPE = syscall.Errno(0x20) @@ -1474,6 +1704,7 @@ const ( EPROCUNAVAIL = syscall.Errno(0x4c) EPROGMISMATCH = syscall.Errno(0x4b) EPROGUNAVAIL = syscall.Errno(0x4a) + EPROTO = syscall.Errno(0x5f) EPROTONOSUPPORT = syscall.Errno(0x2b) EPROTOTYPE = syscall.Errno(0x29) ERANGE = syscall.Errno(0x22) @@ -1570,7 +1801,7 @@ var errorList = [...]struct { {32, "EPIPE", "broken pipe"}, {33, "EDOM", "numerical argument out of domain"}, {34, "ERANGE", "result too large"}, - {35, "EWOULDBLOCK", "resource temporarily unavailable"}, + {35, "EAGAIN", "resource temporarily unavailable"}, {36, "EINPROGRESS", "operation now in progress"}, {37, "EALREADY", "operation already in progress"}, {38, "ENOTSOCK", "socket operation on non-socket"}, @@ -1626,7 +1857,11 @@ var errorList = [...]struct { {88, "ECANCELED", "operation canceled"}, {89, "EIDRM", "identifier removed"}, {90, "ENOMSG", "no message of desired type"}, - {91, "ELAST", "not supported"}, + {91, "ENOTSUP", "not supported"}, + {92, "EBADMSG", "bad message"}, + {93, "ENOTRECOVERABLE", "state not recoverable"}, + {94, "EOWNERDEAD", "previous owner died"}, + {95, "ELAST", "protocol error"}, } // Signal table @@ -1640,7 +1875,7 @@ var signalList = [...]struct { {3, "SIGQUIT", "quit"}, {4, "SIGILL", "illegal instruction"}, {5, "SIGTRAP", "trace/BPT trap"}, - {6, "SIGABRT", "abort trap"}, + {6, "SIGIOT", "abort trap"}, {7, "SIGEMT", "EMT trap"}, {8, "SIGFPE", "floating point exception"}, {9, "SIGKILL", "killed"}, @@ -1667,4 +1902,5 @@ var signalList = [...]struct { {30, "SIGUSR1", "user defined signal 1"}, {31, "SIGUSR2", "user defined signal 2"}, {32, "SIGTHR", "thread AST"}, + {28672, "SIGSTKSZ", "unknown signal"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go index 90de7dfc33..ae16fe7542 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go @@ -112,6 +112,12 @@ const ( BPF_FILDROP_CAPTURE = 0x1 BPF_FILDROP_DROP = 0x2 BPF_FILDROP_PASS = 0x0 + BPF_F_DIR_IN = 0x10 + BPF_F_DIR_MASK = 0x30 + BPF_F_DIR_OUT = 0x20 + BPF_F_DIR_SHIFT = 0x4 + BPF_F_FLOWID = 0x8 + BPF_F_PRI_MASK = 0x7 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -140,6 +146,7 @@ const ( BPF_OR = 0x40 BPF_RELEASE = 0x30bb6 BPF_RET = 0x6 + BPF_RND = 0xc0 BPF_RSH = 0x70 BPF_ST = 0x2 BPF_STX = 0x3 @@ -180,7 +187,65 @@ const ( CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 + DIOCADDQUEUE = 0xc110445d + DIOCADDRULE = 0xcd604404 + DIOCADDSTATE = 0xc1084425 + DIOCCHANGERULE = 0xcd60441a + DIOCCLRIFFLAG = 0xc028445a + DIOCCLRSRCNODES = 0x20004455 + DIOCCLRSTATES = 0xc0e04412 + DIOCCLRSTATUS = 0xc0284416 + DIOCGETLIMIT = 0xc0084427 + DIOCGETQSTATS = 0xc1204460 + DIOCGETQUEUE = 0xc110445f + DIOCGETQUEUES = 0xc110445e + DIOCGETRULE = 0xcd604407 + DIOCGETRULES = 0xcd604406 + DIOCGETRULESET = 0xc444443b + DIOCGETRULESETS = 0xc444443a + DIOCGETSRCNODES = 0xc0104454 + DIOCGETSTATE = 0xc1084413 + DIOCGETSTATES = 0xc0104419 + DIOCGETSTATUS = 0xc1e84415 + DIOCGETSYNFLWATS = 0xc0084463 + DIOCGETTIMEOUT = 0xc008441e + DIOCIGETIFACES = 0xc0284457 + DIOCKILLSRCNODES = 0xc080445b + DIOCKILLSTATES = 0xc0e04429 + DIOCNATLOOK = 0xc0504417 + DIOCOSFPADD = 0xc088444f DIOCOSFPFLUSH = 0x2000444e + DIOCOSFPGET = 0xc0884450 + DIOCRADDADDRS = 0xc4504443 + DIOCRADDTABLES = 0xc450443d + DIOCRCLRADDRS = 0xc4504442 + DIOCRCLRASTATS = 0xc4504448 + DIOCRCLRTABLES = 0xc450443c + DIOCRCLRTSTATS = 0xc4504441 + DIOCRDELADDRS = 0xc4504444 + DIOCRDELTABLES = 0xc450443e + DIOCRGETADDRS = 0xc4504446 + DIOCRGETASTATS = 0xc4504447 + DIOCRGETTABLES = 0xc450443f + DIOCRGETTSTATS = 0xc4504440 + DIOCRINADEFINE = 0xc450444d + DIOCRSETADDRS = 0xc4504445 + DIOCRSETTFLAGS = 0xc450444a + DIOCRTSTADDRS = 0xc4504449 + DIOCSETDEBUG = 0xc0044418 + DIOCSETHOSTID = 0xc0044456 + DIOCSETIFFLAG = 0xc0284459 + DIOCSETLIMIT = 0xc0084428 + DIOCSETREASS = 0xc004445c + DIOCSETSTATUSIF = 0xc0284414 + DIOCSETSYNCOOKIES = 0xc0014462 + DIOCSETSYNFLWATS = 0xc0084461 + DIOCSETTIMEOUT = 0xc008441d + DIOCSTART = 0x20004401 + DIOCSTOP = 0x20004402 + DIOCXBEGIN = 0xc0104451 + DIOCXCOMMIT = 0xc0104452 + DIOCXROLLBACK = 0xc0104453 DLT_ARCNET = 0x7 DLT_ATM_RFC1483 = 0xb DLT_AX25 = 0x3 @@ -243,6 +308,8 @@ const ( EMUL_ENABLED = 0x1 EMUL_NATIVE = 0x2 ENDRUNDISC = 0x9 + ETH64_8021_RSVD_MASK = 0xfffffffffff0 + ETH64_8021_RSVD_PREFIX = 0x180c2000000 ETHERMIN = 0x2e ETHERMTU = 0x5dc ETHERTYPE_8023 = 0x4 @@ -295,6 +362,7 @@ const ( ETHERTYPE_DN = 0x6003 ETHERTYPE_DOGFIGHT = 0x1989 ETHERTYPE_DSMD = 0x8039 + ETHERTYPE_EAPOL = 0x888e ETHERTYPE_ECMA = 0x803 ETHERTYPE_ENCRYPT = 0x803d ETHERTYPE_ES = 0x805d @@ -326,6 +394,7 @@ const ( ETHERTYPE_LLDP = 0x88cc ETHERTYPE_LOGICRAFT = 0x8148 ETHERTYPE_LOOPBACK = 0x9000 + ETHERTYPE_MACSEC = 0x88e5 ETHERTYPE_MATRA = 0x807a ETHERTYPE_MAX = 0xffff ETHERTYPE_MERIT = 0x807c @@ -354,15 +423,16 @@ const ( ETHERTYPE_NCD = 0x8149 ETHERTYPE_NESTAR = 0x8006 ETHERTYPE_NETBEUI = 0x8191 + ETHERTYPE_NHRP = 0x2001 ETHERTYPE_NOVELL = 0x8138 ETHERTYPE_NS = 0x600 ETHERTYPE_NSAT = 0x601 ETHERTYPE_NSCOMPAT = 0x807 + ETHERTYPE_NSH = 0x984f ETHERTYPE_NTRAILER = 0x10 ETHERTYPE_OS9 = 0x7007 ETHERTYPE_OS9NET = 0x7009 ETHERTYPE_PACER = 0x80c6 - ETHERTYPE_PAE = 0x888e ETHERTYPE_PBB = 0x88e7 ETHERTYPE_PCS = 0x4242 ETHERTYPE_PLANNING = 0x8044 @@ -445,10 +515,11 @@ const ( ETHER_VLAN_ENCAP_LEN = 0x4 EVFILT_AIO = -0x3 EVFILT_DEVICE = -0x8 + EVFILT_EXCEPT = -0x9 EVFILT_PROC = -0x5 EVFILT_READ = -0x1 EVFILT_SIGNAL = -0x6 - EVFILT_SYSCOUNT = 0x8 + EVFILT_SYSCOUNT = 0x9 EVFILT_TIMER = -0x7 EVFILT_VNODE = -0x4 EVFILT_WRITE = -0x2 @@ -470,7 +541,7 @@ const ( EV_FLAG1 = 0x2000 EV_ONESHOT = 0x10 EV_RECEIPT = 0x40 - EV_SYSFLAGS = 0xf000 + EV_SYSFLAGS = 0xf800 EXTA = 0x4b00 EXTB = 0x9600 EXTPROC = 0x800 @@ -736,6 +807,7 @@ const ( IFT_VOICEOVERCABLE = 0xc6 IFT_VOICEOVERFRAMERELAY = 0x99 IFT_VOICEOVERIP = 0x68 + IFT_WIREGUARD = 0xfb IFT_X213 = 0x5d IFT_X25 = 0x5 IFT_X25DDN = 0x4 @@ -801,9 +873,11 @@ const ( IPPROTO_RAW = 0xff IPPROTO_ROUTING = 0x2b IPPROTO_RSVP = 0x2e + IPPROTO_SCTP = 0x84 IPPROTO_TCP = 0x6 IPPROTO_TP = 0x1d IPPROTO_UDP = 0x11 + IPPROTO_UDPLITE = 0x88 IPV6_AUTH_LEVEL = 0x35 IPV6_AUTOFLOWLABEL = 0x3b IPV6_CHECKSUM = 0x1a @@ -910,6 +984,9 @@ const ( IP_TTL = 0x4 ISIG = 0x80 ISTRIP = 0x20 + ITIMER_PROF = 0x2 + ITIMER_REAL = 0x0 + ITIMER_VIRTUAL = 0x1 IUCLC = 0x1000 IXANY = 0x800 IXOFF = 0x400 @@ -981,6 +1058,19 @@ const ( MNT_WAIT = 0x1 MNT_WANTRDWR = 0x2000000 MNT_WXALLOWED = 0x800 + MOUNT_AFS = "afs" + MOUNT_CD9660 = "cd9660" + MOUNT_EXT2FS = "ext2fs" + MOUNT_FFS = "ffs" + MOUNT_FUSEFS = "fuse" + MOUNT_MFS = "mfs" + MOUNT_MSDOS = "msdos" + MOUNT_NCPFS = "ncpfs" + MOUNT_NFS = "nfs" + MOUNT_NTFS = "ntfs" + MOUNT_TMPFS = "tmpfs" + MOUNT_UDF = "udf" + MOUNT_UFS = "ffs" MSG_BCAST = 0x100 MSG_CMSG_CLOEXEC = 0x800 MSG_CTRUNC = 0x20 @@ -993,6 +1083,7 @@ const ( MSG_PEEK = 0x2 MSG_TRUNC = 0x10 MSG_WAITALL = 0x40 + MSG_WAITFORONE = 0x1000 MS_ASYNC = 0x1 MS_INVALIDATE = 0x4 MS_SYNC = 0x2 @@ -1001,7 +1092,8 @@ const ( NET_RT_FLAGS = 0x2 NET_RT_IFLIST = 0x3 NET_RT_IFNAMES = 0x6 - NET_RT_MAXID = 0x7 + NET_RT_MAXID = 0x8 + NET_RT_SOURCE = 0x7 NET_RT_STATS = 0x4 NET_RT_TABLE = 0x5 NFDBITS = 0x20 @@ -1018,6 +1110,7 @@ const ( NOTE_FORK = 0x40000000 NOTE_LINK = 0x10 NOTE_LOWAT = 0x1 + NOTE_OOB = 0x4 NOTE_PCTRLMASK = 0xf0000000 NOTE_PDATAMASK = 0xfffff NOTE_RENAME = 0x20 @@ -1154,7 +1247,7 @@ const ( RTM_PROPOSAL = 0x13 RTM_REDIRECT = 0x6 RTM_RESOLVE = 0xb - RTM_RTTUNIT = 0xf4240 + RTM_SOURCE = 0x16 RTM_VERSION = 0x5 RTV_EXPIRE = 0x4 RTV_HOPCOUNT = 0x2 @@ -1172,6 +1265,9 @@ const ( RUSAGE_THREAD = 0x1 SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x4 + SEEK_CUR = 0x1 + SEEK_END = 0x2 + SEEK_SET = 0x0 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1188,30 +1284,30 @@ const ( SIOCBRDGDELS = 0x80606942 SIOCBRDGFLUSH = 0x80606948 SIOCBRDGFRL = 0x808c694e - SIOCBRDGGCACHE = 0xc0186941 - SIOCBRDGGFD = 0xc0186952 - SIOCBRDGGHT = 0xc0186951 + SIOCBRDGGCACHE = 0xc0146941 + SIOCBRDGGFD = 0xc0146952 + SIOCBRDGGHT = 0xc0146951 SIOCBRDGGIFFLGS = 0xc060693e - SIOCBRDGGMA = 0xc0186953 + SIOCBRDGGMA = 0xc0146953 SIOCBRDGGPARAM = 0xc0406958 - SIOCBRDGGPRI = 0xc0186950 + SIOCBRDGGPRI = 0xc0146950 SIOCBRDGGRL = 0xc030694f - SIOCBRDGGTO = 0xc0186946 + SIOCBRDGGTO = 0xc0146946 SIOCBRDGIFS = 0xc0606942 SIOCBRDGRTS = 0xc0206943 SIOCBRDGSADDR = 0xc1286944 - SIOCBRDGSCACHE = 0x80186940 - SIOCBRDGSFD = 0x80186952 - SIOCBRDGSHT = 0x80186951 + SIOCBRDGSCACHE = 0x80146940 + SIOCBRDGSFD = 0x80146952 + SIOCBRDGSHT = 0x80146951 SIOCBRDGSIFCOST = 0x80606955 SIOCBRDGSIFFLGS = 0x8060693f SIOCBRDGSIFPRIO = 0x80606954 SIOCBRDGSIFPROT = 0x8060694a - SIOCBRDGSMA = 0x80186953 - SIOCBRDGSPRI = 0x80186950 - SIOCBRDGSPROTO = 0x8018695a - SIOCBRDGSTO = 0x80186945 - SIOCBRDGSTXHC = 0x80186959 + SIOCBRDGSMA = 0x80146953 + SIOCBRDGSPRI = 0x80146950 + SIOCBRDGSPROTO = 0x8014695a + SIOCBRDGSTO = 0x80146945 + SIOCBRDGSTXHC = 0x80146959 SIOCDELLABEL = 0x80206997 SIOCDELMULTI = 0x80206932 SIOCDIFADDR = 0x80206919 @@ -1264,6 +1360,7 @@ const ( SIOCGPWE3CTRLWORD = 0xc02069dc SIOCGPWE3FAT = 0xc02069dd SIOCGPWE3NEIGHBOR = 0xc21869de + SIOCGRXHPRIO = 0xc02069db SIOCGSPPPPARAMS = 0xc0206994 SIOCGTXHPRIO = 0xc02069c6 SIOCGUMBINFO = 0xc02069be @@ -1310,17 +1407,13 @@ const ( SIOCSPWE3CTRLWORD = 0x802069dc SIOCSPWE3FAT = 0x802069dd SIOCSPWE3NEIGHBOR = 0x821869de + SIOCSRXHPRIO = 0x802069db SIOCSSPPPPARAMS = 0x80206993 SIOCSTXHPRIO = 0x802069c5 SIOCSUMBPARAM = 0x802069bf SIOCSVH = 0xc02069f5 SIOCSVNETFLOWID = 0x802069c3 SIOCSVNETID = 0x802069a6 - SIOCSWGDPID = 0xc018695b - SIOCSWGMAXFLOW = 0xc0186960 - SIOCSWGMAXGROUP = 0xc018695d - SIOCSWSDPID = 0x8018695c - SIOCSWSPORTNO = 0xc060695f SOCK_CLOEXEC = 0x8000 SOCK_DGRAM = 0x2 SOCK_DNS = 0x1000 @@ -1335,6 +1428,7 @@ const ( SO_BINDANY = 0x1000 SO_BROADCAST = 0x20 SO_DEBUG = 0x1 + SO_DOMAIN = 0x1024 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 SO_KEEPALIVE = 0x8 @@ -1342,6 +1436,7 @@ const ( SO_NETPROC = 0x1020 SO_OOBINLINE = 0x100 SO_PEERCRED = 0x1022 + SO_PROTOCOL = 0x1025 SO_RCVBUF = 0x1002 SO_RCVLOWAT = 0x1004 SO_RCVTIMEO = 0x1006 @@ -1391,7 +1486,18 @@ const ( TCOFLUSH = 0x2 TCOOFF = 0x1 TCOON = 0x2 - TCP_MAXBURST = 0x4 + TCPOPT_EOL = 0x0 + TCPOPT_MAXSEG = 0x2 + TCPOPT_NOP = 0x1 + TCPOPT_SACK = 0x5 + TCPOPT_SACK_HDR = 0x1010500 + TCPOPT_SACK_PERMITTED = 0x4 + TCPOPT_SACK_PERMIT_HDR = 0x1010402 + TCPOPT_SIGNATURE = 0x13 + TCPOPT_TIMESTAMP = 0x8 + TCPOPT_TSTAMP_HDR = 0x101080a + TCPOPT_WINDOW = 0x3 + TCP_INFO = 0x9 TCP_MAXSEG = 0x2 TCP_MAXWIN = 0xffff TCP_MAX_SACK = 0x3 @@ -1400,6 +1506,7 @@ const ( TCP_MSS = 0x200 TCP_NODELAY = 0x1 TCP_NOPUSH = 0x10 + TCP_SACKHOLE_LIMIT = 0x80 TCP_SACK_ENABLE = 0x8 TCSAFLUSH = 0x2 TIMER_ABSTIME = 0x1 @@ -1768,7 +1875,7 @@ var signalList = [...]struct { {3, "SIGQUIT", "quit"}, {4, "SIGILL", "illegal instruction"}, {5, "SIGTRAP", "trace/BPT trap"}, - {6, "SIGABRT", "abort trap"}, + {6, "SIGIOT", "abort trap"}, {7, "SIGEMT", "EMT trap"}, {8, "SIGFPE", "floating point exception"}, {9, "SIGKILL", "killed"}, @@ -1795,4 +1902,5 @@ var signalList = [...]struct { {30, "SIGUSR1", "user defined signal 1"}, {31, "SIGUSR2", "user defined signal 2"}, {32, "SIGTHR", "thread AST"}, + {28672, "SIGSTKSZ", "unknown signal"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go index f1154ff56f..03d90fe355 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go @@ -112,6 +112,12 @@ const ( BPF_FILDROP_CAPTURE = 0x1 BPF_FILDROP_DROP = 0x2 BPF_FILDROP_PASS = 0x0 + BPF_F_DIR_IN = 0x10 + BPF_F_DIR_MASK = 0x30 + BPF_F_DIR_OUT = 0x20 + BPF_F_DIR_SHIFT = 0x4 + BPF_F_FLOWID = 0x8 + BPF_F_PRI_MASK = 0x7 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -140,6 +146,7 @@ const ( BPF_OR = 0x40 BPF_RELEASE = 0x30bb6 BPF_RET = 0x6 + BPF_RND = 0xc0 BPF_RSH = 0x70 BPF_ST = 0x2 BPF_STX = 0x3 @@ -301,6 +308,8 @@ const ( EMUL_ENABLED = 0x1 EMUL_NATIVE = 0x2 ENDRUNDISC = 0x9 + ETH64_8021_RSVD_MASK = 0xfffffffffff0 + ETH64_8021_RSVD_PREFIX = 0x180c2000000 ETHERMIN = 0x2e ETHERMTU = 0x5dc ETHERTYPE_8023 = 0x4 @@ -353,6 +362,7 @@ const ( ETHERTYPE_DN = 0x6003 ETHERTYPE_DOGFIGHT = 0x1989 ETHERTYPE_DSMD = 0x8039 + ETHERTYPE_EAPOL = 0x888e ETHERTYPE_ECMA = 0x803 ETHERTYPE_ENCRYPT = 0x803d ETHERTYPE_ES = 0x805d @@ -413,15 +423,16 @@ const ( ETHERTYPE_NCD = 0x8149 ETHERTYPE_NESTAR = 0x8006 ETHERTYPE_NETBEUI = 0x8191 + ETHERTYPE_NHRP = 0x2001 ETHERTYPE_NOVELL = 0x8138 ETHERTYPE_NS = 0x600 ETHERTYPE_NSAT = 0x601 ETHERTYPE_NSCOMPAT = 0x807 + ETHERTYPE_NSH = 0x984f ETHERTYPE_NTRAILER = 0x10 ETHERTYPE_OS9 = 0x7007 ETHERTYPE_OS9NET = 0x7009 ETHERTYPE_PACER = 0x80c6 - ETHERTYPE_PAE = 0x888e ETHERTYPE_PBB = 0x88e7 ETHERTYPE_PCS = 0x4242 ETHERTYPE_PLANNING = 0x8044 @@ -504,10 +515,11 @@ const ( ETHER_VLAN_ENCAP_LEN = 0x4 EVFILT_AIO = -0x3 EVFILT_DEVICE = -0x8 + EVFILT_EXCEPT = -0x9 EVFILT_PROC = -0x5 EVFILT_READ = -0x1 EVFILT_SIGNAL = -0x6 - EVFILT_SYSCOUNT = 0x8 + EVFILT_SYSCOUNT = 0x9 EVFILT_TIMER = -0x7 EVFILT_VNODE = -0x4 EVFILT_WRITE = -0x2 @@ -529,7 +541,7 @@ const ( EV_FLAG1 = 0x2000 EV_ONESHOT = 0x10 EV_RECEIPT = 0x40 - EV_SYSFLAGS = 0xf000 + EV_SYSFLAGS = 0xf800 EXTA = 0x4b00 EXTB = 0x9600 EXTPROC = 0x800 @@ -795,6 +807,7 @@ const ( IFT_VOICEOVERCABLE = 0xc6 IFT_VOICEOVERFRAMERELAY = 0x99 IFT_VOICEOVERIP = 0x68 + IFT_WIREGUARD = 0xfb IFT_X213 = 0x5d IFT_X25 = 0x5 IFT_X25DDN = 0x4 @@ -860,6 +873,7 @@ const ( IPPROTO_RAW = 0xff IPPROTO_ROUTING = 0x2b IPPROTO_RSVP = 0x2e + IPPROTO_SCTP = 0x84 IPPROTO_TCP = 0x6 IPPROTO_TP = 0x1d IPPROTO_UDP = 0x11 @@ -970,6 +984,9 @@ const ( IP_TTL = 0x4 ISIG = 0x80 ISTRIP = 0x20 + ITIMER_PROF = 0x2 + ITIMER_REAL = 0x0 + ITIMER_VIRTUAL = 0x1 IUCLC = 0x1000 IXANY = 0x800 IXOFF = 0x400 @@ -1041,6 +1058,19 @@ const ( MNT_WAIT = 0x1 MNT_WANTRDWR = 0x2000000 MNT_WXALLOWED = 0x800 + MOUNT_AFS = "afs" + MOUNT_CD9660 = "cd9660" + MOUNT_EXT2FS = "ext2fs" + MOUNT_FFS = "ffs" + MOUNT_FUSEFS = "fuse" + MOUNT_MFS = "mfs" + MOUNT_MSDOS = "msdos" + MOUNT_NCPFS = "ncpfs" + MOUNT_NFS = "nfs" + MOUNT_NTFS = "ntfs" + MOUNT_TMPFS = "tmpfs" + MOUNT_UDF = "udf" + MOUNT_UFS = "ffs" MSG_BCAST = 0x100 MSG_CMSG_CLOEXEC = 0x800 MSG_CTRUNC = 0x20 @@ -1053,6 +1083,7 @@ const ( MSG_PEEK = 0x2 MSG_TRUNC = 0x10 MSG_WAITALL = 0x40 + MSG_WAITFORONE = 0x1000 MS_ASYNC = 0x1 MS_INVALIDATE = 0x4 MS_SYNC = 0x2 @@ -1061,7 +1092,8 @@ const ( NET_RT_FLAGS = 0x2 NET_RT_IFLIST = 0x3 NET_RT_IFNAMES = 0x6 - NET_RT_MAXID = 0x7 + NET_RT_MAXID = 0x8 + NET_RT_SOURCE = 0x7 NET_RT_STATS = 0x4 NET_RT_TABLE = 0x5 NFDBITS = 0x20 @@ -1078,6 +1110,7 @@ const ( NOTE_FORK = 0x40000000 NOTE_LINK = 0x10 NOTE_LOWAT = 0x1 + NOTE_OOB = 0x4 NOTE_PCTRLMASK = 0xf0000000 NOTE_PDATAMASK = 0xfffff NOTE_RENAME = 0x20 @@ -1214,7 +1247,7 @@ const ( RTM_PROPOSAL = 0x13 RTM_REDIRECT = 0x6 RTM_RESOLVE = 0xb - RTM_RTTUNIT = 0xf4240 + RTM_SOURCE = 0x16 RTM_VERSION = 0x5 RTV_EXPIRE = 0x4 RTV_HOPCOUNT = 0x2 @@ -1232,6 +1265,9 @@ const ( RUSAGE_THREAD = 0x1 SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x4 + SEEK_CUR = 0x1 + SEEK_END = 0x2 + SEEK_SET = 0x0 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1248,30 +1284,30 @@ const ( SIOCBRDGDELS = 0x80606942 SIOCBRDGFLUSH = 0x80606948 SIOCBRDGFRL = 0x808c694e - SIOCBRDGGCACHE = 0xc0186941 - SIOCBRDGGFD = 0xc0186952 - SIOCBRDGGHT = 0xc0186951 + SIOCBRDGGCACHE = 0xc0146941 + SIOCBRDGGFD = 0xc0146952 + SIOCBRDGGHT = 0xc0146951 SIOCBRDGGIFFLGS = 0xc060693e - SIOCBRDGGMA = 0xc0186953 + SIOCBRDGGMA = 0xc0146953 SIOCBRDGGPARAM = 0xc0406958 - SIOCBRDGGPRI = 0xc0186950 + SIOCBRDGGPRI = 0xc0146950 SIOCBRDGGRL = 0xc030694f - SIOCBRDGGTO = 0xc0186946 + SIOCBRDGGTO = 0xc0146946 SIOCBRDGIFS = 0xc0606942 SIOCBRDGRTS = 0xc0206943 SIOCBRDGSADDR = 0xc1286944 - SIOCBRDGSCACHE = 0x80186940 - SIOCBRDGSFD = 0x80186952 - SIOCBRDGSHT = 0x80186951 + SIOCBRDGSCACHE = 0x80146940 + SIOCBRDGSFD = 0x80146952 + SIOCBRDGSHT = 0x80146951 SIOCBRDGSIFCOST = 0x80606955 SIOCBRDGSIFFLGS = 0x8060693f SIOCBRDGSIFPRIO = 0x80606954 SIOCBRDGSIFPROT = 0x8060694a - SIOCBRDGSMA = 0x80186953 - SIOCBRDGSPRI = 0x80186950 - SIOCBRDGSPROTO = 0x8018695a - SIOCBRDGSTO = 0x80186945 - SIOCBRDGSTXHC = 0x80186959 + SIOCBRDGSMA = 0x80146953 + SIOCBRDGSPRI = 0x80146950 + SIOCBRDGSPROTO = 0x8014695a + SIOCBRDGSTO = 0x80146945 + SIOCBRDGSTXHC = 0x80146959 SIOCDELLABEL = 0x80206997 SIOCDELMULTI = 0x80206932 SIOCDIFADDR = 0x80206919 @@ -1378,11 +1414,6 @@ const ( SIOCSVH = 0xc02069f5 SIOCSVNETFLOWID = 0x802069c3 SIOCSVNETID = 0x802069a6 - SIOCSWGDPID = 0xc018695b - SIOCSWGMAXFLOW = 0xc0186960 - SIOCSWGMAXGROUP = 0xc018695d - SIOCSWSDPID = 0x8018695c - SIOCSWSPORTNO = 0xc060695f SOCK_CLOEXEC = 0x8000 SOCK_DGRAM = 0x2 SOCK_DNS = 0x1000 @@ -1455,7 +1486,18 @@ const ( TCOFLUSH = 0x2 TCOOFF = 0x1 TCOON = 0x2 - TCP_MAXBURST = 0x4 + TCPOPT_EOL = 0x0 + TCPOPT_MAXSEG = 0x2 + TCPOPT_NOP = 0x1 + TCPOPT_SACK = 0x5 + TCPOPT_SACK_HDR = 0x1010500 + TCPOPT_SACK_PERMITTED = 0x4 + TCPOPT_SACK_PERMIT_HDR = 0x1010402 + TCPOPT_SIGNATURE = 0x13 + TCPOPT_TIMESTAMP = 0x8 + TCPOPT_TSTAMP_HDR = 0x101080a + TCPOPT_WINDOW = 0x3 + TCP_INFO = 0x9 TCP_MAXSEG = 0x2 TCP_MAXWIN = 0xffff TCP_MAX_SACK = 0x3 @@ -1833,7 +1875,7 @@ var signalList = [...]struct { {3, "SIGQUIT", "quit"}, {4, "SIGILL", "illegal instruction"}, {5, "SIGTRAP", "trace/BPT trap"}, - {6, "SIGABRT", "abort trap"}, + {6, "SIGIOT", "abort trap"}, {7, "SIGEMT", "EMT trap"}, {8, "SIGFPE", "floating point exception"}, {9, "SIGKILL", "killed"}, @@ -1860,4 +1902,5 @@ var signalList = [...]struct { {30, "SIGUSR1", "user defined signal 1"}, {31, "SIGUSR2", "user defined signal 2"}, {32, "SIGTHR", "thread AST"}, + {81920, "SIGSTKSZ", "unknown signal"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_ppc64.go new file mode 100644 index 0000000000..8e2c51b1ee --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_ppc64.go @@ -0,0 +1,1905 @@ +// mkerrors.sh -m64 +// Code generated by the command above; see README.md. DO NOT EDIT. + +//go:build ppc64 && openbsd +// +build ppc64,openbsd + +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs -- -m64 _const.go + +package unix + +import "syscall" + +const ( + AF_APPLETALK = 0x10 + AF_BLUETOOTH = 0x20 + AF_CCITT = 0xa + AF_CHAOS = 0x5 + AF_CNT = 0x15 + AF_COIP = 0x14 + AF_DATAKIT = 0x9 + AF_DECnet = 0xc + AF_DLI = 0xd + AF_E164 = 0x1a + AF_ECMA = 0x8 + AF_ENCAP = 0x1c + AF_HYLINK = 0xf + AF_IMPLINK = 0x3 + AF_INET = 0x2 + AF_INET6 = 0x18 + AF_IPX = 0x17 + AF_ISDN = 0x1a + AF_ISO = 0x7 + AF_KEY = 0x1e + AF_LAT = 0xe + AF_LINK = 0x12 + AF_LOCAL = 0x1 + AF_MAX = 0x24 + AF_MPLS = 0x21 + AF_NATM = 0x1b + AF_NS = 0x6 + AF_OSI = 0x7 + AF_PUP = 0x4 + AF_ROUTE = 0x11 + AF_SIP = 0x1d + AF_SNA = 0xb + AF_UNIX = 0x1 + AF_UNSPEC = 0x0 + ALTWERASE = 0x200 + ARPHRD_ETHER = 0x1 + ARPHRD_FRELAY = 0xf + ARPHRD_IEEE1394 = 0x18 + ARPHRD_IEEE802 = 0x6 + B0 = 0x0 + B110 = 0x6e + B115200 = 0x1c200 + B1200 = 0x4b0 + B134 = 0x86 + B14400 = 0x3840 + B150 = 0x96 + B1800 = 0x708 + B19200 = 0x4b00 + B200 = 0xc8 + B230400 = 0x38400 + B2400 = 0x960 + B28800 = 0x7080 + B300 = 0x12c + B38400 = 0x9600 + B4800 = 0x12c0 + B50 = 0x32 + B57600 = 0xe100 + B600 = 0x258 + B7200 = 0x1c20 + B75 = 0x4b + B76800 = 0x12c00 + B9600 = 0x2580 + BIOCFLUSH = 0x20004268 + BIOCGBLEN = 0x40044266 + BIOCGDIRFILT = 0x4004427c + BIOCGDLT = 0x4004426a + BIOCGDLTLIST = 0xc010427b + BIOCGETIF = 0x4020426b + BIOCGFILDROP = 0x40044278 + BIOCGHDRCMPLT = 0x40044274 + BIOCGRSIG = 0x40044273 + BIOCGRTIMEOUT = 0x4010426e + BIOCGSTATS = 0x4008426f + BIOCIMMEDIATE = 0x80044270 + BIOCLOCK = 0x20004276 + BIOCPROMISC = 0x20004269 + BIOCSBLEN = 0xc0044266 + BIOCSDIRFILT = 0x8004427d + BIOCSDLT = 0x8004427a + BIOCSETF = 0x80104267 + BIOCSETIF = 0x8020426c + BIOCSETWF = 0x80104277 + BIOCSFILDROP = 0x80044279 + BIOCSHDRCMPLT = 0x80044275 + BIOCSRSIG = 0x80044272 + BIOCSRTIMEOUT = 0x8010426d + BIOCVERSION = 0x40044271 + BPF_A = 0x10 + BPF_ABS = 0x20 + BPF_ADD = 0x0 + BPF_ALIGNMENT = 0x4 + BPF_ALU = 0x4 + BPF_AND = 0x50 + BPF_B = 0x10 + BPF_DIRECTION_IN = 0x1 + BPF_DIRECTION_OUT = 0x2 + BPF_DIV = 0x30 + BPF_FILDROP_CAPTURE = 0x1 + BPF_FILDROP_DROP = 0x2 + BPF_FILDROP_PASS = 0x0 + BPF_F_DIR_IN = 0x10 + BPF_F_DIR_MASK = 0x30 + BPF_F_DIR_OUT = 0x20 + BPF_F_DIR_SHIFT = 0x4 + BPF_F_FLOWID = 0x8 + BPF_F_PRI_MASK = 0x7 + BPF_H = 0x8 + BPF_IMM = 0x0 + BPF_IND = 0x40 + BPF_JA = 0x0 + BPF_JEQ = 0x10 + BPF_JGE = 0x30 + BPF_JGT = 0x20 + BPF_JMP = 0x5 + BPF_JSET = 0x40 + BPF_K = 0x0 + BPF_LD = 0x0 + BPF_LDX = 0x1 + BPF_LEN = 0x80 + BPF_LSH = 0x60 + BPF_MAJOR_VERSION = 0x1 + BPF_MAXBUFSIZE = 0x200000 + BPF_MAXINSNS = 0x200 + BPF_MEM = 0x60 + BPF_MEMWORDS = 0x10 + BPF_MINBUFSIZE = 0x20 + BPF_MINOR_VERSION = 0x1 + BPF_MISC = 0x7 + BPF_MSH = 0xa0 + BPF_MUL = 0x20 + BPF_NEG = 0x80 + BPF_OR = 0x40 + BPF_RELEASE = 0x30bb6 + BPF_RET = 0x6 + BPF_RND = 0xc0 + BPF_RSH = 0x70 + BPF_ST = 0x2 + BPF_STX = 0x3 + BPF_SUB = 0x10 + BPF_TAX = 0x0 + BPF_TXA = 0x80 + BPF_W = 0x0 + BPF_X = 0x8 + BRKINT = 0x2 + CFLUSH = 0xf + CLOCAL = 0x8000 + CLOCK_BOOTTIME = 0x6 + CLOCK_MONOTONIC = 0x3 + CLOCK_PROCESS_CPUTIME_ID = 0x2 + CLOCK_REALTIME = 0x0 + CLOCK_THREAD_CPUTIME_ID = 0x4 + CLOCK_UPTIME = 0x5 + CPUSTATES = 0x6 + CP_IDLE = 0x5 + CP_INTR = 0x4 + CP_NICE = 0x1 + CP_SPIN = 0x3 + CP_SYS = 0x2 + CP_USER = 0x0 + CREAD = 0x800 + CRTSCTS = 0x10000 + CS5 = 0x0 + CS6 = 0x100 + CS7 = 0x200 + CS8 = 0x300 + CSIZE = 0x300 + CSTART = 0x11 + CSTATUS = 0xff + CSTOP = 0x13 + CSTOPB = 0x400 + CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 + CTL_MAXNAME = 0xc + CTL_NET = 0x4 + DIOCADDQUEUE = 0xc110445d + DIOCADDRULE = 0xcd604404 + DIOCADDSTATE = 0xc1084425 + DIOCCHANGERULE = 0xcd60441a + DIOCCLRIFFLAG = 0xc028445a + DIOCCLRSRCNODES = 0x20004455 + DIOCCLRSTATES = 0xc0e04412 + DIOCCLRSTATUS = 0xc0284416 + DIOCGETLIMIT = 0xc0084427 + DIOCGETQSTATS = 0xc1204460 + DIOCGETQUEUE = 0xc110445f + DIOCGETQUEUES = 0xc110445e + DIOCGETRULE = 0xcd604407 + DIOCGETRULES = 0xcd604406 + DIOCGETRULESET = 0xc444443b + DIOCGETRULESETS = 0xc444443a + DIOCGETSRCNODES = 0xc0104454 + DIOCGETSTATE = 0xc1084413 + DIOCGETSTATES = 0xc0104419 + DIOCGETSTATUS = 0xc1e84415 + DIOCGETSYNFLWATS = 0xc0084463 + DIOCGETTIMEOUT = 0xc008441e + DIOCIGETIFACES = 0xc0284457 + DIOCKILLSRCNODES = 0xc080445b + DIOCKILLSTATES = 0xc0e04429 + DIOCNATLOOK = 0xc0504417 + DIOCOSFPADD = 0xc088444f + DIOCOSFPFLUSH = 0x2000444e + DIOCOSFPGET = 0xc0884450 + DIOCRADDADDRS = 0xc4504443 + DIOCRADDTABLES = 0xc450443d + DIOCRCLRADDRS = 0xc4504442 + DIOCRCLRASTATS = 0xc4504448 + DIOCRCLRTABLES = 0xc450443c + DIOCRCLRTSTATS = 0xc4504441 + DIOCRDELADDRS = 0xc4504444 + DIOCRDELTABLES = 0xc450443e + DIOCRGETADDRS = 0xc4504446 + DIOCRGETASTATS = 0xc4504447 + DIOCRGETTABLES = 0xc450443f + DIOCRGETTSTATS = 0xc4504440 + DIOCRINADEFINE = 0xc450444d + DIOCRSETADDRS = 0xc4504445 + DIOCRSETTFLAGS = 0xc450444a + DIOCRTSTADDRS = 0xc4504449 + DIOCSETDEBUG = 0xc0044418 + DIOCSETHOSTID = 0xc0044456 + DIOCSETIFFLAG = 0xc0284459 + DIOCSETLIMIT = 0xc0084428 + DIOCSETREASS = 0xc004445c + DIOCSETSTATUSIF = 0xc0284414 + DIOCSETSYNCOOKIES = 0xc0014462 + DIOCSETSYNFLWATS = 0xc0084461 + DIOCSETTIMEOUT = 0xc008441d + DIOCSTART = 0x20004401 + DIOCSTOP = 0x20004402 + DIOCXBEGIN = 0xc0104451 + DIOCXCOMMIT = 0xc0104452 + DIOCXROLLBACK = 0xc0104453 + DLT_ARCNET = 0x7 + DLT_ATM_RFC1483 = 0xb + DLT_AX25 = 0x3 + DLT_CHAOS = 0x5 + DLT_C_HDLC = 0x68 + DLT_EN10MB = 0x1 + DLT_EN3MB = 0x2 + DLT_ENC = 0xd + DLT_FDDI = 0xa + DLT_IEEE802 = 0x6 + DLT_IEEE802_11 = 0x69 + DLT_IEEE802_11_RADIO = 0x7f + DLT_LOOP = 0xc + DLT_MPLS = 0xdb + DLT_NULL = 0x0 + DLT_OPENFLOW = 0x10b + DLT_PFLOG = 0x75 + DLT_PFSYNC = 0x12 + DLT_PPP = 0x9 + DLT_PPP_BSDOS = 0x10 + DLT_PPP_ETHER = 0x33 + DLT_PPP_SERIAL = 0x32 + DLT_PRONET = 0x4 + DLT_RAW = 0xe + DLT_SLIP = 0x8 + DLT_SLIP_BSDOS = 0xf + DLT_USBPCAP = 0xf9 + DLT_USER0 = 0x93 + DLT_USER1 = 0x94 + DLT_USER10 = 0x9d + DLT_USER11 = 0x9e + DLT_USER12 = 0x9f + DLT_USER13 = 0xa0 + DLT_USER14 = 0xa1 + DLT_USER15 = 0xa2 + DLT_USER2 = 0x95 + DLT_USER3 = 0x96 + DLT_USER4 = 0x97 + DLT_USER5 = 0x98 + DLT_USER6 = 0x99 + DLT_USER7 = 0x9a + DLT_USER8 = 0x9b + DLT_USER9 = 0x9c + DT_BLK = 0x6 + DT_CHR = 0x2 + DT_DIR = 0x4 + DT_FIFO = 0x1 + DT_LNK = 0xa + DT_REG = 0x8 + DT_SOCK = 0xc + DT_UNKNOWN = 0x0 + ECHO = 0x8 + ECHOCTL = 0x40 + ECHOE = 0x2 + ECHOK = 0x4 + ECHOKE = 0x1 + ECHONL = 0x10 + ECHOPRT = 0x20 + EMT_TAGOVF = 0x1 + EMUL_ENABLED = 0x1 + EMUL_NATIVE = 0x2 + ENDRUNDISC = 0x9 + ETH64_8021_RSVD_MASK = 0xfffffffffff0 + ETH64_8021_RSVD_PREFIX = 0x180c2000000 + ETHERMIN = 0x2e + ETHERMTU = 0x5dc + ETHERTYPE_8023 = 0x4 + ETHERTYPE_AARP = 0x80f3 + ETHERTYPE_ACCTON = 0x8390 + ETHERTYPE_AEONIC = 0x8036 + ETHERTYPE_ALPHA = 0x814a + ETHERTYPE_AMBER = 0x6008 + ETHERTYPE_AMOEBA = 0x8145 + ETHERTYPE_AOE = 0x88a2 + ETHERTYPE_APOLLO = 0x80f7 + ETHERTYPE_APOLLODOMAIN = 0x8019 + ETHERTYPE_APPLETALK = 0x809b + ETHERTYPE_APPLITEK = 0x80c7 + ETHERTYPE_ARGONAUT = 0x803a + ETHERTYPE_ARP = 0x806 + ETHERTYPE_AT = 0x809b + ETHERTYPE_ATALK = 0x809b + ETHERTYPE_ATOMIC = 0x86df + ETHERTYPE_ATT = 0x8069 + ETHERTYPE_ATTSTANFORD = 0x8008 + ETHERTYPE_AUTOPHON = 0x806a + ETHERTYPE_AXIS = 0x8856 + ETHERTYPE_BCLOOP = 0x9003 + ETHERTYPE_BOFL = 0x8102 + ETHERTYPE_CABLETRON = 0x7034 + ETHERTYPE_CHAOS = 0x804 + ETHERTYPE_COMDESIGN = 0x806c + ETHERTYPE_COMPUGRAPHIC = 0x806d + ETHERTYPE_COUNTERPOINT = 0x8062 + ETHERTYPE_CRONUS = 0x8004 + ETHERTYPE_CRONUSVLN = 0x8003 + ETHERTYPE_DCA = 0x1234 + ETHERTYPE_DDE = 0x807b + ETHERTYPE_DEBNI = 0xaaaa + ETHERTYPE_DECAM = 0x8048 + ETHERTYPE_DECCUST = 0x6006 + ETHERTYPE_DECDIAG = 0x6005 + ETHERTYPE_DECDNS = 0x803c + ETHERTYPE_DECDTS = 0x803e + ETHERTYPE_DECEXPER = 0x6000 + ETHERTYPE_DECLAST = 0x8041 + ETHERTYPE_DECLTM = 0x803f + ETHERTYPE_DECMUMPS = 0x6009 + ETHERTYPE_DECNETBIOS = 0x8040 + ETHERTYPE_DELTACON = 0x86de + ETHERTYPE_DIDDLE = 0x4321 + ETHERTYPE_DLOG1 = 0x660 + ETHERTYPE_DLOG2 = 0x661 + ETHERTYPE_DN = 0x6003 + ETHERTYPE_DOGFIGHT = 0x1989 + ETHERTYPE_DSMD = 0x8039 + ETHERTYPE_EAPOL = 0x888e + ETHERTYPE_ECMA = 0x803 + ETHERTYPE_ENCRYPT = 0x803d + ETHERTYPE_ES = 0x805d + ETHERTYPE_EXCELAN = 0x8010 + ETHERTYPE_EXPERDATA = 0x8049 + ETHERTYPE_FLIP = 0x8146 + ETHERTYPE_FLOWCONTROL = 0x8808 + ETHERTYPE_FRARP = 0x808 + ETHERTYPE_GENDYN = 0x8068 + ETHERTYPE_HAYES = 0x8130 + ETHERTYPE_HIPPI_FP = 0x8180 + ETHERTYPE_HITACHI = 0x8820 + ETHERTYPE_HP = 0x8005 + ETHERTYPE_IEEEPUP = 0xa00 + ETHERTYPE_IEEEPUPAT = 0xa01 + ETHERTYPE_IMLBL = 0x4c42 + ETHERTYPE_IMLBLDIAG = 0x424c + ETHERTYPE_IP = 0x800 + ETHERTYPE_IPAS = 0x876c + ETHERTYPE_IPV6 = 0x86dd + ETHERTYPE_IPX = 0x8137 + ETHERTYPE_IPXNEW = 0x8037 + ETHERTYPE_KALPANA = 0x8582 + ETHERTYPE_LANBRIDGE = 0x8038 + ETHERTYPE_LANPROBE = 0x8888 + ETHERTYPE_LAT = 0x6004 + ETHERTYPE_LBACK = 0x9000 + ETHERTYPE_LITTLE = 0x8060 + ETHERTYPE_LLDP = 0x88cc + ETHERTYPE_LOGICRAFT = 0x8148 + ETHERTYPE_LOOPBACK = 0x9000 + ETHERTYPE_MACSEC = 0x88e5 + ETHERTYPE_MATRA = 0x807a + ETHERTYPE_MAX = 0xffff + ETHERTYPE_MERIT = 0x807c + ETHERTYPE_MICP = 0x873a + ETHERTYPE_MOPDL = 0x6001 + ETHERTYPE_MOPRC = 0x6002 + ETHERTYPE_MOTOROLA = 0x818d + ETHERTYPE_MPLS = 0x8847 + ETHERTYPE_MPLS_MCAST = 0x8848 + ETHERTYPE_MUMPS = 0x813f + ETHERTYPE_NBPCC = 0x3c04 + ETHERTYPE_NBPCLAIM = 0x3c09 + ETHERTYPE_NBPCLREQ = 0x3c05 + ETHERTYPE_NBPCLRSP = 0x3c06 + ETHERTYPE_NBPCREQ = 0x3c02 + ETHERTYPE_NBPCRSP = 0x3c03 + ETHERTYPE_NBPDG = 0x3c07 + ETHERTYPE_NBPDGB = 0x3c08 + ETHERTYPE_NBPDLTE = 0x3c0a + ETHERTYPE_NBPRAR = 0x3c0c + ETHERTYPE_NBPRAS = 0x3c0b + ETHERTYPE_NBPRST = 0x3c0d + ETHERTYPE_NBPSCD = 0x3c01 + ETHERTYPE_NBPVCD = 0x3c00 + ETHERTYPE_NBS = 0x802 + ETHERTYPE_NCD = 0x8149 + ETHERTYPE_NESTAR = 0x8006 + ETHERTYPE_NETBEUI = 0x8191 + ETHERTYPE_NHRP = 0x2001 + ETHERTYPE_NOVELL = 0x8138 + ETHERTYPE_NS = 0x600 + ETHERTYPE_NSAT = 0x601 + ETHERTYPE_NSCOMPAT = 0x807 + ETHERTYPE_NSH = 0x984f + ETHERTYPE_NTRAILER = 0x10 + ETHERTYPE_OS9 = 0x7007 + ETHERTYPE_OS9NET = 0x7009 + ETHERTYPE_PACER = 0x80c6 + ETHERTYPE_PBB = 0x88e7 + ETHERTYPE_PCS = 0x4242 + ETHERTYPE_PLANNING = 0x8044 + ETHERTYPE_PPP = 0x880b + ETHERTYPE_PPPOE = 0x8864 + ETHERTYPE_PPPOEDISC = 0x8863 + ETHERTYPE_PRIMENTS = 0x7031 + ETHERTYPE_PUP = 0x200 + ETHERTYPE_PUPAT = 0x200 + ETHERTYPE_QINQ = 0x88a8 + ETHERTYPE_RACAL = 0x7030 + ETHERTYPE_RATIONAL = 0x8150 + ETHERTYPE_RAWFR = 0x6559 + ETHERTYPE_RCL = 0x1995 + ETHERTYPE_RDP = 0x8739 + ETHERTYPE_RETIX = 0x80f2 + ETHERTYPE_REVARP = 0x8035 + ETHERTYPE_SCA = 0x6007 + ETHERTYPE_SECTRA = 0x86db + ETHERTYPE_SECUREDATA = 0x876d + ETHERTYPE_SGITW = 0x817e + ETHERTYPE_SG_BOUNCE = 0x8016 + ETHERTYPE_SG_DIAG = 0x8013 + ETHERTYPE_SG_NETGAMES = 0x8014 + ETHERTYPE_SG_RESV = 0x8015 + ETHERTYPE_SIMNET = 0x5208 + ETHERTYPE_SLOW = 0x8809 + ETHERTYPE_SNA = 0x80d5 + ETHERTYPE_SNMP = 0x814c + ETHERTYPE_SONIX = 0xfaf5 + ETHERTYPE_SPIDER = 0x809f + ETHERTYPE_SPRITE = 0x500 + ETHERTYPE_STP = 0x8181 + ETHERTYPE_TALARIS = 0x812b + ETHERTYPE_TALARISMC = 0x852b + ETHERTYPE_TCPCOMP = 0x876b + ETHERTYPE_TCPSM = 0x9002 + ETHERTYPE_TEC = 0x814f + ETHERTYPE_TIGAN = 0x802f + ETHERTYPE_TRAIL = 0x1000 + ETHERTYPE_TRANSETHER = 0x6558 + ETHERTYPE_TYMSHARE = 0x802e + ETHERTYPE_UBBST = 0x7005 + ETHERTYPE_UBDEBUG = 0x900 + ETHERTYPE_UBDIAGLOOP = 0x7002 + ETHERTYPE_UBDL = 0x7000 + ETHERTYPE_UBNIU = 0x7001 + ETHERTYPE_UBNMC = 0x7003 + ETHERTYPE_VALID = 0x1600 + ETHERTYPE_VARIAN = 0x80dd + ETHERTYPE_VAXELN = 0x803b + ETHERTYPE_VEECO = 0x8067 + ETHERTYPE_VEXP = 0x805b + ETHERTYPE_VGLAB = 0x8131 + ETHERTYPE_VINES = 0xbad + ETHERTYPE_VINESECHO = 0xbaf + ETHERTYPE_VINESLOOP = 0xbae + ETHERTYPE_VITAL = 0xff00 + ETHERTYPE_VLAN = 0x8100 + ETHERTYPE_VLTLMAN = 0x8080 + ETHERTYPE_VPROD = 0x805c + ETHERTYPE_VURESERVED = 0x8147 + ETHERTYPE_WATERLOO = 0x8130 + ETHERTYPE_WELLFLEET = 0x8103 + ETHERTYPE_X25 = 0x805 + ETHERTYPE_X75 = 0x801 + ETHERTYPE_XNSSM = 0x9001 + ETHERTYPE_XTP = 0x817d + ETHER_ADDR_LEN = 0x6 + ETHER_ALIGN = 0x2 + ETHER_CRC_LEN = 0x4 + ETHER_CRC_POLY_BE = 0x4c11db6 + ETHER_CRC_POLY_LE = 0xedb88320 + ETHER_HDR_LEN = 0xe + ETHER_MAX_DIX_LEN = 0x600 + ETHER_MAX_HARDMTU_LEN = 0xff9b + ETHER_MAX_LEN = 0x5ee + ETHER_MIN_LEN = 0x40 + ETHER_TYPE_LEN = 0x2 + ETHER_VLAN_ENCAP_LEN = 0x4 + EVFILT_AIO = -0x3 + EVFILT_DEVICE = -0x8 + EVFILT_EXCEPT = -0x9 + EVFILT_PROC = -0x5 + EVFILT_READ = -0x1 + EVFILT_SIGNAL = -0x6 + EVFILT_SYSCOUNT = 0x9 + EVFILT_TIMER = -0x7 + EVFILT_VNODE = -0x4 + EVFILT_WRITE = -0x2 + EVL_ENCAPLEN = 0x4 + EVL_PRIO_BITS = 0xd + EVL_PRIO_MAX = 0x7 + EVL_VLID_MASK = 0xfff + EVL_VLID_MAX = 0xffe + EVL_VLID_MIN = 0x1 + EVL_VLID_NULL = 0x0 + EV_ADD = 0x1 + EV_CLEAR = 0x20 + EV_DELETE = 0x2 + EV_DISABLE = 0x8 + EV_DISPATCH = 0x80 + EV_ENABLE = 0x4 + EV_EOF = 0x8000 + EV_ERROR = 0x4000 + EV_FLAG1 = 0x2000 + EV_ONESHOT = 0x10 + EV_RECEIPT = 0x40 + EV_SYSFLAGS = 0xf800 + EXTA = 0x4b00 + EXTB = 0x9600 + EXTPROC = 0x800 + FD_CLOEXEC = 0x1 + FD_SETSIZE = 0x400 + FLUSHO = 0x800000 + F_DUPFD = 0x0 + F_DUPFD_CLOEXEC = 0xa + F_GETFD = 0x1 + F_GETFL = 0x3 + F_GETLK = 0x7 + F_GETOWN = 0x5 + F_ISATTY = 0xb + F_OK = 0x0 + F_RDLCK = 0x1 + F_SETFD = 0x2 + F_SETFL = 0x4 + F_SETLK = 0x8 + F_SETLKW = 0x9 + F_SETOWN = 0x6 + F_UNLCK = 0x2 + F_WRLCK = 0x3 + HUPCL = 0x4000 + HW_MACHINE = 0x1 + ICANON = 0x100 + ICMP6_FILTER = 0x12 + ICRNL = 0x100 + IEXTEN = 0x400 + IFAN_ARRIVAL = 0x0 + IFAN_DEPARTURE = 0x1 + IFF_ALLMULTI = 0x200 + IFF_BROADCAST = 0x2 + IFF_CANTCHANGE = 0x8e52 + IFF_DEBUG = 0x4 + IFF_LINK0 = 0x1000 + IFF_LINK1 = 0x2000 + IFF_LINK2 = 0x4000 + IFF_LOOPBACK = 0x8 + IFF_MULTICAST = 0x8000 + IFF_NOARP = 0x80 + IFF_OACTIVE = 0x400 + IFF_POINTOPOINT = 0x10 + IFF_PROMISC = 0x100 + IFF_RUNNING = 0x40 + IFF_SIMPLEX = 0x800 + IFF_STATICARP = 0x20 + IFF_UP = 0x1 + IFNAMSIZ = 0x10 + IFT_1822 = 0x2 + IFT_A12MPPSWITCH = 0x82 + IFT_AAL2 = 0xbb + IFT_AAL5 = 0x31 + IFT_ADSL = 0x5e + IFT_AFLANE8023 = 0x3b + IFT_AFLANE8025 = 0x3c + IFT_ARAP = 0x58 + IFT_ARCNET = 0x23 + IFT_ARCNETPLUS = 0x24 + IFT_ASYNC = 0x54 + IFT_ATM = 0x25 + IFT_ATMDXI = 0x69 + IFT_ATMFUNI = 0x6a + IFT_ATMIMA = 0x6b + IFT_ATMLOGICAL = 0x50 + IFT_ATMRADIO = 0xbd + IFT_ATMSUBINTERFACE = 0x86 + IFT_ATMVCIENDPT = 0xc2 + IFT_ATMVIRTUAL = 0x95 + IFT_BGPPOLICYACCOUNTING = 0xa2 + IFT_BLUETOOTH = 0xf8 + IFT_BRIDGE = 0xd1 + IFT_BSC = 0x53 + IFT_CARP = 0xf7 + IFT_CCTEMUL = 0x3d + IFT_CEPT = 0x13 + IFT_CES = 0x85 + IFT_CHANNEL = 0x46 + IFT_CNR = 0x55 + IFT_COFFEE = 0x84 + IFT_COMPOSITELINK = 0x9b + IFT_DCN = 0x8d + IFT_DIGITALPOWERLINE = 0x8a + IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba + IFT_DLSW = 0x4a + IFT_DOCSCABLEDOWNSTREAM = 0x80 + IFT_DOCSCABLEMACLAYER = 0x7f + IFT_DOCSCABLEUPSTREAM = 0x81 + IFT_DOCSCABLEUPSTREAMCHANNEL = 0xcd + IFT_DS0 = 0x51 + IFT_DS0BUNDLE = 0x52 + IFT_DS1FDL = 0xaa + IFT_DS3 = 0x1e + IFT_DTM = 0x8c + IFT_DUMMY = 0xf1 + IFT_DVBASILN = 0xac + IFT_DVBASIOUT = 0xad + IFT_DVBRCCDOWNSTREAM = 0x93 + IFT_DVBRCCMACLAYER = 0x92 + IFT_DVBRCCUPSTREAM = 0x94 + IFT_ECONET = 0xce + IFT_ENC = 0xf4 + IFT_EON = 0x19 + IFT_EPLRS = 0x57 + IFT_ESCON = 0x49 + IFT_ETHER = 0x6 + IFT_FAITH = 0xf3 + IFT_FAST = 0x7d + IFT_FASTETHER = 0x3e + IFT_FASTETHERFX = 0x45 + IFT_FDDI = 0xf + IFT_FIBRECHANNEL = 0x38 + IFT_FRAMERELAYINTERCONNECT = 0x3a + IFT_FRAMERELAYMPI = 0x5c + IFT_FRDLCIENDPT = 0xc1 + IFT_FRELAY = 0x20 + IFT_FRELAYDCE = 0x2c + IFT_FRF16MFRBUNDLE = 0xa3 + IFT_FRFORWARD = 0x9e + IFT_G703AT2MB = 0x43 + IFT_G703AT64K = 0x42 + IFT_GIF = 0xf0 + IFT_GIGABITETHERNET = 0x75 + IFT_GR303IDT = 0xb2 + IFT_GR303RDT = 0xb1 + IFT_H323GATEKEEPER = 0xa4 + IFT_H323PROXY = 0xa5 + IFT_HDH1822 = 0x3 + IFT_HDLC = 0x76 + IFT_HDSL2 = 0xa8 + IFT_HIPERLAN2 = 0xb7 + IFT_HIPPI = 0x2f + IFT_HIPPIINTERFACE = 0x39 + IFT_HOSTPAD = 0x5a + IFT_HSSI = 0x2e + IFT_HY = 0xe + IFT_IBM370PARCHAN = 0x48 + IFT_IDSL = 0x9a + IFT_IEEE1394 = 0x90 + IFT_IEEE80211 = 0x47 + IFT_IEEE80212 = 0x37 + IFT_IEEE8023ADLAG = 0xa1 + IFT_IFGSN = 0x91 + IFT_IMT = 0xbe + IFT_INFINIBAND = 0xc7 + IFT_INTERLEAVE = 0x7c + IFT_IP = 0x7e + IFT_IPFORWARD = 0x8e + IFT_IPOVERATM = 0x72 + IFT_IPOVERCDLC = 0x6d + IFT_IPOVERCLAW = 0x6e + IFT_IPSWITCH = 0x4e + IFT_ISDN = 0x3f + IFT_ISDNBASIC = 0x14 + IFT_ISDNPRIMARY = 0x15 + IFT_ISDNS = 0x4b + IFT_ISDNU = 0x4c + IFT_ISO88022LLC = 0x29 + IFT_ISO88023 = 0x7 + IFT_ISO88024 = 0x8 + IFT_ISO88025 = 0x9 + IFT_ISO88025CRFPINT = 0x62 + IFT_ISO88025DTR = 0x56 + IFT_ISO88025FIBER = 0x73 + IFT_ISO88026 = 0xa + IFT_ISUP = 0xb3 + IFT_L2VLAN = 0x87 + IFT_L3IPVLAN = 0x88 + IFT_L3IPXVLAN = 0x89 + IFT_LAPB = 0x10 + IFT_LAPD = 0x4d + IFT_LAPF = 0x77 + IFT_LINEGROUP = 0xd2 + IFT_LOCALTALK = 0x2a + IFT_LOOP = 0x18 + IFT_MBIM = 0xfa + IFT_MEDIAMAILOVERIP = 0x8b + IFT_MFSIGLINK = 0xa7 + IFT_MIOX25 = 0x26 + IFT_MODEM = 0x30 + IFT_MPC = 0x71 + IFT_MPLS = 0xa6 + IFT_MPLSTUNNEL = 0x96 + IFT_MSDSL = 0x8f + IFT_MVL = 0xbf + IFT_MYRINET = 0x63 + IFT_NFAS = 0xaf + IFT_NSIP = 0x1b + IFT_OPTICALCHANNEL = 0xc3 + IFT_OPTICALTRANSPORT = 0xc4 + IFT_OTHER = 0x1 + IFT_P10 = 0xc + IFT_P80 = 0xd + IFT_PARA = 0x22 + IFT_PFLOG = 0xf5 + IFT_PFLOW = 0xf9 + IFT_PFSYNC = 0xf6 + IFT_PLC = 0xae + IFT_PON155 = 0xcf + IFT_PON622 = 0xd0 + IFT_POS = 0xab + IFT_PPP = 0x17 + IFT_PPPMULTILINKBUNDLE = 0x6c + IFT_PROPATM = 0xc5 + IFT_PROPBWAP2MP = 0xb8 + IFT_PROPCNLS = 0x59 + IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 + IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 + IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 + IFT_PROPMUX = 0x36 + IFT_PROPVIRTUAL = 0x35 + IFT_PROPWIRELESSP2P = 0x9d + IFT_PTPSERIAL = 0x16 + IFT_PVC = 0xf2 + IFT_Q2931 = 0xc9 + IFT_QLLC = 0x44 + IFT_RADIOMAC = 0xbc + IFT_RADSL = 0x5f + IFT_REACHDSL = 0xc0 + IFT_RFC1483 = 0x9f + IFT_RS232 = 0x21 + IFT_RSRB = 0x4f + IFT_SDLC = 0x11 + IFT_SDSL = 0x60 + IFT_SHDSL = 0xa9 + IFT_SIP = 0x1f + IFT_SIPSIG = 0xcc + IFT_SIPTG = 0xcb + IFT_SLIP = 0x1c + IFT_SMDSDXI = 0x2b + IFT_SMDSICIP = 0x34 + IFT_SONET = 0x27 + IFT_SONETOVERHEADCHANNEL = 0xb9 + IFT_SONETPATH = 0x32 + IFT_SONETVT = 0x33 + IFT_SRP = 0x97 + IFT_SS7SIGLINK = 0x9c + IFT_STACKTOSTACK = 0x6f + IFT_STARLAN = 0xb + IFT_T1 = 0x12 + IFT_TDLC = 0x74 + IFT_TELINK = 0xc8 + IFT_TERMPAD = 0x5b + IFT_TR008 = 0xb0 + IFT_TRANSPHDLC = 0x7b + IFT_TUNNEL = 0x83 + IFT_ULTRA = 0x1d + IFT_USB = 0xa0 + IFT_V11 = 0x40 + IFT_V35 = 0x2d + IFT_V36 = 0x41 + IFT_V37 = 0x78 + IFT_VDSL = 0x61 + IFT_VIRTUALIPADDRESS = 0x70 + IFT_VIRTUALTG = 0xca + IFT_VOICEDID = 0xd5 + IFT_VOICEEM = 0x64 + IFT_VOICEEMFGD = 0xd3 + IFT_VOICEENCAP = 0x67 + IFT_VOICEFGDEANA = 0xd4 + IFT_VOICEFXO = 0x65 + IFT_VOICEFXS = 0x66 + IFT_VOICEOVERATM = 0x98 + IFT_VOICEOVERCABLE = 0xc6 + IFT_VOICEOVERFRAMERELAY = 0x99 + IFT_VOICEOVERIP = 0x68 + IFT_WIREGUARD = 0xfb + IFT_X213 = 0x5d + IFT_X25 = 0x5 + IFT_X25DDN = 0x4 + IFT_X25HUNTGROUP = 0x7a + IFT_X25MLP = 0x79 + IFT_X25PLE = 0x28 + IFT_XETHER = 0x1a + IGNBRK = 0x1 + IGNCR = 0x80 + IGNPAR = 0x4 + IMAXBEL = 0x2000 + INLCR = 0x40 + INPCK = 0x10 + IN_CLASSA_HOST = 0xffffff + IN_CLASSA_MAX = 0x80 + IN_CLASSA_NET = 0xff000000 + IN_CLASSA_NSHIFT = 0x18 + IN_CLASSB_HOST = 0xffff + IN_CLASSB_MAX = 0x10000 + IN_CLASSB_NET = 0xffff0000 + IN_CLASSB_NSHIFT = 0x10 + IN_CLASSC_HOST = 0xff + IN_CLASSC_NET = 0xffffff00 + IN_CLASSC_NSHIFT = 0x8 + IN_CLASSD_HOST = 0xfffffff + IN_CLASSD_NET = 0xf0000000 + IN_CLASSD_NSHIFT = 0x1c + IN_LOOPBACKNET = 0x7f + IN_RFC3021_HOST = 0x1 + IN_RFC3021_NET = 0xfffffffe + IN_RFC3021_NSHIFT = 0x1f + IPPROTO_AH = 0x33 + IPPROTO_CARP = 0x70 + IPPROTO_DIVERT = 0x102 + IPPROTO_DONE = 0x101 + IPPROTO_DSTOPTS = 0x3c + IPPROTO_EGP = 0x8 + IPPROTO_ENCAP = 0x62 + IPPROTO_EON = 0x50 + IPPROTO_ESP = 0x32 + IPPROTO_ETHERIP = 0x61 + IPPROTO_FRAGMENT = 0x2c + IPPROTO_GGP = 0x3 + IPPROTO_GRE = 0x2f + IPPROTO_HOPOPTS = 0x0 + IPPROTO_ICMP = 0x1 + IPPROTO_ICMPV6 = 0x3a + IPPROTO_IDP = 0x16 + IPPROTO_IGMP = 0x2 + IPPROTO_IP = 0x0 + IPPROTO_IPCOMP = 0x6c + IPPROTO_IPIP = 0x4 + IPPROTO_IPV4 = 0x4 + IPPROTO_IPV6 = 0x29 + IPPROTO_MAX = 0x100 + IPPROTO_MAXID = 0x103 + IPPROTO_MOBILE = 0x37 + IPPROTO_MPLS = 0x89 + IPPROTO_NONE = 0x3b + IPPROTO_PFSYNC = 0xf0 + IPPROTO_PIM = 0x67 + IPPROTO_PUP = 0xc + IPPROTO_RAW = 0xff + IPPROTO_ROUTING = 0x2b + IPPROTO_RSVP = 0x2e + IPPROTO_SCTP = 0x84 + IPPROTO_TCP = 0x6 + IPPROTO_TP = 0x1d + IPPROTO_UDP = 0x11 + IPPROTO_UDPLITE = 0x88 + IPV6_AUTH_LEVEL = 0x35 + IPV6_AUTOFLOWLABEL = 0x3b + IPV6_CHECKSUM = 0x1a + IPV6_DEFAULT_MULTICAST_HOPS = 0x1 + IPV6_DEFAULT_MULTICAST_LOOP = 0x1 + IPV6_DEFHLIM = 0x40 + IPV6_DONTFRAG = 0x3e + IPV6_DSTOPTS = 0x32 + IPV6_ESP_NETWORK_LEVEL = 0x37 + IPV6_ESP_TRANS_LEVEL = 0x36 + IPV6_FAITH = 0x1d + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff + IPV6_FRAGTTL = 0x78 + IPV6_HLIMDEC = 0x1 + IPV6_HOPLIMIT = 0x2f + IPV6_HOPOPTS = 0x31 + IPV6_IPCOMP_LEVEL = 0x3c + IPV6_JOIN_GROUP = 0xc + IPV6_LEAVE_GROUP = 0xd + IPV6_MAXHLIM = 0xff + IPV6_MAXPACKET = 0xffff + IPV6_MINHOPCOUNT = 0x41 + IPV6_MMTU = 0x500 + IPV6_MULTICAST_HOPS = 0xa + IPV6_MULTICAST_IF = 0x9 + IPV6_MULTICAST_LOOP = 0xb + IPV6_NEXTHOP = 0x30 + IPV6_OPTIONS = 0x1 + IPV6_PATHMTU = 0x2c + IPV6_PIPEX = 0x3f + IPV6_PKTINFO = 0x2e + IPV6_PORTRANGE = 0xe + IPV6_PORTRANGE_DEFAULT = 0x0 + IPV6_PORTRANGE_HIGH = 0x1 + IPV6_PORTRANGE_LOW = 0x2 + IPV6_RECVDSTOPTS = 0x28 + IPV6_RECVDSTPORT = 0x40 + IPV6_RECVHOPLIMIT = 0x25 + IPV6_RECVHOPOPTS = 0x27 + IPV6_RECVPATHMTU = 0x2b + IPV6_RECVPKTINFO = 0x24 + IPV6_RECVRTHDR = 0x26 + IPV6_RECVTCLASS = 0x39 + IPV6_RTABLE = 0x1021 + IPV6_RTHDR = 0x33 + IPV6_RTHDRDSTOPTS = 0x23 + IPV6_RTHDR_LOOSE = 0x0 + IPV6_RTHDR_STRICT = 0x1 + IPV6_RTHDR_TYPE_0 = 0x0 + IPV6_SOCKOPT_RESERVED1 = 0x3 + IPV6_TCLASS = 0x3d + IPV6_UNICAST_HOPS = 0x4 + IPV6_USE_MIN_MTU = 0x2a + IPV6_V6ONLY = 0x1b + IPV6_VERSION = 0x60 + IPV6_VERSION_MASK = 0xf0 + IP_ADD_MEMBERSHIP = 0xc + IP_AUTH_LEVEL = 0x14 + IP_DEFAULT_MULTICAST_LOOP = 0x1 + IP_DEFAULT_MULTICAST_TTL = 0x1 + IP_DF = 0x4000 + IP_DROP_MEMBERSHIP = 0xd + IP_ESP_NETWORK_LEVEL = 0x16 + IP_ESP_TRANS_LEVEL = 0x15 + IP_HDRINCL = 0x2 + IP_IPCOMP_LEVEL = 0x1d + IP_IPDEFTTL = 0x25 + IP_IPSECFLOWINFO = 0x24 + IP_IPSEC_LOCAL_AUTH = 0x1b + IP_IPSEC_LOCAL_CRED = 0x19 + IP_IPSEC_LOCAL_ID = 0x17 + IP_IPSEC_REMOTE_AUTH = 0x1c + IP_IPSEC_REMOTE_CRED = 0x1a + IP_IPSEC_REMOTE_ID = 0x18 + IP_MAXPACKET = 0xffff + IP_MAX_MEMBERSHIPS = 0xfff + IP_MF = 0x2000 + IP_MINTTL = 0x20 + IP_MIN_MEMBERSHIPS = 0xf + IP_MSS = 0x240 + IP_MULTICAST_IF = 0x9 + IP_MULTICAST_LOOP = 0xb + IP_MULTICAST_TTL = 0xa + IP_OFFMASK = 0x1fff + IP_OPTIONS = 0x1 + IP_PIPEX = 0x22 + IP_PORTRANGE = 0x13 + IP_PORTRANGE_DEFAULT = 0x0 + IP_PORTRANGE_HIGH = 0x1 + IP_PORTRANGE_LOW = 0x2 + IP_RECVDSTADDR = 0x7 + IP_RECVDSTPORT = 0x21 + IP_RECVIF = 0x1e + IP_RECVOPTS = 0x5 + IP_RECVRETOPTS = 0x6 + IP_RECVRTABLE = 0x23 + IP_RECVTTL = 0x1f + IP_RETOPTS = 0x8 + IP_RF = 0x8000 + IP_RTABLE = 0x1021 + IP_SENDSRCADDR = 0x7 + IP_TOS = 0x3 + IP_TTL = 0x4 + ISIG = 0x80 + ISTRIP = 0x20 + ITIMER_PROF = 0x2 + ITIMER_REAL = 0x0 + ITIMER_VIRTUAL = 0x1 + IUCLC = 0x1000 + IXANY = 0x800 + IXOFF = 0x400 + IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 + LCNT_OVERLOAD_FLUSH = 0x6 + LOCK_EX = 0x2 + LOCK_NB = 0x4 + LOCK_SH = 0x1 + LOCK_UN = 0x8 + MADV_DONTNEED = 0x4 + MADV_FREE = 0x6 + MADV_NORMAL = 0x0 + MADV_RANDOM = 0x1 + MADV_SEQUENTIAL = 0x2 + MADV_SPACEAVAIL = 0x5 + MADV_WILLNEED = 0x3 + MAP_ANON = 0x1000 + MAP_ANONYMOUS = 0x1000 + MAP_CONCEAL = 0x8000 + MAP_COPY = 0x2 + MAP_FILE = 0x0 + MAP_FIXED = 0x10 + MAP_FLAGMASK = 0xfff7 + MAP_HASSEMAPHORE = 0x0 + MAP_INHERIT = 0x0 + MAP_INHERIT_COPY = 0x1 + MAP_INHERIT_NONE = 0x2 + MAP_INHERIT_SHARE = 0x0 + MAP_INHERIT_ZERO = 0x3 + MAP_NOEXTEND = 0x0 + MAP_NORESERVE = 0x0 + MAP_PRIVATE = 0x2 + MAP_RENAME = 0x0 + MAP_SHARED = 0x1 + MAP_STACK = 0x4000 + MAP_TRYFIXED = 0x0 + MCL_CURRENT = 0x1 + MCL_FUTURE = 0x2 + MNT_ASYNC = 0x40 + MNT_DEFEXPORTED = 0x200 + MNT_DELEXPORT = 0x20000 + MNT_DOOMED = 0x8000000 + MNT_EXPORTANON = 0x400 + MNT_EXPORTED = 0x100 + MNT_EXRDONLY = 0x80 + MNT_FORCE = 0x80000 + MNT_LAZY = 0x3 + MNT_LOCAL = 0x1000 + MNT_NOATIME = 0x8000 + MNT_NODEV = 0x10 + MNT_NOEXEC = 0x4 + MNT_NOPERM = 0x20 + MNT_NOSUID = 0x8 + MNT_NOWAIT = 0x2 + MNT_QUOTA = 0x2000 + MNT_RDONLY = 0x1 + MNT_RELOAD = 0x40000 + MNT_ROOTFS = 0x4000 + MNT_SOFTDEP = 0x4000000 + MNT_STALLED = 0x100000 + MNT_SWAPPABLE = 0x200000 + MNT_SYNCHRONOUS = 0x2 + MNT_UPDATE = 0x10000 + MNT_VISFLAGMASK = 0x400ffff + MNT_WAIT = 0x1 + MNT_WANTRDWR = 0x2000000 + MNT_WXALLOWED = 0x800 + MOUNT_AFS = "afs" + MOUNT_CD9660 = "cd9660" + MOUNT_EXT2FS = "ext2fs" + MOUNT_FFS = "ffs" + MOUNT_FUSEFS = "fuse" + MOUNT_MFS = "mfs" + MOUNT_MSDOS = "msdos" + MOUNT_NCPFS = "ncpfs" + MOUNT_NFS = "nfs" + MOUNT_NTFS = "ntfs" + MOUNT_TMPFS = "tmpfs" + MOUNT_UDF = "udf" + MOUNT_UFS = "ffs" + MSG_BCAST = 0x100 + MSG_CMSG_CLOEXEC = 0x800 + MSG_CTRUNC = 0x20 + MSG_DONTROUTE = 0x4 + MSG_DONTWAIT = 0x80 + MSG_EOR = 0x8 + MSG_MCAST = 0x200 + MSG_NOSIGNAL = 0x400 + MSG_OOB = 0x1 + MSG_PEEK = 0x2 + MSG_TRUNC = 0x10 + MSG_WAITALL = 0x40 + MSG_WAITFORONE = 0x1000 + MS_ASYNC = 0x1 + MS_INVALIDATE = 0x4 + MS_SYNC = 0x2 + NAME_MAX = 0xff + NET_RT_DUMP = 0x1 + NET_RT_FLAGS = 0x2 + NET_RT_IFLIST = 0x3 + NET_RT_IFNAMES = 0x6 + NET_RT_MAXID = 0x8 + NET_RT_SOURCE = 0x7 + NET_RT_STATS = 0x4 + NET_RT_TABLE = 0x5 + NFDBITS = 0x20 + NOFLSH = 0x80000000 + NOKERNINFO = 0x2000000 + NOTE_ATTRIB = 0x8 + NOTE_CHANGE = 0x1 + NOTE_CHILD = 0x4 + NOTE_DELETE = 0x1 + NOTE_EOF = 0x2 + NOTE_EXEC = 0x20000000 + NOTE_EXIT = 0x80000000 + NOTE_EXTEND = 0x4 + NOTE_FORK = 0x40000000 + NOTE_LINK = 0x10 + NOTE_LOWAT = 0x1 + NOTE_OOB = 0x4 + NOTE_PCTRLMASK = 0xf0000000 + NOTE_PDATAMASK = 0xfffff + NOTE_RENAME = 0x20 + NOTE_REVOKE = 0x40 + NOTE_TRACK = 0x1 + NOTE_TRACKERR = 0x2 + NOTE_TRUNCATE = 0x80 + NOTE_WRITE = 0x2 + OCRNL = 0x10 + OLCUC = 0x20 + ONLCR = 0x2 + ONLRET = 0x80 + ONOCR = 0x40 + ONOEOT = 0x8 + OPOST = 0x1 + OXTABS = 0x4 + O_ACCMODE = 0x3 + O_APPEND = 0x8 + O_ASYNC = 0x40 + O_CLOEXEC = 0x10000 + O_CREAT = 0x200 + O_DIRECTORY = 0x20000 + O_DSYNC = 0x80 + O_EXCL = 0x800 + O_EXLOCK = 0x20 + O_FSYNC = 0x80 + O_NDELAY = 0x4 + O_NOCTTY = 0x8000 + O_NOFOLLOW = 0x100 + O_NONBLOCK = 0x4 + O_RDONLY = 0x0 + O_RDWR = 0x2 + O_RSYNC = 0x80 + O_SHLOCK = 0x10 + O_SYNC = 0x80 + O_TRUNC = 0x400 + O_WRONLY = 0x1 + PARENB = 0x1000 + PARMRK = 0x8 + PARODD = 0x2000 + PENDIN = 0x20000000 + PF_FLUSH = 0x1 + PRIO_PGRP = 0x1 + PRIO_PROCESS = 0x0 + PRIO_USER = 0x2 + PROT_EXEC = 0x4 + PROT_NONE = 0x0 + PROT_READ = 0x1 + PROT_WRITE = 0x2 + RLIMIT_CORE = 0x4 + RLIMIT_CPU = 0x0 + RLIMIT_DATA = 0x2 + RLIMIT_FSIZE = 0x1 + RLIMIT_MEMLOCK = 0x6 + RLIMIT_NOFILE = 0x8 + RLIMIT_NPROC = 0x7 + RLIMIT_RSS = 0x5 + RLIMIT_STACK = 0x3 + RLIM_INFINITY = 0x7fffffffffffffff + RTAX_AUTHOR = 0x6 + RTAX_BFD = 0xb + RTAX_BRD = 0x7 + RTAX_DNS = 0xc + RTAX_DST = 0x0 + RTAX_GATEWAY = 0x1 + RTAX_GENMASK = 0x3 + RTAX_IFA = 0x5 + RTAX_IFP = 0x4 + RTAX_LABEL = 0xa + RTAX_MAX = 0xf + RTAX_NETMASK = 0x2 + RTAX_SEARCH = 0xe + RTAX_SRC = 0x8 + RTAX_SRCMASK = 0x9 + RTAX_STATIC = 0xd + RTA_AUTHOR = 0x40 + RTA_BFD = 0x800 + RTA_BRD = 0x80 + RTA_DNS = 0x1000 + RTA_DST = 0x1 + RTA_GATEWAY = 0x2 + RTA_GENMASK = 0x8 + RTA_IFA = 0x20 + RTA_IFP = 0x10 + RTA_LABEL = 0x400 + RTA_NETMASK = 0x4 + RTA_SEARCH = 0x4000 + RTA_SRC = 0x100 + RTA_SRCMASK = 0x200 + RTA_STATIC = 0x2000 + RTF_ANNOUNCE = 0x4000 + RTF_BFD = 0x1000000 + RTF_BLACKHOLE = 0x1000 + RTF_BROADCAST = 0x400000 + RTF_CACHED = 0x20000 + RTF_CLONED = 0x10000 + RTF_CLONING = 0x100 + RTF_CONNECTED = 0x800000 + RTF_DONE = 0x40 + RTF_DYNAMIC = 0x10 + RTF_FMASK = 0x110fc08 + RTF_GATEWAY = 0x2 + RTF_HOST = 0x4 + RTF_LLINFO = 0x400 + RTF_LOCAL = 0x200000 + RTF_MODIFIED = 0x20 + RTF_MPATH = 0x40000 + RTF_MPLS = 0x100000 + RTF_MULTICAST = 0x200 + RTF_PERMANENT_ARP = 0x2000 + RTF_PROTO1 = 0x8000 + RTF_PROTO2 = 0x4000 + RTF_PROTO3 = 0x2000 + RTF_REJECT = 0x8 + RTF_STATIC = 0x800 + RTF_UP = 0x1 + RTF_USETRAILERS = 0x8000 + RTM_80211INFO = 0x15 + RTM_ADD = 0x1 + RTM_BFD = 0x12 + RTM_CHANGE = 0x3 + RTM_CHGADDRATTR = 0x14 + RTM_DELADDR = 0xd + RTM_DELETE = 0x2 + RTM_DESYNC = 0x10 + RTM_GET = 0x4 + RTM_IFANNOUNCE = 0xf + RTM_IFINFO = 0xe + RTM_INVALIDATE = 0x11 + RTM_LOSING = 0x5 + RTM_MAXSIZE = 0x800 + RTM_MISS = 0x7 + RTM_NEWADDR = 0xc + RTM_PROPOSAL = 0x13 + RTM_REDIRECT = 0x6 + RTM_RESOLVE = 0xb + RTM_SOURCE = 0x16 + RTM_VERSION = 0x5 + RTV_EXPIRE = 0x4 + RTV_HOPCOUNT = 0x2 + RTV_MTU = 0x1 + RTV_RPIPE = 0x8 + RTV_RTT = 0x40 + RTV_RTTVAR = 0x80 + RTV_SPIPE = 0x10 + RTV_SSTHRESH = 0x20 + RT_TABLEID_BITS = 0x8 + RT_TABLEID_MASK = 0xff + RT_TABLEID_MAX = 0xff + RUSAGE_CHILDREN = -0x1 + RUSAGE_SELF = 0x0 + RUSAGE_THREAD = 0x1 + SCM_RIGHTS = 0x1 + SCM_TIMESTAMP = 0x4 + SEEK_CUR = 0x1 + SEEK_END = 0x2 + SEEK_SET = 0x0 + SHUT_RD = 0x0 + SHUT_RDWR = 0x2 + SHUT_WR = 0x1 + SIOCADDMULTI = 0x80206931 + SIOCAIFADDR = 0x8040691a + SIOCAIFGROUP = 0x80286987 + SIOCATMARK = 0x40047307 + SIOCBRDGADD = 0x8060693c + SIOCBRDGADDL = 0x80606949 + SIOCBRDGADDS = 0x80606941 + SIOCBRDGARL = 0x808c694d + SIOCBRDGDADDR = 0x81286947 + SIOCBRDGDEL = 0x8060693d + SIOCBRDGDELS = 0x80606942 + SIOCBRDGFLUSH = 0x80606948 + SIOCBRDGFRL = 0x808c694e + SIOCBRDGGCACHE = 0xc0146941 + SIOCBRDGGFD = 0xc0146952 + SIOCBRDGGHT = 0xc0146951 + SIOCBRDGGIFFLGS = 0xc060693e + SIOCBRDGGMA = 0xc0146953 + SIOCBRDGGPARAM = 0xc0406958 + SIOCBRDGGPRI = 0xc0146950 + SIOCBRDGGRL = 0xc030694f + SIOCBRDGGTO = 0xc0146946 + SIOCBRDGIFS = 0xc0606942 + SIOCBRDGRTS = 0xc0206943 + SIOCBRDGSADDR = 0xc1286944 + SIOCBRDGSCACHE = 0x80146940 + SIOCBRDGSFD = 0x80146952 + SIOCBRDGSHT = 0x80146951 + SIOCBRDGSIFCOST = 0x80606955 + SIOCBRDGSIFFLGS = 0x8060693f + SIOCBRDGSIFPRIO = 0x80606954 + SIOCBRDGSIFPROT = 0x8060694a + SIOCBRDGSMA = 0x80146953 + SIOCBRDGSPRI = 0x80146950 + SIOCBRDGSPROTO = 0x8014695a + SIOCBRDGSTO = 0x80146945 + SIOCBRDGSTXHC = 0x80146959 + SIOCDELLABEL = 0x80206997 + SIOCDELMULTI = 0x80206932 + SIOCDIFADDR = 0x80206919 + SIOCDIFGROUP = 0x80286989 + SIOCDIFPARENT = 0x802069b4 + SIOCDIFPHYADDR = 0x80206949 + SIOCDPWE3NEIGHBOR = 0x802069de + SIOCDVNETID = 0x802069af + SIOCGETKALIVE = 0xc01869a4 + SIOCGETLABEL = 0x8020699a + SIOCGETMPWCFG = 0xc02069ae + SIOCGETPFLOW = 0xc02069fe + SIOCGETPFSYNC = 0xc02069f8 + SIOCGETSGCNT = 0xc0207534 + SIOCGETVIFCNT = 0xc0287533 + SIOCGETVLAN = 0xc0206990 + SIOCGIFADDR = 0xc0206921 + SIOCGIFBRDADDR = 0xc0206923 + SIOCGIFCONF = 0xc0106924 + SIOCGIFDATA = 0xc020691b + SIOCGIFDESCR = 0xc0206981 + SIOCGIFDSTADDR = 0xc0206922 + SIOCGIFFLAGS = 0xc0206911 + SIOCGIFGATTR = 0xc028698b + SIOCGIFGENERIC = 0xc020693a + SIOCGIFGLIST = 0xc028698d + SIOCGIFGMEMB = 0xc028698a + SIOCGIFGROUP = 0xc0286988 + SIOCGIFHARDMTU = 0xc02069a5 + SIOCGIFLLPRIO = 0xc02069b6 + SIOCGIFMEDIA = 0xc0406938 + SIOCGIFMETRIC = 0xc0206917 + SIOCGIFMTU = 0xc020697e + SIOCGIFNETMASK = 0xc0206925 + SIOCGIFPAIR = 0xc02069b1 + SIOCGIFPARENT = 0xc02069b3 + SIOCGIFPRIORITY = 0xc020699c + SIOCGIFRDOMAIN = 0xc02069a0 + SIOCGIFRTLABEL = 0xc0206983 + SIOCGIFRXR = 0x802069aa + SIOCGIFSFFPAGE = 0xc1126939 + SIOCGIFXFLAGS = 0xc020699e + SIOCGLIFPHYADDR = 0xc218694b + SIOCGLIFPHYDF = 0xc02069c2 + SIOCGLIFPHYECN = 0xc02069c8 + SIOCGLIFPHYRTABLE = 0xc02069a2 + SIOCGLIFPHYTTL = 0xc02069a9 + SIOCGPGRP = 0x40047309 + SIOCGPWE3 = 0xc0206998 + SIOCGPWE3CTRLWORD = 0xc02069dc + SIOCGPWE3FAT = 0xc02069dd + SIOCGPWE3NEIGHBOR = 0xc21869de + SIOCGRXHPRIO = 0xc02069db + SIOCGSPPPPARAMS = 0xc0206994 + SIOCGTXHPRIO = 0xc02069c6 + SIOCGUMBINFO = 0xc02069be + SIOCGUMBPARAM = 0xc02069c0 + SIOCGVH = 0xc02069f6 + SIOCGVNETFLOWID = 0xc02069c4 + SIOCGVNETID = 0xc02069a7 + SIOCIFAFATTACH = 0x801169ab + SIOCIFAFDETACH = 0x801169ac + SIOCIFCREATE = 0x8020697a + SIOCIFDESTROY = 0x80206979 + SIOCIFGCLONERS = 0xc0106978 + SIOCSETKALIVE = 0x801869a3 + SIOCSETLABEL = 0x80206999 + SIOCSETMPWCFG = 0x802069ad + SIOCSETPFLOW = 0x802069fd + SIOCSETPFSYNC = 0x802069f7 + SIOCSETVLAN = 0x8020698f + SIOCSIFADDR = 0x8020690c + SIOCSIFBRDADDR = 0x80206913 + SIOCSIFDESCR = 0x80206980 + SIOCSIFDSTADDR = 0x8020690e + SIOCSIFFLAGS = 0x80206910 + SIOCSIFGATTR = 0x8028698c + SIOCSIFGENERIC = 0x80206939 + SIOCSIFLLADDR = 0x8020691f + SIOCSIFLLPRIO = 0x802069b5 + SIOCSIFMEDIA = 0xc0206937 + SIOCSIFMETRIC = 0x80206918 + SIOCSIFMTU = 0x8020697f + SIOCSIFNETMASK = 0x80206916 + SIOCSIFPAIR = 0x802069b0 + SIOCSIFPARENT = 0x802069b2 + SIOCSIFPRIORITY = 0x8020699b + SIOCSIFRDOMAIN = 0x8020699f + SIOCSIFRTLABEL = 0x80206982 + SIOCSIFXFLAGS = 0x8020699d + SIOCSLIFPHYADDR = 0x8218694a + SIOCSLIFPHYDF = 0x802069c1 + SIOCSLIFPHYECN = 0x802069c7 + SIOCSLIFPHYRTABLE = 0x802069a1 + SIOCSLIFPHYTTL = 0x802069a8 + SIOCSPGRP = 0x80047308 + SIOCSPWE3CTRLWORD = 0x802069dc + SIOCSPWE3FAT = 0x802069dd + SIOCSPWE3NEIGHBOR = 0x821869de + SIOCSRXHPRIO = 0x802069db + SIOCSSPPPPARAMS = 0x80206993 + SIOCSTXHPRIO = 0x802069c5 + SIOCSUMBPARAM = 0x802069bf + SIOCSVH = 0xc02069f5 + SIOCSVNETFLOWID = 0x802069c3 + SIOCSVNETID = 0x802069a6 + SOCK_CLOEXEC = 0x8000 + SOCK_DGRAM = 0x2 + SOCK_DNS = 0x1000 + SOCK_NONBLOCK = 0x4000 + SOCK_RAW = 0x3 + SOCK_RDM = 0x4 + SOCK_SEQPACKET = 0x5 + SOCK_STREAM = 0x1 + SOL_SOCKET = 0xffff + SOMAXCONN = 0x80 + SO_ACCEPTCONN = 0x2 + SO_BINDANY = 0x1000 + SO_BROADCAST = 0x20 + SO_DEBUG = 0x1 + SO_DOMAIN = 0x1024 + SO_DONTROUTE = 0x10 + SO_ERROR = 0x1007 + SO_KEEPALIVE = 0x8 + SO_LINGER = 0x80 + SO_NETPROC = 0x1020 + SO_OOBINLINE = 0x100 + SO_PEERCRED = 0x1022 + SO_PROTOCOL = 0x1025 + SO_RCVBUF = 0x1002 + SO_RCVLOWAT = 0x1004 + SO_RCVTIMEO = 0x1006 + SO_REUSEADDR = 0x4 + SO_REUSEPORT = 0x200 + SO_RTABLE = 0x1021 + SO_SNDBUF = 0x1001 + SO_SNDLOWAT = 0x1003 + SO_SNDTIMEO = 0x1005 + SO_SPLICE = 0x1023 + SO_TIMESTAMP = 0x800 + SO_TYPE = 0x1008 + SO_USELOOPBACK = 0x40 + SO_ZEROIZE = 0x2000 + S_BLKSIZE = 0x200 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 + TCIFLUSH = 0x1 + TCIOFF = 0x3 + TCIOFLUSH = 0x3 + TCION = 0x4 + TCOFLUSH = 0x2 + TCOOFF = 0x1 + TCOON = 0x2 + TCPOPT_EOL = 0x0 + TCPOPT_MAXSEG = 0x2 + TCPOPT_NOP = 0x1 + TCPOPT_SACK = 0x5 + TCPOPT_SACK_HDR = 0x1010500 + TCPOPT_SACK_PERMITTED = 0x4 + TCPOPT_SACK_PERMIT_HDR = 0x1010402 + TCPOPT_SIGNATURE = 0x13 + TCPOPT_TIMESTAMP = 0x8 + TCPOPT_TSTAMP_HDR = 0x101080a + TCPOPT_WINDOW = 0x3 + TCP_INFO = 0x9 + TCP_MAXSEG = 0x2 + TCP_MAXWIN = 0xffff + TCP_MAX_SACK = 0x3 + TCP_MAX_WINSHIFT = 0xe + TCP_MD5SIG = 0x4 + TCP_MSS = 0x200 + TCP_NODELAY = 0x1 + TCP_NOPUSH = 0x10 + TCP_SACKHOLE_LIMIT = 0x80 + TCP_SACK_ENABLE = 0x8 + TCSAFLUSH = 0x2 + TIMER_ABSTIME = 0x1 + TIMER_RELTIME = 0x0 + TIOCCBRK = 0x2000747a + TIOCCDTR = 0x20007478 + TIOCCHKVERAUTH = 0x2000741e + TIOCCLRVERAUTH = 0x2000741d + TIOCCONS = 0x80047462 + TIOCDRAIN = 0x2000745e + TIOCEXCL = 0x2000740d + TIOCEXT = 0x80047460 + TIOCFLAG_CLOCAL = 0x2 + TIOCFLAG_CRTSCTS = 0x4 + TIOCFLAG_MDMBUF = 0x8 + TIOCFLAG_PPS = 0x10 + TIOCFLAG_SOFTCAR = 0x1 + TIOCFLUSH = 0x80047410 + TIOCGETA = 0x402c7413 + TIOCGETD = 0x4004741a + TIOCGFLAGS = 0x4004745d + TIOCGPGRP = 0x40047477 + TIOCGSID = 0x40047463 + TIOCGTSTAMP = 0x4010745b + TIOCGWINSZ = 0x40087468 + TIOCMBIC = 0x8004746b + TIOCMBIS = 0x8004746c + TIOCMGET = 0x4004746a + TIOCMODG = 0x4004746a + TIOCMODS = 0x8004746d + TIOCMSET = 0x8004746d + TIOCM_CAR = 0x40 + TIOCM_CD = 0x40 + TIOCM_CTS = 0x20 + TIOCM_DSR = 0x100 + TIOCM_DTR = 0x2 + TIOCM_LE = 0x1 + TIOCM_RI = 0x80 + TIOCM_RNG = 0x80 + TIOCM_RTS = 0x4 + TIOCM_SR = 0x10 + TIOCM_ST = 0x8 + TIOCNOTTY = 0x20007471 + TIOCNXCL = 0x2000740e + TIOCOUTQ = 0x40047473 + TIOCPKT = 0x80047470 + TIOCPKT_DATA = 0x0 + TIOCPKT_DOSTOP = 0x20 + TIOCPKT_FLUSHREAD = 0x1 + TIOCPKT_FLUSHWRITE = 0x2 + TIOCPKT_IOCTL = 0x40 + TIOCPKT_NOSTOP = 0x10 + TIOCPKT_START = 0x8 + TIOCPKT_STOP = 0x4 + TIOCREMOTE = 0x80047469 + TIOCSBRK = 0x2000747b + TIOCSCTTY = 0x20007461 + TIOCSDTR = 0x20007479 + TIOCSETA = 0x802c7414 + TIOCSETAF = 0x802c7416 + TIOCSETAW = 0x802c7415 + TIOCSETD = 0x8004741b + TIOCSETVERAUTH = 0x8004741c + TIOCSFLAGS = 0x8004745c + TIOCSIG = 0x8004745f + TIOCSPGRP = 0x80047476 + TIOCSTART = 0x2000746e + TIOCSTAT = 0x20007465 + TIOCSTOP = 0x2000746f + TIOCSTSTAMP = 0x8008745a + TIOCSWINSZ = 0x80087467 + TIOCUCNTL = 0x80047466 + TIOCUCNTL_CBRK = 0x7a + TIOCUCNTL_SBRK = 0x7b + TOSTOP = 0x400000 + UTIME_NOW = -0x2 + UTIME_OMIT = -0x1 + VDISCARD = 0xf + VDSUSP = 0xb + VEOF = 0x0 + VEOL = 0x1 + VEOL2 = 0x2 + VERASE = 0x3 + VINTR = 0x8 + VKILL = 0x5 + VLNEXT = 0xe + VMIN = 0x10 + VM_ANONMIN = 0x7 + VM_LOADAVG = 0x2 + VM_MALLOC_CONF = 0xc + VM_MAXID = 0xd + VM_MAXSLP = 0xa + VM_METER = 0x1 + VM_NKMEMPAGES = 0x6 + VM_PSSTRINGS = 0x3 + VM_SWAPENCRYPT = 0x5 + VM_USPACE = 0xb + VM_UVMEXP = 0x4 + VM_VNODEMIN = 0x9 + VM_VTEXTMIN = 0x8 + VQUIT = 0x9 + VREPRINT = 0x6 + VSTART = 0xc + VSTATUS = 0x12 + VSTOP = 0xd + VSUSP = 0xa + VTIME = 0x11 + VWERASE = 0x4 + WALTSIG = 0x4 + WCONTINUED = 0x8 + WCOREFLAG = 0x80 + WNOHANG = 0x1 + WUNTRACED = 0x2 + XCASE = 0x1000000 +) + +// Errors +const ( + E2BIG = syscall.Errno(0x7) + EACCES = syscall.Errno(0xd) + EADDRINUSE = syscall.Errno(0x30) + EADDRNOTAVAIL = syscall.Errno(0x31) + EAFNOSUPPORT = syscall.Errno(0x2f) + EAGAIN = syscall.Errno(0x23) + EALREADY = syscall.Errno(0x25) + EAUTH = syscall.Errno(0x50) + EBADF = syscall.Errno(0x9) + EBADMSG = syscall.Errno(0x5c) + EBADRPC = syscall.Errno(0x48) + EBUSY = syscall.Errno(0x10) + ECANCELED = syscall.Errno(0x58) + ECHILD = syscall.Errno(0xa) + ECONNABORTED = syscall.Errno(0x35) + ECONNREFUSED = syscall.Errno(0x3d) + ECONNRESET = syscall.Errno(0x36) + EDEADLK = syscall.Errno(0xb) + EDESTADDRREQ = syscall.Errno(0x27) + EDOM = syscall.Errno(0x21) + EDQUOT = syscall.Errno(0x45) + EEXIST = syscall.Errno(0x11) + EFAULT = syscall.Errno(0xe) + EFBIG = syscall.Errno(0x1b) + EFTYPE = syscall.Errno(0x4f) + EHOSTDOWN = syscall.Errno(0x40) + EHOSTUNREACH = syscall.Errno(0x41) + EIDRM = syscall.Errno(0x59) + EILSEQ = syscall.Errno(0x54) + EINPROGRESS = syscall.Errno(0x24) + EINTR = syscall.Errno(0x4) + EINVAL = syscall.Errno(0x16) + EIO = syscall.Errno(0x5) + EIPSEC = syscall.Errno(0x52) + EISCONN = syscall.Errno(0x38) + EISDIR = syscall.Errno(0x15) + ELAST = syscall.Errno(0x5f) + ELOOP = syscall.Errno(0x3e) + EMEDIUMTYPE = syscall.Errno(0x56) + EMFILE = syscall.Errno(0x18) + EMLINK = syscall.Errno(0x1f) + EMSGSIZE = syscall.Errno(0x28) + ENAMETOOLONG = syscall.Errno(0x3f) + ENEEDAUTH = syscall.Errno(0x51) + ENETDOWN = syscall.Errno(0x32) + ENETRESET = syscall.Errno(0x34) + ENETUNREACH = syscall.Errno(0x33) + ENFILE = syscall.Errno(0x17) + ENOATTR = syscall.Errno(0x53) + ENOBUFS = syscall.Errno(0x37) + ENODEV = syscall.Errno(0x13) + ENOENT = syscall.Errno(0x2) + ENOEXEC = syscall.Errno(0x8) + ENOLCK = syscall.Errno(0x4d) + ENOMEDIUM = syscall.Errno(0x55) + ENOMEM = syscall.Errno(0xc) + ENOMSG = syscall.Errno(0x5a) + ENOPROTOOPT = syscall.Errno(0x2a) + ENOSPC = syscall.Errno(0x1c) + ENOSYS = syscall.Errno(0x4e) + ENOTBLK = syscall.Errno(0xf) + ENOTCONN = syscall.Errno(0x39) + ENOTDIR = syscall.Errno(0x14) + ENOTEMPTY = syscall.Errno(0x42) + ENOTRECOVERABLE = syscall.Errno(0x5d) + ENOTSOCK = syscall.Errno(0x26) + ENOTSUP = syscall.Errno(0x5b) + ENOTTY = syscall.Errno(0x19) + ENXIO = syscall.Errno(0x6) + EOPNOTSUPP = syscall.Errno(0x2d) + EOVERFLOW = syscall.Errno(0x57) + EOWNERDEAD = syscall.Errno(0x5e) + EPERM = syscall.Errno(0x1) + EPFNOSUPPORT = syscall.Errno(0x2e) + EPIPE = syscall.Errno(0x20) + EPROCLIM = syscall.Errno(0x43) + EPROCUNAVAIL = syscall.Errno(0x4c) + EPROGMISMATCH = syscall.Errno(0x4b) + EPROGUNAVAIL = syscall.Errno(0x4a) + EPROTO = syscall.Errno(0x5f) + EPROTONOSUPPORT = syscall.Errno(0x2b) + EPROTOTYPE = syscall.Errno(0x29) + ERANGE = syscall.Errno(0x22) + EREMOTE = syscall.Errno(0x47) + EROFS = syscall.Errno(0x1e) + ERPCMISMATCH = syscall.Errno(0x49) + ESHUTDOWN = syscall.Errno(0x3a) + ESOCKTNOSUPPORT = syscall.Errno(0x2c) + ESPIPE = syscall.Errno(0x1d) + ESRCH = syscall.Errno(0x3) + ESTALE = syscall.Errno(0x46) + ETIMEDOUT = syscall.Errno(0x3c) + ETOOMANYREFS = syscall.Errno(0x3b) + ETXTBSY = syscall.Errno(0x1a) + EUSERS = syscall.Errno(0x44) + EWOULDBLOCK = syscall.Errno(0x23) + EXDEV = syscall.Errno(0x12) +) + +// Signals +const ( + SIGABRT = syscall.Signal(0x6) + SIGALRM = syscall.Signal(0xe) + SIGBUS = syscall.Signal(0xa) + SIGCHLD = syscall.Signal(0x14) + SIGCONT = syscall.Signal(0x13) + SIGEMT = syscall.Signal(0x7) + SIGFPE = syscall.Signal(0x8) + SIGHUP = syscall.Signal(0x1) + SIGILL = syscall.Signal(0x4) + SIGINFO = syscall.Signal(0x1d) + SIGINT = syscall.Signal(0x2) + SIGIO = syscall.Signal(0x17) + SIGIOT = syscall.Signal(0x6) + SIGKILL = syscall.Signal(0x9) + SIGPIPE = syscall.Signal(0xd) + SIGPROF = syscall.Signal(0x1b) + SIGQUIT = syscall.Signal(0x3) + SIGSEGV = syscall.Signal(0xb) + SIGSTOP = syscall.Signal(0x11) + SIGSYS = syscall.Signal(0xc) + SIGTERM = syscall.Signal(0xf) + SIGTHR = syscall.Signal(0x20) + SIGTRAP = syscall.Signal(0x5) + SIGTSTP = syscall.Signal(0x12) + SIGTTIN = syscall.Signal(0x15) + SIGTTOU = syscall.Signal(0x16) + SIGURG = syscall.Signal(0x10) + SIGUSR1 = syscall.Signal(0x1e) + SIGUSR2 = syscall.Signal(0x1f) + SIGVTALRM = syscall.Signal(0x1a) + SIGWINCH = syscall.Signal(0x1c) + SIGXCPU = syscall.Signal(0x18) + SIGXFSZ = syscall.Signal(0x19) +) + +// Error table +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disk quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC program not available"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIPSEC", "IPsec processing failure"}, + {83, "ENOATTR", "attribute not found"}, + {84, "EILSEQ", "illegal byte sequence"}, + {85, "ENOMEDIUM", "no medium found"}, + {86, "EMEDIUMTYPE", "wrong medium type"}, + {87, "EOVERFLOW", "value too large to be stored in data type"}, + {88, "ECANCELED", "operation canceled"}, + {89, "EIDRM", "identifier removed"}, + {90, "ENOMSG", "no message of desired type"}, + {91, "ENOTSUP", "not supported"}, + {92, "EBADMSG", "bad message"}, + {93, "ENOTRECOVERABLE", "state not recoverable"}, + {94, "EOWNERDEAD", "previous owner died"}, + {95, "ELAST", "protocol error"}, +} + +// Signal table +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGABRT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGTHR", "thread AST"}, +} diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_riscv64.go new file mode 100644 index 0000000000..13d403031e --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_riscv64.go @@ -0,0 +1,1904 @@ +// mkerrors.sh -m64 +// Code generated by the command above; see README.md. DO NOT EDIT. + +//go:build riscv64 && openbsd +// +build riscv64,openbsd + +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs -- -m64 _const.go + +package unix + +import "syscall" + +const ( + AF_APPLETALK = 0x10 + AF_BLUETOOTH = 0x20 + AF_CCITT = 0xa + AF_CHAOS = 0x5 + AF_CNT = 0x15 + AF_COIP = 0x14 + AF_DATAKIT = 0x9 + AF_DECnet = 0xc + AF_DLI = 0xd + AF_E164 = 0x1a + AF_ECMA = 0x8 + AF_ENCAP = 0x1c + AF_HYLINK = 0xf + AF_IMPLINK = 0x3 + AF_INET = 0x2 + AF_INET6 = 0x18 + AF_IPX = 0x17 + AF_ISDN = 0x1a + AF_ISO = 0x7 + AF_KEY = 0x1e + AF_LAT = 0xe + AF_LINK = 0x12 + AF_LOCAL = 0x1 + AF_MAX = 0x24 + AF_MPLS = 0x21 + AF_NATM = 0x1b + AF_NS = 0x6 + AF_OSI = 0x7 + AF_PUP = 0x4 + AF_ROUTE = 0x11 + AF_SIP = 0x1d + AF_SNA = 0xb + AF_UNIX = 0x1 + AF_UNSPEC = 0x0 + ALTWERASE = 0x200 + ARPHRD_ETHER = 0x1 + ARPHRD_FRELAY = 0xf + ARPHRD_IEEE1394 = 0x18 + ARPHRD_IEEE802 = 0x6 + B0 = 0x0 + B110 = 0x6e + B115200 = 0x1c200 + B1200 = 0x4b0 + B134 = 0x86 + B14400 = 0x3840 + B150 = 0x96 + B1800 = 0x708 + B19200 = 0x4b00 + B200 = 0xc8 + B230400 = 0x38400 + B2400 = 0x960 + B28800 = 0x7080 + B300 = 0x12c + B38400 = 0x9600 + B4800 = 0x12c0 + B50 = 0x32 + B57600 = 0xe100 + B600 = 0x258 + B7200 = 0x1c20 + B75 = 0x4b + B76800 = 0x12c00 + B9600 = 0x2580 + BIOCFLUSH = 0x20004268 + BIOCGBLEN = 0x40044266 + BIOCGDIRFILT = 0x4004427c + BIOCGDLT = 0x4004426a + BIOCGDLTLIST = 0xc010427b + BIOCGETIF = 0x4020426b + BIOCGFILDROP = 0x40044278 + BIOCGHDRCMPLT = 0x40044274 + BIOCGRSIG = 0x40044273 + BIOCGRTIMEOUT = 0x4010426e + BIOCGSTATS = 0x4008426f + BIOCIMMEDIATE = 0x80044270 + BIOCLOCK = 0x20004276 + BIOCPROMISC = 0x20004269 + BIOCSBLEN = 0xc0044266 + BIOCSDIRFILT = 0x8004427d + BIOCSDLT = 0x8004427a + BIOCSETF = 0x80104267 + BIOCSETIF = 0x8020426c + BIOCSETWF = 0x80104277 + BIOCSFILDROP = 0x80044279 + BIOCSHDRCMPLT = 0x80044275 + BIOCSRSIG = 0x80044272 + BIOCSRTIMEOUT = 0x8010426d + BIOCVERSION = 0x40044271 + BPF_A = 0x10 + BPF_ABS = 0x20 + BPF_ADD = 0x0 + BPF_ALIGNMENT = 0x4 + BPF_ALU = 0x4 + BPF_AND = 0x50 + BPF_B = 0x10 + BPF_DIRECTION_IN = 0x1 + BPF_DIRECTION_OUT = 0x2 + BPF_DIV = 0x30 + BPF_FILDROP_CAPTURE = 0x1 + BPF_FILDROP_DROP = 0x2 + BPF_FILDROP_PASS = 0x0 + BPF_F_DIR_IN = 0x10 + BPF_F_DIR_MASK = 0x30 + BPF_F_DIR_OUT = 0x20 + BPF_F_DIR_SHIFT = 0x4 + BPF_F_FLOWID = 0x8 + BPF_F_PRI_MASK = 0x7 + BPF_H = 0x8 + BPF_IMM = 0x0 + BPF_IND = 0x40 + BPF_JA = 0x0 + BPF_JEQ = 0x10 + BPF_JGE = 0x30 + BPF_JGT = 0x20 + BPF_JMP = 0x5 + BPF_JSET = 0x40 + BPF_K = 0x0 + BPF_LD = 0x0 + BPF_LDX = 0x1 + BPF_LEN = 0x80 + BPF_LSH = 0x60 + BPF_MAJOR_VERSION = 0x1 + BPF_MAXBUFSIZE = 0x200000 + BPF_MAXINSNS = 0x200 + BPF_MEM = 0x60 + BPF_MEMWORDS = 0x10 + BPF_MINBUFSIZE = 0x20 + BPF_MINOR_VERSION = 0x1 + BPF_MISC = 0x7 + BPF_MSH = 0xa0 + BPF_MUL = 0x20 + BPF_NEG = 0x80 + BPF_OR = 0x40 + BPF_RELEASE = 0x30bb6 + BPF_RET = 0x6 + BPF_RND = 0xc0 + BPF_RSH = 0x70 + BPF_ST = 0x2 + BPF_STX = 0x3 + BPF_SUB = 0x10 + BPF_TAX = 0x0 + BPF_TXA = 0x80 + BPF_W = 0x0 + BPF_X = 0x8 + BRKINT = 0x2 + CFLUSH = 0xf + CLOCAL = 0x8000 + CLOCK_BOOTTIME = 0x6 + CLOCK_MONOTONIC = 0x3 + CLOCK_PROCESS_CPUTIME_ID = 0x2 + CLOCK_REALTIME = 0x0 + CLOCK_THREAD_CPUTIME_ID = 0x4 + CLOCK_UPTIME = 0x5 + CPUSTATES = 0x6 + CP_IDLE = 0x5 + CP_INTR = 0x4 + CP_NICE = 0x1 + CP_SPIN = 0x3 + CP_SYS = 0x2 + CP_USER = 0x0 + CREAD = 0x800 + CRTSCTS = 0x10000 + CS5 = 0x0 + CS6 = 0x100 + CS7 = 0x200 + CS8 = 0x300 + CSIZE = 0x300 + CSTART = 0x11 + CSTATUS = 0xff + CSTOP = 0x13 + CSTOPB = 0x400 + CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 + CTL_MAXNAME = 0xc + CTL_NET = 0x4 + DIOCADDQUEUE = 0xc110445d + DIOCADDRULE = 0xcd604404 + DIOCADDSTATE = 0xc1084425 + DIOCCHANGERULE = 0xcd60441a + DIOCCLRIFFLAG = 0xc028445a + DIOCCLRSRCNODES = 0x20004455 + DIOCCLRSTATES = 0xc0e04412 + DIOCCLRSTATUS = 0xc0284416 + DIOCGETLIMIT = 0xc0084427 + DIOCGETQSTATS = 0xc1204460 + DIOCGETQUEUE = 0xc110445f + DIOCGETQUEUES = 0xc110445e + DIOCGETRULE = 0xcd604407 + DIOCGETRULES = 0xcd604406 + DIOCGETRULESET = 0xc444443b + DIOCGETRULESETS = 0xc444443a + DIOCGETSRCNODES = 0xc0104454 + DIOCGETSTATE = 0xc1084413 + DIOCGETSTATES = 0xc0104419 + DIOCGETSTATUS = 0xc1e84415 + DIOCGETSYNFLWATS = 0xc0084463 + DIOCGETTIMEOUT = 0xc008441e + DIOCIGETIFACES = 0xc0284457 + DIOCKILLSRCNODES = 0xc080445b + DIOCKILLSTATES = 0xc0e04429 + DIOCNATLOOK = 0xc0504417 + DIOCOSFPADD = 0xc088444f + DIOCOSFPFLUSH = 0x2000444e + DIOCOSFPGET = 0xc0884450 + DIOCRADDADDRS = 0xc4504443 + DIOCRADDTABLES = 0xc450443d + DIOCRCLRADDRS = 0xc4504442 + DIOCRCLRASTATS = 0xc4504448 + DIOCRCLRTABLES = 0xc450443c + DIOCRCLRTSTATS = 0xc4504441 + DIOCRDELADDRS = 0xc4504444 + DIOCRDELTABLES = 0xc450443e + DIOCRGETADDRS = 0xc4504446 + DIOCRGETASTATS = 0xc4504447 + DIOCRGETTABLES = 0xc450443f + DIOCRGETTSTATS = 0xc4504440 + DIOCRINADEFINE = 0xc450444d + DIOCRSETADDRS = 0xc4504445 + DIOCRSETTFLAGS = 0xc450444a + DIOCRTSTADDRS = 0xc4504449 + DIOCSETDEBUG = 0xc0044418 + DIOCSETHOSTID = 0xc0044456 + DIOCSETIFFLAG = 0xc0284459 + DIOCSETLIMIT = 0xc0084428 + DIOCSETREASS = 0xc004445c + DIOCSETSTATUSIF = 0xc0284414 + DIOCSETSYNCOOKIES = 0xc0014462 + DIOCSETSYNFLWATS = 0xc0084461 + DIOCSETTIMEOUT = 0xc008441d + DIOCSTART = 0x20004401 + DIOCSTOP = 0x20004402 + DIOCXBEGIN = 0xc0104451 + DIOCXCOMMIT = 0xc0104452 + DIOCXROLLBACK = 0xc0104453 + DLT_ARCNET = 0x7 + DLT_ATM_RFC1483 = 0xb + DLT_AX25 = 0x3 + DLT_CHAOS = 0x5 + DLT_C_HDLC = 0x68 + DLT_EN10MB = 0x1 + DLT_EN3MB = 0x2 + DLT_ENC = 0xd + DLT_FDDI = 0xa + DLT_IEEE802 = 0x6 + DLT_IEEE802_11 = 0x69 + DLT_IEEE802_11_RADIO = 0x7f + DLT_LOOP = 0xc + DLT_MPLS = 0xdb + DLT_NULL = 0x0 + DLT_OPENFLOW = 0x10b + DLT_PFLOG = 0x75 + DLT_PFSYNC = 0x12 + DLT_PPP = 0x9 + DLT_PPP_BSDOS = 0x10 + DLT_PPP_ETHER = 0x33 + DLT_PPP_SERIAL = 0x32 + DLT_PRONET = 0x4 + DLT_RAW = 0xe + DLT_SLIP = 0x8 + DLT_SLIP_BSDOS = 0xf + DLT_USBPCAP = 0xf9 + DLT_USER0 = 0x93 + DLT_USER1 = 0x94 + DLT_USER10 = 0x9d + DLT_USER11 = 0x9e + DLT_USER12 = 0x9f + DLT_USER13 = 0xa0 + DLT_USER14 = 0xa1 + DLT_USER15 = 0xa2 + DLT_USER2 = 0x95 + DLT_USER3 = 0x96 + DLT_USER4 = 0x97 + DLT_USER5 = 0x98 + DLT_USER6 = 0x99 + DLT_USER7 = 0x9a + DLT_USER8 = 0x9b + DLT_USER9 = 0x9c + DT_BLK = 0x6 + DT_CHR = 0x2 + DT_DIR = 0x4 + DT_FIFO = 0x1 + DT_LNK = 0xa + DT_REG = 0x8 + DT_SOCK = 0xc + DT_UNKNOWN = 0x0 + ECHO = 0x8 + ECHOCTL = 0x40 + ECHOE = 0x2 + ECHOK = 0x4 + ECHOKE = 0x1 + ECHONL = 0x10 + ECHOPRT = 0x20 + EMT_TAGOVF = 0x1 + EMUL_ENABLED = 0x1 + EMUL_NATIVE = 0x2 + ENDRUNDISC = 0x9 + ETH64_8021_RSVD_MASK = 0xfffffffffff0 + ETH64_8021_RSVD_PREFIX = 0x180c2000000 + ETHERMIN = 0x2e + ETHERMTU = 0x5dc + ETHERTYPE_8023 = 0x4 + ETHERTYPE_AARP = 0x80f3 + ETHERTYPE_ACCTON = 0x8390 + ETHERTYPE_AEONIC = 0x8036 + ETHERTYPE_ALPHA = 0x814a + ETHERTYPE_AMBER = 0x6008 + ETHERTYPE_AMOEBA = 0x8145 + ETHERTYPE_AOE = 0x88a2 + ETHERTYPE_APOLLO = 0x80f7 + ETHERTYPE_APOLLODOMAIN = 0x8019 + ETHERTYPE_APPLETALK = 0x809b + ETHERTYPE_APPLITEK = 0x80c7 + ETHERTYPE_ARGONAUT = 0x803a + ETHERTYPE_ARP = 0x806 + ETHERTYPE_AT = 0x809b + ETHERTYPE_ATALK = 0x809b + ETHERTYPE_ATOMIC = 0x86df + ETHERTYPE_ATT = 0x8069 + ETHERTYPE_ATTSTANFORD = 0x8008 + ETHERTYPE_AUTOPHON = 0x806a + ETHERTYPE_AXIS = 0x8856 + ETHERTYPE_BCLOOP = 0x9003 + ETHERTYPE_BOFL = 0x8102 + ETHERTYPE_CABLETRON = 0x7034 + ETHERTYPE_CHAOS = 0x804 + ETHERTYPE_COMDESIGN = 0x806c + ETHERTYPE_COMPUGRAPHIC = 0x806d + ETHERTYPE_COUNTERPOINT = 0x8062 + ETHERTYPE_CRONUS = 0x8004 + ETHERTYPE_CRONUSVLN = 0x8003 + ETHERTYPE_DCA = 0x1234 + ETHERTYPE_DDE = 0x807b + ETHERTYPE_DEBNI = 0xaaaa + ETHERTYPE_DECAM = 0x8048 + ETHERTYPE_DECCUST = 0x6006 + ETHERTYPE_DECDIAG = 0x6005 + ETHERTYPE_DECDNS = 0x803c + ETHERTYPE_DECDTS = 0x803e + ETHERTYPE_DECEXPER = 0x6000 + ETHERTYPE_DECLAST = 0x8041 + ETHERTYPE_DECLTM = 0x803f + ETHERTYPE_DECMUMPS = 0x6009 + ETHERTYPE_DECNETBIOS = 0x8040 + ETHERTYPE_DELTACON = 0x86de + ETHERTYPE_DIDDLE = 0x4321 + ETHERTYPE_DLOG1 = 0x660 + ETHERTYPE_DLOG2 = 0x661 + ETHERTYPE_DN = 0x6003 + ETHERTYPE_DOGFIGHT = 0x1989 + ETHERTYPE_DSMD = 0x8039 + ETHERTYPE_EAPOL = 0x888e + ETHERTYPE_ECMA = 0x803 + ETHERTYPE_ENCRYPT = 0x803d + ETHERTYPE_ES = 0x805d + ETHERTYPE_EXCELAN = 0x8010 + ETHERTYPE_EXPERDATA = 0x8049 + ETHERTYPE_FLIP = 0x8146 + ETHERTYPE_FLOWCONTROL = 0x8808 + ETHERTYPE_FRARP = 0x808 + ETHERTYPE_GENDYN = 0x8068 + ETHERTYPE_HAYES = 0x8130 + ETHERTYPE_HIPPI_FP = 0x8180 + ETHERTYPE_HITACHI = 0x8820 + ETHERTYPE_HP = 0x8005 + ETHERTYPE_IEEEPUP = 0xa00 + ETHERTYPE_IEEEPUPAT = 0xa01 + ETHERTYPE_IMLBL = 0x4c42 + ETHERTYPE_IMLBLDIAG = 0x424c + ETHERTYPE_IP = 0x800 + ETHERTYPE_IPAS = 0x876c + ETHERTYPE_IPV6 = 0x86dd + ETHERTYPE_IPX = 0x8137 + ETHERTYPE_IPXNEW = 0x8037 + ETHERTYPE_KALPANA = 0x8582 + ETHERTYPE_LANBRIDGE = 0x8038 + ETHERTYPE_LANPROBE = 0x8888 + ETHERTYPE_LAT = 0x6004 + ETHERTYPE_LBACK = 0x9000 + ETHERTYPE_LITTLE = 0x8060 + ETHERTYPE_LLDP = 0x88cc + ETHERTYPE_LOGICRAFT = 0x8148 + ETHERTYPE_LOOPBACK = 0x9000 + ETHERTYPE_MACSEC = 0x88e5 + ETHERTYPE_MATRA = 0x807a + ETHERTYPE_MAX = 0xffff + ETHERTYPE_MERIT = 0x807c + ETHERTYPE_MICP = 0x873a + ETHERTYPE_MOPDL = 0x6001 + ETHERTYPE_MOPRC = 0x6002 + ETHERTYPE_MOTOROLA = 0x818d + ETHERTYPE_MPLS = 0x8847 + ETHERTYPE_MPLS_MCAST = 0x8848 + ETHERTYPE_MUMPS = 0x813f + ETHERTYPE_NBPCC = 0x3c04 + ETHERTYPE_NBPCLAIM = 0x3c09 + ETHERTYPE_NBPCLREQ = 0x3c05 + ETHERTYPE_NBPCLRSP = 0x3c06 + ETHERTYPE_NBPCREQ = 0x3c02 + ETHERTYPE_NBPCRSP = 0x3c03 + ETHERTYPE_NBPDG = 0x3c07 + ETHERTYPE_NBPDGB = 0x3c08 + ETHERTYPE_NBPDLTE = 0x3c0a + ETHERTYPE_NBPRAR = 0x3c0c + ETHERTYPE_NBPRAS = 0x3c0b + ETHERTYPE_NBPRST = 0x3c0d + ETHERTYPE_NBPSCD = 0x3c01 + ETHERTYPE_NBPVCD = 0x3c00 + ETHERTYPE_NBS = 0x802 + ETHERTYPE_NCD = 0x8149 + ETHERTYPE_NESTAR = 0x8006 + ETHERTYPE_NETBEUI = 0x8191 + ETHERTYPE_NHRP = 0x2001 + ETHERTYPE_NOVELL = 0x8138 + ETHERTYPE_NS = 0x600 + ETHERTYPE_NSAT = 0x601 + ETHERTYPE_NSCOMPAT = 0x807 + ETHERTYPE_NSH = 0x984f + ETHERTYPE_NTRAILER = 0x10 + ETHERTYPE_OS9 = 0x7007 + ETHERTYPE_OS9NET = 0x7009 + ETHERTYPE_PACER = 0x80c6 + ETHERTYPE_PBB = 0x88e7 + ETHERTYPE_PCS = 0x4242 + ETHERTYPE_PLANNING = 0x8044 + ETHERTYPE_PPP = 0x880b + ETHERTYPE_PPPOE = 0x8864 + ETHERTYPE_PPPOEDISC = 0x8863 + ETHERTYPE_PRIMENTS = 0x7031 + ETHERTYPE_PUP = 0x200 + ETHERTYPE_PUPAT = 0x200 + ETHERTYPE_QINQ = 0x88a8 + ETHERTYPE_RACAL = 0x7030 + ETHERTYPE_RATIONAL = 0x8150 + ETHERTYPE_RAWFR = 0x6559 + ETHERTYPE_RCL = 0x1995 + ETHERTYPE_RDP = 0x8739 + ETHERTYPE_RETIX = 0x80f2 + ETHERTYPE_REVARP = 0x8035 + ETHERTYPE_SCA = 0x6007 + ETHERTYPE_SECTRA = 0x86db + ETHERTYPE_SECUREDATA = 0x876d + ETHERTYPE_SGITW = 0x817e + ETHERTYPE_SG_BOUNCE = 0x8016 + ETHERTYPE_SG_DIAG = 0x8013 + ETHERTYPE_SG_NETGAMES = 0x8014 + ETHERTYPE_SG_RESV = 0x8015 + ETHERTYPE_SIMNET = 0x5208 + ETHERTYPE_SLOW = 0x8809 + ETHERTYPE_SNA = 0x80d5 + ETHERTYPE_SNMP = 0x814c + ETHERTYPE_SONIX = 0xfaf5 + ETHERTYPE_SPIDER = 0x809f + ETHERTYPE_SPRITE = 0x500 + ETHERTYPE_STP = 0x8181 + ETHERTYPE_TALARIS = 0x812b + ETHERTYPE_TALARISMC = 0x852b + ETHERTYPE_TCPCOMP = 0x876b + ETHERTYPE_TCPSM = 0x9002 + ETHERTYPE_TEC = 0x814f + ETHERTYPE_TIGAN = 0x802f + ETHERTYPE_TRAIL = 0x1000 + ETHERTYPE_TRANSETHER = 0x6558 + ETHERTYPE_TYMSHARE = 0x802e + ETHERTYPE_UBBST = 0x7005 + ETHERTYPE_UBDEBUG = 0x900 + ETHERTYPE_UBDIAGLOOP = 0x7002 + ETHERTYPE_UBDL = 0x7000 + ETHERTYPE_UBNIU = 0x7001 + ETHERTYPE_UBNMC = 0x7003 + ETHERTYPE_VALID = 0x1600 + ETHERTYPE_VARIAN = 0x80dd + ETHERTYPE_VAXELN = 0x803b + ETHERTYPE_VEECO = 0x8067 + ETHERTYPE_VEXP = 0x805b + ETHERTYPE_VGLAB = 0x8131 + ETHERTYPE_VINES = 0xbad + ETHERTYPE_VINESECHO = 0xbaf + ETHERTYPE_VINESLOOP = 0xbae + ETHERTYPE_VITAL = 0xff00 + ETHERTYPE_VLAN = 0x8100 + ETHERTYPE_VLTLMAN = 0x8080 + ETHERTYPE_VPROD = 0x805c + ETHERTYPE_VURESERVED = 0x8147 + ETHERTYPE_WATERLOO = 0x8130 + ETHERTYPE_WELLFLEET = 0x8103 + ETHERTYPE_X25 = 0x805 + ETHERTYPE_X75 = 0x801 + ETHERTYPE_XNSSM = 0x9001 + ETHERTYPE_XTP = 0x817d + ETHER_ADDR_LEN = 0x6 + ETHER_ALIGN = 0x2 + ETHER_CRC_LEN = 0x4 + ETHER_CRC_POLY_BE = 0x4c11db6 + ETHER_CRC_POLY_LE = 0xedb88320 + ETHER_HDR_LEN = 0xe + ETHER_MAX_DIX_LEN = 0x600 + ETHER_MAX_HARDMTU_LEN = 0xff9b + ETHER_MAX_LEN = 0x5ee + ETHER_MIN_LEN = 0x40 + ETHER_TYPE_LEN = 0x2 + ETHER_VLAN_ENCAP_LEN = 0x4 + EVFILT_AIO = -0x3 + EVFILT_DEVICE = -0x8 + EVFILT_EXCEPT = -0x9 + EVFILT_PROC = -0x5 + EVFILT_READ = -0x1 + EVFILT_SIGNAL = -0x6 + EVFILT_SYSCOUNT = 0x9 + EVFILT_TIMER = -0x7 + EVFILT_VNODE = -0x4 + EVFILT_WRITE = -0x2 + EVL_ENCAPLEN = 0x4 + EVL_PRIO_BITS = 0xd + EVL_PRIO_MAX = 0x7 + EVL_VLID_MASK = 0xfff + EVL_VLID_MAX = 0xffe + EVL_VLID_MIN = 0x1 + EVL_VLID_NULL = 0x0 + EV_ADD = 0x1 + EV_CLEAR = 0x20 + EV_DELETE = 0x2 + EV_DISABLE = 0x8 + EV_DISPATCH = 0x80 + EV_ENABLE = 0x4 + EV_EOF = 0x8000 + EV_ERROR = 0x4000 + EV_FLAG1 = 0x2000 + EV_ONESHOT = 0x10 + EV_RECEIPT = 0x40 + EV_SYSFLAGS = 0xf800 + EXTA = 0x4b00 + EXTB = 0x9600 + EXTPROC = 0x800 + FD_CLOEXEC = 0x1 + FD_SETSIZE = 0x400 + FLUSHO = 0x800000 + F_DUPFD = 0x0 + F_DUPFD_CLOEXEC = 0xa + F_GETFD = 0x1 + F_GETFL = 0x3 + F_GETLK = 0x7 + F_GETOWN = 0x5 + F_ISATTY = 0xb + F_OK = 0x0 + F_RDLCK = 0x1 + F_SETFD = 0x2 + F_SETFL = 0x4 + F_SETLK = 0x8 + F_SETLKW = 0x9 + F_SETOWN = 0x6 + F_UNLCK = 0x2 + F_WRLCK = 0x3 + HUPCL = 0x4000 + HW_MACHINE = 0x1 + ICANON = 0x100 + ICMP6_FILTER = 0x12 + ICRNL = 0x100 + IEXTEN = 0x400 + IFAN_ARRIVAL = 0x0 + IFAN_DEPARTURE = 0x1 + IFF_ALLMULTI = 0x200 + IFF_BROADCAST = 0x2 + IFF_CANTCHANGE = 0x8e52 + IFF_DEBUG = 0x4 + IFF_LINK0 = 0x1000 + IFF_LINK1 = 0x2000 + IFF_LINK2 = 0x4000 + IFF_LOOPBACK = 0x8 + IFF_MULTICAST = 0x8000 + IFF_NOARP = 0x80 + IFF_OACTIVE = 0x400 + IFF_POINTOPOINT = 0x10 + IFF_PROMISC = 0x100 + IFF_RUNNING = 0x40 + IFF_SIMPLEX = 0x800 + IFF_STATICARP = 0x20 + IFF_UP = 0x1 + IFNAMSIZ = 0x10 + IFT_1822 = 0x2 + IFT_A12MPPSWITCH = 0x82 + IFT_AAL2 = 0xbb + IFT_AAL5 = 0x31 + IFT_ADSL = 0x5e + IFT_AFLANE8023 = 0x3b + IFT_AFLANE8025 = 0x3c + IFT_ARAP = 0x58 + IFT_ARCNET = 0x23 + IFT_ARCNETPLUS = 0x24 + IFT_ASYNC = 0x54 + IFT_ATM = 0x25 + IFT_ATMDXI = 0x69 + IFT_ATMFUNI = 0x6a + IFT_ATMIMA = 0x6b + IFT_ATMLOGICAL = 0x50 + IFT_ATMRADIO = 0xbd + IFT_ATMSUBINTERFACE = 0x86 + IFT_ATMVCIENDPT = 0xc2 + IFT_ATMVIRTUAL = 0x95 + IFT_BGPPOLICYACCOUNTING = 0xa2 + IFT_BLUETOOTH = 0xf8 + IFT_BRIDGE = 0xd1 + IFT_BSC = 0x53 + IFT_CARP = 0xf7 + IFT_CCTEMUL = 0x3d + IFT_CEPT = 0x13 + IFT_CES = 0x85 + IFT_CHANNEL = 0x46 + IFT_CNR = 0x55 + IFT_COFFEE = 0x84 + IFT_COMPOSITELINK = 0x9b + IFT_DCN = 0x8d + IFT_DIGITALPOWERLINE = 0x8a + IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba + IFT_DLSW = 0x4a + IFT_DOCSCABLEDOWNSTREAM = 0x80 + IFT_DOCSCABLEMACLAYER = 0x7f + IFT_DOCSCABLEUPSTREAM = 0x81 + IFT_DOCSCABLEUPSTREAMCHANNEL = 0xcd + IFT_DS0 = 0x51 + IFT_DS0BUNDLE = 0x52 + IFT_DS1FDL = 0xaa + IFT_DS3 = 0x1e + IFT_DTM = 0x8c + IFT_DUMMY = 0xf1 + IFT_DVBASILN = 0xac + IFT_DVBASIOUT = 0xad + IFT_DVBRCCDOWNSTREAM = 0x93 + IFT_DVBRCCMACLAYER = 0x92 + IFT_DVBRCCUPSTREAM = 0x94 + IFT_ECONET = 0xce + IFT_ENC = 0xf4 + IFT_EON = 0x19 + IFT_EPLRS = 0x57 + IFT_ESCON = 0x49 + IFT_ETHER = 0x6 + IFT_FAITH = 0xf3 + IFT_FAST = 0x7d + IFT_FASTETHER = 0x3e + IFT_FASTETHERFX = 0x45 + IFT_FDDI = 0xf + IFT_FIBRECHANNEL = 0x38 + IFT_FRAMERELAYINTERCONNECT = 0x3a + IFT_FRAMERELAYMPI = 0x5c + IFT_FRDLCIENDPT = 0xc1 + IFT_FRELAY = 0x20 + IFT_FRELAYDCE = 0x2c + IFT_FRF16MFRBUNDLE = 0xa3 + IFT_FRFORWARD = 0x9e + IFT_G703AT2MB = 0x43 + IFT_G703AT64K = 0x42 + IFT_GIF = 0xf0 + IFT_GIGABITETHERNET = 0x75 + IFT_GR303IDT = 0xb2 + IFT_GR303RDT = 0xb1 + IFT_H323GATEKEEPER = 0xa4 + IFT_H323PROXY = 0xa5 + IFT_HDH1822 = 0x3 + IFT_HDLC = 0x76 + IFT_HDSL2 = 0xa8 + IFT_HIPERLAN2 = 0xb7 + IFT_HIPPI = 0x2f + IFT_HIPPIINTERFACE = 0x39 + IFT_HOSTPAD = 0x5a + IFT_HSSI = 0x2e + IFT_HY = 0xe + IFT_IBM370PARCHAN = 0x48 + IFT_IDSL = 0x9a + IFT_IEEE1394 = 0x90 + IFT_IEEE80211 = 0x47 + IFT_IEEE80212 = 0x37 + IFT_IEEE8023ADLAG = 0xa1 + IFT_IFGSN = 0x91 + IFT_IMT = 0xbe + IFT_INFINIBAND = 0xc7 + IFT_INTERLEAVE = 0x7c + IFT_IP = 0x7e + IFT_IPFORWARD = 0x8e + IFT_IPOVERATM = 0x72 + IFT_IPOVERCDLC = 0x6d + IFT_IPOVERCLAW = 0x6e + IFT_IPSWITCH = 0x4e + IFT_ISDN = 0x3f + IFT_ISDNBASIC = 0x14 + IFT_ISDNPRIMARY = 0x15 + IFT_ISDNS = 0x4b + IFT_ISDNU = 0x4c + IFT_ISO88022LLC = 0x29 + IFT_ISO88023 = 0x7 + IFT_ISO88024 = 0x8 + IFT_ISO88025 = 0x9 + IFT_ISO88025CRFPINT = 0x62 + IFT_ISO88025DTR = 0x56 + IFT_ISO88025FIBER = 0x73 + IFT_ISO88026 = 0xa + IFT_ISUP = 0xb3 + IFT_L2VLAN = 0x87 + IFT_L3IPVLAN = 0x88 + IFT_L3IPXVLAN = 0x89 + IFT_LAPB = 0x10 + IFT_LAPD = 0x4d + IFT_LAPF = 0x77 + IFT_LINEGROUP = 0xd2 + IFT_LOCALTALK = 0x2a + IFT_LOOP = 0x18 + IFT_MBIM = 0xfa + IFT_MEDIAMAILOVERIP = 0x8b + IFT_MFSIGLINK = 0xa7 + IFT_MIOX25 = 0x26 + IFT_MODEM = 0x30 + IFT_MPC = 0x71 + IFT_MPLS = 0xa6 + IFT_MPLSTUNNEL = 0x96 + IFT_MSDSL = 0x8f + IFT_MVL = 0xbf + IFT_MYRINET = 0x63 + IFT_NFAS = 0xaf + IFT_NSIP = 0x1b + IFT_OPTICALCHANNEL = 0xc3 + IFT_OPTICALTRANSPORT = 0xc4 + IFT_OTHER = 0x1 + IFT_P10 = 0xc + IFT_P80 = 0xd + IFT_PARA = 0x22 + IFT_PFLOG = 0xf5 + IFT_PFLOW = 0xf9 + IFT_PFSYNC = 0xf6 + IFT_PLC = 0xae + IFT_PON155 = 0xcf + IFT_PON622 = 0xd0 + IFT_POS = 0xab + IFT_PPP = 0x17 + IFT_PPPMULTILINKBUNDLE = 0x6c + IFT_PROPATM = 0xc5 + IFT_PROPBWAP2MP = 0xb8 + IFT_PROPCNLS = 0x59 + IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 + IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 + IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 + IFT_PROPMUX = 0x36 + IFT_PROPVIRTUAL = 0x35 + IFT_PROPWIRELESSP2P = 0x9d + IFT_PTPSERIAL = 0x16 + IFT_PVC = 0xf2 + IFT_Q2931 = 0xc9 + IFT_QLLC = 0x44 + IFT_RADIOMAC = 0xbc + IFT_RADSL = 0x5f + IFT_REACHDSL = 0xc0 + IFT_RFC1483 = 0x9f + IFT_RS232 = 0x21 + IFT_RSRB = 0x4f + IFT_SDLC = 0x11 + IFT_SDSL = 0x60 + IFT_SHDSL = 0xa9 + IFT_SIP = 0x1f + IFT_SIPSIG = 0xcc + IFT_SIPTG = 0xcb + IFT_SLIP = 0x1c + IFT_SMDSDXI = 0x2b + IFT_SMDSICIP = 0x34 + IFT_SONET = 0x27 + IFT_SONETOVERHEADCHANNEL = 0xb9 + IFT_SONETPATH = 0x32 + IFT_SONETVT = 0x33 + IFT_SRP = 0x97 + IFT_SS7SIGLINK = 0x9c + IFT_STACKTOSTACK = 0x6f + IFT_STARLAN = 0xb + IFT_T1 = 0x12 + IFT_TDLC = 0x74 + IFT_TELINK = 0xc8 + IFT_TERMPAD = 0x5b + IFT_TR008 = 0xb0 + IFT_TRANSPHDLC = 0x7b + IFT_TUNNEL = 0x83 + IFT_ULTRA = 0x1d + IFT_USB = 0xa0 + IFT_V11 = 0x40 + IFT_V35 = 0x2d + IFT_V36 = 0x41 + IFT_V37 = 0x78 + IFT_VDSL = 0x61 + IFT_VIRTUALIPADDRESS = 0x70 + IFT_VIRTUALTG = 0xca + IFT_VOICEDID = 0xd5 + IFT_VOICEEM = 0x64 + IFT_VOICEEMFGD = 0xd3 + IFT_VOICEENCAP = 0x67 + IFT_VOICEFGDEANA = 0xd4 + IFT_VOICEFXO = 0x65 + IFT_VOICEFXS = 0x66 + IFT_VOICEOVERATM = 0x98 + IFT_VOICEOVERCABLE = 0xc6 + IFT_VOICEOVERFRAMERELAY = 0x99 + IFT_VOICEOVERIP = 0x68 + IFT_WIREGUARD = 0xfb + IFT_X213 = 0x5d + IFT_X25 = 0x5 + IFT_X25DDN = 0x4 + IFT_X25HUNTGROUP = 0x7a + IFT_X25MLP = 0x79 + IFT_X25PLE = 0x28 + IFT_XETHER = 0x1a + IGNBRK = 0x1 + IGNCR = 0x80 + IGNPAR = 0x4 + IMAXBEL = 0x2000 + INLCR = 0x40 + INPCK = 0x10 + IN_CLASSA_HOST = 0xffffff + IN_CLASSA_MAX = 0x80 + IN_CLASSA_NET = 0xff000000 + IN_CLASSA_NSHIFT = 0x18 + IN_CLASSB_HOST = 0xffff + IN_CLASSB_MAX = 0x10000 + IN_CLASSB_NET = 0xffff0000 + IN_CLASSB_NSHIFT = 0x10 + IN_CLASSC_HOST = 0xff + IN_CLASSC_NET = 0xffffff00 + IN_CLASSC_NSHIFT = 0x8 + IN_CLASSD_HOST = 0xfffffff + IN_CLASSD_NET = 0xf0000000 + IN_CLASSD_NSHIFT = 0x1c + IN_LOOPBACKNET = 0x7f + IN_RFC3021_HOST = 0x1 + IN_RFC3021_NET = 0xfffffffe + IN_RFC3021_NSHIFT = 0x1f + IPPROTO_AH = 0x33 + IPPROTO_CARP = 0x70 + IPPROTO_DIVERT = 0x102 + IPPROTO_DONE = 0x101 + IPPROTO_DSTOPTS = 0x3c + IPPROTO_EGP = 0x8 + IPPROTO_ENCAP = 0x62 + IPPROTO_EON = 0x50 + IPPROTO_ESP = 0x32 + IPPROTO_ETHERIP = 0x61 + IPPROTO_FRAGMENT = 0x2c + IPPROTO_GGP = 0x3 + IPPROTO_GRE = 0x2f + IPPROTO_HOPOPTS = 0x0 + IPPROTO_ICMP = 0x1 + IPPROTO_ICMPV6 = 0x3a + IPPROTO_IDP = 0x16 + IPPROTO_IGMP = 0x2 + IPPROTO_IP = 0x0 + IPPROTO_IPCOMP = 0x6c + IPPROTO_IPIP = 0x4 + IPPROTO_IPV4 = 0x4 + IPPROTO_IPV6 = 0x29 + IPPROTO_MAX = 0x100 + IPPROTO_MAXID = 0x103 + IPPROTO_MOBILE = 0x37 + IPPROTO_MPLS = 0x89 + IPPROTO_NONE = 0x3b + IPPROTO_PFSYNC = 0xf0 + IPPROTO_PIM = 0x67 + IPPROTO_PUP = 0xc + IPPROTO_RAW = 0xff + IPPROTO_ROUTING = 0x2b + IPPROTO_RSVP = 0x2e + IPPROTO_SCTP = 0x84 + IPPROTO_TCP = 0x6 + IPPROTO_TP = 0x1d + IPPROTO_UDP = 0x11 + IPPROTO_UDPLITE = 0x88 + IPV6_AUTH_LEVEL = 0x35 + IPV6_AUTOFLOWLABEL = 0x3b + IPV6_CHECKSUM = 0x1a + IPV6_DEFAULT_MULTICAST_HOPS = 0x1 + IPV6_DEFAULT_MULTICAST_LOOP = 0x1 + IPV6_DEFHLIM = 0x40 + IPV6_DONTFRAG = 0x3e + IPV6_DSTOPTS = 0x32 + IPV6_ESP_NETWORK_LEVEL = 0x37 + IPV6_ESP_TRANS_LEVEL = 0x36 + IPV6_FAITH = 0x1d + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 + IPV6_FRAGTTL = 0x78 + IPV6_HLIMDEC = 0x1 + IPV6_HOPLIMIT = 0x2f + IPV6_HOPOPTS = 0x31 + IPV6_IPCOMP_LEVEL = 0x3c + IPV6_JOIN_GROUP = 0xc + IPV6_LEAVE_GROUP = 0xd + IPV6_MAXHLIM = 0xff + IPV6_MAXPACKET = 0xffff + IPV6_MINHOPCOUNT = 0x41 + IPV6_MMTU = 0x500 + IPV6_MULTICAST_HOPS = 0xa + IPV6_MULTICAST_IF = 0x9 + IPV6_MULTICAST_LOOP = 0xb + IPV6_NEXTHOP = 0x30 + IPV6_OPTIONS = 0x1 + IPV6_PATHMTU = 0x2c + IPV6_PIPEX = 0x3f + IPV6_PKTINFO = 0x2e + IPV6_PORTRANGE = 0xe + IPV6_PORTRANGE_DEFAULT = 0x0 + IPV6_PORTRANGE_HIGH = 0x1 + IPV6_PORTRANGE_LOW = 0x2 + IPV6_RECVDSTOPTS = 0x28 + IPV6_RECVDSTPORT = 0x40 + IPV6_RECVHOPLIMIT = 0x25 + IPV6_RECVHOPOPTS = 0x27 + IPV6_RECVPATHMTU = 0x2b + IPV6_RECVPKTINFO = 0x24 + IPV6_RECVRTHDR = 0x26 + IPV6_RECVTCLASS = 0x39 + IPV6_RTABLE = 0x1021 + IPV6_RTHDR = 0x33 + IPV6_RTHDRDSTOPTS = 0x23 + IPV6_RTHDR_LOOSE = 0x0 + IPV6_RTHDR_STRICT = 0x1 + IPV6_RTHDR_TYPE_0 = 0x0 + IPV6_SOCKOPT_RESERVED1 = 0x3 + IPV6_TCLASS = 0x3d + IPV6_UNICAST_HOPS = 0x4 + IPV6_USE_MIN_MTU = 0x2a + IPV6_V6ONLY = 0x1b + IPV6_VERSION = 0x60 + IPV6_VERSION_MASK = 0xf0 + IP_ADD_MEMBERSHIP = 0xc + IP_AUTH_LEVEL = 0x14 + IP_DEFAULT_MULTICAST_LOOP = 0x1 + IP_DEFAULT_MULTICAST_TTL = 0x1 + IP_DF = 0x4000 + IP_DROP_MEMBERSHIP = 0xd + IP_ESP_NETWORK_LEVEL = 0x16 + IP_ESP_TRANS_LEVEL = 0x15 + IP_HDRINCL = 0x2 + IP_IPCOMP_LEVEL = 0x1d + IP_IPDEFTTL = 0x25 + IP_IPSECFLOWINFO = 0x24 + IP_IPSEC_LOCAL_AUTH = 0x1b + IP_IPSEC_LOCAL_CRED = 0x19 + IP_IPSEC_LOCAL_ID = 0x17 + IP_IPSEC_REMOTE_AUTH = 0x1c + IP_IPSEC_REMOTE_CRED = 0x1a + IP_IPSEC_REMOTE_ID = 0x18 + IP_MAXPACKET = 0xffff + IP_MAX_MEMBERSHIPS = 0xfff + IP_MF = 0x2000 + IP_MINTTL = 0x20 + IP_MIN_MEMBERSHIPS = 0xf + IP_MSS = 0x240 + IP_MULTICAST_IF = 0x9 + IP_MULTICAST_LOOP = 0xb + IP_MULTICAST_TTL = 0xa + IP_OFFMASK = 0x1fff + IP_OPTIONS = 0x1 + IP_PIPEX = 0x22 + IP_PORTRANGE = 0x13 + IP_PORTRANGE_DEFAULT = 0x0 + IP_PORTRANGE_HIGH = 0x1 + IP_PORTRANGE_LOW = 0x2 + IP_RECVDSTADDR = 0x7 + IP_RECVDSTPORT = 0x21 + IP_RECVIF = 0x1e + IP_RECVOPTS = 0x5 + IP_RECVRETOPTS = 0x6 + IP_RECVRTABLE = 0x23 + IP_RECVTTL = 0x1f + IP_RETOPTS = 0x8 + IP_RF = 0x8000 + IP_RTABLE = 0x1021 + IP_SENDSRCADDR = 0x7 + IP_TOS = 0x3 + IP_TTL = 0x4 + ISIG = 0x80 + ISTRIP = 0x20 + ITIMER_PROF = 0x2 + ITIMER_REAL = 0x0 + ITIMER_VIRTUAL = 0x1 + IUCLC = 0x1000 + IXANY = 0x800 + IXOFF = 0x400 + IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 + LCNT_OVERLOAD_FLUSH = 0x6 + LOCK_EX = 0x2 + LOCK_NB = 0x4 + LOCK_SH = 0x1 + LOCK_UN = 0x8 + MADV_DONTNEED = 0x4 + MADV_FREE = 0x6 + MADV_NORMAL = 0x0 + MADV_RANDOM = 0x1 + MADV_SEQUENTIAL = 0x2 + MADV_SPACEAVAIL = 0x5 + MADV_WILLNEED = 0x3 + MAP_ANON = 0x1000 + MAP_ANONYMOUS = 0x1000 + MAP_CONCEAL = 0x8000 + MAP_COPY = 0x2 + MAP_FILE = 0x0 + MAP_FIXED = 0x10 + MAP_FLAGMASK = 0xfff7 + MAP_HASSEMAPHORE = 0x0 + MAP_INHERIT = 0x0 + MAP_INHERIT_COPY = 0x1 + MAP_INHERIT_NONE = 0x2 + MAP_INHERIT_SHARE = 0x0 + MAP_INHERIT_ZERO = 0x3 + MAP_NOEXTEND = 0x0 + MAP_NORESERVE = 0x0 + MAP_PRIVATE = 0x2 + MAP_RENAME = 0x0 + MAP_SHARED = 0x1 + MAP_STACK = 0x4000 + MAP_TRYFIXED = 0x0 + MCL_CURRENT = 0x1 + MCL_FUTURE = 0x2 + MNT_ASYNC = 0x40 + MNT_DEFEXPORTED = 0x200 + MNT_DELEXPORT = 0x20000 + MNT_DOOMED = 0x8000000 + MNT_EXPORTANON = 0x400 + MNT_EXPORTED = 0x100 + MNT_EXRDONLY = 0x80 + MNT_FORCE = 0x80000 + MNT_LAZY = 0x3 + MNT_LOCAL = 0x1000 + MNT_NOATIME = 0x8000 + MNT_NODEV = 0x10 + MNT_NOEXEC = 0x4 + MNT_NOPERM = 0x20 + MNT_NOSUID = 0x8 + MNT_NOWAIT = 0x2 + MNT_QUOTA = 0x2000 + MNT_RDONLY = 0x1 + MNT_RELOAD = 0x40000 + MNT_ROOTFS = 0x4000 + MNT_SOFTDEP = 0x4000000 + MNT_STALLED = 0x100000 + MNT_SWAPPABLE = 0x200000 + MNT_SYNCHRONOUS = 0x2 + MNT_UPDATE = 0x10000 + MNT_VISFLAGMASK = 0x400ffff + MNT_WAIT = 0x1 + MNT_WANTRDWR = 0x2000000 + MNT_WXALLOWED = 0x800 + MOUNT_AFS = "afs" + MOUNT_CD9660 = "cd9660" + MOUNT_EXT2FS = "ext2fs" + MOUNT_FFS = "ffs" + MOUNT_FUSEFS = "fuse" + MOUNT_MFS = "mfs" + MOUNT_MSDOS = "msdos" + MOUNT_NCPFS = "ncpfs" + MOUNT_NFS = "nfs" + MOUNT_NTFS = "ntfs" + MOUNT_TMPFS = "tmpfs" + MOUNT_UDF = "udf" + MOUNT_UFS = "ffs" + MSG_BCAST = 0x100 + MSG_CMSG_CLOEXEC = 0x800 + MSG_CTRUNC = 0x20 + MSG_DONTROUTE = 0x4 + MSG_DONTWAIT = 0x80 + MSG_EOR = 0x8 + MSG_MCAST = 0x200 + MSG_NOSIGNAL = 0x400 + MSG_OOB = 0x1 + MSG_PEEK = 0x2 + MSG_TRUNC = 0x10 + MSG_WAITALL = 0x40 + MS_ASYNC = 0x1 + MS_INVALIDATE = 0x4 + MS_SYNC = 0x2 + NAME_MAX = 0xff + NET_RT_DUMP = 0x1 + NET_RT_FLAGS = 0x2 + NET_RT_IFLIST = 0x3 + NET_RT_IFNAMES = 0x6 + NET_RT_MAXID = 0x8 + NET_RT_SOURCE = 0x7 + NET_RT_STATS = 0x4 + NET_RT_TABLE = 0x5 + NFDBITS = 0x20 + NOFLSH = 0x80000000 + NOKERNINFO = 0x2000000 + NOTE_ATTRIB = 0x8 + NOTE_CHANGE = 0x1 + NOTE_CHILD = 0x4 + NOTE_DELETE = 0x1 + NOTE_EOF = 0x2 + NOTE_EXEC = 0x20000000 + NOTE_EXIT = 0x80000000 + NOTE_EXTEND = 0x4 + NOTE_FORK = 0x40000000 + NOTE_LINK = 0x10 + NOTE_LOWAT = 0x1 + NOTE_OOB = 0x4 + NOTE_PCTRLMASK = 0xf0000000 + NOTE_PDATAMASK = 0xfffff + NOTE_RENAME = 0x20 + NOTE_REVOKE = 0x40 + NOTE_TRACK = 0x1 + NOTE_TRACKERR = 0x2 + NOTE_TRUNCATE = 0x80 + NOTE_WRITE = 0x2 + OCRNL = 0x10 + OLCUC = 0x20 + ONLCR = 0x2 + ONLRET = 0x80 + ONOCR = 0x40 + ONOEOT = 0x8 + OPOST = 0x1 + OXTABS = 0x4 + O_ACCMODE = 0x3 + O_APPEND = 0x8 + O_ASYNC = 0x40 + O_CLOEXEC = 0x10000 + O_CREAT = 0x200 + O_DIRECTORY = 0x20000 + O_DSYNC = 0x80 + O_EXCL = 0x800 + O_EXLOCK = 0x20 + O_FSYNC = 0x80 + O_NDELAY = 0x4 + O_NOCTTY = 0x8000 + O_NOFOLLOW = 0x100 + O_NONBLOCK = 0x4 + O_RDONLY = 0x0 + O_RDWR = 0x2 + O_RSYNC = 0x80 + O_SHLOCK = 0x10 + O_SYNC = 0x80 + O_TRUNC = 0x400 + O_WRONLY = 0x1 + PARENB = 0x1000 + PARMRK = 0x8 + PARODD = 0x2000 + PENDIN = 0x20000000 + PF_FLUSH = 0x1 + PRIO_PGRP = 0x1 + PRIO_PROCESS = 0x0 + PRIO_USER = 0x2 + PROT_EXEC = 0x4 + PROT_NONE = 0x0 + PROT_READ = 0x1 + PROT_WRITE = 0x2 + RLIMIT_CORE = 0x4 + RLIMIT_CPU = 0x0 + RLIMIT_DATA = 0x2 + RLIMIT_FSIZE = 0x1 + RLIMIT_MEMLOCK = 0x6 + RLIMIT_NOFILE = 0x8 + RLIMIT_NPROC = 0x7 + RLIMIT_RSS = 0x5 + RLIMIT_STACK = 0x3 + RLIM_INFINITY = 0x7fffffffffffffff + RTAX_AUTHOR = 0x6 + RTAX_BFD = 0xb + RTAX_BRD = 0x7 + RTAX_DNS = 0xc + RTAX_DST = 0x0 + RTAX_GATEWAY = 0x1 + RTAX_GENMASK = 0x3 + RTAX_IFA = 0x5 + RTAX_IFP = 0x4 + RTAX_LABEL = 0xa + RTAX_MAX = 0xf + RTAX_NETMASK = 0x2 + RTAX_SEARCH = 0xe + RTAX_SRC = 0x8 + RTAX_SRCMASK = 0x9 + RTAX_STATIC = 0xd + RTA_AUTHOR = 0x40 + RTA_BFD = 0x800 + RTA_BRD = 0x80 + RTA_DNS = 0x1000 + RTA_DST = 0x1 + RTA_GATEWAY = 0x2 + RTA_GENMASK = 0x8 + RTA_IFA = 0x20 + RTA_IFP = 0x10 + RTA_LABEL = 0x400 + RTA_NETMASK = 0x4 + RTA_SEARCH = 0x4000 + RTA_SRC = 0x100 + RTA_SRCMASK = 0x200 + RTA_STATIC = 0x2000 + RTF_ANNOUNCE = 0x4000 + RTF_BFD = 0x1000000 + RTF_BLACKHOLE = 0x1000 + RTF_BROADCAST = 0x400000 + RTF_CACHED = 0x20000 + RTF_CLONED = 0x10000 + RTF_CLONING = 0x100 + RTF_CONNECTED = 0x800000 + RTF_DONE = 0x40 + RTF_DYNAMIC = 0x10 + RTF_FMASK = 0x110fc08 + RTF_GATEWAY = 0x2 + RTF_HOST = 0x4 + RTF_LLINFO = 0x400 + RTF_LOCAL = 0x200000 + RTF_MODIFIED = 0x20 + RTF_MPATH = 0x40000 + RTF_MPLS = 0x100000 + RTF_MULTICAST = 0x200 + RTF_PERMANENT_ARP = 0x2000 + RTF_PROTO1 = 0x8000 + RTF_PROTO2 = 0x4000 + RTF_PROTO3 = 0x2000 + RTF_REJECT = 0x8 + RTF_STATIC = 0x800 + RTF_UP = 0x1 + RTF_USETRAILERS = 0x8000 + RTM_80211INFO = 0x15 + RTM_ADD = 0x1 + RTM_BFD = 0x12 + RTM_CHANGE = 0x3 + RTM_CHGADDRATTR = 0x14 + RTM_DELADDR = 0xd + RTM_DELETE = 0x2 + RTM_DESYNC = 0x10 + RTM_GET = 0x4 + RTM_IFANNOUNCE = 0xf + RTM_IFINFO = 0xe + RTM_INVALIDATE = 0x11 + RTM_LOSING = 0x5 + RTM_MAXSIZE = 0x800 + RTM_MISS = 0x7 + RTM_NEWADDR = 0xc + RTM_PROPOSAL = 0x13 + RTM_REDIRECT = 0x6 + RTM_RESOLVE = 0xb + RTM_SOURCE = 0x16 + RTM_VERSION = 0x5 + RTV_EXPIRE = 0x4 + RTV_HOPCOUNT = 0x2 + RTV_MTU = 0x1 + RTV_RPIPE = 0x8 + RTV_RTT = 0x40 + RTV_RTTVAR = 0x80 + RTV_SPIPE = 0x10 + RTV_SSTHRESH = 0x20 + RT_TABLEID_BITS = 0x8 + RT_TABLEID_MASK = 0xff + RT_TABLEID_MAX = 0xff + RUSAGE_CHILDREN = -0x1 + RUSAGE_SELF = 0x0 + RUSAGE_THREAD = 0x1 + SCM_RIGHTS = 0x1 + SCM_TIMESTAMP = 0x4 + SEEK_CUR = 0x1 + SEEK_END = 0x2 + SEEK_SET = 0x0 + SHUT_RD = 0x0 + SHUT_RDWR = 0x2 + SHUT_WR = 0x1 + SIOCADDMULTI = 0x80206931 + SIOCAIFADDR = 0x8040691a + SIOCAIFGROUP = 0x80286987 + SIOCATMARK = 0x40047307 + SIOCBRDGADD = 0x8060693c + SIOCBRDGADDL = 0x80606949 + SIOCBRDGADDS = 0x80606941 + SIOCBRDGARL = 0x808c694d + SIOCBRDGDADDR = 0x81286947 + SIOCBRDGDEL = 0x8060693d + SIOCBRDGDELS = 0x80606942 + SIOCBRDGFLUSH = 0x80606948 + SIOCBRDGFRL = 0x808c694e + SIOCBRDGGCACHE = 0xc0146941 + SIOCBRDGGFD = 0xc0146952 + SIOCBRDGGHT = 0xc0146951 + SIOCBRDGGIFFLGS = 0xc060693e + SIOCBRDGGMA = 0xc0146953 + SIOCBRDGGPARAM = 0xc0406958 + SIOCBRDGGPRI = 0xc0146950 + SIOCBRDGGRL = 0xc030694f + SIOCBRDGGTO = 0xc0146946 + SIOCBRDGIFS = 0xc0606942 + SIOCBRDGRTS = 0xc0206943 + SIOCBRDGSADDR = 0xc1286944 + SIOCBRDGSCACHE = 0x80146940 + SIOCBRDGSFD = 0x80146952 + SIOCBRDGSHT = 0x80146951 + SIOCBRDGSIFCOST = 0x80606955 + SIOCBRDGSIFFLGS = 0x8060693f + SIOCBRDGSIFPRIO = 0x80606954 + SIOCBRDGSIFPROT = 0x8060694a + SIOCBRDGSMA = 0x80146953 + SIOCBRDGSPRI = 0x80146950 + SIOCBRDGSPROTO = 0x8014695a + SIOCBRDGSTO = 0x80146945 + SIOCBRDGSTXHC = 0x80146959 + SIOCDELLABEL = 0x80206997 + SIOCDELMULTI = 0x80206932 + SIOCDIFADDR = 0x80206919 + SIOCDIFGROUP = 0x80286989 + SIOCDIFPARENT = 0x802069b4 + SIOCDIFPHYADDR = 0x80206949 + SIOCDPWE3NEIGHBOR = 0x802069de + SIOCDVNETID = 0x802069af + SIOCGETKALIVE = 0xc01869a4 + SIOCGETLABEL = 0x8020699a + SIOCGETMPWCFG = 0xc02069ae + SIOCGETPFLOW = 0xc02069fe + SIOCGETPFSYNC = 0xc02069f8 + SIOCGETSGCNT = 0xc0207534 + SIOCGETVIFCNT = 0xc0287533 + SIOCGETVLAN = 0xc0206990 + SIOCGIFADDR = 0xc0206921 + SIOCGIFBRDADDR = 0xc0206923 + SIOCGIFCONF = 0xc0106924 + SIOCGIFDATA = 0xc020691b + SIOCGIFDESCR = 0xc0206981 + SIOCGIFDSTADDR = 0xc0206922 + SIOCGIFFLAGS = 0xc0206911 + SIOCGIFGATTR = 0xc028698b + SIOCGIFGENERIC = 0xc020693a + SIOCGIFGLIST = 0xc028698d + SIOCGIFGMEMB = 0xc028698a + SIOCGIFGROUP = 0xc0286988 + SIOCGIFHARDMTU = 0xc02069a5 + SIOCGIFLLPRIO = 0xc02069b6 + SIOCGIFMEDIA = 0xc0406938 + SIOCGIFMETRIC = 0xc0206917 + SIOCGIFMTU = 0xc020697e + SIOCGIFNETMASK = 0xc0206925 + SIOCGIFPAIR = 0xc02069b1 + SIOCGIFPARENT = 0xc02069b3 + SIOCGIFPRIORITY = 0xc020699c + SIOCGIFRDOMAIN = 0xc02069a0 + SIOCGIFRTLABEL = 0xc0206983 + SIOCGIFRXR = 0x802069aa + SIOCGIFSFFPAGE = 0xc1126939 + SIOCGIFXFLAGS = 0xc020699e + SIOCGLIFPHYADDR = 0xc218694b + SIOCGLIFPHYDF = 0xc02069c2 + SIOCGLIFPHYECN = 0xc02069c8 + SIOCGLIFPHYRTABLE = 0xc02069a2 + SIOCGLIFPHYTTL = 0xc02069a9 + SIOCGPGRP = 0x40047309 + SIOCGPWE3 = 0xc0206998 + SIOCGPWE3CTRLWORD = 0xc02069dc + SIOCGPWE3FAT = 0xc02069dd + SIOCGPWE3NEIGHBOR = 0xc21869de + SIOCGRXHPRIO = 0xc02069db + SIOCGSPPPPARAMS = 0xc0206994 + SIOCGTXHPRIO = 0xc02069c6 + SIOCGUMBINFO = 0xc02069be + SIOCGUMBPARAM = 0xc02069c0 + SIOCGVH = 0xc02069f6 + SIOCGVNETFLOWID = 0xc02069c4 + SIOCGVNETID = 0xc02069a7 + SIOCIFAFATTACH = 0x801169ab + SIOCIFAFDETACH = 0x801169ac + SIOCIFCREATE = 0x8020697a + SIOCIFDESTROY = 0x80206979 + SIOCIFGCLONERS = 0xc0106978 + SIOCSETKALIVE = 0x801869a3 + SIOCSETLABEL = 0x80206999 + SIOCSETMPWCFG = 0x802069ad + SIOCSETPFLOW = 0x802069fd + SIOCSETPFSYNC = 0x802069f7 + SIOCSETVLAN = 0x8020698f + SIOCSIFADDR = 0x8020690c + SIOCSIFBRDADDR = 0x80206913 + SIOCSIFDESCR = 0x80206980 + SIOCSIFDSTADDR = 0x8020690e + SIOCSIFFLAGS = 0x80206910 + SIOCSIFGATTR = 0x8028698c + SIOCSIFGENERIC = 0x80206939 + SIOCSIFLLADDR = 0x8020691f + SIOCSIFLLPRIO = 0x802069b5 + SIOCSIFMEDIA = 0xc0206937 + SIOCSIFMETRIC = 0x80206918 + SIOCSIFMTU = 0x8020697f + SIOCSIFNETMASK = 0x80206916 + SIOCSIFPAIR = 0x802069b0 + SIOCSIFPARENT = 0x802069b2 + SIOCSIFPRIORITY = 0x8020699b + SIOCSIFRDOMAIN = 0x8020699f + SIOCSIFRTLABEL = 0x80206982 + SIOCSIFXFLAGS = 0x8020699d + SIOCSLIFPHYADDR = 0x8218694a + SIOCSLIFPHYDF = 0x802069c1 + SIOCSLIFPHYECN = 0x802069c7 + SIOCSLIFPHYRTABLE = 0x802069a1 + SIOCSLIFPHYTTL = 0x802069a8 + SIOCSPGRP = 0x80047308 + SIOCSPWE3CTRLWORD = 0x802069dc + SIOCSPWE3FAT = 0x802069dd + SIOCSPWE3NEIGHBOR = 0x821869de + SIOCSRXHPRIO = 0x802069db + SIOCSSPPPPARAMS = 0x80206993 + SIOCSTXHPRIO = 0x802069c5 + SIOCSUMBPARAM = 0x802069bf + SIOCSVH = 0xc02069f5 + SIOCSVNETFLOWID = 0x802069c3 + SIOCSVNETID = 0x802069a6 + SOCK_CLOEXEC = 0x8000 + SOCK_DGRAM = 0x2 + SOCK_DNS = 0x1000 + SOCK_NONBLOCK = 0x4000 + SOCK_RAW = 0x3 + SOCK_RDM = 0x4 + SOCK_SEQPACKET = 0x5 + SOCK_STREAM = 0x1 + SOL_SOCKET = 0xffff + SOMAXCONN = 0x80 + SO_ACCEPTCONN = 0x2 + SO_BINDANY = 0x1000 + SO_BROADCAST = 0x20 + SO_DEBUG = 0x1 + SO_DOMAIN = 0x1024 + SO_DONTROUTE = 0x10 + SO_ERROR = 0x1007 + SO_KEEPALIVE = 0x8 + SO_LINGER = 0x80 + SO_NETPROC = 0x1020 + SO_OOBINLINE = 0x100 + SO_PEERCRED = 0x1022 + SO_PROTOCOL = 0x1025 + SO_RCVBUF = 0x1002 + SO_RCVLOWAT = 0x1004 + SO_RCVTIMEO = 0x1006 + SO_REUSEADDR = 0x4 + SO_REUSEPORT = 0x200 + SO_RTABLE = 0x1021 + SO_SNDBUF = 0x1001 + SO_SNDLOWAT = 0x1003 + SO_SNDTIMEO = 0x1005 + SO_SPLICE = 0x1023 + SO_TIMESTAMP = 0x800 + SO_TYPE = 0x1008 + SO_USELOOPBACK = 0x40 + SO_ZEROIZE = 0x2000 + S_BLKSIZE = 0x200 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 + TCIFLUSH = 0x1 + TCIOFF = 0x3 + TCIOFLUSH = 0x3 + TCION = 0x4 + TCOFLUSH = 0x2 + TCOOFF = 0x1 + TCOON = 0x2 + TCPOPT_EOL = 0x0 + TCPOPT_MAXSEG = 0x2 + TCPOPT_NOP = 0x1 + TCPOPT_SACK = 0x5 + TCPOPT_SACK_HDR = 0x1010500 + TCPOPT_SACK_PERMITTED = 0x4 + TCPOPT_SACK_PERMIT_HDR = 0x1010402 + TCPOPT_SIGNATURE = 0x13 + TCPOPT_TIMESTAMP = 0x8 + TCPOPT_TSTAMP_HDR = 0x101080a + TCPOPT_WINDOW = 0x3 + TCP_INFO = 0x9 + TCP_MAXSEG = 0x2 + TCP_MAXWIN = 0xffff + TCP_MAX_SACK = 0x3 + TCP_MAX_WINSHIFT = 0xe + TCP_MD5SIG = 0x4 + TCP_MSS = 0x200 + TCP_NODELAY = 0x1 + TCP_NOPUSH = 0x10 + TCP_SACKHOLE_LIMIT = 0x80 + TCP_SACK_ENABLE = 0x8 + TCSAFLUSH = 0x2 + TIMER_ABSTIME = 0x1 + TIMER_RELTIME = 0x0 + TIOCCBRK = 0x2000747a + TIOCCDTR = 0x20007478 + TIOCCHKVERAUTH = 0x2000741e + TIOCCLRVERAUTH = 0x2000741d + TIOCCONS = 0x80047462 + TIOCDRAIN = 0x2000745e + TIOCEXCL = 0x2000740d + TIOCEXT = 0x80047460 + TIOCFLAG_CLOCAL = 0x2 + TIOCFLAG_CRTSCTS = 0x4 + TIOCFLAG_MDMBUF = 0x8 + TIOCFLAG_PPS = 0x10 + TIOCFLAG_SOFTCAR = 0x1 + TIOCFLUSH = 0x80047410 + TIOCGETA = 0x402c7413 + TIOCGETD = 0x4004741a + TIOCGFLAGS = 0x4004745d + TIOCGPGRP = 0x40047477 + TIOCGSID = 0x40047463 + TIOCGTSTAMP = 0x4010745b + TIOCGWINSZ = 0x40087468 + TIOCMBIC = 0x8004746b + TIOCMBIS = 0x8004746c + TIOCMGET = 0x4004746a + TIOCMODG = 0x4004746a + TIOCMODS = 0x8004746d + TIOCMSET = 0x8004746d + TIOCM_CAR = 0x40 + TIOCM_CD = 0x40 + TIOCM_CTS = 0x20 + TIOCM_DSR = 0x100 + TIOCM_DTR = 0x2 + TIOCM_LE = 0x1 + TIOCM_RI = 0x80 + TIOCM_RNG = 0x80 + TIOCM_RTS = 0x4 + TIOCM_SR = 0x10 + TIOCM_ST = 0x8 + TIOCNOTTY = 0x20007471 + TIOCNXCL = 0x2000740e + TIOCOUTQ = 0x40047473 + TIOCPKT = 0x80047470 + TIOCPKT_DATA = 0x0 + TIOCPKT_DOSTOP = 0x20 + TIOCPKT_FLUSHREAD = 0x1 + TIOCPKT_FLUSHWRITE = 0x2 + TIOCPKT_IOCTL = 0x40 + TIOCPKT_NOSTOP = 0x10 + TIOCPKT_START = 0x8 + TIOCPKT_STOP = 0x4 + TIOCREMOTE = 0x80047469 + TIOCSBRK = 0x2000747b + TIOCSCTTY = 0x20007461 + TIOCSDTR = 0x20007479 + TIOCSETA = 0x802c7414 + TIOCSETAF = 0x802c7416 + TIOCSETAW = 0x802c7415 + TIOCSETD = 0x8004741b + TIOCSETVERAUTH = 0x8004741c + TIOCSFLAGS = 0x8004745c + TIOCSIG = 0x8004745f + TIOCSPGRP = 0x80047476 + TIOCSTART = 0x2000746e + TIOCSTAT = 0x20007465 + TIOCSTOP = 0x2000746f + TIOCSTSTAMP = 0x8008745a + TIOCSWINSZ = 0x80087467 + TIOCUCNTL = 0x80047466 + TIOCUCNTL_CBRK = 0x7a + TIOCUCNTL_SBRK = 0x7b + TOSTOP = 0x400000 + UTIME_NOW = -0x2 + UTIME_OMIT = -0x1 + VDISCARD = 0xf + VDSUSP = 0xb + VEOF = 0x0 + VEOL = 0x1 + VEOL2 = 0x2 + VERASE = 0x3 + VINTR = 0x8 + VKILL = 0x5 + VLNEXT = 0xe + VMIN = 0x10 + VM_ANONMIN = 0x7 + VM_LOADAVG = 0x2 + VM_MALLOC_CONF = 0xc + VM_MAXID = 0xd + VM_MAXSLP = 0xa + VM_METER = 0x1 + VM_NKMEMPAGES = 0x6 + VM_PSSTRINGS = 0x3 + VM_SWAPENCRYPT = 0x5 + VM_USPACE = 0xb + VM_UVMEXP = 0x4 + VM_VNODEMIN = 0x9 + VM_VTEXTMIN = 0x8 + VQUIT = 0x9 + VREPRINT = 0x6 + VSTART = 0xc + VSTATUS = 0x12 + VSTOP = 0xd + VSUSP = 0xa + VTIME = 0x11 + VWERASE = 0x4 + WALTSIG = 0x4 + WCONTINUED = 0x8 + WCOREFLAG = 0x80 + WNOHANG = 0x1 + WUNTRACED = 0x2 + XCASE = 0x1000000 +) + +// Errors +const ( + E2BIG = syscall.Errno(0x7) + EACCES = syscall.Errno(0xd) + EADDRINUSE = syscall.Errno(0x30) + EADDRNOTAVAIL = syscall.Errno(0x31) + EAFNOSUPPORT = syscall.Errno(0x2f) + EAGAIN = syscall.Errno(0x23) + EALREADY = syscall.Errno(0x25) + EAUTH = syscall.Errno(0x50) + EBADF = syscall.Errno(0x9) + EBADMSG = syscall.Errno(0x5c) + EBADRPC = syscall.Errno(0x48) + EBUSY = syscall.Errno(0x10) + ECANCELED = syscall.Errno(0x58) + ECHILD = syscall.Errno(0xa) + ECONNABORTED = syscall.Errno(0x35) + ECONNREFUSED = syscall.Errno(0x3d) + ECONNRESET = syscall.Errno(0x36) + EDEADLK = syscall.Errno(0xb) + EDESTADDRREQ = syscall.Errno(0x27) + EDOM = syscall.Errno(0x21) + EDQUOT = syscall.Errno(0x45) + EEXIST = syscall.Errno(0x11) + EFAULT = syscall.Errno(0xe) + EFBIG = syscall.Errno(0x1b) + EFTYPE = syscall.Errno(0x4f) + EHOSTDOWN = syscall.Errno(0x40) + EHOSTUNREACH = syscall.Errno(0x41) + EIDRM = syscall.Errno(0x59) + EILSEQ = syscall.Errno(0x54) + EINPROGRESS = syscall.Errno(0x24) + EINTR = syscall.Errno(0x4) + EINVAL = syscall.Errno(0x16) + EIO = syscall.Errno(0x5) + EIPSEC = syscall.Errno(0x52) + EISCONN = syscall.Errno(0x38) + EISDIR = syscall.Errno(0x15) + ELAST = syscall.Errno(0x5f) + ELOOP = syscall.Errno(0x3e) + EMEDIUMTYPE = syscall.Errno(0x56) + EMFILE = syscall.Errno(0x18) + EMLINK = syscall.Errno(0x1f) + EMSGSIZE = syscall.Errno(0x28) + ENAMETOOLONG = syscall.Errno(0x3f) + ENEEDAUTH = syscall.Errno(0x51) + ENETDOWN = syscall.Errno(0x32) + ENETRESET = syscall.Errno(0x34) + ENETUNREACH = syscall.Errno(0x33) + ENFILE = syscall.Errno(0x17) + ENOATTR = syscall.Errno(0x53) + ENOBUFS = syscall.Errno(0x37) + ENODEV = syscall.Errno(0x13) + ENOENT = syscall.Errno(0x2) + ENOEXEC = syscall.Errno(0x8) + ENOLCK = syscall.Errno(0x4d) + ENOMEDIUM = syscall.Errno(0x55) + ENOMEM = syscall.Errno(0xc) + ENOMSG = syscall.Errno(0x5a) + ENOPROTOOPT = syscall.Errno(0x2a) + ENOSPC = syscall.Errno(0x1c) + ENOSYS = syscall.Errno(0x4e) + ENOTBLK = syscall.Errno(0xf) + ENOTCONN = syscall.Errno(0x39) + ENOTDIR = syscall.Errno(0x14) + ENOTEMPTY = syscall.Errno(0x42) + ENOTRECOVERABLE = syscall.Errno(0x5d) + ENOTSOCK = syscall.Errno(0x26) + ENOTSUP = syscall.Errno(0x5b) + ENOTTY = syscall.Errno(0x19) + ENXIO = syscall.Errno(0x6) + EOPNOTSUPP = syscall.Errno(0x2d) + EOVERFLOW = syscall.Errno(0x57) + EOWNERDEAD = syscall.Errno(0x5e) + EPERM = syscall.Errno(0x1) + EPFNOSUPPORT = syscall.Errno(0x2e) + EPIPE = syscall.Errno(0x20) + EPROCLIM = syscall.Errno(0x43) + EPROCUNAVAIL = syscall.Errno(0x4c) + EPROGMISMATCH = syscall.Errno(0x4b) + EPROGUNAVAIL = syscall.Errno(0x4a) + EPROTO = syscall.Errno(0x5f) + EPROTONOSUPPORT = syscall.Errno(0x2b) + EPROTOTYPE = syscall.Errno(0x29) + ERANGE = syscall.Errno(0x22) + EREMOTE = syscall.Errno(0x47) + EROFS = syscall.Errno(0x1e) + ERPCMISMATCH = syscall.Errno(0x49) + ESHUTDOWN = syscall.Errno(0x3a) + ESOCKTNOSUPPORT = syscall.Errno(0x2c) + ESPIPE = syscall.Errno(0x1d) + ESRCH = syscall.Errno(0x3) + ESTALE = syscall.Errno(0x46) + ETIMEDOUT = syscall.Errno(0x3c) + ETOOMANYREFS = syscall.Errno(0x3b) + ETXTBSY = syscall.Errno(0x1a) + EUSERS = syscall.Errno(0x44) + EWOULDBLOCK = syscall.Errno(0x23) + EXDEV = syscall.Errno(0x12) +) + +// Signals +const ( + SIGABRT = syscall.Signal(0x6) + SIGALRM = syscall.Signal(0xe) + SIGBUS = syscall.Signal(0xa) + SIGCHLD = syscall.Signal(0x14) + SIGCONT = syscall.Signal(0x13) + SIGEMT = syscall.Signal(0x7) + SIGFPE = syscall.Signal(0x8) + SIGHUP = syscall.Signal(0x1) + SIGILL = syscall.Signal(0x4) + SIGINFO = syscall.Signal(0x1d) + SIGINT = syscall.Signal(0x2) + SIGIO = syscall.Signal(0x17) + SIGIOT = syscall.Signal(0x6) + SIGKILL = syscall.Signal(0x9) + SIGPIPE = syscall.Signal(0xd) + SIGPROF = syscall.Signal(0x1b) + SIGQUIT = syscall.Signal(0x3) + SIGSEGV = syscall.Signal(0xb) + SIGSTOP = syscall.Signal(0x11) + SIGSYS = syscall.Signal(0xc) + SIGTERM = syscall.Signal(0xf) + SIGTHR = syscall.Signal(0x20) + SIGTRAP = syscall.Signal(0x5) + SIGTSTP = syscall.Signal(0x12) + SIGTTIN = syscall.Signal(0x15) + SIGTTOU = syscall.Signal(0x16) + SIGURG = syscall.Signal(0x10) + SIGUSR1 = syscall.Signal(0x1e) + SIGUSR2 = syscall.Signal(0x1f) + SIGVTALRM = syscall.Signal(0x1a) + SIGWINCH = syscall.Signal(0x1c) + SIGXCPU = syscall.Signal(0x18) + SIGXFSZ = syscall.Signal(0x19) +) + +// Error table +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disk quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC program not available"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIPSEC", "IPsec processing failure"}, + {83, "ENOATTR", "attribute not found"}, + {84, "EILSEQ", "illegal byte sequence"}, + {85, "ENOMEDIUM", "no medium found"}, + {86, "EMEDIUMTYPE", "wrong medium type"}, + {87, "EOVERFLOW", "value too large to be stored in data type"}, + {88, "ECANCELED", "operation canceled"}, + {89, "EIDRM", "identifier removed"}, + {90, "ENOMSG", "no message of desired type"}, + {91, "ENOTSUP", "not supported"}, + {92, "EBADMSG", "bad message"}, + {93, "ENOTRECOVERABLE", "state not recoverable"}, + {94, "EOWNERDEAD", "previous owner died"}, + {95, "ELAST", "protocol error"}, +} + +// Signal table +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGABRT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGTHR", "thread AST"}, +} diff --git a/vendor/golang.org/x/sys/unix/zptrace_armnn_linux.go b/vendor/golang.org/x/sys/unix/zptrace_armnn_linux.go index bd001a6e1c..97f20ca282 100644 --- a/vendor/golang.org/x/sys/unix/zptrace_armnn_linux.go +++ b/vendor/golang.org/x/sys/unix/zptrace_armnn_linux.go @@ -15,12 +15,12 @@ type PtraceRegsArm struct { // PtraceGetRegsArm fetches the registers used by arm binaries. func PtraceGetRegsArm(pid int, regsout *PtraceRegsArm) error { - return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) + return ptracePtr(PTRACE_GETREGS, pid, 0, unsafe.Pointer(regsout)) } // PtraceSetRegsArm sets the registers used by arm binaries. func PtraceSetRegsArm(pid int, regs *PtraceRegsArm) error { - return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) + return ptracePtr(PTRACE_SETREGS, pid, 0, unsafe.Pointer(regs)) } // PtraceRegsArm64 is the registers used by arm64 binaries. @@ -33,10 +33,10 @@ type PtraceRegsArm64 struct { // PtraceGetRegsArm64 fetches the registers used by arm64 binaries. func PtraceGetRegsArm64(pid int, regsout *PtraceRegsArm64) error { - return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) + return ptracePtr(PTRACE_GETREGS, pid, 0, unsafe.Pointer(regsout)) } // PtraceSetRegsArm64 sets the registers used by arm64 binaries. func PtraceSetRegsArm64(pid int, regs *PtraceRegsArm64) error { - return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) + return ptracePtr(PTRACE_SETREGS, pid, 0, unsafe.Pointer(regs)) } diff --git a/vendor/golang.org/x/sys/unix/zptrace_linux_arm64.go b/vendor/golang.org/x/sys/unix/zptrace_linux_arm64.go index 6cb6d688aa..834d2856dd 100644 --- a/vendor/golang.org/x/sys/unix/zptrace_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zptrace_linux_arm64.go @@ -7,11 +7,11 @@ import "unsafe" // PtraceGetRegSetArm64 fetches the registers used by arm64 binaries. func PtraceGetRegSetArm64(pid, addr int, regsout *PtraceRegsArm64) error { iovec := Iovec{(*byte)(unsafe.Pointer(regsout)), uint64(unsafe.Sizeof(*regsout))} - return ptrace(PTRACE_GETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec))) + return ptracePtr(PTRACE_GETREGSET, pid, uintptr(addr), unsafe.Pointer(&iovec)) } // PtraceSetRegSetArm64 sets the registers used by arm64 binaries. func PtraceSetRegSetArm64(pid, addr int, regs *PtraceRegsArm64) error { iovec := Iovec{(*byte)(unsafe.Pointer(regs)), uint64(unsafe.Sizeof(*regs))} - return ptrace(PTRACE_SETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec))) + return ptracePtr(PTRACE_SETREGSET, pid, uintptr(addr), unsafe.Pointer(&iovec)) } diff --git a/vendor/golang.org/x/sys/unix/zptrace_mipsnn_linux.go b/vendor/golang.org/x/sys/unix/zptrace_mipsnn_linux.go index c34d0639be..0b5f794305 100644 --- a/vendor/golang.org/x/sys/unix/zptrace_mipsnn_linux.go +++ b/vendor/golang.org/x/sys/unix/zptrace_mipsnn_linux.go @@ -21,12 +21,12 @@ type PtraceRegsMips struct { // PtraceGetRegsMips fetches the registers used by mips binaries. func PtraceGetRegsMips(pid int, regsout *PtraceRegsMips) error { - return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) + return ptracePtr(PTRACE_GETREGS, pid, 0, unsafe.Pointer(regsout)) } // PtraceSetRegsMips sets the registers used by mips binaries. func PtraceSetRegsMips(pid int, regs *PtraceRegsMips) error { - return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) + return ptracePtr(PTRACE_SETREGS, pid, 0, unsafe.Pointer(regs)) } // PtraceRegsMips64 is the registers used by mips64 binaries. @@ -42,10 +42,10 @@ type PtraceRegsMips64 struct { // PtraceGetRegsMips64 fetches the registers used by mips64 binaries. func PtraceGetRegsMips64(pid int, regsout *PtraceRegsMips64) error { - return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) + return ptracePtr(PTRACE_GETREGS, pid, 0, unsafe.Pointer(regsout)) } // PtraceSetRegsMips64 sets the registers used by mips64 binaries. func PtraceSetRegsMips64(pid int, regs *PtraceRegsMips64) error { - return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) + return ptracePtr(PTRACE_SETREGS, pid, 0, unsafe.Pointer(regs)) } diff --git a/vendor/golang.org/x/sys/unix/zptrace_mipsnnle_linux.go b/vendor/golang.org/x/sys/unix/zptrace_mipsnnle_linux.go index 3ccf0c0c4a..2807f7e646 100644 --- a/vendor/golang.org/x/sys/unix/zptrace_mipsnnle_linux.go +++ b/vendor/golang.org/x/sys/unix/zptrace_mipsnnle_linux.go @@ -21,12 +21,12 @@ type PtraceRegsMipsle struct { // PtraceGetRegsMipsle fetches the registers used by mipsle binaries. func PtraceGetRegsMipsle(pid int, regsout *PtraceRegsMipsle) error { - return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) + return ptracePtr(PTRACE_GETREGS, pid, 0, unsafe.Pointer(regsout)) } // PtraceSetRegsMipsle sets the registers used by mipsle binaries. func PtraceSetRegsMipsle(pid int, regs *PtraceRegsMipsle) error { - return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) + return ptracePtr(PTRACE_SETREGS, pid, 0, unsafe.Pointer(regs)) } // PtraceRegsMips64le is the registers used by mips64le binaries. @@ -42,10 +42,10 @@ type PtraceRegsMips64le struct { // PtraceGetRegsMips64le fetches the registers used by mips64le binaries. func PtraceGetRegsMips64le(pid int, regsout *PtraceRegsMips64le) error { - return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) + return ptracePtr(PTRACE_GETREGS, pid, 0, unsafe.Pointer(regsout)) } // PtraceSetRegsMips64le sets the registers used by mips64le binaries. func PtraceSetRegsMips64le(pid int, regs *PtraceRegsMips64le) error { - return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) + return ptracePtr(PTRACE_SETREGS, pid, 0, unsafe.Pointer(regs)) } diff --git a/vendor/golang.org/x/sys/unix/zptrace_x86_linux.go b/vendor/golang.org/x/sys/unix/zptrace_x86_linux.go index 7d65857004..281ea64e34 100644 --- a/vendor/golang.org/x/sys/unix/zptrace_x86_linux.go +++ b/vendor/golang.org/x/sys/unix/zptrace_x86_linux.go @@ -31,12 +31,12 @@ type PtraceRegs386 struct { // PtraceGetRegs386 fetches the registers used by 386 binaries. func PtraceGetRegs386(pid int, regsout *PtraceRegs386) error { - return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) + return ptracePtr(PTRACE_GETREGS, pid, 0, unsafe.Pointer(regsout)) } // PtraceSetRegs386 sets the registers used by 386 binaries. func PtraceSetRegs386(pid int, regs *PtraceRegs386) error { - return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) + return ptracePtr(PTRACE_SETREGS, pid, 0, unsafe.Pointer(regs)) } // PtraceRegsAmd64 is the registers used by amd64 binaries. @@ -72,10 +72,10 @@ type PtraceRegsAmd64 struct { // PtraceGetRegsAmd64 fetches the registers used by amd64 binaries. func PtraceGetRegsAmd64(pid int, regsout *PtraceRegsAmd64) error { - return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) + return ptracePtr(PTRACE_GETREGS, pid, 0, unsafe.Pointer(regsout)) } // PtraceSetRegsAmd64 sets the registers used by amd64 binaries. func PtraceSetRegsAmd64(pid int, regs *PtraceRegsAmd64) error { - return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) + return ptracePtr(PTRACE_SETREGS, pid, 0, unsafe.Pointer(regs)) } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go index 870215d2c4..ef9dcd1bef 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go @@ -223,6 +223,16 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + r0, er := C.ioctl(C.int(fd), C.int(req), C.uintptr_t(uintptr(arg))) + if r0 == -1 && er != nil { + err = er + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func FcntlInt(fd uintptr, cmd int, arg int) (r int, err error) { r0, er := C.fcntl(C.uintptr_t(fd), C.int(cmd), C.uintptr_t(arg)) r = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go index a89b0bfa53..f86a945923 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go @@ -103,6 +103,16 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, e1 := callioctl_ptr(fd, int(req), arg) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func FcntlInt(fd uintptr, cmd int, arg int) (r int, err error) { r0, e1 := callfcntl(fd, cmd, uintptr(arg)) r = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go index 2caa5adf95..d32a84cae2 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go @@ -423,6 +423,13 @@ func callioctl(fd int, req int, arg uintptr) (r1 uintptr, e1 Errno) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func callioctl_ptr(fd int, req int, arg unsafe.Pointer) (r1 uintptr, e1 Errno) { + r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_ioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func callfcntl(fd uintptr, cmd int, arg uintptr) (r1 uintptr, e1 Errno) { r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fcntl)), 3, fd, uintptr(cmd), arg, 0, 0, 0) return diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go index 944a714b1a..d7d8baf819 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go @@ -191,6 +191,14 @@ func callioctl(fd int, req int, arg uintptr) (r1 uintptr, e1 Errno) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func callioctl_ptr(fd int, req int, arg unsafe.Pointer) (r1 uintptr, e1 Errno) { + r1 = uintptr(C.ioctl(C.int(fd), C.int(req), C.uintptr_t(uintptr(arg)))) + e1 = syscall.GetErrno() + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func callfcntl(fd uintptr, cmd int, arg uintptr) (r1 uintptr, e1 Errno) { r1 = uintptr(C.fcntl(C.uintptr_t(fd), C.int(cmd), C.uintptr_t(arg))) e1 = syscall.GetErrno() diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go deleted file mode 100644 index a06eb09324..0000000000 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go +++ /dev/null @@ -1,40 +0,0 @@ -// go run mksyscall.go -tags darwin,amd64,go1.13 syscall_darwin.1_13.go -// Code generated by the command above; see README.md. DO NOT EDIT. - -//go:build darwin && amd64 && go1.13 -// +build darwin,amd64,go1.13 - -package unix - -import ( - "syscall" - "unsafe" -) - -var _ syscall.Errno - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func closedir(dir uintptr) (err error) { - _, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_closedir_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) { - r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result))) - res = Errno(r0) - return -} - -var libc_readdir_r_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib" diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s deleted file mode 100644 index f5bb40eda9..0000000000 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s +++ /dev/null @@ -1,25 +0,0 @@ -// go run mkasm.go darwin amd64 -// Code generated by the command above; DO NOT EDIT. - -//go:build go1.13 -// +build go1.13 - -#include "textflag.h" - -TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_fdopendir(SB) - -GLOBL ·libc_fdopendir_trampoline_addr(SB), RODATA, $8 -DATA ·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB) - -TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_closedir(SB) - -GLOBL ·libc_closedir_trampoline_addr(SB), RODATA, $8 -DATA ·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB) - -TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_readdir_r(SB) - -GLOBL ·libc_readdir_r_trampoline_addr(SB), RODATA, $8 -DATA ·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index 467deed763..a29ffdd566 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -1,8 +1,8 @@ -// go run mksyscall.go -tags darwin,amd64,go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go +// go run mksyscall.go -tags darwin,amd64 syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go // Code generated by the command above; see README.md. DO NOT EDIT. -//go:build darwin && amd64 && go1.12 -// +build darwin,amd64,go1.12 +//go:build darwin && amd64 +// +build darwin,amd64 package unix @@ -463,6 +463,32 @@ var libc_munlockall_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func closedir(dir uintptr) (err error) { + _, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_closedir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) { + r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result))) + res = Errno(r0) + return +} + +var libc_readdir_r_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe(p *[2]int32) (err error) { _, _, e1 := syscall_rawSyscall(libc_pipe_trampoline_addr, uintptr(unsafe.Pointer(p)), 0, 0) if e1 != 0 { @@ -699,6 +725,14 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + var libc_ioctl_trampoline_addr uintptr //go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib" @@ -2476,6 +2510,14 @@ func ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) { return } +func ptrace1Ptr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) { + _, _, e1 := syscall_syscall6(libc_ptrace_trampoline_addr, uintptr(request), uintptr(pid), addr, uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + var libc_ptrace_trampoline_addr uintptr //go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib" diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s index b41467a0e5..95fe4c0eb9 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s @@ -1,11 +1,14 @@ // go run mkasm.go darwin amd64 // Code generated by the command above; DO NOT EDIT. -//go:build go1.12 -// +build go1.12 - #include "textflag.h" +TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fdopendir(SB) + +GLOBL ·libc_fdopendir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB) + TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgroups(SB) @@ -174,6 +177,18 @@ TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8 DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB) +TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_closedir(SB) + +GLOBL ·libc_closedir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB) + +TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_readdir_r(SB) + +GLOBL ·libc_readdir_r_trampoline_addr(SB), RODATA, $8 +DATA ·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB) + TEXT libc_pipe_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pipe(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go deleted file mode 100644 index cec595d553..0000000000 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go +++ /dev/null @@ -1,40 +0,0 @@ -// go run mksyscall.go -tags darwin,arm64,go1.13 syscall_darwin.1_13.go -// Code generated by the command above; see README.md. DO NOT EDIT. - -//go:build darwin && arm64 && go1.13 -// +build darwin,arm64,go1.13 - -package unix - -import ( - "syscall" - "unsafe" -) - -var _ syscall.Errno - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func closedir(dir uintptr) (err error) { - _, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_closedir_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) { - r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result))) - res = Errno(r0) - return -} - -var libc_readdir_r_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib" diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s deleted file mode 100644 index 0c3f76bc20..0000000000 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s +++ /dev/null @@ -1,25 +0,0 @@ -// go run mkasm.go darwin arm64 -// Code generated by the command above; DO NOT EDIT. - -//go:build go1.13 -// +build go1.13 - -#include "textflag.h" - -TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_fdopendir(SB) - -GLOBL ·libc_fdopendir_trampoline_addr(SB), RODATA, $8 -DATA ·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB) - -TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_closedir(SB) - -GLOBL ·libc_closedir_trampoline_addr(SB), RODATA, $8 -DATA ·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB) - -TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_readdir_r(SB) - -GLOBL ·libc_readdir_r_trampoline_addr(SB), RODATA, $8 -DATA ·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go index 35938d34ff..2fd4590bb7 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go @@ -1,8 +1,8 @@ -// go run mksyscall.go -tags darwin,arm64,go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_arm64.go +// go run mksyscall.go -tags darwin,arm64 syscall_bsd.go syscall_darwin.go syscall_darwin_arm64.go // Code generated by the command above; see README.md. DO NOT EDIT. -//go:build darwin && arm64 && go1.12 -// +build darwin,arm64,go1.12 +//go:build darwin && arm64 +// +build darwin,arm64 package unix @@ -463,6 +463,32 @@ var libc_munlockall_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func closedir(dir uintptr) (err error) { + _, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_closedir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) { + r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result))) + res = Errno(r0) + return +} + +var libc_readdir_r_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe(p *[2]int32) (err error) { _, _, e1 := syscall_rawSyscall(libc_pipe_trampoline_addr, uintptr(unsafe.Pointer(p)), 0, 0) if e1 != 0 { @@ -699,6 +725,14 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + var libc_ioctl_trampoline_addr uintptr //go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib" @@ -2476,6 +2510,14 @@ func ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) { return } +func ptrace1Ptr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) { + _, _, e1 := syscall_syscall6(libc_ptrace_trampoline_addr, uintptr(request), uintptr(pid), addr, uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + var libc_ptrace_trampoline_addr uintptr //go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib" diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s index e1f9204a20..efa5b4c987 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s @@ -1,11 +1,14 @@ // go run mkasm.go darwin arm64 // Code generated by the command above; DO NOT EDIT. -//go:build go1.12 -// +build go1.12 - #include "textflag.h" +TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fdopendir(SB) + +GLOBL ·libc_fdopendir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB) + TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgroups(SB) @@ -174,6 +177,18 @@ TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8 DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB) +TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_closedir(SB) + +GLOBL ·libc_closedir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB) + +TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_readdir_r(SB) + +GLOBL ·libc_readdir_r_trampoline_addr(SB), RODATA, $8 +DATA ·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB) + TEXT libc_pipe_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pipe(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go index 1b6eedfa61..3b85134707 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go @@ -436,6 +436,16 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { var _p0 unsafe.Pointer if len(mib) > 0 { @@ -552,6 +562,16 @@ func Chroot(path string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := Syscall(SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go index 039c4aa06c..1129065624 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go @@ -388,6 +388,16 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { var _p0 unsafe.Pointer if len(mib) > 0 { @@ -414,6 +424,16 @@ func ptrace(request int, pid int, addr uintptr, data int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ptracePtr(request int, pid int, addr unsafe.Pointer, data int) (err error) { + _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -544,6 +564,16 @@ func Chroot(path string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := Syscall(SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go index 0535d3cfdf..55f5abfe59 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go @@ -388,6 +388,16 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { var _p0 unsafe.Pointer if len(mib) > 0 { @@ -414,6 +424,16 @@ func ptrace(request int, pid int, addr uintptr, data int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ptracePtr(request int, pid int, addr unsafe.Pointer, data int) (err error) { + _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -544,6 +564,16 @@ func Chroot(path string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := Syscall(SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go index 1018b52217..d39651c2b5 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go @@ -388,6 +388,16 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { var _p0 unsafe.Pointer if len(mib) > 0 { @@ -414,6 +424,16 @@ func ptrace(request int, pid int, addr uintptr, data int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ptracePtr(request int, pid int, addr unsafe.Pointer, data int) (err error) { + _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -544,6 +564,16 @@ func Chroot(path string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := Syscall(SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go index 3802f4b379..ddb7408680 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go @@ -388,6 +388,16 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { var _p0 unsafe.Pointer if len(mib) > 0 { @@ -414,6 +424,16 @@ func ptrace(request int, pid int, addr uintptr, data int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ptracePtr(request int, pid int, addr unsafe.Pointer, data int) (err error) { + _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -544,6 +564,16 @@ func Chroot(path string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := Syscall(SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go index 8a2db7da9f..09a53a616c 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go @@ -388,6 +388,16 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { var _p0 unsafe.Pointer if len(mib) > 0 { @@ -414,6 +424,16 @@ func ptrace(request int, pid int, addr uintptr, data int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ptracePtr(request int, pid int, addr unsafe.Pointer, data int) (err error) { + _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -544,6 +564,16 @@ func Chroot(path string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := Syscall(SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go index af5cb064ec..b57c7050d7 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go @@ -15,25 +15,19 @@ import ( //go:cgo_import_dynamic libc_writev writev "libc.so" //go:cgo_import_dynamic libc_pwritev pwritev "libc.so" //go:cgo_import_dynamic libc_accept4 accept4 "libsocket.so" -//go:cgo_import_dynamic libc_putmsg putmsg "libc.so" -//go:cgo_import_dynamic libc_getmsg getmsg "libc.so" //go:linkname procreadv libc_readv //go:linkname procpreadv libc_preadv //go:linkname procwritev libc_writev //go:linkname procpwritev libc_pwritev //go:linkname procaccept4 libc_accept4 -//go:linkname procputmsg libc_putmsg -//go:linkname procgetmsg libc_getmsg var ( procreadv, procpreadv, procwritev, procpwritev, - procaccept4, - procputmsg, - procgetmsg syscallFunc + procaccept4 syscallFunc ) // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -106,23 +100,3 @@ func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, } return } - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procputmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(flags), 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(unsafe.Pointer(flags)), 0, 0) - if e1 != 0 { - err = e1 - } - return -} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index bc4a275311..430cb24de7 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -379,6 +379,16 @@ func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) { + _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(arg) @@ -537,6 +547,17 @@ func Chroot(path string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockAdjtime(clockid int32, buf *Timex) (state int, err error) { + r0, _, e1 := Syscall(SYS_CLOCK_ADJTIME, uintptr(clockid), uintptr(unsafe.Pointer(buf)), 0) + state = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ClockGetres(clockid int32, res *Timespec) (err error) { _, _, e1 := Syscall(SYS_CLOCK_GETRES, uintptr(clockid), uintptr(unsafe.Pointer(res)), 0) if e1 != 0 { @@ -2151,3 +2172,13 @@ func setitimer(which int, newValue *Itimerval, oldValue *Itimerval) (err error) } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func rtSigprocmask(how int, set *Sigset_t, oldset *Sigset_t, sigsetsize uintptr) (err error) { + _, _, e1 := RawSyscall6(SYS_RT_SIGPROCMASK, uintptr(how), uintptr(unsafe.Pointer(set)), uintptr(unsafe.Pointer(oldset)), uintptr(sigsetsize), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go index 4af561a48d..8e1d9c8f66 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go @@ -405,6 +405,16 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { var _p0 unsafe.Pointer if len(mib) > 0 { @@ -521,6 +531,16 @@ func Chroot(path string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := Syscall(SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go index 3b90e9448a..21c6950400 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go @@ -405,6 +405,16 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { var _p0 unsafe.Pointer if len(mib) > 0 { @@ -521,6 +531,16 @@ func Chroot(path string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := Syscall(SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go index 890f4ccd13..298168f90a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go @@ -405,6 +405,16 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { var _p0 unsafe.Pointer if len(mib) > 0 { @@ -521,6 +531,16 @@ func Chroot(path string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := Syscall(SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go index c79f071fc6..68b8bd492f 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go @@ -405,6 +405,16 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { var _p0 unsafe.Pointer if len(mib) > 0 { @@ -521,6 +531,16 @@ func Chroot(path string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := Syscall(SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go index 2925fe0a7b..0b0f910e1a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go @@ -527,6 +527,14 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + var libc_ioctl_trampoline_addr uintptr //go:cgo_import_dynamic libc_ioctl ioctl "libc.so" @@ -696,6 +704,20 @@ var libc_chroot_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := syscall_syscall(libc_clock_gettime_trampoline_addr, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_clock_gettime_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s index 75eb2f5f3f..087444250c 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s @@ -5,792 +5,665 @@ TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgroups(SB) - GLOBL ·libc_getgroups_trampoline_addr(SB), RODATA, $4 DATA ·libc_getgroups_trampoline_addr(SB)/4, $libc_getgroups_trampoline<>(SB) TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setgroups(SB) - GLOBL ·libc_setgroups_trampoline_addr(SB), RODATA, $4 DATA ·libc_setgroups_trampoline_addr(SB)/4, $libc_setgroups_trampoline<>(SB) TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_wait4(SB) - GLOBL ·libc_wait4_trampoline_addr(SB), RODATA, $4 DATA ·libc_wait4_trampoline_addr(SB)/4, $libc_wait4_trampoline<>(SB) TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_accept(SB) - GLOBL ·libc_accept_trampoline_addr(SB), RODATA, $4 DATA ·libc_accept_trampoline_addr(SB)/4, $libc_accept_trampoline<>(SB) TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_bind(SB) - GLOBL ·libc_bind_trampoline_addr(SB), RODATA, $4 DATA ·libc_bind_trampoline_addr(SB)/4, $libc_bind_trampoline<>(SB) TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_connect(SB) - GLOBL ·libc_connect_trampoline_addr(SB), RODATA, $4 DATA ·libc_connect_trampoline_addr(SB)/4, $libc_connect_trampoline<>(SB) TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_socket(SB) - GLOBL ·libc_socket_trampoline_addr(SB), RODATA, $4 DATA ·libc_socket_trampoline_addr(SB)/4, $libc_socket_trampoline<>(SB) TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsockopt(SB) - GLOBL ·libc_getsockopt_trampoline_addr(SB), RODATA, $4 DATA ·libc_getsockopt_trampoline_addr(SB)/4, $libc_getsockopt_trampoline<>(SB) TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setsockopt(SB) - GLOBL ·libc_setsockopt_trampoline_addr(SB), RODATA, $4 DATA ·libc_setsockopt_trampoline_addr(SB)/4, $libc_setsockopt_trampoline<>(SB) TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpeername(SB) - GLOBL ·libc_getpeername_trampoline_addr(SB), RODATA, $4 DATA ·libc_getpeername_trampoline_addr(SB)/4, $libc_getpeername_trampoline<>(SB) TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsockname(SB) - GLOBL ·libc_getsockname_trampoline_addr(SB), RODATA, $4 DATA ·libc_getsockname_trampoline_addr(SB)/4, $libc_getsockname_trampoline<>(SB) TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_shutdown(SB) - GLOBL ·libc_shutdown_trampoline_addr(SB), RODATA, $4 DATA ·libc_shutdown_trampoline_addr(SB)/4, $libc_shutdown_trampoline<>(SB) TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_socketpair(SB) - GLOBL ·libc_socketpair_trampoline_addr(SB), RODATA, $4 DATA ·libc_socketpair_trampoline_addr(SB)/4, $libc_socketpair_trampoline<>(SB) TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_recvfrom(SB) - GLOBL ·libc_recvfrom_trampoline_addr(SB), RODATA, $4 DATA ·libc_recvfrom_trampoline_addr(SB)/4, $libc_recvfrom_trampoline<>(SB) TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendto(SB) - GLOBL ·libc_sendto_trampoline_addr(SB), RODATA, $4 DATA ·libc_sendto_trampoline_addr(SB)/4, $libc_sendto_trampoline<>(SB) TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_recvmsg(SB) - GLOBL ·libc_recvmsg_trampoline_addr(SB), RODATA, $4 DATA ·libc_recvmsg_trampoline_addr(SB)/4, $libc_recvmsg_trampoline<>(SB) TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendmsg(SB) - GLOBL ·libc_sendmsg_trampoline_addr(SB), RODATA, $4 DATA ·libc_sendmsg_trampoline_addr(SB)/4, $libc_sendmsg_trampoline<>(SB) TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kevent(SB) - GLOBL ·libc_kevent_trampoline_addr(SB), RODATA, $4 DATA ·libc_kevent_trampoline_addr(SB)/4, $libc_kevent_trampoline<>(SB) TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_utimes(SB) - GLOBL ·libc_utimes_trampoline_addr(SB), RODATA, $4 DATA ·libc_utimes_trampoline_addr(SB)/4, $libc_utimes_trampoline<>(SB) TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_futimes(SB) - GLOBL ·libc_futimes_trampoline_addr(SB), RODATA, $4 DATA ·libc_futimes_trampoline_addr(SB)/4, $libc_futimes_trampoline<>(SB) TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_poll(SB) - GLOBL ·libc_poll_trampoline_addr(SB), RODATA, $4 DATA ·libc_poll_trampoline_addr(SB)/4, $libc_poll_trampoline<>(SB) TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_madvise(SB) - GLOBL ·libc_madvise_trampoline_addr(SB), RODATA, $4 DATA ·libc_madvise_trampoline_addr(SB)/4, $libc_madvise_trampoline<>(SB) TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mlock(SB) - GLOBL ·libc_mlock_trampoline_addr(SB), RODATA, $4 DATA ·libc_mlock_trampoline_addr(SB)/4, $libc_mlock_trampoline<>(SB) TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mlockall(SB) - GLOBL ·libc_mlockall_trampoline_addr(SB), RODATA, $4 DATA ·libc_mlockall_trampoline_addr(SB)/4, $libc_mlockall_trampoline<>(SB) TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mprotect(SB) - GLOBL ·libc_mprotect_trampoline_addr(SB), RODATA, $4 DATA ·libc_mprotect_trampoline_addr(SB)/4, $libc_mprotect_trampoline<>(SB) TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_msync(SB) - GLOBL ·libc_msync_trampoline_addr(SB), RODATA, $4 DATA ·libc_msync_trampoline_addr(SB)/4, $libc_msync_trampoline<>(SB) TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munlock(SB) - GLOBL ·libc_munlock_trampoline_addr(SB), RODATA, $4 DATA ·libc_munlock_trampoline_addr(SB)/4, $libc_munlock_trampoline<>(SB) TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munlockall(SB) - GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $4 DATA ·libc_munlockall_trampoline_addr(SB)/4, $libc_munlockall_trampoline<>(SB) TEXT libc_pipe2_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pipe2(SB) - GLOBL ·libc_pipe2_trampoline_addr(SB), RODATA, $4 DATA ·libc_pipe2_trampoline_addr(SB)/4, $libc_pipe2_trampoline<>(SB) TEXT libc_getdents_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getdents(SB) - GLOBL ·libc_getdents_trampoline_addr(SB), RODATA, $4 DATA ·libc_getdents_trampoline_addr(SB)/4, $libc_getdents_trampoline<>(SB) TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getcwd(SB) - GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $4 DATA ·libc_getcwd_trampoline_addr(SB)/4, $libc_getcwd_trampoline<>(SB) TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ioctl(SB) - GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $4 DATA ·libc_ioctl_trampoline_addr(SB)/4, $libc_ioctl_trampoline<>(SB) TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sysctl(SB) - GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $4 DATA ·libc_sysctl_trampoline_addr(SB)/4, $libc_sysctl_trampoline<>(SB) TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ppoll(SB) - GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $4 DATA ·libc_ppoll_trampoline_addr(SB)/4, $libc_ppoll_trampoline<>(SB) TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_access(SB) - GLOBL ·libc_access_trampoline_addr(SB), RODATA, $4 DATA ·libc_access_trampoline_addr(SB)/4, $libc_access_trampoline<>(SB) TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_adjtime(SB) - GLOBL ·libc_adjtime_trampoline_addr(SB), RODATA, $4 DATA ·libc_adjtime_trampoline_addr(SB)/4, $libc_adjtime_trampoline<>(SB) TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chdir(SB) - GLOBL ·libc_chdir_trampoline_addr(SB), RODATA, $4 DATA ·libc_chdir_trampoline_addr(SB)/4, $libc_chdir_trampoline<>(SB) TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chflags(SB) - GLOBL ·libc_chflags_trampoline_addr(SB), RODATA, $4 DATA ·libc_chflags_trampoline_addr(SB)/4, $libc_chflags_trampoline<>(SB) TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chmod(SB) - GLOBL ·libc_chmod_trampoline_addr(SB), RODATA, $4 DATA ·libc_chmod_trampoline_addr(SB)/4, $libc_chmod_trampoline<>(SB) TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chown(SB) - GLOBL ·libc_chown_trampoline_addr(SB), RODATA, $4 DATA ·libc_chown_trampoline_addr(SB)/4, $libc_chown_trampoline<>(SB) TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chroot(SB) - GLOBL ·libc_chroot_trampoline_addr(SB), RODATA, $4 DATA ·libc_chroot_trampoline_addr(SB)/4, $libc_chroot_trampoline<>(SB) +TEXT libc_clock_gettime_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_clock_gettime(SB) +GLOBL ·libc_clock_gettime_trampoline_addr(SB), RODATA, $4 +DATA ·libc_clock_gettime_trampoline_addr(SB)/4, $libc_clock_gettime_trampoline<>(SB) + TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_close(SB) - GLOBL ·libc_close_trampoline_addr(SB), RODATA, $4 DATA ·libc_close_trampoline_addr(SB)/4, $libc_close_trampoline<>(SB) TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup(SB) - GLOBL ·libc_dup_trampoline_addr(SB), RODATA, $4 DATA ·libc_dup_trampoline_addr(SB)/4, $libc_dup_trampoline<>(SB) TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup2(SB) - GLOBL ·libc_dup2_trampoline_addr(SB), RODATA, $4 DATA ·libc_dup2_trampoline_addr(SB)/4, $libc_dup2_trampoline<>(SB) TEXT libc_dup3_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup3(SB) - GLOBL ·libc_dup3_trampoline_addr(SB), RODATA, $4 DATA ·libc_dup3_trampoline_addr(SB)/4, $libc_dup3_trampoline<>(SB) TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_exit(SB) - GLOBL ·libc_exit_trampoline_addr(SB), RODATA, $4 DATA ·libc_exit_trampoline_addr(SB)/4, $libc_exit_trampoline<>(SB) TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_faccessat(SB) - GLOBL ·libc_faccessat_trampoline_addr(SB), RODATA, $4 DATA ·libc_faccessat_trampoline_addr(SB)/4, $libc_faccessat_trampoline<>(SB) TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchdir(SB) - GLOBL ·libc_fchdir_trampoline_addr(SB), RODATA, $4 DATA ·libc_fchdir_trampoline_addr(SB)/4, $libc_fchdir_trampoline<>(SB) TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchflags(SB) - GLOBL ·libc_fchflags_trampoline_addr(SB), RODATA, $4 DATA ·libc_fchflags_trampoline_addr(SB)/4, $libc_fchflags_trampoline<>(SB) TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchmod(SB) - GLOBL ·libc_fchmod_trampoline_addr(SB), RODATA, $4 DATA ·libc_fchmod_trampoline_addr(SB)/4, $libc_fchmod_trampoline<>(SB) TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchmodat(SB) - GLOBL ·libc_fchmodat_trampoline_addr(SB), RODATA, $4 DATA ·libc_fchmodat_trampoline_addr(SB)/4, $libc_fchmodat_trampoline<>(SB) TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchown(SB) - GLOBL ·libc_fchown_trampoline_addr(SB), RODATA, $4 DATA ·libc_fchown_trampoline_addr(SB)/4, $libc_fchown_trampoline<>(SB) TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchownat(SB) - GLOBL ·libc_fchownat_trampoline_addr(SB), RODATA, $4 DATA ·libc_fchownat_trampoline_addr(SB)/4, $libc_fchownat_trampoline<>(SB) TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_flock(SB) - GLOBL ·libc_flock_trampoline_addr(SB), RODATA, $4 DATA ·libc_flock_trampoline_addr(SB)/4, $libc_flock_trampoline<>(SB) TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fpathconf(SB) - GLOBL ·libc_fpathconf_trampoline_addr(SB), RODATA, $4 DATA ·libc_fpathconf_trampoline_addr(SB)/4, $libc_fpathconf_trampoline<>(SB) TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstat(SB) - GLOBL ·libc_fstat_trampoline_addr(SB), RODATA, $4 DATA ·libc_fstat_trampoline_addr(SB)/4, $libc_fstat_trampoline<>(SB) TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstatat(SB) - GLOBL ·libc_fstatat_trampoline_addr(SB), RODATA, $4 DATA ·libc_fstatat_trampoline_addr(SB)/4, $libc_fstatat_trampoline<>(SB) TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstatfs(SB) - GLOBL ·libc_fstatfs_trampoline_addr(SB), RODATA, $4 DATA ·libc_fstatfs_trampoline_addr(SB)/4, $libc_fstatfs_trampoline<>(SB) TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fsync(SB) - GLOBL ·libc_fsync_trampoline_addr(SB), RODATA, $4 DATA ·libc_fsync_trampoline_addr(SB)/4, $libc_fsync_trampoline<>(SB) TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ftruncate(SB) - GLOBL ·libc_ftruncate_trampoline_addr(SB), RODATA, $4 DATA ·libc_ftruncate_trampoline_addr(SB)/4, $libc_ftruncate_trampoline<>(SB) TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getegid(SB) - GLOBL ·libc_getegid_trampoline_addr(SB), RODATA, $4 DATA ·libc_getegid_trampoline_addr(SB)/4, $libc_getegid_trampoline<>(SB) TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_geteuid(SB) - GLOBL ·libc_geteuid_trampoline_addr(SB), RODATA, $4 DATA ·libc_geteuid_trampoline_addr(SB)/4, $libc_geteuid_trampoline<>(SB) TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgid(SB) - GLOBL ·libc_getgid_trampoline_addr(SB), RODATA, $4 DATA ·libc_getgid_trampoline_addr(SB)/4, $libc_getgid_trampoline<>(SB) TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpgid(SB) - GLOBL ·libc_getpgid_trampoline_addr(SB), RODATA, $4 DATA ·libc_getpgid_trampoline_addr(SB)/4, $libc_getpgid_trampoline<>(SB) TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpgrp(SB) - GLOBL ·libc_getpgrp_trampoline_addr(SB), RODATA, $4 DATA ·libc_getpgrp_trampoline_addr(SB)/4, $libc_getpgrp_trampoline<>(SB) TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpid(SB) - GLOBL ·libc_getpid_trampoline_addr(SB), RODATA, $4 DATA ·libc_getpid_trampoline_addr(SB)/4, $libc_getpid_trampoline<>(SB) TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getppid(SB) - GLOBL ·libc_getppid_trampoline_addr(SB), RODATA, $4 DATA ·libc_getppid_trampoline_addr(SB)/4, $libc_getppid_trampoline<>(SB) TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpriority(SB) - GLOBL ·libc_getpriority_trampoline_addr(SB), RODATA, $4 DATA ·libc_getpriority_trampoline_addr(SB)/4, $libc_getpriority_trampoline<>(SB) TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrlimit(SB) - GLOBL ·libc_getrlimit_trampoline_addr(SB), RODATA, $4 DATA ·libc_getrlimit_trampoline_addr(SB)/4, $libc_getrlimit_trampoline<>(SB) TEXT libc_getrtable_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrtable(SB) - GLOBL ·libc_getrtable_trampoline_addr(SB), RODATA, $4 DATA ·libc_getrtable_trampoline_addr(SB)/4, $libc_getrtable_trampoline<>(SB) TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrusage(SB) - GLOBL ·libc_getrusage_trampoline_addr(SB), RODATA, $4 DATA ·libc_getrusage_trampoline_addr(SB)/4, $libc_getrusage_trampoline<>(SB) TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsid(SB) - GLOBL ·libc_getsid_trampoline_addr(SB), RODATA, $4 DATA ·libc_getsid_trampoline_addr(SB)/4, $libc_getsid_trampoline<>(SB) TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_gettimeofday(SB) - GLOBL ·libc_gettimeofday_trampoline_addr(SB), RODATA, $4 DATA ·libc_gettimeofday_trampoline_addr(SB)/4, $libc_gettimeofday_trampoline<>(SB) TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getuid(SB) - GLOBL ·libc_getuid_trampoline_addr(SB), RODATA, $4 DATA ·libc_getuid_trampoline_addr(SB)/4, $libc_getuid_trampoline<>(SB) TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_issetugid(SB) - GLOBL ·libc_issetugid_trampoline_addr(SB), RODATA, $4 DATA ·libc_issetugid_trampoline_addr(SB)/4, $libc_issetugid_trampoline<>(SB) TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kill(SB) - GLOBL ·libc_kill_trampoline_addr(SB), RODATA, $4 DATA ·libc_kill_trampoline_addr(SB)/4, $libc_kill_trampoline<>(SB) TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kqueue(SB) - GLOBL ·libc_kqueue_trampoline_addr(SB), RODATA, $4 DATA ·libc_kqueue_trampoline_addr(SB)/4, $libc_kqueue_trampoline<>(SB) TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lchown(SB) - GLOBL ·libc_lchown_trampoline_addr(SB), RODATA, $4 DATA ·libc_lchown_trampoline_addr(SB)/4, $libc_lchown_trampoline<>(SB) TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_link(SB) - GLOBL ·libc_link_trampoline_addr(SB), RODATA, $4 DATA ·libc_link_trampoline_addr(SB)/4, $libc_link_trampoline<>(SB) TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_linkat(SB) - GLOBL ·libc_linkat_trampoline_addr(SB), RODATA, $4 DATA ·libc_linkat_trampoline_addr(SB)/4, $libc_linkat_trampoline<>(SB) TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_listen(SB) - GLOBL ·libc_listen_trampoline_addr(SB), RODATA, $4 DATA ·libc_listen_trampoline_addr(SB)/4, $libc_listen_trampoline<>(SB) TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lstat(SB) - GLOBL ·libc_lstat_trampoline_addr(SB), RODATA, $4 DATA ·libc_lstat_trampoline_addr(SB)/4, $libc_lstat_trampoline<>(SB) TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkdir(SB) - GLOBL ·libc_mkdir_trampoline_addr(SB), RODATA, $4 DATA ·libc_mkdir_trampoline_addr(SB)/4, $libc_mkdir_trampoline<>(SB) TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkdirat(SB) - GLOBL ·libc_mkdirat_trampoline_addr(SB), RODATA, $4 DATA ·libc_mkdirat_trampoline_addr(SB)/4, $libc_mkdirat_trampoline<>(SB) TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkfifo(SB) - GLOBL ·libc_mkfifo_trampoline_addr(SB), RODATA, $4 DATA ·libc_mkfifo_trampoline_addr(SB)/4, $libc_mkfifo_trampoline<>(SB) TEXT libc_mkfifoat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkfifoat(SB) - GLOBL ·libc_mkfifoat_trampoline_addr(SB), RODATA, $4 DATA ·libc_mkfifoat_trampoline_addr(SB)/4, $libc_mkfifoat_trampoline<>(SB) TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mknod(SB) - GLOBL ·libc_mknod_trampoline_addr(SB), RODATA, $4 DATA ·libc_mknod_trampoline_addr(SB)/4, $libc_mknod_trampoline<>(SB) TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mknodat(SB) - GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $4 DATA ·libc_mknodat_trampoline_addr(SB)/4, $libc_mknodat_trampoline<>(SB) TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) - GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $4 DATA ·libc_nanosleep_trampoline_addr(SB)/4, $libc_nanosleep_trampoline<>(SB) TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_open(SB) - GLOBL ·libc_open_trampoline_addr(SB), RODATA, $4 DATA ·libc_open_trampoline_addr(SB)/4, $libc_open_trampoline<>(SB) TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_openat(SB) - GLOBL ·libc_openat_trampoline_addr(SB), RODATA, $4 DATA ·libc_openat_trampoline_addr(SB)/4, $libc_openat_trampoline<>(SB) TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pathconf(SB) - GLOBL ·libc_pathconf_trampoline_addr(SB), RODATA, $4 DATA ·libc_pathconf_trampoline_addr(SB)/4, $libc_pathconf_trampoline<>(SB) TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pread(SB) - GLOBL ·libc_pread_trampoline_addr(SB), RODATA, $4 DATA ·libc_pread_trampoline_addr(SB)/4, $libc_pread_trampoline<>(SB) TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pwrite(SB) - GLOBL ·libc_pwrite_trampoline_addr(SB), RODATA, $4 DATA ·libc_pwrite_trampoline_addr(SB)/4, $libc_pwrite_trampoline<>(SB) TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_read(SB) - GLOBL ·libc_read_trampoline_addr(SB), RODATA, $4 DATA ·libc_read_trampoline_addr(SB)/4, $libc_read_trampoline<>(SB) TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_readlink(SB) - GLOBL ·libc_readlink_trampoline_addr(SB), RODATA, $4 DATA ·libc_readlink_trampoline_addr(SB)/4, $libc_readlink_trampoline<>(SB) TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_readlinkat(SB) - GLOBL ·libc_readlinkat_trampoline_addr(SB), RODATA, $4 DATA ·libc_readlinkat_trampoline_addr(SB)/4, $libc_readlinkat_trampoline<>(SB) TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_rename(SB) - GLOBL ·libc_rename_trampoline_addr(SB), RODATA, $4 DATA ·libc_rename_trampoline_addr(SB)/4, $libc_rename_trampoline<>(SB) TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_renameat(SB) - GLOBL ·libc_renameat_trampoline_addr(SB), RODATA, $4 DATA ·libc_renameat_trampoline_addr(SB)/4, $libc_renameat_trampoline<>(SB) TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_revoke(SB) - GLOBL ·libc_revoke_trampoline_addr(SB), RODATA, $4 DATA ·libc_revoke_trampoline_addr(SB)/4, $libc_revoke_trampoline<>(SB) TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_rmdir(SB) - GLOBL ·libc_rmdir_trampoline_addr(SB), RODATA, $4 DATA ·libc_rmdir_trampoline_addr(SB)/4, $libc_rmdir_trampoline<>(SB) TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lseek(SB) - GLOBL ·libc_lseek_trampoline_addr(SB), RODATA, $4 DATA ·libc_lseek_trampoline_addr(SB)/4, $libc_lseek_trampoline<>(SB) TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_select(SB) - GLOBL ·libc_select_trampoline_addr(SB), RODATA, $4 DATA ·libc_select_trampoline_addr(SB)/4, $libc_select_trampoline<>(SB) TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setegid(SB) - GLOBL ·libc_setegid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setegid_trampoline_addr(SB)/4, $libc_setegid_trampoline<>(SB) TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_seteuid(SB) - GLOBL ·libc_seteuid_trampoline_addr(SB), RODATA, $4 DATA ·libc_seteuid_trampoline_addr(SB)/4, $libc_seteuid_trampoline<>(SB) TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setgid(SB) - GLOBL ·libc_setgid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setgid_trampoline_addr(SB)/4, $libc_setgid_trampoline<>(SB) TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setlogin(SB) - GLOBL ·libc_setlogin_trampoline_addr(SB), RODATA, $4 DATA ·libc_setlogin_trampoline_addr(SB)/4, $libc_setlogin_trampoline<>(SB) TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setpgid(SB) - GLOBL ·libc_setpgid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setpgid_trampoline_addr(SB)/4, $libc_setpgid_trampoline<>(SB) TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setpriority(SB) - GLOBL ·libc_setpriority_trampoline_addr(SB), RODATA, $4 DATA ·libc_setpriority_trampoline_addr(SB)/4, $libc_setpriority_trampoline<>(SB) TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setregid(SB) - GLOBL ·libc_setregid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setregid_trampoline_addr(SB)/4, $libc_setregid_trampoline<>(SB) TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setreuid(SB) - GLOBL ·libc_setreuid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setreuid_trampoline_addr(SB)/4, $libc_setreuid_trampoline<>(SB) TEXT libc_setresgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setresgid(SB) - GLOBL ·libc_setresgid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setresgid_trampoline_addr(SB)/4, $libc_setresgid_trampoline<>(SB) TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setresuid(SB) - GLOBL ·libc_setresuid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setresuid_trampoline_addr(SB)/4, $libc_setresuid_trampoline<>(SB) TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setrlimit(SB) - GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $4 DATA ·libc_setrlimit_trampoline_addr(SB)/4, $libc_setrlimit_trampoline<>(SB) TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setrtable(SB) - GLOBL ·libc_setrtable_trampoline_addr(SB), RODATA, $4 DATA ·libc_setrtable_trampoline_addr(SB)/4, $libc_setrtable_trampoline<>(SB) TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setsid(SB) - GLOBL ·libc_setsid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setsid_trampoline_addr(SB)/4, $libc_setsid_trampoline<>(SB) TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_settimeofday(SB) - GLOBL ·libc_settimeofday_trampoline_addr(SB), RODATA, $4 DATA ·libc_settimeofday_trampoline_addr(SB)/4, $libc_settimeofday_trampoline<>(SB) TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setuid(SB) - GLOBL ·libc_setuid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setuid_trampoline_addr(SB)/4, $libc_setuid_trampoline<>(SB) TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_stat(SB) - GLOBL ·libc_stat_trampoline_addr(SB), RODATA, $4 DATA ·libc_stat_trampoline_addr(SB)/4, $libc_stat_trampoline<>(SB) TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_statfs(SB) - GLOBL ·libc_statfs_trampoline_addr(SB), RODATA, $4 DATA ·libc_statfs_trampoline_addr(SB)/4, $libc_statfs_trampoline<>(SB) TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_symlink(SB) - GLOBL ·libc_symlink_trampoline_addr(SB), RODATA, $4 DATA ·libc_symlink_trampoline_addr(SB)/4, $libc_symlink_trampoline<>(SB) TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_symlinkat(SB) - GLOBL ·libc_symlinkat_trampoline_addr(SB), RODATA, $4 DATA ·libc_symlinkat_trampoline_addr(SB)/4, $libc_symlinkat_trampoline<>(SB) TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sync(SB) - GLOBL ·libc_sync_trampoline_addr(SB), RODATA, $4 DATA ·libc_sync_trampoline_addr(SB)/4, $libc_sync_trampoline<>(SB) TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_truncate(SB) - GLOBL ·libc_truncate_trampoline_addr(SB), RODATA, $4 DATA ·libc_truncate_trampoline_addr(SB)/4, $libc_truncate_trampoline<>(SB) TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_umask(SB) - GLOBL ·libc_umask_trampoline_addr(SB), RODATA, $4 DATA ·libc_umask_trampoline_addr(SB)/4, $libc_umask_trampoline<>(SB) TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unlink(SB) - GLOBL ·libc_unlink_trampoline_addr(SB), RODATA, $4 DATA ·libc_unlink_trampoline_addr(SB)/4, $libc_unlink_trampoline<>(SB) TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unlinkat(SB) - GLOBL ·libc_unlinkat_trampoline_addr(SB), RODATA, $4 DATA ·libc_unlinkat_trampoline_addr(SB)/4, $libc_unlinkat_trampoline<>(SB) TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unmount(SB) - GLOBL ·libc_unmount_trampoline_addr(SB), RODATA, $4 DATA ·libc_unmount_trampoline_addr(SB)/4, $libc_unmount_trampoline<>(SB) TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_write(SB) - GLOBL ·libc_write_trampoline_addr(SB), RODATA, $4 DATA ·libc_write_trampoline_addr(SB)/4, $libc_write_trampoline<>(SB) TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mmap(SB) - GLOBL ·libc_mmap_trampoline_addr(SB), RODATA, $4 DATA ·libc_mmap_trampoline_addr(SB)/4, $libc_mmap_trampoline<>(SB) TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munmap(SB) - GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $4 DATA ·libc_munmap_trampoline_addr(SB)/4, $libc_munmap_trampoline<>(SB) TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_utimensat(SB) - GLOBL ·libc_utimensat_trampoline_addr(SB), RODATA, $4 DATA ·libc_utimensat_trampoline_addr(SB)/4, $libc_utimensat_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go index 98446d2b95..48ff5de75b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go @@ -527,6 +527,14 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + var libc_ioctl_trampoline_addr uintptr //go:cgo_import_dynamic libc_ioctl ioctl "libc.so" @@ -696,6 +704,20 @@ var libc_chroot_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := syscall_syscall(libc_clock_gettime_trampoline_addr, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_clock_gettime_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s index 243a6663ce..5782cd1084 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s @@ -5,792 +5,665 @@ TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgroups(SB) - GLOBL ·libc_getgroups_trampoline_addr(SB), RODATA, $8 DATA ·libc_getgroups_trampoline_addr(SB)/8, $libc_getgroups_trampoline<>(SB) TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setgroups(SB) - GLOBL ·libc_setgroups_trampoline_addr(SB), RODATA, $8 DATA ·libc_setgroups_trampoline_addr(SB)/8, $libc_setgroups_trampoline<>(SB) TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_wait4(SB) - GLOBL ·libc_wait4_trampoline_addr(SB), RODATA, $8 DATA ·libc_wait4_trampoline_addr(SB)/8, $libc_wait4_trampoline<>(SB) TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_accept(SB) - GLOBL ·libc_accept_trampoline_addr(SB), RODATA, $8 DATA ·libc_accept_trampoline_addr(SB)/8, $libc_accept_trampoline<>(SB) TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_bind(SB) - GLOBL ·libc_bind_trampoline_addr(SB), RODATA, $8 DATA ·libc_bind_trampoline_addr(SB)/8, $libc_bind_trampoline<>(SB) TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_connect(SB) - GLOBL ·libc_connect_trampoline_addr(SB), RODATA, $8 DATA ·libc_connect_trampoline_addr(SB)/8, $libc_connect_trampoline<>(SB) TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_socket(SB) - GLOBL ·libc_socket_trampoline_addr(SB), RODATA, $8 DATA ·libc_socket_trampoline_addr(SB)/8, $libc_socket_trampoline<>(SB) TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsockopt(SB) - GLOBL ·libc_getsockopt_trampoline_addr(SB), RODATA, $8 DATA ·libc_getsockopt_trampoline_addr(SB)/8, $libc_getsockopt_trampoline<>(SB) TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setsockopt(SB) - GLOBL ·libc_setsockopt_trampoline_addr(SB), RODATA, $8 DATA ·libc_setsockopt_trampoline_addr(SB)/8, $libc_setsockopt_trampoline<>(SB) TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpeername(SB) - GLOBL ·libc_getpeername_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpeername_trampoline_addr(SB)/8, $libc_getpeername_trampoline<>(SB) TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsockname(SB) - GLOBL ·libc_getsockname_trampoline_addr(SB), RODATA, $8 DATA ·libc_getsockname_trampoline_addr(SB)/8, $libc_getsockname_trampoline<>(SB) TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_shutdown(SB) - GLOBL ·libc_shutdown_trampoline_addr(SB), RODATA, $8 DATA ·libc_shutdown_trampoline_addr(SB)/8, $libc_shutdown_trampoline<>(SB) TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_socketpair(SB) - GLOBL ·libc_socketpair_trampoline_addr(SB), RODATA, $8 DATA ·libc_socketpair_trampoline_addr(SB)/8, $libc_socketpair_trampoline<>(SB) TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_recvfrom(SB) - GLOBL ·libc_recvfrom_trampoline_addr(SB), RODATA, $8 DATA ·libc_recvfrom_trampoline_addr(SB)/8, $libc_recvfrom_trampoline<>(SB) TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendto(SB) - GLOBL ·libc_sendto_trampoline_addr(SB), RODATA, $8 DATA ·libc_sendto_trampoline_addr(SB)/8, $libc_sendto_trampoline<>(SB) TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_recvmsg(SB) - GLOBL ·libc_recvmsg_trampoline_addr(SB), RODATA, $8 DATA ·libc_recvmsg_trampoline_addr(SB)/8, $libc_recvmsg_trampoline<>(SB) TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendmsg(SB) - GLOBL ·libc_sendmsg_trampoline_addr(SB), RODATA, $8 DATA ·libc_sendmsg_trampoline_addr(SB)/8, $libc_sendmsg_trampoline<>(SB) TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kevent(SB) - GLOBL ·libc_kevent_trampoline_addr(SB), RODATA, $8 DATA ·libc_kevent_trampoline_addr(SB)/8, $libc_kevent_trampoline<>(SB) TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_utimes(SB) - GLOBL ·libc_utimes_trampoline_addr(SB), RODATA, $8 DATA ·libc_utimes_trampoline_addr(SB)/8, $libc_utimes_trampoline<>(SB) TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_futimes(SB) - GLOBL ·libc_futimes_trampoline_addr(SB), RODATA, $8 DATA ·libc_futimes_trampoline_addr(SB)/8, $libc_futimes_trampoline<>(SB) TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_poll(SB) - GLOBL ·libc_poll_trampoline_addr(SB), RODATA, $8 DATA ·libc_poll_trampoline_addr(SB)/8, $libc_poll_trampoline<>(SB) TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_madvise(SB) - GLOBL ·libc_madvise_trampoline_addr(SB), RODATA, $8 DATA ·libc_madvise_trampoline_addr(SB)/8, $libc_madvise_trampoline<>(SB) TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mlock(SB) - GLOBL ·libc_mlock_trampoline_addr(SB), RODATA, $8 DATA ·libc_mlock_trampoline_addr(SB)/8, $libc_mlock_trampoline<>(SB) TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mlockall(SB) - GLOBL ·libc_mlockall_trampoline_addr(SB), RODATA, $8 DATA ·libc_mlockall_trampoline_addr(SB)/8, $libc_mlockall_trampoline<>(SB) TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mprotect(SB) - GLOBL ·libc_mprotect_trampoline_addr(SB), RODATA, $8 DATA ·libc_mprotect_trampoline_addr(SB)/8, $libc_mprotect_trampoline<>(SB) TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_msync(SB) - GLOBL ·libc_msync_trampoline_addr(SB), RODATA, $8 DATA ·libc_msync_trampoline_addr(SB)/8, $libc_msync_trampoline<>(SB) TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munlock(SB) - GLOBL ·libc_munlock_trampoline_addr(SB), RODATA, $8 DATA ·libc_munlock_trampoline_addr(SB)/8, $libc_munlock_trampoline<>(SB) TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munlockall(SB) - GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8 DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB) TEXT libc_pipe2_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pipe2(SB) - GLOBL ·libc_pipe2_trampoline_addr(SB), RODATA, $8 DATA ·libc_pipe2_trampoline_addr(SB)/8, $libc_pipe2_trampoline<>(SB) TEXT libc_getdents_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getdents(SB) - GLOBL ·libc_getdents_trampoline_addr(SB), RODATA, $8 DATA ·libc_getdents_trampoline_addr(SB)/8, $libc_getdents_trampoline<>(SB) TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getcwd(SB) - GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $8 DATA ·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB) TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ioctl(SB) - GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB) TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sysctl(SB) - GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ppoll(SB) - GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $8 DATA ·libc_ppoll_trampoline_addr(SB)/8, $libc_ppoll_trampoline<>(SB) TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_access(SB) - GLOBL ·libc_access_trampoline_addr(SB), RODATA, $8 DATA ·libc_access_trampoline_addr(SB)/8, $libc_access_trampoline<>(SB) TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_adjtime(SB) - GLOBL ·libc_adjtime_trampoline_addr(SB), RODATA, $8 DATA ·libc_adjtime_trampoline_addr(SB)/8, $libc_adjtime_trampoline<>(SB) TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chdir(SB) - GLOBL ·libc_chdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_chdir_trampoline_addr(SB)/8, $libc_chdir_trampoline<>(SB) TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chflags(SB) - GLOBL ·libc_chflags_trampoline_addr(SB), RODATA, $8 DATA ·libc_chflags_trampoline_addr(SB)/8, $libc_chflags_trampoline<>(SB) TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chmod(SB) - GLOBL ·libc_chmod_trampoline_addr(SB), RODATA, $8 DATA ·libc_chmod_trampoline_addr(SB)/8, $libc_chmod_trampoline<>(SB) TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chown(SB) - GLOBL ·libc_chown_trampoline_addr(SB), RODATA, $8 DATA ·libc_chown_trampoline_addr(SB)/8, $libc_chown_trampoline<>(SB) TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chroot(SB) - GLOBL ·libc_chroot_trampoline_addr(SB), RODATA, $8 DATA ·libc_chroot_trampoline_addr(SB)/8, $libc_chroot_trampoline<>(SB) +TEXT libc_clock_gettime_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_clock_gettime(SB) +GLOBL ·libc_clock_gettime_trampoline_addr(SB), RODATA, $8 +DATA ·libc_clock_gettime_trampoline_addr(SB)/8, $libc_clock_gettime_trampoline<>(SB) + TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_close(SB) - GLOBL ·libc_close_trampoline_addr(SB), RODATA, $8 DATA ·libc_close_trampoline_addr(SB)/8, $libc_close_trampoline<>(SB) TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup(SB) - GLOBL ·libc_dup_trampoline_addr(SB), RODATA, $8 DATA ·libc_dup_trampoline_addr(SB)/8, $libc_dup_trampoline<>(SB) TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup2(SB) - GLOBL ·libc_dup2_trampoline_addr(SB), RODATA, $8 DATA ·libc_dup2_trampoline_addr(SB)/8, $libc_dup2_trampoline<>(SB) TEXT libc_dup3_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup3(SB) - GLOBL ·libc_dup3_trampoline_addr(SB), RODATA, $8 DATA ·libc_dup3_trampoline_addr(SB)/8, $libc_dup3_trampoline<>(SB) TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_exit(SB) - GLOBL ·libc_exit_trampoline_addr(SB), RODATA, $8 DATA ·libc_exit_trampoline_addr(SB)/8, $libc_exit_trampoline<>(SB) TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_faccessat(SB) - GLOBL ·libc_faccessat_trampoline_addr(SB), RODATA, $8 DATA ·libc_faccessat_trampoline_addr(SB)/8, $libc_faccessat_trampoline<>(SB) TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchdir(SB) - GLOBL ·libc_fchdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchdir_trampoline_addr(SB)/8, $libc_fchdir_trampoline<>(SB) TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchflags(SB) - GLOBL ·libc_fchflags_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchflags_trampoline_addr(SB)/8, $libc_fchflags_trampoline<>(SB) TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchmod(SB) - GLOBL ·libc_fchmod_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchmod_trampoline_addr(SB)/8, $libc_fchmod_trampoline<>(SB) TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchmodat(SB) - GLOBL ·libc_fchmodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchmodat_trampoline_addr(SB)/8, $libc_fchmodat_trampoline<>(SB) TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchown(SB) - GLOBL ·libc_fchown_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchown_trampoline_addr(SB)/8, $libc_fchown_trampoline<>(SB) TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchownat(SB) - GLOBL ·libc_fchownat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchownat_trampoline_addr(SB)/8, $libc_fchownat_trampoline<>(SB) TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_flock(SB) - GLOBL ·libc_flock_trampoline_addr(SB), RODATA, $8 DATA ·libc_flock_trampoline_addr(SB)/8, $libc_flock_trampoline<>(SB) TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fpathconf(SB) - GLOBL ·libc_fpathconf_trampoline_addr(SB), RODATA, $8 DATA ·libc_fpathconf_trampoline_addr(SB)/8, $libc_fpathconf_trampoline<>(SB) TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstat(SB) - GLOBL ·libc_fstat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fstat_trampoline_addr(SB)/8, $libc_fstat_trampoline<>(SB) TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstatat(SB) - GLOBL ·libc_fstatat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fstatat_trampoline_addr(SB)/8, $libc_fstatat_trampoline<>(SB) TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstatfs(SB) - GLOBL ·libc_fstatfs_trampoline_addr(SB), RODATA, $8 DATA ·libc_fstatfs_trampoline_addr(SB)/8, $libc_fstatfs_trampoline<>(SB) TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fsync(SB) - GLOBL ·libc_fsync_trampoline_addr(SB), RODATA, $8 DATA ·libc_fsync_trampoline_addr(SB)/8, $libc_fsync_trampoline<>(SB) TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ftruncate(SB) - GLOBL ·libc_ftruncate_trampoline_addr(SB), RODATA, $8 DATA ·libc_ftruncate_trampoline_addr(SB)/8, $libc_ftruncate_trampoline<>(SB) TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getegid(SB) - GLOBL ·libc_getegid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getegid_trampoline_addr(SB)/8, $libc_getegid_trampoline<>(SB) TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_geteuid(SB) - GLOBL ·libc_geteuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_geteuid_trampoline_addr(SB)/8, $libc_geteuid_trampoline<>(SB) TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgid(SB) - GLOBL ·libc_getgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getgid_trampoline_addr(SB)/8, $libc_getgid_trampoline<>(SB) TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpgid(SB) - GLOBL ·libc_getpgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpgid_trampoline_addr(SB)/8, $libc_getpgid_trampoline<>(SB) TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpgrp(SB) - GLOBL ·libc_getpgrp_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpgrp_trampoline_addr(SB)/8, $libc_getpgrp_trampoline<>(SB) TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpid(SB) - GLOBL ·libc_getpid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpid_trampoline_addr(SB)/8, $libc_getpid_trampoline<>(SB) TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getppid(SB) - GLOBL ·libc_getppid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getppid_trampoline_addr(SB)/8, $libc_getppid_trampoline<>(SB) TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpriority(SB) - GLOBL ·libc_getpriority_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpriority_trampoline_addr(SB)/8, $libc_getpriority_trampoline<>(SB) TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrlimit(SB) - GLOBL ·libc_getrlimit_trampoline_addr(SB), RODATA, $8 DATA ·libc_getrlimit_trampoline_addr(SB)/8, $libc_getrlimit_trampoline<>(SB) TEXT libc_getrtable_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrtable(SB) - GLOBL ·libc_getrtable_trampoline_addr(SB), RODATA, $8 DATA ·libc_getrtable_trampoline_addr(SB)/8, $libc_getrtable_trampoline<>(SB) TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrusage(SB) - GLOBL ·libc_getrusage_trampoline_addr(SB), RODATA, $8 DATA ·libc_getrusage_trampoline_addr(SB)/8, $libc_getrusage_trampoline<>(SB) TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsid(SB) - GLOBL ·libc_getsid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getsid_trampoline_addr(SB)/8, $libc_getsid_trampoline<>(SB) TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_gettimeofday(SB) - GLOBL ·libc_gettimeofday_trampoline_addr(SB), RODATA, $8 DATA ·libc_gettimeofday_trampoline_addr(SB)/8, $libc_gettimeofday_trampoline<>(SB) TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getuid(SB) - GLOBL ·libc_getuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getuid_trampoline_addr(SB)/8, $libc_getuid_trampoline<>(SB) TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_issetugid(SB) - GLOBL ·libc_issetugid_trampoline_addr(SB), RODATA, $8 DATA ·libc_issetugid_trampoline_addr(SB)/8, $libc_issetugid_trampoline<>(SB) TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kill(SB) - GLOBL ·libc_kill_trampoline_addr(SB), RODATA, $8 DATA ·libc_kill_trampoline_addr(SB)/8, $libc_kill_trampoline<>(SB) TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kqueue(SB) - GLOBL ·libc_kqueue_trampoline_addr(SB), RODATA, $8 DATA ·libc_kqueue_trampoline_addr(SB)/8, $libc_kqueue_trampoline<>(SB) TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lchown(SB) - GLOBL ·libc_lchown_trampoline_addr(SB), RODATA, $8 DATA ·libc_lchown_trampoline_addr(SB)/8, $libc_lchown_trampoline<>(SB) TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_link(SB) - GLOBL ·libc_link_trampoline_addr(SB), RODATA, $8 DATA ·libc_link_trampoline_addr(SB)/8, $libc_link_trampoline<>(SB) TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_linkat(SB) - GLOBL ·libc_linkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_linkat_trampoline_addr(SB)/8, $libc_linkat_trampoline<>(SB) TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_listen(SB) - GLOBL ·libc_listen_trampoline_addr(SB), RODATA, $8 DATA ·libc_listen_trampoline_addr(SB)/8, $libc_listen_trampoline<>(SB) TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lstat(SB) - GLOBL ·libc_lstat_trampoline_addr(SB), RODATA, $8 DATA ·libc_lstat_trampoline_addr(SB)/8, $libc_lstat_trampoline<>(SB) TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkdir(SB) - GLOBL ·libc_mkdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_mkdir_trampoline_addr(SB)/8, $libc_mkdir_trampoline<>(SB) TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkdirat(SB) - GLOBL ·libc_mkdirat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mkdirat_trampoline_addr(SB)/8, $libc_mkdirat_trampoline<>(SB) TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkfifo(SB) - GLOBL ·libc_mkfifo_trampoline_addr(SB), RODATA, $8 DATA ·libc_mkfifo_trampoline_addr(SB)/8, $libc_mkfifo_trampoline<>(SB) TEXT libc_mkfifoat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkfifoat(SB) - GLOBL ·libc_mkfifoat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mkfifoat_trampoline_addr(SB)/8, $libc_mkfifoat_trampoline<>(SB) TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mknod(SB) - GLOBL ·libc_mknod_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknod_trampoline_addr(SB)/8, $libc_mknod_trampoline<>(SB) TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mknodat(SB) - GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) - GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $8 DATA ·libc_nanosleep_trampoline_addr(SB)/8, $libc_nanosleep_trampoline<>(SB) TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_open(SB) - GLOBL ·libc_open_trampoline_addr(SB), RODATA, $8 DATA ·libc_open_trampoline_addr(SB)/8, $libc_open_trampoline<>(SB) TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_openat(SB) - GLOBL ·libc_openat_trampoline_addr(SB), RODATA, $8 DATA ·libc_openat_trampoline_addr(SB)/8, $libc_openat_trampoline<>(SB) TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pathconf(SB) - GLOBL ·libc_pathconf_trampoline_addr(SB), RODATA, $8 DATA ·libc_pathconf_trampoline_addr(SB)/8, $libc_pathconf_trampoline<>(SB) TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pread(SB) - GLOBL ·libc_pread_trampoline_addr(SB), RODATA, $8 DATA ·libc_pread_trampoline_addr(SB)/8, $libc_pread_trampoline<>(SB) TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pwrite(SB) - GLOBL ·libc_pwrite_trampoline_addr(SB), RODATA, $8 DATA ·libc_pwrite_trampoline_addr(SB)/8, $libc_pwrite_trampoline<>(SB) TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_read(SB) - GLOBL ·libc_read_trampoline_addr(SB), RODATA, $8 DATA ·libc_read_trampoline_addr(SB)/8, $libc_read_trampoline<>(SB) TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_readlink(SB) - GLOBL ·libc_readlink_trampoline_addr(SB), RODATA, $8 DATA ·libc_readlink_trampoline_addr(SB)/8, $libc_readlink_trampoline<>(SB) TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_readlinkat(SB) - GLOBL ·libc_readlinkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_readlinkat_trampoline_addr(SB)/8, $libc_readlinkat_trampoline<>(SB) TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_rename(SB) - GLOBL ·libc_rename_trampoline_addr(SB), RODATA, $8 DATA ·libc_rename_trampoline_addr(SB)/8, $libc_rename_trampoline<>(SB) TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_renameat(SB) - GLOBL ·libc_renameat_trampoline_addr(SB), RODATA, $8 DATA ·libc_renameat_trampoline_addr(SB)/8, $libc_renameat_trampoline<>(SB) TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_revoke(SB) - GLOBL ·libc_revoke_trampoline_addr(SB), RODATA, $8 DATA ·libc_revoke_trampoline_addr(SB)/8, $libc_revoke_trampoline<>(SB) TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_rmdir(SB) - GLOBL ·libc_rmdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_rmdir_trampoline_addr(SB)/8, $libc_rmdir_trampoline<>(SB) TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lseek(SB) - GLOBL ·libc_lseek_trampoline_addr(SB), RODATA, $8 DATA ·libc_lseek_trampoline_addr(SB)/8, $libc_lseek_trampoline<>(SB) TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_select(SB) - GLOBL ·libc_select_trampoline_addr(SB), RODATA, $8 DATA ·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB) TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setegid(SB) - GLOBL ·libc_setegid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setegid_trampoline_addr(SB)/8, $libc_setegid_trampoline<>(SB) TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_seteuid(SB) - GLOBL ·libc_seteuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_seteuid_trampoline_addr(SB)/8, $libc_seteuid_trampoline<>(SB) TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setgid(SB) - GLOBL ·libc_setgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setgid_trampoline_addr(SB)/8, $libc_setgid_trampoline<>(SB) TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setlogin(SB) - GLOBL ·libc_setlogin_trampoline_addr(SB), RODATA, $8 DATA ·libc_setlogin_trampoline_addr(SB)/8, $libc_setlogin_trampoline<>(SB) TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setpgid(SB) - GLOBL ·libc_setpgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setpgid_trampoline_addr(SB)/8, $libc_setpgid_trampoline<>(SB) TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setpriority(SB) - GLOBL ·libc_setpriority_trampoline_addr(SB), RODATA, $8 DATA ·libc_setpriority_trampoline_addr(SB)/8, $libc_setpriority_trampoline<>(SB) TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setregid(SB) - GLOBL ·libc_setregid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setregid_trampoline_addr(SB)/8, $libc_setregid_trampoline<>(SB) TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setreuid(SB) - GLOBL ·libc_setreuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB) TEXT libc_setresgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setresgid(SB) - GLOBL ·libc_setresgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setresgid_trampoline_addr(SB)/8, $libc_setresgid_trampoline<>(SB) TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setresuid(SB) - GLOBL ·libc_setresuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setresuid_trampoline_addr(SB)/8, $libc_setresuid_trampoline<>(SB) TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setrlimit(SB) - GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $8 DATA ·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB) TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setrtable(SB) - GLOBL ·libc_setrtable_trampoline_addr(SB), RODATA, $8 DATA ·libc_setrtable_trampoline_addr(SB)/8, $libc_setrtable_trampoline<>(SB) TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setsid(SB) - GLOBL ·libc_setsid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setsid_trampoline_addr(SB)/8, $libc_setsid_trampoline<>(SB) TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_settimeofday(SB) - GLOBL ·libc_settimeofday_trampoline_addr(SB), RODATA, $8 DATA ·libc_settimeofday_trampoline_addr(SB)/8, $libc_settimeofday_trampoline<>(SB) TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setuid(SB) - GLOBL ·libc_setuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setuid_trampoline_addr(SB)/8, $libc_setuid_trampoline<>(SB) TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_stat(SB) - GLOBL ·libc_stat_trampoline_addr(SB), RODATA, $8 DATA ·libc_stat_trampoline_addr(SB)/8, $libc_stat_trampoline<>(SB) TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_statfs(SB) - GLOBL ·libc_statfs_trampoline_addr(SB), RODATA, $8 DATA ·libc_statfs_trampoline_addr(SB)/8, $libc_statfs_trampoline<>(SB) TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_symlink(SB) - GLOBL ·libc_symlink_trampoline_addr(SB), RODATA, $8 DATA ·libc_symlink_trampoline_addr(SB)/8, $libc_symlink_trampoline<>(SB) TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_symlinkat(SB) - GLOBL ·libc_symlinkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_symlinkat_trampoline_addr(SB)/8, $libc_symlinkat_trampoline<>(SB) TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sync(SB) - GLOBL ·libc_sync_trampoline_addr(SB), RODATA, $8 DATA ·libc_sync_trampoline_addr(SB)/8, $libc_sync_trampoline<>(SB) TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_truncate(SB) - GLOBL ·libc_truncate_trampoline_addr(SB), RODATA, $8 DATA ·libc_truncate_trampoline_addr(SB)/8, $libc_truncate_trampoline<>(SB) TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_umask(SB) - GLOBL ·libc_umask_trampoline_addr(SB), RODATA, $8 DATA ·libc_umask_trampoline_addr(SB)/8, $libc_umask_trampoline<>(SB) TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unlink(SB) - GLOBL ·libc_unlink_trampoline_addr(SB), RODATA, $8 DATA ·libc_unlink_trampoline_addr(SB)/8, $libc_unlink_trampoline<>(SB) TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unlinkat(SB) - GLOBL ·libc_unlinkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_unlinkat_trampoline_addr(SB)/8, $libc_unlinkat_trampoline<>(SB) TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unmount(SB) - GLOBL ·libc_unmount_trampoline_addr(SB), RODATA, $8 DATA ·libc_unmount_trampoline_addr(SB)/8, $libc_unmount_trampoline<>(SB) TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_write(SB) - GLOBL ·libc_write_trampoline_addr(SB), RODATA, $8 DATA ·libc_write_trampoline_addr(SB)/8, $libc_write_trampoline<>(SB) TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mmap(SB) - GLOBL ·libc_mmap_trampoline_addr(SB), RODATA, $8 DATA ·libc_mmap_trampoline_addr(SB)/8, $libc_mmap_trampoline<>(SB) TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munmap(SB) - GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8 DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB) TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_utimensat(SB) - GLOBL ·libc_utimensat_trampoline_addr(SB), RODATA, $8 DATA ·libc_utimensat_trampoline_addr(SB)/8, $libc_utimensat_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go index 8da6791d1e..2452a641da 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go @@ -527,6 +527,14 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + var libc_ioctl_trampoline_addr uintptr //go:cgo_import_dynamic libc_ioctl ioctl "libc.so" @@ -696,6 +704,20 @@ var libc_chroot_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := syscall_syscall(libc_clock_gettime_trampoline_addr, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_clock_gettime_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s index 9ad116d9fb..cf310420c9 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s @@ -5,792 +5,665 @@ TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgroups(SB) - GLOBL ·libc_getgroups_trampoline_addr(SB), RODATA, $4 DATA ·libc_getgroups_trampoline_addr(SB)/4, $libc_getgroups_trampoline<>(SB) TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setgroups(SB) - GLOBL ·libc_setgroups_trampoline_addr(SB), RODATA, $4 DATA ·libc_setgroups_trampoline_addr(SB)/4, $libc_setgroups_trampoline<>(SB) TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_wait4(SB) - GLOBL ·libc_wait4_trampoline_addr(SB), RODATA, $4 DATA ·libc_wait4_trampoline_addr(SB)/4, $libc_wait4_trampoline<>(SB) TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_accept(SB) - GLOBL ·libc_accept_trampoline_addr(SB), RODATA, $4 DATA ·libc_accept_trampoline_addr(SB)/4, $libc_accept_trampoline<>(SB) TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_bind(SB) - GLOBL ·libc_bind_trampoline_addr(SB), RODATA, $4 DATA ·libc_bind_trampoline_addr(SB)/4, $libc_bind_trampoline<>(SB) TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_connect(SB) - GLOBL ·libc_connect_trampoline_addr(SB), RODATA, $4 DATA ·libc_connect_trampoline_addr(SB)/4, $libc_connect_trampoline<>(SB) TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_socket(SB) - GLOBL ·libc_socket_trampoline_addr(SB), RODATA, $4 DATA ·libc_socket_trampoline_addr(SB)/4, $libc_socket_trampoline<>(SB) TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsockopt(SB) - GLOBL ·libc_getsockopt_trampoline_addr(SB), RODATA, $4 DATA ·libc_getsockopt_trampoline_addr(SB)/4, $libc_getsockopt_trampoline<>(SB) TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setsockopt(SB) - GLOBL ·libc_setsockopt_trampoline_addr(SB), RODATA, $4 DATA ·libc_setsockopt_trampoline_addr(SB)/4, $libc_setsockopt_trampoline<>(SB) TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpeername(SB) - GLOBL ·libc_getpeername_trampoline_addr(SB), RODATA, $4 DATA ·libc_getpeername_trampoline_addr(SB)/4, $libc_getpeername_trampoline<>(SB) TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsockname(SB) - GLOBL ·libc_getsockname_trampoline_addr(SB), RODATA, $4 DATA ·libc_getsockname_trampoline_addr(SB)/4, $libc_getsockname_trampoline<>(SB) TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_shutdown(SB) - GLOBL ·libc_shutdown_trampoline_addr(SB), RODATA, $4 DATA ·libc_shutdown_trampoline_addr(SB)/4, $libc_shutdown_trampoline<>(SB) TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_socketpair(SB) - GLOBL ·libc_socketpair_trampoline_addr(SB), RODATA, $4 DATA ·libc_socketpair_trampoline_addr(SB)/4, $libc_socketpair_trampoline<>(SB) TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_recvfrom(SB) - GLOBL ·libc_recvfrom_trampoline_addr(SB), RODATA, $4 DATA ·libc_recvfrom_trampoline_addr(SB)/4, $libc_recvfrom_trampoline<>(SB) TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendto(SB) - GLOBL ·libc_sendto_trampoline_addr(SB), RODATA, $4 DATA ·libc_sendto_trampoline_addr(SB)/4, $libc_sendto_trampoline<>(SB) TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_recvmsg(SB) - GLOBL ·libc_recvmsg_trampoline_addr(SB), RODATA, $4 DATA ·libc_recvmsg_trampoline_addr(SB)/4, $libc_recvmsg_trampoline<>(SB) TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendmsg(SB) - GLOBL ·libc_sendmsg_trampoline_addr(SB), RODATA, $4 DATA ·libc_sendmsg_trampoline_addr(SB)/4, $libc_sendmsg_trampoline<>(SB) TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kevent(SB) - GLOBL ·libc_kevent_trampoline_addr(SB), RODATA, $4 DATA ·libc_kevent_trampoline_addr(SB)/4, $libc_kevent_trampoline<>(SB) TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_utimes(SB) - GLOBL ·libc_utimes_trampoline_addr(SB), RODATA, $4 DATA ·libc_utimes_trampoline_addr(SB)/4, $libc_utimes_trampoline<>(SB) TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_futimes(SB) - GLOBL ·libc_futimes_trampoline_addr(SB), RODATA, $4 DATA ·libc_futimes_trampoline_addr(SB)/4, $libc_futimes_trampoline<>(SB) TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_poll(SB) - GLOBL ·libc_poll_trampoline_addr(SB), RODATA, $4 DATA ·libc_poll_trampoline_addr(SB)/4, $libc_poll_trampoline<>(SB) TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_madvise(SB) - GLOBL ·libc_madvise_trampoline_addr(SB), RODATA, $4 DATA ·libc_madvise_trampoline_addr(SB)/4, $libc_madvise_trampoline<>(SB) TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mlock(SB) - GLOBL ·libc_mlock_trampoline_addr(SB), RODATA, $4 DATA ·libc_mlock_trampoline_addr(SB)/4, $libc_mlock_trampoline<>(SB) TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mlockall(SB) - GLOBL ·libc_mlockall_trampoline_addr(SB), RODATA, $4 DATA ·libc_mlockall_trampoline_addr(SB)/4, $libc_mlockall_trampoline<>(SB) TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mprotect(SB) - GLOBL ·libc_mprotect_trampoline_addr(SB), RODATA, $4 DATA ·libc_mprotect_trampoline_addr(SB)/4, $libc_mprotect_trampoline<>(SB) TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_msync(SB) - GLOBL ·libc_msync_trampoline_addr(SB), RODATA, $4 DATA ·libc_msync_trampoline_addr(SB)/4, $libc_msync_trampoline<>(SB) TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munlock(SB) - GLOBL ·libc_munlock_trampoline_addr(SB), RODATA, $4 DATA ·libc_munlock_trampoline_addr(SB)/4, $libc_munlock_trampoline<>(SB) TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munlockall(SB) - GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $4 DATA ·libc_munlockall_trampoline_addr(SB)/4, $libc_munlockall_trampoline<>(SB) TEXT libc_pipe2_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pipe2(SB) - GLOBL ·libc_pipe2_trampoline_addr(SB), RODATA, $4 DATA ·libc_pipe2_trampoline_addr(SB)/4, $libc_pipe2_trampoline<>(SB) TEXT libc_getdents_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getdents(SB) - GLOBL ·libc_getdents_trampoline_addr(SB), RODATA, $4 DATA ·libc_getdents_trampoline_addr(SB)/4, $libc_getdents_trampoline<>(SB) TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getcwd(SB) - GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $4 DATA ·libc_getcwd_trampoline_addr(SB)/4, $libc_getcwd_trampoline<>(SB) TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ioctl(SB) - GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $4 DATA ·libc_ioctl_trampoline_addr(SB)/4, $libc_ioctl_trampoline<>(SB) TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sysctl(SB) - GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $4 DATA ·libc_sysctl_trampoline_addr(SB)/4, $libc_sysctl_trampoline<>(SB) TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ppoll(SB) - GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $4 DATA ·libc_ppoll_trampoline_addr(SB)/4, $libc_ppoll_trampoline<>(SB) TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_access(SB) - GLOBL ·libc_access_trampoline_addr(SB), RODATA, $4 DATA ·libc_access_trampoline_addr(SB)/4, $libc_access_trampoline<>(SB) TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_adjtime(SB) - GLOBL ·libc_adjtime_trampoline_addr(SB), RODATA, $4 DATA ·libc_adjtime_trampoline_addr(SB)/4, $libc_adjtime_trampoline<>(SB) TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chdir(SB) - GLOBL ·libc_chdir_trampoline_addr(SB), RODATA, $4 DATA ·libc_chdir_trampoline_addr(SB)/4, $libc_chdir_trampoline<>(SB) TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chflags(SB) - GLOBL ·libc_chflags_trampoline_addr(SB), RODATA, $4 DATA ·libc_chflags_trampoline_addr(SB)/4, $libc_chflags_trampoline<>(SB) TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chmod(SB) - GLOBL ·libc_chmod_trampoline_addr(SB), RODATA, $4 DATA ·libc_chmod_trampoline_addr(SB)/4, $libc_chmod_trampoline<>(SB) TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chown(SB) - GLOBL ·libc_chown_trampoline_addr(SB), RODATA, $4 DATA ·libc_chown_trampoline_addr(SB)/4, $libc_chown_trampoline<>(SB) TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chroot(SB) - GLOBL ·libc_chroot_trampoline_addr(SB), RODATA, $4 DATA ·libc_chroot_trampoline_addr(SB)/4, $libc_chroot_trampoline<>(SB) +TEXT libc_clock_gettime_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_clock_gettime(SB) +GLOBL ·libc_clock_gettime_trampoline_addr(SB), RODATA, $4 +DATA ·libc_clock_gettime_trampoline_addr(SB)/4, $libc_clock_gettime_trampoline<>(SB) + TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_close(SB) - GLOBL ·libc_close_trampoline_addr(SB), RODATA, $4 DATA ·libc_close_trampoline_addr(SB)/4, $libc_close_trampoline<>(SB) TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup(SB) - GLOBL ·libc_dup_trampoline_addr(SB), RODATA, $4 DATA ·libc_dup_trampoline_addr(SB)/4, $libc_dup_trampoline<>(SB) TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup2(SB) - GLOBL ·libc_dup2_trampoline_addr(SB), RODATA, $4 DATA ·libc_dup2_trampoline_addr(SB)/4, $libc_dup2_trampoline<>(SB) TEXT libc_dup3_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup3(SB) - GLOBL ·libc_dup3_trampoline_addr(SB), RODATA, $4 DATA ·libc_dup3_trampoline_addr(SB)/4, $libc_dup3_trampoline<>(SB) TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_exit(SB) - GLOBL ·libc_exit_trampoline_addr(SB), RODATA, $4 DATA ·libc_exit_trampoline_addr(SB)/4, $libc_exit_trampoline<>(SB) TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_faccessat(SB) - GLOBL ·libc_faccessat_trampoline_addr(SB), RODATA, $4 DATA ·libc_faccessat_trampoline_addr(SB)/4, $libc_faccessat_trampoline<>(SB) TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchdir(SB) - GLOBL ·libc_fchdir_trampoline_addr(SB), RODATA, $4 DATA ·libc_fchdir_trampoline_addr(SB)/4, $libc_fchdir_trampoline<>(SB) TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchflags(SB) - GLOBL ·libc_fchflags_trampoline_addr(SB), RODATA, $4 DATA ·libc_fchflags_trampoline_addr(SB)/4, $libc_fchflags_trampoline<>(SB) TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchmod(SB) - GLOBL ·libc_fchmod_trampoline_addr(SB), RODATA, $4 DATA ·libc_fchmod_trampoline_addr(SB)/4, $libc_fchmod_trampoline<>(SB) TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchmodat(SB) - GLOBL ·libc_fchmodat_trampoline_addr(SB), RODATA, $4 DATA ·libc_fchmodat_trampoline_addr(SB)/4, $libc_fchmodat_trampoline<>(SB) TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchown(SB) - GLOBL ·libc_fchown_trampoline_addr(SB), RODATA, $4 DATA ·libc_fchown_trampoline_addr(SB)/4, $libc_fchown_trampoline<>(SB) TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchownat(SB) - GLOBL ·libc_fchownat_trampoline_addr(SB), RODATA, $4 DATA ·libc_fchownat_trampoline_addr(SB)/4, $libc_fchownat_trampoline<>(SB) TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_flock(SB) - GLOBL ·libc_flock_trampoline_addr(SB), RODATA, $4 DATA ·libc_flock_trampoline_addr(SB)/4, $libc_flock_trampoline<>(SB) TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fpathconf(SB) - GLOBL ·libc_fpathconf_trampoline_addr(SB), RODATA, $4 DATA ·libc_fpathconf_trampoline_addr(SB)/4, $libc_fpathconf_trampoline<>(SB) TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstat(SB) - GLOBL ·libc_fstat_trampoline_addr(SB), RODATA, $4 DATA ·libc_fstat_trampoline_addr(SB)/4, $libc_fstat_trampoline<>(SB) TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstatat(SB) - GLOBL ·libc_fstatat_trampoline_addr(SB), RODATA, $4 DATA ·libc_fstatat_trampoline_addr(SB)/4, $libc_fstatat_trampoline<>(SB) TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstatfs(SB) - GLOBL ·libc_fstatfs_trampoline_addr(SB), RODATA, $4 DATA ·libc_fstatfs_trampoline_addr(SB)/4, $libc_fstatfs_trampoline<>(SB) TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fsync(SB) - GLOBL ·libc_fsync_trampoline_addr(SB), RODATA, $4 DATA ·libc_fsync_trampoline_addr(SB)/4, $libc_fsync_trampoline<>(SB) TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ftruncate(SB) - GLOBL ·libc_ftruncate_trampoline_addr(SB), RODATA, $4 DATA ·libc_ftruncate_trampoline_addr(SB)/4, $libc_ftruncate_trampoline<>(SB) TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getegid(SB) - GLOBL ·libc_getegid_trampoline_addr(SB), RODATA, $4 DATA ·libc_getegid_trampoline_addr(SB)/4, $libc_getegid_trampoline<>(SB) TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_geteuid(SB) - GLOBL ·libc_geteuid_trampoline_addr(SB), RODATA, $4 DATA ·libc_geteuid_trampoline_addr(SB)/4, $libc_geteuid_trampoline<>(SB) TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgid(SB) - GLOBL ·libc_getgid_trampoline_addr(SB), RODATA, $4 DATA ·libc_getgid_trampoline_addr(SB)/4, $libc_getgid_trampoline<>(SB) TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpgid(SB) - GLOBL ·libc_getpgid_trampoline_addr(SB), RODATA, $4 DATA ·libc_getpgid_trampoline_addr(SB)/4, $libc_getpgid_trampoline<>(SB) TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpgrp(SB) - GLOBL ·libc_getpgrp_trampoline_addr(SB), RODATA, $4 DATA ·libc_getpgrp_trampoline_addr(SB)/4, $libc_getpgrp_trampoline<>(SB) TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpid(SB) - GLOBL ·libc_getpid_trampoline_addr(SB), RODATA, $4 DATA ·libc_getpid_trampoline_addr(SB)/4, $libc_getpid_trampoline<>(SB) TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getppid(SB) - GLOBL ·libc_getppid_trampoline_addr(SB), RODATA, $4 DATA ·libc_getppid_trampoline_addr(SB)/4, $libc_getppid_trampoline<>(SB) TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpriority(SB) - GLOBL ·libc_getpriority_trampoline_addr(SB), RODATA, $4 DATA ·libc_getpriority_trampoline_addr(SB)/4, $libc_getpriority_trampoline<>(SB) TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrlimit(SB) - GLOBL ·libc_getrlimit_trampoline_addr(SB), RODATA, $4 DATA ·libc_getrlimit_trampoline_addr(SB)/4, $libc_getrlimit_trampoline<>(SB) TEXT libc_getrtable_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrtable(SB) - GLOBL ·libc_getrtable_trampoline_addr(SB), RODATA, $4 DATA ·libc_getrtable_trampoline_addr(SB)/4, $libc_getrtable_trampoline<>(SB) TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrusage(SB) - GLOBL ·libc_getrusage_trampoline_addr(SB), RODATA, $4 DATA ·libc_getrusage_trampoline_addr(SB)/4, $libc_getrusage_trampoline<>(SB) TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsid(SB) - GLOBL ·libc_getsid_trampoline_addr(SB), RODATA, $4 DATA ·libc_getsid_trampoline_addr(SB)/4, $libc_getsid_trampoline<>(SB) TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_gettimeofday(SB) - GLOBL ·libc_gettimeofday_trampoline_addr(SB), RODATA, $4 DATA ·libc_gettimeofday_trampoline_addr(SB)/4, $libc_gettimeofday_trampoline<>(SB) TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getuid(SB) - GLOBL ·libc_getuid_trampoline_addr(SB), RODATA, $4 DATA ·libc_getuid_trampoline_addr(SB)/4, $libc_getuid_trampoline<>(SB) TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_issetugid(SB) - GLOBL ·libc_issetugid_trampoline_addr(SB), RODATA, $4 DATA ·libc_issetugid_trampoline_addr(SB)/4, $libc_issetugid_trampoline<>(SB) TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kill(SB) - GLOBL ·libc_kill_trampoline_addr(SB), RODATA, $4 DATA ·libc_kill_trampoline_addr(SB)/4, $libc_kill_trampoline<>(SB) TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kqueue(SB) - GLOBL ·libc_kqueue_trampoline_addr(SB), RODATA, $4 DATA ·libc_kqueue_trampoline_addr(SB)/4, $libc_kqueue_trampoline<>(SB) TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lchown(SB) - GLOBL ·libc_lchown_trampoline_addr(SB), RODATA, $4 DATA ·libc_lchown_trampoline_addr(SB)/4, $libc_lchown_trampoline<>(SB) TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_link(SB) - GLOBL ·libc_link_trampoline_addr(SB), RODATA, $4 DATA ·libc_link_trampoline_addr(SB)/4, $libc_link_trampoline<>(SB) TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_linkat(SB) - GLOBL ·libc_linkat_trampoline_addr(SB), RODATA, $4 DATA ·libc_linkat_trampoline_addr(SB)/4, $libc_linkat_trampoline<>(SB) TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_listen(SB) - GLOBL ·libc_listen_trampoline_addr(SB), RODATA, $4 DATA ·libc_listen_trampoline_addr(SB)/4, $libc_listen_trampoline<>(SB) TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lstat(SB) - GLOBL ·libc_lstat_trampoline_addr(SB), RODATA, $4 DATA ·libc_lstat_trampoline_addr(SB)/4, $libc_lstat_trampoline<>(SB) TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkdir(SB) - GLOBL ·libc_mkdir_trampoline_addr(SB), RODATA, $4 DATA ·libc_mkdir_trampoline_addr(SB)/4, $libc_mkdir_trampoline<>(SB) TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkdirat(SB) - GLOBL ·libc_mkdirat_trampoline_addr(SB), RODATA, $4 DATA ·libc_mkdirat_trampoline_addr(SB)/4, $libc_mkdirat_trampoline<>(SB) TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkfifo(SB) - GLOBL ·libc_mkfifo_trampoline_addr(SB), RODATA, $4 DATA ·libc_mkfifo_trampoline_addr(SB)/4, $libc_mkfifo_trampoline<>(SB) TEXT libc_mkfifoat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkfifoat(SB) - GLOBL ·libc_mkfifoat_trampoline_addr(SB), RODATA, $4 DATA ·libc_mkfifoat_trampoline_addr(SB)/4, $libc_mkfifoat_trampoline<>(SB) TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mknod(SB) - GLOBL ·libc_mknod_trampoline_addr(SB), RODATA, $4 DATA ·libc_mknod_trampoline_addr(SB)/4, $libc_mknod_trampoline<>(SB) TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mknodat(SB) - GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $4 DATA ·libc_mknodat_trampoline_addr(SB)/4, $libc_mknodat_trampoline<>(SB) TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) - GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $4 DATA ·libc_nanosleep_trampoline_addr(SB)/4, $libc_nanosleep_trampoline<>(SB) TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_open(SB) - GLOBL ·libc_open_trampoline_addr(SB), RODATA, $4 DATA ·libc_open_trampoline_addr(SB)/4, $libc_open_trampoline<>(SB) TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_openat(SB) - GLOBL ·libc_openat_trampoline_addr(SB), RODATA, $4 DATA ·libc_openat_trampoline_addr(SB)/4, $libc_openat_trampoline<>(SB) TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pathconf(SB) - GLOBL ·libc_pathconf_trampoline_addr(SB), RODATA, $4 DATA ·libc_pathconf_trampoline_addr(SB)/4, $libc_pathconf_trampoline<>(SB) TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pread(SB) - GLOBL ·libc_pread_trampoline_addr(SB), RODATA, $4 DATA ·libc_pread_trampoline_addr(SB)/4, $libc_pread_trampoline<>(SB) TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pwrite(SB) - GLOBL ·libc_pwrite_trampoline_addr(SB), RODATA, $4 DATA ·libc_pwrite_trampoline_addr(SB)/4, $libc_pwrite_trampoline<>(SB) TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_read(SB) - GLOBL ·libc_read_trampoline_addr(SB), RODATA, $4 DATA ·libc_read_trampoline_addr(SB)/4, $libc_read_trampoline<>(SB) TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_readlink(SB) - GLOBL ·libc_readlink_trampoline_addr(SB), RODATA, $4 DATA ·libc_readlink_trampoline_addr(SB)/4, $libc_readlink_trampoline<>(SB) TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_readlinkat(SB) - GLOBL ·libc_readlinkat_trampoline_addr(SB), RODATA, $4 DATA ·libc_readlinkat_trampoline_addr(SB)/4, $libc_readlinkat_trampoline<>(SB) TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_rename(SB) - GLOBL ·libc_rename_trampoline_addr(SB), RODATA, $4 DATA ·libc_rename_trampoline_addr(SB)/4, $libc_rename_trampoline<>(SB) TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_renameat(SB) - GLOBL ·libc_renameat_trampoline_addr(SB), RODATA, $4 DATA ·libc_renameat_trampoline_addr(SB)/4, $libc_renameat_trampoline<>(SB) TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_revoke(SB) - GLOBL ·libc_revoke_trampoline_addr(SB), RODATA, $4 DATA ·libc_revoke_trampoline_addr(SB)/4, $libc_revoke_trampoline<>(SB) TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_rmdir(SB) - GLOBL ·libc_rmdir_trampoline_addr(SB), RODATA, $4 DATA ·libc_rmdir_trampoline_addr(SB)/4, $libc_rmdir_trampoline<>(SB) TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lseek(SB) - GLOBL ·libc_lseek_trampoline_addr(SB), RODATA, $4 DATA ·libc_lseek_trampoline_addr(SB)/4, $libc_lseek_trampoline<>(SB) TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_select(SB) - GLOBL ·libc_select_trampoline_addr(SB), RODATA, $4 DATA ·libc_select_trampoline_addr(SB)/4, $libc_select_trampoline<>(SB) TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setegid(SB) - GLOBL ·libc_setegid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setegid_trampoline_addr(SB)/4, $libc_setegid_trampoline<>(SB) TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_seteuid(SB) - GLOBL ·libc_seteuid_trampoline_addr(SB), RODATA, $4 DATA ·libc_seteuid_trampoline_addr(SB)/4, $libc_seteuid_trampoline<>(SB) TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setgid(SB) - GLOBL ·libc_setgid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setgid_trampoline_addr(SB)/4, $libc_setgid_trampoline<>(SB) TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setlogin(SB) - GLOBL ·libc_setlogin_trampoline_addr(SB), RODATA, $4 DATA ·libc_setlogin_trampoline_addr(SB)/4, $libc_setlogin_trampoline<>(SB) TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setpgid(SB) - GLOBL ·libc_setpgid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setpgid_trampoline_addr(SB)/4, $libc_setpgid_trampoline<>(SB) TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setpriority(SB) - GLOBL ·libc_setpriority_trampoline_addr(SB), RODATA, $4 DATA ·libc_setpriority_trampoline_addr(SB)/4, $libc_setpriority_trampoline<>(SB) TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setregid(SB) - GLOBL ·libc_setregid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setregid_trampoline_addr(SB)/4, $libc_setregid_trampoline<>(SB) TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setreuid(SB) - GLOBL ·libc_setreuid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setreuid_trampoline_addr(SB)/4, $libc_setreuid_trampoline<>(SB) TEXT libc_setresgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setresgid(SB) - GLOBL ·libc_setresgid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setresgid_trampoline_addr(SB)/4, $libc_setresgid_trampoline<>(SB) TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setresuid(SB) - GLOBL ·libc_setresuid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setresuid_trampoline_addr(SB)/4, $libc_setresuid_trampoline<>(SB) TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setrlimit(SB) - GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $4 DATA ·libc_setrlimit_trampoline_addr(SB)/4, $libc_setrlimit_trampoline<>(SB) TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setrtable(SB) - GLOBL ·libc_setrtable_trampoline_addr(SB), RODATA, $4 DATA ·libc_setrtable_trampoline_addr(SB)/4, $libc_setrtable_trampoline<>(SB) TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setsid(SB) - GLOBL ·libc_setsid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setsid_trampoline_addr(SB)/4, $libc_setsid_trampoline<>(SB) TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_settimeofday(SB) - GLOBL ·libc_settimeofday_trampoline_addr(SB), RODATA, $4 DATA ·libc_settimeofday_trampoline_addr(SB)/4, $libc_settimeofday_trampoline<>(SB) TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setuid(SB) - GLOBL ·libc_setuid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setuid_trampoline_addr(SB)/4, $libc_setuid_trampoline<>(SB) TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_stat(SB) - GLOBL ·libc_stat_trampoline_addr(SB), RODATA, $4 DATA ·libc_stat_trampoline_addr(SB)/4, $libc_stat_trampoline<>(SB) TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_statfs(SB) - GLOBL ·libc_statfs_trampoline_addr(SB), RODATA, $4 DATA ·libc_statfs_trampoline_addr(SB)/4, $libc_statfs_trampoline<>(SB) TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_symlink(SB) - GLOBL ·libc_symlink_trampoline_addr(SB), RODATA, $4 DATA ·libc_symlink_trampoline_addr(SB)/4, $libc_symlink_trampoline<>(SB) TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_symlinkat(SB) - GLOBL ·libc_symlinkat_trampoline_addr(SB), RODATA, $4 DATA ·libc_symlinkat_trampoline_addr(SB)/4, $libc_symlinkat_trampoline<>(SB) TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sync(SB) - GLOBL ·libc_sync_trampoline_addr(SB), RODATA, $4 DATA ·libc_sync_trampoline_addr(SB)/4, $libc_sync_trampoline<>(SB) TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_truncate(SB) - GLOBL ·libc_truncate_trampoline_addr(SB), RODATA, $4 DATA ·libc_truncate_trampoline_addr(SB)/4, $libc_truncate_trampoline<>(SB) TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_umask(SB) - GLOBL ·libc_umask_trampoline_addr(SB), RODATA, $4 DATA ·libc_umask_trampoline_addr(SB)/4, $libc_umask_trampoline<>(SB) TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unlink(SB) - GLOBL ·libc_unlink_trampoline_addr(SB), RODATA, $4 DATA ·libc_unlink_trampoline_addr(SB)/4, $libc_unlink_trampoline<>(SB) TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unlinkat(SB) - GLOBL ·libc_unlinkat_trampoline_addr(SB), RODATA, $4 DATA ·libc_unlinkat_trampoline_addr(SB)/4, $libc_unlinkat_trampoline<>(SB) TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unmount(SB) - GLOBL ·libc_unmount_trampoline_addr(SB), RODATA, $4 DATA ·libc_unmount_trampoline_addr(SB)/4, $libc_unmount_trampoline<>(SB) TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_write(SB) - GLOBL ·libc_write_trampoline_addr(SB), RODATA, $4 DATA ·libc_write_trampoline_addr(SB)/4, $libc_write_trampoline<>(SB) TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mmap(SB) - GLOBL ·libc_mmap_trampoline_addr(SB), RODATA, $4 DATA ·libc_mmap_trampoline_addr(SB)/4, $libc_mmap_trampoline<>(SB) TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munmap(SB) - GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $4 DATA ·libc_munmap_trampoline_addr(SB)/4, $libc_munmap_trampoline<>(SB) TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_utimensat(SB) - GLOBL ·libc_utimensat_trampoline_addr(SB), RODATA, $4 DATA ·libc_utimensat_trampoline_addr(SB)/4, $libc_utimensat_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go index 800aab6e3e..5e35600a60 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go @@ -527,6 +527,14 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + var libc_ioctl_trampoline_addr uintptr //go:cgo_import_dynamic libc_ioctl ioctl "libc.so" @@ -696,6 +704,20 @@ var libc_chroot_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := syscall_syscall(libc_clock_gettime_trampoline_addr, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_clock_gettime_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s index 4efeff9abb..484bb42e0a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s @@ -5,792 +5,665 @@ TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgroups(SB) - GLOBL ·libc_getgroups_trampoline_addr(SB), RODATA, $8 DATA ·libc_getgroups_trampoline_addr(SB)/8, $libc_getgroups_trampoline<>(SB) TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setgroups(SB) - GLOBL ·libc_setgroups_trampoline_addr(SB), RODATA, $8 DATA ·libc_setgroups_trampoline_addr(SB)/8, $libc_setgroups_trampoline<>(SB) TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_wait4(SB) - GLOBL ·libc_wait4_trampoline_addr(SB), RODATA, $8 DATA ·libc_wait4_trampoline_addr(SB)/8, $libc_wait4_trampoline<>(SB) TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_accept(SB) - GLOBL ·libc_accept_trampoline_addr(SB), RODATA, $8 DATA ·libc_accept_trampoline_addr(SB)/8, $libc_accept_trampoline<>(SB) TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_bind(SB) - GLOBL ·libc_bind_trampoline_addr(SB), RODATA, $8 DATA ·libc_bind_trampoline_addr(SB)/8, $libc_bind_trampoline<>(SB) TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_connect(SB) - GLOBL ·libc_connect_trampoline_addr(SB), RODATA, $8 DATA ·libc_connect_trampoline_addr(SB)/8, $libc_connect_trampoline<>(SB) TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_socket(SB) - GLOBL ·libc_socket_trampoline_addr(SB), RODATA, $8 DATA ·libc_socket_trampoline_addr(SB)/8, $libc_socket_trampoline<>(SB) TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsockopt(SB) - GLOBL ·libc_getsockopt_trampoline_addr(SB), RODATA, $8 DATA ·libc_getsockopt_trampoline_addr(SB)/8, $libc_getsockopt_trampoline<>(SB) TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setsockopt(SB) - GLOBL ·libc_setsockopt_trampoline_addr(SB), RODATA, $8 DATA ·libc_setsockopt_trampoline_addr(SB)/8, $libc_setsockopt_trampoline<>(SB) TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpeername(SB) - GLOBL ·libc_getpeername_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpeername_trampoline_addr(SB)/8, $libc_getpeername_trampoline<>(SB) TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsockname(SB) - GLOBL ·libc_getsockname_trampoline_addr(SB), RODATA, $8 DATA ·libc_getsockname_trampoline_addr(SB)/8, $libc_getsockname_trampoline<>(SB) TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_shutdown(SB) - GLOBL ·libc_shutdown_trampoline_addr(SB), RODATA, $8 DATA ·libc_shutdown_trampoline_addr(SB)/8, $libc_shutdown_trampoline<>(SB) TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_socketpair(SB) - GLOBL ·libc_socketpair_trampoline_addr(SB), RODATA, $8 DATA ·libc_socketpair_trampoline_addr(SB)/8, $libc_socketpair_trampoline<>(SB) TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_recvfrom(SB) - GLOBL ·libc_recvfrom_trampoline_addr(SB), RODATA, $8 DATA ·libc_recvfrom_trampoline_addr(SB)/8, $libc_recvfrom_trampoline<>(SB) TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendto(SB) - GLOBL ·libc_sendto_trampoline_addr(SB), RODATA, $8 DATA ·libc_sendto_trampoline_addr(SB)/8, $libc_sendto_trampoline<>(SB) TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_recvmsg(SB) - GLOBL ·libc_recvmsg_trampoline_addr(SB), RODATA, $8 DATA ·libc_recvmsg_trampoline_addr(SB)/8, $libc_recvmsg_trampoline<>(SB) TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendmsg(SB) - GLOBL ·libc_sendmsg_trampoline_addr(SB), RODATA, $8 DATA ·libc_sendmsg_trampoline_addr(SB)/8, $libc_sendmsg_trampoline<>(SB) TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kevent(SB) - GLOBL ·libc_kevent_trampoline_addr(SB), RODATA, $8 DATA ·libc_kevent_trampoline_addr(SB)/8, $libc_kevent_trampoline<>(SB) TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_utimes(SB) - GLOBL ·libc_utimes_trampoline_addr(SB), RODATA, $8 DATA ·libc_utimes_trampoline_addr(SB)/8, $libc_utimes_trampoline<>(SB) TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_futimes(SB) - GLOBL ·libc_futimes_trampoline_addr(SB), RODATA, $8 DATA ·libc_futimes_trampoline_addr(SB)/8, $libc_futimes_trampoline<>(SB) TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_poll(SB) - GLOBL ·libc_poll_trampoline_addr(SB), RODATA, $8 DATA ·libc_poll_trampoline_addr(SB)/8, $libc_poll_trampoline<>(SB) TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_madvise(SB) - GLOBL ·libc_madvise_trampoline_addr(SB), RODATA, $8 DATA ·libc_madvise_trampoline_addr(SB)/8, $libc_madvise_trampoline<>(SB) TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mlock(SB) - GLOBL ·libc_mlock_trampoline_addr(SB), RODATA, $8 DATA ·libc_mlock_trampoline_addr(SB)/8, $libc_mlock_trampoline<>(SB) TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mlockall(SB) - GLOBL ·libc_mlockall_trampoline_addr(SB), RODATA, $8 DATA ·libc_mlockall_trampoline_addr(SB)/8, $libc_mlockall_trampoline<>(SB) TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mprotect(SB) - GLOBL ·libc_mprotect_trampoline_addr(SB), RODATA, $8 DATA ·libc_mprotect_trampoline_addr(SB)/8, $libc_mprotect_trampoline<>(SB) TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_msync(SB) - GLOBL ·libc_msync_trampoline_addr(SB), RODATA, $8 DATA ·libc_msync_trampoline_addr(SB)/8, $libc_msync_trampoline<>(SB) TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munlock(SB) - GLOBL ·libc_munlock_trampoline_addr(SB), RODATA, $8 DATA ·libc_munlock_trampoline_addr(SB)/8, $libc_munlock_trampoline<>(SB) TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munlockall(SB) - GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8 DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB) TEXT libc_pipe2_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pipe2(SB) - GLOBL ·libc_pipe2_trampoline_addr(SB), RODATA, $8 DATA ·libc_pipe2_trampoline_addr(SB)/8, $libc_pipe2_trampoline<>(SB) TEXT libc_getdents_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getdents(SB) - GLOBL ·libc_getdents_trampoline_addr(SB), RODATA, $8 DATA ·libc_getdents_trampoline_addr(SB)/8, $libc_getdents_trampoline<>(SB) TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getcwd(SB) - GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $8 DATA ·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB) TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ioctl(SB) - GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB) TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sysctl(SB) - GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ppoll(SB) - GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $8 DATA ·libc_ppoll_trampoline_addr(SB)/8, $libc_ppoll_trampoline<>(SB) TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_access(SB) - GLOBL ·libc_access_trampoline_addr(SB), RODATA, $8 DATA ·libc_access_trampoline_addr(SB)/8, $libc_access_trampoline<>(SB) TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_adjtime(SB) - GLOBL ·libc_adjtime_trampoline_addr(SB), RODATA, $8 DATA ·libc_adjtime_trampoline_addr(SB)/8, $libc_adjtime_trampoline<>(SB) TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chdir(SB) - GLOBL ·libc_chdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_chdir_trampoline_addr(SB)/8, $libc_chdir_trampoline<>(SB) TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chflags(SB) - GLOBL ·libc_chflags_trampoline_addr(SB), RODATA, $8 DATA ·libc_chflags_trampoline_addr(SB)/8, $libc_chflags_trampoline<>(SB) TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chmod(SB) - GLOBL ·libc_chmod_trampoline_addr(SB), RODATA, $8 DATA ·libc_chmod_trampoline_addr(SB)/8, $libc_chmod_trampoline<>(SB) TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chown(SB) - GLOBL ·libc_chown_trampoline_addr(SB), RODATA, $8 DATA ·libc_chown_trampoline_addr(SB)/8, $libc_chown_trampoline<>(SB) TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chroot(SB) - GLOBL ·libc_chroot_trampoline_addr(SB), RODATA, $8 DATA ·libc_chroot_trampoline_addr(SB)/8, $libc_chroot_trampoline<>(SB) +TEXT libc_clock_gettime_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_clock_gettime(SB) +GLOBL ·libc_clock_gettime_trampoline_addr(SB), RODATA, $8 +DATA ·libc_clock_gettime_trampoline_addr(SB)/8, $libc_clock_gettime_trampoline<>(SB) + TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_close(SB) - GLOBL ·libc_close_trampoline_addr(SB), RODATA, $8 DATA ·libc_close_trampoline_addr(SB)/8, $libc_close_trampoline<>(SB) TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup(SB) - GLOBL ·libc_dup_trampoline_addr(SB), RODATA, $8 DATA ·libc_dup_trampoline_addr(SB)/8, $libc_dup_trampoline<>(SB) TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup2(SB) - GLOBL ·libc_dup2_trampoline_addr(SB), RODATA, $8 DATA ·libc_dup2_trampoline_addr(SB)/8, $libc_dup2_trampoline<>(SB) TEXT libc_dup3_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup3(SB) - GLOBL ·libc_dup3_trampoline_addr(SB), RODATA, $8 DATA ·libc_dup3_trampoline_addr(SB)/8, $libc_dup3_trampoline<>(SB) TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_exit(SB) - GLOBL ·libc_exit_trampoline_addr(SB), RODATA, $8 DATA ·libc_exit_trampoline_addr(SB)/8, $libc_exit_trampoline<>(SB) TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_faccessat(SB) - GLOBL ·libc_faccessat_trampoline_addr(SB), RODATA, $8 DATA ·libc_faccessat_trampoline_addr(SB)/8, $libc_faccessat_trampoline<>(SB) TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchdir(SB) - GLOBL ·libc_fchdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchdir_trampoline_addr(SB)/8, $libc_fchdir_trampoline<>(SB) TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchflags(SB) - GLOBL ·libc_fchflags_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchflags_trampoline_addr(SB)/8, $libc_fchflags_trampoline<>(SB) TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchmod(SB) - GLOBL ·libc_fchmod_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchmod_trampoline_addr(SB)/8, $libc_fchmod_trampoline<>(SB) TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchmodat(SB) - GLOBL ·libc_fchmodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchmodat_trampoline_addr(SB)/8, $libc_fchmodat_trampoline<>(SB) TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchown(SB) - GLOBL ·libc_fchown_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchown_trampoline_addr(SB)/8, $libc_fchown_trampoline<>(SB) TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchownat(SB) - GLOBL ·libc_fchownat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchownat_trampoline_addr(SB)/8, $libc_fchownat_trampoline<>(SB) TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_flock(SB) - GLOBL ·libc_flock_trampoline_addr(SB), RODATA, $8 DATA ·libc_flock_trampoline_addr(SB)/8, $libc_flock_trampoline<>(SB) TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fpathconf(SB) - GLOBL ·libc_fpathconf_trampoline_addr(SB), RODATA, $8 DATA ·libc_fpathconf_trampoline_addr(SB)/8, $libc_fpathconf_trampoline<>(SB) TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstat(SB) - GLOBL ·libc_fstat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fstat_trampoline_addr(SB)/8, $libc_fstat_trampoline<>(SB) TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstatat(SB) - GLOBL ·libc_fstatat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fstatat_trampoline_addr(SB)/8, $libc_fstatat_trampoline<>(SB) TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstatfs(SB) - GLOBL ·libc_fstatfs_trampoline_addr(SB), RODATA, $8 DATA ·libc_fstatfs_trampoline_addr(SB)/8, $libc_fstatfs_trampoline<>(SB) TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fsync(SB) - GLOBL ·libc_fsync_trampoline_addr(SB), RODATA, $8 DATA ·libc_fsync_trampoline_addr(SB)/8, $libc_fsync_trampoline<>(SB) TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ftruncate(SB) - GLOBL ·libc_ftruncate_trampoline_addr(SB), RODATA, $8 DATA ·libc_ftruncate_trampoline_addr(SB)/8, $libc_ftruncate_trampoline<>(SB) TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getegid(SB) - GLOBL ·libc_getegid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getegid_trampoline_addr(SB)/8, $libc_getegid_trampoline<>(SB) TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_geteuid(SB) - GLOBL ·libc_geteuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_geteuid_trampoline_addr(SB)/8, $libc_geteuid_trampoline<>(SB) TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgid(SB) - GLOBL ·libc_getgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getgid_trampoline_addr(SB)/8, $libc_getgid_trampoline<>(SB) TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpgid(SB) - GLOBL ·libc_getpgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpgid_trampoline_addr(SB)/8, $libc_getpgid_trampoline<>(SB) TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpgrp(SB) - GLOBL ·libc_getpgrp_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpgrp_trampoline_addr(SB)/8, $libc_getpgrp_trampoline<>(SB) TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpid(SB) - GLOBL ·libc_getpid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpid_trampoline_addr(SB)/8, $libc_getpid_trampoline<>(SB) TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getppid(SB) - GLOBL ·libc_getppid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getppid_trampoline_addr(SB)/8, $libc_getppid_trampoline<>(SB) TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpriority(SB) - GLOBL ·libc_getpriority_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpriority_trampoline_addr(SB)/8, $libc_getpriority_trampoline<>(SB) TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrlimit(SB) - GLOBL ·libc_getrlimit_trampoline_addr(SB), RODATA, $8 DATA ·libc_getrlimit_trampoline_addr(SB)/8, $libc_getrlimit_trampoline<>(SB) TEXT libc_getrtable_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrtable(SB) - GLOBL ·libc_getrtable_trampoline_addr(SB), RODATA, $8 DATA ·libc_getrtable_trampoline_addr(SB)/8, $libc_getrtable_trampoline<>(SB) TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrusage(SB) - GLOBL ·libc_getrusage_trampoline_addr(SB), RODATA, $8 DATA ·libc_getrusage_trampoline_addr(SB)/8, $libc_getrusage_trampoline<>(SB) TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsid(SB) - GLOBL ·libc_getsid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getsid_trampoline_addr(SB)/8, $libc_getsid_trampoline<>(SB) TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_gettimeofday(SB) - GLOBL ·libc_gettimeofday_trampoline_addr(SB), RODATA, $8 DATA ·libc_gettimeofday_trampoline_addr(SB)/8, $libc_gettimeofday_trampoline<>(SB) TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getuid(SB) - GLOBL ·libc_getuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getuid_trampoline_addr(SB)/8, $libc_getuid_trampoline<>(SB) TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_issetugid(SB) - GLOBL ·libc_issetugid_trampoline_addr(SB), RODATA, $8 DATA ·libc_issetugid_trampoline_addr(SB)/8, $libc_issetugid_trampoline<>(SB) TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kill(SB) - GLOBL ·libc_kill_trampoline_addr(SB), RODATA, $8 DATA ·libc_kill_trampoline_addr(SB)/8, $libc_kill_trampoline<>(SB) TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kqueue(SB) - GLOBL ·libc_kqueue_trampoline_addr(SB), RODATA, $8 DATA ·libc_kqueue_trampoline_addr(SB)/8, $libc_kqueue_trampoline<>(SB) TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lchown(SB) - GLOBL ·libc_lchown_trampoline_addr(SB), RODATA, $8 DATA ·libc_lchown_trampoline_addr(SB)/8, $libc_lchown_trampoline<>(SB) TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_link(SB) - GLOBL ·libc_link_trampoline_addr(SB), RODATA, $8 DATA ·libc_link_trampoline_addr(SB)/8, $libc_link_trampoline<>(SB) TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_linkat(SB) - GLOBL ·libc_linkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_linkat_trampoline_addr(SB)/8, $libc_linkat_trampoline<>(SB) TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_listen(SB) - GLOBL ·libc_listen_trampoline_addr(SB), RODATA, $8 DATA ·libc_listen_trampoline_addr(SB)/8, $libc_listen_trampoline<>(SB) TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lstat(SB) - GLOBL ·libc_lstat_trampoline_addr(SB), RODATA, $8 DATA ·libc_lstat_trampoline_addr(SB)/8, $libc_lstat_trampoline<>(SB) TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkdir(SB) - GLOBL ·libc_mkdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_mkdir_trampoline_addr(SB)/8, $libc_mkdir_trampoline<>(SB) TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkdirat(SB) - GLOBL ·libc_mkdirat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mkdirat_trampoline_addr(SB)/8, $libc_mkdirat_trampoline<>(SB) TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkfifo(SB) - GLOBL ·libc_mkfifo_trampoline_addr(SB), RODATA, $8 DATA ·libc_mkfifo_trampoline_addr(SB)/8, $libc_mkfifo_trampoline<>(SB) TEXT libc_mkfifoat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkfifoat(SB) - GLOBL ·libc_mkfifoat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mkfifoat_trampoline_addr(SB)/8, $libc_mkfifoat_trampoline<>(SB) TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mknod(SB) - GLOBL ·libc_mknod_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknod_trampoline_addr(SB)/8, $libc_mknod_trampoline<>(SB) TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mknodat(SB) - GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) - GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $8 DATA ·libc_nanosleep_trampoline_addr(SB)/8, $libc_nanosleep_trampoline<>(SB) TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_open(SB) - GLOBL ·libc_open_trampoline_addr(SB), RODATA, $8 DATA ·libc_open_trampoline_addr(SB)/8, $libc_open_trampoline<>(SB) TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_openat(SB) - GLOBL ·libc_openat_trampoline_addr(SB), RODATA, $8 DATA ·libc_openat_trampoline_addr(SB)/8, $libc_openat_trampoline<>(SB) TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pathconf(SB) - GLOBL ·libc_pathconf_trampoline_addr(SB), RODATA, $8 DATA ·libc_pathconf_trampoline_addr(SB)/8, $libc_pathconf_trampoline<>(SB) TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pread(SB) - GLOBL ·libc_pread_trampoline_addr(SB), RODATA, $8 DATA ·libc_pread_trampoline_addr(SB)/8, $libc_pread_trampoline<>(SB) TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pwrite(SB) - GLOBL ·libc_pwrite_trampoline_addr(SB), RODATA, $8 DATA ·libc_pwrite_trampoline_addr(SB)/8, $libc_pwrite_trampoline<>(SB) TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_read(SB) - GLOBL ·libc_read_trampoline_addr(SB), RODATA, $8 DATA ·libc_read_trampoline_addr(SB)/8, $libc_read_trampoline<>(SB) TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_readlink(SB) - GLOBL ·libc_readlink_trampoline_addr(SB), RODATA, $8 DATA ·libc_readlink_trampoline_addr(SB)/8, $libc_readlink_trampoline<>(SB) TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_readlinkat(SB) - GLOBL ·libc_readlinkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_readlinkat_trampoline_addr(SB)/8, $libc_readlinkat_trampoline<>(SB) TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_rename(SB) - GLOBL ·libc_rename_trampoline_addr(SB), RODATA, $8 DATA ·libc_rename_trampoline_addr(SB)/8, $libc_rename_trampoline<>(SB) TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_renameat(SB) - GLOBL ·libc_renameat_trampoline_addr(SB), RODATA, $8 DATA ·libc_renameat_trampoline_addr(SB)/8, $libc_renameat_trampoline<>(SB) TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_revoke(SB) - GLOBL ·libc_revoke_trampoline_addr(SB), RODATA, $8 DATA ·libc_revoke_trampoline_addr(SB)/8, $libc_revoke_trampoline<>(SB) TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_rmdir(SB) - GLOBL ·libc_rmdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_rmdir_trampoline_addr(SB)/8, $libc_rmdir_trampoline<>(SB) TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lseek(SB) - GLOBL ·libc_lseek_trampoline_addr(SB), RODATA, $8 DATA ·libc_lseek_trampoline_addr(SB)/8, $libc_lseek_trampoline<>(SB) TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_select(SB) - GLOBL ·libc_select_trampoline_addr(SB), RODATA, $8 DATA ·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB) TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setegid(SB) - GLOBL ·libc_setegid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setegid_trampoline_addr(SB)/8, $libc_setegid_trampoline<>(SB) TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_seteuid(SB) - GLOBL ·libc_seteuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_seteuid_trampoline_addr(SB)/8, $libc_seteuid_trampoline<>(SB) TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setgid(SB) - GLOBL ·libc_setgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setgid_trampoline_addr(SB)/8, $libc_setgid_trampoline<>(SB) TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setlogin(SB) - GLOBL ·libc_setlogin_trampoline_addr(SB), RODATA, $8 DATA ·libc_setlogin_trampoline_addr(SB)/8, $libc_setlogin_trampoline<>(SB) TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setpgid(SB) - GLOBL ·libc_setpgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setpgid_trampoline_addr(SB)/8, $libc_setpgid_trampoline<>(SB) TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setpriority(SB) - GLOBL ·libc_setpriority_trampoline_addr(SB), RODATA, $8 DATA ·libc_setpriority_trampoline_addr(SB)/8, $libc_setpriority_trampoline<>(SB) TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setregid(SB) - GLOBL ·libc_setregid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setregid_trampoline_addr(SB)/8, $libc_setregid_trampoline<>(SB) TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setreuid(SB) - GLOBL ·libc_setreuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB) TEXT libc_setresgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setresgid(SB) - GLOBL ·libc_setresgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setresgid_trampoline_addr(SB)/8, $libc_setresgid_trampoline<>(SB) TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setresuid(SB) - GLOBL ·libc_setresuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setresuid_trampoline_addr(SB)/8, $libc_setresuid_trampoline<>(SB) TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setrlimit(SB) - GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $8 DATA ·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB) TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setrtable(SB) - GLOBL ·libc_setrtable_trampoline_addr(SB), RODATA, $8 DATA ·libc_setrtable_trampoline_addr(SB)/8, $libc_setrtable_trampoline<>(SB) TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setsid(SB) - GLOBL ·libc_setsid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setsid_trampoline_addr(SB)/8, $libc_setsid_trampoline<>(SB) TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_settimeofday(SB) - GLOBL ·libc_settimeofday_trampoline_addr(SB), RODATA, $8 DATA ·libc_settimeofday_trampoline_addr(SB)/8, $libc_settimeofday_trampoline<>(SB) TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setuid(SB) - GLOBL ·libc_setuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setuid_trampoline_addr(SB)/8, $libc_setuid_trampoline<>(SB) TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_stat(SB) - GLOBL ·libc_stat_trampoline_addr(SB), RODATA, $8 DATA ·libc_stat_trampoline_addr(SB)/8, $libc_stat_trampoline<>(SB) TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_statfs(SB) - GLOBL ·libc_statfs_trampoline_addr(SB), RODATA, $8 DATA ·libc_statfs_trampoline_addr(SB)/8, $libc_statfs_trampoline<>(SB) TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_symlink(SB) - GLOBL ·libc_symlink_trampoline_addr(SB), RODATA, $8 DATA ·libc_symlink_trampoline_addr(SB)/8, $libc_symlink_trampoline<>(SB) TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_symlinkat(SB) - GLOBL ·libc_symlinkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_symlinkat_trampoline_addr(SB)/8, $libc_symlinkat_trampoline<>(SB) TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sync(SB) - GLOBL ·libc_sync_trampoline_addr(SB), RODATA, $8 DATA ·libc_sync_trampoline_addr(SB)/8, $libc_sync_trampoline<>(SB) TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_truncate(SB) - GLOBL ·libc_truncate_trampoline_addr(SB), RODATA, $8 DATA ·libc_truncate_trampoline_addr(SB)/8, $libc_truncate_trampoline<>(SB) TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_umask(SB) - GLOBL ·libc_umask_trampoline_addr(SB), RODATA, $8 DATA ·libc_umask_trampoline_addr(SB)/8, $libc_umask_trampoline<>(SB) TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unlink(SB) - GLOBL ·libc_unlink_trampoline_addr(SB), RODATA, $8 DATA ·libc_unlink_trampoline_addr(SB)/8, $libc_unlink_trampoline<>(SB) TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unlinkat(SB) - GLOBL ·libc_unlinkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_unlinkat_trampoline_addr(SB)/8, $libc_unlinkat_trampoline<>(SB) TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unmount(SB) - GLOBL ·libc_unmount_trampoline_addr(SB), RODATA, $8 DATA ·libc_unmount_trampoline_addr(SB)/8, $libc_unmount_trampoline<>(SB) TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_write(SB) - GLOBL ·libc_write_trampoline_addr(SB), RODATA, $8 DATA ·libc_write_trampoline_addr(SB)/8, $libc_write_trampoline<>(SB) TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mmap(SB) - GLOBL ·libc_mmap_trampoline_addr(SB), RODATA, $8 DATA ·libc_mmap_trampoline_addr(SB)/8, $libc_mmap_trampoline<>(SB) TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munmap(SB) - GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8 DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB) TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_utimensat(SB) - GLOBL ·libc_utimensat_trampoline_addr(SB), RODATA, $8 DATA ·libc_utimensat_trampoline_addr(SB)/8, $libc_utimensat_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go index 016d959bc6..b04cef1a19 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go @@ -1,4 +1,4 @@ -// go run mksyscall.go -openbsd -tags openbsd,mips64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_mips64.go +// go run mksyscall.go -openbsd -libc -tags openbsd,mips64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_mips64.go // Code generated by the command above; see README.md. DO NOT EDIT. //go:build openbsd && mips64 @@ -16,7 +16,7 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func getgroups(ngid int, gid *_Gid_t) (n int, err error) { - r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) + r0, _, e1 := syscall_rawSyscall(libc_getgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -24,20 +24,28 @@ func getgroups(ngid int, gid *_Gid_t) (n int, err error) { return } +var libc_getgroups_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getgroups getgroups "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func setgroups(ngid int, gid *_Gid_t) (err error) { - _, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) + _, _, e1 := syscall_rawSyscall(libc_setgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_setgroups_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setgroups setgroups "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) { - r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) + r0, _, e1 := syscall_syscall6(libc_wait4_trampoline_addr, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) wpid = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -45,10 +53,14 @@ func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err return } +var libc_wait4_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_wait4 wait4 "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { - r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + r0, _, e1 := syscall_syscall(libc_accept_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) fd = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -56,30 +68,42 @@ func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { return } +var libc_accept_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_accept accept "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { - _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen)) + _, _, e1 := syscall_syscall(libc_bind_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_bind_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_bind bind "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { - _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen)) + _, _, e1 := syscall_syscall(libc_connect_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_connect_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_connect connect "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func socket(domain int, typ int, proto int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto)) + r0, _, e1 := syscall_rawSyscall(libc_socket_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto)) fd = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -87,66 +111,94 @@ func socket(domain int, typ int, proto int) (fd int, err error) { return } +var libc_socket_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_socket socket "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { - _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) + _, _, e1 := syscall_syscall6(libc_getsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_getsockopt_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getsockopt getsockopt "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { - _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) + _, _, e1 := syscall_syscall6(libc_setsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_setsockopt_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setsockopt setsockopt "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { - _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + _, _, e1 := syscall_rawSyscall(libc_getpeername_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) if e1 != 0 { err = errnoErr(e1) } return } +var libc_getpeername_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpeername getpeername "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { - _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + _, _, e1 := syscall_rawSyscall(libc_getsockname_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) if e1 != 0 { err = errnoErr(e1) } return } +var libc_getsockname_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getsockname getsockname "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Shutdown(s int, how int) (err error) { - _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0) + _, _, e1 := syscall_syscall(libc_shutdown_trampoline_addr, uintptr(s), uintptr(how), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_shutdown_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_shutdown shutdown "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { - _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) + _, _, e1 := syscall_rawSyscall6(libc_socketpair_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_socketpair_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_socketpair socketpair "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { @@ -156,7 +208,7 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl } else { _p0 = unsafe.Pointer(&_zero) } - r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) + r0, _, e1 := syscall_syscall6(libc_recvfrom_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -164,6 +216,10 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl return } +var libc_recvfrom_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_recvfrom recvfrom "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { @@ -173,17 +229,21 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) ( } else { _p0 = unsafe.Pointer(&_zero) } - _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) + _, _, e1 := syscall_syscall6(libc_sendto_trampoline_addr, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_sendto_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_sendto sendto "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) + r0, _, e1 := syscall_syscall(libc_recvmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -191,10 +251,14 @@ func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { return } +var libc_recvmsg_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_recvmsg recvmsg "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) + r0, _, e1 := syscall_syscall(libc_sendmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -202,10 +266,14 @@ func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { return } +var libc_sendmsg_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_sendmsg sendmsg "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) { - r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout))) + r0, _, e1 := syscall_syscall6(libc_kevent_trampoline_addr, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout))) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -213,6 +281,10 @@ func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, ne return } +var libc_kevent_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_kevent kevent "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func utimes(path string, timeval *[2]Timeval) (err error) { @@ -221,27 +293,35 @@ func utimes(path string, timeval *[2]Timeval) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0) + _, _, e1 := syscall_syscall(libc_utimes_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_utimes_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_utimes utimes "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func futimes(fd int, timeval *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0) + _, _, e1 := syscall_syscall(libc_futimes_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_futimes_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_futimes futimes "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { - r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + r0, _, e1 := syscall_syscall(libc_poll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -249,6 +329,10 @@ func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { return } +var libc_poll_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_poll poll "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Madvise(b []byte, behav int) (err error) { @@ -258,13 +342,17 @@ func Madvise(b []byte, behav int) (err error) { } else { _p0 = unsafe.Pointer(&_zero) } - _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + _, _, e1 := syscall_syscall(libc_madvise_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(behav)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_madvise_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_madvise madvise "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Mlock(b []byte) (err error) { @@ -274,23 +362,31 @@ func Mlock(b []byte) (err error) { } else { _p0 = unsafe.Pointer(&_zero) } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + _, _, e1 := syscall_syscall(libc_mlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_mlock_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mlock mlock "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + _, _, e1 := syscall_syscall(libc_mlockall_trampoline_addr, uintptr(flags), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_mlockall_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mlockall mlockall "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Mprotect(b []byte, prot int) (err error) { @@ -300,13 +396,17 @@ func Mprotect(b []byte, prot int) (err error) { } else { _p0 = unsafe.Pointer(&_zero) } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + _, _, e1 := syscall_syscall(libc_mprotect_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(prot)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_mprotect_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mprotect mprotect "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Msync(b []byte, flags int) (err error) { @@ -316,13 +416,17 @@ func Msync(b []byte, flags int) (err error) { } else { _p0 = unsafe.Pointer(&_zero) } - _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + _, _, e1 := syscall_syscall(libc_msync_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(flags)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_msync_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_msync msync "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Munlock(b []byte) (err error) { @@ -332,33 +436,45 @@ func Munlock(b []byte) (err error) { } else { _p0 = unsafe.Pointer(&_zero) } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + _, _, e1 := syscall_syscall(libc_munlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_munlock_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_munlock munlock "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + _, _, e1 := syscall_syscall(libc_munlockall_trampoline_addr, 0, 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_munlockall_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_munlockall munlockall "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func pipe2(p *[2]_C_int, flags int) (err error) { - _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) + _, _, e1 := syscall_rawSyscall(libc_pipe2_trampoline_addr, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_pipe2_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getdents(fd int, buf []byte) (n int, err error) { @@ -368,7 +484,7 @@ func Getdents(fd int, buf []byte) (n int, err error) { } else { _p0 = unsafe.Pointer(&_zero) } - r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf))) + r0, _, e1 := syscall_syscall(libc_getdents_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(buf))) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -376,6 +492,10 @@ func Getdents(fd int, buf []byte) (n int, err error) { return } +var libc_getdents_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getdents getdents "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getcwd(buf []byte) (n int, err error) { @@ -385,7 +505,7 @@ func Getcwd(buf []byte) (n int, err error) { } else { _p0 = unsafe.Pointer(&_zero) } - r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + r0, _, e1 := syscall_syscall(libc_getcwd_trampoline_addr, uintptr(_p0), uintptr(len(buf)), 0) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -393,16 +513,32 @@ func Getcwd(buf []byte) (n int, err error) { return } +var libc_getcwd_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getcwd getcwd "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func ioctl(fd int, req uint, arg uintptr) (err error) { - _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { err = errnoErr(e1) } return } +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_ioctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { @@ -412,17 +548,21 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) } else { _p0 = unsafe.Pointer(&_zero) } - _, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) + _, _, e1 := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_sysctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_sysctl sysctl "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { - r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0) + r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -430,6 +570,10 @@ func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, return } +var libc_ppoll_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ppoll ppoll "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Access(path string, mode uint32) (err error) { @@ -438,23 +582,31 @@ func Access(path string, mode uint32) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + _, _, e1 := syscall_syscall(libc_access_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_access_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_access access "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { - _, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0) + _, _, e1 := syscall_syscall(libc_adjtime_trampoline_addr, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_adjtime_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_adjtime adjtime "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Chdir(path string) (err error) { @@ -463,13 +615,17 @@ func Chdir(path string) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) + _, _, e1 := syscall_syscall(libc_chdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_chdir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chdir chdir "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Chflags(path string, flags int) (err error) { @@ -478,13 +634,17 @@ func Chflags(path string, flags int) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + _, _, e1 := syscall_syscall(libc_chflags_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_chflags_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chflags chflags "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Chmod(path string, mode uint32) (err error) { @@ -493,13 +653,17 @@ func Chmod(path string, mode uint32) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + _, _, e1 := syscall_syscall(libc_chmod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_chmod_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chmod chmod "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Chown(path string, uid int, gid int) (err error) { @@ -508,13 +672,17 @@ func Chown(path string, uid int, gid int) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) + _, _, e1 := syscall_syscall(libc_chown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_chown_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chown chown "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Chroot(path string) (err error) { @@ -523,27 +691,49 @@ func Chroot(path string) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0) + _, _, e1 := syscall_syscall(libc_chroot_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_chroot_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chroot chroot "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := syscall_syscall(libc_clock_gettime_trampoline_addr, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_clock_gettime_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Close(fd int) (err error) { - _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) + _, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_close_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_close close "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Dup(fd int) (nfd int, err error) { - r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0) + r0, _, e1 := syscall_syscall(libc_dup_trampoline_addr, uintptr(fd), 0, 0) nfd = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -551,33 +741,49 @@ func Dup(fd int) (nfd int, err error) { return } +var libc_dup_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_dup dup "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Dup2(from int, to int) (err error) { - _, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0) + _, _, e1 := syscall_syscall(libc_dup2_trampoline_addr, uintptr(from), uintptr(to), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_dup2_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_dup2 dup2 "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Dup3(from int, to int, flags int) (err error) { - _, _, e1 := Syscall(SYS_DUP3, uintptr(from), uintptr(to), uintptr(flags)) + _, _, e1 := syscall_syscall(libc_dup3_trampoline_addr, uintptr(from), uintptr(to), uintptr(flags)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_dup3_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_dup3 dup3 "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Exit(code int) { - Syscall(SYS_EXIT, uintptr(code), 0, 0) + syscall_syscall(libc_exit_trampoline_addr, uintptr(code), 0, 0) return } +var libc_exit_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_exit exit "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { @@ -586,43 +792,59 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { if err != nil { return } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + _, _, e1 := syscall_syscall6(libc_faccessat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_faccessat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_faccessat faccessat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Fchdir(fd int) (err error) { - _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) + _, _, e1 := syscall_syscall(libc_fchdir_trampoline_addr, uintptr(fd), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_fchdir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchdir fchdir "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Fchflags(fd int, flags int) (err error) { - _, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0) + _, _, e1 := syscall_syscall(libc_fchflags_trampoline_addr, uintptr(fd), uintptr(flags), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_fchflags_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchflags fchflags "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Fchmod(fd int, mode uint32) (err error) { - _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0) + _, _, e1 := syscall_syscall(libc_fchmod_trampoline_addr, uintptr(fd), uintptr(mode), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_fchmod_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchmod fchmod "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { @@ -631,23 +853,31 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { if err != nil { return } - _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + _, _, e1 := syscall_syscall6(libc_fchmodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_fchmodat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Fchown(fd int, uid int, gid int) (err error) { - _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) + _, _, e1 := syscall_syscall(libc_fchown_trampoline_addr, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_fchown_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchown fchown "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { @@ -656,27 +886,35 @@ func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { if err != nil { return } - _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) + _, _, e1 := syscall_syscall6(libc_fchownat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_fchownat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchownat fchownat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Flock(fd int, how int) (err error) { - _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) + _, _, e1 := syscall_syscall(libc_flock_trampoline_addr, uintptr(fd), uintptr(how), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_flock_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_flock flock "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Fpathconf(fd int, name int) (val int, err error) { - r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0) + r0, _, e1 := syscall_syscall(libc_fpathconf_trampoline_addr, uintptr(fd), uintptr(name), 0) val = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -684,16 +922,24 @@ func Fpathconf(fd int, name int) (val int, err error) { return } +var libc_fpathconf_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Fstat(fd int, stat *Stat_t) (err error) { - _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + _, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_fstat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fstat fstat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { @@ -702,71 +948,99 @@ func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { if err != nil { return } - _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + _, _, e1 := syscall_syscall6(libc_fstatat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_fstatat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fstatat fstatat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Fstatfs(fd int, stat *Statfs_t) (err error) { - _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + _, _, e1 := syscall_syscall(libc_fstatfs_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_fstatfs_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fstatfs fstatfs "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Fsync(fd int) (err error) { - _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) + _, _, e1 := syscall_syscall(libc_fsync_trampoline_addr, uintptr(fd), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_fsync_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fsync fsync "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Ftruncate(fd int, length int64) (err error) { - _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length)) + _, _, e1 := syscall_syscall(libc_ftruncate_trampoline_addr, uintptr(fd), uintptr(length), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_ftruncate_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) + r0, _, _ := syscall_rawSyscall(libc_getegid_trampoline_addr, 0, 0, 0) egid = int(r0) return } +var libc_getegid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getegid getegid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Geteuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) + r0, _, _ := syscall_rawSyscall(libc_geteuid_trampoline_addr, 0, 0, 0) uid = int(r0) return } +var libc_geteuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_geteuid geteuid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) + r0, _, _ := syscall_rawSyscall(libc_getgid_trampoline_addr, 0, 0, 0) gid = int(r0) return } +var libc_getgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getgid getgid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpgid(pid int) (pgid int, err error) { - r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0) + r0, _, e1 := syscall_rawSyscall(libc_getpgid_trampoline_addr, uintptr(pid), 0, 0) pgid = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -774,34 +1048,50 @@ func Getpgid(pid int) (pgid int, err error) { return } +var libc_getpgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpgid getpgid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpgrp() (pgrp int) { - r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0) + r0, _, _ := syscall_rawSyscall(libc_getpgrp_trampoline_addr, 0, 0, 0) pgrp = int(r0) return } +var libc_getpgrp_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + r0, _, _ := syscall_rawSyscall(libc_getpid_trampoline_addr, 0, 0, 0) pid = int(r0) return } +var libc_getpid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpid getpid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + r0, _, _ := syscall_rawSyscall(libc_getppid_trampoline_addr, 0, 0, 0) ppid = int(r0) return } +var libc_getppid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getppid getppid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpriority(which int, who int) (prio int, err error) { - r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0) + r0, _, e1 := syscall_syscall(libc_getpriority_trampoline_addr, uintptr(which), uintptr(who), 0) prio = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -809,20 +1099,28 @@ func Getpriority(which int, who int) (prio int, err error) { return } +var libc_getpriority_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpriority getpriority "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) + _, _, e1 := syscall_rawSyscall(libc_getrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_getrlimit_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getrtable() (rtable int, err error) { - r0, _, e1 := RawSyscall(SYS_GETRTABLE, 0, 0, 0) + r0, _, e1 := syscall_rawSyscall(libc_getrtable_trampoline_addr, 0, 0, 0) rtable = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -830,20 +1128,28 @@ func Getrtable() (rtable int, err error) { return } +var libc_getrtable_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getrtable getrtable "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getrusage(who int, rusage *Rusage) (err error) { - _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) + _, _, e1 := syscall_rawSyscall(libc_getrusage_trampoline_addr, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_getrusage_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getrusage getrusage "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getsid(pid int) (sid int, err error) { - r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + r0, _, e1 := syscall_rawSyscall(libc_getsid_trampoline_addr, uintptr(pid), 0, 0) sid = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -851,46 +1157,66 @@ func Getsid(pid int) (sid int, err error) { return } +var libc_getsid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getsid getsid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Gettimeofday(tv *Timeval) (err error) { - _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) + _, _, e1 := syscall_rawSyscall(libc_gettimeofday_trampoline_addr, uintptr(unsafe.Pointer(tv)), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_gettimeofday_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) + r0, _, _ := syscall_rawSyscall(libc_getuid_trampoline_addr, 0, 0, 0) uid = int(r0) return } +var libc_getuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getuid getuid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Issetugid() (tainted bool) { - r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0) + r0, _, _ := syscall_syscall(libc_issetugid_trampoline_addr, 0, 0, 0) tainted = bool(r0 != 0) return } +var libc_issetugid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_issetugid issetugid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Kill(pid int, signum syscall.Signal) (err error) { - _, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0) + _, _, e1 := syscall_syscall(libc_kill_trampoline_addr, uintptr(pid), uintptr(signum), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_kill_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_kill kill "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Kqueue() (fd int, err error) { - r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0) + r0, _, e1 := syscall_syscall(libc_kqueue_trampoline_addr, 0, 0, 0) fd = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -898,6 +1224,10 @@ func Kqueue() (fd int, err error) { return } +var libc_kqueue_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_kqueue kqueue "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Lchown(path string, uid int, gid int) (err error) { @@ -906,13 +1236,17 @@ func Lchown(path string, uid int, gid int) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) + _, _, e1 := syscall_syscall(libc_lchown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_lchown_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_lchown lchown "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Link(path string, link string) (err error) { @@ -926,13 +1260,17 @@ func Link(path string, link string) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + _, _, e1 := syscall_syscall(libc_link_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_link_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_link link "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) { @@ -946,23 +1284,31 @@ func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err er if err != nil { return } - _, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + _, _, e1 := syscall_syscall6(libc_linkat_trampoline_addr, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_linkat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_linkat linkat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Listen(s int, backlog int) (err error) { - _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0) + _, _, e1 := syscall_syscall(libc_listen_trampoline_addr, uintptr(s), uintptr(backlog), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_listen_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_listen listen "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Lstat(path string, stat *Stat_t) (err error) { @@ -971,13 +1317,17 @@ func Lstat(path string, stat *Stat_t) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + _, _, e1 := syscall_syscall(libc_lstat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_lstat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_lstat lstat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Mkdir(path string, mode uint32) (err error) { @@ -986,13 +1336,17 @@ func Mkdir(path string, mode uint32) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + _, _, e1 := syscall_syscall(libc_mkdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_mkdir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mkdir mkdir "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Mkdirat(dirfd int, path string, mode uint32) (err error) { @@ -1001,13 +1355,17 @@ func Mkdirat(dirfd int, path string, mode uint32) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + _, _, e1 := syscall_syscall(libc_mkdirat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_mkdirat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mkdirat mkdirat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Mkfifo(path string, mode uint32) (err error) { @@ -1016,13 +1374,17 @@ func Mkfifo(path string, mode uint32) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + _, _, e1 := syscall_syscall(libc_mkfifo_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_mkfifo_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Mkfifoat(dirfd int, path string, mode uint32) (err error) { @@ -1031,13 +1393,17 @@ func Mkfifoat(dirfd int, path string, mode uint32) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_MKFIFOAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + _, _, e1 := syscall_syscall(libc_mkfifoat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_mkfifoat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mkfifoat mkfifoat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Mknod(path string, mode uint32, dev int) (err error) { @@ -1046,13 +1412,17 @@ func Mknod(path string, mode uint32, dev int) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev)) + _, _, e1 := syscall_syscall(libc_mknod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_mknod_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mknod mknod "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { @@ -1061,23 +1431,31 @@ func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { if err != nil { return } - _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) + _, _, e1 := syscall_syscall6(libc_mknodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_mknodat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mknodat mknodat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Nanosleep(time *Timespec, leftover *Timespec) (err error) { - _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) + _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_nanosleep_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Open(path string, mode int, perm uint32) (fd int, err error) { @@ -1086,7 +1464,7 @@ func Open(path string, mode int, perm uint32) (fd int, err error) { if err != nil { return } - r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) + r0, _, e1 := syscall_syscall(libc_open_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) fd = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1094,6 +1472,10 @@ func Open(path string, mode int, perm uint32) (fd int, err error) { return } +var libc_open_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_open open "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) { @@ -1102,7 +1484,7 @@ func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) { if err != nil { return } - r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0) + r0, _, e1 := syscall_syscall6(libc_openat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0) fd = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1110,6 +1492,10 @@ func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) { return } +var libc_openat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_openat openat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Pathconf(path string, name int) (val int, err error) { @@ -1118,7 +1504,7 @@ func Pathconf(path string, name int) (val int, err error) { if err != nil { return } - r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0) + r0, _, e1 := syscall_syscall(libc_pathconf_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0) val = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1126,6 +1512,10 @@ func Pathconf(path string, name int) (val int, err error) { return } +var libc_pathconf_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pathconf pathconf "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func pread(fd int, p []byte, offset int64) (n int, err error) { @@ -1135,7 +1525,7 @@ func pread(fd int, p []byte, offset int64) (n int, err error) { } else { _p0 = unsafe.Pointer(&_zero) } - r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0) + r0, _, e1 := syscall_syscall6(libc_pread_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1143,6 +1533,10 @@ func pread(fd int, p []byte, offset int64) (n int, err error) { return } +var libc_pread_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pread pread "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func pwrite(fd int, p []byte, offset int64) (n int, err error) { @@ -1152,7 +1546,7 @@ func pwrite(fd int, p []byte, offset int64) (n int, err error) { } else { _p0 = unsafe.Pointer(&_zero) } - r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0) + r0, _, e1 := syscall_syscall6(libc_pwrite_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1160,6 +1554,10 @@ func pwrite(fd int, p []byte, offset int64) (n int, err error) { return } +var libc_pwrite_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pwrite pwrite "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func read(fd int, p []byte) (n int, err error) { @@ -1169,7 +1567,7 @@ func read(fd int, p []byte) (n int, err error) { } else { _p0 = unsafe.Pointer(&_zero) } - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p))) + r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p))) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1177,6 +1575,10 @@ func read(fd int, p []byte) (n int, err error) { return } +var libc_read_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_read read "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Readlink(path string, buf []byte) (n int, err error) { @@ -1191,7 +1593,7 @@ func Readlink(path string, buf []byte) (n int, err error) { } else { _p1 = unsafe.Pointer(&_zero) } - r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))) + r0, _, e1 := syscall_syscall(libc_readlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1199,6 +1601,10 @@ func Readlink(path string, buf []byte) (n int, err error) { return } +var libc_readlink_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_readlink readlink "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { @@ -1213,7 +1619,7 @@ func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { } else { _p1 = unsafe.Pointer(&_zero) } - r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) + r0, _, e1 := syscall_syscall6(libc_readlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1221,6 +1627,10 @@ func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { return } +var libc_readlinkat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_readlinkat readlinkat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Rename(from string, to string) (err error) { @@ -1234,13 +1644,17 @@ func Rename(from string, to string) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + _, _, e1 := syscall_syscall(libc_rename_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_rename_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_rename rename "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Renameat(fromfd int, from string, tofd int, to string) (err error) { @@ -1254,13 +1668,17 @@ func Renameat(fromfd int, from string, tofd int, to string) (err error) { if err != nil { return } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0) + _, _, e1 := syscall_syscall6(libc_renameat_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_renameat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_renameat renameat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Revoke(path string) (err error) { @@ -1269,13 +1687,17 @@ func Revoke(path string) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0) + _, _, e1 := syscall_syscall(libc_revoke_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_revoke_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_revoke revoke "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Rmdir(path string) (err error) { @@ -1284,17 +1706,21 @@ func Rmdir(path string) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) + _, _, e1 := syscall_syscall(libc_rmdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_rmdir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_rmdir rmdir "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { - r0, _, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(whence), 0, 0) + r0, _, e1 := syscall_syscall(libc_lseek_trampoline_addr, uintptr(fd), uintptr(offset), uintptr(whence)) newoffset = int64(r0) if e1 != 0 { err = errnoErr(e1) @@ -1302,10 +1728,14 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { return } +var libc_lseek_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_lseek lseek "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { - r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) + r0, _, e1 := syscall_syscall6(libc_select_trampoline_addr, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1313,36 +1743,52 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err return } +var libc_select_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_select select "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Setegid(egid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0) + _, _, e1 := syscall_rawSyscall(libc_setegid_trampoline_addr, uintptr(egid), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_setegid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setegid setegid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Seteuid(euid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0) + _, _, e1 := syscall_rawSyscall(libc_seteuid_trampoline_addr, uintptr(euid), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_seteuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_seteuid seteuid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Setgid(gid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0) + _, _, e1 := syscall_rawSyscall(libc_setgid_trampoline_addr, uintptr(gid), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_setgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setgid setgid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Setlogin(name string) (err error) { @@ -1351,97 +1797,133 @@ func Setlogin(name string) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0) + _, _, e1 := syscall_syscall(libc_setlogin_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_setlogin_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setlogin setlogin "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Setpgid(pid int, pgid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0) + _, _, e1 := syscall_rawSyscall(libc_setpgid_trampoline_addr, uintptr(pid), uintptr(pgid), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_setpgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setpgid setpgid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Setpriority(which int, who int, prio int) (err error) { - _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) + _, _, e1 := syscall_syscall(libc_setpriority_trampoline_addr, uintptr(which), uintptr(who), uintptr(prio)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_setpriority_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setpriority setpriority "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Setregid(rgid int, egid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0) + _, _, e1 := syscall_rawSyscall(libc_setregid_trampoline_addr, uintptr(rgid), uintptr(egid), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_setregid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setregid setregid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Setreuid(ruid int, euid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0) + _, _, e1 := syscall_rawSyscall(libc_setreuid_trampoline_addr, uintptr(ruid), uintptr(euid), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_setreuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setreuid setreuid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Setresgid(rgid int, egid int, sgid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)) + _, _, e1 := syscall_rawSyscall(libc_setresgid_trampoline_addr, uintptr(rgid), uintptr(egid), uintptr(sgid)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_setresgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setresgid setresgid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Setresuid(ruid int, euid int, suid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)) + _, _, e1 := syscall_rawSyscall(libc_setresuid_trampoline_addr, uintptr(ruid), uintptr(euid), uintptr(suid)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_setresuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setresuid setresuid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) + _, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_setrlimit_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Setrtable(rtable int) (err error) { - _, _, e1 := RawSyscall(SYS_SETRTABLE, uintptr(rtable), 0, 0) + _, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_setrtable_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setrtable setrtable "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Setsid() (pid int, err error) { - r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) + r0, _, e1 := syscall_rawSyscall(libc_setsid_trampoline_addr, 0, 0, 0) pid = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1449,26 +1931,38 @@ func Setsid() (pid int, err error) { return } +var libc_setsid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setsid setsid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Settimeofday(tp *Timeval) (err error) { - _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0) + _, _, e1 := syscall_rawSyscall(libc_settimeofday_trampoline_addr, uintptr(unsafe.Pointer(tp)), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_settimeofday_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_settimeofday settimeofday "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Setuid(uid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0) + _, _, e1 := syscall_rawSyscall(libc_setuid_trampoline_addr, uintptr(uid), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_setuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setuid setuid "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Stat(path string, stat *Stat_t) (err error) { @@ -1477,13 +1971,17 @@ func Stat(path string, stat *Stat_t) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + _, _, e1 := syscall_syscall(libc_stat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_stat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_stat stat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Statfs(path string, stat *Statfs_t) (err error) { @@ -1492,13 +1990,17 @@ func Statfs(path string, stat *Statfs_t) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + _, _, e1 := syscall_syscall(libc_statfs_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_statfs_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_statfs statfs "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Symlink(path string, link string) (err error) { @@ -1512,13 +2014,17 @@ func Symlink(path string, link string) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + _, _, e1 := syscall_syscall(libc_symlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_symlink_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_symlink symlink "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { @@ -1532,23 +2038,31 @@ func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) + _, _, e1 := syscall_syscall(libc_symlinkat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) if e1 != 0 { err = errnoErr(e1) } return } +var libc_symlinkat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_symlinkat symlinkat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Sync() (err error) { - _, _, e1 := Syscall(SYS_SYNC, 0, 0, 0) + _, _, e1 := syscall_syscall(libc_sync_trampoline_addr, 0, 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_sync_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_sync sync "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Truncate(path string, length int64) (err error) { @@ -1557,21 +2071,29 @@ func Truncate(path string, length int64) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length)) + _, _, e1 := syscall_syscall(libc_truncate_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_truncate_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_truncate truncate "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Umask(newmask int) (oldmask int) { - r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0) + r0, _, _ := syscall_syscall(libc_umask_trampoline_addr, uintptr(newmask), 0, 0) oldmask = int(r0) return } +var libc_umask_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_umask umask "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Unlink(path string) (err error) { @@ -1580,13 +2102,17 @@ func Unlink(path string) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0) + _, _, e1 := syscall_syscall(libc_unlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_unlink_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_unlink unlink "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Unlinkat(dirfd int, path string, flags int) (err error) { @@ -1595,13 +2121,17 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) + _, _, e1 := syscall_syscall(libc_unlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) if e1 != 0 { err = errnoErr(e1) } return } +var libc_unlinkat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Unmount(path string, flags int) (err error) { @@ -1610,13 +2140,17 @@ func Unmount(path string, flags int) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + _, _, e1 := syscall_syscall(libc_unmount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_unmount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_unmount unmount "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func write(fd int, p []byte) (n int, err error) { @@ -1626,7 +2160,7 @@ func write(fd int, p []byte) (n int, err error) { } else { _p0 = unsafe.Pointer(&_zero) } - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p))) + r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p))) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1634,10 +2168,14 @@ func write(fd int, p []byte) (n int, err error) { return } +var libc_write_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_write write "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) { - r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), 0, 0) + r0, _, e1 := syscall_syscall6(libc_mmap_trampoline_addr, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos)) ret = uintptr(r0) if e1 != 0 { err = errnoErr(e1) @@ -1645,20 +2183,28 @@ func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) ( return } +var libc_mmap_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mmap mmap "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func munmap(addr uintptr, length uintptr) (err error) { - _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0) + _, _, e1 := syscall_syscall(libc_munmap_trampoline_addr, uintptr(addr), uintptr(length), 0) if e1 != 0 { err = errnoErr(e1) } return } +var libc_munmap_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_munmap munmap "libc.so" + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) + r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1669,7 +2215,7 @@ func readlen(fd int, buf *byte, nbuf int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) + r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1685,9 +2231,13 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error if err != nil { return } - _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + _, _, e1 := syscall_syscall6(libc_utimensat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) if e1 != 0 { err = errnoErr(e1) } return } + +var libc_utimensat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_utimensat utimensat "libc.so" diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s new file mode 100644 index 0000000000..55af27263a --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s @@ -0,0 +1,669 @@ +// go run mkasm.go openbsd mips64 +// Code generated by the command above; DO NOT EDIT. + +#include "textflag.h" + +TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getgroups(SB) +GLOBL ·libc_getgroups_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getgroups_trampoline_addr(SB)/8, $libc_getgroups_trampoline<>(SB) + +TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setgroups(SB) +GLOBL ·libc_setgroups_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setgroups_trampoline_addr(SB)/8, $libc_setgroups_trampoline<>(SB) + +TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_wait4(SB) +GLOBL ·libc_wait4_trampoline_addr(SB), RODATA, $8 +DATA ·libc_wait4_trampoline_addr(SB)/8, $libc_wait4_trampoline<>(SB) + +TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_accept(SB) +GLOBL ·libc_accept_trampoline_addr(SB), RODATA, $8 +DATA ·libc_accept_trampoline_addr(SB)/8, $libc_accept_trampoline<>(SB) + +TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_bind(SB) +GLOBL ·libc_bind_trampoline_addr(SB), RODATA, $8 +DATA ·libc_bind_trampoline_addr(SB)/8, $libc_bind_trampoline<>(SB) + +TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_connect(SB) +GLOBL ·libc_connect_trampoline_addr(SB), RODATA, $8 +DATA ·libc_connect_trampoline_addr(SB)/8, $libc_connect_trampoline<>(SB) + +TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_socket(SB) +GLOBL ·libc_socket_trampoline_addr(SB), RODATA, $8 +DATA ·libc_socket_trampoline_addr(SB)/8, $libc_socket_trampoline<>(SB) + +TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getsockopt(SB) +GLOBL ·libc_getsockopt_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getsockopt_trampoline_addr(SB)/8, $libc_getsockopt_trampoline<>(SB) + +TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setsockopt(SB) +GLOBL ·libc_setsockopt_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setsockopt_trampoline_addr(SB)/8, $libc_setsockopt_trampoline<>(SB) + +TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getpeername(SB) +GLOBL ·libc_getpeername_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpeername_trampoline_addr(SB)/8, $libc_getpeername_trampoline<>(SB) + +TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getsockname(SB) +GLOBL ·libc_getsockname_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getsockname_trampoline_addr(SB)/8, $libc_getsockname_trampoline<>(SB) + +TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_shutdown(SB) +GLOBL ·libc_shutdown_trampoline_addr(SB), RODATA, $8 +DATA ·libc_shutdown_trampoline_addr(SB)/8, $libc_shutdown_trampoline<>(SB) + +TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_socketpair(SB) +GLOBL ·libc_socketpair_trampoline_addr(SB), RODATA, $8 +DATA ·libc_socketpair_trampoline_addr(SB)/8, $libc_socketpair_trampoline<>(SB) + +TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_recvfrom(SB) +GLOBL ·libc_recvfrom_trampoline_addr(SB), RODATA, $8 +DATA ·libc_recvfrom_trampoline_addr(SB)/8, $libc_recvfrom_trampoline<>(SB) + +TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_sendto(SB) +GLOBL ·libc_sendto_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sendto_trampoline_addr(SB)/8, $libc_sendto_trampoline<>(SB) + +TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_recvmsg(SB) +GLOBL ·libc_recvmsg_trampoline_addr(SB), RODATA, $8 +DATA ·libc_recvmsg_trampoline_addr(SB)/8, $libc_recvmsg_trampoline<>(SB) + +TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_sendmsg(SB) +GLOBL ·libc_sendmsg_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sendmsg_trampoline_addr(SB)/8, $libc_sendmsg_trampoline<>(SB) + +TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_kevent(SB) +GLOBL ·libc_kevent_trampoline_addr(SB), RODATA, $8 +DATA ·libc_kevent_trampoline_addr(SB)/8, $libc_kevent_trampoline<>(SB) + +TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_utimes(SB) +GLOBL ·libc_utimes_trampoline_addr(SB), RODATA, $8 +DATA ·libc_utimes_trampoline_addr(SB)/8, $libc_utimes_trampoline<>(SB) + +TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_futimes(SB) +GLOBL ·libc_futimes_trampoline_addr(SB), RODATA, $8 +DATA ·libc_futimes_trampoline_addr(SB)/8, $libc_futimes_trampoline<>(SB) + +TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_poll(SB) +GLOBL ·libc_poll_trampoline_addr(SB), RODATA, $8 +DATA ·libc_poll_trampoline_addr(SB)/8, $libc_poll_trampoline<>(SB) + +TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_madvise(SB) +GLOBL ·libc_madvise_trampoline_addr(SB), RODATA, $8 +DATA ·libc_madvise_trampoline_addr(SB)/8, $libc_madvise_trampoline<>(SB) + +TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mlock(SB) +GLOBL ·libc_mlock_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mlock_trampoline_addr(SB)/8, $libc_mlock_trampoline<>(SB) + +TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mlockall(SB) +GLOBL ·libc_mlockall_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mlockall_trampoline_addr(SB)/8, $libc_mlockall_trampoline<>(SB) + +TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mprotect(SB) +GLOBL ·libc_mprotect_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mprotect_trampoline_addr(SB)/8, $libc_mprotect_trampoline<>(SB) + +TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_msync(SB) +GLOBL ·libc_msync_trampoline_addr(SB), RODATA, $8 +DATA ·libc_msync_trampoline_addr(SB)/8, $libc_msync_trampoline<>(SB) + +TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_munlock(SB) +GLOBL ·libc_munlock_trampoline_addr(SB), RODATA, $8 +DATA ·libc_munlock_trampoline_addr(SB)/8, $libc_munlock_trampoline<>(SB) + +TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_munlockall(SB) +GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8 +DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB) + +TEXT libc_pipe2_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pipe2(SB) +GLOBL ·libc_pipe2_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pipe2_trampoline_addr(SB)/8, $libc_pipe2_trampoline<>(SB) + +TEXT libc_getdents_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getdents(SB) +GLOBL ·libc_getdents_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getdents_trampoline_addr(SB)/8, $libc_getdents_trampoline<>(SB) + +TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getcwd(SB) +GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB) + +TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_ioctl(SB) +GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 +DATA ·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB) + +TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_sysctl(SB) +GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) + +TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_ppoll(SB) +GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $8 +DATA ·libc_ppoll_trampoline_addr(SB)/8, $libc_ppoll_trampoline<>(SB) + +TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_access(SB) +GLOBL ·libc_access_trampoline_addr(SB), RODATA, $8 +DATA ·libc_access_trampoline_addr(SB)/8, $libc_access_trampoline<>(SB) + +TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_adjtime(SB) +GLOBL ·libc_adjtime_trampoline_addr(SB), RODATA, $8 +DATA ·libc_adjtime_trampoline_addr(SB)/8, $libc_adjtime_trampoline<>(SB) + +TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_chdir(SB) +GLOBL ·libc_chdir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chdir_trampoline_addr(SB)/8, $libc_chdir_trampoline<>(SB) + +TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_chflags(SB) +GLOBL ·libc_chflags_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chflags_trampoline_addr(SB)/8, $libc_chflags_trampoline<>(SB) + +TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_chmod(SB) +GLOBL ·libc_chmod_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chmod_trampoline_addr(SB)/8, $libc_chmod_trampoline<>(SB) + +TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_chown(SB) +GLOBL ·libc_chown_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chown_trampoline_addr(SB)/8, $libc_chown_trampoline<>(SB) + +TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_chroot(SB) +GLOBL ·libc_chroot_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chroot_trampoline_addr(SB)/8, $libc_chroot_trampoline<>(SB) + +TEXT libc_clock_gettime_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_clock_gettime(SB) +GLOBL ·libc_clock_gettime_trampoline_addr(SB), RODATA, $8 +DATA ·libc_clock_gettime_trampoline_addr(SB)/8, $libc_clock_gettime_trampoline<>(SB) + +TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_close(SB) +GLOBL ·libc_close_trampoline_addr(SB), RODATA, $8 +DATA ·libc_close_trampoline_addr(SB)/8, $libc_close_trampoline<>(SB) + +TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_dup(SB) +GLOBL ·libc_dup_trampoline_addr(SB), RODATA, $8 +DATA ·libc_dup_trampoline_addr(SB)/8, $libc_dup_trampoline<>(SB) + +TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_dup2(SB) +GLOBL ·libc_dup2_trampoline_addr(SB), RODATA, $8 +DATA ·libc_dup2_trampoline_addr(SB)/8, $libc_dup2_trampoline<>(SB) + +TEXT libc_dup3_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_dup3(SB) +GLOBL ·libc_dup3_trampoline_addr(SB), RODATA, $8 +DATA ·libc_dup3_trampoline_addr(SB)/8, $libc_dup3_trampoline<>(SB) + +TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_exit(SB) +GLOBL ·libc_exit_trampoline_addr(SB), RODATA, $8 +DATA ·libc_exit_trampoline_addr(SB)/8, $libc_exit_trampoline<>(SB) + +TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_faccessat(SB) +GLOBL ·libc_faccessat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_faccessat_trampoline_addr(SB)/8, $libc_faccessat_trampoline<>(SB) + +TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fchdir(SB) +GLOBL ·libc_fchdir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchdir_trampoline_addr(SB)/8, $libc_fchdir_trampoline<>(SB) + +TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fchflags(SB) +GLOBL ·libc_fchflags_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchflags_trampoline_addr(SB)/8, $libc_fchflags_trampoline<>(SB) + +TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fchmod(SB) +GLOBL ·libc_fchmod_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchmod_trampoline_addr(SB)/8, $libc_fchmod_trampoline<>(SB) + +TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fchmodat(SB) +GLOBL ·libc_fchmodat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchmodat_trampoline_addr(SB)/8, $libc_fchmodat_trampoline<>(SB) + +TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fchown(SB) +GLOBL ·libc_fchown_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchown_trampoline_addr(SB)/8, $libc_fchown_trampoline<>(SB) + +TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fchownat(SB) +GLOBL ·libc_fchownat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchownat_trampoline_addr(SB)/8, $libc_fchownat_trampoline<>(SB) + +TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_flock(SB) +GLOBL ·libc_flock_trampoline_addr(SB), RODATA, $8 +DATA ·libc_flock_trampoline_addr(SB)/8, $libc_flock_trampoline<>(SB) + +TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fpathconf(SB) +GLOBL ·libc_fpathconf_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fpathconf_trampoline_addr(SB)/8, $libc_fpathconf_trampoline<>(SB) + +TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fstat(SB) +GLOBL ·libc_fstat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fstat_trampoline_addr(SB)/8, $libc_fstat_trampoline<>(SB) + +TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fstatat(SB) +GLOBL ·libc_fstatat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fstatat_trampoline_addr(SB)/8, $libc_fstatat_trampoline<>(SB) + +TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fstatfs(SB) +GLOBL ·libc_fstatfs_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fstatfs_trampoline_addr(SB)/8, $libc_fstatfs_trampoline<>(SB) + +TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fsync(SB) +GLOBL ·libc_fsync_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fsync_trampoline_addr(SB)/8, $libc_fsync_trampoline<>(SB) + +TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_ftruncate(SB) +GLOBL ·libc_ftruncate_trampoline_addr(SB), RODATA, $8 +DATA ·libc_ftruncate_trampoline_addr(SB)/8, $libc_ftruncate_trampoline<>(SB) + +TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getegid(SB) +GLOBL ·libc_getegid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getegid_trampoline_addr(SB)/8, $libc_getegid_trampoline<>(SB) + +TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_geteuid(SB) +GLOBL ·libc_geteuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_geteuid_trampoline_addr(SB)/8, $libc_geteuid_trampoline<>(SB) + +TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getgid(SB) +GLOBL ·libc_getgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getgid_trampoline_addr(SB)/8, $libc_getgid_trampoline<>(SB) + +TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getpgid(SB) +GLOBL ·libc_getpgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpgid_trampoline_addr(SB)/8, $libc_getpgid_trampoline<>(SB) + +TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getpgrp(SB) +GLOBL ·libc_getpgrp_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpgrp_trampoline_addr(SB)/8, $libc_getpgrp_trampoline<>(SB) + +TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getpid(SB) +GLOBL ·libc_getpid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpid_trampoline_addr(SB)/8, $libc_getpid_trampoline<>(SB) + +TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getppid(SB) +GLOBL ·libc_getppid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getppid_trampoline_addr(SB)/8, $libc_getppid_trampoline<>(SB) + +TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getpriority(SB) +GLOBL ·libc_getpriority_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpriority_trampoline_addr(SB)/8, $libc_getpriority_trampoline<>(SB) + +TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getrlimit(SB) +GLOBL ·libc_getrlimit_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getrlimit_trampoline_addr(SB)/8, $libc_getrlimit_trampoline<>(SB) + +TEXT libc_getrtable_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getrtable(SB) +GLOBL ·libc_getrtable_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getrtable_trampoline_addr(SB)/8, $libc_getrtable_trampoline<>(SB) + +TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getrusage(SB) +GLOBL ·libc_getrusage_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getrusage_trampoline_addr(SB)/8, $libc_getrusage_trampoline<>(SB) + +TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getsid(SB) +GLOBL ·libc_getsid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getsid_trampoline_addr(SB)/8, $libc_getsid_trampoline<>(SB) + +TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_gettimeofday(SB) +GLOBL ·libc_gettimeofday_trampoline_addr(SB), RODATA, $8 +DATA ·libc_gettimeofday_trampoline_addr(SB)/8, $libc_gettimeofday_trampoline<>(SB) + +TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getuid(SB) +GLOBL ·libc_getuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getuid_trampoline_addr(SB)/8, $libc_getuid_trampoline<>(SB) + +TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_issetugid(SB) +GLOBL ·libc_issetugid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_issetugid_trampoline_addr(SB)/8, $libc_issetugid_trampoline<>(SB) + +TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_kill(SB) +GLOBL ·libc_kill_trampoline_addr(SB), RODATA, $8 +DATA ·libc_kill_trampoline_addr(SB)/8, $libc_kill_trampoline<>(SB) + +TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_kqueue(SB) +GLOBL ·libc_kqueue_trampoline_addr(SB), RODATA, $8 +DATA ·libc_kqueue_trampoline_addr(SB)/8, $libc_kqueue_trampoline<>(SB) + +TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_lchown(SB) +GLOBL ·libc_lchown_trampoline_addr(SB), RODATA, $8 +DATA ·libc_lchown_trampoline_addr(SB)/8, $libc_lchown_trampoline<>(SB) + +TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_link(SB) +GLOBL ·libc_link_trampoline_addr(SB), RODATA, $8 +DATA ·libc_link_trampoline_addr(SB)/8, $libc_link_trampoline<>(SB) + +TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_linkat(SB) +GLOBL ·libc_linkat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_linkat_trampoline_addr(SB)/8, $libc_linkat_trampoline<>(SB) + +TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_listen(SB) +GLOBL ·libc_listen_trampoline_addr(SB), RODATA, $8 +DATA ·libc_listen_trampoline_addr(SB)/8, $libc_listen_trampoline<>(SB) + +TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_lstat(SB) +GLOBL ·libc_lstat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_lstat_trampoline_addr(SB)/8, $libc_lstat_trampoline<>(SB) + +TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mkdir(SB) +GLOBL ·libc_mkdir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mkdir_trampoline_addr(SB)/8, $libc_mkdir_trampoline<>(SB) + +TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mkdirat(SB) +GLOBL ·libc_mkdirat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mkdirat_trampoline_addr(SB)/8, $libc_mkdirat_trampoline<>(SB) + +TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mkfifo(SB) +GLOBL ·libc_mkfifo_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mkfifo_trampoline_addr(SB)/8, $libc_mkfifo_trampoline<>(SB) + +TEXT libc_mkfifoat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mkfifoat(SB) +GLOBL ·libc_mkfifoat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mkfifoat_trampoline_addr(SB)/8, $libc_mkfifoat_trampoline<>(SB) + +TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mknod(SB) +GLOBL ·libc_mknod_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mknod_trampoline_addr(SB)/8, $libc_mknod_trampoline<>(SB) + +TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mknodat(SB) +GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) + +TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_nanosleep(SB) +GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $8 +DATA ·libc_nanosleep_trampoline_addr(SB)/8, $libc_nanosleep_trampoline<>(SB) + +TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_open(SB) +GLOBL ·libc_open_trampoline_addr(SB), RODATA, $8 +DATA ·libc_open_trampoline_addr(SB)/8, $libc_open_trampoline<>(SB) + +TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_openat(SB) +GLOBL ·libc_openat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_openat_trampoline_addr(SB)/8, $libc_openat_trampoline<>(SB) + +TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pathconf(SB) +GLOBL ·libc_pathconf_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pathconf_trampoline_addr(SB)/8, $libc_pathconf_trampoline<>(SB) + +TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pread(SB) +GLOBL ·libc_pread_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pread_trampoline_addr(SB)/8, $libc_pread_trampoline<>(SB) + +TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pwrite(SB) +GLOBL ·libc_pwrite_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pwrite_trampoline_addr(SB)/8, $libc_pwrite_trampoline<>(SB) + +TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_read(SB) +GLOBL ·libc_read_trampoline_addr(SB), RODATA, $8 +DATA ·libc_read_trampoline_addr(SB)/8, $libc_read_trampoline<>(SB) + +TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_readlink(SB) +GLOBL ·libc_readlink_trampoline_addr(SB), RODATA, $8 +DATA ·libc_readlink_trampoline_addr(SB)/8, $libc_readlink_trampoline<>(SB) + +TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_readlinkat(SB) +GLOBL ·libc_readlinkat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_readlinkat_trampoline_addr(SB)/8, $libc_readlinkat_trampoline<>(SB) + +TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_rename(SB) +GLOBL ·libc_rename_trampoline_addr(SB), RODATA, $8 +DATA ·libc_rename_trampoline_addr(SB)/8, $libc_rename_trampoline<>(SB) + +TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_renameat(SB) +GLOBL ·libc_renameat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_renameat_trampoline_addr(SB)/8, $libc_renameat_trampoline<>(SB) + +TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_revoke(SB) +GLOBL ·libc_revoke_trampoline_addr(SB), RODATA, $8 +DATA ·libc_revoke_trampoline_addr(SB)/8, $libc_revoke_trampoline<>(SB) + +TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_rmdir(SB) +GLOBL ·libc_rmdir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_rmdir_trampoline_addr(SB)/8, $libc_rmdir_trampoline<>(SB) + +TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_lseek(SB) +GLOBL ·libc_lseek_trampoline_addr(SB), RODATA, $8 +DATA ·libc_lseek_trampoline_addr(SB)/8, $libc_lseek_trampoline<>(SB) + +TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_select(SB) +GLOBL ·libc_select_trampoline_addr(SB), RODATA, $8 +DATA ·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB) + +TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setegid(SB) +GLOBL ·libc_setegid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setegid_trampoline_addr(SB)/8, $libc_setegid_trampoline<>(SB) + +TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_seteuid(SB) +GLOBL ·libc_seteuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_seteuid_trampoline_addr(SB)/8, $libc_seteuid_trampoline<>(SB) + +TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setgid(SB) +GLOBL ·libc_setgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setgid_trampoline_addr(SB)/8, $libc_setgid_trampoline<>(SB) + +TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setlogin(SB) +GLOBL ·libc_setlogin_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setlogin_trampoline_addr(SB)/8, $libc_setlogin_trampoline<>(SB) + +TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setpgid(SB) +GLOBL ·libc_setpgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setpgid_trampoline_addr(SB)/8, $libc_setpgid_trampoline<>(SB) + +TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setpriority(SB) +GLOBL ·libc_setpriority_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setpriority_trampoline_addr(SB)/8, $libc_setpriority_trampoline<>(SB) + +TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setregid(SB) +GLOBL ·libc_setregid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setregid_trampoline_addr(SB)/8, $libc_setregid_trampoline<>(SB) + +TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setreuid(SB) +GLOBL ·libc_setreuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB) + +TEXT libc_setresgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setresgid(SB) +GLOBL ·libc_setresgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setresgid_trampoline_addr(SB)/8, $libc_setresgid_trampoline<>(SB) + +TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setresuid(SB) +GLOBL ·libc_setresuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setresuid_trampoline_addr(SB)/8, $libc_setresuid_trampoline<>(SB) + +TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setrlimit(SB) +GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB) + +TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setrtable(SB) +GLOBL ·libc_setrtable_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setrtable_trampoline_addr(SB)/8, $libc_setrtable_trampoline<>(SB) + +TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setsid(SB) +GLOBL ·libc_setsid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setsid_trampoline_addr(SB)/8, $libc_setsid_trampoline<>(SB) + +TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_settimeofday(SB) +GLOBL ·libc_settimeofday_trampoline_addr(SB), RODATA, $8 +DATA ·libc_settimeofday_trampoline_addr(SB)/8, $libc_settimeofday_trampoline<>(SB) + +TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setuid(SB) +GLOBL ·libc_setuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setuid_trampoline_addr(SB)/8, $libc_setuid_trampoline<>(SB) + +TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_stat(SB) +GLOBL ·libc_stat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_stat_trampoline_addr(SB)/8, $libc_stat_trampoline<>(SB) + +TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_statfs(SB) +GLOBL ·libc_statfs_trampoline_addr(SB), RODATA, $8 +DATA ·libc_statfs_trampoline_addr(SB)/8, $libc_statfs_trampoline<>(SB) + +TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_symlink(SB) +GLOBL ·libc_symlink_trampoline_addr(SB), RODATA, $8 +DATA ·libc_symlink_trampoline_addr(SB)/8, $libc_symlink_trampoline<>(SB) + +TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_symlinkat(SB) +GLOBL ·libc_symlinkat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_symlinkat_trampoline_addr(SB)/8, $libc_symlinkat_trampoline<>(SB) + +TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_sync(SB) +GLOBL ·libc_sync_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sync_trampoline_addr(SB)/8, $libc_sync_trampoline<>(SB) + +TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_truncate(SB) +GLOBL ·libc_truncate_trampoline_addr(SB), RODATA, $8 +DATA ·libc_truncate_trampoline_addr(SB)/8, $libc_truncate_trampoline<>(SB) + +TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_umask(SB) +GLOBL ·libc_umask_trampoline_addr(SB), RODATA, $8 +DATA ·libc_umask_trampoline_addr(SB)/8, $libc_umask_trampoline<>(SB) + +TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_unlink(SB) +GLOBL ·libc_unlink_trampoline_addr(SB), RODATA, $8 +DATA ·libc_unlink_trampoline_addr(SB)/8, $libc_unlink_trampoline<>(SB) + +TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_unlinkat(SB) +GLOBL ·libc_unlinkat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_unlinkat_trampoline_addr(SB)/8, $libc_unlinkat_trampoline<>(SB) + +TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_unmount(SB) +GLOBL ·libc_unmount_trampoline_addr(SB), RODATA, $8 +DATA ·libc_unmount_trampoline_addr(SB)/8, $libc_unmount_trampoline<>(SB) + +TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_write(SB) +GLOBL ·libc_write_trampoline_addr(SB), RODATA, $8 +DATA ·libc_write_trampoline_addr(SB)/8, $libc_write_trampoline<>(SB) + +TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mmap(SB) +GLOBL ·libc_mmap_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mmap_trampoline_addr(SB)/8, $libc_mmap_trampoline<>(SB) + +TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_munmap(SB) +GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8 +DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB) + +TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_utimensat(SB) +GLOBL ·libc_utimensat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_utimensat_trampoline_addr(SB)/8, $libc_utimensat_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go new file mode 100644 index 0000000000..47a07ee0c2 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go @@ -0,0 +1,2243 @@ +// go run mksyscall.go -openbsd -libc -tags openbsd,ppc64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_ppc64.go +// Code generated by the command above; see README.md. DO NOT EDIT. + +//go:build openbsd && ppc64 +// +build openbsd,ppc64 + +package unix + +import ( + "syscall" + "unsafe" +) + +var _ syscall.Errno + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getgroups(ngid int, gid *_Gid_t) (n int, err error) { + r0, _, e1 := syscall_rawSyscall(libc_getgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getgroups_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getgroups getgroups "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setgroups(ngid int, gid *_Gid_t) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setgroups_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setgroups setgroups "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) { + r0, _, e1 := syscall_syscall6(libc_wait4_trampoline_addr, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) + wpid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_wait4_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_wait4 wait4 "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { + r0, _, e1 := syscall_syscall(libc_accept_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_accept_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_accept accept "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { + _, _, e1 := syscall_syscall(libc_bind_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_bind_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_bind bind "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { + _, _, e1 := syscall_syscall(libc_connect_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_connect_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_connect connect "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func socket(domain int, typ int, proto int) (fd int, err error) { + r0, _, e1 := syscall_rawSyscall(libc_socket_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_socket_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_socket socket "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { + _, _, e1 := syscall_syscall6(libc_getsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getsockopt_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getsockopt getsockopt "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { + _, _, e1 := syscall_syscall6(libc_setsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setsockopt_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setsockopt setsockopt "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { + _, _, e1 := syscall_rawSyscall(libc_getpeername_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getpeername_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpeername getpeername "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { + _, _, e1 := syscall_rawSyscall(libc_getsockname_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getsockname_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getsockname getsockname "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Shutdown(s int, how int) (err error) { + _, _, e1 := syscall_syscall(libc_shutdown_trampoline_addr, uintptr(s), uintptr(how), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_shutdown_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_shutdown shutdown "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { + _, _, e1 := syscall_rawSyscall6(libc_socketpair_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_socketpair_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_socketpair socketpair "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_recvfrom_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_recvfrom_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_recvfrom recvfrom "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall6(libc_sendto_trampoline_addr, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_sendto_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_sendto sendto "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { + r0, _, e1 := syscall_syscall(libc_recvmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_recvmsg_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_recvmsg recvmsg "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { + r0, _, e1 := syscall_syscall(libc_sendmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_sendmsg_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_sendmsg sendmsg "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) { + r0, _, e1 := syscall_syscall6(libc_kevent_trampoline_addr, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_kevent_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_kevent kevent "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimes(path string, timeval *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_utimes_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_utimes_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_utimes utimes "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func futimes(fd int, timeval *[2]Timeval) (err error) { + _, _, e1 := syscall_syscall(libc_futimes_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_futimes_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_futimes futimes "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := syscall_syscall(libc_poll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_poll_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_poll poll "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall(libc_madvise_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_madvise_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_madvise madvise "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall(libc_mlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mlock_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mlock mlock "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := syscall_syscall(libc_mlockall_trampoline_addr, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mlockall_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mlockall mlockall "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall(libc_mprotect_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mprotect_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mprotect mprotect "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall(libc_msync_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_msync_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_msync msync "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall(libc_munlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_munlock_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_munlock munlock "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := syscall_syscall(libc_munlockall_trampoline_addr, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_munlockall_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_munlockall munlockall "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pipe2(p *[2]_C_int, flags int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_pipe2_trampoline_addr, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pipe2_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getdents(fd int, buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_getdents_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(buf))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getdents_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getdents getdents "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_getcwd_trampoline_addr, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getcwd_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getcwd getcwd "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_ioctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { + var _p0 unsafe.Pointer + if len(mib) > 0 { + _p0 = unsafe.Pointer(&mib[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_sysctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_sysctl sysctl "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_ppoll_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ppoll ppoll "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Access(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_access_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_access_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_access access "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { + _, _, e1 := syscall_syscall(libc_adjtime_trampoline_addr, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_adjtime_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_adjtime adjtime "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chdir(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_chdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_chdir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chdir chdir "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chflags(path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_chflags_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_chflags_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chflags chflags "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chmod(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_chmod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_chmod_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chmod chmod "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chown(path string, uid int, gid int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_chown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_chown_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chown chown "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chroot(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_chroot_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_chroot_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chroot chroot "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := syscall_syscall(libc_clock_gettime_trampoline_addr, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_clock_gettime_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Close(fd int) (err error) { + _, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_close_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_close close "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup(fd int) (nfd int, err error) { + r0, _, e1 := syscall_syscall(libc_dup_trampoline_addr, uintptr(fd), 0, 0) + nfd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_dup_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_dup dup "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup2(from int, to int) (err error) { + _, _, e1 := syscall_syscall(libc_dup2_trampoline_addr, uintptr(from), uintptr(to), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_dup2_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_dup2 dup2 "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup3(from int, to int, flags int) (err error) { + _, _, e1 := syscall_syscall(libc_dup3_trampoline_addr, uintptr(from), uintptr(to), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_dup3_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_dup3 dup3 "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Exit(code int) { + syscall_syscall(libc_exit_trampoline_addr, uintptr(code), 0, 0) + return +} + +var libc_exit_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_exit exit "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_faccessat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_faccessat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_faccessat faccessat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchdir(fd int) (err error) { + _, _, e1 := syscall_syscall(libc_fchdir_trampoline_addr, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fchdir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchdir fchdir "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchflags(fd int, flags int) (err error) { + _, _, e1 := syscall_syscall(libc_fchflags_trampoline_addr, uintptr(fd), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fchflags_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchflags fchflags "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchmod(fd int, mode uint32) (err error) { + _, _, e1 := syscall_syscall(libc_fchmod_trampoline_addr, uintptr(fd), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fchmod_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchmod fchmod "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_fchmodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fchmodat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchown(fd int, uid int, gid int) (err error) { + _, _, e1 := syscall_syscall(libc_fchown_trampoline_addr, uintptr(fd), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fchown_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchown fchown "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_fchownat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fchownat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchownat fchownat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flock(fd int, how int) (err error) { + _, _, e1 := syscall_syscall(libc_flock_trampoline_addr, uintptr(fd), uintptr(how), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_flock_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_flock flock "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fpathconf(fd int, name int) (val int, err error) { + r0, _, e1 := syscall_syscall(libc_fpathconf_trampoline_addr, uintptr(fd), uintptr(name), 0) + val = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fpathconf_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstat(fd int, stat *Stat_t) (err error) { + _, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fstat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fstat fstat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_fstatat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fstatat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fstatat fstatat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstatfs(fd int, stat *Statfs_t) (err error) { + _, _, e1 := syscall_syscall(libc_fstatfs_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fstatfs_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fstatfs fstatfs "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsync(fd int) (err error) { + _, _, e1 := syscall_syscall(libc_fsync_trampoline_addr, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fsync_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fsync fsync "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Ftruncate(fd int, length int64) (err error) { + _, _, e1 := syscall_syscall(libc_ftruncate_trampoline_addr, uintptr(fd), uintptr(length), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_ftruncate_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getegid() (egid int) { + r0, _, _ := syscall_rawSyscall(libc_getegid_trampoline_addr, 0, 0, 0) + egid = int(r0) + return +} + +var libc_getegid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getegid getegid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Geteuid() (uid int) { + r0, _, _ := syscall_rawSyscall(libc_geteuid_trampoline_addr, 0, 0, 0) + uid = int(r0) + return +} + +var libc_geteuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_geteuid geteuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getgid() (gid int) { + r0, _, _ := syscall_rawSyscall(libc_getgid_trampoline_addr, 0, 0, 0) + gid = int(r0) + return +} + +var libc_getgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getgid getgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpgid(pid int) (pgid int, err error) { + r0, _, e1 := syscall_rawSyscall(libc_getpgid_trampoline_addr, uintptr(pid), 0, 0) + pgid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getpgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpgid getpgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpgrp() (pgrp int) { + r0, _, _ := syscall_rawSyscall(libc_getpgrp_trampoline_addr, 0, 0, 0) + pgrp = int(r0) + return +} + +var libc_getpgrp_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpid() (pid int) { + r0, _, _ := syscall_rawSyscall(libc_getpid_trampoline_addr, 0, 0, 0) + pid = int(r0) + return +} + +var libc_getpid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpid getpid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getppid() (ppid int) { + r0, _, _ := syscall_rawSyscall(libc_getppid_trampoline_addr, 0, 0, 0) + ppid = int(r0) + return +} + +var libc_getppid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getppid getppid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpriority(which int, who int) (prio int, err error) { + r0, _, e1 := syscall_syscall(libc_getpriority_trampoline_addr, uintptr(which), uintptr(who), 0) + prio = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getpriority_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpriority getpriority "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrlimit(which int, lim *Rlimit) (err error) { + _, _, e1 := syscall_rawSyscall(libc_getrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getrlimit_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrtable() (rtable int, err error) { + r0, _, e1 := syscall_rawSyscall(libc_getrtable_trampoline_addr, 0, 0, 0) + rtable = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getrtable_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getrtable getrtable "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrusage(who int, rusage *Rusage) (err error) { + _, _, e1 := syscall_rawSyscall(libc_getrusage_trampoline_addr, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getrusage_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getrusage getrusage "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := syscall_rawSyscall(libc_getsid_trampoline_addr, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getsid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getsid getsid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Gettimeofday(tv *Timeval) (err error) { + _, _, e1 := syscall_rawSyscall(libc_gettimeofday_trampoline_addr, uintptr(unsafe.Pointer(tv)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_gettimeofday_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getuid() (uid int) { + r0, _, _ := syscall_rawSyscall(libc_getuid_trampoline_addr, 0, 0, 0) + uid = int(r0) + return +} + +var libc_getuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getuid getuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Issetugid() (tainted bool) { + r0, _, _ := syscall_syscall(libc_issetugid_trampoline_addr, 0, 0, 0) + tainted = bool(r0 != 0) + return +} + +var libc_issetugid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_issetugid issetugid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Kill(pid int, signum syscall.Signal) (err error) { + _, _, e1 := syscall_syscall(libc_kill_trampoline_addr, uintptr(pid), uintptr(signum), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_kill_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_kill kill "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Kqueue() (fd int, err error) { + r0, _, e1 := syscall_syscall(libc_kqueue_trampoline_addr, 0, 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_kqueue_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_kqueue kqueue "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Lchown(path string, uid int, gid int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_lchown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_lchown_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_lchown lchown "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Link(path string, link string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_link_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_link_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_link link "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_linkat_trampoline_addr, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_linkat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_linkat linkat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Listen(s int, backlog int) (err error) { + _, _, e1 := syscall_syscall(libc_listen_trampoline_addr, uintptr(s), uintptr(backlog), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_listen_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_listen listen "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Lstat(path string, stat *Stat_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_lstat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_lstat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_lstat lstat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkdir(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_mkdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mkdir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mkdir mkdir "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkdirat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_mkdirat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mkdirat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mkdirat mkdirat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkfifo(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_mkfifo_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mkfifo_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkfifoat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_mkfifoat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mkfifoat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mkfifoat mkfifoat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mknod(path string, mode uint32, dev int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_mknod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mknod_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mknod mknod "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mknodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mknodat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mknodat mknodat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Nanosleep(time *Timespec, leftover *Timespec) (err error) { + _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_nanosleep_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Open(path string, mode int, perm uint32) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := syscall_syscall(libc_open_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_open_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_open open "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := syscall_syscall6(libc_openat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_openat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_openat openat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pathconf(path string, name int) (val int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := syscall_syscall(libc_pathconf_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0) + val = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pathconf_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pathconf pathconf "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pread(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_pread_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pread_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pread pread "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pwrite(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_pwrite_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pwrite_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pwrite pwrite "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func read(fd int, p []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_read_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_read read "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Readlink(path string, buf []byte) (n int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(buf) > 0 { + _p1 = unsafe.Pointer(&buf[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_readlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_readlink_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_readlink readlink "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(buf) > 0 { + _p1 = unsafe.Pointer(&buf[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_readlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_readlinkat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_readlinkat readlinkat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Rename(from string, to string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_rename_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_rename_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_rename rename "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Renameat(fromfd int, from string, tofd int, to string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_renameat_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_renameat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_renameat renameat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Revoke(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_revoke_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_revoke_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_revoke revoke "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Rmdir(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_rmdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_rmdir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_rmdir rmdir "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { + r0, _, e1 := syscall_syscall(libc_lseek_trampoline_addr, uintptr(fd), uintptr(offset), uintptr(whence)) + newoffset = int64(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_lseek_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_lseek lseek "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { + r0, _, e1 := syscall_syscall6(libc_select_trampoline_addr, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_select_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_select select "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setegid(egid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setegid_trampoline_addr, uintptr(egid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setegid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setegid setegid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Seteuid(euid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_seteuid_trampoline_addr, uintptr(euid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_seteuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_seteuid seteuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setgid(gid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setgid_trampoline_addr, uintptr(gid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setgid setgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setlogin(name string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(name) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_setlogin_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setlogin_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setlogin setlogin "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setpgid(pid int, pgid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setpgid_trampoline_addr, uintptr(pid), uintptr(pgid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setpgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setpgid setpgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setpriority(which int, who int, prio int) (err error) { + _, _, e1 := syscall_syscall(libc_setpriority_trampoline_addr, uintptr(which), uintptr(who), uintptr(prio)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setpriority_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setpriority setpriority "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setregid(rgid int, egid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setregid_trampoline_addr, uintptr(rgid), uintptr(egid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setregid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setregid setregid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setreuid(ruid int, euid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setreuid_trampoline_addr, uintptr(ruid), uintptr(euid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setreuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setreuid setreuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setresgid(rgid int, egid int, sgid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setresgid_trampoline_addr, uintptr(rgid), uintptr(egid), uintptr(sgid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setresgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setresgid setresgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setresuid(ruid int, euid int, suid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setresuid_trampoline_addr, uintptr(ruid), uintptr(euid), uintptr(suid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setresuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setresuid setresuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setrlimit(which int, lim *Rlimit) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setrlimit_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setrtable(rtable int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setrtable_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setrtable setrtable "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setsid() (pid int, err error) { + r0, _, e1 := syscall_rawSyscall(libc_setsid_trampoline_addr, 0, 0, 0) + pid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setsid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setsid setsid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Settimeofday(tp *Timeval) (err error) { + _, _, e1 := syscall_rawSyscall(libc_settimeofday_trampoline_addr, uintptr(unsafe.Pointer(tp)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_settimeofday_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_settimeofday settimeofday "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setuid(uid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setuid_trampoline_addr, uintptr(uid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setuid setuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Stat(path string, stat *Stat_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_stat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_stat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_stat stat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Statfs(path string, stat *Statfs_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_statfs_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_statfs_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_statfs statfs "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Symlink(path string, link string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_symlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_symlink_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_symlink symlink "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_symlinkat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_symlinkat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_symlinkat symlinkat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Sync() (err error) { + _, _, e1 := syscall_syscall(libc_sync_trampoline_addr, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_sync_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_sync sync "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Truncate(path string, length int64) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_truncate_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_truncate_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_truncate truncate "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Umask(newmask int) (oldmask int) { + r0, _, _ := syscall_syscall(libc_umask_trampoline_addr, uintptr(newmask), 0, 0) + oldmask = int(r0) + return +} + +var libc_umask_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_umask umask "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unlink(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_unlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_unlink_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_unlink unlink "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unlinkat(dirfd int, path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_unlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_unlinkat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unmount(path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_unmount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_unmount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_unmount unmount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func write(fd int, p []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_write_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_write write "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) { + r0, _, e1 := syscall_syscall6(libc_mmap_trampoline_addr, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos)) + ret = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mmap_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mmap mmap "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func munmap(addr uintptr, length uintptr) (err error) { + _, _, e1 := syscall_syscall(libc_munmap_trampoline_addr, uintptr(addr), uintptr(length), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_munmap_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_munmap munmap "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func readlen(fd int, buf *byte, nbuf int) (n int, err error) { + r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func writelen(fd int, buf *byte, nbuf int) (n int, err error) { + r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_utimensat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_utimensat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_utimensat utimensat "libc.so" diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s new file mode 100644 index 0000000000..4028255b0d --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s @@ -0,0 +1,802 @@ +// go run mkasm.go openbsd ppc64 +// Code generated by the command above; DO NOT EDIT. + +#include "textflag.h" + +TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getgroups(SB) + RET +GLOBL ·libc_getgroups_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getgroups_trampoline_addr(SB)/8, $libc_getgroups_trampoline<>(SB) + +TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setgroups(SB) + RET +GLOBL ·libc_setgroups_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setgroups_trampoline_addr(SB)/8, $libc_setgroups_trampoline<>(SB) + +TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_wait4(SB) + RET +GLOBL ·libc_wait4_trampoline_addr(SB), RODATA, $8 +DATA ·libc_wait4_trampoline_addr(SB)/8, $libc_wait4_trampoline<>(SB) + +TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_accept(SB) + RET +GLOBL ·libc_accept_trampoline_addr(SB), RODATA, $8 +DATA ·libc_accept_trampoline_addr(SB)/8, $libc_accept_trampoline<>(SB) + +TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_bind(SB) + RET +GLOBL ·libc_bind_trampoline_addr(SB), RODATA, $8 +DATA ·libc_bind_trampoline_addr(SB)/8, $libc_bind_trampoline<>(SB) + +TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_connect(SB) + RET +GLOBL ·libc_connect_trampoline_addr(SB), RODATA, $8 +DATA ·libc_connect_trampoline_addr(SB)/8, $libc_connect_trampoline<>(SB) + +TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_socket(SB) + RET +GLOBL ·libc_socket_trampoline_addr(SB), RODATA, $8 +DATA ·libc_socket_trampoline_addr(SB)/8, $libc_socket_trampoline<>(SB) + +TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getsockopt(SB) + RET +GLOBL ·libc_getsockopt_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getsockopt_trampoline_addr(SB)/8, $libc_getsockopt_trampoline<>(SB) + +TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setsockopt(SB) + RET +GLOBL ·libc_setsockopt_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setsockopt_trampoline_addr(SB)/8, $libc_setsockopt_trampoline<>(SB) + +TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getpeername(SB) + RET +GLOBL ·libc_getpeername_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpeername_trampoline_addr(SB)/8, $libc_getpeername_trampoline<>(SB) + +TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getsockname(SB) + RET +GLOBL ·libc_getsockname_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getsockname_trampoline_addr(SB)/8, $libc_getsockname_trampoline<>(SB) + +TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_shutdown(SB) + RET +GLOBL ·libc_shutdown_trampoline_addr(SB), RODATA, $8 +DATA ·libc_shutdown_trampoline_addr(SB)/8, $libc_shutdown_trampoline<>(SB) + +TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_socketpair(SB) + RET +GLOBL ·libc_socketpair_trampoline_addr(SB), RODATA, $8 +DATA ·libc_socketpair_trampoline_addr(SB)/8, $libc_socketpair_trampoline<>(SB) + +TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_recvfrom(SB) + RET +GLOBL ·libc_recvfrom_trampoline_addr(SB), RODATA, $8 +DATA ·libc_recvfrom_trampoline_addr(SB)/8, $libc_recvfrom_trampoline<>(SB) + +TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_sendto(SB) + RET +GLOBL ·libc_sendto_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sendto_trampoline_addr(SB)/8, $libc_sendto_trampoline<>(SB) + +TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_recvmsg(SB) + RET +GLOBL ·libc_recvmsg_trampoline_addr(SB), RODATA, $8 +DATA ·libc_recvmsg_trampoline_addr(SB)/8, $libc_recvmsg_trampoline<>(SB) + +TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_sendmsg(SB) + RET +GLOBL ·libc_sendmsg_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sendmsg_trampoline_addr(SB)/8, $libc_sendmsg_trampoline<>(SB) + +TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_kevent(SB) + RET +GLOBL ·libc_kevent_trampoline_addr(SB), RODATA, $8 +DATA ·libc_kevent_trampoline_addr(SB)/8, $libc_kevent_trampoline<>(SB) + +TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_utimes(SB) + RET +GLOBL ·libc_utimes_trampoline_addr(SB), RODATA, $8 +DATA ·libc_utimes_trampoline_addr(SB)/8, $libc_utimes_trampoline<>(SB) + +TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_futimes(SB) + RET +GLOBL ·libc_futimes_trampoline_addr(SB), RODATA, $8 +DATA ·libc_futimes_trampoline_addr(SB)/8, $libc_futimes_trampoline<>(SB) + +TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_poll(SB) + RET +GLOBL ·libc_poll_trampoline_addr(SB), RODATA, $8 +DATA ·libc_poll_trampoline_addr(SB)/8, $libc_poll_trampoline<>(SB) + +TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_madvise(SB) + RET +GLOBL ·libc_madvise_trampoline_addr(SB), RODATA, $8 +DATA ·libc_madvise_trampoline_addr(SB)/8, $libc_madvise_trampoline<>(SB) + +TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_mlock(SB) + RET +GLOBL ·libc_mlock_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mlock_trampoline_addr(SB)/8, $libc_mlock_trampoline<>(SB) + +TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_mlockall(SB) + RET +GLOBL ·libc_mlockall_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mlockall_trampoline_addr(SB)/8, $libc_mlockall_trampoline<>(SB) + +TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_mprotect(SB) + RET +GLOBL ·libc_mprotect_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mprotect_trampoline_addr(SB)/8, $libc_mprotect_trampoline<>(SB) + +TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_msync(SB) + RET +GLOBL ·libc_msync_trampoline_addr(SB), RODATA, $8 +DATA ·libc_msync_trampoline_addr(SB)/8, $libc_msync_trampoline<>(SB) + +TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_munlock(SB) + RET +GLOBL ·libc_munlock_trampoline_addr(SB), RODATA, $8 +DATA ·libc_munlock_trampoline_addr(SB)/8, $libc_munlock_trampoline<>(SB) + +TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_munlockall(SB) + RET +GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8 +DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB) + +TEXT libc_pipe2_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_pipe2(SB) + RET +GLOBL ·libc_pipe2_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pipe2_trampoline_addr(SB)/8, $libc_pipe2_trampoline<>(SB) + +TEXT libc_getdents_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getdents(SB) + RET +GLOBL ·libc_getdents_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getdents_trampoline_addr(SB)/8, $libc_getdents_trampoline<>(SB) + +TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getcwd(SB) + RET +GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB) + +TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_ioctl(SB) + RET +GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 +DATA ·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB) + +TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_sysctl(SB) + RET +GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) + +TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_ppoll(SB) + RET +GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $8 +DATA ·libc_ppoll_trampoline_addr(SB)/8, $libc_ppoll_trampoline<>(SB) + +TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_access(SB) + RET +GLOBL ·libc_access_trampoline_addr(SB), RODATA, $8 +DATA ·libc_access_trampoline_addr(SB)/8, $libc_access_trampoline<>(SB) + +TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_adjtime(SB) + RET +GLOBL ·libc_adjtime_trampoline_addr(SB), RODATA, $8 +DATA ·libc_adjtime_trampoline_addr(SB)/8, $libc_adjtime_trampoline<>(SB) + +TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_chdir(SB) + RET +GLOBL ·libc_chdir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chdir_trampoline_addr(SB)/8, $libc_chdir_trampoline<>(SB) + +TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_chflags(SB) + RET +GLOBL ·libc_chflags_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chflags_trampoline_addr(SB)/8, $libc_chflags_trampoline<>(SB) + +TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_chmod(SB) + RET +GLOBL ·libc_chmod_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chmod_trampoline_addr(SB)/8, $libc_chmod_trampoline<>(SB) + +TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_chown(SB) + RET +GLOBL ·libc_chown_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chown_trampoline_addr(SB)/8, $libc_chown_trampoline<>(SB) + +TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_chroot(SB) + RET +GLOBL ·libc_chroot_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chroot_trampoline_addr(SB)/8, $libc_chroot_trampoline<>(SB) + +TEXT libc_clock_gettime_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_clock_gettime(SB) + RET +GLOBL ·libc_clock_gettime_trampoline_addr(SB), RODATA, $8 +DATA ·libc_clock_gettime_trampoline_addr(SB)/8, $libc_clock_gettime_trampoline<>(SB) + +TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_close(SB) + RET +GLOBL ·libc_close_trampoline_addr(SB), RODATA, $8 +DATA ·libc_close_trampoline_addr(SB)/8, $libc_close_trampoline<>(SB) + +TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_dup(SB) + RET +GLOBL ·libc_dup_trampoline_addr(SB), RODATA, $8 +DATA ·libc_dup_trampoline_addr(SB)/8, $libc_dup_trampoline<>(SB) + +TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_dup2(SB) + RET +GLOBL ·libc_dup2_trampoline_addr(SB), RODATA, $8 +DATA ·libc_dup2_trampoline_addr(SB)/8, $libc_dup2_trampoline<>(SB) + +TEXT libc_dup3_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_dup3(SB) + RET +GLOBL ·libc_dup3_trampoline_addr(SB), RODATA, $8 +DATA ·libc_dup3_trampoline_addr(SB)/8, $libc_dup3_trampoline<>(SB) + +TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_exit(SB) + RET +GLOBL ·libc_exit_trampoline_addr(SB), RODATA, $8 +DATA ·libc_exit_trampoline_addr(SB)/8, $libc_exit_trampoline<>(SB) + +TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_faccessat(SB) + RET +GLOBL ·libc_faccessat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_faccessat_trampoline_addr(SB)/8, $libc_faccessat_trampoline<>(SB) + +TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_fchdir(SB) + RET +GLOBL ·libc_fchdir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchdir_trampoline_addr(SB)/8, $libc_fchdir_trampoline<>(SB) + +TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_fchflags(SB) + RET +GLOBL ·libc_fchflags_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchflags_trampoline_addr(SB)/8, $libc_fchflags_trampoline<>(SB) + +TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_fchmod(SB) + RET +GLOBL ·libc_fchmod_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchmod_trampoline_addr(SB)/8, $libc_fchmod_trampoline<>(SB) + +TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_fchmodat(SB) + RET +GLOBL ·libc_fchmodat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchmodat_trampoline_addr(SB)/8, $libc_fchmodat_trampoline<>(SB) + +TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_fchown(SB) + RET +GLOBL ·libc_fchown_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchown_trampoline_addr(SB)/8, $libc_fchown_trampoline<>(SB) + +TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_fchownat(SB) + RET +GLOBL ·libc_fchownat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchownat_trampoline_addr(SB)/8, $libc_fchownat_trampoline<>(SB) + +TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_flock(SB) + RET +GLOBL ·libc_flock_trampoline_addr(SB), RODATA, $8 +DATA ·libc_flock_trampoline_addr(SB)/8, $libc_flock_trampoline<>(SB) + +TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_fpathconf(SB) + RET +GLOBL ·libc_fpathconf_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fpathconf_trampoline_addr(SB)/8, $libc_fpathconf_trampoline<>(SB) + +TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_fstat(SB) + RET +GLOBL ·libc_fstat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fstat_trampoline_addr(SB)/8, $libc_fstat_trampoline<>(SB) + +TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_fstatat(SB) + RET +GLOBL ·libc_fstatat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fstatat_trampoline_addr(SB)/8, $libc_fstatat_trampoline<>(SB) + +TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_fstatfs(SB) + RET +GLOBL ·libc_fstatfs_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fstatfs_trampoline_addr(SB)/8, $libc_fstatfs_trampoline<>(SB) + +TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_fsync(SB) + RET +GLOBL ·libc_fsync_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fsync_trampoline_addr(SB)/8, $libc_fsync_trampoline<>(SB) + +TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_ftruncate(SB) + RET +GLOBL ·libc_ftruncate_trampoline_addr(SB), RODATA, $8 +DATA ·libc_ftruncate_trampoline_addr(SB)/8, $libc_ftruncate_trampoline<>(SB) + +TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getegid(SB) + RET +GLOBL ·libc_getegid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getegid_trampoline_addr(SB)/8, $libc_getegid_trampoline<>(SB) + +TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_geteuid(SB) + RET +GLOBL ·libc_geteuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_geteuid_trampoline_addr(SB)/8, $libc_geteuid_trampoline<>(SB) + +TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getgid(SB) + RET +GLOBL ·libc_getgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getgid_trampoline_addr(SB)/8, $libc_getgid_trampoline<>(SB) + +TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getpgid(SB) + RET +GLOBL ·libc_getpgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpgid_trampoline_addr(SB)/8, $libc_getpgid_trampoline<>(SB) + +TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getpgrp(SB) + RET +GLOBL ·libc_getpgrp_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpgrp_trampoline_addr(SB)/8, $libc_getpgrp_trampoline<>(SB) + +TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getpid(SB) + RET +GLOBL ·libc_getpid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpid_trampoline_addr(SB)/8, $libc_getpid_trampoline<>(SB) + +TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getppid(SB) + RET +GLOBL ·libc_getppid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getppid_trampoline_addr(SB)/8, $libc_getppid_trampoline<>(SB) + +TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getpriority(SB) + RET +GLOBL ·libc_getpriority_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpriority_trampoline_addr(SB)/8, $libc_getpriority_trampoline<>(SB) + +TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getrlimit(SB) + RET +GLOBL ·libc_getrlimit_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getrlimit_trampoline_addr(SB)/8, $libc_getrlimit_trampoline<>(SB) + +TEXT libc_getrtable_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getrtable(SB) + RET +GLOBL ·libc_getrtable_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getrtable_trampoline_addr(SB)/8, $libc_getrtable_trampoline<>(SB) + +TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getrusage(SB) + RET +GLOBL ·libc_getrusage_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getrusage_trampoline_addr(SB)/8, $libc_getrusage_trampoline<>(SB) + +TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getsid(SB) + RET +GLOBL ·libc_getsid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getsid_trampoline_addr(SB)/8, $libc_getsid_trampoline<>(SB) + +TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_gettimeofday(SB) + RET +GLOBL ·libc_gettimeofday_trampoline_addr(SB), RODATA, $8 +DATA ·libc_gettimeofday_trampoline_addr(SB)/8, $libc_gettimeofday_trampoline<>(SB) + +TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getuid(SB) + RET +GLOBL ·libc_getuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getuid_trampoline_addr(SB)/8, $libc_getuid_trampoline<>(SB) + +TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_issetugid(SB) + RET +GLOBL ·libc_issetugid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_issetugid_trampoline_addr(SB)/8, $libc_issetugid_trampoline<>(SB) + +TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_kill(SB) + RET +GLOBL ·libc_kill_trampoline_addr(SB), RODATA, $8 +DATA ·libc_kill_trampoline_addr(SB)/8, $libc_kill_trampoline<>(SB) + +TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_kqueue(SB) + RET +GLOBL ·libc_kqueue_trampoline_addr(SB), RODATA, $8 +DATA ·libc_kqueue_trampoline_addr(SB)/8, $libc_kqueue_trampoline<>(SB) + +TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_lchown(SB) + RET +GLOBL ·libc_lchown_trampoline_addr(SB), RODATA, $8 +DATA ·libc_lchown_trampoline_addr(SB)/8, $libc_lchown_trampoline<>(SB) + +TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_link(SB) + RET +GLOBL ·libc_link_trampoline_addr(SB), RODATA, $8 +DATA ·libc_link_trampoline_addr(SB)/8, $libc_link_trampoline<>(SB) + +TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_linkat(SB) + RET +GLOBL ·libc_linkat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_linkat_trampoline_addr(SB)/8, $libc_linkat_trampoline<>(SB) + +TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_listen(SB) + RET +GLOBL ·libc_listen_trampoline_addr(SB), RODATA, $8 +DATA ·libc_listen_trampoline_addr(SB)/8, $libc_listen_trampoline<>(SB) + +TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_lstat(SB) + RET +GLOBL ·libc_lstat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_lstat_trampoline_addr(SB)/8, $libc_lstat_trampoline<>(SB) + +TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_mkdir(SB) + RET +GLOBL ·libc_mkdir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mkdir_trampoline_addr(SB)/8, $libc_mkdir_trampoline<>(SB) + +TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_mkdirat(SB) + RET +GLOBL ·libc_mkdirat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mkdirat_trampoline_addr(SB)/8, $libc_mkdirat_trampoline<>(SB) + +TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_mkfifo(SB) + RET +GLOBL ·libc_mkfifo_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mkfifo_trampoline_addr(SB)/8, $libc_mkfifo_trampoline<>(SB) + +TEXT libc_mkfifoat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_mkfifoat(SB) + RET +GLOBL ·libc_mkfifoat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mkfifoat_trampoline_addr(SB)/8, $libc_mkfifoat_trampoline<>(SB) + +TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_mknod(SB) + RET +GLOBL ·libc_mknod_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mknod_trampoline_addr(SB)/8, $libc_mknod_trampoline<>(SB) + +TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_mknodat(SB) + RET +GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) + +TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_nanosleep(SB) + RET +GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $8 +DATA ·libc_nanosleep_trampoline_addr(SB)/8, $libc_nanosleep_trampoline<>(SB) + +TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_open(SB) + RET +GLOBL ·libc_open_trampoline_addr(SB), RODATA, $8 +DATA ·libc_open_trampoline_addr(SB)/8, $libc_open_trampoline<>(SB) + +TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_openat(SB) + RET +GLOBL ·libc_openat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_openat_trampoline_addr(SB)/8, $libc_openat_trampoline<>(SB) + +TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_pathconf(SB) + RET +GLOBL ·libc_pathconf_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pathconf_trampoline_addr(SB)/8, $libc_pathconf_trampoline<>(SB) + +TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_pread(SB) + RET +GLOBL ·libc_pread_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pread_trampoline_addr(SB)/8, $libc_pread_trampoline<>(SB) + +TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_pwrite(SB) + RET +GLOBL ·libc_pwrite_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pwrite_trampoline_addr(SB)/8, $libc_pwrite_trampoline<>(SB) + +TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_read(SB) + RET +GLOBL ·libc_read_trampoline_addr(SB), RODATA, $8 +DATA ·libc_read_trampoline_addr(SB)/8, $libc_read_trampoline<>(SB) + +TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_readlink(SB) + RET +GLOBL ·libc_readlink_trampoline_addr(SB), RODATA, $8 +DATA ·libc_readlink_trampoline_addr(SB)/8, $libc_readlink_trampoline<>(SB) + +TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_readlinkat(SB) + RET +GLOBL ·libc_readlinkat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_readlinkat_trampoline_addr(SB)/8, $libc_readlinkat_trampoline<>(SB) + +TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_rename(SB) + RET +GLOBL ·libc_rename_trampoline_addr(SB), RODATA, $8 +DATA ·libc_rename_trampoline_addr(SB)/8, $libc_rename_trampoline<>(SB) + +TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_renameat(SB) + RET +GLOBL ·libc_renameat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_renameat_trampoline_addr(SB)/8, $libc_renameat_trampoline<>(SB) + +TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_revoke(SB) + RET +GLOBL ·libc_revoke_trampoline_addr(SB), RODATA, $8 +DATA ·libc_revoke_trampoline_addr(SB)/8, $libc_revoke_trampoline<>(SB) + +TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_rmdir(SB) + RET +GLOBL ·libc_rmdir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_rmdir_trampoline_addr(SB)/8, $libc_rmdir_trampoline<>(SB) + +TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_lseek(SB) + RET +GLOBL ·libc_lseek_trampoline_addr(SB), RODATA, $8 +DATA ·libc_lseek_trampoline_addr(SB)/8, $libc_lseek_trampoline<>(SB) + +TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_select(SB) + RET +GLOBL ·libc_select_trampoline_addr(SB), RODATA, $8 +DATA ·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB) + +TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setegid(SB) + RET +GLOBL ·libc_setegid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setegid_trampoline_addr(SB)/8, $libc_setegid_trampoline<>(SB) + +TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_seteuid(SB) + RET +GLOBL ·libc_seteuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_seteuid_trampoline_addr(SB)/8, $libc_seteuid_trampoline<>(SB) + +TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setgid(SB) + RET +GLOBL ·libc_setgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setgid_trampoline_addr(SB)/8, $libc_setgid_trampoline<>(SB) + +TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setlogin(SB) + RET +GLOBL ·libc_setlogin_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setlogin_trampoline_addr(SB)/8, $libc_setlogin_trampoline<>(SB) + +TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setpgid(SB) + RET +GLOBL ·libc_setpgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setpgid_trampoline_addr(SB)/8, $libc_setpgid_trampoline<>(SB) + +TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setpriority(SB) + RET +GLOBL ·libc_setpriority_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setpriority_trampoline_addr(SB)/8, $libc_setpriority_trampoline<>(SB) + +TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setregid(SB) + RET +GLOBL ·libc_setregid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setregid_trampoline_addr(SB)/8, $libc_setregid_trampoline<>(SB) + +TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setreuid(SB) + RET +GLOBL ·libc_setreuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB) + +TEXT libc_setresgid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setresgid(SB) + RET +GLOBL ·libc_setresgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setresgid_trampoline_addr(SB)/8, $libc_setresgid_trampoline<>(SB) + +TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setresuid(SB) + RET +GLOBL ·libc_setresuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setresuid_trampoline_addr(SB)/8, $libc_setresuid_trampoline<>(SB) + +TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setrlimit(SB) + RET +GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB) + +TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setrtable(SB) + RET +GLOBL ·libc_setrtable_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setrtable_trampoline_addr(SB)/8, $libc_setrtable_trampoline<>(SB) + +TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setsid(SB) + RET +GLOBL ·libc_setsid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setsid_trampoline_addr(SB)/8, $libc_setsid_trampoline<>(SB) + +TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_settimeofday(SB) + RET +GLOBL ·libc_settimeofday_trampoline_addr(SB), RODATA, $8 +DATA ·libc_settimeofday_trampoline_addr(SB)/8, $libc_settimeofday_trampoline<>(SB) + +TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_setuid(SB) + RET +GLOBL ·libc_setuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setuid_trampoline_addr(SB)/8, $libc_setuid_trampoline<>(SB) + +TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_stat(SB) + RET +GLOBL ·libc_stat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_stat_trampoline_addr(SB)/8, $libc_stat_trampoline<>(SB) + +TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_statfs(SB) + RET +GLOBL ·libc_statfs_trampoline_addr(SB), RODATA, $8 +DATA ·libc_statfs_trampoline_addr(SB)/8, $libc_statfs_trampoline<>(SB) + +TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_symlink(SB) + RET +GLOBL ·libc_symlink_trampoline_addr(SB), RODATA, $8 +DATA ·libc_symlink_trampoline_addr(SB)/8, $libc_symlink_trampoline<>(SB) + +TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_symlinkat(SB) + RET +GLOBL ·libc_symlinkat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_symlinkat_trampoline_addr(SB)/8, $libc_symlinkat_trampoline<>(SB) + +TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_sync(SB) + RET +GLOBL ·libc_sync_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sync_trampoline_addr(SB)/8, $libc_sync_trampoline<>(SB) + +TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_truncate(SB) + RET +GLOBL ·libc_truncate_trampoline_addr(SB), RODATA, $8 +DATA ·libc_truncate_trampoline_addr(SB)/8, $libc_truncate_trampoline<>(SB) + +TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_umask(SB) + RET +GLOBL ·libc_umask_trampoline_addr(SB), RODATA, $8 +DATA ·libc_umask_trampoline_addr(SB)/8, $libc_umask_trampoline<>(SB) + +TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_unlink(SB) + RET +GLOBL ·libc_unlink_trampoline_addr(SB), RODATA, $8 +DATA ·libc_unlink_trampoline_addr(SB)/8, $libc_unlink_trampoline<>(SB) + +TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_unlinkat(SB) + RET +GLOBL ·libc_unlinkat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_unlinkat_trampoline_addr(SB)/8, $libc_unlinkat_trampoline<>(SB) + +TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_unmount(SB) + RET +GLOBL ·libc_unmount_trampoline_addr(SB), RODATA, $8 +DATA ·libc_unmount_trampoline_addr(SB)/8, $libc_unmount_trampoline<>(SB) + +TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_write(SB) + RET +GLOBL ·libc_write_trampoline_addr(SB), RODATA, $8 +DATA ·libc_write_trampoline_addr(SB)/8, $libc_write_trampoline<>(SB) + +TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_mmap(SB) + RET +GLOBL ·libc_mmap_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mmap_trampoline_addr(SB)/8, $libc_mmap_trampoline<>(SB) + +TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_munmap(SB) + RET +GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8 +DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB) + +TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_utimensat(SB) + RET +GLOBL ·libc_utimensat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_utimensat_trampoline_addr(SB)/8, $libc_utimensat_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go new file mode 100644 index 0000000000..573378fdb9 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go @@ -0,0 +1,2243 @@ +// go run mksyscall.go -openbsd -libc -tags openbsd,riscv64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_riscv64.go +// Code generated by the command above; see README.md. DO NOT EDIT. + +//go:build openbsd && riscv64 +// +build openbsd,riscv64 + +package unix + +import ( + "syscall" + "unsafe" +) + +var _ syscall.Errno + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getgroups(ngid int, gid *_Gid_t) (n int, err error) { + r0, _, e1 := syscall_rawSyscall(libc_getgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getgroups_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getgroups getgroups "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setgroups(ngid int, gid *_Gid_t) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setgroups_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setgroups setgroups "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) { + r0, _, e1 := syscall_syscall6(libc_wait4_trampoline_addr, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) + wpid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_wait4_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_wait4 wait4 "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { + r0, _, e1 := syscall_syscall(libc_accept_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_accept_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_accept accept "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { + _, _, e1 := syscall_syscall(libc_bind_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_bind_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_bind bind "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { + _, _, e1 := syscall_syscall(libc_connect_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_connect_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_connect connect "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func socket(domain int, typ int, proto int) (fd int, err error) { + r0, _, e1 := syscall_rawSyscall(libc_socket_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_socket_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_socket socket "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { + _, _, e1 := syscall_syscall6(libc_getsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getsockopt_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getsockopt getsockopt "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { + _, _, e1 := syscall_syscall6(libc_setsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setsockopt_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setsockopt setsockopt "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { + _, _, e1 := syscall_rawSyscall(libc_getpeername_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getpeername_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpeername getpeername "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { + _, _, e1 := syscall_rawSyscall(libc_getsockname_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getsockname_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getsockname getsockname "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Shutdown(s int, how int) (err error) { + _, _, e1 := syscall_syscall(libc_shutdown_trampoline_addr, uintptr(s), uintptr(how), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_shutdown_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_shutdown shutdown "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { + _, _, e1 := syscall_rawSyscall6(libc_socketpair_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_socketpair_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_socketpair socketpair "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_recvfrom_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_recvfrom_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_recvfrom recvfrom "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall6(libc_sendto_trampoline_addr, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_sendto_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_sendto sendto "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { + r0, _, e1 := syscall_syscall(libc_recvmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_recvmsg_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_recvmsg recvmsg "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { + r0, _, e1 := syscall_syscall(libc_sendmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_sendmsg_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_sendmsg sendmsg "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) { + r0, _, e1 := syscall_syscall6(libc_kevent_trampoline_addr, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_kevent_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_kevent kevent "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimes(path string, timeval *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_utimes_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_utimes_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_utimes utimes "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func futimes(fd int, timeval *[2]Timeval) (err error) { + _, _, e1 := syscall_syscall(libc_futimes_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_futimes_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_futimes futimes "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := syscall_syscall(libc_poll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_poll_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_poll poll "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall(libc_madvise_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_madvise_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_madvise madvise "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall(libc_mlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mlock_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mlock mlock "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := syscall_syscall(libc_mlockall_trampoline_addr, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mlockall_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mlockall mlockall "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall(libc_mprotect_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mprotect_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mprotect mprotect "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall(libc_msync_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_msync_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_msync msync "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall(libc_munlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_munlock_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_munlock munlock "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := syscall_syscall(libc_munlockall_trampoline_addr, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_munlockall_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_munlockall munlockall "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pipe2(p *[2]_C_int, flags int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_pipe2_trampoline_addr, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pipe2_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getdents(fd int, buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_getdents_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(buf))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getdents_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getdents getdents "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_getcwd_trampoline_addr, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getcwd_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getcwd getcwd "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_ioctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { + var _p0 unsafe.Pointer + if len(mib) > 0 { + _p0 = unsafe.Pointer(&mib[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_sysctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_sysctl sysctl "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_ppoll_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ppoll ppoll "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Access(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_access_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_access_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_access access "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { + _, _, e1 := syscall_syscall(libc_adjtime_trampoline_addr, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_adjtime_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_adjtime adjtime "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chdir(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_chdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_chdir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chdir chdir "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chflags(path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_chflags_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_chflags_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chflags chflags "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chmod(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_chmod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_chmod_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chmod chmod "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chown(path string, uid int, gid int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_chown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_chown_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chown chown "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chroot(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_chroot_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_chroot_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_chroot chroot "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := syscall_syscall(libc_clock_gettime_trampoline_addr, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_clock_gettime_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Close(fd int) (err error) { + _, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_close_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_close close "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup(fd int) (nfd int, err error) { + r0, _, e1 := syscall_syscall(libc_dup_trampoline_addr, uintptr(fd), 0, 0) + nfd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_dup_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_dup dup "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup2(from int, to int) (err error) { + _, _, e1 := syscall_syscall(libc_dup2_trampoline_addr, uintptr(from), uintptr(to), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_dup2_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_dup2 dup2 "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup3(from int, to int, flags int) (err error) { + _, _, e1 := syscall_syscall(libc_dup3_trampoline_addr, uintptr(from), uintptr(to), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_dup3_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_dup3 dup3 "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Exit(code int) { + syscall_syscall(libc_exit_trampoline_addr, uintptr(code), 0, 0) + return +} + +var libc_exit_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_exit exit "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_faccessat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_faccessat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_faccessat faccessat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchdir(fd int) (err error) { + _, _, e1 := syscall_syscall(libc_fchdir_trampoline_addr, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fchdir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchdir fchdir "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchflags(fd int, flags int) (err error) { + _, _, e1 := syscall_syscall(libc_fchflags_trampoline_addr, uintptr(fd), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fchflags_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchflags fchflags "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchmod(fd int, mode uint32) (err error) { + _, _, e1 := syscall_syscall(libc_fchmod_trampoline_addr, uintptr(fd), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fchmod_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchmod fchmod "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_fchmodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fchmodat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchown(fd int, uid int, gid int) (err error) { + _, _, e1 := syscall_syscall(libc_fchown_trampoline_addr, uintptr(fd), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fchown_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchown fchown "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_fchownat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fchownat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fchownat fchownat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flock(fd int, how int) (err error) { + _, _, e1 := syscall_syscall(libc_flock_trampoline_addr, uintptr(fd), uintptr(how), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_flock_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_flock flock "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fpathconf(fd int, name int) (val int, err error) { + r0, _, e1 := syscall_syscall(libc_fpathconf_trampoline_addr, uintptr(fd), uintptr(name), 0) + val = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fpathconf_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstat(fd int, stat *Stat_t) (err error) { + _, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fstat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fstat fstat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_fstatat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fstatat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fstatat fstatat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstatfs(fd int, stat *Statfs_t) (err error) { + _, _, e1 := syscall_syscall(libc_fstatfs_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fstatfs_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fstatfs fstatfs "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsync(fd int) (err error) { + _, _, e1 := syscall_syscall(libc_fsync_trampoline_addr, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_fsync_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_fsync fsync "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Ftruncate(fd int, length int64) (err error) { + _, _, e1 := syscall_syscall(libc_ftruncate_trampoline_addr, uintptr(fd), uintptr(length), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_ftruncate_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getegid() (egid int) { + r0, _, _ := syscall_rawSyscall(libc_getegid_trampoline_addr, 0, 0, 0) + egid = int(r0) + return +} + +var libc_getegid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getegid getegid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Geteuid() (uid int) { + r0, _, _ := syscall_rawSyscall(libc_geteuid_trampoline_addr, 0, 0, 0) + uid = int(r0) + return +} + +var libc_geteuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_geteuid geteuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getgid() (gid int) { + r0, _, _ := syscall_rawSyscall(libc_getgid_trampoline_addr, 0, 0, 0) + gid = int(r0) + return +} + +var libc_getgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getgid getgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpgid(pid int) (pgid int, err error) { + r0, _, e1 := syscall_rawSyscall(libc_getpgid_trampoline_addr, uintptr(pid), 0, 0) + pgid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getpgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpgid getpgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpgrp() (pgrp int) { + r0, _, _ := syscall_rawSyscall(libc_getpgrp_trampoline_addr, 0, 0, 0) + pgrp = int(r0) + return +} + +var libc_getpgrp_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpid() (pid int) { + r0, _, _ := syscall_rawSyscall(libc_getpid_trampoline_addr, 0, 0, 0) + pid = int(r0) + return +} + +var libc_getpid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpid getpid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getppid() (ppid int) { + r0, _, _ := syscall_rawSyscall(libc_getppid_trampoline_addr, 0, 0, 0) + ppid = int(r0) + return +} + +var libc_getppid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getppid getppid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpriority(which int, who int) (prio int, err error) { + r0, _, e1 := syscall_syscall(libc_getpriority_trampoline_addr, uintptr(which), uintptr(who), 0) + prio = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getpriority_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getpriority getpriority "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrlimit(which int, lim *Rlimit) (err error) { + _, _, e1 := syscall_rawSyscall(libc_getrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getrlimit_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrtable() (rtable int, err error) { + r0, _, e1 := syscall_rawSyscall(libc_getrtable_trampoline_addr, 0, 0, 0) + rtable = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getrtable_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getrtable getrtable "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrusage(who int, rusage *Rusage) (err error) { + _, _, e1 := syscall_rawSyscall(libc_getrusage_trampoline_addr, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getrusage_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getrusage getrusage "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := syscall_rawSyscall(libc_getsid_trampoline_addr, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_getsid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getsid getsid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Gettimeofday(tv *Timeval) (err error) { + _, _, e1 := syscall_rawSyscall(libc_gettimeofday_trampoline_addr, uintptr(unsafe.Pointer(tv)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_gettimeofday_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getuid() (uid int) { + r0, _, _ := syscall_rawSyscall(libc_getuid_trampoline_addr, 0, 0, 0) + uid = int(r0) + return +} + +var libc_getuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getuid getuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Issetugid() (tainted bool) { + r0, _, _ := syscall_syscall(libc_issetugid_trampoline_addr, 0, 0, 0) + tainted = bool(r0 != 0) + return +} + +var libc_issetugid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_issetugid issetugid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Kill(pid int, signum syscall.Signal) (err error) { + _, _, e1 := syscall_syscall(libc_kill_trampoline_addr, uintptr(pid), uintptr(signum), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_kill_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_kill kill "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Kqueue() (fd int, err error) { + r0, _, e1 := syscall_syscall(libc_kqueue_trampoline_addr, 0, 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_kqueue_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_kqueue kqueue "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Lchown(path string, uid int, gid int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_lchown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_lchown_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_lchown lchown "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Link(path string, link string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_link_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_link_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_link link "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_linkat_trampoline_addr, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_linkat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_linkat linkat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Listen(s int, backlog int) (err error) { + _, _, e1 := syscall_syscall(libc_listen_trampoline_addr, uintptr(s), uintptr(backlog), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_listen_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_listen listen "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Lstat(path string, stat *Stat_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_lstat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_lstat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_lstat lstat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkdir(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_mkdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mkdir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mkdir mkdir "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkdirat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_mkdirat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mkdirat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mkdirat mkdirat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkfifo(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_mkfifo_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mkfifo_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkfifoat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_mkfifoat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mkfifoat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mkfifoat mkfifoat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mknod(path string, mode uint32, dev int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_mknod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mknod_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mknod mknod "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mknodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mknodat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mknodat mknodat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Nanosleep(time *Timespec, leftover *Timespec) (err error) { + _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_nanosleep_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Open(path string, mode int, perm uint32) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := syscall_syscall(libc_open_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_open_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_open open "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := syscall_syscall6(libc_openat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_openat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_openat openat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pathconf(path string, name int) (val int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := syscall_syscall(libc_pathconf_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0) + val = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pathconf_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pathconf pathconf "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pread(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_pread_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pread_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pread pread "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pwrite(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_pwrite_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pwrite_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pwrite pwrite "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func read(fd int, p []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_read_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_read read "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Readlink(path string, buf []byte) (n int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(buf) > 0 { + _p1 = unsafe.Pointer(&buf[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_readlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_readlink_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_readlink readlink "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(buf) > 0 { + _p1 = unsafe.Pointer(&buf[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_readlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_readlinkat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_readlinkat readlinkat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Rename(from string, to string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_rename_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_rename_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_rename rename "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Renameat(fromfd int, from string, tofd int, to string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_renameat_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_renameat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_renameat renameat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Revoke(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_revoke_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_revoke_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_revoke revoke "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Rmdir(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_rmdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_rmdir_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_rmdir rmdir "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { + r0, _, e1 := syscall_syscall(libc_lseek_trampoline_addr, uintptr(fd), uintptr(offset), uintptr(whence)) + newoffset = int64(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_lseek_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_lseek lseek "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { + r0, _, e1 := syscall_syscall6(libc_select_trampoline_addr, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_select_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_select select "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setegid(egid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setegid_trampoline_addr, uintptr(egid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setegid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setegid setegid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Seteuid(euid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_seteuid_trampoline_addr, uintptr(euid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_seteuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_seteuid seteuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setgid(gid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setgid_trampoline_addr, uintptr(gid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setgid setgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setlogin(name string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(name) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_setlogin_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setlogin_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setlogin setlogin "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setpgid(pid int, pgid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setpgid_trampoline_addr, uintptr(pid), uintptr(pgid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setpgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setpgid setpgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setpriority(which int, who int, prio int) (err error) { + _, _, e1 := syscall_syscall(libc_setpriority_trampoline_addr, uintptr(which), uintptr(who), uintptr(prio)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setpriority_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setpriority setpriority "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setregid(rgid int, egid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setregid_trampoline_addr, uintptr(rgid), uintptr(egid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setregid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setregid setregid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setreuid(ruid int, euid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setreuid_trampoline_addr, uintptr(ruid), uintptr(euid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setreuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setreuid setreuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setresgid(rgid int, egid int, sgid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setresgid_trampoline_addr, uintptr(rgid), uintptr(egid), uintptr(sgid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setresgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setresgid setresgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setresuid(ruid int, euid int, suid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setresuid_trampoline_addr, uintptr(ruid), uintptr(euid), uintptr(suid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setresuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setresuid setresuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setrlimit(which int, lim *Rlimit) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setrlimit_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setrtable(rtable int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setrtable_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setrtable setrtable "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setsid() (pid int, err error) { + r0, _, e1 := syscall_rawSyscall(libc_setsid_trampoline_addr, 0, 0, 0) + pid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setsid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setsid setsid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Settimeofday(tp *Timeval) (err error) { + _, _, e1 := syscall_rawSyscall(libc_settimeofday_trampoline_addr, uintptr(unsafe.Pointer(tp)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_settimeofday_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_settimeofday settimeofday "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setuid(uid int) (err error) { + _, _, e1 := syscall_rawSyscall(libc_setuid_trampoline_addr, uintptr(uid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setuid setuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Stat(path string, stat *Stat_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_stat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_stat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_stat stat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Statfs(path string, stat *Statfs_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_statfs_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_statfs_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_statfs statfs "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Symlink(path string, link string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_symlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_symlink_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_symlink symlink "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_symlinkat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_symlinkat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_symlinkat symlinkat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Sync() (err error) { + _, _, e1 := syscall_syscall(libc_sync_trampoline_addr, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_sync_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_sync sync "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Truncate(path string, length int64) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_truncate_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_truncate_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_truncate truncate "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Umask(newmask int) (oldmask int) { + r0, _, _ := syscall_syscall(libc_umask_trampoline_addr, uintptr(newmask), 0, 0) + oldmask = int(r0) + return +} + +var libc_umask_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_umask umask "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unlink(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_unlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_unlink_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_unlink unlink "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unlinkat(dirfd int, path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_unlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_unlinkat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unmount(path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_unmount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_unmount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_unmount unmount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func write(fd int, p []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_write_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_write write "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) { + r0, _, e1 := syscall_syscall6(libc_mmap_trampoline_addr, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos)) + ret = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mmap_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mmap mmap "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func munmap(addr uintptr, length uintptr) (err error) { + _, _, e1 := syscall_syscall(libc_munmap_trampoline_addr, uintptr(addr), uintptr(length), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_munmap_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_munmap munmap "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func readlen(fd int, buf *byte, nbuf int) (n int, err error) { + r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func writelen(fd int, buf *byte, nbuf int) (n int, err error) { + r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_utimensat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_utimensat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_utimensat utimensat "libc.so" diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s new file mode 100644 index 0000000000..e1fbd4dfa8 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s @@ -0,0 +1,669 @@ +// go run mkasm.go openbsd riscv64 +// Code generated by the command above; DO NOT EDIT. + +#include "textflag.h" + +TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getgroups(SB) +GLOBL ·libc_getgroups_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getgroups_trampoline_addr(SB)/8, $libc_getgroups_trampoline<>(SB) + +TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setgroups(SB) +GLOBL ·libc_setgroups_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setgroups_trampoline_addr(SB)/8, $libc_setgroups_trampoline<>(SB) + +TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_wait4(SB) +GLOBL ·libc_wait4_trampoline_addr(SB), RODATA, $8 +DATA ·libc_wait4_trampoline_addr(SB)/8, $libc_wait4_trampoline<>(SB) + +TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_accept(SB) +GLOBL ·libc_accept_trampoline_addr(SB), RODATA, $8 +DATA ·libc_accept_trampoline_addr(SB)/8, $libc_accept_trampoline<>(SB) + +TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_bind(SB) +GLOBL ·libc_bind_trampoline_addr(SB), RODATA, $8 +DATA ·libc_bind_trampoline_addr(SB)/8, $libc_bind_trampoline<>(SB) + +TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_connect(SB) +GLOBL ·libc_connect_trampoline_addr(SB), RODATA, $8 +DATA ·libc_connect_trampoline_addr(SB)/8, $libc_connect_trampoline<>(SB) + +TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_socket(SB) +GLOBL ·libc_socket_trampoline_addr(SB), RODATA, $8 +DATA ·libc_socket_trampoline_addr(SB)/8, $libc_socket_trampoline<>(SB) + +TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getsockopt(SB) +GLOBL ·libc_getsockopt_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getsockopt_trampoline_addr(SB)/8, $libc_getsockopt_trampoline<>(SB) + +TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setsockopt(SB) +GLOBL ·libc_setsockopt_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setsockopt_trampoline_addr(SB)/8, $libc_setsockopt_trampoline<>(SB) + +TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getpeername(SB) +GLOBL ·libc_getpeername_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpeername_trampoline_addr(SB)/8, $libc_getpeername_trampoline<>(SB) + +TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getsockname(SB) +GLOBL ·libc_getsockname_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getsockname_trampoline_addr(SB)/8, $libc_getsockname_trampoline<>(SB) + +TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_shutdown(SB) +GLOBL ·libc_shutdown_trampoline_addr(SB), RODATA, $8 +DATA ·libc_shutdown_trampoline_addr(SB)/8, $libc_shutdown_trampoline<>(SB) + +TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_socketpair(SB) +GLOBL ·libc_socketpair_trampoline_addr(SB), RODATA, $8 +DATA ·libc_socketpair_trampoline_addr(SB)/8, $libc_socketpair_trampoline<>(SB) + +TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_recvfrom(SB) +GLOBL ·libc_recvfrom_trampoline_addr(SB), RODATA, $8 +DATA ·libc_recvfrom_trampoline_addr(SB)/8, $libc_recvfrom_trampoline<>(SB) + +TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_sendto(SB) +GLOBL ·libc_sendto_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sendto_trampoline_addr(SB)/8, $libc_sendto_trampoline<>(SB) + +TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_recvmsg(SB) +GLOBL ·libc_recvmsg_trampoline_addr(SB), RODATA, $8 +DATA ·libc_recvmsg_trampoline_addr(SB)/8, $libc_recvmsg_trampoline<>(SB) + +TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_sendmsg(SB) +GLOBL ·libc_sendmsg_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sendmsg_trampoline_addr(SB)/8, $libc_sendmsg_trampoline<>(SB) + +TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_kevent(SB) +GLOBL ·libc_kevent_trampoline_addr(SB), RODATA, $8 +DATA ·libc_kevent_trampoline_addr(SB)/8, $libc_kevent_trampoline<>(SB) + +TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_utimes(SB) +GLOBL ·libc_utimes_trampoline_addr(SB), RODATA, $8 +DATA ·libc_utimes_trampoline_addr(SB)/8, $libc_utimes_trampoline<>(SB) + +TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_futimes(SB) +GLOBL ·libc_futimes_trampoline_addr(SB), RODATA, $8 +DATA ·libc_futimes_trampoline_addr(SB)/8, $libc_futimes_trampoline<>(SB) + +TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_poll(SB) +GLOBL ·libc_poll_trampoline_addr(SB), RODATA, $8 +DATA ·libc_poll_trampoline_addr(SB)/8, $libc_poll_trampoline<>(SB) + +TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_madvise(SB) +GLOBL ·libc_madvise_trampoline_addr(SB), RODATA, $8 +DATA ·libc_madvise_trampoline_addr(SB)/8, $libc_madvise_trampoline<>(SB) + +TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mlock(SB) +GLOBL ·libc_mlock_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mlock_trampoline_addr(SB)/8, $libc_mlock_trampoline<>(SB) + +TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mlockall(SB) +GLOBL ·libc_mlockall_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mlockall_trampoline_addr(SB)/8, $libc_mlockall_trampoline<>(SB) + +TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mprotect(SB) +GLOBL ·libc_mprotect_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mprotect_trampoline_addr(SB)/8, $libc_mprotect_trampoline<>(SB) + +TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_msync(SB) +GLOBL ·libc_msync_trampoline_addr(SB), RODATA, $8 +DATA ·libc_msync_trampoline_addr(SB)/8, $libc_msync_trampoline<>(SB) + +TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_munlock(SB) +GLOBL ·libc_munlock_trampoline_addr(SB), RODATA, $8 +DATA ·libc_munlock_trampoline_addr(SB)/8, $libc_munlock_trampoline<>(SB) + +TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_munlockall(SB) +GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8 +DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB) + +TEXT libc_pipe2_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pipe2(SB) +GLOBL ·libc_pipe2_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pipe2_trampoline_addr(SB)/8, $libc_pipe2_trampoline<>(SB) + +TEXT libc_getdents_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getdents(SB) +GLOBL ·libc_getdents_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getdents_trampoline_addr(SB)/8, $libc_getdents_trampoline<>(SB) + +TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getcwd(SB) +GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB) + +TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_ioctl(SB) +GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 +DATA ·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB) + +TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_sysctl(SB) +GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) + +TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_ppoll(SB) +GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $8 +DATA ·libc_ppoll_trampoline_addr(SB)/8, $libc_ppoll_trampoline<>(SB) + +TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_access(SB) +GLOBL ·libc_access_trampoline_addr(SB), RODATA, $8 +DATA ·libc_access_trampoline_addr(SB)/8, $libc_access_trampoline<>(SB) + +TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_adjtime(SB) +GLOBL ·libc_adjtime_trampoline_addr(SB), RODATA, $8 +DATA ·libc_adjtime_trampoline_addr(SB)/8, $libc_adjtime_trampoline<>(SB) + +TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_chdir(SB) +GLOBL ·libc_chdir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chdir_trampoline_addr(SB)/8, $libc_chdir_trampoline<>(SB) + +TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_chflags(SB) +GLOBL ·libc_chflags_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chflags_trampoline_addr(SB)/8, $libc_chflags_trampoline<>(SB) + +TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_chmod(SB) +GLOBL ·libc_chmod_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chmod_trampoline_addr(SB)/8, $libc_chmod_trampoline<>(SB) + +TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_chown(SB) +GLOBL ·libc_chown_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chown_trampoline_addr(SB)/8, $libc_chown_trampoline<>(SB) + +TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_chroot(SB) +GLOBL ·libc_chroot_trampoline_addr(SB), RODATA, $8 +DATA ·libc_chroot_trampoline_addr(SB)/8, $libc_chroot_trampoline<>(SB) + +TEXT libc_clock_gettime_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_clock_gettime(SB) +GLOBL ·libc_clock_gettime_trampoline_addr(SB), RODATA, $8 +DATA ·libc_clock_gettime_trampoline_addr(SB)/8, $libc_clock_gettime_trampoline<>(SB) + +TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_close(SB) +GLOBL ·libc_close_trampoline_addr(SB), RODATA, $8 +DATA ·libc_close_trampoline_addr(SB)/8, $libc_close_trampoline<>(SB) + +TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_dup(SB) +GLOBL ·libc_dup_trampoline_addr(SB), RODATA, $8 +DATA ·libc_dup_trampoline_addr(SB)/8, $libc_dup_trampoline<>(SB) + +TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_dup2(SB) +GLOBL ·libc_dup2_trampoline_addr(SB), RODATA, $8 +DATA ·libc_dup2_trampoline_addr(SB)/8, $libc_dup2_trampoline<>(SB) + +TEXT libc_dup3_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_dup3(SB) +GLOBL ·libc_dup3_trampoline_addr(SB), RODATA, $8 +DATA ·libc_dup3_trampoline_addr(SB)/8, $libc_dup3_trampoline<>(SB) + +TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_exit(SB) +GLOBL ·libc_exit_trampoline_addr(SB), RODATA, $8 +DATA ·libc_exit_trampoline_addr(SB)/8, $libc_exit_trampoline<>(SB) + +TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_faccessat(SB) +GLOBL ·libc_faccessat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_faccessat_trampoline_addr(SB)/8, $libc_faccessat_trampoline<>(SB) + +TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fchdir(SB) +GLOBL ·libc_fchdir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchdir_trampoline_addr(SB)/8, $libc_fchdir_trampoline<>(SB) + +TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fchflags(SB) +GLOBL ·libc_fchflags_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchflags_trampoline_addr(SB)/8, $libc_fchflags_trampoline<>(SB) + +TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fchmod(SB) +GLOBL ·libc_fchmod_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchmod_trampoline_addr(SB)/8, $libc_fchmod_trampoline<>(SB) + +TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fchmodat(SB) +GLOBL ·libc_fchmodat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchmodat_trampoline_addr(SB)/8, $libc_fchmodat_trampoline<>(SB) + +TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fchown(SB) +GLOBL ·libc_fchown_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchown_trampoline_addr(SB)/8, $libc_fchown_trampoline<>(SB) + +TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fchownat(SB) +GLOBL ·libc_fchownat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fchownat_trampoline_addr(SB)/8, $libc_fchownat_trampoline<>(SB) + +TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_flock(SB) +GLOBL ·libc_flock_trampoline_addr(SB), RODATA, $8 +DATA ·libc_flock_trampoline_addr(SB)/8, $libc_flock_trampoline<>(SB) + +TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fpathconf(SB) +GLOBL ·libc_fpathconf_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fpathconf_trampoline_addr(SB)/8, $libc_fpathconf_trampoline<>(SB) + +TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fstat(SB) +GLOBL ·libc_fstat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fstat_trampoline_addr(SB)/8, $libc_fstat_trampoline<>(SB) + +TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fstatat(SB) +GLOBL ·libc_fstatat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fstatat_trampoline_addr(SB)/8, $libc_fstatat_trampoline<>(SB) + +TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fstatfs(SB) +GLOBL ·libc_fstatfs_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fstatfs_trampoline_addr(SB)/8, $libc_fstatfs_trampoline<>(SB) + +TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_fsync(SB) +GLOBL ·libc_fsync_trampoline_addr(SB), RODATA, $8 +DATA ·libc_fsync_trampoline_addr(SB)/8, $libc_fsync_trampoline<>(SB) + +TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_ftruncate(SB) +GLOBL ·libc_ftruncate_trampoline_addr(SB), RODATA, $8 +DATA ·libc_ftruncate_trampoline_addr(SB)/8, $libc_ftruncate_trampoline<>(SB) + +TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getegid(SB) +GLOBL ·libc_getegid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getegid_trampoline_addr(SB)/8, $libc_getegid_trampoline<>(SB) + +TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_geteuid(SB) +GLOBL ·libc_geteuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_geteuid_trampoline_addr(SB)/8, $libc_geteuid_trampoline<>(SB) + +TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getgid(SB) +GLOBL ·libc_getgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getgid_trampoline_addr(SB)/8, $libc_getgid_trampoline<>(SB) + +TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getpgid(SB) +GLOBL ·libc_getpgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpgid_trampoline_addr(SB)/8, $libc_getpgid_trampoline<>(SB) + +TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getpgrp(SB) +GLOBL ·libc_getpgrp_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpgrp_trampoline_addr(SB)/8, $libc_getpgrp_trampoline<>(SB) + +TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getpid(SB) +GLOBL ·libc_getpid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpid_trampoline_addr(SB)/8, $libc_getpid_trampoline<>(SB) + +TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getppid(SB) +GLOBL ·libc_getppid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getppid_trampoline_addr(SB)/8, $libc_getppid_trampoline<>(SB) + +TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getpriority(SB) +GLOBL ·libc_getpriority_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getpriority_trampoline_addr(SB)/8, $libc_getpriority_trampoline<>(SB) + +TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getrlimit(SB) +GLOBL ·libc_getrlimit_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getrlimit_trampoline_addr(SB)/8, $libc_getrlimit_trampoline<>(SB) + +TEXT libc_getrtable_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getrtable(SB) +GLOBL ·libc_getrtable_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getrtable_trampoline_addr(SB)/8, $libc_getrtable_trampoline<>(SB) + +TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getrusage(SB) +GLOBL ·libc_getrusage_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getrusage_trampoline_addr(SB)/8, $libc_getrusage_trampoline<>(SB) + +TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getsid(SB) +GLOBL ·libc_getsid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getsid_trampoline_addr(SB)/8, $libc_getsid_trampoline<>(SB) + +TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_gettimeofday(SB) +GLOBL ·libc_gettimeofday_trampoline_addr(SB), RODATA, $8 +DATA ·libc_gettimeofday_trampoline_addr(SB)/8, $libc_gettimeofday_trampoline<>(SB) + +TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getuid(SB) +GLOBL ·libc_getuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getuid_trampoline_addr(SB)/8, $libc_getuid_trampoline<>(SB) + +TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_issetugid(SB) +GLOBL ·libc_issetugid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_issetugid_trampoline_addr(SB)/8, $libc_issetugid_trampoline<>(SB) + +TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_kill(SB) +GLOBL ·libc_kill_trampoline_addr(SB), RODATA, $8 +DATA ·libc_kill_trampoline_addr(SB)/8, $libc_kill_trampoline<>(SB) + +TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_kqueue(SB) +GLOBL ·libc_kqueue_trampoline_addr(SB), RODATA, $8 +DATA ·libc_kqueue_trampoline_addr(SB)/8, $libc_kqueue_trampoline<>(SB) + +TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_lchown(SB) +GLOBL ·libc_lchown_trampoline_addr(SB), RODATA, $8 +DATA ·libc_lchown_trampoline_addr(SB)/8, $libc_lchown_trampoline<>(SB) + +TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_link(SB) +GLOBL ·libc_link_trampoline_addr(SB), RODATA, $8 +DATA ·libc_link_trampoline_addr(SB)/8, $libc_link_trampoline<>(SB) + +TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_linkat(SB) +GLOBL ·libc_linkat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_linkat_trampoline_addr(SB)/8, $libc_linkat_trampoline<>(SB) + +TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_listen(SB) +GLOBL ·libc_listen_trampoline_addr(SB), RODATA, $8 +DATA ·libc_listen_trampoline_addr(SB)/8, $libc_listen_trampoline<>(SB) + +TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_lstat(SB) +GLOBL ·libc_lstat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_lstat_trampoline_addr(SB)/8, $libc_lstat_trampoline<>(SB) + +TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mkdir(SB) +GLOBL ·libc_mkdir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mkdir_trampoline_addr(SB)/8, $libc_mkdir_trampoline<>(SB) + +TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mkdirat(SB) +GLOBL ·libc_mkdirat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mkdirat_trampoline_addr(SB)/8, $libc_mkdirat_trampoline<>(SB) + +TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mkfifo(SB) +GLOBL ·libc_mkfifo_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mkfifo_trampoline_addr(SB)/8, $libc_mkfifo_trampoline<>(SB) + +TEXT libc_mkfifoat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mkfifoat(SB) +GLOBL ·libc_mkfifoat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mkfifoat_trampoline_addr(SB)/8, $libc_mkfifoat_trampoline<>(SB) + +TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mknod(SB) +GLOBL ·libc_mknod_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mknod_trampoline_addr(SB)/8, $libc_mknod_trampoline<>(SB) + +TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mknodat(SB) +GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) + +TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_nanosleep(SB) +GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $8 +DATA ·libc_nanosleep_trampoline_addr(SB)/8, $libc_nanosleep_trampoline<>(SB) + +TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_open(SB) +GLOBL ·libc_open_trampoline_addr(SB), RODATA, $8 +DATA ·libc_open_trampoline_addr(SB)/8, $libc_open_trampoline<>(SB) + +TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_openat(SB) +GLOBL ·libc_openat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_openat_trampoline_addr(SB)/8, $libc_openat_trampoline<>(SB) + +TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pathconf(SB) +GLOBL ·libc_pathconf_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pathconf_trampoline_addr(SB)/8, $libc_pathconf_trampoline<>(SB) + +TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pread(SB) +GLOBL ·libc_pread_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pread_trampoline_addr(SB)/8, $libc_pread_trampoline<>(SB) + +TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pwrite(SB) +GLOBL ·libc_pwrite_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pwrite_trampoline_addr(SB)/8, $libc_pwrite_trampoline<>(SB) + +TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_read(SB) +GLOBL ·libc_read_trampoline_addr(SB), RODATA, $8 +DATA ·libc_read_trampoline_addr(SB)/8, $libc_read_trampoline<>(SB) + +TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_readlink(SB) +GLOBL ·libc_readlink_trampoline_addr(SB), RODATA, $8 +DATA ·libc_readlink_trampoline_addr(SB)/8, $libc_readlink_trampoline<>(SB) + +TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_readlinkat(SB) +GLOBL ·libc_readlinkat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_readlinkat_trampoline_addr(SB)/8, $libc_readlinkat_trampoline<>(SB) + +TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_rename(SB) +GLOBL ·libc_rename_trampoline_addr(SB), RODATA, $8 +DATA ·libc_rename_trampoline_addr(SB)/8, $libc_rename_trampoline<>(SB) + +TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_renameat(SB) +GLOBL ·libc_renameat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_renameat_trampoline_addr(SB)/8, $libc_renameat_trampoline<>(SB) + +TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_revoke(SB) +GLOBL ·libc_revoke_trampoline_addr(SB), RODATA, $8 +DATA ·libc_revoke_trampoline_addr(SB)/8, $libc_revoke_trampoline<>(SB) + +TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_rmdir(SB) +GLOBL ·libc_rmdir_trampoline_addr(SB), RODATA, $8 +DATA ·libc_rmdir_trampoline_addr(SB)/8, $libc_rmdir_trampoline<>(SB) + +TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_lseek(SB) +GLOBL ·libc_lseek_trampoline_addr(SB), RODATA, $8 +DATA ·libc_lseek_trampoline_addr(SB)/8, $libc_lseek_trampoline<>(SB) + +TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_select(SB) +GLOBL ·libc_select_trampoline_addr(SB), RODATA, $8 +DATA ·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB) + +TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setegid(SB) +GLOBL ·libc_setegid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setegid_trampoline_addr(SB)/8, $libc_setegid_trampoline<>(SB) + +TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_seteuid(SB) +GLOBL ·libc_seteuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_seteuid_trampoline_addr(SB)/8, $libc_seteuid_trampoline<>(SB) + +TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setgid(SB) +GLOBL ·libc_setgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setgid_trampoline_addr(SB)/8, $libc_setgid_trampoline<>(SB) + +TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setlogin(SB) +GLOBL ·libc_setlogin_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setlogin_trampoline_addr(SB)/8, $libc_setlogin_trampoline<>(SB) + +TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setpgid(SB) +GLOBL ·libc_setpgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setpgid_trampoline_addr(SB)/8, $libc_setpgid_trampoline<>(SB) + +TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setpriority(SB) +GLOBL ·libc_setpriority_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setpriority_trampoline_addr(SB)/8, $libc_setpriority_trampoline<>(SB) + +TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setregid(SB) +GLOBL ·libc_setregid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setregid_trampoline_addr(SB)/8, $libc_setregid_trampoline<>(SB) + +TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setreuid(SB) +GLOBL ·libc_setreuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB) + +TEXT libc_setresgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setresgid(SB) +GLOBL ·libc_setresgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setresgid_trampoline_addr(SB)/8, $libc_setresgid_trampoline<>(SB) + +TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setresuid(SB) +GLOBL ·libc_setresuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setresuid_trampoline_addr(SB)/8, $libc_setresuid_trampoline<>(SB) + +TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setrlimit(SB) +GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB) + +TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setrtable(SB) +GLOBL ·libc_setrtable_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setrtable_trampoline_addr(SB)/8, $libc_setrtable_trampoline<>(SB) + +TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setsid(SB) +GLOBL ·libc_setsid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setsid_trampoline_addr(SB)/8, $libc_setsid_trampoline<>(SB) + +TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_settimeofday(SB) +GLOBL ·libc_settimeofday_trampoline_addr(SB), RODATA, $8 +DATA ·libc_settimeofday_trampoline_addr(SB)/8, $libc_settimeofday_trampoline<>(SB) + +TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setuid(SB) +GLOBL ·libc_setuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setuid_trampoline_addr(SB)/8, $libc_setuid_trampoline<>(SB) + +TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_stat(SB) +GLOBL ·libc_stat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_stat_trampoline_addr(SB)/8, $libc_stat_trampoline<>(SB) + +TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_statfs(SB) +GLOBL ·libc_statfs_trampoline_addr(SB), RODATA, $8 +DATA ·libc_statfs_trampoline_addr(SB)/8, $libc_statfs_trampoline<>(SB) + +TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_symlink(SB) +GLOBL ·libc_symlink_trampoline_addr(SB), RODATA, $8 +DATA ·libc_symlink_trampoline_addr(SB)/8, $libc_symlink_trampoline<>(SB) + +TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_symlinkat(SB) +GLOBL ·libc_symlinkat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_symlinkat_trampoline_addr(SB)/8, $libc_symlinkat_trampoline<>(SB) + +TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_sync(SB) +GLOBL ·libc_sync_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sync_trampoline_addr(SB)/8, $libc_sync_trampoline<>(SB) + +TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_truncate(SB) +GLOBL ·libc_truncate_trampoline_addr(SB), RODATA, $8 +DATA ·libc_truncate_trampoline_addr(SB)/8, $libc_truncate_trampoline<>(SB) + +TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_umask(SB) +GLOBL ·libc_umask_trampoline_addr(SB), RODATA, $8 +DATA ·libc_umask_trampoline_addr(SB)/8, $libc_umask_trampoline<>(SB) + +TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_unlink(SB) +GLOBL ·libc_unlink_trampoline_addr(SB), RODATA, $8 +DATA ·libc_unlink_trampoline_addr(SB)/8, $libc_unlink_trampoline<>(SB) + +TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_unlinkat(SB) +GLOBL ·libc_unlinkat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_unlinkat_trampoline_addr(SB)/8, $libc_unlinkat_trampoline<>(SB) + +TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_unmount(SB) +GLOBL ·libc_unmount_trampoline_addr(SB), RODATA, $8 +DATA ·libc_unmount_trampoline_addr(SB)/8, $libc_unmount_trampoline<>(SB) + +TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_write(SB) +GLOBL ·libc_write_trampoline_addr(SB), RODATA, $8 +DATA ·libc_write_trampoline_addr(SB)/8, $libc_write_trampoline<>(SB) + +TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mmap(SB) +GLOBL ·libc_mmap_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mmap_trampoline_addr(SB)/8, $libc_mmap_trampoline<>(SB) + +TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_munmap(SB) +GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8 +DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB) + +TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_utimensat(SB) +GLOBL ·libc_utimensat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_utimensat_trampoline_addr(SB)/8, $libc_utimensat_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index fdf53f8daf..4873a1e5d3 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -38,6 +38,7 @@ import ( //go:cgo_import_dynamic libc_chmod chmod "libc.so" //go:cgo_import_dynamic libc_chown chown "libc.so" //go:cgo_import_dynamic libc_chroot chroot "libc.so" +//go:cgo_import_dynamic libc_clockgettime clockgettime "libc.so" //go:cgo_import_dynamic libc_close close "libc.so" //go:cgo_import_dynamic libc_creat creat "libc.so" //go:cgo_import_dynamic libc_dup dup "libc.so" @@ -147,6 +148,8 @@ import ( //go:cgo_import_dynamic libc_port_dissociate port_dissociate "libc.so" //go:cgo_import_dynamic libc_port_get port_get "libc.so" //go:cgo_import_dynamic libc_port_getn port_getn "libc.so" +//go:cgo_import_dynamic libc_putmsg putmsg "libc.so" +//go:cgo_import_dynamic libc_getmsg getmsg "libc.so" //go:linkname procpipe libc_pipe //go:linkname procpipe2 libc_pipe2 @@ -175,6 +178,7 @@ import ( //go:linkname procChmod libc_chmod //go:linkname procChown libc_chown //go:linkname procChroot libc_chroot +//go:linkname procClockGettime libc_clockgettime //go:linkname procClose libc_close //go:linkname procCreat libc_creat //go:linkname procDup libc_dup @@ -284,6 +288,8 @@ import ( //go:linkname procport_dissociate libc_port_dissociate //go:linkname procport_get libc_port_get //go:linkname procport_getn libc_port_getn +//go:linkname procputmsg libc_putmsg +//go:linkname procgetmsg libc_getmsg var ( procpipe, @@ -313,6 +319,7 @@ var ( procChmod, procChown, procChroot, + procClockGettime, procClose, procCreat, procDup, @@ -421,7 +428,9 @@ var ( procport_associate, procport_dissociate, procport_get, - procport_getn syscallFunc + procport_getn, + procputmsg, + procgetmsg syscallFunc ) // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -648,6 +657,17 @@ func ioctlRet(fd int, req uint, arg uintptr) (ret int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctlPtrRet(fd int, req uint, arg unsafe.Pointer) (ret int, err error) { + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0) + ret = int(r0) + if e1 != 0 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procpoll)), 3, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout), 0, 0, 0) n = int(r0) @@ -744,6 +764,16 @@ func Chroot(path string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procClockGettime)), 2, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0, 0, 0, 0) + if e1 != 0 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procClose)), 1, uintptr(fd), 0, 0, 0, 0, 0) if e1 != 0 { @@ -2065,3 +2095,23 @@ func port_getn(port int, pe *portEvent, max uint32, nget *uint32, timeout *Times } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error) { + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procputmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(flags), 0, 0) + if e1 != 0 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error) { + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(unsafe.Pointer(flags)), 0, 0) + if e1 != 0 { + err = e1 + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go index f2079457c6..07bfe2ef9a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go @@ -267,6 +267,16 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { + _, _, e1 := syscall_syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go index 9e9d0b2a9c..55e0484719 100644 --- a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go @@ -17,6 +17,7 @@ var sysctlMib = []mibentry{ {"ddb.max_line", []_C_int{9, 3}}, {"ddb.max_width", []_C_int{9, 2}}, {"ddb.panic", []_C_int{9, 5}}, + {"ddb.profile", []_C_int{9, 9}}, {"ddb.radix", []_C_int{9, 1}}, {"ddb.tab_stop_width", []_C_int{9, 4}}, {"ddb.trigger", []_C_int{9, 8}}, @@ -33,29 +34,37 @@ var sysctlMib = []mibentry{ {"hw.ncpufound", []_C_int{6, 21}}, {"hw.ncpuonline", []_C_int{6, 25}}, {"hw.pagesize", []_C_int{6, 7}}, + {"hw.perfpolicy", []_C_int{6, 23}}, {"hw.physmem", []_C_int{6, 19}}, + {"hw.power", []_C_int{6, 26}}, {"hw.product", []_C_int{6, 15}}, {"hw.serialno", []_C_int{6, 17}}, {"hw.setperf", []_C_int{6, 13}}, + {"hw.smt", []_C_int{6, 24}}, {"hw.usermem", []_C_int{6, 20}}, {"hw.uuid", []_C_int{6, 18}}, {"hw.vendor", []_C_int{6, 14}}, {"hw.version", []_C_int{6, 16}}, - {"kern.arandom", []_C_int{1, 37}}, + {"kern.allowdt", []_C_int{1, 65}}, + {"kern.allowkmem", []_C_int{1, 52}}, {"kern.argmax", []_C_int{1, 8}}, + {"kern.audio", []_C_int{1, 84}}, {"kern.boottime", []_C_int{1, 21}}, {"kern.bufcachepercent", []_C_int{1, 72}}, {"kern.ccpu", []_C_int{1, 45}}, {"kern.clockrate", []_C_int{1, 12}}, + {"kern.consbuf", []_C_int{1, 83}}, + {"kern.consbufsize", []_C_int{1, 82}}, {"kern.consdev", []_C_int{1, 75}}, {"kern.cp_time", []_C_int{1, 40}}, {"kern.cp_time2", []_C_int{1, 71}}, - {"kern.cryptodevallowsoft", []_C_int{1, 53}}, + {"kern.cpustats", []_C_int{1, 85}}, {"kern.domainname", []_C_int{1, 22}}, {"kern.file", []_C_int{1, 73}}, {"kern.forkstat", []_C_int{1, 42}}, {"kern.fscale", []_C_int{1, 46}}, {"kern.fsync", []_C_int{1, 33}}, + {"kern.global_ptrace", []_C_int{1, 81}}, {"kern.hostid", []_C_int{1, 11}}, {"kern.hostname", []_C_int{1, 10}}, {"kern.intrcnt.nintrcnt", []_C_int{1, 63, 1}}, @@ -78,17 +87,16 @@ var sysctlMib = []mibentry{ {"kern.ngroups", []_C_int{1, 18}}, {"kern.nosuidcoredump", []_C_int{1, 32}}, {"kern.nprocs", []_C_int{1, 47}}, - {"kern.nselcoll", []_C_int{1, 43}}, {"kern.nthreads", []_C_int{1, 26}}, {"kern.numvnodes", []_C_int{1, 58}}, {"kern.osrelease", []_C_int{1, 2}}, {"kern.osrevision", []_C_int{1, 3}}, {"kern.ostype", []_C_int{1, 1}}, {"kern.osversion", []_C_int{1, 27}}, + {"kern.pfstatus", []_C_int{1, 86}}, {"kern.pool_debug", []_C_int{1, 77}}, {"kern.posix1version", []_C_int{1, 17}}, {"kern.proc", []_C_int{1, 66}}, - {"kern.random", []_C_int{1, 31}}, {"kern.rawpartition", []_C_int{1, 24}}, {"kern.saved_ids", []_C_int{1, 20}}, {"kern.securelevel", []_C_int{1, 9}}, @@ -106,21 +114,20 @@ var sysctlMib = []mibentry{ {"kern.timecounter.hardware", []_C_int{1, 69, 3}}, {"kern.timecounter.tick", []_C_int{1, 69, 1}}, {"kern.timecounter.timestepwarnings", []_C_int{1, 69, 2}}, - {"kern.tty.maxptys", []_C_int{1, 44, 6}}, - {"kern.tty.nptys", []_C_int{1, 44, 7}}, + {"kern.timeout_stats", []_C_int{1, 87}}, {"kern.tty.tk_cancc", []_C_int{1, 44, 4}}, {"kern.tty.tk_nin", []_C_int{1, 44, 1}}, {"kern.tty.tk_nout", []_C_int{1, 44, 2}}, {"kern.tty.tk_rawcc", []_C_int{1, 44, 3}}, {"kern.tty.ttyinfo", []_C_int{1, 44, 5}}, {"kern.ttycount", []_C_int{1, 57}}, - {"kern.userasymcrypto", []_C_int{1, 60}}, - {"kern.usercrypto", []_C_int{1, 52}}, - {"kern.usermount", []_C_int{1, 30}}, + {"kern.utc_offset", []_C_int{1, 88}}, {"kern.version", []_C_int{1, 4}}, - {"kern.vnode", []_C_int{1, 13}}, + {"kern.video", []_C_int{1, 89}}, {"kern.watchdog.auto", []_C_int{1, 64, 2}}, {"kern.watchdog.period", []_C_int{1, 64, 1}}, + {"kern.witnesswatch", []_C_int{1, 53}}, + {"kern.wxabort", []_C_int{1, 74}}, {"net.bpf.bufsize", []_C_int{4, 31, 1}}, {"net.bpf.maxbufsize", []_C_int{4, 31, 2}}, {"net.inet.ah.enable", []_C_int{4, 2, 51, 1}}, @@ -148,7 +155,9 @@ var sysctlMib = []mibentry{ {"net.inet.icmp.stats", []_C_int{4, 2, 1, 7}}, {"net.inet.icmp.tstamprepl", []_C_int{4, 2, 1, 6}}, {"net.inet.igmp.stats", []_C_int{4, 2, 2, 1}}, + {"net.inet.ip.arpdown", []_C_int{4, 2, 0, 40}}, {"net.inet.ip.arpqueued", []_C_int{4, 2, 0, 36}}, + {"net.inet.ip.arptimeout", []_C_int{4, 2, 0, 39}}, {"net.inet.ip.encdebug", []_C_int{4, 2, 0, 12}}, {"net.inet.ip.forwarding", []_C_int{4, 2, 0, 1}}, {"net.inet.ip.ifq.congestion", []_C_int{4, 2, 0, 30, 4}}, @@ -157,8 +166,10 @@ var sysctlMib = []mibentry{ {"net.inet.ip.ifq.maxlen", []_C_int{4, 2, 0, 30, 2}}, {"net.inet.ip.maxqueue", []_C_int{4, 2, 0, 11}}, {"net.inet.ip.mforwarding", []_C_int{4, 2, 0, 31}}, + {"net.inet.ip.mrtmfc", []_C_int{4, 2, 0, 37}}, {"net.inet.ip.mrtproto", []_C_int{4, 2, 0, 34}}, {"net.inet.ip.mrtstats", []_C_int{4, 2, 0, 35}}, + {"net.inet.ip.mrtvif", []_C_int{4, 2, 0, 38}}, {"net.inet.ip.mtu", []_C_int{4, 2, 0, 4}}, {"net.inet.ip.mtudisc", []_C_int{4, 2, 0, 27}}, {"net.inet.ip.mtudisctimeout", []_C_int{4, 2, 0, 28}}, @@ -175,9 +186,7 @@ var sysctlMib = []mibentry{ {"net.inet.ipcomp.stats", []_C_int{4, 2, 108, 2}}, {"net.inet.ipip.allow", []_C_int{4, 2, 4, 1}}, {"net.inet.ipip.stats", []_C_int{4, 2, 4, 2}}, - {"net.inet.mobileip.allow", []_C_int{4, 2, 55, 1}}, {"net.inet.pfsync.stats", []_C_int{4, 2, 240, 1}}, - {"net.inet.pim.stats", []_C_int{4, 2, 103, 1}}, {"net.inet.tcp.ackonpush", []_C_int{4, 2, 6, 13}}, {"net.inet.tcp.always_keepalive", []_C_int{4, 2, 6, 22}}, {"net.inet.tcp.baddynamic", []_C_int{4, 2, 6, 6}}, @@ -191,6 +200,7 @@ var sysctlMib = []mibentry{ {"net.inet.tcp.reasslimit", []_C_int{4, 2, 6, 18}}, {"net.inet.tcp.rfc1323", []_C_int{4, 2, 6, 1}}, {"net.inet.tcp.rfc3390", []_C_int{4, 2, 6, 17}}, + {"net.inet.tcp.rootonly", []_C_int{4, 2, 6, 24}}, {"net.inet.tcp.rstppslimit", []_C_int{4, 2, 6, 12}}, {"net.inet.tcp.sack", []_C_int{4, 2, 6, 10}}, {"net.inet.tcp.sackholelimit", []_C_int{4, 2, 6, 20}}, @@ -198,9 +208,12 @@ var sysctlMib = []mibentry{ {"net.inet.tcp.stats", []_C_int{4, 2, 6, 21}}, {"net.inet.tcp.synbucketlimit", []_C_int{4, 2, 6, 16}}, {"net.inet.tcp.syncachelimit", []_C_int{4, 2, 6, 15}}, + {"net.inet.tcp.synhashsize", []_C_int{4, 2, 6, 25}}, + {"net.inet.tcp.synuselimit", []_C_int{4, 2, 6, 23}}, {"net.inet.udp.baddynamic", []_C_int{4, 2, 17, 2}}, {"net.inet.udp.checksum", []_C_int{4, 2, 17, 1}}, {"net.inet.udp.recvspace", []_C_int{4, 2, 17, 3}}, + {"net.inet.udp.rootonly", []_C_int{4, 2, 17, 6}}, {"net.inet.udp.sendspace", []_C_int{4, 2, 17, 4}}, {"net.inet.udp.stats", []_C_int{4, 2, 17, 5}}, {"net.inet6.divert.recvspace", []_C_int{4, 24, 86, 1}}, @@ -213,13 +226,8 @@ var sysctlMib = []mibentry{ {"net.inet6.icmp6.nd6_delay", []_C_int{4, 24, 30, 8}}, {"net.inet6.icmp6.nd6_maxnudhint", []_C_int{4, 24, 30, 15}}, {"net.inet6.icmp6.nd6_mmaxtries", []_C_int{4, 24, 30, 10}}, - {"net.inet6.icmp6.nd6_prune", []_C_int{4, 24, 30, 6}}, {"net.inet6.icmp6.nd6_umaxtries", []_C_int{4, 24, 30, 9}}, - {"net.inet6.icmp6.nd6_useloopback", []_C_int{4, 24, 30, 11}}, - {"net.inet6.icmp6.nodeinfo", []_C_int{4, 24, 30, 13}}, - {"net.inet6.icmp6.rediraccept", []_C_int{4, 24, 30, 2}}, {"net.inet6.icmp6.redirtimeout", []_C_int{4, 24, 30, 3}}, - {"net.inet6.ip6.accept_rtadv", []_C_int{4, 24, 17, 12}}, {"net.inet6.ip6.auto_flowlabel", []_C_int{4, 24, 17, 17}}, {"net.inet6.ip6.dad_count", []_C_int{4, 24, 17, 16}}, {"net.inet6.ip6.dad_pending", []_C_int{4, 24, 17, 49}}, @@ -232,20 +240,19 @@ var sysctlMib = []mibentry{ {"net.inet6.ip6.maxdynroutes", []_C_int{4, 24, 17, 48}}, {"net.inet6.ip6.maxfragpackets", []_C_int{4, 24, 17, 9}}, {"net.inet6.ip6.maxfrags", []_C_int{4, 24, 17, 41}}, - {"net.inet6.ip6.maxifdefrouters", []_C_int{4, 24, 17, 47}}, - {"net.inet6.ip6.maxifprefixes", []_C_int{4, 24, 17, 46}}, {"net.inet6.ip6.mforwarding", []_C_int{4, 24, 17, 42}}, + {"net.inet6.ip6.mrtmfc", []_C_int{4, 24, 17, 53}}, + {"net.inet6.ip6.mrtmif", []_C_int{4, 24, 17, 52}}, {"net.inet6.ip6.mrtproto", []_C_int{4, 24, 17, 8}}, {"net.inet6.ip6.mtudisctimeout", []_C_int{4, 24, 17, 50}}, {"net.inet6.ip6.multicast_mtudisc", []_C_int{4, 24, 17, 44}}, {"net.inet6.ip6.multipath", []_C_int{4, 24, 17, 43}}, {"net.inet6.ip6.neighborgcthresh", []_C_int{4, 24, 17, 45}}, {"net.inet6.ip6.redirect", []_C_int{4, 24, 17, 2}}, - {"net.inet6.ip6.rr_prune", []_C_int{4, 24, 17, 22}}, + {"net.inet6.ip6.soiikey", []_C_int{4, 24, 17, 54}}, {"net.inet6.ip6.sourcecheck", []_C_int{4, 24, 17, 10}}, {"net.inet6.ip6.sourcecheck_logint", []_C_int{4, 24, 17, 11}}, {"net.inet6.ip6.use_deprecated", []_C_int{4, 24, 17, 21}}, - {"net.inet6.ip6.v6only", []_C_int{4, 24, 17, 24}}, {"net.key.sadb_dump", []_C_int{4, 30, 1}}, {"net.key.spd_dump", []_C_int{4, 30, 2}}, {"net.mpls.ifq.congestion", []_C_int{4, 33, 3, 4}}, @@ -254,12 +261,12 @@ var sysctlMib = []mibentry{ {"net.mpls.ifq.maxlen", []_C_int{4, 33, 3, 2}}, {"net.mpls.mapttl_ip", []_C_int{4, 33, 5}}, {"net.mpls.mapttl_ip6", []_C_int{4, 33, 6}}, - {"net.mpls.maxloop_inkernel", []_C_int{4, 33, 4}}, {"net.mpls.ttl", []_C_int{4, 33, 2}}, {"net.pflow.stats", []_C_int{4, 34, 1}}, {"net.pipex.enable", []_C_int{4, 35, 1}}, {"vm.anonmin", []_C_int{2, 7}}, {"vm.loadavg", []_C_int{2, 2}}, + {"vm.malloc_conf", []_C_int{2, 12}}, {"vm.maxslp", []_C_int{2, 10}}, {"vm.nkmempages", []_C_int{2, 6}}, {"vm.psstrings", []_C_int{2, 3}}, diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go index adecd09667..d2243cf83f 100644 --- a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go @@ -36,23 +36,29 @@ var sysctlMib = []mibentry{ {"hw.pagesize", []_C_int{6, 7}}, {"hw.perfpolicy", []_C_int{6, 23}}, {"hw.physmem", []_C_int{6, 19}}, + {"hw.power", []_C_int{6, 26}}, {"hw.product", []_C_int{6, 15}}, {"hw.serialno", []_C_int{6, 17}}, {"hw.setperf", []_C_int{6, 13}}, + {"hw.smt", []_C_int{6, 24}}, {"hw.usermem", []_C_int{6, 20}}, {"hw.uuid", []_C_int{6, 18}}, {"hw.vendor", []_C_int{6, 14}}, {"hw.version", []_C_int{6, 16}}, + {"kern.allowdt", []_C_int{1, 65}}, {"kern.allowkmem", []_C_int{1, 52}}, {"kern.argmax", []_C_int{1, 8}}, + {"kern.audio", []_C_int{1, 84}}, {"kern.boottime", []_C_int{1, 21}}, {"kern.bufcachepercent", []_C_int{1, 72}}, {"kern.ccpu", []_C_int{1, 45}}, {"kern.clockrate", []_C_int{1, 12}}, + {"kern.consbuf", []_C_int{1, 83}}, + {"kern.consbufsize", []_C_int{1, 82}}, {"kern.consdev", []_C_int{1, 75}}, {"kern.cp_time", []_C_int{1, 40}}, {"kern.cp_time2", []_C_int{1, 71}}, - {"kern.dnsjackport", []_C_int{1, 13}}, + {"kern.cpustats", []_C_int{1, 85}}, {"kern.domainname", []_C_int{1, 22}}, {"kern.file", []_C_int{1, 73}}, {"kern.forkstat", []_C_int{1, 42}}, @@ -81,13 +87,13 @@ var sysctlMib = []mibentry{ {"kern.ngroups", []_C_int{1, 18}}, {"kern.nosuidcoredump", []_C_int{1, 32}}, {"kern.nprocs", []_C_int{1, 47}}, - {"kern.nselcoll", []_C_int{1, 43}}, {"kern.nthreads", []_C_int{1, 26}}, {"kern.numvnodes", []_C_int{1, 58}}, {"kern.osrelease", []_C_int{1, 2}}, {"kern.osrevision", []_C_int{1, 3}}, {"kern.ostype", []_C_int{1, 1}}, {"kern.osversion", []_C_int{1, 27}}, + {"kern.pfstatus", []_C_int{1, 86}}, {"kern.pool_debug", []_C_int{1, 77}}, {"kern.posix1version", []_C_int{1, 17}}, {"kern.proc", []_C_int{1, 66}}, @@ -108,15 +114,19 @@ var sysctlMib = []mibentry{ {"kern.timecounter.hardware", []_C_int{1, 69, 3}}, {"kern.timecounter.tick", []_C_int{1, 69, 1}}, {"kern.timecounter.timestepwarnings", []_C_int{1, 69, 2}}, + {"kern.timeout_stats", []_C_int{1, 87}}, {"kern.tty.tk_cancc", []_C_int{1, 44, 4}}, {"kern.tty.tk_nin", []_C_int{1, 44, 1}}, {"kern.tty.tk_nout", []_C_int{1, 44, 2}}, {"kern.tty.tk_rawcc", []_C_int{1, 44, 3}}, {"kern.tty.ttyinfo", []_C_int{1, 44, 5}}, {"kern.ttycount", []_C_int{1, 57}}, + {"kern.utc_offset", []_C_int{1, 88}}, {"kern.version", []_C_int{1, 4}}, + {"kern.video", []_C_int{1, 89}}, {"kern.watchdog.auto", []_C_int{1, 64, 2}}, {"kern.watchdog.period", []_C_int{1, 64, 1}}, + {"kern.witnesswatch", []_C_int{1, 53}}, {"kern.wxabort", []_C_int{1, 74}}, {"net.bpf.bufsize", []_C_int{4, 31, 1}}, {"net.bpf.maxbufsize", []_C_int{4, 31, 2}}, @@ -176,7 +186,6 @@ var sysctlMib = []mibentry{ {"net.inet.ipcomp.stats", []_C_int{4, 2, 108, 2}}, {"net.inet.ipip.allow", []_C_int{4, 2, 4, 1}}, {"net.inet.ipip.stats", []_C_int{4, 2, 4, 2}}, - {"net.inet.mobileip.allow", []_C_int{4, 2, 55, 1}}, {"net.inet.pfsync.stats", []_C_int{4, 2, 240, 1}}, {"net.inet.tcp.ackonpush", []_C_int{4, 2, 6, 13}}, {"net.inet.tcp.always_keepalive", []_C_int{4, 2, 6, 22}}, @@ -252,12 +261,12 @@ var sysctlMib = []mibentry{ {"net.mpls.ifq.maxlen", []_C_int{4, 33, 3, 2}}, {"net.mpls.mapttl_ip", []_C_int{4, 33, 5}}, {"net.mpls.mapttl_ip6", []_C_int{4, 33, 6}}, - {"net.mpls.maxloop_inkernel", []_C_int{4, 33, 4}}, {"net.mpls.ttl", []_C_int{4, 33, 2}}, {"net.pflow.stats", []_C_int{4, 34, 1}}, {"net.pipex.enable", []_C_int{4, 35, 1}}, {"vm.anonmin", []_C_int{2, 7}}, {"vm.loadavg", []_C_int{2, 2}}, + {"vm.malloc_conf", []_C_int{2, 12}}, {"vm.maxslp", []_C_int{2, 10}}, {"vm.nkmempages", []_C_int{2, 6}}, {"vm.psstrings", []_C_int{2, 3}}, diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go index 8ea52a4a18..82dc51bd8b 100644 --- a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go @@ -17,6 +17,7 @@ var sysctlMib = []mibentry{ {"ddb.max_line", []_C_int{9, 3}}, {"ddb.max_width", []_C_int{9, 2}}, {"ddb.panic", []_C_int{9, 5}}, + {"ddb.profile", []_C_int{9, 9}}, {"ddb.radix", []_C_int{9, 1}}, {"ddb.tab_stop_width", []_C_int{9, 4}}, {"ddb.trigger", []_C_int{9, 8}}, @@ -33,29 +34,37 @@ var sysctlMib = []mibentry{ {"hw.ncpufound", []_C_int{6, 21}}, {"hw.ncpuonline", []_C_int{6, 25}}, {"hw.pagesize", []_C_int{6, 7}}, + {"hw.perfpolicy", []_C_int{6, 23}}, {"hw.physmem", []_C_int{6, 19}}, + {"hw.power", []_C_int{6, 26}}, {"hw.product", []_C_int{6, 15}}, {"hw.serialno", []_C_int{6, 17}}, {"hw.setperf", []_C_int{6, 13}}, + {"hw.smt", []_C_int{6, 24}}, {"hw.usermem", []_C_int{6, 20}}, {"hw.uuid", []_C_int{6, 18}}, {"hw.vendor", []_C_int{6, 14}}, {"hw.version", []_C_int{6, 16}}, - {"kern.arandom", []_C_int{1, 37}}, + {"kern.allowdt", []_C_int{1, 65}}, + {"kern.allowkmem", []_C_int{1, 52}}, {"kern.argmax", []_C_int{1, 8}}, + {"kern.audio", []_C_int{1, 84}}, {"kern.boottime", []_C_int{1, 21}}, {"kern.bufcachepercent", []_C_int{1, 72}}, {"kern.ccpu", []_C_int{1, 45}}, {"kern.clockrate", []_C_int{1, 12}}, + {"kern.consbuf", []_C_int{1, 83}}, + {"kern.consbufsize", []_C_int{1, 82}}, {"kern.consdev", []_C_int{1, 75}}, {"kern.cp_time", []_C_int{1, 40}}, {"kern.cp_time2", []_C_int{1, 71}}, - {"kern.cryptodevallowsoft", []_C_int{1, 53}}, + {"kern.cpustats", []_C_int{1, 85}}, {"kern.domainname", []_C_int{1, 22}}, {"kern.file", []_C_int{1, 73}}, {"kern.forkstat", []_C_int{1, 42}}, {"kern.fscale", []_C_int{1, 46}}, {"kern.fsync", []_C_int{1, 33}}, + {"kern.global_ptrace", []_C_int{1, 81}}, {"kern.hostid", []_C_int{1, 11}}, {"kern.hostname", []_C_int{1, 10}}, {"kern.intrcnt.nintrcnt", []_C_int{1, 63, 1}}, @@ -78,17 +87,16 @@ var sysctlMib = []mibentry{ {"kern.ngroups", []_C_int{1, 18}}, {"kern.nosuidcoredump", []_C_int{1, 32}}, {"kern.nprocs", []_C_int{1, 47}}, - {"kern.nselcoll", []_C_int{1, 43}}, {"kern.nthreads", []_C_int{1, 26}}, {"kern.numvnodes", []_C_int{1, 58}}, {"kern.osrelease", []_C_int{1, 2}}, {"kern.osrevision", []_C_int{1, 3}}, {"kern.ostype", []_C_int{1, 1}}, {"kern.osversion", []_C_int{1, 27}}, + {"kern.pfstatus", []_C_int{1, 86}}, {"kern.pool_debug", []_C_int{1, 77}}, {"kern.posix1version", []_C_int{1, 17}}, {"kern.proc", []_C_int{1, 66}}, - {"kern.random", []_C_int{1, 31}}, {"kern.rawpartition", []_C_int{1, 24}}, {"kern.saved_ids", []_C_int{1, 20}}, {"kern.securelevel", []_C_int{1, 9}}, @@ -106,21 +114,20 @@ var sysctlMib = []mibentry{ {"kern.timecounter.hardware", []_C_int{1, 69, 3}}, {"kern.timecounter.tick", []_C_int{1, 69, 1}}, {"kern.timecounter.timestepwarnings", []_C_int{1, 69, 2}}, - {"kern.tty.maxptys", []_C_int{1, 44, 6}}, - {"kern.tty.nptys", []_C_int{1, 44, 7}}, + {"kern.timeout_stats", []_C_int{1, 87}}, {"kern.tty.tk_cancc", []_C_int{1, 44, 4}}, {"kern.tty.tk_nin", []_C_int{1, 44, 1}}, {"kern.tty.tk_nout", []_C_int{1, 44, 2}}, {"kern.tty.tk_rawcc", []_C_int{1, 44, 3}}, {"kern.tty.ttyinfo", []_C_int{1, 44, 5}}, {"kern.ttycount", []_C_int{1, 57}}, - {"kern.userasymcrypto", []_C_int{1, 60}}, - {"kern.usercrypto", []_C_int{1, 52}}, - {"kern.usermount", []_C_int{1, 30}}, + {"kern.utc_offset", []_C_int{1, 88}}, {"kern.version", []_C_int{1, 4}}, - {"kern.vnode", []_C_int{1, 13}}, + {"kern.video", []_C_int{1, 89}}, {"kern.watchdog.auto", []_C_int{1, 64, 2}}, {"kern.watchdog.period", []_C_int{1, 64, 1}}, + {"kern.witnesswatch", []_C_int{1, 53}}, + {"kern.wxabort", []_C_int{1, 74}}, {"net.bpf.bufsize", []_C_int{4, 31, 1}}, {"net.bpf.maxbufsize", []_C_int{4, 31, 2}}, {"net.inet.ah.enable", []_C_int{4, 2, 51, 1}}, @@ -148,7 +155,9 @@ var sysctlMib = []mibentry{ {"net.inet.icmp.stats", []_C_int{4, 2, 1, 7}}, {"net.inet.icmp.tstamprepl", []_C_int{4, 2, 1, 6}}, {"net.inet.igmp.stats", []_C_int{4, 2, 2, 1}}, + {"net.inet.ip.arpdown", []_C_int{4, 2, 0, 40}}, {"net.inet.ip.arpqueued", []_C_int{4, 2, 0, 36}}, + {"net.inet.ip.arptimeout", []_C_int{4, 2, 0, 39}}, {"net.inet.ip.encdebug", []_C_int{4, 2, 0, 12}}, {"net.inet.ip.forwarding", []_C_int{4, 2, 0, 1}}, {"net.inet.ip.ifq.congestion", []_C_int{4, 2, 0, 30, 4}}, @@ -157,8 +166,10 @@ var sysctlMib = []mibentry{ {"net.inet.ip.ifq.maxlen", []_C_int{4, 2, 0, 30, 2}}, {"net.inet.ip.maxqueue", []_C_int{4, 2, 0, 11}}, {"net.inet.ip.mforwarding", []_C_int{4, 2, 0, 31}}, + {"net.inet.ip.mrtmfc", []_C_int{4, 2, 0, 37}}, {"net.inet.ip.mrtproto", []_C_int{4, 2, 0, 34}}, {"net.inet.ip.mrtstats", []_C_int{4, 2, 0, 35}}, + {"net.inet.ip.mrtvif", []_C_int{4, 2, 0, 38}}, {"net.inet.ip.mtu", []_C_int{4, 2, 0, 4}}, {"net.inet.ip.mtudisc", []_C_int{4, 2, 0, 27}}, {"net.inet.ip.mtudisctimeout", []_C_int{4, 2, 0, 28}}, @@ -175,9 +186,7 @@ var sysctlMib = []mibentry{ {"net.inet.ipcomp.stats", []_C_int{4, 2, 108, 2}}, {"net.inet.ipip.allow", []_C_int{4, 2, 4, 1}}, {"net.inet.ipip.stats", []_C_int{4, 2, 4, 2}}, - {"net.inet.mobileip.allow", []_C_int{4, 2, 55, 1}}, {"net.inet.pfsync.stats", []_C_int{4, 2, 240, 1}}, - {"net.inet.pim.stats", []_C_int{4, 2, 103, 1}}, {"net.inet.tcp.ackonpush", []_C_int{4, 2, 6, 13}}, {"net.inet.tcp.always_keepalive", []_C_int{4, 2, 6, 22}}, {"net.inet.tcp.baddynamic", []_C_int{4, 2, 6, 6}}, @@ -191,6 +200,7 @@ var sysctlMib = []mibentry{ {"net.inet.tcp.reasslimit", []_C_int{4, 2, 6, 18}}, {"net.inet.tcp.rfc1323", []_C_int{4, 2, 6, 1}}, {"net.inet.tcp.rfc3390", []_C_int{4, 2, 6, 17}}, + {"net.inet.tcp.rootonly", []_C_int{4, 2, 6, 24}}, {"net.inet.tcp.rstppslimit", []_C_int{4, 2, 6, 12}}, {"net.inet.tcp.sack", []_C_int{4, 2, 6, 10}}, {"net.inet.tcp.sackholelimit", []_C_int{4, 2, 6, 20}}, @@ -198,9 +208,12 @@ var sysctlMib = []mibentry{ {"net.inet.tcp.stats", []_C_int{4, 2, 6, 21}}, {"net.inet.tcp.synbucketlimit", []_C_int{4, 2, 6, 16}}, {"net.inet.tcp.syncachelimit", []_C_int{4, 2, 6, 15}}, + {"net.inet.tcp.synhashsize", []_C_int{4, 2, 6, 25}}, + {"net.inet.tcp.synuselimit", []_C_int{4, 2, 6, 23}}, {"net.inet.udp.baddynamic", []_C_int{4, 2, 17, 2}}, {"net.inet.udp.checksum", []_C_int{4, 2, 17, 1}}, {"net.inet.udp.recvspace", []_C_int{4, 2, 17, 3}}, + {"net.inet.udp.rootonly", []_C_int{4, 2, 17, 6}}, {"net.inet.udp.sendspace", []_C_int{4, 2, 17, 4}}, {"net.inet.udp.stats", []_C_int{4, 2, 17, 5}}, {"net.inet6.divert.recvspace", []_C_int{4, 24, 86, 1}}, @@ -213,13 +226,8 @@ var sysctlMib = []mibentry{ {"net.inet6.icmp6.nd6_delay", []_C_int{4, 24, 30, 8}}, {"net.inet6.icmp6.nd6_maxnudhint", []_C_int{4, 24, 30, 15}}, {"net.inet6.icmp6.nd6_mmaxtries", []_C_int{4, 24, 30, 10}}, - {"net.inet6.icmp6.nd6_prune", []_C_int{4, 24, 30, 6}}, {"net.inet6.icmp6.nd6_umaxtries", []_C_int{4, 24, 30, 9}}, - {"net.inet6.icmp6.nd6_useloopback", []_C_int{4, 24, 30, 11}}, - {"net.inet6.icmp6.nodeinfo", []_C_int{4, 24, 30, 13}}, - {"net.inet6.icmp6.rediraccept", []_C_int{4, 24, 30, 2}}, {"net.inet6.icmp6.redirtimeout", []_C_int{4, 24, 30, 3}}, - {"net.inet6.ip6.accept_rtadv", []_C_int{4, 24, 17, 12}}, {"net.inet6.ip6.auto_flowlabel", []_C_int{4, 24, 17, 17}}, {"net.inet6.ip6.dad_count", []_C_int{4, 24, 17, 16}}, {"net.inet6.ip6.dad_pending", []_C_int{4, 24, 17, 49}}, @@ -232,20 +240,19 @@ var sysctlMib = []mibentry{ {"net.inet6.ip6.maxdynroutes", []_C_int{4, 24, 17, 48}}, {"net.inet6.ip6.maxfragpackets", []_C_int{4, 24, 17, 9}}, {"net.inet6.ip6.maxfrags", []_C_int{4, 24, 17, 41}}, - {"net.inet6.ip6.maxifdefrouters", []_C_int{4, 24, 17, 47}}, - {"net.inet6.ip6.maxifprefixes", []_C_int{4, 24, 17, 46}}, {"net.inet6.ip6.mforwarding", []_C_int{4, 24, 17, 42}}, + {"net.inet6.ip6.mrtmfc", []_C_int{4, 24, 17, 53}}, + {"net.inet6.ip6.mrtmif", []_C_int{4, 24, 17, 52}}, {"net.inet6.ip6.mrtproto", []_C_int{4, 24, 17, 8}}, {"net.inet6.ip6.mtudisctimeout", []_C_int{4, 24, 17, 50}}, {"net.inet6.ip6.multicast_mtudisc", []_C_int{4, 24, 17, 44}}, {"net.inet6.ip6.multipath", []_C_int{4, 24, 17, 43}}, {"net.inet6.ip6.neighborgcthresh", []_C_int{4, 24, 17, 45}}, {"net.inet6.ip6.redirect", []_C_int{4, 24, 17, 2}}, - {"net.inet6.ip6.rr_prune", []_C_int{4, 24, 17, 22}}, + {"net.inet6.ip6.soiikey", []_C_int{4, 24, 17, 54}}, {"net.inet6.ip6.sourcecheck", []_C_int{4, 24, 17, 10}}, {"net.inet6.ip6.sourcecheck_logint", []_C_int{4, 24, 17, 11}}, {"net.inet6.ip6.use_deprecated", []_C_int{4, 24, 17, 21}}, - {"net.inet6.ip6.v6only", []_C_int{4, 24, 17, 24}}, {"net.key.sadb_dump", []_C_int{4, 30, 1}}, {"net.key.spd_dump", []_C_int{4, 30, 2}}, {"net.mpls.ifq.congestion", []_C_int{4, 33, 3, 4}}, @@ -254,12 +261,12 @@ var sysctlMib = []mibentry{ {"net.mpls.ifq.maxlen", []_C_int{4, 33, 3, 2}}, {"net.mpls.mapttl_ip", []_C_int{4, 33, 5}}, {"net.mpls.mapttl_ip6", []_C_int{4, 33, 6}}, - {"net.mpls.maxloop_inkernel", []_C_int{4, 33, 4}}, {"net.mpls.ttl", []_C_int{4, 33, 2}}, {"net.pflow.stats", []_C_int{4, 34, 1}}, {"net.pipex.enable", []_C_int{4, 35, 1}}, {"vm.anonmin", []_C_int{2, 7}}, {"vm.loadavg", []_C_int{2, 2}}, + {"vm.malloc_conf", []_C_int{2, 12}}, {"vm.maxslp", []_C_int{2, 10}}, {"vm.nkmempages", []_C_int{2, 6}}, {"vm.psstrings", []_C_int{2, 3}}, diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go index 154b57ae3e..cbdda1a4ae 100644 --- a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go @@ -36,6 +36,7 @@ var sysctlMib = []mibentry{ {"hw.pagesize", []_C_int{6, 7}}, {"hw.perfpolicy", []_C_int{6, 23}}, {"hw.physmem", []_C_int{6, 19}}, + {"hw.power", []_C_int{6, 26}}, {"hw.product", []_C_int{6, 15}}, {"hw.serialno", []_C_int{6, 17}}, {"hw.setperf", []_C_int{6, 13}}, @@ -44,6 +45,7 @@ var sysctlMib = []mibentry{ {"hw.uuid", []_C_int{6, 18}}, {"hw.vendor", []_C_int{6, 14}}, {"hw.version", []_C_int{6, 16}}, + {"kern.allowdt", []_C_int{1, 65}}, {"kern.allowkmem", []_C_int{1, 52}}, {"kern.argmax", []_C_int{1, 8}}, {"kern.audio", []_C_int{1, 84}}, @@ -51,6 +53,8 @@ var sysctlMib = []mibentry{ {"kern.bufcachepercent", []_C_int{1, 72}}, {"kern.ccpu", []_C_int{1, 45}}, {"kern.clockrate", []_C_int{1, 12}}, + {"kern.consbuf", []_C_int{1, 83}}, + {"kern.consbufsize", []_C_int{1, 82}}, {"kern.consdev", []_C_int{1, 75}}, {"kern.cp_time", []_C_int{1, 40}}, {"kern.cp_time2", []_C_int{1, 71}}, @@ -83,13 +87,13 @@ var sysctlMib = []mibentry{ {"kern.ngroups", []_C_int{1, 18}}, {"kern.nosuidcoredump", []_C_int{1, 32}}, {"kern.nprocs", []_C_int{1, 47}}, - {"kern.nselcoll", []_C_int{1, 43}}, {"kern.nthreads", []_C_int{1, 26}}, {"kern.numvnodes", []_C_int{1, 58}}, {"kern.osrelease", []_C_int{1, 2}}, {"kern.osrevision", []_C_int{1, 3}}, {"kern.ostype", []_C_int{1, 1}}, {"kern.osversion", []_C_int{1, 27}}, + {"kern.pfstatus", []_C_int{1, 86}}, {"kern.pool_debug", []_C_int{1, 77}}, {"kern.posix1version", []_C_int{1, 17}}, {"kern.proc", []_C_int{1, 66}}, @@ -110,13 +114,16 @@ var sysctlMib = []mibentry{ {"kern.timecounter.hardware", []_C_int{1, 69, 3}}, {"kern.timecounter.tick", []_C_int{1, 69, 1}}, {"kern.timecounter.timestepwarnings", []_C_int{1, 69, 2}}, + {"kern.timeout_stats", []_C_int{1, 87}}, {"kern.tty.tk_cancc", []_C_int{1, 44, 4}}, {"kern.tty.tk_nin", []_C_int{1, 44, 1}}, {"kern.tty.tk_nout", []_C_int{1, 44, 2}}, {"kern.tty.tk_rawcc", []_C_int{1, 44, 3}}, {"kern.tty.ttyinfo", []_C_int{1, 44, 5}}, {"kern.ttycount", []_C_int{1, 57}}, + {"kern.utc_offset", []_C_int{1, 88}}, {"kern.version", []_C_int{1, 4}}, + {"kern.video", []_C_int{1, 89}}, {"kern.watchdog.auto", []_C_int{1, 64, 2}}, {"kern.watchdog.period", []_C_int{1, 64, 1}}, {"kern.witnesswatch", []_C_int{1, 53}}, @@ -179,7 +186,6 @@ var sysctlMib = []mibentry{ {"net.inet.ipcomp.stats", []_C_int{4, 2, 108, 2}}, {"net.inet.ipip.allow", []_C_int{4, 2, 4, 1}}, {"net.inet.ipip.stats", []_C_int{4, 2, 4, 2}}, - {"net.inet.mobileip.allow", []_C_int{4, 2, 55, 1}}, {"net.inet.pfsync.stats", []_C_int{4, 2, 240, 1}}, {"net.inet.tcp.ackonpush", []_C_int{4, 2, 6, 13}}, {"net.inet.tcp.always_keepalive", []_C_int{4, 2, 6, 22}}, @@ -255,7 +261,6 @@ var sysctlMib = []mibentry{ {"net.mpls.ifq.maxlen", []_C_int{4, 33, 3, 2}}, {"net.mpls.mapttl_ip", []_C_int{4, 33, 5}}, {"net.mpls.mapttl_ip6", []_C_int{4, 33, 6}}, - {"net.mpls.maxloop_inkernel", []_C_int{4, 33, 4}}, {"net.mpls.ttl", []_C_int{4, 33, 2}}, {"net.pflow.stats", []_C_int{4, 34, 1}}, {"net.pipex.enable", []_C_int{4, 35, 1}}, diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go index d96bb2ba4d..f55eae1a82 100644 --- a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go @@ -36,6 +36,7 @@ var sysctlMib = []mibentry{ {"hw.pagesize", []_C_int{6, 7}}, {"hw.perfpolicy", []_C_int{6, 23}}, {"hw.physmem", []_C_int{6, 19}}, + {"hw.power", []_C_int{6, 26}}, {"hw.product", []_C_int{6, 15}}, {"hw.serialno", []_C_int{6, 17}}, {"hw.setperf", []_C_int{6, 13}}, @@ -86,7 +87,6 @@ var sysctlMib = []mibentry{ {"kern.ngroups", []_C_int{1, 18}}, {"kern.nosuidcoredump", []_C_int{1, 32}}, {"kern.nprocs", []_C_int{1, 47}}, - {"kern.nselcoll", []_C_int{1, 43}}, {"kern.nthreads", []_C_int{1, 26}}, {"kern.numvnodes", []_C_int{1, 58}}, {"kern.osrelease", []_C_int{1, 2}}, @@ -123,6 +123,7 @@ var sysctlMib = []mibentry{ {"kern.ttycount", []_C_int{1, 57}}, {"kern.utc_offset", []_C_int{1, 88}}, {"kern.version", []_C_int{1, 4}}, + {"kern.video", []_C_int{1, 89}}, {"kern.watchdog.auto", []_C_int{1, 64, 2}}, {"kern.watchdog.period", []_C_int{1, 64, 1}}, {"kern.witnesswatch", []_C_int{1, 53}}, diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_ppc64.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_ppc64.go new file mode 100644 index 0000000000..e44054470b --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_ppc64.go @@ -0,0 +1,281 @@ +// go run mksysctl_openbsd.go +// Code generated by the command above; DO NOT EDIT. + +//go:build ppc64 && openbsd +// +build ppc64,openbsd + +package unix + +type mibentry struct { + ctlname string + ctloid []_C_int +} + +var sysctlMib = []mibentry{ + {"ddb.console", []_C_int{9, 6}}, + {"ddb.log", []_C_int{9, 7}}, + {"ddb.max_line", []_C_int{9, 3}}, + {"ddb.max_width", []_C_int{9, 2}}, + {"ddb.panic", []_C_int{9, 5}}, + {"ddb.profile", []_C_int{9, 9}}, + {"ddb.radix", []_C_int{9, 1}}, + {"ddb.tab_stop_width", []_C_int{9, 4}}, + {"ddb.trigger", []_C_int{9, 8}}, + {"fs.posix.setuid", []_C_int{3, 1, 1}}, + {"hw.allowpowerdown", []_C_int{6, 22}}, + {"hw.byteorder", []_C_int{6, 4}}, + {"hw.cpuspeed", []_C_int{6, 12}}, + {"hw.diskcount", []_C_int{6, 10}}, + {"hw.disknames", []_C_int{6, 8}}, + {"hw.diskstats", []_C_int{6, 9}}, + {"hw.machine", []_C_int{6, 1}}, + {"hw.model", []_C_int{6, 2}}, + {"hw.ncpu", []_C_int{6, 3}}, + {"hw.ncpufound", []_C_int{6, 21}}, + {"hw.ncpuonline", []_C_int{6, 25}}, + {"hw.pagesize", []_C_int{6, 7}}, + {"hw.perfpolicy", []_C_int{6, 23}}, + {"hw.physmem", []_C_int{6, 19}}, + {"hw.power", []_C_int{6, 26}}, + {"hw.product", []_C_int{6, 15}}, + {"hw.serialno", []_C_int{6, 17}}, + {"hw.setperf", []_C_int{6, 13}}, + {"hw.smt", []_C_int{6, 24}}, + {"hw.usermem", []_C_int{6, 20}}, + {"hw.uuid", []_C_int{6, 18}}, + {"hw.vendor", []_C_int{6, 14}}, + {"hw.version", []_C_int{6, 16}}, + {"kern.allowdt", []_C_int{1, 65}}, + {"kern.allowkmem", []_C_int{1, 52}}, + {"kern.argmax", []_C_int{1, 8}}, + {"kern.audio", []_C_int{1, 84}}, + {"kern.boottime", []_C_int{1, 21}}, + {"kern.bufcachepercent", []_C_int{1, 72}}, + {"kern.ccpu", []_C_int{1, 45}}, + {"kern.clockrate", []_C_int{1, 12}}, + {"kern.consbuf", []_C_int{1, 83}}, + {"kern.consbufsize", []_C_int{1, 82}}, + {"kern.consdev", []_C_int{1, 75}}, + {"kern.cp_time", []_C_int{1, 40}}, + {"kern.cp_time2", []_C_int{1, 71}}, + {"kern.cpustats", []_C_int{1, 85}}, + {"kern.domainname", []_C_int{1, 22}}, + {"kern.file", []_C_int{1, 73}}, + {"kern.forkstat", []_C_int{1, 42}}, + {"kern.fscale", []_C_int{1, 46}}, + {"kern.fsync", []_C_int{1, 33}}, + {"kern.global_ptrace", []_C_int{1, 81}}, + {"kern.hostid", []_C_int{1, 11}}, + {"kern.hostname", []_C_int{1, 10}}, + {"kern.intrcnt.nintrcnt", []_C_int{1, 63, 1}}, + {"kern.job_control", []_C_int{1, 19}}, + {"kern.malloc.buckets", []_C_int{1, 39, 1}}, + {"kern.malloc.kmemnames", []_C_int{1, 39, 3}}, + {"kern.maxclusters", []_C_int{1, 67}}, + {"kern.maxfiles", []_C_int{1, 7}}, + {"kern.maxlocksperuid", []_C_int{1, 70}}, + {"kern.maxpartitions", []_C_int{1, 23}}, + {"kern.maxproc", []_C_int{1, 6}}, + {"kern.maxthread", []_C_int{1, 25}}, + {"kern.maxvnodes", []_C_int{1, 5}}, + {"kern.mbstat", []_C_int{1, 59}}, + {"kern.msgbuf", []_C_int{1, 48}}, + {"kern.msgbufsize", []_C_int{1, 38}}, + {"kern.nchstats", []_C_int{1, 41}}, + {"kern.netlivelocks", []_C_int{1, 76}}, + {"kern.nfiles", []_C_int{1, 56}}, + {"kern.ngroups", []_C_int{1, 18}}, + {"kern.nosuidcoredump", []_C_int{1, 32}}, + {"kern.nprocs", []_C_int{1, 47}}, + {"kern.nthreads", []_C_int{1, 26}}, + {"kern.numvnodes", []_C_int{1, 58}}, + {"kern.osrelease", []_C_int{1, 2}}, + {"kern.osrevision", []_C_int{1, 3}}, + {"kern.ostype", []_C_int{1, 1}}, + {"kern.osversion", []_C_int{1, 27}}, + {"kern.pfstatus", []_C_int{1, 86}}, + {"kern.pool_debug", []_C_int{1, 77}}, + {"kern.posix1version", []_C_int{1, 17}}, + {"kern.proc", []_C_int{1, 66}}, + {"kern.rawpartition", []_C_int{1, 24}}, + {"kern.saved_ids", []_C_int{1, 20}}, + {"kern.securelevel", []_C_int{1, 9}}, + {"kern.seminfo", []_C_int{1, 61}}, + {"kern.shminfo", []_C_int{1, 62}}, + {"kern.somaxconn", []_C_int{1, 28}}, + {"kern.sominconn", []_C_int{1, 29}}, + {"kern.splassert", []_C_int{1, 54}}, + {"kern.stackgap_random", []_C_int{1, 50}}, + {"kern.sysvipc_info", []_C_int{1, 51}}, + {"kern.sysvmsg", []_C_int{1, 34}}, + {"kern.sysvsem", []_C_int{1, 35}}, + {"kern.sysvshm", []_C_int{1, 36}}, + {"kern.timecounter.choice", []_C_int{1, 69, 4}}, + {"kern.timecounter.hardware", []_C_int{1, 69, 3}}, + {"kern.timecounter.tick", []_C_int{1, 69, 1}}, + {"kern.timecounter.timestepwarnings", []_C_int{1, 69, 2}}, + {"kern.timeout_stats", []_C_int{1, 87}}, + {"kern.tty.tk_cancc", []_C_int{1, 44, 4}}, + {"kern.tty.tk_nin", []_C_int{1, 44, 1}}, + {"kern.tty.tk_nout", []_C_int{1, 44, 2}}, + {"kern.tty.tk_rawcc", []_C_int{1, 44, 3}}, + {"kern.tty.ttyinfo", []_C_int{1, 44, 5}}, + {"kern.ttycount", []_C_int{1, 57}}, + {"kern.utc_offset", []_C_int{1, 88}}, + {"kern.version", []_C_int{1, 4}}, + {"kern.video", []_C_int{1, 89}}, + {"kern.watchdog.auto", []_C_int{1, 64, 2}}, + {"kern.watchdog.period", []_C_int{1, 64, 1}}, + {"kern.witnesswatch", []_C_int{1, 53}}, + {"kern.wxabort", []_C_int{1, 74}}, + {"net.bpf.bufsize", []_C_int{4, 31, 1}}, + {"net.bpf.maxbufsize", []_C_int{4, 31, 2}}, + {"net.inet.ah.enable", []_C_int{4, 2, 51, 1}}, + {"net.inet.ah.stats", []_C_int{4, 2, 51, 2}}, + {"net.inet.carp.allow", []_C_int{4, 2, 112, 1}}, + {"net.inet.carp.log", []_C_int{4, 2, 112, 3}}, + {"net.inet.carp.preempt", []_C_int{4, 2, 112, 2}}, + {"net.inet.carp.stats", []_C_int{4, 2, 112, 4}}, + {"net.inet.divert.recvspace", []_C_int{4, 2, 258, 1}}, + {"net.inet.divert.sendspace", []_C_int{4, 2, 258, 2}}, + {"net.inet.divert.stats", []_C_int{4, 2, 258, 3}}, + {"net.inet.esp.enable", []_C_int{4, 2, 50, 1}}, + {"net.inet.esp.stats", []_C_int{4, 2, 50, 4}}, + {"net.inet.esp.udpencap", []_C_int{4, 2, 50, 2}}, + {"net.inet.esp.udpencap_port", []_C_int{4, 2, 50, 3}}, + {"net.inet.etherip.allow", []_C_int{4, 2, 97, 1}}, + {"net.inet.etherip.stats", []_C_int{4, 2, 97, 2}}, + {"net.inet.gre.allow", []_C_int{4, 2, 47, 1}}, + {"net.inet.gre.wccp", []_C_int{4, 2, 47, 2}}, + {"net.inet.icmp.bmcastecho", []_C_int{4, 2, 1, 2}}, + {"net.inet.icmp.errppslimit", []_C_int{4, 2, 1, 3}}, + {"net.inet.icmp.maskrepl", []_C_int{4, 2, 1, 1}}, + {"net.inet.icmp.rediraccept", []_C_int{4, 2, 1, 4}}, + {"net.inet.icmp.redirtimeout", []_C_int{4, 2, 1, 5}}, + {"net.inet.icmp.stats", []_C_int{4, 2, 1, 7}}, + {"net.inet.icmp.tstamprepl", []_C_int{4, 2, 1, 6}}, + {"net.inet.igmp.stats", []_C_int{4, 2, 2, 1}}, + {"net.inet.ip.arpdown", []_C_int{4, 2, 0, 40}}, + {"net.inet.ip.arpqueued", []_C_int{4, 2, 0, 36}}, + {"net.inet.ip.arptimeout", []_C_int{4, 2, 0, 39}}, + {"net.inet.ip.encdebug", []_C_int{4, 2, 0, 12}}, + {"net.inet.ip.forwarding", []_C_int{4, 2, 0, 1}}, + {"net.inet.ip.ifq.congestion", []_C_int{4, 2, 0, 30, 4}}, + {"net.inet.ip.ifq.drops", []_C_int{4, 2, 0, 30, 3}}, + {"net.inet.ip.ifq.len", []_C_int{4, 2, 0, 30, 1}}, + {"net.inet.ip.ifq.maxlen", []_C_int{4, 2, 0, 30, 2}}, + {"net.inet.ip.maxqueue", []_C_int{4, 2, 0, 11}}, + {"net.inet.ip.mforwarding", []_C_int{4, 2, 0, 31}}, + {"net.inet.ip.mrtmfc", []_C_int{4, 2, 0, 37}}, + {"net.inet.ip.mrtproto", []_C_int{4, 2, 0, 34}}, + {"net.inet.ip.mrtstats", []_C_int{4, 2, 0, 35}}, + {"net.inet.ip.mrtvif", []_C_int{4, 2, 0, 38}}, + {"net.inet.ip.mtu", []_C_int{4, 2, 0, 4}}, + {"net.inet.ip.mtudisc", []_C_int{4, 2, 0, 27}}, + {"net.inet.ip.mtudisctimeout", []_C_int{4, 2, 0, 28}}, + {"net.inet.ip.multipath", []_C_int{4, 2, 0, 32}}, + {"net.inet.ip.portfirst", []_C_int{4, 2, 0, 7}}, + {"net.inet.ip.porthifirst", []_C_int{4, 2, 0, 9}}, + {"net.inet.ip.porthilast", []_C_int{4, 2, 0, 10}}, + {"net.inet.ip.portlast", []_C_int{4, 2, 0, 8}}, + {"net.inet.ip.redirect", []_C_int{4, 2, 0, 2}}, + {"net.inet.ip.sourceroute", []_C_int{4, 2, 0, 5}}, + {"net.inet.ip.stats", []_C_int{4, 2, 0, 33}}, + {"net.inet.ip.ttl", []_C_int{4, 2, 0, 3}}, + {"net.inet.ipcomp.enable", []_C_int{4, 2, 108, 1}}, + {"net.inet.ipcomp.stats", []_C_int{4, 2, 108, 2}}, + {"net.inet.ipip.allow", []_C_int{4, 2, 4, 1}}, + {"net.inet.ipip.stats", []_C_int{4, 2, 4, 2}}, + {"net.inet.pfsync.stats", []_C_int{4, 2, 240, 1}}, + {"net.inet.tcp.ackonpush", []_C_int{4, 2, 6, 13}}, + {"net.inet.tcp.always_keepalive", []_C_int{4, 2, 6, 22}}, + {"net.inet.tcp.baddynamic", []_C_int{4, 2, 6, 6}}, + {"net.inet.tcp.drop", []_C_int{4, 2, 6, 19}}, + {"net.inet.tcp.ecn", []_C_int{4, 2, 6, 14}}, + {"net.inet.tcp.ident", []_C_int{4, 2, 6, 9}}, + {"net.inet.tcp.keepidle", []_C_int{4, 2, 6, 3}}, + {"net.inet.tcp.keepinittime", []_C_int{4, 2, 6, 2}}, + {"net.inet.tcp.keepintvl", []_C_int{4, 2, 6, 4}}, + {"net.inet.tcp.mssdflt", []_C_int{4, 2, 6, 11}}, + {"net.inet.tcp.reasslimit", []_C_int{4, 2, 6, 18}}, + {"net.inet.tcp.rfc1323", []_C_int{4, 2, 6, 1}}, + {"net.inet.tcp.rfc3390", []_C_int{4, 2, 6, 17}}, + {"net.inet.tcp.rootonly", []_C_int{4, 2, 6, 24}}, + {"net.inet.tcp.rstppslimit", []_C_int{4, 2, 6, 12}}, + {"net.inet.tcp.sack", []_C_int{4, 2, 6, 10}}, + {"net.inet.tcp.sackholelimit", []_C_int{4, 2, 6, 20}}, + {"net.inet.tcp.slowhz", []_C_int{4, 2, 6, 5}}, + {"net.inet.tcp.stats", []_C_int{4, 2, 6, 21}}, + {"net.inet.tcp.synbucketlimit", []_C_int{4, 2, 6, 16}}, + {"net.inet.tcp.syncachelimit", []_C_int{4, 2, 6, 15}}, + {"net.inet.tcp.synhashsize", []_C_int{4, 2, 6, 25}}, + {"net.inet.tcp.synuselimit", []_C_int{4, 2, 6, 23}}, + {"net.inet.udp.baddynamic", []_C_int{4, 2, 17, 2}}, + {"net.inet.udp.checksum", []_C_int{4, 2, 17, 1}}, + {"net.inet.udp.recvspace", []_C_int{4, 2, 17, 3}}, + {"net.inet.udp.rootonly", []_C_int{4, 2, 17, 6}}, + {"net.inet.udp.sendspace", []_C_int{4, 2, 17, 4}}, + {"net.inet.udp.stats", []_C_int{4, 2, 17, 5}}, + {"net.inet6.divert.recvspace", []_C_int{4, 24, 86, 1}}, + {"net.inet6.divert.sendspace", []_C_int{4, 24, 86, 2}}, + {"net.inet6.divert.stats", []_C_int{4, 24, 86, 3}}, + {"net.inet6.icmp6.errppslimit", []_C_int{4, 24, 30, 14}}, + {"net.inet6.icmp6.mtudisc_hiwat", []_C_int{4, 24, 30, 16}}, + {"net.inet6.icmp6.mtudisc_lowat", []_C_int{4, 24, 30, 17}}, + {"net.inet6.icmp6.nd6_debug", []_C_int{4, 24, 30, 18}}, + {"net.inet6.icmp6.nd6_delay", []_C_int{4, 24, 30, 8}}, + {"net.inet6.icmp6.nd6_maxnudhint", []_C_int{4, 24, 30, 15}}, + {"net.inet6.icmp6.nd6_mmaxtries", []_C_int{4, 24, 30, 10}}, + {"net.inet6.icmp6.nd6_umaxtries", []_C_int{4, 24, 30, 9}}, + {"net.inet6.icmp6.redirtimeout", []_C_int{4, 24, 30, 3}}, + {"net.inet6.ip6.auto_flowlabel", []_C_int{4, 24, 17, 17}}, + {"net.inet6.ip6.dad_count", []_C_int{4, 24, 17, 16}}, + {"net.inet6.ip6.dad_pending", []_C_int{4, 24, 17, 49}}, + {"net.inet6.ip6.defmcasthlim", []_C_int{4, 24, 17, 18}}, + {"net.inet6.ip6.forwarding", []_C_int{4, 24, 17, 1}}, + {"net.inet6.ip6.forwsrcrt", []_C_int{4, 24, 17, 5}}, + {"net.inet6.ip6.hdrnestlimit", []_C_int{4, 24, 17, 15}}, + {"net.inet6.ip6.hlim", []_C_int{4, 24, 17, 3}}, + {"net.inet6.ip6.log_interval", []_C_int{4, 24, 17, 14}}, + {"net.inet6.ip6.maxdynroutes", []_C_int{4, 24, 17, 48}}, + {"net.inet6.ip6.maxfragpackets", []_C_int{4, 24, 17, 9}}, + {"net.inet6.ip6.maxfrags", []_C_int{4, 24, 17, 41}}, + {"net.inet6.ip6.mforwarding", []_C_int{4, 24, 17, 42}}, + {"net.inet6.ip6.mrtmfc", []_C_int{4, 24, 17, 53}}, + {"net.inet6.ip6.mrtmif", []_C_int{4, 24, 17, 52}}, + {"net.inet6.ip6.mrtproto", []_C_int{4, 24, 17, 8}}, + {"net.inet6.ip6.mtudisctimeout", []_C_int{4, 24, 17, 50}}, + {"net.inet6.ip6.multicast_mtudisc", []_C_int{4, 24, 17, 44}}, + {"net.inet6.ip6.multipath", []_C_int{4, 24, 17, 43}}, + {"net.inet6.ip6.neighborgcthresh", []_C_int{4, 24, 17, 45}}, + {"net.inet6.ip6.redirect", []_C_int{4, 24, 17, 2}}, + {"net.inet6.ip6.soiikey", []_C_int{4, 24, 17, 54}}, + {"net.inet6.ip6.sourcecheck", []_C_int{4, 24, 17, 10}}, + {"net.inet6.ip6.sourcecheck_logint", []_C_int{4, 24, 17, 11}}, + {"net.inet6.ip6.use_deprecated", []_C_int{4, 24, 17, 21}}, + {"net.key.sadb_dump", []_C_int{4, 30, 1}}, + {"net.key.spd_dump", []_C_int{4, 30, 2}}, + {"net.mpls.ifq.congestion", []_C_int{4, 33, 3, 4}}, + {"net.mpls.ifq.drops", []_C_int{4, 33, 3, 3}}, + {"net.mpls.ifq.len", []_C_int{4, 33, 3, 1}}, + {"net.mpls.ifq.maxlen", []_C_int{4, 33, 3, 2}}, + {"net.mpls.mapttl_ip", []_C_int{4, 33, 5}}, + {"net.mpls.mapttl_ip6", []_C_int{4, 33, 6}}, + {"net.mpls.ttl", []_C_int{4, 33, 2}}, + {"net.pflow.stats", []_C_int{4, 34, 1}}, + {"net.pipex.enable", []_C_int{4, 35, 1}}, + {"vm.anonmin", []_C_int{2, 7}}, + {"vm.loadavg", []_C_int{2, 2}}, + {"vm.malloc_conf", []_C_int{2, 12}}, + {"vm.maxslp", []_C_int{2, 10}}, + {"vm.nkmempages", []_C_int{2, 6}}, + {"vm.psstrings", []_C_int{2, 3}}, + {"vm.swapencrypt.enable", []_C_int{2, 5, 0}}, + {"vm.swapencrypt.keyscreated", []_C_int{2, 5, 1}}, + {"vm.swapencrypt.keysdeleted", []_C_int{2, 5, 2}}, + {"vm.uspace", []_C_int{2, 11}}, + {"vm.uvmexp", []_C_int{2, 4}}, + {"vm.vmmeter", []_C_int{2, 1}}, + {"vm.vnodemin", []_C_int{2, 9}}, + {"vm.vtextmin", []_C_int{2, 8}}, +} diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_riscv64.go new file mode 100644 index 0000000000..a0db82fce2 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_riscv64.go @@ -0,0 +1,282 @@ +// go run mksysctl_openbsd.go +// Code generated by the command above; DO NOT EDIT. + +//go:build riscv64 && openbsd +// +build riscv64,openbsd + +package unix + +type mibentry struct { + ctlname string + ctloid []_C_int +} + +var sysctlMib = []mibentry{ + {"ddb.console", []_C_int{9, 6}}, + {"ddb.log", []_C_int{9, 7}}, + {"ddb.max_line", []_C_int{9, 3}}, + {"ddb.max_width", []_C_int{9, 2}}, + {"ddb.panic", []_C_int{9, 5}}, + {"ddb.profile", []_C_int{9, 9}}, + {"ddb.radix", []_C_int{9, 1}}, + {"ddb.tab_stop_width", []_C_int{9, 4}}, + {"ddb.trigger", []_C_int{9, 8}}, + {"fs.posix.setuid", []_C_int{3, 1, 1}}, + {"hw.allowpowerdown", []_C_int{6, 22}}, + {"hw.byteorder", []_C_int{6, 4}}, + {"hw.cpuspeed", []_C_int{6, 12}}, + {"hw.diskcount", []_C_int{6, 10}}, + {"hw.disknames", []_C_int{6, 8}}, + {"hw.diskstats", []_C_int{6, 9}}, + {"hw.machine", []_C_int{6, 1}}, + {"hw.model", []_C_int{6, 2}}, + {"hw.ncpu", []_C_int{6, 3}}, + {"hw.ncpufound", []_C_int{6, 21}}, + {"hw.ncpuonline", []_C_int{6, 25}}, + {"hw.pagesize", []_C_int{6, 7}}, + {"hw.perfpolicy", []_C_int{6, 23}}, + {"hw.physmem", []_C_int{6, 19}}, + {"hw.power", []_C_int{6, 26}}, + {"hw.product", []_C_int{6, 15}}, + {"hw.serialno", []_C_int{6, 17}}, + {"hw.setperf", []_C_int{6, 13}}, + {"hw.smt", []_C_int{6, 24}}, + {"hw.usermem", []_C_int{6, 20}}, + {"hw.uuid", []_C_int{6, 18}}, + {"hw.vendor", []_C_int{6, 14}}, + {"hw.version", []_C_int{6, 16}}, + {"kern.allowdt", []_C_int{1, 65}}, + {"kern.allowkmem", []_C_int{1, 52}}, + {"kern.argmax", []_C_int{1, 8}}, + {"kern.audio", []_C_int{1, 84}}, + {"kern.boottime", []_C_int{1, 21}}, + {"kern.bufcachepercent", []_C_int{1, 72}}, + {"kern.ccpu", []_C_int{1, 45}}, + {"kern.clockrate", []_C_int{1, 12}}, + {"kern.consbuf", []_C_int{1, 83}}, + {"kern.consbufsize", []_C_int{1, 82}}, + {"kern.consdev", []_C_int{1, 75}}, + {"kern.cp_time", []_C_int{1, 40}}, + {"kern.cp_time2", []_C_int{1, 71}}, + {"kern.cpustats", []_C_int{1, 85}}, + {"kern.domainname", []_C_int{1, 22}}, + {"kern.file", []_C_int{1, 73}}, + {"kern.forkstat", []_C_int{1, 42}}, + {"kern.fscale", []_C_int{1, 46}}, + {"kern.fsync", []_C_int{1, 33}}, + {"kern.global_ptrace", []_C_int{1, 81}}, + {"kern.hostid", []_C_int{1, 11}}, + {"kern.hostname", []_C_int{1, 10}}, + {"kern.intrcnt.nintrcnt", []_C_int{1, 63, 1}}, + {"kern.job_control", []_C_int{1, 19}}, + {"kern.malloc.buckets", []_C_int{1, 39, 1}}, + {"kern.malloc.kmemnames", []_C_int{1, 39, 3}}, + {"kern.maxclusters", []_C_int{1, 67}}, + {"kern.maxfiles", []_C_int{1, 7}}, + {"kern.maxlocksperuid", []_C_int{1, 70}}, + {"kern.maxpartitions", []_C_int{1, 23}}, + {"kern.maxproc", []_C_int{1, 6}}, + {"kern.maxthread", []_C_int{1, 25}}, + {"kern.maxvnodes", []_C_int{1, 5}}, + {"kern.mbstat", []_C_int{1, 59}}, + {"kern.msgbuf", []_C_int{1, 48}}, + {"kern.msgbufsize", []_C_int{1, 38}}, + {"kern.nchstats", []_C_int{1, 41}}, + {"kern.netlivelocks", []_C_int{1, 76}}, + {"kern.nfiles", []_C_int{1, 56}}, + {"kern.ngroups", []_C_int{1, 18}}, + {"kern.nosuidcoredump", []_C_int{1, 32}}, + {"kern.nprocs", []_C_int{1, 47}}, + {"kern.nselcoll", []_C_int{1, 43}}, + {"kern.nthreads", []_C_int{1, 26}}, + {"kern.numvnodes", []_C_int{1, 58}}, + {"kern.osrelease", []_C_int{1, 2}}, + {"kern.osrevision", []_C_int{1, 3}}, + {"kern.ostype", []_C_int{1, 1}}, + {"kern.osversion", []_C_int{1, 27}}, + {"kern.pfstatus", []_C_int{1, 86}}, + {"kern.pool_debug", []_C_int{1, 77}}, + {"kern.posix1version", []_C_int{1, 17}}, + {"kern.proc", []_C_int{1, 66}}, + {"kern.rawpartition", []_C_int{1, 24}}, + {"kern.saved_ids", []_C_int{1, 20}}, + {"kern.securelevel", []_C_int{1, 9}}, + {"kern.seminfo", []_C_int{1, 61}}, + {"kern.shminfo", []_C_int{1, 62}}, + {"kern.somaxconn", []_C_int{1, 28}}, + {"kern.sominconn", []_C_int{1, 29}}, + {"kern.splassert", []_C_int{1, 54}}, + {"kern.stackgap_random", []_C_int{1, 50}}, + {"kern.sysvipc_info", []_C_int{1, 51}}, + {"kern.sysvmsg", []_C_int{1, 34}}, + {"kern.sysvsem", []_C_int{1, 35}}, + {"kern.sysvshm", []_C_int{1, 36}}, + {"kern.timecounter.choice", []_C_int{1, 69, 4}}, + {"kern.timecounter.hardware", []_C_int{1, 69, 3}}, + {"kern.timecounter.tick", []_C_int{1, 69, 1}}, + {"kern.timecounter.timestepwarnings", []_C_int{1, 69, 2}}, + {"kern.timeout_stats", []_C_int{1, 87}}, + {"kern.tty.tk_cancc", []_C_int{1, 44, 4}}, + {"kern.tty.tk_nin", []_C_int{1, 44, 1}}, + {"kern.tty.tk_nout", []_C_int{1, 44, 2}}, + {"kern.tty.tk_rawcc", []_C_int{1, 44, 3}}, + {"kern.tty.ttyinfo", []_C_int{1, 44, 5}}, + {"kern.ttycount", []_C_int{1, 57}}, + {"kern.utc_offset", []_C_int{1, 88}}, + {"kern.version", []_C_int{1, 4}}, + {"kern.video", []_C_int{1, 89}}, + {"kern.watchdog.auto", []_C_int{1, 64, 2}}, + {"kern.watchdog.period", []_C_int{1, 64, 1}}, + {"kern.witnesswatch", []_C_int{1, 53}}, + {"kern.wxabort", []_C_int{1, 74}}, + {"net.bpf.bufsize", []_C_int{4, 31, 1}}, + {"net.bpf.maxbufsize", []_C_int{4, 31, 2}}, + {"net.inet.ah.enable", []_C_int{4, 2, 51, 1}}, + {"net.inet.ah.stats", []_C_int{4, 2, 51, 2}}, + {"net.inet.carp.allow", []_C_int{4, 2, 112, 1}}, + {"net.inet.carp.log", []_C_int{4, 2, 112, 3}}, + {"net.inet.carp.preempt", []_C_int{4, 2, 112, 2}}, + {"net.inet.carp.stats", []_C_int{4, 2, 112, 4}}, + {"net.inet.divert.recvspace", []_C_int{4, 2, 258, 1}}, + {"net.inet.divert.sendspace", []_C_int{4, 2, 258, 2}}, + {"net.inet.divert.stats", []_C_int{4, 2, 258, 3}}, + {"net.inet.esp.enable", []_C_int{4, 2, 50, 1}}, + {"net.inet.esp.stats", []_C_int{4, 2, 50, 4}}, + {"net.inet.esp.udpencap", []_C_int{4, 2, 50, 2}}, + {"net.inet.esp.udpencap_port", []_C_int{4, 2, 50, 3}}, + {"net.inet.etherip.allow", []_C_int{4, 2, 97, 1}}, + {"net.inet.etherip.stats", []_C_int{4, 2, 97, 2}}, + {"net.inet.gre.allow", []_C_int{4, 2, 47, 1}}, + {"net.inet.gre.wccp", []_C_int{4, 2, 47, 2}}, + {"net.inet.icmp.bmcastecho", []_C_int{4, 2, 1, 2}}, + {"net.inet.icmp.errppslimit", []_C_int{4, 2, 1, 3}}, + {"net.inet.icmp.maskrepl", []_C_int{4, 2, 1, 1}}, + {"net.inet.icmp.rediraccept", []_C_int{4, 2, 1, 4}}, + {"net.inet.icmp.redirtimeout", []_C_int{4, 2, 1, 5}}, + {"net.inet.icmp.stats", []_C_int{4, 2, 1, 7}}, + {"net.inet.icmp.tstamprepl", []_C_int{4, 2, 1, 6}}, + {"net.inet.igmp.stats", []_C_int{4, 2, 2, 1}}, + {"net.inet.ip.arpdown", []_C_int{4, 2, 0, 40}}, + {"net.inet.ip.arpqueued", []_C_int{4, 2, 0, 36}}, + {"net.inet.ip.arptimeout", []_C_int{4, 2, 0, 39}}, + {"net.inet.ip.encdebug", []_C_int{4, 2, 0, 12}}, + {"net.inet.ip.forwarding", []_C_int{4, 2, 0, 1}}, + {"net.inet.ip.ifq.congestion", []_C_int{4, 2, 0, 30, 4}}, + {"net.inet.ip.ifq.drops", []_C_int{4, 2, 0, 30, 3}}, + {"net.inet.ip.ifq.len", []_C_int{4, 2, 0, 30, 1}}, + {"net.inet.ip.ifq.maxlen", []_C_int{4, 2, 0, 30, 2}}, + {"net.inet.ip.maxqueue", []_C_int{4, 2, 0, 11}}, + {"net.inet.ip.mforwarding", []_C_int{4, 2, 0, 31}}, + {"net.inet.ip.mrtmfc", []_C_int{4, 2, 0, 37}}, + {"net.inet.ip.mrtproto", []_C_int{4, 2, 0, 34}}, + {"net.inet.ip.mrtstats", []_C_int{4, 2, 0, 35}}, + {"net.inet.ip.mrtvif", []_C_int{4, 2, 0, 38}}, + {"net.inet.ip.mtu", []_C_int{4, 2, 0, 4}}, + {"net.inet.ip.mtudisc", []_C_int{4, 2, 0, 27}}, + {"net.inet.ip.mtudisctimeout", []_C_int{4, 2, 0, 28}}, + {"net.inet.ip.multipath", []_C_int{4, 2, 0, 32}}, + {"net.inet.ip.portfirst", []_C_int{4, 2, 0, 7}}, + {"net.inet.ip.porthifirst", []_C_int{4, 2, 0, 9}}, + {"net.inet.ip.porthilast", []_C_int{4, 2, 0, 10}}, + {"net.inet.ip.portlast", []_C_int{4, 2, 0, 8}}, + {"net.inet.ip.redirect", []_C_int{4, 2, 0, 2}}, + {"net.inet.ip.sourceroute", []_C_int{4, 2, 0, 5}}, + {"net.inet.ip.stats", []_C_int{4, 2, 0, 33}}, + {"net.inet.ip.ttl", []_C_int{4, 2, 0, 3}}, + {"net.inet.ipcomp.enable", []_C_int{4, 2, 108, 1}}, + {"net.inet.ipcomp.stats", []_C_int{4, 2, 108, 2}}, + {"net.inet.ipip.allow", []_C_int{4, 2, 4, 1}}, + {"net.inet.ipip.stats", []_C_int{4, 2, 4, 2}}, + {"net.inet.pfsync.stats", []_C_int{4, 2, 240, 1}}, + {"net.inet.tcp.ackonpush", []_C_int{4, 2, 6, 13}}, + {"net.inet.tcp.always_keepalive", []_C_int{4, 2, 6, 22}}, + {"net.inet.tcp.baddynamic", []_C_int{4, 2, 6, 6}}, + {"net.inet.tcp.drop", []_C_int{4, 2, 6, 19}}, + {"net.inet.tcp.ecn", []_C_int{4, 2, 6, 14}}, + {"net.inet.tcp.ident", []_C_int{4, 2, 6, 9}}, + {"net.inet.tcp.keepidle", []_C_int{4, 2, 6, 3}}, + {"net.inet.tcp.keepinittime", []_C_int{4, 2, 6, 2}}, + {"net.inet.tcp.keepintvl", []_C_int{4, 2, 6, 4}}, + {"net.inet.tcp.mssdflt", []_C_int{4, 2, 6, 11}}, + {"net.inet.tcp.reasslimit", []_C_int{4, 2, 6, 18}}, + {"net.inet.tcp.rfc1323", []_C_int{4, 2, 6, 1}}, + {"net.inet.tcp.rfc3390", []_C_int{4, 2, 6, 17}}, + {"net.inet.tcp.rootonly", []_C_int{4, 2, 6, 24}}, + {"net.inet.tcp.rstppslimit", []_C_int{4, 2, 6, 12}}, + {"net.inet.tcp.sack", []_C_int{4, 2, 6, 10}}, + {"net.inet.tcp.sackholelimit", []_C_int{4, 2, 6, 20}}, + {"net.inet.tcp.slowhz", []_C_int{4, 2, 6, 5}}, + {"net.inet.tcp.stats", []_C_int{4, 2, 6, 21}}, + {"net.inet.tcp.synbucketlimit", []_C_int{4, 2, 6, 16}}, + {"net.inet.tcp.syncachelimit", []_C_int{4, 2, 6, 15}}, + {"net.inet.tcp.synhashsize", []_C_int{4, 2, 6, 25}}, + {"net.inet.tcp.synuselimit", []_C_int{4, 2, 6, 23}}, + {"net.inet.udp.baddynamic", []_C_int{4, 2, 17, 2}}, + {"net.inet.udp.checksum", []_C_int{4, 2, 17, 1}}, + {"net.inet.udp.recvspace", []_C_int{4, 2, 17, 3}}, + {"net.inet.udp.rootonly", []_C_int{4, 2, 17, 6}}, + {"net.inet.udp.sendspace", []_C_int{4, 2, 17, 4}}, + {"net.inet.udp.stats", []_C_int{4, 2, 17, 5}}, + {"net.inet6.divert.recvspace", []_C_int{4, 24, 86, 1}}, + {"net.inet6.divert.sendspace", []_C_int{4, 24, 86, 2}}, + {"net.inet6.divert.stats", []_C_int{4, 24, 86, 3}}, + {"net.inet6.icmp6.errppslimit", []_C_int{4, 24, 30, 14}}, + {"net.inet6.icmp6.mtudisc_hiwat", []_C_int{4, 24, 30, 16}}, + {"net.inet6.icmp6.mtudisc_lowat", []_C_int{4, 24, 30, 17}}, + {"net.inet6.icmp6.nd6_debug", []_C_int{4, 24, 30, 18}}, + {"net.inet6.icmp6.nd6_delay", []_C_int{4, 24, 30, 8}}, + {"net.inet6.icmp6.nd6_maxnudhint", []_C_int{4, 24, 30, 15}}, + {"net.inet6.icmp6.nd6_mmaxtries", []_C_int{4, 24, 30, 10}}, + {"net.inet6.icmp6.nd6_umaxtries", []_C_int{4, 24, 30, 9}}, + {"net.inet6.icmp6.redirtimeout", []_C_int{4, 24, 30, 3}}, + {"net.inet6.ip6.auto_flowlabel", []_C_int{4, 24, 17, 17}}, + {"net.inet6.ip6.dad_count", []_C_int{4, 24, 17, 16}}, + {"net.inet6.ip6.dad_pending", []_C_int{4, 24, 17, 49}}, + {"net.inet6.ip6.defmcasthlim", []_C_int{4, 24, 17, 18}}, + {"net.inet6.ip6.forwarding", []_C_int{4, 24, 17, 1}}, + {"net.inet6.ip6.forwsrcrt", []_C_int{4, 24, 17, 5}}, + {"net.inet6.ip6.hdrnestlimit", []_C_int{4, 24, 17, 15}}, + {"net.inet6.ip6.hlim", []_C_int{4, 24, 17, 3}}, + {"net.inet6.ip6.log_interval", []_C_int{4, 24, 17, 14}}, + {"net.inet6.ip6.maxdynroutes", []_C_int{4, 24, 17, 48}}, + {"net.inet6.ip6.maxfragpackets", []_C_int{4, 24, 17, 9}}, + {"net.inet6.ip6.maxfrags", []_C_int{4, 24, 17, 41}}, + {"net.inet6.ip6.mforwarding", []_C_int{4, 24, 17, 42}}, + {"net.inet6.ip6.mrtmfc", []_C_int{4, 24, 17, 53}}, + {"net.inet6.ip6.mrtmif", []_C_int{4, 24, 17, 52}}, + {"net.inet6.ip6.mrtproto", []_C_int{4, 24, 17, 8}}, + {"net.inet6.ip6.mtudisctimeout", []_C_int{4, 24, 17, 50}}, + {"net.inet6.ip6.multicast_mtudisc", []_C_int{4, 24, 17, 44}}, + {"net.inet6.ip6.multipath", []_C_int{4, 24, 17, 43}}, + {"net.inet6.ip6.neighborgcthresh", []_C_int{4, 24, 17, 45}}, + {"net.inet6.ip6.redirect", []_C_int{4, 24, 17, 2}}, + {"net.inet6.ip6.soiikey", []_C_int{4, 24, 17, 54}}, + {"net.inet6.ip6.sourcecheck", []_C_int{4, 24, 17, 10}}, + {"net.inet6.ip6.sourcecheck_logint", []_C_int{4, 24, 17, 11}}, + {"net.inet6.ip6.use_deprecated", []_C_int{4, 24, 17, 21}}, + {"net.key.sadb_dump", []_C_int{4, 30, 1}}, + {"net.key.spd_dump", []_C_int{4, 30, 2}}, + {"net.mpls.ifq.congestion", []_C_int{4, 33, 3, 4}}, + {"net.mpls.ifq.drops", []_C_int{4, 33, 3, 3}}, + {"net.mpls.ifq.len", []_C_int{4, 33, 3, 1}}, + {"net.mpls.ifq.maxlen", []_C_int{4, 33, 3, 2}}, + {"net.mpls.mapttl_ip", []_C_int{4, 33, 5}}, + {"net.mpls.mapttl_ip6", []_C_int{4, 33, 6}}, + {"net.mpls.ttl", []_C_int{4, 33, 2}}, + {"net.pflow.stats", []_C_int{4, 34, 1}}, + {"net.pipex.enable", []_C_int{4, 35, 1}}, + {"vm.anonmin", []_C_int{2, 7}}, + {"vm.loadavg", []_C_int{2, 2}}, + {"vm.malloc_conf", []_C_int{2, 12}}, + {"vm.maxslp", []_C_int{2, 10}}, + {"vm.nkmempages", []_C_int{2, 6}}, + {"vm.psstrings", []_C_int{2, 3}}, + {"vm.swapencrypt.enable", []_C_int{2, 5, 0}}, + {"vm.swapencrypt.keyscreated", []_C_int{2, 5, 1}}, + {"vm.swapencrypt.keysdeleted", []_C_int{2, 5, 2}}, + {"vm.uspace", []_C_int{2, 11}}, + {"vm.uvmexp", []_C_int{2, 4}}, + {"vm.vmmeter", []_C_int{2, 1}}, + {"vm.vnodemin", []_C_int{2, 9}}, + {"vm.vtextmin", []_C_int{2, 8}}, +} diff --git a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go index a37f773756..01c43a01fd 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go @@ -6,6 +6,7 @@ package unix +// Deprecated: Use libc wrappers instead of direct syscalls. const ( SYS_EXIT = 1 // { void sys_exit(int rval); } SYS_FORK = 2 // { int sys_fork(void); } diff --git a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_ppc64.go new file mode 100644 index 0000000000..f258cfa24e --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_ppc64.go @@ -0,0 +1,218 @@ +// go run mksysnum.go https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master +// Code generated by the command above; see README.md. DO NOT EDIT. + +//go:build ppc64 && openbsd +// +build ppc64,openbsd + +package unix + +const ( + SYS_EXIT = 1 // { void sys_exit(int rval); } + SYS_FORK = 2 // { int sys_fork(void); } + SYS_READ = 3 // { ssize_t sys_read(int fd, void *buf, size_t nbyte); } + SYS_WRITE = 4 // { ssize_t sys_write(int fd, const void *buf, size_t nbyte); } + SYS_OPEN = 5 // { int sys_open(const char *path, int flags, ... mode_t mode); } + SYS_CLOSE = 6 // { int sys_close(int fd); } + SYS_GETENTROPY = 7 // { int sys_getentropy(void *buf, size_t nbyte); } + SYS___TFORK = 8 // { int sys___tfork(const struct __tfork *param, size_t psize); } + SYS_LINK = 9 // { int sys_link(const char *path, const char *link); } + SYS_UNLINK = 10 // { int sys_unlink(const char *path); } + SYS_WAIT4 = 11 // { pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage); } + SYS_CHDIR = 12 // { int sys_chdir(const char *path); } + SYS_FCHDIR = 13 // { int sys_fchdir(int fd); } + SYS_MKNOD = 14 // { int sys_mknod(const char *path, mode_t mode, dev_t dev); } + SYS_CHMOD = 15 // { int sys_chmod(const char *path, mode_t mode); } + SYS_CHOWN = 16 // { int sys_chown(const char *path, uid_t uid, gid_t gid); } + SYS_OBREAK = 17 // { int sys_obreak(char *nsize); } break + SYS_GETDTABLECOUNT = 18 // { int sys_getdtablecount(void); } + SYS_GETRUSAGE = 19 // { int sys_getrusage(int who, struct rusage *rusage); } + SYS_GETPID = 20 // { pid_t sys_getpid(void); } + SYS_MOUNT = 21 // { int sys_mount(const char *type, const char *path, int flags, void *data); } + SYS_UNMOUNT = 22 // { int sys_unmount(const char *path, int flags); } + SYS_SETUID = 23 // { int sys_setuid(uid_t uid); } + SYS_GETUID = 24 // { uid_t sys_getuid(void); } + SYS_GETEUID = 25 // { uid_t sys_geteuid(void); } + SYS_PTRACE = 26 // { int sys_ptrace(int req, pid_t pid, caddr_t addr, int data); } + SYS_RECVMSG = 27 // { ssize_t sys_recvmsg(int s, struct msghdr *msg, int flags); } + SYS_SENDMSG = 28 // { ssize_t sys_sendmsg(int s, const struct msghdr *msg, int flags); } + SYS_RECVFROM = 29 // { ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlenaddr); } + SYS_ACCEPT = 30 // { int sys_accept(int s, struct sockaddr *name, socklen_t *anamelen); } + SYS_GETPEERNAME = 31 // { int sys_getpeername(int fdes, struct sockaddr *asa, socklen_t *alen); } + SYS_GETSOCKNAME = 32 // { int sys_getsockname(int fdes, struct sockaddr *asa, socklen_t *alen); } + SYS_ACCESS = 33 // { int sys_access(const char *path, int amode); } + SYS_CHFLAGS = 34 // { int sys_chflags(const char *path, u_int flags); } + SYS_FCHFLAGS = 35 // { int sys_fchflags(int fd, u_int flags); } + SYS_SYNC = 36 // { void sys_sync(void); } + SYS_STAT = 38 // { int sys_stat(const char *path, struct stat *ub); } + SYS_GETPPID = 39 // { pid_t sys_getppid(void); } + SYS_LSTAT = 40 // { int sys_lstat(const char *path, struct stat *ub); } + SYS_DUP = 41 // { int sys_dup(int fd); } + SYS_FSTATAT = 42 // { int sys_fstatat(int fd, const char *path, struct stat *buf, int flag); } + SYS_GETEGID = 43 // { gid_t sys_getegid(void); } + SYS_PROFIL = 44 // { int sys_profil(caddr_t samples, size_t size, u_long offset, u_int scale); } + SYS_KTRACE = 45 // { int sys_ktrace(const char *fname, int ops, int facs, pid_t pid); } + SYS_SIGACTION = 46 // { int sys_sigaction(int signum, const struct sigaction *nsa, struct sigaction *osa); } + SYS_GETGID = 47 // { gid_t sys_getgid(void); } + SYS_SIGPROCMASK = 48 // { int sys_sigprocmask(int how, sigset_t mask); } + SYS_SETLOGIN = 50 // { int sys_setlogin(const char *namebuf); } + SYS_ACCT = 51 // { int sys_acct(const char *path); } + SYS_SIGPENDING = 52 // { int sys_sigpending(void); } + SYS_FSTAT = 53 // { int sys_fstat(int fd, struct stat *sb); } + SYS_IOCTL = 54 // { int sys_ioctl(int fd, u_long com, ... void *data); } + SYS_REBOOT = 55 // { int sys_reboot(int opt); } + SYS_REVOKE = 56 // { int sys_revoke(const char *path); } + SYS_SYMLINK = 57 // { int sys_symlink(const char *path, const char *link); } + SYS_READLINK = 58 // { ssize_t sys_readlink(const char *path, char *buf, size_t count); } + SYS_EXECVE = 59 // { int sys_execve(const char *path, char * const *argp, char * const *envp); } + SYS_UMASK = 60 // { mode_t sys_umask(mode_t newmask); } + SYS_CHROOT = 61 // { int sys_chroot(const char *path); } + SYS_GETFSSTAT = 62 // { int sys_getfsstat(struct statfs *buf, size_t bufsize, int flags); } + SYS_STATFS = 63 // { int sys_statfs(const char *path, struct statfs *buf); } + SYS_FSTATFS = 64 // { int sys_fstatfs(int fd, struct statfs *buf); } + SYS_FHSTATFS = 65 // { int sys_fhstatfs(const fhandle_t *fhp, struct statfs *buf); } + SYS_VFORK = 66 // { int sys_vfork(void); } + SYS_GETTIMEOFDAY = 67 // { int sys_gettimeofday(struct timeval *tp, struct timezone *tzp); } + SYS_SETTIMEOFDAY = 68 // { int sys_settimeofday(const struct timeval *tv, const struct timezone *tzp); } + SYS_SETITIMER = 69 // { int sys_setitimer(int which, const struct itimerval *itv, struct itimerval *oitv); } + SYS_GETITIMER = 70 // { int sys_getitimer(int which, struct itimerval *itv); } + SYS_SELECT = 71 // { int sys_select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); } + SYS_KEVENT = 72 // { int sys_kevent(int fd, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); } + SYS_MUNMAP = 73 // { int sys_munmap(void *addr, size_t len); } + SYS_MPROTECT = 74 // { int sys_mprotect(void *addr, size_t len, int prot); } + SYS_MADVISE = 75 // { int sys_madvise(void *addr, size_t len, int behav); } + SYS_UTIMES = 76 // { int sys_utimes(const char *path, const struct timeval *tptr); } + SYS_FUTIMES = 77 // { int sys_futimes(int fd, const struct timeval *tptr); } + SYS_GETGROUPS = 79 // { int sys_getgroups(int gidsetsize, gid_t *gidset); } + SYS_SETGROUPS = 80 // { int sys_setgroups(int gidsetsize, const gid_t *gidset); } + SYS_GETPGRP = 81 // { int sys_getpgrp(void); } + SYS_SETPGID = 82 // { int sys_setpgid(pid_t pid, pid_t pgid); } + SYS_FUTEX = 83 // { int sys_futex(uint32_t *f, int op, int val, const struct timespec *timeout, uint32_t *g); } + SYS_UTIMENSAT = 84 // { int sys_utimensat(int fd, const char *path, const struct timespec *times, int flag); } + SYS_FUTIMENS = 85 // { int sys_futimens(int fd, const struct timespec *times); } + SYS_KBIND = 86 // { int sys_kbind(const struct __kbind *param, size_t psize, int64_t proc_cookie); } + SYS_CLOCK_GETTIME = 87 // { int sys_clock_gettime(clockid_t clock_id, struct timespec *tp); } + SYS_CLOCK_SETTIME = 88 // { int sys_clock_settime(clockid_t clock_id, const struct timespec *tp); } + SYS_CLOCK_GETRES = 89 // { int sys_clock_getres(clockid_t clock_id, struct timespec *tp); } + SYS_DUP2 = 90 // { int sys_dup2(int from, int to); } + SYS_NANOSLEEP = 91 // { int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp); } + SYS_FCNTL = 92 // { int sys_fcntl(int fd, int cmd, ... void *arg); } + SYS_ACCEPT4 = 93 // { int sys_accept4(int s, struct sockaddr *name, socklen_t *anamelen, int flags); } + SYS___THRSLEEP = 94 // { int sys___thrsleep(const volatile void *ident, clockid_t clock_id, const struct timespec *tp, void *lock, const int *abort); } + SYS_FSYNC = 95 // { int sys_fsync(int fd); } + SYS_SETPRIORITY = 96 // { int sys_setpriority(int which, id_t who, int prio); } + SYS_SOCKET = 97 // { int sys_socket(int domain, int type, int protocol); } + SYS_CONNECT = 98 // { int sys_connect(int s, const struct sockaddr *name, socklen_t namelen); } + SYS_GETDENTS = 99 // { int sys_getdents(int fd, void *buf, size_t buflen); } + SYS_GETPRIORITY = 100 // { int sys_getpriority(int which, id_t who); } + SYS_PIPE2 = 101 // { int sys_pipe2(int *fdp, int flags); } + SYS_DUP3 = 102 // { int sys_dup3(int from, int to, int flags); } + SYS_SIGRETURN = 103 // { int sys_sigreturn(struct sigcontext *sigcntxp); } + SYS_BIND = 104 // { int sys_bind(int s, const struct sockaddr *name, socklen_t namelen); } + SYS_SETSOCKOPT = 105 // { int sys_setsockopt(int s, int level, int name, const void *val, socklen_t valsize); } + SYS_LISTEN = 106 // { int sys_listen(int s, int backlog); } + SYS_CHFLAGSAT = 107 // { int sys_chflagsat(int fd, const char *path, u_int flags, int atflags); } + SYS_PLEDGE = 108 // { int sys_pledge(const char *promises, const char *execpromises); } + SYS_PPOLL = 109 // { int sys_ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *mask); } + SYS_PSELECT = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *mask); } + SYS_SIGSUSPEND = 111 // { int sys_sigsuspend(int mask); } + SYS_SENDSYSLOG = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, int flags); } + SYS_UNVEIL = 114 // { int sys_unveil(const char *path, const char *permissions); } + SYS_GETSOCKOPT = 118 // { int sys_getsockopt(int s, int level, int name, void *val, socklen_t *avalsize); } + SYS_THRKILL = 119 // { int sys_thrkill(pid_t tid, int signum, void *tcb); } + SYS_READV = 120 // { ssize_t sys_readv(int fd, const struct iovec *iovp, int iovcnt); } + SYS_WRITEV = 121 // { ssize_t sys_writev(int fd, const struct iovec *iovp, int iovcnt); } + SYS_KILL = 122 // { int sys_kill(int pid, int signum); } + SYS_FCHOWN = 123 // { int sys_fchown(int fd, uid_t uid, gid_t gid); } + SYS_FCHMOD = 124 // { int sys_fchmod(int fd, mode_t mode); } + SYS_SETREUID = 126 // { int sys_setreuid(uid_t ruid, uid_t euid); } + SYS_SETREGID = 127 // { int sys_setregid(gid_t rgid, gid_t egid); } + SYS_RENAME = 128 // { int sys_rename(const char *from, const char *to); } + SYS_FLOCK = 131 // { int sys_flock(int fd, int how); } + SYS_MKFIFO = 132 // { int sys_mkfifo(const char *path, mode_t mode); } + SYS_SENDTO = 133 // { ssize_t sys_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); } + SYS_SHUTDOWN = 134 // { int sys_shutdown(int s, int how); } + SYS_SOCKETPAIR = 135 // { int sys_socketpair(int domain, int type, int protocol, int *rsv); } + SYS_MKDIR = 136 // { int sys_mkdir(const char *path, mode_t mode); } + SYS_RMDIR = 137 // { int sys_rmdir(const char *path); } + SYS_ADJTIME = 140 // { int sys_adjtime(const struct timeval *delta, struct timeval *olddelta); } + SYS_GETLOGIN_R = 141 // { int sys_getlogin_r(char *namebuf, u_int namelen); } + SYS_SETSID = 147 // { int sys_setsid(void); } + SYS_QUOTACTL = 148 // { int sys_quotactl(const char *path, int cmd, int uid, char *arg); } + SYS_NFSSVC = 155 // { int sys_nfssvc(int flag, void *argp); } + SYS_GETFH = 161 // { int sys_getfh(const char *fname, fhandle_t *fhp); } + SYS_SYSARCH = 165 // { int sys_sysarch(int op, void *parms); } + SYS_PREAD = 173 // { ssize_t sys_pread(int fd, void *buf, size_t nbyte, int pad, off_t offset); } + SYS_PWRITE = 174 // { ssize_t sys_pwrite(int fd, const void *buf, size_t nbyte, int pad, off_t offset); } + SYS_SETGID = 181 // { int sys_setgid(gid_t gid); } + SYS_SETEGID = 182 // { int sys_setegid(gid_t egid); } + SYS_SETEUID = 183 // { int sys_seteuid(uid_t euid); } + SYS_PATHCONF = 191 // { long sys_pathconf(const char *path, int name); } + SYS_FPATHCONF = 192 // { long sys_fpathconf(int fd, int name); } + SYS_SWAPCTL = 193 // { int sys_swapctl(int cmd, const void *arg, int misc); } + SYS_GETRLIMIT = 194 // { int sys_getrlimit(int which, struct rlimit *rlp); } + SYS_SETRLIMIT = 195 // { int sys_setrlimit(int which, const struct rlimit *rlp); } + SYS_MMAP = 197 // { void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); } + SYS_LSEEK = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, int whence); } + SYS_TRUNCATE = 200 // { int sys_truncate(const char *path, int pad, off_t length); } + SYS_FTRUNCATE = 201 // { int sys_ftruncate(int fd, int pad, off_t length); } + SYS_SYSCTL = 202 // { int sys_sysctl(const int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } + SYS_MLOCK = 203 // { int sys_mlock(const void *addr, size_t len); } + SYS_MUNLOCK = 204 // { int sys_munlock(const void *addr, size_t len); } + SYS_GETPGID = 207 // { pid_t sys_getpgid(pid_t pid); } + SYS_UTRACE = 209 // { int sys_utrace(const char *label, const void *addr, size_t len); } + SYS_SEMGET = 221 // { int sys_semget(key_t key, int nsems, int semflg); } + SYS_MSGGET = 225 // { int sys_msgget(key_t key, int msgflg); } + SYS_MSGSND = 226 // { int sys_msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); } + SYS_MSGRCV = 227 // { int sys_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); } + SYS_SHMAT = 228 // { void *sys_shmat(int shmid, const void *shmaddr, int shmflg); } + SYS_SHMDT = 230 // { int sys_shmdt(const void *shmaddr); } + SYS_MINHERIT = 250 // { int sys_minherit(void *addr, size_t len, int inherit); } + SYS_POLL = 252 // { int sys_poll(struct pollfd *fds, u_int nfds, int timeout); } + SYS_ISSETUGID = 253 // { int sys_issetugid(void); } + SYS_LCHOWN = 254 // { int sys_lchown(const char *path, uid_t uid, gid_t gid); } + SYS_GETSID = 255 // { pid_t sys_getsid(pid_t pid); } + SYS_MSYNC = 256 // { int sys_msync(void *addr, size_t len, int flags); } + SYS_PIPE = 263 // { int sys_pipe(int *fdp); } + SYS_FHOPEN = 264 // { int sys_fhopen(const fhandle_t *fhp, int flags); } + SYS_PREADV = 267 // { ssize_t sys_preadv(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); } + SYS_PWRITEV = 268 // { ssize_t sys_pwritev(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); } + SYS_KQUEUE = 269 // { int sys_kqueue(void); } + SYS_MLOCKALL = 271 // { int sys_mlockall(int flags); } + SYS_MUNLOCKALL = 272 // { int sys_munlockall(void); } + SYS_GETRESUID = 281 // { int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } + SYS_SETRESUID = 282 // { int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid); } + SYS_GETRESGID = 283 // { int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } + SYS_SETRESGID = 284 // { int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid); } + SYS_MQUERY = 286 // { void *sys_mquery(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); } + SYS_CLOSEFROM = 287 // { int sys_closefrom(int fd); } + SYS_SIGALTSTACK = 288 // { int sys_sigaltstack(const struct sigaltstack *nss, struct sigaltstack *oss); } + SYS_SHMGET = 289 // { int sys_shmget(key_t key, size_t size, int shmflg); } + SYS_SEMOP = 290 // { int sys_semop(int semid, struct sembuf *sops, size_t nsops); } + SYS_FHSTAT = 294 // { int sys_fhstat(const fhandle_t *fhp, struct stat *sb); } + SYS___SEMCTL = 295 // { int sys___semctl(int semid, int semnum, int cmd, union semun *arg); } + SYS_SHMCTL = 296 // { int sys_shmctl(int shmid, int cmd, struct shmid_ds *buf); } + SYS_MSGCTL = 297 // { int sys_msgctl(int msqid, int cmd, struct msqid_ds *buf); } + SYS_SCHED_YIELD = 298 // { int sys_sched_yield(void); } + SYS_GETTHRID = 299 // { pid_t sys_getthrid(void); } + SYS___THRWAKEUP = 301 // { int sys___thrwakeup(const volatile void *ident, int n); } + SYS___THREXIT = 302 // { void sys___threxit(pid_t *notdead); } + SYS___THRSIGDIVERT = 303 // { int sys___thrsigdivert(sigset_t sigmask, siginfo_t *info, const struct timespec *timeout); } + SYS___GETCWD = 304 // { int sys___getcwd(char *buf, size_t len); } + SYS_ADJFREQ = 305 // { int sys_adjfreq(const int64_t *freq, int64_t *oldfreq); } + SYS_SETRTABLE = 310 // { int sys_setrtable(int rtableid); } + SYS_GETRTABLE = 311 // { int sys_getrtable(void); } + SYS_FACCESSAT = 313 // { int sys_faccessat(int fd, const char *path, int amode, int flag); } + SYS_FCHMODAT = 314 // { int sys_fchmodat(int fd, const char *path, mode_t mode, int flag); } + SYS_FCHOWNAT = 315 // { int sys_fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flag); } + SYS_LINKAT = 317 // { int sys_linkat(int fd1, const char *path1, int fd2, const char *path2, int flag); } + SYS_MKDIRAT = 318 // { int sys_mkdirat(int fd, const char *path, mode_t mode); } + SYS_MKFIFOAT = 319 // { int sys_mkfifoat(int fd, const char *path, mode_t mode); } + SYS_MKNODAT = 320 // { int sys_mknodat(int fd, const char *path, mode_t mode, dev_t dev); } + SYS_OPENAT = 321 // { int sys_openat(int fd, const char *path, int flags, ... mode_t mode); } + SYS_READLINKAT = 322 // { ssize_t sys_readlinkat(int fd, const char *path, char *buf, size_t count); } + SYS_RENAMEAT = 323 // { int sys_renameat(int fromfd, const char *from, int tofd, const char *to); } + SYS_SYMLINKAT = 324 // { int sys_symlinkat(const char *path, int fd, const char *link); } + SYS_UNLINKAT = 325 // { int sys_unlinkat(int fd, const char *path, int flag); } + SYS___SET_TCB = 329 // { void sys___set_tcb(void *tcb); } + SYS___GET_TCB = 330 // { void *sys___get_tcb(void); } +) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_riscv64.go new file mode 100644 index 0000000000..07919e0ecc --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_riscv64.go @@ -0,0 +1,219 @@ +// go run mksysnum.go https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master +// Code generated by the command above; see README.md. DO NOT EDIT. + +//go:build riscv64 && openbsd +// +build riscv64,openbsd + +package unix + +// Deprecated: Use libc wrappers instead of direct syscalls. +const ( + SYS_EXIT = 1 // { void sys_exit(int rval); } + SYS_FORK = 2 // { int sys_fork(void); } + SYS_READ = 3 // { ssize_t sys_read(int fd, void *buf, size_t nbyte); } + SYS_WRITE = 4 // { ssize_t sys_write(int fd, const void *buf, size_t nbyte); } + SYS_OPEN = 5 // { int sys_open(const char *path, int flags, ... mode_t mode); } + SYS_CLOSE = 6 // { int sys_close(int fd); } + SYS_GETENTROPY = 7 // { int sys_getentropy(void *buf, size_t nbyte); } + SYS___TFORK = 8 // { int sys___tfork(const struct __tfork *param, size_t psize); } + SYS_LINK = 9 // { int sys_link(const char *path, const char *link); } + SYS_UNLINK = 10 // { int sys_unlink(const char *path); } + SYS_WAIT4 = 11 // { pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage); } + SYS_CHDIR = 12 // { int sys_chdir(const char *path); } + SYS_FCHDIR = 13 // { int sys_fchdir(int fd); } + SYS_MKNOD = 14 // { int sys_mknod(const char *path, mode_t mode, dev_t dev); } + SYS_CHMOD = 15 // { int sys_chmod(const char *path, mode_t mode); } + SYS_CHOWN = 16 // { int sys_chown(const char *path, uid_t uid, gid_t gid); } + SYS_OBREAK = 17 // { int sys_obreak(char *nsize); } break + SYS_GETDTABLECOUNT = 18 // { int sys_getdtablecount(void); } + SYS_GETRUSAGE = 19 // { int sys_getrusage(int who, struct rusage *rusage); } + SYS_GETPID = 20 // { pid_t sys_getpid(void); } + SYS_MOUNT = 21 // { int sys_mount(const char *type, const char *path, int flags, void *data); } + SYS_UNMOUNT = 22 // { int sys_unmount(const char *path, int flags); } + SYS_SETUID = 23 // { int sys_setuid(uid_t uid); } + SYS_GETUID = 24 // { uid_t sys_getuid(void); } + SYS_GETEUID = 25 // { uid_t sys_geteuid(void); } + SYS_PTRACE = 26 // { int sys_ptrace(int req, pid_t pid, caddr_t addr, int data); } + SYS_RECVMSG = 27 // { ssize_t sys_recvmsg(int s, struct msghdr *msg, int flags); } + SYS_SENDMSG = 28 // { ssize_t sys_sendmsg(int s, const struct msghdr *msg, int flags); } + SYS_RECVFROM = 29 // { ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlenaddr); } + SYS_ACCEPT = 30 // { int sys_accept(int s, struct sockaddr *name, socklen_t *anamelen); } + SYS_GETPEERNAME = 31 // { int sys_getpeername(int fdes, struct sockaddr *asa, socklen_t *alen); } + SYS_GETSOCKNAME = 32 // { int sys_getsockname(int fdes, struct sockaddr *asa, socklen_t *alen); } + SYS_ACCESS = 33 // { int sys_access(const char *path, int amode); } + SYS_CHFLAGS = 34 // { int sys_chflags(const char *path, u_int flags); } + SYS_FCHFLAGS = 35 // { int sys_fchflags(int fd, u_int flags); } + SYS_SYNC = 36 // { void sys_sync(void); } + SYS_STAT = 38 // { int sys_stat(const char *path, struct stat *ub); } + SYS_GETPPID = 39 // { pid_t sys_getppid(void); } + SYS_LSTAT = 40 // { int sys_lstat(const char *path, struct stat *ub); } + SYS_DUP = 41 // { int sys_dup(int fd); } + SYS_FSTATAT = 42 // { int sys_fstatat(int fd, const char *path, struct stat *buf, int flag); } + SYS_GETEGID = 43 // { gid_t sys_getegid(void); } + SYS_PROFIL = 44 // { int sys_profil(caddr_t samples, size_t size, u_long offset, u_int scale); } + SYS_KTRACE = 45 // { int sys_ktrace(const char *fname, int ops, int facs, pid_t pid); } + SYS_SIGACTION = 46 // { int sys_sigaction(int signum, const struct sigaction *nsa, struct sigaction *osa); } + SYS_GETGID = 47 // { gid_t sys_getgid(void); } + SYS_SIGPROCMASK = 48 // { int sys_sigprocmask(int how, sigset_t mask); } + SYS_SETLOGIN = 50 // { int sys_setlogin(const char *namebuf); } + SYS_ACCT = 51 // { int sys_acct(const char *path); } + SYS_SIGPENDING = 52 // { int sys_sigpending(void); } + SYS_FSTAT = 53 // { int sys_fstat(int fd, struct stat *sb); } + SYS_IOCTL = 54 // { int sys_ioctl(int fd, u_long com, ... void *data); } + SYS_REBOOT = 55 // { int sys_reboot(int opt); } + SYS_REVOKE = 56 // { int sys_revoke(const char *path); } + SYS_SYMLINK = 57 // { int sys_symlink(const char *path, const char *link); } + SYS_READLINK = 58 // { ssize_t sys_readlink(const char *path, char *buf, size_t count); } + SYS_EXECVE = 59 // { int sys_execve(const char *path, char * const *argp, char * const *envp); } + SYS_UMASK = 60 // { mode_t sys_umask(mode_t newmask); } + SYS_CHROOT = 61 // { int sys_chroot(const char *path); } + SYS_GETFSSTAT = 62 // { int sys_getfsstat(struct statfs *buf, size_t bufsize, int flags); } + SYS_STATFS = 63 // { int sys_statfs(const char *path, struct statfs *buf); } + SYS_FSTATFS = 64 // { int sys_fstatfs(int fd, struct statfs *buf); } + SYS_FHSTATFS = 65 // { int sys_fhstatfs(const fhandle_t *fhp, struct statfs *buf); } + SYS_VFORK = 66 // { int sys_vfork(void); } + SYS_GETTIMEOFDAY = 67 // { int sys_gettimeofday(struct timeval *tp, struct timezone *tzp); } + SYS_SETTIMEOFDAY = 68 // { int sys_settimeofday(const struct timeval *tv, const struct timezone *tzp); } + SYS_SETITIMER = 69 // { int sys_setitimer(int which, const struct itimerval *itv, struct itimerval *oitv); } + SYS_GETITIMER = 70 // { int sys_getitimer(int which, struct itimerval *itv); } + SYS_SELECT = 71 // { int sys_select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); } + SYS_KEVENT = 72 // { int sys_kevent(int fd, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); } + SYS_MUNMAP = 73 // { int sys_munmap(void *addr, size_t len); } + SYS_MPROTECT = 74 // { int sys_mprotect(void *addr, size_t len, int prot); } + SYS_MADVISE = 75 // { int sys_madvise(void *addr, size_t len, int behav); } + SYS_UTIMES = 76 // { int sys_utimes(const char *path, const struct timeval *tptr); } + SYS_FUTIMES = 77 // { int sys_futimes(int fd, const struct timeval *tptr); } + SYS_GETGROUPS = 79 // { int sys_getgroups(int gidsetsize, gid_t *gidset); } + SYS_SETGROUPS = 80 // { int sys_setgroups(int gidsetsize, const gid_t *gidset); } + SYS_GETPGRP = 81 // { int sys_getpgrp(void); } + SYS_SETPGID = 82 // { int sys_setpgid(pid_t pid, pid_t pgid); } + SYS_FUTEX = 83 // { int sys_futex(uint32_t *f, int op, int val, const struct timespec *timeout, uint32_t *g); } + SYS_UTIMENSAT = 84 // { int sys_utimensat(int fd, const char *path, const struct timespec *times, int flag); } + SYS_FUTIMENS = 85 // { int sys_futimens(int fd, const struct timespec *times); } + SYS_KBIND = 86 // { int sys_kbind(const struct __kbind *param, size_t psize, int64_t proc_cookie); } + SYS_CLOCK_GETTIME = 87 // { int sys_clock_gettime(clockid_t clock_id, struct timespec *tp); } + SYS_CLOCK_SETTIME = 88 // { int sys_clock_settime(clockid_t clock_id, const struct timespec *tp); } + SYS_CLOCK_GETRES = 89 // { int sys_clock_getres(clockid_t clock_id, struct timespec *tp); } + SYS_DUP2 = 90 // { int sys_dup2(int from, int to); } + SYS_NANOSLEEP = 91 // { int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp); } + SYS_FCNTL = 92 // { int sys_fcntl(int fd, int cmd, ... void *arg); } + SYS_ACCEPT4 = 93 // { int sys_accept4(int s, struct sockaddr *name, socklen_t *anamelen, int flags); } + SYS___THRSLEEP = 94 // { int sys___thrsleep(const volatile void *ident, clockid_t clock_id, const struct timespec *tp, void *lock, const int *abort); } + SYS_FSYNC = 95 // { int sys_fsync(int fd); } + SYS_SETPRIORITY = 96 // { int sys_setpriority(int which, id_t who, int prio); } + SYS_SOCKET = 97 // { int sys_socket(int domain, int type, int protocol); } + SYS_CONNECT = 98 // { int sys_connect(int s, const struct sockaddr *name, socklen_t namelen); } + SYS_GETDENTS = 99 // { int sys_getdents(int fd, void *buf, size_t buflen); } + SYS_GETPRIORITY = 100 // { int sys_getpriority(int which, id_t who); } + SYS_PIPE2 = 101 // { int sys_pipe2(int *fdp, int flags); } + SYS_DUP3 = 102 // { int sys_dup3(int from, int to, int flags); } + SYS_SIGRETURN = 103 // { int sys_sigreturn(struct sigcontext *sigcntxp); } + SYS_BIND = 104 // { int sys_bind(int s, const struct sockaddr *name, socklen_t namelen); } + SYS_SETSOCKOPT = 105 // { int sys_setsockopt(int s, int level, int name, const void *val, socklen_t valsize); } + SYS_LISTEN = 106 // { int sys_listen(int s, int backlog); } + SYS_CHFLAGSAT = 107 // { int sys_chflagsat(int fd, const char *path, u_int flags, int atflags); } + SYS_PLEDGE = 108 // { int sys_pledge(const char *promises, const char *execpromises); } + SYS_PPOLL = 109 // { int sys_ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *mask); } + SYS_PSELECT = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *mask); } + SYS_SIGSUSPEND = 111 // { int sys_sigsuspend(int mask); } + SYS_SENDSYSLOG = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, int flags); } + SYS_UNVEIL = 114 // { int sys_unveil(const char *path, const char *permissions); } + SYS_GETSOCKOPT = 118 // { int sys_getsockopt(int s, int level, int name, void *val, socklen_t *avalsize); } + SYS_THRKILL = 119 // { int sys_thrkill(pid_t tid, int signum, void *tcb); } + SYS_READV = 120 // { ssize_t sys_readv(int fd, const struct iovec *iovp, int iovcnt); } + SYS_WRITEV = 121 // { ssize_t sys_writev(int fd, const struct iovec *iovp, int iovcnt); } + SYS_KILL = 122 // { int sys_kill(int pid, int signum); } + SYS_FCHOWN = 123 // { int sys_fchown(int fd, uid_t uid, gid_t gid); } + SYS_FCHMOD = 124 // { int sys_fchmod(int fd, mode_t mode); } + SYS_SETREUID = 126 // { int sys_setreuid(uid_t ruid, uid_t euid); } + SYS_SETREGID = 127 // { int sys_setregid(gid_t rgid, gid_t egid); } + SYS_RENAME = 128 // { int sys_rename(const char *from, const char *to); } + SYS_FLOCK = 131 // { int sys_flock(int fd, int how); } + SYS_MKFIFO = 132 // { int sys_mkfifo(const char *path, mode_t mode); } + SYS_SENDTO = 133 // { ssize_t sys_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); } + SYS_SHUTDOWN = 134 // { int sys_shutdown(int s, int how); } + SYS_SOCKETPAIR = 135 // { int sys_socketpair(int domain, int type, int protocol, int *rsv); } + SYS_MKDIR = 136 // { int sys_mkdir(const char *path, mode_t mode); } + SYS_RMDIR = 137 // { int sys_rmdir(const char *path); } + SYS_ADJTIME = 140 // { int sys_adjtime(const struct timeval *delta, struct timeval *olddelta); } + SYS_GETLOGIN_R = 141 // { int sys_getlogin_r(char *namebuf, u_int namelen); } + SYS_SETSID = 147 // { int sys_setsid(void); } + SYS_QUOTACTL = 148 // { int sys_quotactl(const char *path, int cmd, int uid, char *arg); } + SYS_NFSSVC = 155 // { int sys_nfssvc(int flag, void *argp); } + SYS_GETFH = 161 // { int sys_getfh(const char *fname, fhandle_t *fhp); } + SYS_SYSARCH = 165 // { int sys_sysarch(int op, void *parms); } + SYS_PREAD = 173 // { ssize_t sys_pread(int fd, void *buf, size_t nbyte, int pad, off_t offset); } + SYS_PWRITE = 174 // { ssize_t sys_pwrite(int fd, const void *buf, size_t nbyte, int pad, off_t offset); } + SYS_SETGID = 181 // { int sys_setgid(gid_t gid); } + SYS_SETEGID = 182 // { int sys_setegid(gid_t egid); } + SYS_SETEUID = 183 // { int sys_seteuid(uid_t euid); } + SYS_PATHCONF = 191 // { long sys_pathconf(const char *path, int name); } + SYS_FPATHCONF = 192 // { long sys_fpathconf(int fd, int name); } + SYS_SWAPCTL = 193 // { int sys_swapctl(int cmd, const void *arg, int misc); } + SYS_GETRLIMIT = 194 // { int sys_getrlimit(int which, struct rlimit *rlp); } + SYS_SETRLIMIT = 195 // { int sys_setrlimit(int which, const struct rlimit *rlp); } + SYS_MMAP = 197 // { void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); } + SYS_LSEEK = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, int whence); } + SYS_TRUNCATE = 200 // { int sys_truncate(const char *path, int pad, off_t length); } + SYS_FTRUNCATE = 201 // { int sys_ftruncate(int fd, int pad, off_t length); } + SYS_SYSCTL = 202 // { int sys_sysctl(const int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } + SYS_MLOCK = 203 // { int sys_mlock(const void *addr, size_t len); } + SYS_MUNLOCK = 204 // { int sys_munlock(const void *addr, size_t len); } + SYS_GETPGID = 207 // { pid_t sys_getpgid(pid_t pid); } + SYS_UTRACE = 209 // { int sys_utrace(const char *label, const void *addr, size_t len); } + SYS_SEMGET = 221 // { int sys_semget(key_t key, int nsems, int semflg); } + SYS_MSGGET = 225 // { int sys_msgget(key_t key, int msgflg); } + SYS_MSGSND = 226 // { int sys_msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); } + SYS_MSGRCV = 227 // { int sys_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); } + SYS_SHMAT = 228 // { void *sys_shmat(int shmid, const void *shmaddr, int shmflg); } + SYS_SHMDT = 230 // { int sys_shmdt(const void *shmaddr); } + SYS_MINHERIT = 250 // { int sys_minherit(void *addr, size_t len, int inherit); } + SYS_POLL = 252 // { int sys_poll(struct pollfd *fds, u_int nfds, int timeout); } + SYS_ISSETUGID = 253 // { int sys_issetugid(void); } + SYS_LCHOWN = 254 // { int sys_lchown(const char *path, uid_t uid, gid_t gid); } + SYS_GETSID = 255 // { pid_t sys_getsid(pid_t pid); } + SYS_MSYNC = 256 // { int sys_msync(void *addr, size_t len, int flags); } + SYS_PIPE = 263 // { int sys_pipe(int *fdp); } + SYS_FHOPEN = 264 // { int sys_fhopen(const fhandle_t *fhp, int flags); } + SYS_PREADV = 267 // { ssize_t sys_preadv(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); } + SYS_PWRITEV = 268 // { ssize_t sys_pwritev(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); } + SYS_KQUEUE = 269 // { int sys_kqueue(void); } + SYS_MLOCKALL = 271 // { int sys_mlockall(int flags); } + SYS_MUNLOCKALL = 272 // { int sys_munlockall(void); } + SYS_GETRESUID = 281 // { int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } + SYS_SETRESUID = 282 // { int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid); } + SYS_GETRESGID = 283 // { int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } + SYS_SETRESGID = 284 // { int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid); } + SYS_MQUERY = 286 // { void *sys_mquery(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); } + SYS_CLOSEFROM = 287 // { int sys_closefrom(int fd); } + SYS_SIGALTSTACK = 288 // { int sys_sigaltstack(const struct sigaltstack *nss, struct sigaltstack *oss); } + SYS_SHMGET = 289 // { int sys_shmget(key_t key, size_t size, int shmflg); } + SYS_SEMOP = 290 // { int sys_semop(int semid, struct sembuf *sops, size_t nsops); } + SYS_FHSTAT = 294 // { int sys_fhstat(const fhandle_t *fhp, struct stat *sb); } + SYS___SEMCTL = 295 // { int sys___semctl(int semid, int semnum, int cmd, union semun *arg); } + SYS_SHMCTL = 296 // { int sys_shmctl(int shmid, int cmd, struct shmid_ds *buf); } + SYS_MSGCTL = 297 // { int sys_msgctl(int msqid, int cmd, struct msqid_ds *buf); } + SYS_SCHED_YIELD = 298 // { int sys_sched_yield(void); } + SYS_GETTHRID = 299 // { pid_t sys_getthrid(void); } + SYS___THRWAKEUP = 301 // { int sys___thrwakeup(const volatile void *ident, int n); } + SYS___THREXIT = 302 // { void sys___threxit(pid_t *notdead); } + SYS___THRSIGDIVERT = 303 // { int sys___thrsigdivert(sigset_t sigmask, siginfo_t *info, const struct timespec *timeout); } + SYS___GETCWD = 304 // { int sys___getcwd(char *buf, size_t len); } + SYS_ADJFREQ = 305 // { int sys_adjfreq(const int64_t *freq, int64_t *oldfreq); } + SYS_SETRTABLE = 310 // { int sys_setrtable(int rtableid); } + SYS_GETRTABLE = 311 // { int sys_getrtable(void); } + SYS_FACCESSAT = 313 // { int sys_faccessat(int fd, const char *path, int amode, int flag); } + SYS_FCHMODAT = 314 // { int sys_fchmodat(int fd, const char *path, mode_t mode, int flag); } + SYS_FCHOWNAT = 315 // { int sys_fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flag); } + SYS_LINKAT = 317 // { int sys_linkat(int fd1, const char *path1, int fd2, const char *path2, int flag); } + SYS_MKDIRAT = 318 // { int sys_mkdirat(int fd, const char *path, mode_t mode); } + SYS_MKFIFOAT = 319 // { int sys_mkfifoat(int fd, const char *path, mode_t mode); } + SYS_MKNODAT = 320 // { int sys_mknodat(int fd, const char *path, mode_t mode, dev_t dev); } + SYS_OPENAT = 321 // { int sys_openat(int fd, const char *path, int flags, ... mode_t mode); } + SYS_READLINKAT = 322 // { ssize_t sys_readlinkat(int fd, const char *path, char *buf, size_t count); } + SYS_RENAMEAT = 323 // { int sys_renameat(int fromfd, const char *from, int tofd, const char *to); } + SYS_SYMLINKAT = 324 // { int sys_symlinkat(const char *path, int fd, const char *link); } + SYS_UNLINKAT = 325 // { int sys_unlinkat(int fd, const char *path, int flag); } + SYS___SET_TCB = 329 // { void sys___set_tcb(void *tcb); } + SYS___GET_TCB = 330 // { void *sys___get_tcb(void); } +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go index d9c78cdcbc..29dc483378 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go @@ -362,7 +362,7 @@ type FpExtendedPrecision struct{} type PtraceIoDesc struct { Op int32 Offs uintptr - Addr uintptr + Addr *byte Len uint32 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go index 26991b1655..0a89b28906 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go @@ -367,7 +367,7 @@ type FpExtendedPrecision struct{} type PtraceIoDesc struct { Op int32 Offs uintptr - Addr uintptr + Addr *byte Len uint64 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go index f8324e7e7f..c8666bb152 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go @@ -350,7 +350,7 @@ type FpExtendedPrecision struct { type PtraceIoDesc struct { Op int32 Offs uintptr - Addr uintptr + Addr *byte Len uint32 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go index 4220411f34..88fb48a887 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go @@ -347,7 +347,7 @@ type FpExtendedPrecision struct{} type PtraceIoDesc struct { Op int32 Offs uintptr - Addr uintptr + Addr *byte Len uint64 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go index 0660fd45c7..698dc975e9 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go @@ -348,7 +348,7 @@ type FpExtendedPrecision struct{} type PtraceIoDesc struct { Op int32 Offs uintptr - Addr uintptr + Addr *byte Len uint64 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_illumos_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_illumos_amd64.go deleted file mode 100644 index 4c485261d6..0000000000 --- a/vendor/golang.org/x/sys/unix/ztypes_illumos_amd64.go +++ /dev/null @@ -1,42 +0,0 @@ -// cgo -godefs types_illumos.go | go run mkpost.go -// Code generated by the command above; see README.md. DO NOT EDIT. - -//go:build amd64 && illumos -// +build amd64,illumos - -package unix - -const ( - TUNNEWPPA = 0x540001 - TUNSETPPA = 0x540002 - - I_STR = 0x5308 - I_POP = 0x5303 - I_PUSH = 0x5302 - I_LINK = 0x530c - I_UNLINK = 0x530d - I_PLINK = 0x5316 - I_PUNLINK = 0x5317 - - IF_UNITSEL = -0x7ffb8cca -) - -type strbuf struct { - Maxlen int32 - Len int32 - Buf *int8 -} - -type Strioctl struct { - Cmd int32 - Timout int32 - Len int32 - Dp *int8 -} - -type Lifreq struct { - Name [32]int8 - Lifru1 [4]byte - Type uint32 - Lifru [336]byte -} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index ff6881167d..ca84727cfe 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -29,6 +29,41 @@ type Itimerval struct { Value Timeval } +const ( + ADJ_OFFSET = 0x1 + ADJ_FREQUENCY = 0x2 + ADJ_MAXERROR = 0x4 + ADJ_ESTERROR = 0x8 + ADJ_STATUS = 0x10 + ADJ_TIMECONST = 0x20 + ADJ_TAI = 0x80 + ADJ_SETOFFSET = 0x100 + ADJ_MICRO = 0x1000 + ADJ_NANO = 0x2000 + ADJ_TICK = 0x4000 + ADJ_OFFSET_SINGLESHOT = 0x8001 + ADJ_OFFSET_SS_READ = 0xa001 +) + +const ( + STA_PLL = 0x1 + STA_PPSFREQ = 0x2 + STA_PPSTIME = 0x4 + STA_FLL = 0x8 + STA_INS = 0x10 + STA_DEL = 0x20 + STA_UNSYNC = 0x40 + STA_FREQHOLD = 0x80 + STA_PPSSIGNAL = 0x100 + STA_PPSJITTER = 0x200 + STA_PPSWANDER = 0x400 + STA_PPSERROR = 0x800 + STA_CLOCKERR = 0x1000 + STA_NANO = 0x2000 + STA_MODE = 0x4000 + STA_CLK = 0x8000 +) + const ( TIME_OK = 0x0 TIME_INS = 0x1 @@ -53,29 +88,30 @@ type StatxTimestamp struct { } type Statx_t struct { - Mask uint32 - Blksize uint32 - Attributes uint64 - Nlink uint32 - Uid uint32 - Gid uint32 - Mode uint16 - _ [1]uint16 - Ino uint64 - Size uint64 - Blocks uint64 - Attributes_mask uint64 - Atime StatxTimestamp - Btime StatxTimestamp - Ctime StatxTimestamp - Mtime StatxTimestamp - Rdev_major uint32 - Rdev_minor uint32 - Dev_major uint32 - Dev_minor uint32 - Mnt_id uint64 - _ uint64 - _ [12]uint64 + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + Mnt_id uint64 + Dio_mem_align uint32 + Dio_offset_align uint32 + _ [12]uint64 } type Fsid struct { @@ -420,36 +456,60 @@ type Ucred struct { } type TCPInfo struct { - State uint8 - Ca_state uint8 - Retransmits uint8 - Probes uint8 - Backoff uint8 - Options uint8 - Rto uint32 - Ato uint32 - Snd_mss uint32 - Rcv_mss uint32 - Unacked uint32 - Sacked uint32 - Lost uint32 - Retrans uint32 - Fackets uint32 - Last_data_sent uint32 - Last_ack_sent uint32 - Last_data_recv uint32 - Last_ack_recv uint32 - Pmtu uint32 - Rcv_ssthresh uint32 - Rtt uint32 - Rttvar uint32 - Snd_ssthresh uint32 - Snd_cwnd uint32 - Advmss uint32 - Reordering uint32 - Rcv_rtt uint32 - Rcv_space uint32 - Total_retrans uint32 + State uint8 + Ca_state uint8 + Retransmits uint8 + Probes uint8 + Backoff uint8 + Options uint8 + Rto uint32 + Ato uint32 + Snd_mss uint32 + Rcv_mss uint32 + Unacked uint32 + Sacked uint32 + Lost uint32 + Retrans uint32 + Fackets uint32 + Last_data_sent uint32 + Last_ack_sent uint32 + Last_data_recv uint32 + Last_ack_recv uint32 + Pmtu uint32 + Rcv_ssthresh uint32 + Rtt uint32 + Rttvar uint32 + Snd_ssthresh uint32 + Snd_cwnd uint32 + Advmss uint32 + Reordering uint32 + Rcv_rtt uint32 + Rcv_space uint32 + Total_retrans uint32 + Pacing_rate uint64 + Max_pacing_rate uint64 + Bytes_acked uint64 + Bytes_received uint64 + Segs_out uint32 + Segs_in uint32 + Notsent_bytes uint32 + Min_rtt uint32 + Data_segs_in uint32 + Data_segs_out uint32 + Delivery_rate uint64 + Busy_time uint64 + Rwnd_limited uint64 + Sndbuf_limited uint64 + Delivered uint32 + Delivered_ce uint32 + Bytes_sent uint64 + Bytes_retrans uint64 + Dsack_dups uint32 + Reord_seen uint32 + Rcv_ooopack uint32 + Snd_wnd uint32 + Rcv_wnd uint32 + Rehash uint32 } type CanFilter struct { @@ -492,7 +552,7 @@ const ( SizeofIPv6MTUInfo = 0x20 SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc - SizeofTCPInfo = 0x68 + SizeofTCPInfo = 0xf0 SizeofCanFilter = 0x8 SizeofTCPRepairOpt = 0x8 ) @@ -1007,6 +1067,7 @@ const ( PerfBitCommExec = CBitFieldMaskBit24 PerfBitUseClockID = CBitFieldMaskBit25 PerfBitContextSwitch = CBitFieldMaskBit26 + PerfBitWriteBackward = CBitFieldMaskBit27 ) const ( @@ -1099,7 +1160,8 @@ const ( PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT = 0xf PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT = 0x10 PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT = 0x11 - PERF_SAMPLE_BRANCH_MAX_SHIFT = 0x12 + PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT = 0x12 + PERF_SAMPLE_BRANCH_MAX_SHIFT = 0x13 PERF_SAMPLE_BRANCH_USER = 0x1 PERF_SAMPLE_BRANCH_KERNEL = 0x2 PERF_SAMPLE_BRANCH_HV = 0x4 @@ -1118,7 +1180,8 @@ const ( PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_SAMPLE_BRANCH_HW_INDEX = 0x20000 - PERF_SAMPLE_BRANCH_MAX = 0x40000 + PERF_SAMPLE_BRANCH_PRIV_SAVE = 0x40000 + PERF_SAMPLE_BRANCH_MAX = 0x80000 PERF_BR_UNKNOWN = 0x0 PERF_BR_COND = 0x1 PERF_BR_UNCOND = 0x2 @@ -1132,7 +1195,10 @@ const ( PERF_BR_COND_RET = 0xa PERF_BR_ERET = 0xb PERF_BR_IRQ = 0xc - PERF_BR_MAX = 0xd + PERF_BR_SERROR = 0xd + PERF_BR_NO_TX = 0xe + PERF_BR_EXTEND_ABI = 0xf + PERF_BR_MAX = 0x10 PERF_SAMPLE_REGS_ABI_NONE = 0x0 PERF_SAMPLE_REGS_ABI_32 = 0x1 PERF_SAMPLE_REGS_ABI_64 = 0x2 @@ -1151,7 +1217,8 @@ const ( PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 PERF_FORMAT_ID = 0x4 PERF_FORMAT_GROUP = 0x8 - PERF_FORMAT_MAX = 0x10 + PERF_FORMAT_LOST = 0x10 + PERF_FORMAT_MAX = 0x20 PERF_IOC_FLAG_GROUP = 0x1 PERF_RECORD_MMAP = 0x1 PERF_RECORD_LOST = 0x2 @@ -1197,7 +1264,7 @@ type TCPMD5Sig struct { Flags uint8 Prefixlen uint8 Keylen uint16 - _ uint32 + Ifindex int32 Key [80]uint8 } @@ -1897,7 +1964,11 @@ const ( NFT_MSG_GETOBJ = 0x13 NFT_MSG_DELOBJ = 0x14 NFT_MSG_GETOBJ_RESET = 0x15 - NFT_MSG_MAX = 0x19 + NFT_MSG_NEWFLOWTABLE = 0x16 + NFT_MSG_GETFLOWTABLE = 0x17 + NFT_MSG_DELFLOWTABLE = 0x18 + NFT_MSG_GETRULE_RESET = 0x19 + NFT_MSG_MAX = 0x1a NFTA_LIST_UNSPEC = 0x0 NFTA_LIST_ELEM = 0x1 NFTA_HOOK_UNSPEC = 0x0 @@ -2401,9 +2472,11 @@ const ( SOF_TIMESTAMPING_OPT_STATS = 0x1000 SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000 SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000 + SOF_TIMESTAMPING_BIND_PHC = 0x8000 + SOF_TIMESTAMPING_OPT_ID_TCP = 0x10000 - SOF_TIMESTAMPING_LAST = 0x8000 - SOF_TIMESTAMPING_MASK = 0xffff + SOF_TIMESTAMPING_LAST = 0x10000 + SOF_TIMESTAMPING_MASK = 0x1ffff SCM_TSTAMP_SND = 0x0 SCM_TSTAMP_SCHED = 0x1 @@ -2979,7 +3052,16 @@ const ( DEVLINK_CMD_TRAP_POLICER_NEW = 0x47 DEVLINK_CMD_TRAP_POLICER_DEL = 0x48 DEVLINK_CMD_HEALTH_REPORTER_TEST = 0x49 - DEVLINK_CMD_MAX = 0x51 + DEVLINK_CMD_RATE_GET = 0x4a + DEVLINK_CMD_RATE_SET = 0x4b + DEVLINK_CMD_RATE_NEW = 0x4c + DEVLINK_CMD_RATE_DEL = 0x4d + DEVLINK_CMD_LINECARD_GET = 0x4e + DEVLINK_CMD_LINECARD_SET = 0x4f + DEVLINK_CMD_LINECARD_NEW = 0x50 + DEVLINK_CMD_LINECARD_DEL = 0x51 + DEVLINK_CMD_SELFTESTS_GET = 0x52 + DEVLINK_CMD_MAX = 0x53 DEVLINK_PORT_TYPE_NOTSET = 0x0 DEVLINK_PORT_TYPE_AUTO = 0x1 DEVLINK_PORT_TYPE_ETH = 0x2 @@ -3208,7 +3290,13 @@ const ( DEVLINK_ATTR_RATE_NODE_NAME = 0xa8 DEVLINK_ATTR_RATE_PARENT_NODE_NAME = 0xa9 DEVLINK_ATTR_REGION_MAX_SNAPSHOTS = 0xaa - DEVLINK_ATTR_MAX = 0xae + DEVLINK_ATTR_LINECARD_INDEX = 0xab + DEVLINK_ATTR_LINECARD_STATE = 0xac + DEVLINK_ATTR_LINECARD_TYPE = 0xad + DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES = 0xae + DEVLINK_ATTR_NESTED_DEVLINK = 0xaf + DEVLINK_ATTR_SELFTESTS = 0xb0 + DEVLINK_ATTR_MAX = 0xb3 DEVLINK_DPIPE_FIELD_MAPPING_TYPE_NONE = 0x0 DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX = 0x1 DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT = 0x0 @@ -3224,7 +3312,8 @@ const ( DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR = 0x1 DEVLINK_PORT_FN_ATTR_STATE = 0x2 DEVLINK_PORT_FN_ATTR_OPSTATE = 0x3 - DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x3 + DEVLINK_PORT_FN_ATTR_CAPS = 0x4 + DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x4 ) type FsverityDigest struct { @@ -3317,7 +3406,8 @@ const ( LWTUNNEL_ENCAP_SEG6_LOCAL = 0x7 LWTUNNEL_ENCAP_RPL = 0x8 LWTUNNEL_ENCAP_IOAM6 = 0x9 - LWTUNNEL_ENCAP_MAX = 0x9 + LWTUNNEL_ENCAP_XFRM = 0xa + LWTUNNEL_ENCAP_MAX = 0xa MPLS_IPTUNNEL_UNSPEC = 0x0 MPLS_IPTUNNEL_DST = 0x1 @@ -3512,7 +3602,10 @@ const ( ETHTOOL_MSG_PHC_VCLOCKS_GET = 0x21 ETHTOOL_MSG_MODULE_GET = 0x22 ETHTOOL_MSG_MODULE_SET = 0x23 - ETHTOOL_MSG_USER_MAX = 0x23 + ETHTOOL_MSG_PSE_GET = 0x24 + ETHTOOL_MSG_PSE_SET = 0x25 + ETHTOOL_MSG_RSS_GET = 0x26 + ETHTOOL_MSG_USER_MAX = 0x26 ETHTOOL_MSG_KERNEL_NONE = 0x0 ETHTOOL_MSG_STRSET_GET_REPLY = 0x1 ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2 @@ -3550,7 +3643,9 @@ const ( ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY = 0x22 ETHTOOL_MSG_MODULE_GET_REPLY = 0x23 ETHTOOL_MSG_MODULE_NTF = 0x24 - ETHTOOL_MSG_KERNEL_MAX = 0x24 + ETHTOOL_MSG_PSE_GET_REPLY = 0x25 + ETHTOOL_MSG_RSS_GET_REPLY = 0x26 + ETHTOOL_MSG_KERNEL_MAX = 0x26 ETHTOOL_A_HEADER_UNSPEC = 0x0 ETHTOOL_A_HEADER_DEV_INDEX = 0x1 ETHTOOL_A_HEADER_DEV_NAME = 0x2 @@ -3609,7 +3704,8 @@ const ( ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG = 0x7 ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE = 0x8 ETHTOOL_A_LINKMODES_LANES = 0x9 - ETHTOOL_A_LINKMODES_MAX = 0x9 + ETHTOOL_A_LINKMODES_RATE_MATCHING = 0xa + ETHTOOL_A_LINKMODES_MAX = 0xa ETHTOOL_A_LINKSTATE_UNSPEC = 0x0 ETHTOOL_A_LINKSTATE_HEADER = 0x1 ETHTOOL_A_LINKSTATE_LINK = 0x2 @@ -3617,7 +3713,8 @@ const ( ETHTOOL_A_LINKSTATE_SQI_MAX = 0x4 ETHTOOL_A_LINKSTATE_EXT_STATE = 0x5 ETHTOOL_A_LINKSTATE_EXT_SUBSTATE = 0x6 - ETHTOOL_A_LINKSTATE_MAX = 0x6 + ETHTOOL_A_LINKSTATE_EXT_DOWN_CNT = 0x7 + ETHTOOL_A_LINKSTATE_MAX = 0x7 ETHTOOL_A_DEBUG_UNSPEC = 0x0 ETHTOOL_A_DEBUG_HEADER = 0x1 ETHTOOL_A_DEBUG_MSGMASK = 0x2 @@ -4201,6 +4298,9 @@ const ( NL80211_ACL_POLICY_DENY_UNLESS_LISTED = 0x1 NL80211_AC_VI = 0x1 NL80211_AC_VO = 0x0 + NL80211_AP_SETTINGS_EXTERNAL_AUTH_SUPPORT = 0x1 + NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT = 0x2 + NL80211_AP_SME_SA_QUERY_OFFLOAD = 0x1 NL80211_ATTR_4ADDR = 0x53 NL80211_ATTR_ACK = 0x5c NL80211_ATTR_ACK_SIGNAL = 0x107 @@ -4209,6 +4309,7 @@ const ( NL80211_ATTR_AIRTIME_WEIGHT = 0x112 NL80211_ATTR_AKM_SUITES = 0x4c NL80211_ATTR_AP_ISOLATE = 0x60 + NL80211_ATTR_AP_SETTINGS_FLAGS = 0x135 NL80211_ATTR_AUTH_DATA = 0x9c NL80211_ATTR_AUTH_TYPE = 0x35 NL80211_ATTR_BANDS = 0xef @@ -4240,6 +4341,9 @@ const ( NL80211_ATTR_COALESCE_RULE_DELAY = 0x1 NL80211_ATTR_COALESCE_RULE_MAX = 0x3 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN = 0x3 + NL80211_ATTR_COLOR_CHANGE_COLOR = 0x130 + NL80211_ATTR_COLOR_CHANGE_COUNT = 0x12f + NL80211_ATTR_COLOR_CHANGE_ELEMS = 0x131 NL80211_ATTR_CONN_FAILED_REASON = 0x9b NL80211_ATTR_CONTROL_PORT = 0x44 NL80211_ATTR_CONTROL_PORT_ETHERTYPE = 0x66 @@ -4266,6 +4370,7 @@ const ( NL80211_ATTR_DEVICE_AP_SME = 0x8d NL80211_ATTR_DFS_CAC_TIME = 0x7 NL80211_ATTR_DFS_REGION = 0x92 + NL80211_ATTR_DISABLE_EHT = 0x137 NL80211_ATTR_DISABLE_HE = 0x12d NL80211_ATTR_DISABLE_HT = 0x93 NL80211_ATTR_DISABLE_VHT = 0xaf @@ -4273,6 +4378,8 @@ const ( NL80211_ATTR_DONT_WAIT_FOR_ACK = 0x8e NL80211_ATTR_DTIM_PERIOD = 0xd NL80211_ATTR_DURATION = 0x57 + NL80211_ATTR_EHT_CAPABILITY = 0x136 + NL80211_ATTR_EML_CAPABILITY = 0x13d NL80211_ATTR_EXT_CAPA = 0xa9 NL80211_ATTR_EXT_CAPA_MASK = 0xaa NL80211_ATTR_EXTERNAL_AUTH_ACTION = 0x104 @@ -4337,10 +4444,11 @@ const ( NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x137 + NL80211_ATTR_MAX = 0x141 NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce NL80211_ATTR_MAX_MATCH_SETS = 0x85 + NL80211_ATTR_MAX_NUM_AKM_SUITES = 0x13c NL80211_ATTR_MAX_NUM_PMKIDS = 0x56 NL80211_ATTR_MAX_NUM_SCAN_SSIDS = 0x2b NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS = 0xde @@ -4350,6 +4458,8 @@ const ( NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL = 0xdf NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS = 0xe0 NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN = 0x7c + NL80211_ATTR_MBSSID_CONFIG = 0x132 + NL80211_ATTR_MBSSID_ELEMS = 0x133 NL80211_ATTR_MCAST_RATE = 0x6b NL80211_ATTR_MDID = 0xb1 NL80211_ATTR_MEASUREMENT_DURATION = 0xeb @@ -4359,6 +4469,11 @@ const ( NL80211_ATTR_MESH_PEER_AID = 0xed NL80211_ATTR_MESH_SETUP = 0x70 NL80211_ATTR_MGMT_SUBTYPE = 0x29 + NL80211_ATTR_MLD_ADDR = 0x13a + NL80211_ATTR_MLD_CAPA_AND_OPS = 0x13e + NL80211_ATTR_MLO_LINK_ID = 0x139 + NL80211_ATTR_MLO_LINKS = 0x138 + NL80211_ATTR_MLO_SUPPORT = 0x13b NL80211_ATTR_MNTR_FLAGS = 0x17 NL80211_ATTR_MPATH_INFO = 0x1b NL80211_ATTR_MPATH_NEXT_HOP = 0x1a @@ -4371,6 +4486,7 @@ const ( NL80211_ATTR_NETNS_FD = 0xdb NL80211_ATTR_NOACK_MAP = 0x95 NL80211_ATTR_NSS = 0x106 + NL80211_ATTR_OBSS_COLOR_BITMAP = 0x12e NL80211_ATTR_OFFCHANNEL_TX_OK = 0x6c NL80211_ATTR_OPER_CLASS = 0xd6 NL80211_ATTR_OPMODE_NOTIF = 0xc2 @@ -4397,6 +4513,7 @@ const ( NL80211_ATTR_PROTOCOL_FEATURES = 0xad NL80211_ATTR_PS_STATE = 0x5d NL80211_ATTR_QOS_MAP = 0xc7 + NL80211_ATTR_RADAR_BACKGROUND = 0x134 NL80211_ATTR_RADAR_EVENT = 0xa8 NL80211_ATTR_REASON_CODE = 0x36 NL80211_ATTR_RECEIVE_MULTICAST = 0x121 @@ -4412,6 +4529,7 @@ const ( NL80211_ATTR_RESP_IE = 0x4e NL80211_ATTR_ROAM_SUPPORT = 0x83 NL80211_ATTR_RX_FRAME_TYPES = 0x64 + NL80211_ATTR_RX_HW_TIMESTAMP = 0x140 NL80211_ATTR_RXMGMT_FLAGS = 0xbc NL80211_ATTR_RX_SIGNAL_DBM = 0x97 NL80211_ATTR_S1G_CAPABILITY = 0x128 @@ -4469,6 +4587,7 @@ const ( NL80211_ATTR_SUPPORT_MESH_AUTH = 0x73 NL80211_ATTR_SURVEY_INFO = 0x54 NL80211_ATTR_SURVEY_RADIO_STATS = 0xda + NL80211_ATTR_TD_BITMAP = 0x141 NL80211_ATTR_TDLS_ACTION = 0x88 NL80211_ATTR_TDLS_DIALOG_TOKEN = 0x89 NL80211_ATTR_TDLS_EXTERNAL_SETUP = 0x8c @@ -4484,6 +4603,7 @@ const ( NL80211_ATTR_TSID = 0xd2 NL80211_ATTR_TWT_RESPONDER = 0x116 NL80211_ATTR_TX_FRAME_TYPES = 0x63 + NL80211_ATTR_TX_HW_TIMESTAMP = 0x13f NL80211_ATTR_TX_NO_CCK_RATE = 0x87 NL80211_ATTR_TXQ_LIMIT = 0x10a NL80211_ATTR_TXQ_MEMORY_LIMIT = 0x10b @@ -4557,6 +4677,10 @@ const ( NL80211_BAND_ATTR_RATES = 0x2 NL80211_BAND_ATTR_VHT_CAPA = 0x8 NL80211_BAND_ATTR_VHT_MCS_SET = 0x7 + NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC = 0x8 + NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET = 0xa + NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY = 0x9 + NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE = 0xb NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA = 0x6 NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC = 0x2 NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET = 0x4 @@ -4564,6 +4688,8 @@ const ( NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE = 0x5 NL80211_BAND_IFTYPE_ATTR_IFTYPES = 0x1 NL80211_BAND_IFTYPE_ATTR_MAX = 0xb + NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS = 0x7 + NL80211_BAND_LC = 0x5 NL80211_BAND_S1GHZ = 0x4 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE = 0x2 NL80211_BITRATE_ATTR_MAX = 0x2 @@ -4584,7 +4710,9 @@ const ( NL80211_BSS_FREQUENCY_OFFSET = 0x14 NL80211_BSS_INFORMATION_ELEMENTS = 0x6 NL80211_BSS_LAST_SEEN_BOOTTIME = 0xf - NL80211_BSS_MAX = 0x14 + NL80211_BSS_MAX = 0x16 + NL80211_BSS_MLD_ADDR = 0x16 + NL80211_BSS_MLO_LINK_ID = 0x15 NL80211_BSS_PAD = 0x10 NL80211_BSS_PARENT_BSSID = 0x12 NL80211_BSS_PARENT_TSF = 0x11 @@ -4612,6 +4740,7 @@ const ( NL80211_CHAN_WIDTH_20 = 0x1 NL80211_CHAN_WIDTH_20_NOHT = 0x0 NL80211_CHAN_WIDTH_2 = 0x9 + NL80211_CHAN_WIDTH_320 = 0xd NL80211_CHAN_WIDTH_40 = 0x2 NL80211_CHAN_WIDTH_4 = 0xa NL80211_CHAN_WIDTH_5 = 0x6 @@ -4621,8 +4750,11 @@ const ( NL80211_CMD_ABORT_SCAN = 0x72 NL80211_CMD_ACTION = 0x3b NL80211_CMD_ACTION_TX_STATUS = 0x3c + NL80211_CMD_ADD_LINK = 0x94 + NL80211_CMD_ADD_LINK_STA = 0x96 NL80211_CMD_ADD_NAN_FUNCTION = 0x75 NL80211_CMD_ADD_TX_TS = 0x69 + NL80211_CMD_ASSOC_COMEBACK = 0x93 NL80211_CMD_ASSOCIATE = 0x26 NL80211_CMD_AUTHENTICATE = 0x25 NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL = 0x38 @@ -4630,6 +4762,10 @@ const ( NL80211_CMD_CHANNEL_SWITCH = 0x66 NL80211_CMD_CH_SWITCH_NOTIFY = 0x58 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY = 0x6e + NL80211_CMD_COLOR_CHANGE_ABORTED = 0x90 + NL80211_CMD_COLOR_CHANGE_COMPLETED = 0x91 + NL80211_CMD_COLOR_CHANGE_REQUEST = 0x8e + NL80211_CMD_COLOR_CHANGE_STARTED = 0x8f NL80211_CMD_CONNECT = 0x2e NL80211_CMD_CONN_FAILED = 0x5b NL80211_CMD_CONTROL_PORT_FRAME = 0x81 @@ -4678,8 +4814,9 @@ const ( NL80211_CMD_LEAVE_IBSS = 0x2c NL80211_CMD_LEAVE_MESH = 0x45 NL80211_CMD_LEAVE_OCB = 0x6d - NL80211_CMD_MAX = 0x93 + NL80211_CMD_MAX = 0x98 NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29 + NL80211_CMD_MODIFY_LINK_STA = 0x97 NL80211_CMD_NAN_MATCH = 0x78 NL80211_CMD_NEW_BEACON = 0xf NL80211_CMD_NEW_INTERFACE = 0x7 @@ -4692,6 +4829,7 @@ const ( NL80211_CMD_NEW_WIPHY = 0x3 NL80211_CMD_NOTIFY_CQM = 0x40 NL80211_CMD_NOTIFY_RADAR = 0x86 + NL80211_CMD_OBSS_COLOR_COLLISION = 0x8d NL80211_CMD_PEER_MEASUREMENT_COMPLETE = 0x85 NL80211_CMD_PEER_MEASUREMENT_RESULT = 0x84 NL80211_CMD_PEER_MEASUREMENT_START = 0x83 @@ -4707,6 +4845,8 @@ const ( NL80211_CMD_REGISTER_FRAME = 0x3a NL80211_CMD_RELOAD_REGDB = 0x7e NL80211_CMD_REMAIN_ON_CHANNEL = 0x37 + NL80211_CMD_REMOVE_LINK = 0x95 + NL80211_CMD_REMOVE_LINK_STA = 0x98 NL80211_CMD_REQ_SET_REG = 0x1b NL80211_CMD_ROAM = 0x2f NL80211_CMD_SCAN_ABORTED = 0x23 @@ -4717,6 +4857,7 @@ const ( NL80211_CMD_SET_CHANNEL = 0x41 NL80211_CMD_SET_COALESCE = 0x65 NL80211_CMD_SET_CQM = 0x3f + NL80211_CMD_SET_FILS_AAD = 0x92 NL80211_CMD_SET_INTERFACE = 0x6 NL80211_CMD_SET_KEY = 0xa NL80211_CMD_SET_MAC_ACL = 0x5d @@ -4791,6 +4932,8 @@ const ( NL80211_EDMG_BW_CONFIG_MIN = 0x4 NL80211_EDMG_CHANNELS_MAX = 0x3c NL80211_EDMG_CHANNELS_MIN = 0x1 + NL80211_EHT_MAX_CAPABILITY_LEN = 0x33 + NL80211_EHT_MIN_CAPABILITY_LEN = 0xd NL80211_EXTERNAL_AUTH_ABORT = 0x1 NL80211_EXTERNAL_AUTH_START = 0x0 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK = 0x32 @@ -4807,6 +4950,7 @@ const ( NL80211_EXT_FEATURE_BEACON_RATE_HT = 0x7 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY = 0x6 NL80211_EXT_FEATURE_BEACON_RATE_VHT = 0x8 + NL80211_EXT_FEATURE_BSS_COLOR = 0x3a NL80211_EXT_FEATURE_BSS_PARENT_TSF = 0x4 NL80211_EXT_FEATURE_CAN_REPLACE_PTK0 = 0x1f NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH = 0x2a @@ -4818,6 +4962,7 @@ const ( NL80211_EXT_FEATURE_DFS_OFFLOAD = 0x19 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER = 0x20 NL80211_EXT_FEATURE_EXT_KEY_ID = 0x24 + NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD = 0x3b NL80211_EXT_FEATURE_FILS_DISCOVERY = 0x34 NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME = 0x11 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD = 0xe @@ -4833,8 +4978,10 @@ const ( NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 0x14 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE = 0x13 NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION = 0x31 + NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE = 0x3d NL80211_EXT_FEATURE_PROTECTED_TWT = 0x2b NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE = 0x39 + NL80211_EXT_FEATURE_RADAR_BACKGROUND = 0x3c NL80211_EXT_FEATURE_RRM = 0x1 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP = 0x33 NL80211_EXT_FEATURE_SAE_OFFLOAD = 0x26 @@ -4906,7 +5053,9 @@ const ( NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc NL80211_FREQUENCY_ATTR_NO_20MHZ = 0x10 + NL80211_FREQUENCY_ATTR_NO_320MHZ = 0x1a NL80211_FREQUENCY_ATTR_NO_80MHZ = 0xb + NL80211_FREQUENCY_ATTR_NO_EHT = 0x1b NL80211_FREQUENCY_ATTR_NO_HE = 0x13 NL80211_FREQUENCY_ATTR_NO_HT40_MINUS = 0x9 NL80211_FREQUENCY_ATTR_NO_HT40_PLUS = 0xa @@ -5006,6 +5155,12 @@ const ( NL80211_MAX_SUPP_HT_RATES = 0x4d NL80211_MAX_SUPP_RATES = 0x20 NL80211_MAX_SUPP_REG_RULES = 0x80 + NL80211_MBSSID_CONFIG_ATTR_EMA = 0x5 + NL80211_MBSSID_CONFIG_ATTR_INDEX = 0x3 + NL80211_MBSSID_CONFIG_ATTR_MAX = 0x5 + NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY = 0x2 + NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES = 0x1 + NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX = 0x4 NL80211_MESHCONF_ATTR_MAX = 0x1f NL80211_MESHCONF_AUTO_OPEN_PLINKS = 0x7 NL80211_MESHCONF_AWAKE_WINDOW = 0x1b @@ -5168,6 +5323,7 @@ const ( NL80211_PMSR_FTM_FAILURE_UNSPECIFIED = 0x0 NL80211_PMSR_FTM_FAILURE_WRONG_CHANNEL = 0x3 NL80211_PMSR_FTM_REQ_ATTR_ASAP = 0x1 + NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR = 0xd NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION = 0x5 NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD = 0x4 NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST = 0x6 @@ -5244,12 +5400,36 @@ const ( NL80211_RADAR_PRE_CAC_EXPIRED = 0x4 NL80211_RATE_INFO_10_MHZ_WIDTH = 0xb NL80211_RATE_INFO_160_MHZ_WIDTH = 0xa + NL80211_RATE_INFO_320_MHZ_WIDTH = 0x12 NL80211_RATE_INFO_40_MHZ_WIDTH = 0x3 NL80211_RATE_INFO_5_MHZ_WIDTH = 0xc NL80211_RATE_INFO_80_MHZ_WIDTH = 0x8 NL80211_RATE_INFO_80P80_MHZ_WIDTH = 0x9 NL80211_RATE_INFO_BITRATE32 = 0x5 NL80211_RATE_INFO_BITRATE = 0x1 + NL80211_RATE_INFO_EHT_GI_0_8 = 0x0 + NL80211_RATE_INFO_EHT_GI_1_6 = 0x1 + NL80211_RATE_INFO_EHT_GI_3_2 = 0x2 + NL80211_RATE_INFO_EHT_GI = 0x15 + NL80211_RATE_INFO_EHT_MCS = 0x13 + NL80211_RATE_INFO_EHT_NSS = 0x14 + NL80211_RATE_INFO_EHT_RU_ALLOC_106 = 0x3 + NL80211_RATE_INFO_EHT_RU_ALLOC_106P26 = 0x4 + NL80211_RATE_INFO_EHT_RU_ALLOC_242 = 0x5 + NL80211_RATE_INFO_EHT_RU_ALLOC_26 = 0x0 + NL80211_RATE_INFO_EHT_RU_ALLOC_2x996 = 0xb + NL80211_RATE_INFO_EHT_RU_ALLOC_2x996P484 = 0xc + NL80211_RATE_INFO_EHT_RU_ALLOC_3x996 = 0xd + NL80211_RATE_INFO_EHT_RU_ALLOC_3x996P484 = 0xe + NL80211_RATE_INFO_EHT_RU_ALLOC_484 = 0x6 + NL80211_RATE_INFO_EHT_RU_ALLOC_484P242 = 0x7 + NL80211_RATE_INFO_EHT_RU_ALLOC_4x996 = 0xf + NL80211_RATE_INFO_EHT_RU_ALLOC_52 = 0x1 + NL80211_RATE_INFO_EHT_RU_ALLOC_52P26 = 0x2 + NL80211_RATE_INFO_EHT_RU_ALLOC_996 = 0x8 + NL80211_RATE_INFO_EHT_RU_ALLOC_996P484 = 0x9 + NL80211_RATE_INFO_EHT_RU_ALLOC_996P484P242 = 0xa + NL80211_RATE_INFO_EHT_RU_ALLOC = 0x16 NL80211_RATE_INFO_HE_1XLTF = 0x0 NL80211_RATE_INFO_HE_2XLTF = 0x1 NL80211_RATE_INFO_HE_4XLTF = 0x2 @@ -5292,6 +5472,7 @@ const ( NL80211_RRF_GO_CONCURRENT = 0x1000 NL80211_RRF_IR_CONCURRENT = 0x1000 NL80211_RRF_NO_160MHZ = 0x10000 + NL80211_RRF_NO_320MHZ = 0x40000 NL80211_RRF_NO_80MHZ = 0x8000 NL80211_RRF_NO_CCK = 0x2 NL80211_RRF_NO_HE = 0x20000 @@ -5607,3 +5788,25 @@ const ( AUDIT_NLGRP_NONE = 0x0 AUDIT_NLGRP_READLOG = 0x1 ) + +const ( + TUN_F_CSUM = 0x1 + TUN_F_TSO4 = 0x2 + TUN_F_TSO6 = 0x4 + TUN_F_TSO_ECN = 0x8 + TUN_F_UFO = 0x10 +) + +const ( + VIRTIO_NET_HDR_F_NEEDS_CSUM = 0x1 + VIRTIO_NET_HDR_F_DATA_VALID = 0x2 + VIRTIO_NET_HDR_F_RSC_INFO = 0x4 +) + +const ( + VIRTIO_NET_HDR_GSO_NONE = 0x0 + VIRTIO_NET_HDR_GSO_TCPV4 = 0x1 + VIRTIO_NET_HDR_GSO_UDP = 0x3 + VIRTIO_NET_HDR_GSO_TCPV6 = 0x4 + VIRTIO_NET_HDR_GSO_ECN = 0x80 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index 2636044018..4ecc1495cd 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -254,6 +254,12 @@ type Sigset_t struct { const _C__NSIG = 0x41 +const ( + SIG_BLOCK = 0x0 + SIG_UNBLOCK = 0x1 + SIG_SETMASK = 0x2 +) + type Siginfo struct { Signo int32 Errno int32 @@ -408,7 +414,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [122]int8 + Data [122]byte _ uint32 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index 8187489d16..34fddff964 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -269,6 +269,12 @@ type Sigset_t struct { const _C__NSIG = 0x41 +const ( + SIG_BLOCK = 0x0 + SIG_UNBLOCK = 0x1 + SIG_SETMASK = 0x2 +) + type Siginfo struct { Signo int32 Errno int32 @@ -421,7 +427,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [118]int8 + Data [118]byte _ uint64 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index d1612335f4..3b14a6031f 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -245,6 +245,12 @@ type Sigset_t struct { const _C__NSIG = 0x41 +const ( + SIG_BLOCK = 0x0 + SIG_UNBLOCK = 0x1 + SIG_SETMASK = 0x2 +) + type Siginfo struct { Signo int32 Errno int32 @@ -399,7 +405,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [122]uint8 + Data [122]byte _ uint32 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index c28e5556b0..0517651ab3 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -248,6 +248,12 @@ type Sigset_t struct { const _C__NSIG = 0x41 +const ( + SIG_BLOCK = 0x0 + SIG_UNBLOCK = 0x1 + SIG_SETMASK = 0x2 +) + type Siginfo struct { Signo int32 Errno int32 @@ -400,7 +406,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [118]int8 + Data [118]byte _ uint64 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go index 187061f9f8..3b0c518134 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go @@ -249,6 +249,12 @@ type Sigset_t struct { const _C__NSIG = 0x41 +const ( + SIG_BLOCK = 0x0 + SIG_UNBLOCK = 0x1 + SIG_SETMASK = 0x2 +) + type Siginfo struct { Signo int32 Errno int32 @@ -401,7 +407,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [118]int8 + Data [118]byte _ uint64 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go index 369129917a..fccdf4dd0f 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go @@ -250,6 +250,12 @@ type Sigset_t struct { const _C__NSIG = 0x80 +const ( + SIG_BLOCK = 0x1 + SIG_UNBLOCK = 0x2 + SIG_SETMASK = 0x3 +) + type Siginfo struct { Signo int32 Code int32 @@ -404,7 +410,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [122]int8 + Data [122]byte _ uint32 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go index 7473468d71..500de8fc07 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go @@ -251,6 +251,12 @@ type Sigset_t struct { const _C__NSIG = 0x80 +const ( + SIG_BLOCK = 0x1 + SIG_UNBLOCK = 0x2 + SIG_SETMASK = 0x3 +) + type Siginfo struct { Signo int32 Code int32 @@ -403,7 +409,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [118]int8 + Data [118]byte _ uint64 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go index ed9448524b..d0434cd2c6 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go @@ -251,6 +251,12 @@ type Sigset_t struct { const _C__NSIG = 0x80 +const ( + SIG_BLOCK = 0x1 + SIG_UNBLOCK = 0x2 + SIG_SETMASK = 0x3 +) + type Siginfo struct { Signo int32 Code int32 @@ -403,7 +409,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [118]int8 + Data [118]byte _ uint64 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go index 0892a73a4b..84206ba534 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go @@ -250,6 +250,12 @@ type Sigset_t struct { const _C__NSIG = 0x80 +const ( + SIG_BLOCK = 0x1 + SIG_UNBLOCK = 0x2 + SIG_SETMASK = 0x3 +) + type Siginfo struct { Signo int32 Code int32 @@ -404,7 +410,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [122]int8 + Data [122]byte _ uint32 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go index e1dd483333..ab078cf1f5 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go @@ -257,6 +257,12 @@ type Sigset_t struct { const _C__NSIG = 0x41 +const ( + SIG_BLOCK = 0x0 + SIG_UNBLOCK = 0x1 + SIG_SETMASK = 0x2 +) + type Siginfo struct { Signo int32 Errno int32 @@ -411,7 +417,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [122]uint8 + Data [122]byte _ uint32 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index d9f654c7b1..42eb2c4cef 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -258,6 +258,12 @@ type Sigset_t struct { const _C__NSIG = 0x41 +const ( + SIG_BLOCK = 0x0 + SIG_UNBLOCK = 0x1 + SIG_SETMASK = 0x2 +) + type Siginfo struct { Signo int32 Errno int32 @@ -410,7 +416,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [118]uint8 + Data [118]byte _ uint64 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index 74acda9fe4..31304a4e8b 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -258,6 +258,12 @@ type Sigset_t struct { const _C__NSIG = 0x41 +const ( + SIG_BLOCK = 0x0 + SIG_UNBLOCK = 0x1 + SIG_SETMASK = 0x2 +) + type Siginfo struct { Signo int32 Errno int32 @@ -410,7 +416,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [118]uint8 + Data [118]byte _ uint64 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index 50ebe69ebc..c311f9612d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -276,6 +276,12 @@ type Sigset_t struct { const _C__NSIG = 0x41 +const ( + SIG_BLOCK = 0x0 + SIG_UNBLOCK = 0x1 + SIG_SETMASK = 0x2 +) + type Siginfo struct { Signo int32 Errno int32 @@ -428,7 +434,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [118]uint8 + Data [118]byte _ uint64 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go index 75b34c2599..bba3cefac1 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go @@ -271,6 +271,12 @@ type Sigset_t struct { const _C__NSIG = 0x41 +const ( + SIG_BLOCK = 0x0 + SIG_UNBLOCK = 0x1 + SIG_SETMASK = 0x2 +) + type Siginfo struct { Signo int32 Errno int32 @@ -423,7 +429,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [118]int8 + Data [118]byte _ uint64 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go index 429c3bf7dd..ad8a013804 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go @@ -253,6 +253,12 @@ type Sigset_t struct { const _C__NSIG = 0x41 +const ( + SIG_BLOCK = 0x1 + SIG_UNBLOCK = 0x2 + SIG_SETMASK = 0x4 +) + type Siginfo struct { Signo int32 Errno int32 @@ -405,7 +411,7 @@ const ( type SockaddrStorage struct { Family uint16 - _ [118]int8 + Data [118]byte _ uint64 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go index 2fd2060e61..9bc4c8f9d8 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go @@ -491,6 +491,90 @@ type Utsname struct { Machine [256]byte } +const SizeofUvmexp = 0x278 + +type Uvmexp struct { + Pagesize int64 + Pagemask int64 + Pageshift int64 + Npages int64 + Free int64 + Active int64 + Inactive int64 + Paging int64 + Wired int64 + Zeropages int64 + Reserve_pagedaemon int64 + Reserve_kernel int64 + Freemin int64 + Freetarg int64 + Inactarg int64 + Wiredmax int64 + Nswapdev int64 + Swpages int64 + Swpginuse int64 + Swpgonly int64 + Nswget int64 + Unused1 int64 + Cpuhit int64 + Cpumiss int64 + Faults int64 + Traps int64 + Intrs int64 + Swtch int64 + Softs int64 + Syscalls int64 + Pageins int64 + Swapins int64 + Swapouts int64 + Pgswapin int64 + Pgswapout int64 + Forks int64 + Forks_ppwait int64 + Forks_sharevm int64 + Pga_zerohit int64 + Pga_zeromiss int64 + Zeroaborts int64 + Fltnoram int64 + Fltnoanon int64 + Fltpgwait int64 + Fltpgrele int64 + Fltrelck int64 + Fltrelckok int64 + Fltanget int64 + Fltanretry int64 + Fltamcopy int64 + Fltnamap int64 + Fltnomap int64 + Fltlget int64 + Fltget int64 + Flt_anon int64 + Flt_acow int64 + Flt_obj int64 + Flt_prcopy int64 + Flt_przero int64 + Pdwoke int64 + Pdrevs int64 + Unused4 int64 + Pdfreed int64 + Pdscans int64 + Pdanscan int64 + Pdobscan int64 + Pdreact int64 + Pdbusy int64 + Pdpageouts int64 + Pdpending int64 + Pddeact int64 + Anonpages int64 + Filepages int64 + Execpages int64 + Colorhit int64 + Colormiss int64 + Ncolors int64 + Bootpages int64 + Poolpages int64 +} + const SizeofClockinfo = 0x14 type Clockinfo struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go index 6a5a1a8ae5..bb05f655d2 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go @@ -499,6 +499,90 @@ type Utsname struct { Machine [256]byte } +const SizeofUvmexp = 0x278 + +type Uvmexp struct { + Pagesize int64 + Pagemask int64 + Pageshift int64 + Npages int64 + Free int64 + Active int64 + Inactive int64 + Paging int64 + Wired int64 + Zeropages int64 + Reserve_pagedaemon int64 + Reserve_kernel int64 + Freemin int64 + Freetarg int64 + Inactarg int64 + Wiredmax int64 + Nswapdev int64 + Swpages int64 + Swpginuse int64 + Swpgonly int64 + Nswget int64 + Unused1 int64 + Cpuhit int64 + Cpumiss int64 + Faults int64 + Traps int64 + Intrs int64 + Swtch int64 + Softs int64 + Syscalls int64 + Pageins int64 + Swapins int64 + Swapouts int64 + Pgswapin int64 + Pgswapout int64 + Forks int64 + Forks_ppwait int64 + Forks_sharevm int64 + Pga_zerohit int64 + Pga_zeromiss int64 + Zeroaborts int64 + Fltnoram int64 + Fltnoanon int64 + Fltpgwait int64 + Fltpgrele int64 + Fltrelck int64 + Fltrelckok int64 + Fltanget int64 + Fltanretry int64 + Fltamcopy int64 + Fltnamap int64 + Fltnomap int64 + Fltlget int64 + Fltget int64 + Flt_anon int64 + Flt_acow int64 + Flt_obj int64 + Flt_prcopy int64 + Flt_przero int64 + Pdwoke int64 + Pdrevs int64 + Unused4 int64 + Pdfreed int64 + Pdscans int64 + Pdanscan int64 + Pdobscan int64 + Pdreact int64 + Pdbusy int64 + Pdpageouts int64 + Pdpending int64 + Pddeact int64 + Anonpages int64 + Filepages int64 + Execpages int64 + Colorhit int64 + Colormiss int64 + Ncolors int64 + Bootpages int64 + Poolpages int64 +} + const SizeofClockinfo = 0x14 type Clockinfo struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go index 84cc8d01e6..db40e3a19c 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go @@ -496,6 +496,90 @@ type Utsname struct { Machine [256]byte } +const SizeofUvmexp = 0x278 + +type Uvmexp struct { + Pagesize int64 + Pagemask int64 + Pageshift int64 + Npages int64 + Free int64 + Active int64 + Inactive int64 + Paging int64 + Wired int64 + Zeropages int64 + Reserve_pagedaemon int64 + Reserve_kernel int64 + Freemin int64 + Freetarg int64 + Inactarg int64 + Wiredmax int64 + Nswapdev int64 + Swpages int64 + Swpginuse int64 + Swpgonly int64 + Nswget int64 + Unused1 int64 + Cpuhit int64 + Cpumiss int64 + Faults int64 + Traps int64 + Intrs int64 + Swtch int64 + Softs int64 + Syscalls int64 + Pageins int64 + Swapins int64 + Swapouts int64 + Pgswapin int64 + Pgswapout int64 + Forks int64 + Forks_ppwait int64 + Forks_sharevm int64 + Pga_zerohit int64 + Pga_zeromiss int64 + Zeroaborts int64 + Fltnoram int64 + Fltnoanon int64 + Fltpgwait int64 + Fltpgrele int64 + Fltrelck int64 + Fltrelckok int64 + Fltanget int64 + Fltanretry int64 + Fltamcopy int64 + Fltnamap int64 + Fltnomap int64 + Fltlget int64 + Fltget int64 + Flt_anon int64 + Flt_acow int64 + Flt_obj int64 + Flt_prcopy int64 + Flt_przero int64 + Pdwoke int64 + Pdrevs int64 + Unused4 int64 + Pdfreed int64 + Pdscans int64 + Pdanscan int64 + Pdobscan int64 + Pdreact int64 + Pdbusy int64 + Pdpageouts int64 + Pdpending int64 + Pddeact int64 + Anonpages int64 + Filepages int64 + Execpages int64 + Colorhit int64 + Colormiss int64 + Ncolors int64 + Bootpages int64 + Poolpages int64 +} + const SizeofClockinfo = 0x14 type Clockinfo struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go index c844e7096f..11121151cc 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go @@ -499,6 +499,90 @@ type Utsname struct { Machine [256]byte } +const SizeofUvmexp = 0x278 + +type Uvmexp struct { + Pagesize int64 + Pagemask int64 + Pageshift int64 + Npages int64 + Free int64 + Active int64 + Inactive int64 + Paging int64 + Wired int64 + Zeropages int64 + Reserve_pagedaemon int64 + Reserve_kernel int64 + Freemin int64 + Freetarg int64 + Inactarg int64 + Wiredmax int64 + Nswapdev int64 + Swpages int64 + Swpginuse int64 + Swpgonly int64 + Nswget int64 + Unused1 int64 + Cpuhit int64 + Cpumiss int64 + Faults int64 + Traps int64 + Intrs int64 + Swtch int64 + Softs int64 + Syscalls int64 + Pageins int64 + Swapins int64 + Swapouts int64 + Pgswapin int64 + Pgswapout int64 + Forks int64 + Forks_ppwait int64 + Forks_sharevm int64 + Pga_zerohit int64 + Pga_zeromiss int64 + Zeroaborts int64 + Fltnoram int64 + Fltnoanon int64 + Fltpgwait int64 + Fltpgrele int64 + Fltrelck int64 + Fltrelckok int64 + Fltanget int64 + Fltanretry int64 + Fltamcopy int64 + Fltnamap int64 + Fltnomap int64 + Fltlget int64 + Fltget int64 + Flt_anon int64 + Flt_acow int64 + Flt_obj int64 + Flt_prcopy int64 + Flt_przero int64 + Pdwoke int64 + Pdrevs int64 + Unused4 int64 + Pdfreed int64 + Pdscans int64 + Pdanscan int64 + Pdobscan int64 + Pdreact int64 + Pdbusy int64 + Pdpageouts int64 + Pdpending int64 + Pddeact int64 + Anonpages int64 + Filepages int64 + Execpages int64 + Colorhit int64 + Colormiss int64 + Ncolors int64 + Bootpages int64 + Poolpages int64 +} + const SizeofClockinfo = 0x14 type Clockinfo struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go index 2ed718ca06..26eba23b72 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go @@ -58,22 +58,22 @@ type Rlimit struct { type _Gid_t uint32 type Stat_t struct { - Mode uint32 - Dev int32 - Ino uint64 - Nlink uint32 - Uid uint32 - Gid uint32 - Rdev int32 - Atim Timespec - Mtim Timespec - Ctim Timespec - Size int64 - Blocks int64 - Blksize uint32 - Flags uint32 - Gen uint32 - X__st_birthtim Timespec + Mode uint32 + Dev int32 + Ino uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev int32 + Atim Timespec + Mtim Timespec + Ctim Timespec + Size int64 + Blocks int64 + Blksize int32 + Flags uint32 + Gen uint32 + _ Timespec } type Statfs_t struct { @@ -98,7 +98,7 @@ type Statfs_t struct { F_mntonname [90]byte F_mntfromname [90]byte F_mntfromspec [90]byte - Pad_cgo_0 [2]byte + _ [2]byte Mount_info [160]byte } @@ -111,13 +111,13 @@ type Flock_t struct { } type Dirent struct { - Fileno uint64 - Off int64 - Reclen uint16 - Type uint8 - Namlen uint8 - X__d_padding [4]uint8 - Name [256]int8 + Fileno uint64 + Off int64 + Reclen uint16 + Type uint8 + Namlen uint8 + _ [4]uint8 + Name [256]int8 } type Fsid struct { @@ -262,8 +262,8 @@ type FdSet struct { } const ( - SizeofIfMsghdr = 0xec - SizeofIfData = 0xd4 + SizeofIfMsghdr = 0xa0 + SizeofIfData = 0x88 SizeofIfaMsghdr = 0x18 SizeofIfAnnounceMsghdr = 0x1a SizeofRtMsghdr = 0x60 @@ -292,7 +292,7 @@ type IfData struct { Link_state uint8 Mtu uint32 Metric uint32 - Pad uint32 + Rdomain uint32 Baudrate uint64 Ipackets uint64 Ierrors uint64 @@ -304,10 +304,10 @@ type IfData struct { Imcasts uint64 Omcasts uint64 Iqdrops uint64 + Oqdrops uint64 Noproto uint64 Capabilities uint32 Lastchange Timeval - Mclpool [7]Mclpool } type IfaMsghdr struct { @@ -368,20 +368,12 @@ type RtMetrics struct { Pad uint32 } -type Mclpool struct { - Grown int32 - Alive uint16 - Hwm uint16 - Cwm uint16 - Lwm uint16 -} - const ( SizeofBpfVersion = 0x4 SizeofBpfStat = 0x8 SizeofBpfProgram = 0x8 SizeofBpfInsn = 0x8 - SizeofBpfHdr = 0x14 + SizeofBpfHdr = 0x18 ) type BpfVersion struct { @@ -407,11 +399,14 @@ type BpfInsn struct { } type BpfHdr struct { - Tstamp BpfTimeval - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [2]byte + Tstamp BpfTimeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + Ifidx uint16 + Flowid uint16 + Flags uint8 + Drops uint8 } type BpfTimeval struct { @@ -488,7 +483,7 @@ type Uvmexp struct { Zeropages int32 Reserve_pagedaemon int32 Reserve_kernel int32 - Anonpages int32 + Unused01 int32 Vnodepages int32 Vtextpages int32 Freemin int32 @@ -507,8 +502,8 @@ type Uvmexp struct { Swpgonly int32 Nswget int32 Nanon int32 - Nanonneeded int32 - Nfreeanon int32 + Unused05 int32 + Unused06 int32 Faults int32 Traps int32 Intrs int32 @@ -516,8 +511,8 @@ type Uvmexp struct { Softs int32 Syscalls int32 Pageins int32 - Obsolete_swapins int32 - Obsolete_swapouts int32 + Unused07 int32 + Unused08 int32 Pgswapin int32 Pgswapout int32 Forks int32 @@ -525,7 +520,7 @@ type Uvmexp struct { Forks_sharevm int32 Pga_zerohit int32 Pga_zeromiss int32 - Zeroaborts int32 + Unused09 int32 Fltnoram int32 Fltnoanon int32 Fltnoamap int32 @@ -557,9 +552,9 @@ type Uvmexp struct { Pdpageouts int32 Pdpending int32 Pddeact int32 - Pdreanon int32 - Pdrevnode int32 - Pdrevtext int32 + Unused11 int32 + Unused12 int32 + Unused13 int32 Fpswtch int32 Kmapent int32 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go index b4fb97ebe6..5a54798869 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go @@ -73,7 +73,6 @@ type Stat_t struct { Blksize int32 Flags uint32 Gen uint32 - _ [4]byte _ Timespec } @@ -81,7 +80,6 @@ type Statfs_t struct { F_flags uint32 F_bsize uint32 F_iosize uint32 - _ [4]byte F_blocks uint64 F_bfree uint64 F_bavail int64 @@ -200,10 +198,8 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - _ [4]byte Iov *Iovec Iovlen uint32 - _ [4]byte Control *byte Controllen uint32 Flags int32 @@ -311,7 +307,6 @@ type IfData struct { Oqdrops uint64 Noproto uint64 Capabilities uint32 - _ [4]byte Lastchange Timeval } @@ -373,14 +368,12 @@ type RtMetrics struct { Pad uint32 } -type Mclpool struct{} - const ( SizeofBpfVersion = 0x4 SizeofBpfStat = 0x8 SizeofBpfProgram = 0x10 SizeofBpfInsn = 0x8 - SizeofBpfHdr = 0x14 + SizeofBpfHdr = 0x18 ) type BpfVersion struct { @@ -395,7 +388,6 @@ type BpfStat struct { type BpfProgram struct { Len uint32 - _ [4]byte Insns *BpfInsn } @@ -411,7 +403,10 @@ type BpfHdr struct { Caplen uint32 Datalen uint32 Hdrlen uint16 - _ [2]byte + Ifidx uint16 + Flowid uint16 + Flags uint8 + Drops uint8 } type BpfTimeval struct { @@ -488,7 +483,7 @@ type Uvmexp struct { Zeropages int32 Reserve_pagedaemon int32 Reserve_kernel int32 - Anonpages int32 + Unused01 int32 Vnodepages int32 Vtextpages int32 Freemin int32 @@ -507,8 +502,8 @@ type Uvmexp struct { Swpgonly int32 Nswget int32 Nanon int32 - Nanonneeded int32 - Nfreeanon int32 + Unused05 int32 + Unused06 int32 Faults int32 Traps int32 Intrs int32 @@ -516,8 +511,8 @@ type Uvmexp struct { Softs int32 Syscalls int32 Pageins int32 - Obsolete_swapins int32 - Obsolete_swapouts int32 + Unused07 int32 + Unused08 int32 Pgswapin int32 Pgswapout int32 Forks int32 @@ -525,7 +520,7 @@ type Uvmexp struct { Forks_sharevm int32 Pga_zerohit int32 Pga_zeromiss int32 - Zeroaborts int32 + Unused09 int32 Fltnoram int32 Fltnoanon int32 Fltnoamap int32 @@ -557,9 +552,9 @@ type Uvmexp struct { Pdpageouts int32 Pdpending int32 Pddeact int32 - Pdreanon int32 - Pdrevnode int32 - Pdrevtext int32 + Unused11 int32 + Unused12 int32 + Unused13 int32 Fpswtch int32 Kmapent int32 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go index 2c4675040e..be58c4e1ff 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go @@ -375,14 +375,12 @@ type RtMetrics struct { Pad uint32 } -type Mclpool struct{} - const ( SizeofBpfVersion = 0x4 SizeofBpfStat = 0x8 SizeofBpfProgram = 0x8 SizeofBpfInsn = 0x8 - SizeofBpfHdr = 0x14 + SizeofBpfHdr = 0x18 ) type BpfVersion struct { @@ -412,7 +410,10 @@ type BpfHdr struct { Caplen uint32 Datalen uint32 Hdrlen uint16 - _ [2]byte + Ifidx uint16 + Flowid uint16 + Flags uint8 + Drops uint8 } type BpfTimeval struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go index ddee045147..52338266cb 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go @@ -368,14 +368,12 @@ type RtMetrics struct { Pad uint32 } -type Mclpool struct{} - const ( SizeofBpfVersion = 0x4 SizeofBpfStat = 0x8 SizeofBpfProgram = 0x10 SizeofBpfInsn = 0x8 - SizeofBpfHdr = 0x14 + SizeofBpfHdr = 0x18 ) type BpfVersion struct { @@ -405,7 +403,10 @@ type BpfHdr struct { Caplen uint32 Datalen uint32 Hdrlen uint16 - _ [2]byte + Ifidx uint16 + Flowid uint16 + Flags uint8 + Drops uint8 } type BpfTimeval struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go index eb13d4e8bf..605cfdb12b 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go @@ -368,14 +368,12 @@ type RtMetrics struct { Pad uint32 } -type Mclpool struct{} - const ( SizeofBpfVersion = 0x4 SizeofBpfStat = 0x8 SizeofBpfProgram = 0x10 SizeofBpfInsn = 0x8 - SizeofBpfHdr = 0x14 + SizeofBpfHdr = 0x18 ) type BpfVersion struct { @@ -405,7 +403,10 @@ type BpfHdr struct { Caplen uint32 Datalen uint32 Hdrlen uint16 - _ [2]byte + Ifidx uint16 + Flowid uint16 + Flags uint8 + Drops uint8 } type BpfTimeval struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_ppc64.go new file mode 100644 index 0000000000..d6724c0102 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_ppc64.go @@ -0,0 +1,571 @@ +// cgo -godefs -- -fsigned-char types_openbsd.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. + +//go:build ppc64 && openbsd +// +build ppc64,openbsd + +package unix + +const ( + SizeofPtr = 0x8 + SizeofShort = 0x2 + SizeofInt = 0x4 + SizeofLong = 0x8 + SizeofLongLong = 0x8 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int64 + _C_long_long int64 +) + +type Timespec struct { + Sec int64 + Nsec int64 +} + +type Timeval struct { + Sec int64 + Usec int64 +} + +type Rusage struct { + Utime Timeval + Stime Timeval + Maxrss int64 + Ixrss int64 + Idrss int64 + Isrss int64 + Minflt int64 + Majflt int64 + Nswap int64 + Inblock int64 + Oublock int64 + Msgsnd int64 + Msgrcv int64 + Nsignals int64 + Nvcsw int64 + Nivcsw int64 +} + +type Rlimit struct { + Cur uint64 + Max uint64 +} + +type _Gid_t uint32 + +type Stat_t struct { + Mode uint32 + Dev int32 + Ino uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev int32 + Atim Timespec + Mtim Timespec + Ctim Timespec + Size int64 + Blocks int64 + Blksize int32 + Flags uint32 + Gen uint32 + _ Timespec +} + +type Statfs_t struct { + F_flags uint32 + F_bsize uint32 + F_iosize uint32 + F_blocks uint64 + F_bfree uint64 + F_bavail int64 + F_files uint64 + F_ffree uint64 + F_favail int64 + F_syncwrites uint64 + F_syncreads uint64 + F_asyncwrites uint64 + F_asyncreads uint64 + F_fsid Fsid + F_namemax uint32 + F_owner uint32 + F_ctime uint64 + F_fstypename [16]byte + F_mntonname [90]byte + F_mntfromname [90]byte + F_mntfromspec [90]byte + _ [2]byte + Mount_info [160]byte +} + +type Flock_t struct { + Start int64 + Len int64 + Pid int32 + Type int16 + Whence int16 +} + +type Dirent struct { + Fileno uint64 + Off int64 + Reclen uint16 + Type uint8 + Namlen uint8 + _ [4]uint8 + Name [256]int8 +} + +type Fsid struct { + Val [2]int32 +} + +const ( + PathMax = 0x400 +) + +type RawSockaddrInet4 struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type RawSockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type RawSockaddrUnix struct { + Len uint8 + Family uint8 + Path [104]int8 +} + +type RawSockaddrDatalink struct { + Len uint8 + Family uint8 + Index uint16 + Type uint8 + Nlen uint8 + Alen uint8 + Slen uint8 + Data [24]int8 +} + +type RawSockaddr struct { + Len uint8 + Family uint8 + Data [14]int8 +} + +type RawSockaddrAny struct { + Addr RawSockaddr + Pad [92]int8 +} + +type _Socklen uint32 + +type Linger struct { + Onoff int32 + Linger int32 +} + +type Iovec struct { + Base *byte + Len uint64 +} + +type IPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type IPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type Msghdr struct { + Name *byte + Namelen uint32 + Iov *Iovec + Iovlen uint32 + Control *byte + Controllen uint32 + Flags int32 +} + +type Cmsghdr struct { + Len uint32 + Level int32 + Type int32 +} + +type Inet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type IPv6MTUInfo struct { + Addr RawSockaddrInet6 + Mtu uint32 +} + +type ICMPv6Filter struct { + Filt [8]uint32 +} + +const ( + SizeofSockaddrInet4 = 0x10 + SizeofSockaddrInet6 = 0x1c + SizeofSockaddrAny = 0x6c + SizeofSockaddrUnix = 0x6a + SizeofSockaddrDatalink = 0x20 + SizeofLinger = 0x8 + SizeofIovec = 0x10 + SizeofIPMreq = 0x8 + SizeofIPv6Mreq = 0x14 + SizeofMsghdr = 0x30 + SizeofCmsghdr = 0xc + SizeofInet6Pktinfo = 0x14 + SizeofIPv6MTUInfo = 0x20 + SizeofICMPv6Filter = 0x20 +) + +const ( + PTRACE_TRACEME = 0x0 + PTRACE_CONT = 0x7 + PTRACE_KILL = 0x8 +) + +type Kevent_t struct { + Ident uint64 + Filter int16 + Flags uint16 + Fflags uint32 + Data int64 + Udata *byte +} + +type FdSet struct { + Bits [32]uint32 +} + +const ( + SizeofIfMsghdr = 0xa8 + SizeofIfData = 0x90 + SizeofIfaMsghdr = 0x18 + SizeofIfAnnounceMsghdr = 0x1a + SizeofRtMsghdr = 0x60 + SizeofRtMetrics = 0x38 +) + +type IfMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + Tableid uint16 + Pad1 uint8 + Pad2 uint8 + Addrs int32 + Flags int32 + Xflags int32 + Data IfData +} + +type IfData struct { + Type uint8 + Addrlen uint8 + Hdrlen uint8 + Link_state uint8 + Mtu uint32 + Metric uint32 + Rdomain uint32 + Baudrate uint64 + Ipackets uint64 + Ierrors uint64 + Opackets uint64 + Oerrors uint64 + Collisions uint64 + Ibytes uint64 + Obytes uint64 + Imcasts uint64 + Omcasts uint64 + Iqdrops uint64 + Oqdrops uint64 + Noproto uint64 + Capabilities uint32 + Lastchange Timeval +} + +type IfaMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + Tableid uint16 + Pad1 uint8 + Pad2 uint8 + Addrs int32 + Flags int32 + Metric int32 +} + +type IfAnnounceMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + What uint16 + Name [16]int8 +} + +type RtMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + Tableid uint16 + Priority uint8 + Mpls uint8 + Addrs int32 + Flags int32 + Fmask int32 + Pid int32 + Seq int32 + Errno int32 + Inits uint32 + Rmx RtMetrics +} + +type RtMetrics struct { + Pksent uint64 + Expire int64 + Locks uint32 + Mtu uint32 + Refcnt uint32 + Hopcount uint32 + Recvpipe uint32 + Sendpipe uint32 + Ssthresh uint32 + Rtt uint32 + Rttvar uint32 + Pad uint32 +} + +type Mclpool struct{} + +const ( + SizeofBpfVersion = 0x4 + SizeofBpfStat = 0x8 + SizeofBpfProgram = 0x10 + SizeofBpfInsn = 0x8 + SizeofBpfHdr = 0x18 +) + +type BpfVersion struct { + Major uint16 + Minor uint16 +} + +type BpfStat struct { + Recv uint32 + Drop uint32 +} + +type BpfProgram struct { + Len uint32 + Insns *BpfInsn +} + +type BpfInsn struct { + Code uint16 + Jt uint8 + Jf uint8 + K uint32 +} + +type BpfHdr struct { + Tstamp BpfTimeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + Ifidx uint16 + Flowid uint16 + Flags uint8 + Drops uint8 +} + +type BpfTimeval struct { + Sec uint32 + Usec uint32 +} + +type Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]uint8 + Ispeed int32 + Ospeed int32 +} + +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +const ( + AT_FDCWD = -0x64 + AT_EACCESS = 0x1 + AT_SYMLINK_NOFOLLOW = 0x2 + AT_SYMLINK_FOLLOW = 0x4 + AT_REMOVEDIR = 0x8 +) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + +type Sigset_t uint32 + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} + +const SizeofUvmexp = 0x158 + +type Uvmexp struct { + Pagesize int32 + Pagemask int32 + Pageshift int32 + Npages int32 + Free int32 + Active int32 + Inactive int32 + Paging int32 + Wired int32 + Zeropages int32 + Reserve_pagedaemon int32 + Reserve_kernel int32 + Unused01 int32 + Vnodepages int32 + Vtextpages int32 + Freemin int32 + Freetarg int32 + Inactarg int32 + Wiredmax int32 + Anonmin int32 + Vtextmin int32 + Vnodemin int32 + Anonminpct int32 + Vtextminpct int32 + Vnodeminpct int32 + Nswapdev int32 + Swpages int32 + Swpginuse int32 + Swpgonly int32 + Nswget int32 + Nanon int32 + Unused05 int32 + Unused06 int32 + Faults int32 + Traps int32 + Intrs int32 + Swtch int32 + Softs int32 + Syscalls int32 + Pageins int32 + Unused07 int32 + Unused08 int32 + Pgswapin int32 + Pgswapout int32 + Forks int32 + Forks_ppwait int32 + Forks_sharevm int32 + Pga_zerohit int32 + Pga_zeromiss int32 + Unused09 int32 + Fltnoram int32 + Fltnoanon int32 + Fltnoamap int32 + Fltpgwait int32 + Fltpgrele int32 + Fltrelck int32 + Fltrelckok int32 + Fltanget int32 + Fltanretry int32 + Fltamcopy int32 + Fltnamap int32 + Fltnomap int32 + Fltlget int32 + Fltget int32 + Flt_anon int32 + Flt_acow int32 + Flt_obj int32 + Flt_prcopy int32 + Flt_przero int32 + Pdwoke int32 + Pdrevs int32 + Pdswout int32 + Pdfreed int32 + Pdscans int32 + Pdanscan int32 + Pdobscan int32 + Pdreact int32 + Pdbusy int32 + Pdpageouts int32 + Pdpending int32 + Pddeact int32 + Unused11 int32 + Unused12 int32 + Unused13 int32 + Fpswtch int32 + Kmapent int32 +} + +const SizeofClockinfo = 0x10 + +type Clockinfo struct { + Hz int32 + Tick int32 + Stathz int32 + Profhz int32 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_riscv64.go new file mode 100644 index 0000000000..ddfd27a434 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_riscv64.go @@ -0,0 +1,571 @@ +// cgo -godefs -- -fsigned-char types_openbsd.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. + +//go:build riscv64 && openbsd +// +build riscv64,openbsd + +package unix + +const ( + SizeofPtr = 0x8 + SizeofShort = 0x2 + SizeofInt = 0x4 + SizeofLong = 0x8 + SizeofLongLong = 0x8 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int64 + _C_long_long int64 +) + +type Timespec struct { + Sec int64 + Nsec int64 +} + +type Timeval struct { + Sec int64 + Usec int64 +} + +type Rusage struct { + Utime Timeval + Stime Timeval + Maxrss int64 + Ixrss int64 + Idrss int64 + Isrss int64 + Minflt int64 + Majflt int64 + Nswap int64 + Inblock int64 + Oublock int64 + Msgsnd int64 + Msgrcv int64 + Nsignals int64 + Nvcsw int64 + Nivcsw int64 +} + +type Rlimit struct { + Cur uint64 + Max uint64 +} + +type _Gid_t uint32 + +type Stat_t struct { + Mode uint32 + Dev int32 + Ino uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev int32 + Atim Timespec + Mtim Timespec + Ctim Timespec + Size int64 + Blocks int64 + Blksize int32 + Flags uint32 + Gen uint32 + _ Timespec +} + +type Statfs_t struct { + F_flags uint32 + F_bsize uint32 + F_iosize uint32 + F_blocks uint64 + F_bfree uint64 + F_bavail int64 + F_files uint64 + F_ffree uint64 + F_favail int64 + F_syncwrites uint64 + F_syncreads uint64 + F_asyncwrites uint64 + F_asyncreads uint64 + F_fsid Fsid + F_namemax uint32 + F_owner uint32 + F_ctime uint64 + F_fstypename [16]byte + F_mntonname [90]byte + F_mntfromname [90]byte + F_mntfromspec [90]byte + _ [2]byte + Mount_info [160]byte +} + +type Flock_t struct { + Start int64 + Len int64 + Pid int32 + Type int16 + Whence int16 +} + +type Dirent struct { + Fileno uint64 + Off int64 + Reclen uint16 + Type uint8 + Namlen uint8 + _ [4]uint8 + Name [256]int8 +} + +type Fsid struct { + Val [2]int32 +} + +const ( + PathMax = 0x400 +) + +type RawSockaddrInet4 struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type RawSockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type RawSockaddrUnix struct { + Len uint8 + Family uint8 + Path [104]int8 +} + +type RawSockaddrDatalink struct { + Len uint8 + Family uint8 + Index uint16 + Type uint8 + Nlen uint8 + Alen uint8 + Slen uint8 + Data [24]int8 +} + +type RawSockaddr struct { + Len uint8 + Family uint8 + Data [14]int8 +} + +type RawSockaddrAny struct { + Addr RawSockaddr + Pad [92]int8 +} + +type _Socklen uint32 + +type Linger struct { + Onoff int32 + Linger int32 +} + +type Iovec struct { + Base *byte + Len uint64 +} + +type IPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type IPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type Msghdr struct { + Name *byte + Namelen uint32 + Iov *Iovec + Iovlen uint32 + Control *byte + Controllen uint32 + Flags int32 +} + +type Cmsghdr struct { + Len uint32 + Level int32 + Type int32 +} + +type Inet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type IPv6MTUInfo struct { + Addr RawSockaddrInet6 + Mtu uint32 +} + +type ICMPv6Filter struct { + Filt [8]uint32 +} + +const ( + SizeofSockaddrInet4 = 0x10 + SizeofSockaddrInet6 = 0x1c + SizeofSockaddrAny = 0x6c + SizeofSockaddrUnix = 0x6a + SizeofSockaddrDatalink = 0x20 + SizeofLinger = 0x8 + SizeofIovec = 0x10 + SizeofIPMreq = 0x8 + SizeofIPv6Mreq = 0x14 + SizeofMsghdr = 0x30 + SizeofCmsghdr = 0xc + SizeofInet6Pktinfo = 0x14 + SizeofIPv6MTUInfo = 0x20 + SizeofICMPv6Filter = 0x20 +) + +const ( + PTRACE_TRACEME = 0x0 + PTRACE_CONT = 0x7 + PTRACE_KILL = 0x8 +) + +type Kevent_t struct { + Ident uint64 + Filter int16 + Flags uint16 + Fflags uint32 + Data int64 + Udata *byte +} + +type FdSet struct { + Bits [32]uint32 +} + +const ( + SizeofIfMsghdr = 0xa8 + SizeofIfData = 0x90 + SizeofIfaMsghdr = 0x18 + SizeofIfAnnounceMsghdr = 0x1a + SizeofRtMsghdr = 0x60 + SizeofRtMetrics = 0x38 +) + +type IfMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + Tableid uint16 + Pad1 uint8 + Pad2 uint8 + Addrs int32 + Flags int32 + Xflags int32 + Data IfData +} + +type IfData struct { + Type uint8 + Addrlen uint8 + Hdrlen uint8 + Link_state uint8 + Mtu uint32 + Metric uint32 + Rdomain uint32 + Baudrate uint64 + Ipackets uint64 + Ierrors uint64 + Opackets uint64 + Oerrors uint64 + Collisions uint64 + Ibytes uint64 + Obytes uint64 + Imcasts uint64 + Omcasts uint64 + Iqdrops uint64 + Oqdrops uint64 + Noproto uint64 + Capabilities uint32 + Lastchange Timeval +} + +type IfaMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + Tableid uint16 + Pad1 uint8 + Pad2 uint8 + Addrs int32 + Flags int32 + Metric int32 +} + +type IfAnnounceMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + What uint16 + Name [16]int8 +} + +type RtMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + Tableid uint16 + Priority uint8 + Mpls uint8 + Addrs int32 + Flags int32 + Fmask int32 + Pid int32 + Seq int32 + Errno int32 + Inits uint32 + Rmx RtMetrics +} + +type RtMetrics struct { + Pksent uint64 + Expire int64 + Locks uint32 + Mtu uint32 + Refcnt uint32 + Hopcount uint32 + Recvpipe uint32 + Sendpipe uint32 + Ssthresh uint32 + Rtt uint32 + Rttvar uint32 + Pad uint32 +} + +type Mclpool struct{} + +const ( + SizeofBpfVersion = 0x4 + SizeofBpfStat = 0x8 + SizeofBpfProgram = 0x10 + SizeofBpfInsn = 0x8 + SizeofBpfHdr = 0x18 +) + +type BpfVersion struct { + Major uint16 + Minor uint16 +} + +type BpfStat struct { + Recv uint32 + Drop uint32 +} + +type BpfProgram struct { + Len uint32 + Insns *BpfInsn +} + +type BpfInsn struct { + Code uint16 + Jt uint8 + Jf uint8 + K uint32 +} + +type BpfHdr struct { + Tstamp BpfTimeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + Ifidx uint16 + Flowid uint16 + Flags uint8 + Drops uint8 +} + +type BpfTimeval struct { + Sec uint32 + Usec uint32 +} + +type Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]uint8 + Ispeed int32 + Ospeed int32 +} + +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +const ( + AT_FDCWD = -0x64 + AT_EACCESS = 0x1 + AT_SYMLINK_NOFOLLOW = 0x2 + AT_SYMLINK_FOLLOW = 0x4 + AT_REMOVEDIR = 0x8 +) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + +type Sigset_t uint32 + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} + +const SizeofUvmexp = 0x158 + +type Uvmexp struct { + Pagesize int32 + Pagemask int32 + Pageshift int32 + Npages int32 + Free int32 + Active int32 + Inactive int32 + Paging int32 + Wired int32 + Zeropages int32 + Reserve_pagedaemon int32 + Reserve_kernel int32 + Unused01 int32 + Vnodepages int32 + Vtextpages int32 + Freemin int32 + Freetarg int32 + Inactarg int32 + Wiredmax int32 + Anonmin int32 + Vtextmin int32 + Vnodemin int32 + Anonminpct int32 + Vtextminpct int32 + Vnodeminpct int32 + Nswapdev int32 + Swpages int32 + Swpginuse int32 + Swpgonly int32 + Nswget int32 + Nanon int32 + Unused05 int32 + Unused06 int32 + Faults int32 + Traps int32 + Intrs int32 + Swtch int32 + Softs int32 + Syscalls int32 + Pageins int32 + Unused07 int32 + Unused08 int32 + Pgswapin int32 + Pgswapout int32 + Forks int32 + Forks_ppwait int32 + Forks_sharevm int32 + Pga_zerohit int32 + Pga_zeromiss int32 + Unused09 int32 + Fltnoram int32 + Fltnoanon int32 + Fltnoamap int32 + Fltpgwait int32 + Fltpgrele int32 + Fltrelck int32 + Fltrelckok int32 + Fltanget int32 + Fltanretry int32 + Fltamcopy int32 + Fltnamap int32 + Fltnomap int32 + Fltlget int32 + Fltget int32 + Flt_anon int32 + Flt_acow int32 + Flt_obj int32 + Flt_prcopy int32 + Flt_przero int32 + Pdwoke int32 + Pdrevs int32 + Pdswout int32 + Pdfreed int32 + Pdscans int32 + Pdanscan int32 + Pdobscan int32 + Pdreact int32 + Pdbusy int32 + Pdpageouts int32 + Pdpending int32 + Pddeact int32 + Unused11 int32 + Unused12 int32 + Unused13 int32 + Fpswtch int32 + Kmapent int32 +} + +const SizeofClockinfo = 0x10 + +type Clockinfo struct { + Hz int32 + Tick int32 + Stathz int32 + Profhz int32 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go index c1a9b83ad5..0400747c67 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go @@ -480,3 +480,38 @@ const ( MOUNTEDOVER = 0x40000000 FILE_EXCEPTION = 0x60000070 ) + +const ( + TUNNEWPPA = 0x540001 + TUNSETPPA = 0x540002 + + I_STR = 0x5308 + I_POP = 0x5303 + I_PUSH = 0x5302 + I_LINK = 0x530c + I_UNLINK = 0x530d + I_PLINK = 0x5316 + I_PUNLINK = 0x5317 + + IF_UNITSEL = -0x7ffb8cca +) + +type strbuf struct { + Maxlen int32 + Len int32 + Buf *int8 +} + +type Strioctl struct { + Cmd int32 + Timout int32 + Len int32 + Dp *int8 +} + +type Lifreq struct { + Name [32]int8 + Lifru1 [4]byte + Type uint32 + Lifru [336]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go index 4ab638cb94..aec1efcb30 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go @@ -339,7 +339,7 @@ type Statfs_t struct { Flags uint64 } -type Dirent struct { +type direntLE struct { Reclen uint16 Namlen uint16 Ino uint32 @@ -347,6 +347,15 @@ type Dirent struct { Name [256]byte } +type Dirent struct { + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]uint8 + _ [5]byte +} + type FdSet struct { Bits [64]int32 } diff --git a/vendor/golang.org/x/sys/windows/syscall.go b/vendor/golang.org/x/sys/windows/syscall.go index 72074d582f..8732cdb957 100644 --- a/vendor/golang.org/x/sys/windows/syscall.go +++ b/vendor/golang.org/x/sys/windows/syscall.go @@ -30,8 +30,6 @@ import ( "strings" "syscall" "unsafe" - - "golang.org/x/sys/internal/unsafeheader" ) // ByteSliceFromString returns a NUL-terminated slice of bytes @@ -83,13 +81,7 @@ func BytePtrToString(p *byte) string { ptr = unsafe.Pointer(uintptr(ptr) + 1) } - var s []byte - h := (*unsafeheader.Slice)(unsafe.Pointer(&s)) - h.Data = unsafe.Pointer(p) - h.Len = n - h.Cap = n - - return string(s) + return string(unsafe.Slice(p, n)) } // Single-word zero for use when we need a valid pointer to 0 bytes. diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index e27913817a..3723b2c224 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -10,7 +10,6 @@ import ( errorspkg "errors" "fmt" "runtime" - "strings" "sync" "syscall" "time" @@ -87,22 +86,13 @@ func StringToUTF16(s string) []uint16 { // s, with a terminating NUL added. If s contains a NUL byte at any // location, it returns (nil, syscall.EINVAL). func UTF16FromString(s string) ([]uint16, error) { - if strings.IndexByte(s, 0) != -1 { - return nil, syscall.EINVAL - } - return utf16.Encode([]rune(s + "\x00")), nil + return syscall.UTF16FromString(s) } // UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s, // with a terminating NUL and any bytes after the NUL removed. func UTF16ToString(s []uint16) string { - for i, v := range s { - if v == 0 { - s = s[:i] - break - } - } - return string(utf16.Decode(s)) + return syscall.UTF16ToString(s) } // StringToUTF16Ptr is deprecated. Use UTF16PtrFromString instead. @@ -138,13 +128,7 @@ func UTF16PtrToString(p *uint16) string { ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p)) } - var s []uint16 - h := (*unsafeheader.Slice)(unsafe.Pointer(&s)) - h.Data = unsafe.Pointer(p) - h.Len = n - h.Cap = n - - return string(utf16.Decode(s)) + return string(utf16.Decode(unsafe.Slice(p, n))) } func Getpagesize() int { return 4096 } @@ -364,6 +348,16 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) //sys GetActiveProcessorCount(groupNumber uint16) (ret uint32) //sys GetMaximumProcessorCount(groupNumber uint16) (ret uint32) +//sys EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) = user32.EnumWindows +//sys EnumChildWindows(hwnd HWND, enumFunc uintptr, param unsafe.Pointer) = user32.EnumChildWindows +//sys GetClassName(hwnd HWND, className *uint16, maxCount int32) (copied int32, err error) = user32.GetClassNameW +//sys GetDesktopWindow() (hwnd HWND) = user32.GetDesktopWindow +//sys GetForegroundWindow() (hwnd HWND) = user32.GetForegroundWindow +//sys IsWindow(hwnd HWND) (isWindow bool) = user32.IsWindow +//sys IsWindowUnicode(hwnd HWND) (isUnicode bool) = user32.IsWindowUnicode +//sys IsWindowVisible(hwnd HWND) (isVisible bool) = user32.IsWindowVisible +//sys GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) = user32.GetGUIThreadInfo +//sys GetLargePageMinimum() (size uintptr) // Volume Management Functions //sys DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW @@ -439,6 +433,10 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys RtlAddFunctionTable(functionTable *RUNTIME_FUNCTION, entryCount uint32, baseAddress uintptr) (ret bool) = ntdll.RtlAddFunctionTable //sys RtlDeleteFunctionTable(functionTable *RUNTIME_FUNCTION) (ret bool) = ntdll.RtlDeleteFunctionTable +// Desktop Window Manager API (Dwmapi) +//sys DwmGetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) = dwmapi.DwmGetWindowAttribute +//sys DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) = dwmapi.DwmSetWindowAttribute + // syscall interface implementation for other packages // GetCurrentProcess returns the handle for the current process. @@ -748,7 +746,7 @@ func Utimes(path string, tv []Timeval) (err error) { if e != nil { return e } - defer Close(h) + defer CloseHandle(h) a := NsecToFiletime(tv[0].Nanoseconds()) w := NsecToFiletime(tv[1].Nanoseconds()) return SetFileTime(h, nil, &a, &w) @@ -768,7 +766,7 @@ func UtimesNano(path string, ts []Timespec) (err error) { if e != nil { return e } - defer Close(h) + defer CloseHandle(h) a := NsecToFiletime(TimespecToNsec(ts[0])) w := NsecToFiletime(TimespecToNsec(ts[1])) return SetFileTime(h, nil, &a, &w) @@ -826,6 +824,9 @@ const socket_error = uintptr(^uint32(0)) //sys WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup //sys WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup //sys WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) [failretval==socket_error] = ws2_32.WSAIoctl +//sys WSALookupServiceBegin(querySet *WSAQUERYSET, flags uint32, handle *Handle) (err error) [failretval==socket_error] = ws2_32.WSALookupServiceBeginW +//sys WSALookupServiceNext(handle Handle, flags uint32, size *int32, querySet *WSAQUERYSET) (err error) [failretval==socket_error] = ws2_32.WSALookupServiceNextW +//sys WSALookupServiceEnd(handle Handle) (err error) [failretval==socket_error] = ws2_32.WSALookupServiceEnd //sys socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket //sys sendto(s Handle, buf []byte, flags int32, to unsafe.Pointer, tolen int32) (err error) [failretval==socket_error] = ws2_32.sendto //sys recvfrom(s Handle, buf []byte, flags int32, from *RawSockaddrAny, fromlen *int32) (n int32, err error) [failretval==-1] = ws2_32.recvfrom @@ -1021,8 +1022,7 @@ func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) { for n < len(pp.Path) && pp.Path[n] != 0 { n++ } - bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] - sa.Name = string(bytes) + sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n)) return sa, nil case AF_INET: @@ -1108,9 +1108,13 @@ func Shutdown(fd Handle, how int) (err error) { } func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) { - rsa, l, err := to.sockaddr() - if err != nil { - return err + var rsa unsafe.Pointer + var l int32 + if to != nil { + rsa, l, err = to.sockaddr() + if err != nil { + return err + } } return WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine) } diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index f9eaca528e..857acf1032 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -1243,6 +1243,51 @@ const ( DnsSectionAdditional = 0x0003 ) +const ( + // flags of WSALookupService + LUP_DEEP = 0x0001 + LUP_CONTAINERS = 0x0002 + LUP_NOCONTAINERS = 0x0004 + LUP_NEAREST = 0x0008 + LUP_RETURN_NAME = 0x0010 + LUP_RETURN_TYPE = 0x0020 + LUP_RETURN_VERSION = 0x0040 + LUP_RETURN_COMMENT = 0x0080 + LUP_RETURN_ADDR = 0x0100 + LUP_RETURN_BLOB = 0x0200 + LUP_RETURN_ALIASES = 0x0400 + LUP_RETURN_QUERY_STRING = 0x0800 + LUP_RETURN_ALL = 0x0FF0 + LUP_RES_SERVICE = 0x8000 + + LUP_FLUSHCACHE = 0x1000 + LUP_FLUSHPREVIOUS = 0x2000 + + LUP_NON_AUTHORITATIVE = 0x4000 + LUP_SECURE = 0x8000 + LUP_RETURN_PREFERRED_NAMES = 0x10000 + LUP_DNS_ONLY = 0x20000 + + LUP_ADDRCONFIG = 0x100000 + LUP_DUAL_ADDR = 0x200000 + LUP_FILESERVER = 0x400000 + LUP_DISABLE_IDN_ENCODING = 0x00800000 + LUP_API_ANSI = 0x01000000 + + LUP_RESOLUTION_HANDLE = 0x80000000 +) + +const ( + // values of WSAQUERYSET's namespace + NS_ALL = 0 + NS_DNS = 12 + NS_NLA = 15 + NS_BTH = 16 + NS_EMAIL = 37 + NS_PNRPNAME = 38 + NS_PNRPCLOUD = 39 +) + type DNSSRVData struct { Target *uint16 Priority uint16 @@ -3213,3 +3258,88 @@ type ModuleInfo struct { } const ALL_PROCESSOR_GROUPS = 0xFFFF + +type Rect struct { + Left int32 + Top int32 + Right int32 + Bottom int32 +} + +type GUIThreadInfo struct { + Size uint32 + Flags uint32 + Active HWND + Focus HWND + Capture HWND + MenuOwner HWND + MoveSize HWND + CaretHandle HWND + CaretRect Rect +} + +const ( + DWMWA_NCRENDERING_ENABLED = 1 + DWMWA_NCRENDERING_POLICY = 2 + DWMWA_TRANSITIONS_FORCEDISABLED = 3 + DWMWA_ALLOW_NCPAINT = 4 + DWMWA_CAPTION_BUTTON_BOUNDS = 5 + DWMWA_NONCLIENT_RTL_LAYOUT = 6 + DWMWA_FORCE_ICONIC_REPRESENTATION = 7 + DWMWA_FLIP3D_POLICY = 8 + DWMWA_EXTENDED_FRAME_BOUNDS = 9 + DWMWA_HAS_ICONIC_BITMAP = 10 + DWMWA_DISALLOW_PEEK = 11 + DWMWA_EXCLUDED_FROM_PEEK = 12 + DWMWA_CLOAK = 13 + DWMWA_CLOAKED = 14 + DWMWA_FREEZE_REPRESENTATION = 15 + DWMWA_PASSIVE_UPDATE_MODE = 16 + DWMWA_USE_HOSTBACKDROPBRUSH = 17 + DWMWA_USE_IMMERSIVE_DARK_MODE = 20 + DWMWA_WINDOW_CORNER_PREFERENCE = 33 + DWMWA_BORDER_COLOR = 34 + DWMWA_CAPTION_COLOR = 35 + DWMWA_TEXT_COLOR = 36 + DWMWA_VISIBLE_FRAME_BORDER_THICKNESS = 37 +) + +type WSAQUERYSET struct { + Size uint32 + ServiceInstanceName *uint16 + ServiceClassId *GUID + Version *WSAVersion + Comment *uint16 + NameSpace uint32 + NSProviderId *GUID + Context *uint16 + NumberOfProtocols uint32 + AfpProtocols *AFProtocols + QueryString *uint16 + NumberOfCsAddrs uint32 + SaBuffer *CSAddrInfo + OutputFlags uint32 + Blob *BLOB +} + +type WSAVersion struct { + Version uint32 + EnumerationOfComparison int32 +} + +type AFProtocols struct { + AddressFamily int32 + Protocol int32 +} + +type CSAddrInfo struct { + LocalAddr SocketAddress + RemoteAddr SocketAddress + SocketType int32 + Protocol int32 +} + +type BLOB struct { + Size uint32 + BlobData *byte +} diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 52d4742cb9..6d2a268534 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -40,6 +40,7 @@ var ( modadvapi32 = NewLazySystemDLL("advapi32.dll") modcrypt32 = NewLazySystemDLL("crypt32.dll") moddnsapi = NewLazySystemDLL("dnsapi.dll") + moddwmapi = NewLazySystemDLL("dwmapi.dll") modiphlpapi = NewLazySystemDLL("iphlpapi.dll") modkernel32 = NewLazySystemDLL("kernel32.dll") modmswsock = NewLazySystemDLL("mswsock.dll") @@ -175,6 +176,8 @@ var ( procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W") procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W") procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree") + procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute") + procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute") procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx") @@ -249,6 +252,7 @@ var ( procGetFileType = modkernel32.NewProc("GetFileType") procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW") procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW") + procGetLargePageMinimum = modkernel32.NewProc("GetLargePageMinimum") procGetLastError = modkernel32.NewProc("GetLastError") procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") procGetLogicalDrives = modkernel32.NewProc("GetLogicalDrives") @@ -444,9 +448,18 @@ var ( procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW") procSHGetKnownFolderPath = modshell32.NewProc("SHGetKnownFolderPath") procShellExecuteW = modshell32.NewProc("ShellExecuteW") + procEnumChildWindows = moduser32.NewProc("EnumChildWindows") + procEnumWindows = moduser32.NewProc("EnumWindows") procExitWindowsEx = moduser32.NewProc("ExitWindowsEx") + procGetClassNameW = moduser32.NewProc("GetClassNameW") + procGetDesktopWindow = moduser32.NewProc("GetDesktopWindow") + procGetForegroundWindow = moduser32.NewProc("GetForegroundWindow") + procGetGUIThreadInfo = moduser32.NewProc("GetGUIThreadInfo") procGetShellWindow = moduser32.NewProc("GetShellWindow") procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId") + procIsWindow = moduser32.NewProc("IsWindow") + procIsWindowUnicode = moduser32.NewProc("IsWindowUnicode") + procIsWindowVisible = moduser32.NewProc("IsWindowVisible") procMessageBoxW = moduser32.NewProc("MessageBoxW") procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock") procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock") @@ -461,6 +474,9 @@ var ( procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW") procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult") procWSAIoctl = modws2_32.NewProc("WSAIoctl") + procWSALookupServiceBeginW = modws2_32.NewProc("WSALookupServiceBeginW") + procWSALookupServiceEnd = modws2_32.NewProc("WSALookupServiceEnd") + procWSALookupServiceNextW = modws2_32.NewProc("WSALookupServiceNextW") procWSARecv = modws2_32.NewProc("WSARecv") procWSARecvFrom = modws2_32.NewProc("WSARecvFrom") procWSASend = modws2_32.NewProc("WSASend") @@ -1525,6 +1541,22 @@ func DnsRecordListFree(rl *DNSRecord, freetype uint32) { return } +func DwmGetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) { + r0, _, _ := syscall.Syscall6(procDwmGetWindowAttribute.Addr(), 4, uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size), 0, 0) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) { + r0, _, _ := syscall.Syscall6(procDwmSetWindowAttribute.Addr(), 4, uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size), 0, 0) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) if r0 != 0 { @@ -2152,6 +2184,12 @@ func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) ( return } +func GetLargePageMinimum() (size uintptr) { + r0, _, _ := syscall.Syscall(procGetLargePageMinimum.Addr(), 0, 0, 0, 0) + size = uintptr(r0) + return +} + func GetLastError() (lasterr error) { r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0) if r0 != 0 { @@ -3802,6 +3840,19 @@ func ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *ui return } +func EnumChildWindows(hwnd HWND, enumFunc uintptr, param unsafe.Pointer) { + syscall.Syscall(procEnumChildWindows.Addr(), 3, uintptr(hwnd), uintptr(enumFunc), uintptr(param)) + return +} + +func EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) { + r1, _, e1 := syscall.Syscall(procEnumWindows.Addr(), 2, uintptr(enumFunc), uintptr(param), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func ExitWindowsEx(flags uint32, reason uint32) (err error) { r1, _, e1 := syscall.Syscall(procExitWindowsEx.Addr(), 2, uintptr(flags), uintptr(reason), 0) if r1 == 0 { @@ -3810,6 +3861,35 @@ func ExitWindowsEx(flags uint32, reason uint32) (err error) { return } +func GetClassName(hwnd HWND, className *uint16, maxCount int32) (copied int32, err error) { + r0, _, e1 := syscall.Syscall(procGetClassNameW.Addr(), 3, uintptr(hwnd), uintptr(unsafe.Pointer(className)), uintptr(maxCount)) + copied = int32(r0) + if copied == 0 { + err = errnoErr(e1) + } + return +} + +func GetDesktopWindow() (hwnd HWND) { + r0, _, _ := syscall.Syscall(procGetDesktopWindow.Addr(), 0, 0, 0, 0) + hwnd = HWND(r0) + return +} + +func GetForegroundWindow() (hwnd HWND) { + r0, _, _ := syscall.Syscall(procGetForegroundWindow.Addr(), 0, 0, 0, 0) + hwnd = HWND(r0) + return +} + +func GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) { + r1, _, e1 := syscall.Syscall(procGetGUIThreadInfo.Addr(), 2, uintptr(thread), uintptr(unsafe.Pointer(info)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetShellWindow() (shellWindow HWND) { r0, _, _ := syscall.Syscall(procGetShellWindow.Addr(), 0, 0, 0, 0) shellWindow = HWND(r0) @@ -3825,6 +3905,24 @@ func GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) { return } +func IsWindow(hwnd HWND) (isWindow bool) { + r0, _, _ := syscall.Syscall(procIsWindow.Addr(), 1, uintptr(hwnd), 0, 0) + isWindow = r0 != 0 + return +} + +func IsWindowUnicode(hwnd HWND) (isUnicode bool) { + r0, _, _ := syscall.Syscall(procIsWindowUnicode.Addr(), 1, uintptr(hwnd), 0, 0) + isUnicode = r0 != 0 + return +} + +func IsWindowVisible(hwnd HWND) (isVisible bool) { + r0, _, _ := syscall.Syscall(procIsWindowVisible.Addr(), 1, uintptr(hwnd), 0, 0) + isVisible = r0 != 0 + return +} + func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) { r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0) ret = int32(r0) @@ -3972,6 +4070,30 @@ func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbo return } +func WSALookupServiceBegin(querySet *WSAQUERYSET, flags uint32, handle *Handle) (err error) { + r1, _, e1 := syscall.Syscall(procWSALookupServiceBeginW.Addr(), 3, uintptr(unsafe.Pointer(querySet)), uintptr(flags), uintptr(unsafe.Pointer(handle))) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func WSALookupServiceEnd(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procWSALookupServiceEnd.Addr(), 1, uintptr(handle), 0, 0) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func WSALookupServiceNext(handle Handle, flags uint32, size *int32, querySet *WSAQUERYSET) (err error) { + r1, _, e1 := syscall.Syscall6(procWSALookupServiceNextW.Addr(), 4, uintptr(handle), uintptr(flags), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(querySet)), 0, 0) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) { r1, _, e1 := syscall.Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) if r1 == socket_error { diff --git a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go index 2ed25a7502..42adb8f697 100644 --- a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go +++ b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go @@ -87,7 +87,11 @@ func NewReader(r io.Reader) (io.Reader, error) { // Read reads export data from in, decodes it, and returns type // information for the package. -// The package name is specified by path. +// +// The package path (effectively its linker symbol prefix) is +// specified by path, since unlike the package name, this information +// may not be recorded in the export data. +// // File position information is added to fset. // // Read may inspect and add to the imports map to ensure that references diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go index 4caa0f55d9..6e4c066b69 100644 --- a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go @@ -51,6 +51,8 @@ const ( iexportVersionPosCol = 1 iexportVersionGo1_18 = 2 iexportVersionGenerics = 2 + + iexportVersionCurrent = 2 ) type ident struct { @@ -96,7 +98,7 @@ func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data } func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data []byte, bundle bool, path string) (pkgs []*types.Package, err error) { - const currentVersion = 1 + const currentVersion = iexportVersionCurrent version := int64(-1) if !debug { defer func() { diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go b/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go index 3c1a437543..2d421c9619 100644 --- a/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go @@ -36,6 +36,12 @@ type pkgReader struct { // laterFns holds functions that need to be invoked at the end of // import reading. laterFns []func() + // laterFors is used in case of 'type A B' to ensure that B is processed before A. + laterFors map[types.Type]int + + // ifaces holds a list of constructed Interfaces, which need to have + // Complete called after importing is done. + ifaces []*types.Interface } // later adds a function to be invoked at the end of import reading. @@ -63,6 +69,15 @@ func UImportData(fset *token.FileSet, imports map[string]*types.Package, data [] return } +// laterFor adds a function to be invoked at the end of import reading, and records the type that function is finishing. +func (pr *pkgReader) laterFor(t types.Type, fn func()) { + if pr.laterFors == nil { + pr.laterFors = make(map[types.Type]int) + } + pr.laterFors[t] = len(pr.laterFns) + pr.laterFns = append(pr.laterFns, fn) +} + // readUnifiedPackage reads a package description from the given // unified IR export data decoder. func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package { @@ -102,6 +117,10 @@ func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[st fn() } + for _, iface := range pr.ifaces { + iface.Complete() + } + pkg.MarkComplete() return pkg } @@ -231,11 +250,35 @@ func (r *reader) doPkg() *types.Package { for i := range imports { imports[i] = r.pkg() } - pkg.SetImports(imports) + pkg.SetImports(flattenImports(imports)) return pkg } +// flattenImports returns the transitive closure of all imported +// packages rooted from pkgs. +func flattenImports(pkgs []*types.Package) []*types.Package { + var res []*types.Package + + seen := make(map[*types.Package]bool) + var add func(pkg *types.Package) + add = func(pkg *types.Package) { + if seen[pkg] { + return + } + seen[pkg] = true + res = append(res, pkg) + for _, imp := range pkg.Imports() { + add(imp) + } + } + + for _, pkg := range pkgs { + add(pkg) + } + return res +} + // @@@ Types func (r *reader) typ() types.Type { @@ -372,6 +415,16 @@ func (r *reader) interfaceType() *types.Interface { if implicit { iface.MarkImplicit() } + + // We need to call iface.Complete(), but if there are any embedded + // defined types, then we may not have set their underlying + // interface type yet. So we need to defer calling Complete until + // after we've called SetUnderlying everywhere. + // + // TODO(mdempsky): After CL 424876 lands, it should be safe to call + // iface.Complete() immediately. + r.p.ifaces = append(r.p.ifaces, iface) + return iface } @@ -477,13 +530,41 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { named.SetTypeParams(r.typeParamNames()) - // TODO(mdempsky): Rewrite receiver types to underlying is an - // Interface? The go/types importer does this (I think because - // unit tests expected that), but cmd/compile doesn't care - // about it, so maybe we can avoid worrying about that here. rhs := r.typ() - r.p.later(func() { + pk := r.p + pk.laterFor(named, func() { + // First be sure that the rhs is initialized, if it needs to be initialized. + delete(pk.laterFors, named) // prevent cycles + if i, ok := pk.laterFors[rhs]; ok { + f := pk.laterFns[i] + pk.laterFns[i] = func() {} // function is running now, so replace it with a no-op + f() // initialize RHS + } underlying := rhs.Underlying() + + // If the underlying type is an interface, we need to + // duplicate its methods so we can replace the receiver + // parameter's type (#49906). + if iface, ok := underlying.(*types.Interface); ok && iface.NumExplicitMethods() != 0 { + methods := make([]*types.Func, iface.NumExplicitMethods()) + for i := range methods { + fn := iface.ExplicitMethod(i) + sig := fn.Type().(*types.Signature) + + recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named) + methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignature(recv, sig.Params(), sig.Results(), sig.Variadic())) + } + + embeds := make([]types.Type, iface.NumEmbeddeds()) + for i := range embeds { + embeds[i] = iface.EmbeddedType(i) + } + + newIface := types.NewInterfaceType(methods, embeds) + r.p.ifaces = append(r.p.ifaces, newIface) + underlying = newIface + } + named.SetUnderlying(underlying) }) diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go b/vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go index 2bc793668e..e08099c663 100644 --- a/vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go @@ -9,6 +9,7 @@ import ( "fmt" "go/constant" "go/token" + "io" "math/big" "os" "runtime" @@ -94,7 +95,7 @@ func NewPkgDecoder(pkgPath, input string) PkgDecoder { pr.elemEnds = make([]uint32, pr.elemEndsEnds[len(pr.elemEndsEnds)-1]) assert(binary.Read(r, binary.LittleEndian, pr.elemEnds[:]) == nil) - pos, err := r.Seek(0, os.SEEK_CUR) + pos, err := r.Seek(0, io.SeekCurrent) assert(err == nil) pr.elemData = input[pos:] @@ -237,7 +238,7 @@ func (r *Decoder) Sync(mWant SyncMarker) { return } - pos, _ := r.Data.Seek(0, os.SEEK_CUR) // TODO(mdempsky): io.SeekCurrent after #44505 is resolved + pos, _ := r.Data.Seek(0, io.SeekCurrent) mHave := SyncMarker(r.rawUvarint()) writerPCs := make([]int, r.rawUvarint()) for i := range writerPCs { diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go b/vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go index c50c838caa..e98e41171e 100644 --- a/vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go @@ -147,8 +147,9 @@ func (pw *PkgEncoder) NewEncoderRaw(k RelocKind) Encoder { type Encoder struct { p *PkgEncoder - Relocs []RelocEnt - Data bytes.Buffer // accumulated element bitstream data + Relocs []RelocEnt + RelocMap map[RelocEnt]uint32 + Data bytes.Buffer // accumulated element bitstream data encodingRelocHeader bool @@ -210,15 +211,18 @@ func (w *Encoder) rawVarint(x int64) { } func (w *Encoder) rawReloc(r RelocKind, idx Index) int { - // TODO(mdempsky): Use map for lookup; this takes quadratic time. - for i, rEnt := range w.Relocs { - if rEnt.Kind == r && rEnt.Idx == idx { - return i + e := RelocEnt{r, idx} + if w.RelocMap != nil { + if i, ok := w.RelocMap[e]; ok { + return int(i) } + } else { + w.RelocMap = make(map[RelocEnt]uint32) } i := len(w.Relocs) - w.Relocs = append(w.Relocs, RelocEnt{r, idx}) + w.RelocMap[e] = uint32(i) + w.Relocs = append(w.Relocs, e) return i } diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go b/vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go index 7a8f04ab3f..fcdfb97ca9 100644 --- a/vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go @@ -5,11 +5,11 @@ package pkgbits // A RelocKind indicates a particular section within a unified IR export. -type RelocKind int +type RelocKind int32 // An Index represents a bitstream element index within a particular // section. -type Index int +type Index int32 // A relocEnt (relocation entry) is an entry in an element's local // reference table. diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go index de881562de..d9a7915bab 100644 --- a/vendor/golang.org/x/tools/go/packages/golist.go +++ b/vendor/golang.org/x/tools/go/packages/golist.go @@ -60,6 +60,7 @@ func (r *responseDeduper) addAll(dr *driverResponse) { for _, root := range dr.Roots { r.addRoot(root) } + r.dr.GoVersion = dr.GoVersion } func (r *responseDeduper) addPackage(p *Package) { @@ -454,11 +455,14 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse if err != nil { return nil, err } + seen := make(map[string]*jsonPackage) pkgs := make(map[string]*Package) additionalErrors := make(map[string][]Error) // Decode the JSON and convert it to Package form. - var response driverResponse + response := &driverResponse{ + GoVersion: goVersion, + } for dec := json.NewDecoder(buf); dec.More(); { p := new(jsonPackage) if err := dec.Decode(p); err != nil { @@ -730,7 +734,7 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse } sort.Slice(response.Packages, func(i, j int) bool { return response.Packages[i].ID < response.Packages[j].ID }) - return &response, nil + return response, nil } func (state *golistState) shouldAddFilenameFromError(p *jsonPackage) bool { @@ -756,6 +760,7 @@ func (state *golistState) shouldAddFilenameFromError(p *jsonPackage) bool { return len(p.Error.ImportStack) == 0 || p.Error.ImportStack[len(p.Error.ImportStack)-1] == p.ImportPath } +// getGoVersion returns the effective minor version of the go command. func (state *golistState) getGoVersion() (int, error) { state.goVersionOnce.Do(func() { state.goVersion, state.goVersionError = gocommand.GoVersion(state.ctx, state.cfgInvocation(), state.cfg.gocmdRunner) diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go index a93dc6add4..54d880d206 100644 --- a/vendor/golang.org/x/tools/go/packages/packages.go +++ b/vendor/golang.org/x/tools/go/packages/packages.go @@ -19,6 +19,7 @@ import ( "log" "os" "path/filepath" + "runtime" "strings" "sync" "time" @@ -233,6 +234,11 @@ type driverResponse struct { // Imports will be connected and then type and syntax information added in a // later pass (see refine). Packages []*Package + + // GoVersion is the minor version number used by the driver + // (e.g. the go command on the PATH) when selecting .go files. + // Zero means unknown. + GoVersion int } // Load loads and returns the Go packages named by the given patterns. @@ -256,7 +262,7 @@ func Load(cfg *Config, patterns ...string) ([]*Package, error) { return nil, err } l.sizes = response.Sizes - return l.refine(response.Roots, response.Packages...) + return l.refine(response) } // defaultDriver is a driver that implements go/packages' fallback behavior. @@ -532,6 +538,7 @@ type loaderPackage struct { needsrc bool // load from source (Mode >= LoadTypes) needtypes bool // type information is either requested or depended on initial bool // package was matched by a pattern + goVersion int // minor version number of go command on PATH } // loader holds the working state of a single call to load. @@ -618,7 +625,8 @@ func newLoader(cfg *Config) *loader { // refine connects the supplied packages into a graph and then adds type and // and syntax information as requested by the LoadMode. -func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) { +func (ld *loader) refine(response *driverResponse) ([]*Package, error) { + roots := response.Roots rootMap := make(map[string]int, len(roots)) for i, root := range roots { rootMap[root] = i @@ -626,7 +634,7 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) { ld.pkgs = make(map[string]*loaderPackage) // first pass, fixup and build the map and roots var initial = make([]*loaderPackage, len(roots)) - for _, pkg := range list { + for _, pkg := range response.Packages { rootIndex := -1 if i, found := rootMap[pkg.ID]; found { rootIndex = i @@ -648,6 +656,7 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) { Package: pkg, needtypes: needtypes, needsrc: needsrc, + goVersion: response.GoVersion, } ld.pkgs[lpkg.ID] = lpkg if rootIndex >= 0 { @@ -923,6 +932,33 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) { lpkg.Errors = append(lpkg.Errors, errs...) } + // If the go command on the PATH is newer than the runtime, + // then the go/{scanner,ast,parser,types} packages from the + // standard library may be unable to process the files + // selected by go list. + // + // There is currently no way to downgrade the effective + // version of the go command (see issue 52078), so we proceed + // with the newer go command but, in case of parse or type + // errors, we emit an additional diagnostic. + // + // See: + // - golang.org/issue/52078 (flag to set release tags) + // - golang.org/issue/50825 (gopls legacy version support) + // - golang.org/issue/55883 (go/packages confusing error) + var runtimeVersion int + if _, err := fmt.Sscanf(runtime.Version(), "go1.%d", &runtimeVersion); err == nil && runtimeVersion < lpkg.goVersion { + defer func() { + if len(lpkg.Errors) > 0 { + appendError(Error{ + Pos: "-", + Msg: fmt.Sprintf("This application uses version go1.%d of the source-processing packages but runs version go1.%d of 'go list'. It may fail to process source files that rely on newer language features. If so, rebuild the application using a newer version of Go.", runtimeVersion, lpkg.goVersion), + Kind: UnknownError, + }) + } + }() + } + if ld.Config.Mode&NeedTypes != 0 && len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" { // The config requested loading sources and types, but sources are missing. // Add an error to the package and fall back to loading from export data. diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go index 67256dc397..d50551693f 100644 --- a/vendor/golang.org/x/tools/internal/gocommand/invoke.go +++ b/vendor/golang.org/x/tools/internal/gocommand/invoke.go @@ -10,8 +10,10 @@ import ( "context" "fmt" "io" + "log" "os" "regexp" + "runtime" "strconv" "strings" "sync" @@ -232,6 +234,12 @@ func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { return runCmdContext(ctx, cmd) } +// DebugHangingGoCommands may be set by tests to enable additional +// instrumentation (including panics) for debugging hanging Go commands. +// +// See golang/go#54461 for details. +var DebugHangingGoCommands = false + // runCmdContext is like exec.CommandContext except it sends os.Interrupt // before os.Kill. func runCmdContext(ctx context.Context, cmd *exec.Cmd) error { @@ -243,11 +251,24 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) error { resChan <- cmd.Wait() }() - select { - case err := <-resChan: - return err - case <-ctx.Done(): + // If we're interested in debugging hanging Go commands, stop waiting after a + // minute and panic with interesting information. + if DebugHangingGoCommands { + select { + case err := <-resChan: + return err + case <-time.After(1 * time.Minute): + HandleHangingGoCommand(cmd.Process) + case <-ctx.Done(): + } + } else { + select { + case err := <-resChan: + return err + case <-ctx.Done(): + } } + // Cancelled. Interrupt and see if it ends voluntarily. cmd.Process.Signal(os.Interrupt) select { @@ -255,11 +276,63 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) error { return err case <-time.After(time.Second): } + // Didn't shut down in response to interrupt. Kill it hard. - cmd.Process.Kill() + // TODO(rfindley): per advice from bcmills@, it may be better to send SIGQUIT + // on certain platforms, such as unix. + if err := cmd.Process.Kill(); err != nil && DebugHangingGoCommands { + // Don't panic here as this reliably fails on windows with EINVAL. + log.Printf("error killing the Go command: %v", err) + } + + // See above: don't wait indefinitely if we're debugging hanging Go commands. + if DebugHangingGoCommands { + select { + case err := <-resChan: + return err + case <-time.After(10 * time.Second): // a shorter wait as resChan should return quickly following Kill + HandleHangingGoCommand(cmd.Process) + } + } return <-resChan } +func HandleHangingGoCommand(proc *os.Process) { + switch runtime.GOOS { + case "linux", "darwin", "freebsd", "netbsd": + fmt.Fprintln(os.Stderr, `DETECTED A HANGING GO COMMAND + +The gopls test runner has detected a hanging go command. In order to debug +this, the output of ps and lsof/fstat is printed below. + +See golang/go#54461 for more details.`) + + fmt.Fprintln(os.Stderr, "\nps axo ppid,pid,command:") + fmt.Fprintln(os.Stderr, "-------------------------") + psCmd := exec.Command("ps", "axo", "ppid,pid,command") + psCmd.Stdout = os.Stderr + psCmd.Stderr = os.Stderr + if err := psCmd.Run(); err != nil { + panic(fmt.Sprintf("running ps: %v", err)) + } + + listFiles := "lsof" + if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" { + listFiles = "fstat" + } + + fmt.Fprintln(os.Stderr, "\n"+listFiles+":") + fmt.Fprintln(os.Stderr, "-----") + listFilesCmd := exec.Command(listFiles) + listFilesCmd.Stdout = os.Stderr + listFilesCmd.Stderr = os.Stderr + if err := listFilesCmd.Run(); err != nil { + panic(fmt.Sprintf("running %s: %v", listFiles, err)) + } + } + panic(fmt.Sprintf("detected hanging go command (pid %d): see golang/go#54461 for more details", proc.Pid)) +} + func cmdDebugStr(cmd *exec.Cmd) string { env := make(map[string]string) for _, kv := range cmd.Env { diff --git a/vendor/golang.org/x/tools/internal/gocommand/version.go b/vendor/golang.org/x/tools/internal/gocommand/version.go index 7130436802..8db5ceb9d5 100644 --- a/vendor/golang.org/x/tools/internal/gocommand/version.go +++ b/vendor/golang.org/x/tools/internal/gocommand/version.go @@ -10,8 +10,15 @@ import ( "strings" ) -// GoVersion checks the go version by running "go list" with modules off. -// It returns the X in Go 1.X. +// GoVersion reports the minor version number of the highest release +// tag built into the go command on the PATH. +// +// Note that this may be higher than the version of the go tool used +// to build this application, and thus the versions of the standard +// go/{scanner,parser,ast,types} packages that are linked into it. +// In that case, callers should either downgrade to the version of +// go used to build the application, or report an error that the +// application is too old to use the go command on the PATH. func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) { inv.Verb = "list" inv.Args = []string{"-e", "-f", `{{context.ReleaseTags}}`, `--`, `unsafe`} @@ -38,7 +45,7 @@ func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) { if len(stdout) < 3 { return 0, fmt.Errorf("bad ReleaseTags output: %q", stdout) } - // Split up "[go1.1 go1.15]" + // Split up "[go1.1 go1.15]" and return highest go1.X value. tags := strings.Fields(stdout[1 : len(stdout)-2]) for i := len(tags) - 1; i >= 0; i-- { var version int diff --git a/vendor/gopkg.in/yaml.v2/go.mod b/vendor/gopkg.in/yaml.v2/go.mod deleted file mode 100644 index 2cbb85aeac..0000000000 --- a/vendor/gopkg.in/yaml.v2/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module gopkg.in/yaml.v2 - -go 1.15 - -require gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 diff --git a/vendor/modules.txt b/vendor/modules.txt index e9e284efa3..e6ad212f27 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,36 +1,43 @@ -# github.com/cilium/ebpf v0.7.0 -## explicit +# github.com/cilium/ebpf v0.11.0 +## explicit; go 1.19 github.com/cilium/ebpf github.com/cilium/ebpf/asm +github.com/cilium/ebpf/btf github.com/cilium/ebpf/internal -github.com/cilium/ebpf/internal/btf +github.com/cilium/ebpf/internal/epoll +github.com/cilium/ebpf/internal/kconfig +github.com/cilium/ebpf/internal/sys +github.com/cilium/ebpf/internal/tracefs github.com/cilium/ebpf/internal/unix github.com/cilium/ebpf/link github.com/cilium/ebpf/ringbuf github.com/cilium/ebpf/rlimit # github.com/cosiner/argv v0.1.0 -## explicit +## explicit; go 1.13 github.com/cosiner/argv # github.com/cpuguy83/go-md2man/v2 v2.0.0 +## explicit; go 1.12 github.com/cpuguy83/go-md2man/v2/md2man # github.com/creack/pty v1.1.9 -## explicit +## explicit; go 1.13 github.com/creack/pty # github.com/derekparker/trie v0.0.0-20221213183930-4c74548207f4 -## explicit +## explicit; go 1.19 github.com/derekparker/trie # github.com/go-delve/liner v1.2.3-0.20220127212407-d32d89dd2a5d ## explicit github.com/go-delve/liner # github.com/google/go-dap v0.9.1 -## explicit +## explicit; go 1.13 github.com/google/go-dap # github.com/hashicorp/golang-lru v0.5.4 -## explicit +## explicit; go 1.12 github.com/hashicorp/golang-lru/simplelru # github.com/inconshreveable/mousetrap v1.0.0 +## explicit github.com/inconshreveable/mousetrap # github.com/konsorten/go-windows-terminal-sequences v1.0.3 +## explicit github.com/konsorten/go-windows-terminal-sequences # github.com/mattn/go-colorable v0.0.9 ## explicit @@ -39,28 +46,31 @@ github.com/mattn/go-colorable ## explicit github.com/mattn/go-isatty # github.com/mattn/go-runewidth v0.0.13 -## explicit +## explicit; go 1.9 github.com/mattn/go-runewidth # github.com/rivo/uniseg v0.2.0 +## explicit; go 1.12 github.com/rivo/uniseg # github.com/russross/blackfriday/v2 v2.0.1 +## explicit github.com/russross/blackfriday/v2 # github.com/shurcooL/sanitized_anchor_name v1.0.0 +## explicit github.com/shurcooL/sanitized_anchor_name # github.com/sirupsen/logrus v1.6.0 -## explicit +## explicit; go 1.13 github.com/sirupsen/logrus # github.com/spf13/cobra v1.1.3 -## explicit +## explicit; go 1.12 github.com/spf13/cobra github.com/spf13/cobra/doc # github.com/spf13/pflag v1.0.5 -## explicit +## explicit; go 1.12 github.com/spf13/pflag # github.com/stretchr/testify v1.7.0 -## explicit +## explicit; go 1.13 # go.starlark.net v0.0.0-20220816155156-cfacd8902214 -## explicit +## explicit; go 1.13 go.starlark.net/internal/compile go.starlark.net/internal/spell go.starlark.net/lib/time @@ -69,20 +79,26 @@ go.starlark.net/starlark go.starlark.net/starlarkstruct go.starlark.net/syntax # golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4 -## explicit +## explicit; go 1.11 golang.org/x/arch/arm64/arm64asm golang.org/x/arch/ppc64/ppc64asm golang.org/x/arch/x86/x86asm -# golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 +# golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 +## explicit; go 1.18 +golang.org/x/exp/constraints +golang.org/x/exp/maps +golang.org/x/exp/slices +# golang.org/x/mod v0.6.0 +## explicit; go 1.17 golang.org/x/mod/semver -# golang.org/x/sys v0.0.0-20220908164124-27713097b956 -## explicit +# golang.org/x/sys v0.6.0 +## explicit; go 1.17 golang.org/x/sys/execabs golang.org/x/sys/internal/unsafeheader golang.org/x/sys/unix golang.org/x/sys/windows -# golang.org/x/tools v0.1.12 -## explicit +# golang.org/x/tools v0.2.0 +## explicit; go 1.18 golang.org/x/tools/go/gcexportdata golang.org/x/tools/go/internal/gcimporter golang.org/x/tools/go/internal/packagesdriver @@ -97,5 +113,5 @@ golang.org/x/tools/internal/packagesinternal golang.org/x/tools/internal/typeparams golang.org/x/tools/internal/typesinternal # gopkg.in/yaml.v2 v2.4.0 -## explicit +## explicit; go 1.15 gopkg.in/yaml.v2 From 86020cdd7a8204a0e900ebc14c8353f60159fdd0 Mon Sep 17 00:00:00 2001 From: Archana Ravindar Date: Thu, 14 Sep 2023 22:38:29 +0530 Subject: [PATCH 114/114] pkg/proc: Fix PIE tests on ppc64le port (#3498) * Fix PIE tests on ppc64le port * formatted ppc64le_disasm.go as part of fixing PIE tests for ppc64le port --- Documentation/backend_test_health.md | 2 -- pkg/proc/ppc64le_disasm.go | 10 ++++++++- pkg/proc/proc_test.go | 33 ++++++++++++++-------------- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/Documentation/backend_test_health.md b/Documentation/backend_test_health.md index e93bbce121..aa7cae7b46 100644 --- a/Documentation/backend_test_health.md +++ b/Documentation/backend_test_health.md @@ -20,8 +20,6 @@ Tests skipped by each supported backend: * 1 broken - cgo stacktraces * linux/ppc64le/native skipped = 1 * 1 broken in linux ppc64le -* linux/ppc64le/native/pie skipped = 11 - * 11 broken - pie mode * pie skipped = 2 * 2 upstream issue - https://github.com/golang/go/issues/29322 * ppc64le skipped = 11 diff --git a/pkg/proc/ppc64le_disasm.go b/pkg/proc/ppc64le_disasm.go index c3f9a72e3a..75b3add779 100644 --- a/pkg/proc/ppc64le_disasm.go +++ b/pkg/proc/ppc64le_disasm.go @@ -17,17 +17,25 @@ func init() { var tinyStacksplit = opcodeSeq{uint64(ppc64asm.ADDI), uint64(ppc64asm.CMPLD), uint64(ppc64asm.BC)} var smallStacksplit = opcodeSeq{uint64(ppc64asm.ADDI), uint64(ppc64asm.CMPLD), uint64(ppc64asm.BC)} var bigStacksplit = opcodeSeq{uint64(ppc64asm.ADDI), uint64(ppc64asm.CMPLD), uint64(ppc64asm.BC), uint64(ppc64asm.STD), uint64(ppc64asm.STD), uint64(ppc64asm.MFSPR)} + var adjustTOCPrologueOnPIE = opcodeSeq{uint64(ppc64asm.ADDIS), uint64(ppc64asm.ADDI)} var unixGetG = opcodeSeq{uint64(ppc64asm.LD)} + var prologue opcodeSeq prologuesPPC64LE = make([]opcodeSeq, 0, 3) + prologue = make(opcodeSeq, 0, 1) for _, getG := range []opcodeSeq{unixGetG} { for _, stacksplit := range []opcodeSeq{tinyStacksplit, smallStacksplit, bigStacksplit} { - prologue := make(opcodeSeq, 0, len(getG)+len(stacksplit)) prologue = append(prologue, getG...) prologue = append(prologue, stacksplit...) prologuesPPC64LE = append(prologuesPPC64LE, prologue) } } + // On PIE mode special prologue is generated two instructions before the function entry point that correlates to call target + // address, Teach delve to recognize this sequence to appropriately adjust PC address so that the breakpoint is actually hit + // while doing step + TOCprologue := make(opcodeSeq, 0, len(adjustTOCPrologueOnPIE)) + TOCprologue = append(TOCprologue, adjustTOCPrologueOnPIE...) + prologuesPPC64LE = append(prologuesPPC64LE, TOCprologue) } func ppc64leAsmDecode(asmInst *AsmInstruction, mem []byte, regs *op.DwarfRegisters, memrw MemoryReadWriter, bi *BinaryInfo) error { diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 8e4010624e..6de1ba1b60 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -905,7 +905,6 @@ func (l1 *loc) match(l2 proc.Stackframe) bool { } func TestStacktrace(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") stacks := [][]loc{ {{4, "main.stacktraceme"}, {8, "main.func1"}, {16, "main.main"}}, {{4, "main.stacktraceme"}, {8, "main.func1"}, {12, "main.func2"}, {17, "main.main"}}, @@ -990,7 +989,6 @@ func stackMatch(stack []loc, locations []proc.Stackframe, skipRuntime bool) bool func TestStacktraceGoroutine(t *testing.T) { skipOn(t, "broken - cgo stacktraces", "darwin", "arm64") - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") mainStack := []loc{{14, "main.stacktraceme"}, {29, "main.main"}} if goversion.VersionAfterOrEqual(runtime.Version(), 1, 11) { @@ -1315,7 +1313,6 @@ func TestVariableEvaluation(t *testing.T) { } func TestFrameEvaluation(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") protest.AllowRecording(t) lenient := false if runtime.GOOS == "windows" { @@ -2308,7 +2305,6 @@ func TestNextDeferReturnAndDirectCall(t *testing.T) { } func TestNextPanicAndDirectCall(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Next should not step into a deferred function if it is called // directly, only if it is called through a panic or a deferreturn. // Here we test the case where the function is called by a panic @@ -2326,7 +2322,6 @@ func TestStepCall(t *testing.T) { } func TestStepCallPtr(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that Step works correctly when calling functions with a // function pointer. if goversion.VersionAfterOrEqual(runtime.Version(), 1, 11) && !protest.RegabiSupported() { @@ -2336,17 +2331,26 @@ func TestStepCallPtr(t *testing.T) { {6, 7}, {7, 11}}, "", t) } else { - testseq("teststepprog", contStep, []nextTest{ - {9, 10}, - {10, 5}, - {5, 6}, - {6, 7}, - {7, 11}}, "", t) + if runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le" && buildMode == "pie" { + testseq("teststepprog", contStep, []nextTest{ + {9, 10}, + {10, 5}, + {5, 6}, + {6, 7}, + {7, 10}, + {10, 11}}, "", t) + } else { + testseq("teststepprog", contStep, []nextTest{ + {9, 10}, + {10, 5}, + {5, 6}, + {6, 7}, + {7, 11}}, "", t) + } } } func TestStepReturnAndPanic(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that Step works correctly when returning from functions // and when a deferred function is called when panic'ing. testseq("defercall", contStep, []nextTest{ @@ -2358,7 +2362,6 @@ func TestStepReturnAndPanic(t *testing.T) { } func TestStepDeferReturn(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that Step works correctly when a deferred function is // called during a return. testseq("defercall", contStep, []nextTest{ @@ -2373,7 +2376,6 @@ func TestStepDeferReturn(t *testing.T) { } func TestStepIgnorePrivateRuntime(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that Step will ignore calls to private runtime functions // (such as runtime.convT2E in this case) switch { @@ -2752,7 +2754,6 @@ func TestIssue594(t *testing.T) { } func TestStepOutPanicAndDirectCall(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // StepOut should not step into a deferred function if it is called // directly, only if it is called through a panic. // Here we test the case where the function is called by a panic @@ -5569,7 +5570,6 @@ func TestManualStopWhileStopped(t *testing.T) { } func TestDwrapStartLocation(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that the start location of a goroutine is unwrapped in Go 1.17 and later. withTestProcess("goroutinestackprog", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { setFunctionBreakpoint(p, t, "main.stacktraceme") @@ -6071,7 +6071,6 @@ func TestEscapeCheckUnreadable(t *testing.T) { } func TestStepShadowConcurrentBreakpoint(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Checks that a StepBreakpoint can not shadow a concurrently hit user breakpoint withTestProcess("stepshadow", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { break2 := setFunctionBreakpoint(p, t, "main.stacktraceme2")

%s3Y=hU?((a63EzkHAy$0=yb; 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 Date: Mon, 24 Apr 2023 22:38:19 +0200 Subject: [PATCH 012/114] debugger: do not panic if defer location can not be found (#3329) convertDefers should not try to dereference nil if the deferred location does not belong to a function. --- service/debugger/debugger.go | 37 ++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index c58eeb2b91..50ac850660 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -1849,25 +1849,30 @@ func (d *Debugger) convertDefers(defers []*proc.Defer) []api.Defer { ddf, ddl, ddfn := defers[i].DeferredFunc(d.target.Selected) drf, drl, drfn := d.target.Selected.BinInfo().PCToLine(defers[i].DeferPC) - r[i] = api.Defer{ - DeferredLoc: api.ConvertLocation(proc.Location{ - PC: ddfn.Entry, - File: ddf, - Line: ddl, - Fn: ddfn, - }), - DeferLoc: api.ConvertLocation(proc.Location{ - PC: defers[i].DeferPC, - File: drf, - Line: drl, - Fn: drfn, - }), - SP: defers[i].SP, - } - if defers[i].Unreadable != nil { r[i].Unreadable = defers[i].Unreadable.Error() + } else { + var entry uint64 = defers[i].DeferPC + if ddfn != nil { + entry = ddfn.Entry + } + r[i] = api.Defer{ + DeferredLoc: api.ConvertLocation(proc.Location{ + PC: entry, + File: ddf, + Line: ddl, + Fn: ddfn, + }), + DeferLoc: api.ConvertLocation(proc.Location{ + PC: defers[i].DeferPC, + File: drf, + Line: drl, + Fn: drfn, + }), + SP: defers[i].SP, + } } + } return r From 47481fe0ab7b58ee79a7db98d12c2ddd8dd3ca0c Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 24 Apr 2023 23:33:38 +0200 Subject: [PATCH 013/114] proc/native: support core dumping on FreeBSD (#3305) Co-authored-by: a --- pkg/proc/native/dump_freebsd.go | 48 +++++++++++++++++++++++++++++++++ pkg/proc/native/dump_other.go | 4 +-- pkg/proc/native/proc.go | 2 +- pkg/proc/proc_test.go | 2 +- 4 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 pkg/proc/native/dump_freebsd.go diff --git a/pkg/proc/native/dump_freebsd.go b/pkg/proc/native/dump_freebsd.go new file mode 100644 index 0000000000..c4e1a97623 --- /dev/null +++ b/pkg/proc/native/dump_freebsd.go @@ -0,0 +1,48 @@ +package native + +import ( + "errors" + "unsafe" + + "github.com/go-delve/delve/pkg/elfwriter" + "github.com/go-delve/delve/pkg/proc" +) + +/* +#include +#include +#include +#include +*/ +import "C" + +func (p *nativeProcess) MemoryMap() ([]proc.MemoryMapEntry, error) { + var cnt C.int + vmentries := C.kinfo_getvmmap(C.int(p.pid), &cnt) + if vmentries == nil { + return nil, errors.New("kinfo_getvmmap call failed") + } + defer C.free(unsafe.Pointer(vmentries)) + r := make([]proc.MemoryMapEntry, 0, int(cnt)) + base := uintptr(unsafe.Pointer(vmentries)) + sz := unsafe.Sizeof(C.struct_kinfo_vmentry{}) + for i := 0; i < int(cnt); i++ { + vmentry := (*C.struct_kinfo_vmentry)(unsafe.Pointer(base + sz*uintptr(i))) + switch vmentry.kve_type { + case C.KVME_TYPE_DEFAULT, C.KVME_TYPE_VNODE, C.KVME_TYPE_SWAP, C.KVME_TYPE_PHYS: + r = append(r, proc.MemoryMapEntry{ + Addr: uint64(vmentry.kve_start), + Size: uint64(vmentry.kve_end - vmentry.kve_start), + + Read: vmentry.kve_protection&C.KVME_PROT_READ != 0, + Write: vmentry.kve_protection&C.KVME_PROT_WRITE != 0, + Exec: vmentry.kve_protection&C.KVME_PROT_EXEC != 0, + }) + } + } + return r, nil +} + +func (p *nativeProcess) DumpProcessNotes(notes []elfwriter.Note, threadDone func()) (threadsDone bool, notesout []elfwriter.Note, err error) { + return false, notes, nil +} diff --git a/pkg/proc/native/dump_other.go b/pkg/proc/native/dump_other.go index e4ebf44217..9422ff296a 100644 --- a/pkg/proc/native/dump_other.go +++ b/pkg/proc/native/dump_other.go @@ -1,5 +1,5 @@ -//go:build (freebsd && amd64) || darwin || (windows && arm64) -// +build freebsd,amd64 darwin windows,arm64 +//go:build darwin || (windows && arm64) +// +build darwin windows,arm64 package native diff --git a/pkg/proc/native/proc.go b/pkg/proc/native/proc.go index c3d6c86433..69423f29dc 100644 --- a/pkg/proc/native/proc.go +++ b/pkg/proc/native/proc.go @@ -318,7 +318,7 @@ func (dbp *nativeProcess) initialize(path string, debugInfoDirs []string) (*proc DisableAsyncPreempt: runtime.GOOS == "windows" || (runtime.GOOS == "linux" && runtime.GOARCH == "arm64"), StopReason: stopReason, - CanDump: runtime.GOOS == "linux" || (runtime.GOOS == "windows" && runtime.GOARCH == "amd64"), + CanDump: runtime.GOOS == "linux" || runtime.GOOS == "freebsd" || (runtime.GOOS == "windows" && runtime.GOARCH == "amd64"), }) procgrp.addTarget = addTarget tgt, err := procgrp.add(dbp, dbp.pid, dbp.memthread, path, stopReason) diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 34dec276ae..bcb53bd901 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -5163,7 +5163,7 @@ func TestIssue2319(t *testing.T) { } func TestDump(t *testing.T) { - if runtime.GOOS == "freebsd" || (runtime.GOOS == "darwin" && testBackend == "native") || (runtime.GOOS == "windows" && runtime.GOARCH != "amd64") { + if (runtime.GOOS == "darwin" && testBackend == "native") || (runtime.GOOS == "windows" && runtime.GOARCH != "amd64") { t.Skip("not supported") } From a61ccea65a14a1640e04847e6ce11fbc8b7a0178 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 24 Apr 2023 23:37:31 +0200 Subject: [PATCH 014/114] service/debugger,terminal: API and user interface for follow exec mode (#3286) Updates #2551 --- Documentation/cli/README.md | 17 +++++ Documentation/cli/starlark.md | 3 + pkg/proc/target_group.go | 5 ++ pkg/terminal/command.go | 88 ++++++++++++++++++++++- pkg/terminal/starbind/starlark_mapping.go | 62 ++++++++++++++++ pkg/terminal/terminal.go | 4 ++ service/api/conversions.go | 11 +++ service/api/types.go | 7 ++ service/client.go | 8 +++ service/debugger/debugger.go | 21 ++++++ service/rpc2/client.go | 24 +++++++ service/rpc2/server.go | 46 ++++++++++++ 12 files changed, 295 insertions(+), 1 deletion(-) diff --git a/Documentation/cli/README.md b/Documentation/cli/README.md index ec14bea199..11b25c5c82 100644 --- a/Documentation/cli/README.md +++ b/Documentation/cli/README.md @@ -91,6 +91,7 @@ Command | Description [list](#list) | Show source code. [source](#source) | Executes a file containing a list of delve commands [sources](#sources) | Print list of source files. +[target](#target) | Manages child process debugging. [transcript](#transcript) | Appends command output to a file. [types](#types) | Print list of types @@ -623,6 +624,22 @@ Step out of the current function. Aliases: so +## target +Manages child process debugging. + + target follow-exec [-on [regex]] [-off] + +Enables or disables follow exec mode. When follow exec mode Delve will automatically attach to new child processes executed by the target process. An optional regular expression can be passed to 'target follow-exec', only child processes with a command line matching the regular expression will be followed. + + target list + +List currently attached processes. + + target switch [pid] + +Switches to the specified process. + + ## thread Switch to the specified thread. diff --git a/Documentation/cli/starlark.md b/Documentation/cli/starlark.md index 4f79900217..8bc593ea62 100644 --- a/Documentation/cli/starlark.md +++ b/Documentation/cli/starlark.md @@ -37,6 +37,8 @@ dump_wait(Wait) | Equivalent to API call [DumpWait](https://godoc.org/github.com eval(Scope, Expr, Cfg) | Equivalent to API call [Eval](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.Eval) examine_memory(Address, Length) | Equivalent to API call [ExamineMemory](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ExamineMemory) find_location(Scope, Loc, IncludeNonExecutableLines, SubstitutePathRules) | Equivalent to API call [FindLocation](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.FindLocation) +follow_exec(Enable, Regex) | Equivalent to API call [FollowExec](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.FollowExec) +follow_exec_enabled() | Equivalent to API call [FollowExecEnabled](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.FollowExecEnabled) function_return_locations(FnName) | Equivalent to API call [FunctionReturnLocations](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.FunctionReturnLocations) get_breakpoint(Id, Name) | Equivalent to API call [GetBreakpoint](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.GetBreakpoint) get_buffered_tracepoints() | Equivalent to API call [GetBufferedTracepoints](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.GetBufferedTracepoints) @@ -54,6 +56,7 @@ package_vars(Filter, Cfg) | Equivalent to API call [ListPackageVars](https://god packages_build_info(IncludeFiles) | Equivalent to API call [ListPackagesBuildInfo](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ListPackagesBuildInfo) registers(ThreadID, IncludeFp, Scope) | Equivalent to API call [ListRegisters](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ListRegisters) sources(Filter) | Equivalent to API call [ListSources](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ListSources) +targets() | Equivalent to API call [ListTargets](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ListTargets) threads() | Equivalent to API call [ListThreads](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ListThreads) types(Filter) | Equivalent to API call [ListTypes](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ListTypes) process_pid() | Equivalent to API call [ProcessPid](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.ProcessPid) diff --git a/pkg/proc/target_group.go b/pkg/proc/target_group.go index 66ed9e735c..5a746399e1 100644 --- a/pkg/proc/target_group.go +++ b/pkg/proc/target_group.go @@ -354,6 +354,11 @@ func (grp *TargetGroup) FollowExec(v bool, regex string) error { return nil } +// FollowExecEnabled returns true if follow exec is enabled +func (grp *TargetGroup) FollowExecEnabled() bool { + return grp.followExecEnabled +} + // ValidTargets iterates through all valid targets in Group. type ValidTargets struct { *Target diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index 5d92d9f9f3..68a6064e5d 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -559,6 +559,20 @@ The core dump is always written in ELF, even on systems (windows, macOS) where t Output of Delve's command is appended to the specified output file. If '-t' is specified and the output file exists it is truncated. If '-x' is specified output to stdout is suppressed instead. Using the -off option disables the transcript.`}, + + {aliases: []string{"target"}, cmdFn: target, helpMsg: `Manages child process debugging. + + target follow-exec [-on [regex]] [-off] + +Enables or disables follow exec mode. When follow exec mode Delve will automatically attach to new child processes executed by the target process. An optional regular expression can be passed to 'target follow-exec', only child processes with a command line matching the regular expression will be followed. + + target list + +List currently attached processes. + + target switch [pid] + +Switches to the specified process.`}, } addrecorded := client == nil @@ -1212,6 +1226,7 @@ func parseOptionalCount(arg string) (int64, error) { } func restartLive(t *Term, ctx callContext, args string) error { + t.oldPid = 0 resetArgs, newArgv, newRedirects, err := parseNewArgv(args) if err != nil { return err @@ -2522,6 +2537,12 @@ func printcontext(t *Term, state *api.DebuggerState) { return } + if state.Pid != t.oldPid { + if t.oldPid != 0 { + fmt.Fprintf(t.stdout, "Switch target process from %d to %d\n", t.oldPid, state.Pid) + } + t.oldPid = state.Pid + } for i := range state.Threads { if (state.CurrentThread != nil) && (state.Threads[i].ID == state.CurrentThread.ID) { continue @@ -3177,6 +3198,71 @@ func transcript(t *Term, ctx callContext, args string) error { return nil } +func target(t *Term, ctx callContext, args string) error { + argv := config.Split2PartsBySpace(args) + switch argv[0] { + case "list": + tgts, err := t.client.ListTargets() + if err != nil { + return err + } + w := new(tabwriter.Writer) + w.Init(t.stdout, 4, 4, 2, ' ', 0) + for _, tgt := range tgts { + selected := "" + if tgt.Pid == t.oldPid { + selected = "*" + } + fmt.Fprintf(w, "%s\t%d\t%s\n", selected, tgt.Pid, tgt.CmdLine) + } + w.Flush() + return nil + case "follow-exec": + if len(argv) == 1 { + return errors.New("not enough arguments") + } + argv = config.Split2PartsBySpace(argv[1]) + switch argv[0] { + case "-on": + var regex string + if len(argv) == 2 { + regex = argv[1] + } + t.client.FollowExec(true, regex) + case "-off": + if len(argv) > 1 { + return errors.New("too many arguments") + } + t.client.FollowExec(false, "") + default: + return fmt.Errorf("unknown argument %q to 'target follow-exec'", argv[0]) + } + return nil + case "switch": + tgts, err := t.client.ListTargets() + if err != nil { + return err + } + pid, err := strconv.Atoi(argv[1]) + if err != nil { + return err + } + found := false + for _, tgt := range tgts { + if tgt.Pid == pid { + found = true + t.client.SwitchThread(tgt.CurrentThread.ID) + } + } + if !found { + return fmt.Errorf("could not find target %d", pid) + } + return nil + default: + return fmt.Errorf("unknown command 'target %s'", argv[0]) + } +} + func formatBreakpointName(bp *api.Breakpoint, upcase bool) string { thing := "breakpoint" if bp.Tracepoint { @@ -3226,5 +3312,5 @@ func (t *Term) formatBreakpointLocation(bp *api.Breakpoint) string { func shouldAskToSuspendBreakpoint(t *Term) bool { fns, _ := t.client.ListFunctions(`^plugin\.Open$`) _, err := t.client.GetState() - return len(fns) > 0 || isErrProcessExited(err) + return len(fns) > 0 || isErrProcessExited(err) || t.client.FollowExecEnabled() } diff --git a/pkg/terminal/starbind/starlark_mapping.go b/pkg/terminal/starbind/starlark_mapping.go index ae892b348e..06ac94c35e 100644 --- a/pkg/terminal/starbind/starlark_mapping.go +++ b/pkg/terminal/starbind/starlark_mapping.go @@ -730,6 +730,56 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + r["follow_exec"] = starlark.NewBuiltin("follow_exec", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + if err := isCancelled(thread); err != nil { + return starlark.None, decorateError(thread, err) + } + var rpcArgs rpc2.FollowExecIn + var rpcRet rpc2.FollowExecOut + if len(args) > 0 && args[0] != starlark.None { + err := unmarshalStarlarkValue(args[0], &rpcArgs.Enable, "Enable") + if err != nil { + return starlark.None, decorateError(thread, err) + } + } + if len(args) > 1 && args[1] != starlark.None { + err := unmarshalStarlarkValue(args[1], &rpcArgs.Regex, "Regex") + if err != nil { + return starlark.None, decorateError(thread, err) + } + } + for _, kv := range kwargs { + var err error + switch kv[0].(starlark.String) { + case "Enable": + err = unmarshalStarlarkValue(kv[1], &rpcArgs.Enable, "Enable") + case "Regex": + err = unmarshalStarlarkValue(kv[1], &rpcArgs.Regex, "Regex") + default: + err = fmt.Errorf("unknown argument %q", kv[0]) + } + if err != nil { + return starlark.None, decorateError(thread, err) + } + } + err := env.ctx.Client().CallAPI("FollowExec", &rpcArgs, &rpcRet) + if err != nil { + return starlark.None, err + } + return env.interfaceToStarlarkValue(rpcRet), nil + }) + r["follow_exec_enabled"] = starlark.NewBuiltin("follow_exec_enabled", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + if err := isCancelled(thread); err != nil { + return starlark.None, decorateError(thread, err) + } + var rpcArgs rpc2.FollowExecEnabledIn + var rpcRet rpc2.FollowExecEnabledOut + err := env.ctx.Client().CallAPI("FollowExecEnabled", &rpcArgs, &rpcRet) + if err != nil { + return starlark.None, err + } + return env.interfaceToStarlarkValue(rpcRet), nil + }) r["function_return_locations"] = starlark.NewBuiltin("function_return_locations", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -1235,6 +1285,18 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + r["targets"] = starlark.NewBuiltin("targets", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + if err := isCancelled(thread); err != nil { + return starlark.None, decorateError(thread, err) + } + var rpcArgs rpc2.ListTargetsIn + var rpcRet rpc2.ListTargetsOut + err := env.ctx.Client().CallAPI("ListTargets", &rpcArgs, &rpcRet) + if err != nil { + return starlark.None, err + } + return env.interfaceToStarlarkValue(rpcRet), nil + }) r["threads"] = starlark.NewBuiltin("threads", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) diff --git a/pkg/terminal/terminal.go b/pkg/terminal/terminal.go index 4b62625ed3..b9a4bfd2d5 100644 --- a/pkg/terminal/terminal.go +++ b/pkg/terminal/terminal.go @@ -58,6 +58,7 @@ type Term struct { stdout *transcriptWriter InitFile string displays []displayEntry + oldPid int historyFile *os.File @@ -115,6 +116,9 @@ func New(client service.Client, conf *config.Config) *Term { if client != nil { lcfg := t.loadConfig() client.SetReturnValuesLoadConfig(&lcfg) + if state, err := client.GetState(); err == nil { + t.oldPid = state.Pid + } } t.starlarkEnv = starbind.New(starlarkContext{t}, t.stdout) diff --git a/service/api/conversions.go b/service/api/conversions.go index 9c66fac474..4361cda8e6 100644 --- a/service/api/conversions.go +++ b/service/api/conversions.go @@ -429,10 +429,12 @@ func ConvertRegisters(in *op.DwarfRegisters, dwarfRegisterToString func(int, *op return } +// ConvertImage convers proc.Image to api.Image. func ConvertImage(image *proc.Image) Image { return Image{Path: image.Path, Address: image.StaticBase} } +// ConvertDumpState converts proc.DumpState to api.DumpState. func ConvertDumpState(dumpState *proc.DumpState) *DumpState { dumpState.Mutex.Lock() defer dumpState.Mutex.Unlock() @@ -449,3 +451,12 @@ func ConvertDumpState(dumpState *proc.DumpState) *DumpState { } return r } + +// ConvertTarget converts a proc.Target into a api.Target. +func ConvertTarget(tgt *proc.Target, convertThreadBreakpoint func(proc.Thread) *Breakpoint) *Target { + //TODO(aarzilli): copy command line here + return &Target{ + Pid: tgt.Pid(), + CurrentThread: ConvertThread(tgt.CurrentThread(), convertThreadBreakpoint(tgt.CurrentThread())), + } +} diff --git a/service/api/types.go b/service/api/types.go index 2e980ef91a..a2ddc752c2 100644 --- a/service/api/types.go +++ b/service/api/types.go @@ -655,3 +655,10 @@ type GoroutineGroupingOptions struct { MaxGroupMembers int MaxGroups int } + +// Target represents a debugging target. +type Target struct { + Pid int + CmdLine string + CurrentThread *Thread +} diff --git a/service/client.go b/service/client.go index 4e066511b0..32cf515464 100644 --- a/service/client.go +++ b/service/client.go @@ -185,6 +185,14 @@ type Client interface { // CoreDumpCancel cancels a core dump in progress CoreDumpCancel() error + // ListTargets returns the list of connected targets + ListTargets() ([]api.Target, error) + // FollowExec enables or disables the follow exec mode. In follow exec mode + // Delve will automatically debug child processes launched by the target + // process + FollowExec(bool, string) error + FollowExecEnabled() bool + // Disconnect closes the connection to the server without sending a Detach request first. // If cont is true a continue command will be sent instead. Disconnect(cont bool) error diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index 50ac850660..320adf1b5a 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -1264,6 +1264,13 @@ func (d *Debugger) Command(command *api.DebuggerCommand, resumeNotify chan struc err = d.target.StepOut() case api.SwitchThread: d.log.Debugf("switching to thread %d", command.ThreadID) + t := proc.ValidTargets{Group: d.target} + for t.Next() { + if _, ok := t.FindThread(command.ThreadID); ok { + d.target.Selected = t.Target + break + } + } err = d.target.Selected.SwitchThread(command.ThreadID) withBreakpointInfo = false case api.SwitchGoroutine: @@ -2252,6 +2259,20 @@ func (d *Debugger) GetBufferedTracepoints() []api.TracepointResult { return results } +// FollowExec enabled or disables follow exec mode. +func (d *Debugger) FollowExec(enabled bool, regex string) error { + d.targetMutex.Lock() + defer d.targetMutex.Unlock() + return d.target.FollowExec(enabled, regex) +} + +// FollowExecEnabled returns true if follow exec mode is enabled. +func (d *Debugger) FollowExecEnabled() bool { + d.targetMutex.Lock() + defer d.targetMutex.Unlock() + return d.target.FollowExecEnabled() +} + func go11DecodeErrorCheck(err error) error { if _, isdecodeerr := err.(dwarf.DecodeError); !isdecodeerr { return err diff --git a/service/rpc2/client.go b/service/rpc2/client.go index 56438ff019..74aa5f4de7 100644 --- a/service/rpc2/client.go +++ b/service/rpc2/client.go @@ -530,6 +530,30 @@ func (c *RPCClient) CoreDumpCancel() error { return c.call("DumpCancel", DumpCancelIn{}, out) } +// ListTargets returns the current list of debug targets. +func (c *RPCClient) ListTargets() ([]api.Target, error) { + out := &ListTargetsOut{} + err := c.call("ListTargets", ListTargetsIn{}, out) + return out.Targets, err +} + +// FollowExec enabled or disabled follow exec mode. When follow exec is +// enabled Delve will automatically attach to new subprocesses with a +// command line matched by regex, if regex is nil all new subprocesses are +// automatically debugged. +func (c *RPCClient) FollowExec(v bool, regex string) error { + out := &FollowExecOut{} + err := c.call("FollowExec", FollowExecIn{Enable: v, Regex: regex}, out) + return err +} + +// FollowExecEnabled returns true if follow exex mode is enabled. +func (c *RPCClient) FollowExecEnabled() bool { + out := &FollowExecEnabledOut{} + _ = c.call("FollowExecEnabled", FollowExecEnabledIn{}, out) + return out.Enabled +} + func (c *RPCClient) call(method string, args, reply interface{}) error { return c.client.Call("RPCServer."+method, args, reply) } diff --git a/service/rpc2/server.go b/service/rpc2/server.go index 4f07607191..b8ee0f69a1 100644 --- a/service/rpc2/server.go +++ b/service/rpc2/server.go @@ -1033,3 +1033,49 @@ func (s *RPCServer) BuildID(arg BuildIDIn, out *BuildIDOut) error { out.BuildID = s.debugger.BuildID() return nil } + +type ListTargetsIn struct { +} + +type ListTargetsOut struct { + Targets []api.Target +} + +// ListTargets returns the list of targets we are currently attached to. +func (s *RPCServer) ListTargets(arg ListTargetsIn, out *ListTargetsOut) error { + s.debugger.LockTarget() + defer s.debugger.UnlockTarget() + out.Targets = []api.Target{} + for _, tgt := range s.debugger.TargetGroup().Targets() { + if _, err := tgt.Valid(); err == nil { + out.Targets = append(out.Targets, *api.ConvertTarget(tgt, s.debugger.ConvertThreadBreakpoint)) + } + } + return nil +} + +type FollowExecIn struct { + Enable bool + Regex string +} + +type FollowExecOut struct { +} + +// FollowExec enables or disables follow exec mode. +func (s *RPCServer) FollowExec(arg FollowExecIn, out *FollowExecOut) error { + return s.debugger.FollowExec(arg.Enable, arg.Regex) +} + +type FollowExecEnabledIn struct { +} + +type FollowExecEnabledOut struct { + Enabled bool +} + +// FollowExecEnabled returns true if follow exec mode is enabled. +func (s *RPCServer) FollowExecEnabled(arg FollowExecEnabledIn, out *FollowExecEnabledOut) error { + out.Enabled = s.debugger.FollowExecEnabled() + return nil +} From e24a7b11740a99c70f45f6b0b87730ab9eb5260c Mon Sep 17 00:00:00 2001 From: cui fliter Date: Tue, 25 Apr 2023 15:54:49 +0800 Subject: [PATCH 015/114] fix some comments Signed-off-by: cui fliter --- pkg/proc/threads.go | 3 ++- pkg/proc/variables.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/proc/threads.go b/pkg/proc/threads.go index e078966b24..8b55e4c7a8 100644 --- a/pkg/proc/threads.go +++ b/pkg/proc/threads.go @@ -2,6 +2,7 @@ package proc import ( "errors" + "github.com/go-delve/delve/pkg/dwarf/op" ) @@ -17,7 +18,7 @@ type Thread interface { // variable returned may or may not change to reflect the new CPU status // when the thread is resumed or the registers are changed by calling // SetPC/SetSP/etc. - // To insure that the the returned variable won't change call the Copy + // To insure that the returned variable won't change call the Copy // method of Registers. Registers() (Registers, error) diff --git a/pkg/proc/variables.go b/pkg/proc/variables.go index a41dac86af..e77515ff90 100644 --- a/pkg/proc/variables.go +++ b/pkg/proc/variables.go @@ -1839,7 +1839,7 @@ func (v *Variable) writeZero() error { return err } -// writeInterface writes the empty interface of type typeAddr and data as the data field. +// writeEmptyInterface writes the empty interface of type typeAddr and data as the data field. func (v *Variable) writeEmptyInterface(typeAddr uint64, data *Variable) error { dstType, dstData, _ := v.readInterface() if v.Unreadable != nil { From 5a159c2ef22084b291cb7f2cb270b8a529afb08a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lex=20S=C3=A1ez?= Date: Tue, 25 Apr 2023 12:51:59 +0200 Subject: [PATCH 016/114] Add additional information to how to filter goroutines --- Documentation/cli/README.md | 16 +++++++++++++++- pkg/terminal/command.go | 16 +++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Documentation/cli/README.md b/Documentation/cli/README.md index 11b25c5c82..257a034063 100644 --- a/Documentation/cli/README.md +++ b/Documentation/cli/README.md @@ -399,9 +399,14 @@ To only display goroutines where the specified location contains (or does not co goroutines -w (userloc|curloc|goloc|startloc) expr goroutines -without (userloc|curloc|goloc|startloc) expr goroutines -wo (userloc|curloc|goloc|startloc) expr + + Where: + userloc: filter by the location of the topmost stackframe in user code + curloc: filter by the location of the topmost stackframe (including frames inside private runtime functions) + goloc: filter by the location of the go instruction that created the goroutine + startloc: filter by the location of the start function To only display goroutines that have (or do not have) the specified label key and value, use: - goroutines -with label key=value goroutines -without label key=value @@ -426,6 +431,15 @@ GROUPING goroutines -group (userloc|curloc|goloc|startloc|running|user) + Where: + userloc: groups goroutines by the location of the topmost stackframe in user code + curloc: groups goroutines by the location of the topmost stackframe + goloc: groups goroutines by the location of the go instruction that created the goroutine + startloc: groups goroutines by the location of the start function + running: groups goroutines by weather they are running or not + user: groups goroutines by weather they are user or runtime goroutines + + Groups goroutines by the given location, running status or user classification, up to 5 goroutines per group will be displayed as well as the total number of goroutines in the group. goroutines -group label key diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index 68a6064e5d..91d9982a65 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -249,9 +249,14 @@ To only display goroutines where the specified location contains (or does not co goroutines -w (userloc|curloc|goloc|startloc) expr goroutines -without (userloc|curloc|goloc|startloc) expr goroutines -wo (userloc|curloc|goloc|startloc) expr + + Where: + userloc: filter by the location of the topmost stackframe in user code + curloc: filter by the location of the topmost stackframe (including frames inside private runtime functions) + goloc: filter by the location of the go instruction that created the goroutine + startloc: filter by the location of the start function To only display goroutines that have (or do not have) the specified label key and value, use: - goroutines -with label key=value goroutines -without label key=value @@ -276,6 +281,15 @@ GROUPING goroutines -group (userloc|curloc|goloc|startloc|running|user) + Where: + userloc: groups goroutines by the location of the topmost stackframe in user code + curloc: groups goroutines by the location of the topmost stackframe + goloc: groups goroutines by the location of the go instruction that created the goroutine + startloc: groups goroutines by the location of the start function + running: groups goroutines by weather they are running or not + user: groups goroutines by weather they are user or runtime goroutines + + Groups goroutines by the given location, running status or user classification, up to 5 goroutines per group will be displayed as well as the total number of goroutines in the group. goroutines -group label key From bdec83da45808be11a8bbc7c990ab74d63b4ba4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lex=20S=C3=A1ez?= Date: Tue, 25 Apr 2023 15:15:08 +0200 Subject: [PATCH 017/114] Fix typo --- Documentation/cli/README.md | 2 +- pkg/terminal/command.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/cli/README.md b/Documentation/cli/README.md index 257a034063..3aa69c382d 100644 --- a/Documentation/cli/README.md +++ b/Documentation/cli/README.md @@ -436,7 +436,7 @@ GROUPING curloc: groups goroutines by the location of the topmost stackframe goloc: groups goroutines by the location of the go instruction that created the goroutine startloc: groups goroutines by the location of the start function - running: groups goroutines by weather they are running or not + running: groups goroutines by whether they are running or not user: groups goroutines by weather they are user or runtime goroutines diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index 91d9982a65..52a846df0c 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -286,7 +286,7 @@ GROUPING curloc: groups goroutines by the location of the topmost stackframe goloc: groups goroutines by the location of the go instruction that created the goroutine startloc: groups goroutines by the location of the start function - running: groups goroutines by weather they are running or not + running: groups goroutines by whether they are running or not user: groups goroutines by weather they are user or runtime goroutines From cc7186359468c4418b54475748dd3c4a0abe5592 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Thu, 27 Apr 2023 23:39:33 +0300 Subject: [PATCH 018/114] service: fix typos in comments (#3344) --- service/api/conversions.go | 2 +- service/api/types.go | 2 +- service/client.go | 2 +- service/dap/daptest/gen/main.go | 2 +- service/dap/server.go | 24 ++++++++++++------------ service/dap/server_test.go | 10 +++++----- service/dap/types.go | 4 ++-- service/rpc2/client.go | 2 +- service/rpccallback.go | 2 +- service/test/integration1_test.go | 2 +- service/test/integration2_test.go | 4 ++-- 11 files changed, 28 insertions(+), 28 deletions(-) diff --git a/service/api/conversions.go b/service/api/conversions.go index 4361cda8e6..f386c69b41 100644 --- a/service/api/conversions.go +++ b/service/api/conversions.go @@ -429,7 +429,7 @@ func ConvertRegisters(in *op.DwarfRegisters, dwarfRegisterToString func(int, *op return } -// ConvertImage convers proc.Image to api.Image. +// ConvertImage converts proc.Image to api.Image. func ConvertImage(image *proc.Image) Image { return Image{Path: image.Path, Address: image.StaticBase} } diff --git a/service/api/types.go b/service/api/types.go index a2ddc752c2..7c5de83796 100644 --- a/service/api/types.go +++ b/service/api/types.go @@ -448,7 +448,7 @@ const ( ReverseStep = "reverseStep" // StepOut continues to the return address of the current function StepOut = "stepOut" - // ReverseStepOut continues backward to the calle rof the current function. + // ReverseStepOut continues backward to the caller of the current function. ReverseStepOut = "reverseStepOut" // StepInstruction continues for exactly 1 cpu instruction. StepInstruction = "stepInstruction" diff --git a/service/client.go b/service/client.go index 32cf515464..79af417849 100644 --- a/service/client.go +++ b/service/client.go @@ -47,7 +47,7 @@ type Client interface { ReverseStep() (*api.DebuggerState, error) // StepOut continues to the return address of the current function. StepOut() (*api.DebuggerState, error) - // ReverseStepOut continues backward to the calle rof the current function. + // ReverseStepOut continues backward to the caller of the current function. ReverseStepOut() (*api.DebuggerState, error) // Call resumes process execution while making a function call. Call(goroutineID int64, expr string, unsafe bool) (*api.DebuggerState, error) diff --git a/service/dap/daptest/gen/main.go b/service/dap/daptest/gen/main.go index a5e3870e02..7750e1ad2b 100644 --- a/service/dap/daptest/gen/main.go +++ b/service/dap/daptest/gen/main.go @@ -83,7 +83,7 @@ func main() { messages := []string{} scope := pkgs[0].Types.Scope() for _, name := range scope.Names() { - // Find only types that are embedding go-dap.Respose message. + // Find only types that are embedding go-dap.Response message. obj := scope.Lookup(name) if !obj.Exported() { continue // skip unexported diff --git a/service/dap/server.go b/service/dap/server.go index e505bab7ac..3b9e10ccdf 100644 --- a/service/dap/server.go +++ b/service/dap/server.go @@ -203,7 +203,7 @@ type process struct { // impact handling of subsequent requests. // The fields with cfgName tag can be updated through an evaluation request. type launchAttachArgs struct { - // stopOnEntry is set to automatically stop the debugee after start. + // stopOnEntry is set to automatically stop the debuggee after start. stopOnEntry bool // StackTraceDepth is the maximum length of the returned list of stack frames. StackTraceDepth int `cfgName:"stackTraceDepth"` @@ -236,7 +236,7 @@ var defaultArgs = launchAttachArgs{ substitutePathServerToClient: [][2]string{}, } -// dapClientCapabilites captures arguments from intitialize request that +// dapClientCapabilites captures arguments from initialize request that // impact handling of subsequent requests. type dapClientCapabilites struct { supportsVariableType bool @@ -362,7 +362,7 @@ func (s *Session) setLaunchAttachArgs(args LaunchAttachCommonConfig) error { // connection. It shuts down the underlying debugger and kills the target // process if it was launched by it or stops the noDebug process. // This method mustn't be called more than once. -// StopTriggered notifies other goroutines that stop is in progreess. +// StopTriggered notifies other goroutines that stop is in progress. func (s *Server) Stop() { s.config.log.Debug("DAP server stopping...") defer s.config.log.Debug("DAP server stopped") @@ -404,7 +404,7 @@ func (s *Session) Close() { // Unless Stop() was called after read loop in ServeDAPCodec() // returned, this will result in a closed connection error // on next read, breaking out the read loop and - // allowing the run goroutinee to exit. + // allowing the run goroutines to exit. // This connection is closed here and in serveDAPCodec(). // If this was a forced shutdown, external stop logic can close this first. // If this was a client loop exit (on error or disconnect), serveDAPCodec() @@ -417,13 +417,13 @@ func (s *Session) Close() { // signals that client sent a disconnect request or there was connection // failure or closure. Since the server currently services only one // client, this is used as a signal to stop the entire server. -// The function safeguards agaist closing the channel more +// The function safeguards against closing the channel more // than once and can be called multiple times. It is not thread-safe // and is currently only called from the run goroutine. func (c *Config) triggerServerStop() { // Avoid accidentally closing the channel twice and causing a panic, when // this function is called more than once because stop was triggered - // by multiple conditions simultenously. + // by multiple conditions simultaneously. if c.DisconnectChan != nil { close(c.DisconnectChan) c.DisconnectChan = nil @@ -1428,7 +1428,7 @@ func (s *Session) onSetFunctionBreakpointsRequest(request *dap.SetFunctionBreakp } }, func(i int) (*bpLocation, error) { want := request.Arguments.Breakpoints[i] - // Set the function breakpoint breakpoint + // Set the function breakpoint spec, err := locspec.Parse(want.Name) if err != nil { return nil, err @@ -1865,7 +1865,7 @@ func (s *Session) stoppedOnBreakpointGoroutineID(state *api.DebuggerState) (int6 // stepUntilStopAndNotify is a wrapper around runUntilStopAndNotify that // first switches selected goroutine. allowNextStateChange is // a channel that will be closed to signal that an -// asynchornous command has completed setup or was interrupted +// asynchronous command has completed setup or was interrupted // due to an error, so the server is ready to receive new requests. func (s *Session) stepUntilStopAndNotify(command string, threadId int, granularity dap.SteppingGranularity, allowNextStateChange chan struct{}) { defer closeIfOpen(allowNextStateChange) @@ -2500,7 +2500,7 @@ func (s *Session) convertVariableWithOpts(v *proc.Variable, qualifiedNameOrExpr if v.DwarfType != nil && len(v.Children) > 0 && v.Children[0].Addr != 0 && v.Children[0].Kind != reflect.Invalid { if v.Children[0].OnlyAddr { // Not loaded if v.Addr == 0 { - // This is equvalent to the following with the cli: + // This is equivalent to the following with the cli: // (dlv) p &a7 // (**main.FooBar)(0xc0000a3918) // @@ -2887,7 +2887,7 @@ func (s *Session) onSetVariableRequest(request *dap.SetVariableRequest) { } if useFnCall { - // TODO(hyangah): function call injection currentlly allows to assign return values of + // TODO(hyangah): function call injection currently allows to assign return values of // a function call to variables. So, curious users would find set variable // on string would accept expression like `fn()`. if state, retVals, err := s.doCall(goid, frame, fmt.Sprintf("%v=%v", evaluateName, arg.Value)); err != nil { @@ -2928,7 +2928,7 @@ func (s *Session) onSetVariableRequest(request *dap.SetVariableRequest) { // to update the variable/watch sections if necessary. // // More complicated situation is when the set variable involves call - // injection - after the injected call is completed, the debugee can + // injection - after the injected call is completed, the debuggee can // be in a completely different state (see the note in doCall) due to // how the call injection is implemented. Ideally, we need to also refresh // the stack frames but that is complicated. For now we don't try to actively @@ -3463,7 +3463,7 @@ func (s *Session) resumeOnce(command string, allowNextStateChange chan struct{}) // termination, error, breakpoint, etc, when an appropriate // event needs to be sent to the client. allowNextStateChange is // a channel that will be closed to signal that an -// asynchornous command has completed setup or was interrupted +// asynchronous command has completed setup or was interrupted // due to an error, so the server is ready to receive new requests. func (s *Session) runUntilStopAndNotify(command string, allowNextStateChange chan struct{}) { state, err := s.runUntilStop(command, allowNextStateChange) diff --git a/service/dap/server_test.go b/service/dap/server_test.go index 09e5bd9be4..8d432a3007 100644 --- a/service/dap/server_test.go +++ b/service/dap/server_test.go @@ -2099,7 +2099,7 @@ func TestVariablesLoading(t *testing.T) { checkChildren(t, c1sa, "c1.sa", 3) ref = checkVarRegex(t, c1sa, 0, `\[0\]`, `c1\.sa\[0\]`, `\*\(\*main\.astruct\)\(0x[0-9a-f]+\)`, `\*main\.astruct`, hasChildren) if ref > 0 { - // Auto-loading of fully missing struc children happens here + // Auto-loading of fully missing struct children happens here client.VariablesRequest(ref) c1sa0 := client.ExpectVariablesResponse(t) checkChildren(t, c1sa0, "c1.sa[0]", 1) @@ -4161,7 +4161,7 @@ func TestVariableValueTruncation(t *testing.T) { // Compound map keys may be truncated even further // As the keys are always inside of a map container, - // this applies to variables requests only, not evalute requests. + // this applies to variables requests only, not evaluate requests. // key - compound, value - scalar (inlined key:value display) => truncate key if too long ref := checkVarExact(t, locals, -1, "m5", "m5", "map[main.C]int [{s: "+longstr+"}: 1, ]", "map[main.C]int", hasChildren) @@ -6717,7 +6717,7 @@ func (s *MultiClientCloseServerMock) acceptNewClient(t *testing.T) *daptest.Clie func (s *MultiClientCloseServerMock) stop(t *testing.T) { close(s.forceStop) // If the server doesn't have an active session, - // closing it would leak the debbuger with the target because + // closing it would leak the debugger with the target because // they are part of dap.Session. // We must take it down manually as if we are in rpccommon::ServerImpl::Stop. if s.debugger.IsRunning() { @@ -6733,7 +6733,7 @@ func (s *MultiClientCloseServerMock) verifyStopped(t *testing.T) { verifyServerStopped(t, s.impl) } -// TestAttachRemoteMultiClientDisconnect tests that that remote attach doesn't take down +// TestAttachRemoteMultiClientDisconnect tests that remote attach doesn't take down // the server in multi-client mode unless terminateDebuggee is explicitly set. func TestAttachRemoteMultiClientDisconnect(t *testing.T) { closingClientSessionOnly := fmt.Sprintf(daptest.ClosingClient, "halted") @@ -7039,7 +7039,7 @@ func TestDisassemble(t *testing.T) { t.Errorf("\ngot %#v\nwant instructions[1].Address = %s", dr, pc) } - // Request zero instrutions. + // Request zero instructions. client.DisassembleRequest(pc, 0, 0) dr = client.ExpectDisassembleResponse(t) if len(dr.Body.Instructions) != 0 { diff --git a/service/dap/types.go b/service/dap/types.go index f67a03f66e..e67a68739d 100644 --- a/service/dap/types.go +++ b/service/dap/types.go @@ -106,7 +106,7 @@ type LaunchConfig struct { // "buildFlags": "-tags=integration -mod=vendor -cover -v" BuildFlags string `json:"buildFlags,omitempty"` - // Output path for the binary of the debugee. + // Output path for the binary of the debuggee. // Relative path is interpreted as the path relative to // the Delve's current working directory. // This is deleted after the debug session ends. @@ -191,7 +191,7 @@ type LaunchAttachCommonConfig struct { // SubstitutePath defines a mapping from a local path to the remote path. // Both 'from' and 'to' must be specified and non-null. // Empty values can be used to add or remove absolute path prefixes when mapping. -// For example, mapping with empy 'to' can be used to work with binaries with trimmed paths. +// For example, mapping with empty 'to' can be used to work with binaries with trimmed paths. type SubstitutePath struct { // The local path to be replaced when passing paths to the debugger. From string `json:"from,omitempty"` diff --git a/service/rpc2/client.go b/service/rpc2/client.go index 74aa5f4de7..328874ae5a 100644 --- a/service/rpc2/client.go +++ b/service/rpc2/client.go @@ -547,7 +547,7 @@ func (c *RPCClient) FollowExec(v bool, regex string) error { return err } -// FollowExecEnabled returns true if follow exex mode is enabled. +// FollowExecEnabled returns true if follow exec mode is enabled. func (c *RPCClient) FollowExecEnabled() bool { out := &FollowExecEnabledOut{} _ = c.call("FollowExecEnabled", FollowExecEnabledIn{}, out) diff --git a/service/rpccallback.go b/service/rpccallback.go index 59e0b79a77..168c4ab49a 100644 --- a/service/rpccallback.go +++ b/service/rpccallback.go @@ -5,7 +5,7 @@ type RPCCallback interface { Return(out interface{}, err error) // SetupDoneChan returns a channel that should be closed to signal that the - // asynchornous method has completed setup and the server is ready to + // asynchronous method has completed setup and the server is ready to // receive other requests. SetupDoneChan() chan struct{} } diff --git a/service/test/integration1_test.go b/service/test/integration1_test.go index dfd006b6d2..93f4df82c6 100644 --- a/service/test/integration1_test.go +++ b/service/test/integration1_test.go @@ -858,7 +858,7 @@ func Test1Issue355(t *testing.T) { } func Test1Disasm(t *testing.T) { - // Tests that disassembling by PC, range, and current PC all yeld similar results + // Tests that disassembling by PC, range, and current PC all yield similar results // Tests that disassembly by current PC will return a disassembly containing the instruction at PC // Tests that stepping on a calculated CALL instruction will yield a disassembly that contains the // effective destination of the CALL instruction diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go index 4ea1dd1dfd..4228907685 100644 --- a/service/test/integration2_test.go +++ b/service/test/integration2_test.go @@ -1360,7 +1360,7 @@ func TestIssue355(t *testing.T) { } func TestDisasm(t *testing.T) { - // Tests that disassembling by PC, range, and current PC all yeld similar results + // Tests that disassembling by PC, range, and current PC all yield similar results // Tests that disassembly by current PC will return a disassembly containing the instruction at PC // Tests that stepping on a calculated CALL instruction will yield a disassembly that contains the // effective destination of the CALL instruction @@ -1962,7 +1962,7 @@ func TestClientServerConsistentExit(t *testing.T) { // Ensure future commands also return the correct exit status. // Previously there was a bug where the command which prompted the - // process to exit (continue, next, etc...) would return the corrent + // process to exit (continue, next, etc...) would return the current // exit status but subsequent commands would return an incorrect exit // status of 0. To test this we simply repeat the 'next' command and // ensure we get the correct response again. From 25f0e7712efd08c50ffbd0c7f29556320ed5d31f Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Fri, 28 Apr 2023 16:12:52 +0300 Subject: [PATCH 019/114] proc/test: replace old func testName with T.Name testName is needed only for Go <= 1.7. --- pkg/proc/test/support.go | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/pkg/proc/test/support.go b/pkg/proc/test/support.go index d58c93381c..fd231cedaf 100644 --- a/pkg/proc/test/support.go +++ b/pkg/proc/test/support.go @@ -237,34 +237,12 @@ func RunTestsWithFixtures(m *testing.M) int { var recordingAllowed = map[string]bool{} var recordingAllowedMu sync.Mutex -// testName returns the name of the test being run using runtime.Caller. -// On go1.8 t.Name() could be called instead, this is a workaround to -// support <=go1.7 -func testName(t testing.TB) string { - for i := 1; i < 10; i++ { - pc, _, _, ok := runtime.Caller(i) - if !ok { - break - } - fn := runtime.FuncForPC(pc) - if fn == nil { - continue - } - name := fn.Name() - v := strings.Split(name, ".") - if strings.HasPrefix(v[len(v)-1], "Test") { - return name - } - } - return "unknown" -} - // AllowRecording allows the calling test to be used with a recording of the // fixture. func AllowRecording(t testing.TB) { recordingAllowedMu.Lock() defer recordingAllowedMu.Unlock() - name := testName(t) + name := t.Name() t.Logf("enabling recording for %s", name) recordingAllowed[name] = true } @@ -292,7 +270,7 @@ func AllowRecording(t testing.TB) { func MustHaveRecordingAllowed(t testing.TB) { recordingAllowedMu.Lock() defer recordingAllowedMu.Unlock() - name := testName(t) + name := t.Name() if !recordingAllowed[name] { t.Skipf("recording not allowed for %s", name) } From 5f588d8927bbd8512fa26a6c197118453f21ccec Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Fri, 28 Apr 2023 16:49:07 +0300 Subject: [PATCH 020/114] service/dap,service/debugger: refactor regexp funcs Use regex.MatchString and regex.MustCompile. --- service/dap/server_test.go | 8 ++++---- service/debugger/debugger.go | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/service/dap/server_test.go b/service/dap/server_test.go index 8d432a3007..b2271114d2 100644 --- a/service/dap/server_test.go +++ b/service/dap/server_test.go @@ -726,7 +726,7 @@ func TestPreSetBreakpoint(t *testing.T) { if len(tResp.Body.Threads) < 2 { // 1 main + runtime t.Errorf("\ngot %#v\nwant len(Threads)>1", tResp.Body.Threads) } - reMain, _ := regexp.Compile(`\* \[Go 1\] main.Increment \(Thread [0-9]+\)`) + reMain := regexp.MustCompile(`\* \[Go 1\] main.Increment \(Thread [0-9]+\)`) wantMain := dap.Thread{Id: 1, Name: "* [Go 1] main.Increment (Thread ...)"} wantRuntime := dap.Thread{Id: 2, Name: "[Go 2] runtime.gopark"} for _, got := range tResp.Body.Threads { @@ -5227,7 +5227,7 @@ func TestLaunchDebugRequest(t *testing.T) { <-done os.Stderr = rescueStderr - rmErrRe, _ := regexp.Compile(`could not remove .*\n`) + rmErrRe := regexp.MustCompile(`could not remove .*\n`) rmErr := rmErrRe.FindString(string(err)) if rmErr != "" { // On Windows, a file in use cannot be removed, resulting in "Access is denied". @@ -6809,7 +6809,7 @@ func TestLaunchAttachErrorWhenDebugInProgress(t *testing.T) { // Both launch and attach requests should go through for additional error checking client.AttachRequest(map[string]interface{}{"mode": "local", "processId": 100}) er := client.ExpectVisibleErrorResponse(t) - msgRe, _ := regexp.Compile("Failed to attach: debug session already in progress at [0-9]+:[0-9]+ - use remote mode to connect to a server with an active debug session") + msgRe := regexp.MustCompile("Failed to attach: debug session already in progress at [0-9]+:[0-9]+ - use remote mode to connect to a server with an active debug session") if er.Body.Error.Id != FailedToAttach || msgRe.MatchString(er.Body.Error.Format) { t.Errorf("got %#v, want Id=%d Format=%q", er, FailedToAttach, msgRe) } @@ -6818,7 +6818,7 @@ func TestLaunchAttachErrorWhenDebugInProgress(t *testing.T) { t.Run(mode, func(t *testing.T) { client.LaunchRequestWithArgs(map[string]interface{}{"mode": mode}) er := client.ExpectVisibleErrorResponse(t) - msgRe, _ := regexp.Compile("Failed to launch: debug session already in progress at [0-9]+:[0-9]+ - use remote attach mode to connect to a server with an active debug session") + msgRe := regexp.MustCompile("Failed to launch: debug session already in progress at [0-9]+:[0-9]+ - use remote attach mode to connect to a server with an active debug session") if er.Body.Error.Id != FailedToLaunch || msgRe.MatchString(er.Body.Error.Format) { t.Errorf("got %#v, want Id=%d Format=%q", er, FailedToLaunch, msgRe) } diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index 320adf1b5a..360a74f83b 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -1395,7 +1395,7 @@ func (d *Debugger) Sources(filter string) ([]string, error) { t := proc.ValidTargets{Group: d.target} for t.Next() { for _, f := range t.BinInfo().Sources { - if regex.Match([]byte(f)) { + if regex.MatchString(f) { files = append(files, f) } } @@ -1464,7 +1464,7 @@ func (d *Debugger) Types(filter string) ([]string, error) { } for _, typ := range types { - if regex.Match([]byte(typ)) { + if regex.MatchString(typ) { r = append(r, typ) } } @@ -1497,7 +1497,7 @@ func (d *Debugger) PackageVariables(filter string, cfg proc.LoadConfig) ([]*proc } pvr := pv[:0] for i := range pv { - if regex.Match([]byte(pv[i].Name)) { + if regex.MatchString(pv[i].Name) { pvr = append(pvr, pv[i]) } } From 9873e0ef63bf8c5b93da68ec7ba78f20e8129630 Mon Sep 17 00:00:00 2001 From: Suzy Mueller Date: Fri, 28 Apr 2023 14:57:36 -0400 Subject: [PATCH 021/114] service/dap: use reloaded value The only part of the reloaded value that was used was the Children. This caused a bug where the Time format string was reloaded, but it was not being displayed. Fixes go-delve/delve#3342 --- service/dap/server.go | 1 + 1 file changed, 1 insertion(+) diff --git a/service/dap/server.go b/service/dap/server.go index 3b9e10ccdf..974d9aab5e 100644 --- a/service/dap/server.go +++ b/service/dap/server.go @@ -2485,6 +2485,7 @@ func (s *Session) convertVariableWithOpts(v *proc.Variable, qualifiedNameOrExpr value += fmt.Sprintf(" - FAILED TO LOAD: %s", err) } else { v.Children = vLoaded.Children + v.Value = vLoaded.Value value = api.ConvertVar(v).SinglelineString() } return value From 13ad7dc1d581b86d7000f6fc4bd37309c30ec480 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 2 May 2023 21:23:59 +0200 Subject: [PATCH 022/114] *: misc improvements to config command and substitute-path rules (#3335) A series of interconnected changes to both the terminal command 'config', DAP command 'dlv config', quality of life improvements to how substitute-path works, and better documentation. - Let 'config substitute-path' show the current substitute path rules - Add a -clear command to 'config substitute-path' - Support 'config-debug-info-directories' - rewrite SubstitutePath to be platform independent (see below) - document path substitution more Regarding the rewrite of SubstitutePath: the previous version used runtime.GOOS and filepath.IsAbs to determine which filepath separator to use and if matching should be case insensitive. This is wrong in all situations where the client and server run on different OSes, when examining core files and when cross-compilation is involved. The new version of SubstitutePath checks the rules and the input path to determine if Windows is involved in the process, if it looks like it is it switches to case-insensitive matching. It uses a lax version of filepath.IsAbs to determine if a path is absolute and tries to avoid having to select a path separator as much as possible Fixes #2891, #2890, #2889, #3179, #3332, #3343 --- Documentation/cli/README.md | 12 +- Documentation/cli/starlark.md | 1 + Documentation/cli/substitutepath.md | 66 +++++++++++ Documentation/faq.md | 2 + pkg/config/config.go | 1 + pkg/config/split.go | 3 + pkg/locspec/locations.go | 104 ++++++++++++----- pkg/locspec/locations_test.go | 94 +++++++++++++--- pkg/proc/bininfo.go | 6 +- pkg/terminal/command.go | 14 ++- pkg/terminal/command_test.go | 131 ++++++++++++++++------ pkg/terminal/config.go | 67 ++++++++++- pkg/terminal/starbind/starlark_mapping.go | 38 +++++++ pkg/terminal/terminal_test.go | 86 -------------- service/client.go | 6 + service/dap/command.go | 12 +- service/dap/config.go | 14 ++- service/dap/config_test.go | 11 -- service/dap/server_test.go | 3 + service/dap/types.go | 1 + service/debugger/debugger.go | 15 +++ service/rpc2/client.go | 10 ++ service/rpc2/server.go | 17 +++ 23 files changed, 529 insertions(+), 185 deletions(-) create mode 100644 Documentation/cli/substitutepath.md diff --git a/Documentation/cli/README.md b/Documentation/cli/README.md index 3aa69c382d..8bc707ab09 100644 --- a/Documentation/cli/README.md +++ b/Documentation/cli/README.md @@ -230,14 +230,24 @@ Changes the value of a configuration parameter. config substitute-path config substitute-path + config substitute-path -clear -Adds or removes a path substitution rule. +Adds or removes a path substitution rule, if -clear is used all +substitute-path rules are removed. Without arguments shows the current list +of substitute-path rules. +See also [Documentation/cli/substitutepath.md](//github.com/go-delve/delve/tree/master/Documentation/cli/substitutepath.md) for how the rules are applied. config alias config alias Defines as an alias to or removes an alias. + config debug-info-directories -add + config debug-info-directories -rm + config debug-info-directories -clear + +Adds, removes or clears debug-info-directories. + ## continue Run until breakpoint or program termination. diff --git a/Documentation/cli/starlark.md b/Documentation/cli/starlark.md index 8bc593ea62..b4c9f159e7 100644 --- a/Documentation/cli/starlark.md +++ b/Documentation/cli/starlark.md @@ -29,6 +29,7 @@ raw_command(Name, ThreadID, GoroutineID, ReturnInfoLoadConfig, Expr, UnsafeCall) create_breakpoint(Breakpoint, LocExpr, SubstitutePathRules, Suspended) | Equivalent to API call [CreateBreakpoint](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.CreateBreakpoint) create_ebpf_tracepoint(FunctionName) | Equivalent to API call [CreateEBPFTracepoint](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.CreateEBPFTracepoint) create_watchpoint(Scope, Expr, Type) | Equivalent to API call [CreateWatchpoint](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.CreateWatchpoint) +debug_info_directories(Set, List) | Equivalent to API call [DebugInfoDirectories](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.DebugInfoDirectories) detach(Kill) | Equivalent to API call [Detach](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.Detach) disassemble(Scope, StartPC, EndPC, Flavour) | Equivalent to API call [Disassemble](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.Disassemble) dump_cancel() | Equivalent to API call [DumpCancel](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.DumpCancel) diff --git a/Documentation/cli/substitutepath.md b/Documentation/cli/substitutepath.md new file mode 100644 index 0000000000..72f8f2e7a0 --- /dev/null +++ b/Documentation/cli/substitutepath.md @@ -0,0 +1,66 @@ +## Path substitution configuration + +Normally Delve finds the path to the source code that was used to produce an executable by looking at the debug symbols of the executable. +However, under [some circumstances](../faq.md#substpath), the paths that end up inside the executable will be different from the paths to the source code on the machine that is running the debugger. If that is the case Delve will need extra configuration to convert the paths stored inside the executable to paths in your local filesystem. + +This configuration is done by specifying a list of path substitution rules. + + +### Where are path substitution rules specified + +#### Delve command line client + +The command line client reads the path substitution rules from Delve's YAML configuration file located at `$XDG_CONFIG_HOME/dlv/config.yml` or `.dlv/config.yml` inside the home directory on Windows. + +The `substitute-path` entry should look like this: + +``` +substitute-path: + - {from: "/compiler/machine/directory", to: "/debugger/machine/directory"} + - {from: "", to: "/mapping/for/relative/paths"} +``` + +If you are starting a headless instance of Delve and connecting to it through `dlv connect` the configuration file that is used is the one that runs `dlv connect`. + +The rules can also be modified while Delve is running by using the [config substitute-path command](./README.md#config): + +``` +(dlv) config substitute-path /from/path /to/path +``` + +Double quotes can be used to specify paths that contain spaces, or to specify empty paths: + +``` +(dlv) config substitute-path "/path containing spaces/" /path-without-spaces/ +(dlv) config substitute-path /make/this/path/relative "" +``` + +#### DAP server + +If you connect to Delve using the DAP protocol then the substitute path rules are specified using the substitutePath option in [launch.json](https://github.com/golang/vscode-go/blob/master/docs/debugging.md#launchjson-attributes). + +``` + "substitutePath": [ + { "from": "/from/path", "to": "/to/path" } + ] +``` + +The [debug console](https://github.com/golang/vscode-go/blob/master/docs/debugging.md#dlv-command-from-debug-console) can also be used to modify the path substitution list: + +``` +dlv config substitutePath /from/path /to/path +``` + +This command works similarly to the `config substitute-path` command described above. + +### How are path substitution rules applied + +Regardless of how they are specified the path substitution rules are an ordered list of `(from-path, to-path)` pairs. When Delve needs to convert a path P found inside the executable file into a path in the local filesystem it will scan through the list of rules looking for the first one where P starts with from-path and replace from-path with to-path. + +Empty paths in both from-path and to-path are special, they represent relative paths: + +- `(from="" to="/home/user/project/src")` converts all relative paths in the executable to absolute paths in `/home/user/project/src` +- `(from="/build/dir" to="")` converts all paths in the executable that start with `/build/dir` into relative paths. + +The path substitution code is SubstitutePath in pkg/locspec/locations.go. + diff --git a/Documentation/faq.md b/Documentation/faq.md index 8efc5463ac..14e99be70b 100644 --- a/Documentation/faq.md +++ b/Documentation/faq.md @@ -116,6 +116,8 @@ The substitute-path feature can be used to solve this problem, see `help config` The `sources` command could also be useful in troubleshooting this problem, it shows the list of file paths that has been embedded by the compiler into the executable. +For more informations on path substitution see [path substitution](cli/substitutepath.md). + If you still think this is a bug in Delve and not a configuration problem, open an [issue](https://github.com/go-delve/delve/issues), filling the issue template and including the logs produced by delve with the options `--log --log-output=rpc,dap`. ### Using Delve to debug the Go runtime diff --git a/pkg/config/config.go b/pkg/config/config.go index 035b137dfd..b01747a3e6 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -278,6 +278,7 @@ aliases: # between compilation and debugging. # Note that substitution rules will not be used for paths passed to "break" and "trace" # commands. +# See also Documentation/cli/substitutepath.md. substitute-path: # - {from: path, to: path} diff --git a/pkg/config/split.go b/pkg/config/split.go index 94a216be15..9515671ea6 100644 --- a/pkg/config/split.go +++ b/pkg/config/split.go @@ -81,6 +81,9 @@ func ConfigureSetSimple(rest string, cfgname string, field reflect.Value) error } return reflect.ValueOf(&n), nil case reflect.Bool: + if rest != "true" && rest != "false" { + return reflect.ValueOf(nil), fmt.Errorf("argument to %q must be true or false", cfgname) + } v := rest == "true" return reflect.ValueOf(&v), nil case reflect.String: diff --git a/pkg/locspec/locations.go b/pkg/locspec/locations.go index c16a5b24d7..caca22745d 100644 --- a/pkg/locspec/locations.go +++ b/pkg/locspec/locations.go @@ -479,47 +479,99 @@ func (loc *NormalLocationSpec) findFuncCandidates(bi *proc.BinaryInfo, limit int return r } -func crossPlatformPath(path string) string { - if runtime.GOOS == "windows" { - return strings.ToLower(path) +// isAbs returns true if path looks like an absolute path. +func isAbs(path string) bool { + // Unix-like absolute path + if strings.HasPrefix(path, "/") { + return true } - return path + return windowsAbsPath(path) +} + +func windowsAbsPath(path string) bool { + // Windows UNC absolute path + if strings.HasPrefix(path, `\\`) { + return true + } + // DOS absolute paths + if len(path) < 3 || path[1] != ':' { + return false + } + return path[2] == '/' || path[2] == '\\' +} + +func hasPathSeparatorSuffix(path string) bool { + return strings.HasSuffix(path, "/") || strings.HasSuffix(path, "\\") +} + +func hasPathSeparatorPrefix(path string) bool { + return strings.HasPrefix(path, "/") || strings.HasPrefix(path, "\\") } // SubstitutePath applies the specified path substitution rules to path. func SubstitutePath(path string, rules [][2]string) string { - path = crossPlatformPath(path) - // On windows paths returned from headless server are as c:/dir/dir - // though os.PathSeparator is '\\' - - separator := "/" // make it default - if strings.Contains(path, "\\") { // dependent on the path - separator = "\\" + // Look for evidence that we are dealing with windows somewhere, if we are use case-insensitive matching + caseInsensitive := windowsAbsPath(path) + if !caseInsensitive { + for i := range rules { + if windowsAbsPath(rules[i][0]) || windowsAbsPath(rules[i][1]) { + caseInsensitive = true + break + } + } } for _, r := range rules { - from := crossPlatformPath(r[0]) - to := r[1] + from, to := r[0], r[1] - // If we have an exact match, use it directly. + // if we have an exact match, use it directly. if path == from { return to } - // Otherwise check if it's a directory prefix. - if from != "" && !strings.HasSuffix(from, separator) { - from = from + separator - } - if to != "" && !strings.HasSuffix(to, separator) { - to = to + separator + match := false + var rest string + if from == "" { + match = !isAbs(path) + rest = path + } else { + if caseInsensitive { + match = strings.HasPrefix(strings.ToLower(path), strings.ToLower(from)) + if match { + path = strings.ToLower(path) + from = strings.ToLower(from) + } + } else { + match = strings.HasPrefix(path, from) + } + if match { + // make sure the match ends on something that looks like a path separator boundary + rest = path[len(from):] + match = hasPathSeparatorSuffix(from) || hasPathSeparatorPrefix(rest) + } } - // Expand relative paths with the specified prefix - if from == "" && !filepath.IsAbs(path) { - return strings.Replace(path, from, to, 1) - } + if match { + if to == "" { + // make sure we return a relative path, regardless of whether 'from' consumed a final / or not + if hasPathSeparatorPrefix(rest) { + return rest[1:] + } + return rest + } - if from != "" && strings.HasPrefix(path, from) { - return strings.Replace(path, from, to, 1) + toEndsWithSlash := hasPathSeparatorSuffix(to) + restStartsWithSlash := hasPathSeparatorPrefix(rest) + + switch { + case toEndsWithSlash && restStartsWithSlash: + return to[:len(to)-1] + rest + case toEndsWithSlash && !restStartsWithSlash: + return to + rest + case !toEndsWithSlash && restStartsWithSlash: + return to + rest + case !toEndsWithSlash && !restStartsWithSlash: + return to + "/" + rest + } } } return path diff --git a/pkg/locspec/locations_test.go b/pkg/locspec/locations_test.go index f83f513f1c..cc10beb33d 100644 --- a/pkg/locspec/locations_test.go +++ b/pkg/locspec/locations_test.go @@ -1,7 +1,6 @@ package locspec import ( - "runtime" "testing" ) @@ -69,16 +68,13 @@ func TestFunctionLocationParsing(t *testing.T) { } func assertSubstitutePathEqual(t *testing.T, expected string, substituted string) { + t.Helper() if expected != substituted { - t.Fatalf("Expected substitutedPath to be %s got %s instead", expected, substituted) + t.Errorf("Expected substitutedPath to be %s got %s instead", expected, substituted) } } func TestSubstitutePathUnix(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("Skipping unix SubstitutePath test in windows") - } - // Relative paths mapping assertSubstitutePathEqual(t, "/my/asb/folder/relative/path", SubstitutePath("relative/path", [][2]string{{"", "/my/asb/folder/"}})) assertSubstitutePathEqual(t, "/already/abs/path", SubstitutePath("/already/abs/path", [][2]string{{"", "/my/asb/folder/"}})) @@ -99,21 +95,17 @@ func TestSubstitutePathUnix(t *testing.T) { } func TestSubstitutePathWindows(t *testing.T) { - if runtime.GOOS != "windows" { - t.Skip("Skipping windows SubstitutePath test in unix") - } - // Relative paths mapping assertSubstitutePathEqual(t, "c:\\my\\asb\\folder\\relative\\path", SubstitutePath("relative\\path", [][2]string{{"", "c:\\my\\asb\\folder\\"}})) - assertSubstitutePathEqual(t, "f:\\already\\abs\\path", SubstitutePath("F:\\already\\abs\\path", [][2]string{{"", "c:\\my\\asb\\folder\\"}})) + assertSubstitutePathEqual(t, "F:\\already\\abs\\path", SubstitutePath("F:\\already\\abs\\path", [][2]string{{"", "c:\\my\\asb\\folder\\"}})) assertSubstitutePathEqual(t, "relative\\path", SubstitutePath("C:\\my\\asb\\folder\\relative\\path", [][2]string{{"c:\\my\\asb\\folder\\", ""}})) - assertSubstitutePathEqual(t, "f:\\another\\folder\\relative\\path", SubstitutePath("F:\\another\\folder\\relative\\path", [][2]string{{"c:\\my\\asb\\folder\\", ""}})) + assertSubstitutePathEqual(t, "F:\\another\\folder\\relative\\path", SubstitutePath("F:\\another\\folder\\relative\\path", [][2]string{{"c:\\my\\asb\\folder\\", ""}})) assertSubstitutePathEqual(t, "my\\path", SubstitutePath("relative\\path\\my\\path", [][2]string{{"relative\\path", ""}})) assertSubstitutePathEqual(t, "c:\\abs\\my\\path", SubstitutePath("c:\\abs\\my\\path", [][2]string{{"abs\\my", ""}})) // Absolute paths mapping assertSubstitutePathEqual(t, "c:\\new\\mapping\\path", SubstitutePath("D:\\original\\path", [][2]string{{"d:\\original", "c:\\new\\mapping"}})) - assertSubstitutePathEqual(t, "f:\\no\\change\\path", SubstitutePath("F:\\no\\change\\path", [][2]string{{"d:\\original", "c:\\new\\mapping"}})) + assertSubstitutePathEqual(t, "F:\\no\\change\\path", SubstitutePath("F:\\no\\change\\path", [][2]string{{"d:\\original", "c:\\new\\mapping"}})) assertSubstitutePathEqual(t, "c:\\folder\\should_not_be_replaced\\path", SubstitutePath("c:\\folder\\should_not_be_replaced\\path", [][2]string{{"should_not_be_replaced", ""}})) // Mix absolute and relative mapping @@ -121,3 +113,79 @@ func TestSubstitutePathWindows(t *testing.T) { assertSubstitutePathEqual(t, "c:\\my\\asb\\folder\\path\\", SubstitutePath("path\\", [][2]string{{"d:\\original", "c:\\new\\mapping"}, {"", "c:\\my\\asb\\folder\\"}, {"c:\\my\\asb\\folder\\", ""}})) assertSubstitutePathEqual(t, "path", SubstitutePath("C:\\my\\asb\\folder\\path", [][2]string{{"d:\\original", "c:\\new\\mapping"}, {"c:\\my\\asb\\folder\\", ""}, {"", "c:\\my\\asb\\folder\\"}})) } + +type tRule struct { + from string + to string +} + +type tCase struct { + rules []tRule + path string + res string +} + +func platformCases() []tCase { + casesUnix := []tCase{ + // Should not depend on separator at the end of rule path + {[]tRule{{"/tmp/path", "/new/path2"}}, "/tmp/path/file.go", "/new/path2/file.go"}, + {[]tRule{{"/tmp/path/", "/new/path2/"}}, "/tmp/path/file.go", "/new/path2/file.go"}, + {[]tRule{{"/tmp/path/", "/new/path2"}}, "/tmp/path/file.go", "/new/path2/file.go"}, + {[]tRule{{"/tmp/path", "/new/path2/"}}, "/tmp/path/file.go", "/new/path2/file.go"}, + // Should apply to directory prefixes + {[]tRule{{"/tmp/path", "/new/path2"}}, "/tmp/path-2/file.go", "/tmp/path-2/file.go"}, + // Should apply to exact matches + {[]tRule{{"/tmp/path/file.go", "/new/path2/file2.go"}}, "/tmp/path/file.go", "/new/path2/file2.go"}, + // First matched rule should be used + {[]tRule{ + {"/tmp/path1", "/new/path1"}, + {"/tmp/path2", "/new/path2"}, + {"/tmp/path2", "/new/path3"}}, "/tmp/path2/file.go", "/new/path2/file.go"}, + } + casesLinux := []tCase{ + // Should be case-sensitive + {[]tRule{{"/tmp/path", "/new/path2"}}, "/TmP/path/file.go", "/TmP/path/file.go"}, + } + casesFreebsd := []tCase{ + // Should be case-sensitive + {[]tRule{{"/tmp/path", "/new/path2"}}, "/TmP/path/file.go", "/TmP/path/file.go"}, + } + casesDarwin := []tCase{ + // Can be either case-sensitive or case-insensitive depending on + // filesystem settings, we always treat it as case-sensitive. + {[]tRule{{"/tmp/path", "/new/path2"}}, "/TmP/PaTh/file.go", "/TmP/PaTh/file.go"}, + } + casesWindows := []tCase{ + // Should not depend on separator at the end of rule path + {[]tRule{{`c:\tmp\path`, `d:\new\path2`}}, `c:\tmp\path\file.go`, `d:\new\path2\file.go`}, + {[]tRule{{`c:\tmp\path\`, `d:\new\path2\`}}, `c:\tmp\path\file.go`, `d:\new\path2\file.go`}, + {[]tRule{{`c:\tmp\path`, `d:\new\path2\`}}, `c:\tmp\path\file.go`, `d:\new\path2\file.go`}, + {[]tRule{{`c:\tmp\path\`, `d:\new\path2`}}, `c:\tmp\path\file.go`, `d:\new\path2/file.go`}, + // Should apply to directory prefixes + {[]tRule{{`c:\tmp\path`, `d:\new\path2`}}, `c:\tmp\path-2\file.go`, `c:\tmp\path-2\file.go`}, + // Should apply to exact matches + {[]tRule{{`c:\tmp\path\file.go`, `d:\new\path2\file2.go`}}, `c:\tmp\path\file.go`, `d:\new\path2\file2.go`}, + // Should be case-insensitive + {[]tRule{{`c:\tmp\path`, `d:\new\path2`}}, `C:\TmP\PaTh\file.go`, `d:\new\path2\file.go`}, + } + + r := append(casesUnix, casesLinux...) + r = append(r, casesFreebsd...) + r = append(r, casesDarwin...) + r = append(r, casesWindows...) + + return r +} + +func TestSubstitutePath(t *testing.T) { + for _, c := range platformCases() { + subRules := [][2]string{} + for _, r := range c.rules { + subRules = append(subRules, [2]string{r.from, r.to}) + } + res := SubstitutePath(c.path, subRules) + if c.res != res { + t.Errorf("terminal.SubstitutePath(%q) => %q, want %q", c.path, res, c.res) + } + } +} diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go index 5f862a9ef5..a12aac8a8c 100644 --- a/pkg/proc/bininfo.go +++ b/pkg/proc/bininfo.go @@ -51,7 +51,7 @@ type BinaryInfo struct { // GOOS operating system this binary is executing on. GOOS string - debugInfoDirectories []string + DebugInfoDirectories []string // BuildID of this binary. BuildID string @@ -676,7 +676,7 @@ func (bi *BinaryInfo) LoadBinaryInfo(path string, entryPoint uint64, debugInfoDi bi.lastModified = fi.ModTime() } - bi.debugInfoDirectories = debugInfoDirs + bi.DebugInfoDirectories = debugInfoDirs return bi.AddImage(path, entryPoint) } @@ -1396,7 +1396,7 @@ func loadBinaryInfoElf(bi *BinaryInfo, image *Image, path string, addr uint64, w if err != nil { var sepFile *os.File var serr error - sepFile, dwarfFile, serr = bi.openSeparateDebugInfo(image, elfFile, bi.debugInfoDirectories) + sepFile, dwarfFile, serr = bi.openSeparateDebugInfo(image, elfFile, bi.DebugInfoDirectories) if serr != nil { return serr } diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index 52a846df0c..7afc9ca850 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -516,13 +516,23 @@ Changes the value of a configuration parameter. config substitute-path config substitute-path + config substitute-path -clear -Adds or removes a path substitution rule. +Adds or removes a path substitution rule, if -clear is used all +substitute-path rules are removed. Without arguments shows the current list +of substitute-path rules. +See also Documentation/cli/substitutepath.md for how the rules are applied. config alias config alias -Defines as an alias to or removes an alias.`}, +Defines as an alias to or removes an alias. + + config debug-info-directories -add + config debug-info-directories -rm + config debug-info-directories -clear + +Adds, removes or clears debug-info-directories.`}, {aliases: []string{"edit", "ed"}, cmdFn: edit, helpMsg: `Open where you are in $DELVE_EDITOR or $EDITOR diff --git a/pkg/terminal/command_test.go b/pkg/terminal/command_test.go index ee9c605154..4a9177b460 100644 --- a/pkg/terminal/command_test.go +++ b/pkg/terminal/command_test.go @@ -714,37 +714,67 @@ func findCmdName(c *Commands, cmdstr string, prefix cmdPrefix) string { return "" } +func assertNoError(t *testing.T, err error, str string) { + t.Helper() + if err != nil { + t.Fatalf("%s: %v", str, err) + } +} + +func assertNoErrorConfigureCmd(t *testing.T, term *Term, cmdstr string) { + t.Helper() + err := configureCmd(term, callContext{}, cmdstr) + assertNoError(t, err, fmt.Sprintf("error executing configureCmd(%s)", cmdstr)) +} + +func assertSubstitutePath(t *testing.T, sp config.SubstitutePathRules, v ...string) { + t.Helper() + if len(sp) != len(v)/2 { + t.Fatalf("wrong number of substitute path rules (expected: %d): %#v", len(v)/2, sp) + } + for i := range sp { + if sp[i].From != v[i*2] || sp[i].To != v[i*2+1] { + t.Fatalf("wrong substitute path rule %#v expected (from: %q to %q)", sp[i], v[i*2], v[i*2+1]) + } + } +} + +func assertDebugInfoDirs(t *testing.T, got []string, tgt ...string) { + if len(got) != len(tgt) { + t.Fatalf("wrong number of debug info directories (got %d expected %d)", len(got), len(tgt)) + } + for i := range got { + if got[i] != tgt[i] { + t.Fatalf("debug info directories mismatch got: %v expected: %v", got, tgt) + } + } +} + func TestConfig(t *testing.T) { + var buf bytes.Buffer var term Term term.conf = &config.Config{} term.cmds = DebugCommands(nil) + term.stdout = &transcriptWriter{pw: &pagingWriter{w: &buf}} err := configureCmd(&term, callContext{}, "nonexistent-parameter 10") if err == nil { t.Fatalf("expected error executing configureCmd(nonexistent-parameter)") } - err = configureCmd(&term, callContext{}, "max-string-len 10") - if err != nil { - t.Fatalf("error executing configureCmd(max-string-len): %v", err) - } + assertNoErrorConfigureCmd(t, &term, "max-string-len 10") if term.conf.MaxStringLen == nil { t.Fatalf("expected MaxStringLen 10, got nil") } if *term.conf.MaxStringLen != 10 { t.Fatalf("expected MaxStringLen 10, got: %d", *term.conf.MaxStringLen) } - err = configureCmd(&term, callContext{}, "show-location-expr true") - if err != nil { - t.Fatalf("error executing configureCmd(show-location-expr true)") - } + assertNoErrorConfigureCmd(t, &term, "show-location-expr true") if term.conf.ShowLocationExpr != true { t.Fatalf("expected ShowLocationExpr true, got false") } - err = configureCmd(&term, callContext{}, "max-variable-recurse 4") - if err != nil { - t.Fatalf("error executing configureCmd(max-variable-recurse): %v", err) - } + + assertNoErrorConfigureCmd(t, &term, "max-variable-recurse 4") if term.conf.MaxVariableRecurse == nil { t.Fatalf("expected MaxVariableRecurse 4, got nil") } @@ -752,26 +782,13 @@ func TestConfig(t *testing.T) { t.Fatalf("expected MaxVariableRecurse 4, got: %d", *term.conf.MaxVariableRecurse) } - err = configureCmd(&term, callContext{}, "substitute-path a b") - if err != nil { - t.Fatalf("error executing configureCmd(substitute-path a b): %v", err) - } - if len(term.conf.SubstitutePath) != 1 || (term.conf.SubstitutePath[0] != config.SubstitutePathRule{From: "a", To: "b"}) { - t.Fatalf("unexpected SubstitutePathRules after insert %v", term.conf.SubstitutePath) - } + assertNoErrorConfigureCmd(t, &term, "substitute-path a b") + assertSubstitutePath(t, term.conf.SubstitutePath, "a", "b") - err = configureCmd(&term, callContext{}, "substitute-path a") - if err != nil { - t.Fatalf("error executing configureCmd(substitute-path a): %v", err) - } - if len(term.conf.SubstitutePath) != 0 { - t.Fatalf("unexpected SubstitutePathRules after delete %v", term.conf.SubstitutePath) - } + assertNoErrorConfigureCmd(t, &term, "substitute-path a") + assertSubstitutePath(t, term.conf.SubstitutePath) - err = configureCmd(&term, callContext{}, "alias print blah") - if err != nil { - t.Fatalf("error executing configureCmd(alias print blah): %v", err) - } + assertNoErrorConfigureCmd(t, &term, "alias print blah") if len(term.conf.Aliases["print"]) != 1 { t.Fatalf("aliases not changed after configure command %v", term.conf.Aliases) } @@ -779,16 +796,62 @@ func TestConfig(t *testing.T) { t.Fatalf("new alias not found") } - err = configureCmd(&term, callContext{}, "alias blah") - if err != nil { - t.Fatalf("error executing configureCmd(alias blah): %v", err) - } + assertNoErrorConfigureCmd(t, &term, "alias blah") if len(term.conf.Aliases["print"]) != 0 { t.Fatalf("alias not removed after configure command %v", term.conf.Aliases) } if findCmdName(term.cmds, "blah", noPrefix) != "" { t.Fatalf("new alias found after delete") } + + err = configureCmd(&term, callContext{}, "show-location-expr") + if err == nil { + t.Fatalf("no error form configureCmd(show-location-expr)") + } + if !term.conf.ShowLocationExpr { + t.Fatalf("ShowLocationExpr not set to true") + } + + assertNoErrorConfigureCmd(t, &term, "show-location-expr false") + if term.conf.ShowLocationExpr { + t.Fatalf("ShowLocationExpr set to true") + } + + assertNoErrorConfigureCmd(t, &term, "substitute-path a b") + assertNoErrorConfigureCmd(t, &term, "substitute-path c d") + assertSubstitutePath(t, term.conf.SubstitutePath, "a", "b", "c", "d") + + buf.Reset() + assertNoErrorConfigureCmd(t, &term, "substitute-path") + t.Logf("current substitute-path: %q", buf.String()) + if buf.String() != "\"a\" → \"b\"\n\"c\" → \"d\"\n" { + t.Fatalf("wrong substitute-path value") + } + + assertNoErrorConfigureCmd(t, &term, "substitute-path -clear c") + assertSubstitutePath(t, term.conf.SubstitutePath, "a", "b") + + assertNoErrorConfigureCmd(t, &term, "substitute-path -clear") + assertSubstitutePath(t, term.conf.SubstitutePath) + + assertNoErrorConfigureCmd(t, &term, "substitute-path \"\" something") + assertSubstitutePath(t, term.conf.SubstitutePath, "", "something") + + assertNoErrorConfigureCmd(t, &term, "substitute-path somethingelse \"\"") + assertSubstitutePath(t, term.conf.SubstitutePath, "", "something", "somethingelse", "") + + assertDebugInfoDirs(t, term.conf.DebugInfoDirectories) + + assertNoErrorConfigureCmd(t, &term, "debug-info-directories -add a") + assertDebugInfoDirs(t, term.conf.DebugInfoDirectories, "a") + assertNoErrorConfigureCmd(t, &term, "debug-info-directories -add b") + assertDebugInfoDirs(t, term.conf.DebugInfoDirectories, "a", "b") + assertNoErrorConfigureCmd(t, &term, "debug-info-directories -add c") + assertDebugInfoDirs(t, term.conf.DebugInfoDirectories, "a", "b", "c") + assertNoErrorConfigureCmd(t, &term, "debug-info-directories -rm b") + assertDebugInfoDirs(t, term.conf.DebugInfoDirectories, "a", "c") + assertNoErrorConfigureCmd(t, &term, "debug-info-directories -clear") + assertDebugInfoDirs(t, term.conf.DebugInfoDirectories) } func TestIssue1090(t *testing.T) { diff --git a/pkg/terminal/config.go b/pkg/terminal/config.go index 3584f9b0c4..92c92f7023 100644 --- a/pkg/terminal/config.go +++ b/pkg/terminal/config.go @@ -1,9 +1,10 @@ package terminal import ( + "errors" "fmt" - "os" "reflect" + "strings" "text/tabwriter" "github.com/go-delve/delve/pkg/config" @@ -33,7 +34,7 @@ func configureCmd(t *Term, ctx callContext, args string) error { func configureList(t *Term) error { w := new(tabwriter.Writer) - w.Init(os.Stdout, 0, 8, 1, ' ', 0) + w.Init(t.stdout, 0, 8, 1, ' ', 0) config.ConfigureList(w, t.conf, "yaml") return w.Flush() } @@ -47,8 +48,11 @@ func configureSet(t *Term, args string) error { rest = v[1] } - if cfgname == "alias" { + switch cfgname { + case "alias": return configureSetAlias(t, rest) + case "debug-info-directories": + return configureSetDebugInfoDirectories(t, rest) } field := config.ConfigureFindFieldByName(t.conf, cfgname, "yaml") @@ -64,8 +68,22 @@ func configureSet(t *Term, args string) error { } func configureSetSubstitutePath(t *Term, rest string) error { + if strings.TrimSpace(rest) == "-clear" { + t.conf.SubstitutePath = t.conf.SubstitutePath[:0] + return nil + } argv := config.SplitQuotedFields(rest, '"') + if len(argv) == 2 && argv[0] == "-clear" { + argv = argv[1:] + } switch len(argv) { + case 0: + w := new(tabwriter.Writer) + w.Init(t.stdout, 0, 8, 1, ' ', 0) + for i := range t.conf.SubstitutePath { + fmt.Fprintf(w, "%q\t→\t%q\n", t.conf.SubstitutePath[i].From, t.conf.SubstitutePath[i].To) + } + w.Flush() case 1: // delete substitute-path rule for i := range t.conf.SubstitutePath { if t.conf.SubstitutePath[i].From == argv[0] { @@ -112,3 +130,46 @@ func configureSetAlias(t *Term, rest string) error { t.cmds.Merge(t.conf.Aliases) return nil } + +func configureSetDebugInfoDirectories(t *Term, rest string) error { + v := config.Split2PartsBySpace(rest) + + if t.client != nil { + did, err := t.client.GetDebugInfoDirectories() + if err == nil { + t.conf.DebugInfoDirectories = did + } + } + + switch v[0] { + case "-clear": + t.conf.DebugInfoDirectories = t.conf.DebugInfoDirectories[:0] + case "-add": + if len(v) < 2 { + return errors.New("not enough arguments to \"config debug-info-directories\"") + } + t.conf.DebugInfoDirectories = append(t.conf.DebugInfoDirectories, v[1]) + case "-rm": + if len(v) < 2 { + return errors.New("not enough arguments to \"config debug-info-directories\"") + } + found := false + for i := range t.conf.DebugInfoDirectories { + if t.conf.DebugInfoDirectories[i] == v[1] { + found = true + t.conf.DebugInfoDirectories = append(t.conf.DebugInfoDirectories[:i], t.conf.DebugInfoDirectories[i+1:]...) + break + } + } + if !found { + return fmt.Errorf("could not find %q in debug-info-directories", v[1]) + } + default: + return errors.New("wrong argument to \"config debug-info-directories\"") + } + + if t.client != nil { + t.client.SetDebugInfoDirectories(t.conf.DebugInfoDirectories) + } + return nil +} diff --git a/pkg/terminal/starbind/starlark_mapping.go b/pkg/terminal/starbind/starlark_mapping.go index 06ac94c35e..ce87f61b19 100644 --- a/pkg/terminal/starbind/starlark_mapping.go +++ b/pkg/terminal/starbind/starlark_mapping.go @@ -427,6 +427,44 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + r["debug_info_directories"] = starlark.NewBuiltin("debug_info_directories", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + if err := isCancelled(thread); err != nil { + return starlark.None, decorateError(thread, err) + } + var rpcArgs rpc2.DebugInfoDirectoriesIn + var rpcRet rpc2.DebugInfoDirectoriesOut + if len(args) > 0 && args[0] != starlark.None { + err := unmarshalStarlarkValue(args[0], &rpcArgs.Set, "Set") + if err != nil { + return starlark.None, decorateError(thread, err) + } + } + if len(args) > 1 && args[1] != starlark.None { + err := unmarshalStarlarkValue(args[1], &rpcArgs.List, "List") + if err != nil { + return starlark.None, decorateError(thread, err) + } + } + for _, kv := range kwargs { + var err error + switch kv[0].(starlark.String) { + case "Set": + err = unmarshalStarlarkValue(kv[1], &rpcArgs.Set, "Set") + case "List": + err = unmarshalStarlarkValue(kv[1], &rpcArgs.List, "List") + default: + err = fmt.Errorf("unknown argument %q", kv[0]) + } + if err != nil { + return starlark.None, decorateError(thread, err) + } + } + err := env.ctx.Client().CallAPI("DebugInfoDirectories", &rpcArgs, &rpcRet) + if err != nil { + return starlark.None, err + } + return env.interfaceToStarlarkValue(rpcRet), nil + }) r["detach"] = starlark.NewBuiltin("detach", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) diff --git a/pkg/terminal/terminal_test.go b/pkg/terminal/terminal_test.go index fee23b7cf9..db7a3c7018 100644 --- a/pkg/terminal/terminal_test.go +++ b/pkg/terminal/terminal_test.go @@ -3,95 +3,9 @@ package terminal import ( "errors" "net/rpc" - "runtime" "testing" - - "github.com/go-delve/delve/pkg/config" ) -type tRule struct { - from string - to string -} - -type tCase struct { - rules []tRule - path string - res string -} - -func platformCases() []tCase { - casesUnix := []tCase{ - // Should not depend on separator at the end of rule path - {[]tRule{{"/tmp/path", "/new/path2"}}, "/tmp/path/file.go", "/new/path2/file.go"}, - {[]tRule{{"/tmp/path/", "/new/path2/"}}, "/tmp/path/file.go", "/new/path2/file.go"}, - {[]tRule{{"/tmp/path/", "/new/path2"}}, "/tmp/path/file.go", "/new/path2/file.go"}, - {[]tRule{{"/tmp/path", "/new/path2/"}}, "/tmp/path/file.go", "/new/path2/file.go"}, - // Should apply to directory prefixes - {[]tRule{{"/tmp/path", "/new/path2"}}, "/tmp/path-2/file.go", "/tmp/path-2/file.go"}, - // Should apply to exact matches - {[]tRule{{"/tmp/path/file.go", "/new/path2/file2.go"}}, "/tmp/path/file.go", "/new/path2/file2.go"}, - // First matched rule should be used - {[]tRule{ - {"/tmp/path1", "/new/path1"}, - {"/tmp/path2", "/new/path2"}, - {"/tmp/path2", "/new/path3"}}, "/tmp/path2/file.go", "/new/path2/file.go"}, - } - casesLinux := []tCase{ - // Should be case-sensitive - {[]tRule{{"/tmp/path", "/new/path2"}}, "/TmP/path/file.go", "/TmP/path/file.go"}, - } - casesFreebsd := []tCase{ - // Should be case-sensitive - {[]tRule{{"/tmp/path", "/new/path2"}}, "/TmP/path/file.go", "/TmP/path/file.go"}, - } - casesDarwin := []tCase{ - // Can be either case-sensitive or case-insensitive depending on - // filesystem settings, we always treat it as case-sensitive. - {[]tRule{{"/tmp/path", "/new/path2"}}, "/TmP/PaTh/file.go", "/TmP/PaTh/file.go"}, - } - casesWindows := []tCase{ - // Should not depend on separator at the end of rule path - {[]tRule{{`c:\tmp\path`, `d:\new\path2`}}, `c:\tmp\path\file.go`, `d:\new\path2\file.go`}, - {[]tRule{{`c:\tmp\path\`, `d:\new\path2\`}}, `c:\tmp\path\file.go`, `d:\new\path2\file.go`}, - {[]tRule{{`c:\tmp\path`, `d:\new\path2\`}}, `c:\tmp\path\file.go`, `d:\new\path2\file.go`}, - {[]tRule{{`c:\tmp\path\`, `d:\new\path2`}}, `c:\tmp\path\file.go`, `d:\new\path2\file.go`}, - // Should apply to directory prefixes - {[]tRule{{`c:\tmp\path`, `d:\new\path2`}}, `c:\tmp\path-2\file.go`, `c:\tmp\path-2\file.go`}, - // Should apply to exact matches - {[]tRule{{`c:\tmp\path\file.go`, `d:\new\path2\file2.go`}}, `c:\tmp\path\file.go`, `d:\new\path2\file2.go`}, - // Should be case-insensitive - {[]tRule{{`c:\tmp\path`, `d:\new\path2`}}, `C:\TmP\PaTh\file.go`, `d:\new\path2\file.go`}, - } - - if runtime.GOOS == "windows" { - return casesWindows - } - if runtime.GOOS == "darwin" { - return append(casesUnix, casesDarwin...) - } - if runtime.GOOS == "linux" { - return append(casesUnix, casesLinux...) - } - if runtime.GOOS == "freebsd" { - return append(casesUnix, casesFreebsd...) - } - return casesUnix -} - -func TestSubstitutePath(t *testing.T) { - for _, c := range platformCases() { - var subRules config.SubstitutePathRules - for _, r := range c.rules { - subRules = append(subRules, config.SubstitutePathRule{From: r.from, To: r.to}) - } - res := New(nil, &config.Config{SubstitutePath: subRules}).substitutePath(c.path) - if c.res != res { - t.Errorf("terminal.SubstitutePath(%q) => %q, want %q", c.path, res, c.res) - } - } -} - func TestIsErrProcessExited(t *testing.T) { tests := []struct { name string diff --git a/service/client.go b/service/client.go index 79af417849..62a10c36f3 100644 --- a/service/client.go +++ b/service/client.go @@ -197,6 +197,12 @@ type Client interface { // If cont is true a continue command will be sent instead. Disconnect(cont bool) error + // SetDebugInfoDirectories sets directories used to search for debug symbols + SetDebugInfoDirectories([]string) error + + // GetDebugInfoDirectories returns the list of directories used to search for debug symbols + GetDebugInfoDirectories() ([]string, error) + // CallAPI allows calling an arbitrary rpc method (used by starlark bindings) CallAPI(method string, args, reply interface{}) error } diff --git a/service/dap/command.go b/service/dap/command.go index ab318e095e..fb81a06978 100644 --- a/service/dap/command.go +++ b/service/dap/command.go @@ -47,20 +47,22 @@ Type "help" followed by the name of a command for more information about it.` dlv config -list - Show all configuration parameters. + Show all configuration parameters. - config -list + dlv config -list - Show value of a configuration parameter. + Show value of a configuration parameter. dlv config - Changes the value of a configuration parameter. + Changes the value of a configuration parameter. dlv config substitutePath dlv config substitutePath + dlv config substitutePath -clear - Adds or removes a path substitution rule.` + Adds or removes a path substitution rule. If -clear is used all substitutePath rules are removed. + See also Documentation/cli/substitutepath.md.` msgSources = `Print list of source files. dlv sources [] diff --git a/service/dap/config.go b/service/dap/config.go index 3a13c12d1b..7844589d4a 100644 --- a/service/dap/config.go +++ b/service/dap/config.go @@ -3,6 +3,7 @@ package dap import ( "bytes" "fmt" + "strings" "github.com/go-delve/delve/pkg/config" ) @@ -44,8 +45,19 @@ func configureSet(sargs *launchAttachArgs, args string) (bool, string, error) { } func configureSetSubstitutePath(args *launchAttachArgs, rest string) error { + if strings.TrimSpace(rest) == "-clear" { + args.substitutePathClientToServer = args.substitutePathClientToServer[:0] + args.substitutePathServerToClient = args.substitutePathServerToClient[:0] + return nil + } argv := config.SplitQuotedFields(rest, '"') + if len(argv) == 2 && argv[0] == "-clear" { + argv = argv[1:] + } switch len(argv) { + case 0: + // do nothing, let caller show the current list of substitute path rules + return nil case 1: // delete substitute-path rule for i := range args.substitutePathClientToServer { if args.substitutePathClientToServer[i][0] == argv[0] { @@ -69,7 +81,7 @@ func configureSetSubstitutePath(args *launchAttachArgs, rest string) error { args.substitutePathServerToClient = append(args.substitutePathServerToClient, [2]string{argv[1], argv[0]}) default: - return fmt.Errorf("too many arguments to \"config substitute-path\"") + return fmt.Errorf("too many arguments to \"config substitutePath\"") } return nil } diff --git a/service/dap/config_test.go b/service/dap/config_test.go index d8ee268494..a65b6ca42f 100644 --- a/service/dap/config_test.go +++ b/service/dap/config_test.go @@ -298,17 +298,6 @@ func TestConfigureSetSubstitutePath(t *testing.T) { wantErr: false, }, // Test invalid input. - { - name: "error on empty args", - args: args{ - args: &launchAttachArgs{ - substitutePathClientToServer: [][2]string{}, - substitutePathServerToClient: [][2]string{}, - }, - rest: " \n\r ", - }, - wantErr: true, - }, { name: "error on delete nonexistent rule", args: args{ diff --git a/service/dap/server_test.go b/service/dap/server_test.go index b2271114d2..f5153fd539 100644 --- a/service/dap/server_test.go +++ b/service/dap/server_test.go @@ -4024,6 +4024,9 @@ Type 'dlv help' followed by a command for full documentation. checkEval(t, got, msgConfig, noChildren) // Test config. + client.EvaluateRequest("dlv config", 1000, "repl") + client.ExpectErrorResponse(t) + client.EvaluateRequest("dlv config -list", 1000, "repl") got = client.ExpectEvaluateResponse(t) checkEval(t, got, formatConfig(50, false, false, "", false, [][2]string{}), noChildren) diff --git a/service/dap/types.go b/service/dap/types.go index e67a68739d..5876ae6c78 100644 --- a/service/dap/types.go +++ b/service/dap/types.go @@ -185,6 +185,7 @@ type LaunchAttachCommonConfig struct { // This setting is useful when working in a file system with symbolic links, // running remote debugging, or debugging an executable compiled externally. // The debug adapter will replace the local path with the remote path in all of the calls. + // See also Documentation/cli/substitutepath.md. SubstitutePath []SubstitutePath `json:"substitutePath,omitempty"` } diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index 360a74f83b..ed1e106726 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -2273,6 +2273,21 @@ func (d *Debugger) FollowExecEnabled() bool { return d.target.FollowExecEnabled() } +func (d *Debugger) SetDebugInfoDirectories(v []string) { + d.recordMutex.Lock() + defer d.recordMutex.Unlock() + it := proc.ValidTargets{Group: d.target} + for it.Next() { + it.BinInfo().DebugInfoDirectories = v + } +} + +func (d *Debugger) DebugInfoDirectories() []string { + d.recordMutex.Lock() + defer d.recordMutex.Unlock() + return d.target.Selected.BinInfo().DebugInfoDirectories +} + func go11DecodeErrorCheck(err error) error { if _, isdecodeerr := err.(dwarf.DecodeError); !isdecodeerr { return err diff --git a/service/rpc2/client.go b/service/rpc2/client.go index 328874ae5a..f28d0de5ca 100644 --- a/service/rpc2/client.go +++ b/service/rpc2/client.go @@ -554,6 +554,16 @@ func (c *RPCClient) FollowExecEnabled() bool { return out.Enabled } +func (c *RPCClient) SetDebugInfoDirectories(v []string) error { + return c.call("DebugInfoDirectories", DebugInfoDirectoriesIn{Set: true, List: v}, &DebugInfoDirectoriesOut{}) +} + +func (c *RPCClient) GetDebugInfoDirectories() ([]string, error) { + out := &DebugInfoDirectoriesOut{} + err := c.call("DebugInfoDirectories", DebugInfoDirectoriesIn{Set: false, List: nil}, out) + return out.List, err +} + func (c *RPCClient) call(method string, args, reply interface{}) error { return c.client.Call("RPCServer."+method, args, reply) } diff --git a/service/rpc2/server.go b/service/rpc2/server.go index b8ee0f69a1..eedc069238 100644 --- a/service/rpc2/server.go +++ b/service/rpc2/server.go @@ -1079,3 +1079,20 @@ func (s *RPCServer) FollowExecEnabled(arg FollowExecEnabledIn, out *FollowExecEn out.Enabled = s.debugger.FollowExecEnabled() return nil } + +type DebugInfoDirectoriesIn struct { + Set bool + List []string +} + +type DebugInfoDirectoriesOut struct { + List []string +} + +func (s *RPCServer) DebugInfoDirectories(arg DebugInfoDirectoriesIn, out *DebugInfoDirectoriesOut) error { + if arg.Set { + s.debugger.SetDebugInfoDirectories(arg.List) + } + out.List = s.debugger.DebugInfoDirectories() + return nil +} From f3bfa7c1774e2eb124a9ca370fe62458235dfb41 Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Wed, 3 May 2023 00:41:32 -0700 Subject: [PATCH 023/114] pkg/proc: remove memlock limit for ebpf trace backend (#3353) Fixes #3283 --- pkg/proc/internal/ebpf/helpers.go | 4 + .../github.com/cilium/ebpf/rlimit/rlimit.go | 113 ++++++++++++++++++ vendor/modules.txt | 3 +- 3 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 vendor/github.com/cilium/ebpf/rlimit/rlimit.go diff --git a/pkg/proc/internal/ebpf/helpers.go b/pkg/proc/internal/ebpf/helpers.go index d9b5e7dfc0..b856cef1cd 100644 --- a/pkg/proc/internal/ebpf/helpers.go +++ b/pkg/proc/internal/ebpf/helpers.go @@ -18,6 +18,7 @@ import ( "github.com/cilium/ebpf" "github.com/cilium/ebpf/link" "github.com/cilium/ebpf/ringbuf" + "github.com/cilium/ebpf/rlimit" ) //lint:file-ignore U1000 some fields are used by the C program @@ -109,6 +110,9 @@ func LoadEBPFTracingProgram(path string) (*EBPFContext, error) { objs traceObjects ) + if err = rlimit.RemoveMemlock(); err != nil { + return nil, err + } ctx.executable, err = link.OpenExecutable(path) if err != nil { return nil, err diff --git a/vendor/github.com/cilium/ebpf/rlimit/rlimit.go b/vendor/github.com/cilium/ebpf/rlimit/rlimit.go new file mode 100644 index 0000000000..22fc8177f2 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/rlimit/rlimit.go @@ -0,0 +1,113 @@ +// Package rlimit allows raising RLIMIT_MEMLOCK if necessary for the use of BPF. +package rlimit + +import ( + "errors" + "fmt" + "sync" + + "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/unix" +) + +var ( + unsupportedMemcgAccounting = &internal.UnsupportedFeatureError{ + MinimumVersion: internal.Version{5, 11, 0}, + Name: "memcg-based accounting for BPF memory", + } + haveMemcgAccounting error + + rlimitMu sync.Mutex +) + +func init() { + // We have to run this feature test at init, since it relies on changing + // RLIMIT_MEMLOCK. Doing so is not safe in a concurrent program. Instead, + // we rely on the initialization order guaranteed by the Go runtime to + // execute the test in a safe environment: + // + // the invocation of init functions happens in a single goroutine, + // sequentially, one package at a time. + // + // This is also the reason why RemoveMemlock is in its own package: + // we only want to run the initializer if RemoveMemlock is called + // from somewhere. + haveMemcgAccounting = detectMemcgAccounting() +} + +func detectMemcgAccounting() error { + // Reduce the limit to zero and store the previous limit. This should always succeed. + var oldLimit unix.Rlimit + zeroLimit := unix.Rlimit{Cur: 0, Max: oldLimit.Max} + if err := unix.Prlimit(0, unix.RLIMIT_MEMLOCK, &zeroLimit, &oldLimit); err != nil { + return fmt.Errorf("lowering memlock rlimit: %s", err) + } + + attr := internal.BPFMapCreateAttr{ + MapType: 2, /* Array */ + KeySize: 4, + ValueSize: 4, + MaxEntries: 1, + } + + // Creating a map allocates shared (and locked) memory that counts against + // the rlimit on pre-5.11 kernels, but against the memory cgroup budget on + // kernels 5.11 and over. If this call succeeds with the process' memlock + // rlimit set to 0, we can reasonably assume memcg accounting is supported. + fd, mapErr := internal.BPFMapCreate(&attr) + + // Restore old limits regardless of what happened. + if err := unix.Prlimit(0, unix.RLIMIT_MEMLOCK, &oldLimit, nil); err != nil { + return fmt.Errorf("restoring old memlock rlimit: %s", err) + } + + // Map creation successful, memcg accounting supported. + if mapErr == nil { + fd.Close() + return nil + } + + // EPERM shows up when map creation would exceed the memory budget. + if errors.Is(mapErr, unix.EPERM) { + return unsupportedMemcgAccounting + } + + // This shouldn't happen really. + return fmt.Errorf("unexpected error detecting memory cgroup accounting: %s", mapErr) +} + +// RemoveMemlock removes the limit on the amount of memory the current +// process can lock into RAM, if necessary. +// +// This is not required to load eBPF resources on kernel versions 5.11+ +// due to the introduction of cgroup-based memory accounting. On such kernels +// the function is a no-op. +// +// Since the function may change global per-process limits it should be invoked +// at program start up, in main() or init(). +// +// This function exists as a convenience and should only be used when +// permanently raising RLIMIT_MEMLOCK to infinite is appropriate. Consider +// invoking prlimit(2) directly with a more reasonable limit if desired. +// +// Requires CAP_SYS_RESOURCE on kernels < 5.11. +func RemoveMemlock() error { + if haveMemcgAccounting == nil { + return nil + } + + if !errors.Is(haveMemcgAccounting, unsupportedMemcgAccounting) { + return haveMemcgAccounting + } + + rlimitMu.Lock() + defer rlimitMu.Unlock() + + // pid 0 affects the current process. Requires CAP_SYS_RESOURCE. + newLimit := unix.Rlimit{Cur: unix.RLIM_INFINITY, Max: unix.RLIM_INFINITY} + if err := unix.Prlimit(0, unix.RLIMIT_MEMLOCK, &newLimit, nil); err != nil { + return fmt.Errorf("failed to set memlock rlimit: %w", err) + } + + return nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index ac1d2a3ab4..161a09fe33 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -7,6 +7,7 @@ github.com/cilium/ebpf/internal/btf github.com/cilium/ebpf/internal/unix github.com/cilium/ebpf/link github.com/cilium/ebpf/ringbuf +github.com/cilium/ebpf/rlimit # github.com/cosiner/argv v0.1.0 ## explicit github.com/cosiner/argv @@ -91,8 +92,6 @@ golang.org/x/tools/internal/gocommand golang.org/x/tools/internal/packagesinternal golang.org/x/tools/internal/typeparams golang.org/x/tools/internal/typesinternal -# golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 -## explicit # gopkg.in/yaml.v2 v2.4.0 ## explicit gopkg.in/yaml.v2 From a3b053df86132c42c6dc774c0a8f871fefb59566 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Thu, 4 May 2023 14:59:16 +0300 Subject: [PATCH 024/114] pkg/proc: add missing response body Close in test (#3355) --- pkg/proc/proc_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index bcb53bd901..ebdbe086ff 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -2917,6 +2917,7 @@ func TestAttachDetach(t *testing.T) { assertNoError(err, t, "Page request after detach") bs, err := ioutil.ReadAll(resp.Body) assertNoError(err, t, "Reading /nobp page") + defer resp.Body.Close() if out := string(bs); !strings.Contains(out, "hello, world!") { t.Fatalf("/nobp page does not contain \"hello, world!\": %q", out) } From 8c9ce617c9d005363361be4e2eb5be967c499458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Sat, 6 May 2023 00:59:43 +0800 Subject: [PATCH 025/114] chore: don't ignore directory cmd/dlv (#3359) Currently, cmd/dlv is ignored, breaks tools which read the gitignore file. For example, rg can't search files under cmd/dlv. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index adbd0ac955..d25c552aa6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ tags .dbg_history **/**/dlv +!cmd/dlv/ .vagrant **/*.swp localtests From 8711f6217dcd2bf64ae3ef89e79d37230a2be077 Mon Sep 17 00:00:00 2001 From: Eng Zer Jun Date: Tue, 9 May 2023 01:37:30 +0800 Subject: [PATCH 026/114] refactor: replace `Readdir(-1)` with `os.ReadDir` (#3361) We can simplify the following code dir, err := os.Open(dirname) if err != nil { return err } defer dir.Close() dirs, err := dir.Readdir(-1) with just `os.ReadDir(dirname)`. Reference: https://pkg.go.dev/os#ReadDir Signed-off-by: Eng Zer Jun --- pkg/proc/core/core_test.go | 7 +------ pkg/proc/gdbserial/rr.go | 7 +------ pkg/proc/test/support.go | 7 +------ 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/pkg/proc/core/core_test.go b/pkg/proc/core/core_test.go index 3444fdc348..fa86493466 100644 --- a/pkg/proc/core/core_test.go +++ b/pkg/proc/core/core_test.go @@ -504,12 +504,7 @@ func procdump(t *testing.T, exePath string) string { t.Fatalf("possible error running procdump64, output: %q, error: %v", string(out), err) } - dh, err := os.Open(exeDir) - if err != nil { - t.Fatalf("could not open executable file directory %q: %v", exeDir, err) - } - defer dh.Close() - fis, err := dh.Readdir(-1) + fis, err := os.ReadDir(exeDir) if err != nil { t.Fatalf("could not read executable file directory %q: %v", exeDir, err) } diff --git a/pkg/proc/gdbserial/rr.go b/pkg/proc/gdbserial/rr.go index ca70850b62..c58a69836c 100644 --- a/pkg/proc/gdbserial/rr.go +++ b/pkg/proc/gdbserial/rr.go @@ -300,12 +300,7 @@ func RecordAndReplay(cmd []string, wd string, quiet bool, debugInfoDirs []string // safeRemoveAll removes dir and its contents but only as long as dir does // not contain directories. func safeRemoveAll(dir string) { - dh, err := os.Open(dir) - if err != nil { - return - } - defer dh.Close() - fis, err := dh.Readdir(-1) + fis, err := os.ReadDir(dir) if err != nil { return } diff --git a/pkg/proc/test/support.go b/pkg/proc/test/support.go index fd231cedaf..c9bd0e3c56 100644 --- a/pkg/proc/test/support.go +++ b/pkg/proc/test/support.go @@ -279,12 +279,7 @@ func MustHaveRecordingAllowed(t testing.TB) { // SafeRemoveAll removes dir and its contents but only as long as dir does // not contain directories. func SafeRemoveAll(dir string) { - dh, err := os.Open(dir) - if err != nil { - return - } - defer dh.Close() - fis, err := dh.Readdir(-1) + fis, err := os.ReadDir(dir) if err != nil { return } From 5c7049b7b14999ab2c5f42633bf4b72458b1cf5b Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 8 May 2023 19:38:53 +0200 Subject: [PATCH 027/114] dwarf/godwarf: fix alignment calculation for typedef types (#3362) Alignment calculation for typedef types was wrong due to a missing Align method. Fixes #3360 --- _fixtures/testvariables2.go | 11 ++++++++++- pkg/dwarf/godwarf/type.go | 6 ++++-- pkg/proc/variables_test.go | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/_fixtures/testvariables2.go b/_fixtures/testvariables2.go index e4c314dd0c..b078e9d87d 100644 --- a/_fixtures/testvariables2.go +++ b/_fixtures/testvariables2.go @@ -145,6 +145,10 @@ type W5 struct { *W5 } +type ThreeInts struct { + a, b, c int +} + var _ I = (*W2)(nil) func main() { @@ -379,6 +383,11 @@ func main() { h.Data = 0 tim3 := time.Date(300000, 1, 1, 0, 0, 0, 0, time.Local) + int3chan := make(chan ThreeInts, 5) + int3chan <- ThreeInts{a: 1} + int3chan <- ThreeInts{a: 2} + int3chan <- ThreeInts{a: 3} + var amb1 = 1 runtime.Breakpoint() for amb1 := 0; amb1 < 10; amb1++ { @@ -389,5 +398,5 @@ func main() { longslice := make([]int, 100, 100) runtime.Breakpoint() - fmt.Println(i1, i2, i3, p1, pp1, amb1, s1, s3, a0, a1, p2, p3, s2, as1, str1, f1, fn1, fn2, nilslice, nilptr, ch1, chnil, m1, mnil, m2, m3, m4, m5, upnil, up1, i4, i5, i6, err1, err2, errnil, iface1, iface2, ifacenil, arr1, parr, cpx1, const1, iface3, iface4, recursive1, recursive1.x, iface5, iface2fn1, iface2fn2, bencharr, benchparr, mapinf, mainMenu, b, b2, sd, anonstruct1, anonstruct2, anoniface1, anonfunc, mapanonstruct1, ifacearr, efacearr, ni8, ni16, ni32, ni64, pinf, ninf, nan, zsvmap, zsslice, zsvar, tm, rettm, errtypednil, emptyslice, emptymap, byteslice, bytestypeslice, runeslice, bytearray, bytetypearray, runearray, longstr, nilstruct, as2, as2.NonPointerRecieverMethod, s4, iface2map, issue1578, ll, unread, w2, w3, w4, w5, longarr, longslice, val, m6, m7, cl, tim1, tim2, typedstringvar, namedA1, namedA2, astructName1(namedA2), badslice, tim3) + fmt.Println(i1, i2, i3, p1, pp1, amb1, s1, s3, a0, a1, p2, p3, s2, as1, str1, f1, fn1, fn2, nilslice, nilptr, ch1, chnil, m1, mnil, m2, m3, m4, m5, upnil, up1, i4, i5, i6, err1, err2, errnil, iface1, iface2, ifacenil, arr1, parr, cpx1, const1, iface3, iface4, recursive1, recursive1.x, iface5, iface2fn1, iface2fn2, bencharr, benchparr, mapinf, mainMenu, b, b2, sd, anonstruct1, anonstruct2, anoniface1, anonfunc, mapanonstruct1, ifacearr, efacearr, ni8, ni16, ni32, ni64, pinf, ninf, nan, zsvmap, zsslice, zsvar, tm, rettm, errtypednil, emptyslice, emptymap, byteslice, bytestypeslice, runeslice, bytearray, bytetypearray, runearray, longstr, nilstruct, as2, as2.NonPointerRecieverMethod, s4, iface2map, issue1578, ll, unread, w2, w3, w4, w5, longarr, longslice, val, m6, m7, cl, tim1, tim2, typedstringvar, namedA1, namedA2, astructName1(namedA2), badslice, tim3, int3chan) } diff --git a/pkg/dwarf/godwarf/type.go b/pkg/dwarf/godwarf/type.go index 5b6df937bc..19ac86e38d 100644 --- a/pkg/dwarf/godwarf/type.go +++ b/pkg/dwarf/godwarf/type.go @@ -180,7 +180,8 @@ func (t *QualType) stringIntl(recCheck recCheck) string { return t.Qual + " " + t.Type.stringIntl(recCheck) } -func (t *QualType) Size() int64 { return sizeAlignToSize(t.sizeAlignIntl(make(recCheck))) } +func (t *QualType) Size() int64 { return sizeAlignToSize(t.sizeAlignIntl(make(recCheck))) } +func (t *QualType) Align() int64 { return sizeAlignToAlign(t.sizeAlignIntl(make(recCheck))) } func (t *QualType) sizeAlignIntl(recCheck recCheck) (int64, int64) { release := recCheck.acquire(t.CommonType.Offset) @@ -457,7 +458,8 @@ func (t *TypedefType) String() string { return t.stringIntl(nil) } func (t *TypedefType) stringIntl(recCheck recCheck) string { return t.Name } -func (t *TypedefType) Size() int64 { sz, _ := t.sizeAlignIntl(make(recCheck)); return sz } +func (t *TypedefType) Size() int64 { return sizeAlignToSize(t.sizeAlignIntl(make(recCheck))) } +func (t *TypedefType) Align() int64 { return sizeAlignToAlign(t.sizeAlignIntl(make(recCheck))) } func (t *TypedefType) sizeAlignIntl(recCheck recCheck) (int64, int64) { release := recCheck.acquire(t.CommonType.Offset) diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go index 77b8677a53..00f7f7b084 100644 --- a/pkg/proc/variables_test.go +++ b/pkg/proc/variables_test.go @@ -558,6 +558,7 @@ func getEvalExpressionTestCases() []varTest { {"ch1", true, "chan int 4/11", "chan int 4/11", "chan int", nil}, {"chnil", true, "chan int nil", "chan int nil", "chan int", nil}, {"ch1+1", false, "", "", "", fmt.Errorf("can not convert 1 constant to chan int")}, + {"int3chan.buf", false, "*[5]main.ThreeInts [{a: 1, b: 0, c: 0},{a: 2, b: 0, c: 0},{a: 3, b: 0, c: 0},{a: 0, b: 0, c: 0},{a: 0, b: 0, c: 0}]", "(*[5]main.ThreeInts)(…", "*[5]main.ThreeInts", nil}, // maps {"m1[\"Malone\"]", false, "main.astruct {A: 2, B: 3}", "main.astruct {A: 2, B: 3}", "main.astruct", nil}, From a57c60e43ac6e26daf7f053c24c225d238fcf9f3 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Mon, 8 May 2023 20:41:14 +0300 Subject: [PATCH 028/114] service/dap: refactor funcs always returning nil error (#3357) --- service/dap/server.go | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/service/dap/server.go b/service/dap/server.go index 974d9aab5e..ecebb778d3 100644 --- a/service/dap/server.go +++ b/service/dap/server.go @@ -336,7 +336,7 @@ func NewSession(conn io.ReadWriteCloser, config *Config, debugger *debugger.Debu // If user-specified options are provided via Launch/AttachRequest, // we override the defaults for optional args. -func (s *Session) setLaunchAttachArgs(args LaunchAttachCommonConfig) error { +func (s *Session) setLaunchAttachArgs(args LaunchAttachCommonConfig) { s.args.stopOnEntry = args.StopOnEntry if depth := args.StackTraceDepth; depth > 0 { s.args.StackTraceDepth = depth @@ -355,7 +355,6 @@ func (s *Session) setLaunchAttachArgs(args LaunchAttachCommonConfig) error { s.args.substitutePathClientToServer = clientToServer s.args.substitutePathServerToClient = serverToClient } - return nil } // Stop stops the DAP debugger service, closes the listener and the client @@ -1000,10 +999,7 @@ func (s *Session) onLaunchRequest(request *dap.LaunchRequest) { } s.config.ProcessArgs = append([]string{debugbinary}, args.Args...) - if err := s.setLaunchAttachArgs(args.LaunchAttachCommonConfig); err != nil { - s.sendShowUserErrorResponse(request.Request, FailedToLaunch, "Failed to launch", err.Error()) - return - } + s.setLaunchAttachArgs(args.LaunchAttachCommonConfig) if args.Cwd == "" { if args.Mode == "test" { @@ -1782,10 +1778,7 @@ func (s *Session) onAttachRequest(request *dap.AttachRequest) { return } - if err := s.setLaunchAttachArgs(args.LaunchAttachCommonConfig); err != nil { - s.sendShowUserErrorResponse(request.Request, FailedToAttach, "Failed to attach", err.Error()) - return - } + s.setLaunchAttachArgs(args.LaunchAttachCommonConfig) // Notify the client that the debugger is ready to start accepting // configuration requests for setting breakpoints, etc. The client @@ -2142,11 +2135,7 @@ func (s *Session) onVariablesRequest(request *dap.VariablesRequest) { children = append(children, named...) } if request.Arguments.Filter == "indexed" || request.Arguments.Filter == "" { - indexed, err := s.childrenToDAPVariables(v) - if err != nil { - s.sendErrorResponse(request.Request, UnableToLookupVariable, "Unable to lookup variable", err.Error()) - return - } + indexed := s.childrenToDAPVariables(v) children = append(children, indexed...) } response := &dap.VariablesResponse{ @@ -2192,7 +2181,7 @@ func getIndexedVariableCount(v *proc.Variable) int { } // childrenToDAPVariables returns the DAP presentation of the referenced variable's children. -func (s *Session) childrenToDAPVariables(v *fullyQualifiedVariable) ([]dap.Variable, error) { +func (s *Session) childrenToDAPVariables(v *fullyQualifiedVariable) []dap.Variable { // TODO(polina): consider convertVariableToString instead of convertVariable // and avoid unnecessary creation of variable handles when this is called to // compute evaluate names when this is called from onSetVariableRequest. @@ -2340,7 +2329,7 @@ func (s *Session) childrenToDAPVariables(v *fullyQualifiedVariable) ([]dap.Varia } } } - return children, nil + return children } func getNamedVariableCount(v *proc.Variable) int { @@ -2833,10 +2822,7 @@ func (s *Session) onReverseContinueRequest(request *dap.ReverseContinueRequest, // computeEvaluateName finds the named child, and computes its evaluate name. func (s *Session) computeEvaluateName(v *fullyQualifiedVariable, cname string) (string, error) { - children, err := s.childrenToDAPVariables(v) - if err != nil { - return "", err - } + children := s.childrenToDAPVariables(v) for _, c := range children { if c.Name == cname { if c.EvaluateName != "" { From 801a9109c7fd7be8b060b466cc041a3695455c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Tue, 9 May 2023 01:41:47 +0800 Subject: [PATCH 029/114] trace: add timestamp to the output (#3358) Fix #3356 --- Documentation/usage/dlv_trace.md | 1 + cmd/dlv/cmds/commands.go | 23 +++++++++++++++++------ pkg/config/config.go | 4 ++++ pkg/terminal/command.go | 5 +++++ 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/Documentation/usage/dlv_trace.md b/Documentation/usage/dlv_trace.md index 176aaca968..018a511429 100644 --- a/Documentation/usage/dlv_trace.md +++ b/Documentation/usage/dlv_trace.md @@ -28,6 +28,7 @@ dlv trace [package] regexp [flags] -p, --pid int Pid to attach to. -s, --stack int Show stack trace with given depth. (Ignored with --ebpf) -t, --test Trace a test binary. + --timestamp Show timestamp in the output ``` ### Options inherited from parent commands diff --git a/cmd/dlv/cmds/commands.go b/cmd/dlv/cmds/commands.go index c98c047b51..54b61ab939 100644 --- a/cmd/dlv/cmds/commands.go +++ b/cmd/dlv/cmds/commands.go @@ -14,6 +14,7 @@ import ( "strconv" "strings" "syscall" + "time" "github.com/go-delve/delve/pkg/config" "github.com/go-delve/delve/pkg/gobuild" @@ -78,11 +79,12 @@ var ( // rootCommand is the root of the command tree. rootCommand *cobra.Command - traceAttachPid int - traceExecFile string - traceTestBinary bool - traceStackDepth int - traceUseEBPF bool + traceAttachPid int + traceExecFile string + traceTestBinary bool + traceStackDepth int + traceUseEBPF bool + traceShowTimestamp bool // redirect specifications for target process redirects []string @@ -307,6 +309,7 @@ only see the output of the trace operations you can redirect stdout.`, traceCommand.Flags().StringVarP(&traceExecFile, "exec", "e", "", "Binary file to exec and trace.") traceCommand.Flags().BoolVarP(&traceTestBinary, "test", "t", false, "Trace a test binary.") traceCommand.Flags().BoolVarP(&traceUseEBPF, "ebpf", "", false, "Trace using eBPF (experimental).") + traceCommand.Flags().BoolVarP(&traceShowTimestamp, "timestamp", "", false, "Show timestamp in the output") traceCommand.Flags().IntVarP(&traceStackDepth, "stack", "s", 0, "Show stack trace with given depth. (Ignored with --ebpf)") traceCommand.Flags().String("output", "debug", "Output path for the binary.") rootCommand.AddCommand(traceCommand) @@ -694,7 +697,10 @@ func traceCmd(cmd *cobra.Command, args []string) { return 1 } cmds := terminal.DebugCommands(client) - t := terminal.New(client, nil) + cfg := &config.Config{ + TraceShowTimestamp: traceShowTimestamp, + } + t := terminal.New(client, cfg) t.SetTraceNonInteractive() t.RedirectTo(os.Stderr) defer t.Close() @@ -723,6 +729,11 @@ func traceCmd(cmd *cobra.Command, args []string) { params.WriteString(p.Value) } } + + if traceShowTimestamp { + fmt.Fprintf(os.Stderr, "%s ", time.Now().Format(time.RFC3339Nano)) + } + if t.IsRet { for _, p := range t.ReturnParams { fmt.Fprintf(os.Stderr, "=> %#v\n", p.Value) diff --git a/pkg/config/config.go b/pkg/config/config.go index b01747a3e6..faf6fa713d 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -102,6 +102,10 @@ type Config struct { // This can be used to shorten the tabstop (e.g. " ") or to print a more // visual indent (e.g. ">__ "). Tab string `yaml:"tab"` + + // TraceShowTimestamp controls whether to show timestamp in the trace + // output. + TraceShowTimestamp bool `yaml:"trace-show-timestamp"` } func (c *Config) GetSourceListLineCount() int { diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index 7afc9ca850..f894703f0d 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -23,6 +23,7 @@ import ( "strconv" "strings" "text/tabwriter" + "time" "github.com/cosiner/argv" "github.com/go-delve/delve/pkg/config" @@ -2756,6 +2757,10 @@ func printBreakpointInfo(t *Term, th *api.Thread, tracepointOnNewline bool) { } func printTracepoint(t *Term, th *api.Thread, bpname string, fn *api.Function, args string, hasReturnValue bool) { + if t.conf.TraceShowTimestamp { + fmt.Fprintf(t.stdout, "%s ", time.Now().Format(time.RFC3339Nano)) + } + if th.Breakpoint.Tracepoint { fmt.Fprintf(t.stdout, "> goroutine(%d): %s%s(%s)\n", th.GoroutineID, bpname, fn.Name(), args) printBreakpointInfo(t, th, !hasReturnValue) From e95ae9c21b9e4d492538c37a27720eeab6d894d1 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 9 May 2023 20:40:00 +0200 Subject: [PATCH 030/114] proc,terminal: read command line of new processes (#3346) Read the command line of the main target process as well as any other process Delve attaches to in follow exec mode. The command line can be viewed using the 'target list' command. In follow exec mode this command line is used to match the follow exec regex to decide whether or not to attach to a child process. On macOS or when using rr the list of arguments is not available for attached processes since there is no way to use the gdb serial protocol to read it. Fixes #2242 --- pkg/proc/core/core.go | 2 +- pkg/proc/gdbserial/gdbserver.go | 24 ++--- pkg/proc/gdbserial/rr.go | 6 +- pkg/proc/native/nonative_darwin.go | 2 +- pkg/proc/native/proc.go | 26 +++--- pkg/proc/native/proc_darwin.go | 2 +- pkg/proc/native/proc_freebsd.c | 4 - pkg/proc/native/proc_freebsd.go | 22 ++++- pkg/proc/native/proc_freebsd.h | 3 + pkg/proc/native/proc_linux.go | 42 ++++++--- pkg/proc/native/proc_windows.go | 140 +++++++++++++++++++++++++++-- pkg/proc/proc_test.go | 51 +++++++++++ pkg/proc/target.go | 6 +- pkg/proc/target_group.go | 36 ++++++-- pkg/terminal/command.go | 2 +- service/api/conversions.go | 2 +- service/api/types.go | 2 + service/debugger/debugger.go | 5 +- 18 files changed, 310 insertions(+), 67 deletions(-) diff --git a/pkg/proc/core/core.go b/pkg/proc/core/core.go index 734dbd4159..358c0b085f 100644 --- a/pkg/proc/core/core.go +++ b/pkg/proc/core/core.go @@ -227,7 +227,7 @@ func OpenCore(corePath, exePath string, debugInfoDirs []string) (*proc.TargetGro DisableAsyncPreempt: false, CanDump: false, }) - _, err = addTarget(p, p.pid, currentThread, exePath, proc.StopAttached) + _, err = addTarget(p, p.pid, currentThread, exePath, proc.StopAttached, "") return grp, err } diff --git a/pkg/proc/gdbserial/gdbserver.go b/pkg/proc/gdbserial/gdbserver.go index 2bb871991e..b51545a044 100644 --- a/pkg/proc/gdbserial/gdbserver.go +++ b/pkg/proc/gdbserial/gdbserver.go @@ -278,7 +278,7 @@ func newProcess(process *os.Process) *gdbProcess { } // Listen waits for a connection from the stub. -func (p *gdbProcess) Listen(listener net.Listener, path string, pid int, debugInfoDirs []string, stopReason proc.StopReason) (*proc.TargetGroup, error) { +func (p *gdbProcess) Listen(listener net.Listener, path, cmdline string, pid int, debugInfoDirs []string, stopReason proc.StopReason) (*proc.TargetGroup, error) { acceptChan := make(chan net.Conn) go func() { @@ -292,7 +292,7 @@ func (p *gdbProcess) Listen(listener net.Listener, path string, pid int, debugIn if conn == nil { return nil, errors.New("could not connect") } - return p.Connect(conn, path, pid, debugInfoDirs, stopReason) + return p.Connect(conn, path, cmdline, pid, debugInfoDirs, stopReason) case status := <-p.waitChan: listener.Close() return nil, fmt.Errorf("stub exited while waiting for connection: %v", status) @@ -300,11 +300,11 @@ func (p *gdbProcess) Listen(listener net.Listener, path string, pid int, debugIn } // Dial attempts to connect to the stub. -func (p *gdbProcess) Dial(addr string, path string, pid int, debugInfoDirs []string, stopReason proc.StopReason) (*proc.TargetGroup, error) { +func (p *gdbProcess) Dial(addr string, path, cmdline string, pid int, debugInfoDirs []string, stopReason proc.StopReason) (*proc.TargetGroup, error) { for { conn, err := net.Dial("tcp", addr) if err == nil { - return p.Connect(conn, path, pid, debugInfoDirs, stopReason) + return p.Connect(conn, path, cmdline, pid, debugInfoDirs, stopReason) } select { case status := <-p.waitChan: @@ -321,7 +321,7 @@ func (p *gdbProcess) Dial(addr string, path string, pid int, debugInfoDirs []str // program and the PID of the target process, both are optional, however // some stubs do not provide ways to determine path and pid automatically // and Connect will be unable to function without knowing them. -func (p *gdbProcess) Connect(conn net.Conn, path string, pid int, debugInfoDirs []string, stopReason proc.StopReason) (*proc.TargetGroup, error) { +func (p *gdbProcess) Connect(conn net.Conn, path, cmdline string, pid int, debugInfoDirs []string, stopReason proc.StopReason) (*proc.TargetGroup, error) { p.conn.conn = conn p.conn.pid = pid err := p.conn.handshake(p.regnames) @@ -345,7 +345,7 @@ func (p *gdbProcess) Connect(conn net.Conn, path string, pid int, debugInfoDirs p.gcmdok = false } - tgt, err := p.initialize(path, debugInfoDirs, stopReason) + tgt, err := p.initialize(path, cmdline, debugInfoDirs, stopReason) if err != nil { return nil, err } @@ -569,9 +569,9 @@ func LLDBLaunch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs [ var grp *proc.TargetGroup if listener != nil { - grp, err = p.Listen(listener, cmd[0], 0, debugInfoDirs, proc.StopLaunched) + grp, err = p.Listen(listener, cmd[0], strings.Join(cmd, " "), 0, debugInfoDirs, proc.StopLaunched) } else { - grp, err = p.Dial(port, cmd[0], 0, debugInfoDirs, proc.StopLaunched) + grp, err = p.Dial(port, cmd[0], strings.Join(cmd, " "), 0, debugInfoDirs, proc.StopLaunched) } if p.conn.pid != 0 && foreground && isatty.IsTerminal(os.Stdin.Fd()) { // Make the target process the controlling process of the tty if it is a foreground process. @@ -635,9 +635,9 @@ func LLDBAttach(pid int, path string, debugInfoDirs []string) (*proc.TargetGroup var grp *proc.TargetGroup if listener != nil { - grp, err = p.Listen(listener, path, pid, debugInfoDirs, proc.StopAttached) + grp, err = p.Listen(listener, path, "", pid, debugInfoDirs, proc.StopAttached) } else { - grp, err = p.Dial(port, path, pid, debugInfoDirs, proc.StopAttached) + grp, err = p.Dial(port, path, "", pid, debugInfoDirs, proc.StopAttached) } return grp, err } @@ -673,7 +673,7 @@ func (p *gdbProcess) EntryPoint() (uint64, error) { // initialize uses qProcessInfo to load the inferior's PID and // executable path. This command is not supported by all stubs and not all // stubs will report both the PID and executable path. -func (p *gdbProcess) initialize(path string, debugInfoDirs []string, stopReason proc.StopReason) (*proc.TargetGroup, error) { +func (p *gdbProcess) initialize(path, cmdline string, debugInfoDirs []string, stopReason proc.StopReason) (*proc.TargetGroup, error) { var err error if path == "" { // If we are attaching to a running process and the user didn't specify @@ -730,7 +730,7 @@ func (p *gdbProcess) initialize(path string, debugInfoDirs []string, stopReason StopReason: stopReason, CanDump: runtime.GOOS == "darwin", }) - _, err = addTarget(p, p.conn.pid, p.currentThread, path, stopReason) + _, err = addTarget(p, p.conn.pid, p.currentThread, path, stopReason, cmdline) if err != nil { p.Detach(true) return nil, err diff --git a/pkg/proc/gdbserial/rr.go b/pkg/proc/gdbserial/rr.go index c58a69836c..364191241f 100644 --- a/pkg/proc/gdbserial/rr.go +++ b/pkg/proc/gdbserial/rr.go @@ -124,7 +124,7 @@ func Record(cmd []string, wd string, quiet bool, redirects [3]string) (tracedir // Replay starts an instance of rr in replay mode, with the specified trace // directory, and connects to it. -func Replay(tracedir string, quiet, deleteOnDetach bool, debugInfoDirs []string, rrOnProcessPid int) (*proc.TargetGroup, error) { +func Replay(tracedir string, quiet, deleteOnDetach bool, debugInfoDirs []string, rrOnProcessPid int, cmdline string) (*proc.TargetGroup, error) { if err := checkRRAvailable(); err != nil { return nil, err } @@ -168,7 +168,7 @@ func Replay(tracedir string, quiet, deleteOnDetach bool, debugInfoDirs []string, safeRemoveAll(p.tracedir) } } - tgt, err := p.Dial(init.port, init.exe, 0, debugInfoDirs, proc.StopLaunched) + tgt, err := p.Dial(init.port, init.exe, cmdline, 0, debugInfoDirs, proc.StopLaunched) if err != nil { rrcmd.Process.Kill() return nil, err @@ -293,7 +293,7 @@ func RecordAndReplay(cmd []string, wd string, quiet bool, debugInfoDirs []string if tracedir == "" { return nil, "", err } - t, err := Replay(tracedir, quiet, true, debugInfoDirs, 0) + t, err := Replay(tracedir, quiet, true, debugInfoDirs, 0, strings.Join(cmd, " ")) return t, tracedir, err } diff --git a/pkg/proc/native/nonative_darwin.go b/pkg/proc/native/nonative_darwin.go index d0f7b19a51..b60ee32d54 100644 --- a/pkg/proc/native/nonative_darwin.go +++ b/pkg/proc/native/nonative_darwin.go @@ -142,4 +142,4 @@ func (t *nativeThread) SoftExc() bool { panic(ErrNativeBackendDisabled) } -func initialize(dbp *nativeProcess) error { return nil } +func initialize(dbp *nativeProcess) (string, error) { return "", nil } diff --git a/pkg/proc/native/proc.go b/pkg/proc/native/proc.go index 69423f29dc..c886202b99 100644 --- a/pkg/proc/native/proc.go +++ b/pkg/proc/native/proc.go @@ -207,12 +207,14 @@ func (procgrp *processGroup) procForThread(tid int) *nativeProcess { return nil } -func (procgrp *processGroup) add(p *nativeProcess, pid int, currentThread proc.Thread, path string, stopReason proc.StopReason) (*proc.Target, error) { - tgt, err := procgrp.addTarget(p, pid, currentThread, path, stopReason) +func (procgrp *processGroup) add(p *nativeProcess, pid int, currentThread proc.Thread, path string, stopReason proc.StopReason, cmdline string) (*proc.Target, error) { + tgt, err := procgrp.addTarget(p, pid, currentThread, path, stopReason, cmdline) if err != nil { return nil, err } - procgrp.procs = append(procgrp.procs, p) + if tgt != nil { + procgrp.procs = append(procgrp.procs, p) + } return tgt, nil } @@ -285,20 +287,24 @@ func (dbp *nativeProcess) FindBreakpoint(pc uint64, adjustPC bool) (*proc.Breakp return nil, false } -func (dbp *nativeProcess) initializeBasic() error { - if err := initialize(dbp); err != nil { - return err +func (dbp *nativeProcess) initializeBasic() (string, error) { + cmdline, err := initialize(dbp) + if err != nil { + return "", err } if err := dbp.updateThreadList(); err != nil { - return err + return "", err } - return nil + return cmdline, nil } // initialize will ensure that all relevant information is loaded // so the process is ready to be debugged. func (dbp *nativeProcess) initialize(path string, debugInfoDirs []string) (*proc.TargetGroup, error) { - dbp.initializeBasic() + cmdline, err := dbp.initializeBasic() + if err != nil { + return nil, err + } stopReason := proc.StopLaunched if !dbp.childProcess { stopReason = proc.StopAttached @@ -321,7 +327,7 @@ func (dbp *nativeProcess) initialize(path string, debugInfoDirs []string) (*proc CanDump: runtime.GOOS == "linux" || runtime.GOOS == "freebsd" || (runtime.GOOS == "windows" && runtime.GOARCH == "amd64"), }) procgrp.addTarget = addTarget - tgt, err := procgrp.add(dbp, dbp.pid, dbp.memthread, path, stopReason) + tgt, err := procgrp.add(dbp, dbp.pid, dbp.memthread, path, stopReason, cmdline) if err != nil { return nil, err } diff --git a/pkg/proc/native/proc_darwin.go b/pkg/proc/native/proc_darwin.go index c8eca1da2e..83eb2dbc7d 100644 --- a/pkg/proc/native/proc_darwin.go +++ b/pkg/proc/native/proc_darwin.go @@ -489,4 +489,4 @@ func (dbp *nativeProcess) GetBufferedTracepoints() []ebpf.RawUProbeParams { panic("not implemented") } -func initialize(dbp *nativeProcess) error { return nil } +func initialize(dbp *nativeProcess) (string, error) { return "", nil } diff --git a/pkg/proc/native/proc_freebsd.c b/pkg/proc/native/proc_freebsd.c index 887aa4df1c..8716f614ed 100644 --- a/pkg/proc/native/proc_freebsd.c +++ b/pkg/proc/native/proc_freebsd.c @@ -2,11 +2,7 @@ #include #include #include -#include -#include -#include -#include #include #include #include diff --git a/pkg/proc/native/proc_freebsd.go b/pkg/proc/native/proc_freebsd.go index 40581e5ae9..51f4889658 100644 --- a/pkg/proc/native/proc_freebsd.go +++ b/pkg/proc/native/proc_freebsd.go @@ -142,12 +142,12 @@ func Attach(pid int, debugInfoDirs []string) (*proc.TargetGroup, error) { return tgt, nil } -func initialize(dbp *nativeProcess) error { +func initialize(dbp *nativeProcess) (string, error) { comm, _ := C.find_command_name(C.int(dbp.pid)) defer C.free(unsafe.Pointer(comm)) comm_str := C.GoString(comm) dbp.os.comm = strings.ReplaceAll(string(comm_str), "%", "%%") - return nil + return getCmdLine(dbp.pid), nil } // kill kills the target process. @@ -227,6 +227,24 @@ func findExecutable(path string, pid int) string { return path } +func getCmdLine(pid int) string { + ps := C.procstat_open_sysctl() + kp := C.kinfo_getproc(C.int(pid)) + argv := C.procstat_getargv(ps, kp, 0) + goargv := []string{} + for { + arg := *argv + if arg == nil { + break + } + argv = (**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(argv)) + unsafe.Sizeof(*argv))) + goargv = append(goargv, C.GoString(arg)) + } + C.free(unsafe.Pointer(kp)) + C.procstat_close(ps) + return strings.Join(goargv, " ") +} + func trapWait(procgrp *processGroup, pid int) (*nativeThread, error) { return procgrp.procs[0].trapWaitInternal(pid, trapWaitNormal) } diff --git a/pkg/proc/native/proc_freebsd.h b/pkg/proc/native/proc_freebsd.h index 76bbc38309..645c3e1035 100644 --- a/pkg/proc/native/proc_freebsd.h +++ b/pkg/proc/native/proc_freebsd.h @@ -1,4 +1,7 @@ #include +#include +#include +#include char * find_command_name(int pid); char * find_executable(int pid); diff --git a/pkg/proc/native/proc_linux.go b/pkg/proc/native/proc_linux.go index e549928b58..a05ecb24f7 100644 --- a/pkg/proc/native/proc_linux.go +++ b/pkg/proc/native/proc_linux.go @@ -169,7 +169,7 @@ func Attach(pid int, debugInfoDirs []string) (*proc.TargetGroup, error) { return tgt, nil } -func initialize(dbp *nativeProcess) error { +func initialize(dbp *nativeProcess) (string, error) { comm, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/comm", dbp.pid)) if err == nil { // removes newline character @@ -179,22 +179,22 @@ func initialize(dbp *nativeProcess) error { if comm == nil || len(comm) <= 0 { stat, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/stat", dbp.pid)) if err != nil { - return fmt.Errorf("could not read proc stat: %v", err) + return "", fmt.Errorf("could not read proc stat: %v", err) } expr := fmt.Sprintf("%d\\s*\\((.*)\\)", dbp.pid) rexp, err := regexp.Compile(expr) if err != nil { - return fmt.Errorf("regexp compile error: %v", err) + return "", fmt.Errorf("regexp compile error: %v", err) } match := rexp.FindSubmatch(stat) if match == nil { - return fmt.Errorf("no match found using regexp '%s' in /proc/%d/stat", expr, dbp.pid) + return "", fmt.Errorf("no match found using regexp '%s' in /proc/%d/stat", expr, dbp.pid) } comm = match[1] } dbp.os.comm = strings.ReplaceAll(string(comm), "%", "%%") - return nil + return getCmdLine(dbp.pid), nil } func (dbp *nativeProcess) GetBufferedTracepoints() []ebpf.RawUProbeParams { @@ -460,8 +460,8 @@ func trapWaitInternal(procgrp *processGroup, pid int, options trapWaitOptions) ( } dbp = newChildProcess(procgrp.procs[0], wpid) dbp.followExec = true - dbp.initializeBasic() - _, err := procgrp.add(dbp, dbp.pid, dbp.memthread, findExecutable("", dbp.pid), proc.StopLaunched) + cmdline, _ := dbp.initializeBasic() + tgt, err := procgrp.add(dbp, dbp.pid, dbp.memthread, findExecutable("", dbp.pid), proc.StopLaunched, cmdline) if err != nil { _ = dbp.Detach(false) return nil, err @@ -469,12 +469,16 @@ func trapWaitInternal(procgrp *processGroup, pid int, options trapWaitOptions) ( if halt { return nil, nil } - // TODO(aarzilli): if we want to give users the ability to stop the target - // group on exec here is where we should return - err = dbp.threads[dbp.pid].Continue() - if err != nil { - return nil, err + if tgt != nil { + // If tgt is nil we decided we are not interested in debugging this + // process, and we have already detached from it. + err = dbp.threads[dbp.pid].Continue() + if err != nil { + return nil, err + } } + //TODO(aarzilli): if we want to give users the ability to stop the target + //group on exec here is where we should return continue } if th == nil { @@ -917,3 +921,17 @@ func (dbp *nativeProcess) FollowExec(v bool) error { func killProcess(pid int) error { return sys.Kill(pid, sys.SIGINT) } + +func getCmdLine(pid int) string { + buf, _ := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid)) + args := strings.SplitN(string(buf), "\x00", -1) + for i := range args { + if strings.Contains(args[i], " ") { + args[i] = strconv.Quote(args[i]) + } + } + if len(args) > 0 && args[len(args)-1] == "" { + args = args[:len(args)-1] + } + return strings.Join(args, " ") +} diff --git a/pkg/proc/native/proc_windows.go b/pkg/proc/native/proc_windows.go index 705fe6e500..318533e83b 100644 --- a/pkg/proc/native/proc_windows.go +++ b/pkg/proc/native/proc_windows.go @@ -4,10 +4,12 @@ import ( "fmt" "os" "syscall" + "unicode/utf16" "unsafe" sys "golang.org/x/sys/windows" + "github.com/go-delve/delve/pkg/logflags" "github.com/go-delve/delve/pkg/proc" "github.com/go-delve/delve/pkg/proc/internal/ebpf" ) @@ -68,7 +70,7 @@ func Launch(cmd []string, wd string, flags proc.LaunchFlags, _ []string, _ strin return tgt, nil } -func initialize(dbp *nativeProcess) error { +func initialize(dbp *nativeProcess) (string, error) { // It should not actually be possible for the // call to waitForDebugEvent to fail, since Windows // will always fire a CREATE_PROCESS_DEBUG_EVENT event @@ -80,19 +82,22 @@ func initialize(dbp *nativeProcess) error { tid, exitCode, err = dbp.waitForDebugEvent(waitBlocking) }) if err != nil { - return err + return "", err } if tid == 0 { dbp.postExit() - return proc.ErrProcessExited{Pid: dbp.pid, Status: exitCode} + return "", proc.ErrProcessExited{Pid: dbp.pid, Status: exitCode} } + + cmdline := dbp.getCmdLine() + // Suspend all threads so that the call to _ContinueDebugEvent will // not resume the target. for _, thread := range dbp.threads { if !thread.os.dbgUiRemoteBreakIn { _, err := _SuspendThread(thread.os.hThread) if err != nil { - return err + return "", err } } } @@ -100,10 +105,10 @@ func initialize(dbp *nativeProcess) error { dbp.execPtraceFunc(func() { err = _ContinueDebugEvent(uint32(dbp.pid), uint32(dbp.os.breakThread), _DBG_CONTINUE) }) - return err + return cmdline, err } -// findExePath searches for process pid, and returns its executable path. +// findExePath searches for process pid, and returns its executable path func findExePath(pid int) (string, error) { // Original code suggested different approach (see below). // Maybe it could be useful in the future. @@ -604,6 +609,129 @@ func (dbp *nativeProcess) GetBufferedTracepoints() []ebpf.RawUProbeParams { return nil } +type _PROCESS_BASIC_INFORMATION struct { + ExitStatus sys.NTStatus + PebBaseAddress uintptr + AffinityMask uintptr + BasePriority int32 + UniqueProcessId uintptr + InheritedFromUniqueProcessId uintptr +} + +type _PEB struct { + reserved1 [2]byte + BeingDebugged byte + BitField byte + reserved3 uintptr + ImageBaseAddress uintptr + Ldr uintptr + ProcessParameters uintptr + reserved4 [3]uintptr + AtlThunkSListPtr uintptr + reserved5 uintptr + reserved6 uint32 + reserved7 uintptr + reserved8 uint32 + AtlThunkSListPtr32 uint32 + reserved9 [45]uintptr + reserved10 [96]byte + PostProcessInitRoutine uintptr + reserved11 [128]byte + reserved12 [1]uintptr + SessionId uint32 +} + +type _RTL_USER_PROCESS_PARAMETERS struct { + MaximumLength, Length uint32 + + Flags, DebugFlags uint32 + + ConsoleHandle sys.Handle + ConsoleFlags uint32 + StandardInput, StandardOutput, StandardError sys.Handle + + CurrentDirectory struct { + DosPath _NTUnicodeString + Handle sys.Handle + } + + DllPath _NTUnicodeString + ImagePathName _NTUnicodeString + CommandLine _NTUnicodeString + Environment unsafe.Pointer + + StartingX, StartingY, CountX, CountY, CountCharsX, CountCharsY, FillAttribute uint32 + + WindowFlags, ShowWindowFlags uint32 + WindowTitle, DesktopInfo, ShellInfo, RuntimeData _NTUnicodeString + CurrentDirectories [32]struct { + Flags uint16 + Length uint16 + TimeStamp uint32 + DosPath _NTString + } + + EnvironmentSize, EnvironmentVersion uintptr + + PackageDependencyData uintptr + ProcessGroupId uint32 + LoaderThreads uint32 + + RedirectionDllName _NTUnicodeString + HeapPartitionName _NTUnicodeString + DefaultThreadpoolCpuSetMasks uintptr + DefaultThreadpoolCpuSetMaskCount uint32 +} + +type _NTString struct { + Length uint16 + MaximumLength uint16 + Buffer uintptr +} + +type _NTUnicodeString struct { + Length uint16 + MaximumLength uint16 + Buffer uintptr +} + +func (dbp *nativeProcess) getCmdLine() string { + logger := logflags.DebuggerLogger() + var info _PROCESS_BASIC_INFORMATION + err := sys.NtQueryInformationProcess(sys.Handle(dbp.os.hProcess), sys.ProcessBasicInformation, unsafe.Pointer(&info), uint32(unsafe.Sizeof(info)), nil) + if err != nil { + logger.Errorf("NtQueryInformationProcess: %v", err) + return "" + } + var peb _PEB + err = _ReadProcessMemory(dbp.os.hProcess, info.PebBaseAddress, (*byte)(unsafe.Pointer(&peb)), unsafe.Sizeof(peb), nil) + if err != nil { + logger.Errorf("Reading PEB: %v", err) + return "" + } + var upp _RTL_USER_PROCESS_PARAMETERS + err = _ReadProcessMemory(dbp.os.hProcess, peb.ProcessParameters, (*byte)(unsafe.Pointer(&upp)), unsafe.Sizeof(upp), nil) + if err != nil { + logger.Errorf("Reading ProcessParameters: %v", err) + return "" + } + if upp.CommandLine.Length%2 != 0 { + logger.Errorf("CommandLine length not a multiple of 2") + return "" + } + buf := make([]byte, upp.CommandLine.Length) + err = _ReadProcessMemory(dbp.os.hProcess, upp.CommandLine.Buffer, &buf[0], uintptr(len(buf)), nil) + if err != nil { + logger.Errorf("Reading CommandLine: %v", err) + return "" + } + utf16buf := make([]uint16, len(buf)/2) + for i := 0; i < len(buf); i += 2 { + utf16buf[i/2] = uint16(buf[i+1])<<8 + uint16(buf[i]) + } + return string(utf16.Decode(utf16buf)) +} + func killProcess(pid int) error { p, err := os.FindProcess(pid) if err != nil { diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index ebdbe086ff..9706ace1c5 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -172,6 +172,17 @@ func assertLineNumber(p *proc.Target, t *testing.T, lineno int, descr string) (s return f, l } +func assertFunctionName(p *proc.Target, t *testing.T, fnname string, descr string) { + pc := currentPC(p, t) + f, l, fn := p.BinInfo().PCToLine(pc) + if fn == nil { + t.Fatalf("%s expected function %s got %s:%d", descr, fnname, f, l) + } + if fn.Name != fnname { + t.Fatalf("%s expected function %s got %s %s:%d", descr, fnname, fn.Name, f, l) + } +} + func TestExit(t *testing.T) { protest.AllowRecording(t) withTestProcess("continuetestprog", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { @@ -6118,3 +6129,43 @@ func TestStepShadowConcurrentBreakpoint(t *testing.T) { } }) } + +func TestFollowExecRegexFilter(t *testing.T) { + skipUnlessOn(t, "follow exec only supported on linux", "linux") + withTestProcessArgs("spawn", t, ".", []string{"spawn", "3"}, 0, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { + grp.LogicalBreakpoints[1] = &proc.LogicalBreakpoint{LogicalID: 1, Set: proc.SetBreakpoint{FunctionName: "main.traceme1"}, HitCount: make(map[int64]uint64)} + grp.LogicalBreakpoints[2] = &proc.LogicalBreakpoint{LogicalID: 2, Set: proc.SetBreakpoint{FunctionName: "main.traceme2"}, HitCount: make(map[int64]uint64)} + grp.LogicalBreakpoints[3] = &proc.LogicalBreakpoint{LogicalID: 3, Set: proc.SetBreakpoint{FunctionName: "main.traceme3"}, HitCount: make(map[int64]uint64)} + + assertNoError(grp.EnableBreakpoint(grp.LogicalBreakpoints[1]), t, "EnableBreakpoint(main.traceme1)") + assertNoError(grp.EnableBreakpoint(grp.LogicalBreakpoints[3]), t, "EnableBreakpoint(main.traceme3)") + + assertNoError(grp.FollowExec(true, "spawn.* child C1"), t, "FollowExec") + + assertNoError(grp.Continue(), t, "Continue 1") + assertFunctionName(grp.Selected, t, "main.traceme1", "Program did not continue to the expected location (1)") + assertNoError(grp.Continue(), t, "Continue 2") + assertFunctionName(grp.Selected, t, "main.traceme2", "Program did not continue to the expected location (2)") + assertNoError(grp.Continue(), t, "Continue 3") + assertFunctionName(grp.Selected, t, "main.traceme3", "Program did not continue to the expected location (3)") + err := grp.Continue() + if err != nil { + _, isexited := err.(proc.ErrProcessExited) + if !isexited { + assertNoError(err, t, "Continue 4") + } + } else { + t.Fatal("process did not exit after 4 continues") + } + }) +} + +func TestReadTargetArguments(t *testing.T) { + protest.AllowRecording(t) + withTestProcessArgs("restartargs", t, ".", []string{"one", "two", "three"}, 0, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { + t.Logf("command line: %q\n", p.CmdLine) + if !strings.HasSuffix(p.CmdLine, " one two three") { + t.Fatalf("wrong command line") + } + }) +} diff --git a/pkg/proc/target.go b/pkg/proc/target.go index 05bae74f97..079a99d955 100644 --- a/pkg/proc/target.go +++ b/pkg/proc/target.go @@ -41,7 +41,8 @@ type Target struct { proc ProcessInternal recman RecordingManipulationInternal - pid int + pid int + CmdLine string // StopReason describes the reason why the target process is stopped. // A process could be stopped for multiple simultaneous reasons, in which @@ -160,7 +161,7 @@ func DisableAsyncPreemptEnv() []string { // newTarget returns an initialized Target object. // The p argument can optionally implement the RecordingManipulation interface. -func (grp *TargetGroup) newTarget(p ProcessInternal, pid int, currentThread Thread, path string) (*Target, error) { +func (grp *TargetGroup) newTarget(p ProcessInternal, pid int, currentThread Thread, path, cmdline string) (*Target, error) { entryPoint, err := p.EntryPoint() if err != nil { return nil, err @@ -182,6 +183,7 @@ func (grp *TargetGroup) newTarget(p ProcessInternal, pid int, currentThread Thre fncallForG: make(map[int64]*callInjection), currentThread: currentThread, pid: pid, + CmdLine: cmdline, } if recman, ok := p.(RecordingManipulationInternal); ok { diff --git a/pkg/proc/target_group.go b/pkg/proc/target_group.go index 5a746399e1..e388310c3c 100644 --- a/pkg/proc/target_group.go +++ b/pkg/proc/target_group.go @@ -2,8 +2,8 @@ package proc import ( "bytes" - "errors" "fmt" + "regexp" "strings" "github.com/go-delve/delve/pkg/logflags" @@ -20,6 +20,7 @@ type TargetGroup struct { targets []*Target Selected *Target followExecEnabled bool + followExecRegex *regexp.Regexp RecordingManipulation recman RecordingManipulationInternal @@ -48,7 +49,7 @@ type NewTargetGroupConfig struct { CanDump bool // Can create core dumps (must implement ProcessInternal.MemoryMap) } -type AddTargetFunc func(ProcessInternal, int, Thread, string, StopReason) (*Target, error) +type AddTargetFunc func(ProcessInternal, int, Thread, string, StopReason, string) (*Target, error) // NewGroup creates a TargetGroup containing the specified Target. func NewGroup(procgrp ProcessGroup, cfg NewTargetGroupConfig) (*TargetGroup, AddTargetFunc) { @@ -86,17 +87,29 @@ func Restart(grp, oldgrp *TargetGroup, discard func(*LogicalBreakpoint, error)) } } if oldgrp.followExecEnabled { - grp.FollowExec(true, "") + rgx := "" + if oldgrp.followExecRegex != nil { + rgx = oldgrp.followExecRegex.String() + } + grp.FollowExec(true, rgx) } } -func (grp *TargetGroup) addTarget(p ProcessInternal, pid int, currentThread Thread, path string, stopReason StopReason) (*Target, error) { - t, err := grp.newTarget(p, pid, currentThread, path) +func (grp *TargetGroup) addTarget(p ProcessInternal, pid int, currentThread Thread, path string, stopReason StopReason, cmdline string) (*Target, error) { + logger := logflags.DebuggerLogger() + t, err := grp.newTarget(p, pid, currentThread, path, cmdline) if err != nil { return nil, err } t.StopReason = stopReason - //TODO(aarzilli): check if the target's command line matches the regex + if grp.followExecRegex != nil && len(grp.targets) > 0 { + if !grp.followExecRegex.MatchString(cmdline) { + logger.Debugf("Detaching from child target %d %q", t.Pid(), t.CmdLine) + t.detach(false) + return nil, nil + } + } + logger.Debugf("Adding target %d %q", t.Pid(), t.CmdLine) if t.partOfGroup { panic("internal error: target is already part of group") } @@ -108,7 +121,7 @@ func (grp *TargetGroup) addTarget(p ProcessInternal, pid int, currentThread Thre if grp.Selected == nil { grp.Selected = t } - logger := logflags.DebuggerLogger() + t.Breakpoints().Logical = grp.LogicalBreakpoints for _, lbp := range grp.LogicalBreakpoints { if lbp.LogicalID < 0 { continue @@ -340,8 +353,13 @@ func (grp *TargetGroup) DisableBreakpoint(lbp *LogicalBreakpoint) error { // If regex is not the empty string only processes whose command line // matches regex will be added to the target group. func (grp *TargetGroup) FollowExec(v bool, regex string) error { - if regex != "" { - return errors.New("regex not implemented") + grp.followExecRegex = nil + if regex != "" && v { + var err error + grp.followExecRegex, err = regexp.Compile(regex) + if err != nil { + return err + } } it := ValidTargets{Group: grp} for it.Next() { diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index f894703f0d..d729311db6 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -2564,7 +2564,7 @@ func printcontext(t *Term, state *api.DebuggerState) { if state.Pid != t.oldPid { if t.oldPid != 0 { - fmt.Fprintf(t.stdout, "Switch target process from %d to %d\n", t.oldPid, state.Pid) + fmt.Fprintf(t.stdout, "Switch target process from %d to %d (%s)\n", t.oldPid, state.Pid, state.TargetCommandLine) } t.oldPid = state.Pid } diff --git a/service/api/conversions.go b/service/api/conversions.go index f386c69b41..0d66749eb6 100644 --- a/service/api/conversions.go +++ b/service/api/conversions.go @@ -454,9 +454,9 @@ func ConvertDumpState(dumpState *proc.DumpState) *DumpState { // ConvertTarget converts a proc.Target into a api.Target. func ConvertTarget(tgt *proc.Target, convertThreadBreakpoint func(proc.Thread) *Breakpoint) *Target { - //TODO(aarzilli): copy command line here return &Target{ Pid: tgt.Pid(), + CmdLine: tgt.CmdLine, CurrentThread: ConvertThread(tgt.CurrentThread(), convertThreadBreakpoint(tgt.CurrentThread())), } } diff --git a/service/api/types.go b/service/api/types.go index 7c5de83796..8c48842ae9 100644 --- a/service/api/types.go +++ b/service/api/types.go @@ -19,6 +19,8 @@ var ErrNotExecutable = errors.New("not an executable file") type DebuggerState struct { // PID of the process we are debugging. Pid int + // Command line of the process we are debugging. + TargetCommandLine string // Running is true if the process is running and no other information can be collected. Running bool // Recording is true if the process is currently being recorded and no other diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index ed1e106726..af5eb5c1b1 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -176,7 +176,7 @@ func New(config *Config, processArgs []string) (*Debugger, error) { switch d.config.Backend { case "rr": d.log.Infof("opening trace %s", d.config.CoreFile) - d.target, err = gdbserial.Replay(d.config.CoreFile, false, false, d.config.DebugInfoDirectories, d.config.RrOnProcessPid) + d.target, err = gdbserial.Replay(d.config.CoreFile, false, false, d.config.DebugInfoDirectories, d.config.RrOnProcessPid, "") default: d.log.Infof("opening core file %s (executable %s)", d.config.CoreFile, d.processArgs[0]) d.target, err = core.OpenCore(d.config.CoreFile, d.processArgs[0], d.config.DebugInfoDirectories) @@ -335,7 +335,7 @@ func (d *Debugger) recordingRun(run func() (string, error)) (*proc.TargetGroup, return nil, err } - return gdbserial.Replay(tracedir, false, true, d.config.DebugInfoDirectories, 0) + return gdbserial.Replay(tracedir, false, true, d.config.DebugInfoDirectories, 0, strings.Join(d.processArgs, " ")) } // Attach will attach to the process specified by 'pid'. @@ -568,6 +568,7 @@ func (d *Debugger) state(retLoadCfg *proc.LoadConfig, withBreakpointInfo bool) ( state = &api.DebuggerState{ Pid: tgt.Pid(), + TargetCommandLine: tgt.CmdLine, SelectedGoroutine: goroutine, Exited: exited, } From 674bd63996836e675079cfabe4ece449a0f69398 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 15 May 2023 19:21:52 +0200 Subject: [PATCH 031/114] proc: fix runtime type handling for Go 1.21 (#3370) Go 1.21 renamed runtime._type to internal/abi.Type and changed the name of its fields. Update Delve so that it uses the new names for loading interfaces and generic type parameters. --- _scripts/rtype-out.txt | 4 ++-- pkg/proc/bininfo.go | 12 ++++++++-- pkg/proc/fncall.go | 6 +++-- pkg/proc/proc_test.go | 6 ++++- pkg/proc/types.go | 11 ++++++--- pkg/proc/variables.go | 48 ++++++++++++++++++++++---------------- pkg/proc/variables_test.go | 3 ++- 7 files changed, 59 insertions(+), 31 deletions(-) diff --git a/_scripts/rtype-out.txt b/_scripts/rtype-out.txt index 8799bfa837..7783cf447c 100644 --- a/_scripts/rtype-out.txt +++ b/_scripts/rtype-out.txt @@ -15,7 +15,7 @@ type bmap struct { } type eface struct { - _type *_type + _type *_type|*internal/abi.Type data unsafe.Pointer } @@ -50,7 +50,7 @@ type iface struct { } type itab struct { - _type *_type + _type *_type|*internal/abi.Type } type moduledata struct { diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go index a12aac8a8c..4cd41dc4d8 100644 --- a/pkg/proc/bininfo.go +++ b/pkg/proc/bininfo.go @@ -900,6 +900,13 @@ func (bi *BinaryInfo) typeToImage(typ godwarf.Type) *Image { return bi.Images[typ.Common().Index] } +func (bi *BinaryInfo) runtimeTypeTypename() string { + if goversion.ProducerAfterOrEqual(bi.Producer(), 1, 21) { + return "internal/abi.Type" + } + return "runtime._type" +} + var errBinaryInfoClose = errors.New("multiple errors closing executable files") // Close closes all internal readers. @@ -2130,10 +2137,11 @@ func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugInfoBytes, debugLineB if fn != nil && fn.cu.image == image { tree, err := image.getDwarfTree(fn.offset) if err == nil { - tree.Children, err = regabiMallocgcWorkaround(bi) + children, err := regabiMallocgcWorkaround(bi) if err != nil { - bi.logger.Errorf("could not patch runtime.mallogc: %v", err) + bi.logger.Errorf("could not patch runtime.mallocgc: %v", err) } else { + tree.Children = children image.runtimeMallocgcTree = tree } } diff --git a/pkg/proc/fncall.go b/pkg/proc/fncall.go index f5dd79a952..bd0df51534 100644 --- a/pkg/proc/fncall.go +++ b/pkg/proc/fncall.go @@ -1263,6 +1263,8 @@ func (e fakeEntry) AttrField(attr dwarf.Attr) *dwarf.Field { } func regabiMallocgcWorkaround(bi *BinaryInfo) ([]*godwarf.Tree, error) { + ptrToRuntimeType := "*" + bi.runtimeTypeTypename() + var err1 error t := func(name string) godwarf.Type { @@ -1298,7 +1300,7 @@ func regabiMallocgcWorkaround(bi *BinaryInfo) ([]*godwarf.Tree, error) { case "amd64": r := []*godwarf.Tree{ m("size", t("uintptr"), regnum.AMD64_Rax, false), - m("typ", t("*runtime._type"), regnum.AMD64_Rbx, false), + m("typ", t(ptrToRuntimeType), regnum.AMD64_Rbx, false), m("needzero", t("bool"), regnum.AMD64_Rcx, false), m("~r1", t("unsafe.Pointer"), regnum.AMD64_Rax, true), } @@ -1306,7 +1308,7 @@ func regabiMallocgcWorkaround(bi *BinaryInfo) ([]*godwarf.Tree, error) { case "arm64": r := []*godwarf.Tree{ m("size", t("uintptr"), regnum.ARM64_X0, false), - m("typ", t("*runtime._type"), regnum.ARM64_X0+1, false), + m("typ", t(ptrToRuntimeType), regnum.ARM64_X0+1, false), m("needzero", t("bool"), regnum.ARM64_X0+2, false), m("~r1", t("unsafe.Pointer"), regnum.ARM64_X0, true), } diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 9706ace1c5..b6852d3d9f 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -4647,7 +4647,10 @@ func TestCgoStacktrace2(t *testing.T) { // If a panic happens during cgo execution the stacktrace should show the C // function that caused the problem. withTestProcess("cgosigsegvstack", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { - grp.Continue() + err := grp.Continue() + if _, exited := err.(proc.ErrProcessExited); exited { + t.Fatal("process exited") + } frames, err := proc.ThreadStacktrace(p.CurrentThread(), 100) assertNoError(err, t, "Stacktrace()") logStacktrace(t, p, frames) @@ -5099,6 +5102,7 @@ func TestStepOutPreservesGoroutine(t *testing.T) { candg := []*proc.G{} bestg := []*proc.G{} for _, g := range gs { + t.Logf("stacktracing goroutine %d (%v)\n", g.ID, g.CurrentLoc) frames, err := g.Stacktrace(20, 0) assertNoError(err, t, "Stacktrace") for _, frame := range frames { diff --git a/pkg/proc/types.go b/pkg/proc/types.go index 1940b26a5a..125bff123d 100644 --- a/pkg/proc/types.go +++ b/pkg/proc/types.go @@ -122,6 +122,8 @@ func runtimeTypeToDIE(_type *Variable, dataAddr uint64) (typ godwarf.Type, kind if rtdie.kind == -1 { if kindField := _type.loadFieldNamed("kind"); kindField != nil && kindField.Value != nil { rtdie.kind, _ = constant.Int64Val(kindField.Value) + } else if kindField := _type.loadFieldNamed("Kind_"); kindField != nil && kindField.Value != nil { + rtdie.kind, _ = constant.Int64Val(kindField.Value) } } return typ, rtdie.kind, nil @@ -146,7 +148,7 @@ func resolveParametricType(bi *BinaryInfo, mem MemoryReadWriter, t godwarf.Type, if err != nil { return ptyp.TypedefType.Type, err } - runtimeType, err := bi.findType("runtime._type") + runtimeType, err := bi.findType(bi.runtimeTypeTypename()) if err != nil { return ptyp.TypedefType.Type, err } @@ -189,13 +191,16 @@ func dwarfToRuntimeType(bi *BinaryInfo, mem MemoryReadWriter, typ godwarf.Type) typeAddr = uint64(md.types) + off - rtyp, err := bi.findType("runtime._type") + rtyp, err := bi.findType(bi.runtimeTypeTypename()) if err != nil { return 0, 0, false, err } _type := newVariable("", typeAddr, rtyp, bi, mem) kindv := _type.loadFieldNamed("kind") - if kindv.Unreadable != nil || kindv.Kind != reflect.Uint { + if kindv == nil || kindv.Unreadable != nil || kindv.Kind != reflect.Uint { + kindv = _type.loadFieldNamed("Kind_") + } + if kindv == nil || kindv.Unreadable != nil || kindv.Kind != reflect.Uint { return 0, 0, false, fmt.Errorf("unreadable interface type: %v", kindv.Unreadable) } typeKind, _ = constant.Uint64Val(kindv.Value) diff --git a/pkg/proc/variables.go b/pkg/proc/variables.go index e77515ff90..e04e16fa8b 100644 --- a/pkg/proc/variables.go +++ b/pkg/proc/variables.go @@ -671,7 +671,7 @@ func newVariable(name string, addr uint64, dwarfType godwarf.Type, bi *BinaryInf v.stride = 1 v.fieldType = &godwarf.UintType{BasicType: godwarf.BasicType{CommonType: godwarf.CommonType{ByteSize: 1, Name: "byte", ReflectKind: reflect.Uint8}, BitSize: 8, BitOffset: 0}} if v.Addr != 0 { - v.Base, v.Len, v.Unreadable = readStringInfo(v.mem, v.bi.Arch, v.Addr) + v.Base, v.Len, v.Unreadable = readStringInfo(v.mem, v.bi.Arch, v.Addr, t) } case *godwarf.SliceType: v.Kind = reflect.Slice @@ -1455,30 +1455,38 @@ func convertToEface(srcv, dstv *Variable) error { return dstv.writeEmptyInterface(typeAddr, srcv) } -func readStringInfo(mem MemoryReadWriter, arch *Arch, addr uint64) (uint64, int64, error) { +func readStringInfo(mem MemoryReadWriter, arch *Arch, addr uint64, typ *godwarf.StringType) (uint64, int64, error) { // string data structure is always two ptrs in size. Addr, followed by len // http://research.swtch.com/godata mem = cacheMemory(mem, addr, arch.PtrSize()*2) - // read len - strlen, err := readIntRaw(mem, addr+uint64(arch.PtrSize()), int64(arch.PtrSize())) - if err != nil { - return 0, 0, fmt.Errorf("could not read string len %s", err) - } - if strlen < 0 { - return 0, 0, fmt.Errorf("invalid length: %d", strlen) - } + var strlen int64 + var outaddr uint64 + var err error - // read addr - addr, err = readUintRaw(mem, addr, int64(arch.PtrSize())) - if err != nil { - return 0, 0, fmt.Errorf("could not read string pointer %s", err) - } - if addr == 0 { - return 0, 0, nil + for _, field := range typ.StructType.Field { + switch field.Name { + case "len": + strlen, err = readIntRaw(mem, addr+uint64(field.ByteOffset), int64(arch.PtrSize())) + if err != nil { + return 0, 0, fmt.Errorf("could not read string len %s", err) + } + if strlen < 0 { + return 0, 0, fmt.Errorf("invalid length: %d", strlen) + } + case "str": + outaddr, err = readUintRaw(mem, addr+uint64(field.ByteOffset), int64(arch.PtrSize())) + if err != nil { + return 0, 0, fmt.Errorf("could not read string pointer %s", err) + } + if addr == 0 { + return 0, 0, nil + } + } } - return addr, strlen, nil + + return outaddr, strlen, nil } func readStringValue(mem MemoryReadWriter, addr uint64, strlen int64, cfg LoadConfig) (string, error) { @@ -2248,7 +2256,7 @@ func (v *Variable) readInterface() (_type, data *Variable, isnil bool) { // +rtype -field iface.tab *itab // +rtype -field iface.data unsafe.Pointer - // +rtype -field eface._type *_type + // +rtype -field eface._type *_type|*internal/abi.Type // +rtype -field eface.data unsafe.Pointer for _, f := range ityp.Field { @@ -2259,7 +2267,7 @@ func (v *Variable) readInterface() (_type, data *Variable, isnil bool) { isnil = tab.Addr == 0 if !isnil { var err error - _type, err = tab.structMember("_type") // +rtype *_type + _type, err = tab.structMember("_type") // +rtype *_type|*internal/abi.Type if err != nil { v.Unreadable = fmt.Errorf("invalid interface type: %v", err) return diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go index 00f7f7b084..82c155e4f3 100644 --- a/pkg/proc/variables_test.go +++ b/pkg/proc/variables_test.go @@ -212,7 +212,7 @@ func TestSetVariable(t *testing.T) { assertNoError(err, t, "EvalVariable()") assertVariable(t, variable, varTest{tc.name, true, tc.startVal, "", tc.typ, nil}) - assertNoError(setVariable(p, tc.name, tc.expr), t, "SetVariable()") + assertNoError(setVariable(p, tc.name, tc.expr), t, fmt.Sprintf("SetVariable(%q, %q)", tc.name, tc.expr)) variable, err = evalVariableWithCfg(p, tc.name, pnormalLoadConfig) assertNoError(err, t, "EvalVariable()") @@ -856,6 +856,7 @@ func TestEvalExpression(t *testing.T) { assertNoError(grp.Continue(), t, "Continue() returned an error") for i, tc := range testcases { t.Run(strconv.Itoa(i), func(t *testing.T) { + t.Logf("%q", tc.name) variable, err := evalVariableWithCfg(p, tc.name, pnormalLoadConfig) if err != nil && err.Error() == "evaluating methods not supported on this version of Go" { // this type of eval is unsupported with the current version of Go. From 1c9792bce46b02bec3ae0af5f18fb9a8ca891f5c Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Mon, 15 May 2023 20:22:33 +0300 Subject: [PATCH 032/114] cmd/dlv: logger is not closed in connect command (#3367) --- cmd/dlv/cmds/commands.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/dlv/cmds/commands.go b/cmd/dlv/cmds/commands.go index 54b61ab939..44ab2ae26f 100644 --- a/cmd/dlv/cmds/commands.go +++ b/cmd/dlv/cmds/commands.go @@ -818,16 +818,18 @@ func connectCmd(cmd *cobra.Command, args []string) { os.Exit(1) return } - defer logflags.Close() if loadConfErr != nil { logflags.DebuggerLogger().Errorf("%v", loadConfErr) } addr := args[0] if addr == "" { fmt.Fprint(os.Stderr, "An empty address was provided. You must provide an address as the first argument.\n") + logflags.Close() os.Exit(1) } - os.Exit(connect(addr, nil, conf, debugger.ExecutingOther)) + ec := connect(addr, nil, conf, debugger.ExecutingOther) + logflags.Close() + os.Exit(ec) } // waitForDisconnectSignal is a blocking function that waits for either From 463b97dd3661f5f74b6ad17116a00ff893faf2d5 Mon Sep 17 00:00:00 2001 From: Zeke Lu Date: Tue, 16 May 2023 05:46:33 +0800 Subject: [PATCH 033/114] pkg/proc: pad variable mem in extractVarInfoFromEntry (#3365) * pkg/proc: pad variable mem in extractVarInfoFromEntry On 64 bit system, the byte size of the following struct is 16: type myStruct struct { a int b uint32 } But extractVarInfoFromEntry only allocates a mem of 12 bytes for it. When calling method of this struct with the "call" command, it will result in this error: write out of bounds This patch extends the mem by adding padding bytes to the end of the mem. Fixes #3364. * move the padding logic into newCompositeMemory --- _fixtures/fncall.go | 15 ++++++++++++++- pkg/proc/dwarf_export_test.go | 2 +- pkg/proc/mem.go | 11 ++++++++--- pkg/proc/target.go | 6 +++--- pkg/proc/variables.go | 4 ++-- pkg/proc/variables_test.go | 1 + 6 files changed, 29 insertions(+), 10 deletions(-) diff --git a/_fixtures/fncall.go b/_fixtures/fncall.go index f1839ca4ad..d5e8ef85b0 100644 --- a/_fixtures/fncall.go +++ b/_fixtures/fncall.go @@ -199,6 +199,15 @@ func (i Issue2698) String() string { return fmt.Sprintf("%d %d %d %d", i.a, i.b, i.c, i.d) } +type Issue3364 struct { + a int + b uint32 +} + +func (i Issue3364) String() string { + return fmt.Sprintf("%d %d", i.a, i.b) +} + func main() { one, two := 1, 2 intslice := []int{1, 2, 3} @@ -222,6 +231,10 @@ func main() { c: 3, d: 4, } + issue3364 := Issue3364{ + a: 1, + b: 2, + } fn2clos := makeclos(pa) fn2glob := call1 @@ -241,5 +254,5 @@ func main() { d.Method() d.Base.Method() x.CallMe() - fmt.Println(one, two, zero, call, call0, call2, callexit, callpanic, callbreak, callstacktrace, stringsJoin, intslice, stringslice, comma, a.VRcvr, a.PRcvr, pa, vable_a, vable_pa, pable_pa, fn2clos, fn2glob, fn2valmeth, fn2ptrmeth, fn2nil, ga, escapeArg, a2, square, intcallpanic, onetwothree, curriedAdd, getAStruct, getAStructPtr, getVRcvrableFromAStruct, getPRcvrableFromAStructPtr, getVRcvrableFromAStructPtr, pa2, noreturncall, str, d, x, x2.CallMe(5), longstrs, regabistacktest, regabistacktest2, issue2698.String(), regabistacktest3, rast3, floatsum, ref) + fmt.Println(one, two, zero, call, call0, call2, callexit, callpanic, callbreak, callstacktrace, stringsJoin, intslice, stringslice, comma, a.VRcvr, a.PRcvr, pa, vable_a, vable_pa, pable_pa, fn2clos, fn2glob, fn2valmeth, fn2ptrmeth, fn2nil, ga, escapeArg, a2, square, intcallpanic, onetwothree, curriedAdd, getAStruct, getAStructPtr, getVRcvrableFromAStruct, getPRcvrableFromAStructPtr, getVRcvrableFromAStructPtr, pa2, noreturncall, str, d, x, x2.CallMe(5), longstrs, regabistacktest, regabistacktest2, issue2698.String(), issue3364.String(), regabistacktest3, rast3, floatsum, ref) } diff --git a/pkg/proc/dwarf_export_test.go b/pkg/proc/dwarf_export_test.go index 191fde56d0..7add16c718 100644 --- a/pkg/proc/dwarf_export_test.go +++ b/pkg/proc/dwarf_export_test.go @@ -20,7 +20,7 @@ func NewCompositeMemory(p *Target, pieces []op.Piece, base uint64) (*compositeMe dwarfregs := arch.RegistersToDwarfRegisters(0, regs) dwarfregs.ChangeFunc = p.CurrentThread().SetReg - mem, err := newCompositeMemory(p.Memory(), arch, *dwarfregs, pieces) + mem, err := newCompositeMemory(p.Memory(), arch, *dwarfregs, pieces, 0) if mem != nil { mem.base = base } diff --git a/pkg/proc/mem.go b/pkg/proc/mem.go index cb2a35f67b..a215d274e9 100644 --- a/pkg/proc/mem.go +++ b/pkg/proc/mem.go @@ -98,17 +98,17 @@ type compositeMemory struct { // CreateCompositeMemory created a new composite memory type using the provided MemoryReadWriter as the // underlying memory buffer. -func CreateCompositeMemory(mem MemoryReadWriter, arch *Arch, regs op.DwarfRegisters, pieces []op.Piece) (*compositeMemory, error) { +func CreateCompositeMemory(mem MemoryReadWriter, arch *Arch, regs op.DwarfRegisters, pieces []op.Piece, size int64) (*compositeMemory, error) { // This is basically a small wrapper to avoid having to change all callers // of newCompositeMemory since it existed first. - cm, err := newCompositeMemory(mem, arch, regs, pieces) + cm, err := newCompositeMemory(mem, arch, regs, pieces, size) if cm != nil { cm.base = fakeAddressUnresolv } return cm, err } -func newCompositeMemory(mem MemoryReadWriter, arch *Arch, regs op.DwarfRegisters, pieces []op.Piece) (*compositeMemory, error) { +func newCompositeMemory(mem MemoryReadWriter, arch *Arch, regs op.DwarfRegisters, pieces []op.Piece, size int64) (*compositeMemory, error) { cmem := &compositeMemory{realmem: mem, arch: arch, regs: regs, pieces: pieces, data: []byte{}} for i := range pieces { piece := &pieces[i] @@ -147,6 +147,11 @@ func newCompositeMemory(mem MemoryReadWriter, arch *Arch, regs op.DwarfRegisters panic("unsupported piece kind") } } + paddingBytes := int(size) - len(cmem.data) + if paddingBytes > 0 && paddingBytes < arch.ptrSize { + padding := make([]byte, paddingBytes) + cmem.data = append(cmem.data, padding...) + } return cmem, nil } diff --git a/pkg/proc/target.go b/pkg/proc/target.go index 079a99d955..0a77344852 100644 --- a/pkg/proc/target.go +++ b/pkg/proc/target.go @@ -454,7 +454,7 @@ func (t *Target) GetBufferedTracepoints() []*UProbeTraceResult { v.Kind = ip.Kind cachedMem := CreateLoadedCachedMemory(ip.Data) - compMem, _ := CreateCompositeMemory(cachedMem, t.BinInfo().Arch, op.DwarfRegisters{}, ip.Pieces) + compMem, _ := CreateCompositeMemory(cachedMem, t.BinInfo().Arch, op.DwarfRegisters{}, ip.Pieces, ip.RealType.Common().ByteSize) v.mem = compMem // Load the value here so that we don't have to export @@ -506,7 +506,7 @@ const ( // This caching is primarily done so that registerized variables don't get a // different address every time they are evaluated, which would be confusing // and leak memory. -func (t *Target) newCompositeMemory(mem MemoryReadWriter, regs op.DwarfRegisters, pieces []op.Piece, descr *locationExpr) (int64, *compositeMemory, error) { +func (t *Target) newCompositeMemory(mem MemoryReadWriter, regs op.DwarfRegisters, pieces []op.Piece, descr *locationExpr, size int64) (int64, *compositeMemory, error) { var key string if regs.CFA != 0 && len(pieces) > 0 { // key is created by concatenating the location expression with the CFA, @@ -521,7 +521,7 @@ func (t *Target) newCompositeMemory(mem MemoryReadWriter, regs op.DwarfRegisters } } - cmem, err := newCompositeMemory(mem, t.BinInfo().Arch, regs, pieces) + cmem, err := newCompositeMemory(mem, t.BinInfo().Arch, regs, pieces, size) if err != nil { return 0, cmem, err } diff --git a/pkg/proc/variables.go b/pkg/proc/variables.go index e04e16fa8b..65f5040dc1 100644 --- a/pkg/proc/variables.go +++ b/pkg/proc/variables.go @@ -1198,9 +1198,9 @@ func extractVarInfoFromEntry(tgt *Target, bi *BinaryInfo, image *Image, regs op. if pieces != nil { var cmem *compositeMemory if tgt != nil { - addr, cmem, err = tgt.newCompositeMemory(mem, regs, pieces, descr) + addr, cmem, err = tgt.newCompositeMemory(mem, regs, pieces, descr, t.Common().ByteSize) } else { - cmem, err = newCompositeMemory(mem, bi.Arch, regs, pieces) + cmem, err = newCompositeMemory(mem, bi.Arch, regs, pieces, t.Common().ByteSize) if cmem != nil { cmem.base = fakeAddressUnresolv addr = int64(cmem.base) diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go index 82c155e4f3..7cc2dc5ef4 100644 --- a/pkg/proc/variables_test.go +++ b/pkg/proc/variables_test.go @@ -1267,6 +1267,7 @@ func TestCallFunction(t *testing.T) { {`regabistacktest("one", "two", "three", "four", "five", 4)`, []string{`:string:"onetwo"`, `:string:"twothree"`, `:string:"threefour"`, `:string:"fourfive"`, `:string:"fiveone"`, ":uint8:8"}, nil}, {`regabistacktest2(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)`, []string{":int:3", ":int:5", ":int:7", ":int:9", ":int:11", ":int:13", ":int:15", ":int:17", ":int:19", ":int:11"}, nil}, {`issue2698.String()`, []string{`:string:"1 2 3 4"`}, nil}, + {`issue3364.String()`, []string{`:string:"1 2"`}, nil}, {`regabistacktest3(rast3, 5)`, []string{`:[10]string:[10]string ["onetwo","twothree","threefour","fourfive","fivesix","sixseven","sevenheight","heightnine","nineten","tenone"]`, ":uint8:15"}, nil}, {`floatsum(1, 2)`, []string{":float64:3"}, nil}, } From 84b757ad57dc2877f3bc421c58b4975d7060bf3b Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 16 May 2023 18:36:15 +0200 Subject: [PATCH 034/114] cmd/dlv,service/dap: use randomized name as default output binary (#3366) Using a fixed path as the default output binary means that executing Delve twice in the same directory will cause the second invocation to overwrite the output binary of the first instance of Delve, making the restart command not work correctly. Fixes #3345 --- Documentation/usage/dlv_debug.md | 2 +- Documentation/usage/dlv_test.md | 2 +- Documentation/usage/dlv_trace.md | 2 +- cmd/dlv/cmds/commands.go | 28 +++++++++++++++++------ cmd/dlv/dlv_test.go | 38 +++++++++++++++++++++++++++++++- pkg/gobuild/defaultexe.go | 28 +++++++++++++++++++++++ service/dap/server.go | 14 +++++++----- 7 files changed, 98 insertions(+), 16 deletions(-) create mode 100644 pkg/gobuild/defaultexe.go diff --git a/Documentation/usage/dlv_debug.md b/Documentation/usage/dlv_debug.md index 718ae476c6..23c75ea840 100644 --- a/Documentation/usage/dlv_debug.md +++ b/Documentation/usage/dlv_debug.md @@ -20,7 +20,7 @@ dlv debug [package] [flags] ``` --continue Continue the debugged process on start. -h, --help help for debug - --output string Output path for the binary. (default "./__debug_bin") + --output string Output path for the binary. --tty string TTY to use for the target program ``` diff --git a/Documentation/usage/dlv_test.md b/Documentation/usage/dlv_test.md index d7817541a2..37a9fe0ff0 100644 --- a/Documentation/usage/dlv_test.md +++ b/Documentation/usage/dlv_test.md @@ -23,7 +23,7 @@ dlv test [package] [flags] ``` -h, --help help for test - --output string Output path for the binary. (default "debug.test") + --output string Output path for the binary. ``` ### Options inherited from parent commands diff --git a/Documentation/usage/dlv_trace.md b/Documentation/usage/dlv_trace.md index 018a511429..a6428100b9 100644 --- a/Documentation/usage/dlv_trace.md +++ b/Documentation/usage/dlv_trace.md @@ -24,7 +24,7 @@ dlv trace [package] regexp [flags] --ebpf Trace using eBPF (experimental). -e, --exec string Binary file to exec and trace. -h, --help help for trace - --output string Output path for the binary. (default "debug") + --output string Output path for the binary. -p, --pid int Pid to attach to. -s, --stack int Show stack trace with given depth. (Ignored with --ebpf) -t, --test Trace a test binary. diff --git a/cmd/dlv/cmds/commands.go b/cmd/dlv/cmds/commands.go index 44ab2ae26f..a189e480b1 100644 --- a/cmd/dlv/cmds/commands.go +++ b/cmd/dlv/cmds/commands.go @@ -230,7 +230,7 @@ package name and Delve will compile that package instead, and begin a new debug session.`, Run: debugCmd, } - debugCommand.Flags().String("output", "./__debug_bin", "Output path for the binary.") + debugCommand.Flags().String("output", "", "Output path for the binary.") debugCommand.Flags().BoolVar(&continueOnStart, "continue", false, "Continue the debugged process on start.") debugCommand.Flags().StringVar(&tty, "tty", "", "TTY to use for the target program") rootCommand.AddCommand(debugCommand) @@ -287,7 +287,7 @@ dlv test [package] -- -test.run TestSomething -test.v -other-argument See also: 'go help testflag'.`, Run: testCmd, } - testCommand.Flags().String("output", "debug.test", "Output path for the binary.") + testCommand.Flags().String("output", "", "Output path for the binary.") rootCommand.AddCommand(testCommand) // 'trace' subcommand. @@ -311,7 +311,7 @@ only see the output of the trace operations you can redirect stdout.`, traceCommand.Flags().BoolVarP(&traceUseEBPF, "ebpf", "", false, "Trace using eBPF (experimental).") traceCommand.Flags().BoolVarP(&traceShowTimestamp, "timestamp", "", false, "Show timestamp in the output") traceCommand.Flags().IntVarP(&traceStackDepth, "stack", "s", 0, "Show stack trace with given depth. (Ignored with --ebpf)") - traceCommand.Flags().String("output", "debug", "Output path for the binary.") + traceCommand.Flags().String("output", "", "Output path for the binary.") rootCommand.AddCommand(traceCommand) coreCommand := &cobra.Command{ @@ -528,10 +528,21 @@ func dapCmd(cmd *cobra.Command, args []string) { } func buildBinary(cmd *cobra.Command, args []string, isTest bool) (string, bool) { - debugname, err := filepath.Abs(cmd.Flag("output").Value.String()) - if err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - return "", false + outputFlag := cmd.Flag("output").Value.String() + var debugname string + var err error + if outputFlag == "" { + if isTest { + debugname = gobuild.DefaultDebugBinaryPath("debug.test") + } else { + debugname = gobuild.DefaultDebugBinaryPath("__debug_bin") + } + } else { + debugname, err = filepath.Abs(outputFlag) + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + return "", false + } } if isTest { @@ -540,6 +551,9 @@ func buildBinary(cmd *cobra.Command, args []string, isTest bool) (string, bool) err = gobuild.GoBuild(debugname, args, buildFlags) } if err != nil { + if outputFlag == "" { + gobuild.Remove(debugname) + } fmt.Fprintf(os.Stderr, "%v\n", err) return "", false } diff --git a/cmd/dlv/dlv_test.go b/cmd/dlv/dlv_test.go index e1c3006528..06b8fd6020 100644 --- a/cmd/dlv/dlv_test.go +++ b/cmd/dlv/dlv_test.go @@ -239,7 +239,7 @@ func getDlvBinInternal(t *testing.T, goflags ...string) string { func TestOutput(t *testing.T) { dlvbin := getDlvBin(t) - for _, output := range []string{"", "myownname", filepath.Join(t.TempDir(), "absolute.path")} { + for _, output := range []string{"__debug_bin", "myownname", filepath.Join(t.TempDir(), "absolute.path")} { testOutput(t, dlvbin, output, []string{"exit"}) const hello = "hello world!" @@ -1327,3 +1327,39 @@ func TestStaticcheck(t *testing.T) { out, _ := cmd.CombinedOutput() checkAutogenDoc(t, "_scripts/staticcheck-out.txt", fmt.Sprintf("staticcheck %s > _scripts/staticcheck-out.txt", strings.Join(args, " ")), out) } + +func TestDefaultBinary(t *testing.T) { + // Check that when delve is run twice in the same directory simultaneously + // it will pick different default output binary paths. + dlvbin := getDlvBin(t) + fixture := filepath.Join(protest.FindFixturesDir(), "testargs.go") + + startOne := func() (io.WriteCloser, func() error, *bytes.Buffer) { + cmd := exec.Command(dlvbin, "debug", "--allow-non-terminal-interactive=true", fixture, "--", "test") + stdin, _ := cmd.StdinPipe() + stdoutBuf := new(bytes.Buffer) + cmd.Stdout = stdoutBuf + + assertNoError(cmd.Start(), t, "dlv debug") + return stdin, cmd.Wait, stdoutBuf + } + + stdin1, wait1, stdoutBuf1 := startOne() + defer stdin1.Close() + + stdin2, wait2, stdoutBuf2 := startOne() + defer stdin2.Close() + + fmt.Fprintf(stdin1, "continue\nquit\n") + fmt.Fprintf(stdin2, "continue\nquit\n") + + wait1() + wait2() + + out1, out2 := stdoutBuf1.String(), stdoutBuf2.String() + t.Logf("%q", out1) + t.Logf("%q", out2) + if out1 == out2 { + t.Errorf("outputs match") + } +} diff --git a/pkg/gobuild/defaultexe.go b/pkg/gobuild/defaultexe.go new file mode 100644 index 0000000000..14fb313fa0 --- /dev/null +++ b/pkg/gobuild/defaultexe.go @@ -0,0 +1,28 @@ +package gobuild + +import ( + "io/ioutil" + "runtime" + + "github.com/go-delve/delve/pkg/logflags" +) + +// DefaultDebugBinaryPath returns an unused file path in the current +// directory named 'name' followed by a random string +func DefaultDebugBinaryPath(name string) string { + pattern := name + if runtime.GOOS == "windows" { + pattern += "*.exe" + } + f, err := ioutil.TempFile(".", pattern) + if err != nil { + logflags.DebuggerLogger().Errorf("could not create temporary file for build output: %v", err) + if runtime.GOOS == "windows" { + return name + ".exe" + } + return name + } + r := f.Name() + f.Close() + return r +} diff --git a/service/dap/server.go b/service/dap/server.go index ecebb778d3..2b0532e222 100644 --- a/service/dap/server.go +++ b/service/dap/server.go @@ -859,10 +859,6 @@ func (s *Session) setClientCapabilities(args dap.InitializeRequestArguments) { s.clientCapabilities.supportsVariableType = args.SupportsVariableType } -// Default output file pathname for the compiled binary in debug or test modes. -// This is relative to the current working directory of the server. -const defaultDebugBinary string = "./__debug_bin" - func cleanExeName(name string) string { if runtime.GOOS == "windows" && filepath.Ext(name) != ".exe" { return name + ".exe" @@ -957,8 +953,10 @@ func (s *Session) onLaunchRequest(request *dap.LaunchRequest) { // Prepare the debug executable filename, building it if necessary debugbinary := args.Program if args.Mode == "debug" || args.Mode == "test" { + deleteOnError := false if args.Output == "" { - args.Output = cleanExeName(defaultDebugBinary) + deleteOnError = true + args.Output = gobuild.DefaultDebugBinaryPath("__debug_bin") } else { args.Output = cleanExeName(args.Output) } @@ -981,6 +979,9 @@ func (s *Session) onLaunchRequest(request *dap.LaunchRequest) { args.DlvCwd, _ = filepath.Abs(args.DlvCwd) s.config.log.Debugf("building from %q: [%s]", args.DlvCwd, cmd) if err != nil { + if deleteOnError { + gobuild.Remove(args.Output) + } s.send(&dap.OutputEvent{ Event: *newEvent("output"), Body: dap.OutputEventBody{ @@ -1049,6 +1050,9 @@ func (s *Session) onLaunchRequest(request *dap.LaunchRequest) { s.debugger, err = debugger.New(&s.config.Debugger, s.config.ProcessArgs) }() if err != nil { + if s.binaryToRemove != "" { + gobuild.Remove(s.binaryToRemove) + } s.sendShowUserErrorResponse(request.Request, FailedToLaunch, "Failed to launch", err.Error()) return } From c5d9baaeb68d37e48178f9d3ba2d5b71c740f2a9 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Wed, 17 May 2023 13:01:26 +0300 Subject: [PATCH 035/114] pkg/proc,pkg/terminal: close response body in tests (#3372) --- pkg/proc/proc_test.go | 10 ++++++++-- pkg/terminal/command_test.go | 5 ++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index b6852d3d9f..066c206520 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -741,7 +741,10 @@ func TestNextNetHTTP(t *testing.T) { } time.Sleep(50 * time.Millisecond) } - http.Get("http://127.0.0.1:9191") + resp, err := http.Get("http://127.0.0.1:9191") + if err == nil { + resp.Body.Close() + } }() if err := grp.Continue(); err != nil { t.Fatal(err) @@ -2913,7 +2916,10 @@ func TestAttachDetach(t *testing.T) { assertNoError(err, t, "Attach") go func() { time.Sleep(1 * time.Second) - http.Get("http://127.0.0.1:9191") + resp, err := http.Get("http://127.0.0.1:9191") + if err == nil { + resp.Body.Close() + } }() assertNoError(p.Continue(), t, "Continue") diff --git a/pkg/terminal/command_test.go b/pkg/terminal/command_test.go index 4a9177b460..36ac44e84c 100644 --- a/pkg/terminal/command_test.go +++ b/pkg/terminal/command_test.go @@ -693,7 +693,10 @@ func TestIssue827(t *testing.T) { withTestTerminal("notify-v2", t, func(term *FakeTerminal) { go func() { time.Sleep(1 * time.Second) - http.Get("http://127.0.0.1:8888/test") + resp, err := http.Get("http://127.0.0.1:8888/test") + if err == nil { + resp.Body.Close() + } time.Sleep(1 * time.Second) term.client.Halt() }() From faebde12f4e9b72c203b4aec4c95fb28b3731d41 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 17 May 2023 18:10:19 +0200 Subject: [PATCH 036/114] proc: remove addrret field from Stackframe struct (#3373) This field was part of the original stack tracing algorithm, we haven't used this in years. --- pkg/proc/amd64_arch.go | 4 ++-- pkg/proc/arm64_arch.go | 4 ++-- pkg/proc/stack.go | 5 +---- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/pkg/proc/amd64_arch.go b/pkg/proc/amd64_arch.go index 1d4ab4b9d1..2c6b66f300 100644 --- a/pkg/proc/amd64_arch.go +++ b/pkg/proc/amd64_arch.go @@ -162,8 +162,8 @@ func amd64SwitchStack(it *stackIterator, _ *op.DwarfRegisters) bool { it.systemstack = false // advances to the next frame in the call stack - it.frame.addrret = uint64(int64(it.regs.SP()) + int64(it.bi.Arch.PtrSize())) - it.frame.Ret, _ = readUintRaw(it.mem, it.frame.addrret, int64(it.bi.Arch.PtrSize())) + addrret := uint64(int64(it.regs.SP()) + int64(it.bi.Arch.PtrSize())) + it.frame.Ret, _ = readUintRaw(it.mem, addrret, int64(it.bi.Arch.PtrSize())) it.pc = it.frame.Ret it.top = false diff --git a/pkg/proc/arm64_arch.go b/pkg/proc/arm64_arch.go index 46ddd463b5..6de8c0bfa5 100644 --- a/pkg/proc/arm64_arch.go +++ b/pkg/proc/arm64_arch.go @@ -211,8 +211,8 @@ func arm64SwitchStack(it *stackIterator, callFrameRegs *op.DwarfRegisters) bool it.top = false it.systemstack = false // The return value is stored in the LR register which is saved at 24(SP). - it.frame.addrret = uint64(int64(it.regs.SP()) + int64(it.bi.Arch.PtrSize()*3)) - it.frame.Ret, _ = readUintRaw(it.mem, it.frame.addrret, int64(it.bi.Arch.PtrSize())) + addrret := uint64(int64(it.regs.SP()) + int64(it.bi.Arch.PtrSize()*3)) + it.frame.Ret, _ = readUintRaw(it.mem, addrret, int64(it.bi.Arch.PtrSize())) it.pc = it.frame.Ret return true diff --git a/pkg/proc/stack.go b/pkg/proc/stack.go index 3ad7f2c4e9..9fdcb93e8a 100644 --- a/pkg/proc/stack.go +++ b/pkg/proc/stack.go @@ -39,8 +39,6 @@ type Stackframe struct { stackHi uint64 // Return address for this stack frame (as read from the stack frame itself). Ret uint64 - // Address to the memory location containing the return address - addrret uint64 // Err is set if an error occurred during stacktrace Err error // SystemStack is true if this frame belongs to a system stack. @@ -275,7 +273,7 @@ func (it *stackIterator) newStackframe(ret, retaddr uint64) Stackframe { } else { it.regs.FrameBase = it.frameBase(fn) } - r := Stackframe{Current: Location{PC: it.pc, File: f, Line: l, Fn: fn}, Regs: it.regs, Ret: ret, addrret: retaddr, stackHi: it.stackhi, SystemStack: it.systemstack, lastpc: it.pc} + r := Stackframe{Current: Location{PC: it.pc, File: f, Line: l, Fn: fn}, Regs: it.regs, Ret: ret, stackHi: it.stackhi, SystemStack: it.systemstack, lastpc: it.pc} if r.Regs.Reg(it.regs.PCRegNum) == nil { r.Regs.AddReg(it.regs.PCRegNum, op.DwarfRegisterFromUint64(it.pc)) } @@ -366,7 +364,6 @@ func (it *stackIterator) appendInlineCalls(frames []Stackframe, frame Stackframe Regs: frame.Regs, stackHi: frame.stackHi, Ret: frame.Ret, - addrret: frame.addrret, Err: frame.Err, SystemStack: frame.SystemStack, Inlined: true, From e33806a3f742b47344ee4aa3c46d5611656995bb Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Tue, 23 May 2023 19:21:36 +0300 Subject: [PATCH 037/114] service: fix typos in comments, logs, tests, and vars (#3378) --- service/api/prettyprint.go | 2 +- service/api/types.go | 2 +- service/dap/daptest/client.go | 4 ++-- service/dap/server.go | 16 ++++++++-------- service/dap/server_test.go | 14 +++++++------- service/rpc2/server.go | 2 +- service/test/integration2_test.go | 10 +++++----- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/service/api/prettyprint.go b/service/api/prettyprint.go index 6bb4332d23..cd10842779 100644 --- a/service/api/prettyprint.go +++ b/service/api/prettyprint.go @@ -449,7 +449,7 @@ func PrettyExamineMemory(address uintptr, memArea []byte, isLittleEndian bool, f cols = 8 colFormat = fmt.Sprintf("0x%%0%dx", colBytes*2) // Always keep one leading '0x' for hex. default: - return fmt.Sprintf("not supprted format %q\n", string(format)) + return fmt.Sprintf("not supported format %q\n", string(format)) } colFormat += "\t" diff --git a/service/api/types.go b/service/api/types.go index 8c48842ae9..c4a947c597 100644 --- a/service/api/types.go +++ b/service/api/types.go @@ -407,7 +407,7 @@ type DebuggerCommand struct { // UnsafeCall disables parameter escape checking for function calls. // Go objects can be allocated on the stack or on the heap. Heap objects // can be used by any goroutine; stack objects can only be used by the - // goroutine that owns the stack they are allocated on and can not surivive + // goroutine that owns the stack they are allocated on and can not survive // the stack frame of allocation. // The Go compiler will use escape analysis to determine whether to // allocate an object on the stack or the heap. diff --git a/service/dap/daptest/client.go b/service/dap/daptest/client.go index 82b3fe05a1..7277c78d31 100644 --- a/service/dap/daptest/client.go +++ b/service/dap/daptest/client.go @@ -556,14 +556,14 @@ func (c *Client) ReadMemoryRequest() { } // DisassembleRequest sends a 'disassemble' request. -func (c *Client) DisassembleRequest(memoryReference string, instructionOffset, inctructionCount int) { +func (c *Client) DisassembleRequest(memoryReference string, instructionOffset, instructionCount int) { c.send(&dap.DisassembleRequest{ Request: *c.newRequest("disassemble"), Arguments: dap.DisassembleArguments{ MemoryReference: memoryReference, Offset: 0, InstructionOffset: instructionOffset, - InstructionCount: inctructionCount, + InstructionCount: instructionCount, ResolveSymbols: false, }, }) diff --git a/service/dap/server.go b/service/dap/server.go index 2b0532e222..f6e1b1f7e3 100644 --- a/service/dap/server.go +++ b/service/dap/server.go @@ -71,7 +71,7 @@ import ( // a dummy/error response to avoid blocking. // // This is the only goroutine that sends a stop-server signal -// via config.DisconnecChan when encountering a client connection +// via config.DisconnectChan when encountering a client connection // error or responding to a (synchronous) DAP disconnect request. // Once stop is triggered, the goroutine exits. // @@ -124,7 +124,7 @@ type Session struct { // exceptionErr tracks the runtime error that last occurred. exceptionErr error // clientCapabilities tracks special settings for handling debug session requests. - clientCapabilities dapClientCapabilites + clientCapabilities dapClientCapabilities // mu synchronizes access to objects set on start-up (from run goroutine) // and stopped on teardown (from main goroutine) @@ -236,9 +236,9 @@ var defaultArgs = launchAttachArgs{ substitutePathServerToClient: [][2]string{}, } -// dapClientCapabilites captures arguments from initialize request that +// dapClientCapabilities captures arguments from initialize request that // impact handling of subsequent requests. -type dapClientCapabilites struct { +type dapClientCapabilities struct { supportsVariableType bool supportsVariablePaging bool supportsRunInTerminalRequest bool @@ -1072,7 +1072,7 @@ func (s *Session) getPackageDir(pkg string) string { cmd := exec.Command("go", "list", "-f", "{{.Dir}}", pkg) out, err := cmd.Output() if err != nil { - s.config.log.Debugf("failed to determin package directory for %v: %v\n%s", pkg, err, out) + s.config.log.Debugf("failed to determine package directory for %v: %v\n%s", pkg, err, out) return "." } return string(bytes.TrimSpace(out)) @@ -2594,7 +2594,7 @@ func (s *Session) convertVariableWithOpts(v *proc.Variable, qualifiedNameOrExpr return value, variablesReference } -// onEvaluateRequest handles 'evalute' requests. +// onEvaluateRequest handles 'evaluate' requests. // This is a mandatory request to support. // Support the following expressions: // @@ -3127,7 +3127,7 @@ func alignPCs(bi *proc.BinaryInfo, start, end uint64) (uint64, uint64) { // Handle start values: fn := bi.PCToFunc(start) if fn != nil { - // start is in a funcition. + // start is in a function. start = fn.Entry } else if b, pc := checkOutOfAddressSpace(start, bi); b { start = pc @@ -3142,7 +3142,7 @@ func alignPCs(bi *proc.BinaryInfo, start, end uint64) (uint64, uint64) { // Handle end values: if fn := bi.PCToFunc(end); fn != nil { - // end is in a funcition. + // end is in a function. end = fn.End } else if b, pc := checkOutOfAddressSpace(end, bi); b { end = pc diff --git a/service/dap/server_test.go b/service/dap/server_test.go index f5153fd539..5b9b515a8e 100644 --- a/service/dap/server_test.go +++ b/service/dap/server_test.go @@ -284,7 +284,7 @@ func TestSessionStop(t *testing.T) { defer client.Close() <-acceptDone if err != nil { - t.Fatalf("cannot accept client requireed for testing: %v", err) + t.Fatalf("cannot accept client required for testing: %v", err) } session := NewSession(conn, &Config{ Config: &service.Config{DisconnectChan: make(chan struct{})}, @@ -962,7 +962,7 @@ func checkStackFramesNamed(testName string, t *testing.T, got *dap.StackTraceRes // checkScope is a helper for verifying the values within a ScopesResponse. // -// i - index of the scope within ScopesRespose.Body.Scopes array +// i - index of the scope within ScopesResponse.Body.Scopes array // name - name of the scope // varRef - reference to retrieve variables of this scope. If varRef is negative, the reference is not checked. func checkScope(t *testing.T, got *dap.ScopesResponse, i int, name string, varRef int) { @@ -1668,7 +1668,7 @@ func TestScopesAndVariablesRequests2(t *testing.T) { client.ScopesRequest(1000) scopes := client.ExpectScopesResponse(t) if len(scopes.Body.Scopes) > 1 { - t.Errorf("\ngot %#v\nwant len(scopes)=1 (Argumes & Locals)", scopes) + t.Errorf("\ngot %#v\nwant len(scopes)=1 (Arguments & Locals)", scopes) } checkScope(t, scopes, 0, "Locals", localsScope) @@ -2109,7 +2109,7 @@ func TestVariablesLoading(t *testing.T) { } } - // Fully missing struct auto-loaded when hitting LoadConfig.MaxVariableRecurse (also tests evaluteName corner case) + // Fully missing struct auto-loaded when hitting LoadConfig.MaxVariableRecurse (also tests evaluateName corner case) ref = checkVarRegex(t, locals, -1, "aas", "aas", `\[\]main\.a len: 1, cap: 1, \[{aas: \[\]main\.a len: 1, cap: 1, \[\(\*main\.a\)\(0x[0-9a-f]+\)\]}\]`, `\[\]main\.a`, hasChildren) if ref > 0 { client.VariablesRequest(ref) @@ -2146,7 +2146,7 @@ func TestVariablesLoading(t *testing.T) { checkChildren(t, tm, "tm", 1) ref = checkVarExact(t, tm, 0, "v", "tm.v", "[]map[string]main.astruct len: 1, cap: 1, [[...]]", "[]map[string]main.astruct", hasChildren) if ref > 0 { - // Auto-loading of fully missing map chidlren happens here, but they get trancated at MaxArrayValuess + // Auto-loading of fully missing map chidlren happens here, but they get truncated at MaxArrayValuess client.VariablesRequest(ref) tmV := client.ExpectVariablesResponse(t) checkChildren(t, tmV, "tm.v", 1) @@ -4650,7 +4650,7 @@ func testNextParkedHelper(t *testing.T, client *daptest.Client, fixture protest. // ok case *dap.TerminatedEvent: // This is very unlikely to happen. But in theory if all sayhi - // gouritines are run serially, there will never be a second parked + // goroutines are run serially, there will never be a second parked // sayhi goroutine when another breaks and we will keep trying // until process termination. return -1 @@ -5772,7 +5772,7 @@ func TestPauseAndContinue(t *testing.T) { }) } -func TestUnupportedCommandResponses(t *testing.T) { +func TestUnsupportedCommandResponses(t *testing.T) { var got *dap.ErrorResponse runTest(t, "increment", func(client *daptest.Client, fixture protest.Fixture) { seqCnt := 1 diff --git a/service/rpc2/server.go b/service/rpc2/server.go index eedc069238..3d8f6215d0 100644 --- a/service/rpc2/server.go +++ b/service/rpc2/server.go @@ -253,7 +253,7 @@ type CreateBreakpointOut struct { } // CreateBreakpoint creates a new breakpoint. The client is expected to populate `CreateBreakpointIn` -// with an `api.Breakpoint` struct describing where to set the breakpoing. For more information on +// with an `api.Breakpoint` struct describing where to set the breakpoint. For more information on // how to properly request a breakpoint via the `api.Breakpoint` struct see the documentation for // `debugger.CreateBreakpoint` here: https://pkg.go.dev/github.com/go-delve/delve/service/debugger#Debugger.CreateBreakpoint. func (s *RPCServer) CreateBreakpoint(arg CreateBreakpointIn, out *CreateBreakpointOut) error { diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go index 4228907685..a6c3b45e3f 100644 --- a/service/test/integration2_test.go +++ b/service/test/integration2_test.go @@ -611,7 +611,7 @@ func TestClientServer_toggleAmendedBreakpoint(t *testing.T) { t.Fatal(err) } if amended.Cond == "" { - t.Fatal("breakpoint amendedments not preserved after toggle") + t.Fatal("breakpoint amendments not preserved after toggle") } }) } @@ -2188,7 +2188,7 @@ func TestAncestors(t *testing.T) { defer os.Setenv("GODEBUG", savedGodebug) withTestClient2("testnextprog", t, func(c service.Client) { _, err := c.CreateBreakpoint(&api.Breakpoint{FunctionName: "main.testgoroutine", Line: -1}) - assertNoError(err, t, "CreateBreakpoin") + assertNoError(err, t, "CreateBreakpoint") state := <-c.Continue() assertNoError(state.Err, t, "Continue()") ancestors, err := c.Ancestors(-1, 1000, 1000) @@ -2259,7 +2259,7 @@ func TestRerecord(t *testing.T) { withTestClient2("testrerecord", t, func(c service.Client) { fp := testProgPath(t, "testrerecord") _, err := c.CreateBreakpoint(&api.Breakpoint{File: fp, Line: 10}) - assertNoError(err, t, "CreateBreakpoin") + assertNoError(err, t, "CreateBreakpoint") gett := func() int { state := <-c.Continue() @@ -2531,7 +2531,7 @@ func TestToggleBreakpointRestart(t *testing.T) { } func TestStopServerWithClosedListener(t *testing.T) { - // Checks that the error erturned by listener.Accept() is ignored when we + // Checks that the error returned by listener.Accept() is ignored when we // are trying to shutdown. See issue #1633. if testBackend == "rr" || buildMode == "pie" { t.Skip("N/A") @@ -3000,7 +3000,7 @@ func TestClientServer_breakpointOnFuncWithABIWrapper(t *testing.T) { protest.AllowRecording(t) withTestClient2("math", t, func(c service.Client) { bp, err := c.CreateBreakpoint(&api.Breakpoint{FunctionName: "runtime.schedinit"}) - assertNoError(err, t, "CreateBreakpoin()") + assertNoError(err, t, "CreateBreakpoint()") t.Log(bp) found := false From 3b251c9dd38bb2635211bf62886b97cce8245f27 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Tue, 23 May 2023 19:22:20 +0300 Subject: [PATCH 038/114] dwarf,proc: fix typos in comments and error messages (#3379) --- pkg/dwarf/godwarf/tree_test.go | 4 ++-- pkg/dwarf/godwarf/type.go | 2 +- pkg/dwarf/reader/reader.go | 2 +- pkg/proc/i386_disasm.go | 2 +- pkg/proc/linutil/dynamic.go | 2 +- pkg/proc/proc_test.go | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/dwarf/godwarf/tree_test.go b/pkg/dwarf/godwarf/tree_test.go index 643308b3a1..f27a4b1c4c 100644 --- a/pkg/dwarf/godwarf/tree_test.go +++ b/pkg/dwarf/godwarf/tree_test.go @@ -50,7 +50,7 @@ func TestRangeContains(t *testing.T) { for _, tc := range tcs { if rangeContains(tc.a, tc.b) != tc.tgt { if tc.tgt { - t.Errorf("range %v does not contan %v (but should)", tc.a, tc.b) + t.Errorf("range %v does not contain %v (but should)", tc.a, tc.b) } else { t.Errorf("range %v does contain %v (but shouldn't)", tc.a, tc.b) } @@ -81,7 +81,7 @@ func TestRangesContains(t *testing.T) { for _, tc := range tcs { if rangesContains(tc.rngs1, tc.rngs2) != tc.tgt { if tc.tgt { - t.Errorf("ranges %v does not contan %v (but should)", tc.rngs1, tc.rngs2) + t.Errorf("ranges %v does not contain %v (but should)", tc.rngs1, tc.rngs2) } else { t.Errorf("ranges %v does contain %v (but shouldn't)", tc.rngs1, tc.rngs2) } diff --git a/pkg/dwarf/godwarf/type.go b/pkg/dwarf/godwarf/type.go index 19ac86e38d..e06c118e30 100644 --- a/pkg/dwarf/godwarf/type.go +++ b/pkg/dwarf/godwarf/type.go @@ -42,7 +42,7 @@ const ( encImaginaryFloat = 0x09 ) -const cyclicalTypeStop = "" // guard value printed for types with a cyclical definition, to avoid inifinite recursion in Type.String +const cyclicalTypeStop = "" // guard value printed for types with a cyclical definition, to avoid infinite recursion in Type.String type recCheck map[dwarf.Offset]struct{} diff --git a/pkg/dwarf/reader/reader.go b/pkg/dwarf/reader/reader.go index d0a8691177..2b48fbd31d 100644 --- a/pkg/dwarf/reader/reader.go +++ b/pkg/dwarf/reader/reader.go @@ -228,7 +228,7 @@ func (reader *Reader) NextMemberVariable() (*dwarf.Entry, error) { } // NextPackageVariable moves the reader to the next debug entry that describes a package variable. -// Any TagVariable entry that is not inside a sub prgram entry and is marked external is considered a package variable. +// Any TagVariable entry that is not inside a sub program entry and is marked external is considered a package variable. func (reader *Reader) NextPackageVariable() (*dwarf.Entry, error) { for entry, err := reader.Next(); entry != nil; entry, err = reader.Next() { if err != nil { diff --git a/pkg/proc/i386_disasm.go b/pkg/proc/i386_disasm.go index bebcb9f777..cd66aa59b5 100644 --- a/pkg/proc/i386_disasm.go +++ b/pkg/proc/i386_disasm.go @@ -17,7 +17,7 @@ func i386AsmDecode(asmInst *AsmInstruction, mem []byte, regs *op.DwarfRegisters, // Possible stacksplit prologues are inserted by stacksplit in // $GOROOT/src/cmd/internal/obj/x86/obj6.go. -// If 386 on linux when pie, the stacksplit prologue beigin with `call __x86.get_pc_thunk.` sometime. +// If 386 on linux when pie, the stacksplit prologue begin with `call __x86.get_pc_thunk.` sometime. var prologuesI386 []opcodeSeq func init() { diff --git a/pkg/proc/linutil/dynamic.go b/pkg/proc/linutil/dynamic.go index 2e02a7741c..6e041a40b2 100644 --- a/pkg/proc/linutil/dynamic.go +++ b/pkg/proc/linutil/dynamic.go @@ -38,7 +38,7 @@ func readUintRaw(reader io.Reader, order binary.ByteOrder, ptrSize int) (uint64, } return n, nil } - return 0, fmt.Errorf("not supprted ptr size %d", ptrSize) + return 0, fmt.Errorf("not supported ptr size %d", ptrSize) } // dynamicSearchDebug searches for the DT_DEBUG entry in the .dynamic section diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 066c206520..4a145591c2 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -2840,7 +2840,7 @@ func TestNextInDeferReturn(t *testing.T) { // runtime.deferreturn updates the G struct in a way that for one // instruction leaves the curg._defer field non-nil but with curg._defer.fn // field being nil. - // We need to deal with this without panicing. + // We need to deal with this without panicking. protest.AllowRecording(t) withTestProcess("defercall", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { setFunctionBreakpoint(p, t, "runtime.deferreturn") @@ -3735,7 +3735,7 @@ func TestHaltKeepsSteppingBreakpoints(t *testing.T) { func TestDisassembleGlobalVars(t *testing.T) { skipOn(t, "broken - global variable symbolication", "arm64") // On ARM64 symLookup can't look up variables due to how they are loaded, see issue #1778 - // On 386 linux when pie, the genered code use __x86.get_pc_thunk to ensure position-independent. + // On 386 linux when pie, the generated code use __x86.get_pc_thunk to ensure position-independent. // Locate global variable by // `CALL __x86.get_pc_thunk.ax(SB) 0xb0f7f // LEAL 0xc0a19(AX), AX` From 68f58561bb11b62a12c2b2ca676888eb079a18d3 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Tue, 23 May 2023 14:11:51 -0400 Subject: [PATCH 039/114] debuginfod-find stderr may contain diagnostics; look at stdout only for filename (#3381) --- pkg/proc/debuginfod/debuginfod.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/proc/debuginfod/debuginfod.go b/pkg/proc/debuginfod/debuginfod.go index a46d98067c..e0297b1f61 100644 --- a/pkg/proc/debuginfod/debuginfod.go +++ b/pkg/proc/debuginfod/debuginfod.go @@ -12,7 +12,7 @@ func execFind(args ...string) (string, error) { return "", err } cmd := exec.Command(debuginfodFind, args...) - out, err := cmd.CombinedOutput() + out, err := cmd.Output() // ignore stderr if err != nil { return "", err } From b79dd04070836ee4793ccdbd8dc959bc06a6be2c Mon Sep 17 00:00:00 2001 From: Andrei Matei Date: Tue, 23 May 2023 14:22:41 -0400 Subject: [PATCH 040/114] documentation: add a note about starlark structs (#3376) It took me a bit to understand how to pass structs to Starlark built-ins. The documentation didn't really address it - there was an example, but quite hidden. This patch adds some words about it. --- Documentation/cli/starlark.md | 36 +++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/Documentation/cli/starlark.md b/Documentation/cli/starlark.md index b4c9f159e7..7a1679c61e 100644 --- a/Documentation/cli/starlark.md +++ b/Documentation/cli/starlark.md @@ -111,7 +111,7 @@ The `Value` field will return the value of the target variable converted to a st For example, given this variable in the target program: -``` +```go type astruct struct { A int B int @@ -143,7 +143,7 @@ For more examples see the [linked list example](#Print-all-elements-of-a-linked- Create a `goroutine_start_line` command that prints the starting line of each goroutine, sets `gsl` as an alias: -``` +```python def command_goroutine_start_line(args): gs = goroutines().Goroutines for g in gs: @@ -174,7 +174,7 @@ Use it like this: After evaluating this script: -``` +```python def command_echo(args): print(args) @@ -195,7 +195,7 @@ a 4 b 1 c 6 Set a breakpoint on all private methods of package `main`: -``` +```python def main(): for f in functions().Funcs: v = f.split('.') @@ -211,7 +211,7 @@ def main(): Create a command, `switch_to_main_goroutine`, that searches for a goroutine running a function in the main package and switches to it: -``` +```python def command_switch_to_main_goroutine(args): for g in goroutines().Goroutines: if g.currentLoc.function != None and g.currentLoc.function.name.startswith("main."): @@ -224,7 +224,7 @@ def command_switch_to_main_goroutine(args): Create a command, "goexcl", that lists all goroutines excluding the ones stopped on a specified function. -``` +```python def command_goexcl(args): """Prints all goroutines not stopped in the function passed as argument.""" excluded = 0 @@ -255,7 +255,7 @@ prints all goroutines that are not stopped inside `main.somefunc`. Repeatedly call continue and restart until the target hits a breakpoint. -``` +```python def command_flaky(args): "Repeatedly runs program until a breakpoint is hit" while True: @@ -266,7 +266,7 @@ def command_flaky(args): ## Print all elements of a linked list -``` +```python def command_linked_list(args): """Prints the contents of a linked list. @@ -287,7 +287,7 @@ Prints up to max_depth elements of the linked list variable 'var_name' using 'ne ## Find an array element matching a predicate -``` +```python def command_find_array(arr, pred): """Calls pred for each element of the array or slice 'arr' returns the index of the first element for which pred returns true. @@ -309,7 +309,7 @@ Example use (find the first element of slice 's2' with field A equal to 5): ## Rerunning a program until it fails or hits a breakpoint -``` +```python def command_flaky(args): "Continues and restarts the target program repeatedly (re-recording it on the rr backend), until a breakpoint is hit" count = 1 @@ -321,3 +321,19 @@ def command_flaky(args): restart(Rerecord=True) ``` + +## Passing a struct as an argument + +Struct literals can be passed to built-ins as Starlark dictionaries. For example, the following snippet passes +in an [api.EvalScope](https://pkg.go.dev/github.com/go-delve/delve/service/api#EvalScope) +and [api.LoadConfig](https://pkg.go.dev/github.com/go-delve/delve/service/api#LoadConfig) +to the `eval` built-in. `None` can be passed for optional arguments, and +trailing optional arguments can be elided completely. + +```python +var = eval( + {"GoroutineID": 42, "Frame": 5}, + "myVar", + {"FollowPointers":True, "MaxVariableRecurse":2, "MaxStringLen":100, "MaxArrayValues":10, "MaxStructFields":100} + ) +``` From c2bfdfc76b1d570eeca392d8fb75bcb2af84d07a Mon Sep 17 00:00:00 2001 From: Andrei Matei Date: Tue, 23 May 2023 14:23:33 -0400 Subject: [PATCH 041/114] starbind: Make the time module available to star scripts (#3375) This patch makes the time library available to Starlark scripts. This library is one of the very few few that are built into starlark-go (the others are json, math, proto). I've played around with Starlark scripting today, and immediately I wanted to measure how long certain computations take. --- Documentation/cli/starlark.md | 2 + pkg/terminal/starbind/starlark.go | 4 + vendor/go.starlark.net/lib/time/time.go | 507 ++++++++++++++++++ .../go.starlark.net/starlarkstruct/module.go | 43 ++ .../go.starlark.net/starlarkstruct/struct.go | 281 ++++++++++ vendor/modules.txt | 2 + 6 files changed, 839 insertions(+) create mode 100644 vendor/go.starlark.net/lib/time/time.go create mode 100644 vendor/go.starlark.net/starlarkstruct/module.go create mode 100644 vendor/go.starlark.net/starlarkstruct/struct.go diff --git a/Documentation/cli/starlark.md b/Documentation/cli/starlark.md index 7a1679c61e..5b35dab759 100644 --- a/Documentation/cli/starlark.md +++ b/Documentation/cli/starlark.md @@ -74,6 +74,8 @@ cur_scope() | Returns the current evaluation scope default_load_config() | Returns the current default load configuration +In addition to these built-ins, the [time](https://pkg.go.dev/go.starlark.net/lib/time#pkg-variables) library from the starlark-go project is also available to scripts. + ## Should I use raw_command or dlv_command? There are two ways to resume the execution of the target program: diff --git a/pkg/terminal/starbind/starlark.go b/pkg/terminal/starbind/starlark.go index de37879e4b..ac74b47f3c 100644 --- a/pkg/terminal/starbind/starlark.go +++ b/pkg/terminal/starbind/starlark.go @@ -9,6 +9,7 @@ import ( "strings" "sync" + startime "go.starlark.net/lib/time" "go.starlark.net/resolve" "go.starlark.net/starlark" @@ -67,6 +68,9 @@ func New(ctx Context, out EchoWriter) *Env { env.ctx = ctx env.out = out + // Make the "time" module available to Starlark scripts. + starlark.Universe["time"] = startime.Module + env.env = env.starlarkPredeclare() env.env[dlvCommandBuiltinName] = starlark.NewBuiltin(dlvCommandBuiltinName, func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { diff --git a/vendor/go.starlark.net/lib/time/time.go b/vendor/go.starlark.net/lib/time/time.go new file mode 100644 index 0000000000..de8bf53350 --- /dev/null +++ b/vendor/go.starlark.net/lib/time/time.go @@ -0,0 +1,507 @@ +// Copyright 2021 The Bazel 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 time provides time-related constants and functions. +package time // import "go.starlark.net/lib/time" + +import ( + "fmt" + "sort" + "time" + + "go.starlark.net/starlark" + "go.starlark.net/starlarkstruct" + "go.starlark.net/syntax" +) + +// Module time is a Starlark module of time-related functions and constants. +// The module defines the following functions: +// +// from_timestamp(sec, nsec) - Converts the given Unix time corresponding to the number of seconds +// and (optionally) nanoseconds since January 1, 1970 UTC into an object +// of type Time. For more details, refer to https://pkg.go.dev/time#Unix. +// +// is_valid_timezone(loc) - Reports whether loc is a valid time zone name. +// +// now() - Returns the current local time. Applications may replace this function by a deterministic one. +// +// parse_duration(d) - Parses the given duration string. For more details, refer to +// https://pkg.go.dev/time#ParseDuration. +// +// parseTime(x, format, location) - Parses the given time string using a specific time format and location. +// The expected arguments are a time string (mandatory), a time format +// (optional, set to RFC3339 by default, e.g. "2021-03-22T23:20:50.52Z") +// and a name of location (optional, set to UTC by default). For more details, +// refer to https://pkg.go.dev/time#Parse and https://pkg.go.dev/time#ParseInLocation. +// +// time(year, month, day, hour, minute, second, nanosecond, location) - Returns the Time corresponding to +// yyyy-mm-dd hh:mm:ss + nsec nanoseconds +// in the appropriate zone for that time +// in the given location. All the parameters +// are optional. +// The module also defines the following constants: +// +// nanosecond - A duration representing one nanosecond. +// microsecond - A duration representing one microsecond. +// millisecond - A duration representing one millisecond. +// second - A duration representing one second. +// minute - A duration representing one minute. +// hour - A duration representing one hour. +// +var Module = &starlarkstruct.Module{ + Name: "time", + Members: starlark.StringDict{ + "from_timestamp": starlark.NewBuiltin("from_timestamp", fromTimestamp), + "is_valid_timezone": starlark.NewBuiltin("is_valid_timezone", isValidTimezone), + "now": starlark.NewBuiltin("now", now), + "parse_duration": starlark.NewBuiltin("parse_duration", parseDuration), + "parse_time": starlark.NewBuiltin("parse_time", parseTime), + "time": starlark.NewBuiltin("time", newTime), + + "nanosecond": Duration(time.Nanosecond), + "microsecond": Duration(time.Microsecond), + "millisecond": Duration(time.Millisecond), + "second": Duration(time.Second), + "minute": Duration(time.Minute), + "hour": Duration(time.Hour), + }, +} + +// NowFunc is a function that generates the current time. Intentionally exported +// so that it can be overridden, for example by applications that require their +// Starlark scripts to be fully deterministic. +var NowFunc = time.Now + +func parseDuration(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var d Duration + err := starlark.UnpackPositionalArgs("parse_duration", args, kwargs, 1, &d) + return d, err +} + +func isValidTimezone(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var s string + if err := starlark.UnpackPositionalArgs("is_valid_timezone", args, kwargs, 1, &s); err != nil { + return nil, err + } + _, err := time.LoadLocation(s) + return starlark.Bool(err == nil), nil +} + +func parseTime(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var ( + x string + location = "UTC" + format = time.RFC3339 + ) + if err := starlark.UnpackArgs("parse_time", args, kwargs, "x", &x, "format?", &format, "location?", &location); err != nil { + return nil, err + } + + if location == "UTC" { + t, err := time.Parse(format, x) + if err != nil { + return nil, err + } + return Time(t), nil + } + + loc, err := time.LoadLocation(location) + if err != nil { + return nil, err + } + t, err := time.ParseInLocation(format, x, loc) + if err != nil { + return nil, err + } + return Time(t), nil +} + +func fromTimestamp(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var ( + sec int64 + nsec int64 = 0 + ) + if err := starlark.UnpackPositionalArgs("from_timestamp", args, kwargs, 1, &sec, &nsec); err != nil { + return nil, err + } + return Time(time.Unix(sec, nsec)), nil +} + +func now(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + return Time(NowFunc()), nil +} + +// Duration is a Starlark representation of a duration. +type Duration time.Duration + +// Assert at compile time that Duration implements Unpacker. +var _ starlark.Unpacker = (*Duration)(nil) + +// Unpack is a custom argument unpacker +func (d *Duration) Unpack(v starlark.Value) error { + switch x := v.(type) { + case Duration: + *d = x + return nil + case starlark.String: + dur, err := time.ParseDuration(string(x)) + if err != nil { + return err + } + + *d = Duration(dur) + return nil + } + + return fmt.Errorf("got %s, want a duration, string, or int", v.Type()) +} + +// String implements the Stringer interface. +func (d Duration) String() string { return time.Duration(d).String() } + +// Type returns a short string describing the value's type. +func (d Duration) Type() string { return "time.duration" } + +// Freeze renders Duration immutable. required by starlark.Value interface +// because duration is already immutable this is a no-op. +func (d Duration) Freeze() {} + +// Hash returns a function of x such that Equals(x, y) => Hash(x) == Hash(y) +// required by starlark.Value interface. +func (d Duration) Hash() (uint32, error) { + return uint32(d) ^ uint32(int64(d)>>32), nil +} + +// Truth reports whether the duration is non-zero. +func (d Duration) Truth() starlark.Bool { return d != 0 } + +// Attr gets a value for a string attribute, implementing dot expression support +// in starklark. required by starlark.HasAttrs interface. +func (d Duration) Attr(name string) (starlark.Value, error) { + switch name { + case "hours": + return starlark.Float(time.Duration(d).Hours()), nil + case "minutes": + return starlark.Float(time.Duration(d).Minutes()), nil + case "seconds": + return starlark.Float(time.Duration(d).Seconds()), nil + case "milliseconds": + return starlark.MakeInt64(time.Duration(d).Milliseconds()), nil + case "microseconds": + return starlark.MakeInt64(time.Duration(d).Microseconds()), nil + case "nanoseconds": + return starlark.MakeInt64(time.Duration(d).Nanoseconds()), nil + } + return nil, fmt.Errorf("unrecognized %s attribute %q", d.Type(), name) +} + +// AttrNames lists available dot expression strings. required by +// starlark.HasAttrs interface. +func (d Duration) AttrNames() []string { + return []string{ + "hours", + "minutes", + "seconds", + "milliseconds", + "microseconds", + "nanoseconds", + } +} + +// CompareSameType implements comparison of two Duration values. required by +// starlark.Comparable interface. +func (d Duration) CompareSameType(op syntax.Token, v starlark.Value, depth int) (bool, error) { + cmp := 0 + if x, y := d, v.(Duration); x < y { + cmp = -1 + } else if x > y { + cmp = 1 + } + return threeway(op, cmp), nil +} + +// Binary implements binary operators, which satisfies the starlark.HasBinary +// interface. operators: +// duration + duration = duration +// duration + time = time +// duration - duration = duration +// duration / duration = float +// duration / int = duration +// duration / float = duration +// duration // duration = int +// duration * int = duration +func (d Duration) Binary(op syntax.Token, y starlark.Value, side starlark.Side) (starlark.Value, error) { + x := time.Duration(d) + + switch op { + case syntax.PLUS: + switch y := y.(type) { + case Duration: + return Duration(x + time.Duration(y)), nil + case Time: + return Time(time.Time(y).Add(x)), nil + } + + case syntax.MINUS: + switch y := y.(type) { + case Duration: + return Duration(x - time.Duration(y)), nil + } + + case syntax.SLASH: + switch y := y.(type) { + case Duration: + if y == 0 { + return nil, fmt.Errorf("%s division by zero", d.Type()) + } + return starlark.Float(x.Nanoseconds()) / starlark.Float(time.Duration(y).Nanoseconds()), nil + case starlark.Int: + if side == starlark.Right { + return nil, fmt.Errorf("unsupported operation") + } + i, ok := y.Int64() + if !ok { + return nil, fmt.Errorf("int value out of range (want signed 64-bit value)") + } + if i == 0 { + return nil, fmt.Errorf("%s division by zero", d.Type()) + } + return d / Duration(i), nil + case starlark.Float: + f := float64(y) + if f == 0 { + return nil, fmt.Errorf("%s division by zero", d.Type()) + } + return Duration(float64(x.Nanoseconds()) / f), nil + } + + case syntax.SLASHSLASH: + switch y := y.(type) { + case Duration: + if y == 0 { + return nil, fmt.Errorf("%s division by zero", d.Type()) + } + return starlark.MakeInt64(x.Nanoseconds() / time.Duration(y).Nanoseconds()), nil + } + + case syntax.STAR: + switch y := y.(type) { + case starlark.Int: + i, ok := y.Int64() + if !ok { + return nil, fmt.Errorf("int value out of range (want signed 64-bit value)") + } + return d * Duration(i), nil + } + } + + return nil, nil +} + +// Time is a Starlark representation of a moment in time. +type Time time.Time + +func newTime(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var ( + year, month, day, hour, min, sec, nsec int + loc string + ) + if err := starlark.UnpackArgs("time", args, kwargs, + "year?", &year, + "month?", &month, + "day?", &day, + "hour?", &hour, + "minute?", &min, + "second?", &sec, + "nanosecond?", &nsec, + "location?", &loc, + ); err != nil { + return nil, err + } + if len(args) > 0 { + return nil, fmt.Errorf("time: unexpected positional arguments") + } + location, err := time.LoadLocation(loc) + if err != nil { + return nil, err + } + return Time(time.Date(year, time.Month(month), day, hour, min, sec, nsec, location)), nil +} + +// String returns the time formatted using the format string +// "2006-01-02 15:04:05.999999999 -0700 MST". +func (t Time) String() string { return time.Time(t).String() } + +// Type returns "time.time". +func (t Time) Type() string { return "time.time" } + +// Freeze renders time immutable. required by starlark.Value interface +// because Time is already immutable this is a no-op. +func (t Time) Freeze() {} + +// Hash returns a function of x such that Equals(x, y) => Hash(x) == Hash(y) +// required by starlark.Value interface. +func (t Time) Hash() (uint32, error) { + return uint32(time.Time(t).UnixNano()) ^ uint32(int64(time.Time(t).UnixNano())>>32), nil +} + +// Truth returns the truth value of an object required by starlark.Value +// interface. +func (t Time) Truth() starlark.Bool { return starlark.Bool(time.Time(t).IsZero()) } + +// Attr gets a value for a string attribute, implementing dot expression support +// in starklark. required by starlark.HasAttrs interface. +func (t Time) Attr(name string) (starlark.Value, error) { + switch name { + case "year": + return starlark.MakeInt(time.Time(t).Year()), nil + case "month": + return starlark.MakeInt(int(time.Time(t).Month())), nil + case "day": + return starlark.MakeInt(time.Time(t).Day()), nil + case "hour": + return starlark.MakeInt(time.Time(t).Hour()), nil + case "minute": + return starlark.MakeInt(time.Time(t).Minute()), nil + case "second": + return starlark.MakeInt(time.Time(t).Second()), nil + case "nanosecond": + return starlark.MakeInt(time.Time(t).Nanosecond()), nil + case "unix": + return starlark.MakeInt64(time.Time(t).Unix()), nil + case "unix_nano": + return starlark.MakeInt64(time.Time(t).UnixNano()), nil + } + return builtinAttr(t, name, timeMethods) +} + +// AttrNames lists available dot expression strings for time. required by +// starlark.HasAttrs interface. +func (t Time) AttrNames() []string { + return append(builtinAttrNames(timeMethods), + "year", + "month", + "day", + "hour", + "minute", + "second", + "nanosecond", + "unix", + "unix_nano", + ) +} + +// CompareSameType implements comparison of two Time values. required by +// starlark.Comparable interface. +func (t Time) CompareSameType(op syntax.Token, yV starlark.Value, depth int) (bool, error) { + x := time.Time(t) + y := time.Time(yV.(Time)) + cmp := 0 + if x.Before(y) { + cmp = -1 + } else if x.After(y) { + cmp = 1 + } + return threeway(op, cmp), nil +} + +// Binary implements binary operators, which satisfies the starlark.HasBinary +// interface +// time + duration = time +// time - duration = time +// time - time = duration +func (t Time) Binary(op syntax.Token, y starlark.Value, side starlark.Side) (starlark.Value, error) { + x := time.Time(t) + + switch op { + case syntax.PLUS: + switch y := y.(type) { + case Duration: + return Time(x.Add(time.Duration(y))), nil + } + case syntax.MINUS: + switch y := y.(type) { + case Duration: + return Time(x.Add(time.Duration(-y))), nil + case Time: + // time - time = duration + return Duration(x.Sub(time.Time(y))), nil + } + } + + return nil, nil +} + +var timeMethods = map[string]builtinMethod{ + "in_location": timeIn, + "format": timeFormat, +} + +func timeFormat(fnname string, recV starlark.Value, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var x string + if err := starlark.UnpackPositionalArgs("format", args, kwargs, 1, &x); err != nil { + return nil, err + } + + recv := time.Time(recV.(Time)) + return starlark.String(recv.Format(x)), nil +} + +func timeIn(fnname string, recV starlark.Value, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var x string + if err := starlark.UnpackPositionalArgs("in_location", args, kwargs, 1, &x); err != nil { + return nil, err + } + loc, err := time.LoadLocation(x) + if err != nil { + return nil, err + } + + recv := time.Time(recV.(Time)) + return Time(recv.In(loc)), nil +} + +type builtinMethod func(fnname string, recv starlark.Value, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) + +func builtinAttr(recv starlark.Value, name string, methods map[string]builtinMethod) (starlark.Value, error) { + method := methods[name] + if method == nil { + return nil, nil // no such method + } + + // Allocate a closure over 'method'. + impl := func(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + return method(b.Name(), b.Receiver(), args, kwargs) + } + return starlark.NewBuiltin(name, impl).BindReceiver(recv), nil +} + +func builtinAttrNames(methods map[string]builtinMethod) []string { + names := make([]string, 0, len(methods)) + for name := range methods { + names = append(names, name) + } + sort.Strings(names) + return names +} + +// Threeway interprets a three-way comparison value cmp (-1, 0, +1) +// as a boolean comparison (e.g. x < y). +func threeway(op syntax.Token, cmp int) bool { + switch op { + case syntax.EQL: + return cmp == 0 + case syntax.NEQ: + return cmp != 0 + case syntax.LE: + return cmp <= 0 + case syntax.LT: + return cmp < 0 + case syntax.GE: + return cmp >= 0 + case syntax.GT: + return cmp > 0 + } + panic(op) +} diff --git a/vendor/go.starlark.net/starlarkstruct/module.go b/vendor/go.starlark.net/starlarkstruct/module.go new file mode 100644 index 0000000000..735c98ae31 --- /dev/null +++ b/vendor/go.starlark.net/starlarkstruct/module.go @@ -0,0 +1,43 @@ +package starlarkstruct + +import ( + "fmt" + + "go.starlark.net/starlark" +) + +// A Module is a named collection of values, +// typically a suite of functions imported by a load statement. +// +// It differs from Struct primarily in that its string representation +// does not enumerate its fields. +type Module struct { + Name string + Members starlark.StringDict +} + +var _ starlark.HasAttrs = (*Module)(nil) + +func (m *Module) Attr(name string) (starlark.Value, error) { return m.Members[name], nil } +func (m *Module) AttrNames() []string { return m.Members.Keys() } +func (m *Module) Freeze() { m.Members.Freeze() } +func (m *Module) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: %s", m.Type()) } +func (m *Module) String() string { return fmt.Sprintf("", m.Name) } +func (m *Module) Truth() starlark.Bool { return true } +func (m *Module) Type() string { return "module" } + +// MakeModule may be used as the implementation of a Starlark built-in +// function, module(name, **kwargs). It returns a new module with the +// specified name and members. +func MakeModule(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var name string + if err := starlark.UnpackPositionalArgs(b.Name(), args, nil, 1, &name); err != nil { + return nil, err + } + members := make(starlark.StringDict, len(kwargs)) + for _, kwarg := range kwargs { + k := string(kwarg[0].(starlark.String)) + members[k] = kwarg[1] + } + return &Module{name, members}, nil +} diff --git a/vendor/go.starlark.net/starlarkstruct/struct.go b/vendor/go.starlark.net/starlarkstruct/struct.go new file mode 100644 index 0000000000..7285bfa5a2 --- /dev/null +++ b/vendor/go.starlark.net/starlarkstruct/struct.go @@ -0,0 +1,281 @@ +// Copyright 2017 The Bazel 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 starlarkstruct defines the Starlark types 'struct' and +// 'module', both optional language extensions. +// +package starlarkstruct // import "go.starlark.net/starlarkstruct" + +// It is tempting to introduce a variant of Struct that is a wrapper +// around a Go struct value, for stronger typing guarantees and more +// efficient and convenient field lookup. However: +// 1) all fields of Starlark structs are optional, so we cannot represent +// them using more specific types such as String, Int, *Depset, and +// *File, as such types give no way to represent missing fields. +// 2) the efficiency gain of direct struct field access is rather +// marginal: finding the index of a field by binary searching on the +// sorted list of field names is quite fast compared to the other +// overheads. +// 3) the gains in compactness and spatial locality are also rather +// marginal: the array behind the []entry slice is (due to field name +// strings) only a factor of 2 larger than the corresponding Go struct +// would be, and, like the Go struct, requires only a single allocation. + +import ( + "fmt" + "sort" + "strings" + + "go.starlark.net/starlark" + "go.starlark.net/syntax" +) + +// Make is the implementation of a built-in function that instantiates +// an immutable struct from the specified keyword arguments. +// +// An application can add 'struct' to the Starlark environment like so: +// +// globals := starlark.StringDict{ +// "struct": starlark.NewBuiltin("struct", starlarkstruct.Make), +// } +// +func Make(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + if len(args) > 0 { + return nil, fmt.Errorf("struct: unexpected positional arguments") + } + return FromKeywords(Default, kwargs), nil +} + +// FromKeywords returns a new struct instance whose fields are specified by the +// key/value pairs in kwargs. (Each kwargs[i][0] must be a starlark.String.) +func FromKeywords(constructor starlark.Value, kwargs []starlark.Tuple) *Struct { + if constructor == nil { + panic("nil constructor") + } + s := &Struct{ + constructor: constructor, + entries: make(entries, 0, len(kwargs)), + } + for _, kwarg := range kwargs { + k := string(kwarg[0].(starlark.String)) + v := kwarg[1] + s.entries = append(s.entries, entry{k, v}) + } + sort.Sort(s.entries) + return s +} + +// FromStringDict returns a new struct instance whose elements are those of d. +// The constructor parameter specifies the constructor; use Default for an ordinary struct. +func FromStringDict(constructor starlark.Value, d starlark.StringDict) *Struct { + if constructor == nil { + panic("nil constructor") + } + s := &Struct{ + constructor: constructor, + entries: make(entries, 0, len(d)), + } + for k, v := range d { + s.entries = append(s.entries, entry{k, v}) + } + sort.Sort(s.entries) + return s +} + +// Struct is an immutable Starlark type that maps field names to values. +// It is not iterable and does not support len. +// +// A struct has a constructor, a distinct value that identifies a class +// of structs, and which appears in the struct's string representation. +// +// Operations such as x+y fail if the constructors of the two operands +// are not equal. +// +// The default constructor, Default, is the string "struct", but +// clients may wish to 'brand' structs for their own purposes. +// The constructor value appears in the printed form of the value, +// and is accessible using the Constructor method. +// +// Use Attr to access its fields and AttrNames to enumerate them. +type Struct struct { + constructor starlark.Value + entries entries // sorted by name +} + +// Default is the default constructor for structs. +// It is merely the string "struct". +const Default = starlark.String("struct") + +type entries []entry + +func (a entries) Len() int { return len(a) } +func (a entries) Less(i, j int) bool { return a[i].name < a[j].name } +func (a entries) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +type entry struct { + name string + value starlark.Value +} + +var ( + _ starlark.HasAttrs = (*Struct)(nil) + _ starlark.HasBinary = (*Struct)(nil) +) + +// ToStringDict adds a name/value entry to d for each field of the struct. +func (s *Struct) ToStringDict(d starlark.StringDict) { + for _, e := range s.entries { + d[e.name] = e.value + } +} + +func (s *Struct) String() string { + buf := new(strings.Builder) + if s.constructor == Default { + // NB: The Java implementation always prints struct + // even for Bazel provider instances. + buf.WriteString("struct") // avoid String()'s quotation + } else { + buf.WriteString(s.constructor.String()) + } + buf.WriteByte('(') + for i, e := range s.entries { + if i > 0 { + buf.WriteString(", ") + } + buf.WriteString(e.name) + buf.WriteString(" = ") + buf.WriteString(e.value.String()) + } + buf.WriteByte(')') + return buf.String() +} + +// Constructor returns the constructor used to create this struct. +func (s *Struct) Constructor() starlark.Value { return s.constructor } + +func (s *Struct) Type() string { return "struct" } +func (s *Struct) Truth() starlark.Bool { return true } // even when empty +func (s *Struct) Hash() (uint32, error) { + // Same algorithm as Tuple.hash, but with different primes. + var x, m uint32 = 8731, 9839 + for _, e := range s.entries { + namehash, _ := starlark.String(e.name).Hash() + x = x ^ 3*namehash + y, err := e.value.Hash() + if err != nil { + return 0, err + } + x = x ^ y*m + m += 7349 + } + return x, nil +} +func (s *Struct) Freeze() { + for _, e := range s.entries { + e.value.Freeze() + } +} + +func (x *Struct) Binary(op syntax.Token, y starlark.Value, side starlark.Side) (starlark.Value, error) { + if y, ok := y.(*Struct); ok && op == syntax.PLUS { + if side == starlark.Right { + x, y = y, x + } + + if eq, err := starlark.Equal(x.constructor, y.constructor); err != nil { + return nil, fmt.Errorf("in %s + %s: error comparing constructors: %v", + x.constructor, y.constructor, err) + } else if !eq { + return nil, fmt.Errorf("cannot add structs of different constructors: %s + %s", + x.constructor, y.constructor) + } + + z := make(starlark.StringDict, x.len()+y.len()) + for _, e := range x.entries { + z[e.name] = e.value + } + for _, e := range y.entries { + z[e.name] = e.value + } + + return FromStringDict(x.constructor, z), nil + } + return nil, nil // unhandled +} + +// Attr returns the value of the specified field. +func (s *Struct) Attr(name string) (starlark.Value, error) { + // Binary search the entries. + // This implementation is a specialization of + // sort.Search that avoids dynamic dispatch. + n := len(s.entries) + i, j := 0, n + for i < j { + h := int(uint(i+j) >> 1) + if s.entries[h].name < name { + i = h + 1 + } else { + j = h + } + } + if i < n && s.entries[i].name == name { + return s.entries[i].value, nil + } + + var ctor string + if s.constructor != Default { + ctor = s.constructor.String() + " " + } + return nil, starlark.NoSuchAttrError( + fmt.Sprintf("%sstruct has no .%s attribute", ctor, name)) +} + +func (s *Struct) len() int { return len(s.entries) } + +// AttrNames returns a new sorted list of the struct fields. +func (s *Struct) AttrNames() []string { + names := make([]string, len(s.entries)) + for i, e := range s.entries { + names[i] = e.name + } + return names +} + +func (x *Struct) CompareSameType(op syntax.Token, y_ starlark.Value, depth int) (bool, error) { + y := y_.(*Struct) + switch op { + case syntax.EQL: + return structsEqual(x, y, depth) + case syntax.NEQ: + eq, err := structsEqual(x, y, depth) + return !eq, err + default: + return false, fmt.Errorf("%s %s %s not implemented", x.Type(), op, y.Type()) + } +} + +func structsEqual(x, y *Struct, depth int) (bool, error) { + if x.len() != y.len() { + return false, nil + } + + if eq, err := starlark.Equal(x.constructor, y.constructor); err != nil { + return false, fmt.Errorf("error comparing struct constructors %v and %v: %v", + x.constructor, y.constructor, err) + } else if !eq { + return false, nil + } + + for i, n := 0, x.len(); i < n; i++ { + if x.entries[i].name != y.entries[i].name { + return false, nil + } else if eq, err := starlark.EqualDepth(x.entries[i].value, y.entries[i].value, depth-1); err != nil { + return false, err + } else if !eq { + return false, nil + } + } + return true, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 161a09fe33..29230a474a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -62,8 +62,10 @@ github.com/spf13/pflag ## explicit go.starlark.net/internal/compile go.starlark.net/internal/spell +go.starlark.net/lib/time go.starlark.net/resolve go.starlark.net/starlark +go.starlark.net/starlarkstruct go.starlark.net/syntax # golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4 ## explicit From 47989248edaaf265e08a93a37d510c4fa1b76205 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Fri, 26 May 2023 19:04:37 +0200 Subject: [PATCH 042/114] dwarf/op: use readMemory function (#3391) dwarf/op gained the ability to execute DW_OP_deref opcodes a while ago but because we didn't save the readMemory function in the context structure it never worked. --- pkg/dwarf/op/op.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/dwarf/op/op.go b/pkg/dwarf/op/op.go index a3269f2012..e8a807f6d5 100644 --- a/pkg/dwarf/op/op.go +++ b/pkg/dwarf/op/op.go @@ -7,8 +7,8 @@ import ( "fmt" "io" - "github.com/go-delve/delve/pkg/dwarf/leb128" "github.com/go-delve/delve/pkg/dwarf" + "github.com/go-delve/delve/pkg/dwarf/leb128" ) // Opcode represent a DWARF stack program instruction. @@ -67,6 +67,7 @@ func ExecuteStackProgram(regs DwarfRegisters, instructions []byte, ptrSize int, stack: make([]int64, 0, 3), DwarfRegisters: regs, ptrSize: ptrSize, + readMemory: readMemory, } for tick := 0; tick < len(instructions)*arbitraryExecutionLimitFactor; tick++ { From 9d6bce467c87d8f209bee6b346e96da088fbc409 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Wed, 31 May 2023 17:33:23 +0300 Subject: [PATCH 043/114] _scripts: fix typos (#3402) --- _scripts/gen-travis.go | 2 +- _scripts/make.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_scripts/gen-travis.go b/_scripts/gen-travis.go index a6028c92ec..cd9d454341 100644 --- a/_scripts/gen-travis.go +++ b/_scripts/gen-travis.go @@ -26,7 +26,7 @@ var minVersion = goVersion{Major: goversion.MinSupportedVersionOfGoMajor, Minor: func (v goVersion) dec() goVersion { v.Minor-- if v.Minor < 0 { - panic("TODO: fill the maximum minor version number for v.Maxjor here") + panic("TODO: fill the maximum minor version number for v.Major here") } return v } diff --git a/_scripts/make.go b/_scripts/make.go index 3b2fc299bf..eef24266b1 100644 --- a/_scripts/make.go +++ b/_scripts/make.go @@ -144,7 +144,7 @@ func checkCert() bool { return false } if err != nil { - fmt.Printf("An error occoured when generating and installing a new certificate: %v\n", err) + fmt.Printf("An error occurred when generating and installing a new certificate: %v\n", err) return false } os.Setenv("CERT", "dlv-cert") From 6a56d0eedc182fd867c9265ca16b2d9d75c80e8c Mon Sep 17 00:00:00 2001 From: Andrei Matei Date: Wed, 31 May 2023 12:58:47 -0400 Subject: [PATCH 044/114] dwarf: ignore DeclLine for function args (#3400) --- _fixtures/decllinetest.go | 5 ++++- pkg/dwarf/reader/variables.go | 20 ++++++++++++-------- pkg/proc/proc_test.go | 9 ++++++++- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/_fixtures/decllinetest.go b/_fixtures/decllinetest.go index 60fc110ffa..9074d7e32d 100644 --- a/_fixtures/decllinetest.go +++ b/_fixtures/decllinetest.go @@ -11,6 +11,9 @@ func main() { f1(a, b) } -func f1(a, b int) { +func f1( + a int, + b int, +) { fmt.Printf("%d %d\n", a, b) } diff --git a/pkg/dwarf/reader/variables.go b/pkg/dwarf/reader/variables.go index d39f9d68ae..b47b7011e4 100644 --- a/pkg/dwarf/reader/variables.go +++ b/pkg/dwarf/reader/variables.go @@ -54,14 +54,18 @@ func variablesInternal(v []Variable, root *godwarf.Tree, depth int, pc uint64, l } return v default: - o := 0 - if root.Tag != dwarf.TagFormalParameter && (flags&VariablesTrustDeclLine != 0) { - // visibility for variables starts the line after declaration line, - // except for formal parameters, which are visible on the same line they - // are defined. - o = 1 - } - if declLine, ok := root.Val(dwarf.AttrDeclLine).(int64); (flags&VariablesNoDeclLineCheck != 0) || !ok || line >= int(declLine)+o { + // Variables are considered to be visible starting on the line after the + // line they are declared on. Function arguments are an exception - the line + // they are declared on does not matter; they are considered to be + // visible throughout the function. + declLine, varHasDeclLine := root.Val(dwarf.AttrDeclLine).(int64) + checkDeclLine := + root.Tag != dwarf.TagFormalParameter && // var is not a function argument + varHasDeclLine && // we know the DeclLine + (flags&VariablesNoDeclLineCheck == 0) // we were not explicitly instructed to ignore DeclLine + + varVisible := !checkDeclLine || (line >= int(declLine)+1) // +1 because visibility starts on the line after DeclLine + if varVisible { return append(v, Variable{root, depth}) } return v diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 4a145591c2..874434c85c 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -3612,7 +3612,11 @@ func TestDeclLine(t *testing.T) { setFileBreakpoint(p, t, fixture.Source, 9) setFileBreakpoint(p, t, fixture.Source, 10) setFileBreakpoint(p, t, fixture.Source, 11) - setFileBreakpoint(p, t, fixture.Source, 14) + b := setFunctionBreakpoint(p, t, "main.f1") + if b.Line != 14 { + // Line 14 is hard-coded below. + t.Fatalf("expected \"main.f1\" breakpoint to be set on line 14, but got line: %d", b.Line) + } assertNoError(grp.Continue(), t, "Continue 1") if goversion.VersionAfterOrEqual(runtime.Version(), 1, 15) { @@ -3635,6 +3639,9 @@ func TestDeclLine(t *testing.T) { testDeclLineCount(t, p, 11, []string{"a", "b"}) assertNoError(grp.Continue(), t, "Continue 5") + // On line 14, we expect the function's arguments to be available, even + // though their DW_AT_decl_line declares higher line numbers. The decl_line + // is supposed to be ignored for the visibility of arguments. testDeclLineCount(t, p, 14, []string{"a", "b"}) }) } From 5c711f8d09696d620f36b56fe88a38f428ca5730 Mon Sep 17 00:00:00 2001 From: Andrei Matei Date: Wed, 31 May 2023 13:00:06 -0400 Subject: [PATCH 045/114] docgen: fix links with trailing dots (#3399) --- Documentation/cli/README.md | 2 +- pkg/terminal/docgen.go | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/cli/README.md b/Documentation/cli/README.md index 8bc707ab09..01818a5036 100644 --- a/Documentation/cli/README.md +++ b/Documentation/cli/README.md @@ -551,7 +551,7 @@ Print contents of CPU registers. regs [-a] -Argument -a shows more registers. Individual registers can also be displayed by 'print' and 'display'. See [Documentation/cli/expr.md.](//github.com/go-delve/delve/tree/master/Documentation/cli/expr.md.) +Argument -a shows more registers. Individual registers can also be displayed by 'print' and 'display'. See [Documentation/cli/expr.md](//github.com/go-delve/delve/tree/master/Documentation/cli/expr.md). ## restart diff --git a/pkg/terminal/docgen.go b/pkg/terminal/docgen.go index a3a22fc0a0..1cea225cc4 100644 --- a/pkg/terminal/docgen.go +++ b/pkg/terminal/docgen.go @@ -27,6 +27,10 @@ func replaceDocPath(s string) string { break } } + // If we captured a trailing dot, backtrack. + if s[end-1] == '.' { + end-- + } text := s[start:end] s = s[:start] + fmt.Sprintf("[%s](//github.com/go-delve/delve/tree/master/%s)", text, text) + s[end:] From 6d7263f6f9049d992e63ea0edc78420fe3463989 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 31 May 2023 19:11:47 +0200 Subject: [PATCH 046/114] service/rpccommon: correct wrong comments (#3397) --- service/rpccommon/server.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/service/rpccommon/server.go b/service/rpccommon/server.go index d7916cb5c3..3a2302d83a 100644 --- a/service/rpccommon/server.go +++ b/service/rpccommon/server.go @@ -32,7 +32,7 @@ import ( type ServerImpl struct { // config is all the information necessary to start the debugger and server. config *service.Config - // listener is used to serve HTTP. + // listener is used to serve JSON-RPC. listener net.Listener // stopChan is used to stop the listener goroutine. stopChan chan struct{} @@ -103,9 +103,8 @@ func (s *ServerImpl) Stop() error { return s.debugger.Detach(kill) } -// Run starts a debugger and exposes it with an HTTP server. The debugger -// itself can be stopped with the `detach` API. Run blocks until the HTTP -// server stops. +// Run starts a debugger and exposes it with an JSON-RPC server. The debugger +// itself can be stopped with the `detach` API. func (s *ServerImpl) Run() error { var err error From cc05aa20641b347d99b09299567e0e0a61881c04 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 31 May 2023 19:18:15 +0200 Subject: [PATCH 047/114] TeamCity: actually run linux/386 tests on linux/386 (#3392) --- .teamcity/settings.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/.teamcity/settings.kts b/.teamcity/settings.kts index c57106a48c..7a792ee6c6 100644 --- a/.teamcity/settings.kts +++ b/.teamcity/settings.kts @@ -192,6 +192,7 @@ class TestBuild(val os: String, val arch: String, version: String, buildId: Abso --env TEAMCITY_VERSION=${'$'}TEAMCITY_VERSION --env CI=true --privileged + --platform linux/$dockerArch $dockerArch/ubuntu:20.04 /delve/_scripts/test_linux.sh ${"go$version"} $arch """.trimIndent() From 407ace96c852dc473acadb2268c0fb86791777be Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 31 May 2023 19:21:12 +0200 Subject: [PATCH 048/114] debugger: inline clearBreakpoint, createLogicalBreakpoint (#3389) --- service/debugger/debugger.go | 72 +++++++++++++++--------------------- 1 file changed, 29 insertions(+), 43 deletions(-) diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index af5eb5c1b1..4cd6e72ab1 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -732,42 +732,7 @@ func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint, locExpr string, return locs[0].PCs } } - createdBp, err := createLogicalBreakpoint(d, requestedBp, &setbp, suspended) - if err != nil { - return nil, err - } - d.log.Infof("created breakpoint: %#v", createdBp) - return createdBp, nil -} - -func (d *Debugger) convertBreakpoint(lbp *proc.LogicalBreakpoint) *api.Breakpoint { - abp := api.ConvertLogicalBreakpoint(lbp) - bps := []*proc.Breakpoint{} - pids := []int{} - t := proc.ValidTargets{Group: d.target} - for t.Next() { - for _, bp := range t.Breakpoints().M { - if bp.LogicalID() == lbp.LogicalID { - bps = append(bps, bp) - pids = append(pids, t.Pid()) - } - } - } - api.ConvertPhysicalBreakpoints(abp, pids, bps) - return abp -} - -func (d *Debugger) ConvertThreadBreakpoint(thread proc.Thread) *api.Breakpoint { - if b := thread.Breakpoint(); b.Active && b.Breakpoint.Logical != nil { - return d.convertBreakpoint(b.Breakpoint.Logical) - } - return nil -} - -// createLogicalBreakpoint creates one physical breakpoint for each address -// in addrs and associates all of them with the same logical breakpoint. -func createLogicalBreakpoint(d *Debugger, requestedBp *api.Breakpoint, setbp *proc.SetBreakpoint, suspended bool) (*api.Breakpoint, error) { id := requestedBp.ID if id <= 0 { @@ -780,12 +745,12 @@ func createLogicalBreakpoint(d *Debugger, requestedBp *api.Breakpoint, setbp *pr lbp := &proc.LogicalBreakpoint{LogicalID: id, HitCount: make(map[int64]uint64), Enabled: true} d.target.LogicalBreakpoints[id] = lbp - err := copyLogicalBreakpointInfo(lbp, requestedBp) + err = copyLogicalBreakpointInfo(lbp, requestedBp) if err != nil { return nil, err } - lbp.Set = *setbp + lbp.Set = setbp if lbp.Set.Expr != nil { addrs := lbp.Set.Expr(d.Target()) @@ -809,7 +774,33 @@ func createLogicalBreakpoint(d *Debugger, requestedBp *api.Breakpoint, setbp *pr } } - return d.convertBreakpoint(lbp), nil + createdBp := d.convertBreakpoint(lbp) + d.log.Infof("created breakpoint: %#v", createdBp) + return createdBp, nil +} + +func (d *Debugger) convertBreakpoint(lbp *proc.LogicalBreakpoint) *api.Breakpoint { + abp := api.ConvertLogicalBreakpoint(lbp) + bps := []*proc.Breakpoint{} + pids := []int{} + t := proc.ValidTargets{Group: d.target} + for t.Next() { + for _, bp := range t.Breakpoints().M { + if bp.LogicalID() == lbp.LogicalID { + bps = append(bps, bp) + pids = append(pids, t.Pid()) + } + } + } + api.ConvertPhysicalBreakpoints(abp, pids, bps) + return abp +} + +func (d *Debugger) ConvertThreadBreakpoint(thread proc.Thread) *api.Breakpoint { + if b := thread.Breakpoint(); b.Active && b.Breakpoint.Logical != nil { + return d.convertBreakpoint(b.Breakpoint.Logical) + } + return nil } func (d *Debugger) CreateEBPFTracepoint(fnName string) error { @@ -970,11 +961,6 @@ func parseHitCondition(hitCond string) (token.Token, int, error) { func (d *Debugger) ClearBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoint, error) { d.targetMutex.Lock() defer d.targetMutex.Unlock() - return d.clearBreakpoint(requestedBp) -} - -// clearBreakpoint clears a breakpoint, we can consume this function to avoid locking a goroutine -func (d *Debugger) clearBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoint, error) { if requestedBp.ID <= 0 { if len(d.target.Targets()) != 1 { return nil, ErrNotImplementedWithMultitarget From 7603e46f75d610e99bd6438f1afe3a945c8292d0 Mon Sep 17 00:00:00 2001 From: Andrei Matei Date: Wed, 31 May 2023 13:29:36 -0400 Subject: [PATCH 049/114] starbind: fix use of ptr variables in starlark (#3386) --- .../testvariables_pointers_not_loaded.go | 17 +++++ pkg/terminal/starbind/conv.go | 7 +- pkg/terminal/starbind/starlark.go | 3 +- pkg/terminal/starlark_test.go | 67 +++++++++++++++++++ 4 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 _fixtures/testvariables_pointers_not_loaded.go diff --git a/_fixtures/testvariables_pointers_not_loaded.go b/_fixtures/testvariables_pointers_not_loaded.go new file mode 100644 index 0000000000..f21b0ea06e --- /dev/null +++ b/_fixtures/testvariables_pointers_not_loaded.go @@ -0,0 +1,17 @@ +package main + +import "runtime" + +func main() { + type StructWithInterface struct { + Val any + } + var i int + var ba = StructWithInterface{} + ba.Val = &i + + var ptrPtr **int + _ = ptrPtr + + runtime.Breakpoint() +} diff --git a/pkg/terminal/starbind/conv.go b/pkg/terminal/starbind/conv.go index 595409a950..196c295bac 100644 --- a/pkg/terminal/starbind/conv.go +++ b/pkg/terminal/starbind/conv.go @@ -453,10 +453,15 @@ func (v ptrVariableAsStarlarkValue) Attr(name string) (starlark.Value, error) { } func (v ptrVariableAsStarlarkValue) AttrNames() []string { + if len(v.v.Children) == 0 { + // The pointer variable was not loaded; we don't know the field names. + return nil + } if v.v.Children[0].Kind != reflect.Struct { return nil } - // autodereference + // autodereference: present the field names of the pointed-to struct as the + // fields of this pointer variable. x := structVariableAsStarlarkValue{&v.v.Children[0], v.env} return x.AttrNames() } diff --git a/pkg/terminal/starbind/starlark.go b/pkg/terminal/starbind/starlark.go index ac74b47f3c..f34335b0e6 100644 --- a/pkg/terminal/starbind/starlark.go +++ b/pkg/terminal/starbind/starlark.go @@ -141,12 +141,13 @@ func (env *Env) printFunc() func(_ *starlark.Thread, msg string) { // Source can be either a []byte, a string or a io.Reader. If source is nil // Execute will execute the file specified by 'path'. // After the file is executed if a function named mainFnName exists it will be called, passing args to it. -func (env *Env) Execute(path string, source interface{}, mainFnName string, args []interface{}) (starlark.Value, error) { +func (env *Env) Execute(path string, source interface{}, mainFnName string, args []interface{}) (_ starlark.Value, _err error) { defer func() { err := recover() if err == nil { return } + _err = fmt.Errorf("panic executing starlark script: %v", err) fmt.Fprintf(env.out, "panic executing starlark script: %v\n", err) for i := 0; ; i++ { pc, file, line, ok := runtime.Caller(i) diff --git a/pkg/terminal/starlark_test.go b/pkg/terminal/starlark_test.go index 7a304da14d..7f4f8706c8 100644 --- a/pkg/terminal/starlark_test.go +++ b/pkg/terminal/starlark_test.go @@ -158,3 +158,70 @@ func TestStarlarkVariable(t *testing.T) { } }) } + +// Test that pointer variables that were not loaded don't lead to crashes when +// used in Starlark scripts. +func TestStarlarkVariablePointerNotLoaded(t *testing.T) { + withTestTerminal("testvariables_pointers_not_loaded", t, func(term *FakeTerminal) { + term.MustExec("continue") + + // We're going to partially load some variables through the eval() + // builtin. Then we're going to attempt to evaluate expressions which + // try to access a field from a pointer variable that wasn't loaded + // (i.e. a ptrVariableAsStarlarkValue with no children). The tests will + // verify that we get an error. This is a regression test; we used to + // panic. + for _, tc := range []struct{ name, script, expErr string }{ + { + // In this test, we'll load v. v will have a child (i.e. + // v.Children[0]), but because v is nil, v.Children[0] will not + // be loaded. We'll turn v.Children[0] into a + // ptrVariableAsStarlarkValue, and attempt to access a field on + // it. + // + // v -> structAsStarlarkValue> + // v.Children[0] -> structAsStarlarkValue> + // v.Children[0].Value -> ptrVariableAsStarlarkValue<*int> ; this pointer variable has not been loaded + name: "partial load because of nil ptr", + script: ` +v = eval( + None, "ptrPtr", None + ).Variable +v.Children[0].Value.XXX +`, + expErr: "*int has no .XXX field or method", + }, + { + // In this test, MaxStructFields = 10 and MaxVariableRecurse = 0 + // will cause us to load v, and v.Children[0] (in the sense that + // v.Children[0] has a child), but _not_ load + // v.Children[0].Children[0] (because the recursion limit is + // exhausted by the descent into the top-level struct, so we + // don't load what hides under the interface). + // + // v -> structAsStarlarkValue> + // v.Children[0] -> structAsStarlarkValue> + // v.Children[0].Children[0] -> structAsStarlarkValue> + // v.Children[0].Children[0].Value -> ptrVariableAsStarlarkValue<*int> ; this pointer variable has not been loaded + name: "partial load because of recursion limit", + script: ` +v = eval( + None, "ba", {"MaxVariableRecurse": 0, "MaxStructFields": 10} + ).Variable; +v.Children[0].Children[0].Value.XXX +`, + expErr: "*int has no .XXX field or method", + }, + } { + t.Run(tc.name, func(t *testing.T) { + _, err := term.ExecStarlark(tc.script) + if err == nil { + t.Fatalf("expected error %q, got success", tc.expErr) + } + if !strings.Contains(err.Error(), tc.expErr) { + t.Fatalf("expected error %q, got \"%s\"", tc.expErr, err) + } + }) + } + }) +} From 8b9c3a93f503cbbe54a701bedfbe3af114aa55aa Mon Sep 17 00:00:00 2001 From: nozzy123nozzy Date: Wed, 7 Jun 2023 08:12:11 +0900 Subject: [PATCH 050/114] cmd/commands: Fix to read debug info file from the correct directory when using trace command with -e option. (#3405) --- cmd/dlv/cmds/commands.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cmd/dlv/cmds/commands.go b/cmd/dlv/cmds/commands.go index a189e480b1..38221c9707 100644 --- a/cmd/dlv/cmds/commands.go +++ b/cmd/dlv/cmds/commands.go @@ -303,7 +303,8 @@ to know what functions your process is executing. The output of the trace sub command is printed to stderr, so if you would like to only see the output of the trace operations you can redirect stdout.`, - Run: traceCmd, + Run: func(cmd *cobra.Command, args []string) { + os.Exit(traceCmd(cmd, args, conf)) }, } traceCommand.Flags().IntVarP(&traceAttachPid, "pid", "p", 0, "Pid to attach to.") traceCommand.Flags().StringVarP(&traceExecFile, "exec", "e", "", "Binary file to exec and trace.") @@ -574,7 +575,7 @@ func debugCmd(cmd *cobra.Command, args []string) { os.Exit(status) } -func traceCmd(cmd *cobra.Command, args []string) { +func traceCmd(cmd *cobra.Command, args []string, conf *config.Config) int { status := func() int { err := logflags.Setup(log, logOutput, logDest) defer logflags.Close() @@ -648,6 +649,7 @@ func traceCmd(cmd *cobra.Command, args []string) { WorkingDir: workingDir, Backend: backend, CheckGoVersion: checkGoVersion, + DebugInfoDirectories: conf.DebugInfoDirectories, }, }) if err := server.Run(); err != nil { @@ -769,7 +771,7 @@ func traceCmd(cmd *cobra.Command, args []string) { } return 0 }() - os.Exit(status) + return status } func isBreakpointExistsErr(err error) bool { From 6d412c65da65a57e1ea0d458a04f996a3da794a3 Mon Sep 17 00:00:00 2001 From: Andrei Matei Date: Tue, 6 Jun 2023 23:44:51 -0400 Subject: [PATCH 051/114] rpc2, debugger: Fix comments around goroutine grouping (#3374) --- service/debugger/debugger.go | 13 ++++++++++--- service/rpc2/server.go | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index 4cd6e72ab1..27441fbaf3 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -1669,9 +1669,16 @@ func formatLoc(loc proc.Location) string { return fmt.Sprintf("%s:%d in %s", loc.File, loc.Line, fnname) } -// GroupGoroutines divides goroutines in gs into groups as specified by groupBy and groupByArg. -// A maximum of maxGoroutinesPerGroup are saved in each group, but the total -// number of goroutines in each group is recorded. +// GroupGoroutines divides goroutines in gs into groups as specified by +// group.{GroupBy,GroupByKey}. A maximum of group.MaxGroupMembers are saved in +// each group, but the total number of goroutines in each group is recorded. If +// group.MaxGroups is set, then at most that many groups are returned. If some +// groups end up being dropped because of this limit, the tooManyGroups return +// value is set. +// +// The first return value represents the goroutines that have been included in +// one of the returned groups (subject to the MaxGroupMembers and MaxGroups +// limits). The second return value represents the groups. func (d *Debugger) GroupGoroutines(gs []*proc.G, group *api.GoroutineGroupingOptions) ([]*proc.G, []api.GoroutineGroup, bool) { if group.GroupBy == api.GoroutineFieldNone { return gs, nil, false diff --git a/service/rpc2/server.go b/service/rpc2/server.go index 3d8f6215d0..f90153980a 100644 --- a/service/rpc2/server.go +++ b/service/rpc2/server.go @@ -657,7 +657,7 @@ type ListGoroutinesOut struct { // be grouped with the specified criterion. // If the value of arg.GroupBy is GoroutineLabel goroutines will // be grouped by the value of the label with key GroupByKey. -// For each group a maximum of MaxExamples example goroutines are +// For each group a maximum of MaxGroupMembers example goroutines are // returned, as well as the total number of goroutines in the group. func (s *RPCServer) ListGoroutines(arg ListGoroutinesIn, out *ListGoroutinesOut) error { //TODO(aarzilli): if arg contains a running goroutines filter (not negated) From ea13a24f38f1cac859fc34e0fdb7cbd8c0c8a5f0 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 7 Jun 2023 05:46:00 +0200 Subject: [PATCH 052/114] TeamCity: fix linux/arm64 build (#3403) --- .teamcity/settings.kts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.teamcity/settings.kts b/.teamcity/settings.kts index 7a792ee6c6..d1b912db99 100644 --- a/.teamcity/settings.kts +++ b/.teamcity/settings.kts @@ -176,6 +176,12 @@ class TestBuild(val os: String, val arch: String, version: String, buildId: Abso arch } } + val dockerPlatformArch = when (arch) { + "arm64" -> "arm64/v8" + else -> { + dockerArch + } + } dockerCommand { name = "Pull Ubuntu" commandType = other { From 9b17415e83934f976cc0ab7cb2f2a5a10c83093c Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 7 Jun 2023 05:46:56 +0200 Subject: [PATCH 053/114] terminal: ask for confirmation when using 'quit -c' with breakpoints (#3398) --- pkg/terminal/command.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index d729311db6..3103af8d76 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -2876,6 +2876,20 @@ func exitCommand(t *Term, ctx callContext, args string) error { if !t.client.IsMulticlient() { return errors.New("not connected to an --accept-multiclient server") } + bps, _ := t.client.ListBreakpoints(false) + hasUserBreakpoints := false + for _, bp := range bps { + if bp.ID >= 0 { + hasUserBreakpoints = true + break + } + } + if hasUserBreakpoints { + yes, _ := yesno(t.line, "There are breakpoints set, do you wish to quit and continue without clearing breakpoints? [Y/n] ", "yes") + if !yes { + return nil + } + } t.quitContinue = true } return ExitRequestError{} From 5880f4cec94d57b817a905b249e030fb2db73208 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 7 Jun 2023 05:50:03 +0200 Subject: [PATCH 054/114] proc/test: reenable cgo testing on FreeBSD (#3394) --- pkg/proc/test/support.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/proc/test/support.go b/pkg/proc/test/support.go index c9bd0e3c56..2e882d99ba 100644 --- a/pkg/proc/test/support.go +++ b/pkg/proc/test/support.go @@ -364,8 +364,9 @@ var hasCgo = func() bool { if strings.TrimSpace(string(out)) != "1" { return false } - _, err = exec.LookPath("gcc") - return err == nil + _, err1 := exec.LookPath("gcc") + _, err2 := exec.LookPath("clang") + return (err1 == nil) || (err2 == nil) }() func MustHaveCgo(t *testing.T) { From c958128f2143d13636bcda5afc1951dc445c576f Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Wed, 7 Jun 2023 05:52:19 +0200 Subject: [PATCH 055/114] terminal: expand ~ in paths passed to 'source' (#3387) --- pkg/terminal/command.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index 3103af8d76..ef83ea4646 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -19,6 +19,7 @@ import ( "path/filepath" "reflect" "regexp" + "runtime" "sort" "strconv" "strings" @@ -2451,15 +2452,26 @@ func (c *Commands) sourceCommand(t *Term, ctx callContext, args string) error { return fmt.Errorf("wrong number of arguments: source ") } + if args == "-" { + return t.starlarkEnv.REPL() + } + + if runtime.GOOS != "windows" && strings.HasPrefix(args, "~") { + home, err := os.UserHomeDir() + if err == nil { + if args == "~" { + args = home + } else if strings.HasPrefix(args, "~/") { + args = filepath.Join(home, args[2:]) + } + } + } + if filepath.Ext(args) == ".star" { _, err := t.starlarkEnv.Execute(args, nil, "main", nil) return err } - if args == "-" { - return t.starlarkEnv.REPL() - } - return c.executeFile(t, args) } From 380920c340f3f4da24ca68e1387d45675c0a661e Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 12 Jun 2023 23:29:09 +0200 Subject: [PATCH 056/114] TeamCity: fix linux/arm64 build (second attempt) (#3411) Second attempt at doing what PR #3403 tried to do. --- .teamcity/settings.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.teamcity/settings.kts b/.teamcity/settings.kts index d1b912db99..3ef170be55 100644 --- a/.teamcity/settings.kts +++ b/.teamcity/settings.kts @@ -198,7 +198,7 @@ class TestBuild(val os: String, val arch: String, version: String, buildId: Abso --env TEAMCITY_VERSION=${'$'}TEAMCITY_VERSION --env CI=true --privileged - --platform linux/$dockerArch + --platform linux/$dockerPlatformArch $dockerArch/ubuntu:20.04 /delve/_scripts/test_linux.sh ${"go$version"} $arch """.trimIndent() From e549a02f0e3f361e69fb26dc42581e6ed222614f Mon Sep 17 00:00:00 2001 From: Suzy Mueller Date: Mon, 12 Jun 2023 17:29:44 -0400 Subject: [PATCH 057/114] service/dap: update go-dap to latest (#3414) * service/dap: update go-dap to latest * update remaining possible nil checks * move helper functions to the end of the file --- go.mod | 2 +- go.sum | 4 +- service/dap/daptest/client.go | 12 +- service/dap/server.go | 25 +- service/dap/server_test.go | 92 +- vendor/github.com/google/go-dap/go.mod | 2 + .../github.com/google/go-dap/schematypes.go | 828 +++++++++--------- vendor/modules.txt | 2 +- 8 files changed, 517 insertions(+), 450 deletions(-) diff --git a/go.mod b/go.mod index 2be8c4d5b5..9385f2d4a3 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/creack/pty v1.1.9 github.com/derekparker/trie v0.0.0-20221213183930-4c74548207f4 github.com/go-delve/liner v1.2.3-0.20220127212407-d32d89dd2a5d - github.com/google/go-dap v0.7.0 + github.com/google/go-dap v0.9.1 github.com/hashicorp/golang-lru v0.5.4 github.com/mattn/go-colorable v0.0.9 github.com/mattn/go-isatty v0.0.3 diff --git a/go.sum b/go.sum index af05495ef7..9cf8af0c48 100644 --- a/go.sum +++ b/go.sum @@ -89,8 +89,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-dap v0.7.0 h1:088PdKBUkxAxrXrnY8FREUJXpS6Y6jhAyZIuJv3OGOM= -github.com/google/go-dap v0.7.0/go.mod h1:5q8aYQFnHOAZEMP+6vmq25HKYAEwE+LF5yh7JKrrhSQ= +github.com/google/go-dap v0.9.1 h1:d8dETjgHMR9/xs+Xza+NrZmB7jxIS5OtM2uRsyJVA/c= +github.com/google/go-dap v0.9.1/go.mod h1:HAeyoSd2WIfTfg+0GRXcFrb+RnojAtGNh+k+XTIxJDE= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= diff --git a/service/dap/daptest/client.go b/service/dap/daptest/client.go index 7277c78d31..77de55110f 100644 --- a/service/dap/daptest/client.go +++ b/service/dap/daptest/client.go @@ -73,7 +73,7 @@ func (c *Client) ExpectMessage(t *testing.T) dap.Message { func (c *Client) ExpectInvisibleErrorResponse(t *testing.T) *dap.ErrorResponse { t.Helper() er := c.ExpectErrorResponse(t) - if er.Body.Error.ShowUser { + if er.Body.Error != nil && er.Body.Error.ShowUser { t.Errorf("\ngot %#v\nwant ShowUser=false", er) } return er @@ -82,7 +82,7 @@ func (c *Client) ExpectInvisibleErrorResponse(t *testing.T) *dap.ErrorResponse { func (c *Client) ExpectVisibleErrorResponse(t *testing.T) *dap.ErrorResponse { t.Helper() er := c.ExpectErrorResponse(t) - if !er.Body.Error.ShowUser { + if er.Body.Error == nil || !er.Body.Error.ShowUser { t.Errorf("\ngot %#v\nwant ShowUser=true", er) } return er @@ -91,6 +91,10 @@ func (c *Client) ExpectVisibleErrorResponse(t *testing.T) *dap.ErrorResponse { func (c *Client) ExpectErrorResponseWith(t *testing.T, id int, message string, showUser bool) *dap.ErrorResponse { t.Helper() er := c.ExpectErrorResponse(t) + if er.Body.Error == nil { + t.Errorf("got nil, want Id=%d Format=%q ShowUser=%v", id, message, showUser) + return er + } if matched, _ := regexp.MatchString(message, er.Body.Error.Format); !matched || er.Body.Error.Id != id || er.Body.Error.ShowUser != showUser { t.Errorf("got %#v, want Id=%d Format=%q ShowUser=%v", er, id, message, showUser) } @@ -277,7 +281,9 @@ func (c *Client) DisconnectRequest() { // `terminateDebuggee`. func (c *Client) DisconnectRequestWithKillOption(kill bool) { request := &dap.DisconnectRequest{Request: *c.newRequest("disconnect")} - request.Arguments.TerminateDebuggee = kill + request.Arguments = &dap.DisconnectArguments{ + TerminateDebuggee: kill, + } c.send(request) } diff --git a/service/dap/server.go b/service/dap/server.go index f6e1b1f7e3..80ad6570d9 100644 --- a/service/dap/server.go +++ b/service/dap/server.go @@ -1128,7 +1128,7 @@ func (s *Session) onDisconnectRequest(request *dap.DisconnectRequest) { s.mu.Lock() defer s.mu.Unlock() - if s.debugger != nil && s.config.AcceptMulti && !request.Arguments.TerminateDebuggee { + if s.debugger != nil && s.config.AcceptMulti && (request.Arguments == nil || !request.Arguments.TerminateDebuggee) { // This is a multi-use server/debugger, so a disconnect request that doesn't // terminate the debuggee should clean up only the client connection and pointer to debugger, // but not the entire server. @@ -1161,7 +1161,7 @@ func (s *Session) onDisconnectRequest(request *dap.DisconnectRequest) { // In case of attach, we leave the program // running by default, which can be // overridden by an explicit request to terminate. - killProcess := s.debugger.AttachPid() == 0 || request.Arguments.TerminateDebuggee + killProcess := s.debugger.AttachPid() == 0 || (request.Arguments != nil && request.Arguments.TerminateDebuggee) err = s.stopDebugSession(killProcess) } else if s.noDebugProcess != nil { s.stopNoDebugProcess() @@ -1966,7 +1966,7 @@ func (s *Session) onStackTraceRequest(request *dap.StackTraceRequest) { stackFrame := dap.StackFrame{Id: uniqueStackFrameID, Line: loc.Line, Name: fnName(loc), InstructionPointerReference: fmt.Sprintf("%#x", loc.PC)} if loc.File != "" { clientPath := s.toClientPath(loc.File) - stackFrame.Source = dap.Source{Name: filepath.Base(clientPath), Path: clientPath} + stackFrame.Source = &dap.Source{Name: filepath.Base(clientPath), Path: clientPath} } stackFrame.Column = 0 @@ -3045,7 +3045,7 @@ func (s *Session) onDisassembleRequest(request *dap.DisassembleRequest) { } // Only set the location on the first instruction for a given line. if instruction.Loc.File != lastFile || instruction.Loc.Line != lastLine { - instructions[i].Location = dap.Source{Path: instruction.Loc.File} + instructions[i].Location = &dap.Source{Path: instruction.Loc.File} instructions[i].Line = instruction.Loc.Line lastFile, lastLine = instruction.Loc.File, instruction.Loc.Line } @@ -3252,6 +3252,7 @@ func (s *Session) onExceptionInfoRequest(request *dap.ExceptionInfoRequest) { } if includeStackTrace { + body.Details = &dap.ExceptionDetails{} frames, err := s.stacktrace(goroutineID, g) if err != nil { body.Details.StackTrace = fmt.Sprintf("Error getting stack trace: %s", err.Error()) @@ -3320,9 +3321,11 @@ func (s *Session) sendErrorResponseWithOpts(request dap.Request, id int, summary er.RequestSeq = request.Seq er.Success = false er.Message = summary - er.Body.Error.Id = id - er.Body.Error.Format = fmt.Sprintf("%s: %s", summary, details) - er.Body.Error.ShowUser = showUser + er.Body.Error = &dap.ErrorMessage{ + Id: id, + Format: fmt.Sprintf("%s: %s", summary, details), + ShowUser: showUser, + } s.config.log.Debug(er.Body.Error.Format) s.send(er) } @@ -3346,8 +3349,10 @@ func (s *Session) sendInternalErrorResponse(seq int, details string) { er.RequestSeq = seq er.Success = false er.Message = "Internal Error" - er.Body.Error.Id = InternalError - er.Body.Error.Format = fmt.Sprintf("%s: %s", er.Message, details) + er.Body.Error = &dap.ErrorMessage{ + Id: InternalError, + Format: fmt.Sprintf("%s: %s", er.Message, details), + } s.config.log.Debug(er.Body.Error.Format) s.send(er) } @@ -3667,7 +3672,7 @@ func (s *Session) logBreakpointMessage(bp *api.Breakpoint, goid int64) bool { Body: dap.OutputEventBody{ Category: "stdout", Output: fmt.Sprintf("> [Go %d]: %s\n", goid, msg), - Source: dap.Source{ + Source: &dap.Source{ Path: s.toClientPath(bp.File), }, Line: bp.Line, diff --git a/service/dap/server_test.go b/service/dap/server_test.go index 5b9b515a8e..3faee83799 100644 --- a/service/dap/server_test.go +++ b/service/dap/server_test.go @@ -429,21 +429,21 @@ func TestLaunchStopOnEntry(t *testing.T) { // 8 >> stackTrace, << error client.StackTraceRequest(1, 0, 20) stResp := client.ExpectInvisibleErrorResponse(t) - if stResp.Seq != 0 || stResp.RequestSeq != 8 || stResp.Body.Error.Format != "Unable to produce stack trace: unknown goroutine 1" { + if stResp.Seq != 0 || stResp.RequestSeq != 8 || !checkErrorMessageFormat(stResp.Body.Error, "Unable to produce stack trace: unknown goroutine 1") { t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=8 Format=\"Unable to produce stack trace: unknown goroutine 1\"", stResp) } // 9 >> stackTrace, << error client.StackTraceRequest(1, 0, 20) stResp = client.ExpectInvisibleErrorResponse(t) - if stResp.Seq != 0 || stResp.RequestSeq != 9 || stResp.Body.Error.Id != UnableToProduceStackTrace { + if stResp.Seq != 0 || stResp.RequestSeq != 9 || !checkErrorMessageId(stResp.Body.Error, UnableToProduceStackTrace) { t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=9 Id=%d", stResp, UnableToProduceStackTrace) } // 10 >> evaluate, << error client.EvaluateRequest("foo", 0 /*no frame specified*/, "repl") erResp := client.ExpectInvisibleErrorResponse(t) - if erResp.Seq != 0 || erResp.RequestSeq != 10 || erResp.Body.Error.Id != UnableToEvaluateExpression { + if erResp.Seq != 0 || erResp.RequestSeq != 10 || !checkErrorMessageId(erResp.Body.Error, UnableToEvaluateExpression) { t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=10 Id=%d", erResp, UnableToEvaluateExpression) } @@ -576,7 +576,7 @@ func TestAttachStopOnEntry(t *testing.T) { // 10 >> evaluate, << error client.EvaluateRequest("foo", 0 /*no frame specified*/, "repl") erResp := client.ExpectInvisibleErrorResponse(t) - if erResp.Seq != 0 || erResp.RequestSeq != 10 || erResp.Body.Error.Id != UnableToEvaluateExpression { + if erResp.Seq != 0 || erResp.RequestSeq != 10 || !checkErrorMessageId(erResp.Body.Error, UnableToEvaluateExpression) { t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=10 Id=%d", erResp, UnableToEvaluateExpression) } @@ -749,7 +749,7 @@ func TestPreSetBreakpoint(t *testing.T) { if got.Id != id || got.Name != name { t.Errorf("\ngot %#v\nwant Id=%d Name=%s", got, id, name) } - if (sourceName != "" && got.Source.Name != sourceName) || (line > 0 && got.Line != line) { + if (sourceName != "" && (got.Source == nil || got.Source.Name != sourceName)) || (line > 0 && got.Line != line) { t.Errorf("\ngot %#v\nwant Source.Name=%s Line=%d", got, sourceName, line) } } @@ -1613,7 +1613,7 @@ func TestScopesAndVariablesRequests(t *testing.T) { client.ScopesRequest(1111) erres := client.ExpectInvisibleErrorResponse(t) - if erres.Body.Error.Format != "Unable to list locals: unknown frame id 1111" { + if !checkErrorMessageFormat(erres.Body.Error, "Unable to list locals: unknown frame id 1111") { t.Errorf("\ngot %#v\nwant Format=\"Unable to list locals: unknown frame id 1111\"", erres) } @@ -1628,7 +1628,7 @@ func TestScopesAndVariablesRequests(t *testing.T) { client.VariablesRequest(7777) erres = client.ExpectInvisibleErrorResponse(t) - if erres.Body.Error.Format != "Unable to lookup variable: unknown reference 7777" { + if !checkErrorMessageFormat(erres.Body.Error, "Unable to lookup variable: unknown reference 7777") { t.Errorf("\ngot %#v\nwant Format=\"Unable to lookup variable: unknown reference 7777\"", erres) } }, @@ -3337,7 +3337,7 @@ func checkLogMessage(t *testing.T, oe *dap.OutputEvent, goid int, text, path str if oe.Body.Category != "stdout" || !strings.HasPrefix(oe.Body.Output, prefix) || !strings.HasSuffix(oe.Body.Output, text+"\n") { t.Errorf("got output event = %#v, \nwant Category=\"stdout\" Output=\"%s: %s\\n\"", oe, prefix, text) } - if oe.Body.Line != line || oe.Body.Source.Path != path { + if oe.Body.Line != line || oe.Body.Source == nil || oe.Body.Source.Path != path { t.Errorf("got output event = %#v, \nwant Line=%d Source.Path=%s", oe, line, path) } } @@ -3955,27 +3955,27 @@ func TestEvaluateRequest(t *testing.T) { // Next frame client.EvaluateRequest("a1", 1002, "any context but watch") erres := client.ExpectVisibleErrorResponse(t) - if erres.Body.Error.Format != "Unable to evaluate expression: could not find symbol value for a1" { + if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: could not find symbol value for a1") { t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: could not find symbol value for a1\"", erres) } client.EvaluateRequest("a1", 1002, "watch") erres = client.ExpectInvisibleErrorResponse(t) - if erres.Body.Error.Format != "Unable to evaluate expression: could not find symbol value for a1" { + if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: could not find symbol value for a1") { t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: could not find symbol value for a1\"", erres) } client.EvaluateRequest("a1", 1002, "repl") erres = client.ExpectInvisibleErrorResponse(t) - if erres.Body.Error.Format != "Unable to evaluate expression: could not find symbol value for a1" { + if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: could not find symbol value for a1") { t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: could not find symbol value for a1\"", erres) } client.EvaluateRequest("a1", 1002, "hover") erres = client.ExpectInvisibleErrorResponse(t) - if erres.Body.Error.Format != "Unable to evaluate expression: could not find symbol value for a1" { + if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: could not find symbol value for a1") { t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: could not find symbol value for a1\"", erres) } client.EvaluateRequest("a1", 1002, "clipboard") erres = client.ExpectVisibleErrorResponse(t) - if erres.Body.Error.Format != "Unable to evaluate expression: could not find symbol value for a1" { + if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: could not find symbol value for a1") { t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: could not find symbol value for a1\"", erres) } }, @@ -4291,7 +4291,7 @@ func TestEvaluateCallRequest(t *testing.T) { client.ExpectEvaluateResponse(t) client.EvaluateRequest("call callstacktrace()", 1001, "not watch") erres := client.ExpectVisibleErrorResponse(t) - if erres.Body.Error.Format != "Unable to evaluate expression: call is only supported with topmost stack frame" { + if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: call is only supported with topmost stack frame") { t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: call is only supported with topmost stack frame\"", erres) } @@ -4302,14 +4302,14 @@ func TestEvaluateCallRequest(t *testing.T) { t.Errorf("\ngot %#v\nwant Reason=\"hardcoded breakpoint\"", s) } erres = client.ExpectVisibleErrorResponse(t) - if erres.Body.Error.Format != "Unable to evaluate expression: call stopped" { + if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: call stopped") { t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: call stopped\"", erres) } // A call during a call causes an error client.EvaluateRequest("call callstacktrace()", 1000, "not watch") erres = client.ExpectVisibleErrorResponse(t) - if erres.Body.Error.Format != "Unable to evaluate expression: cannot call function while another function call is already in progress" { + if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: cannot call function while another function call is already in progress") { t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: cannot call function while another function call is already in progress\"", erres) } @@ -4327,7 +4327,7 @@ func TestEvaluateCallRequest(t *testing.T) { client.EvaluateRequest("call makeclos(nil)", 1000, "not watch") stopped := client.ExpectStoppedEvent(t) erres = client.ExpectVisibleErrorResponse(t) - if erres.Body.Error.Format != "Unable to evaluate expression: call stopped" { + if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: call stopped") { t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: call stopped\"", erres) } checkStop(t, client, stopped.Body.ThreadId, "main.makeclos", 88) @@ -4401,7 +4401,7 @@ func TestEvaluateCallRequest(t *testing.T) { // Call error client.EvaluateRequest("call call1(one)", 1000, "watch") erres := client.ExpectInvisibleErrorResponse(t) - if erres.Body.Error.Format != "Unable to evaluate expression: not enough arguments" { + if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: not enough arguments") { t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: not enough arguments\"", erres) } @@ -4417,7 +4417,7 @@ func TestEvaluateCallRequest(t *testing.T) { // Call can exit. client.EvaluateRequest("call callexit()", 1000, "this context will be ignored") client.ExpectTerminatedEvent(t) - if res := client.ExpectVisibleErrorResponse(t); !strings.Contains(res.Body.Error.Format, "terminated") { + if res := client.ExpectVisibleErrorResponse(t); res.Body.Error == nil || !strings.Contains(res.Body.Error.Format, "terminated") { t.Errorf("\ngot %#v\nwant Format=.*terminated.*", res) } }, @@ -4957,7 +4957,7 @@ func TestPanicBreakpointOnContinue(t *testing.T) { if frame.PresentationHint != "subtle" { t.Errorf("\ngot Body.StackFrames[%d]=%#v\nwant Source.PresentationHint=\"subtle\"", i, frame) } - } else if frame.Source.PresentationHint != "" { + } else if frame.Source != nil && frame.Source.PresentationHint != "" { t.Errorf("\ngot Body.StackFrames[%d]=%#v\nwant Source.PresentationHint=\"\"", i, frame) } @@ -5377,7 +5377,7 @@ func TestNoDebug_AcceptNoRequestsButDisconnect(t *testing.T) { // Anything other than disconnect should get rejected var ExpectNoDebugError = func(cmd string) { er := client.ExpectErrorResponse(t) - if er.Body.Error.Format != fmt.Sprintf("noDebug mode: unable to process '%s' request", cmd) { + if !checkErrorMessageFormat(er.Body.Error, fmt.Sprintf("noDebug mode: unable to process '%s' request", cmd)) { t.Errorf("\ngot %#v\nwant 'noDebug mode: unable to process '%s' request'", er, cmd) } } @@ -5877,7 +5877,7 @@ func (h *helperForSetVariable) failSetVariable0(ref int, name, value, wantErrInf h.c.ExpectStoppedEvent(h.t) } resp := h.c.ExpectErrorResponse(h.t) - if got := resp.Body.Error.Format; !stringContainsCaseInsensitive(got, wantErrInfo) { + if got := resp.Body.Error; !stringContainsCaseInsensitive(got.Format, wantErrInfo) { h.t.Errorf("got %#v, want error string containing %v", got, wantErrInfo) } } @@ -6231,8 +6231,8 @@ func TestBadLaunchRequests(t *testing.T) { if response.Message != "Failed to launch" { t.Errorf("Message got %q, want \"Failed to launch\"", response.Message) } - if response.Body.Error.Id != FailedToLaunch { - t.Errorf("Id got %d, want %d", response.Body.Error.Id, FailedToLaunch) + if !checkErrorMessageId(response.Body.Error, FailedToLaunch) { + t.Errorf("Id got %v, want Id=%d", response.Body.Error, FailedToLaunch) } seqCnt++ } @@ -6240,8 +6240,8 @@ func TestBadLaunchRequests(t *testing.T) { checkFailedToLaunchWithMessage := func(response *dap.ErrorResponse, errmsg string) { t.Helper() checkFailedToLaunch(response) - if response.Body.Error.Format != errmsg { - t.Errorf("\ngot %q\nwant %q", response.Body.Error.Format, errmsg) + if !checkErrorMessageFormat(response.Body.Error, errmsg) { + t.Errorf("\ngot %v\nwant Format=%q", response.Body.Error, errmsg) } } @@ -6432,8 +6432,8 @@ func TestBadAttachRequest(t *testing.T) { if response.Message != "Failed to attach" { t.Errorf("Message got %q, want \"Failed to attach\"", response.Message) } - if response.Body.Error.Id != FailedToAttach { - t.Errorf("Id got %d, want %d", response.Body.Error.Id, FailedToAttach) + if !checkErrorMessageId(response.Body.Error, FailedToAttach) { + t.Errorf("Id got %v, want %d", response.Body.Error, FailedToAttach) } seqCnt++ } @@ -6441,8 +6441,8 @@ func TestBadAttachRequest(t *testing.T) { checkFailedToAttachWithMessage := func(response *dap.ErrorResponse, errmsg string) { t.Helper() checkFailedToAttach(response) - if response.Body.Error.Format != errmsg { - t.Errorf("\ngot %q\nwant %q", response.Body.Error.Format, errmsg) + if !checkErrorMessageFormat(response.Body.Error, errmsg) { + t.Errorf("\ngot %v\nwant Format=%q", response.Body.Error, errmsg) } } @@ -6494,11 +6494,11 @@ func TestBadAttachRequest(t *testing.T) { if er.Command != "" { t.Errorf("Command got %q, want \"attach\"", er.Command) } - if er.Body.Error.Format != "Internal Error: runtime error: index out of range [0] with length 0" { + if !checkErrorMessageFormat(er.Body.Error, "Internal Error: runtime error: index out of range [0] with length 0") { t.Errorf("Message got %q, want \"Internal Error: runtime error: index out of range [0] with length 0\"", er.Message) } - if er.Body.Error.Id != InternalError { - t.Errorf("Id got %d, want %d", er.Body.Error.Id, InternalError) + if !checkErrorMessageId(er.Body.Error, InternalError) { + t.Errorf("Id got %v, want Id=%d", er.Body.Error, InternalError) } // Bad "backend" @@ -6813,8 +6813,8 @@ func TestLaunchAttachErrorWhenDebugInProgress(t *testing.T) { client.AttachRequest(map[string]interface{}{"mode": "local", "processId": 100}) er := client.ExpectVisibleErrorResponse(t) msgRe := regexp.MustCompile("Failed to attach: debug session already in progress at [0-9]+:[0-9]+ - use remote mode to connect to a server with an active debug session") - if er.Body.Error.Id != FailedToAttach || msgRe.MatchString(er.Body.Error.Format) { - t.Errorf("got %#v, want Id=%d Format=%q", er, FailedToAttach, msgRe) + if er.Body.Error == nil || er.Body.Error.Id != FailedToAttach || msgRe.MatchString(er.Body.Error.Format) { + t.Errorf("got %#v, want Id=%d Format=%q", er.Body.Error, FailedToAttach, msgRe) } tests := []string{"debug", "test", "exec", "replay", "core"} for _, mode := range tests { @@ -6822,8 +6822,8 @@ func TestLaunchAttachErrorWhenDebugInProgress(t *testing.T) { client.LaunchRequestWithArgs(map[string]interface{}{"mode": mode}) er := client.ExpectVisibleErrorResponse(t) msgRe := regexp.MustCompile("Failed to launch: debug session already in progress at [0-9]+:[0-9]+ - use remote attach mode to connect to a server with an active debug session") - if er.Body.Error.Id != FailedToLaunch || msgRe.MatchString(er.Body.Error.Format) { - t.Errorf("got %#v, want Id=%d Format=%q", er, FailedToLaunch, msgRe) + if er.Body.Error == nil || er.Body.Error.Id != FailedToLaunch || msgRe.MatchString(er.Body.Error.Format) { + t.Errorf("got %#v, want Id=%d Format=%q", er.Body.Error, FailedToLaunch, msgRe) } }) } @@ -6849,10 +6849,10 @@ func TestBadInitializeRequest(t *testing.T) { if response.Message != "Failed to initialize" { t.Errorf("Message got %q, want \"Failed to launch\"", response.Message) } - if response.Body.Error.Id != FailedToInitialize { - t.Errorf("Id got %d, want %d", response.Body.Error.Id, FailedToInitialize) + if !checkErrorMessageId(response.Body.Error, FailedToInitialize) { + t.Errorf("Id got %v, want Id=%d", response.Body.Error, FailedToInitialize) } - if response.Body.Error.Format != err { + if !checkErrorMessageFormat(response.Body.Error, err) { t.Errorf("\ngot %q\nwant %q", response.Body.Error.Format, err) } @@ -6913,7 +6913,7 @@ func TestBadlyFormattedMessageToServer(t *testing.T) { // an error response. client.UnknownRequest() err := client.ExpectErrorResponse(t) - if err.Body.Error.Format != "Internal Error: Request command 'unknown' is not supported (seq: 1)" || err.RequestSeq != 1 { + if !checkErrorMessageFormat(err.Body.Error, "Internal Error: Request command 'unknown' is not supported (seq: 1)") || err.RequestSeq != 1 { t.Errorf("got %v, want RequestSeq=1 Error=\"Internal Error: Request command 'unknown' is not supported (seq: 1)\"", err) } @@ -7365,3 +7365,13 @@ func TestDisassembleCgo(t *testing.T) { }, protest.AllNonOptimized, true) } + +// Helper functions for checking ErrorMessage field values. + +func checkErrorMessageId(er *dap.ErrorMessage, id int) bool { + return er != nil && er.Id == id +} + +func checkErrorMessageFormat(er *dap.ErrorMessage, fmt string) bool { + return er != nil && er.Format == fmt +} diff --git a/vendor/github.com/google/go-dap/go.mod b/vendor/github.com/google/go-dap/go.mod index 6a37a23905..d90f6f0c9c 100644 --- a/vendor/github.com/google/go-dap/go.mod +++ b/vendor/github.com/google/go-dap/go.mod @@ -1,3 +1,5 @@ module github.com/google/go-dap go 1.13 + +retract v0.9.0 diff --git a/vendor/github.com/google/go-dap/schematypes.go b/vendor/github.com/google/go-dap/schematypes.go index 3fd2770ce1..54200bc8a4 100644 --- a/vendor/github.com/google/go-dap/schematypes.go +++ b/vendor/github.com/google/go-dap/schematypes.go @@ -93,7 +93,7 @@ type Response struct { Message string `json:"message,omitempty"` } -// ErrorResponse: On error (whenever 'success' is false), the body can provide more details. +// ErrorResponse: On error (whenever `success` is false), the body can provide more details. type ErrorResponse struct { Response @@ -101,52 +101,51 @@ type ErrorResponse struct { } type ErrorResponseBody struct { - Error ErrorMessage `json:"error,omitempty"` + Error *ErrorMessage `json:"error,omitempty"` } func (r *ErrorResponse) GetResponse() *Response { return &r.Response } -// CancelRequest: The 'cancel' request is used by the frontend in two situations: +// CancelRequest: The `cancel` request is used by the client in two situations: // - to indicate that it is no longer interested in the result produced by a specific request issued earlier -// - to cancel a progress sequence. Clients should only call this request if the capability 'supportsCancelRequest' is true. -// This request has a hint characteristic: a debug adapter can only be expected to make a 'best effort' in honouring this request but there are no guarantees. -// The 'cancel' request may return an error if it could not cancel an operation but a frontend should refrain from presenting this error to end users. -// A frontend client should only call this request if the capability 'supportsCancelRequest' is true. -// The request that got canceled still needs to send a response back. This can either be a normal result ('success' attribute true) -// or an error response ('success' attribute false and the 'message' set to 'cancelled'). -// Returning partial results from a cancelled request is possible but please note that a frontend client has no generic way for detecting that a response is partial or not. -// The progress that got cancelled still needs to send a 'progressEnd' event back. -// A client should not assume that progress just got cancelled after sending the 'cancel' request. +// - to cancel a progress sequence. Clients should only call this request if the corresponding capability `supportsCancelRequest` is true. +// This request has a hint characteristic: a debug adapter can only be expected to make a 'best effort' in honoring this request but there are no guarantees. +// The `cancel` request may return an error if it could not cancel an operation but a client should refrain from presenting this error to end users. +// The request that got cancelled still needs to send a response back. This can either be a normal result (`success` attribute true) or an error response (`success` attribute false and the `message` set to `cancelled`). +// Returning partial results from a cancelled request is possible but please note that a client has no generic way for detecting that a response is partial or not. +// The progress that got cancelled still needs to send a `progressEnd` event back. +// +// A client should not assume that progress just got cancelled after sending the `cancel` request. type CancelRequest struct { Request - Arguments CancelArguments `json:"arguments,omitempty"` + Arguments *CancelArguments `json:"arguments,omitempty"` } func (r *CancelRequest) GetRequest() *Request { return &r.Request } -// CancelArguments: Arguments for 'cancel' request. +// CancelArguments: Arguments for `cancel` request. type CancelArguments struct { RequestId int `json:"requestId,omitempty"` ProgressId string `json:"progressId,omitempty"` } -// CancelResponse: Response to 'cancel' request. This is just an acknowledgement, so no body field is required. +// CancelResponse: Response to `cancel` request. This is just an acknowledgement, so no body field is required. type CancelResponse struct { Response } func (r *CancelResponse) GetResponse() *Response { return &r.Response } -// InitializedEvent: This event indicates that the debug adapter is ready to accept configuration requests (e.g. SetBreakpointsRequest, SetExceptionBreakpointsRequest). -// A debug adapter is expected to send this event when it is ready to accept configuration requests (but not before the 'initialize' request has finished). +// InitializedEvent: This event indicates that the debug adapter is ready to accept configuration requests (e.g. `setBreakpoints`, `setExceptionBreakpoints`). +// A debug adapter is expected to send this event when it is ready to accept configuration requests (but not before the `initialize` request has finished). // The sequence of events/requests is as follows: -// - adapters sends 'initialized' event (after the 'initialize' request has returned) -// - frontend sends zero or more 'setBreakpoints' requests -// - frontend sends one 'setFunctionBreakpoints' request (if capability 'supportsFunctionBreakpoints' is true) -// - frontend sends a 'setExceptionBreakpoints' request if one or more 'exceptionBreakpointFilters' have been defined (or if 'supportsConfigurationDoneRequest' is not defined or false) -// - frontend sends other future configuration requests -// - frontend sends one 'configurationDone' request to indicate the end of the configuration. +// - adapters sends `initialized` event (after the `initialize` request has returned) +// - client sends zero or more `setBreakpoints` requests +// - client sends one `setFunctionBreakpoints` request (if corresponding capability `supportsFunctionBreakpoints` is true) +// - client sends a `setExceptionBreakpoints` request if one or more `exceptionBreakpointFilters` have been defined (or if `supportsConfigurationDoneRequest` is not true) +// - client sends other future configuration requests +// - client sends one `configurationDone` request to indicate the end of the configuration. type InitializedEvent struct { Event } @@ -154,7 +153,7 @@ type InitializedEvent struct { func (e *InitializedEvent) GetEvent() *Event { return &e.Event } // StoppedEvent: The event indicates that the execution of the debuggee has stopped due to some condition. -// This can be caused by a break point previously set, a stepping request has completed, by executing a debugger statement etc. +// This can be caused by a breakpoint previously set, a stepping request has completed, by executing a debugger statement etc. type StoppedEvent struct { Event @@ -174,8 +173,8 @@ type StoppedEventBody struct { func (e *StoppedEvent) GetEvent() *Event { return &e.Event } // ContinuedEvent: The event indicates that the execution of the debuggee has continued. -// Please note: a debug adapter is not expected to send this event in response to a request that implies that execution continues, e.g. 'launch' or 'continue'. -// It is only necessary to send a 'continued' event if there was no previous request that implied this. +// Please note: a debug adapter is not expected to send this event in response to a request that implies that execution continues, e.g. `launch` or `continue`. +// It is only necessary to send a `continued` event if there was no previous request that implied this. type ContinuedEvent struct { Event @@ -241,7 +240,7 @@ type OutputEventBody struct { Output string `json:"output"` Group string `json:"group,omitempty"` VariablesReference int `json:"variablesReference,omitempty"` - Source Source `json:"source,omitempty"` + Source *Source `json:"source,omitempty"` Line int `json:"line,omitempty"` Column int `json:"column,omitempty"` Data interface{} `json:"data,omitempty"` @@ -309,8 +308,8 @@ type ProcessEventBody struct { func (e *ProcessEvent) GetEvent() *Event { return &e.Event } // CapabilitiesEvent: The event indicates that one or more capabilities have changed. -// Since the capabilities are dependent on the frontend and its UI, it might not be possible to change that at random times (or too late). -// Consequently this event has a hint characteristic: a frontend can only be expected to make a 'best effort' in honouring individual capabilities but there are no guarantees. +// Since the capabilities are dependent on the client and its UI, it might not be possible to change that at random times (or too late). +// Consequently this event has a hint characteristic: a client can only be expected to make a 'best effort' in honoring individual capabilities but there are no guarantees. // Only changed capabilities need to be included, all other capabilities keep their values. type CapabilitiesEvent struct { Event @@ -324,10 +323,9 @@ type CapabilitiesEventBody struct { func (e *CapabilitiesEvent) GetEvent() *Event { return &e.Event } -// ProgressStartEvent: The event signals that a long running operation is about to start and -// provides additional information for the client to set up a corresponding progress and cancellation UI. +// ProgressStartEvent: The event signals that a long running operation is about to start and provides additional information for the client to set up a corresponding progress and cancellation UI. // The client is free to delay the showing of the UI in order to reduce flicker. -// This event should only be sent if the client has passed the value true for the 'supportsProgressReporting' capability of the 'initialize' request. +// This event should only be sent if the corresponding capability `supportsProgressReporting` is true. type ProgressStartEvent struct { Event @@ -345,9 +343,9 @@ type ProgressStartEventBody struct { func (e *ProgressStartEvent) GetEvent() *Event { return &e.Event } -// ProgressUpdateEvent: The event signals that the progress reporting needs to updated with a new message and/or percentage. +// ProgressUpdateEvent: The event signals that the progress reporting needs to be updated with a new message and/or percentage. // The client does not have to update the UI immediately, but the clients needs to keep track of the message and/or percentage values. -// This event should only be sent if the client has passed the value true for the 'supportsProgressReporting' capability of the 'initialize' request. +// This event should only be sent if the corresponding capability `supportsProgressReporting` is true. type ProgressUpdateEvent struct { Event @@ -362,8 +360,8 @@ type ProgressUpdateEventBody struct { func (e *ProgressUpdateEvent) GetEvent() *Event { return &e.Event } -// ProgressEndEvent: The event signals the end of the progress reporting with an optional final message. -// This event should only be sent if the client has passed the value true for the 'supportsProgressReporting' capability of the 'initialize' request. +// ProgressEndEvent: The event signals the end of the progress reporting with a final message. +// This event should only be sent if the corresponding capability `supportsProgressReporting` is true. type ProgressEndEvent struct { Event @@ -379,7 +377,7 @@ func (e *ProgressEndEvent) GetEvent() *Event { return &e.Event } // InvalidatedEvent: This event signals that some state in the debug adapter has changed and requires that the client needs to re-render the data snapshot previously requested. // Debug adapters do not have to emit this event for runtime changes like stopped or thread events because in that case the client refetches the new state anyway. But the event can be used for example to refresh the UI after rendering formatting has changed in the debug adapter. -// This event should only be sent if the debug adapter has received a value true for the 'supportsInvalidatedEvent' capability of the 'initialize' request. +// This event should only be sent if the corresponding capability `supportsInvalidatedEvent` is true. type InvalidatedEvent struct { Event @@ -394,9 +392,9 @@ type InvalidatedEventBody struct { func (e *InvalidatedEvent) GetEvent() *Event { return &e.Event } -// MemoryEvent: This event indicates that some memory range has been updated. It should only be sent if the debug adapter has received a value true for the `supportsMemoryEvent` capability of the `initialize` request. +// MemoryEvent: This event indicates that some memory range has been updated. It should only be sent if the corresponding capability `supportsMemoryEvent` is true. // Clients typically react to the event by re-issuing a `readMemory` request if they show the memory identified by the `memoryReference` and if the updated memory range overlaps the displayed range. Clients should not make assumptions how individual memory references relate to each other, so they should not assume that they are part of a single continuous address range and might overlap. -// Debug adapters can use this event to indicate that the contents of a memory range has changed due to some other DAP request like `setVariable` or `setExpression`. Debug adapters are not expected to emit this event for each and every memory change of a running program, because that information is typically not available from debuggers and it would flood clients with too many events. +// Debug adapters can use this event to indicate that the contents of a memory range has changed due to some other request like `setVariable` or `setExpression`. Debug adapters are not expected to emit this event for each and every memory change of a running program, because that information is typically not available from debuggers and it would flood clients with too many events. type MemoryEvent struct { Event @@ -411,9 +409,11 @@ type MemoryEventBody struct { func (e *MemoryEvent) GetEvent() *Event { return &e.Event } -// RunInTerminalRequest: This optional request is sent from the debug adapter to the client to run a command in a terminal. +// RunInTerminalRequest: This request is sent from the debug adapter to the client to run a command in a terminal. // This is typically used to launch the debuggee in a terminal provided by the client. -// This request should only be called if the client has passed the value true for the 'supportsRunInTerminalRequest' capability of the 'initialize' request. +// This request should only be called if the corresponding client capability `supportsRunInTerminalRequest` is true. +// Client implementations of `runInTerminal` are free to run the command however they choose including issuing the command to a command line interpreter (aka 'shell'). Argument strings passed to the `runInTerminal` request must arrive verbatim in the command to be run. As a consequence, clients which use a shell are responsible for escaping any special shell characters in the argument strings to prevent them from being interpreted (and modified) by the shell. +// Some users may wish to take advantage of shell processing in the argument strings. For clients which implement `runInTerminal` using an intermediary shell, the `argsCanBeInterpretedByShell` property can be set to true. In this case the client is requested not to escape any special shell characters in the argument strings. type RunInTerminalRequest struct { Request @@ -422,16 +422,17 @@ type RunInTerminalRequest struct { func (r *RunInTerminalRequest) GetRequest() *Request { return &r.Request } -// RunInTerminalRequestArguments: Arguments for 'runInTerminal' request. +// RunInTerminalRequestArguments: Arguments for `runInTerminal` request. type RunInTerminalRequestArguments struct { - Kind string `json:"kind,omitempty"` - Title string `json:"title,omitempty"` - Cwd string `json:"cwd"` - Args []string `json:"args"` - Env map[string]interface{} `json:"env,omitempty"` + Kind string `json:"kind,omitempty"` + Title string `json:"title,omitempty"` + Cwd string `json:"cwd"` + Args []string `json:"args"` + Env map[string]interface{} `json:"env,omitempty"` + ArgsCanBeInterpretedByShell bool `json:"argsCanBeInterpretedByShell,omitempty"` } -// RunInTerminalResponse: Response to 'runInTerminal' request. +// RunInTerminalResponse: Response to `runInTerminal` request. type RunInTerminalResponse struct { Response @@ -445,11 +446,34 @@ type RunInTerminalResponseBody struct { func (r *RunInTerminalResponse) GetResponse() *Response { return &r.Response } -// InitializeRequest: The 'initialize' request is sent as the first request from the client to the debug adapter -// in order to configure it with client capabilities and to retrieve capabilities from the debug adapter. -// Until the debug adapter has responded to with an 'initialize' response, the client must not send any additional requests or events to the debug adapter. -// In addition the debug adapter is not allowed to send any requests or events to the client until it has responded with an 'initialize' response. -// The 'initialize' request may only be sent once. +// StartDebuggingRequest: This request is sent from the debug adapter to the client to start a new debug session of the same type as the caller. +// This request should only be sent if the corresponding client capability `supportsStartDebuggingRequest` is true. +// A client implementation of `startDebugging` should start a new debug session (of the same type as the caller) in the same way that the caller's session was started. If the client supports hierarchical debug sessions, the newly created session can be treated as a child of the caller session. +type StartDebuggingRequest struct { + Request + + Arguments StartDebuggingRequestArguments `json:"arguments"` +} + +func (r *StartDebuggingRequest) GetRequest() *Request { return &r.Request } + +// StartDebuggingRequestArguments: Arguments for `startDebugging` request. +type StartDebuggingRequestArguments struct { + Configuration map[string]interface{} `json:"configuration"` + Request string `json:"request"` +} + +// StartDebuggingResponse: Response to `startDebugging` request. This is just an acknowledgement, so no body field is required. +type StartDebuggingResponse struct { + Response +} + +func (r *StartDebuggingResponse) GetResponse() *Response { return &r.Response } + +// InitializeRequest: The `initialize` request is sent as the first request from the client to the debug adapter in order to configure it with client capabilities and to retrieve capabilities from the debug adapter. +// Until the debug adapter has responded with an `initialize` response, the client must not send any additional requests or events to the debug adapter. +// In addition the debug adapter is not allowed to send any requests or events to the client until it has responded with an `initialize` response. +// The `initialize` request may only be sent once. type InitializeRequest struct { Request @@ -458,25 +482,27 @@ type InitializeRequest struct { func (r *InitializeRequest) GetRequest() *Request { return &r.Request } -// InitializeRequestArguments: Arguments for 'initialize' request. +// InitializeRequestArguments: Arguments for `initialize` request. type InitializeRequestArguments struct { - ClientID string `json:"clientID,omitempty"` - ClientName string `json:"clientName,omitempty"` - AdapterID string `json:"adapterID"` - Locale string `json:"locale,omitempty"` - LinesStartAt1 bool `json:"linesStartAt1"` - ColumnsStartAt1 bool `json:"columnsStartAt1"` - PathFormat string `json:"pathFormat,omitempty"` - SupportsVariableType bool `json:"supportsVariableType,omitempty"` - SupportsVariablePaging bool `json:"supportsVariablePaging,omitempty"` - SupportsRunInTerminalRequest bool `json:"supportsRunInTerminalRequest,omitempty"` - SupportsMemoryReferences bool `json:"supportsMemoryReferences,omitempty"` - SupportsProgressReporting bool `json:"supportsProgressReporting,omitempty"` - SupportsInvalidatedEvent bool `json:"supportsInvalidatedEvent,omitempty"` - SupportsMemoryEvent bool `json:"supportsMemoryEvent,omitempty"` -} - -// InitializeResponse: Response to 'initialize' request. + ClientID string `json:"clientID,omitempty"` + ClientName string `json:"clientName,omitempty"` + AdapterID string `json:"adapterID"` + Locale string `json:"locale,omitempty"` + LinesStartAt1 bool `json:"linesStartAt1"` + ColumnsStartAt1 bool `json:"columnsStartAt1"` + PathFormat string `json:"pathFormat,omitempty"` + SupportsVariableType bool `json:"supportsVariableType,omitempty"` + SupportsVariablePaging bool `json:"supportsVariablePaging,omitempty"` + SupportsRunInTerminalRequest bool `json:"supportsRunInTerminalRequest,omitempty"` + SupportsMemoryReferences bool `json:"supportsMemoryReferences,omitempty"` + SupportsProgressReporting bool `json:"supportsProgressReporting,omitempty"` + SupportsInvalidatedEvent bool `json:"supportsInvalidatedEvent,omitempty"` + SupportsMemoryEvent bool `json:"supportsMemoryEvent,omitempty"` + SupportsArgsCanBeInterpretedByShell bool `json:"supportsArgsCanBeInterpretedByShell,omitempty"` + SupportsStartDebuggingRequest bool `json:"supportsStartDebuggingRequest,omitempty"` +} + +// InitializeResponse: Response to `initialize` request. type InitializeResponse struct { Response @@ -485,29 +511,29 @@ type InitializeResponse struct { func (r *InitializeResponse) GetResponse() *Response { return &r.Response } -// ConfigurationDoneRequest: This optional request indicates that the client has finished initialization of the debug adapter. -// So it is the last request in the sequence of configuration requests (which was started by the 'initialized' event). -// Clients should only call this request if the capability 'supportsConfigurationDoneRequest' is true. +// ConfigurationDoneRequest: This request indicates that the client has finished initialization of the debug adapter. +// So it is the last request in the sequence of configuration requests (which was started by the `initialized` event). +// Clients should only call this request if the corresponding capability `supportsConfigurationDoneRequest` is true. type ConfigurationDoneRequest struct { Request - Arguments ConfigurationDoneArguments `json:"arguments,omitempty"` + Arguments *ConfigurationDoneArguments `json:"arguments,omitempty"` } func (r *ConfigurationDoneRequest) GetRequest() *Request { return &r.Request } -// ConfigurationDoneArguments: Arguments for 'configurationDone' request. +// ConfigurationDoneArguments: Arguments for `configurationDone` request. type ConfigurationDoneArguments struct { } -// ConfigurationDoneResponse: Response to 'configurationDone' request. This is just an acknowledgement, so no body field is required. +// ConfigurationDoneResponse: Response to `configurationDone` request. This is just an acknowledgement, so no body field is required. type ConfigurationDoneResponse struct { Response } func (r *ConfigurationDoneResponse) GetResponse() *Response { return &r.Response } -// LaunchRequest: This launch request is sent from the client to the debug adapter to start the debuggee with or without debugging (if 'noDebug' is true). +// LaunchRequest: This launch request is sent from the client to the debug adapter to start the debuggee with or without debugging (if `noDebug` is true). // Since launching is debugger/runtime specific, the arguments for this request are not part of this specification. type LaunchRequest struct { Request @@ -518,14 +544,14 @@ type LaunchRequest struct { func (r *LaunchRequest) GetRequest() *Request { return &r.Request } func (r *LaunchRequest) GetArguments() json.RawMessage { return r.Arguments } -// LaunchResponse: Response to 'launch' request. This is just an acknowledgement, so no body field is required. +// LaunchResponse: Response to `launch` request. This is just an acknowledgement, so no body field is required. type LaunchResponse struct { Response } func (r *LaunchResponse) GetResponse() *Response { return &r.Response } -// AttachRequest: The attach request is sent from the client to the debug adapter to attach to a debuggee that is already running. +// AttachRequest: The `attach` request is sent from the client to the debug adapter to attach to a debuggee that is already running. // Since attaching is debugger/runtime specific, the arguments for this request are not part of this specification. type AttachRequest struct { Request @@ -536,95 +562,95 @@ type AttachRequest struct { func (r *AttachRequest) GetRequest() *Request { return &r.Request } func (r *AttachRequest) GetArguments() json.RawMessage { return r.Arguments } -// AttachResponse: Response to 'attach' request. This is just an acknowledgement, so no body field is required. +// AttachResponse: Response to `attach` request. This is just an acknowledgement, so no body field is required. type AttachResponse struct { Response } func (r *AttachResponse) GetResponse() *Response { return &r.Response } -// RestartRequest: Restarts a debug session. Clients should only call this request if the capability 'supportsRestartRequest' is true. -// If the capability is missing or has the value false, a typical client will emulate 'restart' by terminating the debug adapter first and then launching it anew. +// RestartRequest: Restarts a debug session. Clients should only call this request if the corresponding capability `supportsRestartRequest` is true. +// If the capability is missing or has the value false, a typical client emulates `restart` by terminating the debug adapter first and then launching it anew. type RestartRequest struct { Request - Arguments RestartArguments `json:"arguments,omitempty"` + Arguments *RestartArguments `json:"arguments,omitempty"` } func (r *RestartRequest) GetRequest() *Request { return &r.Request } -// RestartArguments: Arguments for 'restart' request. +// RestartArguments: Arguments for `restart` request. type RestartArguments struct { Arguments interface{} `json:"arguments,omitempty"` } -// RestartResponse: Response to 'restart' request. This is just an acknowledgement, so no body field is required. +// RestartResponse: Response to `restart` request. This is just an acknowledgement, so no body field is required. type RestartResponse struct { Response } func (r *RestartResponse) GetResponse() *Response { return &r.Response } -// DisconnectRequest: The 'disconnect' request is sent from the client to the debug adapter in order to stop debugging. -// It asks the debug adapter to disconnect from the debuggee and to terminate the debug adapter. -// If the debuggee has been started with the 'launch' request, the 'disconnect' request terminates the debuggee. -// If the 'attach' request was used to connect to the debuggee, 'disconnect' does not terminate the debuggee. -// This behavior can be controlled with the 'terminateDebuggee' argument (if supported by the debug adapter). +// DisconnectRequest: The `disconnect` request asks the debug adapter to disconnect from the debuggee (thus ending the debug session) and then to shut down itself (the debug adapter). +// In addition, the debug adapter must terminate the debuggee if it was started with the `launch` request. If an `attach` request was used to connect to the debuggee, then the debug adapter must not terminate the debuggee. +// This implicit behavior of when to terminate the debuggee can be overridden with the `terminateDebuggee` argument (which is only supported by a debug adapter if the corresponding capability `supportTerminateDebuggee` is true). type DisconnectRequest struct { Request - Arguments DisconnectArguments `json:"arguments,omitempty"` + Arguments *DisconnectArguments `json:"arguments,omitempty"` } func (r *DisconnectRequest) GetRequest() *Request { return &r.Request } -// DisconnectArguments: Arguments for 'disconnect' request. +// DisconnectArguments: Arguments for `disconnect` request. type DisconnectArguments struct { Restart bool `json:"restart,omitempty"` TerminateDebuggee bool `json:"terminateDebuggee,omitempty"` SuspendDebuggee bool `json:"suspendDebuggee,omitempty"` } -// DisconnectResponse: Response to 'disconnect' request. This is just an acknowledgement, so no body field is required. +// DisconnectResponse: Response to `disconnect` request. This is just an acknowledgement, so no body field is required. type DisconnectResponse struct { Response } func (r *DisconnectResponse) GetResponse() *Response { return &r.Response } -// TerminateRequest: The 'terminate' request is sent from the client to the debug adapter in order to give the debuggee a chance for terminating itself. -// Clients should only call this request if the capability 'supportsTerminateRequest' is true. +// TerminateRequest: The `terminate` request is sent from the client to the debug adapter in order to shut down the debuggee gracefully. Clients should only call this request if the capability `supportsTerminateRequest` is true. +// Typically a debug adapter implements `terminate` by sending a software signal which the debuggee intercepts in order to clean things up properly before terminating itself. +// Please note that this request does not directly affect the state of the debug session: if the debuggee decides to veto the graceful shutdown for any reason by not terminating itself, then the debug session just continues. +// Clients can surface the `terminate` request as an explicit command or they can integrate it into a two stage Stop command that first sends `terminate` to request a graceful shutdown, and if that fails uses `disconnect` for a forceful shutdown. type TerminateRequest struct { Request - Arguments TerminateArguments `json:"arguments,omitempty"` + Arguments *TerminateArguments `json:"arguments,omitempty"` } func (r *TerminateRequest) GetRequest() *Request { return &r.Request } -// TerminateArguments: Arguments for 'terminate' request. +// TerminateArguments: Arguments for `terminate` request. type TerminateArguments struct { Restart bool `json:"restart,omitempty"` } -// TerminateResponse: Response to 'terminate' request. This is just an acknowledgement, so no body field is required. +// TerminateResponse: Response to `terminate` request. This is just an acknowledgement, so no body field is required. type TerminateResponse struct { Response } func (r *TerminateResponse) GetResponse() *Response { return &r.Response } -// BreakpointLocationsRequest: The 'breakpointLocations' request returns all possible locations for source breakpoints in a given range. -// Clients should only call this request if the capability 'supportsBreakpointLocationsRequest' is true. +// BreakpointLocationsRequest: The `breakpointLocations` request returns all possible locations for source breakpoints in a given range. +// Clients should only call this request if the corresponding capability `supportsBreakpointLocationsRequest` is true. type BreakpointLocationsRequest struct { Request - Arguments BreakpointLocationsArguments `json:"arguments,omitempty"` + Arguments *BreakpointLocationsArguments `json:"arguments,omitempty"` } func (r *BreakpointLocationsRequest) GetRequest() *Request { return &r.Request } -// BreakpointLocationsArguments: Arguments for 'breakpointLocations' request. +// BreakpointLocationsArguments: Arguments for `breakpointLocations` request. type BreakpointLocationsArguments struct { Source Source `json:"source"` Line int `json:"line"` @@ -633,7 +659,7 @@ type BreakpointLocationsArguments struct { EndColumn int `json:"endColumn,omitempty"` } -// BreakpointLocationsResponse: Response to 'breakpointLocations' request. +// BreakpointLocationsResponse: Response to `breakpointLocations` request. // Contains possible locations for source breakpoints. type BreakpointLocationsResponse struct { Response @@ -649,7 +675,7 @@ func (r *BreakpointLocationsResponse) GetResponse() *Response { return &r.Respon // SetBreakpointsRequest: Sets multiple breakpoints for a single source and clears all previous breakpoints in that source. // To clear all breakpoint for a source, specify an empty array. -// When a breakpoint is hit, a 'stopped' event (with reason 'breakpoint') is generated. +// When a breakpoint is hit, a `stopped` event (with reason `breakpoint`) is generated. type SetBreakpointsRequest struct { Request @@ -658,7 +684,7 @@ type SetBreakpointsRequest struct { func (r *SetBreakpointsRequest) GetRequest() *Request { return &r.Request } -// SetBreakpointsArguments: Arguments for 'setBreakpoints' request. +// SetBreakpointsArguments: Arguments for `setBreakpoints` request. type SetBreakpointsArguments struct { Source Source `json:"source"` Breakpoints []SourceBreakpoint `json:"breakpoints,omitempty"` @@ -666,11 +692,11 @@ type SetBreakpointsArguments struct { SourceModified bool `json:"sourceModified,omitempty"` } -// SetBreakpointsResponse: Response to 'setBreakpoints' request. +// SetBreakpointsResponse: Response to `setBreakpoints` request. // Returned is information about each breakpoint created by this request. // This includes the actual code location and whether the breakpoint could be verified. -// The breakpoints returned are in the same order as the elements of the 'breakpoints' -// (or the deprecated 'lines') array in the arguments. +// The breakpoints returned are in the same order as the elements of the `breakpoints` +// (or the deprecated `lines`) array in the arguments. type SetBreakpointsResponse struct { Response @@ -685,8 +711,8 @@ func (r *SetBreakpointsResponse) GetResponse() *Response { return &r.Response } // SetFunctionBreakpointsRequest: Replaces all existing function breakpoints with new function breakpoints. // To clear all function breakpoints, specify an empty array. -// When a function breakpoint is hit, a 'stopped' event (with reason 'function breakpoint') is generated. -// Clients should only call this request if the capability 'supportsFunctionBreakpoints' is true. +// When a function breakpoint is hit, a `stopped` event (with reason `function breakpoint`) is generated. +// Clients should only call this request if the corresponding capability `supportsFunctionBreakpoints` is true. type SetFunctionBreakpointsRequest struct { Request @@ -695,12 +721,12 @@ type SetFunctionBreakpointsRequest struct { func (r *SetFunctionBreakpointsRequest) GetRequest() *Request { return &r.Request } -// SetFunctionBreakpointsArguments: Arguments for 'setFunctionBreakpoints' request. +// SetFunctionBreakpointsArguments: Arguments for `setFunctionBreakpoints` request. type SetFunctionBreakpointsArguments struct { Breakpoints []FunctionBreakpoint `json:"breakpoints"` } -// SetFunctionBreakpointsResponse: Response to 'setFunctionBreakpoints' request. +// SetFunctionBreakpointsResponse: Response to `setFunctionBreakpoints` request. // Returned is information about each breakpoint created by this request. type SetFunctionBreakpointsResponse struct { Response @@ -714,9 +740,9 @@ type SetFunctionBreakpointsResponseBody struct { func (r *SetFunctionBreakpointsResponse) GetResponse() *Response { return &r.Response } -// SetExceptionBreakpointsRequest: The request configures the debuggers response to thrown exceptions. -// If an exception is configured to break, a 'stopped' event is fired (with reason 'exception'). -// Clients should only call this request if the capability 'exceptionBreakpointFilters' returns one or more filters. +// SetExceptionBreakpointsRequest: The request configures the debugger's response to thrown exceptions. +// If an exception is configured to break, a `stopped` event is fired (with reason `exception`). +// Clients should only call this request if the corresponding capability `exceptionBreakpointFilters` returns one or more filters. type SetExceptionBreakpointsRequest struct { Request @@ -725,17 +751,17 @@ type SetExceptionBreakpointsRequest struct { func (r *SetExceptionBreakpointsRequest) GetRequest() *Request { return &r.Request } -// SetExceptionBreakpointsArguments: Arguments for 'setExceptionBreakpoints' request. +// SetExceptionBreakpointsArguments: Arguments for `setExceptionBreakpoints` request. type SetExceptionBreakpointsArguments struct { Filters []string `json:"filters"` FilterOptions []ExceptionFilterOptions `json:"filterOptions,omitempty"` ExceptionOptions []ExceptionOptions `json:"exceptionOptions,omitempty"` } -// SetExceptionBreakpointsResponse: Response to 'setExceptionBreakpoints' request. -// The response contains an array of Breakpoint objects with information about each exception breakpoint or filter. The Breakpoint objects are in the same order as the elements of the 'filters', 'filterOptions', 'exceptionOptions' arrays given as arguments. If both 'filters' and 'filterOptions' are given, the returned array must start with 'filters' information first, followed by 'filterOptions' information. -// The mandatory 'verified' property of a Breakpoint object signals whether the exception breakpoint or filter could be successfully created and whether the optional condition or hit count expressions are valid. In case of an error the 'message' property explains the problem. An optional 'id' property can be used to introduce a unique ID for the exception breakpoint or filter so that it can be updated subsequently by sending breakpoint events. -// For backward compatibility both the 'breakpoints' array and the enclosing 'body' are optional. If these elements are missing a client will not be able to show problems for individual exception breakpoints or filters. +// SetExceptionBreakpointsResponse: Response to `setExceptionBreakpoints` request. +// The response contains an array of `Breakpoint` objects with information about each exception breakpoint or filter. The `Breakpoint` objects are in the same order as the elements of the `filters`, `filterOptions`, `exceptionOptions` arrays given as arguments. If both `filters` and `filterOptions` are given, the returned array must start with `filters` information first, followed by `filterOptions` information. +// The `verified` property of a `Breakpoint` object signals whether the exception breakpoint or filter could be successfully created and whether the condition or hit count expressions are valid. In case of an error the `message` property explains the problem. The `id` property can be used to introduce a unique ID for the exception breakpoint or filter so that it can be updated subsequently by sending breakpoint events. +// For backward compatibility both the `breakpoints` array and the enclosing `body` are optional. If these elements are missing a client is not able to show problems for individual exception breakpoints or filters. type SetExceptionBreakpointsResponse struct { Response @@ -749,7 +775,7 @@ type SetExceptionBreakpointsResponseBody struct { func (r *SetExceptionBreakpointsResponse) GetResponse() *Response { return &r.Response } // DataBreakpointInfoRequest: Obtains information on a possible data breakpoint that could be set on an expression or variable. -// Clients should only call this request if the capability 'supportsDataBreakpoints' is true. +// Clients should only call this request if the corresponding capability `supportsDataBreakpoints` is true. type DataBreakpointInfoRequest struct { Request @@ -758,13 +784,14 @@ type DataBreakpointInfoRequest struct { func (r *DataBreakpointInfoRequest) GetRequest() *Request { return &r.Request } -// DataBreakpointInfoArguments: Arguments for 'dataBreakpointInfo' request. +// DataBreakpointInfoArguments: Arguments for `dataBreakpointInfo` request. type DataBreakpointInfoArguments struct { VariablesReference int `json:"variablesReference,omitempty"` Name string `json:"name"` + FrameId int `json:"frameId,omitempty"` } -// DataBreakpointInfoResponse: Response to 'dataBreakpointInfo' request. +// DataBreakpointInfoResponse: Response to `dataBreakpointInfo` request. type DataBreakpointInfoResponse struct { Response @@ -782,8 +809,8 @@ func (r *DataBreakpointInfoResponse) GetResponse() *Response { return &r.Respons // SetDataBreakpointsRequest: Replaces all existing data breakpoints with new data breakpoints. // To clear all data breakpoints, specify an empty array. -// When a data breakpoint is hit, a 'stopped' event (with reason 'data breakpoint') is generated. -// Clients should only call this request if the capability 'supportsDataBreakpoints' is true. +// When a data breakpoint is hit, a `stopped` event (with reason `data breakpoint`) is generated. +// Clients should only call this request if the corresponding capability `supportsDataBreakpoints` is true. type SetDataBreakpointsRequest struct { Request @@ -792,12 +819,12 @@ type SetDataBreakpointsRequest struct { func (r *SetDataBreakpointsRequest) GetRequest() *Request { return &r.Request } -// SetDataBreakpointsArguments: Arguments for 'setDataBreakpoints' request. +// SetDataBreakpointsArguments: Arguments for `setDataBreakpoints` request. type SetDataBreakpointsArguments struct { Breakpoints []DataBreakpoint `json:"breakpoints"` } -// SetDataBreakpointsResponse: Response to 'setDataBreakpoints' request. +// SetDataBreakpointsResponse: Response to `setDataBreakpoints` request. // Returned is information about each breakpoint created by this request. type SetDataBreakpointsResponse struct { Response @@ -811,10 +838,10 @@ type SetDataBreakpointsResponseBody struct { func (r *SetDataBreakpointsResponse) GetResponse() *Response { return &r.Response } -// SetInstructionBreakpointsRequest: Replaces all existing instruction breakpoints. Typically, instruction breakpoints would be set from a diassembly window. +// SetInstructionBreakpointsRequest: Replaces all existing instruction breakpoints. Typically, instruction breakpoints would be set from a disassembly window. // To clear all instruction breakpoints, specify an empty array. -// When an instruction breakpoint is hit, a 'stopped' event (with reason 'instruction breakpoint') is generated. -// Clients should only call this request if the capability 'supportsInstructionBreakpoints' is true. +// When an instruction breakpoint is hit, a `stopped` event (with reason `instruction breakpoint`) is generated. +// Clients should only call this request if the corresponding capability `supportsInstructionBreakpoints` is true. type SetInstructionBreakpointsRequest struct { Request @@ -823,12 +850,12 @@ type SetInstructionBreakpointsRequest struct { func (r *SetInstructionBreakpointsRequest) GetRequest() *Request { return &r.Request } -// SetInstructionBreakpointsArguments: Arguments for 'setInstructionBreakpoints' request +// SetInstructionBreakpointsArguments: Arguments for `setInstructionBreakpoints` request type SetInstructionBreakpointsArguments struct { Breakpoints []InstructionBreakpoint `json:"breakpoints"` } -// SetInstructionBreakpointsResponse: Response to 'setInstructionBreakpoints' request +// SetInstructionBreakpointsResponse: Response to `setInstructionBreakpoints` request type SetInstructionBreakpointsResponse struct { Response @@ -841,7 +868,7 @@ type SetInstructionBreakpointsResponseBody struct { func (r *SetInstructionBreakpointsResponse) GetResponse() *Response { return &r.Response } -// ContinueRequest: The request starts the debuggee to run again. +// ContinueRequest: The request resumes execution of all threads. If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true resumes only the specified thread. If not all threads were resumed, the `allThreadsContinued` attribute of the response should be set to false. type ContinueRequest struct { Request @@ -850,12 +877,13 @@ type ContinueRequest struct { func (r *ContinueRequest) GetRequest() *Request { return &r.Request } -// ContinueArguments: Arguments for 'continue' request. +// ContinueArguments: Arguments for `continue` request. type ContinueArguments struct { - ThreadId int `json:"threadId"` + ThreadId int `json:"threadId"` + SingleThread bool `json:"singleThread,omitempty"` } -// ContinueResponse: Response to 'continue' request. +// ContinueResponse: Response to `continue` request. type ContinueResponse struct { Response @@ -868,8 +896,9 @@ type ContinueResponseBody struct { func (r *ContinueResponse) GetResponse() *Response { return &r.Response } -// NextRequest: The request starts the debuggee to run again for one step. -// The debug adapter first sends the response and then a 'stopped' event (with reason 'step') after the step has completed. +// NextRequest: The request executes one step (in the given granularity) for the specified thread and allows all other threads to run freely by resuming them. +// If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true prevents other suspended threads from resuming. +// The debug adapter first sends the response and then a `stopped` event (with reason `step`) after the step has completed. type NextRequest struct { Request @@ -878,25 +907,27 @@ type NextRequest struct { func (r *NextRequest) GetRequest() *Request { return &r.Request } -// NextArguments: Arguments for 'next' request. +// NextArguments: Arguments for `next` request. type NextArguments struct { - ThreadId int `json:"threadId"` - Granularity SteppingGranularity `json:"granularity,omitempty"` + ThreadId int `json:"threadId"` + SingleThread bool `json:"singleThread,omitempty"` + Granularity SteppingGranularity `json:"granularity,omitempty"` } -// NextResponse: Response to 'next' request. This is just an acknowledgement, so no body field is required. +// NextResponse: Response to `next` request. This is just an acknowledgement, so no body field is required. type NextResponse struct { Response } func (r *NextResponse) GetResponse() *Response { return &r.Response } -// StepInRequest: The request starts the debuggee to step into a function/method if possible. -// If it cannot step into a target, 'stepIn' behaves like 'next'. -// The debug adapter first sends the response and then a 'stopped' event (with reason 'step') after the step has completed. +// StepInRequest: The request resumes the given thread to step into a function/method and allows all other threads to run freely by resuming them. +// If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true prevents other suspended threads from resuming. +// If the request cannot step into a target, `stepIn` behaves like the `next` request. +// The debug adapter first sends the response and then a `stopped` event (with reason `step`) after the step has completed. // If there are multiple function/method calls (or other targets) on the source line, -// the optional argument 'targetId' can be used to control into which target the 'stepIn' should occur. -// The list of possible targets for a given source line can be retrieved via the 'stepInTargets' request. +// the argument `targetId` can be used to control into which target the `stepIn` should occur. +// The list of possible targets for a given source line can be retrieved via the `stepInTargets` request. type StepInRequest struct { Request @@ -905,22 +936,24 @@ type StepInRequest struct { func (r *StepInRequest) GetRequest() *Request { return &r.Request } -// StepInArguments: Arguments for 'stepIn' request. +// StepInArguments: Arguments for `stepIn` request. type StepInArguments struct { - ThreadId int `json:"threadId"` - TargetId int `json:"targetId,omitempty"` - Granularity SteppingGranularity `json:"granularity,omitempty"` + ThreadId int `json:"threadId"` + SingleThread bool `json:"singleThread,omitempty"` + TargetId int `json:"targetId,omitempty"` + Granularity SteppingGranularity `json:"granularity,omitempty"` } -// StepInResponse: Response to 'stepIn' request. This is just an acknowledgement, so no body field is required. +// StepInResponse: Response to `stepIn` request. This is just an acknowledgement, so no body field is required. type StepInResponse struct { Response } func (r *StepInResponse) GetResponse() *Response { return &r.Response } -// StepOutRequest: The request starts the debuggee to run again for one step. -// The debug adapter first sends the response and then a 'stopped' event (with reason 'step') after the step has completed. +// StepOutRequest: The request resumes the given thread to step out (return) from a function/method and allows all other threads to run freely by resuming them. +// If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true prevents other suspended threads from resuming. +// The debug adapter first sends the response and then a `stopped` event (with reason `step`) after the step has completed. type StepOutRequest struct { Request @@ -929,22 +962,24 @@ type StepOutRequest struct { func (r *StepOutRequest) GetRequest() *Request { return &r.Request } -// StepOutArguments: Arguments for 'stepOut' request. +// StepOutArguments: Arguments for `stepOut` request. type StepOutArguments struct { - ThreadId int `json:"threadId"` - Granularity SteppingGranularity `json:"granularity,omitempty"` + ThreadId int `json:"threadId"` + SingleThread bool `json:"singleThread,omitempty"` + Granularity SteppingGranularity `json:"granularity,omitempty"` } -// StepOutResponse: Response to 'stepOut' request. This is just an acknowledgement, so no body field is required. +// StepOutResponse: Response to `stepOut` request. This is just an acknowledgement, so no body field is required. type StepOutResponse struct { Response } func (r *StepOutResponse) GetResponse() *Response { return &r.Response } -// StepBackRequest: The request starts the debuggee to run one step backwards. -// The debug adapter first sends the response and then a 'stopped' event (with reason 'step') after the step has completed. -// Clients should only call this request if the capability 'supportsStepBack' is true. +// StepBackRequest: The request executes one backward step (in the given granularity) for the specified thread and allows all other threads to run backward freely by resuming them. +// If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true prevents other suspended threads from resuming. +// The debug adapter first sends the response and then a `stopped` event (with reason `step`) after the step has completed. +// Clients should only call this request if the corresponding capability `supportsStepBack` is true. type StepBackRequest struct { Request @@ -953,21 +988,22 @@ type StepBackRequest struct { func (r *StepBackRequest) GetRequest() *Request { return &r.Request } -// StepBackArguments: Arguments for 'stepBack' request. +// StepBackArguments: Arguments for `stepBack` request. type StepBackArguments struct { - ThreadId int `json:"threadId"` - Granularity SteppingGranularity `json:"granularity,omitempty"` + ThreadId int `json:"threadId"` + SingleThread bool `json:"singleThread,omitempty"` + Granularity SteppingGranularity `json:"granularity,omitempty"` } -// StepBackResponse: Response to 'stepBack' request. This is just an acknowledgement, so no body field is required. +// StepBackResponse: Response to `stepBack` request. This is just an acknowledgement, so no body field is required. type StepBackResponse struct { Response } func (r *StepBackResponse) GetResponse() *Response { return &r.Response } -// ReverseContinueRequest: The request starts the debuggee to run backward. -// Clients should only call this request if the capability 'supportsStepBack' is true. +// ReverseContinueRequest: The request resumes backward execution of all threads. If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true resumes only the specified thread. If not all threads were resumed, the `allThreadsContinued` attribute of the response should be set to false. +// Clients should only call this request if the corresponding capability `supportsStepBack` is true. type ReverseContinueRequest struct { Request @@ -976,21 +1012,22 @@ type ReverseContinueRequest struct { func (r *ReverseContinueRequest) GetRequest() *Request { return &r.Request } -// ReverseContinueArguments: Arguments for 'reverseContinue' request. +// ReverseContinueArguments: Arguments for `reverseContinue` request. type ReverseContinueArguments struct { - ThreadId int `json:"threadId"` + ThreadId int `json:"threadId"` + SingleThread bool `json:"singleThread,omitempty"` } -// ReverseContinueResponse: Response to 'reverseContinue' request. This is just an acknowledgement, so no body field is required. +// ReverseContinueResponse: Response to `reverseContinue` request. This is just an acknowledgement, so no body field is required. type ReverseContinueResponse struct { Response } func (r *ReverseContinueResponse) GetResponse() *Response { return &r.Response } -// RestartFrameRequest: The request restarts execution of the specified stackframe. -// The debug adapter first sends the response and then a 'stopped' event (with reason 'restart') after the restart has completed. -// Clients should only call this request if the capability 'supportsRestartFrame' is true. +// RestartFrameRequest: The request restarts execution of the specified stack frame. +// The debug adapter first sends the response and then a `stopped` event (with reason `restart`) after the restart has completed. +// Clients should only call this request if the corresponding capability `supportsRestartFrame` is true. type RestartFrameRequest struct { Request @@ -999,12 +1036,12 @@ type RestartFrameRequest struct { func (r *RestartFrameRequest) GetRequest() *Request { return &r.Request } -// RestartFrameArguments: Arguments for 'restartFrame' request. +// RestartFrameArguments: Arguments for `restartFrame` request. type RestartFrameArguments struct { FrameId int `json:"frameId"` } -// RestartFrameResponse: Response to 'restartFrame' request. This is just an acknowledgement, so no body field is required. +// RestartFrameResponse: Response to `restartFrame` request. This is just an acknowledgement, so no body field is required. type RestartFrameResponse struct { Response } @@ -1012,10 +1049,10 @@ type RestartFrameResponse struct { func (r *RestartFrameResponse) GetResponse() *Response { return &r.Response } // GotoRequest: The request sets the location where the debuggee will continue to run. -// This makes it possible to skip the execution of code or to executed code again. +// This makes it possible to skip the execution of code or to execute code again. // The code between the current location and the goto target is not executed but skipped. -// The debug adapter first sends the response and then a 'stopped' event with reason 'goto'. -// Clients should only call this request if the capability 'supportsGotoTargetsRequest' is true (because only then goto targets exist that can be passed as arguments). +// The debug adapter first sends the response and then a `stopped` event with reason `goto`. +// Clients should only call this request if the corresponding capability `supportsGotoTargetsRequest` is true (because only then goto targets exist that can be passed as arguments). type GotoRequest struct { Request @@ -1024,13 +1061,13 @@ type GotoRequest struct { func (r *GotoRequest) GetRequest() *Request { return &r.Request } -// GotoArguments: Arguments for 'goto' request. +// GotoArguments: Arguments for `goto` request. type GotoArguments struct { ThreadId int `json:"threadId"` TargetId int `json:"targetId"` } -// GotoResponse: Response to 'goto' request. This is just an acknowledgement, so no body field is required. +// GotoResponse: Response to `goto` request. This is just an acknowledgement, so no body field is required. type GotoResponse struct { Response } @@ -1038,7 +1075,7 @@ type GotoResponse struct { func (r *GotoResponse) GetResponse() *Response { return &r.Response } // PauseRequest: The request suspends the debuggee. -// The debug adapter first sends the response and then a 'stopped' event (with reason 'pause') after the thread has been paused successfully. +// The debug adapter first sends the response and then a `stopped` event (with reason `pause`) after the thread has been paused successfully. type PauseRequest struct { Request @@ -1047,12 +1084,12 @@ type PauseRequest struct { func (r *PauseRequest) GetRequest() *Request { return &r.Request } -// PauseArguments: Arguments for 'pause' request. +// PauseArguments: Arguments for `pause` request. type PauseArguments struct { ThreadId int `json:"threadId"` } -// PauseResponse: Response to 'pause' request. This is just an acknowledgement, so no body field is required. +// PauseResponse: Response to `pause` request. This is just an acknowledgement, so no body field is required. type PauseResponse struct { Response } @@ -1060,7 +1097,7 @@ type PauseResponse struct { func (r *PauseResponse) GetResponse() *Response { return &r.Response } // StackTraceRequest: The request returns a stacktrace from the current execution state of a given thread. -// A client can request all stack frames by omitting the startFrame and levels arguments. For performance conscious clients and if the debug adapter's 'supportsDelayedStackTraceLoading' capability is true, stack frames can be retrieved in a piecemeal way with the startFrame and levels arguments. The response of the stackTrace request may contain a totalFrames property that hints at the total number of frames in the stack. If a client needs this total number upfront, it can issue a request for a single (first) frame and depending on the value of totalFrames decide how to proceed. In any case a client should be prepared to receive less frames than requested, which is an indication that the end of the stack has been reached. +// A client can request all stack frames by omitting the startFrame and levels arguments. For performance-conscious clients and if the corresponding capability `supportsDelayedStackTraceLoading` is true, stack frames can be retrieved in a piecemeal way with the `startFrame` and `levels` arguments. The response of the `stackTrace` request may contain a `totalFrames` property that hints at the total number of frames in the stack. If a client needs this total number upfront, it can issue a request for a single (first) frame and depending on the value of `totalFrames` decide how to proceed. In any case a client should be prepared to receive fewer frames than requested, which is an indication that the end of the stack has been reached. type StackTraceRequest struct { Request @@ -1069,15 +1106,15 @@ type StackTraceRequest struct { func (r *StackTraceRequest) GetRequest() *Request { return &r.Request } -// StackTraceArguments: Arguments for 'stackTrace' request. +// StackTraceArguments: Arguments for `stackTrace` request. type StackTraceArguments struct { - ThreadId int `json:"threadId"` - StartFrame int `json:"startFrame,omitempty"` - Levels int `json:"levels,omitempty"` - Format StackFrameFormat `json:"format,omitempty"` + ThreadId int `json:"threadId"` + StartFrame int `json:"startFrame,omitempty"` + Levels int `json:"levels,omitempty"` + Format *StackFrameFormat `json:"format,omitempty"` } -// StackTraceResponse: Response to 'stackTrace' request. +// StackTraceResponse: Response to `stackTrace` request. type StackTraceResponse struct { Response @@ -1091,7 +1128,7 @@ type StackTraceResponseBody struct { func (r *StackTraceResponse) GetResponse() *Response { return &r.Response } -// ScopesRequest: The request returns the variable scopes for a given stackframe ID. +// ScopesRequest: The request returns the variable scopes for a given stack frame ID. type ScopesRequest struct { Request @@ -1100,12 +1137,12 @@ type ScopesRequest struct { func (r *ScopesRequest) GetRequest() *Request { return &r.Request } -// ScopesArguments: Arguments for 'scopes' request. +// ScopesArguments: Arguments for `scopes` request. type ScopesArguments struct { FrameId int `json:"frameId"` } -// ScopesResponse: Response to 'scopes' request. +// ScopesResponse: Response to `scopes` request. type ScopesResponse struct { Response @@ -1119,7 +1156,7 @@ type ScopesResponseBody struct { func (r *ScopesResponse) GetResponse() *Response { return &r.Response } // VariablesRequest: Retrieves all child variables for the given variable reference. -// An optional filter can be used to limit the fetched children to either named or indexed children. +// A filter can be used to limit the fetched children to either named or indexed children. type VariablesRequest struct { Request @@ -1128,16 +1165,16 @@ type VariablesRequest struct { func (r *VariablesRequest) GetRequest() *Request { return &r.Request } -// VariablesArguments: Arguments for 'variables' request. +// VariablesArguments: Arguments for `variables` request. type VariablesArguments struct { - VariablesReference int `json:"variablesReference"` - Filter string `json:"filter,omitempty"` - Start int `json:"start,omitempty"` - Count int `json:"count,omitempty"` - Format ValueFormat `json:"format,omitempty"` + VariablesReference int `json:"variablesReference"` + Filter string `json:"filter,omitempty"` + Start int `json:"start,omitempty"` + Count int `json:"count,omitempty"` + Format *ValueFormat `json:"format,omitempty"` } -// VariablesResponse: Response to 'variables' request. +// VariablesResponse: Response to `variables` request. type VariablesResponse struct { Response @@ -1150,8 +1187,8 @@ type VariablesResponseBody struct { func (r *VariablesResponse) GetResponse() *Response { return &r.Response } -// SetVariableRequest: Set the variable with the given name in the variable container to a new value. Clients should only call this request if the capability 'supportsSetVariable' is true. -// If a debug adapter implements both setVariable and setExpression, a client will only use setExpression if the variable has an evaluateName property. +// SetVariableRequest: Set the variable with the given name in the variable container to a new value. Clients should only call this request if the corresponding capability `supportsSetVariable` is true. +// If a debug adapter implements both `setVariable` and `setExpression`, a client will only use `setExpression` if the variable has an `evaluateName` property. type SetVariableRequest struct { Request @@ -1160,15 +1197,15 @@ type SetVariableRequest struct { func (r *SetVariableRequest) GetRequest() *Request { return &r.Request } -// SetVariableArguments: Arguments for 'setVariable' request. +// SetVariableArguments: Arguments for `setVariable` request. type SetVariableArguments struct { - VariablesReference int `json:"variablesReference"` - Name string `json:"name"` - Value string `json:"value"` - Format ValueFormat `json:"format,omitempty"` + VariablesReference int `json:"variablesReference"` + Name string `json:"name"` + Value string `json:"value"` + Format *ValueFormat `json:"format,omitempty"` } -// SetVariableResponse: Response to 'setVariable' request. +// SetVariableResponse: Response to `setVariable` request. type SetVariableResponse struct { Response @@ -1194,13 +1231,13 @@ type SourceRequest struct { func (r *SourceRequest) GetRequest() *Request { return &r.Request } -// SourceArguments: Arguments for 'source' request. +// SourceArguments: Arguments for `source` request. type SourceArguments struct { - Source Source `json:"source,omitempty"` - SourceReference int `json:"sourceReference"` + Source *Source `json:"source,omitempty"` + SourceReference int `json:"sourceReference"` } -// SourceResponse: Response to 'source' request. +// SourceResponse: Response to `source` request. type SourceResponse struct { Response @@ -1221,7 +1258,7 @@ type ThreadsRequest struct { func (r *ThreadsRequest) GetRequest() *Request { return &r.Request } -// ThreadsResponse: Response to 'threads' request. +// ThreadsResponse: Response to `threads` request. type ThreadsResponse struct { Response @@ -1235,7 +1272,7 @@ type ThreadsResponseBody struct { func (r *ThreadsResponse) GetResponse() *Response { return &r.Response } // TerminateThreadsRequest: The request terminates the threads with the given ids. -// Clients should only call this request if the capability 'supportsTerminateThreadsRequest' is true. +// Clients should only call this request if the corresponding capability `supportsTerminateThreadsRequest` is true. type TerminateThreadsRequest struct { Request @@ -1244,12 +1281,12 @@ type TerminateThreadsRequest struct { func (r *TerminateThreadsRequest) GetRequest() *Request { return &r.Request } -// TerminateThreadsArguments: Arguments for 'terminateThreads' request. +// TerminateThreadsArguments: Arguments for `terminateThreads` request. type TerminateThreadsArguments struct { ThreadIds []int `json:"threadIds,omitempty"` } -// TerminateThreadsResponse: Response to 'terminateThreads' request. This is just an acknowledgement, so no body field is required. +// TerminateThreadsResponse: Response to `terminateThreads` request. This is just an acknowledgement, no body field is required. type TerminateThreadsResponse struct { Response } @@ -1257,7 +1294,7 @@ type TerminateThreadsResponse struct { func (r *TerminateThreadsResponse) GetResponse() *Response { return &r.Response } // ModulesRequest: Modules can be retrieved from the debug adapter with this request which can either return all modules or a range of modules to support paging. -// Clients should only call this request if the capability 'supportsModulesRequest' is true. +// Clients should only call this request if the corresponding capability `supportsModulesRequest` is true. type ModulesRequest struct { Request @@ -1266,13 +1303,13 @@ type ModulesRequest struct { func (r *ModulesRequest) GetRequest() *Request { return &r.Request } -// ModulesArguments: Arguments for 'modules' request. +// ModulesArguments: Arguments for `modules` request. type ModulesArguments struct { StartModule int `json:"startModule,omitempty"` ModuleCount int `json:"moduleCount,omitempty"` } -// ModulesResponse: Response to 'modules' request. +// ModulesResponse: Response to `modules` request. type ModulesResponse struct { Response @@ -1287,20 +1324,20 @@ type ModulesResponseBody struct { func (r *ModulesResponse) GetResponse() *Response { return &r.Response } // LoadedSourcesRequest: Retrieves the set of all sources currently loaded by the debugged process. -// Clients should only call this request if the capability 'supportsLoadedSourcesRequest' is true. +// Clients should only call this request if the corresponding capability `supportsLoadedSourcesRequest` is true. type LoadedSourcesRequest struct { Request - Arguments LoadedSourcesArguments `json:"arguments,omitempty"` + Arguments *LoadedSourcesArguments `json:"arguments,omitempty"` } func (r *LoadedSourcesRequest) GetRequest() *Request { return &r.Request } -// LoadedSourcesArguments: Arguments for 'loadedSources' request. +// LoadedSourcesArguments: Arguments for `loadedSources` request. type LoadedSourcesArguments struct { } -// LoadedSourcesResponse: Response to 'loadedSources' request. +// LoadedSourcesResponse: Response to `loadedSources` request. type LoadedSourcesResponse struct { Response @@ -1313,7 +1350,7 @@ type LoadedSourcesResponseBody struct { func (r *LoadedSourcesResponse) GetResponse() *Response { return &r.Response } -// EvaluateRequest: Evaluates the given expression in the context of the top most stack frame. +// EvaluateRequest: Evaluates the given expression in the context of the topmost stack frame. // The expression has access to any variables and arguments that are in scope. type EvaluateRequest struct { Request @@ -1323,15 +1360,15 @@ type EvaluateRequest struct { func (r *EvaluateRequest) GetRequest() *Request { return &r.Request } -// EvaluateArguments: Arguments for 'evaluate' request. +// EvaluateArguments: Arguments for `evaluate` request. type EvaluateArguments struct { - Expression string `json:"expression"` - FrameId int `json:"frameId,omitempty"` - Context string `json:"context,omitempty"` - Format ValueFormat `json:"format,omitempty"` + Expression string `json:"expression"` + FrameId int `json:"frameId,omitempty"` + Context string `json:"context,omitempty"` + Format *ValueFormat `json:"format,omitempty"` } -// EvaluateResponse: Response to 'evaluate' request. +// EvaluateResponse: Response to `evaluate` request. type EvaluateResponse struct { Response @@ -1339,21 +1376,21 @@ type EvaluateResponse struct { } type EvaluateResponseBody struct { - Result string `json:"result"` - Type string `json:"type,omitempty"` - PresentationHint VariablePresentationHint `json:"presentationHint,omitempty"` - VariablesReference int `json:"variablesReference"` - NamedVariables int `json:"namedVariables,omitempty"` - IndexedVariables int `json:"indexedVariables,omitempty"` - MemoryReference string `json:"memoryReference,omitempty"` + Result string `json:"result"` + Type string `json:"type,omitempty"` + PresentationHint *VariablePresentationHint `json:"presentationHint,omitempty"` + VariablesReference int `json:"variablesReference"` + NamedVariables int `json:"namedVariables,omitempty"` + IndexedVariables int `json:"indexedVariables,omitempty"` + MemoryReference string `json:"memoryReference,omitempty"` } func (r *EvaluateResponse) GetResponse() *Response { return &r.Response } -// SetExpressionRequest: Evaluates the given 'value' expression and assigns it to the 'expression' which must be a modifiable l-value. +// SetExpressionRequest: Evaluates the given `value` expression and assigns it to the `expression` which must be a modifiable l-value. // The expressions have access to any variables and arguments that are in scope of the specified frame. -// Clients should only call this request if the capability 'supportsSetExpression' is true. -// If a debug adapter implements both setExpression and setVariable, a client will only use setExpression if the variable has an evaluateName property. +// Clients should only call this request if the corresponding capability `supportsSetExpression` is true. +// If a debug adapter implements both `setExpression` and `setVariable`, a client uses `setExpression` if the variable has an `evaluateName` property. type SetExpressionRequest struct { Request @@ -1362,15 +1399,15 @@ type SetExpressionRequest struct { func (r *SetExpressionRequest) GetRequest() *Request { return &r.Request } -// SetExpressionArguments: Arguments for 'setExpression' request. +// SetExpressionArguments: Arguments for `setExpression` request. type SetExpressionArguments struct { - Expression string `json:"expression"` - Value string `json:"value"` - FrameId int `json:"frameId,omitempty"` - Format ValueFormat `json:"format,omitempty"` + Expression string `json:"expression"` + Value string `json:"value"` + FrameId int `json:"frameId,omitempty"` + Format *ValueFormat `json:"format,omitempty"` } -// SetExpressionResponse: Response to 'setExpression' request. +// SetExpressionResponse: Response to `setExpression` request. type SetExpressionResponse struct { Response @@ -1378,20 +1415,19 @@ type SetExpressionResponse struct { } type SetExpressionResponseBody struct { - Value string `json:"value"` - Type string `json:"type,omitempty"` - PresentationHint VariablePresentationHint `json:"presentationHint,omitempty"` - VariablesReference int `json:"variablesReference,omitempty"` - NamedVariables int `json:"namedVariables,omitempty"` - IndexedVariables int `json:"indexedVariables,omitempty"` + Value string `json:"value"` + Type string `json:"type,omitempty"` + PresentationHint *VariablePresentationHint `json:"presentationHint,omitempty"` + VariablesReference int `json:"variablesReference,omitempty"` + NamedVariables int `json:"namedVariables,omitempty"` + IndexedVariables int `json:"indexedVariables,omitempty"` } func (r *SetExpressionResponse) GetResponse() *Response { return &r.Response } -// StepInTargetsRequest: This request retrieves the possible stepIn targets for the specified stack frame. -// These targets can be used in the 'stepIn' request. -// The StepInTargets may only be called if the 'supportsStepInTargetsRequest' capability exists and is true. -// Clients should only call this request if the capability 'supportsStepInTargetsRequest' is true. +// StepInTargetsRequest: This request retrieves the possible step-in targets for the specified stack frame. +// These targets can be used in the `stepIn` request. +// Clients should only call this request if the corresponding capability `supportsStepInTargetsRequest` is true. type StepInTargetsRequest struct { Request @@ -1400,12 +1436,12 @@ type StepInTargetsRequest struct { func (r *StepInTargetsRequest) GetRequest() *Request { return &r.Request } -// StepInTargetsArguments: Arguments for 'stepInTargets' request. +// StepInTargetsArguments: Arguments for `stepInTargets` request. type StepInTargetsArguments struct { FrameId int `json:"frameId"` } -// StepInTargetsResponse: Response to 'stepInTargets' request. +// StepInTargetsResponse: Response to `stepInTargets` request. type StepInTargetsResponse struct { Response @@ -1419,8 +1455,8 @@ type StepInTargetsResponseBody struct { func (r *StepInTargetsResponse) GetResponse() *Response { return &r.Response } // GotoTargetsRequest: This request retrieves the possible goto targets for the specified source location. -// These targets can be used in the 'goto' request. -// Clients should only call this request if the capability 'supportsGotoTargetsRequest' is true. +// These targets can be used in the `goto` request. +// Clients should only call this request if the corresponding capability `supportsGotoTargetsRequest` is true. type GotoTargetsRequest struct { Request @@ -1429,14 +1465,14 @@ type GotoTargetsRequest struct { func (r *GotoTargetsRequest) GetRequest() *Request { return &r.Request } -// GotoTargetsArguments: Arguments for 'gotoTargets' request. +// GotoTargetsArguments: Arguments for `gotoTargets` request. type GotoTargetsArguments struct { Source Source `json:"source"` Line int `json:"line"` Column int `json:"column,omitempty"` } -// GotoTargetsResponse: Response to 'gotoTargets' request. +// GotoTargetsResponse: Response to `gotoTargets` request. type GotoTargetsResponse struct { Response @@ -1450,7 +1486,7 @@ type GotoTargetsResponseBody struct { func (r *GotoTargetsResponse) GetResponse() *Response { return &r.Response } // CompletionsRequest: Returns a list of possible completions for a given caret position and text. -// Clients should only call this request if the capability 'supportsCompletionsRequest' is true. +// Clients should only call this request if the corresponding capability `supportsCompletionsRequest` is true. type CompletionsRequest struct { Request @@ -1459,7 +1495,7 @@ type CompletionsRequest struct { func (r *CompletionsRequest) GetRequest() *Request { return &r.Request } -// CompletionsArguments: Arguments for 'completions' request. +// CompletionsArguments: Arguments for `completions` request. type CompletionsArguments struct { FrameId int `json:"frameId,omitempty"` Text string `json:"text"` @@ -1467,7 +1503,7 @@ type CompletionsArguments struct { Line int `json:"line,omitempty"` } -// CompletionsResponse: Response to 'completions' request. +// CompletionsResponse: Response to `completions` request. type CompletionsResponse struct { Response @@ -1481,7 +1517,7 @@ type CompletionsResponseBody struct { func (r *CompletionsResponse) GetResponse() *Response { return &r.Response } // ExceptionInfoRequest: Retrieves the details of the exception that caused this event to be raised. -// Clients should only call this request if the capability 'supportsExceptionInfoRequest' is true. +// Clients should only call this request if the corresponding capability `supportsExceptionInfoRequest` is true. type ExceptionInfoRequest struct { Request @@ -1490,12 +1526,12 @@ type ExceptionInfoRequest struct { func (r *ExceptionInfoRequest) GetRequest() *Request { return &r.Request } -// ExceptionInfoArguments: Arguments for 'exceptionInfo' request. +// ExceptionInfoArguments: Arguments for `exceptionInfo` request. type ExceptionInfoArguments struct { ThreadId int `json:"threadId"` } -// ExceptionInfoResponse: Response to 'exceptionInfo' request. +// ExceptionInfoResponse: Response to `exceptionInfo` request. type ExceptionInfoResponse struct { Response @@ -1506,13 +1542,13 @@ type ExceptionInfoResponseBody struct { ExceptionId string `json:"exceptionId"` Description string `json:"description,omitempty"` BreakMode ExceptionBreakMode `json:"breakMode"` - Details ExceptionDetails `json:"details,omitempty"` + Details *ExceptionDetails `json:"details,omitempty"` } func (r *ExceptionInfoResponse) GetResponse() *Response { return &r.Response } // ReadMemoryRequest: Reads bytes from memory at the provided location. -// Clients should only call this request if the capability 'supportsReadMemoryRequest' is true. +// Clients should only call this request if the corresponding capability `supportsReadMemoryRequest` is true. type ReadMemoryRequest struct { Request @@ -1521,14 +1557,14 @@ type ReadMemoryRequest struct { func (r *ReadMemoryRequest) GetRequest() *Request { return &r.Request } -// ReadMemoryArguments: Arguments for 'readMemory' request. +// ReadMemoryArguments: Arguments for `readMemory` request. type ReadMemoryArguments struct { MemoryReference string `json:"memoryReference"` Offset int `json:"offset,omitempty"` Count int `json:"count"` } -// ReadMemoryResponse: Response to 'readMemory' request. +// ReadMemoryResponse: Response to `readMemory` request. type ReadMemoryResponse struct { Response @@ -1544,7 +1580,7 @@ type ReadMemoryResponseBody struct { func (r *ReadMemoryResponse) GetResponse() *Response { return &r.Response } // WriteMemoryRequest: Writes bytes to memory at the provided location. -// Clients should only call this request if the capability 'supportsWriteMemoryRequest' is true. +// Clients should only call this request if the corresponding capability `supportsWriteMemoryRequest` is true. type WriteMemoryRequest struct { Request @@ -1553,7 +1589,7 @@ type WriteMemoryRequest struct { func (r *WriteMemoryRequest) GetRequest() *Request { return &r.Request } -// WriteMemoryArguments: Arguments for 'writeMemory' request. +// WriteMemoryArguments: Arguments for `writeMemory` request. type WriteMemoryArguments struct { MemoryReference string `json:"memoryReference"` Offset int `json:"offset,omitempty"` @@ -1561,7 +1597,7 @@ type WriteMemoryArguments struct { Data string `json:"data"` } -// WriteMemoryResponse: Response to 'writeMemory' request. +// WriteMemoryResponse: Response to `writeMemory` request. type WriteMemoryResponse struct { Response @@ -1576,7 +1612,7 @@ type WriteMemoryResponseBody struct { func (r *WriteMemoryResponse) GetResponse() *Response { return &r.Response } // DisassembleRequest: Disassembles code stored at the provided location. -// Clients should only call this request if the capability 'supportsDisassembleRequest' is true. +// Clients should only call this request if the corresponding capability `supportsDisassembleRequest` is true. type DisassembleRequest struct { Request @@ -1585,7 +1621,7 @@ type DisassembleRequest struct { func (r *DisassembleRequest) GetRequest() *Request { return &r.Request } -// DisassembleArguments: Arguments for 'disassemble' request. +// DisassembleArguments: Arguments for `disassemble` request. type DisassembleArguments struct { MemoryReference string `json:"memoryReference"` Offset int `json:"offset,omitempty"` @@ -1594,7 +1630,7 @@ type DisassembleArguments struct { ResolveSymbols bool `json:"resolveSymbols,omitempty"` } -// DisassembleResponse: Response to 'disassemble' request. +// DisassembleResponse: Response to `disassemble` request. type DisassembleResponse struct { Response @@ -1609,47 +1645,48 @@ func (r *DisassembleResponse) GetResponse() *Response { return &r.Response } // Capabilities: Information about the capabilities of a debug adapter. type Capabilities struct { - SupportsConfigurationDoneRequest bool `json:"supportsConfigurationDoneRequest,omitempty"` - SupportsFunctionBreakpoints bool `json:"supportsFunctionBreakpoints,omitempty"` - SupportsConditionalBreakpoints bool `json:"supportsConditionalBreakpoints,omitempty"` - SupportsHitConditionalBreakpoints bool `json:"supportsHitConditionalBreakpoints,omitempty"` - SupportsEvaluateForHovers bool `json:"supportsEvaluateForHovers,omitempty"` - ExceptionBreakpointFilters []ExceptionBreakpointsFilter `json:"exceptionBreakpointFilters,omitempty"` - SupportsStepBack bool `json:"supportsStepBack,omitempty"` - SupportsSetVariable bool `json:"supportsSetVariable,omitempty"` - SupportsRestartFrame bool `json:"supportsRestartFrame,omitempty"` - SupportsGotoTargetsRequest bool `json:"supportsGotoTargetsRequest,omitempty"` - SupportsStepInTargetsRequest bool `json:"supportsStepInTargetsRequest,omitempty"` - SupportsCompletionsRequest bool `json:"supportsCompletionsRequest,omitempty"` - CompletionTriggerCharacters []string `json:"completionTriggerCharacters,omitempty"` - SupportsModulesRequest bool `json:"supportsModulesRequest,omitempty"` - AdditionalModuleColumns []ColumnDescriptor `json:"additionalModuleColumns,omitempty"` - SupportedChecksumAlgorithms []ChecksumAlgorithm `json:"supportedChecksumAlgorithms,omitempty"` - SupportsRestartRequest bool `json:"supportsRestartRequest,omitempty"` - SupportsExceptionOptions bool `json:"supportsExceptionOptions,omitempty"` - SupportsValueFormattingOptions bool `json:"supportsValueFormattingOptions,omitempty"` - SupportsExceptionInfoRequest bool `json:"supportsExceptionInfoRequest,omitempty"` - SupportTerminateDebuggee bool `json:"supportTerminateDebuggee,omitempty"` - SupportSuspendDebuggee bool `json:"supportSuspendDebuggee,omitempty"` - SupportsDelayedStackTraceLoading bool `json:"supportsDelayedStackTraceLoading,omitempty"` - SupportsLoadedSourcesRequest bool `json:"supportsLoadedSourcesRequest,omitempty"` - SupportsLogPoints bool `json:"supportsLogPoints,omitempty"` - SupportsTerminateThreadsRequest bool `json:"supportsTerminateThreadsRequest,omitempty"` - SupportsSetExpression bool `json:"supportsSetExpression,omitempty"` - SupportsTerminateRequest bool `json:"supportsTerminateRequest,omitempty"` - SupportsDataBreakpoints bool `json:"supportsDataBreakpoints,omitempty"` - SupportsReadMemoryRequest bool `json:"supportsReadMemoryRequest,omitempty"` - SupportsWriteMemoryRequest bool `json:"supportsWriteMemoryRequest,omitempty"` - SupportsDisassembleRequest bool `json:"supportsDisassembleRequest,omitempty"` - SupportsCancelRequest bool `json:"supportsCancelRequest,omitempty"` - SupportsBreakpointLocationsRequest bool `json:"supportsBreakpointLocationsRequest,omitempty"` - SupportsClipboardContext bool `json:"supportsClipboardContext,omitempty"` - SupportsSteppingGranularity bool `json:"supportsSteppingGranularity,omitempty"` - SupportsInstructionBreakpoints bool `json:"supportsInstructionBreakpoints,omitempty"` - SupportsExceptionFilterOptions bool `json:"supportsExceptionFilterOptions,omitempty"` -} - -// ExceptionBreakpointsFilter: An ExceptionBreakpointsFilter is shown in the UI as an filter option for configuring how exceptions are dealt with. + SupportsConfigurationDoneRequest bool `json:"supportsConfigurationDoneRequest,omitempty"` + SupportsFunctionBreakpoints bool `json:"supportsFunctionBreakpoints,omitempty"` + SupportsConditionalBreakpoints bool `json:"supportsConditionalBreakpoints,omitempty"` + SupportsHitConditionalBreakpoints bool `json:"supportsHitConditionalBreakpoints,omitempty"` + SupportsEvaluateForHovers bool `json:"supportsEvaluateForHovers,omitempty"` + ExceptionBreakpointFilters []ExceptionBreakpointsFilter `json:"exceptionBreakpointFilters,omitempty"` + SupportsStepBack bool `json:"supportsStepBack,omitempty"` + SupportsSetVariable bool `json:"supportsSetVariable,omitempty"` + SupportsRestartFrame bool `json:"supportsRestartFrame,omitempty"` + SupportsGotoTargetsRequest bool `json:"supportsGotoTargetsRequest,omitempty"` + SupportsStepInTargetsRequest bool `json:"supportsStepInTargetsRequest,omitempty"` + SupportsCompletionsRequest bool `json:"supportsCompletionsRequest,omitempty"` + CompletionTriggerCharacters []string `json:"completionTriggerCharacters,omitempty"` + SupportsModulesRequest bool `json:"supportsModulesRequest,omitempty"` + AdditionalModuleColumns []ColumnDescriptor `json:"additionalModuleColumns,omitempty"` + SupportedChecksumAlgorithms []ChecksumAlgorithm `json:"supportedChecksumAlgorithms,omitempty"` + SupportsRestartRequest bool `json:"supportsRestartRequest,omitempty"` + SupportsExceptionOptions bool `json:"supportsExceptionOptions,omitempty"` + SupportsValueFormattingOptions bool `json:"supportsValueFormattingOptions,omitempty"` + SupportsExceptionInfoRequest bool `json:"supportsExceptionInfoRequest,omitempty"` + SupportTerminateDebuggee bool `json:"supportTerminateDebuggee,omitempty"` + SupportSuspendDebuggee bool `json:"supportSuspendDebuggee,omitempty"` + SupportsDelayedStackTraceLoading bool `json:"supportsDelayedStackTraceLoading,omitempty"` + SupportsLoadedSourcesRequest bool `json:"supportsLoadedSourcesRequest,omitempty"` + SupportsLogPoints bool `json:"supportsLogPoints,omitempty"` + SupportsTerminateThreadsRequest bool `json:"supportsTerminateThreadsRequest,omitempty"` + SupportsSetExpression bool `json:"supportsSetExpression,omitempty"` + SupportsTerminateRequest bool `json:"supportsTerminateRequest,omitempty"` + SupportsDataBreakpoints bool `json:"supportsDataBreakpoints,omitempty"` + SupportsReadMemoryRequest bool `json:"supportsReadMemoryRequest,omitempty"` + SupportsWriteMemoryRequest bool `json:"supportsWriteMemoryRequest,omitempty"` + SupportsDisassembleRequest bool `json:"supportsDisassembleRequest,omitempty"` + SupportsCancelRequest bool `json:"supportsCancelRequest,omitempty"` + SupportsBreakpointLocationsRequest bool `json:"supportsBreakpointLocationsRequest,omitempty"` + SupportsClipboardContext bool `json:"supportsClipboardContext,omitempty"` + SupportsSteppingGranularity bool `json:"supportsSteppingGranularity,omitempty"` + SupportsInstructionBreakpoints bool `json:"supportsInstructionBreakpoints,omitempty"` + SupportsExceptionFilterOptions bool `json:"supportsExceptionFilterOptions,omitempty"` + SupportsSingleThreadExecutionRequests bool `json:"supportsSingleThreadExecutionRequests,omitempty"` +} + +// ExceptionBreakpointsFilter: An `ExceptionBreakpointsFilter` is shown in the UI as an filter option for configuring how exceptions are dealt with. type ExceptionBreakpointsFilter struct { Filter string `json:"filter"` Label string `json:"label"` @@ -1671,13 +1708,12 @@ type ErrorMessage struct { } // Module: A Module object represents a row in the modules view. -// Two attributes are mandatory: an id identifies a module in the modules view and is used in a ModuleEvent for identifying a module for adding, updating or deleting. -// The name is used to minimally render the module in the UI. +// The `id` attribute identifies a module in the modules view and is used in a `module` event for identifying a module for adding, updating or deleting. +// The `name` attribute is used to minimally render the module in the UI. // -// Additional attributes can be added to the module. They will show up in the module View if they have a corresponding ColumnDescriptor. +// Additional attributes can be added to the module. They show up in the module view if they have a corresponding `ColumnDescriptor`. // -// To avoid an unnecessary proliferation of additional attributes with similar semantics but different names -// we recommend to re-use attributes from the 'recommended' list below first, and only introduce new attributes if nothing appropriate could be found. +// To avoid an unnecessary proliferation of additional attributes with similar semantics but different names, we recommend to re-use attributes from the 'recommended' list below first, and only introduce new attributes if nothing appropriate could be found. type Module struct { Id interface{} `json:"id"` Name string `json:"name"` @@ -1691,7 +1727,7 @@ type Module struct { AddressRange string `json:"addressRange,omitempty"` } -// ColumnDescriptor: A ColumnDescriptor specifies what module attribute to show in a column of the ModulesView, how to format it, +// ColumnDescriptor: A `ColumnDescriptor` specifies what module attribute to show in a column of the modules view, how to format it, // and what the column's label should be. // It is only used if the underlying UI actually supports this level of customization. type ColumnDescriptor struct { @@ -1702,7 +1738,7 @@ type ColumnDescriptor struct { Width int `json:"width,omitempty"` } -// ModulesViewDescriptor: The ModulesViewDescriptor is the container for all declarative configuration options of a ModuleView. +// ModulesViewDescriptor: The ModulesViewDescriptor is the container for all declarative configuration options of a module view. // For now it only specifies the columns to be shown in the modules view. type ModulesViewDescriptor struct { Columns []ColumnDescriptor `json:"columns"` @@ -1714,8 +1750,8 @@ type Thread struct { Name string `json:"name"` } -// Source: A Source is a descriptor for source code. -// It is returned from the debug adapter as part of a StackFrame and it is used by clients when specifying breakpoints. +// Source: A `Source` is a descriptor for source code. +// It is returned from the debug adapter as part of a `StackFrame` and it is used by clients when specifying breakpoints. type Source struct { Name string `json:"name,omitempty"` Path string `json:"path,omitempty"` @@ -1731,7 +1767,7 @@ type Source struct { type StackFrame struct { Id int `json:"id"` Name string `json:"name"` - Source Source `json:"source,omitempty"` + Source *Source `json:"source,omitempty"` Line int `json:"line"` Column int `json:"column"` EndLine int `json:"endLine,omitempty"` @@ -1742,47 +1778,48 @@ type StackFrame struct { PresentationHint string `json:"presentationHint,omitempty"` } -// Scope: A Scope is a named container for variables. Optionally a scope can map to a source or a range within a source. +// Scope: A `Scope` is a named container for variables. Optionally a scope can map to a source or a range within a source. type Scope struct { - Name string `json:"name"` - PresentationHint string `json:"presentationHint,omitempty"` - VariablesReference int `json:"variablesReference"` - NamedVariables int `json:"namedVariables,omitempty"` - IndexedVariables int `json:"indexedVariables,omitempty"` - Expensive bool `json:"expensive"` - Source Source `json:"source,omitempty"` - Line int `json:"line,omitempty"` - Column int `json:"column,omitempty"` - EndLine int `json:"endLine,omitempty"` - EndColumn int `json:"endColumn,omitempty"` + Name string `json:"name"` + PresentationHint string `json:"presentationHint,omitempty"` + VariablesReference int `json:"variablesReference"` + NamedVariables int `json:"namedVariables,omitempty"` + IndexedVariables int `json:"indexedVariables,omitempty"` + Expensive bool `json:"expensive"` + Source *Source `json:"source,omitempty"` + Line int `json:"line,omitempty"` + Column int `json:"column,omitempty"` + EndLine int `json:"endLine,omitempty"` + EndColumn int `json:"endColumn,omitempty"` } // Variable: A Variable is a name/value pair. -// Optionally a variable can have a 'type' that is shown if space permits or when hovering over the variable's name. -// An optional 'kind' is used to render additional properties of the variable, e.g. different icons can be used to indicate that a variable is public or private. -// If the value is structured (has children), a handle is provided to retrieve the children with the VariablesRequest. -// If the number of named or indexed children is large, the numbers should be returned via the optional 'namedVariables' and 'indexedVariables' attributes. -// The client can use this optional information to present the children in a paged UI and fetch them in chunks. +// The `type` attribute is shown if space permits or when hovering over the variable's name. +// The `kind` attribute is used to render additional properties of the variable, e.g. different icons can be used to indicate that a variable is public or private. +// If the value is structured (has children), a handle is provided to retrieve the children with the `variables` request. +// If the number of named or indexed children is large, the numbers should be returned via the `namedVariables` and `indexedVariables` attributes. +// The client can use this information to present the children in a paged UI and fetch them in chunks. type Variable struct { - Name string `json:"name"` - Value string `json:"value"` - Type string `json:"type,omitempty"` - PresentationHint VariablePresentationHint `json:"presentationHint,omitempty"` - EvaluateName string `json:"evaluateName,omitempty"` - VariablesReference int `json:"variablesReference"` - NamedVariables int `json:"namedVariables,omitempty"` - IndexedVariables int `json:"indexedVariables,omitempty"` - MemoryReference string `json:"memoryReference,omitempty"` -} - -// VariablePresentationHint: Optional properties of a variable that can be used to determine how to render the variable in the UI. + Name string `json:"name"` + Value string `json:"value"` + Type string `json:"type,omitempty"` + PresentationHint *VariablePresentationHint `json:"presentationHint,omitempty"` + EvaluateName string `json:"evaluateName,omitempty"` + VariablesReference int `json:"variablesReference"` + NamedVariables int `json:"namedVariables,omitempty"` + IndexedVariables int `json:"indexedVariables,omitempty"` + MemoryReference string `json:"memoryReference,omitempty"` +} + +// VariablePresentationHint: Properties of a variable that can be used to determine how to render the variable in the UI. type VariablePresentationHint struct { Kind string `json:"kind,omitempty"` Attributes []string `json:"attributes,omitempty"` Visibility string `json:"visibility,omitempty"` + Lazy bool `json:"lazy,omitempty"` } -// BreakpointLocation: Properties of a breakpoint location returned from the 'breakpointLocations' request. +// BreakpointLocation: Properties of a breakpoint location returned from the `breakpointLocations` request. type BreakpointLocation struct { Line int `json:"line"` Column int `json:"column,omitempty"` @@ -1790,7 +1827,7 @@ type BreakpointLocation struct { EndColumn int `json:"endColumn,omitempty"` } -// SourceBreakpoint: Properties of a breakpoint or logpoint passed to the setBreakpoints request. +// SourceBreakpoint: Properties of a breakpoint or logpoint passed to the `setBreakpoints` request. type SourceBreakpoint struct { Line int `json:"line"` Column int `json:"column,omitempty"` @@ -1799,7 +1836,7 @@ type SourceBreakpoint struct { LogMessage string `json:"logMessage,omitempty"` } -// FunctionBreakpoint: Properties of a breakpoint passed to the setFunctionBreakpoints request. +// FunctionBreakpoint: Properties of a breakpoint passed to the `setFunctionBreakpoints` request. type FunctionBreakpoint struct { Name string `json:"name"` Condition string `json:"condition,omitempty"` @@ -1809,7 +1846,7 @@ type FunctionBreakpoint struct { // DataBreakpointAccessType: This enumeration defines all possible access types for data breakpoints. type DataBreakpointAccessType string -// DataBreakpoint: Properties of a data breakpoint passed to the setDataBreakpoints request. +// DataBreakpoint: Properties of a data breakpoint passed to the `setDataBreakpoints` request. type DataBreakpoint struct { DataId string `json:"dataId"` AccessType DataBreakpointAccessType `json:"accessType,omitempty"` @@ -1817,7 +1854,7 @@ type DataBreakpoint struct { HitCondition string `json:"hitCondition,omitempty"` } -// InstructionBreakpoint: Properties of a breakpoint passed to the setInstructionBreakpoints request +// InstructionBreakpoint: Properties of a breakpoint passed to the `setInstructionBreakpoints` request type InstructionBreakpoint struct { InstructionReference string `json:"instructionReference"` Offset int `json:"offset,omitempty"` @@ -1825,7 +1862,7 @@ type InstructionBreakpoint struct { HitCondition string `json:"hitCondition,omitempty"` } -// Breakpoint: Information about a Breakpoint created in setBreakpoints, setFunctionBreakpoints, setInstructionBreakpoints, or setDataBreakpoints. +// Breakpoint: Information about a breakpoint created in `setBreakpoints`, `setFunctionBreakpoints`, `setInstructionBreakpoints`, or `setDataBreakpoints` requests. type Breakpoint struct { Id int `json:"id,omitempty"` Verified bool `json:"verified"` @@ -1839,17 +1876,21 @@ type Breakpoint struct { Offset int `json:"offset,omitempty"` } -// SteppingGranularity: The granularity of one 'step' in the stepping requests 'next', 'stepIn', 'stepOut', and 'stepBack'. +// SteppingGranularity: The granularity of one 'step' in the stepping requests `next`, `stepIn`, `stepOut`, and `stepBack`. type SteppingGranularity string -// StepInTarget: A StepInTarget can be used in the 'stepIn' request and determines into which single target the stepIn request should step. +// StepInTarget: A `StepInTarget` can be used in the `stepIn` request and determines into which single target the `stepIn` request should step. type StepInTarget struct { - Id int `json:"id"` - Label string `json:"label"` + Id int `json:"id"` + Label string `json:"label"` + Line int `json:"line,omitempty"` + Column int `json:"column,omitempty"` + EndLine int `json:"endLine,omitempty"` + EndColumn int `json:"endColumn,omitempty"` } -// GotoTarget: A GotoTarget describes a code location that can be used as a target in the 'goto' request. -// The possible goto targets can be determined via the 'gotoTargets' request. +// GotoTarget: A `GotoTarget` describes a code location that can be used as a target in the `goto` request. +// The possible goto targets can be determined via the `gotoTargets` request. type GotoTarget struct { Id int `json:"id"` Label string `json:"label"` @@ -1860,11 +1901,12 @@ type GotoTarget struct { InstructionPointerReference string `json:"instructionPointerReference,omitempty"` } -// CompletionItem: CompletionItems are the suggestions returned from the CompletionsRequest. +// CompletionItem: `CompletionItems` are the suggestions returned from the `completions` request. type CompletionItem struct { Label string `json:"label"` Text string `json:"text,omitempty"` SortText string `json:"sortText,omitempty"` + Detail string `json:"detail,omitempty"` Type CompletionItemType `json:"type,omitempty"` Start int `json:"start,omitempty"` Length int `json:"length,omitempty"` @@ -1902,13 +1944,13 @@ type StackFrameFormat struct { IncludeAll bool `json:"includeAll,omitempty"` } -// ExceptionFilterOptions: An ExceptionFilterOptions is used to specify an exception filter together with a condition for the setExceptionsFilter request. +// ExceptionFilterOptions: An `ExceptionFilterOptions` is used to specify an exception filter together with a condition for the `setExceptionBreakpoints` request. type ExceptionFilterOptions struct { FilterId string `json:"filterId"` Condition string `json:"condition,omitempty"` } -// ExceptionOptions: An ExceptionOptions assigns configuration options to a set of exceptions. +// ExceptionOptions: An `ExceptionOptions` assigns configuration options to a set of exceptions. type ExceptionOptions struct { Path []ExceptionPathSegment `json:"path,omitempty"` BreakMode ExceptionBreakMode `json:"breakMode"` @@ -1921,9 +1963,8 @@ type ExceptionOptions struct { // userUnhandled: breaks if the exception is not handled by user code. type ExceptionBreakMode string -// ExceptionPathSegment: An ExceptionPathSegment represents a segment in a path that is used to match leafs or nodes in a tree of exceptions. -// If a segment consists of more than one name, it matches the names provided if 'negate' is false or missing or -// it matches anything except the names provided if 'negate' is true. +// ExceptionPathSegment: An `ExceptionPathSegment` represents a segment in a path that is used to match leafs or nodes in a tree of exceptions. +// If a segment consists of more than one name, it matches the names provided if `negate` is false or missing, or it matches anything except the names provided if `negate` is true. type ExceptionPathSegment struct { Negate bool `json:"negate,omitempty"` Names []string `json:"names"` @@ -1941,25 +1982,26 @@ type ExceptionDetails struct { // DisassembledInstruction: Represents a single disassembled instruction. type DisassembledInstruction struct { - Address string `json:"address"` - InstructionBytes string `json:"instructionBytes,omitempty"` - Instruction string `json:"instruction"` - Symbol string `json:"symbol,omitempty"` - Location Source `json:"location,omitempty"` - Line int `json:"line,omitempty"` - Column int `json:"column,omitempty"` - EndLine int `json:"endLine,omitempty"` - EndColumn int `json:"endColumn,omitempty"` -} - -// InvalidatedAreas: Logical areas that can be invalidated by the 'invalidated' event. + Address string `json:"address"` + InstructionBytes string `json:"instructionBytes,omitempty"` + Instruction string `json:"instruction"` + Symbol string `json:"symbol,omitempty"` + Location *Source `json:"location,omitempty"` + Line int `json:"line,omitempty"` + Column int `json:"column,omitempty"` + EndLine int `json:"endLine,omitempty"` + EndColumn int `json:"endColumn,omitempty"` +} + +// InvalidatedAreas: Logical areas that can be invalidated by the `invalidated` event. type InvalidatedAreas string // Mapping of request commands and corresponding struct constructors that // can be passed to json.Unmarshal. var requestCtor = map[string]messageCtor{ - "cancel": func() Message { return &CancelRequest{} }, - "runInTerminal": func() Message { return &RunInTerminalRequest{} }, + "cancel": func() Message { return &CancelRequest{} }, + "runInTerminal": func() Message { return &RunInTerminalRequest{} }, + "startDebugging": func() Message { return &StartDebuggingRequest{} }, "initialize": func() Message { return &InitializeRequest{ Arguments: InitializeRequestArguments{ @@ -2017,6 +2059,7 @@ var requestCtor = map[string]messageCtor{ var responseCtor = map[string]messageCtor{ "cancel": func() Message { return &CancelResponse{} }, "runInTerminal": func() Message { return &RunInTerminalResponse{} }, + "startDebugging": func() Message { return &StartDebuggingResponse{} }, "initialize": func() Message { return &InitializeResponse{} }, "configurationDone": func() Message { return &ConfigurationDoneResponse{} }, "launch": func() Message { return &LaunchResponse{} }, @@ -2081,3 +2124,4 @@ var eventCtor = map[string]messageCtor{ "invalidated": func() Message { return &InvalidatedEvent{} }, "memory": func() Message { return &MemoryEvent{} }, } + \ No newline at end of file diff --git a/vendor/modules.txt b/vendor/modules.txt index 29230a474a..783546ca5a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -22,7 +22,7 @@ github.com/derekparker/trie # github.com/go-delve/liner v1.2.3-0.20220127212407-d32d89dd2a5d ## explicit github.com/go-delve/liner -# github.com/google/go-dap v0.7.0 +# github.com/google/go-dap v0.9.1 ## explicit github.com/google/go-dap # github.com/hashicorp/golang-lru v0.5.4 From 7d8f47674b86c6e8e814dd2d69f85aeac713daaa Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 12 Jun 2023 23:31:31 +0200 Subject: [PATCH 058/114] terminal/starbind: add online help for starlark (#3388) Adds a new starlark builtin 'help' that prints the list of available builtins when called without arguments and help for the specified builtin when passed an argument. The help is autogenerated from godoc comments so it isn't always exactly accurate for starlark (in particular we sometimes refer to the In structs), but it's better than nothing. --- _scripts/gen-starlark-bindings.go | 55 +++++++++++++++++++-- pkg/terminal/starbind/starlark.go | 58 ++++++++++++++++++++++- pkg/terminal/starbind/starlark_mapping.go | 55 ++++++++++++++++++++- 3 files changed, 160 insertions(+), 8 deletions(-) diff --git a/_scripts/gen-starlark-bindings.go b/_scripts/gen-starlark-bindings.go index 25d4c8d55f..7c24e235d5 100644 --- a/_scripts/gen-starlark-bindings.go +++ b/_scripts/gen-starlark-bindings.go @@ -3,6 +3,7 @@ package main import ( "bytes" "fmt" + "go/ast" "go/format" "go/token" "go/types" @@ -99,9 +100,11 @@ type binding struct { argNames []string argTypes []string + + docStr string } -func processServerMethods(serverMethods []*types.Func) []binding { +func processServerMethods(serverMethods []*types.Func, funcDeclByPos map[token.Pos]*ast.FuncDecl) []binding { bindings := make([]binding, len(serverMethods)) for i, fn := range serverMethods { sig, _ := fn.Type().(*types.Signature) @@ -133,6 +136,22 @@ func processServerMethods(serverMethods []*types.Func) []binding { retType = "rpc2.StateOut" } + docStr := "" + + if decl := funcDeclByPos[fn.Pos()]; decl != nil && decl.Doc != nil { + docs := []string{} + for _, cmnt := range decl.Doc.List { + docs = append(docs, strings.TrimPrefix(strings.TrimPrefix(cmnt.Text, "//"), " ")) + } + + // fix name of the function in the first line of the documentation + if fields := strings.SplitN(docs[0], " ", 2); len(fields) == 2 && fields[0] == fn.Name() { + docs[0] = name + " " + fields[1] + } + + docStr = strings.Join(docs, "\n") + } + bindings[i] = binding{ name: name, fn: fn, @@ -140,6 +159,7 @@ func processServerMethods(serverMethods []*types.Func) []binding { retType: retType, argNames: argNames, argTypes: argTypes, + docStr: docStr, } } return bindings @@ -159,8 +179,9 @@ func genMapping(bindings []binding) []byte { fmt.Fprintf(buf, "// DO NOT EDIT: auto-generated using _scripts/gen-starlark-bindings.go\n\n") fmt.Fprintf(buf, "package starbind\n\n") fmt.Fprintf(buf, "import ( \"go.starlark.net/starlark\" \n \"github.com/go-delve/delve/service/api\" \n \"github.com/go-delve/delve/service/rpc2\" \n \"fmt\" )\n\n") - fmt.Fprintf(buf, "func (env *Env) starlarkPredeclare() starlark.StringDict {\n") - fmt.Fprintf(buf, "r := starlark.StringDict{}\n\n") + fmt.Fprintf(buf, "func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {\n") + fmt.Fprintf(buf, "r := starlark.StringDict{}\n") + fmt.Fprintf(buf, "doc := make(map[string]string)\n\n") for _, binding := range bindings { fmt.Fprintf(buf, "r[%q] = starlark.NewBuiltin(%q, func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {", binding.name, binding.name) @@ -209,9 +230,24 @@ func genMapping(bindings []binding) []byte { fmt.Fprintf(buf, "return env.interfaceToStarlarkValue(rpcRet), nil\n") fmt.Fprintf(buf, "})\n") + + // builtin documentation + docstr := new(strings.Builder) + fmt.Fprintf(docstr, "builtin %s(", binding.name) + for i, argname := range binding.argNames { + if i != 0 { + fmt.Fprintf(docstr, ", ") + } + fmt.Fprintf(docstr, argname) + } + fmt.Fprintf(docstr, ")") + if binding.docStr != "" { + fmt.Fprintf(docstr, "\n\n%s", binding.docStr) + } + fmt.Fprintf(buf, "doc[%q] = %q\n", binding.name, docstr.String()) } - fmt.Fprintf(buf, "return r\n") + fmt.Fprintf(buf, "return r, doc\n") fmt.Fprintf(buf, "}\n") return buf.Bytes() @@ -301,14 +337,23 @@ func main() { } var serverMethods []*types.Func + funcDeclByPos := make(map[token.Pos]*ast.FuncDecl) packages.Visit(pkgs, func(pkg *packages.Package) bool { if pkg.PkgPath == "github.com/go-delve/delve/service/rpc2" { serverMethods = getSuitableMethods(pkg.Types, "RPCServer") } + for _, file := range pkg.Syntax { + ast.Inspect(file, func(n ast.Node) bool { + if n, ok := n.(*ast.FuncDecl); ok { + funcDeclByPos[n.Name.Pos()] = n + } + return true + }) + } return true }, nil) - bindings := processServerMethods(serverMethods) + bindings := processServerMethods(serverMethods, funcDeclByPos) switch kind { case "go": diff --git a/pkg/terminal/starbind/starlark.go b/pkg/terminal/starbind/starlark.go index f34335b0e6..2e2360af28 100644 --- a/pkg/terminal/starbind/starlark.go +++ b/pkg/terminal/starbind/starlark.go @@ -6,6 +6,7 @@ import ( "io" "io/ioutil" "runtime" + "sort" "strings" "sync" @@ -28,6 +29,7 @@ const ( dlvContextName = "dlv_context" curScopeBuiltinName = "cur_scope" defaultLoadConfigBuiltinName = "default_load_config" + helpBuiltinName = "help" ) func init() { @@ -71,7 +73,13 @@ func New(ctx Context, out EchoWriter) *Env { // Make the "time" module available to Starlark scripts. starlark.Universe["time"] = startime.Module - env.env = env.starlarkPredeclare() + var doc map[string]string + env.env, doc = env.starlarkPredeclare() + + builtindoc := func(name, args, descr string) { + doc[name] = name + args + "\n\n" + name + " " + descr + } + env.env[dlvCommandBuiltinName] = starlark.NewBuiltin(dlvCommandBuiltinName, func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, err @@ -90,6 +98,8 @@ func New(ctx Context, out EchoWriter) *Env { } return starlark.None, decorateError(thread, err) }) + builtindoc(dlvCommandBuiltinName, "(Command)", "interrupts, continues and steps through the program.") + env.env[readFileBuiltinName] = starlark.NewBuiltin(readFileBuiltinName, func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if len(args) != 1 { return nil, decorateError(thread, fmt.Errorf("wrong number of arguments")) @@ -104,6 +114,8 @@ func New(ctx Context, out EchoWriter) *Env { } return starlark.String(string(buf)), nil }) + builtindoc(readFileBuiltinName, "(Path)", "reads a file.") + env.env[writeFileBuiltinName] = starlark.NewBuiltin(writeFileBuiltinName, func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if len(args) != 2 { return nil, decorateError(thread, fmt.Errorf("wrong number of arguments")) @@ -115,12 +127,56 @@ func New(ctx Context, out EchoWriter) *Env { err := ioutil.WriteFile(string(path), []byte(args[1].String()), 0640) return starlark.None, decorateError(thread, err) }) + builtindoc(writeFileBuiltinName, "(Path, Text)", "writes text to the specified file.") + env.env[curScopeBuiltinName] = starlark.NewBuiltin(curScopeBuiltinName, func(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { return env.interfaceToStarlarkValue(env.ctx.Scope()), nil }) + builtindoc(curScopeBuiltinName, "()", "returns the current scope.") + env.env[defaultLoadConfigBuiltinName] = starlark.NewBuiltin(defaultLoadConfigBuiltinName, func(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { return env.interfaceToStarlarkValue(env.ctx.LoadConfig()), nil }) + builtindoc(defaultLoadConfigBuiltinName, "()", "returns the default load configuration.") + + env.env[helpBuiltinName] = starlark.NewBuiltin(helpBuiltinName, func(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + switch len(args) { + case 0: + fmt.Fprintln(env.out, "Available builtins:") + bins := make([]string, 0, len(env.env)) + for name, value := range env.env { + switch value.(type) { + case *starlark.Builtin: + bins = append(bins, name) + } + } + sort.Strings(bins) + for _, bin := range bins { + fmt.Fprintf(env.out, "\t%s\n", bin) + } + case 1: + switch x := args[0].(type) { + case *starlark.Builtin: + if doc[x.Name()] != "" { + fmt.Fprintf(env.out, "%s\n", doc[x.Name()]) + } else { + fmt.Fprintf(env.out, "no help for builtin %s\n", x.Name()) + } + case *starlark.Function: + fmt.Fprintf(env.out, "user defined function %s\n", x.Name()) + if doc := x.Doc(); doc != "" { + fmt.Fprintln(env.out, doc) + } + default: + fmt.Fprintf(env.out, "no help for object of type %T\n", args[0]) + } + default: + fmt.Fprintln(env.out, "wrong number of arguments ", len(args)) + } + return starlark.None, nil + }) + builtindoc(helpBuiltinName, "(Object)", "prints help for Object.") + return env } diff --git a/pkg/terminal/starbind/starlark_mapping.go b/pkg/terminal/starbind/starlark_mapping.go index ce87f61b19..b2f9d1d517 100644 --- a/pkg/terminal/starbind/starlark_mapping.go +++ b/pkg/terminal/starbind/starlark_mapping.go @@ -9,8 +9,9 @@ import ( "go.starlark.net/starlark" ) -func (env *Env) starlarkPredeclare() starlark.StringDict { +func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) { r := starlark.StringDict{} + doc := make(map[string]string) r["amend_breakpoint"] = starlark.NewBuiltin("amend_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { @@ -42,6 +43,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["amend_breakpoint"] = "builtin amend_breakpoint(Breakpoint)\n\namend_breakpoint allows user to update an existing breakpoint\nfor example to change the information retrieved when the\nbreakpoint is hit or to change, add or remove the break condition.\n\narg.Breakpoint.ID must be a valid breakpoint ID" r["ancestors"] = starlark.NewBuiltin("ancestors", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -88,6 +90,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["ancestors"] = "builtin ancestors(GoroutineID, NumAncestors, Depth)\n\nancestors returns the stacktraces for the ancestors of a goroutine." r["attached_to_existing_process"] = starlark.NewBuiltin("attached_to_existing_process", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -100,6 +103,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["attached_to_existing_process"] = "builtin attached_to_existing_process()\n\nattached_to_existing_process returns whether we attached to a running process or not" r["build_id"] = starlark.NewBuiltin("build_id", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -112,6 +116,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["build_id"] = "builtin build_id()" r["cancel_next"] = starlark.NewBuiltin("cancel_next", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -124,6 +129,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["cancel_next"] = "builtin cancel_next()" r["checkpoint"] = starlark.NewBuiltin("checkpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -154,6 +160,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["checkpoint"] = "builtin checkpoint(Where)" r["clear_breakpoint"] = starlark.NewBuiltin("clear_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -192,6 +199,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["clear_breakpoint"] = "builtin clear_breakpoint(Id, Name)\n\nclear_breakpoint deletes a breakpoint by Name (if Name is not an\nempty string) or by ID." r["clear_checkpoint"] = starlark.NewBuiltin("clear_checkpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -222,6 +230,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["clear_checkpoint"] = "builtin clear_checkpoint(ID)" r["raw_command"] = starlark.NewBuiltin("raw_command", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -295,6 +304,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["raw_command"] = "builtin raw_command(Name, ThreadID, GoroutineID, ReturnInfoLoadConfig, Expr, UnsafeCall)\n\nraw_command interrupts, continues and steps through the program." r["create_breakpoint"] = starlark.NewBuiltin("create_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -349,6 +359,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["create_breakpoint"] = "builtin create_breakpoint(Breakpoint, LocExpr, SubstitutePathRules, Suspended)\n\ncreate_breakpoint creates a new breakpoint. The client is expected to populate `CreateBreakpointIn`\nwith an `api.Breakpoint` struct describing where to set the breakpoint. For more information on\nhow to properly request a breakpoint via the `api.Breakpoint` struct see the documentation for\n`debugger.CreateBreakpoint` here: https://pkg.go.dev/github.com/go-delve/delve/service/debugger#Debugger.CreateBreakpoint." r["create_ebpf_tracepoint"] = starlark.NewBuiltin("create_ebpf_tracepoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -379,6 +390,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["create_ebpf_tracepoint"] = "builtin create_ebpf_tracepoint(FunctionName)" r["create_watchpoint"] = starlark.NewBuiltin("create_watchpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -427,6 +439,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["create_watchpoint"] = "builtin create_watchpoint(Scope, Expr, Type)" r["debug_info_directories"] = starlark.NewBuiltin("debug_info_directories", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -465,6 +478,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["debug_info_directories"] = "builtin debug_info_directories(Set, List)" r["detach"] = starlark.NewBuiltin("detach", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -495,6 +509,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["detach"] = "builtin detach(Kill)\n\ndetach detaches the debugger, optionally killing the process." r["disassemble"] = starlark.NewBuiltin("disassemble", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -551,6 +566,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["disassemble"] = "builtin disassemble(Scope, StartPC, EndPC, Flavour)\n\ndisassemble code.\n\nIf both StartPC and EndPC are non-zero the specified range will be disassembled, otherwise the function containing StartPC will be disassembled.\n\nScope is used to mark the instruction the specified goroutine is stopped at.\n\nDisassemble will also try to calculate the destination address of an absolute indirect CALL if it happens to be the instruction the selected goroutine is stopped at." r["dump_cancel"] = starlark.NewBuiltin("dump_cancel", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -563,6 +579,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["dump_cancel"] = "builtin dump_cancel()\n\ndump_cancel cancels the core dump." r["dump_start"] = starlark.NewBuiltin("dump_start", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -593,6 +610,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["dump_start"] = "builtin dump_start(Destination)\n\ndump_start starts a core dump to arg.Destination." r["dump_wait"] = starlark.NewBuiltin("dump_wait", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -623,6 +641,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["dump_wait"] = "builtin dump_wait(Wait)\n\ndump_wait waits for the core dump to finish or for arg.Wait milliseconds.\nWait == 0 means return immediately.\nReturns the core dump status" r["eval"] = starlark.NewBuiltin("eval", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -674,6 +693,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["eval"] = "builtin eval(Scope, Expr, Cfg)\n\neval returns a variable in the specified context.\n\nSee https://github.com/go-delve/delve/blob/master/Documentation/cli/expr.md\nfor a description of acceptable values of arg.Expr." r["examine_memory"] = starlark.NewBuiltin("examine_memory", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -712,6 +732,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["examine_memory"] = "builtin examine_memory(Address, Length)" r["find_location"] = starlark.NewBuiltin("find_location", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { if err := isCancelled(thread); err != nil { return starlark.None, decorateError(thread, err) @@ -768,6 +789,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict { } return env.interfaceToStarlarkValue(rpcRet), nil }) + doc["find_location"] = "builtin find_location(Scope, Loc, IncludeNonExecutableLines, SubstitutePathRules)\n\nfind_location returns concrete location information described by a location expression.\n\n\tloc ::= : | [:] | // | (+|-) | | *