Skip to main content

ConvertUnit

Struct ConvertUnit 

Source
pub struct ConvertUnit<'a, R: Reader<Offset = usize>> {
    pub read_unit: UnitRef<'a, R>,
    pub read_skeleton_unit: Option<UnitRef<'a, R>>,
    pub unit: &'a mut Unit,
    pub line_strings: &'a mut LineStringTable,
    pub strings: &'a mut StringTable,
    /* private fields */
}
Expand description

The state for the conversion of a .debug_info unit.

This is created by ConvertUnitSection::read_unit or ConvertSplitUnitSection::read_unit.

§Example

Convert a unit.

let read_dwarf = gimli::read::Dwarf::load(loader)?;
let mut write_dwarf = gimli::write::Dwarf::new();
let mut convert = write_dwarf.convert(&read_dwarf)?;
while let Some((mut unit, root_entry)) = convert.read_unit()? {
    if let Some(convert_program) = unit.read_line_program(None, None)? {
        let (program, files) = convert_program.convert(
            &|address| Some(gimli::write::Address::Constant(address)),
        )?;
        unit.set_line_program(program, files);
    }
    let root_id = unit.unit.root();
    convert_attributes(&mut unit, root_id, &root_entry)?;
    let mut entry = root_entry;
    while let Some(id) = unit.read_entry(&mut entry)? {
        // `id` is `None` for DIEs that weren't reserved and thus don't need converting.
        // This only happens when `FilterUnitSection` is used.
        if id.is_none() {
            continue;
        }
        let id = unit.add_entry(id, &entry);
        convert_attributes(&mut unit, id, &entry)?;
    }
}

fn convert_attributes<R: gimli::Reader<Offset = usize>>(
    unit: &mut gimli::write::ConvertUnit<'_, R>,
    id: gimli::write::UnitEntryId,
    entry: &gimli::write::ConvertUnitEntry<'_, R>,
) -> gimli::write::ConvertResult<()> {
    for attr in &entry.attrs {
        let value = unit.convert_attribute_value(
            entry.read_unit,
            attr,
            &|address| Some(gimli::write::Address::Constant(address)),
        )?;
        unit.unit.get_mut(id).set(attr.name(), value);
    }
    Ok(())
}

Fields§

§read_unit: UnitRef<'a, R>

The unit being read from.

§read_skeleton_unit: Option<UnitRef<'a, R>>

The skeleton unit being read from if read_unit is a split unit.

§unit: &'a mut Unit

The unit being written to.

§line_strings: &'a mut LineStringTable

The table containing converted line strings.

§strings: &'a mut StringTable

The table containing converted strings.

Implementations§

Source§

impl<'a, R: Reader<Offset = usize>> ConvertUnit<'a, R>

Source

pub fn convert_split( &'a mut self, split_dwarf: &'a Dwarf<R>, ) -> ConvertResult<ConvertSplitUnitSection<'a, R>>

Create a converter for all DIEs in a split DWARF unit and its skeleton unit.

split_dwarf is the unit’s contribution to the DWARF sections in a DwarfPackage, or the DWARF sections in a DWO file.

§Example

Convert a split DWARF unit using convert_split.

let dwp = gimli::read::DwarfPackage::load(loader, Default::default())?;
let mut convert: gimli::write::ConvertUnitSection<_> = unimplemented!();
while let Some((mut unit, root_entry)) = convert.read_unit()? {
    let Some(dwo_id) = unit.read_unit.dwo_id else {
        // Not a split unit. Handling omitted for this example.
        continue;
    };
    let split_dwarf = dwp.find_cu(dwo_id, skeleton_unit.dwarf)?.unwrap();
    let mut convert_split = unit.convert_split(&split_dwarf)?;
    let (split_unit, split_root_entry) = convert_split.read_unit()?;
    // Now you can convert the root entry attributes, and other entries.
}
Source

pub fn convert_split_with_filter( &'a mut self, filter: FilterUnitSection<'a, R>, ) -> ConvertResult<ConvertSplitUnitSection<'a, R>>

Create a converter for some of the DIEs in a split DWARF unit and its skeleton unit.

filter determines which DIEs are converted. This can be created using FilterUnitSection::new_split.

§Example

Convert a split DWARF unit using convert_split_with_filter.

let dwp = gimli::read::DwarfPackage::load(loader, Default::default())?;
let mut convert: gimli::write::ConvertUnitSection<_> = unimplemented!();
while let Some((mut unit, root_entry)) = convert.read_unit()? {
    let Some(dwo_id) = unit.read_unit.dwo_id else {
        // Not a split unit. Handling omitted for this example.
        continue;
    };
    let split_dwarf = dwp.find_cu(dwo_id, skeleton_unit.dwarf)?.unwrap();
    let mut filter = gimli::write::FilterUnitSection::new_split(&split_dwarf, unit.read_unit)?;
    while let Some(mut unit) = filter.read_unit()? {
        let mut entry = unit.null_entry();
        while unit.read_entry(&mut entry)? {
            if need_entry(&entry)? {
                unit.require_entry(entry.offset);
            }
        }
    }
    let mut convert_split = unit.convert_split_with_filter(filter)?;
    let (split_unit, split_root_entry) = convert_split.read_unit()?;
    // Now you can convert the root entry attributes, and other entries.
}
Source

pub fn read_line_program( &mut self, encoding: Option<Encoding>, line_encoding: Option<LineEncoding>, ) -> ConvertResult<Option<ConvertLineProgram<'_, R>>>

