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>
impl<D: AsRef<[u8]>> Gsym<D>
Sourcepub fn lookup(&self, address: u64) -> Result<Option<Lookup<'_>>>
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());Sourcepub fn lookup_with_options<'data>(
&'data self,
address: u64,
options: LookupOptions,
scratch: &mut LookupScratch,
) -> Result<Option<Lookup<'data>>>
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.
Sourcepub fn for_each_frame<'data>(
&'data self,
address: u64,
options: FrameLookupOptions,
scratch: &mut LookupScratch,
visitor: impl FnMut(LookupFrame<'data>),
) -> Result<bool>
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>>
impl Gsym<Vec<u8>>
Sourcepub fn open(path: impl AsRef<Path>) -> Result<Self>
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>
impl<D: AsRef<[u8]>> Gsym<D>
Sourcepub fn parse(data: D) -> Result<Self>
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.
Sourcepub fn into_inner(self) -> D
pub fn into_inner(self) -> D
Returns the caller-provided byte storage.
Sourcepub fn build_id(&self) -> &[u8] ⓘ
pub fn build_id(&self) -> &[u8] ⓘ
Returns the opaque build identifier, or an empty slice when absent.
Sourcepub const fn functions(&self) -> Functions<'_, D> ⓘ
pub const fn functions(&self) -> Functions<'_, D> ⓘ
Iterates all indexed functions in address-table order.
Sourcepub fn function(&self, index: usize) -> Result<FunctionRef<'_>>
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.
Sourcepub fn get_function(&self, index: usize) -> Result<Option<FunctionRef<'_>>>
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).
Sourcepub fn string(&self, offset: u64) -> Result<&[u8]>
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.
Sourcepub fn file(&self, index: impl Into<FileIndex>) -> Result<(&[u8], &[u8])>
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.
Sourcepub fn verify(&self) -> Result<VerifyReport>
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>
impl<D: AsRef<[u8]>> Gsym<D>
Sourcepub fn decode_all(&self) -> Result<DecodedGsym>
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§impl Gsym<MappedBytes>
impl Gsym<MappedBytes>
Sourcepub unsafe fn map(path: impl AsRef<Path>) -> Result<Self>
Available on crate feature mmap only.
pub unsafe fn map(path: impl AsRef<Path>) -> Result<Self>
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.
Sourcepub unsafe fn map_file(file: &File) -> Result<Self>
Available on crate feature mmap only.
pub unsafe fn map_file(file: &File) -> Result<Self>
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§
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> ToHex for T
impl<T> ToHex for T
Source§fn encode_hex<U>(&self) -> Uwhere
U: FromIterator<char>,
fn encode_hex<U>(&self) -> Uwhere
U: FromIterator<char>,
self into the result. Lower case
letters are used (e.g. f9b4ca)Source§fn encode_hex_upper<U>(&self) -> Uwhere
U: FromIterator<char>,
fn encode_hex_upper<U>(&self) -> Uwhere
U: FromIterator<char>,
self into the result. Upper case
letters are used (e.g. F9B4CA)