On startup, the kernel is probed for support of chained program ids for
CpuMap, DevMap and DevMapHash, and will patch maps at load time to have
the proper size. Then, at runtime, the support is checked and will error
out if a program id is passed when the kernel does not support it.
`MapData::fd` is now a `MapFd`. This means that `MapData` now closes the
file descriptor on drop. In the future we might consider making `MapFd`
hold a `BorrowedFd` but this requires API design work due to overlapping
borrows.
Since `SockMapFd` is no longer `Copy`, attach methods to take it by
reference to allow callers to use it multiple times as they are
accustomed to doing.
`SockMapFd` implements `try_clone`. `MapFd` and `SockMapFd` are now
returned by reference to allow callers to avoid file descriptor cloning
when desired.
This is an API breaking change.
Updates #612.
Remove repetition of permitted cgroup attach types. Make optionality of
name more explicit rather than pretending both kind and name are equal
to section.
The primary driver of change here is that `MapData::create` is now a
factory function that returns `Result<Self, _>` rather than mutating
`&mut self`. The remaining changes are consequences of that change, the
most notable of which is the removal of several errors which are no
longer possible.
This commit adds:
- A probe to see if the ENUM64 feature is supported
- Fixups for the use of signed enums, or enum64 types
on systems where enum64 is not supported
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
The BTF we're working on is Cow anyway so modifying in-place is fine.
All we need to do is store some information before we start our
mutable iteration to avoid concurrently borrowing types both mutably and
immutably.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
Rather than creating an empty vector and iteratively appending - which
might induce intermediate allocations - create an ExactSizeIterator and
collect it into a vector, which should produce exactly one allocation.
This commit fixes the (func|line)_info when we have multiple programs in
the same section. The integration test reloc.bpf.c serves as our test
case here. This required filtering down the (func|line)_info to only
that in scope of the current symbol + then adjusting the offets to
appease the kernel.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
This makes a few changes to the way that Aya reads the ELF object
files.
1. To find programs in a section, we use the symbols table. This allows
for cases where multiple programs could appear in the same section.
2. When parsing our ELF file we build symbols_by_section_index as an
optimization as we use it for legacy maps, BTF maps and now programs.
As a result of theses changes the "NAME" used in `bpf.prog_mut("NAME")`
is now ALWAYS the same as the function name in the eBPF code, making the
user experience more consistent.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
Wrap verifier logs in a newtype whose `Debug` impl emits unescaped
newlines. This improves ergonomics in tests where we `Result::unwrap()`
those load errors; when these fail today they emit the errors with
newlines escaped, making them incredibly difficult to read.
The matches crate has been archived now that `matches!` is in std.
However `assert_matches!` is still unstable in std, and the
assert_matches crate provides a more expressive form:
```
assert_matches!(foo, Ok(bar) => {
assert_eq!(bar, baz);
});
```
Replace all `assert!(matches!(..))` with `assert_matches!(..)`.
Remove the now-unused build-integration-test xtask command whose logic
doesn't match that of the build-and-run command.
This commit adds a new probe for bpf_attach_cookie, which would be used
to implement USDT probes. Since USDT probes aren't currently supported,
we this triggers a dead_code warning in clippy.
There are cases where exposing FEATURES - our lazy static - is actually
helpful to users of the library. For example, they may wish to choose to
load a different version of their bytecode based on current features.
Or, in the case of an orchestrator like bpfd, we might want to allow
users to describe which features their program needs and return nice
error message is one or more nodes in their cluster doesn't support the
necessary feature set.
To do this without breaking the API, we make all the internal members of
the `Features` and `BtfFeatures` structs private, and add accessors for
them. We then add a `features()` API to avoid leaking the
lazy_static.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
This fix aya wrong logic causing non entrypoint functions to not have
any BTF relocations working.
Also fix missing section_offset computation for instruction offset in
multiple spots.
Files changed:
M aya-obj/src/generated/btf_internal_bindings.rs
M aya-obj/src/generated/linux_bindings_aarch64.rs
M aya-obj/src/generated/linux_bindings_armv7.rs
M aya-obj/src/generated/linux_bindings_riscv64.rs
M aya-obj/src/generated/linux_bindings_x86_64.rs
M bpf/aya-bpf-bindings/src/aarch64/bindings.rs
M bpf/aya-bpf-bindings/src/armv7/bindings.rs
M bpf/aya-bpf-bindings/src/riscv64/bindings.rs
M bpf/aya-bpf-bindings/src/x86_64/bindings.rs
* use the hdr_len of BTF.ext sections rather than size of struct
Otherwise this will erroneously fail on older btf_ext_header that have
less fields than the bindgen'd struct
* do not attempt to load a BTF object that has no types
* add tests
* fix: hdr_len i32 -> u32
* guard against a bigger header in the future
* use separate unsafe blocks
* simplify writing to zero'd out header
* merge safe block and address typo
Fix map creation failure when a BPF have a data section on older
kernel. (< 5.2)
If the BPF uses that section, relocation will fail accordingly and
report an error.
Remove mem::forget::<HashMap>() calls in tests which fail to compile when
HashMap is provided by hashbrown:
info: running `cargo check --all-targets --no-default-features` on aya-obj (11/23)
Checking aya-obj v0.1.0 (/home/tamird/src/aya/aya-obj)
error[E0505]: cannot move out of `map` because it is borrowed
--> aya-obj/src/relocation.rs:594:21
|
578 | let map = fake_legacy_map(1);
| --- binding `map` declared here
579 | let maps_by_symbol = HashMap::from([(1, ("test_map", Some(1), &map))]);
| ---- borrow of `map` occurs here
...
594 | mem::forget(map);
| ^^^ move out of `map` occurs here
595 | }
| - borrow might be used here, when `maps_by_symbol` is dropped and runs the destructor for type `hashbrown::HashMap<usize, (&str, Option<i32>, &maps::Map)>`
error[E0505]: cannot move out of `map_1` because it is borrowed
--> aya-obj/src/relocation.rs:655:21
|
632 | let map_1 = fake_legacy_map(1);
| ----- binding `map_1` declared here
...
635 | (1, ("test_map_1", Some(1), &map_1)),
| ------ borrow of `map_1` occurs here
...
655 | mem::forget(map_1);
| ^^^^^ move out of `map_1` occurs here
656 | mem::forget(map_2);
657 | }
| - borrow might be used here, when `maps_by_symbol` is dropped and runs the destructor for type `hashbrown::HashMap<usize, (&str, Option<i32>, &maps::Map)>`
error[E0505]: cannot move out of `map_2` because it is borrowed
--> aya-obj/src/relocation.rs:656:21
|
633 | let map_2 = fake_legacy_map(2);
| ----- binding `map_2` declared here
...
636 | (2, ("test_map_2", Some(2), &map_2)),
| ------ borrow of `map_2` occurs here
...
656 | mem::forget(map_2);
| ^^^^^ move out of `map_2` occurs here
657 | }
| - borrow might be used here, when `maps_by_symbol` is dropped and runs the destructor for type `hashbrown::HashMap<usize, (&str, Option<i32>, &maps::Map)>`
error[E0505]: cannot move out of `map` because it is borrowed
--> aya-obj/src/relocation.rs:694:21
|
678 | let map = fake_btf_map(1);
| --- binding `map` declared here
679 | let maps_by_symbol = HashMap::from([(1, ("test_map", Some(1), &map))]);
| ---- borrow of `map` occurs here
...
694 | mem::forget(map);
| ^^^ move out of `map` occurs here
695 | }
| - borrow might be used here, when `maps_by_symbol` is dropped and runs the destructor for type `hashbrown::HashMap<usize, (&str, Option<i32>, &maps::Map)>`
error[E0505]: cannot move out of `map_1` because it is borrowed
--> aya-obj/src/relocation.rs:755:21
|
732 | let map_1 = fake_btf_map(1);
| ----- binding `map_1` declared here
...
735 | (1, ("test_map_1", Some(1), &map_1)),
| ------ borrow of `map_1` occurs here
...
755 | mem::forget(map_1);
| ^^^^^ move out of `map_1` occurs here
756 | mem::forget(map_2);
757 | }
| - borrow might be used here, when `maps_by_symbol` is dropped and runs the destructor for type `hashbrown::HashMap<usize, (&str, Option<i32>, &maps::Map)>`
error[E0505]: cannot move out of `map_2` because it is borrowed
--> aya-obj/src/relocation.rs:756:21
|
733 | let map_2 = fake_btf_map(2);
| ----- binding `map_2` declared here
...
736 | (2, ("test_map_2", Some(2), &map_2)),
| ------ borrow of `map_2` occurs here
...
756 | mem::forget(map_2);
| ^^^^^ move out of `map_2` occurs here
757 | }
| - borrow might be used here, when `maps_by_symbol` is dropped and runs the destructor for type `hashbrown::HashMap<usize, (&str, Option<i32>, &maps::Map)>`
For more information about this error, try `rustc --explain E0505`.
error: could not compile `aya-obj` due to 6 previous errors
warning: build failed, waiting for other jobs to finish...
error: process didn't exit successfully: `/home/tamird/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/cargo check --all-targets --manifest-path aya-obj/Cargo.toml --no-default-features` (exit status: 101)