in auditbeat/tracing/tracefs.go [252:362]
func (dfs *TraceFS) LoadProbeFormat(probe Probe) (format ProbeFormat, err error) {
path := filepath.Join(dfs.basePath, "events", probe.EffectiveGroup(), probe.Name, "format")
file, err := os.Open(path)
if err != nil {
return format, err
}
defer file.Close()
format.Probe = probe
format.Fields = make(map[string]Field)
scanner := bufio.NewScanner(file)
parseFormat := false
for scanner.Scan() {
line := scanner.Text()
if !parseFormat {
// Parse the header
parts := strings.SplitN(line, ": ", 2)
switch {
case len(parts) == 2 && parts[0] == "ID":
if format.ID, err = strconv.Atoi(parts[1]); err != nil {
return format, err
}
case len(parts) == 1 && parts[0] == "format:":
parseFormat = true
}
} else {
// Parse the fields
// Ends on the first line that doesn't start with a TAB
if len(line) > 0 && line[0] != '\t' && line[0] != ' ' {
break
}
// Find all "<key>:<value>;" matches
// The actual format is:
// "\tfield:%s %s;\toffset:%u;\tsize:%u;\tsigned:%d;\n"
var f Field
matches := formatRegexp.FindAllStringSubmatch(line, -1)
if len(matches) != 4 {
continue
}
for _, match := range matches {
if len(match) != 3 {
continue
}
key, value := match[1], match[2]
switch key {
case "field":
fparts := strings.Split(value, " ")
n := len(fparts)
if n < 2 {
return format, fmt.Errorf("bad format for kprobe '%s': `field` has no type: %s", probe.String(), value)
}
fparts, f.Name = fparts[:n-1], fparts[n-1]
typeIdx, isDataLoc := -1, false
for idx, part := range fparts {
switch part {
case "signed", "unsigned":
// ignore
case "__data_loc":
isDataLoc = true
default:
if typeIdx != -1 {
return format, fmt.Errorf("bad format for kprobe '%s': unknown parameter=`%s` in type=`%s`", probe.String(), part, value)
}
typeIdx = idx
}
}
if typeIdx == -1 {
return format, fmt.Errorf("bad format for kprobe '%s': type not found in `%s`", probe.String(), value)
}
intLen, isInt := integerTypes[fparts[typeIdx]]
if isInt {
f.Type = FieldTypeInteger
f.Size = int(intLen)
} else {
if fparts[typeIdx] != "char[]" || !isDataLoc {
return format, fmt.Errorf("bad format for kprobe '%s': unsupported type in `%s`", probe.String(), value)
}
f.Type = FieldTypeString
}
case "offset":
f.Offset, err = strconv.Atoi(value)
if err != nil {
return format, err
}
case "size":
prev := f.Size
f.Size, err = strconv.Atoi(value)
if err != nil {
return format, err
}
if prev != 0 && prev != f.Size {
return format, fmt.Errorf("bad format for kprobe '%s': int field length mismatch at `%s`", probe.String(), line)
}
case "signed":
f.Signed = len(value) > 0 && value[0] == '1'
}
}
if f.Type == FieldTypeString && f.Size != 4 {
return format, fmt.Errorf("bad format for kprobe '%s': unexpected size for string in `%s`", probe.String(), line)
}
format.Fields[f.Name] = f
}
}
return format, nil
}