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 UnitThe unit being written to.
line_strings: &'a mut LineStringTableThe table containing converted line strings.
strings: &'a mut StringTableThe table containing converted strings.
Implementations§
Source§impl<'a, R: Reader<Offset = usize>> ConvertUnit<'a, R>
impl<'a, R: Reader<Offset = usize>> ConvertUnit<'a, R>
Sourcepub fn convert_split(
&'a mut self,
split_dwarf: &'a Dwarf<R>,
) -> ConvertResult<ConvertSplitUnitSection<'a, R>>
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.
}Sourcepub fn convert_split_with_filter(
&'a mut self,
filter: FilterUnitSection<'a, R>,
) -> ConvertResult<ConvertSplitUnitSection<'a, R>>
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.
}Sourcepub fn read_line_program(
&mut self,
encoding: Option<Encoding>,
line_encoding: Option<LineEncoding>,
) -> ConvertResult<Option<ConvertLineProgram<'_, R>>>
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.
Sourcepub fn set_line_program(
&mut self,
line_program: LineProgram,
line_program_files: Vec<FileId>,
)
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.
Sourcepub fn null_entry(&self) -> ConvertUnitEntry<'a, R>
pub fn null_entry(&self) -> ConvertUnitEntry<'a, R>
Return a null DIE for use with ConvertUnit::read_entry.
Sourcepub fn read_entry(
&mut self,
entry: &mut ConvertUnitEntry<'a, R>,
) -> ConvertResult<Option<Option<UnitEntryId>>>
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.
Sourcepub fn add_entry(
&mut self,
id: Option<UnitEntryId>,
entry: &ConvertUnitEntry<'_, R>,
) -> UnitEntryId
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).
Sourcepub fn write<W: Writer>(&mut self, sections: &mut Sections<W>) -> Result<()>
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.
Sourcepub fn skip(&mut self)
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.
Sourcepub fn convert(
&mut self,
root_entry: ConvertUnitEntry<'a, R>,
convert_address: &dyn Fn(u64) -> Option<Address>,
) -> ConvertResult<()>
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.
Sourcepub fn convert_attribute_value(
&mut self,
read_unit: UnitRef<'_, R>,
attr: &Attribute<R>,
convert_address: &dyn Fn(u64) -> Option<Address>,
) -> ConvertResult<AttributeValue>
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.
Sourcepub fn convert_expression(
&self,
read_unit: UnitRef<'_, R>,
expression: Expression<R>,
convert_address: &dyn Fn(u64) -> Option<Address>,
) -> ConvertResult<Expression>
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.
Sourcepub fn convert_file_index(
&self,
read_unit: UnitRef<'_, R>,
index: u64,
) -> ConvertResult<Option<FileId>>
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.
Sourcepub fn convert_location_list(
&self,
read_unit: UnitRef<'_, R>,
offset: LocationListsOffset,
convert_address: &dyn Fn(u64) -> Option<Address>,
) -> ConvertResult<LocationList>
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.
Sourcepub fn convert_range_list(
&self,
read_unit: UnitRef<'_, R>,
offset: RangeListsOffset,
convert_address: &dyn Fn(u64) -> Option<Address>,
) -> ConvertResult<RangeList>
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.
Sourcepub fn convert_unit_ref(&self, entry: UnitOffset) -> ConvertResult<UnitEntryId>
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.
Sourcepub fn convert_debug_info_ref(
&self,
entry: DebugInfoOffset,
) -> ConvertResult<DebugInfoRef>
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.