Skip to main content

Gsym

Struct Gsym 

Source
pub struct Gsym<D> { /* private fields */ }
Expand description

Parsed GSYM data backed by caller-selected byte storage.

D may be a borrowed slice or an owned type such as Vec<u8>, Box<[u8]>, or Arc<[u8]>, and none of them is copied. With the mmap feature, MappedGsym is this same type over a read-only memory map.

Construct one with Gsym::open for a path or Gsym::parse for bytes. Both reject an unsupported version, a truncated file, or a section outside the input. A malformed function record is reported when it is read, so Gsym::verify is the way to check a whole file up front.

Lookups take &self and keep no interior state, so a reader can be shared between threads whenever its storage is Sync.

§Borrowed and owned storage

use gsym::{AddressRange, Function, Gsym, GsymBuilder};

let mut builder = GsymBuilder::new();
builder.add_function(Function::new(
    AddressRange::new(0x2000, 0x2010),
    b"borrowed",
))?;
let bytes = builder.to_bytes()?;

let borrowed = Gsym::parse(bytes.as_slice())?;
assert_eq!(borrowed.as_ref().as_ptr(), bytes.as_ptr());

let owned = Gsym::parse(bytes)?;
assert_eq!(owned.lookup(0x2000)?.unwrap().frames()[0].name, b"borrowed");

Implementations§

Source§

impl<D: AsRef<[u8]>> Gsym<D>

Source

pub fn lookup(&self, address: u64) -> Result<Option<Lookup<'_>>>

Resolves an unslid virtual address with the default lookup options.

address must be an address of the image the file describes. An address from a running PIE executable or shared object needs its load bias removed first; see docs::symbolication.

Returns Ok(None) when no function covers the address, which is the normal answer for padding between functions and for addresses belonging to another module. The result borrows names and paths from this reader.

Frames come back innermost first. Use Self::lookup_with_options to skip record kinds you do not need, or Self::for_each_frame to resolve an address without allocating.

§Errors

Returns an error if the matched function’s data is malformed.

use gsym::{AddressRange, FileEntry, Function, Gsym, GsymBuilder, LineEntry};

let mut builder = GsymBuilder::new();
let file = builder.add_file(FileEntry::new(b"/src", b"main.rs"))?;
builder.add_function(Function {
    lines: vec![LineEntry::new(0x1000, file, 7)],
    ..Function::new(AddressRange::new(0x1000, 0x1010), b"main")
})?;
let bytes = builder.to_bytes()?;
let gsym = Gsym::parse(&bytes)?;

let hit = gsym.lookup(0x1004)?.expect("covered address");
assert_eq!(hit.frames()[0].name, b"main");
assert_eq!(hit.frames()[0].basename, b"main.rs");
assert_eq!(hit.frames()[0].line, 7);

assert!(gsym.lookup(0x2000)?.is_none());
Source

pub fn lookup_with_options<'data>( &'data self, address: u64, options: LookupOptions, scratch: &mut LookupScratch, ) -> Result<Option<Lookup<'data>>>

Resolves an address while reusing caller-owned inline scratch storage.

Same result as Self::lookup, with control over which optional records are read and with the scratch buffer supplied by the caller. The returned Lookup still owns its frames; use Self::for_each_frame to avoid that allocation as well.

§Errors

Returns an error if the matched function’s data is malformed.

Source

