Repository: cilium/ebpf
Pull request #195 (2021-01-18 17:32:34)

bpf2go: rework the generated API
cmd/bpf2go: rework the generated API
    
    After working with the API generated by bpf2go for a bit, I think
    there are some improvements to be made:
    
    * Fields have "Program" and "Map" prefixes to avoid name collisions,
      which leads to repetitive typing. From what I can tell most ELFs
      don't have name collisions, so we make the API less nice because
      of an uncommon problem.
    * The API forces loading all maps and programs, even if the user is
      only interested in all maps or programs or a subset.
    * There is too much code generated.
    * The generated code is undocumented.
    
    The first two points are addressed by splitting the "container"
    structs into smaller structs that only contain programs or maps.
    Using Go struct embedding we have a lot of flexibility how to
    compose the types. Embedding also means we remove the "Map" and
    "Program" field prefixes, since name collisions are handled by
    the Go compiler. Finally, reduce the generated API surface to
    two functions:
    
    * loadExampleSpec(): this only parses the embedded ELF and then
      gives the user access to a CollectionSpec. This is intended
      for complicated use cases that need custom logic during loading.
    * loadExampleObjects(): this parses the ELF and calls LoadAndAssign
      on the result. This is intended for simple / common use cases
      that we can cover by extending CollectionOptions.
    
    Finally, add a little bit of documentation to the generated functions.

collection: merge Assign and LoadAndAssign
    
    The two function are basically identical now that LoadAndAssign does
    lazy loading. Merge the two functions into one that can assign both
    *ProgramSpec and *Program, etc.

collection: support embedded structs in Assign
    
    Allow using embedded structs when assigning maps and programs from
    a collection. For example:
    
        type maps struct {
            Bar *ebpf.Map `ebpf:"bar"`
        }
    
        var objs struct {
            maps
            Prog *ebpf.Program `ebpf:"prog"`
        }
    
        collection.Assign(&objs)
    
    This is useful for separating out maps and programs, since they tend
    to have different lifetimes: programs are loaded, attached and then
    discarded. Maps stick around, since they are used to communicate with
    the program.


lmb: @ti-mo @florianl feel free to remove yourselves if you don't have time to review the PR, I just wanted to make sure to include you in case you're using bpf2go somewhere.
lmb: The PR fails on Go 1.14, it seems like the semantics of `reflect` have changed. Nothing obvious in the release notes though.
lmb: It's probably this: https://github.com/golang/go/issues/32772#issue-460489872
ti-mo: Currently not using bpf2go, so have too little context, but the synopsis makes sense. :+1: 
lmb: Thanks for taking a look :) I'm currently mulling over whether to remove `SectionRodata` and friends. There isn't a need for them anymore, so removing them for now would give us flexibility in the future..

Patch:
diff --git a/cmd/bpf2go/example_bpfeb.go b/cmd/bpf2go/example_bpfeb.go
index 883124e..f5e7af5 100644
--- a/cmd/bpf2go/example_bpfeb.go
+++ b/cmd/bpf2go/example_bpfeb.go
@@ -11,56 +11,100 @@ import (
 	"github.com/cilium/ebpf"
 )
 
