This removes the fake std module in aya-obj which is no longer needed as
thiserror now properly supports no_std.
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
The loader should fill bss maps with zeros according to the size of the
ELF section.
Failure to do so yields weird verifier messages as follows:
```
cannot access ptr member ops with moff 0 in struct bpf_map with off 0 size 4
```
Reference to this in the cilium/ebpf code is here [1].
I could not find a reference in libbpf.
1: d0c8fc1937/elf_reader.go (L1159-L1165)
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
```
error: the following explicit lifetimes could be elided: 'data, 'file
--> aya-obj/src/obj.rs:1083:6
|
1083 | impl<'data, 'file, 'a> TryFrom<&'a ObjSection<'data, 'file>> for Section<'a> {
| ^^^^^ ^^^^^ ^^^^^ ^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
```
Adds detection for whether a field is available in `MapInfo`:
- For `map_type()`, we treturn new enum `MapType` instead of the integer
representation.
- For fields that can't be zero, we return `Option<NonZero*>` type.
- For `name_as_str()`, it now uses the feature probe `bpf_name()` to
detect if field is available.
Although the feature probe checks for program name, it can also be
used for map name since they were both introduced in the same commit.
Purpose of this commit is to add detections for whether a field is
available in `ProgramInfo`.
- For `program_type()`, we return the new enum `ProgramType` instead of
the integer representation.
- For fields that we know cannot be zero, we return `Option<NonZero*>`
type.
- For `name_as_str()`, it now also uses the feature probe `bpf_name()`
to detect if field is available or not.
- Two additional feature probes are added for the fields:
- `prog_info_map_ids()` probe -> `map_ids()` field
- `prog_info_gpl_compatible()` probe -> `gpl_compatible()` field
With the `prog_info_map_ids()` probe, the previous implementation that
I had for `bpf_prog_get_info_by_fd()` is shortened to use the probe
instead of having to make 2 potential syscalls.
The `test_loaded_at()` test is also moved into info tests since it is
better related to the info tests.
`aya::programs::Programs::prog_type(&self)` now returns `ProgramType`
instead of the generated FFI from aya-obj.
Also previously, `loaded_programs()` could be accessed either through
`aya` or `aya::programs`. To avoid confusion and duplicate export of
the item, the function should now only be exposed through
`aya::programs`.
Add conversion from u32 to program type, link type, and attach type.
Additionally, remove duplicate match statement for u32 conversion to
`BPF_MAP_TYPE_BLOOM_FILTER` & `BPF_MAP_TYPE_CGRP_STORAGE`.
New error `InvalidTypeBinding<T>` is created to represent when a
parsed/received value binding to a type is invalid.
This is used in the new conversions added here, and also replaces
`InvalidMapTypeError` in `TryFrom` for `bpf_map_type`.
Where possible, replace the hardcoded byte arrays in the tests with the
structs they represent, then convert the structs to byte arrays.
Signed-off-by: Billy McFall <22157057+Billy99@users.noreply.github.com>
Adding support for s390x (big endian architecture) and found that some
of the unit tests have structures and files implemented as byte arrays.
They are all coded as little endian and need a bug endian version to
work properly.
Signed-off-by: Billy McFall <22157057+Billy99@users.noreply.github.com>
```
error: unnecessary use of `get("foo").is_some()`
--> aya-obj/src/obj.rs:1690:26
|
1690 | assert!(obj.maps.get("foo").is_some());
| ^^^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key("foo")`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_get_then_check
note: the lint level is defined here
--> aya-obj/src/lib.rs:68:9
|
68 | #![deny(clippy::all, missing_docs)]
| ^^^^^^^^^^^
= note: `#[deny(clippy::unnecessary_get_then_check)]` implied by `#[deny(clippy::all)]`
error: unnecessary use of `get("foo").is_some()`
--> aya-obj/src/obj.rs:1777:26
|
1777 | assert!(obj.maps.get("foo").is_some());
| ^^^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key("foo")`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_get_then_check
error: unnecessary use of `get("bar").is_some()`
--> aya-obj/src/obj.rs:1778:26
|
1778 | assert!(obj.maps.get("bar").is_some());
| ^^^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key("bar")`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_get_then_check
error: unnecessary use of `get("baz").is_some()`
--> aya-obj/src/obj.rs:1779:26
|
1779 | assert!(obj.maps.get("baz").is_some());
| ^^^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key("baz")`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_get_then_check
error: unnecessary use of `get(".bss").is_some()`
--> aya-obj/src/obj.rs:1799:26
|
1799 | assert!(obj.maps.get(".bss").is_some());
| ^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key(".bss")`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_get_then_check
error: unnecessary use of `get(".rodata").is_some()`
--> aya-obj/src/obj.rs:1810:26
|
1810 | assert!(obj.maps.get(".rodata").is_some());
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key(".rodata")`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_get_then_check
error: unnecessary use of `get(".rodata.boo").is_some()`
--> aya-obj/src/obj.rs:1821:26
|
1821 | assert!(obj.maps.get(".rodata.boo").is_some());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key(".rodata.boo")`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_get_then_check
error: unnecessary use of `get(".data").is_some()`
--> aya-obj/src/obj.rs:1832:26
|
1832 | assert!(obj.maps.get(".data").is_some());
| ^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key(".data")`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_get_then_check
error: unnecessary use of `get(".data.boo").is_some()`
--> aya-obj/src/obj.rs:1843:26
|
1843 | assert!(obj.maps.get(".data.boo").is_some());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key(".data.boo")`
```
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.
Remove repetition of permitted cgroup attach types. Make optionality of
name more explicit rather than pretending both kind and name are equal
to section.
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>
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.
* 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.
This fixes `cargo build --all-features` by sidestepping the feature
unification problem described in The Cargo Book[0].
Add `cargo hack --feature-powerset` to CI to enforce that this doesn't
regress (and that all combinations of features work).
Since error_in_core is nightly-only, use core-error and a fake std
module to allow aya-obj to build without std on stable.
[0] https://doc.rust-lang.org/cargo/reference/features.html#feature-unification
Clearly split the code between `.maps`, `maps` and data maps (bss, data,
rodata). Sprinkle comments.
Remove MapKind which was effectively only needed since we used to have
one variant - BpfSectionKind::Data - to represent all data maps. Instead
add explicit BpfSectionKind::{Data, Rodata, Bss} variants and match on
those when we initialize maps.