diff options
| author | Florent Revest <revest@chromium.org> | 2024-11-28 01:49:47 +0100 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2024-12-09 18:35:48 +0000 |
| commit | 07e46fbc2bd7ff8782c975596672e4e3d3891865 (patch) | |
| tree | e5b5faf3f3225f930127716f3242b31b667dd36d /pkg/compiler | |
| parent | 9ac0fdc66500475f1914254ef369b32d51adbff9 (diff) | |
pkg/compiler: handle string syscall attributes
Diffstat (limited to 'pkg/compiler')
| -rw-r--r-- | pkg/compiler/attrs.go | 3 | ||||
| -rw-r--r-- | pkg/compiler/check.go | 6 | ||||
| -rw-r--r-- | pkg/compiler/compiler.go | 37 | ||||
| -rw-r--r-- | pkg/compiler/gen.go | 15 |
4 files changed, 45 insertions, 16 deletions
diff --git a/pkg/compiler/attrs.go b/pkg/compiler/attrs.go index 197093b50..ba877caf6 100644 --- a/pkg/compiler/attrs.go +++ b/pkg/compiler/attrs.go @@ -18,6 +18,7 @@ const ( // This will facilitate const expressions in e.g. size[] or align[]. intAttr exprAttr + stringAttr ) type attrDesc struct { @@ -80,6 +81,8 @@ func initCallAttrs() { case reflect.Bool: case reflect.Uint64: desc.Type = intAttr + case reflect.String: + desc.Type = stringAttr default: panic("unsupported syscall attribute type") } diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go index d693fa790..92e3e5e03 100644 --- a/pkg/compiler/check.go +++ b/pkg/compiler/check.go @@ -209,7 +209,7 @@ func (comp *compiler) checkStructFields(n *ast.Struct, typ, name string) { prevFieldHadIf := false for fieldIdx, f := range n.Fields { if n.IsUnion { - _, exprs := comp.parseAttrs(unionFieldAttrs, f, f.Attrs) + _, exprs, _ := comp.parseAttrs(unionFieldAttrs, f, f.Attrs) if fieldIdx > 0 && fieldIdx+1 < len(n.Fields) && prevFieldHadIf && exprs[attrIf] == nil { comp.error(f.Pos, "either no fields have conditions or all except the last") @@ -220,7 +220,7 @@ func (comp *compiler) checkStructFields(n *ast.Struct, typ, name string) { } continue } - attrs, _ := comp.parseAttrs(structFieldAttrs, f, f.Attrs) + attrs, _, _ := comp.parseAttrs(structFieldAttrs, f, f.Attrs) dirCount := attrs[attrIn] + attrs[attrOut] + attrs[attrInOut] if dirCount != 0 { hasDirections = true @@ -1458,7 +1458,7 @@ func (comp *compiler) checkVarlen(n *ast.Struct) { } } for i, f := range n.Fields { - _, exprs := comp.parseAttrs(structOrUnionFieldAttrs(n), f, f.Attrs) + _, exprs, _ := comp.parseAttrs(structOrUnionFieldAttrs(n), f, f.Attrs) if !n.IsUnion && i == len(n.Fields)-1 { break } diff --git a/pkg/compiler/compiler.go b/pkg/compiler/compiler.go index 978255219..fa23ce6bf 100644 --- a/pkg/compiler/compiler.go +++ b/pkg/compiler/compiler.go @@ -210,34 +210,36 @@ func (comp *compiler) structIsVarlen(name string) bool { func (comp *compiler) parseIntAttrs(descs map[string]*attrDesc, parent ast.Node, attrs []*ast.Type) map[*attrDesc]uint64 { - intAttrs, _ := comp.parseAttrs(descs, parent, attrs) + intAttrs, _, _ := comp.parseAttrs(descs, parent, attrs) return intAttrs } func (comp *compiler) parseAttrs(descs map[string]*attrDesc, parent ast.Node, attrs []*ast.Type) ( - map[*attrDesc]uint64, map[*attrDesc]prog.Expression) { + map[*attrDesc]uint64, map[*attrDesc]prog.Expression, map[*attrDesc]string) { _, parentType, parentName := parent.Info() resInt := make(map[*attrDesc]uint64) resExpr := make(map[*attrDesc]prog.Expression) + resString := make(map[*attrDesc]string) for _, attr := range attrs { if unexpected, _, ok := checkTypeKind(attr, kindIdent); !ok { comp.error(attr.Pos, "unexpected %v, expect attribute", unexpected) - return resInt, resExpr + return resInt, resExpr, resString } if len(attr.Colon) != 0 { comp.error(attr.Colon[0].Pos, "unexpected ':'") - return resInt, resExpr + return resInt, resExpr, resString } desc := descs[attr.Ident] if desc == nil { comp.error(attr.Pos, "unknown %v %v attribute %v", parentType, parentName, attr.Ident) - return resInt, resExpr + return resInt, resExpr, resString } _, dupInt := resInt[desc] _, dupExpr := resExpr[desc] - if dupInt || dupExpr { + _, dupString := resString[desc] + if dupInt || dupExpr || dupString { comp.error(attr.Pos, "duplicate %v %v attribute %v", parentType, parentName, attr.Ident) - return resInt, resExpr + return resInt, resExpr, resString } switch desc.Type { @@ -245,18 +247,20 @@ func (comp *compiler) parseAttrs(descs map[string]*attrDesc, parent ast.Node, at resInt[desc] = 1 if len(attr.Args) != 0 { comp.error(attr.Pos, "%v attribute has args", attr.Ident) - return nil, nil + return nil, nil, nil } case intAttr: resInt[desc] = comp.parseAttrIntArg(attr) case exprAttr: resExpr[desc] = comp.parseAttrExprArg(attr) + case stringAttr: + resString[desc] = comp.parseAttrStringArg(attr) default: comp.error(attr.Pos, "attribute %v has unknown type", attr.Ident) - return nil, nil + return nil, nil, nil } } - return resInt, resExpr + return resInt, resExpr, resString } func (comp *compiler) parseAttrExprArg(attr *ast.Type) prog.Expression { @@ -289,6 +293,19 @@ func (comp *compiler) parseAttrIntArg(attr *ast.Type) uint64 { return sz.Value } +func (comp *compiler) parseAttrStringArg(attr *ast.Type) string { + if len(attr.Args) != 1 { + comp.error(attr.Pos, "%v attribute is expected to have 1 argument", attr.Ident) + return "" + } + arg := attr.Args[0] + if !arg.HasString { + comp.error(attr.Pos, "%v argument must be a string", attr.Ident) + return "" + } + return arg.String +} + func (comp *compiler) getTypeDesc(t *ast.Type) *typeDesc { if desc := builtinTypes[t.Ident]; desc != nil { return desc diff --git a/pkg/compiler/gen.go b/pkg/compiler/gen.go index a6fd938a9..fb803875a 100644 --- a/pkg/compiler/gen.go +++ b/pkg/compiler/gen.go @@ -132,8 +132,8 @@ func (comp *compiler) genSyscall(n *ast.Call, argSizes []uint64) *prog.Syscall { ret = comp.genType(n.Ret, comp.ptrSize) } var attrs prog.SyscallAttrs - descAttrs := comp.parseIntAttrs(callAttrs, n, n.Attrs) - for desc, val := range descAttrs { + intAttrs, _, stringAttrs := comp.parseAttrs(callAttrs, n, n.Attrs) + for desc, val := range intAttrs { fld := reflect.ValueOf(&attrs).Elem().FieldByName(desc.Name) switch desc.Type { case intAttr: @@ -144,6 +144,15 @@ func (comp *compiler) genSyscall(n *ast.Call, argSizes []uint64) *prog.Syscall { panic(fmt.Sprintf("unexpected attrDesc type: %q", desc.Type)) } } + for desc, val := range stringAttrs { + fld := reflect.ValueOf(&attrs).Elem().FieldByName(desc.Name) + switch desc.Type { + case stringAttr: + fld.SetString(val) + default: + panic(fmt.Sprintf("unexpected attrDesc type: %q", desc.Type)) + } + } fields, _ := comp.genFieldArray(n.Args, argSizes) return &prog.Syscall{ Name: n.Name.Name, @@ -513,7 +522,7 @@ func (comp *compiler) genFieldDir(attrs map[*attrDesc]uint64) (prog.Dir, bool) { } func (comp *compiler) genField(f *ast.Field, argSize uint64, overlayDir prog.Dir) prog.Field { - intAttrs, exprAttrs := comp.parseAttrs(structFieldAttrs, f, f.Attrs) + intAttrs, exprAttrs, _ := comp.parseAttrs(structFieldAttrs, f, f.Attrs) dir, hasDir := overlayDir, true if overlayDir == prog.DirInOut { dir, hasDir = comp.genFieldDir(intAttrs) |
