Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update DwarfWalker subrange handling #1369

Merged
merged 33 commits into from Feb 27, 2023

Conversation

hainest
Copy link
Contributor

@hainest hainest commented Feb 14, 2023

This effectively rewrites the handling of subranges and arrays in DwarfWalker by

  1. Removing custom handling of DW_FORM* types. This should only be done by libdw.
  2. Simplifying array dimension parsing (effectively removing the need for parseMultidimensionalArray)
  3. Separating subrange parsing from array parsing

This implementation was neither correct nor complete. Moreover, we
shouldn't be parsing FORM types. Looking for DW_TAG* is sufficient.
The LONG_MIN/MAX aren't great, but they are propagated to preserve
behavior.
This will happen in the callee
@hainest hainest added the DWARF Item is related to DWARF parsing label Feb 14, 2023
@hainest hainest self-assigned this Feb 14, 2023
@hainest hainest force-pushed the update_DwarfWalker_subrange_handling branch from 2ad8210 to ea0e6a9 Compare February 17, 2023 03:04
Copy link
Contributor

@kupsch kupsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that there are some corner cases that could be fixed now or in the future. See comments in the code.

What's there looks good.

dwarf/src/dwarf_subrange.h Show resolved Hide resolved
dwarf/src/dwarf_subrange.cpp Show resolved Hide resolved
common/h/dyninstversion.h Outdated Show resolved Hide resolved
namespace Dyninst {
namespace DwarfDyninst {

dwarf_result<long> dwarf_subrange_upper_bound(Dwarf_Die *die) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int64_t or Dwarf_Word instead of long? OK on linux and everywhere Dyninst runs, but long is required to be only at least 32-bits and would narrow the result if you were on a non-64-bit long system such as win64.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about C VLAs and C flexible arrays? The DWARF form type is an exprloc and not a constant integer type. I also see subranges with a type, but without a DW_AT_upper_bound attribute (it also changes an array of array to a single subrange without the DW_AT_upper_bound.

These could be deferred to a new issue: array types need an unknown (and maybe locexpr) upper bound value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched using Dwarf_Word. VLAs and flexible arrays aren't handled in libdw's dwarf_aggregate_size. Maybe we can just ignore them here, as well?

Dwarf_Word count;
if (dwarf_formudata(&attr, &count) != 0)
return dwarf_error{};
return count;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return count + lower_bound - 1?

Works for zero-based array languages, but not 1-based arrays for languages or those that support a true range for the index values. Perhaps for efficiency there should only a function to return both lower and upper bounds as a pair so lower bound doesn't need to be computed twice if DW_AT_count is used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I refactored this with the added assumption of zero-based if there is DW_AT_count but no DW_AT_lower_bound or dwarf_srclang_lower_bound.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable

This was accidentally included.
C++ doesn't guarantee it is convertible to `long`.
The calculation for a range's upper bound when DW_AT_count is used
requires knowing the lower bound (if given), so these needed to be
merged.
@hainest
Copy link
Contributor Author

hainest commented Feb 27, 2023

Updates are testing fine.

@hainest hainest merged commit 9d15c0f into dyninst:master Feb 27, 2023
@hainest hainest deleted the update_DwarfWalker_subrange_handling branch February 27, 2023 18:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DWARF Item is related to DWARF parsing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants