Skip to main content

llvm_mapper/block/
symtab.rs

1//! Functionality for mapping the `SYMTAB_BLOCK` block.
2
3use llvm_support::bitcodes::{IrBlockId, SymtabCode};
4use thiserror::Error;
5
6use crate::block::IrBlock;
7use crate::map::{MapError, PartialMapCtx};
8use crate::record::RecordBlobError;
9use crate::unroll::UnrolledBlock;
10
11/// Errors that can occur when accessing a symbol table.
12#[derive(Debug, Error)]
13pub enum SymtabError {
14    /// The symbol table is missing its blob.
15    #[error("malformed symbol table: missing blob")]
16    MissingBlob,
17
18    /// The blob containing the symbol table is invalid.
19    #[error("invalid string table: {0}")]
20    InvalidBlob(#[from] RecordBlobError),
21
22    /// A generic mapping error occured.
23    #[error("mapping error in string table")]
24    Map(#[from] MapError),
25}
26
27/// Models the `SYMTAB_BLOCK` block.
28///
29/// For now, this is an opaque block: it's really only used to accelerate LTO,
30/// so we don't attempt to expand its fields here.
31#[derive(Debug)]
32pub struct Symtab(Vec<u8>);
33
34impl AsRef<[u8]> for Symtab {
35    fn as_ref(&self) -> &[u8] {
36        &self.0
37    }
38}
39
40impl IrBlock for Symtab {
41    type Error = SymtabError;
42
43    const BLOCK_ID: IrBlockId = IrBlockId::Symtab;
44
45    fn try_map_inner(block: &UnrolledBlock, _ctx: &mut PartialMapCtx) -> Result<Self, Self::Error> {
46        let symtab = block
47            .records()
48            .one(SymtabCode::Blob as u64)
49            .ok_or(SymtabError::MissingBlob)
50            .and_then(|r| r.try_blob(0).map_err(SymtabError::from))?;
51
52        Ok(Self(symtab))
53    }
54}