Skip to content

Commit

Permalink
Add read-core feature gate
Browse files Browse the repository at this point in the history
  • Loading branch information
nbdd0121 committed Oct 13, 2021
1 parent 80010ee commit f270f9c
Show file tree
Hide file tree
Showing 13 changed files with 143 additions and 43 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ jobs:
steps:
- uses: actions/checkout@v2
- run: cargo test --no-default-features
# Ensure gimli can be built without alloc.
- run: cargo check --no-default-features --features read-core
- run: cargo test --no-default-features --features read
- run: cargo test --no-default-features --features read,fallible-iterator
- run: cargo test --no-default-features --features read,std
Expand Down
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ test-assembler = "0.1.3"
typed-arena = "2"

[features]
read = []
endian-reader = ["stable_deref_trait"]
read-core = []
read = ["read-core"]
endian-reader = ["read", "stable_deref_trait"]
write = ["indexmap"]
std = ["fallible-iterator/std", "stable_deref_trait/std"]
default = ["read", "write", "std", "fallible-iterator", "endian-reader"]
Expand Down
11 changes: 8 additions & 3 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,14 @@ macro_rules! dw {
if let Some(s) = self.static_string() {
f.pad(s)
} else {
f.pad(&format!("Unknown {}: {}",
stringify!($struct_name),
self.0))
#[cfg(feature = "read")]
{
f.pad(&format!("Unknown {}: {}", stringify!($struct_name), self.0))
}
#[cfg(not(feature = "read"))]
{
write!(f, "Unknown {}: {}", stringify!($struct_name), self.0)
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/leb128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
//! ```

const CONTINUATION_BIT: u8 = 1 << 7;
#[cfg(feature = "read")]
#[cfg(feature = "read-core")]
const SIGN_BIT: u8 = 1 << 6;

#[inline]
Expand All @@ -62,7 +62,7 @@ fn low_bits_of_u64(val: u64) -> u8 {

/// A module for reading signed and unsigned integers that have been LEB128
/// encoded.
#[cfg(feature = "read")]
#[cfg(feature = "read-core")]
pub mod read {
use super::{low_bits_of_byte, CONTINUATION_BIT, SIGN_BIT};
use crate::read::{Error, Reader, Result};
Expand Down
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#![no_std]

#[allow(unused_imports)]
#[cfg(any(feature = "read", feature = "write"))]
#[macro_use]
extern crate alloc;

Expand All @@ -62,10 +63,10 @@ pub use crate::endianity::{BigEndian, Endianity, LittleEndian, NativeEndian, Run

pub mod leb128;

#[cfg(feature = "read")]
#[cfg(feature = "read-core")]
pub mod read;
// For backwards compat.
#[cfg(feature = "read")]
#[cfg(feature = "read-core")]
pub use crate::read::*;

#[cfg(feature = "write")]
Expand Down
45 changes: 36 additions & 9 deletions src/read/cfi.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[cfg(feature = "read")]
use alloc::vec::Vec;

use core::cmp::{Ord, Ordering};
Expand All @@ -10,9 +11,9 @@ use super::util::{ArrayLike, ArrayVec};
use crate::common::{DebugFrameOffset, EhFrameOffset, Encoding, Format, Register, SectionId};
use crate::constants::{self, DwEhPe};
use crate::endianity::Endianity;
use crate::read::{
EndianSlice, Error, Expression, Reader, ReaderOffset, Result, Section, StoreOnHeap,
};
#[cfg(feature = "read")]
use crate::read::StoreOnHeap;
use crate::read::{EndianSlice, Error, Expression, Reader, ReaderOffset, Result, Section};

/// `DebugFrame` contains the `.debug_frame` section's frame unwinding
/// information required to unwind to and recover registers from older frames on
Expand Down Expand Up @@ -1738,8 +1739,13 @@ impl<R: Reader> FrameDescriptionEntry<R> {

/// Specification of what storage should be used for [`UnwindContext`].
///
/// Normally you would only need to use [`StoreOnHeap`], which places the stack
/// on the heap using [`Vec`]. This is the default storage type parameter for [`UnwindContext`].
#[cfg_attr(
feature = "read",
doc = "
Normally you would only need to use [`StoreOnHeap`], which places the stack
on the heap using [`Vec`]. This is the default storage type parameter for [`UnwindContext`].
"
)]
///
/// If you need to avoid [`UnwindContext`] from allocating memory, e.g. for signal safety,
/// you can provide you own storage specification:
Expand Down Expand Up @@ -1780,8 +1786,10 @@ pub trait UnwindContextStorage<R: Reader>: Sized {
type Stack: ArrayLike<Item = UnwindTableRow<R, Self>>;
}

#[cfg(feature = "read")]
const MAX_RULES: usize = 192;

#[cfg(feature = "read")]
impl<R: Reader> UnwindContextStorage<R> for StoreOnHeap {
type Rules = [(Register, RegisterRule<R>); MAX_RULES];
type Stack = Vec<UnwindTableRow<R, Self>>;
Expand Down Expand Up @@ -1814,7 +1822,11 @@ impl<R: Reader> UnwindContextStorage<R> for StoreOnHeap {
/// # }
/// ```
#[derive(Clone, PartialEq, Eq)]
pub struct UnwindContext<R: Reader, A: UnwindContextStorage<R> = StoreOnHeap> {
pub struct UnwindContext<
R: Reader,
#[cfg(not(feature = "read"))] A: UnwindContextStorage<R>,
#[cfg(feature = "read")] A: UnwindContextStorage<R> = StoreOnHeap,
> {
// Stack of rows. The last row is the row currently being built by the
// program. There is always at least one row. The vast majority of CFI
// programs will only ever have one row on the stack.
Expand Down Expand Up @@ -1849,6 +1861,7 @@ impl<R: Reader, A: UnwindContextStorage<R>> Default for UnwindContext<R, A> {
}
}

#[cfg(feature = "read")]
impl<R: Reader> UnwindContext<R> {
/// Construct a new call frame unwinding context.
pub fn new() -> Self {
Expand Down Expand Up @@ -2036,7 +2049,13 @@ impl<R: Reader, A: UnwindContextStorage<R>> UnwindContext<R, A> {
/// > recording just the differences starting at the beginning address of each
/// > subroutine in the program.
#[derive(Debug)]
pub struct UnwindTable<'a, 'ctx, R: Reader, A: UnwindContextStorage<R> = StoreOnHeap> {
pub struct UnwindTable<
'a,
'ctx,
R: Reader,
#[cfg(not(feature = "read"))] A: UnwindContextStorage<R>,
#[cfg(feature = "read")] A: UnwindContextStorage<R> = StoreOnHeap,
> {
code_alignment_factor: Wrapping<u64>,
data_alignment_factor: Wrapping<i64>,
next_start_address: u64,
Expand Down Expand Up @@ -2347,7 +2366,11 @@ impl<'a, 'ctx, R: Reader, A: UnwindContextStorage<R>> UnwindTable<'a, 'ctx, R, A
// - https://github.com/libunwind/libunwind/blob/11fd461095ea98f4b3e3a361f5a8a558519363fa/include/tdep-aarch64/dwarf-config.h#L32
// - https://github.com/libunwind/libunwind/blob/11fd461095ea98f4b3e3a361f5a8a558519363fa/include/tdep-arm/dwarf-config.h#L31
// - https://github.com/libunwind/libunwind/blob/11fd461095ea98f4b3e3a361f5a8a558519363fa/include/tdep-mips/dwarf-config.h#L31
struct RegisterRuleMap<R: Reader, S: UnwindContextStorage<R> = StoreOnHeap> {
struct RegisterRuleMap<
R: Reader,
#[cfg(not(feature = "read"))] S: UnwindContextStorage<R>,
#[cfg(feature = "read")] S: UnwindContextStorage<R> = StoreOnHeap,
> {
rules: ArrayVec<S::Rules>,
}

Expand Down Expand Up @@ -2490,7 +2513,11 @@ impl<'iter, R: Reader> Iterator for RegisterRuleIter<'iter, R> {
/// A row in the virtual unwind table that describes how to find the values of
/// the registers in the *previous* frame for a range of PC addresses.
#[derive(PartialEq, Eq)]
pub struct UnwindTableRow<R: Reader, S: UnwindContextStorage<R> = StoreOnHeap> {
pub struct UnwindTableRow<
R: Reader,
#[cfg(not(feature = "read"))] S: UnwindContextStorage<R>,
#[cfg(feature = "read")] S: UnwindContextStorage<R> = StoreOnHeap,
> {
start_address: u64,
end_address: u64,
saved_args_size: u64,
Expand Down
11 changes: 11 additions & 0 deletions src/read/endian_slice.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Working with byte slices that have an associated endianity.

#[cfg(feature = "read")]
use alloc::borrow::Cow;
#[cfg(feature = "read")]
use alloc::string::String;
use core::ops::{Deref, Index, Range, RangeFrom, RangeTo};
use core::str;
Expand Down Expand Up @@ -82,6 +84,7 @@ where

/// Converts the slice to a string, including invalid characters,
/// using `String::from_utf8_lossy`.
#[cfg(feature = "read")]
#[inline]
pub fn to_string_lossy(&self) -> Cow<'input, str> {
String::from_utf8_lossy(self.slice)
Expand Down Expand Up @@ -284,11 +287,18 @@ where
Ok(EndianSlice::new(slice, self.endian))
}

#[cfg(not(feature = "read"))]
fn cannot_implement() -> super::reader::seal_if_no_alloc::Sealed {
super::reader::seal_if_no_alloc::Sealed
}

#[cfg(feature = "read")]
#[inline]
fn to_slice(&self) -> Result<Cow<[u8]>> {
Ok(self.slice.into())
}

#[cfg(feature = "read")]
#[inline]
fn to_string(&self) -> Result<Cow<str>> {
match str::from_utf8(self.slice) {
Expand All @@ -297,6 +307,7 @@ where
}
}

#[cfg(feature = "read")]
#[inline]
fn to_string_lossy(&self) -> Result<Cow<str>> {
Ok(String::from_utf8_lossy(self.slice))
Expand Down
17 changes: 17 additions & 0 deletions src/read/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,9 @@ pub use self::addr::*;
mod cfi;
pub use self::cfi::*;

#[cfg(feature = "read")]
mod dwarf;
#[cfg(feature = "read")]
pub use self::dwarf::*;

mod endian_slice;
Expand All @@ -200,7 +202,9 @@ pub use self::endian_reader::*;
mod reader;
pub use self::reader::*;

#[cfg(feature = "read")]
mod abbrev;
#[cfg(feature = "read")]
pub use self::abbrev::*;

mod aranges;
Expand All @@ -209,23 +213,30 @@ pub use self::aranges::*;
mod index;
pub use self::index::*;

#[cfg(feature = "read")]
mod line;
#[cfg(feature = "read")]
pub use self::line::*;

mod lists;

mod loclists;
pub use self::loclists::*;

#[cfg(feature = "read")]
mod lookup;

mod op;
pub use self::op::*;

#[cfg(feature = "read")]
mod pubnames;
#[cfg(feature = "read")]
pub use self::pubnames::*;

#[cfg(feature = "read")]
mod pubtypes;
#[cfg(feature = "read")]
pub use self::pubtypes::*;

mod rnglists;
Expand All @@ -234,7 +245,13 @@ pub use self::rnglists::*;
mod str;
pub use self::str::*;

/// An offset into the current compilation or type unit.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub struct UnitOffset<T = usize>(pub T);

#[cfg(feature = "read")]
mod unit;
#[cfg(feature = "read")]
pub use self::unit::*;

mod value;
Expand Down
Loading

0 comments on commit f270f9c

Please sign in to comment.