Obtain the linkage name of a subprogram or inlined subroutine.
(
&self,
unit: &Unit<ReaderTy<'_>>,
die: &DebuggingInformationEntry<ReaderTy<'_>>,
)
| 296 | |
| 297 | /// Obtain the linkage name of a subprogram or inlined subroutine. |
| 298 | fn linkage_name( |
| 299 | &self, |
| 300 | unit: &Unit<ReaderTy<'_>>, |
| 301 | die: &DebuggingInformationEntry<ReaderTy<'_>>, |
| 302 | ) -> Result<String, Error> { |
| 303 | let mut name = None; |
| 304 | let mut deleg = None; |
| 305 | |
| 306 | for attr in die.attrs() { |
| 307 | match attr.name() { |
| 308 | gimli::DW_AT_linkage_name => { |
| 309 | return Ok(self |
| 310 | .dwarf() |
| 311 | .attr_string(unit, attr.value())? |
| 312 | .to_string()? |
| 313 | .to_owned()); |
| 314 | } |
| 315 | |
| 316 | gimli::DW_AT_name => { |
| 317 | name = Some( |
| 318 | self.dwarf() |
| 319 | .attr_string(unit, attr.value())? |
| 320 | .to_string()? |
| 321 | .to_owned(), |
| 322 | ); |
| 323 | } |
| 324 | |
| 325 | gimli::DW_AT_abstract_origin | gimli::DW_AT_specification => { |
| 326 | // Delegation |
| 327 | deleg = Some(attr.value()); |
| 328 | } |
| 329 | |
| 330 | _ => (), |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | if let Some(name) = name { |
| 335 | return Ok(name); |
| 336 | } |
| 337 | |
| 338 | let Some(refer) = deleg else { |
| 339 | Err(Error::UnexpectedDwarf( |
| 340 | "Cannot find name for DW_TAG_subprogram", |
| 341 | ))? |
| 342 | }; |
| 343 | |
| 344 | match refer { |
| 345 | AttributeValue::UnitRef(offset) => { |
| 346 | let mut entries = unit.entries_at_offset(offset)?; |
| 347 | entries |
| 348 | .next_entry()? |
| 349 | .then_some(()) |
| 350 | .ok_or(Error::UnexpectedDwarf("Referenced entry not found"))?; |
| 351 | |
| 352 | let next_die = entries.current().unwrap(); |
| 353 | self.linkage_name(unit, next_die) |
| 354 | } |
| 355 |
no test coverage detected