(
&self,
addr_tr: &AddressTransform,
out_unit: &mut write::Unit,
current_scope_id: write::UnitEntryId,
)
| 90 | } |
| 91 | |
| 92 | pub(crate) fn build( |
| 93 | &self, |
| 94 | addr_tr: &AddressTransform, |
| 95 | out_unit: &mut write::Unit, |
| 96 | current_scope_id: write::UnitEntryId, |
| 97 | ) { |
| 98 | match self { |
| 99 | RangeInfoBuilder::Undefined => (), |
| 100 | RangeInfoBuilder::Position(pc) => { |
| 101 | let addr = addr_tr |
| 102 | .translate(*pc) |
| 103 | .unwrap_or(write::Address::Constant(0)); |
| 104 | let current_scope = out_unit.get_mut(current_scope_id); |
| 105 | current_scope.set(gimli::DW_AT_low_pc, write::AttributeValue::Address(addr)); |
| 106 | } |
| 107 | RangeInfoBuilder::Ranges(ranges) => { |
| 108 | let mut result = Vec::new(); |
| 109 | for (begin, end) in ranges { |
| 110 | result.extend(addr_tr.translate_ranges(*begin, *end)); |
| 111 | } |
| 112 | |
| 113 | // If we're seeing the ranges for a `DW_TAG_compile_unit` DIE |
| 114 | // then don't use `DW_AT_low_pc` and `DW_AT_high_pc`. These |
| 115 | // attributes, if set, will configure the base address of all |
| 116 | // location lists that this unit refers to. Currently this |
| 117 | // debug transform does not take this base address into account |
| 118 | // when generate the `.debug_loc` section. Consequently when a |
| 119 | // compile unit is configured here the `DW_AT_ranges` attribute |
| 120 | // is unconditionally used instead of |
| 121 | // `DW_AT_low_pc`/`DW_AT_high_pc`. |
| 122 | let is_attr_for_compile_unit = |
| 123 | out_unit.get(current_scope_id).tag() == gimli::DW_TAG_compile_unit; |
| 124 | |
| 125 | if result.len() != 1 || is_attr_for_compile_unit { |
| 126 | let range_list = result |
| 127 | .iter() |
| 128 | .map(|tr| write::Range::StartLength { |
| 129 | begin: tr.0, |
| 130 | length: tr.1, |
| 131 | }) |
| 132 | .collect::<Vec<_>>(); |
| 133 | let range_list_id = out_unit.ranges.add(write::RangeList(range_list)); |
| 134 | let current_scope = out_unit.get_mut(current_scope_id); |
| 135 | current_scope.set( |
| 136 | gimli::DW_AT_ranges, |
| 137 | write::AttributeValue::RangeListRef(range_list_id), |
| 138 | ); |
| 139 | } else { |
| 140 | let current_scope = out_unit.get_mut(current_scope_id); |
| 141 | current_scope.set( |
| 142 | gimli::DW_AT_low_pc, |
| 143 | write::AttributeValue::Address(result[0].0), |
| 144 | ); |
| 145 | current_scope.set( |
| 146 | gimli::DW_AT_high_pc, |
| 147 | write::AttributeValue::Udata(result[0].1), |
| 148 | ); |
| 149 | } |
nothing calls this directly
no test coverage detected