-type exampleSpecs struct {
-	ProgramFilter *ebpf.ProgramSpec `ebpf:"filter"`
-}
-
-func newExampleSpecs() (*exampleSpecs, error) {
+// loadExample returns the embedded CollectionSpec for example.
+func loadExample() (*ebpf.CollectionSpec, error) {
 	reader := bytes.NewReader(_ExampleBytes)
 	spec, err := ebpf.LoadCollectionSpecFromReader(reader)
 	if err != nil {
 		return nil, fmt.Errorf("can't load example: %w", err)
 	}
 
-	specs := new(exampleSpecs)
-	if err := spec.Assign(specs); err != nil {
-		return nil, fmt.Errorf("can't assign example: %w", err)
+	return spec, err
+}
+
+// loadExampleObjects loads example and converts it into a struct.
+//
+// The following types are suitable as obj argument:
+//
+//     *exampleObjects
+//     *examplePrograms
+//     *exampleMaps
+//
+// See ebpf.CollectionSpec.LoadAndAssign documentation for details.
+func loadExampleObjects(obj interface{}, opts *ebpf.CollectionOptions) error {
+	spec, err := loadExample()
+	if err != nil {
+		return err
 	}
 
-	return specs, nil
+	return spec.LoadAndAssign(obj, opts)
 }
 
-func (s *exampleSpecs) CollectionSpec() *ebpf.CollectionSpec {
-	return &ebpf.CollectionSpec{
-		Programs: map[string]*ebpf.ProgramSpec{
-			"filter": s.ProgramFilter,
-		},
-		Maps: map[string]*ebpf.MapSpec{},
-	}
+// exampleSpecs contains maps and programs before they are loaded into the kernel.
+//
+// It can be passed ebpf.CollectionSpec.Assign.
+type exampleSpecs struct {
+	exampleProgramSpecs
+	exampleMapSpecs
 }
 
-func (s *exampleSpecs) Load(opts *ebpf.CollectionOptions) (*exampleObjects, error) {
-	var objs exampleObjects
-	if err := s.CollectionSpec().LoadAndAssign(&objs, opts); err != nil {
-		return nil, err
-	}
-	return &objs, nil
+// exampleSpecs contains programs before they are loaded into the kernel.
+//
+// It can be passed ebpf.CollectionSpec.Assign.
+type exampleProgramSpecs struct {
+	Filter *ebpf.ProgramSpec `ebpf:"filter"`
 }
 
-func (s *exampleSpecs) Copy() *exampleSpecs {
-	return &exampleSpecs{
-		ProgramFilter: s.ProgramFilter.Copy(),
-	}
+// exampleMapSpecs contains maps before they are loaded into the kernel.
+//
+// It can be passed ebpf.CollectionSpec.Assign.
+type exampleMapSpecs struct {
+	Map1 *ebpf.MapSpec `ebpf:"map1"`
 }
 
+// exampleObjects contains all objects after they have been loaded into the kernel.
+//
+// It can be passed to loadExampleObjects or ebpf.CollectionSpec.LoadAndAssign.
 type exampleObjects struct {
-	ProgramFilter *ebpf.Program `ebpf:"filter"`
+	examplePrograms
+	exampleMaps
 }
 
 func (o *exampleObjects) Close() error {
-	for _, closer := range []io.Closer{
-		o.ProgramFilter,
-	} {
+	return _ExampleClose(
+		&o.examplePrograms,
+		&o.exampleMaps,
+	)
+}
+
+// exampleMaps contains all maps after they have been loaded into the kernel.
+//
+// It can be passed to loadExampleObjects or ebpf.CollectionSpec.LoadAndAssign.
+type exampleMaps struct {
+	Map1 *ebpf.Map `ebpf:"map1"`
+}
+
+func (m *exampleMaps) Close() error {
+	return _ExampleClose(
+		m.Map1,
+	)
+}
+
+// examplePrograms contains all programs after they have been loaded into the kernel.
+//
+// It can be passed to loadExampleObjects or ebpf.CollectionSpec.LoadAndAssign.
+type examplePrograms struct {
+	Filter *ebpf.Program `ebpf:"filter"`
+}
+
+func (p *examplePrograms) Close() error {
+	return _ExampleClose(
+		p.Filter,
+	)
+}
+
+func _ExampleClose(closers ...io.Closer) error {
+	for _, closer := range closers {
 		if err := closer.Close(); err != nil {
 			return err
 		}
@@ -69,4 +113,4 @@ func (o *exampleObjects) Close() error {
 }
 
 // Do not access this directly.
-var _ExampleBytes = []byte("\x7f\x45\x4c\x46\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xf7\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\xb0\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x40\x00\x14\x00\x01\xb7\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00\x00\x00\x00\x00\x00\x4d\x49\x54\x00\x00\x74\x65\x73\x74\x64\x61\x74\x61\x2f\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x2e\x00\x5f\x5f\x6c\x69\x63\x65\x6e\x73\x65\x00\x63\x68\x61\x72\x00\x5f\x5f\x41\x52\x52\x41\x59\x5f\x53\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\x00\x66\x69\x6c\x74\x65\x72\x00\x69\x6e\x74\x00\x01\x11\x01\x25\x0e\x13\x05\x03\x0e\x10\x17\x1b\x0e\x11\x01\x12\x06\x00\x00\x02\x34\x00\x03\x0e\x49\x13\x3f\x19\x3a\x0b\x3b\x0b\x02\x18\x00\x00\x03\x01\x01\x49\x13\x00\x00\x04\x21\x00\x49\x13\x37\x0b\x00\x00\x05\x24\x00\x03\x0e\x3e\x0b\x0b\x0b\x00\x00\x06\x24\x00\x03\x0e\x0b\x0b\x3e\x0b\x00\x00\x07\x2e\x00\x11\x01\x12\x06\x40\x18\x03\x0e\x3a\x0b\x3b\x0b\x49\x13\x3f\x19\x00\x00\x00\x00\x00\x00\x76\x00\x04\x00\x00\x00\x00\x08\x01\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x02\x00\x00\x00\x00\x00\x00\x00\x3f\x01\x03\x09\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x4b\x04\x00\x00\x00\x52\x04\x00\x05\x00\x00\x00\x00\x06\x01\x06\x00\x00\x00\x00\x08\x07\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x01\x5a\x00\x00\x00\x00\x01\x05\x00\x00\x00\x72\x05\x00\x00\x00\x00\x05\x04\x00\x00\xeb\x9f\x01\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x88\x00\x00\x00\x88\x00\x00\x00\x5e\x00\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x20\x00\x00\x00\x05\x0c\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x33\x01\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x08\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\x38\x01\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x20\x00\x00\x00\x4c\x0e\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x56\x0f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x04\x00\x69\x6e\x74\x00\x66\x69\x6c\x74\x65\x72\x00\x73\x6f\x63\x6b\x65\x74\x00\x2e\x2f\x74\x65\x73\x74\x64\x61\x74\x61\x2f\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x09\x72\x65\x74\x75\x72\x6e\x20\x30\x3b\x00\x63\x68\x61\x72\x00\x5f\x5f\x41\x52\x52\x41\x59\x5f\x53\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\x00\x5f\x5f\x6c\x69\x63\x65\x6e\x73\x65\x00\x6c\x69\x63\x65\x6e\x73\x65\x00\xeb\x9f\x01\x00\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x1c\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x10\x00\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x28\x00\x00\x18\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\xff\xff\xff\xff\x04\x00\x08\x00\x08\x7c\x0b\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x45\x00\x04\x00\x00\x00\x2a\x08\x01\x01\xfb\x0e\x0d\x00\x01\x01\x01\x01\x00\x00\x00\x01\x00\x00\x01\x74\x65\x73\x74\x64\x61\x74\x61\x00\x00\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x01\x00\x00\x00\x00\x09\x02\x00\x00\x00\x00\x00\x00\x00\x00\x16\x05\x02\x0a\x13\x02\x02\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\x04\x00\xff\xf1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x39\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x11\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x34\x12\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x0b\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x03\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x0d\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x04\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x0a\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x2b\x00\x00\x00\x05\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x37\x00\x00\x00\x0e\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x4c\x00\x00\x00\x06\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x53\x00\x00\x00\x07\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x5a\x00\x00\x00\x0a\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x68\x00\x00\x00\x08\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x73\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x98\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x0c\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x0a\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x37\x00\x00\x00\x0a\x00\x00\x00\x01\x0f\x0e\x00\x2e\x64\x65\x62\x75\x67\x5f\x61\x62\x62\x72\x65\x76\x00\x2e\x74\x65\x78\x74\x00\x2e\x72\x65\x6c\x2e\x42\x54\x46\x2e\x65\x78\x74\x00\x73\x6f\x63\x6b\x65\x74\x00\x2e\x64\x65\x62\x75\x67\x5f\x73\x74\x72\x00\x66\x69\x6c\x74\x65\x72\x00\x2e\x64\x65\x62\x75\x67\x5f\x6d\x61\x63\x69\x6e\x66\x6f\x00\x2e\x72\x65\x6c\x2e\x64\x65\x62\x75\x67\x5f\x69\x6e\x66\x6f\x00\x2e\x6c\x6c\x76\x6d\x5f\x61\x64\x64\x72\x73\x69\x67\x00\x5f\x5f\x6c\x69\x63\x65\x6e\x73\x65\x00\x2e\x72\x65\x6c\x2e\x64\x65\x62\x75\x67\x5f\x6c\x69\x6e\x65\x00\x2e\x72\x65\x6c\x2e\x64\x65\x62\x75\x67\x5f\x66\x72\x61\x6d\x65\x00\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x2e\x73\x74\x72\x74\x61\x62\x00\x2e\x73\x79\x6d\x74\x61\x62\x00\x2e\x72\x65\x6c\x2e\x42\x54\x46\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\xfa\x00\x00\x00\x00\x00\x00\x00\xb6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x22\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6a\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x50\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x29\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4e\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4a\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\xc8\x00\x00\x00\x00\x00\x00\x00\xd0\x00\x00\x00\x13\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x3b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x72\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x73\x00\x00\x00\x00\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x98\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x13\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x19\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x71\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\xa8\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x13\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x86\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xd0\x00\x00\x00\x00\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\xc8\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x13\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x76\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xf8\x00\x00\x00\x00\x00\x00\x00\x49\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x72\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\xe8\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x13\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x5a\x6f\xff\x4c\x03\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\xf8\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x48\x00\x00\x00\x00\x00\x00\x01\x80\x00\x00\x00\x01\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x18")
+var _ExampleBytes = []byte("\x7f\x45\x4c\x46\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xf7\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x10\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x40\x00\x15\x00\x01\xb7\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00\x00\x00\x00\x00\x00\x4d\x49\x54\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00\x00\x74\x65\x73\x74\x64\x61\x74\x61\x2f\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x2e\x00\x5f\x5f\x6c\x69\x63\x65\x6e\x73\x65\x00\x63\x68\x61\x72\x00\x5f\x5f\x41\x52\x52\x41\x59\x5f\x53\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\x00\x6d\x61\x70\x31\x00\x74\x79\x70\x65\x00\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\x00\x6b\x65\x79\x5f\x73\x69\x7a\x65\x00\x76\x61\x6c\x75\x65\x5f\x73\x69\x7a\x65\x00\x6d\x61\x78\x5f\x65\x6e\x74\x72\x69\x65\x73\x00\x6d\x61\x70\x5f\x66\x6c\x61\x67\x73\x00\x62\x70\x66\x5f\x6d\x61\x70\x5f\x64\x65\x66\x00\x66\x69\x6c\x74\x65\x72\x00\x69\x6e\x74\x00\x01\x11\x01\x25\x0e\x13\x05\x03\x0e\x10\x17\x1b\x0e\x11\x01\x12\x06\x00\x00\x02\x34\x00\x03\x0e\x49\x13\x3f\x19\x3a\x0b\x3b\x0b\x02\x18\x00\x00\x03\x01\x01\x49\x13\x00\x00\x04\x21\x00\x49\x13\x37\x0b\x00\x00\x05\x24\x00\x03\x0e\x3e\x0b\x0b\x0b\x00\x00\x06\x24\x00\x03\x0e\x0b\x0b\x3e\x0b\x00\x00\x07\x13\x01\x03\x0e\x0b\x0b\x3a\x0b\x3b\x0b\x00\x00\x08\x0d\x00\x03\x0e\x49\x13\x3a\x0b\x3b\x0b\x38\x0b\x00\x00\x09\x2e\x00\x11\x01\x12\x06\x40\x18\x03\x0e\x3a\x0b\x3b\x0b\x49\x13\x3f\x19\x00\x00\x00\x00\x00\x00\xd7\x00\x04\x00\x00\x00\x00\x08\x01\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x02\x00\x00\x00\x00\x00\x00\x00\x3f\x01\x03\x09\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x4b\x04\x00\x00\x00\x52\x04\x00\x05\x00\x00\x00\x00\x06\x01\x06\x00\x00\x00\x00\x08\x07\x02\x00\x00\x00\x00\x00\x00\x00\x6e\x01\x05\x09\x03\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x14\x02\x14\x08\x00\x00\x00\x00\x00\x00\x00\xb3\x02\x15\x00\x08\x00\x00\x00\x00\x00\x00\x00\xb3\x02\x16\x04\x08\x00\x00\x00\x00\x00\x00\x00\xb3\x02\x17\x08\x08\x00\x00\x00\x00\x00\x00\x00\xb3\x02\x18\x0c\x08\x00\x00\x00\x00\x00\x00\x00\xb3\x02\x19\x10\x00\x05\x00\x00\x00\x00\x07\x04\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x01\x5a\x00\x00\x00\x00\x01\x0c\x00\x00\x00\xd3\x05\x00\x00\x00\x00\x05\x04\x00\x00\xeb\x9f\x01\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x01\x08\x00\x00\x01\x08\x00\x00\x00\xb0\x00\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x20\x00\x00\x00\x05\x0c\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x33\x01\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x08\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\x38\x01\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x20\x00\x00\x00\x4c\x0e\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x56\x04\x00\x00\x05\x00\x00\x00\x14\x00\x00\x00\x62\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x67\x00\x00\x00\x09\x00\x00\x00\x20\x00\x00\x00\x70\x00\x00\x00\x09\x00\x00\x00\x40\x00\x00\x00\x7b\x00\x00\x00\x09\x00\x00\x00\x60\x00\x00\x00\x87\x00\x00\x00\x09\x00\x00\x00\x80\x00\x00\x00\x91\x01\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x20\x00\x00\x00\x9e\x0e\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00\xa3\x0f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\xab\x0f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x14\x00\x69\x6e\x74\x00\x66\x69\x6c\x74\x65\x72\x00\x73\x6f\x63\x6b\x65\x74\x00\x2e\x2f\x74\x65\x73\x74\x64\x61\x74\x61\x2f\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x09\x72\x65\x74\x75\x72\x6e\x20\x30\x3b\x00\x63\x68\x61\x72\x00\x5f\x5f\x41\x52\x52\x41\x59\x5f\x53\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\x00\x5f\x5f\x6c\x69\x63\x65\x6e\x73\x65\x00\x62\x70\x66\x5f\x6d\x61\x70\x5f\x64\x65\x66\x00\x74\x79\x70\x65\x00\x6b\x65\x79\x5f\x73\x69\x7a\x65\x00\x76\x61\x6c\x75\x65\x5f\x73\x69\x7a\x65\x00\x6d\x61\x78\x5f\x65\x6e\x74\x72\x69\x65\x73\x00\x6d\x61\x70\x5f\x66\x6c\x61\x67\x73\x00\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\x00\x6d\x61\x70\x31\x00\x6c\x69\x63\x65\x6e\x73\x65\x00\x6d\x61\x70\x73\x00\xeb\x9f\x01\x00\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x1c\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x10\x00\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x28\x00\x00\x34\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\xff\xff\xff\xff\x04\x00\x08\x00\x08\x7c\x0b\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x6e\x00\x04\x00\x00\x00\x51\x08\x01\x01\xfb\x0e\x0d\x00\x01\x01\x01\x01\x00\x00\x00\x01\x00\x00\x01\x74\x65\x73\x74\x64\x61\x74\x61\x00\x74\x65\x73\x74\x64\x61\x74\x61\x2f\x2e\x2e\x2f\x2e\x2e\x2f\x2e\x2e\x2f\x74\x65\x73\x74\x64\x61\x74\x61\x00\x00\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x01\x00\x00\x63\x6f\x6d\x6d\x6f\x6e\x2e\x68\x00\x02\x00\x00\x00\x00\x09\x02\x00\x00\x00\x00\x00\x00\x00\x00\x03\x0b\x01\x05\x02\x0a\x13\x02\x02\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\x04\x00\xff\xf1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x39\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x43\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x59\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x86\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6d\x11\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x39\x12\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\xbb\x11\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x13\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x03\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x15\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x04\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x12\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x2b\x00\x00\x00\x05\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x37\x00\x00\x00\x16\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x4c\x00\x00\x00\x06\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x53\x00\x00\x00\x07\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x5a\x00\x00\x00\x08\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x66\x00\x00\x00\x18\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x6f\x00\x00\x00\x0f\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x77\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x83\x00\x00\x00\x0b\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x00\x00\x0c\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x9b\x00\x00\x00\x0d\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\xa7\x00\x00\x00\x0e\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\xb4\x00\x00\x00\x0a\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\xbb\x00\x00\x00\x12\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xc9\x00\x00\x00\x10\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\xd4\x00\x00\x00\x11\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x18\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x12\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x5e\x00\x00\x00\x12\x00\x00\x00\x01\x17\x16\x18\x00\x2e\x64\x65\x62\x75\x67\x5f\x61\x62\x62\x72\x65\x76\x00\x2e\x74\x65\x78\x74\x00\x2e\x72\x65\x6c\x2e\x42\x54\x46\x2e\x65\x78\x74\x00\x73\x6f\x63\x6b\x65\x74\x00\x6d\x61\x70\x73\x00\x2e\x64\x65\x62\x75\x67\x5f\x73\x74\x72\x00\x66\x69\x6c\x74\x65\x72\x00\x2e\x64\x65\x62\x75\x67\x5f\x6d\x61\x63\x69\x6e\x66\x6f\x00\x2e\x72\x65\x6c\x2e\x64\x65\x62\x75\x67\x5f\x69\x6e\x66\x6f\x00\x2e\x6c\x6c\x76\x6d\x5f\x61\x64\x64\x72\x73\x69\x67\x00\x5f\x5f\x6c\x69\x63\x65\x6e\x73\x65\x00\x2e\x72\x65\x6c\x2e\x64\x65\x62\x75\x67\x5f\x6c\x69\x6e\x65\x00\x2e\x72\x65\x6c\x2e\x64\x65\x62\x75\x67\x5f\x66\x72\x61\x6d\x65\x00\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x2e\x73\x74\x72\x74\x61\x62\x00\x2e\x73\x79\x6d\x74\x61\x62\x00\x2e\x72\x65\x6c\x2e\x42\x54\x46\x00\x6d\x61\x70\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x4b\x00\x00\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x22\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6f\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x50\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x29\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2e\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x00\x00\x00\x00\x00\x00\x00\x91\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9\x00\x00\x00\x00\x00\x00\x00\x7c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x53\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x75\x00\x00\x00\x00\x00\x00\x00\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4f\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x78\x00\x00\x00\x00\x00\x00\x01\x60\x00\x00\x00\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x40\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x50\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb6\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x51\x00\x00\x00\x00\x00\x00\x01\xd0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\xd8\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x14\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x19\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x21\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\xf8\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x14\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x8b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x80\x00\x00\x00\x00\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x18\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x14\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x7b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\xa8\x00\x00\x00\x00\x00\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x38\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x14\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x5f\x6f\xff\x4c\x03\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x48\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x00\x00\x00\x02\x58\x00\x00\x00\x01\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x18")
diff --git a/cmd/bpf2go/example_bpfel.go b/cmd/bpf2go/example_bpfel.go
index 5e95604..aa2036c 100644
--- a/cmd/bpf2go/example_bpfel.go
+++ b/cmd/bpf2go/example_bpfel.go
@@ -11,56 +11,100 @@ import (
 	"github.com/cilium/ebpf"
 )
 
-type exampleSpecs struct {
-	ProgramFilter *ebpf.ProgramSpec `ebpf:"filter"`
-}
-
-func newExampleSpecs() (*exampleSpecs, error) {
+// loadExample returns the embedded CollectionSpec for example.
+func loadExample() (*ebpf.CollectionSpec, error) {
 	reader := bytes.NewReader(_ExampleBytes)
 	spec, err := ebpf.LoadCollectionSpecFromReader(reader)
 	if err != nil {
 		return nil, fmt.Errorf("can't load example: %w", err)
 	}
 
-	specs := new(exampleSpecs)
-	if err := spec.Assign(specs); err != nil {
-		return nil, fmt.Errorf("can't assign example: %w", err)
+	return spec, err
+}
+
+// loadExampleObjects loads example and converts it into a struct.
+//
+// The following types are suitable as obj argument:
+//
+//     *exampleObjects
+//     *examplePrograms
+//     *exampleMaps
+//
+// See ebpf.CollectionSpec.LoadAndAssign documentation for details.
+func loadExampleObjects(obj interface{}, opts *ebpf.CollectionOptions) error {
+	spec, err := loadExample()
+	if err != nil {
+		return err
 	}
 
-	return specs, nil
+	return spec.LoadAndAssign(obj, opts)
 }
 
-func (s *exampleSpecs) CollectionSpec() *ebpf.CollectionSpec {
-	return &ebpf.CollectionSpec{
-		Programs: map[string]*ebpf.ProgramSpec{
-			"filter": s.ProgramFilter,
-		},
-		Maps: map[string]*ebpf.MapSpec{},
-	}
+// exampleSpecs contains maps and programs before they are loaded into the kernel.
+//
+// It can be passed ebpf.CollectionSpec.Assign.
+type exampleSpecs struct {
+	exampleProgramSpecs
+	exampleMapSpecs
 }
 
-func (s *exampleSpecs) Load(opts *ebpf.CollectionOptions) (*exampleObjects, error) {
-	var objs exampleObjects
-	if err := s.CollectionSpec().LoadAndAssign(&objs, opts); err != nil {
-		return nil, err
-	}
-	return &objs, nil
+// exampleSpecs contains programs before they are loaded into the kernel.
+//
+// It can be passed ebpf.CollectionSpec.Assign.
+type exampleProgramSpecs struct {
+	Filter *ebpf.ProgramSpec `ebpf:"filter"`
 }
 
-func (s *exampleSpecs) Copy() *exampleSpecs {
-	return &exampleSpecs{
-		ProgramFilter: s.ProgramFilter.Copy(),
-	}
+// exampleMapSpecs contains maps before they are loaded into the kernel.
+//
+// It can be passed ebpf.CollectionSpec.Assign.
+type exampleMapSpecs struct {
+	Map1 *ebpf.MapSpec `ebpf:"map1"`
 }
 
+// exampleObjects contains all objects after they have been loaded into the kernel.
+//
+// It can be passed to loadExampleObjects or ebpf.CollectionSpec.LoadAndAssign.
 type exampleObjects struct {
-	ProgramFilter *ebpf.Program `ebpf:"filter"`
+	examplePrograms
+	exampleMaps
 }
 
 func (o *exampleObjects) Close() error {
-	for _, closer := range []io.Closer{
-		o.ProgramFilter,
-	} {
+	return _ExampleClose(
+		&o.examplePrograms,
+		&o.exampleMaps,
+	)
+}
+
+// exampleMaps contains all maps after they have been loaded into the kernel.
+//
+// It can be passed to loadExampleObjects or ebpf.CollectionSpec.LoadAndAssign.
+type exampleMaps struct {
+	Map1 *ebpf.Map `ebpf:"map1"`
+}
+
+func (m *exampleMaps) Close() error {
+	return _ExampleClose(
+		m.Map1,
+	)
+}
+
+// examplePrograms contains all programs after they have been loaded into the kernel.
+//
+// It can be passed to loadExampleObjects or ebpf.CollectionSpec.LoadAndAssign.
+type examplePrograms struct {
+	Filter *ebpf.Program `ebpf:"filter"`
+}
+
+func (p *examplePrograms) Close() error {
+	return _ExampleClose(
+		p.Filter,
+	)
+}
+
+func _ExampleClose(closers ...io.Closer) error {
+	for _, closer := range closers {
 		if err := closer.Close(); err != nil {
 			return err
 		}
@@ -69,4 +113,4 @@ func (o *exampleObjects) Close() error {
 }
 
 // Do not access this directly.
-var _ExampleBytes = []byte("\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xf7\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x40\x00\x14\x00\x01\x00\xb7\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00\x00\x00\x00\x00\x00\x4d\x49\x54\x00\x00\x74\x65\x73\x74\x64\x61\x74\x61\x2f\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x2e\x00\x5f\x5f\x6c\x69\x63\x65\x6e\x73\x65\x00\x63\x68\x61\x72\x00\x5f\x5f\x41\x52\x52\x41\x59\x5f\x53\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\x00\x66\x69\x6c\x74\x65\x72\x00\x69\x6e\x74\x00\x01\x11\x01\x25\x0e\x13\x05\x03\x0e\x10\x17\x1b\x0e\x11\x01\x12\x06\x00\x00\x02\x34\x00\x03\x0e\x49\x13\x3f\x19\x3a\x0b\x3b\x0b\x02\x18\x00\x00\x03\x01\x01\x49\x13\x00\x00\x04\x21\x00\x49\x13\x37\x0b\x00\x00\x05\x24\x00\x03\x0e\x3e\x0b\x0b\x0b\x00\x00\x06\x24\x00\x03\x0e\x0b\x0b\x3e\x0b\x00\x00\x07\x2e\x00\x11\x01\x12\x06\x40\x18\x03\x0e\x3a\x0b\x3b\x0b\x49\x13\x3f\x19\x00\x00\x00\x76\x00\x00\x00\x04\x00\x00\x00\x00\x00\x08\x01\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x02\x00\x00\x00\x00\x3f\x00\x00\x00\x01\x03\x09\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x4b\x00\x00\x00\x04\x52\x00\x00\x00\x04\x00\x05\x00\x00\x00\x00\x06\x01\x06\x00\x00\x00\x00\x08\x07\x07\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x01\x5a\x00\x00\x00\x00\x01\x05\x72\x00\x00\x00\x05\x00\x00\x00\x00\x05\x04\x00\x00\x9f\xeb\x01\x00\x18\x00\x00\x00\x00\x00\x00\x00\x88\x00\x00\x00\x88\x00\x00\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x04\x00\x00\x00\x20\x00\x00\x01\x05\x00\x00\x00\x00\x00\x00\x0c\x01\x00\x00\x00\x33\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x08\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\x38\x00\x00\x00\x00\x00\x00\x01\x04\x00\x00\x00\x20\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x00\x0e\x05\x00\x00\x00\x01\x00\x00\x00\x56\x00\x00\x00\x01\x00\x00\x0f\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x69\x6e\x74\x00\x66\x69\x6c\x74\x65\x72\x00\x73\x6f\x63\x6b\x65\x74\x00\x2e\x2f\x74\x65\x73\x74\x64\x61\x74\x61\x2f\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x09\x72\x65\x74\x75\x72\x6e\x20\x30\x3b\x00\x63\x68\x61\x72\x00\x5f\x5f\x41\x52\x52\x41\x59\x5f\x53\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\x00\x5f\x5f\x6c\x69\x63\x65\x6e\x73\x65\x00\x6c\x69\x63\x65\x6e\x73\x65\x00\x9f\xeb\x01\x00\x28\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x1c\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x10\x00\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x28\x00\x00\x00\x02\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\xff\xff\xff\xff\x04\x00\x08\x00\x08\x7c\x0b\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x45\x00\x00\x00\x04\x00\x2a\x00\x00\x00\x08\x01\x01\xfb\x0e\x0d\x00\x01\x01\x01\x01\x00\x00\x00\x01\x00\x00\x01\x74\x65\x73\x74\x64\x61\x74\x61\x00\x00\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x01\x00\x00\x00\x00\x09\x02\x00\x00\x00\x00\x00\x00\x00\x00\x16\x05\x02\x0a\x13\x02\x02\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\x00\x00\x00\x04\x00\xf1\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x39\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x00\x00\x00\x11\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x34\x00\x00\x00\x12\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x03\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x0d\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x04\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x0a\x00\x00\x00\x2b\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x05\x00\x00\x00\x37\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x0e\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x06\x00\x00\x00\x53\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x07\x00\x00\x00\x5a\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x0a\x00\x00\x00\x68\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x08\x00\x00\x00\x73\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x09\x00\x00\x00\x98\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x0c\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x0a\x00\x00\x00\x37\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x0a\x00\x00\x00\x0f\x0e\x00\x2e\x64\x65\x62\x75\x67\x5f\x61\x62\x62\x72\x65\x76\x00\x2e\x74\x65\x78\x74\x00\x2e\x72\x65\x6c\x2e\x42\x54\x46\x2e\x65\x78\x74\x00\x73\x6f\x63\x6b\x65\x74\x00\x2e\x64\x65\x62\x75\x67\x5f\x73\x74\x72\x00\x66\x69\x6c\x74\x65\x72\x00\x2e\x64\x65\x62\x75\x67\x5f\x6d\x61\x63\x69\x6e\x66\x6f\x00\x2e\x72\x65\x6c\x2e\x64\x65\x62\x75\x67\x5f\x69\x6e\x66\x6f\x00\x2e\x6c\x6c\x76\x6d\x5f\x61\x64\x64\x72\x73\x69\x67\x00\x5f\x5f\x6c\x69\x63\x65\x6e\x73\x65\x00\x2e\x72\x65\x6c\x2e\x64\x65\x62\x75\x67\x5f\x6c\x69\x6e\x65\x00\x2e\x72\x65\x6c\x2e\x64\x65\x62\x75\x67\x5f\x66\x72\x61\x6d\x65\x00\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x2e\x73\x74\x72\x74\x61\x62\x00\x2e\x73\x79\x6d\x74\x61\x62\x00\x2e\x72\x65\x6c\x2e\x42\x54\x46\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x05\x00\x00\x00\x00\x00\x00\xb6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x22\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6a\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x50\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x29\x00\x00\x00\x01\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4e\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4a\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x04\x00\x00\x00\x00\x00\x00\xd0\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x3b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x72\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x01\x00\x00\x00\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\x05\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x0a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x71\x02\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8\x05\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x0c\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x86\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x02\x00\x00\x00\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x05\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x0e\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x76\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x02\x00\x00\x00\x00\x00\x00\x49\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x72\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x05\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x10\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x5a\x00\x00\x00\x03\x4c\xff\x6f\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x05\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x03\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x0e\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00")
+var _ExampleBytes = []byte("\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xf7\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x40\x00\x15\x00\x01\x00\xb7\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00\x00\x00\x00\x00\x00\x4d\x49\x54\x00\x01\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x74\x65\x73\x74\x64\x61\x74\x61\x2f\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x2e\x00\x5f\x5f\x6c\x69\x63\x65\x6e\x73\x65\x00\x63\x68\x61\x72\x00\x5f\x5f\x41\x52\x52\x41\x59\x5f\x53\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\x00\x6d\x61\x70\x31\x00\x74\x79\x70\x65\x00\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\x00\x6b\x65\x79\x5f\x73\x69\x7a\x65\x00\x76\x61\x6c\x75\x65\x5f\x73\x69\x7a\x65\x00\x6d\x61\x78\x5f\x65\x6e\x74\x72\x69\x65\x73\x00\x6d\x61\x70\x5f\x66\x6c\x61\x67\x73\x00\x62\x70\x66\x5f\x6d\x61\x70\x5f\x64\x65\x66\x00\x66\x69\x6c\x74\x65\x72\x00\x69\x6e\x74\x00\x01\x11\x01\x25\x0e\x13\x05\x03\x0e\x10\x17\x1b\x0e\x11\x01\x12\x06\x00\x00\x02\x34\x00\x03\x0e\x49\x13\x3f\x19\x3a\x0b\x3b\x0b\x02\x18\x00\x00\x03\x01\x01\x49\x13\x00\x00\x04\x21\x00\x49\x13\x37\x0b\x00\x00\x05\x24\x00\x03\x0e\x3e\x0b\x0b\x0b\x00\x00\x06\x24\x00\x03\x0e\x0b\x0b\x3e\x0b\x00\x00\x07\x13\x01\x03\x0e\x0b\x0b\x3a\x0b\x3b\x0b\x00\x00\x08\x0d\x00\x03\x0e\x49\x13\x3a\x0b\x3b\x0b\x38\x0b\x00\x00\x09\x2e\x00\x11\x01\x12\x06\x40\x18\x03\x0e\x3a\x0b\x3b\x0b\x49\x13\x3f\x19\x00\x00\x00\xd7\x00\x00\x00\x04\x00\x00\x00\x00\x00\x08\x01\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x02\x00\x00\x00\x00\x3f\x00\x00\x00\x01\x03\x09\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x4b\x00\x00\x00\x04\x52\x00\x00\x00\x04\x00\x05\x00\x00\x00\x00\x06\x01\x06\x00\x00\x00\x00\x08\x07\x02\x00\x00\x00\x00\x6e\x00\x00\x00\x01\x05\x09\x03\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x14\x02\x14\x08\x00\x00\x00\x00\xb3\x00\x00\x00\x02\x15\x00\x08\x00\x00\x00\x00\xb3\x00\x00\x00\x02\x16\x04\x08\x00\x00\x00\x00\xb3\x00\x00\x00\x02\x17\x08\x08\x00\x00\x00\x00\xb3\x00\x00\x00\x02\x18\x0c\x08\x00\x00\x00\x00\xb3\x00\x00\x00\x02\x19\x10\x00\x05\x00\x00\x00\x00\x07\x04\x09\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x01\x5a\x00\x00\x00\x00\x01\x0c\xd3\x00\x00\x00\x05\x00\x00\x00\x00\x05\x04\x00\x00\x9f\xeb\x01\x00\x18\x00\x00\x00\x00\x00\x00\x00\x08\x01\x00\x00\x08\x01\x00\x00\xb0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x04\x00\x00\x00\x20\x00\x00\x01\x05\x00\x00\x00\x00\x00\x00\x0c\x01\x00\x00\x00\x33\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x08\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\x38\x00\x00\x00\x00\x00\x00\x01\x04\x00\x00\x00\x20\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x00\x0e\x05\x00\x00\x00\x01\x00\x00\x00\x56\x00\x00\x00\x05\x00\x00\x04\x14\x00\x00\x00\x62\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x67\x00\x00\x00\x09\x00\x00\x00\x20\x00\x00\x00\x70\x00\x00\x00\x09\x00\x00\x00\x40\x00\x00\x00\x7b\x00\x00\x00\x09\x00\x00\x00\x60\x00\x00\x00\x87\x00\x00\x00\x09\x00\x00\x00\x80\x00\x00\x00\x91\x00\x00\x00\x00\x00\x00\x01\x04\x00\x00\x00\x20\x00\x00\x00\x9e\x00\x00\x00\x00\x00\x00\x0e\x08\x00\x00\x00\x01\x00\x00\x00\xa3\x00\x00\x00\x01\x00\x00\x0f\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\xab\x00\x00\x00\x01\x00\x00\x0f\x00\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x69\x6e\x74\x00\x66\x69\x6c\x74\x65\x72\x00\x73\x6f\x63\x6b\x65\x74\x00\x2e\x2f\x74\x65\x73\x74\x64\x61\x74\x61\x2f\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x09\x72\x65\x74\x75\x72\x6e\x20\x30\x3b\x00\x63\x68\x61\x72\x00\x5f\x5f\x41\x52\x52\x41\x59\x5f\x53\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\x00\x5f\x5f\x6c\x69\x63\x65\x6e\x73\x65\x00\x62\x70\x66\x5f\x6d\x61\x70\x5f\x64\x65\x66\x00\x74\x79\x70\x65\x00\x6b\x65\x79\x5f\x73\x69\x7a\x65\x00\x76\x61\x6c\x75\x65\x5f\x73\x69\x7a\x65\x00\x6d\x61\x78\x5f\x65\x6e\x74\x72\x69\x65\x73\x00\x6d\x61\x70\x5f\x66\x6c\x61\x67\x73\x00\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\x00\x6d\x61\x70\x31\x00\x6c\x69\x63\x65\x6e\x73\x65\x00\x6d\x61\x70\x73\x00\x9f\xeb\x01\x00\x28\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x1c\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x10\x00\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x28\x00\x00\x00\x02\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\xff\xff\xff\xff\x04\x00\x08\x00\x08\x7c\x0b\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x00\x00\x04\x00\x51\x00\x00\x00\x08\x01\x01\xfb\x0e\x0d\x00\x01\x01\x01\x01\x00\x00\x00\x01\x00\x00\x01\x74\x65\x73\x74\x64\x61\x74\x61\x00\x74\x65\x73\x74\x64\x61\x74\x61\x2f\x2e\x2e\x2f\x2e\x2e\x2f\x2e\x2e\x2f\x74\x65\x73\x74\x64\x61\x74\x61\x00\x00\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x01\x00\x00\x63\x6f\x6d\x6d\x6f\x6e\x2e\x68\x00\x02\x00\x00\x00\x00\x09\x02\x00\x00\x00\x00\x00\x00\x00\x00\x03\x0b\x01\x05\x02\x0a\x13\x02\x02\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\x00\x00\x00\x04\x00\xf1\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x39\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x43\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x59\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x7a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x86\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x8d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x00\x00\x11\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x39\x00\x00\x00\x12\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\xbb\x00\x00\x00\x11\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x13\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x03\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x15\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x04\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x2b\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x05\x00\x00\x00\x37\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x16\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x06\x00\x00\x00\x53\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x07\x00\x00\x00\x5a\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x08\x00\x00\x00\x66\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x18\x00\x00\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x0f\x00\x00\x00\x77\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x09\x00\x00\x00\x83\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x8f\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x0c\x00\x00\x00\x9b\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x0d\x00\x00\x00\xa7\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x0e\x00\x00\x00\xb4\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x0a\x00\x00\x00\xbb\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\xc9\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x10\x00\x00\x00\xd4\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x11\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x18\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x14\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x17\x16\x18\x00\x2e\x64\x65\x62\x75\x67\x5f\x61\x62\x62\x72\x65\x76\x00\x2e\x74\x65\x78\x74\x00\x2e\x72\x65\x6c\x2e\x42\x54\x46\x2e\x65\x78\x74\x00\x73\x6f\x63\x6b\x65\x74\x00\x6d\x61\x70\x73\x00\x2e\x64\x65\x62\x75\x67\x5f\x73\x74\x72\x00\x66\x69\x6c\x74\x65\x72\x00\x2e\x64\x65\x62\x75\x67\x5f\x6d\x61\x63\x69\x6e\x66\x6f\x00\x2e\x72\x65\x6c\x2e\x64\x65\x62\x75\x67\x5f\x69\x6e\x66\x6f\x00\x2e\x6c\x6c\x76\x6d\x5f\x61\x64\x64\x72\x73\x69\x67\x00\x5f\x5f\x6c\x69\x63\x65\x6e\x73\x65\x00\x2e\x72\x65\x6c\x2e\x64\x65\x62\x75\x67\x5f\x6c\x69\x6e\x65\x00\x2e\x72\x65\x6c\x2e\x64\x65\x62\x75\x67\x5f\x66\x72\x61\x6d\x65\x00\x6d\x69\x6e\x69\x6d\x61\x6c\x2e\x63\x00\x2e\x73\x74\x72\x74\x61\x62\x00\x2e\x73\x79\x6d\x74\x61\x62\x00\x2e\x72\x65\x6c\x2e\x42\x54\x46\x00\x6d\x61\x70\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4b\x09\x00\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x22\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6f\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x50\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x29\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2e\x00\x00\x00\x01\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x00\x00\x00\x00\x00\x00\x00\x91\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9\x00\x00\x00\x00\x00\x00\x00\x7c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x53\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x01\x00\x00\x00\x00\x00\x00\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4f\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x78\x07\x00\x00\x00\x00\x00\x00\x60\x01\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x50\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb6\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x51\x02\x00\x00\x00\x00\x00\x00\xd0\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x08\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x0b\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x21\x04\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x08\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x0d\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x8b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x04\x00\x00\x00\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x09\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x0f\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x7b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8\x04\x00\x00\x00\x00\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x38\x09\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x11\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x03\x4c\xff\x6f\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x09\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x05\x00\x00\x00\x00\x00\x00\x58\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x16\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00")
diff --git a/cmd/bpf2go/output.go b/cmd/bpf2go/output.go
index 642793f..938a622 100644
--- a/cmd/bpf2go/output.go
+++ b/cmd/bpf2go/output.go
@@ -31,111 +31,112 @@ import (
 	"{{ .Module }}"
 )
 
-type {{ .Name.Specs }} struct {
-{{- range $name, $_ := .Programs }}
-	Program{{ identifier $name }} *ebpf.ProgramSpec {{ tag $name }}
-{{- end }}
-
-{{- range $name, $_ := .Maps }}
-	Map{{ identifier $name }} *ebpf.MapSpec {{ tag $name }}
-{{- end }}
-
-{{- range $name, $_ := .Sections }}
-	Section{{ identifier $name }} *ebpf.MapSpec {{ tag $name }}
-{{- end }}
-}
-
-func {{ .Name.NewSpecs }}() (*{{ .Name.Specs }}, error) {
+// {{ .Name.Load }} returns the embedded CollectionSpec for {{ .Name }}.
+func {{ .Name.Load }}() (*ebpf.CollectionSpec, error) {
 	reader := bytes.NewReader({{ .Name.Bytes }})
 	spec, err := ebpf.LoadCollectionSpecFromReader(reader)
 	if err != nil {
 		return nil, fmt.Errorf("can't load {{ .Name }}: %w", err)
 	}
 
-	specs := new({{ .Name.Specs }})
-	if err := spec.Assign(specs); err != nil {
-		return nil, fmt.Errorf("can't assign {{ .Name }}: %w", err)
-	}
-
-	return specs, nil
+	return spec, err
 }
 
-func (s *{{ .Name.Specs }}) CollectionSpec() *ebpf.CollectionSpec {
-	return &ebpf.CollectionSpec{
-		Programs: map[string]*ebpf.ProgramSpec{
-{{- range $name, $_ := .Programs }}
-			"{{ $name }}": s.Program{{ identifier $name }},
-{{- end }}
-		},
-		Maps: map[string]*ebpf.MapSpec{
-{{- range $name, $_ := .Maps }}
-			"{{ $name }}": s.Map{{ identifier $name }},
-{{- end }}
-{{- range $name, $_ := .Sections }}
-			"{{ $name }}": s.Section{{ identifier $name }},
-{{- end }}
-		},
+// {{ .Name.LoadObjects }} loads {{ .Name }} and converts it into a struct.
+//
+// The following types are suitable as obj argument:
+//
+//     *{{ .Name.Objects }}
+//     *{{ .Name.Programs }}
+//     *{{ .Name.Maps }}
+//
+// See ebpf.CollectionSpec.LoadAndAssign documentation for details.
+func {{ .Name.LoadObjects }}(obj interface{}, opts *ebpf.CollectionOptions) (error) {
+	spec, err := {{ .Name.Load }}()
+	if err != nil {
+		return err
 	}
-}
 
-func (s *{{ .Name.Specs }}) Load(opts *ebpf.CollectionOptions) (*{{ .Name.Objects }}, error) {
-	var objs {{ .Name.Objects }}
-	if err := s.CollectionSpec().LoadAndAssign(&objs, opts); err != nil {
-		return nil, err
-	}
-	return &objs, nil
+	return spec.LoadAndAssign(obj, opts)
 }
 
-func (s *{{ .Name.Specs }}) Copy() *{{ .Name.Specs }} {
-	return &{{ .Name.Specs }}{
-{{- range $name, $_ := .Programs }}
-{{- with $id := identifier $name }}
-		Program{{ $id }}: s.Program{{ $id }}.Copy(),
-{{- end }}
-{{- end }}
+// {{ .Name.Specs }} contains maps and programs before they are loaded into the kernel.
+//
+// It can be passed ebpf.CollectionSpec.Assign.
+type {{ .Name.Specs }} struct {
+	{{ .Name.ProgramSpecs }}
+	{{ .Name.MapSpecs }}
+}
 
-{{- range $name, $_ := .Maps }}
-{{- with $id := identifier $name }}
-		Map{{ $id }}: s.Map{{ $id }}.Copy(),
-{{- end }}
+// {{ .Name.Specs }} contains programs before they are loaded into the kernel.
+//
+// It can be passed ebpf.CollectionSpec.Assign.
+type {{ .Name.ProgramSpecs }} struct {
+{{- range $name, $id := .Programs }}
+	{{ $id }} *ebpf.ProgramSpec {{ tag $name }}
 {{- end }}
+}
 
-{{- range $name, $_ := .Sections }}
-{{- with $id := identifier $name }}
-		Section{{ $id }}: s.Section{{ $id }}.Copy(),
-{{- end }}
+// {{ .Name.MapSpecs }} contains maps before they are loaded into the kernel.
+//
+// It can be passed ebpf.CollectionSpec.Assign.
+type {{ .Name.MapSpecs }} struct {
+{{- range $name, $id := .Maps }}
+	{{ $id }} *ebpf.MapSpec {{ tag $name }}
 {{- end }}
-	}
 }
 
+// {{ .Name.Objects }} contains all objects after they have been loaded into the kernel.
+//
+// It can be passed to {{ .Name.LoadObjects }} or ebpf.CollectionSpec.LoadAndAssign.
 type {{ .Name.Objects }} struct {
-{{- range $name, $_ := .Programs }}
-	Program{{ identifier $name }} *ebpf.Program {{ tag $name }}
-{{- end }}
+	{{ .Name.Programs }}
+	{{ .Name.Maps }}
+}
 
-{{- range $name, $_ := .Maps }}
-	Map{{ identifier $name }} *ebpf.Map {{ tag $name }}
-{{- end }}
+func (o *{{ .Name.Objects }}) Close() error {
+	return {{ .Name.CloseHelper }}(
+		&o.{{ .Name.Programs }},
+		&o.{{ .Name.Maps }},
+	)
+}
 
-{{- range $name, $_ := .Sections }}
-	Section{{ identifier $name }} *ebpf.Map {{ tag $name }}
+// {{ .Name.Maps }} contains all maps after they have been loaded into the kernel.
+//
+// It can be passed to {{ .Name.LoadObjects }} or ebpf.CollectionSpec.LoadAndAssign.
+type {{ .Name.Maps }} struct {
+{{- range $name, $id := .Maps }}
+	{{ $id }} *ebpf.Map {{ tag $name }}
 {{- end }}
 }
 
-func (o *{{ .Name.Objects }}) Close() error {
-	for _, closer := range []io.Closer{
-{{- range $name, $_ := .Programs }}
-		o.Program{{ identifier $name }},
+func (m *{{ .Name.Maps }}) Close() error {
+	return {{ .Name.CloseHelper }}(
+{{- range $id := .Maps }}
+		m.{{ $id }},
 {{- end }}
+	)
+}
 
-{{- range $name, $_ := .Maps }}
-		o.Map{{ identifier $name}},
+// {{ .Name.Programs }} contains all programs after they have been loaded into the kernel.
+//
+// It can be passed to {{ .Name.LoadObjects }} or ebpf.CollectionSpec.LoadAndAssign.
+type {{ .Name.Programs }} struct {
+{{- range $name, $id := .Programs }}
+	{{ $id }} *ebpf.Program {{ tag $name }}
 {{- end }}
+}
 
-{{- range $name, $_ := .Sections }}
-		o.Section{{ identifier $name}},
+func (p *{{ .Name.Programs }}) Close() error {
+	return {{ .Name.CloseHelper }}(
+{{- range $id := .Programs }}
+		p.{{ $id }},
 {{- end }}
-	} {
+	)
+}
+
+func {{ .Name.CloseHelper }}(closers ...io.Closer) error {
+	for _, closer := range closers {
 		if err := closer.Close(); err != nil {
 			return err
 		}
@@ -150,8 +151,7 @@ var {{ .Name.Bytes }} = []byte("{{ .Bytes }}")
 
 var (
 	tplFuncs = map[string]interface{}{
-		"identifier": identifier,
-		"tag":        tag,
+		"tag": tag,
 	}
 	commonTemplate = template.Must(template.New("common").Funcs(tplFuncs).Parse(commonRaw))
 )
@@ -174,14 +174,38 @@ func (n templateName) Specs() string {
 	return n.maybeExport(string(n) + "Specs")
 }
 
-func (n templateName) NewSpecs() string {
-	return n.maybeExport("new" + toUpperFirst(string(n)) + "Specs")
+func (n templateName) ProgramSpecs() string {
+	return n.maybeExport(string(n) + "ProgramSpecs")
+}
+
+func (n templateName) MapSpecs() string {
+	return n.maybeExport(string(n) + "MapSpecs")
+}
+
+func (n templateName) Load() string {
+	return n.maybeExport("load" + toUpperFirst(string(n)))
+}
+
+func (n templateName) LoadObjects() string {
+	return n.maybeExport("load" + toUpperFirst(string(n)) + "Objects")
 }
 
 func (n templateName) Objects() string {
 	return n.maybeExport(string(n) + "Objects")
 }
 
+func (n templateName) Maps() string {
+	return n.maybeExport(string(n) + "Maps")
+}
+
+func (n templateName) Programs() string {
+	return n.maybeExport(string(n) + "Programs")
+}
+
+func (n templateName) CloseHelper() string {
+	return "_" + toUpperFirst(string(n)) + "Close"
+}
+
 type writeArgs struct {
 	pkg   string
 	ident string
@@ -201,14 +225,23 @@ func writeCommon(args writeArgs) error {
 		return fmt.Errorf("can't load BPF from ELF: %s", err)
 	}
 
-	sections := make(map[string]struct{})
-	maps := make(map[string]struct{})
+	maps := make(map[string]string)
 	for name := range spec.Maps {
 		if strings.HasPrefix(name, ".") {
-			sections[name] = struct{}{}
-		} else {
-			maps[name] = struct{}{}
+			// Skip .rodata, .data, .bss, etc. sections
+			continue
 		}
+
+		maps[name] = identifier(name)
+	}
+
+	programs := make(map[string]string)
+	for name := range spec.Programs {
+		programs[name] = identifier(name)
+	}
+
+	type typ struct {
+		Name string
 	}
 
 	ctx := struct {
@@ -216,18 +249,16 @@ func writeCommon(args writeArgs) error {
 		Package  string
 		Tags     []string
 		Name     templateName
-		Sections map[string]struct{}
-		Maps     map[string]struct{}
-		Programs map[string]*ebpf.ProgramSpec
+		Maps     map[string]string
+		Programs map[string]string
 		Bytes    string
 	}{
 		ebpfModule,
 		args.pkg,
 		args.tags,
 		templateName(args.ident),
-		sections,
 		maps,
-		spec.Programs,
+		programs,
 		binaryString(obj),
 	}
 
diff --git a/collection.go b/collection.go
index 2bd1877..8e36290 100644
--- a/collection.go
+++ b/collection.go
@@ -441,16 +441,8 @@ func (coll *Collection) DetachProgram(name string) *Program {
 
 // Assign the contents of a collection to a struct.
 //
-// `to` must be a pointer to a struct like the following:
-//
-//    struct {
-//        Foo     *ebpf.Program `ebpf:"xdp_foo"`
-//        Bar     *ebpf.Map     `ebpf:"bar_map"`
-//        Ignored int
-//    }
-//
-// DetachMap and DetachProgram is invoked for all assigned elements
-// if the function is successful.
+// Deprecated: use CollectionSpec.Assign instead. It provides the same
+// functionality but creates only the maps and programs requested.
 func (coll *Collection) Assign(to interface{}) error {
 	assignedMaps := make(map[string]struct{})
 	assignedPrograms := make(map[string]struct{})
@@ -491,28 +483,86 @@ func (coll *Collection) Assign(to interface{}) error {
 }
 
 func assignValues(to interface{}, valueOf func(reflect.Type, string) (reflect.Value, error)) error {
-	v := reflect.ValueOf(to)
-	if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
-		return fmt.Errorf("%T is not a pointer to a struct", to)
+	type structField struct {
+		reflect.StructField
+		value reflect.Value
+	}
+
+	var (
+		fields        []structField
+		visitedTypes  = make(map[reflect.Type]bool)
+		flattenStruct func(reflect.Value) error
+	)
+
+	flattenStruct = func(structVal reflect.Value) error {
+		structType := structVal.Type()
+		if structType.Kind() != reflect.Struct {
+			return fmt.Errorf("%s is not a struct", structType)
+		}
+
+		if visitedTypes[structType] {
+			return fmt.Errorf("recursion on type %s", structType)
+		}
+
+		for i := 0; i < structType.NumField(); i++ {
+			field := structField{structType.Field(i), structVal.Field(i)}
+
+			name := field.Tag.Get("ebpf")
+			if name != "" {
+				fields = append(fields, field)
+				continue
+			}
+
+			var err error
+			switch field.Type.Kind() {
+			case reflect.Ptr:
+				if field.Type.Elem().Kind() != reflect.Struct {
+					continue
+				}
+
+				if field.value.IsNil() {
+					return fmt.Errorf("nil pointer to %s", structType)
+				}
+
+				err = flattenStruct(field.value.Elem())
+
+			case reflect.Struct:
+				err = flattenStruct(field.value)
+
+			default:
+				continue
+			}
+
+			if err != nil {
+				return fmt.Errorf("field %s: %s", field.Name, err)
+			}
+		}
+
+		return nil
+	}
+
+	toValue := reflect.ValueOf(to)
+	if toValue.Type().Kind() != reflect.Ptr {
+		return fmt.Errorf("%T is not a pointer to struct", to)
+	}
+
+	if toValue.IsNil() {
+		return fmt.Errorf("nil pointer to %T", to)
+	}
+
+	if err := flattenStruct(toValue.Elem()); err != nil {
+		return err
 	}
 
 	type elem struct {
+		// Either *Map or *Program
 		typ  reflect.Type
 		name string
 	}
 
-	var (
-		s          = v.Elem()
-		sT         = s.Type()
-		assignedTo = make(map[elem]string)
-	)
-	for i := 0; i < sT.NumField(); i++ {
-		field := sT.Field(i)
-
+	assignedTo := make(map[elem]string)
+	for _, field := range fields {
 		name := field.Tag.Get("ebpf")
-		if name == "" {
-			continue
-		}
 		if strings.Contains(name, ",") {
 			return fmt.Errorf("field %s: ebpf tag contains a comma", field.Name)
 		}
@@ -527,12 +577,11 @@ func assignValues(to interface{}, valueOf func(reflect.Type, string) (reflect.Va
 			return fmt.Errorf("field %s: %w", field.Name, err)
 		}
 
-		fieldValue := s.Field(i)
-		if !fieldValue.CanSet() {
-			return fmt.Errorf("can't set value of field %s", field.Name)
+		if !field.value.CanSet() {
+			return fmt.Errorf("field %s: can't set value", field.Name)
 		}
 
-		fieldValue.Set(value)
+		field.value.Set(value)
 		assignedTo[e] = field.Name
 	}
 


Test patch:
diff --git a/cmd/bpf2go/api_test.go b/cmd/bpf2go/api_test.go
index 6676fe0..b982570 100644
--- a/cmd/bpf2go/api_test.go
+++ b/cmd/bpf2go/api_test.go
@@ -5,28 +5,28 @@ import (
 )
 
 func TestLoadingSpec(t *testing.T) {
-	specs, err := newExampleSpecs()
+	spec, err := loadExample()
 	if err != nil {
-		t.Fatal("Can't load specs:", err)
+		t.Fatal("Can't load spec:", err)
 	}
 
-	cpy := specs.Copy()
-	if cpy == specs || cpy.ProgramFilter == specs.ProgramFilter {
-		t.Error("Copy doesn't copy all fields")
-	}
-
-	spec := specs.CollectionSpec()
-	if spec.Programs["filter"] != specs.ProgramFilter {
-		t.Error("CollectionSpec copies programs instead of using the same reference")
+	if spec == nil {
+		t.Fatal("Got a nil spec")
 	}
+}
 
-	objs, err := specs.Load(nil)
-	if err != nil {
+func TestLoadingObjects(t *testing.T) {
+	var objs exampleObjects
+	if err := loadExampleObjects(&objs, nil); err != nil {
 		t.Fatal("Can't load objects:", err)
 	}
 	defer objs.Close()
 
-	if objs.ProgramFilter == nil {
-		t.Error("Loading returns an object with nil references")
+	if objs.Filter == nil {
+		t.Error("Loading returns an object with nil programs")
+	}
+
+	if objs.Map1 == nil {
+		t.Error("Loading returns an object with nil maps")
 	}
 }
diff --git a/cmd/bpf2go/example_test.go b/cmd/bpf2go/example_test.go
index 5f47da4..31e20f2 100644
--- a/cmd/bpf2go/example_test.go
+++ b/cmd/bpf2go/example_test.go
@@ -2,25 +2,17 @@ package main
 
 import (
 	"fmt"
-	"os"
 )
 
 //go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang-9 example testdata/minimal.c
 
 func Example() {
-	specs, err := newExampleSpecs()
-	if err != nil {
-		fmt.Println("Can't load specs:", err)
-		os.Exit(1)
-	}
-
-	objs, err := specs.Load(nil)
-	if err != nil {
-		fmt.Println("Can't load objects:", err)
-		os.Exit(1)
+	var objs exampleObjects
+	if err := loadExampleObjects(&objs, nil); err != nil {
+		panic("Can't load objects: " + err.Error())
 	}
 	defer objs.Close()
 
 	// Do something useful with the program.
-	fmt.Println(objs.ProgramFilter.String())
+	fmt.Println(objs.Filter.String())
 }
diff --git a/cmd/bpf2go/testdata/minimal.c b/cmd/bpf2go/testdata/minimal.c
index dcb4b98..3218056 100644
--- a/cmd/bpf2go/testdata/minimal.c
+++ b/cmd/bpf2go/testdata/minimal.c
@@ -1,7 +1,14 @@
-// +build ignore
+#include "../../../testdata/common.h"
 
-char __license[] __attribute__((section("license"), used)) = "MIT";
+char __license[] __section("license") = "MIT";
 
-__attribute__((section("socket"), used)) int filter() {
+struct bpf_map_def map1 __section("maps") = {
+	.type = BPF_MAP_TYPE_HASH,
+	.key_size = 4,
+	.value_size = 4,
+	.max_entries = 1,
+};
+
+__section("socket") int filter() {
 	return 0;
 }
diff --git a/collection_test.go b/collection_test.go
index 98394ce..6eed18f 100644
--- a/collection_test.go
+++ b/collection_test.go
@@ -2,6 +2,7 @@ package ebpf
 
 import (
 	"fmt"
+	"reflect"
 	"testing"
 
 	"github.com/cilium/ebpf/asm"
@@ -276,11 +277,23 @@ func TestCollectionAssign(t *testing.T) {
 		Map     *Map     `ebpf:"map1"`
 	}
 
+	prog1 := coll.Programs["prog1"]
+	defer prog1.Close()
+
+	map1 := coll.Maps["map1"]
+	defer map1.Close()
+
 	if err := coll.Assign(&objs); err != nil {
 		t.Fatal("Can't Assign objects:", err)
 	}
-	objs.Program.Close()
-	objs.Map.Close()
+
+	if objs.Program != prog1 {
+		t.Errorf("Program is %p not %p", objs.Program, prog1)
+	}
+
+	if objs.Map != map1 {
+		t.Errorf("Map is %p not %p", objs.Map, map1)
+	}
 
 	if coll.Programs["prog1"] != nil {
 		t.Fatal("Assign doesn't detach Program")
@@ -291,6 +304,72 @@ func TestCollectionAssign(t *testing.T) {
 	}
 }
 
+func TestAssignValues(t *testing.T) {
+	zero := func(t reflect.Type, name string) (reflect.Value, error) {
+		return reflect.Zero(t), nil
+	}
+
+	type t1 struct {
+		Bar int `ebpf:"bar"`
+	}
+
+	type t2 struct {
+		t1
+		Foo int `ebpf:"foo"`
+	}
+
+	type t2ptr struct {
+		*t1
+		Foo int `ebpf:"foo"`
+	}
+
+	invalid := []struct {
+		name string
+		to   interface{}
+	}{
+		{"non-struct", 1},
+		{"non-pointer struct", t1{}},
+		{"pointer to non-struct", new(int)},
+		{"embedded nil pointer", &t2ptr{}},
+		{"unexported field", new(struct {
+			foo int `ebpf:"foo"`
+		})},
+		{"identical tag", new(struct {
+			Foo1 int `ebpf:"foo"`
+			Foo2 int `ebpf:"foo"`
+		})},
+	}
+
+	for _, testcase := range invalid {
+		t.Run(testcase.name, func(t *testing.T) {
+			if err := assignValues(testcase.to, zero); err == nil {
+				t.Fatal("assignValues didn't return an error")
+			} else {
+				t.Log(err)
+			}
+		})
+	}
+
+	valid := []struct {
+		name string
+		to   interface{}
+	}{
+		{"pointer to struct", new(t1)},
+		{"embedded struct", new(t2)},
+		{"embedded struct pointer", &t2ptr{t1: new(t1)}},
+		{"untagged field", new(struct{ Foo int })},
+	}
+
+	for _, testcase := range valid {
+		t.Run(testcase.name, func(t *testing.T) {
+			if err := assignValues(testcase.to, zero); err != nil {
+				t.Fatal("assignValues returned", err)
+			}
+		})
+	}
+
+}
+
 func ExampleCollectionSpec_Assign() {
 	spec := &CollectionSpec{
 		Maps: map[string]*MapSpec{
@@ -313,9 +392,13 @@ func ExampleCollectionSpec_Assign() {
 		},
 	}
 
+	type maps struct {
+		Map *MapSpec `ebpf:"map1"`
+	}
+
 	var specs struct {
+		maps
 		Program *ProgramSpec `ebpf:"prog1"`
-		Map     *MapSpec     `ebpf:"map1"`
 	}
 
 	if err := spec.Assign(&specs); err != nil {
@@ -392,9 +475,13 @@ func ExampleCollection_Assign() {
 		panic(err)
 	}
 
+	type maps struct {
+		Map *Map `ebpf:"map1"`
+	}
+
 	var objs struct {
+		maps
 		Program *Program `ebpf:"prog1"`
-		Map     *Map     `ebpf:"map1"`
 	}
 
 	if err := coll.Assign(&objs); err != nil {