aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorFlorent Revest <revest@chromium.org>2024-11-28 01:49:47 +0100
committerAleksandr Nogikh <nogikh@google.com>2024-12-09 18:35:48 +0000
commit07e46fbc2bd7ff8782c975596672e4e3d3891865 (patch)
treee5b5faf3f3225f930127716f3242b31b667dd36d /pkg
parent9ac0fdc66500475f1914254ef369b32d51adbff9 (diff)
pkg/compiler: handle string syscall attributes
Diffstat (limited to 'pkg')
-rw-r--r--pkg/compiler/attrs.go3
-rw-r--r--pkg/compiler/check.go6
-rw-r--r--pkg/compiler/compiler.go37
-rw-r--r--pkg/compiler/gen.go15
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)