pub fn for_each_frame<'data>( &'data self, address: u64, options: FrameLookupOptions, scratch: &mut LookupScratch, visitor: impl FnMut(LookupFrame<'data>), ) -> Result<bool>

Visits source frames without allocating an output collection.

Frames are yielded innermost first and borrow their names and paths from the reader. Sizing the LookupScratch with LookupScratch::with_capacity keeps repeated lookups allocation-free.

Returns whether a function covered the address. The visitor is not called when it returns false. Call-site patterns are not reported here; use Self::lookup_with_options when they are needed.

use gsym::{
    AddressRange, FrameLookupOptions, Function, Gsym, GsymBuilder,
    LookupScratch,
};

let mut builder = GsymBuilder::new();
builder.add_function(Function::new(
    AddressRange::new(0x3000, 0x3010),
    b"visited",
))?;
let bytes = builder.to_bytes()?;
let gsym = Gsym::parse(bytes)?;

let mut scratch = LookupScratch::with_capacity(8);
let mut names = Vec::new();
let found = gsym.for_each_frame(
    0x3004,
    FrameLookupOptions::default(),
    &mut scratch,
    |frame| names.push(frame.name.to_vec()),
)?;
assert!(found);
assert_eq!(names, [b"visited".to_vec()]);
§Errors

Returns an error if the matched function’s data is malformed.

Source§

impl Gsym<Vec<u8>>

Source

pub fn open(path: impl AsRef<Path>) -> Result<Self>

Opens a GSYM file as an owned, immutable byte snapshot.

This is the safe filesystem entry point. Use MappedGsym::map when demand paging is worth the file-stability contract of a memory map.

§Errors

Returns a contextual I/O error when the file cannot be read, or a format error when its GSYM metadata is invalid.

use gsym::Gsym;

let gsym = Gsym::open("app.gsym")?;
let symbol = gsym.lookup(0x401000)?;
Source§

impl<D: AsRef<[u8]>> Gsym<D>

Source

pub fn parse(data: D) -> Result<Self>

Parses and validates the top-level GSYM tables without copying them.

§Errors

Returns an error for an unsupported version, truncated input, invalid table layout, or out-of-bounds section.

Source

pub fn into_inner(self) -> D

Returns the caller-provided byte storage.

Source

pub fn header(&self) -> Header<'_>

Returns decoded header metadata.

Source

pub fn build_id(&self) -> &[u8]

Returns the opaque build identifier, or an empty slice when absent.

Source

pub const fn functions(&self) -> Functions<'_, D>

Iterates all indexed functions in address-table order.

Source

pub fn function(&self, index: usize) -> Result<FunctionRef<'_>>

Returns a borrowed function record by address-table index.

§Errors

Returns Error::FunctionIndexOutOfBounds when index does not exist, or a format error when its address or function header is malformed.

Source

pub fn get_function(&self, index: usize) -> Result<Option<FunctionRef<'_>>>

Optionally returns a borrowed function record by address-table index.

This is the non-erroring bounds-checking counterpart to Self::function.

§Errors

Returns a format error if the indexed address or function header is malformed. An out-of-bounds index returns Ok(None).

Source

pub fn string(&self, offset: u64) -> Result<&[u8]>

Resolves a string-table offset to borrowed bytes.

§Errors

Returns an error for an out-of-bounds offset or missing NUL terminator.

Source

pub fn file(&self, index: impl Into<FileIndex>) -> Result<(&[u8], &[u8])>

Resolves a file-table index to borrowed directory and basename bytes.

§Errors

Returns an error for an invalid index or malformed string reference.

Source

pub fn verify(&self) -> Result<VerifyReport>

Fully verifies all indexed functions and their referenced metadata.

Checks that the address table is sorted, that every function record decodes, and that the strings, files, line programs, and inline ranges they reference are in bounds and well formed. Cost is proportional to the file, so this belongs at load time for an untrusted file, not in front of each lookup.

§Errors

Returns the first structural or semantic validation error.

use gsym::{AddressRange, Function, Gsym, GsymBuilder};

let mut builder = GsymBuilder::new();
builder.add_function(Function::new(
    AddressRange::new(0x1000, 0x1010),
    b"verified",
))?;
let bytes = builder.to_bytes()?;

let report = Gsym::parse(&bytes)?.verify()?;
assert_eq!(report.functions, 1);
Source§

impl<D: AsRef<[u8]>> Gsym<D>

Source

pub fn decode_all(&self) -> Result<DecodedGsym>

Decodes every file and function into an owned semantic model.

A record type this crate cannot represent is rejected to prevent a lossy transformation.

§Errors

Returns the first structural, reference, or semantic decoding error, including a file table whose reserved entry zero is not empty.

Source

pub fn transcode(&self, options: TranscodeOptions) -> Result<Vec<u8>>

Re-encodes this file with a selected version or byte order.

§Errors

Returns an error if the input is malformed or the semantic data cannot be represented by the requested output version.

Source§

impl Gsym<MappedBytes>

Source

pub unsafe fn map(path: impl AsRef<Path>) -> Result<Self>

Available on crate feature mmap only.

Opens and validates a GSYM file through a read-only memory map.

§Safety

The mapped file must not be modified or truncated by any process for the lifetime of the returned mapping. Use Gsym::open to read owned bytes when that cannot be guaranteed.

§Errors

Returns an I/O error when the file cannot be opened or mapped, or a format error when its GSYM metadata is invalid.

Source

pub unsafe fn map_file(file: &File) -> Result<Self>

Available on crate feature mmap only.

Maps and validates an already-open file.

Use this when the file was opened elsewhere, for instance through a descriptor passed in or a handle kept for locking. The mapping does not keep the File alive, so it may be closed once this returns.

§Safety

file must not be modified or truncated by any process for the lifetime of the returned mapping.

§Errors

Returns an I/O error when mapping fails or a format error for invalid GSYM metadata.

Trait Implementations§

Source§

impl<D: AsRef<[u8]>> AsRef<[u8]> for Gsym<D>

Source§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl<D: AsRef<[u8]>> Debug for Gsym<D>

Source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<D> Freeze for Gsym<D>
where D: Freeze,

§

impl<D> RefUnwindSafe for Gsym<D>
where D: RefUnwindSafe,

§

impl<D> Send for Gsym<D>
where D: Send,

§

impl<D> Sync for Gsym<D>
where D: Sync,

§

impl<D> Unpin for Gsym<D>
where D: Unpin,

§

impl<D> UnsafeUnpin for Gsym<D>
where D: UnsafeUnpin,

§

impl<D> UnwindSafe for Gsym<D>
where D: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToHex for T
where T: AsRef<[u8]>,

Source§

fn encode_hex<U>(&self) -> U
where U: FromIterator<char>,

Encode the hex strict representing self into the result. Lower case letters are used (e.g. f9b4ca)
Source§

fn encode_hex_upper<U>(&self) -> U
where U: FromIterator<char>,

Encode the hex strict representing self into the result. Upper case letters are used (e.g. F9B4CA)
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more