-
Notifications
You must be signed in to change notification settings - Fork 67
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
Add support for dwarf expressions for PLTs #1058
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Signed-off-by: Francisco Javier Honduvilla Coto <[email protected]>
javierhonduco
force-pushed
the
dwarf-expressions-plt
branch
3 times, most recently
from
November 22, 2022 15:36
f6d2551
to
d9acde2
Compare
kakkoyun
approved these changes
Nov 22, 2022
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Looks good to me. I only have comments on naming conventions. We seem to change them back and forth. We can try to find a linter setting for us to vet these if you want.
This commits adds partial support for DWARF expressions, in particular, for unwind ranges that cover PLTs for the CFA calculation (`DW_CFA_def_cfa_expression`). Arbitrary expressions require a VM to evaluate them, which is not easy to do in BPF, so after doing some quick data analysis (see below) it was clear that by adding some hardcoded expressions to increase the success ratio of the stack walker without bloating it too much. I don't think we should add every "common" expression, but the PLT ones seemed like good bang for the buck. On my Fedora machine, these were the most common expressions for binaries, and libraries, as well as for processes running: ``` [javierhonduco@fedora parca-agent]$ sudo readelf -wf /bin/* 2>/dev/null | grep DW_CFA_def_cfa_expression | sort | uniq -c | sort -k1h 1 DW_CFA_def_cfa_expression (DW_OP_breg7 (rsp): 160; DW_OP_deref) 5 DW_CFA_def_cfa_expression (DW_OP_breg4 (esp): 4; DW_OP_breg8 (eip): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit9; DW_OP_ge; DW_OP_lit2; DW_OP_shl; DW_OP_plus) 5 DW_CFA_def_cfa_expression (DW_OP_breg5 (ebp): -16; DW_OP_deref) 12 DW_CFA_def_cfa_expression (DW_OP_breg6 (rbp): -40; DW_OP_deref) 62 DW_CFA_def_cfa_expression (DW_OP_breg7 (rsp): 8; DW_OP_breg16 (rip): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit11; DW_OP_ge; DW_OP_lit3; DW_OP_shl; DW_OP_plus) 1673 DW_CFA_def_cfa_expression (DW_OP_breg7 (rsp): 8; DW_OP_breg16 (rip): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit10; DW_OP_ge; DW_OP_lit3; DW_OP_shl; DW_OP_plus) ``` ``` [javierhonduco@fedora parca-agent]$ sudo readelf -wf /lib64/* 2>/dev/null | grep DW_CFA_def_cfa_expression | sort | uniq -c | sort -k1h [...] 47 DW_CFA_def_cfa_expression (DW_OP_breg7 (rsp): 8; DW_OP_breg16 (rip): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit11; DW_OP_ge; DW_OP_lit3; DW_OP_shl; DW_OP_plus) 237 DW_CFA_def_cfa_expression (DW_OP_breg6 (rbp): -24; DW_OP_deref) 910 DW_CFA_def_cfa_expression (DW_OP_breg6 (rbp): -8; DW_OP_deref) 1006 DW_CFA_def_cfa_expression (DW_OP_breg6 (rbp): -40; DW_OP_deref) 2563 DW_CFA_def_cfa_expression (DW_OP_breg7 (rsp): 8; DW_OP_breg16 (rip): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit10; DW_OP_ge; DW_OP_lit3; DW_OP_shl; DW_OP_plus) ``` ``` [javierhonduco@fedora parca-agent]$ sudo readelf -wf /proc/*/exe 2>/dev/null | grep DW_CFA_def_cfa_expression | sort | uniq -c | sort -k1h [...] 25 DW_CFA_def_cfa_expression (DW_OP_breg7 (rsp): 120; DW_OP_deref; DW_OP_plus_uconst: 8) 25 DW_CFA_def_cfa_expression (DW_OP_breg7 (rsp): 152; DW_OP_deref; DW_OP_plus_uconst: 8) 25 DW_CFA_def_cfa_expression (DW_OP_breg7 (rsp): 88; DW_OP_deref; DW_OP_plus_uconst: 8) 30 DW_CFA_def_cfa_expression (DW_OP_breg7 (rsp): 0; DW_OP_deref; DW_OP_plus_uconst: 8) 35 DW_CFA_def_cfa_expression (DW_OP_breg7 (rsp): 40; DW_OP_deref; DW_OP_plus_uconst: 8) 45 DW_CFA_def_cfa_expression (DW_OP_breg7 (rsp): -8; DW_OP_deref; DW_OP_plus_uconst: 8) 130 DW_CFA_def_cfa_expression (DW_OP_breg7 (rsp): 8; DW_OP_breg16 (rip): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit10; DW_OP_ge; DW_OP_lit3; DW_OP_shl; DW_OP_plus) ``` As it can be seen above, by adding PLT expression support, we can get ~50% more unwind sections working. PLT sections are particularly important as libc is typically dynamically linked. In this case, most libc calls go through the Procedure Linkage Table, and before this commit, we will stop walking the stack. See test plan in the PR. Signed-off-by: Francisco Javier Honduvilla Coto <[email protected]>
javierhonduco
force-pushed
the
dwarf-expressions-plt
branch
from
November 22, 2022 16:05
d9acde2
to
b7d873d
Compare
Sylfrena
added a commit
that referenced
this pull request
Jan 26, 2024
DWARF Expressions are encoded with a `DW_CFA_def_cfa_expression` or `DW_CFA_expression` (as per aarch64 DWARF ABI). However grepping for either in `.eh_frame` debug information did not show any results (including hardcoded PLT patter heuristics) unlike in x86. (See #1058 for the x86 implementation). Tested on system binaries and libc in multiple distros: Debian, Fedora, Centos, Ubuntu Workflow: ``` `docker run -it --network=host arm64v8/fedora bash` `docker cp 0693985d3bba:/ ./fedrepo` `sudo readelf -wf ./fedrepo/bin/* 2>/dev/null | grep DW_CFA_cfa_def_expression` `sudo readelf -wF ./centos-repo/bin/* 2>/dev/null | grep exp` ``` Return an error for now if we come across an expression in Arm64 binaries. Signed-off-by: Sumera Priyadarsini <[email protected]>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
More context and rationale in the commit message, but this PR adds support for a small subset of DWARF expressions to compute the CFA. In particular, this tackles the common Procedure Linkage Tables (PLT). See this great post by MaskRay.
Bear in mind that while now we can theoretically add more hardcoded expressions I think we should be mindful of the increase in code size they can cause, so we ideally limit the number of hardcoded (or not) expressions.
Test Plan
Added a basic unittest to ensure that we don't accidentally change the dwarf expression constants (which were wrong in the Delve project. Will upstream this in some days)
No errors in both:
basic-cpp-plt
Whole debug log:
ruby