symbolizer::findDefinitionDie returns incorrect DW_AT_specification offset for DW_FORM_ref_addr
- Dominant language
- C++
- Stars
- 30.5k
- Forks
- 5.9k
- PR merge metrics
- No merged PRs in 30d
Description
`symbolizer::findDefinitionDie` unconditionally adds `cu.offset` to the offset returned by `getAttribute(cu, die, DW_AT_specification)`. in my gcc14-compiled binaries, that is usually correct since the `DW_AT_specification` is specified as `DW_FORM_sdata`, but sometimes it is represented as `DW_FORM_ref_addr`, in which case it is an absolute offset form the beginning of the `.debug_info` section (this is according to https://github.com/eliben/pyelftools/issues/241#issuecomment-565637775 ). this issue caused a an out-of-bounds `FOLLY_SAFE_CHECK(sp.size() >= sizeof(T), "underflow");` in `read`.
a small patch to `readAttribute` fixes my use case, but i'm not sure it's completely proper, especially since it causes the `Attribute`'s `uint64_t attrValue` to be negative:
```
case DW_FORM_ref_addr:
- return {spec, die, readOffset(info, die.is64Bit)};
+ {
+ uint64_t rawval = readOffset(info, die.is64Bit);
+ if(spec.name == DW_AT_specification) {
+ // A DW_AT_specification attribute is of class reference, and a
+ // reference is relative to the first byte of the cu header unless its
+ // of form DW_AT_refaddr, where its relative to the .debug_info section.
+ rawval -= cu.offset;
+ }
+ return {spec, die, rawval};
+ }
```
Contributor guide
Research direction
Start by locating symbolizer::findDefinitionDie and readAttribute, then trace how DW_AT_specification values are read for DW_FORM_sdata and DW_FORM_ref_addr. Reproduce the issue with a GCC 14-compiled binary using DW_FORM_ref_addr, and verify that the resulting offset is interpreted correctly without triggering the reported read underflow.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100