aya: flip feature "no_std" to feature "std"

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
pull/586/head
Tamir Duberstein 2 years ago
parent b5c2928b0e
commit 33a0a2b604
No known key found for this signature in database

@ -31,6 +31,10 @@ jobs:
toolchain: stable toolchain: stable
override: true override: true
- uses: taiki-e/install-action@cargo-hack
- name: Check
run: cargo hack check --feature-powerset --ignore-private
- uses: Swatinem/rust-cache@v1 - uses: Swatinem/rust-cache@v1
- name: Prereqs - name: Prereqs
run: cargo install cross --git https://github.com/cross-rs/cross run: cargo install cross --git https://github.com/cross-rs/cross

@ -14,14 +14,13 @@ edition = "2021"
bytes = "1" bytes = "1"
log = "0.4" log = "0.4"
object = { version = "0.30", default-features = false, features = ["read_core", "elf"] } object = { version = "0.30", default-features = false, features = ["read_core", "elf"] }
hashbrown = { version = "0.13", optional = true } hashbrown = { version = "0.13" }
thiserror-std = { package = "thiserror", version = "1" } thiserror = { version = "1", default-features = false }
thiserror-core = { version = "1", default-features = false, features = [], optional = true } core-error = { version = "0.0.0" }
[dev-dependencies] [dev-dependencies]
matches = "0.1.8" matches = "0.1.8"
rbpf = "0.1.0" rbpf = "0.1.0"
[features] [features]
default = [] std = []
no_std = ["hashbrown", "thiserror-core"]

