Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/gimli/src/read/   (Firefox Browser Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 6 kB image not shown  

Quelle  lookup.rs

  Sprache: Rust
 

use core::marker::PhantomData;

use crate::common::{DebugInfoOffset, Format};
use crate::read::{parse_debug_info_offset, Error, Reader, ReaderOffset, Result, UnitOffset};

// The various "Accelerated Access" sections (DWARF standard v4 Section 6.1) all have
// similar structures. They consist of a header with metadata and an offset into the
// .debug_info section for the entire compilation unit, and a series
// of following entries that list addresses (for .debug_aranges) or names
// (for .debug_pubnames and .debug_pubtypes) that are covered.
//
// Because these three tables all have similar structures, we abstract out some of
// the parsing mechanics.

pub trait LookupParser<R: Reader> {
    /// The type of the produced header.
    type Header;
    /// The type of the produced entry.
    type Entry;

    /// Parse a header from `input`. Returns a tuple of `input` sliced to contain just the entries
    /// corresponding to this header (without the header itself), and the parsed representation of
    /// the header itself.
    fn parse_header(input: &mut R) -> Result<(R, Self::Header)>;

    /// Parse a single entry from `input`. Returns either a parsed representation of the entry
    /// or None if `input` is exhausted.
    fn parse_entry(input: &mut R, header: &Self::Header) -> Result<Option<Self::Entry>>;
}

#[derive(Clone, Debug)]
pub struct DebugLookup<R, Parser>
where
    R: Reader,
    Parser: LookupParser<R>,
{
    input_buffer: R,
    phantom: PhantomData<Parser>,
}

impl<R, Parser> From<R> for DebugLookup<R, Parser>
where
    R: Reader,
    Parser: LookupParser<R>,
{
    fn from(input_buffer: R) -> Self {
        DebugLookup {
            input_buffer,
            phantom: PhantomData,
        }
    }
}

impl<R, Parser> DebugLookup<R, Parser>
where
    R: Reader,
    Parser: LookupParser<R>,
{
    pub fn items(&self) -> LookupEntryIter<R, Parser> {
        LookupEntryIter {
            current_set: None,
            remaining_input: self.input_buffer.clone(),
        }
    }

    pub fn reader(&self) -> &R {
        &self.input_buffer
    }
}

#[derive(Clone, Debug)]
pub struct LookupEntryIter<R, Parser>
where
    R: Reader,
    Parser: LookupParser<R>,
{
    current_set: Option<(R, Parser::Header)>, // Only none at the very beginning and end.
    remaining_input: R,
}

impl<R, Parser> LookupEntryIter<R, Parser>
where
    R: Reader,
    Parser: LookupParser<R>,
{
    /// Advance the iterator and return the next entry.
    ///
    /// Returns the newly parsed entry as `Ok(Some(Parser::Entry))`. Returns
    /// `Ok(None)` when iteration is complete and all entries have already been
    /// parsed and yielded. If an error occurs while parsing the next entry,
    /// then this error is returned as `Err(e)`, and all subsequent calls return
    /// `Ok(None)`.
    ///
    /// Can be [used with `FallibleIterator`](./index.html#using-with-fallibleiterator).
    pub fn next(&mut self) -> Result<Option<Parser::Entry>> {
        loop {
            if let Some((ref mut input, ref header)) = self.current_set {
                if !input.is_empty() {
                    match Parser::parse_entry(input, header) {
                        Ok(Some(entry)) => return Ok(Some(entry)),
                        Ok(None) => {}
                        Err(e) => {
                            input.empty();
                            self.remaining_input.empty();
                            return Err(e);
                        }
                    }
                }
            }
            if self.remaining_input.is_empty() {
                self.current_set = None;
                return Ok(None);
            }
            match Parser::parse_header(&mut self.remaining_input) {
                Ok(set) => {
                    self.current_set = Some(set);
                }
                Err(e) => {
                    self.current_set = None;
                    self.remaining_input.empty();
                    return Err(e);
                }
            }
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PubStuffHeader<T = usize> {
    format: Format,
    length: T,
    version: u16,
    unit_offset: DebugInfoOffset<T>,
    unit_length: T,
}

pub trait PubStuffEntry<R: Reader> {
    fn new(
        die_offset: UnitOffset<R::Offset>,
        name: R,
        unit_header_offset: DebugInfoOffset<R::Offset>,
    ) -> Self;
}

#[derive(Clone, Debug)]
pub struct PubStuffParser<R, Entry>
where
    R: Reader,
    Entry: PubStuffEntry<R>,
{
    // This struct is never instantiated.
    phantom: PhantomData<(R, Entry)>,
}

impl<R, Entry> LookupParser<R> for PubStuffParser<R, Entry>
where
    R: Reader,
    Entry: PubStuffEntry<R>,
{
    type Header = PubStuffHeader<R::Offset>;
    type Entry = Entry;

    /// Parse an pubthings set header. Returns a tuple of the
    /// pubthings to be parsed for this set, and the newly created PubThingHeader struct.
    fn parse_header(input: &mut R) -> Result<(R, Self::Header)> {
        let (length, format) = input.read_initial_length()?;
        let mut rest = input.split(length)?;

        let version = rest.read_u16()?;
        if version != 2 {
            return Err(Error::UnknownVersion(u64::from(version)));
        }

        let unit_offset = parse_debug_info_offset(&mut rest, format)?;
        let unit_length = rest.read_length(format)?;

        let header = PubStuffHeader {
            format,
            length,
            version,
            unit_offset,
            unit_length,
        };
        Ok((rest, header))
    }

    /// Parse a single pubthing. Return `None` for the null pubthing, `Some` for an actual pubthing.
    fn parse_entry(input: &mut R, header: &Self::Header) -> Result<Option<Self::Entry>> {
        let offset = input.read_offset(header.format)?;
        if offset.into_u64() == 0 {
            input.empty();
            Ok(None)
        } else {
            let name = input.read_null_terminated_slice()?;
            Ok(Some(Self::Entry::new(
                UnitOffset(offset),
                name,
                header.unit_offset,
            )))
        }
    }
}

Messung V0.5 in Prozent
C=85 H=96 G=90

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-06-19) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.