Start converting the line number program for this unit.

encoding and line_encoding apply to the converted program, and may be different from the source program. If None, the encoding from the source program is used.

Returns Ok(None) if there is no line number program for this unit.

See ConvertLineProgram for an example of converting the program.

Source

pub fn set_line_program( &mut self, line_program: LineProgram, line_program_files: Vec<FileId>, )

Sets the converted line program for the unit, and the mapping for converting file index attributes.

The parameters are from the result of ConvertLineProgram::program.

Source

pub fn null_entry(&self) -> ConvertUnitEntry<'a, R>

Return a null DIE for use with ConvertUnit::read_entry.

Source

pub fn read_entry( &mut self, entry: &mut ConvertUnitEntry<'a, R>, ) -> ConvertResult<Option<Option<UnitEntryId>>>

Read the next DIE from the input.

Returns the UnitEntryId that was reserved for the entry, if any. If you wish to use this ID, you must call Unit::add_reserved or ConvertUnit::add_entry.

Returns a ConvertUnitEntry containing information about the DIE and its attributes.

Returns Ok(None) if there are no more entries.

Source

pub fn add_entry( &mut self, id: Option<UnitEntryId>, entry: &ConvertUnitEntry<'_, R>, ) -> UnitEntryId

Add an entry to the converted unit.

The tag, parent, and DW_AT_sibling attribute are set using the fields of entry. No other attributes are copied.

id is the entry ID that was reserved, if any. This is usually the ID that was returned by ConvertUnit::read_entry. Unit::add_reserved will automatically be called for this ID. If not specified then a new ID is created.

Returns the ID of the entry (either reserved or newly created).

Source

pub fn write<W: Writer>(&mut self, sections: &mut Sections<W>) -> Result<()>

Write the unit to the given sections.

This unit will be written immediately, instead of when Dwarf::write is called. Note that Dwarf::write must still be called after all units have been converted.

This also frees memory associated with DIEs for this, which is useful for reducing total memory usage.

Source

pub fn skip(&mut self)

Mark this unit as unneeded.

This unit will not be written, even when Dwarf::write is called.

This also frees memory associated with DIEs for this unit, which is useful for reducing total memory usage.

Source

pub fn convert( &mut self, root_entry: ConvertUnitEntry<'a, R>, convert_address: &dyn Fn(u64) -> Option<Address>, ) -> ConvertResult<()>

Convert everything in the unit.

This will convert all DIEs, and the values referenced by the attributes such as strings, ranges, locations and line programs. The converted values will be stored in Self::unit.

root_entry must be the entry returned by ConvertUnitSection::read_unit.

See Dwarf::from for the meaning of convert_address.

Source

pub fn convert_attribute_value( &mut self, read_unit: UnitRef<'_, R>, attr: &Attribute<R>, convert_address: &dyn Fn(u64) -> Option<Address>, ) -> ConvertResult<AttributeValue>

Convert an attribute value.

Self::set_line_program must be called before converting file index attributes.

See Dwarf::from for the meaning of convert_address.

Source

pub fn convert_expression( &self, read_unit: UnitRef<'_, R>, expression: Expression<R>, convert_address: &dyn Fn(u64) -> Option<Address>, ) -> ConvertResult<Expression>

Convert an expression.

See Dwarf::from for the meaning of convert_address.

Source

pub fn convert_file_index( &self, read_unit: UnitRef<'_, R>, index: u64, ) -> ConvertResult<Option<FileId>>

Convert a file index from a DW_AT_decl_file or similar attribute.

Self::set_line_program must be called before converting file index attributes.

Source

pub fn convert_location_list( &self, read_unit: UnitRef<'_, R>, offset: LocationListsOffset, convert_address: &dyn Fn(u64) -> Option<Address>, ) -> ConvertResult<LocationList>

Convert a location list.

See Dwarf::from for the meaning of convert_address.

Source

pub fn convert_range_list( &self, read_unit: UnitRef<'_, R>, offset: RangeListsOffset, convert_address: &dyn Fn(u64) -> Option<Address>, ) -> ConvertResult<RangeList>

Convert a range list.

See Dwarf::from for the meaning of convert_address.

Source

pub fn convert_unit_ref(&self, entry: UnitOffset) -> ConvertResult<UnitEntryId>

Convert a reference to an entry in the same unit.

This conversion doesn’t work for references from a skeleton unit, but those shouldn’t occur in practice.

Source

pub fn convert_debug_info_ref( &self, entry: DebugInfoOffset, ) -> ConvertResult<DebugInfoRef>

Convert a .debug_info reference.

This conversion doesn’t work for references from a skeleton unit, but those shouldn’t occur in practice.

Trait Implementations§

Source§

impl<'a, R: Debug + Reader<Offset = usize>> Debug for ConvertUnit<'a, R>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a, R> Freeze for ConvertUnit<'a, R>
where R: Freeze,

§

impl<'a, R> RefUnwindSafe for ConvertUnit<'a, R>
where R: RefUnwindSafe,

§

impl<'a, R> Send for ConvertUnit<'a, R>
where R: Send + Sync,

§

impl<'a, R> Sync for ConvertUnit<'a, R>
where R: Sync + Send,

§

impl<'a, R> Unpin for ConvertUnit<'a, R>
where R: Unpin,

§

impl<'a, R> UnsafeUnpin for ConvertUnit<'a, R>
where R: UnsafeUnpin,

§

impl<'a, R> !UnwindSafe for ConvertUnit<'a, R>

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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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, 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.