Upgrade containerd/cgroups to remove github.com/cilium/ebpf's fuzzer
The fuzzer is broken and it breaks OSS-Fuzz according to #7288. Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
This commit is contained in:
319
vendor/github.com/cilium/ebpf/btf/format.go
generated
vendored
Normal file
319
vendor/github.com/cilium/ebpf/btf/format.go
generated
vendored
Normal file
@@ -0,0 +1,319 @@
|
||||
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)
|
||||
}
|
||||
|
||||
switch v := skipQualifiers(typ).(type) {
|
||||
case *Enum:
|
||||
fmt.Fprintf(&gf.w, "type %s ", name)
|
||||
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:
|
||||
return fmt.Errorf("%s: invalid enum size %d", typ, v.Size)
|
||||
}
|
||||
|
||||
if len(v.Values) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
gf.w.WriteString("; const ( ")
|
||||
for _, ev := range v.Values {
|
||||
id := gf.enumIdentifier(name, ev.Name)
|
||||
fmt.Fprintf(&gf.w, "%s %s = %d; ", id, name, ev.Value)
|
||||
}
|
||||
gf.w.WriteString(")")
|
||||
|
||||
return nil
|
||||
|
||||
default:
|
||||
fmt.Fprintf(&gf.w, "type %s ", name)
|
||||
return gf.writeTypeLit(v, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// 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:
|
||||
gf.writeIntLit(v)
|
||||
|
||||
case *Enum:
|
||||
gf.w.WriteString("int32")
|
||||
|
||||
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) {
|
||||
// NB: Encoding.IsChar is ignored.
|
||||
if i.Encoding.IsBool() && i.Size == 1 {
|
||||
gf.w.WriteString("bool")
|
||||
return
|
||||
}
|
||||
|
||||
bits := i.Size * 8
|
||||
if i.Encoding.IsSigned() {
|
||||
fmt.Fprintf(&gf.w, "int%d", bits)
|
||||
} else {
|
||||
fmt.Fprintf(&gf.w, "uint%d", bits)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
size, err := Sizeof(m.Type)
|
||||
if err != nil {
|
||||
return fmt.Errorf("field %d: %w", i, err)
|
||||
}
|
||||
prevOffset = offset + uint32(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 := vsi.Type.(*Var)
|
||||
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}
|
||||
}
|
||||
Reference in New Issue
Block a user