Browse Source

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
Tamir Duberstein 1 year ago
parent
commit
33a0a2b

+ 4 - 0
.github/workflows/build-aya.yml

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

+ 4 - 5
aya-obj/Cargo.toml

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

+ 9 - 7
aya-obj/src/btf/btf.rs

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

+ 6 - 4
aya-obj/src/btf/relocation.rs

@@ -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_K, BPF_LD, BPF_LDX, BPF_ST, BPF_STX, BPF_W, BTF_INT_SIGNED,
     },
-    thiserror::{self, Error},
     util::HashMap,
     Object, Program, ProgramSection,
 };
 
+#[cfg(not(feature = "std"))]
+use crate::std;
+
 /// The error type returned by [`Object::relocate_btf`].
-#[derive(Error, Debug)]
+#[derive(thiserror::Error, Debug)]
 #[error("error relocating `{section}`")]
 pub struct BtfRelocationError {
     /// The function name
@@ -34,9 +36,9 @@ pub struct BtfRelocationError {
 }
 
 /// Relocation failures
-#[derive(Error, Debug)]
+#[derive(thiserror::Error, Debug)]
 enum RelocationError {
-    #[cfg(not(feature = "no_std"))]
+    #[cfg(feature = "std")]
     /// I/O error
     #[error(transparent)]
     IOError(#[from] std::io::Error),

+ 8 - 7
aya-obj/src/lib.rs

@@ -63,16 +63,17 @@
 #![cfg_attr(docsrs, feature(doc_cfg))]
 #![deny(clippy::all, missing_docs)]
 #![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;
-#[cfg(not(feature = "no_std"))]
+#[cfg(feature = "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 generated;

+ 5 - 5
aya-obj/src/maps.rs

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

+ 4 - 2
aya-obj/src/obj.rs

@@ -19,10 +19,12 @@ use crate::{
     generated::{BPF_CALL, BPF_JMP, BPF_K},
     maps::{BtfMap, LegacyMap, Map, MINIMUM_MAP_SIZE},
     relocation::*,
-    thiserror::{self, Error},
     util::HashMap,
 };
 
+#[cfg(not(feature = "std"))]
+use crate::std;
+
 use crate::{
     btf::{Btf, BtfError, BtfExt, BtfType},
     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
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 #[allow(missing_docs)]
 pub enum ParseError {
     #[error("error parsing ELF data")]

+ 5 - 5
aya-obj/src/programs/cgroup_sock.rs

@@ -1,10 +1,10 @@
 //! Cgroup socket programs.
 use alloc::{borrow::ToOwned, string::String};
 
-use crate::{
-    generated::bpf_attach_type,
-    thiserror::{self, Error},
-};
+use crate::generated::bpf_attach_type;
+
+#[cfg(not(feature = "std"))]
+use crate::std;
 
 /// Defines where to attach a `CgroupSock` program.
 #[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")]
 pub(crate) struct InvalidAttachType(String);
 

+ 5 - 5
aya-obj/src/programs/cgroup_sock_addr.rs

@@ -1,10 +1,10 @@
 //! Cgroup socket address programs.
 use alloc::{borrow::ToOwned, string::String};
 
-use crate::{
-    generated::bpf_attach_type,
-    thiserror::{self, Error},
-};
+use crate::generated::bpf_attach_type;
+
+#[cfg(not(feature = "std"))]
+use crate::std;
 
 /// Defines where to attach a `CgroupSockAddr` program.
 #[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")]
 pub(crate) struct InvalidAttachType(String);
 

+ 5 - 5
aya-obj/src/programs/cgroup_sockopt.rs

@@ -1,10 +1,10 @@
 //! Cgroup socket option programs.
 use alloc::{borrow::ToOwned, string::String};
 
-use crate::{
-    generated::bpf_attach_type,
-    thiserror::{self, Error},
-};
+use crate::generated::bpf_attach_type;
+
+#[cfg(not(feature = "std"))]
+use crate::std;
 
 /// Defines where to attach a `CgroupSockopt` program.
 #[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")]
 pub(crate) struct InvalidAttachType(String);
 

+ 6 - 5
aya-obj/src/relocation.rs

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

+ 7 - 2
aya-obj/src/util.rs

@@ -1,10 +1,15 @@
 use core::{mem, slice};
 
-#[cfg(feature = "no_std")]
+#[cfg(not(feature = "std"))]
 pub(crate) use hashbrown::HashMap;
-#[cfg(not(feature = "no_std"))]
+#[cfg(feature = "std")]
 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
 pub(crate) unsafe fn bytes_of<T>(val: &T) -> &[u8] {
     let size = mem::size_of::<T>();

+ 1 - 1
aya/Cargo.toml

@@ -12,7 +12,7 @@ edition = "2021"
 
 [dependencies]
 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"
 object = { version = "0.30", default-features = false, features = ["std", "read_core", "elf"] }
 bitflags = "1.2.1"