Skip to content

Commit

Permalink
Revert "remove ELF loader"
Browse files Browse the repository at this point in the history
This reverts commit 164d109.
  • Loading branch information
lmb committed Oct 24, 2019
1 parent 6cc6137 commit 581057b
Show file tree
Hide file tree
Showing 19 changed files with 1,947 additions and 0 deletions.
49 changes: 49 additions & 0 deletions abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,55 @@ import (
"github.com/pkg/errors"
)

// CollectionABI describes the interface of an eBPF collection.
type CollectionABI struct {
Maps map[string]*MapABI
Programs map[string]*ProgramABI
}

// CheckSpec verifies that all maps and programs mentioned
// in the ABI are present in the spec.
func (abi *CollectionABI) CheckSpec(cs *CollectionSpec) error {
for name := range abi.Maps {
if cs.Maps[name] == nil {
return errors.Errorf("missing map %s", name)
}
}

for name := range abi.Programs {
if cs.Programs[name] == nil {
return errors.Errorf("missing program %s", name)
}
}

return nil
}

// Check verifies that all items in a collection conform to this ABI.
func (abi *CollectionABI) Check(coll *Collection) error {
for name, mapABI := range abi.Maps {
m := coll.Maps[name]
if m == nil {
return errors.Errorf("missing map %s", name)
}
if err := mapABI.Check(m); err != nil {
return errors.Wrapf(err, "map %s", name)
}
}

for name, progABI := range abi.Programs {
p := coll.Programs[name]
if p == nil {
return errors.Errorf("missing program %s", name)
}
if err := progABI.Check(p); err != nil {
return errors.Wrapf(err, "program %s", name)
}
}

return nil
}

// MapABI describes a Map.
//
// Use it to assert that a Map matches what your code expects.
Expand Down
124 changes: 124 additions & 0 deletions abi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,68 @@ import (
"testing"
)

func TestCollectionABI(t *testing.T) {
cabi := &CollectionABI{
Maps: map[string]*MapABI{
"a": {
Type: ArrayOfMaps,
KeySize: 4,
ValueSize: 2,
MaxEntries: 3,
InnerMap: &MapABI{
Type: Array,
},
},
},
Programs: map[string]*ProgramABI{
"1": {Type: SocketFilter},
},
}

if err := cabi.CheckSpec(abiFixtureCollectionSpec()); err != nil {
t.Error("ABI check found error:", err)
}

cs := abiFixtureCollectionSpec()
delete(cs.Maps, "a")
if err := cabi.CheckSpec(cs); err == nil {
t.Error("Did not detect missing map")
}

cs = abiFixtureCollectionSpec()
delete(cs.Programs, "1")
if err := cabi.CheckSpec(cs); err == nil {
t.Error("Did not detect missing program")
}

if err := cabi.Check(abiFixtureCollection()); err != nil {
t.Error("ABI check found error:", err)

}

coll := abiFixtureCollection()
coll.Maps["a"].abi.KeySize = 12
if err := cabi.Check(coll); err == nil {
t.Error("Check not check map ABI")
}

delete(coll.Maps, "a")
if err := cabi.Check(coll); err == nil {
t.Error("Check did not detect missing map")
}

coll = abiFixtureCollection()
coll.Programs["1"].abi.Type = TracePoint
if err := cabi.Check(coll); err == nil {
t.Error("Did not check program ABI")
}

delete(coll.Programs, "1")
if err := cabi.Check(coll); err == nil {
t.Error("Check did not detect missing program")
}
}

func TestMapABI(t *testing.T) {
mabi := &MapABI{
Type: ArrayOfMaps,
Expand Down Expand Up @@ -70,6 +132,28 @@ func TestProgramABI(t *testing.T) {
}
}

func abiFixtureCollectionSpec() *CollectionSpec {
return &CollectionSpec{
Maps: map[string]*MapSpec{
"a": abiFixtureMapSpec(),
},
Programs: map[string]*ProgramSpec{
"1": abiFixtureProgramSpec(),
},
}
}

func abiFixtureCollection() *Collection {
return &Collection{
Maps: map[string]*Map{
"a": abiFixtureMap(),
},
Programs: map[string]*Program{
"1": abiFixtureProgram(),
},
}
}

func abiFixtureMapSpec() *MapSpec {
return &MapSpec{
Type: ArrayOfMaps,
Expand Down Expand Up @@ -100,3 +184,43 @@ func abiFixtureProgram() *Program {
abi: *newProgramABIFromSpec(abiFixtureProgramSpec()),
}
}

func ExampleCollectionABI() {
abi := CollectionABI{
Maps: map[string]*MapABI{
"a": {
Type: Array,
// Members which aren't specified are not checked
},
// Use an empty ABI if you just want to make sure
// something is present.
"b": {},
},
Programs: map[string]*ProgramABI{
"1": {Type: XDP},
},
}

spec, err := LoadCollectionSpec("from-somewhere.elf")
if err != nil {
panic(err)
}

// CheckSpec only makes sure that all entries of the ABI
// are present. It doesn't check whether the ABI is correct.
// See below for how to do that.
if err := abi.CheckSpec(spec); err != nil {
panic(err)
}

coll, err := NewCollection(spec)
if err != nil {
panic(err)
}

// Check finally compares the ABI and the collection, and
// makes sure that they match.
if err := abi.Check(coll); err != nil {
panic(err)
}
}
Loading

0 comments on commit 581057b

Please sign in to comment.