@ -21,18 +21,20 @@ use crate::{
IntEncoding, LineInfo, Struct, Typedef, VarLinkage, IntEncoding, LineInfo, Struct, Typedef, VarLinkage,
}, },
generated::{btf_ext_header, btf_header}, generated::{btf_ext_header, btf_header},
thiserror::{self, Error},
util::{bytes_of, HashMap}, util::{bytes_of, HashMap},
Object, Object,
}; };
#[cfg(not(feature = "std"))]
use crate::std;
pub(crate) const MAX_RESOLVE_DEPTH: u8 = 32; pub(crate) const MAX_RESOLVE_DEPTH: u8 = 32;
pub(crate) const MAX_SPEC_LEN: usize = 64; pub(crate) const MAX_SPEC_LEN: usize = 64;
/// The error type returned when `BTF` operations fail. /// The error type returned when `BTF` operations fail.
#[derive(Error, Debug)] #[derive(thiserror::Error, Debug)]
pub enum BtfError { pub enum BtfError {
#[cfg(not(feature = "no_std"))] #[cfg(feature = "std")]
/// Error parsing file /// Error parsing file
#[error("error parsing {path}")] #[error("error parsing {path}")]
FileError { FileError {
@ -126,7 +128,7 @@ pub enum BtfError {
type_id: u32, type_id: u32,
}, },
#[cfg(not(feature = "no_std"))] #[cfg(feature = "std")]
/// Loading the btf failed /// Loading the btf failed
#[error("the BPF_BTF_LOAD syscall failed. Verifier output: {verifier_log}")] #[error("the BPF_BTF_LOAD syscall failed. Verifier output: {verifier_log}")]
LoadError { LoadError {
@ -232,13 +234,13 @@ impl Btf {
} }
/// Loads BTF metadata from `/sys/kernel/btf/vmlinux`. /// Loads BTF metadata from `/sys/kernel/btf/vmlinux`.
#[cfg(not(feature = "no_std"))] #[cfg(feature = "std")]
pub fn from_sys_fs() -> Result<Btf, BtfError> { pub fn from_sys_fs() -> Result<Btf, BtfError> {
Btf::parse_file("/sys/kernel/btf/vmlinux", Endianness::default()) Btf::parse_file("/sys/kernel/btf/vmlinux", Endianness::default())
} }
/// Loads BTF metadata from the given `path`. /// Loads BTF metadata from the given `path`.
#[cfg(not(feature = "no_std"))] #[cfg(feature = "std")]
pub fn parse_file<P: AsRef<std::path::Path>>( pub fn parse_file<P: AsRef<std::path::Path>>(
path: P, path: P,
endianness: Endianness, endianness: Endianness,
@ -1457,7 +1459,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(not(feature = "no_std"))] #[cfg(feature = "std")]
#[cfg_attr(miri, ignore)] #[cfg_attr(miri, ignore)]
fn test_read_btf_from_sys_fs() { fn test_read_btf_from_sys_fs() {
let btf = Btf::parse_file("/sys/kernel/btf/vmlinux", Endianness::default()).unwrap(); let btf = Btf::parse_file("/sys/kernel/btf/vmlinux", Endianness::default()).unwrap();

@ -17,13 +17,15 @@ use crate::{
bpf_core_relo, bpf_core_relo_kind::*, bpf_insn, BPF_ALU, BPF_ALU64, BPF_B, BPF_DW, BPF_H, bpf_core_relo, bpf_core_relo_kind::*, bpf_insn, BPF_ALU, BPF_ALU64, BPF_B, BPF_DW, BPF_H,
BPF_K, BPF_LD, BPF_LDX, BPF_ST, BPF_STX, BPF_W, BTF_INT_SIGNED, BPF_K, BPF_LD, BPF_LDX, BPF_ST, BPF_STX, BPF_W, BTF_INT_SIGNED,
}, },
thiserror::{self, Error},
util::HashMap, util::HashMap,
Object, Program, ProgramSection, Object, Program, ProgramSection,
}; };
#[cfg(not(feature = "std"))]
use crate::std;
/// The error type returned by [`Object::relocate_btf`]. /// The error type returned by [`Object::relocate_btf`].
#[derive(Error, Debug)] #[derive(thiserror::Error, Debug)]
#[error("error relocating `{section}`")] #[error("error relocating `{section}`")]
pub struct BtfRelocationError { pub struct BtfRelocationError {
/// The function name /// The function name
@ -34,9 +36,9 @@ pub struct BtfRelocationError {
} }
/// Relocation failures /// Relocation failures
#[derive(Error, Debug)] #[derive(thiserror::Error, Debug)]
enum RelocationError { enum RelocationError {
#[cfg(not(feature = "no_std"))] #[cfg(feature = "std")]
/// I/O error /// I/O error
#[error(transparent)] #[error(transparent)]
IOError(#[from] std::io::Error), IOError(#[from] std::io::Error),

@ -63,16 +63,17 @@
#![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(clippy::all, missing_docs)] #![deny(clippy::all, missing_docs)]
#![allow(clippy::missing_safety_doc, clippy::len_without_is_empty)] #![allow(clippy::missing_safety_doc, clippy::len_without_is_empty)]
#![cfg_attr(feature = "no_std", feature(error_in_core))]
#[cfg(feature = "no_std")]
pub(crate) use thiserror_core as thiserror;
#[cfg(not(feature = "no_std"))]
pub(crate) use thiserror_std as thiserror;
extern crate alloc; extern crate alloc;
#[cfg(not(feature = "no_std"))] #[cfg(feature = "std")]
extern crate std; extern crate std;
#[cfg(not(feature = "std"))]
mod std {
pub mod error {
pub use core_error::Error;
}
pub use core::*;
}
pub mod btf; pub mod btf;
pub mod generated; pub mod generated;

@ -2,12 +2,12 @@
use core::mem; use core::mem;
use crate::{ use crate::BpfSectionKind;
thiserror::{self, Error},
BpfSectionKind,
};
use alloc::vec::Vec; use alloc::vec::Vec;
#[cfg(not(feature = "std"))]
use crate::std;
/// Invalid map type encontered /// Invalid map type encontered
pub struct InvalidMapTypeError { pub struct InvalidMapTypeError {
/// The map type /// The map type
@ -94,7 +94,7 @@ pub enum PinningType {
} }
/// The error type returned when failing to parse a [PinningType] /// The error type returned when failing to parse a [PinningType]
#[derive(Debug, Error)] #[derive(Debug, thiserror::Error)]
pub enum PinningError { pub enum PinningError {
/// Unsupported pinning type /// Unsupported pinning type
#[error("unsupported pinning type `{pinning_type}`")] #[error("unsupported pinning type `{pinning_type}`")]

@ -19,10 +19,12 @@ use crate::{
generated::{BPF_CALL, BPF_JMP, BPF_K}, generated::{BPF_CALL, BPF_JMP, BPF_K},
maps::{BtfMap, LegacyMap, Map, MINIMUM_MAP_SIZE}, maps::{BtfMap, LegacyMap, Map, MINIMUM_MAP_SIZE},
relocation::*, relocation::*,
thiserror::{self, Error},
util::HashMap, util::HashMap,
}; };
#[cfg(not(feature = "std"))]
use crate::std;
use crate::{ use crate::{
btf::{Btf, BtfError, BtfExt, BtfType}, btf::{Btf, BtfError, BtfExt, BtfType},
generated::{bpf_insn, bpf_map_info, bpf_map_type::BPF_MAP_TYPE_ARRAY, BPF_F_RDONLY_PROG}, generated::{bpf_insn, bpf_map_info, bpf_map_type::BPF_MAP_TYPE_ARRAY, BPF_F_RDONLY_PROG},
@ -978,7 +980,7 @@ fn parse_maps_section<'a, I: Iterator<Item = &'a Symbol>>(
} }
/// Errors caught during parsing the object file /// Errors caught during parsing the object file
#[derive(Debug, Error)] #[derive(Debug, thiserror::Error)]
#[allow(missing_docs)] #[allow(missing_docs)]
pub enum ParseError { pub enum ParseError {
#[error("error parsing ELF data")] #[error("error parsing ELF data")]

@ -1,10 +1,10 @@
//! Cgroup socket programs. //! Cgroup socket programs.
use alloc::{borrow::ToOwned, string::String}; use alloc::{borrow::ToOwned, string::String};
use crate::{ use crate::generated::bpf_attach_type;
generated::bpf_attach_type,
thiserror::{self, Error}, #[cfg(not(feature = "std"))]
}; use crate::std;
/// Defines where to attach a `CgroupSock` program. /// Defines where to attach a `CgroupSock` program.
#[derive(Copy, Clone, Debug, Default)] #[derive(Copy, Clone, Debug, Default)]
@ -31,7 +31,7 @@ impl From<CgroupSockAttachType> for bpf_attach_type {
} }
} }
#[derive(Debug, Error)] #[derive(Debug, thiserror::Error)]
#[error("{0} is not a valid attach type for a CGROUP_SOCK program")] #[error("{0} is not a valid attach type for a CGROUP_SOCK program")]
pub(crate) struct InvalidAttachType(String); pub(crate) struct InvalidAttachType(String);

@ -1,10 +1,10 @@
//! Cgroup socket address programs. //! Cgroup socket address programs.
use alloc::{borrow::ToOwned, string::String}; use alloc::{borrow::ToOwned, string::String};
use crate::{ use crate::generated::bpf_attach_type;
generated::bpf_attach_type,
thiserror::{self, Error}, #[cfg(not(feature = "std"))]
}; use crate::std;
/// Defines where to attach a `CgroupSockAddr` program. /// Defines where to attach a `CgroupSockAddr` program.
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
@ -54,7 +54,7 @@ impl From<CgroupSockAddrAttachType> for bpf_attach_type {
} }
} }
#[derive(Debug, Error)] #[derive(Debug, thiserror::Error)]
#[error("{0} is not a valid attach type for a CGROUP_SOCK_ADDR program")] #[error("{0} is not a valid attach type for a CGROUP_SOCK_ADDR program")]
pub(crate) struct InvalidAttachType(String); pub(crate) struct InvalidAttachType(String);

@ -1,10 +1,10 @@
//! Cgroup socket option programs. //! Cgroup socket option programs.
use alloc::{borrow::ToOwned, string::String}; use alloc::{borrow::ToOwned, string::String};
use crate::{ use crate::generated::bpf_attach_type;
generated::bpf_attach_type,
thiserror::{self, Error}, #[cfg(not(feature = "std"))]
}; use crate::std;
/// Defines where to attach a `CgroupSockopt` program. /// Defines where to attach a `CgroupSockopt` program.
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
@ -24,7 +24,7 @@ impl From<CgroupSockoptAttachType> for bpf_attach_type {
} }
} }
#[derive(Debug, Error)] #[derive(Debug, thiserror::Error)]
#[error("{0} is not a valid attach type for a CGROUP_SOCKOPT program")] #[error("{0} is not a valid attach type for a CGROUP_SOCKOPT program")]
pub(crate) struct InvalidAttachType(String); pub(crate) struct InvalidAttachType(String);

@ -1,7 +1,6 @@
//! Program relocation handling. //! Program relocation handling.
use core::mem; use core::mem;
use std::collections::HashSet;
use alloc::{borrow::ToOwned, string::String}; use alloc::{borrow::ToOwned, string::String};
use log::debug; use log::debug;
@ -14,15 +13,17 @@ use crate::{
}, },
maps::Map, maps::Map,
obj::{Function, Object, Program}, obj::{Function, Object, Program},
thiserror::{self, Error}, util::{HashMap, HashSet},
util::HashMap,
BpfSectionKind, BpfSectionKind,
}; };
#[cfg(not(feature = "std"))]
use crate::std;
pub(crate) const INS_SIZE: usize = mem::size_of::<bpf_insn>(); pub(crate) const INS_SIZE: usize = mem::size_of::<bpf_insn>();
/// The error type returned by [`Object::relocate_maps`] and [`Object::relocate_calls`] /// The error type returned by [`Object::relocate_maps`] and [`Object::relocate_calls`]
#[derive(Error, Debug)] #[derive(thiserror::Error, Debug)]
#[error("error relocating `{function}`")] #[error("error relocating `{function}`")]
pub struct BpfRelocationError { pub struct BpfRelocationError {
/// The function name /// The function name
@ -33,7 +34,7 @@ pub struct BpfRelocationError {
} }
/// Relocation failures /// Relocation failures
#[derive(Debug, Error)] #[derive(Debug, thiserror::Error)]
pub enum RelocationError { pub enum RelocationError {
/// Unknown symbol /// Unknown symbol
#[error("unknown symbol, index `{index}`")] #[error("unknown symbol, index `{index}`")]

@ -1,10 +1,15 @@
use core::{mem, slice}; use core::{mem, slice};
#[cfg(feature = "no_std")] #[cfg(not(feature = "std"))]
pub(crate) use hashbrown::HashMap; pub(crate) use hashbrown::HashMap;
#[cfg(not(feature = "no_std"))] #[cfg(feature = "std")]
pub(crate) use std::collections::HashMap; pub(crate) use std::collections::HashMap;
#[cfg(not(feature = "std"))]
pub(crate) use hashbrown::HashSet;
#[cfg(feature = "std")]
pub(crate) use std::collections::HashSet;
/// bytes_of converts a <T> to a byte slice /// bytes_of converts a <T> to a byte slice
pub(crate) unsafe fn bytes_of<T>(val: &T) -> &[u8] { pub(crate) unsafe fn bytes_of<T>(val: &T) -> &[u8] {
let size = mem::size_of::<T>(); let size = mem::size_of::<T>();

@ -12,7 +12,7 @@ edition = "2021"
[dependencies] [dependencies]
libc = { version = "0.2.105" } libc = { version = "0.2.105" }
aya-obj = { path = "../aya-obj", version = "0.1.0" } aya-obj = { path = "../aya-obj", version = "0.1.0", features = ["std"] }
thiserror = "1" thiserror = "1"
object = { version = "0.30", default-features = false, features = ["std", "read_core", "elf"] } object = { version = "0.30", default-features = false, features = ["std", "read_core", "elf"] }
bitflags = "1.2.1" bitflags = "1.2.1"

Loading…
Cancel
Save