Skip to content

Commit 5a78e09

Browse files
committed
pkg/compiler: handle string syscall attributes
1 parent b50eb25 commit 5a78e09

File tree

5 files changed

+47
-16
lines changed

5 files changed

+47
-16
lines changed

pkg/compiler/attrs.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const (
1818
// This will facilitate const expressions in e.g. size[] or align[].
1919
intAttr
2020
exprAttr
21+
stringAttr
2122
)
2223

2324
type attrDesc struct {
@@ -80,6 +81,8 @@ func initCallAttrs() {
8081
case reflect.Bool:
8182
case reflect.Uint64:
8283
desc.Type = intAttr
84+
case reflect.String:
85+
desc.Type = stringAttr
8386
default:
8487
panic("unsupported syscall attribute type")
8588
}

pkg/compiler/check.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ func (comp *compiler) checkStructFields(n *ast.Struct, typ, name string) {
209209
prevFieldHadIf := false
210210
for fieldIdx, f := range n.Fields {
211211
if n.IsUnion {
212-
_, exprs := comp.parseAttrs(unionFieldAttrs, f, f.Attrs)
212+
_, exprs, _ := comp.parseAttrs(unionFieldAttrs, f, f.Attrs)
213213
if fieldIdx > 0 && fieldIdx+1 < len(n.Fields) &&
214214
prevFieldHadIf && exprs[attrIf] == nil {
215215
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) {
220220
}
221221
continue
222222
}
223-
attrs, _ := comp.parseAttrs(structFieldAttrs, f, f.Attrs)
223+
attrs, _, _ := comp.parseAttrs(structFieldAttrs, f, f.Attrs)
224224
dirCount := attrs[attrIn] + attrs[attrOut] + attrs[attrInOut]
225225
if dirCount != 0 {
226226
hasDirections = true
@@ -1458,7 +1458,7 @@ func (comp *compiler) checkVarlen(n *ast.Struct) {
14581458
}
14591459
}
14601460
for i, f := range n.Fields {
1461-
_, exprs := comp.parseAttrs(structOrUnionFieldAttrs(n), f, f.Attrs)
1461+
_, exprs, _ := comp.parseAttrs(structOrUnionFieldAttrs(n), f, f.Attrs)
14621462
if !n.IsUnion && i == len(n.Fields)-1 {
14631463
break
14641464
}

pkg/compiler/compiler.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -210,53 +210,57 @@ func (comp *compiler) structIsVarlen(name string) bool {
210210

211211
func (comp *compiler) parseIntAttrs(descs map[string]*attrDesc, parent ast.Node,
212212
attrs []*ast.Type) map[*attrDesc]uint64 {
213-
intAttrs, _ := comp.parseAttrs(descs, parent, attrs)
213+
intAttrs, _, _ := comp.parseAttrs(descs, parent, attrs)
214214
return intAttrs
215215
}
216216

217217
func (comp *compiler) parseAttrs(descs map[string]*attrDesc, parent ast.Node, attrs []*ast.Type) (
218-
map[*attrDesc]uint64, map[*attrDesc]prog.Expression) {
218+
map[*attrDesc]uint64, map[*attrDesc]prog.Expression, map[*attrDesc]string) {
219219
_, parentType, parentName := parent.Info()
220220
resInt := make(map[*attrDesc]uint64)
221221
resExpr := make(map[*attrDesc]prog.Expression)
222+
resString := make(map[*attrDesc]string)
222223
for _, attr := range attrs {
223224
if unexpected, _, ok := checkTypeKind(attr, kindIdent); !ok {
224225
comp.error(attr.Pos, "unexpected %v, expect attribute", unexpected)
225-
return resInt, resExpr
226+
return resInt, resExpr, resString
226227
}
227228
if len(attr.Colon) != 0 {
228229
comp.error(attr.Colon[0].Pos, "unexpected ':'")
229-
return resInt, resExpr
230+
return resInt, resExpr, resString
230231
}
231232
desc := descs[attr.Ident]
232233
if desc == nil {
233234
comp.error(attr.Pos, "unknown %v %v attribute %v", parentType, parentName, attr.Ident)
234-
return resInt, resExpr
235+
return resInt, resExpr, resString
235236
}
236237
_, dupInt := resInt[desc]
237238
_, dupExpr := resExpr[desc]
238-
if dupInt || dupExpr {
239+
_, dupString := resString[desc]
240+
if dupInt || dupExpr || dupString {
239241
comp.error(attr.Pos, "duplicate %v %v attribute %v", parentType, parentName, attr.Ident)
240-
return resInt, resExpr
242+
return resInt, resExpr, resString
241243
}
242244

243245
switch desc.Type {
244246
case flagAttr:
245247
resInt[desc] = 1
246248
if len(attr.Args) != 0 {
247249
comp.error(attr.Pos, "%v attribute has args", attr.Ident)
248-
return nil, nil
250+
return nil, nil, nil
249251
}
250252
case intAttr:
251253
resInt[desc] = comp.parseAttrIntArg(attr)
252254
case exprAttr:
253255
resExpr[desc] = comp.parseAttrExprArg(attr)
256+
case stringAttr:
257+
resString[desc] = comp.parseAttrStringArg(attr)
254258
default:
255259
comp.error(attr.Pos, "attribute %v has unknown type", attr.Ident)
256-
return nil, nil
260+
return nil, nil, nil
257261
}
258262
}
259-
return resInt, resExpr
263+
return resInt, resExpr, resString
260264
}
261265

262266
func (comp *compiler) parseAttrExprArg(attr *ast.Type) prog.Expression {
@@ -289,6 +293,19 @@ func (comp *compiler) parseAttrIntArg(attr *ast.Type) uint64 {
289293
return sz.Value
290294
}
291295

296+
func (comp *compiler) parseAttrStringArg(attr *ast.Type) string {
297+
if len(attr.Args) != 1 {
298+
comp.error(attr.Pos, "%v attribute is expected to have 1 argument", attr.Ident)
299+
return ""
300+
}
301+
arg := attr.Args[0]
302+
if !arg.HasString {
303+
comp.error(attr.Pos, "%v argument must be a string", attr.Ident)
304+
return ""
305+
}
306+
return arg.String
307+
}
308+
292309
func (comp *compiler) getTypeDesc(t *ast.Type) *typeDesc {
293310
if desc := builtinTypes[t.Ident]; desc != nil {
294311
return desc

pkg/compiler/gen.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ func (comp *compiler) genSyscall(n *ast.Call, argSizes []uint64) *prog.Syscall {
132132
ret = comp.genType(n.Ret, comp.ptrSize)
133133
}
134134
var attrs prog.SyscallAttrs
135-
descAttrs := comp.parseIntAttrs(callAttrs, n, n.Attrs)
136-
for desc, val := range descAttrs {
135+
intAttrs, _, stringAttrs := comp.parseAttrs(callAttrs, n, n.Attrs)
136+
for desc, val := range intAttrs {
137137
fld := reflect.ValueOf(&attrs).Elem().FieldByName(desc.Name)
138138
switch desc.Type {
139139
case intAttr:
@@ -144,6 +144,15 @@ func (comp *compiler) genSyscall(n *ast.Call, argSizes []uint64) *prog.Syscall {
144144
panic(fmt.Sprintf("unexpected attrDesc type: %q", desc.Type))
145145
}
146146
}
147+
for desc, val := range stringAttrs {
148+
fld := reflect.ValueOf(&attrs).Elem().FieldByName(desc.Name)
149+
switch desc.Type {
150+
case stringAttr:
151+
fld.SetString(val)
152+
default:
153+
panic(fmt.Sprintf("unexpected attrDesc type: %q", desc.Type))
154+
}
155+
}
147156
fields, _ := comp.genFieldArray(n.Args, argSizes)
148157
return &prog.Syscall{
149158
Name: n.Name.Name,
@@ -513,7 +522,7 @@ func (comp *compiler) genFieldDir(attrs map[*attrDesc]uint64) (prog.Dir, bool) {
513522
}
514523

515524
func (comp *compiler) genField(f *ast.Field, argSize uint64, overlayDir prog.Dir) prog.Field {
516-
intAttrs, exprAttrs := comp.parseAttrs(structFieldAttrs, f, f.Attrs)
525+
intAttrs, exprAttrs, _ := comp.parseAttrs(structFieldAttrs, f, f.Attrs)
517526
dir, hasDir := overlayDir, true
518527
if overlayDir == prog.DirInOut {
519528
dir, hasDir = comp.genFieldDir(intAttrs)

sys/syz-sysgen/sysgen.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ func generateExecutorSyscalls(target *targets.Target, syscalls []*prog.Syscall,
312312
}
313313
case reflect.Uint64:
314314
val = attr.Uint()
315+
case reflect.String:
316+
continue
315317
default:
316318
panic("unsupported syscall attribute type")
317319
}

0 commit comments

Comments
 (0)